@orkestrel/database 0.0.12 → 0.0.14
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.
- package/README.md +12 -8
- package/dist/src/browser/index.d.ts +95 -70
- package/dist/src/browser/index.js +115 -86
- package/dist/src/browser/index.js.map +1 -1
- package/dist/src/core/index.cjs +595 -410
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +712 -313
- package/dist/src/core/index.d.ts +712 -313
- package/dist/src/core/index.js +588 -409
- package/dist/src/core/index.js.map +1 -1
- package/dist/src/server/index.cjs +236 -332
- package/dist/src/server/index.cjs.map +1 -1
- package/dist/src/server/index.d.cts +213 -223
- package/dist/src/server/index.d.ts +213 -223
- package/dist/src/server/index.js +230 -324
- package/dist/src/server/index.js.map +1 -1
- package/package.json +22 -18
|
@@ -1,29 +1,24 @@
|
|
|
1
|
-
import { AggregateOperation } from '@orkestrel/database';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
import { TableSchema } from '@orkestrel/database';
|
|
23
|
-
import { TableSchema as TableSchema_2 } from '@orkestrel/database';
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Compile an {@link AggregateOperation} over a {@link FieldPath}.
|
|
1
|
+
import type { AggregateOperation } from '@orkestrel/database';
|
|
2
|
+
import type { ColumnSchema } from '@orkestrel/database';
|
|
3
|
+
import type { ColumnStorage } from '@orkestrel/database';
|
|
4
|
+
import type { Condition } from '@orkestrel/database';
|
|
5
|
+
import type { DriverInterface } from '@orkestrel/database';
|
|
6
|
+
import type { DriverMetadata } from '@orkestrel/database';
|
|
7
|
+
import type { FieldPath } from '@orkestrel/contract';
|
|
8
|
+
import type { Key } from '@orkestrel/database';
|
|
9
|
+
import type { MigrationInput } from '@orkestrel/database';
|
|
10
|
+
import type { MigrationStep } from '@orkestrel/database';
|
|
11
|
+
import type { OperationOptions } from '@orkestrel/database';
|
|
12
|
+
import type { Order } from '@orkestrel/database';
|
|
13
|
+
import type { QueryInput } from '@orkestrel/database';
|
|
14
|
+
import type { Row } from '@orkestrel/database';
|
|
15
|
+
import type { SQLiteRow } from '@orkestrel/sqlite';
|
|
16
|
+
import type { SQLiteValue } from '@orkestrel/sqlite';
|
|
17
|
+
import type { StorageInterface } from '@orkestrel/database';
|
|
18
|
+
import type { TableSchema } from '@orkestrel/database';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Compiles an {@link AggregateOperation} over a {@link FieldPath}.
|
|
27
22
|
*
|
|
28
23
|
* @param operation - The aggregate to compute
|
|
29
24
|
* @param column - The column or nested path to aggregate
|
|
@@ -32,7 +27,7 @@ import { TableSchema as TableSchema_2 } from '@orkestrel/database';
|
|
|
32
27
|
export declare function compileAggregateSQL(operation: AggregateOperation, column: FieldPath): string;
|
|
33
28
|
|
|
34
29
|
/**
|
|
35
|
-
*
|
|
30
|
+
* Maps a portable {@link ColumnStorage} to its SQLite column type.
|
|
36
31
|
*
|
|
37
32
|
* @param storage - The portable column type
|
|
38
33
|
* @returns The SQLite column type keyword
|
|
@@ -40,25 +35,25 @@ export declare function compileAggregateSQL(operation: AggregateOperation, colum
|
|
|
40
35
|
export declare function compileColumnSQL(storage: ColumnStorage): string;
|
|
41
36
|
|
|
42
37
|
/**
|
|
43
|
-
*
|
|
38
|
+
* Compiles one condition to its `<column> <operator>` SQL fragment and the parameters
|
|
44
39
|
* it binds — engine-exact under SQL's three-valued NULL logic.
|
|
45
40
|
*
|
|
46
41
|
* @remarks
|
|
47
42
|
* Every operand is run through `encodeValue`, so a bound value matches the SQL
|
|
48
|
-
* the column side compiles to. A flat column encodes operands with its
|
|
43
|
+
* the column side compiles to. A flat column encodes operands with its declared
|
|
49
44
|
* schema type (a flat `json` column → `JSON.stringify`); a nested `FieldPath`
|
|
50
|
-
* encodes each operand as the
|
|
45
|
+
* encodes each operand as the native scalar `json_extract` returns, derived from
|
|
51
46
|
* the operand's runtime type (per-operand, since `between` / `any` / `none` can
|
|
52
47
|
* mix types). `any` / `none` collapse an empty list to a constant (`0` matches
|
|
53
48
|
* nothing, `1` matches all) with no parameters.
|
|
54
49
|
*
|
|
55
|
-
* The core engine's total order ranks `undefined` (rank 0)
|
|
56
|
-
* (rank 1) (see `compareValues`), so a
|
|
50
|
+
* The core engine's total order ranks `undefined` (rank 0) below `null`
|
|
51
|
+
* (rank 1) (see `compareValues`), so a missing/`NULL` column matches
|
|
57
52
|
* `below` / `to` / a scalar `not` / `none` — the opposite of raw SQL, where a
|
|
58
53
|
* comparison against `NULL` is `NULL` (excluded). This fragment replicates the
|
|
59
54
|
* engine exactly. Truth table (`value` = the engine's decoded field read; a
|
|
60
|
-
*
|
|
61
|
-
* flat `value` is
|
|
55
|
+
* flat column's stored `NULL` decodes to `undefined` per `decodeRow`, so a
|
|
56
|
+
* flat `value` is never a present `null` — only a nested path can be
|
|
62
57
|
* present-but-`null`):
|
|
63
58
|
*
|
|
64
59
|
* ```text
|
|
@@ -84,15 +79,15 @@ export declare function compileColumnSQL(storage: ColumnStorage): string;
|
|
|
84
79
|
* refines every optional or nullable scalar comparison through the core engine.
|
|
85
80
|
* This compiler still emits a total SQL fragment for direct consumers.
|
|
86
81
|
*
|
|
87
|
-
* A
|
|
88
|
-
* `json_extract` reads back as SQL `NULL` — indistinguishable from an
|
|
82
|
+
* A nested path can be present-but-`null` (a stored JSON `null`), which
|
|
83
|
+
* `json_extract` reads back as SQL `NULL` — indistinguishable from an absent
|
|
89
84
|
* path. `json_type(col, path)` disambiguates them (`'null'` for present-null,
|
|
90
85
|
* SQL `NULL` for absent), so nested `equals` / `not` against a `null` operand
|
|
91
86
|
* compile through `json_type` instead of `IS NULL` / `IS NOT NULL`.
|
|
92
87
|
*
|
|
93
88
|
* Every other MATCH-on-null-or-absent row is expressed uniformly (flat and
|
|
94
89
|
* nested alike) as `(<column> <op> ? OR <column> IS NULL)` — for a nested
|
|
95
|
-
* path, `json_extract` already collapses
|
|
90
|
+
* path, `json_extract` already collapses both absent and present-null to SQL
|
|
96
91
|
* `NULL`, so `IS NULL` catches both in one clause; for a flat column there is
|
|
97
92
|
* only the absent case to catch.
|
|
98
93
|
*
|
|
@@ -111,7 +106,8 @@ export declare function compileColumnSQL(storage: ColumnStorage): string;
|
|
|
111
106
|
export declare function compileConditionSQL(condition: Condition, schema: TableSchema): CompiledSQL;
|
|
112
107
|
|
|
113
108
|
/**
|
|
114
|
-
*
|
|
109
|
+
* Represents a parameterized SQL fragment or statement plus its bind values. The
|
|
110
|
+
* `@orkestrel/database/server` entry point exports this type.
|
|
115
111
|
*
|
|
116
112
|
* @remarks
|
|
117
113
|
* Produced by the pure SQL compilers (`compilers.ts`) that turn a core
|
|
@@ -126,7 +122,11 @@ export declare interface CompiledSQL {
|
|
|
126
122
|
}
|
|
127
123
|
|
|
128
124
|
/**
|
|
129
|
-
*
|
|
125
|
+
* Compiles a {@link FieldPath} to the SQL expression that reads it.
|
|
126
|
+
*
|
|
127
|
+
* @remarks
|
|
128
|
+
* A flat path compiles to the quoted column; a nested path compiles to a
|
|
129
|
+
* `json_extract` over the head column with the rest of the path as its accessor.
|
|
130
130
|
*
|
|
131
131
|
* @param path - The field path
|
|
132
132
|
* @returns The SQL expression selecting the value
|
|
@@ -134,9 +134,9 @@ export declare interface CompiledSQL {
|
|
|
134
134
|
export declare function compileFieldSQL(path: FieldPath): string;
|
|
135
135
|
|
|
136
136
|
/**
|
|
137
|
-
*
|
|
137
|
+
* Compiles a nested {@link FieldPath} to the `json_type(<col>, <path>)` SQL
|
|
138
138
|
* expression — the {@link compileFieldSQL} `json_extract` sibling used to tell a
|
|
139
|
-
*
|
|
139
|
+
* present JSON `null` apart from an absent path (both read back as SQL `NULL`
|
|
140
140
|
* through `json_extract`, but `json_type` reports `'null'` for the former and
|
|
141
141
|
* SQL `NULL` for the latter).
|
|
142
142
|
*
|
|
@@ -151,14 +151,14 @@ export declare function compileFieldSQL(path: FieldPath): string;
|
|
|
151
151
|
export declare function compileJSONTypeSQL(path: readonly string[]): string;
|
|
152
152
|
|
|
153
153
|
/**
|
|
154
|
-
*
|
|
154
|
+
* Compiles the ORDER BY clause from the order terms, always ending with the
|
|
155
155
|
* primary key as the final determinant.
|
|
156
156
|
*
|
|
157
157
|
* @remarks
|
|
158
158
|
* The native `records` read then resolves ties in key order, matching a
|
|
159
159
|
* primary-key-ordered `scan` and the core engine's stable `sortRows` over a
|
|
160
160
|
* key-ordered scan (and IndexedDB's key-ordered reads), so a native read equals
|
|
161
|
-
* the scan path
|
|
161
|
+
* the scan path — native ↔ engine parity. SQLite without an
|
|
162
162
|
* `ORDER BY` returns rowid (insertion) order, and an explicit order alone breaks
|
|
163
163
|
* ties by rowid too — both diverge from every key-ordered backend. The
|
|
164
164
|
* tie-breaker is ASCENDING regardless of the explicit directions: the engine's
|
|
@@ -172,14 +172,14 @@ export declare function compileJSONTypeSQL(path: readonly string[]): string;
|
|
|
172
172
|
*
|
|
173
173
|
* @example
|
|
174
174
|
* ```ts
|
|
175
|
-
*
|
|
175
|
+
* compileOrderSQL([{ column: 'age', direction: 'descending' }], schema)
|
|
176
176
|
* // 'ORDER BY "age" DESC, "id"'
|
|
177
177
|
* ```
|
|
178
178
|
*/
|
|
179
|
-
export declare function
|
|
179
|
+
export declare function compileOrderSQL(order: readonly Order[] | undefined, schema: TableSchema): string;
|
|
180
180
|
|
|
181
181
|
/**
|
|
182
|
-
*
|
|
182
|
+
* Compiles the LIMIT / OFFSET clause.
|
|
183
183
|
*
|
|
184
184
|
* @remarks
|
|
185
185
|
* An offset without a limit uses `LIMIT -1` (SQLite's "no limit") so OFFSET is
|
|
@@ -191,13 +191,13 @@ export declare function compileOrder(order: readonly Order[] | undefined, schema
|
|
|
191
191
|
*
|
|
192
192
|
* @example
|
|
193
193
|
* ```ts
|
|
194
|
-
*
|
|
194
|
+
* compilePageSQL(undefined, 5) // { sql: 'LIMIT -1 OFFSET ?', parameters: [5] }
|
|
195
195
|
* ```
|
|
196
196
|
*/
|
|
197
|
-
export declare function
|
|
197
|
+
export declare function compilePageSQL(limit: number | undefined, offset: number | undefined): CompiledSQL;
|
|
198
198
|
|
|
199
199
|
/**
|
|
200
|
-
*
|
|
200
|
+
* Compiles a {@link QueryInput} into the SQL clause that follows a table name, with
|
|
201
201
|
* its bound parameters in clause order.
|
|
202
202
|
*
|
|
203
203
|
* @remarks
|
|
@@ -207,11 +207,13 @@ export declare function compilePage(limit: number | undefined, offset: number |
|
|
|
207
207
|
* over a JS `scan`. The WHERE fold is parenthesized **left-to-right** to mirror
|
|
208
208
|
* the core engine's `matchesQuery` (not SQL's native AND-over-OR precedence),
|
|
209
209
|
* so a native and an engine read return identical rows. Each operand is encoded
|
|
210
|
-
*
|
|
210
|
+
* through `encodeValue`: a flat column uses its declared schema type, while a nested
|
|
211
211
|
* `FieldPath` (a `json_extract` read) encodes each operand as the native scalar
|
|
212
212
|
* the extract returns — derived from the operand's runtime type — so it compares.
|
|
213
|
-
*
|
|
214
|
-
* `starts` / `ends`
|
|
213
|
+
* Every operator maps per the databases guide's operator table, with
|
|
214
|
+
* `starts` / `ends` compiling to a code-point `substr` slice guarded by
|
|
215
|
+
* `typeof(<column>) = 'text'` (case-sensitive, matching the engine's
|
|
216
|
+
* `String.prototype.startsWith` / `endsWith`) and an empty `any` / `none` list
|
|
215
217
|
* collapsing to a constant. An `undefined` input (or one with no parts)
|
|
216
218
|
* compiles to an empty clause.
|
|
217
219
|
*
|
|
@@ -228,13 +230,13 @@ export declare function compilePage(limit: number | undefined, offset: number |
|
|
|
228
230
|
export declare function compileQuerySQL(input: QueryInput | undefined, schema: TableSchema): CompiledSQL;
|
|
229
231
|
|
|
230
232
|
/**
|
|
231
|
-
*
|
|
233
|
+
* Folds the conditions into one WHERE clause, parenthesizing progressively
|
|
232
234
|
* left-to-right so the grouping matches the engine's `matchesQuery` fold.
|
|
233
235
|
*
|
|
234
236
|
* @remarks
|
|
235
237
|
* The first condition's connector is ignored, per the {@link Condition} types.
|
|
236
238
|
* Every fragment (see {@link compileConditionSQL}'s truth table) replicates the core
|
|
237
|
-
* engine's total order
|
|
239
|
+
* engine's total order exactly under SQL's three-valued NULL logic, so this
|
|
238
240
|
* clause matches `applyQuery` row-for-row over the same table — a native
|
|
239
241
|
* `records` / `count` read never disagrees with a scan-and-filter fallback.
|
|
240
242
|
*
|
|
@@ -244,14 +246,14 @@ export declare function compileQuerySQL(input: QueryInput | undefined, schema: T
|
|
|
244
246
|
*
|
|
245
247
|
* @example
|
|
246
248
|
* ```ts
|
|
247
|
-
*
|
|
249
|
+
* compileWhereSQL([{ column: 'age', operator: 'from', values: [18], connector: 'and' }], schema)
|
|
248
250
|
* // { sql: 'WHERE "age" >= ?', parameters: [18] }
|
|
249
251
|
* ```
|
|
250
252
|
*/
|
|
251
|
-
export declare function
|
|
253
|
+
export declare function compileWhereSQL(conditions: readonly Condition[], schema: TableSchema): CompiledSQL;
|
|
252
254
|
|
|
253
255
|
/**
|
|
254
|
-
*
|
|
256
|
+
* Creates a persistent JSON-file {@link DriverInterface} for a given path.
|
|
255
257
|
*
|
|
256
258
|
* @remarks
|
|
257
259
|
* Pass it to `createDatabase` from `@orkestrel/database` to run the typed
|
|
@@ -259,9 +261,10 @@ export declare function compileWhere(conditions: readonly Condition[], schema: T
|
|
|
259
261
|
* `Table` / `Query` API is unchanged; only where the bytes live changes.
|
|
260
262
|
* The driver is the reference `MemoryDriver` plus JSON-file persistence: `open` loads
|
|
261
263
|
* the file, every mutation flushes the whole store back, and querying runs through
|
|
262
|
-
* the core engine
|
|
263
|
-
* `
|
|
264
|
-
*
|
|
264
|
+
* the core engine's `matchesQuery`. The driver implements the native `stream`
|
|
265
|
+
* hook and neither `records` nor `aggregate`, so the engine answers every query
|
|
266
|
+
* on either path. A missing, corrupt, or wrong-shaped file starts empty rather
|
|
267
|
+
* than throwing.
|
|
265
268
|
*
|
|
266
269
|
* @param path - The JSON file path data is loaded from and flushed to
|
|
267
270
|
* @returns A {@link DriverInterface} backed by a JSON file
|
|
@@ -282,7 +285,8 @@ export declare function compileWhere(conditions: readonly Condition[], schema: T
|
|
|
282
285
|
export declare function createJSONDriver(path: string): DriverInterface;
|
|
283
286
|
|
|
284
287
|
/**
|
|
285
|
-
*
|
|
288
|
+
* Creates a trusted-mode, server-native SQLite {@link DriverInterface} for a database path,
|
|
289
|
+
* or for `:memory:` when the options bag omits one.
|
|
286
290
|
*
|
|
287
291
|
* @remarks
|
|
288
292
|
* Pass it to `createDatabase` from `@orkestrel/database` to run the typed
|
|
@@ -320,7 +324,7 @@ export declare function createJSONDriver(path: string): DriverInterface;
|
|
|
320
324
|
export declare function createSQLiteDriver(options?: SQLiteDriverOptions): DriverInterface;
|
|
321
325
|
|
|
322
326
|
/**
|
|
323
|
-
*
|
|
327
|
+
* Decodes a stored {@link SQLiteRow} back to a {@link Row} by its table's schema.
|
|
324
328
|
*
|
|
325
329
|
* @remarks
|
|
326
330
|
* Decodes each declared column with {@link decodeValue} and **omits** any column
|
|
@@ -341,7 +345,7 @@ export declare function createSQLiteDriver(options?: SQLiteDriverOptions): Drive
|
|
|
341
345
|
export declare function decodeRow(row: SQLiteRow, schema: TableSchema): Row;
|
|
342
346
|
|
|
343
347
|
/**
|
|
344
|
-
*
|
|
348
|
+
* Decodes a stored {@link SQLiteValue} back to its JS value for a declared column —
|
|
345
349
|
* the exact inverse of {@link encodeValue}.
|
|
346
350
|
*
|
|
347
351
|
* @remarks
|
|
@@ -363,12 +367,12 @@ export declare function decodeRow(row: SQLiteRow, schema: TableSchema): Row;
|
|
|
363
367
|
export declare function decodeValue(value: SQLiteValue, column: ColumnSchema): unknown;
|
|
364
368
|
|
|
365
369
|
/**
|
|
366
|
-
*
|
|
370
|
+
* Builds a collision-free SQL index name for a table + column-group index —
|
|
367
371
|
* shared by the compiler module's `schemaToIndexes` and `stepToSQL`,
|
|
368
372
|
* so a plan-built index name always matches one `open` would have created.
|
|
369
373
|
*
|
|
370
374
|
* @remarks
|
|
371
|
-
* A naive `idx_<table>_<cols joined by _>` is
|
|
375
|
+
* A naive `idx_<table>_<cols joined by _>` is ambiguous: table `'a_b'` with
|
|
372
376
|
* column `'c'` and table `'a'` with columns `['b', 'c']` both produce
|
|
373
377
|
* `idx_a_b_c`. This encodes each part (the table name, then each column name)
|
|
374
378
|
* length-prefixed (`<len>_<part>`) so the boundary between parts is always
|
|
@@ -388,7 +392,7 @@ export declare function decodeValue(value: SQLiteValue, column: ColumnSchema): u
|
|
|
388
392
|
export declare function deriveSQLiteIndexName(table: string, columns: readonly string[]): string;
|
|
389
393
|
|
|
390
394
|
/**
|
|
391
|
-
*
|
|
395
|
+
* Encodes a whole {@link Row} to a {@link SQLiteRow} by its table's schema.
|
|
392
396
|
*
|
|
393
397
|
* @remarks
|
|
394
398
|
* Encodes each declared column's value with {@link encodeValue}; columns the row
|
|
@@ -407,7 +411,7 @@ export declare function deriveSQLiteIndexName(table: string, columns: readonly s
|
|
|
407
411
|
export declare function encodeRow(row: Row, schema: TableSchema): SQLiteRow;
|
|
408
412
|
|
|
409
413
|
/**
|
|
410
|
-
*
|
|
414
|
+
* Encodes a JS value to its stored {@link SQLiteValue} for a declared column.
|
|
411
415
|
*
|
|
412
416
|
* @remarks
|
|
413
417
|
* The codec is total: a malformed value encodes to SQL `NULL`. Absence always
|
|
@@ -428,42 +432,28 @@ export declare function encodeRow(row: Row, schema: TableSchema): SQLiteRow;
|
|
|
428
432
|
export declare function encodeValue(value: unknown, column: ColumnSchema): SQLiteValue;
|
|
429
433
|
|
|
430
434
|
/**
|
|
431
|
-
*
|
|
432
|
-
* operand is matched literally under the `LIKE … ESCAPE '\'` clause.
|
|
433
|
-
*
|
|
434
|
-
* @param text - The raw operand text
|
|
435
|
-
* @returns The text with LIKE metacharacters escaped
|
|
436
|
-
*
|
|
437
|
-
* @example
|
|
438
|
-
* ```ts
|
|
439
|
-
* escapeLike('50%_off') // '50\\%\\_off'
|
|
440
|
-
* ```
|
|
441
|
-
*/
|
|
442
|
-
export declare function escapeLike(text: string): string;
|
|
443
|
-
|
|
444
|
-
/**
|
|
445
|
-
* The declared {@link ColumnStorage}s whose SQL EQUALITY comparisons (`equals` /
|
|
435
|
+
* Lists the declared {@link ColumnStorage}s whose SQL equality comparisons (`equals` /
|
|
446
436
|
* `not` / `any` / `none`) and `starts` / `ends` compiles are provably
|
|
447
437
|
* engine-exact under declared-type trust — `text` / `integer` / `real` /
|
|
448
438
|
* `boolean`; a `json` or `blob` column always refines instead.
|
|
449
439
|
*
|
|
450
440
|
* @remarks
|
|
451
|
-
* This set governs equality and prefix/suffix matching only.
|
|
441
|
+
* This set governs equality and prefix/suffix matching only. Range
|
|
452
442
|
* comparisons (`above` / `below` / `from` / `to` / `between`) and `ORDER BY`
|
|
453
|
-
* are exact for `integer` / `real` / `boolean` but
|
|
443
|
+
* are exact for `integer` / `real` / `boolean` but not for `text`: compiled
|
|
454
444
|
* SQL orders/ranges under SQLite's default BINARY collation, which compares
|
|
455
|
-
* TEXT byte-for-byte as UTF-8 — equivalent to Unicode
|
|
445
|
+
* TEXT byte-for-byte as UTF-8 — equivalent to Unicode code-point order —
|
|
456
446
|
* while the core engine's `compareValues` orders JS strings with `<`, which
|
|
457
|
-
* compares UTF-16
|
|
458
|
-
* plane characters (code points ≥ U+10000,
|
|
459
|
-
* (`\uD800`–`\uDBFF`) sorts
|
|
460
|
-
* its code point sorts
|
|
447
|
+
* compares UTF-16 code-unit order. The two orders diverge for supplementary-
|
|
448
|
+
* plane characters (code points ≥ U+10000, for example many emoji): a lead surrogate
|
|
449
|
+
* (`\uD800`–`\uDBFF`) sorts below ``–`` in code-unit order, while
|
|
450
|
+
* its code point sorts above them. So `matchesConditionExactly`'s range family and
|
|
461
451
|
* `matchesOrderExactly` exclude `text`, refining through the core engine instead.
|
|
462
452
|
*/
|
|
463
453
|
export declare const EXACT_COLUMN_STORAGE: readonly ColumnStorage[];
|
|
464
454
|
|
|
465
455
|
/**
|
|
466
|
-
*
|
|
456
|
+
* Lists the declared {@link ColumnStorage}s whose SQL range comparisons
|
|
467
457
|
* (`above` / `below` / `from` / `to` / `between`) and `ORDER BY` compiles are
|
|
468
458
|
* provably engine-exact — `integer` / `real` / `boolean` only. `text` is
|
|
469
459
|
* excluded: see {@link EXACT_COLUMN_STORAGE}'s remarks for the BINARY-collation
|
|
@@ -473,7 +463,7 @@ export declare const EXACT_COLUMN_STORAGE: readonly ColumnStorage[];
|
|
|
473
463
|
export declare const EXACT_RANGE_COLUMN_STORAGE: readonly ColumnStorage[];
|
|
474
464
|
|
|
475
465
|
/**
|
|
476
|
-
*
|
|
466
|
+
* Extracts a stored row's values in a declared positional order.
|
|
477
467
|
*
|
|
478
468
|
* @remarks
|
|
479
469
|
* SQLite statements bind arrays positionally. Every requested column must be
|
|
@@ -494,22 +484,8 @@ export declare const EXACT_RANGE_COLUMN_STORAGE: readonly ColumnStorage[];
|
|
|
494
484
|
export declare function extractValues(row: SQLiteRow, names: readonly string[], table: string): readonly SQLiteValue[];
|
|
495
485
|
|
|
496
486
|
/**
|
|
497
|
-
*
|
|
498
|
-
*
|
|
499
|
-
* @param column - The column name
|
|
500
|
-
* @param schema - The table's schema
|
|
501
|
-
* @returns The column's {@link ColumnStorage}, or `undefined` if the schema does not carry it
|
|
502
|
-
*
|
|
503
|
-
* @example
|
|
504
|
-
* ```ts
|
|
505
|
-
* findColumnStorage('age', schema) // 'integer'
|
|
506
|
-
* ```
|
|
507
|
-
*/
|
|
508
|
-
export declare function findColumnStorage(column: string, schema: TableSchema): ColumnStorage | undefined;
|
|
509
|
-
|
|
510
|
-
/**
|
|
511
|
-
* The storage type a nested (`json_extract`) operand encodes as, derived from its
|
|
512
|
-
* RUNTIME value — NOT `json`.
|
|
487
|
+
* Reads the storage type a nested (`json_extract`) operand encodes as from its
|
|
488
|
+
* runtime value, never as `json`.
|
|
513
489
|
*
|
|
514
490
|
* @remarks
|
|
515
491
|
* `json_extract` returns the unquoted, natively-typed scalar (a JSON boolean as
|
|
@@ -531,7 +507,7 @@ export declare function findColumnStorage(column: string, schema: TableSchema):
|
|
|
531
507
|
export declare function inferValueStorage(value: unknown): ColumnStorage;
|
|
532
508
|
|
|
533
509
|
/**
|
|
534
|
-
*
|
|
510
|
+
* Implements a persistent {@link DriverInterface} backed by a single JSON file — the
|
|
535
511
|
* reference {@link MemoryDriver} plus file load / flush.
|
|
536
512
|
*
|
|
537
513
|
* @remarks
|
|
@@ -545,15 +521,15 @@ export declare function inferValueStorage(value: unknown): ColumnStorage;
|
|
|
545
521
|
* primary (the table contract), so the key is recovered on load with
|
|
546
522
|
* {@link extractKey} and the file need not store it. The parsed JSON crosses the
|
|
547
523
|
* boundary as `unknown` and is narrowed with {@link isRecord} / {@link extractKey},
|
|
548
|
-
* never asserted
|
|
524
|
+
* never asserted. A read that reports no document there starts empty —
|
|
549
525
|
* `ENOENT` for a plain absence, and `ENOTDIR` for a path whose parent is not a
|
|
550
526
|
* directory, which no later write could find either; every other read failure or
|
|
551
527
|
* invalid existing document fails closed without publication, mutation, or
|
|
552
|
-
* automatic repair. It
|
|
553
|
-
*
|
|
554
|
-
*
|
|
555
|
-
*
|
|
556
|
-
* driver.
|
|
528
|
+
* automatic repair. It implements the optional native `stream` hook that
|
|
529
|
+
* `TableInterface.scan` prefers over `scan`, and neither `records` nor
|
|
530
|
+
* `aggregate`, so the core engine's `matchesQuery` answers every query on
|
|
531
|
+
* either path. For development, small datasets, and portable / inspectable
|
|
532
|
+
* data; for large or concurrent workloads reach for a SQLite-backed driver.
|
|
557
533
|
*
|
|
558
534
|
* Metadata crosses {@link cloneDriverMetadata} at parsed-file ingress, public and
|
|
559
535
|
* scoped write ingress, candidate/root publication, serialization, and copy-out.
|
|
@@ -566,19 +542,19 @@ export declare function inferValueStorage(value: unknown): ColumnStorage;
|
|
|
566
542
|
* remains an `ABORTED` `DatabaseError` in `context.cause`. The fail-closed read path
|
|
567
543
|
* ({@link JSONDriver.#document}) remains separate from this write-error contract.
|
|
568
544
|
*/
|
|
569
|
-
export declare class JSONDriver implements
|
|
545
|
+
export declare class JSONDriver implements DriverInterface {
|
|
570
546
|
#private;
|
|
571
547
|
constructor(path: string);
|
|
572
|
-
open(schema: readonly
|
|
548
|
+
open(schema: readonly TableSchema[]): Promise<void>;
|
|
573
549
|
close(): Promise<void>;
|
|
574
|
-
read(table: string, key: Key): Promise<
|
|
575
|
-
write(table: string, key: Key, row:
|
|
576
|
-
insert(table: string, key: Key, row:
|
|
550
|
+
read(table: string, key: Key): Promise<Row | undefined>;
|
|
551
|
+
write(table: string, key: Key, row: Row, options?: OperationOptions): Promise<void>;
|
|
552
|
+
insert(table: string, key: Key, row: Row, options?: OperationOptions): Promise<void>;
|
|
577
553
|
delete(table: string, key: Key, options?: OperationOptions): Promise<boolean>;
|
|
578
554
|
keys(table: string): Promise<readonly Key[]>;
|
|
579
|
-
scan(table: string): AsyncIterable<
|
|
555
|
+
scan(table: string): AsyncIterable<Row>;
|
|
580
556
|
/**
|
|
581
|
-
*
|
|
557
|
+
* Iterates rows lazily with native filtering — delegates to the inner {@link MemoryDriver}.
|
|
582
558
|
*
|
|
583
559
|
* @remarks
|
|
584
560
|
* Semantics are the memory driver's own: `input.conditions` filters, `offset`
|
|
@@ -588,10 +564,10 @@ export declare class JSONDriver implements DriverInterface_2 {
|
|
|
588
564
|
* @param table - The table to stream
|
|
589
565
|
* @param input - The filter / offset / limit to apply lazily
|
|
590
566
|
*/
|
|
591
|
-
stream(table: string, input:
|
|
567
|
+
stream(table: string, input: QueryInput): AsyncIterable<Row>;
|
|
592
568
|
clear(table: string): Promise<void>;
|
|
593
569
|
/**
|
|
594
|
-
*
|
|
570
|
+
* Runs an isolated native transaction callback over a candidate memory store.
|
|
595
571
|
*
|
|
596
572
|
* @remarks
|
|
597
573
|
* Single-writer: nesting and root operations while active throw `CONFLICT`.
|
|
@@ -605,7 +581,7 @@ export declare class JSONDriver implements DriverInterface_2 {
|
|
|
605
581
|
*/
|
|
606
582
|
transaction<R>(scope: (storage: StorageInterface) => Promise<R>): Promise<R>;
|
|
607
583
|
/**
|
|
608
|
-
*
|
|
584
|
+
* Captures an owned row snapshot at an exact writer-queue position.
|
|
609
585
|
*
|
|
610
586
|
* @remarks
|
|
611
587
|
* Capture owns table names, schemas, rows, and one session-local identity per
|
|
@@ -621,7 +597,7 @@ export declare class JSONDriver implements DriverInterface_2 {
|
|
|
621
597
|
snapshot(tables?: readonly string[]): Promise<() => Promise<void>>;
|
|
622
598
|
metadata(): Promise<DriverMetadata | undefined>;
|
|
623
599
|
/**
|
|
624
|
-
*
|
|
600
|
+
* Persists an owned metadata snapshot for a later `metadata()` to copy out.
|
|
625
601
|
*
|
|
626
602
|
* @remarks
|
|
627
603
|
* Root stamping conflicts while a transaction is active. The scoped
|
|
@@ -632,7 +608,7 @@ export declare class JSONDriver implements DriverInterface_2 {
|
|
|
632
608
|
*/
|
|
633
609
|
stamp(metadata: DriverMetadata): Promise<void>;
|
|
634
610
|
/**
|
|
635
|
-
*
|
|
611
|
+
* Applies one atomic {@link MigrationInput} through an isolated candidate.
|
|
636
612
|
*
|
|
637
613
|
* @remarks
|
|
638
614
|
* The candidate receives every plan step plus optional metadata. Its complete
|
|
@@ -646,7 +622,7 @@ export declare class JSONDriver implements DriverInterface_2 {
|
|
|
646
622
|
}
|
|
647
623
|
|
|
648
624
|
/**
|
|
649
|
-
*
|
|
625
|
+
* Reports whether a caught filesystem error says that nothing is there to read.
|
|
650
626
|
*
|
|
651
627
|
* @remarks
|
|
652
628
|
* Two codes carry that meaning: `ENOENT` is a plain absence, and `ENOTDIR` is a
|
|
@@ -663,7 +639,7 @@ export declare class JSONDriver implements DriverInterface_2 {
|
|
|
663
639
|
* answers `false` rather than being read for a `code` any object could carry.
|
|
664
640
|
*
|
|
665
641
|
* @param error - The caught value to classify; any runtime is accepted
|
|
666
|
-
* @returns
|
|
642
|
+
* @returns True if the error reports that the path holds nothing; false otherwise
|
|
667
643
|
*
|
|
668
644
|
* @example
|
|
669
645
|
* ```ts
|
|
@@ -675,19 +651,19 @@ export declare class JSONDriver implements DriverInterface_2 {
|
|
|
675
651
|
export declare function matchesAbsentPath(error: unknown): boolean;
|
|
676
652
|
|
|
677
653
|
/**
|
|
678
|
-
*
|
|
654
|
+
* Reports whether SQLite can execute an aggregate exactly like the core engine.
|
|
679
655
|
*
|
|
680
656
|
* @param operation - Aggregate operation
|
|
681
657
|
* @param column - Aggregate field
|
|
682
658
|
* @param schema - Current table schema
|
|
683
|
-
* @returns
|
|
659
|
+
* @returns True if native aggregation is exact; false otherwise
|
|
684
660
|
*/
|
|
685
661
|
export declare function matchesAggregateExactly(operation: AggregateOperation, column: FieldPath, schema: TableSchema): boolean;
|
|
686
662
|
|
|
687
663
|
/**
|
|
688
|
-
*
|
|
689
|
-
* the core engine's `matchesCondition` for every value its
|
|
690
|
-
* type can store.
|
|
664
|
+
* Reports whether one {@link Condition} compiles to SQL that is provably
|
|
665
|
+
* identical to the core engine's `matchesCondition` for every value its
|
|
666
|
+
* column's declared type can store.
|
|
691
667
|
*
|
|
692
668
|
* @remarks
|
|
693
669
|
* `false` for a nested `FieldPath` (an array) or a column absent from `schema`.
|
|
@@ -699,88 +675,95 @@ export declare function matchesAggregateExactly(operation: AggregateOperation, c
|
|
|
699
675
|
* Required non-null `equals` / `not` require an operand matching the declared
|
|
700
676
|
* storage and exclude `json` / `blob`. `above` / `below` / `from` / `to` /
|
|
701
677
|
* `between` are exact only for {@link EXACT_RANGE_COLUMN_STORAGE} (`integer` /
|
|
702
|
-
* `real` / `boolean`) — a `text` column's range conditions
|
|
703
|
-
* SQLite's default BINARY collation orders TEXT by Unicode
|
|
704
|
-
* the core engine's `compareValues` orders JS strings by UTF-16
|
|
678
|
+
* `real` / `boolean`) — a `text` column's range conditions refine, because
|
|
679
|
+
* SQLite's default BINARY collation orders TEXT by Unicode code point while
|
|
680
|
+
* the core engine's `compareValues` orders JS strings by UTF-16 code unit,
|
|
705
681
|
* and the two diverge for supplementary-plane characters (see
|
|
706
682
|
* {@link EXACT_COLUMN_STORAGE}'s remarks for the full rationale).
|
|
707
|
-
* `any` / `none` require a
|
|
683
|
+
* `any` / `none` require a non-empty list where every element matches (an empty
|
|
708
684
|
* list is exact under neither: the engine's `any([])` matches nothing while
|
|
709
685
|
* `none([])` matches everything, and SQL `IN ()` is a syntax error) — these
|
|
710
686
|
* stay exact on `text` (byte equality is collation-independent and engine-
|
|
711
687
|
* identical). `starts` / `ends` are exact only on a `text` column with a
|
|
712
688
|
* string operand (case-sensitive `substr` compile, see {@link compileConditionSQL}) —
|
|
713
|
-
* likewise collation-independent. `like` / `glob` are
|
|
689
|
+
* likewise collation-independent. `like` / `glob` are never exact — SQLite
|
|
714
690
|
* `LIKE` folds case ASCII-only against the engine's Unicode fold, and `GLOB`
|
|
715
691
|
* has character classes the engine treats literally.
|
|
716
692
|
*
|
|
717
693
|
* @param condition - The condition to test
|
|
718
694
|
* @param schema - The table's schema
|
|
719
|
-
* @returns
|
|
695
|
+
* @returns True if `condition` is exact; false otherwise
|
|
720
696
|
*/
|
|
721
697
|
export declare function matchesConditionExactly(condition: Condition, schema: TableSchema): boolean;
|
|
722
698
|
|
|
723
699
|
/**
|
|
724
|
-
*
|
|
725
|
-
* the operand side of the declared-type-trust proof.
|
|
700
|
+
* Reports whether a value's runtime type matches a column's declared exact type
|
|
701
|
+
* — the operand side of the declared-type-trust proof.
|
|
726
702
|
*
|
|
727
703
|
* @remarks
|
|
728
|
-
* `text` ↔ string, `integer` / `real` ↔
|
|
704
|
+
* `text` ↔ string, `integer` / `real` ↔ finite number (`NaN` / `±Infinity`
|
|
729
705
|
* fail), `boolean` ↔ boolean. Backs {@link matchesConditionExactly}'s operand checks.
|
|
730
706
|
*
|
|
731
707
|
* @param value - The condition operand to test
|
|
732
|
-
* @param
|
|
733
|
-
* @returns
|
|
708
|
+
* @param storage - The column's declared portable storage type
|
|
709
|
+
* @returns True if the operand's runtime type matches the declared type; false otherwise
|
|
734
710
|
*
|
|
735
711
|
* @example
|
|
736
712
|
* ```ts
|
|
737
|
-
*
|
|
738
|
-
*
|
|
713
|
+
* matchesDeclaredStorage('Ada', 'text') // true
|
|
714
|
+
* matchesDeclaredStorage(Number.NaN, 'integer') // false — only finite numbers
|
|
739
715
|
* ```
|
|
740
716
|
*/
|
|
741
717
|
export declare function matchesDeclaredStorage(value: unknown, storage: ColumnStorage): boolean;
|
|
742
718
|
|
|
743
719
|
/**
|
|
744
|
-
*
|
|
745
|
-
* matches the engine's {@link import('@
|
|
720
|
+
* Reports whether one {@link Order} term's column compiles to an `ORDER BY`
|
|
721
|
+
* that matches the engine's {@link import('@orkestrel/database').sortRows} exactly.
|
|
746
722
|
*
|
|
747
723
|
* @remarks
|
|
748
724
|
* `false` for a nested `FieldPath`, a column absent from `schema`, or a
|
|
749
725
|
* declared type outside {@link EXACT_RANGE_COLUMN_STORAGE} (`integer` / `real` /
|
|
750
|
-
* `boolean`). `text` is
|
|
726
|
+
* `boolean`). `text` is not exact here: SQLite's default BINARY collation
|
|
751
727
|
* orders TEXT by Unicode code point while the core engine's `compareValues`
|
|
752
728
|
* orders JS strings by UTF-16 code unit, and the two diverge for
|
|
753
729
|
* supplementary-plane characters (see {@link EXACT_COLUMN_STORAGE}'s remarks) —
|
|
754
|
-
* a `text` order term
|
|
730
|
+
* a `text` order term refines through the core engine instead. The column must
|
|
731
|
+
* also be required and non-null: an optional or nullable column refines, because
|
|
732
|
+
* SQL orders its `NULL`s ahead of every value while the core total order ranks
|
|
733
|
+
* `undefined` before `null` before every other value.
|
|
755
734
|
*
|
|
756
735
|
* @param order - The order term to test
|
|
757
736
|
* @param schema - The table's schema
|
|
758
|
-
* @returns
|
|
737
|
+
* @returns True if `order` is exact; false otherwise
|
|
759
738
|
*/
|
|
760
739
|
export declare function matchesOrderExactly(order: Order, schema: TableSchema): boolean;
|
|
761
740
|
|
|
762
741
|
/**
|
|
763
|
-
*
|
|
764
|
-
* term is exact. `limit` / `offset` never affect exactness (SQL
|
|
765
|
-
* `OFFSET` are always engine-identical).
|
|
742
|
+
* Reports whether a whole {@link QueryInput} is exact — every condition and
|
|
743
|
+
* every order term is exact. `limit` / `offset` never affect exactness (SQL
|
|
744
|
+
* `LIMIT` / `OFFSET` are always engine-identical).
|
|
745
|
+
*
|
|
746
|
+
* @remarks
|
|
747
|
+
* The gate {@link import('./drivers/SQLiteDriver.js').SQLiteDriver} checks before
|
|
748
|
+
* trusting a native SQL read over a full-scan refine through the core engine.
|
|
766
749
|
*
|
|
767
750
|
* @param input - The query input to test
|
|
768
751
|
* @param schema - The table's schema
|
|
769
|
-
* @returns
|
|
752
|
+
* @returns True if every part of `input` is exact; false otherwise
|
|
770
753
|
*/
|
|
771
754
|
export declare function matchesQueryExactly(input: QueryInput, schema: TableSchema): boolean;
|
|
772
755
|
|
|
773
756
|
/**
|
|
774
|
-
*
|
|
757
|
+
* Checks a declared SQLite type against a portable storage affinity.
|
|
775
758
|
*
|
|
776
759
|
* @param declared - Native declared type
|
|
777
760
|
* @param storage - Portable column storage
|
|
778
|
-
* @returns
|
|
761
|
+
* @returns True if SQLite's official affinity rules yield the expected affinity; false otherwise
|
|
779
762
|
*/
|
|
780
763
|
export declare function matchesSQLiteAffinity(declared: unknown, storage: ColumnStorage): boolean;
|
|
781
764
|
|
|
782
765
|
/**
|
|
783
|
-
*
|
|
766
|
+
* Names the reserved metadata table the {@link SQLiteDriver} creates on `open` to
|
|
784
767
|
* persist its stamped `DriverMetadata` (`version` + declared schema JSON) — the
|
|
785
768
|
* SQLite realization of the `metadata` / `stamp` driver hooks.
|
|
786
769
|
*
|
|
@@ -791,7 +774,7 @@ export declare function matchesSQLiteAffinity(declared: unknown, storage: Column
|
|
|
791
774
|
export declare const METADATA_TABLE = "_metadata";
|
|
792
775
|
|
|
793
776
|
/**
|
|
794
|
-
*
|
|
777
|
+
* Quotes a SQL identifier (a table or column name) so any characters are literal.
|
|
795
778
|
*
|
|
796
779
|
* @remarks
|
|
797
780
|
* Wraps the name in double quotes and doubles any embedded quote — the standard
|
|
@@ -809,7 +792,11 @@ export declare const METADATA_TABLE = "_metadata";
|
|
|
809
792
|
export declare function quoteIdentifier(identifier: string): string;
|
|
810
793
|
|
|
811
794
|
/**
|
|
812
|
-
*
|
|
795
|
+
* Projects a {@link TableSchema} to its declared SQLite indexes.
|
|
796
|
+
*
|
|
797
|
+
* @remarks
|
|
798
|
+
* Each statement is a `CREATE INDEX IF NOT EXISTS` named by
|
|
799
|
+
* {@link deriveSQLiteIndexName}, so a reopen re-issues the set safely.
|
|
813
800
|
*
|
|
814
801
|
* @param schema - The table schema
|
|
815
802
|
* @returns One statement per declared index
|
|
@@ -817,7 +804,7 @@ export declare function quoteIdentifier(identifier: string): string;
|
|
|
817
804
|
export declare function schemaToIndexes(schema: TableSchema): readonly string[];
|
|
818
805
|
|
|
819
806
|
/**
|
|
820
|
-
*
|
|
807
|
+
* Projects a {@link TableSchema} to its `CREATE TABLE IF NOT EXISTS` statement.
|
|
821
808
|
*
|
|
822
809
|
* @param schema - The table schema
|
|
823
810
|
* @returns The complete table declaration
|
|
@@ -825,8 +812,8 @@ export declare function schemaToIndexes(schema: TableSchema): readonly string[];
|
|
|
825
812
|
export declare function schemaToTable(schema: TableSchema): string;
|
|
826
813
|
|
|
827
814
|
/**
|
|
828
|
-
*
|
|
829
|
-
* built on the published `@orkestrel/sqlite` synchronous wrapper.
|
|
815
|
+
* Implements the {@link DriverInterface} over SQLite — the server-native, trusted-mode
|
|
816
|
+
* backend built on the published `@orkestrel/sqlite` synchronous wrapper.
|
|
830
817
|
*
|
|
831
818
|
* @remarks
|
|
832
819
|
* A thin adapter: it implements the storage primitives the core database layer
|
|
@@ -837,59 +824,58 @@ export declare function schemaToTable(schema: TableSchema): string;
|
|
|
837
824
|
* reopen-safe), and readies a reserved `_metadata` single-row table `metadata()` /
|
|
838
825
|
* `stamp()` read and write — **a user table named `_metadata` collides with it**;
|
|
839
826
|
* avoid the name. Rows cross the boundary through the codecs in `helpers.ts`
|
|
840
|
-
* (`json` columns store / parse JSON text, a `boolean` stores `1` / `0`), so
|
|
841
|
-
* typed layer above imposes the exact shape
|
|
827
|
+
* (`json` columns store / parse JSON text, a `boolean` stores `1` / `0`), so
|
|
828
|
+
* the typed layer above imposes the exact shape. `write` is an
|
|
842
829
|
* `INSERT OR REPLACE` upsert, while `insert` uses a plain `INSERT` and maps its
|
|
843
830
|
* atomic primary-key constraint failure to `CONFLICT`; every other backend
|
|
844
831
|
* `SQLiteError` is contained by the same `DatabaseError` boundary described
|
|
845
|
-
* below. Querying, ordering, paging, and
|
|
846
|
-
*
|
|
847
|
-
*
|
|
848
|
-
* `
|
|
849
|
-
*
|
|
850
|
-
*
|
|
851
|
-
*
|
|
852
|
-
*
|
|
853
|
-
*
|
|
854
|
-
*
|
|
855
|
-
*
|
|
856
|
-
*
|
|
857
|
-
*
|
|
858
|
-
* `JSONDriver` migrate; a step referencing an undeclared table throws
|
|
832
|
+
* below. Querying, ordering, paging, and aggregation is native: `records` /
|
|
833
|
+
* `stream` compile a `QueryInput` to SQL with `compileQuerySQL`, and
|
|
834
|
+
* `aggregate` runs a SQL `COUNT`/`SUM`/`AVG`/`MIN`/`MAX` (through
|
|
835
|
+
* `compileAggregateSQL`) over the same compiled WHERE. `transaction` runs a
|
|
836
|
+
* callback inside native `BEGIN` / `COMMIT` / `ROLLBACK`, passing a scoped
|
|
837
|
+
* storage capability that becomes invalid after settlement. `migrate` runs the
|
|
838
|
+
* plan's projected DDL ({@link import('../compilers.js').stepToSQL}) inside
|
|
839
|
+
* whichever native transaction is active: joined into the active transaction
|
|
840
|
+
* callback when one exists (the core's versioned reconcile path wraps migrate +
|
|
841
|
+
* stamp in one native `BEGIN`, and node:sqlite rejects a nested `BEGIN`), or
|
|
842
|
+
* inside its own `database.transact` otherwise — a mid-plan failure rolls
|
|
843
|
+
* back atomically either way, an improvement over the non-atomic `MemoryDriver`
|
|
844
|
+
* / `JSONDriver` migrate; a step referencing an undeclared table throws
|
|
859
845
|
* `DatabaseError` `MIGRATION` before any DDL for that step runs. `snapshot` is
|
|
860
|
-
* capture-replay (SELECT the
|
|
861
|
-
*
|
|
862
|
-
*
|
|
863
|
-
*
|
|
864
|
-
*
|
|
865
|
-
*
|
|
866
|
-
*
|
|
867
|
-
*
|
|
868
|
-
*
|
|
869
|
-
*
|
|
870
|
-
*
|
|
871
|
-
*
|
|
872
|
-
*
|
|
873
|
-
*
|
|
874
|
-
*
|
|
875
|
-
*/
|
|
876
|
-
export declare class SQLiteDriver implements
|
|
846
|
+
* capture-replay (SELECT the named tables' rows, replay through DELETE + INSERT OR
|
|
847
|
+
* REPLACE inside a native transaction on rollback) rather than a SQL
|
|
848
|
+
* `SAVEPOINT`, since the core `transaction` calls the rollback thunk only on
|
|
849
|
+
* failure with no commit-on-success signal — a long-lived `SAVEPOINT` would
|
|
850
|
+
* leave the connection uncommitted (lost on close). Every backend interaction
|
|
851
|
+
* runs through `#guard`, which maps a thrown backend `SQLiteError` (or any
|
|
852
|
+
* unexpected non-`SQLiteError` throw) to a typed {@link DatabaseError} — never
|
|
853
|
+
* a raw backend error escapes `DriverInterface`: `CONSTRAINT` → `CONFLICT`, the
|
|
854
|
+
* wrapper's own `CLOSED` → `CLOSED`, `BUSY` (a locked database that outlasted
|
|
855
|
+
* the configured `timeout`) → a retryable `DRIVER` (`context.retryable` is
|
|
856
|
+
* `true`), and `UNKNOWN` / any other throw → `DRIVER`. The original error is
|
|
857
|
+
* preserved as `context.cause`. A `DatabaseError` this driver throws directly
|
|
858
|
+
* (`CLOSED` from the `#require` gate, `NOT_FOUND` from `#table`, `MIGRATION`
|
|
859
|
+
* from a migration-plan fault) passes through `#guard` unchanged, never
|
|
860
|
+
* re-wrapped.
|
|
861
|
+
*/
|
|
862
|
+
export declare class SQLiteDriver implements DriverInterface {
|
|
877
863
|
#private;
|
|
878
864
|
constructor(options?: SQLiteDriverOptions);
|
|
879
|
-
open(schema: readonly
|
|
865
|
+
open(schema: readonly TableSchema[]): Promise<void>;
|
|
880
866
|
close(): Promise<void>;
|
|
881
|
-
read(table: string, key: Key): Promise<
|
|
882
|
-
write(table: string, key: Key, row:
|
|
883
|
-
insert(table: string, key: Key, row:
|
|
867
|
+
read(table: string, key: Key): Promise<Row | undefined>;
|
|
868
|
+
write(table: string, key: Key, row: Row, options?: OperationOptions): Promise<void>;
|
|
869
|
+
insert(table: string, key: Key, row: Row, options?: OperationOptions): Promise<void>;
|
|
884
870
|
delete(table: string, key: Key, options?: OperationOptions): Promise<boolean>;
|
|
885
871
|
keys(table: string): Promise<readonly Key[]>;
|
|
886
|
-
scan(table: string): AsyncIterable<
|
|
872
|
+
scan(table: string): AsyncIterable<Row>;
|
|
887
873
|
clear(table: string): Promise<void>;
|
|
888
|
-
records(table: string, input:
|
|
889
|
-
aggregate(table: string, operation:
|
|
890
|
-
stream(table: string, input:
|
|
874
|
+
records(table: string, input: QueryInput): Promise<readonly Row[]>;
|
|
875
|
+
aggregate(table: string, operation: AggregateOperation, column: FieldPath, input: QueryInput): Promise<number | undefined>;
|
|
876
|
+
stream(table: string, input: QueryInput): AsyncIterable<Row>;
|
|
891
877
|
/**
|
|
892
|
-
*
|
|
878
|
+
* Begins a native transaction — real `BEGIN`, `COMMIT`, `ROLLBACK`.
|
|
893
879
|
*
|
|
894
880
|
* @remarks
|
|
895
881
|
* The callback receives a scoped {@link StorageInterface}. Fulfillment
|
|
@@ -901,23 +887,22 @@ export declare class SQLiteDriver implements DriverInterface_2 {
|
|
|
901
887
|
*/
|
|
902
888
|
transaction<R>(scope: (storage: StorageInterface) => Promise<R>): Promise<R>;
|
|
903
889
|
/**
|
|
904
|
-
*
|
|
890
|
+
* Applies a {@link Migration} plan by executing each step's projected DDL
|
|
905
891
|
* ({@link import('../compilers.js').stepToSQL}).
|
|
906
892
|
*
|
|
907
893
|
* @remarks
|
|
908
|
-
* Atomicity is provided by whichever native transaction is active: when
|
|
909
|
-
*
|
|
910
|
-
*
|
|
911
|
-
*
|
|
912
|
-
*
|
|
913
|
-
*
|
|
914
|
-
* generally) rejects a nested `BEGIN`, so this driver must never open a
|
|
894
|
+
* Atomicity is provided by whichever native transaction is active: when this
|
|
895
|
+
* driver's own `transaction()` callback is active (the core's versioned
|
|
896
|
+
* reconcile / migrate path joins migrate + stamp under one native `BEGIN`),
|
|
897
|
+
* the plan's DDL runs directly inside that enclosing transaction — a mid-plan
|
|
898
|
+
* failure rejects the callback and the driver rolls it back. node:sqlite (and
|
|
899
|
+
* SQLite generally) rejects a nested `BEGIN`, so this driver must never open a
|
|
915
900
|
* second native transaction while one is already open. Otherwise (no
|
|
916
901
|
* enclosing transaction), `migrate` wraps the plan in its own native
|
|
917
902
|
* `database.transaction` — atomic on its own: a mid-plan failure rolls
|
|
918
903
|
* back every DDL statement already applied by the plan. A scoped migration
|
|
919
904
|
* uses one fixed internal savepoint literal because the published SQLite
|
|
920
|
-
* wrapper intentionally exposes raw `
|
|
905
|
+
* wrapper intentionally exposes raw `execute` but no savepoint manager. That
|
|
921
906
|
* savepoint contains a caught inner migration so the outer callback
|
|
922
907
|
* transaction remains active and may continue safely. A step referencing a
|
|
923
908
|
* table not in this driver's declared schema (and that is not itself a
|
|
@@ -928,14 +913,14 @@ export declare class SQLiteDriver implements DriverInterface_2 {
|
|
|
928
913
|
*/
|
|
929
914
|
migrate(input: MigrationInput): Promise<void>;
|
|
930
915
|
/**
|
|
931
|
-
*
|
|
916
|
+
* Reads the persisted {@link DriverMetadata} from the reserved `_metadata` table.
|
|
932
917
|
*
|
|
933
918
|
* @returns The last-stamped `DriverMetadata`, or `undefined` when never stamped
|
|
934
919
|
* (or the stored row is malformed)
|
|
935
920
|
*/
|
|
936
921
|
metadata(): Promise<DriverMetadata | undefined>;
|
|
937
922
|
/**
|
|
938
|
-
*
|
|
923
|
+
* Persists an owned metadata snapshot into the reserved `_metadata` table's
|
|
939
924
|
* single row.
|
|
940
925
|
*
|
|
941
926
|
* @param metadata - The {@link DriverMetadata} to persist
|
|
@@ -945,7 +930,8 @@ export declare class SQLiteDriver implements DriverInterface_2 {
|
|
|
945
930
|
}
|
|
946
931
|
|
|
947
932
|
/**
|
|
948
|
-
*
|
|
933
|
+
* Configures {@link import('./factories.js').createSQLiteDriver}. The
|
|
934
|
+
* `@orkestrel/database/server` entry point exports this type.
|
|
949
935
|
*
|
|
950
936
|
* @remarks
|
|
951
937
|
* Threaded into the underlying `@orkestrel/sqlite` wrapper's connection.
|
|
@@ -954,11 +940,11 @@ export declare class SQLiteDriver implements DriverInterface_2 {
|
|
|
954
940
|
* {@link DatabaseError}); `timeout` is the busy-timeout in milliseconds before
|
|
955
941
|
* a locked database fails `BUSY`; `references` enables or disables foreign-key
|
|
956
942
|
* constraint enforcement, while omission retains the upstream default.
|
|
957
|
-
* `pragmas` is an ordered record of PRAGMA name to
|
|
958
|
-
*
|
|
959
|
-
*
|
|
960
|
-
*
|
|
961
|
-
*
|
|
943
|
+
* `pragmas` is an ordered record of PRAGMA name to value, applied through the
|
|
944
|
+
* wrapper's `pragma()` right after `connect()`, in insertion order (for
|
|
945
|
+
* example `{ journal_mode: 'WAL' }`). Core rows are number-typed — this driver
|
|
946
|
+
* never surfaces a `bigint`, so a stored integer beyond
|
|
947
|
+
* `Number.MAX_SAFE_INTEGER` reads back imprecisely (the wrapper's own
|
|
962
948
|
* `bigints` option is not exposed here).
|
|
963
949
|
*/
|
|
964
950
|
export declare interface SQLiteDriverOptions {
|
|
@@ -970,7 +956,11 @@ export declare interface SQLiteDriverOptions {
|
|
|
970
956
|
}
|
|
971
957
|
|
|
972
958
|
/**
|
|
973
|
-
*
|
|
959
|
+
* Projects one {@link MigrationStep} to SQLite DDL.
|
|
960
|
+
*
|
|
961
|
+
* @remarks
|
|
962
|
+
* These are the statements the SQLite driver's `migrate` executes for the step,
|
|
963
|
+
* inside whichever native transaction is active.
|
|
974
964
|
*
|
|
975
965
|
* @param step - The migration step
|
|
976
966
|
* @returns The statements that apply the step
|