@quereus/store 4.5.0 → 4.7.0

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 (107) hide show
  1. package/README.md +34 -6
  2. package/dist/src/common/encoding.d.ts +4 -3
  3. package/dist/src/common/encoding.d.ts.map +1 -1
  4. package/dist/src/common/encoding.js +17 -13
  5. package/dist/src/common/encoding.js.map +1 -1
  6. package/dist/src/common/events.d.ts +31 -25
  7. package/dist/src/common/events.d.ts.map +1 -1
  8. package/dist/src/common/events.js +38 -39
  9. package/dist/src/common/events.js.map +1 -1
  10. package/dist/src/common/implicit-unique-index.d.ts +80 -0
  11. package/dist/src/common/implicit-unique-index.d.ts.map +1 -0
  12. package/dist/src/common/implicit-unique-index.js +148 -0
  13. package/dist/src/common/implicit-unique-index.js.map +1 -0
  14. package/dist/src/common/index.d.ts +7 -3
  15. package/dist/src/common/index.d.ts.map +1 -1
  16. package/dist/src/common/index.js +5 -2
  17. package/dist/src/common/index.js.map +1 -1
  18. package/dist/src/common/json-key.d.ts +30 -2
  19. package/dist/src/common/json-key.d.ts.map +1 -1
  20. package/dist/src/common/json-key.js +49 -2
  21. package/dist/src/common/json-key.js.map +1 -1
  22. package/dist/src/common/key-builder.d.ts +40 -20
  23. package/dist/src/common/key-builder.d.ts.map +1 -1
  24. package/dist/src/common/key-builder.js +31 -23
  25. package/dist/src/common/key-builder.js.map +1 -1
  26. package/dist/src/common/kv-store.d.ts +10 -0
  27. package/dist/src/common/kv-store.d.ts.map +1 -1
  28. package/dist/src/common/pk-key-resolution.d.ts +348 -0
  29. package/dist/src/common/pk-key-resolution.d.ts.map +1 -0
  30. package/dist/src/common/pk-key-resolution.js +481 -0
  31. package/dist/src/common/pk-key-resolution.js.map +1 -0
  32. package/dist/src/common/store-module-access-plan.d.ts +32 -0
  33. package/dist/src/common/store-module-access-plan.d.ts.map +1 -0
  34. package/dist/src/common/store-module-access-plan.js +428 -0
  35. package/dist/src/common/store-module-access-plan.js.map +1 -0
  36. package/dist/src/common/store-module-alter-column.d.ts +23 -0
  37. package/dist/src/common/store-module-alter-column.d.ts.map +1 -0
  38. package/dist/src/common/store-module-alter-column.js +389 -0
  39. package/dist/src/common/store-module-alter-column.js.map +1 -0
  40. package/dist/src/common/store-module-alter.d.ts +55 -0
  41. package/dist/src/common/store-module-alter.d.ts.map +1 -0
  42. package/dist/src/common/store-module-alter.js +504 -0
  43. package/dist/src/common/store-module-alter.js.map +1 -0
  44. package/dist/src/common/store-module-base.d.ts +268 -0
  45. package/dist/src/common/store-module-base.d.ts.map +1 -0
  46. package/dist/src/common/store-module-base.js +362 -0
  47. package/dist/src/common/store-module-base.js.map +1 -0
  48. package/dist/src/common/store-module-catalog.d.ts +269 -0
  49. package/dist/src/common/store-module-catalog.d.ts.map +1 -0
  50. package/dist/src/common/store-module-catalog.js +462 -0
  51. package/dist/src/common/store-module-catalog.js.map +1 -0
  52. package/dist/src/common/store-module-index-build.d.ts +88 -0
  53. package/dist/src/common/store-module-index-build.d.ts.map +1 -0
  54. package/dist/src/common/store-module-index-build.js +280 -0
  55. package/dist/src/common/store-module-index-build.js.map +1 -0
  56. package/dist/src/common/store-module-index.d.ts +116 -0
  57. package/dist/src/common/store-module-index.d.ts.map +1 -0
  58. package/dist/src/common/store-module-index.js +373 -0
  59. package/dist/src/common/store-module-index.js.map +1 -0
  60. package/dist/src/common/store-module-rename.d.ts +49 -0
  61. package/dist/src/common/store-module-rename.d.ts.map +1 -0
  62. package/dist/src/common/store-module-rename.js +268 -0
  63. package/dist/src/common/store-module-rename.js.map +1 -0
  64. package/dist/src/common/store-module-schema-rewrite.d.ts +57 -0
  65. package/dist/src/common/store-module-schema-rewrite.d.ts.map +1 -0
  66. package/dist/src/common/store-module-schema-rewrite.js +140 -0
  67. package/dist/src/common/store-module-schema-rewrite.js.map +1 -0
  68. package/dist/src/common/store-module-schema-sync.d.ts +232 -0
  69. package/dist/src/common/store-module-schema-sync.d.ts.map +1 -0
  70. package/dist/src/common/store-module-schema-sync.js +529 -0
  71. package/dist/src/common/store-module-schema-sync.js.map +1 -0
  72. package/dist/src/common/store-module.d.ts +43 -909
  73. package/dist/src/common/store-module.d.ts.map +1 -1
  74. package/dist/src/common/store-module.js +184 -3276
  75. package/dist/src/common/store-module.js.map +1 -1
  76. package/dist/src/common/store-table-base.d.ts +539 -0
  77. package/dist/src/common/store-table-base.d.ts.map +1 -0
  78. package/dist/src/common/store-table-base.js +900 -0
  79. package/dist/src/common/store-table-base.js.map +1 -0
  80. package/dist/src/common/store-table-constraints.d.ts +237 -0
  81. package/dist/src/common/store-table-constraints.d.ts.map +1 -0
  82. package/dist/src/common/store-table-constraints.js +624 -0
  83. package/dist/src/common/store-table-constraints.js.map +1 -0
  84. package/dist/src/common/store-table-scan.d.ts +452 -0
  85. package/dist/src/common/store-table-scan.d.ts.map +1 -0
  86. package/dist/src/common/store-table-scan.js +901 -0
  87. package/dist/src/common/store-table-scan.js.map +1 -0
  88. package/dist/src/common/store-table.d.ts +71 -1144
  89. package/dist/src/common/store-table.d.ts.map +1 -1
  90. package/dist/src/common/store-table.js +168 -2385
  91. package/dist/src/common/store-table.js.map +1 -1
  92. package/dist/src/testing/index.d.ts +12 -0
  93. package/dist/src/testing/index.d.ts.map +1 -0
  94. package/dist/src/testing/index.js +12 -0
  95. package/dist/src/testing/index.js.map +1 -0
  96. package/dist/src/testing/kv-assert.d.ts +19 -0
  97. package/dist/src/testing/kv-assert.d.ts.map +1 -0
  98. package/dist/src/testing/kv-assert.js +25 -0
  99. package/dist/src/testing/kv-assert.js.map +1 -0
  100. package/dist/src/testing/kv-conformance.d.ts.map +1 -1
  101. package/dist/src/testing/kv-conformance.js +1 -15
  102. package/dist/src/testing/kv-conformance.js.map +1 -1
  103. package/dist/src/testing/kv-provider-conformance.d.ts +54 -0
  104. package/dist/src/testing/kv-provider-conformance.d.ts.map +1 -0
  105. package/dist/src/testing/kv-provider-conformance.js +183 -0
  106. package/dist/src/testing/kv-provider-conformance.js.map +1 -0
  107. package/package.json +8 -8
