@pennixrv/trellis-core 0.6.44 → 0.7.0-beta.10
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/dist/mem/adapters/claude.d.ts +1 -1
- package/dist/mem/adapters/claude.js +1 -1
- package/dist/mem/adapters/codex.d.ts +1 -1
- package/dist/mem/adapters/codex.js +1 -1
- package/dist/mem/adapters/devin.d.ts +50 -0
- package/dist/mem/adapters/devin.d.ts.map +1 -0
- package/dist/mem/adapters/devin.js +383 -0
- package/dist/mem/adapters/devin.js.map +1 -0
- package/dist/mem/adapters/grok.d.ts +1 -1
- package/dist/mem/adapters/grok.js +1 -1
- package/dist/mem/adapters/opencode.d.ts.map +1 -1
- package/dist/mem/adapters/opencode.js +35 -139
- package/dist/mem/adapters/opencode.js.map +1 -1
- package/dist/mem/adapters/zcode.d.ts +1 -1
- package/dist/mem/adapters/zcode.d.ts.map +1 -1
- package/dist/mem/adapters/zcode.js +55 -141
- package/dist/mem/adapters/zcode.js.map +1 -1
- package/dist/mem/index.d.ts +1 -0
- package/dist/mem/index.d.ts.map +1 -1
- package/dist/mem/index.js +1 -0
- package/dist/mem/index.js.map +1 -1
- package/dist/mem/internal/paths.d.ts +22 -0
- package/dist/mem/internal/paths.d.ts.map +1 -1
- package/dist/mem/internal/paths.js +45 -0
- package/dist/mem/internal/paths.js.map +1 -1
- package/dist/mem/internal/sqlite-adapter.d.ts +46 -0
- package/dist/mem/internal/sqlite-adapter.d.ts.map +1 -0
- package/dist/mem/internal/sqlite-adapter.js +116 -0
- package/dist/mem/internal/sqlite-adapter.js.map +1 -0
- package/dist/mem/internal/sqlite-readonly.d.ts +3 -0
- package/dist/mem/internal/sqlite-readonly.d.ts.map +1 -1
- package/dist/mem/internal/sqlite-readonly.js +159 -60
- package/dist/mem/internal/sqlite-readonly.js.map +1 -1
- package/dist/mem/phase.d.ts +4 -4
- package/dist/mem/phase.d.ts.map +1 -1
- package/dist/mem/phase.js +26 -23
- package/dist/mem/phase.js.map +1 -1
- package/dist/mem/platforms.d.ts +20 -0
- package/dist/mem/platforms.d.ts.map +1 -0
- package/dist/mem/platforms.js +72 -0
- package/dist/mem/platforms.js.map +1 -0
- package/dist/mem/projects.d.ts +1 -1
- package/dist/mem/projects.d.ts.map +1 -1
- package/dist/mem/projects.js +5 -8
- package/dist/mem/projects.js.map +1 -1
- package/dist/mem/sessions.d.ts +3 -3
- package/dist/mem/sessions.d.ts.map +1 -1
- package/dist/mem/sessions.js +41 -79
- package/dist/mem/sessions.js.map +1 -1
- package/dist/mem/types.d.ts +5 -4
- package/dist/mem/types.d.ts.map +1 -1
- package/dist/mem/types.js +9 -1
- package/dist/mem/types.js.map +1 -1
- package/package.json +1 -1
|
@@ -30,6 +30,28 @@ export declare const GROK_SESSIONS: string;
|
|
|
30
30
|
* `XDG_DATA_HOME` sees its own value.
|
|
31
31
|
*/
|
|
32
32
|
export declare function opencodeDataDir(): string;
|
|
33
|
+
/**
|
|
34
|
+
* Cognition Devin CLI data root (terminal agent, not Devin Desktop / Cascade
|
|
35
|
+
* and not Factory Droid):
|
|
36
|
+
* - Unix: `$XDG_DATA_HOME/devin/cli`, else `~/.local/share/devin/cli`
|
|
37
|
+
* - Windows: `%APPDATA%\devin\cli` (official logs path; falls back to
|
|
38
|
+
* `~/AppData/Roaming` when `APPDATA` is unset)
|
|
39
|
+
*
|
|
40
|
+
* Read per call so tests (and a caller that sets `XDG_DATA_HOME` / `APPDATA`)
|
|
41
|
+
* see their own value. `os.platform()` is also read per call, matching
|
|
42
|
+
* `HOME` reflecting a mocked `os.homedir()`.
|
|
43
|
+
*/
|
|
44
|
+
export declare function devinCliDataDir(): string;
|
|
45
|
+
/**
|
|
46
|
+
* Resolve the Devin CLI session database (`sessions.db`), or `undefined`
|
|
47
|
+
* when `DEVIN_DB_PATH=:memory:` (no file to read).
|
|
48
|
+
*
|
|
49
|
+
* 1. `DEVIN_DB_PATH` — absolute path used as-is, `~/` expanded, relative
|
|
50
|
+
* name joined to the data dir, `:memory:` meaning there is no file.
|
|
51
|
+
* 2. `<data>/sessions.db` — Cognition's default store. Missing file is a
|
|
52
|
+
* normal empty result; the adapter checks existence.
|
|
53
|
+
*/
|
|
54
|
+
export declare function devinCliDbPath(): string | undefined;
|
|
33
55
|
/**
|
|
34
56
|
* Resolve the OpenCode session database, or `undefined` when this machine has
|
|
35
57
|
* none (a normal empty result, not an error).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../../src/mem/internal/paths.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,eAAO,MAAM,IAAI,QAAe,CAAC;AACjC,eAAO,MAAM,eAAe,QAAyC,CAAC;AACtE,eAAO,MAAM,cAAc,QAAwC,CAAC;AACpE;2CAC2C;AAC3C,eAAO,MAAM,QAAQ,QAAsD,CAAC;AAC5E;;4DAE4D;AAC5D,eAAO,MAAM,aAAa,QAAuC,CAAC;AAElE;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAIxC;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,IAAI,MAAM,GAAG,SAAS,CA8BnD;AASD,eAAO,MAAM,YAAY,QAExB,CAAC;AACF,eAAO,MAAM,WAAW,QAGvB,CAAC;AAiBF;;;+EAG+E;AAC/E,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED;8CAC8C;AAC9C,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED;wEACwE;AACxE,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAMzE;AAED,0EAA0E;AAC1E,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAIvD;AAED,8EAA8E;AAC9E,wBAAgB,cAAc,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAsBrD;AAED;4EAC4E;AAC5E,wBAAiB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,CAkBxD"}
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../../src/mem/internal/paths.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,eAAO,MAAM,IAAI,QAAe,CAAC;AACjC,eAAO,MAAM,eAAe,QAAyC,CAAC;AACtE,eAAO,MAAM,cAAc,QAAwC,CAAC;AACpE;2CAC2C;AAC3C,eAAO,MAAM,QAAQ,QAAsD,CAAC;AAC5E;;4DAE4D;AAC5D,eAAO,MAAM,aAAa,QAAuC,CAAC;AAElE;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAIxC;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAYxC;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,IAAI,MAAM,GAAG,SAAS,CAUnD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,IAAI,MAAM,GAAG,SAAS,CA8BnD;AASD,eAAO,MAAM,YAAY,QAExB,CAAC;AACF,eAAO,MAAM,WAAW,QAGvB,CAAC;AAiBF;;;+EAG+E;AAC/E,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED;8CAC8C;AAC9C,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED;wEACwE;AACxE,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAMzE;AAED,0EAA0E;AAC1E,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAIvD;AAED,8EAA8E;AAC9E,wBAAgB,cAAc,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAsBrD;AAED;4EAC4E;AAC5E,wBAAiB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,CAkBxD"}
|
|
@@ -38,6 +38,51 @@ export function opencodeDataDir() {
|
|
|
38
38
|
return path.join(xdg, "opencode");
|
|
39
39
|
return path.join(HOME, ".local", "share", "opencode");
|
|
40
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* Cognition Devin CLI data root (terminal agent, not Devin Desktop / Cascade
|
|
43
|
+
* and not Factory Droid):
|
|
44
|
+
* - Unix: `$XDG_DATA_HOME/devin/cli`, else `~/.local/share/devin/cli`
|
|
45
|
+
* - Windows: `%APPDATA%\devin\cli` (official logs path; falls back to
|
|
46
|
+
* `~/AppData/Roaming` when `APPDATA` is unset)
|
|
47
|
+
*
|
|
48
|
+
* Read per call so tests (and a caller that sets `XDG_DATA_HOME` / `APPDATA`)
|
|
49
|
+
* see their own value. `os.platform()` is also read per call, matching
|
|
50
|
+
* `HOME` reflecting a mocked `os.homedir()`.
|
|
51
|
+
*/
|
|
52
|
+
export function devinCliDataDir() {
|
|
53
|
+
if (os.platform() === "win32") {
|
|
54
|
+
const appData = process.env.APPDATA?.trim();
|
|
55
|
+
const base = appData && appData.length > 0
|
|
56
|
+
? appData
|
|
57
|
+
: path.join(HOME, "AppData", "Roaming");
|
|
58
|
+
return path.join(base, "devin", "cli");
|
|
59
|
+
}
|
|
60
|
+
const xdg = process.env.XDG_DATA_HOME?.trim();
|
|
61
|
+
if (xdg)
|
|
62
|
+
return path.join(xdg, "devin", "cli");
|
|
63
|
+
return path.join(HOME, ".local", "share", "devin", "cli");
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Resolve the Devin CLI session database (`sessions.db`), or `undefined`
|
|
67
|
+
* when `DEVIN_DB_PATH=:memory:` (no file to read).
|
|
68
|
+
*
|
|
69
|
+
* 1. `DEVIN_DB_PATH` — absolute path used as-is, `~/` expanded, relative
|
|
70
|
+
* name joined to the data dir, `:memory:` meaning there is no file.
|
|
71
|
+
* 2. `<data>/sessions.db` — Cognition's default store. Missing file is a
|
|
72
|
+
* normal empty result; the adapter checks existence.
|
|
73
|
+
*/
|
|
74
|
+
export function devinCliDbPath() {
|
|
75
|
+
const override = process.env.DEVIN_DB_PATH?.trim();
|
|
76
|
+
if (override) {
|
|
77
|
+
if (override === ":memory:")
|
|
78
|
+
return undefined;
|
|
79
|
+
const expanded = expandHome(override);
|
|
80
|
+
return path.isAbsolute(expanded)
|
|
81
|
+
? expanded
|
|
82
|
+
: path.join(devinCliDataDir(), expanded);
|
|
83
|
+
}
|
|
84
|
+
return path.join(devinCliDataDir(), "sessions.db");
|
|
85
|
+
}
|
|
41
86
|
/**
|
|
42
87
|
* Resolve the OpenCode session database, or `undefined` when this machine has
|
|
43
88
|
* none (a normal empty result, not an error).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../../src/mem/internal/paths.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../../src/mem/internal/paths.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared SQLite adapter kit for mem readers (OpenCode, ZCode, Devin CLI).
|
|
3
|
+
*
|
|
4
|
+
* Schema contract, structured warnings, one-slot prepare/release, and a
|
|
5
|
+
* scan visitor that never retains raw rows. Platform files own path, table
|
|
6
|
+
* mapping, and dialogue cleaning — not another copy of these helpers.
|
|
7
|
+
*
|
|
8
|
+
* Access is always through `sqlite-readonly.ts`. No native module, WASM
|
|
9
|
+
* blob, system `sqlite3`, or `better-sqlite3`.
|
|
10
|
+
*/
|
|
11
|
+
import type { MemWarning } from "../types.js";
|
|
12
|
+
import { SqliteParseError, type SqliteReadOnly, type SqliteRow, type SqliteTableInfo } from "./sqlite-readonly.js";
|
|
13
|
+
/** Schema mismatch (missing table / column). Distinct from a truncated file. */
|
|
14
|
+
export declare class SqliteSchemaError extends SqliteParseError {
|
|
15
|
+
constructor(message: string);
|
|
16
|
+
}
|
|
17
|
+
export interface SqliteWarningCopy {
|
|
18
|
+
unreadableCode: string;
|
|
19
|
+
snapshotUnstableCode: string;
|
|
20
|
+
/** Omit for ZCode: schema errors degrade to `unreadableCode`. */
|
|
21
|
+
schemaUnsupportedCode?: string;
|
|
22
|
+
writingMessage: (dbPath: string) => string;
|
|
23
|
+
unreadableMessage: (dbPath: string, error: SqliteParseError) => string;
|
|
24
|
+
unsupportedMessage?: (dbPath: string, error: SqliteParseError) => string;
|
|
25
|
+
}
|
|
26
|
+
/** Record one degradation per condition per command. */
|
|
27
|
+
export declare function pushSqliteWarning(warnings: MemWarning[], dbPath: string, error: SqliteParseError, copy: SqliteWarningCopy): void;
|
|
28
|
+
export declare function findTable(db: SqliteReadOnly, name: string): SqliteTableInfo;
|
|
29
|
+
/** True when `CREATE TABLE` sql declares a column of this exact name.
|
|
30
|
+
* Line comments (`-- ...`) sit between columns in some live schemas (Devin
|
|
31
|
+
* CLI) and must not hide the next name. */
|
|
32
|
+
export declare function declaresColumn(table: SqliteTableInfo, name: string): boolean;
|
|
33
|
+
export declare function requireColumns(table: SqliteTableInfo, names: readonly string[]): void;
|
|
34
|
+
export declare function requireOneOfColumns(table: SqliteTableInfo, candidates: readonly string[]): string;
|
|
35
|
+
/** Re-check the first decoded row; CREATE TABLE parse and rows can disagree. */
|
|
36
|
+
export declare function requireRowColumns(rows: readonly SqliteRow[] | SqliteRow, tableName: string, names: readonly string[]): void;
|
|
37
|
+
/** Visit every row and always return false so `scanTable` retains nothing. */
|
|
38
|
+
export declare function scanAndDiscard(db: SqliteReadOnly, tableName: string, visit: (row: SqliteRow) => void): void;
|
|
39
|
+
export declare function withSqliteDb<T>(dbPath: string, warnings: MemWarning[], copy: SqliteWarningCopy, fallback: T, run: (db: SqliteReadOnly) => T): T;
|
|
40
|
+
/** One-slot search-scoped store. Extract reuses it when the path matches. */
|
|
41
|
+
export declare function createSqlitePreparedStore<T>(): {
|
|
42
|
+
prepare: (dbPath: string, load: () => T) => void;
|
|
43
|
+
release: () => void;
|
|
44
|
+
get: (dbPath: string) => T | undefined;
|
|
45
|
+
};
|
|
46
|
+
//# sourceMappingURL=sqlite-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite-adapter.d.ts","sourceRoot":"","sources":["../../../src/mem/internal/sqlite-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAEL,gBAAgB,EAGhB,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,KAAK,eAAe,EACrB,MAAM,sBAAsB,CAAC;AAE9B,gFAAgF;AAChF,qBAAa,iBAAkB,SAAQ,gBAAgB;gBACzC,OAAO,EAAE,MAAM;CAI5B;AAED,MAAM,WAAW,iBAAiB;IAChC,cAAc,EAAE,MAAM,CAAC;IACvB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,iEAAiE;IACjE,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,cAAc,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC;IAC3C,iBAAiB,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,KAAK,MAAM,CAAC;IACvE,kBAAkB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,KAAK,MAAM,CAAC;CAC1E;AAED,wDAAwD;AACxD,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,UAAU,EAAE,EACtB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,gBAAgB,EACvB,IAAI,EAAE,iBAAiB,GACtB,IAAI,CAiBN;AAED,wBAAgB,SAAS,CAAC,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,GAAG,eAAe,CAM3E;AAED;;2CAE2C;AAC3C,wBAAgB,cAAc,CAAC,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAO5E;AAED,wBAAgB,cAAc,CAC5B,KAAK,EAAE,eAAe,EACtB,KAAK,EAAE,SAAS,MAAM,EAAE,GACvB,IAAI,CAON;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,eAAe,EACtB,UAAU,EAAE,SAAS,MAAM,EAAE,GAC5B,MAAM,CAQR;AAED,gFAAgF;AAChF,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,SAAS,SAAS,EAAE,GAAG,SAAS,EACtC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,SAAS,MAAM,EAAE,GACvB,IAAI,CASN;AAED,8EAA8E;AAC9E,wBAAgB,cAAc,CAC5B,EAAE,EAAE,cAAc,EAClB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,CAAC,GAAG,EAAE,SAAS,KAAK,IAAI,GAC9B,IAAI,CAKN;AAED,wBAAgB,YAAY,CAAC,CAAC,EAC5B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,UAAU,EAAE,EACtB,IAAI,EAAE,iBAAiB,EACvB,QAAQ,EAAE,CAAC,EACX,GAAG,EAAE,CAAC,EAAE,EAAE,cAAc,KAAK,CAAC,GAC7B,CAAC,CAcH;AAED,6EAA6E;AAC7E,wBAAgB,yBAAyB,CAAC,CAAC,KAAK;IAC9C,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC;IACjD,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,CAAC,GAAG,SAAS,CAAC;CACxC,CAaA"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared SQLite adapter kit for mem readers (OpenCode, ZCode, Devin CLI).
|
|
3
|
+
*
|
|
4
|
+
* Schema contract, structured warnings, one-slot prepare/release, and a
|
|
5
|
+
* scan visitor that never retains raw rows. Platform files own path, table
|
|
6
|
+
* mapping, and dialogue cleaning — not another copy of these helpers.
|
|
7
|
+
*
|
|
8
|
+
* Access is always through `sqlite-readonly.ts`. No native module, WASM
|
|
9
|
+
* blob, system `sqlite3`, or `better-sqlite3`.
|
|
10
|
+
*/
|
|
11
|
+
import * as fs from "node:fs";
|
|
12
|
+
import { openSqliteReadOnly, SqliteParseError, SqliteSnapshotUnstableError, stripSqlLineComments, } from "./sqlite-readonly.js";
|
|
13
|
+
/** Schema mismatch (missing table / column). Distinct from a truncated file. */
|
|
14
|
+
export class SqliteSchemaError extends SqliteParseError {
|
|
15
|
+
constructor(message) {
|
|
16
|
+
super(message);
|
|
17
|
+
this.name = "SqliteSchemaError";
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/** Record one degradation per condition per command. */
|
|
21
|
+
export function pushSqliteWarning(warnings, dbPath, error, copy) {
|
|
22
|
+
const code = error instanceof SqliteSnapshotUnstableError
|
|
23
|
+
? copy.snapshotUnstableCode
|
|
24
|
+
: error instanceof SqliteSchemaError && copy.schemaUnsupportedCode
|
|
25
|
+
? copy.schemaUnsupportedCode
|
|
26
|
+
: copy.unreadableCode;
|
|
27
|
+
if (warnings.some((warning) => warning.code === code))
|
|
28
|
+
return;
|
|
29
|
+
const message = code === copy.snapshotUnstableCode
|
|
30
|
+
? copy.writingMessage(dbPath)
|
|
31
|
+
: code === copy.schemaUnsupportedCode
|
|
32
|
+
? (copy.unsupportedMessage?.(dbPath, error) ??
|
|
33
|
+
copy.unreadableMessage(dbPath, error))
|
|
34
|
+
: copy.unreadableMessage(dbPath, error);
|
|
35
|
+
warnings.push({ code, message });
|
|
36
|
+
}
|
|
37
|
+
export function findTable(db, name) {
|
|
38
|
+
const table = db.listTables().find((item) => item.name === name);
|
|
39
|
+
if (!table) {
|
|
40
|
+
throw new SqliteSchemaError(`missing table: ${name}`);
|
|
41
|
+
}
|
|
42
|
+
return table;
|
|
43
|
+
}
|
|
44
|
+
/** True when `CREATE TABLE` sql declares a column of this exact name.
|
|
45
|
+
* Line comments (`-- ...`) sit between columns in some live schemas (Devin
|
|
46
|
+
* CLI) and must not hide the next name. */
|
|
47
|
+
export function declaresColumn(table, name) {
|
|
48
|
+
const sql = stripSqlLineComments(table.sql);
|
|
49
|
+
const pattern = new RegExp(`(?:\\(|,)\\s*["\`\\[]?${name}(?:["\`\\]]|\\b)`, "i");
|
|
50
|
+
return pattern.test(sql);
|
|
51
|
+
}
|
|
52
|
+
export function requireColumns(table, names) {
|
|
53
|
+
const missing = names.filter((name) => !declaresColumn(table, name));
|
|
54
|
+
if (missing.length > 0) {
|
|
55
|
+
throw new SqliteSchemaError(`table ${table.name} is missing column(s): ${missing.join(", ")}`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
export function requireOneOfColumns(table, candidates) {
|
|
59
|
+
const found = candidates.find((name) => declaresColumn(table, name));
|
|
60
|
+
if (!found) {
|
|
61
|
+
throw new SqliteSchemaError(`table ${table.name} has none of the expected column(s): ${candidates.join(" / ")}`);
|
|
62
|
+
}
|
|
63
|
+
return found;
|
|
64
|
+
}
|
|
65
|
+
/** Re-check the first decoded row; CREATE TABLE parse and rows can disagree. */
|
|
66
|
+
export function requireRowColumns(rows, tableName, names) {
|
|
67
|
+
const first = Array.isArray(rows) ? rows[0] : rows;
|
|
68
|
+
if (!first)
|
|
69
|
+
return;
|
|
70
|
+
const missing = names.filter((name) => !(name in first));
|
|
71
|
+
if (missing.length > 0) {
|
|
72
|
+
throw new SqliteSchemaError(`table ${tableName} is missing column(s): ${missing.join(", ")}`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/** Visit every row and always return false so `scanTable` retains nothing. */
|
|
76
|
+
export function scanAndDiscard(db, tableName, visit) {
|
|
77
|
+
db.scanTable(tableName, (row) => {
|
|
78
|
+
visit(row);
|
|
79
|
+
return false;
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
export function withSqliteDb(dbPath, warnings, copy, fallback, run) {
|
|
83
|
+
if (!fs.existsSync(dbPath))
|
|
84
|
+
return fallback;
|
|
85
|
+
try {
|
|
86
|
+
const db = openSqliteReadOnly(dbPath);
|
|
87
|
+
try {
|
|
88
|
+
return run(db);
|
|
89
|
+
}
|
|
90
|
+
finally {
|
|
91
|
+
db.close();
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
if (!(error instanceof SqliteParseError))
|
|
96
|
+
throw error;
|
|
97
|
+
pushSqliteWarning(warnings, dbPath, error, copy);
|
|
98
|
+
return fallback;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/** One-slot search-scoped store. Extract reuses it when the path matches. */
|
|
102
|
+
export function createSqlitePreparedStore() {
|
|
103
|
+
let slot = null;
|
|
104
|
+
return {
|
|
105
|
+
prepare(dbPath, load) {
|
|
106
|
+
slot = { dbPath, store: load() };
|
|
107
|
+
},
|
|
108
|
+
release() {
|
|
109
|
+
slot = null;
|
|
110
|
+
},
|
|
111
|
+
get(dbPath) {
|
|
112
|
+
return slot?.dbPath === dbPath ? slot.store : undefined;
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=sqlite-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite-adapter.js","sourceRoot":"","sources":["../../../src/mem/internal/sqlite-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -61,6 +61,9 @@ export declare class SqliteParseError extends Error {
|
|
|
61
61
|
export declare class SqliteSnapshotUnstableError extends SqliteParseError {
|
|
62
62
|
constructor(mainPath: string);
|
|
63
63
|
}
|
|
64
|
+
/** Strip `-- line comments` so a comma on the previous line still reveals
|
|
65
|
+
* the next column. Live Devin CLI `CREATE TABLE` SQL uses that layout. */
|
|
66
|
+
export declare function stripSqlLineComments(sql: string): string;
|
|
64
67
|
/**
|
|
65
68
|
* Open a SQLite database file for read-only access. Automatically loads the
|
|
66
69
|
* sibling `<db>-wal` file when present so active WAL-mode databases (e.g.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sqlite-readonly.d.ts","sourceRoot":"","sources":["../../../src/mem/internal/sqlite-readonly.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAMH;;;iFAGiF;AACjF,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEhD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,iEAAiE;IACjE,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,cAAc;IAC7B,0DAA0D;IAC1D,UAAU,IAAI,eAAe,EAAE,CAAC;IAChC;sEACkE;IAClE,SAAS,CACP,SAAS,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,SAAS,KAAK,OAAO,GACtC,SAAS,EAAE,CAAC;IACf,uDAAuD;IACvD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,KAAK,IAAI,IAAI,CAAC;CACf;AAID;6EAC6E;AAC7E,qBAAa,gBAAiB,SAAQ,KAAK;IAGvC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO;gBADxB,OAAO,EAAE,MAAM,EACN,KAAK,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED;;;;GAIG;AACH,qBAAa,2BAA4B,SAAQ,gBAAgB;gBACnD,QAAQ,EAAE,MAAM;CAM7B;
|
|
1
|
+
{"version":3,"file":"sqlite-readonly.d.ts","sourceRoot":"","sources":["../../../src/mem/internal/sqlite-readonly.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAMH;;;iFAGiF;AACjF,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEhD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,iEAAiE;IACjE,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,cAAc;IAC7B,0DAA0D;IAC1D,UAAU,IAAI,eAAe,EAAE,CAAC;IAChC;sEACkE;IAClE,SAAS,CACP,SAAS,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,SAAS,KAAK,OAAO,GACtC,SAAS,EAAE,CAAC;IACf,uDAAuD;IACvD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,KAAK,IAAI,IAAI,CAAC;CACf;AAID;6EAC6E;AAC7E,qBAAa,gBAAiB,SAAQ,KAAK;IAGvC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO;gBADxB,OAAO,EAAE,MAAM,EACN,KAAK,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED;;;;GAIG;AACH,qBAAa,2BAA4B,SAAQ,gBAAgB;gBACnD,QAAQ,EAAE,MAAM;CAM7B;AAq1BD;0EAC0E;AAC1E,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAExD;AAID;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,CA8KnE;AAED;;uBAEuB;AACvB,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,GAChB,SAAS,EAAE,CAWb"}
|
|
@@ -177,16 +177,18 @@ function equalBytes(a, b) {
|
|
|
177
177
|
}
|
|
178
178
|
return true;
|
|
179
179
|
}
|
|
180
|
+
function stampFromStat(stat) {
|
|
181
|
+
return {
|
|
182
|
+
size: stat.size,
|
|
183
|
+
mtimeMs: stat.mtimeMs,
|
|
184
|
+
ctimeMs: stat.ctimeMs,
|
|
185
|
+
dev: stat.dev,
|
|
186
|
+
ino: stat.ino,
|
|
187
|
+
};
|
|
188
|
+
}
|
|
180
189
|
function fileStamp(path) {
|
|
181
190
|
try {
|
|
182
|
-
|
|
183
|
-
return {
|
|
184
|
-
size: stat.size,
|
|
185
|
-
mtimeMs: stat.mtimeMs,
|
|
186
|
-
ctimeMs: stat.ctimeMs,
|
|
187
|
-
dev: stat.dev,
|
|
188
|
-
ino: stat.ino,
|
|
189
|
-
};
|
|
191
|
+
return stampFromStat(fs.statSync(path));
|
|
190
192
|
}
|
|
191
193
|
catch (error) {
|
|
192
194
|
const code = error.code;
|
|
@@ -195,6 +197,9 @@ function fileStamp(path) {
|
|
|
195
197
|
throw error;
|
|
196
198
|
}
|
|
197
199
|
}
|
|
200
|
+
function fileDescriptorStamp(fd) {
|
|
201
|
+
return stampFromStat(fs.fstatSync(fd));
|
|
202
|
+
}
|
|
198
203
|
function sameStamp(a, b) {
|
|
199
204
|
if (a === null || b === null)
|
|
200
205
|
return a === b;
|
|
@@ -270,6 +275,7 @@ function captureSnapshot(mainPath) {
|
|
|
270
275
|
const shmPath = mainPath + "-shm";
|
|
271
276
|
let lastError;
|
|
272
277
|
for (let attempt = 0; attempt < SNAPSHOT_ATTEMPTS; attempt++) {
|
|
278
|
+
let mainFd = null;
|
|
273
279
|
try {
|
|
274
280
|
const shmBefore = readWalIndexPrefix(shmPath);
|
|
275
281
|
const mainBefore = fileStamp(mainPath);
|
|
@@ -277,7 +283,7 @@ function captureSnapshot(mainPath) {
|
|
|
277
283
|
if (mainBefore === null) {
|
|
278
284
|
throw new SqliteParseError(`cannot read db file: ${mainPath}`);
|
|
279
285
|
}
|
|
280
|
-
|
|
286
|
+
mainFd = fs.openSync(mainPath, "r");
|
|
281
287
|
const walBytes = readOptionalFile(walPath);
|
|
282
288
|
const mainAfter = fileStamp(mainPath);
|
|
283
289
|
const walAfter = fileStamp(walPath);
|
|
@@ -285,13 +291,22 @@ function captureSnapshot(mainPath) {
|
|
|
285
291
|
if (!sameStamp(mainBefore, mainAfter) ||
|
|
286
292
|
!sameStamp(walBefore, walAfter) ||
|
|
287
293
|
!equalBytes(shmBefore, shmAfter)) {
|
|
294
|
+
fs.closeSync(mainFd);
|
|
295
|
+
mainFd = null;
|
|
288
296
|
lastError = new SqliteSnapshotUnstableError(mainPath);
|
|
289
297
|
continue;
|
|
290
298
|
}
|
|
291
299
|
const walIndex = walBytes === null ? null : parseWalIndexHeader(shmAfter);
|
|
292
|
-
return {
|
|
300
|
+
return {
|
|
301
|
+
mainFd,
|
|
302
|
+
mainStamp: mainAfter ?? mainBefore,
|
|
303
|
+
walBytes,
|
|
304
|
+
walIndex,
|
|
305
|
+
};
|
|
293
306
|
}
|
|
294
307
|
catch (error) {
|
|
308
|
+
if (mainFd !== null)
|
|
309
|
+
fs.closeSync(mainFd);
|
|
295
310
|
lastError = error;
|
|
296
311
|
}
|
|
297
312
|
}
|
|
@@ -394,7 +409,7 @@ function loadWal(walBytes, expectedPageSize, walIndex) {
|
|
|
394
409
|
}
|
|
395
410
|
return { pageMap };
|
|
396
411
|
}
|
|
397
|
-
function makePageSource(
|
|
412
|
+
function makePageSource(snapshot, header, wal) {
|
|
398
413
|
return {
|
|
399
414
|
pageSize: header.pageSize,
|
|
400
415
|
getPage(pgno) {
|
|
@@ -406,14 +421,46 @@ function makePageSource(mainBytes, header, wal) {
|
|
|
406
421
|
}
|
|
407
422
|
const start = (pgno - 1) * header.pageSize;
|
|
408
423
|
const end = start + header.pageSize;
|
|
409
|
-
if (end >
|
|
424
|
+
if (end > snapshot.mainStamp.size) {
|
|
410
425
|
// Page lives beyond the main file and has no WAL copy — treat as empty.
|
|
411
426
|
return new Uint8Array(header.pageSize);
|
|
412
427
|
}
|
|
413
|
-
|
|
428
|
+
const page = new Uint8Array(header.pageSize);
|
|
429
|
+
const bytesRead = readExactly(snapshot.mainFd, page, start);
|
|
430
|
+
if (bytesRead !== header.pageSize) {
|
|
431
|
+
throw new SqliteParseError(`short read for SQLite page ${pgno}`);
|
|
432
|
+
}
|
|
433
|
+
return page;
|
|
414
434
|
},
|
|
415
435
|
};
|
|
416
436
|
}
|
|
437
|
+
function readExactly(fd, target, position) {
|
|
438
|
+
let offset = 0;
|
|
439
|
+
while (offset < target.length) {
|
|
440
|
+
const bytesRead = fs.readSync(fd, target, offset, target.length - offset, position + offset);
|
|
441
|
+
if (bytesRead === 0)
|
|
442
|
+
break;
|
|
443
|
+
offset += bytesRead;
|
|
444
|
+
}
|
|
445
|
+
return offset;
|
|
446
|
+
}
|
|
447
|
+
function readMainHeader(snapshot) {
|
|
448
|
+
const bytes = new Uint8Array(DB_HEADER_SIZE);
|
|
449
|
+
const bytesRead = readExactly(snapshot.mainFd, bytes, 0);
|
|
450
|
+
if (bytesRead !== DB_HEADER_SIZE) {
|
|
451
|
+
throw new SqliteParseError("SQLite database header is truncated");
|
|
452
|
+
}
|
|
453
|
+
return bytes;
|
|
454
|
+
}
|
|
455
|
+
function isMainSnapshotStable(mainPath, snapshot) {
|
|
456
|
+
try {
|
|
457
|
+
return (sameStamp(snapshot.mainStamp, fileStamp(mainPath)) &&
|
|
458
|
+
sameStamp(snapshot.mainStamp, fileDescriptorStamp(snapshot.mainFd)));
|
|
459
|
+
}
|
|
460
|
+
catch {
|
|
461
|
+
return false;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
417
464
|
/** Decode a record body (the payload of a table-leaf cell) into an array of
|
|
418
465
|
* JS values. Serial type reference: https://www.sqlite.org/fileformat2.html
|
|
419
466
|
* section 2.1. Only TEXT / INTEGER / NULL / float / BLOB are handled. The
|
|
@@ -613,11 +660,12 @@ function decodeLeafCell(page, cellOff, src, header, td) {
|
|
|
613
660
|
* not columns.
|
|
614
661
|
*/
|
|
615
662
|
function parseColumnNames(sql) {
|
|
616
|
-
const
|
|
617
|
-
const
|
|
663
|
+
const cleaned = stripSqlLineComments(sql);
|
|
664
|
+
const open = cleaned.indexOf("(");
|
|
665
|
+
const close = cleaned.lastIndexOf(")");
|
|
618
666
|
if (open < 0 || close < 0 || close <= open)
|
|
619
667
|
return null;
|
|
620
|
-
const body =
|
|
668
|
+
const body = cleaned.slice(open + 1, close);
|
|
621
669
|
const segments = splitTopLevelCommas(body);
|
|
622
670
|
const cols = [];
|
|
623
671
|
for (const seg of segments) {
|
|
@@ -661,6 +709,11 @@ function firstIdentifier(piece) {
|
|
|
661
709
|
function isConstraintKeyword(id) {
|
|
662
710
|
return /^(primary|unique|check|foreign|constraint)$/i.test(id);
|
|
663
711
|
}
|
|
712
|
+
/** Strip `-- line comments` so a comma on the previous line still reveals
|
|
713
|
+
* the next column. Live Devin CLI `CREATE TABLE` SQL uses that layout. */
|
|
714
|
+
export function stripSqlLineComments(sql) {
|
|
715
|
+
return sql.replace(/--[^\n]*/g, " ");
|
|
716
|
+
}
|
|
664
717
|
// ---------- public entry ----------
|
|
665
718
|
/**
|
|
666
719
|
* Open a SQLite database file for read-only access. Automatically loads the
|
|
@@ -672,13 +725,53 @@ function isConstraintKeyword(id) {
|
|
|
672
725
|
*/
|
|
673
726
|
export function openSqliteReadOnly(mainPath) {
|
|
674
727
|
const snapshot = captureSnapshot(mainPath);
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
728
|
+
let closed = false;
|
|
729
|
+
let header;
|
|
730
|
+
let src;
|
|
731
|
+
try {
|
|
732
|
+
if (snapshot.mainStamp.size < DB_HEADER_SIZE) {
|
|
733
|
+
throw new SqliteParseError(`db file too small: ${mainPath}`);
|
|
734
|
+
}
|
|
735
|
+
header = parseDbHeader(readMainHeader(snapshot));
|
|
736
|
+
const wal = loadWal(snapshot.walBytes, header.pageSize, snapshot.walIndex);
|
|
737
|
+
src = makePageSource(snapshot, header, wal);
|
|
738
|
+
if (!isMainSnapshotStable(mainPath, snapshot)) {
|
|
739
|
+
throw new SqliteSnapshotUnstableError(mainPath);
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
catch (error) {
|
|
743
|
+
fs.closeSync(snapshot.mainFd);
|
|
744
|
+
throw error instanceof SqliteParseError
|
|
745
|
+
? error
|
|
746
|
+
: new SqliteParseError(`cannot read db file: ${mainPath}`, error);
|
|
747
|
+
}
|
|
748
|
+
function assertOpen() {
|
|
749
|
+
if (closed)
|
|
750
|
+
throw new SqliteParseError("SQLite reader is closed");
|
|
751
|
+
}
|
|
752
|
+
function assertMainSnapshotStable() {
|
|
753
|
+
if (!isMainSnapshotStable(mainPath, snapshot)) {
|
|
754
|
+
throw new SqliteSnapshotUnstableError(mainPath);
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
function readStable(read) {
|
|
758
|
+
assertOpen();
|
|
759
|
+
try {
|
|
760
|
+
const value = read();
|
|
761
|
+
assertMainSnapshotStable();
|
|
762
|
+
return value;
|
|
763
|
+
}
|
|
764
|
+
catch (error) {
|
|
765
|
+
if (error instanceof SqliteSnapshotUnstableError)
|
|
766
|
+
throw error;
|
|
767
|
+
if (!isMainSnapshotStable(mainPath, snapshot)) {
|
|
768
|
+
throw new SqliteSnapshotUnstableError(mainPath);
|
|
769
|
+
}
|
|
770
|
+
throw error instanceof SqliteParseError
|
|
771
|
+
? error
|
|
772
|
+
: new SqliteParseError(`failed reading SQLite snapshot: ${mainPath}`, error);
|
|
773
|
+
}
|
|
678
774
|
}
|
|
679
|
-
const header = parseDbHeader(mainBytes);
|
|
680
|
-
const wal = loadWal(snapshot.walBytes, header.pageSize, snapshot.walIndex);
|
|
681
|
-
const src = makePageSource(mainBytes, header, wal);
|
|
682
775
|
// Column-name cache: tableName → column list (or null).
|
|
683
776
|
const columnCache = new Map();
|
|
684
777
|
function readSqliteMaster() {
|
|
@@ -708,11 +801,12 @@ export function openSqliteReadOnly(mainPath) {
|
|
|
708
801
|
function rowidAliasIndex(table, columns) {
|
|
709
802
|
if (!table.sql || !columns)
|
|
710
803
|
return -1;
|
|
711
|
-
const
|
|
712
|
-
const
|
|
804
|
+
const cleaned = stripSqlLineComments(table.sql);
|
|
805
|
+
const open = cleaned.indexOf("(");
|
|
806
|
+
const close = cleaned.lastIndexOf(")");
|
|
713
807
|
if (open < 0 || close < 0)
|
|
714
808
|
return -1;
|
|
715
|
-
const body =
|
|
809
|
+
const body = cleaned.slice(open + 1, close);
|
|
716
810
|
const segments = splitTopLevelCommas(body);
|
|
717
811
|
let idx = 0;
|
|
718
812
|
for (const seg of segments) {
|
|
@@ -734,46 +828,51 @@ export function openSqliteReadOnly(mainPath) {
|
|
|
734
828
|
return {
|
|
735
829
|
dbPath: mainPath,
|
|
736
830
|
listTables() {
|
|
737
|
-
return readSqliteMaster
|
|
831
|
+
return readStable(readSqliteMaster);
|
|
738
832
|
},
|
|
739
833
|
scanTable(tableName, predicate) {
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
834
|
+
return readStable(() => {
|
|
835
|
+
let table;
|
|
836
|
+
try {
|
|
837
|
+
table = readSqliteMaster().find((t) => t.name === tableName);
|
|
838
|
+
if (!table || table.rootPgno <= 0)
|
|
839
|
+
return [];
|
|
840
|
+
const columns = columnsFor(table);
|
|
841
|
+
const aliasIdx = rowidAliasIndex(table, columns);
|
|
842
|
+
const rows = [];
|
|
843
|
+
visitTableBtree(src, table.rootPgno, header.textEncoding, header, ({ rowid, values }) => {
|
|
844
|
+
const row = {};
|
|
845
|
+
for (let i = 0; i < values.length; i++) {
|
|
846
|
+
const key = columns?.[i] ?? `col${i}`;
|
|
847
|
+
// INTEGER PRIMARY KEY columns store NULL in the record; the real
|
|
848
|
+
// value is the cell rowid. Splice it in so callers see the integer.
|
|
849
|
+
if (i === aliasIdx && values[i] === null) {
|
|
850
|
+
row[key] = rowid;
|
|
851
|
+
}
|
|
852
|
+
else {
|
|
853
|
+
row[key] = values[i];
|
|
854
|
+
}
|
|
759
855
|
}
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
}
|
|
856
|
+
if (!predicate || predicate(row))
|
|
857
|
+
rows.push(row);
|
|
858
|
+
});
|
|
859
|
+
return rows;
|
|
860
|
+
}
|
|
861
|
+
catch (error) {
|
|
862
|
+
// Wrap any non-SqliteParseError (e.g. RangeError from a truncated
|
|
863
|
+
// float64, TypeError from a bad cell pointer) so the adapter's single
|
|
864
|
+
// catch on SqliteParseError degrades cleanly instead of crashing CLI.
|
|
865
|
+
throw error instanceof SqliteParseError
|
|
866
|
+
? error
|
|
867
|
+
: new SqliteParseError(`failed reading table "${tableName}"`, error);
|
|
868
|
+
}
|
|
869
|
+
});
|
|
774
870
|
},
|
|
775
871
|
close() {
|
|
776
|
-
|
|
872
|
+
if (closed)
|
|
873
|
+
return;
|
|
874
|
+
closed = true;
|
|
875
|
+
fs.closeSync(snapshot.mainFd);
|
|
777
876
|
},
|
|
778
877
|
};
|
|
779
878
|
}
|