@malloydata/db-duckdb 0.0.386 → 0.0.388
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/duckdb_connection.d.ts +14 -0
- package/dist/duckdb_connection.js +44 -0
- package/package.json +2 -2
|
@@ -38,6 +38,12 @@ export declare class DuckDBConnection extends DuckDBCommon {
|
|
|
38
38
|
protected connection: DuckDBNodeConnection | null;
|
|
39
39
|
protected setupError: Error | undefined;
|
|
40
40
|
protected isSetup: Promise<void> | undefined;
|
|
41
|
+
/**
|
|
42
|
+
* Set by `close()`. Once true, `setup()` throws and no operation will
|
|
43
|
+
* reattach. This is the "poison pill" that distinguishes terminal close
|
|
44
|
+
* from reversible idle.
|
|
45
|
+
*/
|
|
46
|
+
protected closed: boolean;
|
|
41
47
|
static activeDBs: Record<string, ActiveDB>;
|
|
42
48
|
constructor(options: DuckDBConnectionOptions, queryOptions?: QueryOptionsReader);
|
|
43
49
|
constructor(name: string, databasePath?: string, workingDirectory?: string, queryOptions?: QueryOptionsReader);
|
|
@@ -56,6 +62,14 @@ export declare class DuckDBConnection extends DuckDBCommon {
|
|
|
56
62
|
}>;
|
|
57
63
|
runSQLStream(sql: string, { rowLimit, abortSignal }?: RunSQLOptions): AsyncIterableIterator<QueryRecord>;
|
|
58
64
|
close(): Promise<void>;
|
|
65
|
+
idle(): Promise<void>;
|
|
66
|
+
/**
|
|
67
|
+
* Remove this connection from the shared `activeDBs` entry. When the
|
|
68
|
+
* last connection sharing the entry is removed, close the underlying
|
|
69
|
+
* `DuckDBInstance` and drop the entry — releasing DuckDB's per-process
|
|
70
|
+
* file lock.
|
|
71
|
+
*/
|
|
72
|
+
private detachInstance;
|
|
59
73
|
/**
|
|
60
74
|
* Forcefully close all cached DuckDB instances. Useful for test cleanup
|
|
61
75
|
* to release file locks between test runs.
|
|
@@ -36,6 +36,12 @@ class DuckDBConnection extends duckdb_common_1.DuckDBCommon {
|
|
|
36
36
|
var _a;
|
|
37
37
|
super();
|
|
38
38
|
this.connection = null;
|
|
39
|
+
/**
|
|
40
|
+
* Set by `close()`. Once true, `setup()` throws and no operation will
|
|
41
|
+
* reattach. This is the "poison pill" that distinguishes terminal close
|
|
42
|
+
* from reversible idle.
|
|
43
|
+
*/
|
|
44
|
+
this.closed = false;
|
|
39
45
|
const options = typeof arg === 'string'
|
|
40
46
|
? buildLegacyOptions(arg, arg2, workingDirectory)
|
|
41
47
|
: arg;
|
|
@@ -84,6 +90,9 @@ class DuckDBConnection extends duckdb_common_1.DuckDBCommon {
|
|
|
84
90
|
}
|
|
85
91
|
}
|
|
86
92
|
async setup() {
|
|
93
|
+
if (this.closed) {
|
|
94
|
+
throw new Error(`DuckDB connection "${this.name}" is closed`);
|
|
95
|
+
}
|
|
87
96
|
if (this.setupError) {
|
|
88
97
|
throw this.setupError;
|
|
89
98
|
}
|
|
@@ -91,6 +100,16 @@ class DuckDBConnection extends duckdb_common_1.DuckDBCommon {
|
|
|
91
100
|
if (this.setupError) {
|
|
92
101
|
throw this.setupError;
|
|
93
102
|
}
|
|
103
|
+
// Lazy reattach after idle(): if our connection was released, re-run
|
|
104
|
+
// init() now. setupSQL gets replayed below because isSetup was cleared
|
|
105
|
+
// alongside the connection.
|
|
106
|
+
if (this.connection === null) {
|
|
107
|
+
this.connecting = this.init();
|
|
108
|
+
await this.connecting;
|
|
109
|
+
if (this.setupError) {
|
|
110
|
+
throw this.setupError;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
94
113
|
if (!this.isSetup) {
|
|
95
114
|
this.isSetup = this.setupOnce();
|
|
96
115
|
}
|
|
@@ -257,6 +276,31 @@ class DuckDBConnection extends duckdb_common_1.DuckDBCommon {
|
|
|
257
276
|
}
|
|
258
277
|
}
|
|
259
278
|
async close() {
|
|
279
|
+
this.detachInstance();
|
|
280
|
+
this.connection = null;
|
|
281
|
+
this.isSetup = undefined;
|
|
282
|
+
this.setupError = undefined;
|
|
283
|
+
this.closed = true;
|
|
284
|
+
}
|
|
285
|
+
async idle() {
|
|
286
|
+
// No-op for in-memory: closing the instance silently destroys state.
|
|
287
|
+
if (this.normalized.databasePath === ':memory:')
|
|
288
|
+
return;
|
|
289
|
+
this.detachInstance();
|
|
290
|
+
this.connection = null;
|
|
291
|
+
this.isSetup = undefined;
|
|
292
|
+
this.setupError = undefined;
|
|
293
|
+
// Reattach is deferred — `setup()` detects the null connection on next
|
|
294
|
+
// use and runs a fresh init() then. Doing it eagerly here would
|
|
295
|
+
// re-acquire the lock immediately and defeat the point of idling.
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Remove this connection from the shared `activeDBs` entry. When the
|
|
299
|
+
* last connection sharing the entry is removed, close the underlying
|
|
300
|
+
* `DuckDBInstance` and drop the entry — releasing DuckDB's per-process
|
|
301
|
+
* file lock.
|
|
302
|
+
*/
|
|
303
|
+
detachInstance() {
|
|
260
304
|
const activeDB = DuckDBConnection.activeDBs[this.shareKey];
|
|
261
305
|
if (activeDB) {
|
|
262
306
|
activeDB.connections = activeDB.connections.filter(connection => connection !== this.connection);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@malloydata/db-duckdb",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.388",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"dependencies": {
|
|
61
61
|
"@duckdb/duckdb-wasm": "1.33.1-dev13.0",
|
|
62
62
|
"@duckdb/node-api": "1.4.4-r.1",
|
|
63
|
-
"@malloydata/malloy": "0.0.
|
|
63
|
+
"@malloydata/malloy": "0.0.388",
|
|
64
64
|
"@motherduck/wasm-client": "^0.6.6",
|
|
65
65
|
"apache-arrow": "^17.0.0",
|
|
66
66
|
"web-worker": "^1.3.0"
|