module Database.Bolty
(
Config(..)
, ValidatedConfig
, validateConfig
, Scheme(..)
, Routing(..)
, UserAgent(..)
, Version(..)
, Connection
, connect
, close
, reset
, ping
, logon
, logoff
, connectionVersion
, connectionAgent
, connectionId
, connectionTelemetryEnabled
, connectionServerIdleTimeout
, TelemetryApi(..)
, sendTelemetry
, withTransaction
, withRetryTransaction
, withTransaction'
, RetryConfig(..)
, defaultRetryConfig
, isTransient
, isRoutingError
, Bolt(..)
, Record
, Error(..)
, asNull, asBool, asInt, asFloat, asBytes, asText
, asList, asDict, asNode, asRelationship, asPath
, QueryMeta(..)
, BoltPool
, PoolConfig(..)
, defaultPoolConfig
, ValidationStrategy(..)
, PoolCounters(..)
, createPool
, destroyPool
, withConnection
, CheckedOutConnection(..)
, acquireConnection
, releaseConnection
, releaseConnectionOnError
, poolCounters
, AccessMode(..)
, RoutingTable(..)
, RoutingPool
, RoutingPoolConfig(..)
, defaultRoutingPoolConfig
, createRoutingPool
, destroyRoutingPool
, withRoutingConnection
, acquireRoutingConnection
, withRoutingTransaction
, invalidateRoutingTable
, getRoutingTable
, Session
, SessionConfig(..)
, defaultSessionConfig
, BookmarkManager
, createSession
, createRoutingSession
, readTransaction
, writeTransaction
, getLastBookmarks
, PlanNode(..)
, ProfileNode(..)
, queryExplain
, queryProfile
, QueryLog(..)
, Notification(..)
, Severity(..)
, Position(..)
, QueryStats(..)
, BoltM
, runBolt
, query
, queryWith
, queryResult
, queryMeta
, queryMetaWith
, queryResultMeta
, execute
, DecodeError(..)
, Decode(..)
, RowDecoder(..)
, FromBolt(..)
, ToBolt(..)
, Database.Bolty.Decode.bool
, Database.Bolty.Decode.int
, int64
, Database.Bolty.Decode.float
, Database.Bolty.Decode.text
, Database.Bolty.Decode.bytes
, nullable, list, dict
, Database.Bolty.Decode.uuid
, utcTime, day, timeOfDay
, aesonValue
, nodeProperty, nodePropertyOptional, Database.Bolty.Decode.nodeLabels, Database.Bolty.Decode.nodeProperties
, Database.Bolty.Decode.node
, Database.Bolty.Decode.relationship
, Database.Bolty.Decode.path
, column, field
, ResultSet(..)
, decodeResultSet
, decodeHead
, groupByField
, Ps(..)
) where
import Database.Bolty.Connection (queryPWithFieldsIO, queryPMetaIO)
import Database.Bolty.Logging (QueryLog(..))
import Database.Bolty.Plan (PlanNode(..), ProfileNode(..))
import Database.Bolty.Notification (Notification(..), Severity(..), Position(..))
import Database.Bolty.Stats (QueryStats(..))
import Database.Bolty.Decode
import Database.Bolty.Connection.Config (validateConfig)
import qualified Database.Bolty.Connection.Pipe as P
import Database.Bolty.Connection.Pipe (connectionVersion, connectionAgent,
connectionId, connectionTelemetryEnabled,
connectionServerIdleTimeout)
import Database.Bolty.Connection.Type
import Database.Bolty.Message.Request (Begin(Begin), TelemetryApi(..))
import Database.Bolty.Message.Response
import Database.Bolty.Pool
import Database.Bolty.Record
import Database.Bolty.ResultSet
import Database.Bolty.Routing (AccessMode(..), RoutingPool, RoutingPoolConfig(..),
defaultRoutingPoolConfig, createRoutingPool,
destroyRoutingPool, withRoutingConnection,
acquireRoutingConnection,
withRoutingTransaction, invalidateRoutingTable,
getRoutingTable)
import Database.Bolty.Session (Session, SessionConfig(..), defaultSessionConfig,
BookmarkManager, createSession, createRoutingSession,
readTransaction, writeTransaction, getLastBookmarks)
import Database.Bolty.Value.Type (Bolt(..), asNull, asBool, asInt, asFloat
, asBytes, asText, asList, asDict
, asNode, asRelationship, asPath)
import Database.Bolty.Connection.Version (Version(..))
import Data.Kind (Type)
import Control.Concurrent (threadDelay)
import Control.Exception (SomeException, fromException, onException,
throwIO, try)
import Control.Monad (void)
import Control.Monad.Reader (ReaderT(..))
import Control.Monad.Trans (MonadIO(..))
import Data.Text (Text)
import GHC.Stack (HasCallStack)
import qualified Data.HashMap.Lazy as H
import qualified Data.Vector as V
import Data.PackStream.Ps (Ps(..))
connect :: (MonadIO m, HasCallStack) => ValidatedConfig -> m Connection
connect :: forall (m :: * -> *).
(MonadIO m, HasCallStack) =>
ValidatedConfig -> m Connection
connect = ValidatedConfig -> m Connection
forall (m :: * -> *).
(MonadIO m, HasCallStack) =>
ValidatedConfig -> m Connection
P.connect
close :: (MonadIO m, HasCallStack) => Connection -> m ()
close :: forall (m :: * -> *).
(MonadIO m, HasCallStack) =>
Connection -> m ()
close = Connection -> m ()
forall (m :: * -> *).
(MonadIO m, HasCallStack) =>
Connection -> m ()
P.close
reset :: (MonadIO m, HasCallStack) => Connection -> m ()
reset :: forall (m :: * -> *).
(MonadIO m, HasCallStack) =>
Connection -> m ()
reset = Connection -> m ()
forall (m :: * -> *).
(MonadIO m, HasCallStack) =>
Connection -> m ()
P.reset
ping :: MonadIO m => Connection -> m Bool
ping :: forall (m :: * -> *). MonadIO m => Connection -> m Bool
ping = Connection -> m Bool
forall (m :: * -> *). MonadIO m => Connection -> m Bool
P.ping
logon :: (MonadIO m, HasCallStack) => Connection -> Scheme -> m ()
logon :: forall (m :: * -> *).
(MonadIO m, HasCallStack) =>
Connection -> Scheme -> m ()
logon = Connection -> Scheme -> m ()
forall (m :: * -> *).
(MonadIO m, HasCallStack) =>
Connection -> Scheme -> m ()
P.logon
logoff :: (MonadIO m, HasCallStack) => Connection -> m ()
logoff :: forall (m :: * -> *).
(MonadIO m, HasCallStack) =>
Connection -> m ()
logoff = Connection -> m ()
forall (m :: * -> *).
(MonadIO m, HasCallStack) =>
Connection -> m ()
P.logoff
sendTelemetry :: (MonadIO m, HasCallStack) => Connection -> TelemetryApi -> m ()
sendTelemetry :: forall (m :: * -> *).
(MonadIO m, HasCallStack) =>
Connection -> TelemetryApi -> m ()
sendTelemetry = Connection -> TelemetryApi -> m ()
forall (m :: * -> *).
(MonadIO m, HasCallStack) =>
Connection -> TelemetryApi -> m ()
P.sendTelemetry
type BoltM :: Type -> Type
type role BoltM nominal
newtype BoltM a = BoltM (ReaderT Connection IO a)
deriving newtype ((forall a b. (a -> b) -> BoltM a -> BoltM b)
-> (forall a b. a -> BoltM b -> BoltM a) -> Functor BoltM
forall a b. a -> BoltM b -> BoltM a
forall a b. (a -> b) -> BoltM a -> BoltM b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall a b. (a -> b) -> BoltM a -> BoltM b
fmap :: forall a b. (a -> b) -> BoltM a -> BoltM b
$c<$ :: forall a b. a -> BoltM b -> BoltM a
<$ :: forall a b. a -> BoltM b -> BoltM a
Functor, Functor BoltM
Functor BoltM =>
(forall a. a -> BoltM a)
-> (forall a b. BoltM (a -> b) -> BoltM a -> BoltM b)
-> (forall a b c. (a -> b -> c) -> BoltM a -> BoltM b -> BoltM c)
-> (forall a b. BoltM a -> BoltM b -> BoltM b)
-> (forall a b. BoltM a -> BoltM b -> BoltM a)
-> Applicative BoltM
forall a. a -> BoltM a
forall a b. BoltM a -> BoltM b -> BoltM a
forall a b. BoltM a -> BoltM b -> BoltM b
forall a b. BoltM (a -> b) -> BoltM a -> BoltM b
forall a b c. (a -> b -> c) -> BoltM a -> BoltM b -> BoltM c
forall (f :: * -> *).
Functor f =>
(forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
$cpure :: forall a. a -> BoltM a
pure :: forall a. a -> BoltM a
$c<*> :: forall a b. BoltM (a -> b) -> BoltM a -> BoltM b
<*> :: forall a b. BoltM (a -> b) -> BoltM a -> BoltM b
$cliftA2 :: forall a b c. (a -> b -> c) -> BoltM a -> BoltM b -> BoltM c
liftA2 :: forall a b c. (a -> b -> c) -> BoltM a -> BoltM b -> BoltM c
$c*> :: forall a b. BoltM a -> BoltM b -> BoltM b
*> :: forall a b. BoltM a -> BoltM b -> BoltM b
$c<* :: forall a b. BoltM a -> BoltM b -> BoltM a
<* :: forall a b. BoltM a -> BoltM b -> BoltM a
Applicative, Applicative BoltM
Applicative BoltM =>
(forall a b. BoltM a -> (a -> BoltM b) -> BoltM b)
-> (forall a b. BoltM a -> BoltM b -> BoltM b)
-> (forall a. a -> BoltM a)
-> Monad BoltM
forall a. a -> BoltM a
forall a b. BoltM a -> BoltM b -> BoltM b
forall a b. BoltM a -> (a -> BoltM b) -> BoltM b
forall (m :: * -> *).
Applicative m =>
(forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
$c>>= :: forall a b. BoltM a -> (a -> BoltM b) -> BoltM b
>>= :: forall a b. BoltM a -> (a -> BoltM b) -> BoltM b
$c>> :: forall a b. BoltM a -> BoltM b -> BoltM b
>> :: forall a b. BoltM a -> BoltM b -> BoltM b
$creturn :: forall a. a -> BoltM a
return :: forall a. a -> BoltM a
Monad, Monad BoltM
Monad BoltM => (forall a. IO a -> BoltM a) -> MonadIO BoltM
forall a. IO a -> BoltM a
forall (m :: * -> *).
Monad m =>
(forall a. IO a -> m a) -> MonadIO m
$cliftIO :: forall a. IO a -> BoltM a
liftIO :: forall a. IO a -> BoltM a
MonadIO)
runBolt :: Connection -> BoltM a -> IO a
runBolt :: forall a. Connection -> BoltM a -> IO a
runBolt Connection
conn (BoltM ReaderT Connection IO a
m) = ReaderT Connection IO a -> Connection -> IO a
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT ReaderT Connection IO a
m Connection
conn
query :: (FromBolt a, HasCallStack) => Text -> H.HashMap Text Ps -> BoltM (Either DecodeError (V.Vector a))
query :: forall a.
(FromBolt a, HasCallStack) =>
Text -> HashMap Text Ps -> BoltM (Either DecodeError (Vector a))
query = RowDecoder a
-> Text -> HashMap Text Ps -> BoltM (Either DecodeError (Vector a))
forall a.
HasCallStack =>
RowDecoder a
-> Text -> HashMap Text Ps -> BoltM (Either DecodeError (Vector a))
queryWith RowDecoder a
forall a. FromBolt a => RowDecoder a
rowDecoder
queryWith :: HasCallStack => RowDecoder a -> Text -> H.HashMap Text Ps -> BoltM (Either DecodeError (V.Vector a))
queryWith :: forall a.
HasCallStack =>
RowDecoder a
-> Text -> HashMap Text Ps -> BoltM (Either DecodeError (Vector a))
queryWith RowDecoder a
decoder Text
cypher HashMap Text Ps
params = ReaderT Connection IO (Either DecodeError (Vector a))
-> BoltM (Either DecodeError (Vector a))
forall a. ReaderT Connection IO a -> BoltM a
BoltM (ReaderT Connection IO (Either DecodeError (Vector a))
-> BoltM (Either DecodeError (Vector a)))
-> ReaderT Connection IO (Either DecodeError (Vector a))
-> BoltM (Either DecodeError (Vector a))
forall a b. (a -> b) -> a -> b
$ (Connection -> IO (Either DecodeError (Vector a)))
-> ReaderT Connection IO (Either DecodeError (Vector a))
forall r (m :: * -> *) a. (r -> m a) -> ReaderT r m a
ReaderT ((Connection -> IO (Either DecodeError (Vector a)))
-> ReaderT Connection IO (Either DecodeError (Vector a)))
-> (Connection -> IO (Either DecodeError (Vector a)))
-> ReaderT Connection IO (Either DecodeError (Vector a))
forall a b. (a -> b) -> a -> b
$ \Connection
conn -> do
(cols, recs) <- HasCallStack =>
Connection
-> Text -> HashMap Text Ps -> IO (Vector Text, Vector Record)
Connection
-> Text -> HashMap Text Ps -> IO (Vector Text, Vector Record)
queryPWithFieldsIO Connection
conn Text
cypher HashMap Text Ps
params
pure $ decodeRows decoder cols recs
queryResult :: HasCallStack => Text -> H.HashMap Text Ps -> BoltM ResultSet
queryResult :: HasCallStack => Text -> HashMap Text Ps -> BoltM ResultSet
queryResult Text
cypher HashMap Text Ps
params = ReaderT Connection IO ResultSet -> BoltM ResultSet
forall a. ReaderT Connection IO a -> BoltM a
BoltM (ReaderT Connection IO ResultSet -> BoltM ResultSet)
-> ReaderT Connection IO ResultSet -> BoltM ResultSet
forall a b. (a -> b) -> a -> b
$ (Connection -> IO ResultSet) -> ReaderT Connection IO ResultSet
forall r (m :: * -> *) a. (r -> m a) -> ReaderT r m a
ReaderT ((Connection -> IO ResultSet) -> ReaderT Connection IO ResultSet)
-> (Connection -> IO ResultSet) -> ReaderT Connection IO ResultSet
forall a b. (a -> b) -> a -> b
$ \Connection
conn -> do
(fs, rs) <- HasCallStack =>
Connection
-> Text -> HashMap Text Ps -> IO (Vector Text, Vector Record)
Connection
-> Text -> HashMap Text Ps -> IO (Vector Text, Vector Record)
queryPWithFieldsIO Connection
conn Text
cypher HashMap Text Ps
params
pure $ ResultSet fs rs
queryMeta :: (FromBolt a, HasCallStack) => Text -> H.HashMap Text Ps -> BoltM (Either DecodeError (V.Vector a), QueryMeta)
queryMeta :: forall a.
(FromBolt a, HasCallStack) =>
Text
-> HashMap Text Ps
-> BoltM (Either DecodeError (Vector a), QueryMeta)
queryMeta = RowDecoder a
-> Text
-> HashMap Text Ps
-> BoltM (Either DecodeError (Vector a), QueryMeta)
forall a.
HasCallStack =>
RowDecoder a
-> Text
-> HashMap Text Ps
-> BoltM (Either DecodeError (Vector a), QueryMeta)
queryMetaWith RowDecoder a
forall a. FromBolt a => RowDecoder a
rowDecoder
queryMetaWith :: HasCallStack => RowDecoder a -> Text -> H.HashMap Text Ps -> BoltM (Either DecodeError (V.Vector a), QueryMeta)
queryMetaWith :: forall a.
HasCallStack =>
RowDecoder a
-> Text
-> HashMap Text Ps
-> BoltM (Either DecodeError (Vector a), QueryMeta)
queryMetaWith RowDecoder a
decoder Text
cypher HashMap Text Ps
params = ReaderT Connection IO (Either DecodeError (Vector a), QueryMeta)
-> BoltM (Either DecodeError (Vector a), QueryMeta)
forall a. ReaderT Connection IO a -> BoltM a
BoltM (ReaderT Connection IO (Either DecodeError (Vector a), QueryMeta)
-> BoltM (Either DecodeError (Vector a), QueryMeta))
-> ReaderT Connection IO (Either DecodeError (Vector a), QueryMeta)
-> BoltM (Either DecodeError (Vector a), QueryMeta)
forall a b. (a -> b) -> a -> b
$ (Connection -> IO (Either DecodeError (Vector a), QueryMeta))
-> ReaderT Connection IO (Either DecodeError (Vector a), QueryMeta)
forall r (m :: * -> *) a. (r -> m a) -> ReaderT r m a
ReaderT ((Connection -> IO (Either DecodeError (Vector a), QueryMeta))
-> ReaderT
Connection IO (Either DecodeError (Vector a), QueryMeta))
-> (Connection -> IO (Either DecodeError (Vector a), QueryMeta))
-> ReaderT Connection IO (Either DecodeError (Vector a), QueryMeta)
forall a b. (a -> b) -> a -> b
$ \Connection
conn -> do
(fs, rs, qi) <- HasCallStack =>
Connection
-> Text
-> HashMap Text Ps
-> IO (Vector Text, Vector Record, QueryMeta)
Connection
-> Text
-> HashMap Text Ps
-> IO (Vector Text, Vector Record, QueryMeta)
queryPMetaIO Connection
conn Text
cypher HashMap Text Ps
params
pure (decodeRows decoder fs rs, qi)
queryResultMeta :: HasCallStack => Text -> H.HashMap Text Ps -> BoltM (ResultSet, QueryMeta)
queryResultMeta :: HasCallStack =>
Text -> HashMap Text Ps -> BoltM (ResultSet, QueryMeta)
queryResultMeta Text
cypher HashMap Text Ps
params = ReaderT Connection IO (ResultSet, QueryMeta)
-> BoltM (ResultSet, QueryMeta)
forall a. ReaderT Connection IO a -> BoltM a
BoltM (ReaderT Connection IO (ResultSet, QueryMeta)
-> BoltM (ResultSet, QueryMeta))
-> ReaderT Connection IO (ResultSet, QueryMeta)
-> BoltM (ResultSet, QueryMeta)
forall a b. (a -> b) -> a -> b
$ (Connection -> IO (ResultSet, QueryMeta))
-> ReaderT Connection IO (ResultSet, QueryMeta)
forall r (m :: * -> *) a. (r -> m a) -> ReaderT r m a
ReaderT ((Connection -> IO (ResultSet, QueryMeta))
-> ReaderT Connection IO (ResultSet, QueryMeta))
-> (Connection -> IO (ResultSet, QueryMeta))
-> ReaderT Connection IO (ResultSet, QueryMeta)
forall a b. (a -> b) -> a -> b
$ \Connection
conn -> do
(fs, rs, qi) <- HasCallStack =>
Connection
-> Text
-> HashMap Text Ps
-> IO (Vector Text, Vector Record, QueryMeta)
Connection
-> Text
-> HashMap Text Ps
-> IO (Vector Text, Vector Record, QueryMeta)
queryPMetaIO Connection
conn Text
cypher HashMap Text Ps
params
pure (ResultSet fs rs, qi)
execute :: HasCallStack => Text -> H.HashMap Text Ps -> BoltM ()
execute :: HasCallStack => Text -> HashMap Text Ps -> BoltM ()
execute Text
cypher HashMap Text Ps
params = BoltM ResultSet -> BoltM ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (BoltM ResultSet -> BoltM ()) -> BoltM ResultSet -> BoltM ()
forall a b. (a -> b) -> a -> b
$ HasCallStack => Text -> HashMap Text Ps -> BoltM ResultSet
Text -> HashMap Text Ps -> BoltM ResultSet
queryResult Text
cypher HashMap Text Ps
params
queryExplain :: HasCallStack => Text -> H.HashMap Text Ps -> BoltM (Maybe PlanNode)
queryExplain :: HasCallStack => Text -> HashMap Text Ps -> BoltM (Maybe PlanNode)
queryExplain Text
cypher HashMap Text Ps
params = do
(_, meta) <- HasCallStack =>
Text -> HashMap Text Ps -> BoltM (ResultSet, QueryMeta)
Text -> HashMap Text Ps -> BoltM (ResultSet, QueryMeta)
queryResultMeta (Text
"EXPLAIN " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
cypher) HashMap Text Ps
params
pure (parsedPlan meta)
queryProfile :: (FromBolt a, HasCallStack)
=> Text -> H.HashMap Text Ps
-> BoltM (Either DecodeError (V.Vector a), ProfileNode)
queryProfile :: forall a.
(FromBolt a, HasCallStack) =>
Text
-> HashMap Text Ps
-> BoltM (Either DecodeError (Vector a), ProfileNode)
queryProfile Text
cypher HashMap Text Ps
params = do
(result, meta) <- Text
-> HashMap Text Ps
-> BoltM (Either DecodeError (Vector a), QueryMeta)
forall a.
(FromBolt a, HasCallStack) =>
Text
-> HashMap Text Ps
-> BoltM (Either DecodeError (Vector a), QueryMeta)
queryMeta (Text
"PROFILE " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
cypher) HashMap Text Ps
params
case parsedProfile meta of
Just ProfileNode
prof -> (Either DecodeError (Vector a), ProfileNode)
-> BoltM (Either DecodeError (Vector a), ProfileNode)
forall a. a -> BoltM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either DecodeError (Vector a)
result, ProfileNode
prof)
Maybe ProfileNode
Nothing -> String -> BoltM (Either DecodeError (Vector a), ProfileNode)
forall a. HasCallStack => String -> a
error String
"queryProfile: no profile in response"
withTransaction :: HasCallStack => Connection -> (Connection -> IO a) -> IO a
withTransaction :: forall a.
HasCallStack =>
Connection -> (Connection -> IO a) -> IO a
withTransaction Connection
conn Connection -> IO a
action = do
HasCallStack => Connection -> Begin -> IO ()
Connection -> Begin -> IO ()
P.beginTx Connection
conn Begin
defaultBegin
result <- Connection -> IO a
action Connection
conn IO a -> IO () -> IO a
forall a b. IO a -> IO b -> IO a
`onException` Connection -> IO ()
P.tryRollback Connection
conn
_ <- P.commitTx conn
pure result
where
defaultBegin :: Begin
defaultBegin = Vector Text
-> Maybe Int64
-> HashMap Text Ps
-> Char
-> Maybe Text
-> Maybe Text
-> Begin
Begin Vector Text
forall a. Vector a
V.empty Maybe Int64
forall a. Maybe a
Nothing HashMap Text Ps
forall k v. HashMap k v
H.empty Char
'w' Maybe Text
forall a. Maybe a
Nothing Maybe Text
forall a. Maybe a
Nothing
withRetryTransaction :: HasCallStack
=> RetryConfig -> Connection -> (Connection -> IO a) -> IO a
withRetryTransaction :: forall a.
HasCallStack =>
RetryConfig -> Connection -> (Connection -> IO a) -> IO a
withRetryTransaction RetryConfig{Int
maxRetries :: Int
maxRetries :: RetryConfig -> Int
maxRetries, Int
initialDelay :: Int
initialDelay :: RetryConfig -> Int
initialDelay, Int
maxDelay :: Int
maxDelay :: RetryConfig -> Int
maxDelay} Connection
conn Connection -> IO a
action =
Int -> Int -> IO a
go Int
maxRetries Int
initialDelay
where
go :: Int -> Int -> IO a
go Int
0 Int
_ = Connection -> (Connection -> IO a) -> IO a
forall a.
HasCallStack =>
Connection -> (Connection -> IO a) -> IO a
withTransaction Connection
conn Connection -> IO a
action
go Int
n Int
delay = do
result <- IO a -> IO (Either SomeException a)
forall e a. Exception e => IO a -> IO (Either e a)
try (IO a -> IO (Either SomeException a))
-> IO a -> IO (Either SomeException a)
forall a b. (a -> b) -> a -> b
$ Connection -> (Connection -> IO a) -> IO a
forall a.
HasCallStack =>
Connection -> (Connection -> IO a) -> IO a
withTransaction Connection
conn Connection -> IO a
action
case result of
Right a
x -> a -> IO a
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
x
Left (SomeException
e :: SomeException) -> case SomeException -> Maybe Error
forall e. Exception e => SomeException -> Maybe e
fromException SomeException
e :: Maybe Error of
Just Error
err | Error -> Bool
isTransient Error
err -> do
Int -> IO ()
threadDelay Int
delay
Int -> Int -> IO a
go (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) (Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
maxDelay (Int
delay Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
2))
Maybe Error
_ -> SomeException -> IO a
forall e a. (HasCallStack, Exception e) => e -> IO a
throwIO SomeException
e
withTransaction' :: HasCallStack => BoltPool -> (Connection -> IO a) -> IO a
withTransaction' :: forall a. HasCallStack => BoltPool -> (Connection -> IO a) -> IO a
withTransaction' pool :: BoltPool
pool@BoltPool{RetryConfig
bpRetryConfig :: RetryConfig
bpRetryConfig :: BoltPool -> RetryConfig
bpRetryConfig} Connection -> IO a
action =
BoltPool -> (Connection -> IO a) -> IO a
forall a. HasCallStack => BoltPool -> (Connection -> IO a) -> IO a
withConnection BoltPool
pool ((Connection -> IO a) -> IO a) -> (Connection -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ \Connection
conn ->
RetryConfig -> Connection -> (Connection -> IO a) -> IO a
forall a.
HasCallStack =>
RetryConfig -> Connection -> (Connection -> IO a) -> IO a
withRetryTransaction RetryConfig
bpRetryConfig Connection
conn Connection -> IO a
action