qubu 0.6.2 → 0.6.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/dist/mysql.d.mts +1 -1
  2. package/dist/postgres.d.mts +1 -1
  3. package/docs/dialects-and-execution.md +54 -25
  4. package/docs/getting-started.md +9 -9
  5. package/docs/guides/better-auth.md +16 -5
  6. package/docs/guides/compose-queries.md +21 -9
  7. package/docs/guides/drizzle.md +8 -3
  8. package/docs/guides/extensions/dialects.md +1 -1
  9. package/docs/guides/extensions/overview.md +1 -1
  10. package/docs/guides/extensions/sources-and-clauses.md +7 -3
  11. package/docs/guides/extensions/typed-expressions.md +25 -13
  12. package/docs/guides/extensions/unsafe-syntax.md +10 -6
  13. package/docs/guides/json.md +52 -27
  14. package/docs/guides/mutations.md +15 -6
  15. package/docs/guides/select/conditions.md +18 -11
  16. package/docs/guides/select/grouping-and-windows.md +5 -2
  17. package/docs/guides/select/ordering-and-pagination.md +5 -3
  18. package/docs/guides/select/overview.md +6 -3
  19. package/docs/guides/sql-templates.md +11 -5
  20. package/docs/guides/valtio-sync.md +11 -5
  21. package/docs/guides/vite-plugin.md +2 -2
  22. package/docs/index.md +24 -17
  23. package/docs/migrations/adapters.md +47 -19
  24. package/docs/migrations/artifacts-and-policy.md +49 -20
  25. package/docs/migrations/index.md +15 -8
  26. package/docs/migrations/lotta-adoption.md +16 -5
  27. package/docs/migrations/operations.md +29 -15
  28. package/docs/migrations/recovery.md +34 -17
  29. package/docs/query-model/fragments.md +13 -5
  30. package/docs/query-model/result-shapes.md +2 -2
  31. package/docs/query-model/source-scope.md +5 -3
  32. package/docs/reference/introspection-support.md +26 -19
  33. package/docs/reference/mysql-snapshot.md +19 -4
  34. package/docs/reference/postgres-snapshot.md +17 -4
  35. package/docs/reference/sqlite-snapshot.md +19 -2
  36. package/docs/reference/supported-surface.md +221 -85
  37. package/docs/schema/catalog-model.md +24 -7
  38. package/docs/schema/code-generation.md +40 -21
  39. package/docs/schema/columns-and-writes.md +21 -11
  40. package/docs/schema/constraints-and-indexes.md +12 -5
  41. package/docs/schema/ddl-emission.md +16 -5
  42. package/docs/schema/diff.md +12 -4
  43. package/docs/schema/introspection.md +47 -21
  44. package/docs/schema/migration-plans.md +18 -10
  45. package/docs/schema/snapshots.md +57 -29
  46. package/docs/schema/storage-and-schema-sql.md +10 -4
  47. package/docs/schema/tables-and-names.md +1 -1
  48. package/docs/sql-semantic-types.md +11 -8
  49. package/docs/troubleshooting.md +14 -6
  50. package/package.json +1 -1
@@ -1,6 +1,6 @@
1
1
  # Command line operations
2
2
 
3
- > Configure, inspect, baseline, and apply a complete migration chain with stable non-interactive behavior.
3
+ > Configure the CLI, inspect migration status, and apply a migration chain.
4
4
 
5
5
  Install the CLI, migration library, and one verified migration adapter. For a
6
6
  libSQL application:
@@ -9,11 +9,16 @@ libSQL application:
9
9
  pnpm add @qubu/cli @qubu/migrate @qubu/adapter-libsql @libsql/client
