@malloydata/db-duckdb 0.0.20-dev230107153725 → 0.0.20-dev230110224239

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.
@@ -54,6 +54,7 @@ export declare abstract class DuckDBCommon implements Connection, PersistSQLResu
54
54
  private getTableSchema;
55
55
  canStream(): this is StreamingConnection;
56
56
  test(): Promise<void>;
57
- protected abstract createHash(sqlCommand: string): Promise<string>;
57
+ abstract createHash(sqlCommand: string): Promise<string>;
58
58
  manifestTemporaryTable(sqlCommand: string): Promise<string>;
59
+ abstract close(): Promise<void>;
59
60
  }
@@ -1,13 +1,16 @@
1
1
  import { DuckDBCommon, QueryOptionsReader } from "./duckdb_common";
2
- import { Row } from "duckdb";
2
+ import { Connection, Database, Row } from "duckdb";
3
3
  import { QueryDataRow, RunSQLOptions } from "@malloydata/malloy";
4
4
  export declare class DuckDBConnection extends DuckDBCommon {
5
5
  readonly name: string;
6
+ private databasePath;
6
7
  private workingDirectory;
7
- protected connection: any;
8
- protected database: any;
8
+ connecting: Promise<void>;
9
+ protected connection: Connection | null;
10
+ protected database: Database | null;
9
11
  protected isSetup: Promise<void> | undefined;
10
12
  constructor(name: string, databasePath?: string, workingDirectory?: string, queryOptions?: QueryOptionsReader);
13
+ private init;
11
14
  protected setup(): Promise<void>;
12
15
  protected runDuckDBQuery(sql: string): Promise<{
13
16
  rows: Row[];
@@ -15,4 +18,5 @@ export declare class DuckDBConnection extends DuckDBCommon {
15
18
  }>;
16
19
  runSQLStream(sql: string, _options?: RunSQLOptions): AsyncIterableIterator<QueryDataRow>;
17
20
  createHash(sqlCommand: string): Promise<string>;
21
+ close(): Promise<void>;
18
22
  }
@@ -11,46 +11,35 @@
11
11
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
12
  * GNU General Public License for more details.
13
13
  */
14
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
15
- if (k2 === undefined) k2 = k;
16
- var desc = Object.getOwnPropertyDescriptor(m, k);
17
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
18
- desc = { enumerable: true, get: function() { return m[k]; } };
19
- }
20
- Object.defineProperty(o, k2, desc);
21
- }) : (function(o, m, k, k2) {
22
- if (k2 === undefined) k2 = k;
23
- o[k2] = m[k];
24
- }));
25
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
26
- Object.defineProperty(o, "default", { enumerable: true, value: v });
27
- }) : function(o, v) {
28
- o["default"] = v;
29
- });
30
- var __importStar = (this && this.__importStar) || function (mod) {
31
- if (mod && mod.__esModule) return mod;
32
- var result = {};
33
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
34
- __setModuleDefault(result, mod);
35
- return result;
14
+ var __importDefault = (this && this.__importDefault) || function (mod) {
15
+ return (mod && mod.__esModule) ? mod : { "default": mod };
36
16
  };
37
17
  Object.defineProperty(exports, "__esModule", { value: true });
38
18
  exports.DuckDBConnection = void 0;
39
- const crypto = __importStar(require("crypto"));
19
+ const crypto_1 = __importDefault(require("crypto"));
40
20
  const duckdb_common_1 = require("./duckdb_common");
41
21
  const duckdb_1 = require("duckdb");
42
22
  class DuckDBConnection extends duckdb_common_1.DuckDBCommon {
43
23
  constructor(name, databasePath = ":memory:", workingDirectory = ".", queryOptions) {
44
24
  super(queryOptions);
45
25
  this.name = name;
26
+ this.databasePath = databasePath;
46
27
  this.workingDirectory = workingDirectory;
47
- this.database = new duckdb_1.Database(databasePath, duckdb_1.OPEN_READWRITE, // databasePath === ":memory:" ? OPEN_READWRITE : OPEN_READONLY,
48
- (err) => {
49
- if (err) {
50
- return console.error(err);
51
- }
28
+ this.connection = null;
29
+ this.database = null;
30
+ this.connecting = this.init();
31
+ }
32
+ async init() {
33
+ return new Promise((resolve, reject) => {
34
+ this.database = new duckdb_1.Database(this.databasePath, duckdb_1.OPEN_READWRITE, // databasePath === ":memory:" ? OPEN_READWRITE : OPEN_READONLY,
35
+ (err) => {
36
+ if (err) {
37
+ reject(err);
38
+ }
39
+ });
40
+ this.connection = this.database.connect();
41
+ resolve();
52
42
  });
53
- this.connection = this.database.connect();
54
43
  }
55
44
  async setup() {
56
45
  const doSetup = async () => {
@@ -74,6 +63,7 @@ class DuckDBConnection extends duckdb_common_1.DuckDBCommon {
74
63
  console.error("Unable to load httpfs extension", error);
75
64
  }
76
65
  };
66
+ await this.connecting;
77
67
  if (!this.isSetup) {
78
68
  this.isSetup = doSetup();
79
69
  }
@@ -81,21 +71,29 @@ class DuckDBConnection extends duckdb_common_1.DuckDBCommon {
81
71
  }
82
72
  async runDuckDBQuery(sql) {
83
73
  return new Promise((resolve, reject) => {
84
- this.connection.all(sql, (err, rows) => {
85
- if (err) {
86
- reject(err);
87
- }
88
- else {
89
- resolve({
90
- rows,
91
- totalRows: rows.length,
92
- });
93
- }
94
- });
74
+ if (this.connection) {
75
+ this.connection.all(sql, (err, rows) => {
76
+ if (err) {
77
+ reject(err);
78
+ }
79
+ else {
80
+ resolve({
81
+ rows,
82
+ totalRows: rows.length,
83
+ });
84
+ }
85
+ });
86
+ }
87
+ else {
88
+ reject(new Error("Connection not open"));
89
+ }
95
90
  });
96
91
  }
97
92
  async *runSQLStream(sql, _options = {}) {
98
93
  await this.setup();
94
+ if (!this.connection) {
95
+ throw new Error("Connection not open");
96
+ }
99
97
  const statements = sql.split("-- hack: split on this");
100
98
  while (statements.length > 1) {
101
99
  await this.runDuckDBQuery(statements[0]);
@@ -105,8 +103,17 @@ class DuckDBConnection extends duckdb_common_1.DuckDBCommon {
105
103
  yield row;
106
104
  }
107
105
  }
108
- createHash(sqlCommand) {
109
- return Promise.resolve(crypto.createHash("md5").update(sqlCommand).digest("hex"));
106
+ async createHash(sqlCommand) {
107
+ return crypto_1.default.createHash("md5").update(sqlCommand).digest("hex");
108
+ }
109
+ async close() {
110
+ if (this.connection) {
111
+ this.connection = null;
112
+ }
113
+ if (this.database) {
114
+ this.database.close();
115
+ this.database = null;
116
+ }
110
117
  }
111
118
  }
112
119
  exports.DuckDBConnection = DuckDBConnection;
@@ -1,15 +1,18 @@
1
- import { QueryDataRow, RunSQLOptions } from "@malloydata/malloy";
2
1
  import * as duckdb from "@duckdb/duckdb-wasm";
2
+ import { QueryDataRow, RunSQLOptions } from "@malloydata/malloy";
3
3
  import { DuckDBCommon, QueryOptionsReader } from "./duckdb_common";
4
- export declare class DuckDBWASMConnection extends DuckDBCommon {
4
+ export declare abstract class DuckDBWASMConnection extends DuckDBCommon {
5
5
  readonly name: string;
6
+ private databasePath;
6
7
  private workingDirectory;
7
8
  connecting: Promise<void>;
8
9
  protected _connection: duckdb.AsyncDuckDBConnection | null;
9
10
  protected _database: duckdb.AsyncDuckDB | null;
10
11
  protected isSetup: boolean;
11
- constructor(name: string, databasePath?: string, workingDirectory?: string, queryOptions?: QueryOptionsReader);
12
+ private worker;
13
+ constructor(name: string, databasePath?: string | null, workingDirectory?: string, queryOptions?: QueryOptionsReader);
12
14
  private init;
15
+ abstract getBundles(): duckdb.DuckDBBundles;
13
16
  get connection(): duckdb.AsyncDuckDBConnection | null;
14
17
  get database(): duckdb.AsyncDuckDB | null;
15
18
  protected setup(): Promise<void>;
@@ -18,5 +21,6 @@ export declare class DuckDBWASMConnection extends DuckDBCommon {
18
21
  totalRows: number;
19
22
  }>;
20
23
  runSQLStream(sql: string, _options?: RunSQLOptions): AsyncIterableIterator<QueryDataRow>;
21
- protected createHash(sqlCommand: string): Promise<string>;
24
+ close(): Promise<void>;
25
+ registerRemoteTable(tableName: string, url: string): Promise<void>;
22
26
  }
@@ -22,9 +22,25 @@ var __importStar = (this && this.__importStar) || function (mod) {
22
22
  __setModuleDefault(result, mod);
23
23
  return result;
24
24
  };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
25
28
  Object.defineProperty(exports, "__esModule", { value: true });
26
29
  exports.DuckDBWASMConnection = void 0;
30
+ /*
31
+ * Copyright 2022 Google LLC
32
+ *
33
+ * This program is free software; you can redistribute it and/or
34
+ * modify it under the terms of the GNU General Public License
35
+ * version 2 as published by the Free Software Foundation.
36
+ *
37
+ * This program is distributed in the hope that it will be useful,
38
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
39
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
40
+ * GNU General Public License for more details.
41
+ */
27
42
  const duckdb = __importStar(require("@duckdb/duckdb-wasm"));
43
+ const web_worker_1 = __importDefault(require("web-worker"));
28
44
  const apache_arrow_1 = require("apache-arrow");
29
45
  const duckdb_common_1 = require("./duckdb_common");
30
46
  /**
@@ -89,29 +105,38 @@ const unwrapRow = (row) => {
89
105
  const unwrapTable = (table) => {
90
106
  return table.toArray().map(unwrapRow);
91
107
  };
108
+ const isNode = () => typeof navigator === "undefined";
92
109
  class DuckDBWASMConnection extends duckdb_common_1.DuckDBCommon {
93
- constructor(name, databasePath = "test/data/duckdb/duckdb_test.db", workingDirectory = "/", queryOptions) {
110
+ constructor(name, databasePath = null, workingDirectory = "/", queryOptions) {
94
111
  super(queryOptions);
95
112
  this.name = name;
113
+ this.databasePath = databasePath;
96
114
  this.workingDirectory = workingDirectory;
97
115
  this._connection = null;
98
116
  this._database = null;
99
117
  this.isSetup = false;
118
+ this.worker = null;
100
119
  this.connecting = this.init();
101
120
  }
102
121
  async init() {
103
- const JSDELIVR_BUNDLES = duckdb.getJsDelivrBundles();
104
122
  // Select a bundle based on browser checks
105
- const bundle = await duckdb.selectBundle(JSDELIVR_BUNDLES);
123
+ const bundle = await duckdb.selectBundle(this.getBundles());
106
124
  if (bundle.mainWorker) {
107
- const workerUrl = URL.createObjectURL(new Blob([`importScripts("${bundle.mainWorker}");`], {
108
- type: "text/javascript",
109
- }));
125
+ const workerUrl = isNode()
126
+ ? bundle.mainWorker
127
+ : URL.createObjectURL(new Blob([`importScripts("${bundle.mainWorker}");`], {
128
+ type: "text/javascript",
129
+ }));
110
130
  // Instantiate the asynchronous version of DuckDB-wasm
111
- const worker = new Worker(workerUrl);
112
- const logger = new duckdb.ConsoleLogger();
113
- this._database = new duckdb.AsyncDuckDB(logger, worker);
131
+ this.worker = new web_worker_1.default(workerUrl);
132
+ const logger = new duckdb.VoidLogger();
133
+ this._database = new duckdb.AsyncDuckDB(logger, this.worker);
114
134
  await this._database.instantiate(bundle.mainModule, bundle.pthreadWorker);
135
+ if (this.databasePath) {
136
+ await this._database.open({
137
+ path: this.databasePath,
138
+ });
139
+ }
115
140
  URL.revokeObjectURL(workerUrl);
116
141
  this._connection = await this._database.connect();
117
142
  }
@@ -160,14 +185,23 @@ class DuckDBWASMConnection extends duckdb_common_1.DuckDBCommon {
160
185
  }
161
186
  }
162
187
  }
163
- async createHash(sqlCommand) {
164
- const msgUint8 = new TextEncoder().encode(sqlCommand);
165
- const hashBuffer = await crypto.subtle.digest("SHA-256", msgUint8);
166
- const hashArray = Array.from(new Uint8Array(hashBuffer));
167
- const hashHex = hashArray
168
- .map((b) => b.toString(16).padStart(2, "0"))
169
- .join("");
170
- return hashHex;
188
+ async close() {
189
+ if (this._connection) {
190
+ await this._connection.close();
191
+ this._connection = null;
192
+ }
193
+ if (this._database) {
194
+ await this._database.terminate();
195
+ this._database = null;
196
+ }
197
+ if (this.worker) {
198
+ this.worker.terminate();
199
+ this.worker = null;
200
+ }
201
+ }
202
+ async registerRemoteTable(tableName, url) {
203
+ var _a;
204
+ (_a = this.database) === null || _a === void 0 ? void 0 : _a.registerFileURL(tableName, url, duckdb.DuckDBDataProtocol.HTTP, true);
171
205
  }
172
206
  }
173
207
  exports.DuckDBWASMConnection = DuckDBWASMConnection;
@@ -0,0 +1,6 @@
1
+ import * as duckdb from "@duckdb/duckdb-wasm";
2
+ import { DuckDBWASMConnection as DuckDBWASMConnectionBase } from "./duckdb_wasm_connection";
3
+ export declare class DuckDBWASMConnection extends DuckDBWASMConnectionBase {
4
+ getBundles(): duckdb.DuckDBBundles;
5
+ createHash(sqlCommand: string): Promise<string>;
6
+ }
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ /*
3
+ * Copyright 2022 Google LLC
4
+ *
5
+ * This program is free software; you can redistribute it and/or
6
+ * modify it under the terms of the GNU General Public License
7
+ * version 2 as published by the Free Software Foundation.
8
+ *
9
+ * This program is distributed in the hope that it will be useful,
10
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ * GNU General Public License for more details.
13
+ */
14
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
15
+ if (k2 === undefined) k2 = k;
16
+ var desc = Object.getOwnPropertyDescriptor(m, k);
17
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
18
+ desc = { enumerable: true, get: function() { return m[k]; } };
19
+ }
20
+ Object.defineProperty(o, k2, desc);
21
+ }) : (function(o, m, k, k2) {
22
+ if (k2 === undefined) k2 = k;
23
+ o[k2] = m[k];
24
+ }));
25
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
26
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
27
+ }) : function(o, v) {
28
+ o["default"] = v;
29
+ });
30
+ var __importStar = (this && this.__importStar) || function (mod) {
31
+ if (mod && mod.__esModule) return mod;
32
+ var result = {};
33
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
34
+ __setModuleDefault(result, mod);
35
+ return result;
36
+ };
37
+ Object.defineProperty(exports, "__esModule", { value: true });
38
+ exports.DuckDBWASMConnection = void 0;
39
+ const duckdb = __importStar(require("@duckdb/duckdb-wasm"));
40
+ const duckdb_wasm_connection_1 = require("./duckdb_wasm_connection");
41
+ class DuckDBWASMConnection extends duckdb_wasm_connection_1.DuckDBWASMConnection {
42
+ getBundles() {
43
+ return duckdb.getJsDelivrBundles();
44
+ }
45
+ async createHash(sqlCommand) {
46
+ const msgUint8 = new TextEncoder().encode(sqlCommand);
47
+ const hashBuffer = await crypto.subtle.digest("SHA-256", msgUint8);
48
+ const hashArray = Array.from(new Uint8Array(hashBuffer));
49
+ const hashHex = hashArray
50
+ .map((b) => b.toString(16).padStart(2, "0"))
51
+ .join("");
52
+ return hashHex;
53
+ }
54
+ }
55
+ exports.DuckDBWASMConnection = DuckDBWASMConnection;
56
+ //# sourceMappingURL=duckdb_wasm_connection_browser.js.map
@@ -0,0 +1,6 @@
1
+ import { DuckDBBundles } from "@duckdb/duckdb-wasm";
2
+ import { DuckDBWASMConnection as DuckDBWASMConnectionBase } from "./duckdb_wasm_connection";
3
+ export declare class DuckDBWASMConnection extends DuckDBWASMConnectionBase {
4
+ getBundles(): DuckDBBundles;
5
+ createHash(sqlCommand: string): Promise<string>;
6
+ }
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ /*
3
+ * Copyright 2022 Google LLC
4
+ *
5
+ * This program is free software; you can redistribute it and/or
6
+ * modify it under the terms of the GNU General Public License
7
+ * version 2 as published by the Free Software Foundation.
8
+ *
9
+ * This program is distributed in the hope that it will be useful,
10
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ * GNU General Public License for more details.
13
+ */
14
+ var __importDefault = (this && this.__importDefault) || function (mod) {
15
+ return (mod && mod.__esModule) ? mod : { "default": mod };
16
+ };
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.DuckDBWASMConnection = void 0;
19
+ const crypto_1 = __importDefault(require("crypto"));
20
+ const duckdb_wasm_connection_1 = require("./duckdb_wasm_connection");
21
+ class DuckDBWASMConnection extends duckdb_wasm_connection_1.DuckDBWASMConnection {
22
+ getBundles() {
23
+ const resolvePath = require.resolve("@duckdb/duckdb-wasm");
24
+ if (!resolvePath) {
25
+ throw new Error("Unable to resolve @duckdb/duckdb-wasm path");
26
+ }
27
+ const distMatch = resolvePath.match(/^.*\/dist\//);
28
+ if (!distMatch) {
29
+ throw new Error("Unable to resolve @duckdb/duckdb-wasm dist path");
30
+ }
31
+ const dist = distMatch[0];
32
+ return {
33
+ mvp: {
34
+ mainModule: `${dist}/duckdb-mvp.wasm`,
35
+ mainWorker: `${dist}/duckdb-node-mvp.worker.cjs`,
36
+ },
37
+ eh: {
38
+ mainModule: `${dist}/duckdb-eh.wasm`,
39
+ mainWorker: `${dist}/duckdb-node-eh.worker.cjs`,
40
+ },
41
+ };
42
+ }
43
+ async createHash(sqlCommand) {
44
+ return crypto_1.default.createHash("md5").update(sqlCommand).digest("hex");
45
+ }
46
+ }
47
+ exports.DuckDBWASMConnection = DuckDBWASMConnection;
48
+ //# sourceMappingURL=duckdb_wasm_connection_node.js.map
package/package.json CHANGED
@@ -1,9 +1,27 @@
1
1
  {
2
2
  "name": "@malloydata/db-duckdb",
3
- "version": "0.0.20-dev230107153725",
3
+ "version": "0.0.20-dev230110224239",
4
4
  "license": "GPL-2.0",
5
- "main": "dist/index.js",
6
- "types": "dist/index.d.ts",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "exports": {
8
+ ".": "./dist/index.js",
9
+ "./package.json": "./package.json",
10
+ "./wasm": {
11
+ "browser": "./dist/duckdb_wasm_connection_browser.js",
12
+ "node": "./dist/duckdb_wasm_connection_node.js"
13
+ }
14
+ },
15
+ "typesVersions": {
16
+ "*": {
17
+ "index": [
18
+ "./dist/index.d.ts"
19
+ ],
20
+ "wasm": [
21
+ "./dist/duckdb_wasm_connection_browser.d.ts"
22
+ ]
23
+ }
24
+ },
7
25
  "homepage": "https://github.com/malloydata/malloy#readme",
8
26
  "repository": {
9
27
  "type": "git",
@@ -18,8 +36,9 @@
18
36
  "prepublishOnly": "npm run build"
19
37
  },
20
38
  "dependencies": {
21
- "@duckdb/duckdb-wasm": "^1.17.0",
22
- "@malloydata/malloy": "^0.0.20-dev230107153725",
23
- "duckdb": "0.6.1"
39
+ "@duckdb/duckdb-wasm": "^1.20.0",
40
+ "@malloydata/malloy": "^0.0.20-dev230110224239",
41
+ "duckdb": "0.6.1",
42
+ "web-worker": "^1.2.0"
24
43
  }
25
44
  }