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.Renderer as Renderer
import qualified Hasql.Postgres.ResultParser as Result
import qualified Hasql.Postgres.ResultHandler as ResultHandler
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 (Renderer.run w Renderer.word16)
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