10
10
  ```
11
11
 
12
- The `qubu` binary is implemented with `@alloc/cmd-ts`. It loads
13
- `qubu.config.js` by default; `--config <path>` selects another application-owned
14
- module. Every command accepts `--format human|json` (default `human`) and
15
- `--non-interactive`. Commands do not prompt today; `--non-interactive` records
16
- the deployment contract and missing explicit input still fails.
12
+ The `qubu` command loads `qubu.config.js` by default. Use `--config <path>` to
13
+ select another configuration module.
14
+
15
+ Every command accepts:
16
+
17
+ - `--format human|json`, defaulting to `human`.
18
+ - `--non-interactive`, to state that the command must run without prompts.
19
+
20
+ Commands currently never prompt. Missing required input fails even without
21
+ `--non-interactive`.
17
22
 
18
23
  ## Configuration
19
24
 
@@ -72,9 +77,13 @@ working directory.
72
77
  | `qubu migrate reconcile <attempt-id> --outcome applied\|rolled_back --reason <text>` | Runs application-owned verification, then records the explicit outcome | Requires `verifyReconciliation` in config; no automatic inference |
73
78
  | `qubu schema bootstrap [--approve <operation-id=reason>...] [--dry-run]` | Plans an empty SQLite or PostgreSQL snapshot through diff/plan/program; executes through the normal executor unless dry-run | Rejects other dialects; unsafe or incomplete facts still require exact approvals or custom programs |
74
79
 
75
- JSON output is stable, newline-terminated, recursively key-sorted, and redacts
76
- credential-like keys and credentials or secrets embedded in URLs. Human output
77
- is deliberately terse. Signals propagate through adapters; an abort exits 130.
80
+ ## Output and exit codes
81
+
82
+ JSON output has stable, recursively sorted keys and ends with a newline. It
83
+ redacts credential-like keys and secrets embedded in URLs. Human output is
84
+ brief.
85
+
86
+ Signals pass through adapters. An abort exits with code 130.
78
87
 
79
88
  | Exit | Meaning |
80
89
  | ---: | ----------------------------------------------------------------------------- |
@@ -94,14 +103,19 @@ snapshot. Logical IDs help reporting but do not prove equality. Objects not
94
103
  owned by the managed snapshot are returned separately as `unmanagedObjects`;
95
104
  Qubu journal objects are excluded by migration snapshot readers.
96
105
 
106
+ ### Bootstrap a fresh database
107
+
97
108
  `schema bootstrap` is for a fresh SQLite database or a fresh PostgreSQL schema.
98
109
  It produces the same reviewed plan, versioned program, sealed artifact, and
99
- executor path as a migration. A complete PostgreSQL snapshot retains standalone
100
- enums as authoritative objects; bootstrap creates each enum before a table that
101
- uses it as a native column type. SQLite inline constraints are compiled into
102
- table creation, while table rebuilds are explicit phases with copy/postcondition
103
- checks. Session settings such as SQLite PRAGMAs remain in the application or
104
- adapter setup.
110
+ execution path as a migration.
111
+
112
+ Database-specific behavior:
113
+
114
+ - PostgreSQL bootstrap creates standalone enums before tables that use them
115
+ as native column types. The complete target snapshot defines those enums.
116
+ - SQLite inline constraints are included in table creation. Table rebuilds
117
+ use explicit phases with data-copy and postcondition checks.
118
+ - Session settings, such as SQLite PRAGMAs, stay in application or adapter setup.
105
119
 
106
120
  Use the reviewed complete snapshot directly as the PostgreSQL target:
107
121
 
@@ -1,12 +1,12 @@
1
1
  # Recovery and reconciliation
2
2
 
3
- > Stop after an ambiguous attempt, prove the live outcome, and repair journal lineage without replaying SQL.
3
+ > Verify what happened after an uncertain migration and record the outcome before continuing.
4
4
 
5
- The journal has one versioned metadata row with an atomic head, immutable
6
- applied artifact records, mutable attempts, phase/statement checkpoints, and
7
- append-only reconciliation records. Adapter implementations store it in the
8
- same database and reserve `__qubu_migration_`-prefixed objects from managed
9
- schema inspection.
5
+ The journal records migration progress in the same database as the schema.
6
+ Its head is the digest of the last applied artifact.
7
+
8
+ Adapters reserve objects prefixed with `__qubu_migration_` and exclude them
9
+ from managed schema inspection. The journal contains these records:
10
10
 
11
11
  | Record | Fields and invariant |
12
12
  | ---------------- | -------------------------------------------------------------------------------------------------------------- |
@@ -45,13 +45,23 @@ head, or a non-prefix repository fail before any statement executes.
45
45
 
46
46
  ## Execution and concurrency guarantees
47
47
 
48
- For each invocation, the executor verifies the entire repository, opens one
49
- migration session, checks capabilities, acquires the migrator lease, validates the
50
- journal and repository prefix, checks the live before-snapshot digest, then
51
- applies each pending artifact. Within an artifact it creates an attempt,
52
- executes ordered phases with preconditions and postconditions, writes durable
53
- checkpoints, appends immutable history, and compare-and-swaps the head.
54
- Resources are released in reverse order: DDL lock, migrator lease, then session.
48
+ Before applying migrations, the executor:
49
+
50
+ 1. Verifies the entire artifact repository.
51
+ 2. Opens one migration session and checks its capabilities.
52
+ 3. Acquires the migrator lease.
53
+ 4. Verifies that the journal matches the start of the repository chain.
54
+ 5. Checks the live before-snapshot digest.
55
+
56
+ For each pending artifact, it:
57
+
58
+ 1. Creates an attempt record.
59
+ 2. Runs phases in order, checking their preconditions and postconditions.
60
+ 3. Writes durable checkpoints.
61
+ 4. Appends the applied history and updates the head only if it still matches
62
+ the expected parent.
63
+
64
+ Cleanup releases the DDL lock, then the migrator lease, then the session.
55
65
 
56
66
  An `atomic-batch` profile instead applies one single-phase artifact in one
57
67
  database transaction, including its checks and terminal journal writes. It
@@ -76,10 +86,17 @@ must be resolved by the renderer or explicit custom program before sealing.
76
86
  Transactions are phase-scoped. Do not infer that an earlier committed phase
77
87
  will roll back because a later phase fails.
78
88
 
79
- Errors use stable codes: `validation`, `policy`, `drift`, `concurrency`,
80
- `capability`, `definite-rollback`, `uncertain-outcome`, `recovery-required`,
81
- `aborted`, and `adapter`. Context may include artifact, attempt, phase, and
82
- statement identifiers. Persisted failures omit SQL parameters and credentials.
89
+ ### Errors and retries
90
+
91
+ Errors use stable codes:
92
+
93
+ - `validation`, `policy`, and `capability`.
94
+ - `drift` and `concurrency`.
95
+ - `definite-rollback`, `uncertain-outcome`, and `recovery-required`.
96
+ - `aborted` and `adapter`.
97
+
98
+ Error context may identify the artifact, attempt, phase, and statement.
99
+ Persisted failures omit SQL parameters and credentials.
83
100
 
84
101
  Do not automatically retry after any statement may have taken effect. Only an
85
102
  error explicitly marked `retry: "safe"`—normally validation or a failure proven
@@ -1,6 +1,6 @@
1
1
  # Fragments and metadata
2
2
 
3
- > Build custom SQL from values while preserving the source, result, grouping, and capability facts that later composition checks.
3
+ > Understand how SQL fragments carry the type information Qubu needs to check a query.
4
4
 
5
5
  ## A fragment has a renderer and metadata
6
6
 
@@ -39,9 +39,12 @@ Composition helpers keep the facts that their children already carry:
39
39
  | `groupBy()` | Record grouping expressions and the column dependencies they make available. |
40
40
  | `leftJoin()` | Add `NullableSourceMeta` for the joined source. |
41
41
 
42
- The type-level contract stays small. `OutputOf<T>` describes a result,
43
- `SqlTypeOf<T>` its SQL domain, `RequiresOf<T>` its required sources, and
44
- `NullabilityOf<T>` the sources that can make it null after an outer join.
42
+ Use these types to read a fragment’s metadata:
43
+
44
+ - `OutputOf<T>`: the result type.
45
+ - `SqlTypeOf<T>`: the SQL domain.
46
+ - `RequiresOf<T>`: the sources it requires.
47
+ - `NullabilityOf<T>`: the sources that can make it null after an outer join.
45
48
 
46
49
  Qubu does not infer every SQL rule. Grouping checks use declared dependencies,
47
50
  and functional dependencies from database keys are handled where the source
@@ -73,7 +76,10 @@ render(query)
73
76
  // parameters: [7, '%Ada%']
74
77
  ```
