Liking cljdoc? Tell your friends :D

konserve-jdbc.core

Address globally aggregated immutable key-value stores(s).

Address globally aggregated immutable key-value stores(s).
raw docstring

bulk-delete-statementclj

(bulk-delete-statement db-type table store-keys)

bulk-insert-statementclj

(bulk-insert-statement db-type table store-key-values)

bulk-select-statementclj

(bulk-select-statement db-type table store-keys)

Generate SELECT statement for multiple keys. Returns a vector with [sql-string & parameters].

Generate SELECT statement for multiple keys.
Returns a vector with [sql-string & parameters].
raw docstring

change-row-idclj

(change-row-id connection table from to)

conditional-write-domainclj

(conditional-write-domain {:keys [dbtype dbname]})

How far this store's fence reaches: :global, :machine, :process, or nil.

For the servers it follows the dbtype. For the two embedded databases it cannot, because one dbtype spells three different deployments and the difference is the whole answer:

  • h2 with a mem: name, and sqlite with :memory:, live in one JVM heap. A second process on the same host opens an entirely DIFFERENT database, so the honest domain is :process. Reporting :machine here would be an OVER-claim — a caller asking (conditional-write? store :machine) would be told yes about writers that cannot even see this data.
  • h2 reached over tcp:// or ssl:// is a server like any other, and orders writers anywhere on the network: :global.
  • otherwise both are a file, ordering processes on the host that holds it and no further — and not even that on a network filesystem, where SQLite's own documentation calls locking unreliable.

A database this does not recognise gets NO domain and :expected-revision is refused. The statement would work on any SQL database; what cannot be guessed is how far its answer reaches, and guessing generously is how a deployment comes to believe it is fenced across hosts when it is not.

How far this store's fence reaches: `:global`, `:machine`, `:process`, or nil.

For the servers it follows the dbtype. For the two embedded databases it
cannot, because one dbtype spells three different deployments and the
difference is the whole answer:

  - `h2` with a `mem:` name, and sqlite with `:memory:`, live in one JVM heap.
    A second process on the same host opens an entirely DIFFERENT database, so
    the honest domain is `:process`. Reporting `:machine` here would be an
    OVER-claim — a caller asking `(conditional-write? store :machine)` would be
    told yes about writers that cannot even see this data.
  - `h2` reached over `tcp://` or `ssl://` is a server like any other, and
    orders writers anywhere on the network: `:global`.
  - otherwise both are a file, ordering processes on the host that holds it and
    no further — and not even that on a network filesystem, where SQLite's own
    documentation calls locking unreliable.

A database this does not recognise gets NO domain and `:expected-revision` is
refused. The statement would work on any SQL database; what cannot be guessed
is how far its answer reaches, and guessing generously is how a deployment
comes to believe it is fenced across hosts when it is not.
raw docstring

connect-jdbc-storeclj


connect-storeclj

(connect-store db-spec & {:keys [table opts] :as params})

copy-row-statementclj

(copy-row-statement db-type table to from)

create-statementclj

(create-statement db-type table)

dbtypesclj


default-tableclj


delete-statementclj

(delete-statement db-type table)

delete-storeclj

(delete-store db-spec & {:keys [table opts]})

Drop the store's table. Uses a connection of its own rather than the shared pool, so deleting one tenant's store leaves every other store on the database untouched.

Drop the store's table. Uses a connection of its own rather than the shared
pool, so deleting one tenant's store leaves every other store on the database
untouched.
raw docstring

extract-bytesclj

(extract-bytes obj dbtype)

fenced-insert-statementclj

(fenced-insert-statement db-type table id header meta value)

Insert the row for id, relying on the PRIMARY KEY to refuse it if the row already exists — which is create-if-absent, evaluated by the database.

A plain INSERT rather than a dialect-specific upsert precisely because it must NOT overwrite. The refusal arrives as an integrity-constraint violation, which is SQLSTATE class 23 in the standard and in every driver here.

Insert the row for `id`, relying on the PRIMARY KEY to refuse it if the row
already exists — which is create-if-absent, evaluated by the database.

A plain INSERT rather than a dialect-specific upsert precisely because it must
NOT overwrite. The refusal arrives as an integrity-constraint violation, which
is SQLSTATE class 23 in the standard and in every driver here.
raw docstring

fenced-read?clj

(fenced-read? env)

fenced-update-statementclj

