Skip to contents

Recalculates the plan's digest and requires it to match both the preview and its approval, refuses a ledger written for a different batch, and skips the entries an earlier run completed. Every row is recorded before and after its effect, so an interrupted batch leaves a ledger that names the row whose outcome is unknown.

Usage

zotExecute(config, preview, approval, ledgerPath)

Arguments

config

A zotConfig() object.

preview

The zotPreview() being executed.

approval

Its zotApprove() record.

ledgerPath

JSON ledger file; reuse the same path to resume.

Value

The ledger as a list (class zotLedger).

Details

Patch operations read the current item version, use a conditional write, and compare requested fields with a subsequent API read. Create operations record the new key after it can be read. Trash operations use the status returned by zotTrash(). The approval record is application metadata; this function does not independently determine who authorized the batch.

The digest is recalculated from the plan being executed, so a preview whose rows changed after approval is refused instead of written under the old consent. Before each effect the row is written as "attempt" and the ledger is replaced atomically; the result overwrites it immediately afterwards. A resumed batch that meets an "attempt" stops with a zotLedgerError: that row's effect is unknown, and only the caller can reconcile it against the library before retrying.

Examples

Store <- new.env(parent = emptyenv())
Store$version <- 1L
Store$title <- "Before"
Performer <- function(config, method, path, query, body, version) {
  if (method == "GET") {
    return(list(
      status = 200L, headers = list(),
      body = list(version = Store$version, data = list(title = Store$title))
    ))
  }
  Store$title <- body$title
  Store$version <- Store$version + 1L
  list(status = 204L, headers = list(), body = NULL)
}
Config <- structure(
  list(userID = "42", key = "example", apiBase = "https://example.invalid",
       performer = Performer),
  class = "zotConfig"
)
Plan <- data.table::data.table(
  action = "patch", library = "user", itemKey = "K1",
  payload = list(list(title = "After"))
)
Preview <- zotPreview(Plan, describe = "Synthetic offline patch")
Approval <- zotApprove(Preview, notes = "Documentation example")
LedgerPath <- tempfile(fileext = ".json")
Ledger <- zotExecute(Config, Preview, Approval, ledgerPath = LedgerPath)
Ledger$items$K1$status
#> [1] "done"
unlink(LedgerPath)