bolty-0.1.0.2: Haskell driver for Neo4j (BOLT protocol 4.4-5.4)
Safe HaskellNone
LanguageGHC2021

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.validateConfig def{ Bolt.scheme = Bolt.Basic "neo4j" "password" }
  conn <- Bolt.connect cfg
  rows <- Bolt.runBolt conn $
    Bolt.queryWith (Bolt.field "n" Bolt.node) "MATCH (n) RETURN n LIMIT 10" mempty
  print rows  -- Either DecodeError (Vector Node)
  Bolt.close conn
Synopsis

Configuration

data Config Source #

Connection configuration. Use def for sensible defaults and override the fields you need. Must be validated with validateConfig before use.

Constructors

Config 

Fields

Instances

Instances details
Default Config Source # 
Instance details

Defined in Database.Bolty.Connection.Type

Methods

def :: Config #

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.

data Scheme Source #

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

Instances details
Generic Scheme Source # 
Instance details

Defined in Database.Bolty.Connection.Type

Associated Types

type Rep Scheme 
Instance details

Defined in Database.Bolty.Connection.Type

type Rep Scheme = D1 ('MetaData "Scheme" "Database.Bolty.Connection.Type" "bolty-0.1.0.2-D4CzMg1BY3r5YzeDrGyWz4" 'False) ((C1 ('MetaCons "None" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "Basic" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Principal) :*: S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Credentials))) :+: (C1 ('MetaCons "Kerberos" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "Bearer" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Credentials))))

Methods

from :: Scheme -> Rep Scheme x #

to :: Rep Scheme x -> Scheme #

Eq Scheme Source # 
Instance details

Defined in Database.Bolty.Connection.Type

Methods

(==) :: Scheme -> Scheme -> Bool #

(/=) :: Scheme -> Scheme -> Bool #

PackStream Scheme Source # 
Instance details

Defined in Database.Bolty.Connection.Instances

Methods

toPs :: Scheme -> Ps #

toBinary :: Scheme -> Put #

fromPs :: Ps -> Result Scheme #

type Rep Scheme Source # 
Instance details

Defined in Database.Bolty.Connection.Type

type Rep Scheme = D1 ('MetaData "Scheme" "Database.Bolty.Connection.Type" "bolty-0.1.0.2-D4CzMg1BY3r5YzeDrGyWz4" 'False) ((C1 ('MetaCons "None" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "Basic" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Principal) :*: S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Credentials))) :+: (C1 ('MetaCons "Kerberos" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "Bearer" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Credentials))))

data Routing Source #

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. "core1:7687"), additional routing context parameters.

Instances

Instances details
Eq Routing Source # 
Instance details

Defined in Database.Bolty.Connection.Type

Methods

(==) :: Routing -> Routing -> Bool #

(/=) :: Routing -> Routing -> Bool #

PackStream Routing Source # 
Instance details

Defined in Database.Bolty.Connection.Instances

data UserAgent Source #

User-agent identifier sent to the server in the HELLO message.

Constructors

UserAgent 

Fields

Instances

Instances details
Eq UserAgent Source # 
Instance details

Defined in Database.Bolty.Connection.Type

PackStream UserAgent Source # 
Instance details

Defined in Database.Bolty.Connection.Instances

data Version Source #

A BOLT protocol version (major.minor).

Constructors

Version 

Fields

Instances

Instances details
Eq Version Source # 
Instance details

Defined in Database.Bolty.Connection.Version

Methods

(==) :: Version -> Version -> Bool #

(/=) :: Version -> Version -> Bool #

Ord Version Source # 
Instance details

Defined in Database.Bolty.Connection.Version

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

Instances details
Show TelemetryApi Source # 
Instance details

Defined in Database.Bolty.Message.Request

Eq TelemetryApi Source # 
Instance details

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

  • maxRetries :: !Int

    Maximum number of retry attempts. Default: 5.

  • initialDelay :: !Int

    Initial delay in microseconds before first retry. Default: 200000 (200ms).

  • maxDelay :: !Int

    Maximum delay in microseconds between retries. Default: 5000000 (5s).

Instances

Instances details
Show RetryConfig Source # 
Instance details