75
78
 
76
- The optional domain metadata stays in a sidecar aligned with `parameters`:
79
+ ### Give parameters a SQL domain
80
+
81
+ Optional SQL domains are stored in `parameterSqlTypes`. Each entry matches
82
+ the parameter at the same position:
77
83
 
78
84
  ```ts
79
85
  import { typedValue } from "qubu/core"
@@ -96,6 +102,8 @@ The parameter array follows the placeholders in the rendered text. `select()`
96
102
  normalizes independent clause values, but keep the final call in SQL order in
97
103
  new code so source scope and repair hints are visible at a glance.
98
104
 
105
+ ### Compose SQL templates
106
+
99
107
  The public [`sql` template tag](../guides/sql-templates.md) uses the same
100
108
  renderer. Ordinary substitutions call `context.parameter()`, while expression,
101
109
  query, and fragment substitutions call back into the active render context.
@@ -1,6 +1,6 @@
1
1
  # Result shapes and cardinality
2
2
 
3
- > Choose a projection, understand how joins change its nullability, and check when a nested query can return no row.
3
+ > Choose result fields and understand when a join or subquery can make them null.
4
4
 
5
5
  ## Name the selected row
6
6
 
@@ -27,7 +27,7 @@ type Row = typeof query.row
27
27
  ```
