persistent 2.13.2.2 → 2.13.3.0
raw patch · 13 files changed
+378/−53 lines, 13 filesdep +vaultdep ~mtl
Dependencies added: vault
Dependency ranges changed: mtl
Files
- ChangeLog.md +8/−0
- Database/Persist/Sql/Raw.hs +15/−12
- Database/Persist/Sql/Run.hs +35/−11
- Database/Persist/Sql/Types.hs +1/−2
- Database/Persist/Sql/Types/Internal.hs +15/−11
- Database/Persist/SqlBackend.hs +64/−4
- Database/Persist/SqlBackend/Internal.hs +28/−8
- Database/Persist/SqlBackend/Internal/MkSqlBackend.hs +4/−4
- Database/Persist/SqlBackend/Internal/SqlPoolHooks.hs +21/−0
- Database/Persist/SqlBackend/Internal/StatementCache.hs +23/−0
- Database/Persist/SqlBackend/SqlPoolHooks.hs +92/−0
- Database/Persist/SqlBackend/StatementCache.hs +66/−0
- persistent.cabal +6/−1
ChangeLog.md view
@@ -1,5 +1,13 @@ # Changelog for persistent +## 2.13.3.0++* [#1341](https://github.com/yesodweb/persistent/pull/1341)+ * Add `SqlBackendHooks` to allow for instrumentation of queries.+* [#1327](https://github.com/yesodweb/persistent/pull/1327)+ * Update `SqlBackend` to use new `StatementCache` interface+ instead of `IORef (Map Text Statement)`+ ## 2.13.2.2 * [#1351](https://github.com/yesodweb/persistent/pull/1351/)
Database/Persist/Sql/Raw.hs view
@@ -1,23 +1,23 @@ module Database.Persist.Sql.Raw where import Control.Exception (throwIO)-import Control.Monad (when, liftM)+import Control.Monad (liftM, when) import Control.Monad.IO.Class (MonadIO, liftIO) import Control.Monad.Logger (logDebugNS, runLoggingT)-import Control.Monad.Reader (ReaderT, ask, MonadReader)-import Control.Monad.Trans.Resource (MonadResource,release)-import Data.Acquire (allocateAcquire, Acquire, mkAcquire, with)+import Control.Monad.Reader (MonadReader, ReaderT, ask)+import Control.Monad.Trans.Resource (MonadResource, release)+import Data.Acquire (Acquire, allocateAcquire, mkAcquire, with) import Data.Conduit-import Data.IORef (writeIORef, readIORef, newIORef)-import qualified Data.Map as Map+import Data.IORef (newIORef, readIORef, writeIORef) import Data.Int (Int64) import Data.Text (Text, pack) import qualified Data.Text as T import Database.Persist+import Database.Persist.Sql.Class import Database.Persist.Sql.Types import Database.Persist.Sql.Types.Internal-import Database.Persist.Sql.Class+import Database.Persist.SqlBackend.Internal.StatementCache rawQuery :: (MonadResource m, MonadReader env m, BackendCompatible SqlBackend env) => Text@@ -75,9 +75,10 @@ getStmtConn :: SqlBackend -> Text -> IO Statement getStmtConn conn sql = do- smap <- liftIO $ readIORef $ connStmtMap conn- case Map.lookup sql smap of- Just stmt -> return stmt+ let cacheK = mkCacheKeyFromQuery sql+ mstmt <- statementCacheLookup (connStmtMap conn) cacheK+ stmt <- case mstmt of+ Just stmt -> pure stmt Nothing -> do stmt' <- liftIO $ connPrepare conn sql iactive <- liftIO $ newIORef True@@ -100,8 +101,10 @@ then stmtQuery stmt' x else liftIO $ throwIO $ StatementAlreadyFinalized sql }- liftIO $ writeIORef (connStmtMap conn) $ Map.insert sql stmt smap- return stmt++ liftIO $ statementCacheInsert (connStmtMap conn) cacheK stmt+ pure stmt+ (hookGetStatement $ connHooks conn) conn sql stmt -- | Execute a raw SQL statement and return its results as a -- list. If you do not expect a return value, use of
Database/Persist/Sql/Run.hs view
@@ -1,23 +1,25 @@ {-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE RecordWildCards #-} module Database.Persist.Sql.Run where import Control.Monad.IO.Unlift-import qualified UnliftIO.Exception as UE import Control.Monad.Logger.CallStack-import Control.Monad.Reader (MonadReader)+import Control.Monad.Reader (MonadReader, void) import qualified Control.Monad.Reader as MonadReader import Control.Monad.Trans.Reader hiding (local) import Control.Monad.Trans.Resource import Data.Acquire (Acquire, ReleaseType(..), mkAcquireType, with)-import Data.IORef (readIORef) import Data.Pool as P-import qualified Data.Map as Map import qualified Data.Text as T+import qualified UnliftIO.Exception as UE import Database.Persist.Class.PersistStore+import Database.Persist.Sql.Raw import Database.Persist.Sql.Types import Database.Persist.Sql.Types.Internal-import Database.Persist.Sql.Raw+import Database.Persist.SqlBackend.Internal.StatementCache+import Database.Persist.SqlBackend.Internal.SqlPoolHooks -- | Get a connection from the pool, run the given action, and then return the -- connection to the pool.@@ -93,15 +95,36 @@ -- cleanup function is complete. -> m a runSqlPoolWithHooks r pconn i before after onException =+ runSqlPoolWithExtensibleHooks r pconn i $ SqlPoolHooks+ { alterBackend = pure+ , runBefore = \conn _ -> void $ before conn+ , runAfter = \conn _ -> void $ after conn+ , runOnException = \b _ e -> void $ onException b e+ }++-- | This function is how 'runSqlPoolWithHooks' is defined.+--+-- It's currently the most general function for using a SQL pool.+--+-- @since 2.13.0.0+runSqlPoolWithExtensibleHooks+ :: forall backend m a. (MonadUnliftIO m, BackendCompatible SqlBackend backend)+ => ReaderT backend m a+ -> Pool backend+ -> Maybe IsolationLevel+ -> SqlPoolHooks m backend+ -> m a+runSqlPoolWithExtensibleHooks r pconn i SqlPoolHooks{..} = withRunInIO $ \runInIO -> withResource pconn $ \conn -> UE.mask $ \restore -> do- _ <- restore $ runInIO $ before conn- a <- restore (runInIO (runReaderT r conn))+ conn' <- restore $ runInIO $ alterBackend conn+ _ <- restore $ runInIO $ runBefore conn' i+ a <- restore (runInIO (runReaderT r conn')) `UE.catchAny` \e -> do- _ <- restore $ runInIO $ onException conn e+ _ <- restore $ runInIO $ runOnException conn' i e UE.throwIO e- _ <- restore $ runInIO $ after conn+ _ <- restore $ runInIO $ runAfter conn' i pure a rawAcquireSqlConn@@ -296,5 +319,6 @@ close' :: (BackendCompatible SqlBackend backend) => backend -> IO () close' conn = do- readIORef (connStmtMap $ projectBackend conn) >>= mapM_ stmtFinalize . Map.elems- connClose $ projectBackend conn+ let backend = projectBackend conn+ statementCacheClear $ connStmtMap backend+ connClose backend
Database/Persist/Sql/Types.hs view
@@ -12,9 +12,8 @@ import Control.Monad.Logger (NoLoggingT) import Control.Monad.Trans.Reader (ReaderT(..)) import Control.Monad.Trans.Resource (ResourceT)-import Control.Monad.Trans.Writer (WriterT) import Data.Pool (Pool)-import Data.Text (Text, unpack)+import Data.Text (Text) import Data.Time (NominalDiffTime) import Database.Persist.Sql.Types.Internal
Database/Persist/Sql/Types/Internal.hs view
@@ -1,7 +1,7 @@ {-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE DuplicateRecordFields #-} {-# LANGUAGE RankNTypes #-}-{-# language RecordWildCards #-}-{-# language DuplicateRecordFields #-}+{-# LANGUAGE RecordWildCards #-} -- | Breaking changes to this module are not reflected in the major version -- number. Prefer to import from "Database.Persist.Sql" instead. If you neeed@@ -25,24 +25,28 @@ , SqlReadT , SqlWriteT , IsSqlBackend+ , SqlBackendHooks (..) ) where import Control.Monad.Trans.Class (lift)-import Control.Monad.Trans.Reader (ReaderT, runReaderT, ask)+import Control.Monad.Trans.Reader (ReaderT, ask, runReaderT) import Database.Persist.Class- ( HasPersistBackend (..)- , PersistQueryRead, PersistQueryWrite- , PersistStoreRead, PersistStoreWrite- , PersistUniqueRead, PersistUniqueWrite- , BackendCompatible(..)- )-import Database.Persist.Class.PersistStore (IsPersistBackend (..))+ ( BackendCompatible(..)+ , HasPersistBackend(..)+ , PersistQueryRead+ , PersistQueryWrite+ , PersistStoreRead+ , PersistStoreWrite+ , PersistUniqueRead+ , PersistUniqueWrite+ )+import Database.Persist.Class.PersistStore (IsPersistBackend(..)) import Database.Persist.SqlBackend.Internal import Database.Persist.SqlBackend.Internal.InsertSqlResult+import Database.Persist.SqlBackend.Internal.IsolationLevel import Database.Persist.SqlBackend.Internal.MkSqlBackend import Database.Persist.SqlBackend.Internal.Statement-import Database.Persist.SqlBackend.Internal.IsolationLevel -- | An SQL backend which can only handle read queries --
Database/Persist/SqlBackend.hs view
@@ -6,35 +6,46 @@ SqlBackend , mkSqlBackend , MkSqlBackendArgs(..)+ , SqlBackendHooks+ , emptySqlBackendHooks -- * Utilities -- $utilities -- ** SqlBackend Getters+ , getRDBMS , getEscapedFieldName , getEscapedRawName , getEscapeRawNameFunction , getConnLimitOffset , getConnUpsertSql+ , getConnVault+ , getConnHooks -- ** SqlBackend Setters , setConnMaxParams , setConnRepsertManySql , setConnInsertManySql , setConnUpsertSql , setConnPutManySql+ , setConnVault+ , modifyConnVault+ , setConnHooks+ -- ** SqlBackendHooks ) where import Control.Monad.Reader+import Data.List.NonEmpty (NonEmpty) import Data.Text (Text)+import Data.Vault.Strict (Vault) import Database.Persist.Class.PersistStore (BackendCompatible(..))+import Database.Persist.Names import Database.Persist.SqlBackend.Internal import qualified Database.Persist.SqlBackend.Internal as SqlBackend (SqlBackend(..))-import Database.Persist.SqlBackend.Internal.MkSqlBackend as Mk (MkSqlBackendArgs(..))-import Database.Persist.Types.Base-import Database.Persist.Names import Database.Persist.SqlBackend.Internal.InsertSqlResult-import Data.List.NonEmpty (NonEmpty)+import Database.Persist.SqlBackend.Internal.MkSqlBackend as Mk+ (MkSqlBackendArgs(..))+import Database.Persist.Types.Base -- $utilities --@@ -129,7 +140,35 @@ getConnUpsertSql = do asks (SqlBackend.connUpsertSql . projectBackend) +-- | Retrieve the vault from the provided database backend.+--+-- @since 2.13.3.0+getConnVault+ :: (BackendCompatible SqlBackend backend, MonadReader backend m)+ => m Vault+getConnVault = do+ asks (SqlBackend.connVault . projectBackend) +-- | Retrieve instrumentation hooks from the provided database backend.+--+-- @since 2.13.3.0+getConnHooks+ :: (BackendCompatible SqlBackend backend, MonadReader backend m)+ => m SqlBackendHooks+getConnHooks = do+ asks (SqlBackend.connHooks . projectBackend)++-- | Get a tag displaying what database the 'SqlBackend' is for. Can be+-- used to differentiate features in downstream libraries for different+-- database backends.+-- @since 2.13.3.0+getRDBMS+ :: (BackendCompatible SqlBackend backend, MonadReader backend m)+ => m Text+getRDBMS = do+ asks (SqlBackend.connRDBMS . projectBackend)++ -- | Set the maximum parameters that may be issued in a given SQL query. This -- should be used only if the database backend have this limitation. --@@ -188,3 +227,24 @@ -> SqlBackend setConnPutManySql mkQuery sb = sb { connPutManySql = Just mkQuery }++-- | Set the vault on the provided database backend.+--+-- @since 2.13.0+setConnVault :: Vault -> SqlBackend -> SqlBackend+setConnVault vault sb =+ sb { connVault = vault }++-- | Modify the vault on the provided database backend.+--+-- @since 2.13.0+modifyConnVault :: (Vault -> Vault) -> SqlBackend -> SqlBackend+modifyConnVault f sb =+ sb { connVault = f $ connVault sb }++-- | Set hooks on the provided database backend.+--+-- @since 2.13.0+setConnHooks :: SqlBackendHooks -> SqlBackend -> SqlBackend+setConnHooks hooks sb =+ sb { connHooks = hooks }
Database/Persist/SqlBackend/Internal.hs view
@@ -1,19 +1,21 @@-{-# language RecordWildCards #-}-{-# language RankNTypes #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE RecordWildCards #-} module Database.Persist.SqlBackend.Internal where -import Data.Map (Map) import Data.List.NonEmpty (NonEmpty) import Data.Text (Text)+import Data.Vault.Strict (Vault)+import qualified Data.Vault.Strict as Vault import Database.Persist.Class.PersistStore-import Database.Persist.Types.Base import Database.Persist.Names-import Data.IORef-import Database.Persist.SqlBackend.Internal.MkSqlBackend-import Database.Persist.SqlBackend.Internal.Statement import Database.Persist.SqlBackend.Internal.InsertSqlResult import Database.Persist.SqlBackend.Internal.IsolationLevel+import Database.Persist.SqlBackend.Internal.MkSqlBackend+import Database.Persist.SqlBackend.Internal.Statement+import Database.Persist.SqlBackend.Internal.StatementCache (StatementCache)+import Database.Persist.SqlBackend.StatementCache+import Database.Persist.Types.Base -- | A 'SqlBackend' represents a handle or connection to a database. It -- contains functions and values that allow databases to have more@@ -69,7 +71,7 @@ -- When left as 'Nothing', we default to using 'defaultPutMany'. -- -- @since 2.8.1- , connStmtMap :: IORef (Map Text Statement)+ , connStmtMap :: StatementCache -- ^ A reference to the cache of statements. 'Statement's are keyed by -- the 'Text' queries that generated them. , connClose :: IO ()@@ -132,8 +134,23 @@ -- When left as 'Nothing', we default to using 'defaultRepsertMany'. -- -- @since 2.9.0+ , connVault :: Vault+ -- ^ Carry arbitrary payloads for the connection that+ -- may be used to propagate information into hooks.+ , connHooks :: SqlBackendHooks+ -- ^ Instrumentation hooks that may be used to track the+ -- behaviour of a backend. } +newtype SqlBackendHooks = SqlBackendHooks+ { hookGetStatement :: SqlBackend -> Text -> Statement -> IO Statement+ }++emptySqlBackendHooks :: SqlBackendHooks+emptySqlBackendHooks = SqlBackendHooks+ { hookGetStatement = \_ _ s -> pure s+ }+ -- | A function for creating a value of the 'SqlBackend' type. You should prefer -- to use this instead of the constructor for 'SqlBackend', because default -- values for this will be provided for new fields on the record when new@@ -148,6 +165,9 @@ , connPutManySql = Nothing , connUpsertSql = Nothing , connInsertManySql = Nothing+ , connVault = Vault.empty+ , connHooks = emptySqlBackendHooks+ , connStmtMap = mkStatementCache $ mkSimpleStatementCache connStmtMap , .. }
Database/Persist/SqlBackend/Internal/MkSqlBackend.hs view
@@ -3,14 +3,14 @@ module Database.Persist.SqlBackend.Internal.MkSqlBackend where import Control.Monad.Logger (Loc, LogLevel, LogSource, LogStr)-import Data.IORef-import Data.Map (Map) import Data.Text (Text)-import Database.Persist.SqlBackend.Internal.Statement+import Database.Persist.Names import Database.Persist.SqlBackend.Internal.InsertSqlResult import Database.Persist.SqlBackend.Internal.IsolationLevel+import Database.Persist.SqlBackend.Internal.Statement import Database.Persist.Types.Base-import Database.Persist.Names+import Data.Map (Map)+import Data.IORef (IORef) -- | This type shares many of the same field names as the 'SqlBackend' type. -- It's useful for library authors to use this when migrating from using the
+ Database/Persist/SqlBackend/Internal/SqlPoolHooks.hs view
@@ -0,0 +1,21 @@+module Database.Persist.SqlBackend.Internal.SqlPoolHooks+ ( SqlPoolHooks(..)+ ) where+import Control.Exception (SomeException)+import Database.Persist.SqlBackend.Internal.IsolationLevel++-- | A set of hooks that may be used to alter the behaviour+-- of @runSqlPoolWithExtensibleHooks@ in a backwards-compatible+-- fashion.+data SqlPoolHooks m backend = SqlPoolHooks+ { alterBackend :: backend -> m backend+ -- ^ Alter the backend prior to executing any actions with it.+ , runBefore :: backend -> Maybe IsolationLevel -> m ()+ -- ^ Run this action immediately before the action is performed.+ , runAfter :: backend -> Maybe IsolationLevel -> m ()+ -- ^ Run this action immediately after the action is completed.+ , runOnException :: backend -> Maybe IsolationLevel -> SomeException -> m ()+ -- ^ This action is performed when an exception is received. The+ -- exception is provided as a convenience - it is rethrown once this+ -- cleanup function is complete.+ }
+ Database/Persist/SqlBackend/Internal/StatementCache.hs view
@@ -0,0 +1,23 @@+module Database.Persist.SqlBackend.Internal.StatementCache where++import Data.Text (Text)+import Database.Persist.SqlBackend.Internal.Statement++-- | A statement cache used to lookup statements that have already been prepared+-- for a given query.+--+-- @since 2.13.3+data StatementCache = StatementCache+ { statementCacheLookup :: StatementCacheKey -> IO (Maybe Statement)+ , statementCacheInsert :: StatementCacheKey -> Statement -> IO ()+ , statementCacheClear :: IO ()+ , statementCacheSize :: IO Int+ }++newtype StatementCacheKey = StatementCacheKey { cacheKey :: Text }+-- Wrapping around this to allow for more efficient keying mechanisms+-- in the future, perhaps.++-- | Construct a `StatementCacheKey` from a raw SQL query.+mkCacheKeyFromQuery :: Text -> StatementCacheKey+mkCacheKeyFromQuery = StatementCacheKey
+ Database/Persist/SqlBackend/SqlPoolHooks.hs view
@@ -0,0 +1,92 @@+module Database.Persist.SqlBackend.SqlPoolHooks+ ( SqlPoolHooks+ , defaultSqlPoolHooks+ , getAlterBackend+ , modifyAlterBackend+ , setAlterBackend+ , getRunBefore+ , modifyRunBefore+ , setRunBefore+ , getRunAfter+ , modifyRunAfter+ , setRunAfter+ , getRunOnException+ )+ where++import Control.Exception+import Control.Monad.IO.Class+import Database.Persist.Sql.Raw+import Database.Persist.SqlBackend.Internal+import Database.Persist.SqlBackend.Internal.SqlPoolHooks+import Database.Persist.SqlBackend.Internal.IsolationLevel+import Database.Persist.Class.PersistStore++-- | Lifecycle hooks that may be altered to extend SQL pool behavior+-- in a backwards compatible fashion.+--+-- By default, the hooks have the following semantics:+--+-- - 'alterBackend' has no effect+-- - 'runBefore' begins a transaction+-- - 'runAfter' commits the current transaction+-- - 'runOnException' rolls back the current transaction+--+-- @since 2.13.3.0+defaultSqlPoolHooks :: (MonadIO m, BackendCompatible SqlBackend backend) => SqlPoolHooks m backend+defaultSqlPoolHooks = SqlPoolHooks+ { alterBackend = pure+ , runBefore = \conn mi -> do+ let sqlBackend = projectBackend conn+ let getter = getStmtConn sqlBackend+ liftIO $ connBegin sqlBackend getter mi+ , runAfter = \conn _ -> do+ let sqlBackend = projectBackend conn+ let getter = getStmtConn sqlBackend+ liftIO $ connCommit sqlBackend getter+ , runOnException = \conn _ _ -> do+ let sqlBackend = projectBackend conn+ let getter = getStmtConn sqlBackend+ liftIO $ connRollback sqlBackend getter+ }++getAlterBackend :: SqlPoolHooks m backend -> (backend -> m backend)+getAlterBackend = alterBackend++modifyAlterBackend :: SqlPoolHooks m backend -> ((backend -> m backend) -> (backend -> m backend)) -> SqlPoolHooks m backend+modifyAlterBackend hooks f = hooks { alterBackend = f $ alterBackend hooks }++setAlterBackend :: SqlPoolHooks m backend -> (backend -> m backend) -> SqlPoolHooks m backend+setAlterBackend hooks f = hooks { alterBackend = f }+++getRunBefore :: SqlPoolHooks m backend -> (backend -> Maybe IsolationLevel -> m ())+getRunBefore = runBefore++modifyRunBefore :: SqlPoolHooks m backend -> ((backend -> Maybe IsolationLevel -> m ()) -> (backend -> Maybe IsolationLevel -> m ())) -> SqlPoolHooks m backend+modifyRunBefore hooks f = hooks { runBefore = f $ runBefore hooks }++setRunBefore :: SqlPoolHooks m backend -> (backend -> Maybe IsolationLevel -> m ()) -> SqlPoolHooks m backend+setRunBefore h f = h { runBefore = f }+++getRunAfter :: SqlPoolHooks m backend -> (backend -> Maybe IsolationLevel -> m ())+getRunAfter = runAfter++modifyRunAfter :: SqlPoolHooks m backend -> ((backend -> Maybe IsolationLevel -> m ()) -> (backend -> Maybe IsolationLevel -> m ())) -> SqlPoolHooks m backend+modifyRunAfter hooks f = hooks { runAfter = f $ runAfter hooks }++setRunAfter :: SqlPoolHooks m backend -> (backend -> Maybe IsolationLevel -> m ()) -> SqlPoolHooks m backend+setRunAfter hooks f = hooks { runAfter = f }+++getRunOnException :: SqlPoolHooks m backend -> (backend -> Maybe IsolationLevel -> SomeException -> m ())+getRunOnException = runOnException++modifyRunOnException :: SqlPoolHooks m backend -> ((backend -> Maybe IsolationLevel -> SomeException -> m ()) -> (backend -> Maybe IsolationLevel -> SomeException -> m ())) -> SqlPoolHooks m backend+modifyRunOnException hooks f = hooks { runOnException = f $ runOnException hooks }++setRunOnException :: SqlPoolHooks m backend -> (backend -> Maybe IsolationLevel -> SomeException -> m ()) -> SqlPoolHooks m backend+setRunOnException hooks f = hooks { runOnException = f }++
+ Database/Persist/SqlBackend/StatementCache.hs view
@@ -0,0 +1,66 @@+{-# LANGUAGE RecordWildCards #-}+module Database.Persist.SqlBackend.StatementCache+ ( StatementCache+ , StatementCacheKey+ , mkCacheKeyFromQuery+ , MkStatementCache(..)+ , mkSimpleStatementCache+ , mkStatementCache+ ) where++import Data.Foldable+import Data.IORef+import qualified Data.Map as Map+import Database.Persist.SqlBackend.Internal.Statement+import Database.Persist.SqlBackend.Internal.StatementCache+import Data.Map (Map)+import Data.Text (Text)++-- | Configuration parameters for creating a custom statement cache+--+-- @since 2.13.3+data MkStatementCache = MkStatementCache+ { statementCacheLookup :: StatementCacheKey -> IO (Maybe Statement)+ -- ^ Retrieve a statement from the cache, or return nothing if it is not found.+ --+ -- @since 2.13.3+ , statementCacheInsert :: StatementCacheKey -> Statement -> IO ()+ -- ^ Put a new statement into the cache. An immediate lookup of+ -- the statement MUST return the inserted statement for the given+ -- cache key. Depending on the implementation, the statement cache MAY+ -- choose to evict other statements from the cache within this function.+ --+ -- @since 2.13.3+ , statementCacheClear :: IO ()+ -- ^ Remove all statements from the cache. Implementations of this+ -- should be sure to call `stmtFinalize` on all statements removed+ -- from the cache.+ --+ -- @since 2.13.3+ , statementCacheSize :: IO Int+ -- ^ Get the current size of the cache.+ --+ -- @since 2.13.3+ }+++-- | Make a simple statement cache that will cache statements if they are not currently cached.+--+-- @since 2.13.3+mkSimpleStatementCache :: IORef (Map Text Statement) -> MkStatementCache+mkSimpleStatementCache stmtMap =+ MkStatementCache+ { statementCacheLookup = \sql -> Map.lookup (cacheKey sql) <$> readIORef stmtMap+ , statementCacheInsert = \sql stmt ->+ modifyIORef' stmtMap (Map.insert (cacheKey sql) stmt)+ , statementCacheClear = do+ oldStatements <- atomicModifyIORef' stmtMap (\oldStatements -> (Map.empty, oldStatements))+ traverse_ stmtFinalize oldStatements+ , statementCacheSize = Map.size <$> readIORef stmtMap+ }++-- | Create a statement cache.+--+-- @since 2.13.0+mkStatementCache :: MkStatementCache -> StatementCache+mkStatementCache MkStatementCache{..} = StatementCache { .. }
persistent.cabal view
@@ -1,5 +1,5 @@ name: persistent-version: 2.13.2.2+version: 2.13.3.0 license: MIT license-file: LICENSE author: Michael Snoyman <michael@snoyman.com>@@ -42,6 +42,7 @@ , unliftio , unliftio-core , unordered-containers+ , vault , vector default-extensions: @@ -72,10 +73,14 @@ Database.Persist.Sql.Util Database.Persist.SqlBackend+ Database.Persist.SqlBackend.StatementCache+ Database.Persist.SqlBackend.SqlPoolHooks Database.Persist.SqlBackend.Internal Database.Persist.SqlBackend.Internal.InsertSqlResult Database.Persist.SqlBackend.Internal.IsolationLevel+ Database.Persist.SqlBackend.Internal.SqlPoolHooks Database.Persist.SqlBackend.Internal.Statement+ Database.Persist.SqlBackend.Internal.StatementCache Database.Persist.SqlBackend.Internal.MkSqlBackend Database.Persist.Class