Write and test a DataRaft adapter
An adapter is a specification with S3 methods. Constructors describe work;
preflight checks configuration; execution performs I/O. Import the generics from
dataraft.core and register each method with roxygen @export in your package.
Never put credentials, live connections or executable callbacks in dr_inspect().
library(dataraft.core)
library(dataraft.adapters)
csv_source <- function(path) structure(list(path = path), class = "example_csv")
dr_check_component.example_csv <- function(x, ...) {
stopifnot(is.character(x$path), length(x$path) == 1L, file.exists(x$path))
invisible(x)
}
dr_inspect.example_csv <- function(x, ...) list(type = "CSV", path = x$path)
dr_capabilities.example_csv <- function(x, ...) {
dr_component_capabilities(read = TRUE, write = FALSE, lazy = FALSE,
transactions = FALSE, immutable = FALSE)
}
dr_read_source.example_csv <- function(source, ...) {
dr_check_component(source)
read.csv(source$path)
}
path <- tempfile(fileext = ".csv")
write.csv(data.frame(id = 1:3), path, row.names = FALSE)
source <- csv_source(path)
dr_test_adapter(source, expected = data.frame(id = 1:3))
unlink(path)
For a target implement dr_write_target(target, data, context, ...) and return
a descriptive list identifying the committed output. Honour context$contract:
validate the stored candidate before exposing it, and fail closed if validation
cannot establish success. A target must never claim success on a partial write.
path <- tempfile("adapter-test-")
input <- data.frame(id = 1:3)
result <- dr_test_adapter(dr_target_rds(path), data = input,
context = list(contract = dr_contract(columns = c(id = "integer"))),
read_back = function(output) dr_read_source(dr_source_rds(path, output$version)))
unlink(path, recursive = TRUE)
Use disposable locations. The helper performs real reads and explicitly requested writes. Add failure-injection tests for partial writes, rollback, concurrent writers, invalid contracts, and secrets in exceptions. The helper is a protocol smoke test, not certification of these backend-specific guarantees.
For OpenLineage, a descriptor can include
dataset = list(namespace = "postgres://warehouse:5432",
name = "insurance.public.contracts"). Only provide verified public physical
identities. See the OpenLineage naming conventions.
Adapter conformance
These requirements apply to provider implementations, including built-in ones.
- Constructors and inspection MUST NOT perform I/O or expose credentials.
- Sources MUST return the declared table shape and MUST document snapshot and connection ownership. The generic executor freezes lazy output before its gate.
- Writers MUST consume the supplied, checked candidate. They MUST NOT rerun an upstream query or silently substitute a different dataset.
- A failed write MUST raise an error. A target claiming transactions MUST leave the previously committed state intact, including on a failure during commit.
- Each target MUST document replay behavior: overwrite, append, deduplicate or reject. Idempotence MUST NOT be assumed from a successful smoke test.
- Metadata delivery MUST be retryable independently from data publication and MUST NOT report a failed data publication as successful.
- Capability declarations MUST describe supported behavior. The core consumes
write,transactions,immutableand layer configuration in the relevant execution paths. Undeclared capabilities are never a guarantee.
dr_test_adapter() checks a real roundtrip on disposable resources. Supply
failure_probe plus read_committed to inject a failure after staging and verify
that committed state remains unchanged. A passing probe establishes that tested
failure only; it does not certify every backend failure or concurrent execution.
Backend protocols beyond a single source or target
Core delegates provider-owned release operations through S3 methods. Register
methods against the generics exported by dataraft.core; do not add a reverse
namespace call to core. These protocols are an extension interface, separate from
the seventeen entry topics in the umbrella reference.
| Protocol | Method arguments after dispatch object | Result and ownership |
|---|---|---|
dr_connect_backend |
Provider connection options | Connected backend; caller closes what it opens |
dr_close_backend |
Provider close options | Release only provider-owned resources |
dr_resolve_release |
Asset ID and optional exact release ID | One release-reference row; missing or ambiguous identities must fail |
dr_release_table |
Asset ID and exact release ID | Pinned table reference |
dr_read_release_data |
Asset ID and exact release ID | Retained data for that release |
dr_registry_data |
Registry table name | Registry data frame |
dr_filter_metadata |
Table, asset and run ID filters | Filtered registry rows |
dr_configure_target |
Layer settings | Updated target definition, no writes |
dr_publish_model_result |
Product, checked model result and expected previous release | Atomically published model result or error |
The other protocols cover source landing, source replacement, model reconstruction, lineage and metric diagnostics. Their provider methods must retain the same identity and ownership rules. A method's existence alone does not demonstrate atomicity; use the conformance and failure probes above on its real backend.
Code examples are documented source examples; they are not executed in this website build.