Skip to main content

Module sql

Module sql 

Source
Expand description

A small, engine-agnostic SQL backend contract for the handler sql binding.

The handler engine exposes a sql capability to guests, but which database serves it is a deployment detail — the same seam as the blob (Storage) and KV (kv::KvStore) backends. SqlBackend is that seam, so the guest interface and the server UX stay identical across single-node and cluster deployments. The one implementation is libsql (SQLite-compatible): an embedded file per site (single-node) or a sqld namespace per site (cluster, read-replicable) — one engine, the split being config, not a backend choice.

Each backend instance is scoped to one site; the engine/transport and the per-site database mapping live behind the trait, so a handler can never address another site’s data (crate::deploy-style isolation).

The contract is deliberately tiny — begin a transaction, query/execute within it, then commit/rollback — and the trait keeps the engine decoupled from libsql’s specifics (and lets tests substitute a fake). The handler engine wraps each invocation in one transaction (commit on success, roll back on trap/error).

Structs§

RlsGuc
Operator-configured SQL session-context GUC names carrying the host-resolved tenant (and the anonymous session) to an app’s Postgres RLS, so its policies (current_setting(name, true)) mirror boatramp’s injected tenancy predicate as a defense-in-depth backstop. Set on a managed / external SQL binding (the rls_session flag + these names, e.g. app.tenant_id). Postgres only — the backstop is the current_setting RLS pattern; a libsql/MySQL backend leaves these unset. The guest can NEVER set them itself (the reserved-write guard blocks the configured names, reject_reserved_session_writes); the host derives the value from the SAME resolution the injected predicate uses (own / target / session) or, for a posture-vetted all write, from the row/statement being written — the DB’s WITH CHECK / USING is the final arbiter of a mismatch.
SqlPingReplica
One replica’s reachability, returned by OperatorSql::ping.
SqlRows
The rows a SqlTransaction::query returned: column names plus row-major cells (each row’s length equals columns.len()).

Enums§

Dialect
The SQL dialect a backend speaks. The orm compiler is ?N-portable for almost everything (the backend rewrites the placeholders), and only consults this for the handful of constructs whose syntax genuinely differs across engines — currently JSON extraction (json_extract(...) on SQLite/MySQL vs #>> on Postgres).
PreviewSqlMode
How a preview deployment’s SQL database relates to the site’s live one (operator policy; see the per-site/server config). The default is the safe, isolated choice.
SqlError
Why a SQL operation failed.
SqlValue
A single SQL value. Boolean is carried as a distinct class (so a guest can express one and a strictly-typed engine could bind a native BOOL); libsql, being SQLite-family, maps it to 0/1.

Traits§

OperatorSql
The operator-facing SQL capability for a managed database: run a migration script or a single query against a compute-backed database boatramp runs, using its sealed managed credential (resolved server-side — the credential never leaves the node). Backs POST /api/sql/{db}/{exec,query} and the boatramp sql CLI. Distinct from SqlBackends (the per-site guest binding): this is a project-scoped operator tool, admin-gated at the API.
SqlBackend
A per-site SQL backend (libsql — a local file or a remote sqld namespace).
SqlBackends
Resolves a site’s named SQL databases to SqlBackends — the seam the server’s handler runtime uses to obtain a per-site database on demand (opening/caching it lazily). The concrete mapping (a libsql file per site, or a sqld namespace per site) lives behind this, so the server stays storage-agnostic.
SqlTransaction
One transaction’s worth of work. Dropping it without commit must leave the database unchanged (the engine rolls back).
TenantDeprovisioner
Tear down a deleted tenant’s managed databases — the delete-time counterpart to the create-time provisioning of a per-tenant managed sql binding. When a project (or site) is deleted through the control plane, boatramp drops that tenant’s databases + login roles + sealed credentials — exactly that tenant’s, nothing else — so a deleted tenant leaves no orphaned data plane behind.

Functions§

reject_reserved_session_writes
Reject a guest SQL statement that would set or reset a boatramp-reserved session key — the boatramp.* GUC (Postgres) or an @boatramp_* user variable (MySQL). Used by the guest sql binding when the backend injects_session_context: with rls_session on, boatramp injects the request’s tenant into those keys for the app’s RLS, so a guest that could overwrite them would spoof its tenant and defeat that RLS.
render_set_local_guc
Render a transaction-local Postgres GUC set (SELECT set_config($1, $2, true)). Both the setting NAME and the VALUE are BOUND parameters (never interpolated), so a dotted operator name like app.tenant_id and any value are injection-safe; the true scopes the setting to the current transaction (auto-cleared at COMMIT/ROLLBACK, like the boatramp.project/site context). The value is bound as TEXT (set_config’s argument type); the operator’s RLS policy casts if its key column isn’t text. Postgres only — callers gate on Dialect::Postgres.