@@ -0,0 +1,268 @@
1
+ /**
2
+ * ALTER TABLE ... RENAME TO: the two-phase table rename. The first phase relocates the
3
+ * physical data / index / stats stores and writes the new catalog entry while leaving
4
+ * the old entry in place; the second, called by the engine once every dependent object
5
+ * has been rewritten, drains those dependent catalog writes and only then drops it.
6
+ *
7
+ * Seventh layer of the store-module chain:
8
+ * StoreModuleBase -> StoreModuleCatalog -> StoreModuleSchemaSync -> StoreModuleIndex
9
+ * -> StoreModuleAlterColumn -> StoreModuleAlter -> StoreModuleRename -> StoreModule
10
+ */
11
+ import { QuereusError, StatusCode, renameTableInCheckConstraints, renameTableInColumnExpressions, renameTableInIndexPredicates, } from '@quereus/quereus';
12
+ import { StoreConnection } from './store-connection.js';
13
+ import { buildDataStoreName, buildIndexStoreName, buildStatsKey } from './key-builder.js';
14
+ import { StoreModuleAlter } from './store-module-alter.js';
15
+ import { collectOccupiedStoreNames } from './store-module-base.js';
16
+ import { retargetSelfForeignKeys } from './store-module-schema-rewrite.js';
17
+ export class StoreModuleRename extends StoreModuleAlter {
18
+ /**
19
+ * Rename a store-backed table.
20
+ *
21
+ * Drops every in-memory reference to the old name (so the coordinator, open
22
+ * handles, and cached StoreTable instance don't linger with stale paths),
23
+ * delegates physical storage relocation to the provider, then rewrites the
24
+ * persistent catalog DDL under the new key. After this returns, the next
25
+ * access to `newName` will reconnect via `connect()` and open fresh stores
26
+ * against the moved directories.
27
+ */
28
+ async renameTable(db, schemaName, oldName, newName, ddl) {
29
+ const oldKey = `${schemaName}.${oldName}`.toLowerCase();
30
+ const newKey = `${schemaName}.${newName}`.toLowerCase();
31
+ if (this.tables.has(newKey)) {
32
+ throw new QuereusError(`Store table '${newName}' already exists in schema '${schemaName}'`, StatusCode.ERROR);
33
+ }
34
+ // Capture the current schema BEFORE the guard (and before we drop in-memory
35
+ // references): the guard needs the index list to compute every relocated
36
+ // store name, and the new catalog DDL must reflect the real column set.
37
+ const existing = this.tables.get(oldKey);
38
+ const currentSchema = existing?.getSchema() ?? db.schemaManager.getTable(schemaName, oldName);
39
+ // Authoritative index list (exact store names): the provider relocates
40
+ // exactly these index stores instead of prefix-scanning `{oldName}_idx_`,
41
+ // which would also catch a sibling table named `{oldName}_idx_<x>`.
42
+ // MATERIALIZED, so the hidden `_uc_*` store realizing a plain UNIQUE moves with
43
+ // the table — otherwise the renamed table seeks a fresh EMPTY `_uc_*` and silently
44
+ // accepts a duplicate of a pre-rename row. `currentSchema` itself stays
45
+ // non-materialized: the catalog DDL rewritten below must carry no `_uc_*`.
46
+ const indexNames = this.materializedIndexNames(existing, currentSchema);
47
+ // Reject when ANY physical name the rename introduces — the new data store
48
+ // AND each relocated index store `{schema}.{newName}_idx_{x}` — already
49
+ // names an existing store. E.g. rename some table to `q_idx_archive` while
50
+ // table `q` has index `archive` (both → `{schema}.q_idx_archive`); or rename
51
+ // `t`→`u` while `t` has index `x` and a sibling table is literally named
52
+ // `u_idx_x`, which would relocate `t`'s index onto the sibling's data store.
53
+ // The renamed table's own current stores stay in the occupied set (see
54
+ // collectOccupiedStoreNames): an introduced name can only equal an own store
55
+ // in a footprint-swap rename providers cannot relocate safely. All checks
56
+ // run before the FIRST side effect (the coordinator commit, disconnect, and
57
+ // cache evictions below, then the physical relocation) so a colliding
58
+ // rename is a clean no-op.
59
+ const occupied = collectOccupiedStoreNames(this.tables.values(), db, schemaName, this);
60
+ this.assertStoreNameFree(db, schemaName, buildDataStoreName(schemaName, newName), `data store of table '${schemaName}.${newName}' (rename target)`, occupied);
61
+ for (const indexName of indexNames) {
62
+ this.assertStoreNameFree(db, schemaName, buildIndexStoreName(schemaName, newName, indexName), `index store of index '${indexName}' on table '${schemaName}.${newName}' (rename target)`, occupied);
63
+ }
64
+ // Flush buffered writes before the old store's handle is closed: once the
65
+ // on-disk directory moves, prior buffered ops address stores that no longer
66
+ // exist under those names. See `StoreModuleBase.ddlCommitPendingOps`.
67
+ await this.ddlCommitPendingOps();
68
+ // Hard-dispose the evicted handle: flush any lazy stats it was buffering AND
69
+ // deregister its coordinator stats-callback pair (the renamed instance is
70
+ // gone after this — the next connect()/getOrReconnectTable mints a fresh one
71
+ // that re-registers against the shared coordinator). Dispose failures must
72
+ // not block the physical rename.
73
+ if (existing) {
74
+ try {
75
+ await existing.dispose();
76
+ }
77
+ catch {
78
+ /* ignore — physical rename must proceed */
79
+ }
80
+ }
81
+ this.tables.delete(oldKey);
82
+ this.stores.delete(oldKey);
83
+ // The coordinator is module-wide (flushed above); it is not per-table, so
84
+ // it is not evicted here.
85
+ // Evict the disposed instance's registered engine connections — but ONLY the
86
+ // ones this module created. Unlike drop — where the engine's schema manager
87
+ // calls `removeConnectionsForTable` for us — the generic rename path
88
+ // (`alter-table.ts` renameTableImpl) does NOT, so the store must evict here or
89
+ // a StoreConnection leaks one per rename. Safe for `StoreConnection`s (both the
90
+ // StoreTable-owned DML connection and the StoreBackingHost-owned one): they hold
91
+ // no state of their own, delegating to the module-wide coordinator that the
92
+ // DDL-commit above already flushed, and their owning StoreTable is now disposed.
93
+ //
94
+ // A blanket name-keyed sweep is NOT safe: a wrapping module (the isolation layer)
95
+ // registers its own connection under the same qualified name, and that connection
96
+ // is the only thing that drives its staged overlay to storage at COMMIT. Evicting
97
+ // it silently drops the transaction's writes.
98
+ //
99
+ // NOTE: a rename onto a never-before-used name leaves the wrapper's connection
100
+ // registered under the stale old name (it is not retargeted here). Benign — the
101
+ // commit flush resolves overlays db-wide by their re-keyed names — but a workload
102
+ // that renames one table through many distinct names in a single process
103
+ // accumulates one such connection per name. If that ever matters, retarget the
104
+ // connection's `tableName` across the rename instead of leaving it stale.
105
+ const oldQualified = `${schemaName}.${oldName}`.toLowerCase();
106
+ for (const conn of db.getAllConnections()) {
107
+ if (conn instanceof StoreConnection && conn.tableName.toLowerCase() === oldQualified) {
108
+ db.removeConnection(conn.connectionId);
109
+ }
110
+ }
111
+ // Move physical storage (data directory + index directories).
112
+ //
113
+ // NOTE: the relocation runs BEFORE the catalog rewrite below, and nothing undoes it.
114
+ // Any failure after this point — an IO error, or the DDL-text guard in
115
+ // `encodeCatalogDDL` firing on an unpaired surrogate in a column name or a `default`
116
+ // literal — strands the rows under the NEW physical name while the catalog still
117
+ // names the old table, so the table reads as empty with only the raised error as a
118
+ // clue. Harmless for today's validation cases: the store-name guard in
119
+ // `buildDataStoreName` (called above, before any side effect) refuses a bad target
120
+ // name outright, and a table whose DDL text is unpersistable can never have held
121
+ // rows in the first place. If a new post-relocation failure mode appears, the
122
+ // relocation must be undone here or deferred until after the catalog write.
123
+ if (this.provider.renameTableStores) {
124
+ await this.provider.renameTableStores(schemaName, oldName, newName, indexNames);
125
+ }
126
+ // Rewrite persistent catalog under the new name. Write the new DDL first
127
+ // so a crash mid-rename leaves the table discoverable under at least one
128
+ // name rather than neither.
129
+ if (currentSchema) {
130
+ const renamedSchema = {
131
+ ...currentSchema,
132
+ name: newName,
133
+ // A self-referencing FK is persisted as `references <oldName>(...)`; after
134
+ // `removeTableDDL` below, that names a table no longer in the catalog. Pure
135
+ // copy — no rollback needed, `renamedSchema` is local to the write.
136
+ foreignKeys: retargetSelfForeignKeys(currentSchema.foreignKeys, schemaName, oldName, newName),
137
+ };
138
+ // A partial index's WHERE clause, a CHECK constraint's expression, and a column's
139
+ // DEFAULT / `generated always as` body can each name the OLD table — a
140
+ // table-qualified self-reference (`where t.b > 0`), or, for a column expression,
141
+ // a subquery reading it (`default ((select count(*) from t))`). All three are
142
+ // rendered into the persisted DDL bundle, and `propagateTableRename` runs only
143
+ // after this hook returns, so — exactly as in the `renameColumn` arm of
144
+ // `alterTable` — persisting now would durably write a stale reference that only
145
+ // the later propagation event corrects.
146
+ // Rewrite first, in place (each `Expression` is shared with the catalog
147
+ // `TableSchema` and, for a unique partial index, with its derived UNIQUE
148
+ // constraint), which also makes that later pass a no-op for these fields. A
149
+ // throw anywhere in the `try` — including partway through a walk — reverses the
150
+ // rewrites; reversing is a no-op wherever nothing names `newName`. The physical
151
+ // stores have already moved by this point, so the reverse restores only the AST,
152
+ // not the on-disk layout.
153
+ //
154
+ // NOTE: the reverse assumes no expression legitimately named `newName` before
155
+ // the rename. The rename-target guard above makes that true for a real table,
156
+ // and `compilePredicate` now rejects a foreign `table` qualifier at create time,
157
+ // so a live partial-index predicate can only carry a self-qualifier (`where
158
+ // <thisTable>.b > 0`) or a bare reference — never `where <newName>.b > 0` for a
159
+ // different table. The mis-reversal path is therefore unreachable for a live
160
+ // predicate.
161
+ //
162
+ // NOTE: that argument does NOT extend to the column-expression arm, and the
163
+ // residual is left open deliberately. A DEFAULT naming a table that does not
164
+ // exist is accepted at create time (the reference is only resolved when a row is
165
+ // written), so `create table u (…, v integer default ((select 1 from u2)))`
166
+ // followed by `alter table u rename to u2` has a forward pass that matches
167
+ // nothing and a reverse pass that would clobber that `u2` back to `u`. Reaching
168
+ // it needs `saveTableDDL` to throw, and closing it needs a per-walk changed-set
169
+ // threaded through every arm — not worth it for a failed-persist-only path.
170
+ const rewriteTable = (from, to) => {
171
+ renameTableInIndexPredicates(currentSchema.indexes, from, to, schemaName);
172
+ renameTableInCheckConstraints(currentSchema.checkConstraints, from, to, schemaName);
173
+ renameTableInColumnExpressions(currentSchema.columns, from, to, schemaName);
174
+ };
175
+ try {
176
+ rewriteTable(oldName, newName);
177
+ await this.saveTableDDL(renamedSchema);
178
+ }
179
+ catch (e) {
180
+ rewriteTable(newName, oldName);
181
+ throw e;
182
+ }
183
+ }
184
+ // NOTE: the OLD name's catalog entry is deliberately NOT removed here. Deleting it
185
+ // synchronously would drop `oldName` from the catalog BEFORE the engine's post-hook
186
+ // `propagateTableRename` has rewritten — let alone persisted — the OTHER tables /
187
+ // views / MVs that still name `oldName` (a cross-schema FK, a CHECK expression, a
188
+ // dependent view/MV body). A crash in that gap would strand a durable catalog set
189
+ // naming a vanished table, which reopens as a healthy-looking database whose
190
+ // dependents cannot be written to. The removal is deferred to `finalizeRename`,
191
+ // which the engine calls AFTER propagation has made the dependents durable.
192
+ // Migrate the stats entry (unified __stats__ store, keyed by schema.table).
193
+ // The entry is RE-KEYED, not physically moved with the directory: a unified
194
+ // store keys every table's stats under `schema.table` in one store, so the
195
+ // value must be copied from the old key to the new key and the old key
196
+ // dropped. `dispose()` above already flushed any buffered delta to disk under
197
+ // the old key, so the read here sees the current row-count estimate; deleting
198
+ // without copying (the prior behavior) blinded the planner — a freshly-renamed
199
+ // table reported getEstimatedRowCount() === 0 until stats were re-gathered.
200
+ //
201
+ // NOTE: this re-key reaches the old value only when getStatsStore(newName)
202
+ // returns a store that CONTAINS the old key — true for the shipped providers,
203
+ // which all share one unified __stats__ store, and for any provider whose
204
+ // renameTableStores physically relocates a per-table stats store. A provider
205
+ // that kept per-table stats stores and did NOT relocate them in
206
+ // renameTableStores would orphan the old-keyed value out of reach here (the
207
+ // prior delete-only code lost it just the same — no regression). No shipped
208
+ // provider does this; revisit if one ever keeps per-table, non-relocated stats.
209
+ try {
210
+ const statsStore = await this.provider.getStatsStore(schemaName, newName);
211
+ const oldStatsKey = buildStatsKey(schemaName, oldName);
212
+ const statsValue = await statsStore.get(oldStatsKey);
213
+ if (statsValue) {
214
+ // A table with no stats yet (never flushed) returns undefined here —
215
+ // skip the copy so no spurious zero-count entry lands under the new key.
216
+ await statsStore.put(buildStatsKey(schemaName, newName), statsValue);
217
+ }
218
+ await statsStore.delete(oldStatsKey);
219
+ }
220
+ catch {
221
+ /* stats are advisory — a stats hiccup must never block the rename */
222
+ }
223
+ // Same emit-iff-`ddl` rule as `StoreModuleAlter.alterTable`: `ddl` set means this
224
+ // call IS the RENAME TO statement's action; absent means an engine-internal step
225
+ // that must announce nothing. No in-tree caller omits it today — the shadow-table
226
+ // rebuild's trailing rename is itself a RENAME TO statement and is silenced by
227
+ // `withPublicEventsSuppressed`, not by this gate.
228
+ // `oldObjectName` says what the table renamed FROM — `objectName` names only the
229
+ // new table, and a receiver could not otherwise tell which of its tables moved.
230
+ if (ddl !== undefined) {
231
+ this.eventEmitter?.emitSchemaChange({
232
+ type: 'alter',
233
+ objectType: 'table',
234
+ schemaName,
235
+ objectName: newName,
236
+ oldObjectName: oldName,
237
+ ddl,
238
+ });
239
+ }
240
+ }
241
+ /**
242
+ * Second phase of a two-phase RENAME TABLE (see {@link renameTable}). The engine calls
243
+ * this at the END of ALTER TABLE ... RENAME TO — AFTER its `propagateTableRename` has
244
+ * rewritten every dependent object that named `oldName` and enqueued their corrective
245
+ * catalog writes onto `StoreModuleBase.persistQueue`. `renameTable` deliberately left `oldName`'s
246
+ * catalog entry in place; here we drain those dependent writes to durability and only
247
+ * THEN drop the old entry. During the window both entries coexist on disk, so every
248
+ * dependent resolves against one of them and every intermediate catalog set rehydrates
249
+ * into a working database.
250
+ *
251
+ * The old-entry delete rides `persistQueue` behind the dependents' already-enqueued
252
+ * writes (FIFO), so it can only run after them, and the drain below awaits the whole
253
+ * chain. Errors are swallowed+logged (the `StoreModuleBase.enqueuePersist` contract): a failed
254
+ * delete leaves the old entry present — a visible, droppable orphan, strictly safer
255
+ * than a dependent stranded against a vanished table.
256
+ *
257
+ * NOTE: full cross-table atomicity — bundling this old-entry delete together with every
258
+ * dependent rewrite into one `provider.beginAtomicBatch` commit — would eliminate even
259
+ * the transient two-entry window (and the physical-move orphan `renameTableStores`
260
+ * leaves), but only on atomic providers, and the dependent set is known only to the
261
+ * engine post-propagate. That is the atomic-provider hardening path; out of scope here.
262
+ */
263
+ async finalizeRename(_db, schemaName, oldName, _newName) {
264
+ this.enqueuePersist(() => this.removeTableDDL(schemaName, oldName));
265
+ await this.whenCatalogPersisted();
266
+ }
267
+ }
268
+ //# sourceMappingURL=store-module-rename.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store-module-rename.js","sourceRoot":"","sources":["../../../src/common/store-module-rename.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Pure schema-to-schema rewrites the module applies around DDL: reconciling an
3
+ * implicit-default text primary-key collation to the store's key collation at CREATE
4
+ * time, and retargeting a table's SELF-referencing foreign keys when the table or one
5
+ * of its columns is renamed.
6
+ *
7
+ * Free functions rather than a layer of the store-module chain — each takes a schema
8
+ * and returns a schema, reading no module state.
9
+ */
10
+ import type { ForeignKeyConstraintSchema, TableSchema } from '@quereus/quereus';
11
+ /**
12
+ * Reconcile each text PRIMARY KEY column's declared collation at CREATE time.
13
+ *
14
+ * The store now encodes PRIMARY KEY uniqueness/ordering PHYSICALLY with a
15
+ * PER-COLUMN key collation (`StoreTable.pkKeyCollations`, drawn from each PK
16
+ * column's declared `collation`), so ANY declared PK collation is honored
17
+ * natively — an explicit `collate binary` text PK is keyed under BINARY, a
18
+ * `collate nocase` under NOCASE, etc. The only thing this reconcile still does is
19
+ * supply the store's table-level DEFAULT (`keyCollation` = K = `config.collation`,
20
+ * default NOCASE) to a text PK column that declares NO explicit collation, so an
21
+ * implicit-default text PK keeps the store's historical NOCASE-keyed behavior
22
+ * (rather than the engine's BINARY column default). An EXPLICIT collation — even
23
+ * one diverging from K — is left exactly as declared and re-keyed natively.
24
+ *
25
+ * Collation governs key bytes only for text, so only PK members whose logical type
26
+ * is textual are touched (an `integer primary key` keeps its BINARY; temporal
27
+ * text-physical types carry no collation). Non-PK columns are never touched.
28
+ *
29
+ * This is the CREATE path only — the load path (`connect` / rehydrate) does not
30
+ * reconcile; the persisted DDL is the source of truth on reopen, and the column's
31
+ * (BINARY-elided) `COLLATE` clause round-trips the per-column key collation.
32
+ *
33
+ * Returns the schema unchanged when no implicit text PK column needs the default
34
+ * applied; otherwise a new schema with a rebuilt `columns` array + `columnIndexMap`.
35
+ */
36
+ export declare function reconcilePkCollations(schema: TableSchema, keyCollation: string): TableSchema;
37
+ /**
38
+ * Build a column remap array: newColumnIndex -> oldColumnIndex | -1.
39
+ * Maps each column in the new layout to its position in the old layout.
40
+ * -1 means the column is new (fill with default).
41
+ */
42
+ export declare function buildColumnRemap(oldColumnNames: string[], newColumnNames: string[]): number[];
43
+ /**
44
+ * Retarget a self-referencing foreign key's `referencedTable` across a rename of
45
+ * the owning table. A pure copy — unlike the CHECK / partial-index rewrites this
46
+ * touches a name field, not a shared AST, so the caller needs no rollback.
47
+ * Returns the input array when nothing self-references.
48
+ */
49
+ export declare function retargetSelfForeignKeys(fks: ReadonlyArray<ForeignKeyConstraintSchema> | undefined, schemaName: string, oldName: string, newName: string): ReadonlyArray<ForeignKeyConstraintSchema> | undefined;
50
+ /**
51
+ * Rename a column inside a self-referencing foreign key's `referencedColumnNames`
52
+ * (the names the FK resolves to parent-column indices at enforcement time). Pure
53
+ * copy, as in {@link retargetSelfForeignKeys}. The child-side `columns` are
54
+ * indices, unaffected by a rename.
55
+ */
56
+ export declare function renameColumnInSelfForeignKeys(fks: ReadonlyArray<ForeignKeyConstraintSchema> | undefined, schemaName: string, tableName: string, oldCol: string, newCol: string): ReadonlyArray<ForeignKeyConstraintSchema> | undefined;
57
+ //# sourceMappingURL=store-module-schema-rewrite.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store-module-schema-rewrite.d.ts","sourceRoot":"","sources":["../../../src/common/store-module-schema-rewrite.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,0BAA0B,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAGhF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,qBAAqB,CACpC,MAAM,EAAE,WAAW,EACnB,YAAY,EAAE,MAAM,GAClB,WAAW,CAkCb;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,cAAc,EAAE,MAAM,EAAE,EAAE,cAAc,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAS7F;AAYD;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACtC,GAAG,EAAE,aAAa,CAAC,0BAA0B,CAAC,GAAG,SAAS,EAC1D,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACb,aAAa,CAAC,0BAA0B,CAAC,GAAG,SAAS,CAWvD;AAED;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAC5C,GAAG,EAAE,aAAa,CAAC,0BAA0B,CAAC,GAAG,SAAS,EAC1D,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,GACZ,aAAa,CAAC,0BAA0B,CAAC,GAAG,SAAS,CAiBvD"}
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Pure schema-to-schema rewrites the module applies around DDL: reconciling an
3
+ * implicit-default text primary-key collation to the store's key collation at CREATE
4
+ * time, and retargeting a table's SELF-referencing foreign keys when the table or one
5
+ * of its columns is renamed.
6
+ *
7
+ * Free functions rather than a layer of the store-module chain — each takes a schema
8
+ * and returns a schema, reading no module state.
9
+ */
10
+ import { buildColumnIndexMap } from '@quereus/quereus';
11
+ /**
12
+ * Reconcile each text PRIMARY KEY column's declared collation at CREATE time.
13
+ *
14
+ * The store now encodes PRIMARY KEY uniqueness/ordering PHYSICALLY with a
15
+ * PER-COLUMN key collation (`StoreTable.pkKeyCollations`, drawn from each PK
16
+ * column's declared `collation`), so ANY declared PK collation is honored
17
+ * natively — an explicit `collate binary` text PK is keyed under BINARY, a
18
+ * `collate nocase` under NOCASE, etc. The only thing this reconcile still does is
19
+ * supply the store's table-level DEFAULT (`keyCollation` = K = `config.collation`,
20
+ * default NOCASE) to a text PK column that declares NO explicit collation, so an
21
+ * implicit-default text PK keeps the store's historical NOCASE-keyed behavior
22
+ * (rather than the engine's BINARY column default). An EXPLICIT collation — even
23
+ * one diverging from K — is left exactly as declared and re-keyed natively.
24
+ *
25
+ * Collation governs key bytes only for text, so only PK members whose logical type
26
+ * is textual are touched (an `integer primary key` keeps its BINARY; temporal
27
+ * text-physical types carry no collation). Non-PK columns are never touched.
28
+ *
29
+ * This is the CREATE path only — the load path (`connect` / rehydrate) does not
30
+ * reconcile; the persisted DDL is the source of truth on reopen, and the column's
31
+ * (BINARY-elided) `COLLATE` clause round-trips the per-column key collation.
32
+ *
33
+ * Returns the schema unchanged when no implicit text PK column needs the default
34
+ * applied; otherwise a new schema with a rebuilt `columns` array + `columnIndexMap`.
35
+ */
36
+ export function reconcilePkCollations(schema, keyCollation) {
37
+ const pkIndices = new Set(schema.primaryKeyDefinition.map(def => def.index));
38
+ if (pkIndices.size === 0)
39
+ return schema;
40
+ let changed = false;
41
+ const newColumns = schema.columns.map((col, idx) => {
42
+ if (!pkIndices.has(idx))
43
+ return col;
44
+ // Collation governs key bytes only for text; non-text PK columns (integer,
45
+ // real, blob, …) are encoded type-natively and keep their declared collation.
46
+ // Deliberately `isTextual`, NOT `collationAware`: `any` now keys (and
47
+ // compares) under its declared collation, but an undecorated `any` PK's
48
+ // declared collation is always BINARY — `resolveDefaultCollation` never
49
+ // applies a non-BINARY default to ANY, which declares no supported-collation
50
+ // list — and rewriting it to K here would silently flip that shape's
51
+ // comparison semantics store-side only, diverging from the memory backend
52
+ // for no compatibility gain (the historical K-default covers text PKs, not
53
+ // `any`). Only `text` takes the rewrite.
54
+ if (!col.logicalType.isTextual)
55
+ return col;
56
+ // An EXPLICIT collation is honored as-declared — the per-column key encoding
57
+ // keys the column under it (Option B physical re-key parity with memory).
58
+ if (col.collationExplicit)
59
+ return col;
60
+ const declared = (col.collation || 'BINARY').toUpperCase();
61
+ if (declared === keyCollation)
62
+ return col; // implicit default already == K
63
+ // Implicit default diverges from K (e.g. the engine's BINARY column default
64
+ // under the store's NOCASE K): apply the store's table-level default so an
65
+ // undecorated text PK keeps the store's historical NOCASE-keyed semantics.
66
+ changed = true;
67
+ return { ...col, collation: keyCollation };
68
+ });
69
+ if (!changed)
70
+ return schema;
71
+ const columns = Object.freeze(newColumns);
72
+ return { ...schema, columns, columnIndexMap: buildColumnIndexMap(columns) };
73
+ }
74
+ /**
75
+ * Build a column remap array: newColumnIndex -> oldColumnIndex | -1.
76
+ * Maps each column in the new layout to its position in the old layout.
77
+ * -1 means the column is new (fill with default).
78
+ */
79
+ export function buildColumnRemap(oldColumnNames, newColumnNames) {
80
+ const oldIndexByName = new Map();
81
+ for (let i = 0; i < oldColumnNames.length; i++) {
82
+ oldIndexByName.set(oldColumnNames[i].toLowerCase(), i);
83
+ }
84
+ return newColumnNames.map(name => {
85
+ const oldIdx = oldIndexByName.get(name.toLowerCase());
86
+ return oldIdx !== undefined ? oldIdx : -1;
87
+ });
88
+ }
89
+ /** Whether `fk` points back at the table that owns it. */
90
+ function isSelfForeignKey(fk, schemaLower, tableLower) {
91
+ return (fk.referencedSchema ?? schemaLower).toLowerCase() === schemaLower
92
+ && fk.referencedTable.toLowerCase() === tableLower;
93
+ }
94
+ /**
95
+ * Retarget a self-referencing foreign key's `referencedTable` across a rename of
96
+ * the owning table. A pure copy — unlike the CHECK / partial-index rewrites this
97
+ * touches a name field, not a shared AST, so the caller needs no rollback.
98
+ * Returns the input array when nothing self-references.
99
+ */
100
+ export function retargetSelfForeignKeys(fks, schemaName, oldName, newName) {
101
+ if (!fks)
102
+ return fks;
103
+ const schemaLower = schemaName.toLowerCase();
104
+ const oldLower = oldName.toLowerCase();
105
+ let changed = false;
106
+ const next = fks.map(fk => {
107
+ if (!isSelfForeignKey(fk, schemaLower, oldLower))
108
+ return fk;
109
+ changed = true;
110
+ return { ...fk, referencedTable: newName };
111
+ });
112
+ return changed ? Object.freeze(next) : fks;
113
+ }
114
+ /**
115
+ * Rename a column inside a self-referencing foreign key's `referencedColumnNames`
116
+ * (the names the FK resolves to parent-column indices at enforcement time). Pure
117
+ * copy, as in {@link retargetSelfForeignKeys}. The child-side `columns` are
118
+ * indices, unaffected by a rename.
119
+ */
120
+ export function renameColumnInSelfForeignKeys(fks, schemaName, tableName, oldCol, newCol) {
121
+ if (!fks)
122
+ return fks;
123
+ const schemaLower = schemaName.toLowerCase();
124
+ const tableLower = tableName.toLowerCase();
125
+ const oldColLower = oldCol.toLowerCase();
126
+ let changed = false;
127
+ const next = fks.map(fk => {
128
+ if (!isSelfForeignKey(fk, schemaLower, tableLower))
129
+ return fk;
130
+ if (!fk.referencedColumnNames?.some(n => n.toLowerCase() === oldColLower))
131
+ return fk;
132
+ changed = true;
133
+ return {
134
+ ...fk,
135
+ referencedColumnNames: Object.freeze(fk.referencedColumnNames.map(n => n.toLowerCase() === oldColLower ? newCol : n)),
136
+ };
137
+ });
138
+ return changed ? Object.freeze(next) : fks;
139
+ }
140
+ //# sourceMappingURL=store-module-schema-rewrite.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store-module-schema-rewrite.js","sourceRoot":"","sources":["../../../src/common/store-module-schema-rewrite.ts"],"names":[],"mappings":"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"}