| Safe Haskell | None |
|---|---|
| Language | Haskell2010 |
Ouroboros.Consensus.Storage.LeiosDB.Impl.SQLite.Primitives
Description
Low-level SQLite primitives that turn every SQLite error into a
LeiosDbException.
Synopsis
- useStmt ∷ Statement → IO a → IO a
- dbBindBlob ∷ HasCallStack ⇒ Statement → ParamIndex → ByteString → IO ()
- dbBindUtf8 ∷ HasCallStack ⇒ Statement → ParamIndex → ByteString → IO ()
- dbBindInt64 ∷ HasCallStack ⇒ Statement → ParamIndex → Int64 → IO ()
- dbExec ∷ HasCallStack ⇒ Database → Utf8 → IO ()
- dbFinalize ∷ Statement → IO ()
- dbPrepare ∷ HasCallStack ⇒ Database → Utf8 → IO Statement
- withStmt ∷ HasCallStack ⇒ Database → String → (Statement → IO a) → IO a
- orCloseOnError ∷ Database → IO a → IO a
- dbWithTransaction ∷ HasCallStack ⇒ Database → IO a → IO a
- dbWithWriteTransactionRaw ∷ HasCallStack ⇒ Database → IO a → IO a
- dbWithTransactionAs ∷ HasCallStack ⇒ String → Database → IO a → IO a
- dbStep ∷ HasCallStack ⇒ Statement → IO StepResult
- dbStep1 ∷ HasCallStack ⇒ Statement → IO ()
- dbStepSafe ∷ HasCallStack ⇒ Statement → IO StepResult
- dbStep1Safe ∷ HasCallStack ⇒ Statement → IO ()
- readSingleInt64 ∷ HasCallStack ⇒ Statement → IO Int64
- readReturningInt64 ∷ Statement → IO Int64
- queryInt64 ∷ HasCallStack ⇒ Database → String → IO Int64
- collectBlobs ∷ HasCallStack ⇒ Statement → IO [ByteString]
- execJson ∷ HasCallStack ⇒ Statement → ByteString → IO ()
- dbStepInsert ∷ HasCallStack ⇒ Statement → IO Bool
- dbStepInsertOrTrace ∷ HasCallStack ⇒ Tracer IO TraceLeiosDb → String → String → Statement → IO ()
- jsonHexArray ∷ [ByteString] → ByteString
- jsonIntArray ∷ [Int] → ByteString
- withDie ∷ HasCallStack ⇒ Database → IO (Either Error a) → IO a
- withDieStmt ∷ HasCallStack ⇒ Statement → IO (Either Error a) → IO a
- withDieJust ∷ HasCallStack ⇒ Database → IO (Either Error (Maybe a)) → IO a
- withDieDoneStmt ∷ HasCallStack ⇒ Statement → IO (Either Error StepResult) → IO ()
- throwDbException ∷ HasCallStack ⇒ Database → Error → IO a
Documentation
useStmt ∷ Statement → IO a → IO a Source #
Run an action on a pre-prepared statement and always sqlite3_reset
it afterwards, regardless of outcome. Reset uses raw reset (no
error re-throw) because SQLite reports the previous step's error via
reset; we let the original exception propagate instead.
dbBindBlob ∷ HasCallStack ⇒ Statement → ParamIndex → ByteString → IO () Source #
dbBindUtf8 ∷ HasCallStack ⇒ Statement → ParamIndex → ByteString → IO () Source #
Bind as TEXT. Needed for JSON1 payloads: json_each interprets BLOB
arguments as JSONB (SQLite ≥ 3.45), our payload is ASCII JSON.
dbBindInt64 ∷ HasCallStack ⇒ Statement → ParamIndex → Int64 → IO () Source #
dbFinalize ∷ Statement → IO () Source #
Finalize a statement, exactly once, ignoring the return code.
sqlite3_finalize always frees the statement; its return code merely
replays the most recent evaluation's error (sticky, like reset -- see
useStmt). Neither retrying nor throwing is ever right here: a busy-retry
would call sqlite3_finalize on freed memory (the use-after-free behind
the devnet segfaults of 2026-08-31), and a throw would propagate from
bracket cleanup.
withStmt ∷ HasCallStack ⇒ Database → String → (Statement → IO a) → IO a Source #
Prepare a statement, run the action, finalize.
orCloseOnError ∷ Database → IO a → IO a Source #
Close the connection if the action throws, then rethrow. For whatever is acquired on a fresh connection -- an attach, a schema, a statement -- after the open succeeded and before anything owns the close.
dbWithTransaction ∷ HasCallStack ⇒ Database → IO a → IO a Source #
A read-only transaction: BEGIN DEFERRED, so readers do not exclude each
other. Any transaction that writes must use dbWithWriteTransaction.
dbWithWriteTransactionRaw ∷ HasCallStack ⇒ Database → IO a → IO a Source #
dbWithWriteTransaction for the maintenance paths (promotion to immutable, GC), which hold
a raw Database rather than a Conn.
dbWithTransactionAs ∷ HasCallStack ⇒ String → Database → IO a → IO a Source #
dbStep ∷ HasCallStack ⇒ Statement → IO StepResult Source #
dbStep1Safe ∷ HasCallStack ⇒ Statement → IO () Source #
dbStep1 through the safe FFI call; see dbStepSafe.
readSingleInt64 ∷ HasCallStack ⇒ Statement → IO Int64 Source #
Read a single-row, single-column integer result, stepping (safe FFI)
through to completion -- which also suits RETURNING statements, whose
write only certainly happened once they report Done.
readReturningInt64 ∷ Statement → IO Int64 Source #
Read a single-column Int64 from a statement that uses a
RETURNING clause on a PK-scoped UPDATE (i.e. produces exactly one
row followed by Done). Any other shape is a programmer error.
queryInt64 ∷ HasCallStack ⇒ Database → String → IO Int64 Source #
Run a query that yields exactly one integer column.
collectBlobs ∷ HasCallStack ⇒ Statement → IO [ByteString] Source #
Step a statement (safe FFI) to completion, collecting blob column 0.
execJson ∷ HasCallStack ⇒ Statement → ByteString → IO () Source #
Bind a JSON payload (jsonHexArray) to parameter 1 and execute the statement
via non-blocking Safe FFI.
dbStepInsert ∷ HasCallStack ⇒ Statement → IO Bool Source #
dbStepInsertOrTrace ∷ HasCallStack ⇒ Tracer IO TraceLeiosDb → String → String → Statement → IO () Source #
Step an INSERT statement, absorbing UNIQUE/PRIMARY KEY violations and
emitting a TraceLeiosDbInsertCollision for each one. The caller supplies a
table label and a key description for the trace.
After a constraint error, sqlite3_reset reports the same error code; the
normal dbReset would re-throw it, so we use raw reset and discard the
return value. This also leaves the statement in a clean state for the
subsequent bracket-time dbFinalize to succeed.
jsonHexArray ∷ [ByteString] → ByteString Source #
Build a JSON array of hex-encoded blobs: ["aabb...","1234...",...].
Consumed on the SQL side via json_each(?) + unhex(je.value).
jsonIntArray ∷ [Int] → ByteString Source #
Build a JSON array of integers: [1,2,3,...]. Same consumer pattern
as jsonHexArray (values are already ints, so no decoding step).
withDie ∷ HasCallStack ⇒ Database → IO (Either Error a) → IO a Source #
Run a database action that may return an error, and throw a
LeiosDbException if it does.
Including ErrorBusy: the connections set a busy_timeout, so SQLite
has already waited that long in C before reporting it. Waiting again on
top of that only converts a lock nobody is going to release into an
unbounded stall -- and with one writer per partition, a lock nobody is
going to release means another process has the file.
withDieStmt ∷ HasCallStack ⇒ Statement → IO (Either Error a) → IO a Source #
withDieJust ∷ HasCallStack ⇒ Database → IO (Either Error (Maybe a)) → IO a Source #
withDieDoneStmt ∷ HasCallStack ⇒ Statement → IO (Either Error StepResult) → IO () Source #
throwDbException ∷ HasCallStack ⇒ Database → Error → IO a Source #