module Hasql.Private.PreparedStatementRegistry
(
PreparedStatementRegistry,
new,
update,
LocalKey(..),
)
where
import Hasql.Private.Prelude hiding (lookup)
import qualified Data.HashTable.IO as A
import qualified ByteString.StrictBuilder as B
data PreparedStatementRegistry =
PreparedStatementRegistry !(A.BasicHashTable LocalKey ByteString) !(IORef Word)
{-# INLINABLE new #-}
new :: IO PreparedStatementRegistry
new =
PreparedStatementRegistry <$> A.new <*> newIORef 0
{-# INLINABLE update #-}
update :: LocalKey -> (ByteString -> IO (Bool, a)) -> (ByteString -> IO a) -> PreparedStatementRegistry -> IO a
update localKey onNewRemoteKey onOldRemoteKey (PreparedStatementRegistry table counter) =
lookup >>= maybe new old
where
lookup =
A.lookup table localKey
new =
readIORef counter >>= onN
where
onN n =
do
(save, result) <- onNewRemoteKey remoteKey
when save $ do
A.insert table localKey remoteKey
writeIORef counter (succ n)
return result
where
remoteKey =
B.builderBytes . B.asciiIntegral $ n
old =
onOldRemoteKey
data LocalKey =
LocalKey !ByteString ![Word32]
deriving (Show, Eq)
instance Hashable LocalKey where
{-# INLINE hashWithSalt #-}
hashWithSalt salt (LocalKey template types) =
hashWithSalt salt template