Skip to content

Commit

Permalink
[ADP-3335] Add withDBHandleInMemory (#4525)
Browse files Browse the repository at this point in the history
This pull request adds a function `withDBHandleInMemory` and uses it in
`Cardano.Wallet.Deposit.IO.DB`.

### Comment

This pull request prepares the implementation of a mock environment for
the Deposit Wallet. In turn, this enables execution of user scenarios.

### Issue Number

ADP-3335
  • Loading branch information
HeinrichApfelmus authored Apr 8, 2024
2 parents df60978 + 1b5b9c2 commit 402014f
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 5 deletions.
32 changes: 27 additions & 5 deletions lib/customer-deposit-wallet/src/Cardano/Wallet/Deposit/IO/DB.hs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ module Cardano.Wallet.Deposit.IO.DB
( SqlM
, SqlContext (..)
, withSqliteFile
, withSqlContextInMemory

, DBLog (..)
) where
Expand All @@ -17,10 +18,12 @@ import Cardano.DB.Sqlite
( DBLog (..)
, dbBackend
, withDBHandle
, withDBHandleInMemory
)
import Control.Concurrent.MVar
( newMVar
, withMVar
, withMVarMasked
)
import Control.Tracer
( Tracer
Expand All @@ -33,17 +36,36 @@ import Data.Time.Clock
import qualified Database.Persist.Sql as Persistent

{-----------------------------------------------------------------------------
Comment layout
SqlContext
------------------------------------------------------------------------------}
-- | Monad to run SQL queries in.
type SqlM = Persistent.SqlPersistT IO

-- | A facility to run 'SqlM' computations.
-- Importantly, computations are not run in parallel, but sequenced.
newtype SqlContext = SqlContext
{ runQuery :: forall a. SqlM a -> IO a
{ runSqlM :: forall a. SqlM a -> IO a
}

-- | Acquire and release an 'SqlContext' in memory.
withSqlContextInMemory
:: Tracer IO DBLog
-- ^ Logging
-> (SqlContext -> IO a)
-- ^ Action to run
-> IO a
withSqlContextInMemory tr action = do
withDBHandleInMemory tr $ \dbhandle -> do
-- Lock ensures that database operations are sequenced.
lock <- newMVar (dbBackend dbhandle)
let runSqlM :: SqlM a -> IO a
runSqlM cmd =
withMVarMasked lock (observe . Persistent.runSqlConn cmd)
action $ SqlContext{runSqlM}
where
observe :: IO a -> IO a
observe = bracketTracer (contramap MsgRun tr)

-- | Open an .sqlite database file
-- and provide an 'SqlContext' for running 'SqlM' actions.
withSqliteFile
Expand All @@ -61,16 +83,16 @@ withSqliteFile tr fp action = do
let
-- Run a query on the open database,
-- but retry on busy.
runQuery :: SqlM a -> IO a
runQuery cmd =
runSqlM :: SqlM a -> IO a
runSqlM cmd =
observe
. retryOnBusy tr retryOnBusyTimeout
$ withMVar lock
$ const
$ Persistent.runSqlConn cmd
$ dbBackend dbHandle
in
action $ SqlContext{runQuery}
action $ SqlContext{runSqlM}
where
observe :: IO a -> IO a
observe = bracketTracer (contramap MsgRun tr)
Expand Down
9 changes: 9 additions & 0 deletions lib/wallet/src/Cardano/DB/Sqlite.hs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ module Cardano.DB.Sqlite
-- * DB Connections
, DBHandle
, withDBHandle
, withDBHandleInMemory
, dbConn
, dbFile
, dbBackend
Expand Down Expand Up @@ -302,6 +303,14 @@ withDBHandle
withDBHandle tr fp =
bracket (newDBHandle tr fp) (closeDBHandleRetrying tr)

-- | Acquire and release a 'DBHandle' in memory.
withDBHandleInMemory
:: Tracer IO DBLog
-> (DBHandle -> IO a)
-> IO a
withDBHandleInMemory tr =
bracket (newDBHandleInMemory tr) (closeDBHandle tr)

-- | Create a new 'DBHandle' from a file.
-- Needs to be closed explicitly.
newDBHandle
Expand Down

0 comments on commit 402014f

Please sign in to comment.