@duckdb/node-api 1.2.0-alpha.15 → 1.2.1-alpha.17
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/README.md +211 -16
- package/lib/DuckDBAppender.d.ts +2 -2
- package/lib/DuckDBAppender.js +4 -4
- package/lib/DuckDBConnection.d.ts +4 -4
- package/lib/DuckDBConnection.js +10 -6
- package/lib/DuckDBDataChunk.d.ts +12 -4
- package/lib/DuckDBDataChunk.js +64 -6
- package/lib/DuckDBInstance.d.ts +2 -0
- package/lib/DuckDBInstance.js +9 -9
- package/lib/DuckDBInstanceCache.d.ts +8 -0
- package/lib/DuckDBInstanceCache.js +28 -0
- package/lib/DuckDBResult.d.ts +15 -1
- package/lib/DuckDBResult.js +62 -9
- package/lib/DuckDBResultReader.d.ts +15 -1
- package/lib/DuckDBResultReader.js +42 -5
- package/lib/DuckDBType.d.ts +9 -0
- package/lib/DuckDBType.js +61 -0
- package/lib/DuckDBValueConverter.d.ts +1 -3
- package/lib/DuckDBValueConverters.d.ts +47 -0
- package/lib/DuckDBValueConverters.js +214 -0
- package/lib/JS.d.ts +3 -0
- package/lib/JS.js +2 -0
- package/lib/JSDuckDBValueConverter.d.ts +3 -0
- package/lib/JSDuckDBValueConverter.js +46 -0
- package/lib/Json.d.ts +3 -0
- package/lib/Json.js +2 -0
- package/lib/JsonDuckDBValueConverter.d.ts +3 -0
- package/lib/JsonDuckDBValueConverter.js +46 -0
- package/lib/conversion/stringFromBlob.d.ts +2 -0
- package/lib/conversion/stringFromBlob.js +28 -2
- package/lib/convertColumnsFromChunks.d.ts +1 -1
- package/lib/convertColumnsFromChunks.js +1 -1
- package/lib/convertColumnsObjectFromChunks.d.ts +1 -1
- package/lib/convertColumnsObjectFromChunks.js +1 -1
- package/lib/convertRowObjectsFromChunks.d.ts +1 -1
- package/lib/convertRowObjectsFromChunks.js +1 -1
- package/lib/convertRowsFromChunks.d.ts +1 -1
- package/lib/createConfig.d.ts +2 -0
- package/lib/createConfig.js +19 -0
- package/lib/createDuckDBValueConverter.d.ts +3 -0
- package/lib/createDuckDBValueConverter.js +15 -0
- package/lib/createValue.js +2 -2
- package/lib/duckdb.d.ts +26 -0
- package/lib/duckdb.js +47 -0
- package/lib/getColumnsFromChunks.js +2 -8
- package/lib/getColumnsObjectFromChunks.js +2 -11
- package/lib/getRowObjectsFromChunks.js +1 -8
- package/lib/getRowsFromChunks.js +1 -1
- package/lib/index.d.ts +3 -21
- package/lib/index.js +25 -26
- package/lib/values/DuckDBBitValue.d.ts +1 -1
- package/lib/values/DuckDBBitValue.js +13 -2
- package/lib/values/DuckDBDateValue.d.ts +1 -1
- package/lib/values/DuckDBDateValue.js +5 -2
- package/lib/values/DuckDBDecimalValue.d.ts +1 -1
- package/lib/values/DuckDBDecimalValue.js +3 -0
- package/lib/values/DuckDBTimeValue.d.ts +1 -1
- package/lib/values/DuckDBTimeValue.js +5 -2
- package/lib/values/DuckDBTimestampTZValue.d.ts +1 -1
- package/lib/values/DuckDBTimestampTZValue.js +5 -2
- package/lib/values/DuckDBTimestampValue.d.ts +1 -1
- package/lib/values/DuckDBTimestampValue.js +5 -2
- package/package.json +2 -2
- package/lib/DuckDBValueToJsonConverter.d.ts +0 -10
- package/lib/DuckDBValueToJsonConverter.js +0 -101
package/README.md
CHANGED
|
@@ -18,16 +18,19 @@ available separately as [@duckdb/duckdb-bindings](https://www.npmjs.com/package/
|
|
|
18
18
|
### Roadmap
|
|
19
19
|
|
|
20
20
|
Some features are not yet complete:
|
|
21
|
-
- Binding
|
|
22
|
-
- Appending
|
|
23
|
-
- User-defined types & functions
|
|
24
|
-
- Profiling info
|
|
25
|
-
- Table description
|
|
26
|
-
- APIs for Arrow
|
|
21
|
+
- Binding and appending the MAP and UNION data types
|
|
22
|
+
- Appending default values row-by-row
|
|
23
|
+
- User-defined types & functions
|
|
24
|
+
- Profiling info
|
|
25
|
+
- Table description
|
|
26
|
+
- APIs for Arrow
|
|
27
|
+
|
|
28
|
+
See the [issues list on GitHub](https://github.com/duckdb/duckdb-node-neo/issues)
|
|
29
|
+
for the most up-to-date roadmap.
|
|
27
30
|
|
|
28
31
|
### Supported Platforms
|
|
29
32
|
|
|
30
|
-
- Linux arm64
|
|
33
|
+
- Linux arm64
|
|
31
34
|
- Linux x64
|
|
32
35
|
- Mac OS X (Darwin) arm64 (Apple Silicon)
|
|
33
36
|
- Mac OS X (Darwin) x64 (Intel)
|
|
@@ -45,6 +48,17 @@ console.log(duckdb.version());
|
|
|
45
48
|
console.log(duckdb.configurationOptionDescriptions());
|
|
46
49
|
```
|
|
47
50
|
|
|
51
|
+
### Connect
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
import { DuckDBConnection } from '@duckdb/node-api';
|
|
55
|
+
|
|
56
|
+
const connection = await DuckDBConnection.create();
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
This uses the default instance.
|
|
60
|
+
For advanced usage, you can create instances explicitly.
|
|
61
|
+
|
|
48
62
|
### Create Instance
|
|
49
63
|
|
|
50
64
|
```ts
|
|
@@ -66,14 +80,33 @@ Read from and write to a database file, which is created if needed:
|
|
|
66
80
|
const instance = await DuckDBInstance.create('my_duckdb.db');
|
|
67
81
|
```
|
|
68
82
|
|
|
69
|
-
Set configuration options:
|
|
83
|
+
Set [configuration options](https://duckdb.org/docs/stable/configuration/overview.html#configuration-reference):
|
|
70
84
|
```ts
|
|
71
85
|
const instance = await DuckDBInstance.create('my_duckdb.db', {
|
|
72
86
|
threads: '4'
|
|
73
87
|
});
|
|
74
88
|
```
|
|
75
89
|
|
|
76
|
-
###
|
|
90
|
+
### Instance Cache
|
|
91
|
+
|
|
92
|
+
Multiple instances in the same process should not
|
|
93
|
+
attach the same database.
|
|
94
|
+
|
|
95
|
+
To prevent this, an instance cache can be used:
|
|
96
|
+
```ts
|
|
97
|
+
const instance = await DuckDBInstance.fromCache('my_duckdb.db');
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
This uses the default instance cache. For advanced usage, you can create
|
|
101
|
+
instance caches explicitly:
|
|
102
|
+
```ts
|
|
103
|
+
import { DuckDBInstanceCache } from '@duckdb/node-api';
|
|
104
|
+
|
|
105
|
+
const cache = new DuckDBInstanceCache();
|
|
106
|
+
const instance = await cache.getOrCreateInstance('my_duckdb.db');
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Connect to Instance
|
|
77
110
|
|
|
78
111
|
```ts
|
|
79
112
|
const connection = await instance.connect();
|
|
@@ -150,6 +183,36 @@ const result = await connection.run('select $a, $b, $c', {
|
|
|
150
183
|
});
|
|
151
184
|
```
|
|
152
185
|
|
|
186
|
+
### Specifying Values
|
|
187
|
+
|
|
188
|
+
Values of many data types are represented using one of the JS primitives
|
|
189
|
+
`boolean`, `number`, `bigint`, or `string`.
|
|
190
|
+
Also, any type can have `null` values.
|
|
191
|
+
|
|
192
|
+
Values of some data types need to be constructed using special functions.
|
|
193
|
+
These are:
|
|
194
|
+
|
|
195
|
+
| Type | Function |
|
|
196
|
+
| ---- | -------- |
|
|
197
|
+
| `ARRAY` | `arrayValue` |
|
|
198
|
+
| `BIT` | `bitValue` |
|
|
199
|
+
| `BLOB` | `blobValue` |
|
|
200
|
+
| `DATE` | `dateValue` |
|
|
201
|
+
| `DECIMAL` | `decimalValue` |
|
|
202
|
+
| `INTERVAL` | `intervalValue` |
|
|
203
|
+
| `LIST` | `listValue` |
|
|
204
|
+
| `MAP` | `mapValue` |
|
|
205
|
+
| `STRUCT` | `structValue` |
|
|
206
|
+
| `TIME` | `timeValue` |
|
|
207
|
+
| `TIMETZ` | `timeTZValue` |
|
|
208
|
+
| `TIMESTAMP` | `timestampValue` |
|
|
209
|
+
| `TIMESTAMPTZ` | `timestampTZValue` |
|
|
210
|
+
| `TIMESTAMP_S` | `timestampSecondsValue` |
|
|
211
|
+
| `TIMESTAMP_MS` | `timestampMillisValue` |
|
|
212
|
+
| `TIMESTAMP_NS` | `timestampNanosValue` |
|
|
213
|
+
| `UNION` | `unionValue` |
|
|
214
|
+
| `UUID` | `uuidValue` |
|
|
215
|
+
|
|
153
216
|
### Stream Results
|
|
154
217
|
|
|
155
218
|
Streaming results evaluate lazily when rows are read.
|
|
@@ -221,13 +284,21 @@ const columnsObject = reader.getColumnsObject();
|
|
|
221
284
|
// { i: [0, 1, 2], n: [10, 11, 12] }
|
|
222
285
|
```
|
|
223
286
|
|
|
224
|
-
### Convert Result Data
|
|
287
|
+
### Convert Result Data
|
|
288
|
+
|
|
289
|
+
By default, data values that cannot be represented as JS built-ins
|
|
290
|
+
are returned as specialized JS objects; see `Inspect Data Values` below.
|
|
225
291
|
|
|
226
|
-
|
|
227
|
-
|
|
292
|
+
To retrieve data in a different form, such as JS built-ins or values that
|
|
293
|
+
can be losslessly serialized to JSON, use the `JS` or `Json` forms of the
|
|
294
|
+
above result data methods.
|
|
228
295
|
|
|
229
|
-
|
|
230
|
-
|
|
296
|
+
Custom converters can be supplied as well. See the implementations of
|
|
297
|
+
[JSDuckDBValueConverter](https://github.com/duckdb/duckdb-node-neo/blob/main/api/src/JSDuckDBValueConverter.ts)
|
|
298
|
+
and [JsonDuckDBValueConverters](https://github.com/duckdb/duckdb-node-neo/blob/main/api/src/JsonDuckDBValueConverter.ts)
|
|
299
|
+
for how to do this.
|
|
300
|
+
|
|
301
|
+
Examples (using the `Json` forms):
|
|
231
302
|
|
|
232
303
|
```ts
|
|
233
304
|
const reader = await connection.runAndReadAll(
|
|
@@ -375,6 +446,127 @@ const columnsObject = reader.getColumnsObjectJson();
|
|
|
375
446
|
// }
|
|
376
447
|
```
|
|
377
448
|
|
|
449
|
+
Column names and types can also be serialized to JSON:
|
|
450
|
+
```ts
|
|
451
|
+
const columnNamesAndTypes = reader.columnNamesAndTypesJson();
|
|
452
|
+
// {
|
|
453
|
+
// "columnNames": [
|
|
454
|
+
// "int_array",
|
|
455
|
+
// "struct",
|
|
456
|
+
// "map",
|
|
457
|
+
// "union"
|
|
458
|
+
// ],
|
|
459
|
+
// "columnTypes": [
|
|
460
|
+
// {
|
|
461
|
+
// "typeId": 24,
|
|
462
|
+
// "valueType": {
|
|
463
|
+
// "typeId": 4
|
|
464
|
+
// }
|
|
465
|
+
// },
|
|
466
|
+
// {
|
|
467
|
+
// "typeId": 25,
|
|
468
|
+
// "entryNames": [
|
|
469
|
+
// "a",
|
|
470
|
+
// "b"
|
|
471
|
+
// ],
|
|
472
|
+
// "entryTypes": [
|
|
473
|
+
// {
|
|
474
|
+
// "typeId": 4
|
|
475
|
+
// },
|
|
476
|
+
// {
|
|
477
|
+
// "typeId": 17
|
|
478
|
+
// }
|
|
479
|
+
// ]
|
|
480
|
+
// },
|
|
481
|
+
// {
|
|
482
|
+
// "typeId": 26,
|
|
483
|
+
// "keyType": {
|
|
484
|
+
// "typeId": 17
|
|
485
|
+
// },
|
|
486
|
+
// "valueType": {
|
|
487
|
+
// "typeId": 17
|
|
488
|
+
// }
|
|
489
|
+
// },
|
|
490
|
+
// {
|
|
491
|
+
// "typeId": 28,
|
|
492
|
+
// "memberTags": [
|
|
493
|
+
// "name",
|
|
494
|
+
// "age"
|
|
495
|
+
// ],
|
|
496
|
+
// "memberTypes": [
|
|
497
|
+
// {
|
|
498
|
+
// "typeId": 17
|
|
499
|
+
// },
|
|
500
|
+
// {
|
|
501
|
+
// "typeId": 3
|
|
502
|
+
// }
|
|
503
|
+
// ]
|
|
504
|
+
// }
|
|
505
|
+
// ]
|
|
506
|
+
// }
|
|
507
|
+
|
|
508
|
+
const columnNameAndTypeObjects = reader.columnNameAndTypeObjectsJson();
|
|
509
|
+
// [
|
|
510
|
+
// {
|
|
511
|
+
// "columnName": "int_array",
|
|
512
|
+
// "columnType": {
|
|
513
|
+
// "typeId": 24,
|
|
514
|
+
// "valueType": {
|
|
515
|
+
// "typeId": 4
|
|
516
|
+
// }
|
|
517
|
+
// }
|
|
518
|
+
// },
|
|
519
|
+
// {
|
|
520
|
+
// "columnName": "struct",
|
|
521
|
+
// "columnType": {
|
|
522
|
+
// "typeId": 25,
|
|
523
|
+
// "entryNames": [
|
|
524
|
+
// "a",
|
|
525
|
+
// "b"
|
|
526
|
+
// ],
|
|
527
|
+
// "entryTypes": [
|
|
528
|
+
// {
|
|
529
|
+
// "typeId": 4
|
|
530
|
+
// },
|
|
531
|
+
// {
|
|
532
|
+
// "typeId": 17
|
|
533
|
+
// }
|
|
534
|
+
// ]
|
|
535
|
+
// }
|
|
536
|
+
// },
|
|
537
|
+
// {
|
|
538
|
+
// "columnName": "map",
|
|
539
|
+
// "columnType": {
|
|
540
|
+
// "typeId": 26,
|
|
541
|
+
// "keyType": {
|
|
542
|
+
// "typeId": 17
|
|
543
|
+
// },
|
|
544
|
+
// "valueType": {
|
|
545
|
+
// "typeId": 17
|
|
546
|
+
// }
|
|
547
|
+
// }
|
|
548
|
+
// },
|
|
549
|
+
// {
|
|
550
|
+
// "columnName": "union",
|
|
551
|
+
// "columnType": {
|
|
552
|
+
// "typeId": 28,
|
|
553
|
+
// "memberTags": [
|
|
554
|
+
// "name",
|
|
555
|
+
// "age"
|
|
556
|
+
// ],
|
|
557
|
+
// "memberTypes": [
|
|
558
|
+
// {
|
|
559
|
+
// "typeId": 17
|
|
560
|
+
// },
|
|
561
|
+
// {
|
|
562
|
+
// "typeId": 3
|
|
563
|
+
// }
|
|
564
|
+
// ]
|
|
565
|
+
// }
|
|
566
|
+
// }
|
|
567
|
+
// ]
|
|
568
|
+
```
|
|
569
|
+
|
|
378
570
|
### Fetch Chunks
|
|
379
571
|
|
|
380
572
|
Fetch all chunks:
|
|
@@ -409,11 +601,12 @@ Get chunk data:
|
|
|
409
601
|
```ts
|
|
410
602
|
const rows = chunk.getRows();
|
|
411
603
|
|
|
412
|
-
const rowObjects = chunk.getRowObjects();
|
|
604
|
+
const rowObjects = chunk.getRowObjects(result.deduplicatedColumnNames());
|
|
413
605
|
|
|
414
606
|
const columns = chunk.getColumns();
|
|
415
607
|
|
|
416
|
-
const columnsObject =
|
|
608
|
+
const columnsObject =
|
|
609
|
+
chunk.getColumnsObject(result.deduplicatedColumnNames());
|
|
417
610
|
```
|
|
418
611
|
|
|
419
612
|
Get chunk data (one value at a time)
|
|
@@ -688,6 +881,8 @@ appender.appendDataChunk(chunk);
|
|
|
688
881
|
appender.flush();
|
|
689
882
|
```
|
|
690
883
|
|
|
884
|
+
See "Specifying Values" above for how to supply values to the appender.
|
|
885
|
+
|
|
691
886
|
### Extract Statements
|
|
692
887
|
|
|
693
888
|
```ts
|
package/lib/DuckDBAppender.d.ts
CHANGED
|
@@ -5,8 +5,8 @@ import { DuckDBArrayValue, DuckDBBitValue, DuckDBDateValue, DuckDBDecimalValue,
|
|
|
5
5
|
export declare class DuckDBAppender {
|
|
6
6
|
private readonly appender;
|
|
7
7
|
constructor(appender: duckdb.Appender);
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
closeSync(): void;
|
|
9
|
+
flushSync(): void;
|
|
10
10
|
get columnCount(): number;
|
|
11
11
|
columnType(columnIndex: number): DuckDBType;
|
|
12
12
|
endRow(): void;
|
package/lib/DuckDBAppender.js
CHANGED
|
@@ -13,11 +13,11 @@ class DuckDBAppender {
|
|
|
13
13
|
constructor(appender) {
|
|
14
14
|
this.appender = appender;
|
|
15
15
|
}
|
|
16
|
-
|
|
17
|
-
node_bindings_1.default.
|
|
16
|
+
closeSync() {
|
|
17
|
+
node_bindings_1.default.appender_close_sync(this.appender);
|
|
18
18
|
}
|
|
19
|
-
|
|
20
|
-
node_bindings_1.default.
|
|
19
|
+
flushSync() {
|
|
20
|
+
node_bindings_1.default.appender_flush_sync(this.appender);
|
|
21
21
|
}
|
|
22
22
|
get columnCount() {
|
|
23
23
|
return node_bindings_1.default.appender_column_count(this.appender);
|
|
@@ -12,10 +12,10 @@ import { DuckDBValue } from './values';
|
|
|
12
12
|
export declare class DuckDBConnection {
|
|
13
13
|
private readonly connection;
|
|
14
14
|
constructor(connection: duckdb.Connection);
|
|
15
|
-
static create(instance
|
|
16
|
-
/** Same as
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
static create(instance?: DuckDBInstance): Promise<DuckDBConnection>;
|
|
16
|
+
/** Same as disconnectSync. */
|
|
17
|
+
closeSync(): void;
|
|
18
|
+
disconnectSync(): void;
|
|
19
19
|
interrupt(): void;
|
|
20
20
|
get progress(): duckdb.QueryProgress;
|
|
21
21
|
run(sql: string, values?: DuckDBValue[] | Record<string, DuckDBValue>, types?: DuckDBType[] | Record<string, DuckDBType | undefined>): Promise<DuckDBMaterializedResult>;
|
package/lib/DuckDBConnection.js
CHANGED
|
@@ -7,6 +7,7 @@ exports.DuckDBConnection = void 0;
|
|
|
7
7
|
const node_bindings_1 = __importDefault(require("@duckdb/node-bindings"));
|
|
8
8
|
const DuckDBAppender_1 = require("./DuckDBAppender");
|
|
9
9
|
const DuckDBExtractedStatements_1 = require("./DuckDBExtractedStatements");
|
|
10
|
+
const DuckDBInstance_1 = require("./DuckDBInstance");
|
|
10
11
|
const DuckDBMaterializedResult_1 = require("./DuckDBMaterializedResult");
|
|
11
12
|
const DuckDBPreparedStatement_1 = require("./DuckDBPreparedStatement");
|
|
12
13
|
const DuckDBResultReader_1 = require("./DuckDBResultReader");
|
|
@@ -16,14 +17,17 @@ class DuckDBConnection {
|
|
|
16
17
|
this.connection = connection;
|
|
17
18
|
}
|
|
18
19
|
static async create(instance) {
|
|
19
|
-
|
|
20
|
+
if (instance) {
|
|
21
|
+
return instance.connect();
|
|
22
|
+
}
|
|
23
|
+
return (await DuckDBInstance_1.DuckDBInstance.fromCache()).connect();
|
|
20
24
|
}
|
|
21
|
-
/** Same as
|
|
22
|
-
|
|
23
|
-
return this.
|
|
25
|
+
/** Same as disconnectSync. */
|
|
26
|
+
closeSync() {
|
|
27
|
+
return this.disconnectSync();
|
|
24
28
|
}
|
|
25
|
-
|
|
26
|
-
return node_bindings_1.default.
|
|
29
|
+
disconnectSync() {
|
|
30
|
+
return node_bindings_1.default.disconnect_sync(this.connection);
|
|
27
31
|
}
|
|
28
32
|
interrupt() {
|
|
29
33
|
node_bindings_1.default.interrupt(this.connection);
|
package/lib/DuckDBDataChunk.d.ts
CHANGED
|
@@ -14,20 +14,28 @@ export declare class DuckDBDataChunk {
|
|
|
14
14
|
set rowCount(count: number);
|
|
15
15
|
getColumnVector(columnIndex: number): DuckDBVector;
|
|
16
16
|
visitColumnValues(columnIndex: number, visitValue: (value: DuckDBValue, rowIndex: number, columnIndex: number, type: DuckDBType) => void): void;
|
|
17
|
+
appendColumnValues(columnIndex: number, values: DuckDBValue[]): void;
|
|
17
18
|
getColumnValues(columnIndex: number): DuckDBValue[];
|
|
18
|
-
convertColumnValues<T>(columnIndex: number, converter: DuckDBValueConverter<T>): T[];
|
|
19
|
+
convertColumnValues<T>(columnIndex: number, converter: DuckDBValueConverter<T>): (T | null)[];
|
|
19
20
|
setColumnValues(columnIndex: number, values: readonly DuckDBValue[]): void;
|
|
20
21
|
visitColumns(visitColumn: (column: DuckDBValue[], columnIndex: number, type: DuckDBType) => void): void;
|
|
22
|
+
appendToColumns(columns: (DuckDBValue[] | undefined)[]): void;
|
|
21
23
|
getColumns(): DuckDBValue[][];
|
|
22
|
-
convertColumns<T>(converter: DuckDBValueConverter<T>): T[][];
|
|
24
|
+
convertColumns<T>(converter: DuckDBValueConverter<T>): (T | null)[][];
|
|
23
25
|
setColumns(columns: readonly (readonly DuckDBValue[])[]): void;
|
|
26
|
+
appendToColumnsObject(columnNames: readonly string[], columnsObject: Record<string, DuckDBValue[] | undefined>): void;
|
|
27
|
+
getColumnsObject(columnNames: readonly string[]): Record<string, DuckDBValue[]>;
|
|
24
28
|
visitColumnMajor(visitValue: (value: DuckDBValue, rowIndex: number, columnIndex: number, type: DuckDBType) => void): void;
|
|
25
29
|
visitRowValues(rowIndex: number, visitValue: (value: DuckDBValue, rowIndex: number, columnIndex: number, type: DuckDBType) => void): void;
|
|
30
|
+
appendRowValues(rowIndex: number, values: DuckDBValue[]): void;
|
|
26
31
|
getRowValues(rowIndex: number): DuckDBValue[];
|
|
27
|
-
convertRowValues<T>(rowIndex: number, converter: DuckDBValueConverter<T>): T[];
|
|
32
|
+
convertRowValues<T>(rowIndex: number, converter: DuckDBValueConverter<T>): (T | null)[];
|
|
28
33
|
visitRows(visitRow: (row: DuckDBValue[], rowIndex: number) => void): void;
|
|
34
|
+
appendToRows(rows: DuckDBValue[][]): void;
|
|
29
35
|
getRows(): DuckDBValue[][];
|
|
30
|
-
convertRows<T>(converter: DuckDBValueConverter<T>): T[][];
|
|
36
|
+
convertRows<T>(converter: DuckDBValueConverter<T>): (T | null)[][];
|
|
31
37
|
setRows(rows: readonly (readonly DuckDBValue[])[]): void;
|
|
38
|
+
appendToRowObjects(columnNames: readonly string[], rowObjects: Record<string, DuckDBValue>[]): void;
|
|
39
|
+
getRowObjects(columnNames: readonly string[]): Record<string, DuckDBValue>[];
|
|
32
40
|
visitRowMajor(visitValue: (value: DuckDBValue, rowIndex: number, columnIndex: number, type: DuckDBType) => void): void;
|
|
33
41
|
}
|
package/lib/DuckDBDataChunk.js
CHANGED
|
@@ -46,15 +46,17 @@ class DuckDBDataChunk {
|
|
|
46
46
|
visitValue(vector.getItem(rowIndex), rowIndex, columnIndex, type);
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
|
+
appendColumnValues(columnIndex, values) {
|
|
50
|
+
this.visitColumnValues(columnIndex, (value) => values.push(value));
|
|
51
|
+
}
|
|
49
52
|
getColumnValues(columnIndex) {
|
|
50
53
|
const values = [];
|
|
51
|
-
this.
|
|
54
|
+
this.appendColumnValues(columnIndex, values);
|
|
52
55
|
return values;
|
|
53
56
|
}
|
|
54
57
|
convertColumnValues(columnIndex, converter) {
|
|
55
58
|
const convertedValues = [];
|
|
56
|
-
|
|
57
|
-
this.visitColumnValues(columnIndex, (value) => convertedValues.push(converter.convertValue(value, type)));
|
|
59
|
+
this.visitColumnValues(columnIndex, (value, _r, _c, type) => convertedValues.push(converter(value, type, converter)));
|
|
58
60
|
return convertedValues;
|
|
59
61
|
}
|
|
60
62
|
setColumnValues(columnIndex, values) {
|
|
@@ -73,6 +75,17 @@ class DuckDBDataChunk {
|
|
|
73
75
|
visitColumn(this.getColumnValues(columnIndex), columnIndex, this.getColumnVector(columnIndex).type);
|
|
74
76
|
}
|
|
75
77
|
}
|
|
78
|
+
appendToColumns(columns) {
|
|
79
|
+
const columnCount = this.columnCount;
|
|
80
|
+
for (let columnIndex = 0; columnIndex < columnCount; columnIndex++) {
|
|
81
|
+
let column = columns[columnIndex];
|
|
82
|
+
if (!column) {
|
|
83
|
+
column = [];
|
|
84
|
+
columns[columnIndex] = column;
|
|
85
|
+
}
|
|
86
|
+
this.appendColumnValues(columnIndex, column);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
76
89
|
getColumns() {
|
|
77
90
|
const columns = [];
|
|
78
91
|
this.visitColumns((column) => columns.push(column));
|
|
@@ -94,6 +107,26 @@ class DuckDBDataChunk {
|
|
|
94
107
|
this.setColumnValues(columnIndex, columns[columnIndex]);
|
|
95
108
|
}
|
|
96
109
|
}
|
|
110
|
+
appendToColumnsObject(columnNames, columnsObject) {
|
|
111
|
+
const columnCount = this.columnCount;
|
|
112
|
+
if (columnNames.length !== columnCount) {
|
|
113
|
+
throw new Error(`Provided number of column names (${columnNames.length}) does not match column count (${this.columnCount})`);
|
|
114
|
+
}
|
|
115
|
+
for (let columnIndex = 0; columnIndex < columnCount; columnIndex++) {
|
|
116
|
+
const columnName = columnNames[columnIndex];
|
|
117
|
+
let columnValues = columnsObject[columnName];
|
|
118
|
+
if (!columnValues) {
|
|
119
|
+
columnValues = [];
|
|
120
|
+
columnsObject[columnName] = columnValues;
|
|
121
|
+
}
|
|
122
|
+
this.appendColumnValues(columnIndex, columnValues);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
getColumnsObject(columnNames) {
|
|
126
|
+
const columnsObject = {};
|
|
127
|
+
this.appendToColumnsObject(columnNames, columnsObject);
|
|
128
|
+
return columnsObject;
|
|
129
|
+
}
|
|
97
130
|
visitColumnMajor(visitValue) {
|
|
98
131
|
const columnCount = this.columnCount;
|
|
99
132
|
for (let columnIndex = 0; columnIndex < columnCount; columnIndex++) {
|
|
@@ -107,14 +140,17 @@ class DuckDBDataChunk {
|
|
|
107
140
|
visitValue(vector.getItem(rowIndex), rowIndex, columnIndex, vector.type);
|
|
108
141
|
}
|
|
109
142
|
}
|
|
143
|
+
appendRowValues(rowIndex, values) {
|
|
144
|
+
this.visitRowValues(rowIndex, (value) => values.push(value));
|
|
145
|
+
}
|
|
110
146
|
getRowValues(rowIndex) {
|
|
111
147
|
const values = [];
|
|
112
|
-
this.
|
|
148
|
+
this.appendRowValues(rowIndex, values);
|
|
113
149
|
return values;
|
|
114
150
|
}
|
|
115
151
|
convertRowValues(rowIndex, converter) {
|
|
116
152
|
const convertedValues = [];
|
|
117
|
-
this.visitRowValues(rowIndex, (value, _, columnIndex) => convertedValues.push(converter
|
|
153
|
+
this.visitRowValues(rowIndex, (value, _, columnIndex) => convertedValues.push(converter(value, this.getColumnVector(columnIndex).type, converter)));
|
|
118
154
|
return convertedValues;
|
|
119
155
|
}
|
|
120
156
|
visitRows(visitRow) {
|
|
@@ -123,9 +159,12 @@ class DuckDBDataChunk {
|
|
|
123
159
|
visitRow(this.getRowValues(rowIndex), rowIndex);
|
|
124
160
|
}
|
|
125
161
|
}
|
|
162
|
+
appendToRows(rows) {
|
|
163
|
+
this.visitRows((row) => rows.push(row));
|
|
164
|
+
}
|
|
126
165
|
getRows() {
|
|
127
166
|
const rows = [];
|
|
128
|
-
this.
|
|
167
|
+
this.appendToRows(rows);
|
|
129
168
|
return rows;
|
|
130
169
|
}
|
|
131
170
|
convertRows(converter) {
|
|
@@ -147,6 +186,25 @@ class DuckDBDataChunk {
|
|
|
147
186
|
vector.flush();
|
|
148
187
|
}
|
|
149
188
|
}
|
|
189
|
+
appendToRowObjects(columnNames, rowObjects) {
|
|
190
|
+
const columnCount = this.columnCount;
|
|
191
|
+
if (columnNames.length !== columnCount) {
|
|
192
|
+
throw new Error(`Provided number of column names (${columnNames.length}) does not match column count (${this.columnCount})`);
|
|
193
|
+
}
|
|
194
|
+
const rowCount = this.rowCount;
|
|
195
|
+
for (let rowIndex = 0; rowIndex < rowCount; rowIndex++) {
|
|
196
|
+
let rowObject = {};
|
|
197
|
+
this.visitRowValues(rowIndex, (value, _, columnIndex) => {
|
|
198
|
+
rowObject[columnNames[columnIndex]] = value;
|
|
199
|
+
});
|
|
200
|
+
rowObjects.push(rowObject);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
getRowObjects(columnNames) {
|
|
204
|
+
const rowObjects = [];
|
|
205
|
+
this.appendToRowObjects(columnNames, rowObjects);
|
|
206
|
+
return rowObjects;
|
|
207
|
+
}
|
|
150
208
|
visitRowMajor(visitValue) {
|
|
151
209
|
const rowCount = this.rowCount;
|
|
152
210
|
const columnCount = this.columnCount;
|
package/lib/DuckDBInstance.d.ts
CHANGED
|
@@ -4,5 +4,7 @@ export declare class DuckDBInstance {
|
|
|
4
4
|
private readonly db;
|
|
5
5
|
constructor(db: duckdb.Database);
|
|
6
6
|
static create(path?: string, options?: Record<string, string>): Promise<DuckDBInstance>;
|
|
7
|
+
static fromCache(path?: string, options?: Record<string, string>): Promise<DuckDBInstance>;
|
|
7
8
|
connect(): Promise<DuckDBConnection>;
|
|
9
|
+
closeSync(): void;
|
|
8
10
|
}
|
package/lib/DuckDBInstance.js
CHANGED
|
@@ -5,26 +5,26 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.DuckDBInstance = void 0;
|
|
7
7
|
const node_bindings_1 = __importDefault(require("@duckdb/node-bindings"));
|
|
8
|
+
const createConfig_1 = require("./createConfig");
|
|
8
9
|
const DuckDBConnection_1 = require("./DuckDBConnection");
|
|
10
|
+
const DuckDBInstanceCache_1 = require("./DuckDBInstanceCache");
|
|
9
11
|
class DuckDBInstance {
|
|
10
12
|
db;
|
|
11
13
|
constructor(db) {
|
|
12
14
|
this.db = db;
|
|
13
15
|
}
|
|
14
16
|
static async create(path, options) {
|
|
15
|
-
const config =
|
|
16
|
-
// Set the default duckdb_api value for the api. Can be overridden.
|
|
17
|
-
node_bindings_1.default.set_config(config, 'duckdb_api', 'node-neo-api');
|
|
18
|
-
if (options) {
|
|
19
|
-
for (const optionName in options) {
|
|
20
|
-
const optionValue = String(options[optionName]);
|
|
21
|
-
node_bindings_1.default.set_config(config, optionName, optionValue);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
17
|
+
const config = (0, createConfig_1.createConfig)(options);
|
|
24
18
|
return new DuckDBInstance(await node_bindings_1.default.open(path, config));
|
|
25
19
|
}
|
|
20
|
+
static async fromCache(path, options) {
|
|
21
|
+
return DuckDBInstanceCache_1.DuckDBInstanceCache.singleton.getOrCreateInstance(path, options);
|
|
22
|
+
}
|
|
26
23
|
async connect() {
|
|
27
24
|
return new DuckDBConnection_1.DuckDBConnection(await node_bindings_1.default.connect(this.db));
|
|
28
25
|
}
|
|
26
|
+
closeSync() {
|
|
27
|
+
node_bindings_1.default.close_sync(this.db);
|
|
28
|
+
}
|
|
29
29
|
}
|
|
30
30
|
exports.DuckDBInstance = DuckDBInstance;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { DuckDBInstance } from './DuckDBInstance';
|
|
2
|
+
export declare class DuckDBInstanceCache {
|
|
3
|
+
private readonly cache;
|
|
4
|
+
constructor();
|
|
5
|
+
getOrCreateInstance(path?: string, options?: Record<string, string>): Promise<DuckDBInstance>;
|
|
6
|
+
private static singletonInstance;
|
|
7
|
+
static get singleton(): DuckDBInstanceCache;
|
|
8
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.DuckDBInstanceCache = void 0;
|
|
7
|
+
const node_bindings_1 = __importDefault(require("@duckdb/node-bindings"));
|
|
8
|
+
const DuckDBInstance_1 = require("./DuckDBInstance");
|
|
9
|
+
const createConfig_1 = require("./createConfig");
|
|
10
|
+
class DuckDBInstanceCache {
|
|
11
|
+
cache;
|
|
12
|
+
constructor() {
|
|
13
|
+
this.cache = node_bindings_1.default.create_instance_cache();
|
|
14
|
+
}
|
|
15
|
+
async getOrCreateInstance(path, options) {
|
|
16
|
+
const config = (0, createConfig_1.createConfig)(options);
|
|
17
|
+
const db = await node_bindings_1.default.get_or_create_from_cache(this.cache, path, config);
|
|
18
|
+
return new DuckDBInstance_1.DuckDBInstance(db);
|
|
19
|
+
}
|
|
20
|
+
static singletonInstance;
|
|
21
|
+
static get singleton() {
|
|
22
|
+
if (!DuckDBInstanceCache.singletonInstance) {
|
|
23
|
+
DuckDBInstanceCache.singletonInstance = new DuckDBInstanceCache();
|
|
24
|
+
}
|
|
25
|
+
return DuckDBInstanceCache.singletonInstance;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
exports.DuckDBInstanceCache = DuckDBInstanceCache;
|
package/lib/DuckDBResult.d.ts
CHANGED
|
@@ -3,7 +3,9 @@ import { DuckDBDataChunk } from './DuckDBDataChunk';
|
|
|
3
3
|
import { DuckDBLogicalType } from './DuckDBLogicalType';
|
|
4
4
|
import { DuckDBType } from './DuckDBType';
|
|
5
5
|
import { DuckDBTypeId } from './DuckDBTypeId';
|
|
6
|
-
import {
|
|
6
|
+
import { DuckDBValueConverter } from './DuckDBValueConverter';
|
|
7
|
+
import { JS } from './JS';
|
|
8
|
+
import { Json } from './Json';
|
|
7
9
|
import { ResultReturnType, StatementType } from './enums';
|
|
8
10
|
import { DuckDBValue } from './values';
|
|
9
11
|
export declare class DuckDBResult {
|
|
@@ -18,17 +20,29 @@ export declare class DuckDBResult {
|
|
|
18
20
|
columnTypeId(columnIndex: number): DuckDBTypeId;
|
|
19
21
|
columnLogicalType(columnIndex: number): DuckDBLogicalType;
|
|
20
22
|
columnType(columnIndex: number): DuckDBType;
|
|
23
|
+
columnTypeJson(columnIndex: number): Json;
|
|
21
24
|
columnTypes(): DuckDBType[];
|
|
25
|
+
columnTypesJson(): Json;
|
|
26
|
+
columnNamesAndTypesJson(): Json;
|
|
27
|
+
columnNameAndTypeObjectsJson(): Json;
|
|
22
28
|
get isStreaming(): boolean;
|
|
23
29
|
get rowsChanged(): number;
|
|
24
30
|
fetchChunk(): Promise<DuckDBDataChunk | null>;
|
|
25
31
|
fetchAllChunks(): Promise<DuckDBDataChunk[]>;
|
|
26
32
|
getColumns(): Promise<DuckDBValue[][]>;
|
|
33
|
+
convertColumns<T>(converter: DuckDBValueConverter<T>): Promise<(T | null)[][]>;
|
|
34
|
+
getColumnsJS(): Promise<JS[][]>;
|
|
27
35
|
getColumnsJson(): Promise<Json[][]>;
|
|
28
36
|
getColumnsObject(): Promise<Record<string, DuckDBValue[]>>;
|
|
37
|
+
convertColumnsObject<T>(converter: DuckDBValueConverter<T>): Promise<Record<string, (T | null)[]>>;
|
|
38
|
+
getColumnsObjectJS(): Promise<Record<string, JS[]>>;
|
|
29
39
|
getColumnsObjectJson(): Promise<Record<string, Json[]>>;
|
|
30
40
|
getRows(): Promise<DuckDBValue[][]>;
|
|
41
|
+
convertRows<T>(converter: DuckDBValueConverter<T>): Promise<(T | null)[][]>;
|
|
42
|
+
getRowsJS(): Promise<JS[][]>;
|
|
31
43
|
getRowsJson(): Promise<Json[][]>;
|
|
32
44
|
getRowObjects(): Promise<Record<string, DuckDBValue>[]>;
|
|
45
|
+
convertRowObjects<T>(converter: DuckDBValueConverter<T>): Promise<Record<string, T | null>[]>;
|
|
46
|
+
getRowObjectsJS(): Promise<Record<string, JS>[]>;
|
|
33
47
|
getRowObjectsJson(): Promise<Record<string, Json>[]>;
|
|
34
48
|
}
|