module Hasql.Transaction.Queries
where
import Hasql.Transaction.Prelude
import qualified Hasql.Query as HQ
import qualified Hasql.Encoding as HE
import qualified Hasql.Decoding as HD
import qualified ByteString.TreeBuilder as TB
data Isolation =
ReadCommitted |
RepeatableRead |
Serializable
type TransactionMode =
(Isolation, Bool)
beginTransaction :: TransactionMode -> HQ.Query () ()
beginTransaction (isolation, write) =
HQ.Query sql HE.unit HD.unit True
where
sql =
TB.toByteString $
mconcat $
[
"BEGIN "
,
case isolation of
ReadCommitted -> "ISOLATION LEVEL READ COMMITTED"
RepeatableRead -> "ISOLATION LEVEL REPEATABLE READ"
Serializable -> "ISOLATION LEVEL SERIALIZABLE"
,
" "
,
case write of
True -> "READ WRITE"
False -> "READ ONLY"
]
commitTransaction :: HQ.Query () ()
commitTransaction =
HQ.Query "commit" HE.unit HD.unit True
abortTransaction :: HQ.Query () ()
abortTransaction =
HQ.Query "abort" HE.unit HD.unit True
declareCursor :: ByteString -> ByteString -> HE.Params a -> HQ.Query a ()
declareCursor name sql encoder =
HQ.Query sql' encoder HD.unit False
where
sql' =
TB.toByteString $
"DECLARE " <> TB.byteString name <> " NO SCROLL CURSOR FOR " <> TB.byteString sql
closeCursor :: HQ.Query ByteString ()
closeCursor =
HQ.Query "CLOSE $1" (HE.value HE.bytea) HD.unit True
fetchFromCursor :: (b -> a -> b) -> b -> HD.Row a -> HQ.Query (Int64, ByteString) b
fetchFromCursor step init rowDec =
HQ.Query sql encoder decoder True
where
sql =
"FETCH FORWARD $1 FROM $2"
encoder =
contrazip2
(HE.value HE.int8)
(HE.value HE.bytea)
decoder =
HD.foldlRows step init rowDec