Skip to contents

Transitions a snapshot from CREATED to SEALED and stores a deterministic snapshot_hash in a single DuckDB transaction.

Usage

ledgr_snapshot_seal(con, snapshot_id)

Arguments

con

A DBI connection to DuckDB or a ledgr_snapshot.

snapshot_id

Snapshot id (must exist and be status CREATED or SEALED) when con is a connection.

Value

The computed snapshot hash (character(1)) when called with a DBI connection and snapshot_id. When called with a ledgr_snapshot handle, returns an invisible list with $hash and $snapshot.

Details

Snapshot mutability rule: sealing computes the hash while status is CREATED. Calling ledgr_snapshot_seal() again on an already sealed snapshot is idempotent: it ensures the current-process proof, returns the existing snapshot hash, and does not mutate snapshot contents. After sealing, snapshot write operations must be rejected by ledgr code paths. When basic metadata such as start_date, end_date, n_bars, or n_instruments is missing, sealing derives it from the imported snapshot tables. Metadata does not contribute to snapshot_hash.

Errors:

  • LEDGR_SNAPSHOT_NOT_FOUND if snapshot_id does not exist.

  • Already sealed snapshots ensure and return their existing hash idempotently.

  • LEDGR_SNAPSHOT_NOT_MUTABLE if the snapshot status is not CREATED.

  • LEDGR_SNAPSHOT_EMPTY if there are 0 bars or 0 instruments.

  • LEDGR_SNAPSHOT_REFERENTIAL_INTEGRITY if bars reference missing instruments.

  • LEDGR_SNAPSHOT_OHLC_INVALID if OHLC bars are internally inconsistent, with subclass ledgr_ohlc_non_positive when a price is zero or negative.

  • LEDGR_SNAPSHOT_SEAL_FAILED on hashing/transaction failures (snapshot is marked FAILED).

Articles

Durable experiment stores: vignette("experiment-store", package = "ledgr") system.file("doc", "experiment-store.html", package = "ledgr")

Examples

db_path <- tempfile(fileext = ".duckdb")
con <- ledgr_db_init(db_path)
snapshot_id <- ledgr_snapshot_create(
  con,
  snapshot_id = "snapshot_20200101_000000_abcd"
)
DBI::dbAppendTable(con, "snapshot_instruments", data.frame(
  snapshot_id = snapshot_id,
  instrument_id = "AAA",
  symbol = "AAA",
  currency = "USD",
  asset_class = "EQUITY",
  multiplier = 1,
  tick_size = 0.01,
  meta_json = NA_character_
))
DBI::dbAppendTable(con, "snapshot_bars", data.frame(
  snapshot_id = snapshot_id,
  instrument_id = "AAA",
  ts_utc = as.POSIXct(
    c("2020-01-01", "2020-01-02"),
    tz = "UTC"
  ),
  open = c(100, 101),
  high = c(101, 102),
  low = c(99, 100),
  close = c(100, 101),
  volume = 1000
))
ledgr_snapshot_seal(con, snapshot_id)
#> [1] "f425781cd274ae4e987171debd8b55ba847bb0efd689af2248d54980e3f835e0"
DBI::dbDisconnect(con, shutdown = TRUE)