@malloydata/db-duckdb 0.0.22-dev230207182613 → 0.0.22-dev230208192220
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_common.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Connection, MalloyQueryData, PersistSQLResults, PooledConnection, RunSQLOptions, SQLBlock, StreamingConnection, StructDef
|
|
1
|
+
import { Connection, MalloyQueryData, PersistSQLResults, PooledConnection, QueryDataRow, RunSQLOptions, SQLBlock, StreamingConnection, StructDef } from "@malloydata/malloy";
|
|
2
2
|
export interface DuckDBQueryOptions {
|
|
3
3
|
rowLimit: number;
|
|
4
4
|
}
|
package/dist/duckdb_common.js
CHANGED
|
@@ -25,15 +25,15 @@ exports.DuckDBCommon = void 0;
|
|
|
25
25
|
*/
|
|
26
26
|
const malloy_1 = require("@malloydata/malloy");
|
|
27
27
|
const duckDBToMalloyTypes = {
|
|
28
|
-
BIGINT: "number",
|
|
29
|
-
DOUBLE: "number",
|
|
30
|
-
VARCHAR: "string",
|
|
31
|
-
DATE: "date",
|
|
32
|
-
TIMESTAMP: "timestamp",
|
|
33
|
-
TIME: "string",
|
|
34
|
-
DECIMAL: "number",
|
|
35
|
-
BOOLEAN: "boolean",
|
|
36
|
-
INTEGER: "number"
|
|
28
|
+
"BIGINT": "number",
|
|
29
|
+
"DOUBLE": "number",
|
|
30
|
+
"VARCHAR": "string",
|
|
31
|
+
"DATE": "date",
|
|
32
|
+
"TIMESTAMP": "timestamp",
|
|
33
|
+
"TIME": "string",
|
|
34
|
+
"DECIMAL": "number",
|
|
35
|
+
"BOOLEAN": "boolean",
|
|
36
|
+
"INTEGER": "number"
|
|
37
37
|
};
|
|
38
38
|
class DuckDBCommon {
|
|
39
39
|
constructor(queryOptions) {
|
|
@@ -83,23 +83,23 @@ class DuckDBCommon {
|
|
|
83
83
|
if (result.length > rowLimit) {
|
|
84
84
|
result = result.slice(0, rowLimit);
|
|
85
85
|
}
|
|
86
|
-
return { rows: result, totalRows: result.length };
|
|
86
|
+
return { "rows": result, "totalRows": result.length };
|
|
87
87
|
}
|
|
88
88
|
async getSQLBlockSchema(sqlRef) {
|
|
89
89
|
const structDef = {
|
|
90
|
-
type: "struct",
|
|
91
|
-
dialect: "duckdb",
|
|
92
|
-
name: sqlRef.name,
|
|
93
|
-
structSource: {
|
|
94
|
-
type: "sql",
|
|
95
|
-
method: "subquery",
|
|
96
|
-
sqlBlock: sqlRef
|
|
90
|
+
"type": "struct",
|
|
91
|
+
"dialect": "duckdb",
|
|
92
|
+
"name": sqlRef.name,
|
|
93
|
+
"structSource": {
|
|
94
|
+
"type": "sql",
|
|
95
|
+
"method": "subquery",
|
|
96
|
+
"sqlBlock": sqlRef
|
|
97
97
|
},
|
|
98
|
-
structRelationship: {
|
|
99
|
-
type: "basetable",
|
|
100
|
-
connectionName: this.name
|
|
98
|
+
"structRelationship": {
|
|
99
|
+
"type": "basetable",
|
|
100
|
+
"connectionName": this.name
|
|
101
101
|
},
|
|
102
|
-
fields: []
|
|
102
|
+
"fields": []
|
|
103
103
|
};
|
|
104
104
|
await this.schemaFromQuery(`DESCRIBE SELECT * FROM (${sqlRef.selectStr})`, structDef);
|
|
105
105
|
return structDef;
|
|
@@ -174,16 +174,16 @@ class DuckDBCommon {
|
|
|
174
174
|
if (structMatch && structMatch.groups) {
|
|
175
175
|
const newTypeMap = this.stringToTypeMap(structMatch.groups["fields"]);
|
|
176
176
|
const innerStructDef = {
|
|
177
|
-
type: "struct",
|
|
177
|
+
"type": "struct",
|
|
178
178
|
name,
|
|
179
|
-
dialect: this.dialectName,
|
|
180
|
-
structSource: { type: arrayMatch ? "nested" : "inline" },
|
|
181
|
-
structRelationship: {
|
|
182
|
-
type: arrayMatch ? "nested" : "inline",
|
|
183
|
-
field: name,
|
|
184
|
-
isArray: false
|
|
179
|
+
"dialect": this.dialectName,
|
|
180
|
+
"structSource": { "type": arrayMatch ? "nested" : "inline" },
|
|
181
|
+
"structRelationship": {
|
|
182
|
+
"type": arrayMatch ? "nested" : "inline",
|
|
183
|
+
"field": name,
|
|
184
|
+
"isArray": false
|
|
185
185
|
},
|
|
186
|
-
fields: []
|
|
186
|
+
"fields": []
|
|
187
187
|
};
|
|
188
188
|
this.fillStructDefFromTypeMap(innerStructDef, newTypeMap);
|
|
189
189
|
structDef.fields.push(innerStructDef);
|
|
@@ -192,27 +192,31 @@ class DuckDBCommon {
|
|
|
192
192
|
if (arrayMatch) {
|
|
193
193
|
malloyType = duckDBToMalloyTypes[duckDBType];
|
|
194
194
|
const innerStructDef = {
|
|
195
|
-
type: "struct",
|
|
195
|
+
"type": "struct",
|
|
196
196
|
name,
|
|
197
|
-
dialect: this.dialectName,
|
|
198
|
-
structSource: { type: "nested" },
|
|
199
|
-
structRelationship: {
|
|
200
|
-
|
|
197
|
+
"dialect": this.dialectName,
|
|
198
|
+
"structSource": { "type": "nested" },
|
|
199
|
+
"structRelationship": {
|
|
200
|
+
"type": "nested",
|
|
201
|
+
"field": name,
|
|
202
|
+
"isArray": true
|
|
203
|
+
},
|
|
204
|
+
"fields": [{ "type": malloyType, "name": "value" }]
|
|
201
205
|
};
|
|
202
206
|
structDef.fields.push(innerStructDef);
|
|
203
207
|
}
|
|
204
208
|
else {
|
|
205
209
|
if (malloyType !== undefined) {
|
|
206
210
|
structDef.fields.push({
|
|
207
|
-
type: malloyType,
|
|
208
|
-
name
|
|
211
|
+
"type": malloyType,
|
|
212
|
+
name
|
|
209
213
|
});
|
|
210
214
|
}
|
|
211
215
|
else {
|
|
212
216
|
structDef.fields.push({
|
|
213
217
|
name,
|
|
214
|
-
type: "string",
|
|
215
|
-
e: [`'DuckDB type "${duckDBType}" not supported by Malloy'`]
|
|
218
|
+
"type": "string",
|
|
219
|
+
"e": [`'DuckDB type "${duckDBType}" not supported by Malloy'`]
|
|
216
220
|
});
|
|
217
221
|
}
|
|
218
222
|
}
|
|
@@ -233,11 +237,11 @@ class DuckDBCommon {
|
|
|
233
237
|
if (!inCache) {
|
|
234
238
|
try {
|
|
235
239
|
inCache = {
|
|
236
|
-
structDef: await this.getSQLBlockSchema(sqlRef)
|
|
240
|
+
"structDef": await this.getSQLBlockSchema(sqlRef)
|
|
237
241
|
};
|
|
238
242
|
}
|
|
239
243
|
catch (error) {
|
|
240
|
-
inCache = { error: error.message };
|
|
244
|
+
inCache = { "error": error.message };
|
|
241
245
|
}
|
|
242
246
|
this.sqlSchemaCache.set(key, inCache);
|
|
243
247
|
}
|
|
@@ -251,12 +255,12 @@ class DuckDBCommon {
|
|
|
251
255
|
if (!inCache) {
|
|
252
256
|
try {
|
|
253
257
|
inCache = {
|
|
254
|
-
schema: await this.getTableSchema(tableURL)
|
|
258
|
+
"schema": await this.getTableSchema(tableURL)
|
|
255
259
|
};
|
|
256
260
|
this.schemaCache.set(tableURL, inCache);
|
|
257
261
|
}
|
|
258
262
|
catch (error) {
|
|
259
|
-
inCache = { error: error.message };
|
|
263
|
+
inCache = { "error": error.message };
|
|
260
264
|
}
|
|
261
265
|
}
|
|
262
266
|
if (inCache.schema !== undefined) {
|
|
@@ -271,15 +275,15 @@ class DuckDBCommon {
|
|
|
271
275
|
async getTableSchema(tableURL) {
|
|
272
276
|
const { tablePath } = (0, malloy_1.parseTableURI)(tableURL);
|
|
273
277
|
const structDef = {
|
|
274
|
-
type: "struct",
|
|
275
|
-
name: tablePath,
|
|
276
|
-
dialect: "duckdb",
|
|
277
|
-
structSource: { type: "table", tablePath },
|
|
278
|
-
structRelationship: {
|
|
279
|
-
type: "basetable",
|
|
280
|
-
connectionName: this.name
|
|
278
|
+
"type": "struct",
|
|
279
|
+
"name": tablePath,
|
|
280
|
+
"dialect": "duckdb",
|
|
281
|
+
"structSource": { "type": "table", tablePath },
|
|
282
|
+
"structRelationship": {
|
|
283
|
+
"type": "basetable",
|
|
284
|
+
"connectionName": this.name
|
|
281
285
|
},
|
|
282
|
-
fields: []
|
|
286
|
+
"fields": []
|
|
283
287
|
};
|
|
284
288
|
const quotedTablePath = tablePath.match(/[:*/]/)
|
|
285
289
|
? `'${tablePath}'`
|
|
@@ -305,6 +309,6 @@ class DuckDBCommon {
|
|
|
305
309
|
}
|
|
306
310
|
exports.DuckDBCommon = DuckDBCommon;
|
|
307
311
|
DuckDBCommon.DEFAULT_QUERY_OPTIONS = {
|
|
308
|
-
rowLimit: 10
|
|
312
|
+
"rowLimit": 10
|
|
309
313
|
};
|
|
310
314
|
//# sourceMappingURL=duckdb_common.js.map
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as duckdb from "@duckdb/duckdb-wasm";
|
|
2
|
-
import { QueryDataRow, RunSQLOptions } from "@malloydata/malloy";
|
|
2
|
+
import { QueryDataRow, RunSQLOptions, StructDef } from "@malloydata/malloy";
|
|
3
3
|
import { DuckDBCommon, QueryOptionsReader } from "./duckdb_common";
|
|
4
|
+
declare type RemoteFileCallback = (tableName: string) => Promise<Uint8Array | undefined>;
|
|
4
5
|
export declare abstract class DuckDBWASMConnection extends DuckDBCommon {
|
|
5
6
|
readonly name: string;
|
|
6
7
|
private databasePath;
|
|
@@ -10,6 +11,8 @@ export declare abstract class DuckDBWASMConnection extends DuckDBCommon {
|
|
|
10
11
|
protected _database: duckdb.AsyncDuckDB | null;
|
|
11
12
|
protected isSetup: boolean;
|
|
12
13
|
private worker;
|
|
14
|
+
private remoteFileCallbacks;
|
|
15
|
+
private remoteFileStatus;
|
|
13
16
|
constructor(name: string, databasePath?: string | null, workingDirectory?: string, queryOptions?: QueryOptionsReader);
|
|
14
17
|
private init;
|
|
15
18
|
abstract getBundles(): duckdb.DuckDBBundles;
|
|
@@ -21,6 +24,12 @@ export declare abstract class DuckDBWASMConnection extends DuckDBCommon {
|
|
|
21
24
|
totalRows: number;
|
|
22
25
|
}>;
|
|
23
26
|
runSQLStream(sql: string, _options?: RunSQLOptions): AsyncIterableIterator<QueryDataRow>;
|
|
27
|
+
fetchSchemaForTables(tables: string[]): Promise<{
|
|
28
|
+
schemas: Record<string, StructDef>;
|
|
29
|
+
errors: Record<string, string>;
|
|
30
|
+
}>;
|
|
24
31
|
close(): Promise<void>;
|
|
32
|
+
registerRemoteTableCallback(callback: RemoteFileCallback): void;
|
|
25
33
|
registerRemoteTable(tableName: string, url: string): Promise<void>;
|
|
26
34
|
}
|
|
35
|
+
export {};
|
|
@@ -51,6 +51,7 @@ exports.DuckDBWASMConnection = void 0;
|
|
|
51
51
|
*/
|
|
52
52
|
const duckdb = __importStar(require("@duckdb/duckdb-wasm"));
|
|
53
53
|
const web_worker_1 = __importDefault(require("web-worker"));
|
|
54
|
+
const malloy_1 = require("@malloydata/malloy");
|
|
54
55
|
const apache_arrow_1 = require("apache-arrow");
|
|
55
56
|
const duckdb_common_1 = require("./duckdb_common");
|
|
56
57
|
/**
|
|
@@ -126,6 +127,8 @@ class DuckDBWASMConnection extends duckdb_common_1.DuckDBCommon {
|
|
|
126
127
|
this._database = null;
|
|
127
128
|
this.isSetup = false;
|
|
128
129
|
this.worker = null;
|
|
130
|
+
this.remoteFileCallbacks = [];
|
|
131
|
+
this.remoteFileStatus = {};
|
|
129
132
|
this.connecting = this.init();
|
|
130
133
|
}
|
|
131
134
|
async init() {
|
|
@@ -135,7 +138,7 @@ class DuckDBWASMConnection extends duckdb_common_1.DuckDBCommon {
|
|
|
135
138
|
const workerUrl = isNode()
|
|
136
139
|
? bundle.mainWorker
|
|
137
140
|
: URL.createObjectURL(new Blob([`importScripts("${bundle.mainWorker}");`], {
|
|
138
|
-
type: "text/javascript"
|
|
141
|
+
"type": "text/javascript"
|
|
139
142
|
}));
|
|
140
143
|
// Instantiate the asynchronous version of DuckDB-wasm
|
|
141
144
|
this.worker = new web_worker_1.default(workerUrl);
|
|
@@ -144,7 +147,7 @@ class DuckDBWASMConnection extends duckdb_common_1.DuckDBCommon {
|
|
|
144
147
|
await this._database.instantiate(bundle.mainModule, bundle.pthreadWorker);
|
|
145
148
|
if (this.databasePath) {
|
|
146
149
|
await this._database.open({
|
|
147
|
-
path: this.databasePath
|
|
150
|
+
"path": this.databasePath
|
|
148
151
|
});
|
|
149
152
|
}
|
|
150
153
|
URL.revokeObjectURL(workerUrl);
|
|
@@ -172,7 +175,7 @@ class DuckDBWASMConnection extends duckdb_common_1.DuckDBCommon {
|
|
|
172
175
|
return {
|
|
173
176
|
// Normalize the data from its default proxied form
|
|
174
177
|
rows,
|
|
175
|
-
totalRows: table.numRows
|
|
178
|
+
"totalRows": table.numRows
|
|
176
179
|
};
|
|
177
180
|
}
|
|
178
181
|
else {
|
|
@@ -195,6 +198,28 @@ class DuckDBWASMConnection extends duckdb_common_1.DuckDBCommon {
|
|
|
195
198
|
}
|
|
196
199
|
}
|
|
197
200
|
}
|
|
201
|
+
async fetchSchemaForTables(tables) {
|
|
202
|
+
var _a;
|
|
203
|
+
await this.setup();
|
|
204
|
+
for (const tableUri of tables) {
|
|
205
|
+
const { tablePath } = (0, malloy_1.parseTableURI)(tableUri);
|
|
206
|
+
if (tablePath.match(/^https?:\/\//)) {
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
209
|
+
if (this.remoteFileStatus[tablePath]) {
|
|
210
|
+
continue;
|
|
211
|
+
}
|
|
212
|
+
for (const callback of this.remoteFileCallbacks) {
|
|
213
|
+
this.remoteFileStatus[tablePath] = true;
|
|
214
|
+
const data = await callback(tablePath);
|
|
215
|
+
if (data) {
|
|
216
|
+
await ((_a = this.database) === null || _a === void 0 ? void 0 : _a.registerFileBuffer(tablePath, data));
|
|
217
|
+
break;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
return super.fetchSchemaForTables(tables);
|
|
222
|
+
}
|
|
198
223
|
async close() {
|
|
199
224
|
if (this._connection) {
|
|
200
225
|
await this._connection.close();
|
|
@@ -209,6 +234,9 @@ class DuckDBWASMConnection extends duckdb_common_1.DuckDBCommon {
|
|
|
209
234
|
this.worker = null;
|
|
210
235
|
}
|
|
211
236
|
}
|
|
237
|
+
registerRemoteTableCallback(callback) {
|
|
238
|
+
this.remoteFileCallbacks.push(callback);
|
|
239
|
+
}
|
|
212
240
|
async registerRemoteTable(tableName, url) {
|
|
213
241
|
var _a;
|
|
214
242
|
(_a = this.database) === null || _a === void 0 ? void 0 : _a.registerFileURL(tableName, url, duckdb.DuckDBDataProtocol.HTTP, true);
|
|
@@ -40,14 +40,14 @@ class DuckDBWASMConnection extends duckdb_wasm_connection_1.DuckDBWASMConnection
|
|
|
40
40
|
}
|
|
41
41
|
const dist = distMatch[0];
|
|
42
42
|
return {
|
|
43
|
-
mvp: {
|
|
44
|
-
mainModule: `${dist}/duckdb-mvp.wasm`,
|
|
45
|
-
mainWorker: `${dist}/duckdb-node-mvp.worker.cjs
|
|
46
|
-
},
|
|
47
|
-
eh: {
|
|
48
|
-
mainModule: `${dist}/duckdb-eh.wasm`,
|
|
49
|
-
mainWorker: `${dist}/duckdb-node-eh.worker.cjs`,
|
|
43
|
+
"mvp": {
|
|
44
|
+
"mainModule": `${dist}/duckdb-mvp.wasm`,
|
|
45
|
+
"mainWorker": `${dist}/duckdb-node-mvp.worker.cjs`
|
|
50
46
|
},
|
|
47
|
+
"eh": {
|
|
48
|
+
"mainModule": `${dist}/duckdb-eh.wasm`,
|
|
49
|
+
"mainWorker": `${dist}/duckdb-node-eh.worker.cjs`
|
|
50
|
+
}
|
|
51
51
|
};
|
|
52
52
|
}
|
|
53
53
|
async createHash(sqlCommand) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@malloydata/db-duckdb",
|
|
3
|
-
"version": "0.0.22-
|
|
3
|
+
"version": "0.0.22-dev230208192220",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"@duckdb/duckdb-wasm": "^1.20.0",
|
|
41
|
-
"@malloydata/malloy": "^0.0.22-
|
|
41
|
+
"@malloydata/malloy": "^0.0.22-dev230208192220",
|
|
42
42
|
"duckdb": "0.6.1",
|
|
43
43
|
"web-worker": "^1.2.0"
|
|
44
44
|
}
|