Liking cljdoc? Tell your friends :D

syncopate.core

Syncopate — a production-quality ragtime adaptor for Datalevin.

Public surface:

  • store construct the ragtime DataStore (re-exported from syncopate.store).
  • load-resources build migrations from EDN/CLJ files on the classpath.
  • ->migration build a single migration from a spec map.
  • pending / status observability without running anything.

Migrations are EDN-first. A migration spec is a map:

{:id "0002-split-names" ; optional; defaults to the filename :up <step | [step ...]> :down <step | [step ...]> ; optional if :up is purely additive :transaction? true ; optional, default true :irreversible? false} ; optional

A step is one of:

  • {:schema/create {attr def ...}} add NEW attributes (auto-invertible)
  • {:schema/alter {attr def ...}} modify existing attrs (needs :down)
  • {:schema/remove [attr ...]} retract + drop attrs (needs :down)
  • {:tx [tx-data ...]} raw transact! data
  • a fully-qualified symbol resolved to (fn [conn] ...) and called
  • (in .clj files) an actual fn called as (fn [conn] ...)

Sugar:

  • :up/:down may be a single step instead of a vector.
  • Omit :down and it is derived automatically iff every :up step is a :schema/create (adds → removes). Otherwise supply :down, or set :irreversible? true to opt out of rollback with a clear error.

The obsolete bare :schema step (ambiguous between create and alter) is rejected with an actionable error — see ->migration.

Syncopate — a production-quality ragtime adaptor for Datalevin.

Public surface:
  - `store`            construct the ragtime DataStore (re-exported from
                       `syncopate.store`).
  - `load-resources`   build migrations from EDN/CLJ files on the classpath.
  - `->migration`      build a single migration from a spec map.
  - `pending` / `status`  observability without running anything.

Migrations are EDN-first. A migration spec is a map:

  {:id "0002-split-names"          ; optional; defaults to the filename
   :up   <step | [step ...]>
   :down <step | [step ...]>        ; optional if :up is purely additive
   :transaction? true               ; optional, default true
   :irreversible? false}            ; optional

A *step* is one of:
  - {:schema/create {attr def ...}} add NEW attributes     (auto-invertible)
  - {:schema/alter  {attr def ...}} modify existing attrs  (needs :down)
  - {:schema/remove [attr ...]}     retract + drop attrs   (needs :down)
  - {:tx [tx-data ...]}             raw `transact!` data
  - a fully-qualified symbol        resolved to (fn [conn] ...) and called
  - (in .clj files) an actual fn    called as (fn [conn] ...)

Sugar:
  - `:up`/`:down` may be a single step instead of a vector.
  - Omit `:down` and it is derived automatically iff every `:up` step is a
    `:schema/create` (adds → removes). Otherwise supply `:down`, or set
    `:irreversible? true` to opt out of rollback with a clear error.

The obsolete bare `:schema` step (ambiguous between create and alter) is
rejected with an actionable error — see `->migration`.
raw docstring

syncopate.schema

Declarative schema operations for Datalevin migrations.

A schema step carries exactly one operation, along two orthogonal axes:

existence axis (does the attribute exist at all): :schema/create - map of attr -> definition to add NEW attributes. Auto-invertible (its :down drops them again), which powers the auto-:down sugar in syncopate.core. :schema/remove - collection of attrs to drop. Datalevin won't drop an attr that still has datoms, so we retract them first. NOT auto-invertible (the data, and prior definitions, are gone) — supply an explicit :down or set :irreversible?.

definition axis (change an existing attribute's property keys): :schema/alter - map of attr -> definition, merged (patched) into the existing definition via update-schema. The attribute keeps existing. NOT auto-invertible (the prior definition is unknown) — supply an explicit :down (itself a :schema/alter describing the inverse change).

:schema/create and :schema/alter apply identically at run time (update-schema conn <map>); they differ only in declared reversibility. We never inspect the live schema to guess intent — the declared key IS the intent.

Declarative schema operations for Datalevin migrations.

A schema step carries exactly one operation, along two orthogonal axes:

  existence axis (does the attribute exist at all):
    :schema/create - map of attr -> definition to add NEW attributes.
                     Auto-invertible (its :down drops them again), which powers
                     the auto-`:down` sugar in `syncopate.core`.
    :schema/remove - collection of attrs to drop. Datalevin won't drop an attr
                     that still has datoms, so we retract them first. NOT
                     auto-invertible (the data, and prior definitions, are gone)
                     — supply an explicit :down or set :irreversible?.

  definition axis (change an existing attribute's property keys):
    :schema/alter  - map of attr -> definition, merged (patched) into the
                     existing definition via `update-schema`. The attribute
                     keeps existing. NOT auto-invertible (the prior definition
                     is unknown) — supply an explicit :down (itself a
                     :schema/alter describing the inverse change).

`:schema/create` and `:schema/alter` apply identically at run time
(`update-schema conn <map>`); they differ only in declared reversibility. We
never inspect the live schema to guess intent — the declared key IS the intent.
raw docstring

syncopate.store

The ragtime DataStore half of Syncopate.

Applied-migration state lives in a dedicated key-value DBI on the same environment the app's Datalog connection already holds — never as datoms. This holds for both connection kinds:

  • embedded (a local LMDB directory): reuse the connection's own environment via the backing datalevin.storage.Store's lmdb handle (Datalevin forbids a second LMDB connection to the same directory in one process, so we can't just open-kv).
  • client/server (a dtlv:// URI): the remote Datalog store does not expose the KV surface, so open a KV client to the SAME server database via open-kv. It shares the datalog connection's server environment (its DBIs sit alongside datalevin/eav etc.), so the promise holds — a KV DBI on the same env, never datoms. (Because that KV client is a separate session, it can't join the datalog with-transaction, so client/server migrations record with the two-transaction seam rather than the single-transaction fold.)
The ragtime DataStore half of Syncopate.

Applied-migration state lives in a dedicated key-value DBI on the *same*
environment the app's Datalog connection already holds — never as datoms. This
holds for both connection kinds:

- **embedded** (a local LMDB directory): reuse the connection's own environment
  via the backing `datalevin.storage.Store`'s `lmdb` handle (Datalevin forbids a
  second LMDB connection to the same directory in one process, so we can't just
  `open-kv`).
- **client/server** (a `dtlv://` URI): the remote Datalog store does not expose
  the KV surface, so open a KV *client* to the SAME server database via
  `open-kv`. It shares the datalog connection's server environment (its DBIs sit
  alongside `datalevin/eav` etc.), so the promise holds — a KV DBI on the same
  env, never datoms. (Because that KV client is a separate session, it can't join
  the datalog `with-transaction`, so client/server migrations record with the
  two-transaction seam rather than the single-transaction fold.)
raw docstring

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