{-# LANGUAGE NamedFieldPuns #-}
module BaseXClient.Query where

import BaseXClient.Utils hiding (exec)
import qualified BaseXClient.Utils as Utils
import Control.Applicative
import System.IO

data Query = Query
  { session :: Handle
  , ident :: String
  } deriving Show

bind :: String -> String -> String -> Query -> IO String
bind name val ty = exec 3 [name, val, ty]

context :: String -> String -> Query -> IO String
context val ty = exec 14 [val, ty]

results :: Query -> IO [String]
results Query { session, ident } = do
  writeCode session 4
  writeString session ident
  result <- untilM (ok session) (readString session)
  ok session >>= \b -> if b
    then return result
    else readString session >>= error

execute, info, options, updating, close :: Query -> IO String
execute  = sendCode 5
info     = sendCode 6
options  = sendCode 7
updating = sendCode 30
close    = sendCode 2

sendCode :: Int -> Query -> IO String
sendCode code = exec code []

exec :: Int -> [String] -> Query -> IO String
exec code args Query { session, ident } = Utils.exec code (ident : args) session