module Hasql.Postgres.StatementPreparer where
import Hasql.Postgres.Prelude
import qualified Data.HashTable.IO as Hashtables
import qualified Database.PostgreSQL.LibPQ as PQ
import qualified Hasql.Postgres.ResultParser as Result
import qualified Hasql.Postgres.ResultHandler as ResultHandler
import qualified Data.ByteString as B
import qualified Data.ByteString.Builder as BB
import qualified Data.ByteString.Lazy as BL
type StatementPreparer =
(PQ.Connection, IORef Word16, Hashtables.BasicHashTable LocalKey RemoteKey)
data LocalKey =
LocalKey !ByteString ![PQ.Oid]
deriving (Show, Eq)
instance Hashable LocalKey where
hashWithSalt s (LocalKey b _) = hashWithSalt s b
type RemoteKey =
ByteString
new :: PQ.Connection -> IO StatementPreparer
new connection =
(,,) <$> pure connection <*> newIORef 0 <*> Hashtables.new
prepare :: ByteString -> [PQ.Oid] -> StatementPreparer -> IO RemoteKey
prepare s tl (c, counter, table) =
do
let k = LocalKey s tl
r <- Hashtables.lookup table k
case r of
Just r ->
return r
Nothing ->
do
w <- readIORef counter
n <- return (BL.toStrict $ BB.toLazyByteString $ BB.word16Dec w)
ResultHandler.unit =<< Result.parse c =<< PQ.prepare c n s (partial (not . null) tl)
Hashtables.insert table k n
writeIORef counter (succ w)
return n