module Hasql.Postgres.Statement where import Hasql.Postgres.Prelude import qualified Database.PostgreSQL.LibPQ as L import qualified Hasql.Postgres.OID as OID import qualified Hasql.Postgres.Renderer as Renderer type Statement = (ByteString, [(ValueType, Value)], Preparable) -- | -- Maybe a rendered value with its serialization format. -- 'Nothing' implies @NULL@. type Value = Maybe (ByteString, L.Format) type ValueType = L.Oid type Preparable = Bool -- * Transaction types ------------------------- type Cursor = ByteString data Isolation = ReadCommitted | RepeatableRead | Serializable type TransactionMode = (Isolation, Bool) declareCursor :: Cursor -> Statement -> Statement declareCursor cursor (template, values, preparable) = let template' = "DECLARE " <> cursor <> " NO SCROLL CURSOR FOR " <> template in (template', values, preparable) closeCursor :: Cursor -> Statement closeCursor cursor = (template, [], False) where template = Renderer.run cursor $ \c -> Renderer.string7 "CLOSE " <> Renderer.byteString c fetchFromCursor :: Cursor -> Statement fetchFromCursor cursor = (template, [], False) where template = Renderer.run cursor $ \c -> Renderer.string7 "FETCH FORWARD 256 FROM " <> Renderer.byteString c beginTransaction :: TransactionMode -> Statement beginTransaction mode = (template, [], True) where template = Renderer.run mode $ \(i, w) -> mconcat $ intersperse (Renderer.char7 ' ') $ [ Renderer.string7 "BEGIN" , case i of ReadCommitted -> Renderer.string7 "ISOLATION LEVEL READ COMMITTED" RepeatableRead -> Renderer.string7 "ISOLATION LEVEL REPEATABLE READ" Serializable -> Renderer.string7 "ISOLATION LEVEL SERIALIZABLE" , case w of True -> "READ WRITE" False -> "READ ONLY" ] commitTransaction :: Statement commitTransaction = ("COMMIT", [], True) abortTransaction :: Statement abortTransaction = ("ABORT", [], True)