@visactor/vquery 0.1.46 → 0.1.47
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/{dataset.d.ts → dataset/dataset.d.ts} +7 -5
- package/dist/dataset/index.d.ts +1 -0
- package/dist/index.cjs +46 -40
- package/dist/index.js +46 -40
- package/dist/vquery.d.ts +12 -2
- package/package.json +1 -1
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DatasetColumn } from '../types';
|
|
2
|
+
import { DuckDB } from '../db/duckDb';
|
|
3
|
+
import { IndexedDB } from '../db/indexedDb';
|
|
2
4
|
export declare class Dataset {
|
|
3
5
|
private duckDB;
|
|
6
|
+
private indexedDB;
|
|
4
7
|
private _datasetId;
|
|
5
|
-
|
|
6
|
-
|
|
8
|
+
constructor(duckDB: DuckDB, indexedDB: IndexedDB, datasetId: string);
|
|
9
|
+
init(temporaryStructs?: DatasetColumn[]): Promise<void>;
|
|
7
10
|
queryBySQL(sql: string): Promise<{
|
|
8
11
|
performance: {
|
|
9
12
|
startAt: string;
|
|
@@ -13,7 +16,6 @@ export declare class Dataset {
|
|
|
13
16
|
dataset: any[];
|
|
14
17
|
table: any;
|
|
15
18
|
}>;
|
|
16
|
-
|
|
19
|
+
disconnect(): Promise<void>;
|
|
17
20
|
get datasetId(): string;
|
|
18
|
-
get tableName(): string;
|
|
19
21
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Dataset } from './dataset';
|
package/dist/index.cjs
CHANGED
|
@@ -35,12 +35,39 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
35
35
|
});
|
|
36
36
|
class Dataset {
|
|
37
37
|
duckDB;
|
|
38
|
+
indexedDB;
|
|
38
39
|
_datasetId;
|
|
39
|
-
|
|
40
|
-
constructor(duckDB, datasetId, tableName){
|
|
40
|
+
constructor(duckDB, indexedDB1, datasetId){
|
|
41
41
|
this.duckDB = duckDB;
|
|
42
|
+
this.indexedDB = indexedDB1;
|
|
42
43
|
this._datasetId = datasetId;
|
|
43
|
-
|
|
44
|
+
}
|
|
45
|
+
async init(temporaryStructs) {
|
|
46
|
+
const readFunctionMap = {
|
|
47
|
+
csv: 'read_csv_auto',
|
|
48
|
+
json: 'read_json_auto',
|
|
49
|
+
xlsx: 'read_excel',
|
|
50
|
+
parquet: 'read_parquet'
|
|
51
|
+
};
|
|
52
|
+
const dataTypeMap = {
|
|
53
|
+
number: 'DOUBLE',
|
|
54
|
+
string: 'VARCHAR',
|
|
55
|
+
date: 'DATE',
|
|
56
|
+
datetime: 'TIMESTAMP',
|
|
57
|
+
timestamp: 'TIMESTAMP'
|
|
58
|
+
};
|
|
59
|
+
const datasetInfo = await this.indexedDB.readDataset(this._datasetId);
|
|
60
|
+
if (!datasetInfo) throw new Error(`Dataset ${this._datasetId} not found`);
|
|
61
|
+
const { dataSource } = datasetInfo;
|
|
62
|
+
const datasetSchema = datasetInfo.datasetSchema;
|
|
63
|
+
const columns = temporaryStructs || datasetSchema.columns;
|
|
64
|
+
const readFunction = readFunctionMap[dataSource.type];
|
|
65
|
+
if (!readFunction) throw new Error(`Unsupported dataSource type: ${dataSource.type}`);
|
|
66
|
+
await this.duckDB.writeFile(this._datasetId, dataSource.blob);
|
|
67
|
+
const columnsStruct = `{${columns.map((c)=>`'${c.name}': '${dataTypeMap[c.type] || 'VARCHAR'}'`).join(', ')}}`;
|
|
68
|
+
const columnNames = columns.map((c)=>`"${c.name}"`).join(', ');
|
|
69
|
+
const createViewSql = `CREATE OR REPLACE VIEW "${this._datasetId}" AS SELECT ${columnNames} FROM ${readFunction}('${this._datasetId}', columns=${columnsStruct})`;
|
|
70
|
+
await this.duckDB.query(createViewSql);
|
|
44
71
|
}
|
|
45
72
|
async queryBySQL(sql) {
|
|
46
73
|
const start = performance?.now?.()?.toFixed(3) ?? Date.now().toFixed(3);
|
|
@@ -55,13 +82,12 @@ class Dataset {
|
|
|
55
82
|
}
|
|
56
83
|
};
|
|
57
84
|
}
|
|
58
|
-
async
|
|
85
|
+
async disconnect() {
|
|
86
|
+
await this.duckDB.query(`DROP VIEW IF EXISTS "${this._datasetId}"`);
|
|
87
|
+
}
|
|
59
88
|
get datasetId() {
|
|
60
89
|
return this._datasetId;
|
|
61
90
|
}
|
|
62
|
-
get tableName() {
|
|
63
|
-
return this._tableName;
|
|
64
|
-
}
|
|
65
91
|
}
|
|
66
92
|
const duckdb_wasm_namespaceObject = require("@duckdb/duckdb-wasm");
|
|
67
93
|
class DuckDB {
|
|
@@ -312,22 +338,6 @@ class DataSourceBuilder {
|
|
|
312
338
|
return await response.blob();
|
|
313
339
|
}
|
|
314
340
|
}
|
|
315
|
-
function mapDataTypeToDuckDB(type) {
|
|
316
|
-
switch(type){
|
|
317
|
-
case 'number':
|
|
318
|
-
return 'DOUBLE';
|
|
319
|
-
case 'string':
|
|
320
|
-
return 'VARCHAR';
|
|
321
|
-
case 'date':
|
|
322
|
-
return 'DATE';
|
|
323
|
-
case 'datetime':
|
|
324
|
-
return 'TIMESTAMP';
|
|
325
|
-
case 'timestamp':
|
|
326
|
-
return 'TIMESTAMP';
|
|
327
|
-
default:
|
|
328
|
-
return 'VARCHAR';
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
341
|
class VQuery {
|
|
332
342
|
duckDB;
|
|
333
343
|
indexedDB;
|
|
@@ -363,23 +373,19 @@ class VQuery {
|
|
|
363
373
|
}
|
|
364
374
|
async connectDataset(datasetId) {
|
|
365
375
|
await this.ensureInitialized();
|
|
366
|
-
const
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
await this.
|
|
378
|
-
|
|
379
|
-
const columnNames = datasetSchema.columns.map((c)=>`"${c.name}"`).join(', ');
|
|
380
|
-
const createViewSql = `CREATE OR REPLACE VIEW "${datasetId}" AS SELECT ${columnNames} FROM ${readFunction}('${datasetId}', columns=${columnsStruct})`;
|
|
381
|
-
await this.duckDB.query(createViewSql);
|
|
382
|
-
return new Dataset(this.duckDB, datasetId, datasetSchema.datasetAlias || datasetId);
|
|
376
|
+
const dataset = new Dataset(this.duckDB, this.indexedDB, datasetId);
|
|
377
|
+
await dataset.init();
|
|
378
|
+
return dataset;
|
|
379
|
+
}
|
|
380
|
+
async connectTemporaryDataset(datasetId, temporaryDatasetSchema) {
|
|
381
|
+
await this.ensureInitialized();
|
|
382
|
+
const dataset = new Dataset(this.duckDB, this.indexedDB, datasetId);
|
|
383
|
+
await dataset.init(temporaryDatasetSchema);
|
|
384
|
+
return dataset;
|
|
385
|
+
}
|
|
386
|
+
async close() {
|
|
387
|
+
await this.ensureInitialized();
|
|
388
|
+
await this.duckDB.close();
|
|
383
389
|
}
|
|
384
390
|
}
|
|
385
391
|
exports.DataSourceBuilder = __webpack_exports__.DataSourceBuilder;
|
package/dist/index.js
CHANGED
|
@@ -1,12 +1,39 @@
|
|
|
1
1
|
import { AsyncDuckDB, ConsoleLogger, selectBundle } from "@duckdb/duckdb-wasm";
|
|
2
2
|
class Dataset {
|
|
3
3
|
duckDB;
|
|
4
|
+
indexedDB;
|
|
4
5
|
_datasetId;
|
|
5
|
-
|
|
6
|
-
constructor(duckDB, datasetId, tableName){
|
|
6
|
+
constructor(duckDB, indexedDB1, datasetId){
|
|
7
7
|
this.duckDB = duckDB;
|
|
8
|
+
this.indexedDB = indexedDB1;
|
|
8
9
|
this._datasetId = datasetId;
|
|
9
|
-
|
|
10
|
+
}
|
|
11
|
+
async init(temporaryStructs) {
|
|
12
|
+
const readFunctionMap = {
|
|
13
|
+
csv: 'read_csv_auto',
|
|
14
|
+
json: 'read_json_auto',
|
|
15
|
+
xlsx: 'read_excel',
|
|
16
|
+
parquet: 'read_parquet'
|
|
17
|
+
};
|
|
18
|
+
const dataTypeMap = {
|
|
19
|
+
number: 'DOUBLE',
|
|
20
|
+
string: 'VARCHAR',
|
|
21
|
+
date: 'DATE',
|
|
22
|
+
datetime: 'TIMESTAMP',
|
|
23
|
+
timestamp: 'TIMESTAMP'
|
|
24
|
+
};
|
|
25
|
+
const datasetInfo = await this.indexedDB.readDataset(this._datasetId);
|
|
26
|
+
if (!datasetInfo) throw new Error(`Dataset ${this._datasetId} not found`);
|
|
27
|
+
const { dataSource } = datasetInfo;
|
|
28
|
+
const datasetSchema = datasetInfo.datasetSchema;
|
|
29
|
+
const columns = temporaryStructs || datasetSchema.columns;
|
|
30
|
+
const readFunction = readFunctionMap[dataSource.type];
|
|
31
|
+
if (!readFunction) throw new Error(`Unsupported dataSource type: ${dataSource.type}`);
|
|
32
|
+
await this.duckDB.writeFile(this._datasetId, dataSource.blob);
|
|
33
|
+
const columnsStruct = `{${columns.map((c)=>`'${c.name}': '${dataTypeMap[c.type] || 'VARCHAR'}'`).join(', ')}}`;
|
|
34
|
+
const columnNames = columns.map((c)=>`"${c.name}"`).join(', ');
|
|
35
|
+
const createViewSql = `CREATE OR REPLACE VIEW "${this._datasetId}" AS SELECT ${columnNames} FROM ${readFunction}('${this._datasetId}', columns=${columnsStruct})`;
|
|
36
|
+
await this.duckDB.query(createViewSql);
|
|
10
37
|
}
|
|
11
38
|
async queryBySQL(sql) {
|
|
12
39
|
const start = performance?.now?.()?.toFixed(3) ?? Date.now().toFixed(3);
|
|
@@ -21,13 +48,12 @@ class Dataset {
|
|
|
21
48
|
}
|
|
22
49
|
};
|
|
23
50
|
}
|
|
24
|
-
async
|
|
51
|
+
async disconnect() {
|
|
52
|
+
await this.duckDB.query(`DROP VIEW IF EXISTS "${this._datasetId}"`);
|
|
53
|
+
}
|
|
25
54
|
get datasetId() {
|
|
26
55
|
return this._datasetId;
|
|
27
56
|
}
|
|
28
|
-
get tableName() {
|
|
29
|
-
return this._tableName;
|
|
30
|
-
}
|
|
31
57
|
}
|
|
32
58
|
class DuckDB {
|
|
33
59
|
db = null;
|
|
@@ -277,22 +303,6 @@ class DataSourceBuilder {
|
|
|
277
303
|
return await response.blob();
|
|
278
304
|
}
|
|
279
305
|
}
|
|
280
|
-
function mapDataTypeToDuckDB(type) {
|
|
281
|
-
switch(type){
|
|
282
|
-
case 'number':
|
|
283
|
-
return 'DOUBLE';
|
|
284
|
-
case 'string':
|
|
285
|
-
return 'VARCHAR';
|
|
286
|
-
case 'date':
|
|
287
|
-
return 'DATE';
|
|
288
|
-
case 'datetime':
|
|
289
|
-
return 'TIMESTAMP';
|
|
290
|
-
case 'timestamp':
|
|
291
|
-
return 'TIMESTAMP';
|
|
292
|
-
default:
|
|
293
|
-
return 'VARCHAR';
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
306
|
class VQuery {
|
|
297
307
|
duckDB;
|
|
298
308
|
indexedDB;
|
|
@@ -328,23 +338,19 @@ class VQuery {
|
|
|
328
338
|
}
|
|
329
339
|
async connectDataset(datasetId) {
|
|
330
340
|
await this.ensureInitialized();
|
|
331
|
-
const
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
await this.
|
|
343
|
-
|
|
344
|
-
const columnNames = datasetSchema.columns.map((c)=>`"${c.name}"`).join(', ');
|
|
345
|
-
const createViewSql = `CREATE OR REPLACE VIEW "${datasetId}" AS SELECT ${columnNames} FROM ${readFunction}('${datasetId}', columns=${columnsStruct})`;
|
|
346
|
-
await this.duckDB.query(createViewSql);
|
|
347
|
-
return new Dataset(this.duckDB, datasetId, datasetSchema.datasetAlias || datasetId);
|
|
341
|
+
const dataset = new Dataset(this.duckDB, this.indexedDB, datasetId);
|
|
342
|
+
await dataset.init();
|
|
343
|
+
return dataset;
|
|
344
|
+
}
|
|
345
|
+
async connectTemporaryDataset(datasetId, temporaryDatasetSchema) {
|
|
346
|
+
await this.ensureInitialized();
|
|
347
|
+
const dataset = new Dataset(this.duckDB, this.indexedDB, datasetId);
|
|
348
|
+
await dataset.init(temporaryDatasetSchema);
|
|
349
|
+
return dataset;
|
|
350
|
+
}
|
|
351
|
+
async close() {
|
|
352
|
+
await this.ensureInitialized();
|
|
353
|
+
await this.duckDB.close();
|
|
348
354
|
}
|
|
349
355
|
}
|
|
350
356
|
export { DataSourceBuilder, VQuery, isBase64Url, isHttpUrl, isUrl };
|
package/dist/vquery.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Dataset } from './dataset';
|
|
2
|
-
import { DatasetSchema, TidyDatum, DataSourceType } from './types';
|
|
1
|
+
import { Dataset } from './dataset/dataset';
|
|
2
|
+
import { DatasetSchema, TidyDatum, DataSourceType, DatasetColumn } from './types';
|
|
3
3
|
export declare class VQuery {
|
|
4
4
|
private duckDB;
|
|
5
5
|
private indexedDB;
|
|
@@ -30,4 +30,14 @@ export declare class VQuery {
|
|
|
30
30
|
* 连接数据集,返回数据集信息,从indexedDB获取表结构,使用DuckDB在内存中创建表
|
|
31
31
|
*/
|
|
32
32
|
connectDataset(datasetId: string): Promise<Dataset>;
|
|
33
|
+
/**
|
|
34
|
+
* 连接临时数据集,返回数据集信息,从indexedDB获取表结构,使用DuckDB在内存中创建表
|
|
35
|
+
* @param datasetId
|
|
36
|
+
* @returns
|
|
37
|
+
*/
|
|
38
|
+
connectTemporaryDataset(datasetId: string, temporaryDatasetSchema?: DatasetColumn[]): Promise<Dataset>;
|
|
39
|
+
/**
|
|
40
|
+
* 关闭所有数据集连接,释放DuckDB资源
|
|
41
|
+
*/
|
|
42
|
+
close(): Promise<void>;
|
|
33
43
|
}
|