| Safe Haskell | None |
|---|---|
| Language | GHC2021 |
Database.Bolty
Description
Haskell driver for Neo4j over the BOLT protocol (4.4+).
This is the main entry point for using bolty. It re-exports everything needed to connect, run queries, manage transactions, and decode results.
import qualified Database.Bolty as Bolt import Data.Default (def) main :: IO () main = do cfg <- Bolt.validateConfigdef{ Bolt.scheme= Bolt.Basic"neo4j" "password" } conn <- Bolt.connectcfg rows <- Bolt.runBoltconn $ Bolt.queryWith(Bolt.field"n" Bolt.node) "MATCH (n) RETURN n LIMIT 10" mempty print rows -- Either DecodeError (Vector Node) Bolt.closeconn
Synopsis
- data Config = Config {}
- data ValidatedConfig
- validateConfig :: Config -> Validation [Text] ValidatedConfig
- data Scheme
- = None
- | Basic !Principal !Credentials
- | Kerberos
- | Bearer !Credentials
- data Routing
- data UserAgent = UserAgent {}
- data Version = Version {}
- data Connection
- connect :: (MonadIO m, HasCallStack) => ValidatedConfig -> m Connection
- close :: (MonadIO m, HasCallStack) => Connection -> m ()
- reset :: (MonadIO m, HasCallStack) => Connection -> m ()
- ping :: MonadIO m => Connection -> m Bool
- logon :: (MonadIO m, HasCallStack) => Connection -> Scheme -> m ()
- logoff :: (MonadIO m, HasCallStack) => Connection -> m ()
- connectionVersion :: Connection -> Word32
- connectionAgent :: Connection -> Text
- connectionId :: Connection -> Text
- connectionTelemetryEnabled :: Connection -> Bool
- connectionServerIdleTimeout :: Connection -> Maybe Int
- data TelemetryApi
- sendTelemetry :: (MonadIO m, HasCallStack) => Connection -> TelemetryApi -> m ()
- withTransaction :: HasCallStack => Connection -> (Connection -> IO a) -> IO a
- withRetryTransaction :: HasCallStack => RetryConfig -> Connection -> (Connection -> IO a) -> IO a
- withTransaction' :: HasCallStack => BoltPool -> (Connection -> IO a) -> IO a
- data RetryConfig = RetryConfig {
- maxRetries :: !Int
- initialDelay :: !Int
- maxDelay :: !Int
- defaultRetryConfig :: RetryConfig
- isTransient :: Error -> Bool
- isRoutingError :: Error -> Bool
- data Bolt
- = BoltNull
- | BoltBoolean !Bool
- | BoltInteger !PSInteger
- | BoltFloat !Double
- | BoltBytes !ByteString
- | BoltString !Text
- | BoltList !(Vector Bolt)
- | BoltDictionary !(HashMap Text Bolt)
- | BoltNode Node
- | BoltRelationship Relationship
- | BoltUnboundRelationship UnboundRelationship
- | BoltPath Path
- | BoltDate Date
- | BoltTime Time
- | BoltLocalTime LocalTime
- | BoltDateTime DateTime
- | BoltDateTimeZoneId DateTimeZoneId
- | BoltLocalDateTime LocalDateTime
- | BoltDuration Duration
- | BoltPoint2D Point2D
- | BoltPoint3D Point3D
- type Record = Vector Bolt
- data Error
- asNull :: Bolt -> Maybe ()
- asBool :: Bolt -> Maybe Bool
- asInt :: Bolt -> Maybe PSInteger
- asFloat :: Bolt -> Maybe Double
- asBytes :: Bolt -> Maybe ByteString
- asText :: Bolt -> Maybe Text
- asList :: Bolt -> Maybe (Vector Bolt)
- asDict :: Bolt -> Maybe (HashMap Text Bolt)
- asNode :: Bolt -> Maybe Node
- asRelationship :: Bolt -> Maybe Relationship
- asPath :: Bolt -> Maybe Path
- data QueryMeta = QueryMeta {
- bookmark :: !(Maybe Text)
- t_last :: !Int64
- type_ :: !Text
- stats :: !(Maybe Ps)
- parsedStats :: !(Maybe QueryStats)
- plan :: !(Maybe Ps)
- profile :: !(Maybe Ps)
- notifications :: !(Maybe Ps)
- parsedNotifications :: !(Vector Notification)
- parsedPlan :: !(Maybe PlanNode)
- parsedProfile :: !(Maybe ProfileNode)
- db :: !Text
- data BoltPool
- data PoolConfig = PoolConfig {}
- defaultPoolConfig :: PoolConfig
- data ValidationStrategy
- = AlwaysPing
- | PingIfIdle !Int
- | NeverPing
- data PoolCounters = PoolCounters {
- pcActive :: !Int
- pcTotalAcqs :: !Int
- pcTotalWaitNs :: !Word64
- createPool :: HasCallStack => ValidatedConfig -> PoolConfig -> IO BoltPool
- destroyPool :: BoltPool -> IO ()
- withConnection :: HasCallStack => BoltPool -> (Connection -> IO a) -> IO a
- data CheckedOutConnection = CheckedOutConnection {}
- acquireConnection :: BoltPool -> IO CheckedOutConnection
- releaseConnection :: CheckedOutConnection -> IO ()
- releaseConnectionOnError :: CheckedOutConnection -> IO ()
- poolCounters :: BoltPool -> IO PoolCounters
- data AccessMode
- data RoutingTable = RoutingTable {}
- data RoutingPool
- data RoutingPoolConfig = RoutingPoolConfig {}
- defaultRoutingPoolConfig :: RoutingPoolConfig
- createRoutingPool :: ValidatedConfig -> RoutingPoolConfig -> IO RoutingPool
- destroyRoutingPool :: RoutingPool -> IO ()
- withRoutingConnection :: HasCallStack => RoutingPool -> AccessMode -> (Connection -> IO a) -> IO a
- acquireRoutingConnection :: HasCallStack => RoutingPool -> AccessMode -> IO CheckedOutConnection
- withRoutingTransaction :: HasCallStack => RoutingPool -> AccessMode -> (Connection -> IO a) -> IO a
- invalidateRoutingTable :: RoutingPool -> IO ()
- getRoutingTable :: HasCallStack => Connection -> Maybe Text -> IO RoutingTable
- data Session
- data SessionConfig = SessionConfig {
- database :: !(Maybe Text)
- accessMode :: !AccessMode
- sessionBookmarks :: ![Text]
- defaultSessionConfig :: SessionConfig
- data BookmarkManager
- createSession :: BoltPool -> SessionConfig -> IO Session
- createRoutingSession :: RoutingPool -> SessionConfig -> IO Session
- readTransaction :: HasCallStack => Session -> (Connection -> IO a) -> IO a
- writeTransaction :: HasCallStack => Session -> (Connection -> IO a) -> IO a
- getLastBookmarks :: Session -> IO [Text]
- data PlanNode = PlanNode {
- pnOperatorType :: !Text
- pnArguments :: !(HashMap Text Ps)
- pnIdentifiers :: !(Vector Text)
- pnEstimatedRows :: !Double
- pnChildren :: !(Vector PlanNode)
- data ProfileNode = ProfileNode {
- prOperatorType :: !Text
- prArguments :: !(HashMap Text Ps)
- prIdentifiers :: !(Vector Text)
- prEstimatedRows :: !Double
- prDbHits :: !Int64
- prRows :: !Int64
- prPageCacheHits :: !Int64
- prPageCacheMisses :: !Int64
- prTime :: !Int64
- prChildren :: !(Vector ProfileNode)
- queryExplain :: HasCallStack => Text -> HashMap Text Ps -> BoltM (Maybe PlanNode)
- queryProfile :: (FromBolt a, HasCallStack) => Text -> HashMap Text Ps -> BoltM (Either DecodeError (Vector a), ProfileNode)
- data QueryLog = QueryLog {
- qlCypher :: !Text
- qlParameters :: !(HashMap Text Ps)
- qlRowCount :: !Int
- qlServerFirst :: !Int64
- qlServerLast :: !Int64
- qlClientTime :: !Double
- data Notification = Notification {}
- data Severity
- data Position = Position {}
- data QueryStats = QueryStats {
- nodesCreated :: !Int64
- nodesDeleted :: !Int64
- relationshipsCreated :: !Int64
- relationshipsDeleted :: !Int64
- propertiesSet :: !Int64
- labelsAdded :: !Int64
- labelsRemoved :: !Int64
- indexesAdded :: !Int64
- indexesRemoved :: !Int64
- constraintsAdded :: !Int64
- constraintsRemoved :: !Int64
- containsUpdates :: !Bool
- containsSystemUpdates :: !Bool
- systemUpdates :: !Int64
- data BoltM a
- runBolt :: Connection -> BoltM a -> IO a
- query :: (FromBolt a, HasCallStack) => Text -> HashMap Text Ps -> BoltM (Either DecodeError (Vector a))
- queryWith :: HasCallStack => RowDecoder a -> Text -> HashMap Text Ps -> BoltM (Either DecodeError (Vector a))
- queryResult :: HasCallStack => Text -> HashMap Text Ps -> BoltM ResultSet
- queryMeta :: (FromBolt a, HasCallStack) => Text -> HashMap Text Ps -> BoltM (Either DecodeError (Vector a), QueryMeta)
- queryMetaWith :: HasCallStack => RowDecoder a -> Text -> HashMap Text Ps -> BoltM (Either DecodeError (Vector a), QueryMeta)
- queryResultMeta :: HasCallStack => Text -> HashMap Text Ps -> BoltM (ResultSet, QueryMeta)
- execute :: HasCallStack => Text -> HashMap Text Ps -> BoltM ()
- data DecodeError
- newtype Decode a = Decode {
- runDecode :: Bolt -> Either DecodeError a
- newtype RowDecoder a = RowDecoder {
- runRowDecoder :: Vector Text -> Record -> Either DecodeError a
- class FromBolt a where
- rowDecoder :: RowDecoder a
- class ToBolt a where
- bool :: Decode Bool
- int :: Decode PSInteger
- int64 :: Decode Int64
- float :: Decode Double
- text :: Decode Text
- bytes :: Decode ByteString
- nullable :: Decode a -> Decode (Maybe a)
- list :: Decode a -> Decode (Vector a)
- dict :: Decode (HashMap Text Bolt)
- uuid :: Decode UUID
- utcTime :: Decode UTCTime
- day :: Decode Day
- timeOfDay :: Decode TimeOfDay
- aesonValue :: Decode Value
- nodeProperty :: Text -> Decode a -> Decode a
- nodePropertyOptional :: Text -> Decode a -> Decode (Maybe a)
- nodeLabels :: Decode (Vector Text)
- nodeProperties :: Decode (HashMap Text Ps)
- node :: Decode Node
- relationship :: Decode Relationship
- path :: Decode Path
- column :: Int -> Decode a -> RowDecoder a
- field :: Text -> Decode a -> RowDecoder a
- data ResultSet = ResultSet {}
- decodeResultSet :: RowDecoder a -> ResultSet -> Either DecodeError (Vector a)
- decodeHead :: RowDecoder a -> ResultSet -> Either DecodeError a
- groupByField :: Eq k => RowDecoder (Maybe k) -> ResultSet -> Either DecodeError (Vector (k, ResultSet))
- data Ps
Configuration
Connection configuration. Use def for sensible defaults and
override the fields you need. Must be validated with validateConfig before use.
Constructors
| Config | |
Fields
| |
data ValidatedConfig Source #
A validated configuration ready for connect. Created via validateConfig.
validateConfig :: Config -> Validation [Text] ValidatedConfig Source #
Validate a Config, returning either validation errors or a ValidatedConfig.
Authentication scheme for the HELLO handshake.
Constructors
| None | No authentication. |
| Basic !Principal !Credentials | Basic username/password authentication. |
| Kerberos | Kerberos authentication (ticket obtained externally). |
| Bearer !Credentials | Bearer token authentication (e.g. SSO). |
Instances
Routing mode for cluster-aware connections.
Constructors
| NoRouting | Direct connection (no routing). |
| Routing | Use server-side routing with default settings. |
| RoutingSpec !Text !(HashMap Text Text) | Use server-side routing with explicit address and parameters.
Arguments: advertised address (e.g. |
User-agent identifier sent to the server in the HELLO message.
A BOLT protocol version (major.minor).
Connection
data Connection Source #
An open connection to a Neo4j server. Obtain via connect.
connect :: (MonadIO m, HasCallStack) => ValidatedConfig -> m Connection Source #
Connect to a Neo4j server using a validated configuration.
close :: (MonadIO m, HasCallStack) => Connection -> m () Source #
Close a connection to a Neo4j server.
reset :: (MonadIO m, HasCallStack) => Connection -> m () Source #
Reset the connection state after an error.
ping :: MonadIO m => Connection -> m Bool Source #
Check if a connection is alive by sending RESET. Returns True if healthy, False otherwise.
logon :: (MonadIO m, HasCallStack) => Connection -> Scheme -> m () Source #
Send LOGON with credentials (Bolt 5.1+). Transitions from Authentication to Ready state.
logoff :: (MonadIO m, HasCallStack) => Connection -> m () Source #
Send LOGOFF (Bolt 5.1+). Transitions from Ready to Authentication state.
connectionVersion :: Connection -> Word32 Source #
Get the negotiated BOLT protocol version.
connectionAgent :: Connection -> Text Source #
Get the server agent string.
connectionId :: Connection -> Text Source #
Get the server-assigned connection ID.
connectionTelemetryEnabled :: Connection -> Bool Source #
Check whether the server supports telemetry.
connectionServerIdleTimeout :: Connection -> Maybe Int Source #
Get the server-advertised idle timeout in seconds, if any.
Telemetry
data TelemetryApi Source #
Telemetry API type indicators (Bolt 5.4+).
Instances
| Show TelemetryApi Source # | |
Defined in Database.Bolty.Message.Request Methods showsPrec :: Int -> TelemetryApi -> ShowS # show :: TelemetryApi -> String # showList :: [TelemetryApi] -> ShowS # | |
| Eq TelemetryApi Source # | |
Defined in Database.Bolty.Message.Request | |
sendTelemetry :: (MonadIO m, HasCallStack) => Connection -> TelemetryApi -> m () Source #
Send a TELEMETRY message if the server supports it (Bolt 5.4+). No-op if the server does not support telemetry.
Transactions
withTransaction :: HasCallStack => Connection -> (Connection -> IO a) -> IO a Source #
Run an action inside an explicit transaction. Automatically commits on success and rolls back on failure.
withRetryTransaction :: HasCallStack => RetryConfig -> Connection -> (Connection -> IO a) -> IO a Source #
Run a transaction with automatic retry on transient failures. Uses exponential backoff between retries.
withTransaction' :: HasCallStack => BoltPool -> (Connection -> IO a) -> IO a Source #
Convenience: acquire a pooled connection, run a retrying transaction, and release.
Retry configuration
data RetryConfig Source #
Configuration for retry logic on transient failures.
Constructors
| RetryConfig | |
Fields
| |
Instances
| Show RetryConfig Source # | |
Defined in Database.Bolty.Pool Methods showsPrec :: Int -> RetryConfig -> ShowS # show :: RetryConfig -> String # showList :: [RetryConfig] -> ShowS # | |
| Eq RetryConfig Source # | |
Defined in Database.Bolty.Pool | |
defaultRetryConfig :: RetryConfig Source #
Default retry configuration: 5 retries, 200ms initial delay, 5s max delay.
Error helpers
isTransient :: Error -> Bool Source #
Check if an error is a transient Neo4j failure that can be retried.
isRoutingError :: Error -> Bool Source #
Check if an error indicates stale routing information. These errors mean the driver sent a request to the wrong server (e.g. a write to a read replica). The routing table should be invalidated and the operation retried on a fresh leader.
Types
A typed Neo4j value. Every field in a query result record is a Bolt.
Constructors
| BoltNull | |
| BoltBoolean !Bool | |
| BoltInteger !PSInteger | |
| BoltFloat !Double | |
| BoltBytes !ByteString | |
| BoltString !Text | |
| BoltList !(Vector Bolt) | |
| BoltDictionary !(HashMap Text Bolt) | |
| BoltNode Node | |
| BoltRelationship Relationship | |
| BoltUnboundRelationship UnboundRelationship | |
| BoltPath Path | |
| BoltDate Date | |
| BoltTime Time | |
| BoltLocalTime LocalTime | |
| BoltDateTime DateTime | |
| BoltDateTimeZoneId DateTimeZoneId | |
| BoltLocalDateTime LocalDateTime | |
| BoltDuration Duration | |
| BoltPoint2D Point2D | |
| BoltPoint3D Point3D |
Instances
| Generic Bolt Source # | |||||
Defined in Database.Bolty.Value.Type Associated Types
| |||||
| Show Bolt Source # | |||||
| Eq Bolt Source # | |||||
| PackStream Bolt Source # | |||||
| type Rep Bolt Source # | |||||
Defined in Database.Bolty.Value.Type type Rep Bolt = D1 ('MetaData "Bolt" "Database.Bolty.Value.Type" "bolty-0.1.0.2-D4CzMg1BY3r5YzeDrGyWz4" 'False) ((((C1 ('MetaCons "BoltNull" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "BoltBoolean" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Bool))) :+: (C1 ('MetaCons "BoltInteger" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 PSInteger)) :+: (C1 ('MetaCons "BoltFloat" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Double)) :+: C1 ('MetaCons "BoltBytes" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 ByteString))))) :+: ((C1 ('MetaCons "BoltString" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Text)) :+: C1 ('MetaCons "BoltList" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 (Vector Bolt)))) :+: (C1 ('MetaCons "BoltDictionary" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 (HashMap Text Bolt))) :+: (C1 ('MetaCons "BoltNode" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Node)) :+: C1 ('MetaCons "BoltRelationship" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Relationship)))))) :+: (((C1 ('MetaCons "BoltUnboundRelationship" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 UnboundRelationship)) :+: C1 ('MetaCons "BoltPath" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Path))) :+: (C1 ('MetaCons "BoltDate" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Date)) :+: (C1 ('MetaCons "BoltTime" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Time)) :+: C1 ('MetaCons "BoltLocalTime" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 LocalTime))))) :+: ((C1 ('MetaCons "BoltDateTime" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 DateTime)) :+: (C1 ('MetaCons "BoltDateTimeZoneId" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 DateTimeZoneId)) :+: C1 ('MetaCons "BoltLocalDateTime" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 LocalDateTime)))) :+: (C1 ('MetaCons "BoltDuration" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Duration)) :+: (C1 ('MetaCons "BoltPoint2D" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Point2D)) :+: C1 ('MetaCons "BoltPoint3D" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Point3D))))))) | |||||
Errors that can occur during BOLT communication.
Constructors
| TimeOut Text | A network operation timed out. |
| AuthentificationFailed | The server rejected the authentication credentials. |
| UnsupportedServerVersion Word32 | No mutually supported BOLT version could be negotiated. |
| ResetFailed | A RESET message failed (connection is likely defunct). |
| CannotReadResponse Text | Failed to parse a response from the server. |
| NonboltyError SomeException | A non-BOLT exception (e.g. network IO error). |
| ResponseErrorRecords | Received records when a non-record response was expected. |
| WrongMessageFormat Text | The server sent an unexpected message type. |
| ResponseErrorIgnored | The server sent an IGNORED response. |
| ResponseErrorFailure Text Text | A FAILURE response with Neo4j error code and message. |
| InvalidState ServerState Text | Attempted an operation in an invalid server state. |
| RoutingTableError Text | Failed to fetch or parse a routing table. |
Instances
| Exception Error Source # | |
Defined in Database.Bolty.Connection.Type Methods toException :: Error -> SomeException # fromException :: SomeException -> Maybe Error # displayException :: Error -> String # backtraceDesired :: Error -> Bool # | |
| Show Error Source # | |
Bolt value extractors
asRelationship :: Bolt -> Maybe Relationship Source #
Extract a relationship value.
Query metadata
Server metadata from a PULL SUCCESS response.
Constructors
| QueryMeta | |
Fields
| |
Connection pooling
data PoolConfig Source #
Configuration for the connection pool.
Constructors
| PoolConfig | |
Fields
| |
defaultPoolConfig :: PoolConfig Source #
Default pool configuration: 10 max connections, 60 second idle timeout, 1 ping retry.
data ValidationStrategy Source #
Strategy for validating connections when they are checked out of the pool.
Constructors
| AlwaysPing | Always send RESET before use (current default, safest). |
| PingIfIdle !Int | Only ping if the connection has been idle for more than N seconds. Connections used within the last N seconds are assumed healthy. |
| NeverPing | Skip health check entirely (fastest, use only in trusted environments). |
Instances
| Show ValidationStrategy Source # | |
Defined in Database.Bolty.Pool Methods showsPrec :: Int -> ValidationStrategy -> ShowS # show :: ValidationStrategy -> String # showList :: [ValidationStrategy] -> ShowS # | |
| Eq ValidationStrategy Source # | |
Defined in Database.Bolty.Pool Methods (==) :: ValidationStrategy -> ValidationStrategy -> Bool # (/=) :: ValidationStrategy -> ValidationStrategy -> Bool # | |
data PoolCounters Source #
Snapshot of pool-level counters.
Constructors
| PoolCounters | |
Fields
| |
Instances
| Show PoolCounters Source # | |
Defined in Database.Bolty.Pool Methods showsPrec :: Int -> PoolCounters -> ShowS # show :: PoolCounters -> String # showList :: [PoolCounters] -> ShowS # | |
| Eq PoolCounters Source # | |
Defined in Database.Bolty.Pool | |
createPool :: HasCallStack => ValidatedConfig -> PoolConfig -> IO BoltPool Source #
Create a new connection pool.
If the server advertises connection.recv_timeout_seconds, the pool's
idle timeout is capped to min(configured, hint - 5) so connections
are recycled before the server closes them.
destroyPool :: BoltPool -> IO () Source #
Destroy the pool, closing all connections.
withConnection :: HasCallStack => BoltPool -> (Connection -> IO a) -> IO a Source #
Acquire a healthy connection from the pool, run an action, then release it.
Validates the connection using the configured ValidationStrategy.
On connection failure during the action, discards the dead connection and
retries once with a fresh one.
data CheckedOutConnection Source #
A checked-out connection handle, bundling the connection with its local pool reference for proper release.
Constructors
| CheckedOutConnection | |
Fields
| |
acquireConnection :: BoltPool -> IO CheckedOutConnection Source #
Acquire a validated connection from the pool. The caller is responsible
for releasing it with releaseConnection or releaseConnectionOnError.
This is the low-level primitive behind withConnection. Prefer
withConnection for simple request-response patterns.
Use acquireConnection when you need the connection to outlive a callback
(e.g. for streaming with bracketIO).
releaseConnection :: CheckedOutConnection -> IO () Source #
Release a connection back to the pool after successful use.
releaseConnectionOnError :: CheckedOutConnection -> IO () Source #
Release a connection after an error, destroying it instead of returning it to the pool (since it may be in a bad state).
poolCounters :: BoltPool -> IO PoolCounters Source #
Read a snapshot of the pool's lifetime counters.
Routing
data AccessMode Source #
Access mode for routing: determines whether to use reader or writer servers.
Constructors
| ReadAccess | |
| WriteAccess |
Instances
| Show AccessMode Source # | |
Defined in Database.Bolty.Routing Methods showsPrec :: Int -> AccessMode -> ShowS # show :: AccessMode -> String # showList :: [AccessMode] -> ShowS # | |
| Eq AccessMode Source # | |
Defined in Database.Bolty.Routing | |
data RoutingTable Source #
A parsed routing table returned by the ROUTE message.
Constructors
| RoutingTable | |
Instances
| Show RoutingTable Source # | |
Defined in Database.Bolty.Message.Response Methods showsPrec :: Int -> RoutingTable -> ShowS # show :: RoutingTable -> String # showList :: [RoutingTable] -> ShowS # | |
| Eq RoutingTable Source # | |
Defined in Database.Bolty.Message.Response | |
data RoutingPool Source #
A routing-aware connection pool that directs connections based on access mode.
data RoutingPoolConfig Source #
Configuration for a routing-aware connection pool.
Constructors
| RoutingPoolConfig | |
Fields
| |
defaultRoutingPoolConfig :: RoutingPoolConfig Source #
Default routing pool configuration.
createRoutingPool :: ValidatedConfig -> RoutingPoolConfig -> IO RoutingPool Source #
Create a routing-aware connection pool. Connects to the seed address, fetches the initial routing table, and sets up per-address pools.
destroyRoutingPool :: RoutingPool -> IO () Source #
Destroy all per-address pools in the routing pool.
withRoutingConnection :: HasCallStack => RoutingPool -> AccessMode -> (Connection -> IO a) -> IO a Source #
Acquire a connection routed by access mode, run an action, then release. On connection failure, tries the next address in round-robin order until all addresses are exhausted.
acquireRoutingConnection :: HasCallStack => RoutingPool -> AccessMode -> IO CheckedOutConnection Source #
Acquire a routed connection by access mode. Returns a
CheckedOutConnection that must be released by the caller.
Tries addresses in round-robin order, failing over on unavailable servers.
withRoutingTransaction :: HasCallStack => RoutingPool -> AccessMode -> (Connection -> IO a) -> IO a Source #
Run a retrying transaction routed by access mode. Re-acquires routing table and connection on each retry attempt, so that routing errors (NotALeader) and transient errors trigger fresh routing.
invalidateRoutingTable :: RoutingPool -> IO () Source #
Invalidate the cached routing table, forcing a refresh on the next operation. Use this when a routing error (e.g. NotALeader) indicates the table is stale.
getRoutingTable :: HasCallStack => Connection -> Maybe Text -> IO RoutingTable Source #
Fetch a routing table from the server. The connection must be in Ready state.
Sessions
A session bundles a connection pool with bookmark management and configuration.
Sessions track bookmarks automatically across managed transactions
(readTransaction, writeTransaction) to ensure causal consistency.
data SessionConfig Source #
Session configuration.
Constructors
| SessionConfig | |
Fields
| |
defaultSessionConfig :: SessionConfig Source #
Default session configuration: default database, write access, no initial bookmarks.
data BookmarkManager Source #
Mutable bookmark holder for causal consistency across transactions. Within a session, each committed transaction produces a bookmark that supersedes all previous bookmarks. The manager tracks the latest bookmark(s) so they can be passed to the next transaction's BEGIN.
createSession :: BoltPool -> SessionConfig -> IO Session Source #
Create a session using a direct (non-routing) connection pool.
createRoutingSession :: RoutingPool -> SessionConfig -> IO Session Source #
Create a session using a routing-aware connection pool.
readTransaction :: HasCallStack => Session -> (Connection -> IO a) -> IO a Source #
Run a read transaction. Uses ReadAccess for routing (directs to
read replicas in a cluster). Automatically handles BEGIN, COMMIT,
ROLLBACK, bookmark propagation, and retries on transient failures.
writeTransaction :: HasCallStack => Session -> (Connection -> IO a) -> IO a Source #
Run a write transaction. Uses WriteAccess for routing (directs to
the leader in a cluster). Automatically handles BEGIN, COMMIT,
ROLLBACK, bookmark propagation, and retries on transient failures.
getLastBookmarks :: Session -> IO [Text] Source #
Get the last bookmarks from the session. Pass these to a new session's
SessionConfig to ensure the new session sees all committed writes.
Plan / Profile
A node in the query execution plan tree (from EXPLAIN).
Constructors
| PlanNode | |
Fields
| |
Instances
data ProfileNode Source #
A node in the query profile tree (from PROFILE).
Extends PlanNode with actual execution statistics.
Constructors
| ProfileNode | |
Fields
| |
Instances
| Show ProfileNode Source # | |
Defined in Database.Bolty.Plan Methods showsPrec :: Int -> ProfileNode -> ShowS # show :: ProfileNode -> String # showList :: [ProfileNode] -> ShowS # | |
| Eq ProfileNode Source # | |
Defined in Database.Bolty.Plan | |
queryExplain :: HasCallStack => Text -> HashMap Text Ps -> BoltM (Maybe PlanNode) Source #
Run EXPLAIN on a Cypher query, returning the query plan without executing it.
queryProfile :: (FromBolt a, HasCallStack) => Text -> HashMap Text Ps -> BoltM (Either DecodeError (Vector a), ProfileNode) Source #
Run PROFILE on a Cypher query, returning both decoded rows and the profile tree with actual execution statistics (db hits, rows, timing, etc.).
Query logging
Information about a completed query, passed to the queryLogger callback.
Constructors
| QueryLog | |
Fields
| |
Notifications
data Notification Source #
A notification emitted by the server during query execution. Notifications include warnings about performance (cartesian products, missing indexes), deprecation notices, and hints.
Constructors
| Notification | |
Fields
| |
Instances
| Show Notification Source # | |
Defined in Database.Bolty.Notification Methods showsPrec :: Int -> Notification -> ShowS # show :: Notification -> String # showList :: [Notification] -> ShowS # | |
| Eq Notification Source # | |
Defined in Database.Bolty.Notification | |
Severity level of a notification.
Constructors
| SevWarning | |
| SevInformation | |
| SevUnknown !Text |
Query statistics
data QueryStats Source #
Typed query statistics from the PULL SUCCESS metadata. All integer fields default to 0 and booleans to False when absent.
Constructors
| QueryStats | |
Fields
| |
Instances
| Show QueryStats Source # | |
Defined in Database.Bolty.Stats Methods showsPrec :: Int -> QueryStats -> ShowS # show :: QueryStats -> String # showList :: [QueryStats] -> ShowS # | |
| Eq QueryStats Source # | |
Defined in Database.Bolty.Stats | |
BoltM monad
A monad for running queries against a Neo4j connection.
Use runBolt to execute a BoltM action with a Connection.
runBolt :: Connection -> BoltM a -> IO a Source #
Run a BoltM action with a Connection.
Queries
query :: (FromBolt a, HasCallStack) => Text -> HashMap Text Ps -> BoltM (Either DecodeError (Vector a)) Source #
Run a Cypher query, decode each record using the FromBolt instance, and
return the decoded rows or a DecodeError. Pass mempty for no parameters.
queryWith :: HasCallStack => RowDecoder a -> Text -> HashMap Text Ps -> BoltM (Either DecodeError (Vector a)) Source #
Like query, but with an explicit RowDecoder instead of using FromBolt.
queryResult :: HasCallStack => Text -> HashMap Text Ps -> BoltM ResultSet Source #
Run a Cypher query and return a ResultSet (field names + records).
Use decodeResultSet or groupByField for multi-pass decoding.
Pass mempty for no parameters.
queryMeta :: (FromBolt a, HasCallStack) => Text -> HashMap Text Ps -> BoltM (Either DecodeError (Vector a), QueryMeta) Source #
queryMetaWith :: HasCallStack => RowDecoder a -> Text -> HashMap Text Ps -> BoltM (Either DecodeError (Vector a), QueryMeta) Source #
Like queryMeta, but with an explicit RowDecoder instead of using FromBolt.
execute :: HasCallStack => Text -> HashMap Text Ps -> BoltM () Source #
Run a Cypher query for side effects only, discarding the result.
Pass mempty for no parameters.
Record decoding
data DecodeError Source #
Errors that can occur when decoding a Bolt value or record row.
Constructors
| TypeMismatch Text Text | The value had a different type than expected (expected, got). |
| MissingField Text | A named field was not present in the column list. |
| IndexOutOfBounds Int Int | Column index was out of range (requested index, actual length). |
| EmptyResultSet | The result set contained no records. |
Instances
| Exception DecodeError Source # | |
Defined in Database.Bolty.Decode Methods toException :: DecodeError -> SomeException # fromException :: SomeException -> Maybe DecodeError # displayException :: DecodeError -> String # backtraceDesired :: DecodeError -> Bool # | |
| Show DecodeError Source # | |
Defined in Database.Bolty.Decode Methods showsPrec :: Int -> DecodeError -> ShowS # show :: DecodeError -> String # showList :: [DecodeError] -> ShowS # | |
| Eq DecodeError Source # | |
Defined in Database.Bolty.Decode | |
| TextShow DecodeError Source # | |
Defined in Database.Bolty.Decode Methods showbPrec :: Int -> DecodeError -> Builder # showb :: DecodeError -> Builder # showbList :: [DecodeError] -> Builder # showtPrec :: Int -> DecodeError -> Text # showt :: DecodeError -> Text # showtList :: [DecodeError] -> Text # showtlPrec :: Int -> DecodeError -> Text # showtl :: DecodeError -> Text # showtlList :: [DecodeError] -> Text # | |
A decoder for a single Bolt value.
Constructors
| Decode | |
Fields
| |
newtype RowDecoder a Source #
A decoder for a full result row. Compose with Applicative to decode multiple columns.
Constructors
| RowDecoder | |
Fields
| |
Instances
| Applicative RowDecoder Source # | |
Defined in Database.Bolty.Decode Methods pure :: a -> RowDecoder a # (<*>) :: RowDecoder (a -> b) -> RowDecoder a -> RowDecoder b # liftA2 :: (a -> b -> c) -> RowDecoder a -> RowDecoder b -> RowDecoder c # (*>) :: RowDecoder a -> RowDecoder b -> RowDecoder b # (<*) :: RowDecoder a -> RowDecoder b -> RowDecoder a # | |
| Functor RowDecoder Source # | |
Defined in Database.Bolty.Decode Methods fmap :: (a -> b) -> RowDecoder a -> RowDecoder b # (<$) :: a -> RowDecoder b -> RowDecoder a # | |
class FromBolt a where Source #
Types that can be decoded from a result row without an explicit decoder.
Implement this for your application types to use query
without passing a RowDecoder explicitly:
data Person = Person { name :: Text, age :: Int64 }
instance FromBolt Person where
rowDecoder = Person <$> field "name" text <*> field "age" int64
Methods
rowDecoder :: RowDecoder a Source #
Types that can be encoded to a Ps value for use as query parameters.
All PackStream instances are automatically ToBolt instances.
Instances
| PackStream a => ToBolt a Source # | |
Defined in Database.Bolty.Decode | |
int64 :: Decode Int64 Source #
Decode a BoltInteger narrowed to Int64. Fails if the value is out of range.
list :: Decode a -> Decode (Vector a) Source #
Decode a BoltList, applying the element decoder to each item.
utcTime :: Decode UTCTime Source #
Decode a UTCTime from a BoltString (ISO 8601) or BoltDateTime.
nodeProperty :: Text -> Decode a -> Decode a Source #
Extract a property from a BoltNode by key and decode it.
nodeProperties :: Decode (HashMap Text Ps) Source #
Extract the raw properties HashMap from a BoltNode.
relationship :: Decode Relationship Source #
Decode a BoltRelationship.
Result sets
A query result: field (column) names paired with the result records.
Supports multi-pass decoding — decode the same rows with different
RowDecoders without re-running the query.
decodeResultSet :: RowDecoder a -> ResultSet -> Either DecodeError (Vector a) Source #
Decode every record in a ResultSet using a RowDecoder.
Fails on the first DecodeError.
decodeHead :: RowDecoder a -> ResultSet -> Either DecodeError a Source #
Decode the first record of a ResultSet, or fail with EmptyResultSet.
groupByField :: Eq k => RowDecoder (Maybe k) -> ResultSet -> Either DecodeError (Vector (k, ResultSet)) Source #
Group consecutive records by a decoded key field.
Records whose key decodes to Nothing (e.g. NULL from an OPTIONAL MATCH
with no match) are skipped. Grouping is consecutive, not global: if the same
key appears in non-adjacent runs, they become separate groups.
Each sub-ResultSet shares the parent's field names.
Prefer Cypher COLLECT() when possible — this function is an escape
hatch for queries where server-side aggregation is impractical.
PackStream re-exports
A PackStream value. This is the intermediate AST used for serialization.
Constructors
| PsNull | missing or empty value |
| PsBoolean !Bool | true or false |
| PsInteger !PSInteger | signed 64-bit integer |
| PsFloat !Double | 64-bit floating point number |
| PsBytes !ByteString | byte array |
| PsString !Text | unicode text, UTF-8 |
| PsList !(Vector Ps) | ordered collection of values |
| PsDictionary !(HashMap Text Ps) | collection of key-value entries (no order guaranteed) |
| PsStructure !Tag !(Vector Ps) | composite value with a type signature fields being a Vector is a bit wasteful, but the spec demands it in practice there is always just 1 field, which is a dictionary Control messages all use dictionaries: https://neo4j.com/docs/bolt/current/bolt/message/#messages Datatypes all use dictionaries: https://neo4j.com/docs/bolt/current/bolt/structure-semantics/ |
Instances
| NFData Ps | |
Defined in Data.PackStream.Ps | |
| Show Ps | |
| Eq Ps | |
| PackStream Ps | The trivial identity |
| Persist Ps | This |