@visactor/vquery 0.4.12 → 0.4.14

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.
Files changed (28) hide show
  1. package/dist/browser/esm/adapters/storage-adapter/idb-helpers.d.ts +4 -0
  2. package/dist/browser/esm/browser.js +60 -92
  3. package/dist/browser/esm/dataset/constants.d.ts +7 -0
  4. package/dist/browser/esm/dataset/dataset.d.ts +0 -18
  5. package/dist/browser/esm/sql-builder/utils/escape.d.ts +1 -0
  6. package/dist/browser/esm/sql-builder/utils/guards.d.ts +2 -0
  7. package/dist/browser/esm/sql-builder/utils/index.d.ts +3 -0
  8. package/dist/browser/esm/sql-builder/utils/operator.d.ts +5 -0
  9. package/dist/node/cjs/adapters/storage-adapter/idb-helpers.d.ts +4 -0
  10. package/dist/node/cjs/dataset/constants.d.ts +7 -0
  11. package/dist/node/cjs/dataset/dataset.d.ts +0 -18
  12. package/dist/node/cjs/node.cjs +14 -23
  13. package/dist/node/cjs/sql-builder/utils/escape.d.ts +1 -0
  14. package/dist/node/cjs/sql-builder/utils/guards.d.ts +2 -0
  15. package/dist/node/cjs/sql-builder/utils/index.d.ts +3 -0
  16. package/dist/node/cjs/sql-builder/utils/operator.d.ts +5 -0
  17. package/dist/node/esm/adapters/storage-adapter/idb-helpers.d.ts +4 -0
  18. package/dist/node/esm/dataset/constants.d.ts +7 -0
  19. package/dist/node/esm/dataset/dataset.d.ts +0 -18
  20. package/dist/node/esm/node.js +21 -30
  21. package/dist/node/esm/sql-builder/utils/escape.d.ts +1 -0
  22. package/dist/node/esm/sql-builder/utils/guards.d.ts +2 -0
  23. package/dist/node/esm/sql-builder/utils/index.d.ts +3 -0
  24. package/dist/node/esm/sql-builder/utils/operator.d.ts +5 -0
  25. package/package.json +2 -1
  26. package/dist/browser/esm/sql-builder/utils.d.ts +0 -8
  27. package/dist/node/cjs/sql-builder/utils.d.ts +0 -8
  28. package/dist/node/esm/sql-builder/utils.d.ts +0 -8
@@ -0,0 +1,4 @@
1
+ export declare const idbPut: <T>(db: IDBDatabase, storeName: string, value: T) => Promise<any>;
2
+ export declare const idbGet: <T>(db: IDBDatabase, storeName: string, key: any) => Promise<T | undefined>;
3
+ export declare const idbDelete: (db: IDBDatabase, storeName: string, key: any) => Promise<any>;
4
+ export declare const idbGetAll: <T>(db: IDBDatabase, storeName: string) => Promise<T[]>;
@@ -29,7 +29,15 @@ class PostgresDialect {
29
29
  return new NullIntrospector();
30
30
  }
31
31
  }