28
28
 
29
29
  The projection key also names the SQL output column. Use explicit fields for a
30
- shaped result. Reserve `all(source)` for a whole-source result contract. It
30
+ shaped result. Use `all(source)` when you want every source column. It
31
31
  expands to named columns, so the SQL columns and inferred row keys stay aligned:
32
32
 
33
33
  ```ts
@@ -1,6 +1,6 @@
1
1
  # Source scope
2
2
 
3
- > Keep each column tied to the table, alias, CTE, or derived source that provides it; use this page to fix scope errors and intentional correlations.
3
+ > Learn why a column must belong to a source in the query, and how to refer to an enclosing query.
4
4
 
5
5
  A column carries the identity of the source that provides it. Qubu checks that
6
6
  identity when you assemble a query. The source must appear in `FROM` or a join
@@ -118,7 +118,9 @@ const query = select({ value: entries.value }, from(entries), where(eq(entries.k
118
118
  ```
119
119
 
120
120
  `identity` is the type-level source key. `reference` is the SQL qualifier used
121
- by the generated columns. The nullable `value` column stays nullable, and a
121
+ by the generated columns.
122
+
123
+ The nullable `value` column stays nullable, and a
122
124
  `leftJoin()` adds outer-join nullability to every selected column from
123
125
  `entries`.
124
126
 
@@ -128,7 +130,7 @@ keeps those values in placeholder order.
128
130
  ## Correlate an inner query
129
131
 
130
132
  Use `correlate()` when an inner query intentionally reads a source from its
131
- enclosing query. The provision changes type checking but emits no SQL:
133
+ enclosing query. `correlate()` changes type checking but emits no SQL:
132
134
 