Defined in Database.Bolty.Pool

Eq RetryConfig Source # 
Instance details

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

data Bolt Source #

A typed Neo4j value. Every field in a query result record is a Bolt.

Instances

Instances details
Generic Bolt Source # 
Instance details

Defined in Database.Bolty.Value.Type

Associated Types

type Rep Bolt 
Instance details

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)))))))

Methods

from :: Bolt -> Rep Bolt x #

to :: Rep Bolt x -> Bolt #

Show Bolt Source # 
Instance details

Defined in Database.Bolty.Value.Type

Methods

showsPrec :: Int -> Bolt -> ShowS #

show :: Bolt -> String #

showList :: [Bolt] -> ShowS #

Eq Bolt Source # 
Instance details

Defined in Database.Bolty.Value.Type

Methods

(==) :: Bolt -> Bolt -> Bool #

(/=) :: Bolt -> Bolt -> Bool #

PackStream Bolt Source # 
Instance details

Defined in Database.Bolty.Value.Type

Methods

toPs :: Bolt -> Ps #

toBinary :: Bolt -> Put #

fromPs :: Ps -> Result Bolt #

type Rep Bolt Source # 
Instance details

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)))))))

type Record = Vector Bolt Source #

A single result row: a vector of Bolt values, one per column.

data Error Source #

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.

Bolt value extractors

asNull :: Bolt -> Maybe () Source #

Extract a null value.

asBool :: Bolt -> Maybe Bool Source #

Extract a boolean value.

asInt :: Bolt -> Maybe PSInteger Source #

Extract an integer value.

asFloat :: Bolt -> Maybe Double Source #

Extract a floating-point value.

asBytes :: Bolt -> Maybe ByteString Source #

Extract a byte string value.

asText :: Bolt -> Maybe Text Source #

Extract a text value.

asList :: Bolt -> Maybe (Vector Bolt) Source #

Extract a list value.

asDict :: Bolt -> Maybe (HashMap Text Bolt) Source #

Extract a dictionary value.

asNode :: Bolt -> Maybe Node Source #

Extract a node value.

asRelationship :: Bolt -> Maybe Relationship Source #

Extract a relationship value.

asPath :: Bolt -> Maybe Path Source #

Extract a path value.

Query metadata

data QueryMeta Source #

Server metadata from a PULL SUCCESS response.

Constructors

QueryMeta 

Fields

  • bookmark :: !(Maybe Text)

    the bookmark after committing this transaction (Autocommit Transaction only, absent in explicit transactions).

  • t_last :: !Int64

    the time, specified in ms, which the last record in the result stream is consumed after.

  • type_ :: !Text

    the type of the statement, e.g. "r" for read-only statement, "w" for write-only statement, "rw" for read-and-write, and "s" for schema only.

  • stats :: !(Maybe Ps)

    counter information, such as db-hits etc. May be omitted.

  • parsedStats :: !(Maybe QueryStats)

    parsed stats from the raw field above.

  • plan :: !(Maybe Ps)

    plan result. May be omitted.

  • profile :: !(Maybe Ps)

    profile result. May be omitted.

  • notifications :: !(Maybe Ps)

    a list of all notifications generated during execution of this statement. May be omitted.

  • parsedNotifications :: !(Vector Notification)

    parsed notifications from the raw field above.

  • parsedPlan :: !(Maybe PlanNode)

    parsed plan tree from the raw plan field above.

  • parsedProfile :: !(Maybe ProfileNode)

    parsed profile tree from the raw profile field above.

  • db :: !Text

    the database name where the query was executed (v4.0+).

Connection pooling

data BoltPool Source #

A pool of Neo4j connections with health-check and retry configuration.

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).

data PoolCounters Source #

Snapshot of pool-level counters.

Constructors

PoolCounters 

Fields

Instances

Instances details
Show PoolCounters Source # 
Instance details

Defined in Database.Bolty.Pool

Eq PoolCounters Source # 
Instance details

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.

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

Instances details
Show AccessMode Source # 
Instance details

Defined in Database.Bolty.Routing

Eq AccessMode Source # 
Instance details

Defined in Database.Bolty.Routing

