@crvouga/sqlite-mem 1.2.0 → 1.3.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/README.md +12 -4
- package/compat/divergences.json +1 -1
- package/dist/api/statement.d.ts +1 -0
- package/dist/executor/env.d.ts +2 -0
- package/dist/index.js +135 -26
- package/dist/index.js.map +3 -3
- package/dist/parser/index.d.ts +7 -1
- package/dist/parser/parser.d.ts +12 -2
- package/dist/schema/master-sql.d.ts +10 -0
- package/dist/unstable.js +20 -8
- package/dist/unstable.js.map +2 -2
- package/package.json +6 -2
package/README.md
CHANGED
|
@@ -6,10 +6,11 @@ Pure TypeScript, completely in-memory SQLite implementation aiming for **full SQ
|
|
|
6
6
|
- **Zero** WASM, native bindings, workers, or filesystem dependencies
|
|
7
7
|
- Entire database stored in memory
|
|
8
8
|
- **Synchronous** ESM-only API (no Promises, no `require`)
|
|
9
|
-
- **
|
|
9
|
+
- **SQL dialect verified** against SQLite 3.51.0 / 3.53.0 (`bun:sqlite`) via differential contracts + fail-closed gate
|
|
10
|
+
- **Not** a drop-in for `sql.js` / `sqlite-wasm` APIs, on-disk `.sqlite` files, or user-defined functions
|
|
10
11
|
- Intentional differences: deterministic `random()` / `'now'` by default, and a custom snapshot format (not `.sqlite` files)
|
|
11
12
|
|
|
12
|
-
See [COMPATIBILITY.md](COMPATIBILITY.md) for the matrix
|
|
13
|
+
See [COMPATIBILITY.md](COMPATIBILITY.md) for the matrix, [docs/DROP-IN-CONTRACT.md](docs/DROP-IN-CONTRACT.md) for the falsifiable claim, and [docs/GAP-ANALYSIS.md](docs/GAP-ANALYSIS.md) for what is still unproven. Agents: [AGENTS.md](AGENTS.md).
|
|
13
14
|
|
|
14
15
|
## Documentation
|
|
15
16
|
|
|
@@ -19,6 +20,11 @@ See [COMPATIBILITY.md](COMPATIBILITY.md) for the matrix and [COMPATIBILITY-AUDIT
|
|
|
19
20
|
| [AGENTS.md](AGENTS.md) | Architecture, how to change code, test/compat gates |
|
|
20
21
|
| [COMPATIBILITY.md](COMPATIBILITY.md) | Feature matrix + verify commands |
|
|
21
22
|
| [COMPATIBILITY-AUDIT.md](COMPATIBILITY-AUDIT.md) | Audit evidence |
|
|
23
|
+
| [docs/DROP-IN-CONTRACT.md](docs/DROP-IN-CONTRACT.md) | Falsifiable drop-in claim (what “same” means) |
|
|
24
|
+
| [docs/PROOF.md](docs/PROOF.md) | Evidence argument + what is not proven |
|
|
25
|
+
| [docs/GAP-ANALYSIS.md](docs/GAP-ANALYSIS.md) | Phase 0 gap analysis vs full drop-in catalog |
|
|
26
|
+
| [docs/GAP-CATALOG.md](docs/GAP-CATALOG.md) | Current unproven / thin / intentional inventory |
|
|
27
|
+
| [DIVERGENCES.md](DIVERGENCES.md) | Auto-generated intentional divergences |
|
|
22
28
|
| [docs/SECRETS.md](docs/SECRETS.md) | npm / CI publish setup |
|
|
23
29
|
| [benchmarks/PERFORMANCE.md](benchmarks/PERFORMANCE.md) | Performance notes |
|
|
24
30
|
|
|
@@ -208,9 +214,11 @@ The exports of the main entry (`@crvouga/sqlite-mem`) are **frozen**:
|
|
|
208
214
|
|
|
209
215
|
## Compatibility notes for integrators
|
|
210
216
|
|
|
211
|
-
Goal:
|
|
217
|
+
Goal: **SQL dialect** behavioral parity vs SQLite **3.51.0** / **3.53.0** for the `@crvouga/sqlite-mem` sync API. Full matrix: [COMPATIBILITY.md](COMPATIBILITY.md). Contract: [docs/DROP-IN-CONTRACT.md](docs/DROP-IN-CONTRACT.md).
|
|
212
218
|
|
|
213
|
-
**
|
|
219
|
+
This is **not** a drop-in replacement for `sql.js`, `@sqlite.org/sqlite-wasm`, or better-sqlite3’s full Node API. There is no `.sqlite` file codec, no `create_function` / custom collations, no `stmt.step()` / `iterate()`, and `ATTACH 'file'` opens an empty in-memory schema.
|
|
220
|
+
|
|
221
|
+
**Intentional differences:** custom `SQLM` snapshots; seeded `random()` / fixed `'now'` by default (`{ random: "os" }` / `{ now: "system" }` match SQLite entropy and wall clock); no C API / on-disk DB / VFS. Machine-readable list: [DIVERGENCES.md](DIVERGENCES.md).
|
|
214
222
|
|
|
215
223
|
**Know these thin or partial areas** (do not assume full oracle fidelity):
|
|
216
224
|
|
package/compat/divergences.json
CHANGED
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"scope": "select",
|
|
49
49
|
"predicate": "INDEXED BY / NOT INDEXED is accepted and ignored",
|
|
50
50
|
"specifiedBehavior": "Query results match the unhinted plan; missing-index errors are not raised.",
|
|
51
|
-
"pinnedBy": ["COMPATIBILITY.md"]
|
|
51
|
+
"pinnedBy": ["indexes/indexed-by.test.ts", "COMPATIBILITY.md"]
|
|
52
52
|
},
|
|
53
53
|
{
|
|
54
54
|
"id": "materialized-hint-ignored",
|
package/dist/api/statement.d.ts
CHANGED
package/dist/executor/env.d.ts
CHANGED
|
@@ -51,6 +51,8 @@ export declare class ExecutionEnv {
|
|
|
51
51
|
maxRows: number;
|
|
52
52
|
includeNamedRows: boolean;
|
|
53
53
|
includeValues: boolean;
|
|
54
|
+
/** Source text of the statement currently executing (for sqlite_master.sql). */
|
|
55
|
+
statementSql: string | null;
|
|
54
56
|
constructor(state: DatabaseState, transactions: TransactionManager, params?: readonly unknown[], functions?: FunctionRegistry, hooks?: ExecutionHooks);
|
|
55
57
|
reset(params: readonly unknown[]): void;
|
|
56
58
|
getBoundParameter(name: string | number): SqlValue;
|
package/dist/index.js
CHANGED
|
@@ -640,10 +640,12 @@ var PREC = {
|
|
|
640
640
|
JSON_ARROW: 80
|
|
641
641
|
};
|
|
642
642
|
var Parser = class {
|
|
643
|
-
constructor(tokens) {
|
|
643
|
+
constructor(tokens, source = "") {
|
|
644
644
|
this.tokens = tokens;
|
|
645
|
+
this.source = source;
|
|
645
646
|
}
|
|
646
647
|
tokens;
|
|
648
|
+
source;
|
|
647
649
|
pos = 0;
|
|
648
650
|
current() {
|
|
649
651
|
return this.tokens[this.pos] ?? this.tokens[this.tokens.length - 1];
|
|
@@ -727,13 +729,21 @@ var Parser = class {
|
|
|
727
729
|
}
|
|
728
730
|
// ── Statements ──────────────────────────────────────────────────────────
|
|
729
731
|
parseStatements() {
|
|
730
|
-
|
|
732
|
+
return this.parseUnits().map((unit) => unit.statement);
|
|
733
|
+
}
|
|
734
|
+
/** Parse statements with per-statement source slices for catalog `sql` text. */
|
|
735
|
+
parseUnits() {
|
|
736
|
+
const units = [];
|
|
731
737
|
while (!this.at("EOF")) {
|
|
732
738
|
if (this.match("SEMI")) continue;
|
|
733
|
-
|
|
739
|
+
const start = this.current().start;
|
|
740
|
+
const statement = this.parseStatement();
|
|
741
|
+
const end = this.pos > 0 ? this.tokens[this.pos - 1].end : this.current().end;
|
|
734
742
|
this.match("SEMI");
|
|
743
|
+
const sql = this.source ? this.source.slice(start, end).trimEnd() : "";
|
|
744
|
+
units.push({ statement, sql });
|
|
735
745
|
}
|
|
736
|
-
return
|
|
746
|
+
return units;
|
|
737
747
|
}
|
|
738
748
|
parseStatement() {
|
|
739
749
|
if (this.match("EXPLAIN")) {
|
|
@@ -2359,14 +2369,13 @@ var Parser = class {
|
|
|
2359
2369
|
return { kind: "following", expr };
|
|
2360
2370
|
}
|
|
2361
2371
|
};
|
|
2362
|
-
function
|
|
2363
|
-
return new Parser(tokens).
|
|
2372
|
+
function parseTokenUnits(tokens, source) {
|
|
2373
|
+
return new Parser(tokens, source).parseUnits();
|
|
2364
2374
|
}
|
|
2365
2375
|
|
|
2366
2376
|
// src/parser/index.ts
|
|
2367
|
-
function
|
|
2368
|
-
|
|
2369
|
-
return parseTokens(tokens);
|
|
2377
|
+
function parseUnits(sql) {
|
|
2378
|
+
return parseTokenUnits(tokenize(sql), sql);
|
|
2370
2379
|
}
|
|
2371
2380
|
|
|
2372
2381
|
// src/runtime/clock.ts
|
|
@@ -9160,6 +9169,8 @@ var ExecutionEnv = class {
|
|
|
9160
9169
|
maxRows = Number.POSITIVE_INFINITY;
|
|
9161
9170
|
includeNamedRows = true;
|
|
9162
9171
|
includeValues = true;
|
|
9172
|
+
/** Source text of the statement currently executing (for sqlite_master.sql). */
|
|
9173
|
+
statementSql = null;
|
|
9163
9174
|
constructor(state, transactions, params = [], functions = defaultFunctionRegistry, hooks = {}) {
|
|
9164
9175
|
this.state = state;
|
|
9165
9176
|
this.transactions = transactions;
|
|
@@ -9178,6 +9189,7 @@ var ExecutionEnv = class {
|
|
|
9178
9189
|
this.maxRows = Number.POSITIVE_INFINITY;
|
|
9179
9190
|
this.includeNamedRows = true;
|
|
9180
9191
|
this.includeValues = true;
|
|
9192
|
+
this.statementSql = null;
|
|
9181
9193
|
}
|
|
9182
9194
|
getBoundParameter(name) {
|
|
9183
9195
|
if (typeof name === "number") {
|
|
@@ -9410,6 +9422,78 @@ function executeDetach(stmt, env) {
|
|
|
9410
9422
|
return emptyResult(0, env.state.lastInsertRowid);
|
|
9411
9423
|
}
|
|
9412
9424
|
|
|
9425
|
+
// src/schema/master-sql.ts
|
|
9426
|
+
function normalizeMasterSql(sql) {
|
|
9427
|
+
const trimmed = sql.trim().replace(/;+\s*$/u, "").trim();
|
|
9428
|
+
if (!trimmed) return trimmed;
|
|
9429
|
+
const tokens = tokenize(trimmed);
|
|
9430
|
+
if (tokens.length === 0 || tokens[0].kind === "EOF") return trimmed;
|
|
9431
|
+
let i = 0;
|
|
9432
|
+
const at = (offset, ...kinds) => {
|
|
9433
|
+
const tok = tokens[i + offset];
|
|
9434
|
+
return tok !== void 0 && kinds.includes(tok.kind);
|
|
9435
|
+
};
|
|
9436
|
+
if (!at(0, "CREATE")) return trimmed;
|
|
9437
|
+
i++;
|
|
9438
|
+
if (at(0, "TEMP", "TEMPORARY")) i++;
|
|
9439
|
+
let headKind = "table";
|
|
9440
|
+
if (at(0, "UNIQUE") && at(1, "INDEX")) {
|
|
9441
|
+
headKind = "unique_index";
|
|
9442
|
+
i += 2;
|
|
9443
|
+
} else if (at(0, "VIRTUAL") && at(1, "TABLE")) {
|
|
9444
|
+
headKind = "vtable";
|
|
9445
|
+
i += 2;
|
|
9446
|
+
} else if (at(0, "TABLE")) {
|
|
9447
|
+
headKind = "table";
|
|
9448
|
+
i++;
|
|
9449
|
+
} else if (at(0, "VIEW")) {
|
|
9450
|
+
headKind = "view";
|
|
9451
|
+
i++;
|
|
9452
|
+
} else if (at(0, "INDEX")) {
|
|
9453
|
+
headKind = "index";
|
|
9454
|
+
i++;
|
|
9455
|
+
} else if (at(0, "TRIGGER")) {
|
|
9456
|
+
headKind = "trigger";
|
|
9457
|
+
i++;
|
|
9458
|
+
} else {
|
|
9459
|
+
return trimmed;
|
|
9460
|
+
}
|
|
9461
|
+
if (at(0, "IF") && at(1, "NOT") && at(2, "EXISTS")) i += 3;
|
|
9462
|
+
let nameText = "";
|
|
9463
|
+
let nameEnd = 0;
|
|
9464
|
+
if (tokens[i] && tokens[i].kind !== "EOF" && at(1, "DOT") && tokens[i + 2] && tokens[i + 2].kind !== "EOF") {
|
|
9465
|
+
nameText = trimmed.slice(tokens[i + 2].start, tokens[i + 2].end);
|
|
9466
|
+
nameEnd = tokens[i + 2].end;
|
|
9467
|
+
i += 3;
|
|
9468
|
+
} else if (tokens[i] && tokens[i].kind !== "EOF") {
|
|
9469
|
+
nameText = trimmed.slice(tokens[i].start, tokens[i].end);
|
|
9470
|
+
nameEnd = tokens[i].end;
|
|
9471
|
+
i++;
|
|
9472
|
+
}
|
|
9473
|
+
const body = nameEnd < trimmed.length ? trimmed.slice(nameEnd) : "";
|
|
9474
|
+
const needsSpace = body.length > 0 && !/^[\s(]/u.test(body);
|
|
9475
|
+
const head = headKind === "unique_index" ? "CREATE UNIQUE INDEX" : headKind === "vtable" ? "CREATE VIRTUAL TABLE" : headKind === "view" ? "CREATE VIEW" : headKind === "index" ? "CREATE INDEX" : headKind === "trigger" ? "CREATE TRIGGER" : "CREATE TABLE";
|
|
9476
|
+
if (body.length === 0) return `${head} ${nameText}`;
|
|
9477
|
+
return needsSpace ? `${head} ${nameText} ${body}` : `${head} ${nameText}${body}`;
|
|
9478
|
+
}
|
|
9479
|
+
function appendAddColumnToMasterSql(originalSql, alterSql) {
|
|
9480
|
+
if (!originalSql || !alterSql) return originalSql;
|
|
9481
|
+
const match = alterSql.match(/\bADD\s+(?:COLUMN\s+)?(.+)$/iu);
|
|
9482
|
+
if (!match?.[1]) return originalSql;
|
|
9483
|
+
const colDef = match[1].trim().replace(/;+\s*$/u, "").trim();
|
|
9484
|
+
const close = originalSql.lastIndexOf(")");
|
|
9485
|
+
if (close < 0) return originalSql;
|
|
9486
|
+
return `${originalSql.slice(0, close)}, ${colDef}${originalSql.slice(close)}`;
|
|
9487
|
+
}
|
|
9488
|
+
function synthesizeCtasMasterSql(tableName, columnNames) {
|
|
9489
|
+
const cols = columnNames.map(quoteIdentIfNeeded).join(",");
|
|
9490
|
+
return `CREATE TABLE ${quoteIdentIfNeeded(tableName)}(${cols})`;
|
|
9491
|
+
}
|
|
9492
|
+
function quoteIdentIfNeeded(name) {
|
|
9493
|
+
if (/^[A-Za-z_][A-Za-z0-9_]*$/u.test(name)) return name;
|
|
9494
|
+
return `"${name.replaceAll('"', '""')}"`;
|
|
9495
|
+
}
|
|
9496
|
+
|
|
9413
9497
|
// src/functions/window.ts
|
|
9414
9498
|
function rowsEqual(left, right) {
|
|
9415
9499
|
if (left.length !== right.length) return false;
|
|
@@ -11991,14 +12075,17 @@ function scanFtsVocab(db, alias, vocab) {
|
|
|
11991
12075
|
|
|
11992
12076
|
// src/executor/ddl.ts
|
|
11993
12077
|
function executeCreateTable(stmt, env) {
|
|
12078
|
+
const sourceSql = env.statementSql ? normalizeMasterSql(env.statementSql) : null;
|
|
11994
12079
|
if (!stmt.asSelect) {
|
|
11995
|
-
env.state.createTable(stmt);
|
|
12080
|
+
env.state.createTable(stmt, sourceSql);
|
|
11996
12081
|
env.state.recordChange(0);
|
|
11997
12082
|
return emptyResult(0, env.state.lastInsertRowid);
|
|
11998
12083
|
}
|
|
11999
12084
|
const result = executeSelect2(stmt.asSelect, env);
|
|
12000
12085
|
const columns = result.columns.map((name) => ({ name, typeName: null, constraints: [] }));
|
|
12001
|
-
const
|
|
12086
|
+
const bareName = stmt.name.includes(".") ? stmt.name.split(".").pop() ?? stmt.name : stmt.name;
|
|
12087
|
+
const ctasSql = synthesizeCtasMasterSql(bareName, result.columns);
|
|
12088
|
+
const table = env.state.createTable({ ...stmt, columns, constraints: [], asSelect: null }, ctasSql);
|
|
12002
12089
|
for (const values of resultValues(result)) {
|
|
12003
12090
|
table.insert(
|
|
12004
12091
|
new Map(table.columns.map((column, index) => [normalizeColumnName(column.name), values[index] ?? null]))
|
|
@@ -12023,7 +12110,7 @@ function executeCreateTable(stmt, env) {
|
|
|
12023
12110
|
return emptyResult(0, env.state.lastInsertRowid);
|
|
12024
12111
|
}
|
|
12025
12112
|
function executeCreateIndex(stmt, env) {
|
|
12026
|
-
const index = env.state.createIndex(stmt);
|
|
12113
|
+
const index = env.state.createIndex(stmt, env.statementSql ? normalizeMasterSql(env.statementSql) : null);
|
|
12027
12114
|
const table = env.state.getTable(stmt.table);
|
|
12028
12115
|
try {
|
|
12029
12116
|
for (const row of table.scan()) {
|
|
@@ -12103,6 +12190,7 @@ function executeAlterTable(stmt, env) {
|
|
|
12103
12190
|
throw new SqliteError("Cannot add a NOT NULL column with default value NULL", "other");
|
|
12104
12191
|
table.columns.push(column);
|
|
12105
12192
|
for (const row of table.rows.values()) row.values.set(normalizeColumnName(column.name), defaultValue);
|
|
12193
|
+
table.originalSql = appendAddColumnToMasterSql(table.originalSql, env.statementSql);
|
|
12106
12194
|
table.clearEqualityHashes();
|
|
12107
12195
|
env.state.schemaVersion++;
|
|
12108
12196
|
} else {
|
|
@@ -12150,7 +12238,7 @@ function executeDropIndex(stmt, env) {
|
|
|
12150
12238
|
return emptyResult(0, env.state.lastInsertRowid);
|
|
12151
12239
|
}
|
|
12152
12240
|
function executeCreateView(stmt, env) {
|
|
12153
|
-
env.state.createView(stmt);
|
|
12241
|
+
env.state.createView(stmt, env.statementSql ? normalizeMasterSql(env.statementSql) : null);
|
|
12154
12242
|
return emptyResult(0, env.state.lastInsertRowid);
|
|
12155
12243
|
}
|
|
12156
12244
|
function executeDropView(stmt, env) {
|
|
@@ -12243,7 +12331,7 @@ function executeCreateTrigger(stmt, env) {
|
|
|
12243
12331
|
forEachRow: stmt.forEachRow,
|
|
12244
12332
|
body: stmt.body,
|
|
12245
12333
|
updateColumns: stmt.updateColumns,
|
|
12246
|
-
originalSql: null
|
|
12334
|
+
originalSql: env.statementSql ? normalizeMasterSql(env.statementSql) : null
|
|
12247
12335
|
});
|
|
12248
12336
|
return emptyResult(0, env.state.lastInsertRowid);
|
|
12249
12337
|
}
|
|
@@ -12340,7 +12428,7 @@ function triggerScope(table, oldRow, newValues) {
|
|
|
12340
12428
|
|
|
12341
12429
|
// src/executor/vtable.ts
|
|
12342
12430
|
function executeCreateVirtualTable(stmt, env) {
|
|
12343
|
-
env.state.createVirtualTable(stmt);
|
|
12431
|
+
env.state.createVirtualTable(stmt, env.statementSql ? normalizeMasterSql(env.statementSql) : null);
|
|
12344
12432
|
env.state.recordChange(0);
|
|
12345
12433
|
return emptyResult(0, env.state.lastInsertRowid);
|
|
12346
12434
|
}
|
|
@@ -13642,10 +13730,11 @@ function executeAnalyze(stmt, env) {
|
|
|
13642
13730
|
|
|
13643
13731
|
// src/api/statement.ts
|
|
13644
13732
|
var Statement = class _Statement {
|
|
13645
|
-
constructor(database, sql, statements) {
|
|
13733
|
+
constructor(database, sql, statements, statementSqls) {
|
|
13646
13734
|
this.database = database;
|
|
13647
13735
|
this.sql = sql;
|
|
13648
13736
|
this.statements = statements;
|
|
13737
|
+
this.statementSqls = statementSqls;
|
|
13649
13738
|
this.schemaVersion = database.state.schemaVersion;
|
|
13650
13739
|
}
|
|
13651
13740
|
database;
|
|
@@ -13653,13 +13742,24 @@ var Statement = class _Statement {
|
|
|
13653
13742
|
namedPlan = null;
|
|
13654
13743
|
env = null;
|
|
13655
13744
|
statements;
|
|
13745
|
+
statementSqls;
|
|
13656
13746
|
schemaVersion;
|
|
13657
13747
|
/**
|
|
13658
13748
|
* Construct a {@link Statement} for {@link Database.prepare} / {@link Database.exec}.
|
|
13659
13749
|
* @internal
|
|
13660
13750
|
*/
|
|
13661
|
-
static create(database, sql, statements) {
|
|
13662
|
-
return new _Statement(database, sql, statements);
|
|
13751
|
+
static create(database, sql, statements, statementSqls) {
|
|
13752
|
+
return new _Statement(database, sql, statements, statementSqls ?? statements.map(() => sql));
|
|
13753
|
+
}
|
|
13754
|
+
/** @internal Build from {@link parseUnits}. */
|
|
13755
|
+
static createFromSql(database, sql) {
|
|
13756
|
+
const units = parseUnits(sql);
|
|
13757
|
+
return new _Statement(
|
|
13758
|
+
database,
|
|
13759
|
+
sql,
|
|
13760
|
+
units.map((u) => u.statement),
|
|
13761
|
+
units.map((u) => u.sql)
|
|
13762
|
+
);
|
|
13663
13763
|
}
|
|
13664
13764
|
/**
|
|
13665
13765
|
* Execute for side effects (INSERT / UPDATE / DELETE / DDL).
|
|
@@ -13722,9 +13822,11 @@ var Statement = class _Statement {
|
|
|
13722
13822
|
env.includeValues = true;
|
|
13723
13823
|
this.bindNamed(env, params);
|
|
13724
13824
|
let result;
|
|
13725
|
-
for (
|
|
13726
|
-
|
|
13825
|
+
for (let i = 0; i < this.statements.length; i++) {
|
|
13826
|
+
env.statementSql = this.statementSqls[i] ?? this.sql;
|
|
13827
|
+
result = executeStatement(this.statements[i], env);
|
|
13727
13828
|
}
|
|
13829
|
+
env.statementSql = null;
|
|
13728
13830
|
return result;
|
|
13729
13831
|
}
|
|
13730
13832
|
obtainEnv(params) {
|
|
@@ -13744,7 +13846,9 @@ var Statement = class _Statement {
|
|
|
13744
13846
|
}
|
|
13745
13847
|
reprepareIfSchemaChanged() {
|
|
13746
13848
|
if (this.schemaVersion === this.database.state.schemaVersion) return;
|
|
13747
|
-
|
|
13849
|
+
const units = parseUnits(this.sql);
|
|
13850
|
+
this.statements = units.map((u) => u.statement);
|
|
13851
|
+
this.statementSqls = units.map((u) => u.sql);
|
|
13748
13852
|
this.env = null;
|
|
13749
13853
|
this.namedPlan = null;
|
|
13750
13854
|
this.schemaVersion = this.database.state.schemaVersion;
|
|
@@ -13835,7 +13939,7 @@ var Database = class {
|
|
|
13835
13939
|
if (arguments.length > 1) {
|
|
13836
13940
|
throw new SqliteError("exec() does not accept parameters; use prepare() or query()", "misuse");
|
|
13837
13941
|
}
|
|
13838
|
-
Statement.
|
|
13942
|
+
Statement.createFromSql(this, sql).run();
|
|
13839
13943
|
}
|
|
13840
13944
|
/**
|
|
13841
13945
|
* Execute a single-statement query and return all rows as objects keyed by column name.
|
|
@@ -13985,14 +14089,19 @@ var Database = class {
|
|
|
13985
14089
|
if (this.closed) throw new SqliteError("Database is closed", "misuse");
|
|
13986
14090
|
}
|
|
13987
14091
|
prepareSingle(sql) {
|
|
13988
|
-
const
|
|
13989
|
-
if (
|
|
14092
|
+
const units = parseUnits(sql);
|
|
14093
|
+
if (units.length === 0) {
|
|
13990
14094
|
throw new SqliteError("empty statement", "misuse");
|
|
13991
14095
|
}
|
|
13992
|
-
if (
|
|
14096
|
+
if (units.length > 1) {
|
|
13993
14097
|
throw new SqliteError("query()/prepare() accept a single statement only; use exec() for scripts", "misuse");
|
|
13994
14098
|
}
|
|
13995
|
-
return Statement.create(
|
|
14099
|
+
return Statement.create(
|
|
14100
|
+
this,
|
|
14101
|
+
sql,
|
|
14102
|
+
units.map((u) => u.statement),
|
|
14103
|
+
units.map((u) => u.sql)
|
|
14104
|
+
);
|
|
13996
14105
|
}
|
|
13997
14106
|
};
|
|
13998
14107
|
var disposeKey = Symbol.dispose;
|