File: StatementCache.hs

package info (click to toggle)
haskell-persistent 2.17.1.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,196 kB
  • sloc: haskell: 14,076; makefile: 3
file content (66 lines) | stat: -rw-r--r-- 2,380 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
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 { .. }