Rindle docs and package mapSkip to main content

Module schema_envelope

Module schema_envelope 

Expand description

The replicated-SQL schema envelope: what SQLite objects the public surface accepts, how a table is introspected into ReplicatedTableSchema, and how a DDL/migration batch is applied under the registered-table guard with an audit trail.

Split out of rindle-replica’s schema.rs, which mixed this with the engine-facing TableSchema/discover pair. Only that pair needs rindle_sqlite::ColumnDef; everything here is rusqlite + rindle’s value types, so it belongs on the write-plane side of the split — the write-master validates and applies schema without running an engine. See follow-ups/replica-writeplane-extraction.md, step 5.

Structs§

DdlActionRecorder
Observe-mode twin of RegisteredTableDdlGuard (private to this module) — the same authorizer, the opposite verdict. The follower MUST apply destructive DDL (its statements are the write-master’s, already committed upstream), so nothing is denied: the destructive operations are RECORDED for the post-apply bounce/purge decisions instead of being refused. One authorizer per connection: install only on paths that do not install the deny guard (protect_registered_tables = falseCluster::exec_ddl_with_marker, in rindle-replica, is the consumer).
DdlActions
The destructive DDL actions observed so far (design 227, third review pass): which main-schema tables were DROPPED or ALTERED, reported by SQLite’s authorizer as each statement was prepared. This is the real parser’s verdict, so comments between tokens, script-valued slots, quoting, and schema-qualified names are all handled by construction — the lexical scanners this replaced were evadable by each in turn.
DdlApplyReport
The full, ordered apply report of one ddl entry. Persisted — as JSON, in the same transaction as the entry’s idempotency marker — so a replay (an in-connection retry after a later step failed, or a crash before cursor advancement) re-drives bounce decisions from durable truth instead of observing nothing. Desired-index effects normally commit in this same transaction; old reports are retained for conservative compatibility repair.
DdlStep
One executed statement of a ddl entry plus the destructive actions the authorizer attributed to it. Order is the EXECUTION order — load-bearing for the desired-index bookkeeping (design 227 fourth review pass): in DROP TABLE t; CREATE TABLE t; CREATE INDEX ix ON t the index belongs to the final table, so its recording must follow the drop’s purge, not race it.

Functions§

ensure_embedded_ddl_batch
Preflight one trusted embedded schema batch before it touches SQLite. exec_ddl historically accepts multiple DDL statements and bounded ANALYZE, but it must not double as an unobserved DML escape hatch. Classification happens for the complete batch before the transaction begins, so a late INSERT cannot leave an earlier CREATE committed.
introspect_replicated_table
Introspect and validate one persistent application table.
introspect_schema_envelope
Introspect every public application table and validate the complete replicated SQL schema envelope. Internal bookkeeping objects remain excluded.
transactionally_apply_schema
Run an already-preflighted schema operation and prove its post-state before commit.
transactionally_apply_schema_checked
transactionally_apply_schema with one caller-owned validation hook after the complete schema envelope has been introspected but before COMMIT. The generic error keeps a host’s typed policy failures intact while every connection/capture/schema failure still enters through ReplicaError.
validate_default_expression
Prove that a column default cannot manufacture a BLOB on a later evaluation.
validate_schema_envelope
Validate the complete replicated SQL schema envelope without retaining its introspection result.
value_type_of
Map a declared SQLite column type to the engine’s [ValueType], following SQLite type-affinity rules (with BOOLEAN/JSON special-cased, and the exact BIGINT/INT8 declarations mapped to the exact-i64 plane — design 226 §4.1). Returns None for BLOB and untyped columns — the engine’s OwnedValue has no Blob variant, so we reject rather than silently null them.