Transitions a snapshot from CREATED to SEALED and stores a deterministic
snapshot_hash in a single DuckDB transaction.
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 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_FOUNDifsnapshot_iddoes not exist.Already sealed snapshots return their existing hash idempotently.
LEDGR_SNAPSHOT_NOT_MUTABLEif the snapshot status is notCREATED.LEDGR_SNAPSHOT_EMPTYif there are 0 bars or 0 instruments.LEDGR_SNAPSHOT_REFERENTIAL_INTEGRITYif bars reference missing instruments.LEDGR_SNAPSHOT_OHLC_INVALIDif OHLC bars are internally inconsistent.LEDGR_SNAPSHOT_SEAL_FAILEDon hashing/transaction failures (snapshot is markedFAILED).
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"
)
bars_csv <- tempfile(fileext = ".csv")
utils::write.csv(data.frame(
instrument_id = "AAA",
ts_utc = c("2020-01-01T00:00:00Z", "2020-01-02T00:00:00Z"),
open = c(100, 101),
high = c(101, 102),
low = c(99, 100),
close = c(100, 101),
volume = 1000
), bars_csv, row.names = FALSE)
ledgr_snapshot_import_bars_csv(con, snapshot_id, bars_csv)
ledgr_snapshot_seal(con, snapshot_id)
#> [1] "cdce2950fdab774786acf556eb1f8f76ccc2c932afc2e2a2e6e02358f13d2d94"
DBI::dbDisconnect(con, shutdown = TRUE)