32
- const isSelectItem = (item)=>'object' == typeof item && 'field' in item;
32
+ const OPERATOR_MAP = {
33
+ gt: '>',
34
+ gte: '>=',
35
+ lt: '<',
36
+ lte: '<=',
37
+ eq: '=',
38
+ neq: '!='
39
+ };
40
+ const toSqlOperator = (op)=>OPERATOR_MAP[op] ?? op;
33
41
  const escapeValue = (value)=>{
34
42
  if (null === value) return 'null';
35
43
  if ('string' == typeof value) return `'${value.replace(/'/g, "''")}'`;
@@ -37,6 +45,7 @@ const escapeValue = (value)=>{
37
45
  if ('boolean' == typeof value) return value ? 'TRUE' : 'FALSE';
38
46
  return `'${String(value).replace(/'/g, "''")}'`;
39
47
  };
48
+ const isSelectItem = (item)=>'object' == typeof item && 'field' in item;
40
49
  const inlineParameters = (sql, params)=>{
41
50
  if (0 === params.length) return sql;
42
51
  if (sql.includes('?')) {
@@ -51,15 +60,6 @@ const inlineParameters = (sql, params)=>{
51
60
  });
52
61
  return sql;
53
62
  };
54
- const operatorMap = {
55
- gt: '>',
56
- gte: '>=',
57
- lt: '<',
58
- lte: '<=',
59
- eq: '=',
60
- neq: '!='
61
- };
62
- const toSqlOperator = (op)=>operatorMap[op] ?? op;
63
63
  const applyWhere = (qb, where)=>{
64
64
  if (!where) return qb;
65
65
  const toRaw = (w)=>{
@@ -114,15 +114,6 @@ const applyGroupBy = (qb, fields)=>{
114
114
  }
115
115
  return qb;
116
116
  };
117
- const having_operatorMap = {
118
- gt: '>',
119
- gte: '>=',
120
- lt: '<',
121
- lte: '<=',
122
- eq: '=',
123
- neq: '!='
124
- };
125
- const having_toSqlOperator = (op)=>having_operatorMap[op] ?? op;
126
117
  const applyHaving = (qb, having)=>{
127
118
  if (!having) return qb;
128
119
  const toRaw = (h)=>{
@@ -134,7 +125,7 @@ const applyHaving = (qb, having)=>{
134
125
  const leaf = h;
135
126
  const field = leaf.field;
136
127
  const value = leaf.value;
137
- const op = having_toSqlOperator(leaf.op);
128
+ const op = toSqlOperator(leaf.op);
138
129
  if ([
139
130
  'sum',
140
131
  'avg',
@@ -265,6 +256,13 @@ const DATA_TYPE_MAP = {
265
256
  datetime: 'TIMESTAMP',
266
257
  timestamp: 'TIMESTAMP'
267
258
  };
259
+ const buildColumnsStruct = (columns)=>{
260
+ const columnDefs = columns.map((c)=>{
261
+ const duckDBType = DATA_TYPE_MAP[c.type] || 'VARCHAR';
262
+ return `'${c.name}': '${duckDBType}'`;
263
+ });
264
+ return `{${columnDefs.join(', ')}}`;
265
+ };
268
266
  class Dataset {
269
267
  queryAdapter;
270
268
  storageAdapter;
@@ -286,7 +284,7 @@ class Dataset {
286
284
  const readFunction = READ_FUNCTION_MAP[datasetSource.type];
287
285
  if (!readFunction) throw new Error(`Unsupported dataSource type: ${datasetSource.type}`);
288
286
  await this.queryAdapter.writeFile(this._datasetId, datasetSource.blob);
289
- const columnsStruct = this.buildColumnsStruct(columns);
287
+ const columnsStruct = buildColumnsStruct(columns);
290
288
  const columnNames = columns.map((c)=>`"${c.name}"`).join(', ');
291
289
  let readSql = `${readFunction}('${this._datasetId}')`;
292
290
  if ('csv' === datasetSource.type || 'json' === datasetSource.type) readSql = `${readFunction}('${this._datasetId}', columns=${columnsStruct})`;
@@ -316,13 +314,6 @@ class Dataset {
316
314
  get datasetId() {
317
315
  return this._datasetId;
318
316
  }
319
- buildColumnsStruct(columns) {
320
- const columnDefs = columns.map((c)=>{
321
- const duckDBType = DATA_TYPE_MAP[c.type] || 'VARCHAR';
322
- return `'${c.name}': '${duckDBType}'`;
323
- });
324
- return `{${columnDefs.join(', ')}}`;
325
- }
326
317
  }
327
318
  const isUrl = (url)=>isHttpUrl(url) || isBase64Url(url);
328
319
  const isHttpUrl = (url)=>url.startsWith('http://') || url.startsWith('https://');
@@ -369,6 +360,23 @@ class DatasetSourceBuilder {
369
360
  });
370
361
  }
371
362
  }
363
+ const wrapIDBRequest = (db, storeName, mode, operation)=>new Promise((resolve, reject)=>{
364
+ const transaction = db.transaction([
365
+ storeName
366
+ ], mode);
367
+ const store = transaction.objectStore(storeName);
368
+ const request = operation(store);
369
+ request.onsuccess = ()=>{
370
+ resolve(request.result);
371
+ };
372
+ request.onerror = ()=>{
373
+ reject(request.error);
374
+ };
375
+ });
376
+ const idbPut = (db, storeName, value)=>wrapIDBRequest(db, storeName, 'readwrite', (store)=>store.put(value));
377
+ const idbGet = (db, storeName, key)=>wrapIDBRequest(db, storeName, 'readonly', (store)=>store.get(key));
378
+ const idbDelete = (db, storeName, key)=>wrapIDBRequest(db, storeName, 'readwrite', (store)=>store.delete(key));
379
+ const idbGetAll = (db, storeName)=>wrapIDBRequest(db, storeName, 'readonly', (store)=>store.getAll());
372
380
  class IndexedDBAdapter {
373
381
  db = null;
374
382
  dbName;
@@ -398,68 +406,28 @@ class IndexedDBAdapter {
398
406
  this.db = null;
399
407
  }
400
408
  };
401
- writeDataset = (datasetId, datasetSchema, datasetSource)=>new Promise((resolve, reject)=>{
402
- if (!this.db) return reject('DB is not open');
403
- const transaction = this.db.transaction([
404
- this.datasetStoreName
405
- ], 'readwrite');
406
- const store = transaction.objectStore(this.datasetStoreName);
407
- const request = store.put({
408
- datasetId,
409
- datasetSchema,
410
- datasetSource
411
- });
412
- request.onsuccess = ()=>{
413
- resolve();
414
- };
415
- request.onerror = (event)=>{
416
- reject(event.target.error);
417
- };
418
- });
419
- readDataset = (datasetId)=>new Promise((resolve, reject)=>{
420
- if (!this.db) return reject('DB is not open');
421
- const transaction = this.db.transaction([
422
- this.datasetStoreName
423
- ], 'readonly');
424
- const store = transaction.objectStore(this.datasetStoreName);
425
- const request = store.get(datasetId);
426
- request.onsuccess = (event)=>{
427
- const result = event.target.result;
428
- resolve(result || null);
429
- };
430
- request.onerror = (event)=>{
431
- reject(event.target.error);
432
- };
433
- });
434
- deleteDataset = (datasetId)=>new Promise((resolve, reject)=>{
435
- if (!this.db) return reject('DB is not open');
436
- const transaction = this.db.transaction([
437
- this.datasetStoreName
438
- ], 'readwrite');
439
- const store = transaction.objectStore(this.datasetStoreName);
440
- const request = store.delete(datasetId);
441
- request.onsuccess = ()=>{
442
- resolve();
443
- };
444
- request.onerror = (event)=>{
445
- reject(event.target.error);
446
- };
447
- });
448
- listDatasets = ()=>new Promise((resolve, reject)=>{
449
- if (!this.db) return reject('DB is not open');
450
- const transaction = this.db.transaction([
451
- this.datasetStoreName
452
- ], 'readonly');
453
- const store = transaction.objectStore(this.datasetStoreName);
454
- const request = store.getAll();
455
- request.onsuccess = (event)=>{
456
- const result = event.target.result;
457
- resolve(result);
458
- };
459
- request.onerror = (event)=>{
460
- reject(event.target.error);
461
- };
462
- });
409
+ writeDataset = (datasetId, datasetSchema, datasetSource)=>{
410
+ if (!this.db) return Promise.reject('DB is not open');
411
+ const record = {
412
+ datasetId,
413
+ datasetSchema,
414
+ datasetSource
415
+ };
416
+ return idbPut(this.db, this.datasetStoreName, record).then(()=>void 0);
417
+ };
418
+ readDataset = async (datasetId)=>{
419
+ if (!this.db) return Promise.reject('DB is not open');
420
+ const result = await idbGet(this.db, this.datasetStoreName, datasetId);
421
+ return result ?? null;
422
+ };
423
+ deleteDataset = (datasetId)=>{
424
+ if (!this.db) return Promise.reject('DB is not open');
425
+ return idbDelete(this.db, this.datasetStoreName, datasetId).then(()=>void 0);
426
+ };
427
+ listDatasets = async ()=>{
428
+ if (!this.db) return Promise.reject('DB is not open');
429
+ return idbGetAll(this.db, this.datasetStoreName);
430
+ };
463
431
  }
464
432
  class DuckDBWebQueryAdapter {
465
433
  db = null;
@@ -548,7 +516,7 @@ class VQuery {
548
516
  const datasetSchema = {
549
517
  datasetId,
550
518
  datasetAlias: datasetId,
551
- columns: columns
519
+ columns
552
520
  };
553
521
  await this.storageAdapter.writeDataset(datasetId, datasetSchema, datasetSource);
554
522
  }
@@ -559,7 +527,7 @@ class VQuery {
559
527
  const datasetSchema = {
560
528
  datasetId,
561
529
  datasetAlias: datasetId,
562
- columns: columns
530
+ columns
563
531
  };
564
532
  await this.storageAdapter.writeDataset(datasetId, datasetSchema, datasetSource);
565
533
  }
@@ -0,0 +1,7 @@
1
+ import { DatasetSourceType, DataType } from '../types';
2
+ export declare const READ_FUNCTION_MAP: Record<DatasetSourceType, string>;
3
+ export declare const DATA_TYPE_MAP: Record<DataType, string>;
4
+ export declare const buildColumnsStruct: (columns: {
5
+ name: string;
6
+ type: DataType;
7
+ }[]) => string;
@@ -5,19 +5,8 @@ export declare class Dataset {
5
5
  private storageAdapter;
6
6
  private _datasetId;
7
7
  constructor(queryAdapter: QueryAdapter, storageAdapter: StorageAdapter, datasetId: string);
8
- /**
9
- * Initialize the dataset by loading it into the query engine
10
- * @param temporaryColumns Optional temporary columns to override storage schema
11
- * @param temporaryDatasetSource Optional temporary data source to override storage source
12
- */
13
8
  init(temporaryColumns?: DatasetColumn[], temporaryDatasetSource?: DatasetSource): Promise<void>;
14
- /**
15
- * Register file and create a view in DuckDB
16
- */
17
9
  createOrReplaceView(columns: DatasetColumn[], datasetSource: DatasetSource): Promise<void>;
18
- /**
19
- * Execute query using VQuery DSL
20
- */
21
10
  query<T extends Record<string, number | string>>(queryDSL: QueryDSL<T> | VQueryDSL<T>): Promise<{
22
11
  performance: {
23
12
  startAt: string;
@@ -27,9 +16,6 @@ export declare class Dataset {
27
16
  dataset: any[];
28
17
  table: any;
29
18
  }>;
30
- /**
31
- * Execute raw SQL query
32
- */
33
19
  queryBySQL(sql: string): Promise<{
34
20
  performance: {
35
21
  startAt: string;
@@ -39,10 +25,6 @@ export declare class Dataset {
39
25
  dataset: any[];
40
26
  table: any;
41
27
  }>;
42
- /**
43
- * Clean up resources
44
- */
45
28
  disconnect(): Promise<void>;
46
29
  get datasetId(): string;
47
- private buildColumnsStruct;
48
30
  }
@@ -0,0 +1 @@
1
+ export declare const escapeValue: (value: unknown) => string;
@@ -0,0 +1,2 @@
1
+ import { SelectItem } from '../../types/dsl/Select';
2
+ export declare const isSelectItem: <T>(item: keyof T | SelectItem<T>) => item is SelectItem<T>;
@@ -0,0 +1,3 @@
1
+ export * from './operator';
2
+ export * from './escape';
3
+ export * from './guards';
@@ -0,0 +1,5 @@
1
+ /**
2
+ * SQL operator mapping from VBI DSL operators to SQL operators
3
+ */
4
+ export declare const OPERATOR_MAP: Record<string, string>;
5
+ export declare const toSqlOperator: (op: string) => string;
@@ -0,0 +1,4 @@
1
+ export declare const idbPut: <T>(db: IDBDatabase, storeName: string, value: T) => Promise<any>;
2
+ export declare const idbGet: <T>(db: IDBDatabase, storeName: string, key: any) => Promise<T | undefined>;
3
+ export declare const idbDelete: (db: IDBDatabase, storeName: string, key: any) => Promise<any>;
4
+ export declare const idbGetAll: <T>(db: IDBDatabase, storeName: string) => Promise<T[]>;
@@ -0,0 +1,7 @@
1
+ import { DatasetSourceType, DataType } from '../types';
2
+ export declare const READ_FUNCTION_MAP: Record<DatasetSourceType, string>;
3
+ export declare const DATA_TYPE_MAP: Record<DataType, string>;
4
+ export declare const buildColumnsStruct: (columns: {
5
+ name: string;
6
+ type: DataType;
7
+ }[]) => string;
@@ -5,19 +5,8 @@ export declare class Dataset {
5
5
  private storageAdapter;
6
6
  private _datasetId;
7
7
  constructor(queryAdapter: QueryAdapter, storageAdapter: StorageAdapter, datasetId: string);
8
- /**
9
- * Initialize the dataset by loading it into the query engine
10
- * @param temporaryColumns Optional temporary columns to override storage schema
11
- * @param temporaryDatasetSource Optional temporary data source to override storage source
12
- */
13
8
  init(temporaryColumns?: DatasetColumn[], temporaryDatasetSource?: DatasetSource): Promise<void>;
14
- /**
15
- * Register file and create a view in DuckDB
16
- */
17
9
  createOrReplaceView(columns: DatasetColumn[], datasetSource: DatasetSource): Promise<void>;
18
- /**
19
- * Execute query using VQuery DSL
20
- */
21
10
  query<T extends Record<string, number | string>>(queryDSL: QueryDSL<T> | VQueryDSL<T>): Promise<{
22
11
  performance: {
23
12
  startAt: string;
@@ -27,9 +16,6 @@ export declare class Dataset {
27
16
  dataset: any[];
28
17
  table: any;
29
18
  }>;
30
- /**
31
- * Execute raw SQL query
32
- */
33
19
  queryBySQL(sql: string): Promise<{
34
20
  performance: {
35
21
  startAt: string;
@@ -39,10 +25,6 @@ export declare class Dataset {
39
25
  dataset: any[];
40
26
  table: any;
41
27
  }>;
42
- /**
43
- * Clean up resources
44
- */
45
28
  disconnect(): Promise<void>;
46
29
  get datasetId(): string;
47
- private buildColumnsStruct;
48
30
  }
@@ -67,7 +67,6 @@ class PostgresDialect {
67
67
  return new NullIntrospector();
68
68
  }
69
69
  }
70
- const isSelectItem = (item)=>'object' == typeof item && 'field' in item;
71
70
  const escapeValue = (value)=>{
72
71
  if (null === value) return 'null';
73
72
  if ('string' == typeof value) return `'${value.replace(/'/g, "''")}'`;
@@ -89,7 +88,7 @@ const inlineParameters = (sql, params)=>{
89
88
  });
90
89
  return sql;
91
90
  };
92
- const operatorMap = {
91
+ const OPERATOR_MAP = {
93
92
  gt: '>',
94
93
  gte: '>=',
95
94
  lt: '<',
@@ -97,7 +96,7 @@ const operatorMap = {
97
96
  eq: '=',
98
97
  neq: '!='
99
98
  };
100
- const toSqlOperator = (op)=>operatorMap[op] ?? op;
99
+ const toSqlOperator = (op)=>OPERATOR_MAP[op] ?? op;
101
100
  const applyWhere = (qb, where)=>{
102
101
  if (!where) return qb;
103
102
  const toRaw = (w)=>{
@@ -152,15 +151,6 @@ const applyGroupBy = (qb, fields)=>{
152
151
  }
153
152
  return qb;
154
153
  };
155
- const having_operatorMap = {
156
- gt: '>',
157
- gte: '>=',
158
- lt: '<',
159
- lte: '<=',
160
- eq: '=',
161
- neq: '!='
162
- };
163
- const having_toSqlOperator = (op)=>having_operatorMap[op] ?? op;
164
154
  const applyHaving = (qb, having)=>{
165
155
  if (!having) return qb;
166
156
  const toRaw = (h)=>{
@@ -172,7 +162,7 @@ const applyHaving = (qb, having)=>{
172
162
  const leaf = h;
173
163
  const field = leaf.field;
174
164
  const value = leaf.value;
175
- const op = having_toSqlOperator(leaf.op);
165
+ const op = toSqlOperator(leaf.op);
176
166
  if ([
177
167
  'sum',
178
168
  'avg',
@@ -228,6 +218,7 @@ const applyOrder = (qb, orderBy)=>{
228
218
  });
229
219
  return qb;
230
220
  };
221
+ const isSelectItem = (item)=>'object' == typeof item && 'field' in item;
231
222
  const DATE_FORMAT_MAP = {
232
223
  year: '%Y',
233
224
  month: '%Y-%m',
@@ -303,6 +294,13 @@ const DATA_TYPE_MAP = {
303
294
  datetime: 'TIMESTAMP',
304
295
  timestamp: 'TIMESTAMP'
305
296
  };
297
+ const buildColumnsStruct = (columns)=>{
298
+ const columnDefs = columns.map((c)=>{
299
+ const duckDBType = DATA_TYPE_MAP[c.type] || 'VARCHAR';
300
+ return `'${c.name}': '${duckDBType}'`;
301
+ });
302
+ return `{${columnDefs.join(', ')}}`;
303
+ };
306
304
  class Dataset {
307
305
  queryAdapter;
308
306
  storageAdapter;
@@ -324,7 +322,7 @@ class Dataset {
324
322
  const readFunction = READ_FUNCTION_MAP[datasetSource.type];
325
323
  if (!readFunction) throw new Error(`Unsupported dataSource type: ${datasetSource.type}`);
326
324
  await this.queryAdapter.writeFile(this._datasetId, datasetSource.blob);
327
- const columnsStruct = this.buildColumnsStruct(columns);
325
+ const columnsStruct = buildColumnsStruct(columns);
328
326
  const columnNames = columns.map((c)=>`"${c.name}"`).join(', ');
329
327
  let readSql = `${readFunction}('${this._datasetId}')`;
330
328
  if ('csv' === datasetSource.type || 'json' === datasetSource.type) readSql = `${readFunction}('${this._datasetId}', columns=${columnsStruct})`;
@@ -354,13 +352,6 @@ class Dataset {
354
352
  get datasetId() {
355
353
  return this._datasetId;
356
354
  }
357
- buildColumnsStruct(columns) {
358
- const columnDefs = columns.map((c)=>{
359
- const duckDBType = DATA_TYPE_MAP[c.type] || 'VARCHAR';
360
- return `'${c.name}': '${duckDBType}'`;
361
- });
362
- return `{${columnDefs.join(', ')}}`;
363
- }
364
355
  }
365
356
  const isUrl = (url)=>isHttpUrl(url) || isBase64Url(url);
366
357
  const isHttpUrl = (url)=>url.startsWith('http://') || url.startsWith('https://');
@@ -523,7 +514,7 @@ class VQuery {
523
514
  const datasetSchema = {
524
515
  datasetId,
525
516
  datasetAlias: datasetId,
526
- columns: columns
517
+ columns
527
518
  };
528
519
  await this.storageAdapter.writeDataset(datasetId, datasetSchema, datasetSource);
529
520
  }
@@ -534,7 +525,7 @@ class VQuery {
534
525
  const datasetSchema = {
535
526
  datasetId,
536
527
  datasetAlias: datasetId,
537
- columns: columns
528
+ columns
538
529
  };
539
530
  await this.storageAdapter.writeDataset(datasetId, datasetSchema, datasetSource);
540
531
  }
@@ -0,0 +1 @@
1
+ export declare const escapeValue: (value: unknown) => string;
@@ -0,0 +1,2 @@
1
+ import { SelectItem } from '../../types/dsl/Select';
2
+ export declare const isSelectItem: <T>(item: keyof T | SelectItem<T>) => item is SelectItem<T>;
@@ -0,0 +1,3 @@
1
+ export * from './operator';
2
+ export * from './escape';
3
+ export * from './guards';
@@ -0,0 +1,5 @@
1
+ /**
2
+ * SQL operator mapping from VBI DSL operators to SQL operators
3
+ */
4
+ export declare const OPERATOR_MAP: Record<string, string>;
5
+ export declare const toSqlOperator: (op: string) => string;
@@ -0,0 +1,4 @@
1
+ export declare const idbPut: <T>(db: IDBDatabase, storeName: string, value: T) => Promise<any>;
2
+ export declare const idbGet: <T>(db: IDBDatabase, storeName: string, key: any) => Promise<T | undefined>;
3
+ export declare const idbDelete: (db: IDBDatabase, storeName: string, key: any) => Promise<any>;
4
+ export declare const idbGetAll: <T>(db: IDBDatabase, storeName: string) => Promise<T[]>;
@@ -0,0 +1,7 @@
1
+ import { DatasetSourceType, DataType } from '../types';
2
+ export declare const READ_FUNCTION_MAP: Record<DatasetSourceType, string>;
3
+ export declare const DATA_TYPE_MAP: Record<DataType, string>;
4
+ export declare const buildColumnsStruct: (columns: {
5
+ name: string;
6
+ type: DataType;
7
+ }[]) => string;
@@ -5,19 +5,8 @@ export declare class Dataset {
5
5
  private storageAdapter;
6
6
  private _datasetId;
7
7
  constructor(queryAdapter: QueryAdapter, storageAdapter: StorageAdapter, datasetId: string);
8
- /**
9
- * Initialize the dataset by loading it into the query engine
10
- * @param temporaryColumns Optional temporary columns to override storage schema
11
- * @param temporaryDatasetSource Optional temporary data source to override storage source
12
- */
13
8
  init(temporaryColumns?: DatasetColumn[], temporaryDatasetSource?: DatasetSource): Promise<void>;
14
- /**
15
- * Register file and create a view in DuckDB
16
- */
17
9
  createOrReplaceView(columns: DatasetColumn[], datasetSource: DatasetSource): Promise<void>;
18
- /**
19
- * Execute query using VQuery DSL
20
- */
21
10
  query<T extends Record<string, number | string>>(queryDSL: QueryDSL<T> | VQueryDSL<T>): Promise<{
22
11
  performance: {
23
12
  startAt: string;
@@ -27,9 +16,6 @@ export declare class Dataset {
27
16
  dataset: any[];
28
17
  table: any;
29
18
  }>;
30
- /**
31
- * Execute raw SQL query
32
- */
33
19
  queryBySQL(sql: string): Promise<{
34
20
  performance: {
35
21
  startAt: string;
@@ -39,10 +25,6 @@ export declare class Dataset {
39
25
  dataset: any[];
40
26
  table: any;
41
27
  }>;
42
- /**
43
- * Clean up resources
44
- */
45
28
  disconnect(): Promise<void>;
46
29
  get datasetId(): string;
47
- private buildColumnsStruct;
48
30
  }
@@ -30,7 +30,15 @@ class PostgresDialect {
30
30
  return new NullIntrospector();
31
31
  }
32
32
  }
33
- const isSelectItem = (item)=>'object' == typeof item && 'field' in item;
33
+ const OPERATOR_MAP = {
34
+ gt: '>',
35
+ gte: '>=',
36
+ lt: '<',
37
+ lte: '<=',
38
+ eq: '=',
39
+ neq: '!='
40
+ };
41
+ const toSqlOperator = (op)=>OPERATOR_MAP[op] ?? op;
34
42
  const escapeValue = (value)=>{
35
43
  if (null === value) return 'null';
36
44
  if ('string' == typeof value) return `'${value.replace(/'/g, "''")}'`;
@@ -38,6 +46,7 @@ const escapeValue = (value)=>{
38
46
  if ('boolean' == typeof value) return value ? 'TRUE' : 'FALSE';
39
47
  return `'${String(value).replace(/'/g, "''")}'`;
40
48
  };
49
+ const isSelectItem = (item)=>'object' == typeof item && 'field' in item;
41
50
  const inlineParameters = (sql, params)=>{
42
51
  if (0 === params.length) return sql;
43
52
  if (sql.includes('?')) {
@@ -52,15 +61,6 @@ const inlineParameters = (sql, params)=>{
52
61
  });
53
62
  return sql;
54
63
  };
55
- const operatorMap = {
56
- gt: '>',
57
- gte: '>=',
58
- lt: '<',
59
- lte: '<=',
60
- eq: '=',
61
- neq: '!='
62
- };
63
- const toSqlOperator = (op)=>operatorMap[op] ?? op;
64
64
  const applyWhere = (qb, where)=>{
65
65
  if (!where) return qb;
66
66
  const toRaw = (w)=>{
@@ -115,15 +115,6 @@ const applyGroupBy = (qb, fields)=>{
115
115
  }
116
116
  return qb;
117
117
  };
118
- const having_operatorMap = {
119
- gt: '>',
120
- gte: '>=',
121
- lt: '<',
122
- lte: '<=',
123
- eq: '=',
124
- neq: '!='
125
- };
126
- const having_toSqlOperator = (op)=>having_operatorMap[op] ?? op;
127
118
  const applyHaving = (qb, having)=>{
128
119
  if (!having) return qb;
129
120
  const toRaw = (h)=>{
@@ -135,7 +126,7 @@ const applyHaving = (qb, having)=>{
135
126
  const leaf = h;
136
127
  const field = leaf.field;
137
128
  const value = leaf.value;
138
- const op = having_toSqlOperator(leaf.op);
129
+ const op = toSqlOperator(leaf.op);
139
130
  if ([
140
131
  'sum',
141
132
  'avg',
@@ -266,6 +257,13 @@ const DATA_TYPE_MAP = {
266
257
  datetime: 'TIMESTAMP',
267
258
  timestamp: 'TIMESTAMP'
268
259
  };
260
+ const buildColumnsStruct = (columns)=>{
261
+ const columnDefs = columns.map((c)=>{
262
+ const duckDBType = DATA_TYPE_MAP[c.type] || 'VARCHAR';
263
+ return `'${c.name}': '${duckDBType}'`;
264
+ });
265
+ return `{${columnDefs.join(', ')}}`;
266
+ };
269
267
  class Dataset {
270
268
  queryAdapter;
271
269
  storageAdapter;
@@ -287,7 +285,7 @@ class Dataset {
287
285
  const readFunction = READ_FUNCTION_MAP[datasetSource.type];
288
286
  if (!readFunction) throw new Error(`Unsupported dataSource type: ${datasetSource.type}`);
289
287
  await this.queryAdapter.writeFile(this._datasetId, datasetSource.blob);
290
- const columnsStruct = this.buildColumnsStruct(columns);
288
+ const columnsStruct = buildColumnsStruct(columns);
291
289
  const columnNames = columns.map((c)=>`"${c.name}"`).join(', ');
292
290
  let readSql = `${readFunction}('${this._datasetId}')`;
293
291
  if ('csv' === datasetSource.type || 'json' === datasetSource.type) readSql = `${readFunction}('${this._datasetId}', columns=${columnsStruct})`;
@@ -317,13 +315,6 @@ class Dataset {
317
315
  get datasetId() {
318
316
  return this._datasetId;
319
317
  }
320
- buildColumnsStruct(columns) {
321
- const columnDefs = columns.map((c)=>{
322
- const duckDBType = DATA_TYPE_MAP[c.type] || 'VARCHAR';
323
- return `'${c.name}': '${duckDBType}'`;
324
- });
325
- return `{${columnDefs.join(', ')}}`;
326
- }
327
318
  }
328
319
  const isUrl = (url)=>isHttpUrl(url) || isBase64Url(url);
329
320
  const isHttpUrl = (url)=>url.startsWith('http://') || url.startsWith('https://');
@@ -484,7 +475,7 @@ class VQuery {
484
475
  const datasetSchema = {
485
476
  datasetId,
486
477
  datasetAlias: datasetId,
487
- columns: columns
478
+ columns
488
479
  };
489
480
  await this.storageAdapter.writeDataset(datasetId, datasetSchema, datasetSource);
490
481
  }
@@ -495,7 +486,7 @@ class VQuery {
495
486
  const datasetSchema = {
496
487
  datasetId,
497
488
  datasetAlias: datasetId,
498
- columns: columns
489
+ columns
499
490
  };
500
491
  await this.storageAdapter.writeDataset(datasetId, datasetSchema, datasetSource);
501
492
  }
@@ -0,0 +1 @@
1
+ export declare const escapeValue: (value: unknown) => string;
@@ -0,0 +1,2 @@
1
+ import { SelectItem } from '../../types/dsl/Select';
2
+ export declare const isSelectItem: <T>(item: keyof T | SelectItem<T>) => item is SelectItem<T>;
@@ -0,0 +1,3 @@
1
+ export * from './operator';
2
+ export * from './escape';
3
+ export * from './guards';
@@ -0,0 +1,5 @@
1
+ /**
2
+ * SQL operator mapping from VBI DSL operators to SQL operators
3
+ */
4
+ export declare const OPERATOR_MAP: Record<string, string>;
5
+ export declare const toSqlOperator: (op: string) => string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@visactor/vquery",
3
- "version": "0.4.12",
3
+ "version": "0.4.14",
4
4
  "license": "MIT",
5
5
  "homepage": "https://visactor.github.io/VBI",
6
6
  "bugs": "https://github.com/VisActor/VBI/issues",
@@ -63,6 +63,7 @@
63
63
  "dev": "rslib build --watch --no-clean",
64
64
  "lint": "eslint .",
65
65
  "test": "rstest",
66
+ "format": "prettier --write .",
66
67
  "test:update": "rstest --update",
67
68
  "test:coverage": "rstest --coverage && node scripts/build-coverage-badge.mjs && open ./coverage/index.html",
68
69
  "typecheck": "tsc --noEmit"
@@ -1,8 +0,0 @@
1
- import { Where, WhereClause, WhereGroup, WhereLeaf } from '../types';
2
- import { SelectItem } from '../types/dsl/Select';
3
- export declare const isSelectItem: <T>(item: keyof T | SelectItem<T>) => item is SelectItem<T>;
4
- export declare const isWhereLeaf: <T>(where: Where<T> | WhereClause<T>) => where is WhereLeaf<T>;
5
- export declare const isWhereGroup: <T>(where: Where<T> | WhereClause<T>) => where is WhereGroup<T>;
6
- export declare const isStringOrNumber: (value: unknown) => value is string | number;
7
- export declare const escapeLiteral: <T>(value: T[keyof T]) => T[keyof T];
8
- export declare const escapeValue: (value: unknown) => string;
@@ -1,8 +0,0 @@
1
- import { Where, WhereClause, WhereGroup, WhereLeaf } from '../types';
2
- import { SelectItem } from '../types/dsl/Select';
3
- export declare const isSelectItem: <T>(item: keyof T | SelectItem<T>) => item is SelectItem<T>;
4
- export declare const isWhereLeaf: <T>(where: Where<T> | WhereClause<T>) => where is WhereLeaf<T>;
5
- export declare const isWhereGroup: <T>(where: Where<T> | WhereClause<T>) => where is WhereGroup<T>;
6
- export declare const isStringOrNumber: (value: unknown) => value is string | number;
7
- export declare const escapeLiteral: <T>(value: T[keyof T]) => T[keyof T];
8
- export declare const escapeValue: (value: unknown) => string;
@@ -1,8 +0,0 @@
1
- import { Where, WhereClause, WhereGroup, WhereLeaf } from '../types';
2
- import { SelectItem } from '../types/dsl/Select';
3
- export declare const isSelectItem: <T>(item: keyof T | SelectItem<T>) => item is SelectItem<T>;
4
- export declare const isWhereLeaf: <T>(where: Where<T> | WhereClause<T>) => where is WhereLeaf<T>;
5
- export declare const isWhereGroup: <T>(where: Where<T> | WhereClause<T>) => where is WhereGroup<T>;
6
- export declare const isStringOrNumber: (value: unknown) => value is string | number;
7
- export declare const escapeLiteral: <T>(value: T[keyof T]) => T[keyof T];
8
- export declare const escapeValue: (value: unknown) => string;