data RoutingTable Source #

A parsed routing table returned by the ROUTE message.

Constructors

RoutingTable 

Fields

  • ttl :: !Int64

    Seconds to cache this routing table.

  • db :: !Text

    Database name this routing table is for.

  • routers :: !(Vector Text)

    "host:port" addresses for ROUTE role.

  • readers :: !(Vector Text)

    "host:port" addresses for READ role.

  • writers :: !(Vector Text)

    "host:port" addresses for WRITE role.

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

data Session Source #

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

data PlanNode Source #

A node in the query execution plan tree (from EXPLAIN).

Constructors

PlanNode 

Instances

Instances details
Show PlanNode Source # 
Instance details

Defined in Database.Bolty.Plan

Eq PlanNode Source # 
Instance details

Defined in Database.Bolty.Plan

data ProfileNode Source #

A node in the query profile tree (from PROFILE). Extends PlanNode with actual execution statistics.

Instances

Instances details
Show ProfileNode Source # 
Instance details

Defined in Database.Bolty.Plan

Eq ProfileNode Source # 
Instance details

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

data QueryLog Source #

Information about a completed query, passed to the queryLogger callback.

Constructors

QueryLog 

Fields

Instances

Instances details
Show QueryLog Source # 
Instance details

Defined in Database.Bolty.Logging

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

Instances details
Show Notification Source # 
Instance details

Defined in Database.Bolty.Notification

Eq Notification Source # 
Instance details

Defined in Database.Bolty.Notification

data Severity Source #

Severity level of a notification.

Instances

Instances details
Show Severity Source # 
Instance details

Defined in Database.Bolty.Notification

Eq Severity Source # 
Instance details

Defined in Database.Bolty.Notification

data Position Source #

Position in a Cypher query string.

Constructors

Position 

Fields

Instances

Instances details
Show Position Source # 
Instance details

Defined in Database.Bolty.Notification

Eq Position Source # 
Instance details

Defined in Database.Bolty.Notification

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.

Instances

Instances details
Show QueryStats Source # 
Instance details

Defined in Database.Bolty.Stats

Eq QueryStats Source # 
Instance details

Defined in Database.Bolty.Stats

BoltM monad

data BoltM a Source #

A monad for running queries against a Neo4j connection. Use runBolt to execute a BoltM action with a Connection.

Instances

Instances details
MonadIO BoltM Source # 
Instance details

Defined in Database.Bolty

Methods

liftIO :: IO a -> BoltM a #

Applicative BoltM Source # 
Instance details

Defined in Database.Bolty

Methods

pure :: a -> BoltM a #

(<*>) :: BoltM (a -> b) -> BoltM a -> BoltM b #

liftA2 :: (a -> b -> c) -> BoltM a -> BoltM b -> BoltM c #

(*>) :: BoltM a -> BoltM b -> BoltM b #

(<*) :: BoltM a -> BoltM b -> BoltM a #

Functor BoltM Source # 
Instance details

Defined in Database.Bolty

Methods

fmap :: (a -> b) -> BoltM a -> BoltM b #

(<$) :: a -> BoltM b -> BoltM a #

Monad BoltM Source # 
Instance details

Defined in Database.Bolty

Methods

(>>=) :: BoltM a -> (a -> BoltM b) -> BoltM b #

(>>) :: BoltM a -> BoltM b -> BoltM b #

return :: a -> BoltM a #

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 #

Run a Cypher query, decode each record using the FromBolt instance, and return the decoded rows paired with server metadata (QueryMeta). Pass mempty for no parameters.

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.

queryResultMeta :: HasCallStack => Text -> HashMap Text Ps -> BoltM (ResultSet, QueryMeta) Source #

Run a Cypher query and return a ResultSet paired with server metadata (QueryMeta — timing, statistics, notifications, plan/profile). Pass mempty for no parameters.

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.

newtype Decode a Source #

A decoder for a single Bolt value.

Constructors

Decode 

Instances

Instances details
Applicative Decode Source # 
Instance details

Defined in Database.Bolty.Decode

Methods

pure :: a -> Decode a #

(<*>) :: Decode (a -> b) -> Decode a -> Decode b #

