{-# 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 :: Query -> String -> String -> String -> IO String
bind query name val ty = exec query 3 [name, val, ty]

context :: Query -> String -> String -> IO String
context query val ty = exec query 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 query = exec query code []

exec :: Query -> Int -> [String] -> IO String
exec Query{session, ident} code strs = Utils.exec session code $ ident : strs