Expand description
cratefield-adapter-postgres: the Database port over sqlx
Postgres for the native runtime (ADR 0004, issue #18). Native only —
it must never enter a wasm build.
§Native-only gate
The sqlx driver does not compile to wasm, so this crate is impossible
to build for a wasm target: src/lib.rs fails compilation with a
clear message on wasm32/wasm64, and the sqlx dependency itself is
target-gated to non-wasm builds in Cargo.toml. The wasm graph of
examples/venture must stay free of this crate (CI asserts it with
cargo tree --target wasm32-unknown-unknown -p venture | grep -c sqlx → 0).
§Statement pipeline
Modules build queries with sea-query; the port’s Statement carries
them rendered with SqliteQueryBuilder (the portable ?-placeholder
wire form D1 and rusqlite execute directly). This adapter rewrites ?
to Postgres $n placeholders — skipping string literals, quoted
identifiers and comments — and binds the sea-query values positionally
(src/convert.rs). The migration runner’s own
bookkeeping statements are rendered by sea-query’s
PostgresQueryBuilder directly.
§The SQLite → Postgres mapping actually used
The portable subset (ADR 0004, architecture section 7) is deliberately the intersection of SQLite and Postgres, so migration files run verbatim on both engines:
| Portable concept | SQLite | Postgres | Notes |
|---|---|---|---|
| ULID ids | TEXT PRIMARY KEY | TEXT PRIMARY KEY | no AUTOINCREMENT/SERIAL anywhere |
| timestamps | ISO-8601 TEXT | ISO-8601 TEXT | computed in Rust, never NOW()/datetime() |
| counters | INTEGER | INTEGER (int4) | referrals, position |
| booleans | INTEGER 0/1 by convention | INTEGER 0/1 by convention | no SQL BOOLEAN columns; SeaValue::Bool binds as SMALLINT 0/1, and rows read back through Row::get::<bool> accept both |
| upserts | INSERT … ON CONFLICT … | identical syntax | rendered by sea-query for both dialects |
| read-back writes | INSERT … RETURNING … | identical syntax | rendered by sea-query for both dialects |
batch runs all statements in one transaction (atomic, ADR 0004).
use cratefield_adapter_postgres::Postgres;
let db = Postgres::connect("postgres://user:pass@host:5432/venture").await?;
// db.apply_harness_migrations(&harness).await?; // library entry point
// … or through Arc<dyn Database> as with any adapterModules§
- testing
- Shared Postgres test infrastructure: per-test throwaway databases on
the server named by
FZ_TEST_POSTGRES_URL, so tests never see each other’s tables (issue #18).
Structs§
- Postgres
- An open Postgres connection pool (
sqlx0.8,runtime-tokio,tls-rustls).
Functions§
- select_
set - Selects the migration set a module contributes to a Postgres
deployment: its
postgresset when it ships one, else itssqliteset — but only when every file passes the portable-SQL lint (cratefield_core::lint_portable_sql, the same predicatefz doctorenforces, so the two can never drift).