liftA2 :: (a -> b -> c) -> Decode a -> Decode b -> Decode c #

(*>) :: Decode a -> Decode b -> Decode b #

(<*) :: Decode a -> Decode b -> Decode a #

Functor Decode Source # 
Instance details

Defined in Database.Bolty.Decode

Methods

fmap :: (a -> b) -> Decode a -> Decode b #

(<$) :: a -> Decode b -> Decode a #

Monad Decode Source # 
Instance details

Defined in Database.Bolty.Decode

Methods

(>>=) :: Decode a -> (a -> Decode b) -> Decode b #

(>>) :: Decode a -> Decode b -> Decode b #

return :: a -> Decode a #

newtype RowDecoder a Source #

A decoder for a full result row. Compose with Applicative to decode multiple columns.

Constructors

RowDecoder 

Fields

Instances

Instances details
Applicative RowDecoder Source # 
Instance details

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 # 
Instance details

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

class ToBolt a where Source #

Types that can be encoded to a Ps value for use as query parameters. All PackStream instances are automatically ToBolt instances.

Methods

toBolt :: a -> Ps Source #

Instances

Instances details
PackStream a => ToBolt a Source # 
Instance details

Defined in Database.Bolty.Decode

Methods

toBolt :: a -> Ps Source #

int64 :: Decode Int64 Source #

Decode a BoltInteger narrowed to Int64. Fails if the value is out of range.

nullable :: Decode a -> Decode (Maybe a) Source #

Make a decoder nullable: returns Nothing for BoltNull, otherwise applies the inner decoder.

list :: Decode a -> Decode (Vector a) Source #

Decode a BoltList, applying the element decoder to each item.

uuid :: Decode UUID Source #

Decode a UUID from a BoltString.

utcTime :: Decode UTCTime Source #

Decode a UTCTime from a BoltString (ISO 8601) or BoltDateTime.

day :: Decode Day Source #

Decode a Day from a BoltString (ISO 8601).

timeOfDay :: Decode TimeOfDay Source #

Decode a TimeOfDay from a BoltString (ISO 8601).

aesonValue :: Decode Value Source #

Decode any Bolt value to an Value.

nodeProperty :: Text -> Decode a -> Decode a Source #

Extract a property from a BoltNode by key and decode it.

nodePropertyOptional :: Text -> Decode a -> Decode (Maybe a) Source #

Extract a property from a BoltNode by key, returning Nothing if the key is missing.

nodeLabels :: Decode (Vector Text) Source #

Extract labels from a BoltNode.

nodeProperties :: Decode (HashMap Text Ps) Source #

Extract the raw properties HashMap from a BoltNode.

column :: Int -> Decode a -> RowDecoder a Source #

Decode a value at a positional column index.

field :: Text -> Decode a -> RowDecoder a Source #

Decode a value by column name.

Result sets

data ResultSet Source #

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.

Constructors

ResultSet 

Fields

Instances

Instances details
Show ResultSet Source # 
Instance details

Defined in Database.Bolty.ResultSet

Eq ResultSet Source # 
Instance details

Defined in Database.Bolty.ResultSet

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

data Ps #

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

Instances details
NFData Ps 
Instance details

Defined in Data.PackStream.Ps

Methods

rnf :: Ps -> () #

Show Ps 
Instance details

Defined in Data.PackStream.Ps

Methods

showsPrec :: Int -> Ps -> ShowS #

show :: Ps -> String #

showList :: [Ps] -> ShowS #

Eq Ps 
Instance details

Defined in Data.PackStream.Ps

Methods

(==) :: Ps -> Ps -> Bool #

(/=) :: Ps -> Ps -> Bool #

PackStream Ps

The trivial identity PackStream instance

Instance details

Defined in Data.PackStream.Ps

Methods

toPs :: Ps -> Ps #

toBinary :: Ps -> Put #

fromPs :: Ps -> Result Ps #

Persist Ps

This Persist instance encodes/decodes to/from PackStream format

Instance details

Defined in Data.PackStream.Ps

Methods

put :: Ps -> Put () #

get :: Get Ps #

unsafePut :: Ps -> Put () #

unsafeGet :: Get Ps #