@crvouga/sqlite-mem 0.2.0 → 1.1.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.
- package/AGENTS.md +1 -3
- package/COMPATIBILITY.md +1 -1
- package/README.md +37 -25
- package/dist/api/database.d.ts +20 -13
- package/dist/api/statement.d.ts +7 -17
- package/dist/errors/index.d.ts +14 -5
- package/dist/executor/pragma-engine.d.ts +25 -0
- package/dist/executor/result.d.ts +2 -2
- package/dist/functions/pragma-tvf.d.ts +8 -0
- package/dist/functions/table-valued-registry.d.ts +11 -0
- package/dist/functions/table-valued.d.ts +4 -4
- package/dist/index.d.ts +6 -12
- package/dist/index.js +742 -282
- package/dist/index.js.map +4 -4
- package/dist/runtime/options.d.ts +0 -3
- package/dist/unstable.d.ts +20 -0
- package/dist/unstable.js +8734 -0
- package/dist/unstable.js.map +7 -0
- package/package.json +6 -4
package/AGENTS.md
CHANGED
|
@@ -107,9 +107,8 @@ Hot / large files: `parser/parser.ts`, `executor/select.ts`, `executor/dml.ts`.
|
|
|
107
107
|
| `tests/fuzz/` | fast-check property tests (seeded); same two backends |
|
|
108
108
|
| `tests/harness/` | Compare/normalize helpers + harness unit tests |
|
|
109
109
|
| `tests/adapters/` | Wrappers for sqlite-mem and `bun:sqlite` |
|
|
110
|
-
| `tests/browser/` | Playwright smoke only — **not** the SQL oracle |
|
|
111
110
|
|
|
112
|
-
Examples of public API usage: `tests/contract/api/`, `tests/
|
|
111
|
+
Examples of public API usage: `tests/contract/api/`, `tests/contract/parameters/`, `tests/contract/determinism/`, `examples/react-vite`.
|
|
113
112
|
|
|
114
113
|
### Fuzz replay
|
|
115
114
|
|
|
@@ -148,7 +147,6 @@ bun run typecheck
|
|
|
148
147
|
bun run test:sqlite-compat
|
|
149
148
|
bun test # contract + fuzz + harness
|
|
150
149
|
bun run build
|
|
151
|
-
bun run test:browser # Playwright smoke
|
|
152
150
|
```
|
|
153
151
|
|
|
154
152
|
## PR and commits
|
package/COMPATIBILITY.md
CHANGED
|
@@ -86,7 +86,7 @@ Reference: **SQLite 3.51.0** (`bun:sqlite`). Inventory: `bun run scripts/fts-ora
|
|
|
86
86
|
bun run test:sqlite-compat # requirements + gate + contract/fuzz/harness
|
|
87
87
|
bun run inventory # oracle function/module inventory
|
|
88
88
|
bun run requirements # refresh SQLite.org requirements + coverage
|
|
89
|
-
bun run
|
|
89
|
+
bun run build && bun run verify-package # ESM browser build + isomorphic pack gates
|
|
90
90
|
```
|
|
91
91
|
|
|
92
92
|
Do not treat isolated unit tests of internal modules as proof of SQLite compatibility. The differential matrix runner is authoritative for SQL behavior; `test:sqlite-compat` is the release gate.
|
package/README.md
CHANGED
|
@@ -46,7 +46,7 @@ db.exec(`
|
|
|
46
46
|
)
|
|
47
47
|
`);
|
|
48
48
|
|
|
49
|
-
db.
|
|
49
|
+
db.prepare(`INSERT INTO users (name) VALUES (?)`).run("Alice");
|
|
50
50
|
|
|
51
51
|
const users = db.query<{ id: number; name: string }>(`SELECT * FROM users`);
|
|
52
52
|
console.log(users);
|
|
@@ -78,28 +78,27 @@ import { Database, SqliteError } from "@crvouga/sqlite-mem";
|
|
|
78
78
|
interface DatabaseOptions {
|
|
79
79
|
seed?: number | bigint; // default 1 — PRNG for random() / randomblob()
|
|
80
80
|
now?: Date | (() => Date); // default 2000-01-01T00:00:00.000Z
|
|
81
|
-
prng?: Prng; // optional; overrides seed
|
|
82
81
|
}
|
|
83
82
|
|
|
84
83
|
interface Database {
|
|
85
84
|
constructor(options?: DatabaseOptions);
|
|
86
|
-
exec(sql: string
|
|
85
|
+
exec(sql: string): void;
|
|
87
86
|
query<T = QueryRow>(sql: string, params?: BindValue[]): T[];
|
|
88
87
|
prepare(sql: string): Statement;
|
|
89
88
|
transaction<T>(fn: () => T): T;
|
|
90
89
|
snapshot(): Uint8Array;
|
|
91
90
|
restore(snapshot: Uint8Array): void;
|
|
92
91
|
close(): void;
|
|
92
|
+
[Symbol.dispose]?(): void; // alias for close() when Symbol.dispose exists
|
|
93
93
|
readonly changes: number;
|
|
94
94
|
readonly lastInsertRowid: number | bigint;
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
interface Statement {
|
|
98
|
-
bind(...params: BindValue[]): Statement;
|
|
99
98
|
run(...params: BindValue[]): RunResult;
|
|
100
99
|
all<T = QueryRow>(...params: BindValue[]): T[];
|
|
101
100
|
get<T = QueryRow>(...params: BindValue[]): T | undefined;
|
|
102
|
-
result(...params: BindValue[]): ResultSet; // includes columns when zero rows
|
|
101
|
+
result(...params: BindValue[]): ResultSet; // includes columns + values when zero rows
|
|
103
102
|
}
|
|
104
103
|
|
|
105
104
|
interface RunResult {
|
|
@@ -110,46 +109,48 @@ interface RunResult {
|
|
|
110
109
|
interface ResultSet {
|
|
111
110
|
columns: string[];
|
|
112
111
|
rows: QueryRow[];
|
|
113
|
-
values
|
|
112
|
+
values: QueryValue[][]; // always present (empty array for zero rows)
|
|
114
113
|
changes: number;
|
|
115
114
|
lastInsertRowid: number | bigint;
|
|
116
115
|
}
|
|
117
116
|
|
|
118
117
|
class SqliteError extends Error {
|
|
119
118
|
readonly category: ErrorCategory; // syntax, no_such_table, constraint_unique, misuse, …
|
|
120
|
-
readonly sqliteCode
|
|
119
|
+
readonly sqliteCode: string; // always set; default "SQLITE_ERROR"
|
|
120
|
+
readonly code: string; // === sqliteCode (Node err.code convention)
|
|
121
121
|
}
|
|
122
122
|
```
|
|
123
123
|
|
|
124
|
-
Stick to `Database`, `Statement`, and `SqliteError` for application code.
|
|
124
|
+
Stick to `Database`, `Statement`, and `SqliteError` for application code. Advanced internals (`parse`, `tokenize`, `evalExpr`, snapshot codec pieces, `SqlValue` utilities, `Prng`, …) are available only from `@crvouga/sqlite-mem/unstable` and are **exempt from semver**.
|
|
125
125
|
|
|
126
126
|
### Method semantics
|
|
127
127
|
|
|
128
128
|
| Method | Behavior |
|
|
129
129
|
| --- | --- |
|
|
130
|
-
| `exec(sql
|
|
131
|
-
| `query(sql, params?)` |
|
|
132
|
-
| `prepare(sql)` | Parses immediately; AST is reused. `run` / `all` / `get` / `result`
|
|
133
|
-
| `transaction(fn)` | If idle: `BEGIN` → `fn()` → `COMMIT`, or `ROLLBACK` + rethrow. If already in a transaction: nested savepoint. Nested SQL `BEGIN` still errors. |
|
|
130
|
+
| `exec(sql)` | Runs all semicolon-separated statements; **discards** row results (`void`). Does **not** accept bind parameters. Read `db.changes` / `db.lastInsertRowid` afterward if needed (counters reflect the **most recent** completed statement, matching SQLite). |
|
|
131
|
+
| `query(sql, params?)` | **Single statement only** (trailing `;` is fine). Returns all rows. Multi-statement scripts throw `misuse`. |
|
|
132
|
+
| `prepare(sql)` | **Single statement only**. Parses immediately; AST is reused. Pass binds as rest args to `run` / `all` / `get` / `result` on each call. |
|
|
133
|
+
| `transaction(fn)` | If idle: `BEGIN` → `fn()` → `COMMIT`, or `ROLLBACK` + rethrow. If already in a transaction: nested savepoint. Nested SQL `BEGIN` still errors. `close()` inside `fn` throws `misuse`. |
|
|
134
134
|
| `snapshot` / `restore` | Custom binary format (see below). |
|
|
135
|
-
| `close()` | Idempotent; rolls back an open transaction; further ops throw `misuse`. |
|
|
135
|
+
| `close()` | Idempotent; rolls back an open SQL transaction; further ops throw `misuse`. Also available as `[Symbol.dispose]` when supported. |
|
|
136
136
|
|
|
137
|
-
SQL `BEGIN` / `COMMIT` / `ROLLBACK` / `SAVEPOINT` / `RELEASE` are first-class. Empty SQL throws `misuse` (`empty statement`).
|
|
137
|
+
SQL `BEGIN` / `COMMIT` / `ROLLBACK` / `SAVEPOINT` / `RELEASE` are first-class. Empty / comment-only SQL on `prepare` / `query` throws `misuse` (`empty statement`), matching SQLite prepare failure.
|
|
138
138
|
|
|
139
139
|
### Parameter binding
|
|
140
140
|
|
|
141
141
|
Supported styles: `?`, `?NNN`, `:name`, `@name`, `$name`.
|
|
142
142
|
|
|
143
|
-
- The JS API takes
|
|
143
|
+
- The JS API takes **rest args** (or a positional array into `query`) only — there is **no** sticky `bind()` and **no** `bind({ name: value })`.
|
|
144
144
|
- Named parameters occupy slots in **first-occurrence order**; repeated names share one slot.
|
|
145
145
|
- Prefixes are part of the name: `@x`, `$x`, and `:x` are **three different** parameters.
|
|
146
146
|
- Names are lowercased for lookup (`:Left` ≡ `:left`).
|
|
147
147
|
- Bindable: `null`, `string`, finite `number`, `bigint`, `boolean` → `0`/`1`, `Uint8Array` / `ArrayBuffer`.
|
|
148
|
-
- Rejected
|
|
148
|
+
- Rejected (`misuse`): `DataView`, typed-array views other than `Uint8Array`, `SharedArrayBuffer` / SAB-backed buffers.
|
|
149
|
+
- Rejected (`datatype_mismatch`): `undefined`, `Date`, plain objects, `NaN` / `Infinity`.
|
|
149
150
|
|
|
150
151
|
```ts
|
|
151
152
|
db.query(`SELECT ? AS a, :name AS b`, [1, "Alice"]);
|
|
152
|
-
db.prepare(`SELECT @id AS id`).
|
|
153
|
+
db.prepare(`SELECT @id AS id`).get(42);
|
|
153
154
|
```
|
|
154
155
|
|
|
155
156
|
### Returned JavaScript types
|
|
@@ -166,12 +167,13 @@ Duplicate column names collapse in row objects (last write wins). Use `stmt.resu
|
|
|
166
167
|
|
|
167
168
|
### Snapshots
|
|
168
169
|
|
|
169
|
-
- Format magic `SQLM` — **not** a portable `.sqlite` file and not loadable by the SQLite CLI.
|
|
170
|
+
- Format magic `SQLM` followed by an explicit little-endian format-version `u32` — **not** a portable `.sqlite` file and not loadable by the SQLite CLI.
|
|
170
171
|
- Round-trips ordinary tables, views, indexes, change counters, PRNG state, and clock.
|
|
171
172
|
- **Not** encoded: triggers, ATTACH’d schemas, virtual tables (FTS / RTREE / …), `userVersion`.
|
|
172
173
|
- Cannot `restore()` while a transaction is open.
|
|
173
174
|
- `restore()` replaces `now` with a fixed clock from the snapshot (a live `() => Date` is overwritten).
|
|
174
|
-
- Equivalent databases produce byte-identical snapshots (schema/rows sorted)
|
|
175
|
+
- Equivalent databases produce byte-identical snapshots (schema/rows sorted) **within a single library version**.
|
|
176
|
+
- **Compatibility policy:** newer library versions can always restore older snapshots; older libraries cannot restore newer format versions (`snapshot_version` / `SQLITE_FORMAT`). Corrupt magic yields a distinct error.
|
|
175
177
|
|
|
176
178
|
## Determinism
|
|
177
179
|
|
|
@@ -179,7 +181,7 @@ The engine is deterministic by default. Invariants:
|
|
|
179
181
|
|
|
180
182
|
| Source | Default | Override / notes |
|
|
181
183
|
| --- | --- | --- |
|
|
182
|
-
| `random()` / `randomblob()` | Seeded xorshift64* (`seed: 1`) | `new Database({ seed })`
|
|
184
|
+
| `random()` / `randomblob()` | Seeded xorshift64* (`seed: 1`) | `new Database({ seed })` |
|
|
183
185
|
| `date('now')` / friends | Fixed `2000-01-01T00:00:00.000Z` | `new Database({ now: Date \| (() => Date) })` |
|
|
184
186
|
| Table scans | Rowid order | Same order after `snapshot`/`restore` |
|
|
185
187
|
| Snapshots | Sorted schema/rows + PRNG state + clock | Restored into PRNG and `now` |
|
|
@@ -194,6 +196,15 @@ SQLITE_MEM_FUZZ_SEED=12345 bun test tests/fuzz
|
|
|
194
196
|
SQLITE_MEM_FUZZ_SEED=12345 SQLITE_MEM_FUZZ_PATH='0:1' bun test tests/fuzz # exact replay
|
|
195
197
|
```
|
|
196
198
|
|
|
199
|
+
## Stability policy
|
|
200
|
+
|
|
201
|
+
The exports of the main entry (`@crvouga/sqlite-mem`) are **frozen**:
|
|
202
|
+
|
|
203
|
+
- **Never** outside a major: removals, renames, signature changes, or changes to documented behavior of the stable surface.
|
|
204
|
+
- **Allowed in minors:** additions (new methods, new optional `DatabaseOptions` fields, new `ErrorCategory` values). Consumers that `switch` on `category` must include a default case — new categories may appear without a major bump.
|
|
205
|
+
- **`@crvouga/sqlite-mem/unstable`** is exempt from semver and may change or disappear in any release.
|
|
206
|
+
- **Snapshots:** newer library → can restore older blobs; older library → cannot restore newer format versions; byte-identical snapshot guarantee holds only within one library version.
|
|
207
|
+
|
|
197
208
|
## Compatibility notes for integrators
|
|
198
209
|
|
|
199
210
|
Goal: drop-in SQL behavior vs SQLite **3.51.0**. Full matrix: [COMPATIBILITY.md](COMPATIBILITY.md).
|
|
@@ -205,20 +216,21 @@ Goal: drop-in SQL behavior vs SQLite **3.51.0**. Full matrix: [COMPATIBILITY.md]
|
|
|
205
216
|
- FTS3/4/5 — largely implemented; shadow-table change counters intentionally diverge; some edges partial
|
|
206
217
|
- `EXPLAIN` / `EXPLAIN QUERY PLAN` — stub shapes, not real bytecode
|
|
207
218
|
- `INDEXED BY` / `NOT INDEXED` — parsed and discarded
|
|
208
|
-
- Unknown `PRAGMA` succeeds with an empty result (SQLite-like)
|
|
219
|
+
- Unknown statement `PRAGMA` succeeds with an empty result (SQLite-like). All oracle-exposed `pragma_*` eponymous TVFs are supported (`SELECT * FROM pragma_table_info('t')`, bare `FROM pragma_database_list`, …). Storage/journal getters return bun `:memory:`-compatible defaults.
|
|
209
220
|
|
|
210
221
|
## Common pitfalls
|
|
211
222
|
|
|
212
223
|
1. **Do not `await`** — the API is sync.
|
|
213
|
-
2. **No named-object binds
|
|
214
|
-
3. **
|
|
215
|
-
4. **`exec` returns `void
|
|
224
|
+
2. **No named-object binds and no sticky `bind()`** — pass positional rest args / arrays in declaration order to `query` / `run` / `all` / `get` / `result`.
|
|
225
|
+
3. **`query` / `prepare` are single-statement only** — multi-statement scripts belong in `exec()` (which does not take bind parameters).
|
|
226
|
+
4. **`exec` returns `void` and takes no params** — use `db.prepare(…).run(…)` or `db.query(…)` for binds; use `db.changes` / `stmt.run()` for counters.
|
|
216
227
|
5. **`'now'` is not wall-clock** unless you pass `{ now: () => new Date() }`. Default is year 2000.
|
|
217
228
|
6. **`random()` is seeded**, not OS entropy; snapshots restore the PRNG.
|
|
218
229
|
7. **Snapshots are not `.sqlite` files** and do not round-trip FTS / triggers / ATTACH.
|
|
219
230
|
8. **No better-sqlite3 extras** — no `iterate`, `pluck`/`raw`, `safeIntegers` option, `pragma()` helper, `loadExtension`, or SQLite-file `serialize()`.
|
|
220
|
-
9. **Do not bind `Date` objects** — store unixepoch integers or ISO text.
|
|
231
|
+
9. **Do not bind `Date` objects** — store unixepoch integers or ISO text. Do not bind `DataView` / non-`Uint8Array` typed arrays.
|
|
221
232
|
10. **Do not use `Number.isInteger` for SQL REAL vs INTEGER** — use SQL `typeof()`.
|
|
233
|
+
11. **Do not import `@crvouga/sqlite-mem/unstable` in application code** unless you accept breakage in any release.
|
|
222
234
|
|
|
223
235
|
Working examples beyond this README: `examples/react-vite`, `tests/contract/api/`, `tests/contract/parameters/`, `tests/browser/run.ts`.
|
|
224
236
|
|
package/dist/api/database.d.ts
CHANGED
|
@@ -14,15 +14,17 @@ import { Statement } from "./statement.js";
|
|
|
14
14
|
*
|
|
15
15
|
* const db = new Database();
|
|
16
16
|
* db.exec("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT NOT NULL)");
|
|
17
|
-
* db.
|
|
17
|
+
* db.prepare("INSERT INTO users (name) VALUES (?)").run("Alice");
|
|
18
18
|
* const users = db.query<{ id: number; name: string }>("SELECT * FROM users");
|
|
19
19
|
* ```
|
|
20
20
|
*/
|
|
21
21
|
export declare class Database {
|
|
22
|
-
/** Seed used to construct the PRNG
|
|
22
|
+
/** Seed used to construct the PRNG. */
|
|
23
23
|
readonly seed: number | bigint;
|
|
24
24
|
private closed;
|
|
25
25
|
private transactionSequence;
|
|
26
|
+
/** Depth of active {@link transaction} callbacks (not SQL BEGIN). */
|
|
27
|
+
private apiTransactionDepth;
|
|
26
28
|
/**
|
|
27
29
|
* Create an empty in-memory database.
|
|
28
30
|
*
|
|
@@ -32,33 +34,34 @@ export declare class Database {
|
|
|
32
34
|
/**
|
|
33
35
|
* Execute SQL for its side effects (DDL/DML). Multiple statements are allowed.
|
|
34
36
|
*
|
|
37
|
+
* Does not accept bind parameters — use {@link prepare} or {@link query}.
|
|
38
|
+
*
|
|
35
39
|
* @param sql - SQL to run (semicolon-separated statements are ok).
|
|
36
|
-
* @
|
|
37
|
-
* @throws {SqliteError} If the database is closed or the SQL fails.
|
|
40
|
+
* @throws {SqliteError} If the database is closed, extra arguments are passed, or the SQL fails.
|
|
38
41
|
*/
|
|
39
|
-
exec(sql: string
|
|
42
|
+
exec(sql: string): void;
|
|
40
43
|
/**
|
|
41
|
-
* Execute a query and return all rows as objects keyed by column name.
|
|
44
|
+
* Execute a single-statement query and return all rows as objects keyed by column name.
|
|
42
45
|
*
|
|
43
46
|
* @typeParam T - Row shape. Defaults to {@link QueryRow}.
|
|
44
|
-
* @param sql -
|
|
47
|
+
* @param sql - A single SQL statement (trailing `;` is fine).
|
|
45
48
|
* @param params - Bound parameters for `?` / `:name` placeholders.
|
|
46
49
|
* @returns All result rows.
|
|
47
|
-
* @throws {SqliteError} If the database is closed or
|
|
50
|
+
* @throws {SqliteError} If the database is closed, `sql` is not a single statement, or execution fails.
|
|
48
51
|
*/
|
|
49
52
|
query<T = QueryRow>(sql: string, params?: readonly BindValue[]): T[];
|
|
50
53
|
/**
|
|
51
|
-
* Compile
|
|
54
|
+
* Compile a single SQL statement into a reusable {@link Statement}.
|
|
52
55
|
*
|
|
53
|
-
* @param sql - SQL
|
|
54
|
-
* @throws {SqliteError} If the database is closed or `sql` cannot be
|
|
56
|
+
* @param sql - A single SQL statement (trailing `;` is fine). Multi-statement scripts are rejected.
|
|
57
|
+
* @throws {SqliteError} If the database is closed or `sql` cannot be prepared as one statement.
|
|
55
58
|
*/
|
|
56
59
|
prepare(sql: string): Statement;
|
|
57
60
|
/**
|
|
58
61
|
* Run `fn` inside a transaction. Commits on success; rolls back if `fn` throws.
|
|
59
62
|
*
|
|
60
63
|
* Nested calls use SAVEPOINTs so an inner failure does not abort the outer
|
|
61
|
-
* transaction.
|
|
64
|
+
* transaction. Calling {@link close} from inside `fn` throws `misuse`.
|
|
62
65
|
*
|
|
63
66
|
* @param fn - Work to run while the transaction is open.
|
|
64
67
|
* @returns The value returned by `fn`.
|
|
@@ -77,6 +80,8 @@ export declare class Database {
|
|
|
77
80
|
* Replace this database's contents with a blob from {@link snapshot}.
|
|
78
81
|
*
|
|
79
82
|
* Restores PRNG state and the clock when the snapshot includes them (v2).
|
|
83
|
+
* Newer library versions can restore older snapshots; older libraries cannot
|
|
84
|
+
* restore newer format versions.
|
|
80
85
|
*
|
|
81
86
|
* @param snapshot - Bytes previously returned by {@link snapshot}.
|
|
82
87
|
* @throws {SqliteError} If the database is closed, a transaction is open, or the blob is invalid.
|
|
@@ -85,7 +90,8 @@ export declare class Database {
|
|
|
85
90
|
/**
|
|
86
91
|
* Close the database. Further SQL throws {@link SqliteError}. Idempotent.
|
|
87
92
|
*
|
|
88
|
-
* Rolls back an open transaction, if any.
|
|
93
|
+
* Rolls back an open SQL transaction, if any. Throws if called from inside
|
|
94
|
+
* a {@link transaction} callback.
|
|
89
95
|
*/
|
|
90
96
|
close(): void;
|
|
91
97
|
/**
|
|
@@ -100,5 +106,6 @@ export declare class Database {
|
|
|
100
106
|
* @throws {SqliteError} If the database is closed.
|
|
101
107
|
*/
|
|
102
108
|
get lastInsertRowid(): number | bigint;
|
|
109
|
+
private prepareSingle;
|
|
103
110
|
}
|
|
104
111
|
export type { DatabaseOptions };
|
package/dist/api/statement.d.ts
CHANGED
|
@@ -10,9 +10,9 @@ export interface RunResult {
|
|
|
10
10
|
/**
|
|
11
11
|
* Prepared SQL statement bound to a {@link Database}.
|
|
12
12
|
*
|
|
13
|
-
* Create with {@link Database.prepare}.
|
|
14
|
-
* {@link all}, {@link get}, or {@link result}
|
|
15
|
-
*
|
|
13
|
+
* Create with {@link Database.prepare}. Pass bind values as rest arguments to
|
|
14
|
+
* {@link run}, {@link all}, {@link get}, or {@link result} on each call
|
|
15
|
+
* (stateless — there is no sticky `bind()`).
|
|
16
16
|
*
|
|
17
17
|
* @example
|
|
18
18
|
* ```ts
|
|
@@ -28,25 +28,15 @@ export interface RunResult {
|
|
|
28
28
|
export declare class Statement {
|
|
29
29
|
private readonly database;
|
|
30
30
|
private readonly sql;
|
|
31
|
-
private bound;
|
|
32
31
|
private namedPlan;
|
|
33
32
|
private env;
|
|
34
33
|
private statements;
|
|
35
34
|
private schemaVersion;
|
|
36
35
|
private constructor();
|
|
37
|
-
/**
|
|
38
|
-
* Store parameters for later {@link run} / {@link all} / {@link get} / {@link result}.
|
|
39
|
-
*
|
|
40
|
-
* Supports positional `?` / `?NNN` and named `:name` / `@name` / `$name` placeholders.
|
|
41
|
-
*
|
|
42
|
-
* @param params - Values to bind, in placeholder order.
|
|
43
|
-
* @returns `this` for chaining.
|
|
44
|
-
*/
|
|
45
|
-
bind(...params: BindValue[]): Statement;
|
|
46
36
|
/**
|
|
47
37
|
* Execute for side effects (INSERT / UPDATE / DELETE / DDL).
|
|
48
38
|
*
|
|
49
|
-
* @param params -
|
|
39
|
+
* @param params - Bind values for this call only.
|
|
50
40
|
* @returns Mutation counters for this execution.
|
|
51
41
|
* @throws {SqliteError} If the database is closed, the statement is empty, or execution fails.
|
|
52
42
|
*/
|
|
@@ -55,7 +45,7 @@ export declare class Statement {
|
|
|
55
45
|
* Execute and return every result row as an object keyed by column name.
|
|
56
46
|
*
|
|
57
47
|
* @typeParam T - Row shape. Defaults to {@link QueryRow}.
|
|
58
|
-
* @param params -
|
|
48
|
+
* @param params - Bind values for this call only.
|
|
59
49
|
* @throws {SqliteError} If the database is closed, the statement is empty, or execution fails.
|
|
60
50
|
*/
|
|
61
51
|
all<T = QueryRow>(...params: BindValue[]): T[];
|
|
@@ -65,7 +55,7 @@ export declare class Statement {
|
|
|
65
55
|
* Use this when you need metadata for an empty result (column names with zero rows).
|
|
66
56
|
* {@link all} only returns row objects.
|
|
67
57
|
*
|
|
68
|
-
* @param params -
|
|
58
|
+
* @param params - Bind values for this call only.
|
|
69
59
|
* @throws {SqliteError} If the database is closed, the statement is empty, or execution fails.
|
|
70
60
|
*/
|
|
71
61
|
result(...params: BindValue[]): ResultSet;
|
|
@@ -73,7 +63,7 @@ export declare class Statement {
|
|
|
73
63
|
* Execute and return the first row, or `undefined` if there are no rows.
|
|
74
64
|
*
|
|
75
65
|
* @typeParam T - Row shape. Defaults to {@link QueryRow}.
|
|
76
|
-
* @param params -
|
|
66
|
+
* @param params - Bind values for this call only.
|
|
77
67
|
* @throws {SqliteError} If the database is closed, the statement is empty, or execution fails.
|
|
78
68
|
*/
|
|
79
69
|
get<T = QueryRow>(...params: BindValue[]): T | undefined;
|
package/dist/errors/index.d.ts
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
|
-
/** Coarse classification of {@link SqliteError} for catch-site branching.
|
|
2
|
-
|
|
1
|
+
/** Coarse classification of {@link SqliteError} for catch-site branching.
|
|
2
|
+
*
|
|
3
|
+
* New categories may be added in minor releases. Consumers that switch on
|
|
4
|
+
* `category` must include a default case.
|
|
5
|
+
*/
|
|
6
|
+
export type ErrorCategory = "syntax" | "no_such_table" | "no_such_column" | "constraint_unique" | "constraint_primary" | "constraint_notnull" | "constraint_check" | "constraint_foreign" | "constraint" | "transaction" | "datatype_mismatch" | "unsupported" | "misuse" | "snapshot_version" | "other" | (string & {});
|
|
3
7
|
/**
|
|
4
8
|
* Engine error. `name` is always `"SqliteError"`.
|
|
5
9
|
*
|
|
10
|
+
* `sqliteCode` and Node's conventional `code` property are always set (default
|
|
11
|
+
* `"SQLITE_ERROR"` when no more specific code applies).
|
|
12
|
+
*
|
|
6
13
|
* @example
|
|
7
14
|
* ```ts
|
|
8
15
|
* import { Database, SqliteError } from "@crvouga/sqlite-mem";
|
|
@@ -20,12 +27,14 @@ export type ErrorCategory = "syntax" | "no_such_table" | "no_such_column" | "con
|
|
|
20
27
|
export declare class SqliteError extends Error {
|
|
21
28
|
/** Coarse error class (constraint vs syntax vs missing object, …). */
|
|
22
29
|
readonly category: ErrorCategory;
|
|
23
|
-
/**
|
|
24
|
-
readonly sqliteCode
|
|
30
|
+
/** SQLite result-code name such as `SQLITE_CONSTRAINT_UNIQUE`. */
|
|
31
|
+
readonly sqliteCode: string;
|
|
32
|
+
/** Same value as {@link sqliteCode} (Node `err.code` convention). */
|
|
33
|
+
readonly code: string;
|
|
25
34
|
/**
|
|
26
35
|
* @param message - Human-readable error text.
|
|
27
36
|
* @param category - Coarse class; defaults to `"other"`.
|
|
28
|
-
* @param sqliteCode -
|
|
37
|
+
* @param sqliteCode - SQLite result-code name; defaults to `"SQLITE_ERROR"`.
|
|
29
38
|
*/
|
|
30
39
|
constructor(message: string, category?: ErrorCategory, sqliteCode?: string);
|
|
31
40
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared PRAGMA query engine used by statement-form `PRAGMA …` and `pragma_*` TVFs.
|
|
3
|
+
*/
|
|
4
|
+
import type { Expr } from "../ast/nodes.js";
|
|
5
|
+
import { type SqlValue } from "../types/value.js";
|
|
6
|
+
import type { ExecutionEnv } from "./env.js";
|
|
7
|
+
export interface PragmaQueryResult {
|
|
8
|
+
columns: string[];
|
|
9
|
+
rows: SqlValue[][];
|
|
10
|
+
}
|
|
11
|
+
/** Oracle-exposed pragma_* TVF base names (without the `pragma_` prefix). */
|
|
12
|
+
export declare const PRAGMA_TVF_NAMES: readonly ["analysis_limit", "application_id", "auto_vacuum", "automatic_index", "busy_timeout", "cache_size", "cache_spill", "cell_size_check", "checkpoint_fullfsync", "collation_list", "compile_options", "count_changes", "data_version", "database_list", "default_cache_size", "defer_foreign_keys", "empty_result_callbacks", "encoding", "foreign_key_check", "foreign_key_list", "foreign_keys", "freelist_count", "full_column_names", "fullfsync", "function_list", "hard_heap_limit", "ignore_check_constraints", "index_info", "index_list", "index_xinfo", "integrity_check", "journal_mode", "journal_size_limit", "legacy_alter_table", "locking_mode", "max_page_count", "module_list", "optimize", "page_count", "page_size", "pragma_list", "query_only", "quick_check", "read_uncommitted", "recursive_triggers", "reverse_unordered_selects", "schema_version", "secure_delete", "short_column_names", "soft_heap_limit", "synchronous", "table_info", "table_list", "table_xinfo", "temp_store", "threads", "trusted_schema", "user_version", "writable_schema"];
|
|
13
|
+
/** Full pragma name list for `pragma_pragma_list` (includes names without TVFs). */
|
|
14
|
+
export declare const PRAGMA_LIST_NAMES: string[];
|
|
15
|
+
export declare function isPragmaTvfName(name: string): boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Query a pragma by name with optional SQL values (TVF args or evaluated statement args).
|
|
18
|
+
* Read-only — writers stay in {@link executePragma}.
|
|
19
|
+
*/
|
|
20
|
+
export declare function queryPragma(name: string, args: readonly SqlValue[], env: ExecutionEnv): PragmaQueryResult;
|
|
21
|
+
/** Evaluate a statement-form pragma argument expression to a SQL value list. */
|
|
22
|
+
export declare function evalPragmaArgs(expr: Expr | null, env: ExecutionEnv): SqlValue[];
|
|
23
|
+
export declare function evalPragmaSetValue(expr: Expr, env: ExecutionEnv): SqlValue;
|
|
24
|
+
export declare function coercePragmaInt(value: SqlValue): number;
|
|
25
|
+
export declare function coercePragmaTruthy(value: SqlValue): boolean;
|
|
@@ -5,8 +5,8 @@ export interface ResultSet {
|
|
|
5
5
|
columns: string[];
|
|
6
6
|
/** Named rows. Duplicate column names keep the last value. */
|
|
7
7
|
rows: QueryRow[];
|
|
8
|
-
/** Positional rows
|
|
9
|
-
values
|
|
8
|
+
/** Positional rows; always present (empty array when there are zero rows). */
|
|
9
|
+
values: QueryValue[][];
|
|
10
10
|
/** Rows changed by the most recent mutating statement in this execution. */
|
|
11
11
|
changes: number;
|
|
12
12
|
/** Rowid of the most recent INSERT in this execution. */
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Register all oracle-exposed `pragma_*` eponymous table-valued functions.
|
|
3
|
+
* Imported for side effects from table-valued / select.
|
|
4
|
+
*/
|
|
5
|
+
import { isPragmaTvfName } from "../executor/pragma-engine.js";
|
|
6
|
+
/** Idempotent registration of every oracle `pragma_*` TVF. */
|
|
7
|
+
export declare function ensurePragmaTvfsRegistered(): void;
|
|
8
|
+
export { isPragmaTvfName };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ExecutionEnv, ScopeRow } from "../executor/env.js";
|
|
2
|
+
import type { SqlValue } from "../types/value.js";
|
|
3
|
+
export interface TableValuedResult {
|
|
4
|
+
columns: string[];
|
|
5
|
+
rows: ScopeRow[];
|
|
6
|
+
}
|
|
7
|
+
export type TableValuedFn = (args: SqlValue[], alias: string | null, env: ExecutionEnv) => TableValuedResult;
|
|
8
|
+
export declare function registerTableValuedFunction(name: string, fn: TableValuedFn): void;
|
|
9
|
+
export declare function getTableValuedFunction(name: string): TableValuedFn | undefined;
|
|
10
|
+
export declare function listRegisteredTableValuedFunctions(): string[];
|
|
11
|
+
export declare function hasRegisteredTableValuedFunction(name: string): boolean;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { Expr } from "../ast/nodes.js";
|
|
2
2
|
import type { ExecutionEnv, ScopeRow } from "../executor/env.js";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
}
|
|
3
|
+
import { registerTableValuedFunction, type TableValuedResult } from "./table-valued-registry.js";
|
|
4
|
+
export type { TableValuedResult };
|
|
5
|
+
export { registerTableValuedFunction };
|
|
7
6
|
export declare function evaluateTableFunction(name: string, args: Expr[], alias: string | null, env: ExecutionEnv, scope?: ScopeRow | null, parent?: import("../expressions/context.js").EvalContext): TableValuedResult;
|
|
8
7
|
export declare function listTableValuedFunctions(): string[];
|
|
8
|
+
export declare function hasTableValuedFunction(name: string): boolean;
|
package/dist/index.d.ts
CHANGED
|
@@ -5,29 +5,23 @@
|
|
|
5
5
|
* Deterministic by default (`random()` seed `1`, `'now'` = `2000-01-01T00:00:00.000Z`).
|
|
6
6
|
* Zero WASM, native bindings, or filesystem.
|
|
7
7
|
*
|
|
8
|
+
* Advanced / internal helpers live under `@crvouga/sqlite-mem/unstable` and are
|
|
9
|
+
* exempt from semver.
|
|
10
|
+
*
|
|
8
11
|
* @example
|
|
9
12
|
* ```ts
|
|
10
13
|
* import { Database } from "@crvouga/sqlite-mem";
|
|
11
14
|
*
|
|
12
15
|
* const db = new Database();
|
|
13
16
|
* db.exec("CREATE TABLE t (id INTEGER PRIMARY KEY, name TEXT)");
|
|
14
|
-
* db.
|
|
17
|
+
* db.prepare("INSERT INTO t (name) VALUES (?)").run("Ada");
|
|
15
18
|
* const rows = db.query<{ id: number; name: string }>("SELECT * FROM t");
|
|
16
19
|
* ```
|
|
17
20
|
*
|
|
18
21
|
* @module
|
|
19
22
|
*/
|
|
20
|
-
export
|
|
23
|
+
export { Database, type DatabaseOptions } from "./api/database.js";
|
|
21
24
|
export { Statement, type RunResult } from "./api/statement.js";
|
|
22
|
-
export type { Expr } from "./ast/nodes.js";
|
|
23
25
|
export { SqliteError, type ErrorCategory } from "./errors/index.js";
|
|
24
26
|
export type { ResultSet } from "./executor/result.js";
|
|
25
|
-
export type {
|
|
26
|
-
export { evalExpr } from "./expressions/eval.js";
|
|
27
|
-
export { globMatch, likeMatch } from "./expressions/like.js";
|
|
28
|
-
export { tokenize, type Token, type TokenKind } from "./lexer/tokenize.js";
|
|
29
|
-
export { parse, type ParsedStatement } from "./parser/index.js";
|
|
30
|
-
export { type Clock, DEFAULT_DATABASE_SEED, DEFAULT_NOW, deriveSeed, fixedClock, Prng, resolveClock, } from "./runtime/index.js";
|
|
31
|
-
export { type DecodedSnapshot, decodeDatabaseState, encodeDatabaseState, type SnapshotRuntime, } from "./serialization/index.js";
|
|
32
|
-
export type { DatabaseState } from "./storage/database-state.js";
|
|
33
|
-
export { type Affinity, affinityFromTypeName, applyAffinity, asSqlJsonText, asSqlReal, type BindValue, canonicalizeNumber, cloneSqlValue, coerceToNumber, compareSql, isSqlJsonText, isSqlReal, isTruthySql, type QueryRow, type QueryValue, SqlJsonText, SqlReal, type SqlValue, type StorageClass, sqlValueEquals, storageClassOf, toInteger, typeofSql, utf8Decode, utf8Encode, } from "./types/value.js";
|
|
27
|
+
export type { BindValue, QueryRow, QueryValue } from "./types/value.js";
|