(fenced-update-statement db-type table id header meta value expected-meta)

Replace the row for id, but only while its meta column still holds expected-meta. Row count 1 means the write happened, 0 that it was refused.

ONE statement, so the comparison and the write are the same step — the database evaluates it, which is what makes this backing's guarantee reach as far as the database does. No transaction is needed for that; an UPDATE is atomic on its own.

The comparison is on the META column rather than a separate version column. konserve's revision lives inside the serialized metadata, so for this row the meta bytes ARE the revision, and comparing them needs no schema change and no migration for existing tables.

SQL Server needs the length too. Its varbinary comparison treats trailing zero bytes as insignificant, so two values of different lengths can compare EQUAL — which for a fence means a stale write passing. Microsoft's own guidance is to test the length alongside the data, and DATALENGTH is how. The other dialects compare binary exactly: bytea, longblob and SQLite BLOBs are all memcmp.

Replace the row for `id`, but only while its `meta` column still holds
`expected-meta`. Row count 1 means the write happened, 0 that it was refused.

ONE statement, so the comparison and the write are the same step — the database
evaluates it, which is what makes this backing's guarantee reach as far as the
database does. No transaction is needed for that; an UPDATE is atomic on its
own.

The comparison is on the META column rather than a separate version column.
konserve's revision lives inside the serialized metadata, so for this row the
meta bytes ARE the revision, and comparing them needs no schema change and no
migration for existing tables.

SQL Server needs the length too. Its varbinary comparison treats trailing zero
bytes as insignificant, so two values of different lengths can compare EQUAL —
which for a fence means a stale write passing. Microsoft's own guidance is to
test the length alongside the data, and DATALENGTH is how. The other dialects
compare binary exactly: bytea, longblob and SQLite BLOBs are all memcmp.
raw docstring

fenced-write-operationsclj

The :operation values konserve puts in the env of a CONDITIONAL write. The read it takes under the lock to evaluate that write carries the same one, which is what lets the read path tell itself apart from every other read.

The `:operation` values konserve puts in the env of a CONDITIONAL write. The
read it takes under the lock to evaluate that write carries the same one, which
is what lets the read path tell itself apart from every other read.
raw docstring

get-connectionclj

(get-connection db-spec)

Return the pooled DataSource for db-spec, opening it if needed, and take a reference to it. Every call must be paired with a release (or release-pool!), or the pool is never closed.

With :validate-pool? true in the spec, an already-open pool is probed before it is handed out and rebuilt if it has been closed out of band. The probe costs a connection checkout per connect, so it is off by default.

Return the pooled DataSource for `db-spec`, opening it if needed, and take a
reference to it. Every call must be paired with a `release` (or
`release-pool!`), or the pool is never closed.

With `:validate-pool? true` in the spec, an already-open pool is probed
before it is handed out and rebuilt if it has been closed out of band. The
probe costs a connection checkout per connect, so it is off by default.
raw docstring

integrity-violation?clj

(integrity-violation? e)

Is this the database refusing a duplicate primary key?

SQLSTATE class 23 is the standard's integrity-constraint violation. Measured against every database this backend supports: postgres 23505, mysql 23000, h2 23505, sqlserver 23000 — and sqlite, which reports NO SQLSTATE at all (nil) and carries the refusal in the vendor code instead, 19 for SQLITE_CONSTRAINT. Missing that case would turn create-if-absent on sqlite from a clean rejection into a raw driver exception the caller cannot classify, so the vendor code is matched too — narrowly, by driver class name, because the number 19 means nothing in particular anywhere else.

Is this the database refusing a duplicate primary key?

SQLSTATE class 23 is the standard's integrity-constraint violation. Measured
against every database this backend supports: postgres 23505, mysql 23000,
h2 23505, sqlserver 23000 — and sqlite, which reports NO SQLSTATE at all
(`nil`) and carries the refusal in the vendor code instead, 19 for
SQLITE_CONSTRAINT. Missing that case would turn create-if-absent on sqlite
from a clean rejection into a raw driver exception the caller cannot classify,
so the vendor code is matched too — narrowly, by driver class name, because
the number 19 means nothing in particular anywhere else.
raw docstring

offset-queryclj

(offset-query db-type table offset)

poolclj


pool-statusclj

(pool-status)

Registry snapshot for diagnostics and tests: pool key -> {:refs n :open? bool :db-spec spec}, with credentials stripped. Never returns the DataSource itself.