133
135
  ```ts
134
136
  import { correlate, crossJoin, eq, from, integer, lateral, select, table, where } from "qubu"
@@ -1,6 +1,6 @@
1
1
  # Introspection support
2
2
 
3
- > Look up which catalog facts each adapter reads, which versions it accepts, and which database features remain outside Snapshot v1.
3
+ > Check supported database versions, catalog objects, and snapshot-mapping limits.
4
4
 
5
5
  The optional `qubu/introspection` entrypoint reads one selected database
6
6
  namespace through a user-owned `CatalogConnection`. It returns normalized
@@ -67,19 +67,22 @@ table-valued PRAGMAs `database_list`, `table_list`, `table_xinfo`,
67
67
  receives bound namespace or object parameters through the caller's
68
68
  `CatalogConnection`. The reader does not interpolate a database name into SQL.
69
69
 
70
- SQLite views and triggers become typed complete catalog objects when their
71
- CREATE SQL has a recoverable definition and target. Their SQL remains tagged
72
- opaque data with a `sqlite` dialect and a catalog reference. Generated column
73
- expressions, declared storage types, SQLite affinity, rowid aliases, and
70
+ SQLite views and triggers become typed catalog objects when Qubu can recover
71
+ their definition and target from CREATE SQL. Their SQL remains opaque data,
72
+ tagged with the `sqlite` dialect and a catalog reference.
73
+
74
+ Generated column expressions, declared storage types, SQLite affinity, rowid aliases, and
74
75
  `AUTOINCREMENT` are kept as column or identity dialect extensions. User indexes
75
- retain ordered column or expression terms and partial predicates. Inline UNIQUE
76
- constraints are recovered from their internal indexes with deterministic Qubu
76
+ retain ordered column or expression terms and partial predicates.
77
+
78
+ Inline UNIQUE constraints are recovered from their internal indexes with deterministic Qubu
77
79
  names, so SQLite's `sqlite_autoindex_*` names do not become persisted logical
78
80
  IDs.
79
81
 
80
82
  SQLite virtual tables and shadow tables remain typed deferred objects with an
81
- `unmodeled-object` diagnostic. A selected attached database can expose table
82
- PRAGMA rows, but its schema SQL is outside the fixed `main` and `temp`
83
+ `unmodeled-object` diagnostic.
84
+
85
+ A selected attached database can expose table PRAGMA rows, but its schema SQL is outside the fixed `main` and `temp`
83
86
  statements. Qubu marks that result as limited and keeps other attached
84
87
  databases as opaque boundary records. It never combines attached databases into
85
88
  the selected namespace. SQLite does not provide the PostgreSQL object families
@@ -101,13 +104,20 @@ strict Snapshot v1 result through a separate controlled printer.
101
104
 
102
105
  The MySQL reader accepts MySQL 8.0.16 and later within the MySQL 8 series. It
103
106
  rejects MariaDB and older MySQL versions instead of applying MySQL catalog
104
- rules to a different product or server version. It reads `INFORMATION_SCHEMA`
105
- rows for one selected database and retains database-provided SQL as tagged,
107
+ rules to a different product or server version.
108
+
109
+ It reads `INFORMATION_SCHEMA` rows for one selected database and retains database-provided SQL as tagged,
106
110
  unevaluated MySQL data.
107
111
 
108
- MySQL has typed complete records for views, routines and their parameters,
109
- triggers, partitions, collations used by selected tables or columns, and
110
- comments. View definitions come from `INFORMATION_SCHEMA.VIEWS`; each view's
112
+ MySQL has typed records for:
113
+
114
+ - Views.
115
+ - Routines and their parameters.
116
+ - Triggers and partitions.
117
+ - Collations used by selected tables or columns.
118
+ - Comments.
119
+
120
+ View definitions come from `INFORMATION_SCHEMA.VIEWS`; each view's
111
121
  columns are joined back to the matching `COLUMNS` rows by physical table name,
112
122
  so the complete Snapshot v1 cross-reference points at the view's own column
113
123
  IDs. Missing view definitions or unresolved trigger, partition, or other
@@ -154,12 +164,9 @@ canonical content, not an identity or rename marker.
154
164
 
155
165
  ## Deferred and limited features
156
166
 
157
- The following remain catalog facts or diagnostics rather than fabricated
158
- Snapshot v1 objects:
167
+ Supported object families become typed Snapshot v1 records, as described in
168
+ the database sections above. Limits still apply to individual features:
159
169
 
160
- - views and materialized views;
161
- - sequences, enums, domains, routines, triggers, policies, extensions,
162
- collations, comments, and partition metadata;
163
170
  - PostgreSQL identity sequence options that have no typed field;
164
171
  - SQLite virtual/shadow tables, attached namespaces, and unrecoverable
165
172
  generated or expression definitions;
@@ -1,8 +1,6 @@
1
1
  # MySQL snapshot support
2
2
 
3
- > Use this matrix before selecting `mysqlSnapshotAdapter`; it records the
4
- > MySQL facts Qubu v1 can encode and the combinations that need a later server
5
- > version or engine policy.
3
+ > Check which MySQL schema features the Snapshot v1 adapter can save.
6
4
 
7
5
  Import the adapter from the MySQL snapshot subpath:
8
6
 
@@ -21,7 +19,7 @@ to this adapter.
21
19
 
22
20
  | Schema fact | MySQL v1 behavior |
23
21
  | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
24
- | Portable storage | Maps `integer` to `INT`, `numeric` to `DECIMAL`, `text` to `TEXT`, `boolean` to `BOOLEAN`, `date` to `DATE`, `timestamp` to `DATETIME`, `uuid` to `CHAR(36)`, `json` to `JSON`, `bigint` to `BIGINT`, and `binary` to `VARBINARY`. |
22
+ | Portable storage | Uses the mappings below. |
25
23
  | Native storage | Preserves a non-empty declaration tagged `mysql` exactly. Native declarations owned by another dialect fail. |
26
24
  | Literals | Encodes `NULL`, finite numbers, strings, booleans, and `bigint` without query parameters. Strings use SQL quote doubling. |
27
25
  | Defaults | Canonical literals, branded deterministic expressions, and explicit external behavior are retained. Default expressions cannot reference columns or parameters. |
@@ -34,6 +32,23 @@ to this adapter.
34
32
  | Indexes | Ordered terms, expressions, uniqueness, and candidate-key evidence are retained. Partial predicates, included columns, and `NULLS FIRST/LAST` are diagnosed. Algorithm, locking, access method, parser, and key-block options live under `dialect`. |
35
33
  | Names | Table, column, constraint, and index names are checked against MySQL's 64-character identifier limit. Table names are database-scoped; index names are table-scoped. |
36
34
 
35
+ ## Portable storage types
36
+
37
+ | Qubu storage | Database declaration |
38
+ | ------------ | -------------------- |
39
+ | `integer` | `INT` |
40
+ | `numeric` | `DECIMAL` |
41
+ | `text` | `TEXT` |
42
+ | `boolean` | `BOOLEAN` |
43
+ | `date` | `DATE` |
44
+ | `timestamp` | `DATETIME` |
45
+ | `uuid` | `CHAR(36)` |
46
+ | `json` | `JSON` |
47
+ | `bigint` | `BIGINT` |
48
+ | `binary` | `VARBINARY` |
49
+
50
+ ## Diagnostics
51
+
37
52
  Capability checks run before common traversal. Use the non-throwing form when
38
53
  a schema may include a MySQL engine or version-specific feature:
39
54
 
@@ -1,8 +1,6 @@
1
1
  # PostgreSQL snapshot support
2
2
 
3
- > Use this matrix before selecting `postgresSnapshotAdapter`; it records the
4
- > PostgreSQL facts Qubu v1 can encode and the cases that need a later server
5
- > version policy.
3
+ > Check which PostgreSQL schema features the Snapshot v1 adapter can save.
6
4
 
7
5
  Import the adapter from the PostgreSQL snapshot subpath:
8
6
 
@@ -24,7 +22,7 @@ snapshot metadata and `unsafeSchemaSql()` use `postgresql` consistently.
24
22
 
25
23
  | Schema fact | PostgreSQL v1 behavior |
26
24
  | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
27
- | Portable storage | Emits PostgreSQL declarations: `INTEGER`, `NUMERIC`, `TEXT`, `BOOLEAN`, `DATE`, `TIMESTAMP`, `UUID`, `JSONB`, `BIGINT`, and `BYTEA`. |
25
+ | Portable storage | Uses the mappings below. |
28
26
  | Native storage | Preserves a non-empty declaration tagged `postgresql` exactly. Other dialect tags fail. |
29
27
  | Literals | Encodes finite numbers, strings, booleans, `bigint`, and `NULL` without query parameters. |
30
28
  | Defaults | Canonical literals, branded deterministic expressions, and explicit external behavior are retained. Column references in defaults fail. |
@@ -41,6 +39,21 @@ deterministic data for the `qubu/snapshot` decoder. The package-wide
41
39
  [ownership map](supported-surface.md#ownership-boundary) shows the separate
42
40
  schema and application boundaries.
43
41
 
42
+ ## Portable storage types
43
+
44
+ | Qubu storage | Database declaration |
45
+ | ------------ | -------------------- |
46
+ | `integer` | `INTEGER` |
47
+ | `numeric` | `NUMERIC` |
48
+ | `text` | `TEXT` |
49
+ | `boolean` | `BOOLEAN` |
50
+ | `date` | `DATE` |
51
+ | `timestamp` | `TIMESTAMP` |
52
+ | `uuid` | `UUID` |
53
+ | `json` | `JSONB` |
54
+ | `bigint` | `BIGINT` |
55
+ | `binary` | `BYTEA` |
56
+
44
57
  ## Diagnostics
45
58
 
46
59
  Use the non-throwing form when a schema may contain a server-specific feature:
@@ -1,6 +1,6 @@
1
1
  # SQLite snapshot support
2
2
 
3
- > Use this matrix to decide which SQLite schema facts Qubu v1 can serialize and which combinations must be diagnosed before a snapshot is written.
3
+ > Check which SQLite schema features the Snapshot v1 adapter can save.
4
4
 
5
5
  Import the adapter from the SQLite snapshot subpath:
6
6
 
@@ -20,7 +20,7 @@ to distinguish it from the query renderer. A dialect-tagged
20
20
 
21
21
  | Schema fact | SQLite v1 behavior |
22
22
  | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
23
- | Portable storage | Maps `integer`, `boolean`, and `bigint` to `INTEGER`; `text`, `date`, `timestamp`, `uuid`, and `json` to `TEXT`; `numeric` to `NUMERIC`; and `binary` to `BLOB`. The snapshot also records SQLite's derived affinity. |
23
+ | Portable storage | Uses the mappings below. SQLite affinity is also recorded. |
24
24
  | Native storage | Preserves a non-empty declaration tagged `sqlite` exactly and records its affinity using SQLite's ordered declared-type rules. Other dialect tags fail. |
25
25
  | Literals | Encodes `NULL`, finite numbers, strings, `bigint`, and booleans as parameter-free SQL. Boolean literals use `1` and `0`; strings retain SQL escaping. |
26
26
  | Defaults | Canonical literals, branded deterministic expressions, and explicit external behavior are retained. Default expressions cannot reference columns or parameters. |
@@ -32,6 +32,23 @@ to distinguish it from the query renderer. A dialect-tagged
32
32
  | Indexes | Ordered terms, expressions, uniqueness, predicates for partial indexes, and candidate-key evidence are retained. Included columns are diagnosed as unsupported. The typed SQLite index extension is encoded under `dialect`. |
33
33
  | Namespaces | An optional unqualified namespace is retained; Qubu does not attach or inspect SQLite databases. |
34
34
 
35
+ ## Portable storage types
36
+
37
+ | Qubu storage | Database declaration |
38
+ | ------------ | -------------------- |
39
+ | `integer` | `INTEGER` |
40
+ | `numeric` | `NUMERIC` |
41
+ | `text` | `TEXT` |
42
+ | `boolean` | `INTEGER` |
43
+ | `date` | `TEXT` |
44
+ | `timestamp` | `TEXT` |
45
+ | `uuid` | `TEXT` |
46
+ | `json` | `TEXT` |
47
+ | `bigint` | `INTEGER` |
48
+ | `binary` | `BLOB` |
49
+
50
+ ## Diagnostics
51
+
35
52
  Capability checks run before common traversal. Use the non-throwing form when a
36
53
  schema may include a feature that depends on a SQLite version or table shape:
37
54