hasql/library/Hasql/PreparedStatementRegistry.hs
2024-04-19 07:38:30 +03:00

54 lines
1.4 KiB
Haskell

module Hasql.PreparedStatementRegistry
( PreparedStatementRegistry,
new,
update,
LocalKey (..),
)
where
import ByteString.StrictBuilder qualified as B
import Data.HashTable.IO qualified as A
import Hasql.Prelude hiding (lookup)
data PreparedStatementRegistry
= PreparedStatementRegistry !(A.BasicHashTable LocalKey ByteString) !(IORef Word)
{-# INLINEABLE new #-}
new :: IO PreparedStatementRegistry
new =
PreparedStatementRegistry <$> A.new <*> newIORef 0
{-# INLINEABLE 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
-- |
-- Local statement key.
data LocalKey
= LocalKey !ByteString ![Word32]
deriving (Show, Eq)
instance Hashable LocalKey where
{-# INLINE hashWithSalt #-}
hashWithSalt salt (LocalKey template types) =
hashWithSalt salt template