Registry snapshot for diagnostics and tests: pool key -> {:refs n :open? bool
:db-spec spec}, with credentials stripped. Never returns the DataSource
itself.
raw docstring

read-allclj

(read-all db-type connection table id)

read-batch-limitsclj

Maximum keys per SELECT IN clause, by database type. Based on SQL parameter limits (1 param per key) and practical result set sizes.

Maximum keys per SELECT IN clause, by database type.
Based on SQL parameter limits (1 param per key) and practical result set sizes.
raw docstring

read-fieldclj

(read-field db-type
            connection
            table
            id
            column
            &
            {:keys [binary? locked-cb] :or {binary? false}})

read-metaclj

(read-meta db-type connection table id)

read-operationclj

(read-operation env db-type connection table id)

releaseclj

(release store env)

Hand back this store's reference to its connection pool. Must be called when work on the store has finished.

The pool is shared with every other store on the same database, so it is only closed once the last store using it has been released. Returns :closed, :retained, :absent, :already-released or :stale (the pool this store was opened against has since been closed out of band and rebuilt; the store's reference no longer counts and nothing is closed).

{:force? true} in env closes the shared pool regardless of who else is using it -- the pre-refcount behaviour, appropriate at process shutdown and nowhere else.

Hand back this store's reference to its connection pool. Must be called when
work on the store has finished.

The pool is shared with every other store on the same database, so it is only
closed once the last store using it has been released. Returns `:closed`,
`:retained`, `:absent`, `:already-released` or `:stale` (the pool this store
was opened against has since been closed out of band and rebuilt; the
store's reference no longer counts and nothing is closed).

`{:force? true}` in `env` closes the shared pool regardless of who else is
using it -- the pre-refcount behaviour, appropriate at process shutdown and
nowhere else.
raw docstring

release-pool!clj

(release-pool! db-spec & {:keys [force? token]})

Give back one reference to the pool for db-spec. Closes and forgets the pool when the last reference goes. Returns :closed, :retained or :absent.

:force? true closes the pool no matter how many stores still hold it. That is the old, unconditional behaviour -- a footgun on a shared database, and only appropriate when shutting the whole process down.

:token is the token acquire-pool handed out with the reference. It makes releases generation-safe: a holder of a retired pool decrements that retired generation, never the replacement active under the same key. :stale means the referenced generation has already been forcibly closed.

Give back one reference to the pool for `db-spec`. Closes and forgets the
pool when the last reference goes. Returns `:closed`, `:retained` or
`:absent`.

`:force? true` closes the pool no matter how many stores still hold it. That
is the old, unconditional behaviour -- a footgun on a shared database, and
only appropriate when shutting the whole process down.

`:token` is the token `acquire-pool` handed out with the reference. It makes
releases generation-safe: a holder of a retired pool decrements that retired
generation, never the replacement active under the same key. `:stale` means
the referenced generation has already been forcibly closed.
raw docstring

remove-from-poolclj

(remove-from-pool db-spec)

Retire the active pool for db-spec without interrupting its holders, so the next connect-store builds a fresh generation. The retired pool remains reference counted and closes when its final original holder releases it.

Retire the active pool for `db-spec` without interrupting its holders, so the
next `connect-store` builds a fresh generation. The retired pool remains
reference counted and closes when its final original holder releases it.
raw docstring

retired-pool-statusclj

(retired-pool-status)

Credential-free snapshot of pool generations retired by remove-from-pool.

Credential-free snapshot of pool generations retired by `remove-from-pool`.
raw docstring

server-conditional-write-domainsclj

How far a fenced write reaches, for the databases that are SERVERS. The mechanism is the same everywhere — one UPDATE ... WHERE meta = ?, evaluated by the database — but the reach is a property of where that database runs, and a server on the network is reachable from any host, so its comparison orders every writer anywhere.

How far a fenced write reaches, for the databases that are SERVERS. The
mechanism is the same everywhere — one `UPDATE ... WHERE meta = ?`, evaluated
by the database — but the reach is a property of where that database runs, and
a server on the network is reachable from any host, so its comparison orders
every writer anywhere.
raw docstring

supported-dbtypesclj


table-exists-queryclj

(table-exists-query db-type table)

update-statementclj

(update-statement db-type table id header meta value)

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
Move to previous article
Move to next article
Ctrl+/Jump to the search field
× close