Skip to content

Commit f639cda

Browse files
committed
change some types
1 parent 08b0892 commit f639cda

File tree

7 files changed

+338
-209
lines changed

7 files changed

+338
-209
lines changed

api/pkgs/@duckdb/node-api/README.md

Lines changed: 131 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ This is a high-level API meant for applications. It depends on low-level binding
1616
### Roadmap
1717

1818
Some features are not yet complete:
19-
- Friendlier APIs for consuming advanced data types and values, especially converting them to strings.
19+
- Friendlier APIs for convering results to common JS data structures.
20+
- Friendlier APIs for converting values of specialized and complex DuckDB types to common JS types.
21+
- Automatic memory management (i.e. avoiding the need to call `dispose` manually in most cases).
2022
- Appending and binding advanced data types. (Additional DuckDB C API support needed.)
2123
- Writing to data chunk vectors. (Directly writing to binary buffers is challenging to support using the Node Addon API.)
2224
- User-defined types & functions. (Support for this was added to the DuckDB C API in v1.1.0.)
@@ -163,89 +165,149 @@ chunk.dispose();
163165
```ts
164166
import { DuckDBTypeId } from '@duckdb/node-api';
165167

166-
function typeToString(dataType) {
167-
switch (dataType.typeId) {
168-
case DuckDBTypeId.ARRAY:
169-
return `${typeToString(dataType.valueType)}[${dataType.length}]`;
170-
case DuckDBTypeId.DECIMAL:
171-
return `DECIMAL(${dataType.width},${dataType.scale})`;
172-
case DuckDBTypeId.ENUM:
173-
return `ENUM(${dataType.values.map(
174-
value => `'${value.replace(`'`, `''`)}'`
175-
).join(', ')})`;
176-
case DuckDBTypeId.LIST:
177-
return `${typeToString(dataType.valueType)}[]`;
178-
case DuckDBTypeId.MAP:
179-
return `MAP(${typeToString(dataType.keyType)}, ${typeToString(dataType.valueType)})`;
180-
case DuckDBTypeId.STRUCT:
181-
return `STRUCT(${dataType.entries.map(
182-
entry => `"${entry.name.replace(`"`, `""`)}" ${typeToString(entry.valueType)}`
183-
).join(', ')})`;
184-
case DuckDBTypeId.UNION:
185-
return `UNION(${dataType.alternatives.map(
186-
alt => `"${alt.tag.replace(`"`, `""`)}" ${typeToString(alt.valueType)}`
187-
).join(', ')})`;
188-
default:
189-
return DuckDBTypeId[dataType.typeId];
190-
}
168+
if (columnType.typeId === DuckDBTypeId.ARRAY) {
169+
const arrayValueType = columnType.valueType;
170+
const arrayLength = columnType.length;
171+
}
172+
173+
if (columnType.typeId === DuckDBTypeId.DECIMAL) {
174+
const decimalWidth = columnType.width;
175+
const decimalScale = columnType.scale;
176+
}
177+
178+
if (columnType.typeId === DuckDBTypeId.ENUM) {
179+
const enumValues = columnType.values;
180+
}
181+
182+
if (columnType.typeId === DuckDBTypeId.LIST) {
183+
const listValueType = columnType.valueType;
184+
}
185+
186+
if (columnType.typeId === DuckDBTypeId.MAP) {
187+
const mapKeyType = columnType.keyType;
188+
const mapValueType = columnType.valueType;
189+
}
190+
191+
if (columnType.typeId === DuckDBTypeId.STRUCT) {
192+
const structEntryNames = columnType.names;
193+
const structEntryTypes = columnType.valueTypes;
194+
}
195+
196+
if (columnType.typeId === DuckDBTypeId.UNION) {
197+
const unionMemberTags = columnType.memberTags;
198+
const unionMemberTypes = columnType.memberTypes;
191199
}
192200
```
193201

194-
While the example above demonstrates how to access the properties of data type objects, there is a much simpler way to convert them to strings:
202+
Every type implements toString, matching DuckDB's type-to-string conversion.
195203

196204
```ts
197-
const dataTypeString = dataType.toString();
205+
const typeString = columnType.toString();
198206
```
199207

200208
### Inspect Data Values
201209

202210
```ts
203211
import { DuckDBTypeId } from '@duckdb/node-api';
204212

205-
function valueToString(value, dataType) {
206-
switch (dataType.typeId) {
207-
case DuckDBTypeId.ARRAY:
208-
return value
209-
? `[${Array.from({ length: dataType.length }).map(
210-
(_, i) => valueToString(value.getItem(i), dataType.valueType)
211-
).join(', ')}]`
212-
: 'null';
213-
case DuckDBTypeId.DECIMAL:
214-
return JSON.stringify(value, replacer);
215-
case DuckDBTypeId.INTERVAL:
216-
return JSON.stringify(value, replacer);
217-
case DuckDBTypeId.LIST:
218-
return value
219-
? `[${Array.from({ length: value.itemCount }).map(
220-
(_, i) => valueToString(value.getItem(i), dataType.valueType)
221-
).join(', ')}]`
222-
: 'null';
223-
case DuckDBTypeId.MAP:
224-
return value
225-
? `{ ${value.map(
226-
(entry) => `${valueToString(entry.key, dataType.keyType)}=${valueToString(entry.value, dataType.valueType)}`
227-
).join(', ')} }`
228-
: 'null';
229-
case DuckDBTypeId.STRUCT:
230-
return value
231-
? `{ ${value.map(
232-
(entry, i) => `'${entry.name.replace(`'`, `''`)}': ${valueToString(entry.value, dataType.entries[i].valueType)}`
233-
).join(', ')} }`
234-
: 'null';
235-
case DuckDBTypeId.TIME_TZ:
236-
return JSON.stringify(value, replacer);
237-
case DuckDBTypeId.UNION:
238-
return value
239-
? valueToString(value.value, dataType.alternatives.find((alt) => alt.tag === value.tag).valueType)
240-
: 'null';
241-
default:
242-
return String(value);
243-
}
213+
if (columnType.typeId === DuckDBTypeId.ARRAY) {
214+
const arrayItems = columnValue.items; // array of values
215+
const arrayString = columnValue.toString();
216+
}
217+
218+
if (columnType.typeId === DuckDBTypeId.BIT) {
219+
const bools = columnValue.toBools(); // array of booleans
220+
const bits = columnValue.toBits(); // arrary of 0s and 1s
221+
const bitString = columnValue.toString(); // string of '0's and '1's
222+
}
223+
224+
if (columnType.typeId === DuckDBTypeId.BLOB) {
225+
const blobBytes = columnValue.bytes; // Uint8Array
226+
const blobString = columnValue.toString();
227+
}
228+
229+
if (columnType.typeId === DuckDBTypeId.DATE) {
230+
const dateDays = columnValue.days;
231+
const dateString = columnValue.toString();
232+
}
233+
234+
if (columnType.typeId === DuckDBTypeId.DECIMAL) {
235+
const decimalWidth = columnValue.width;
236+
const decimalScale = columnValue.scale;
237+
const decimalValue = columnValue.value; // bigint (raw fixed-point integer; `scale` indicates number of fractional digits)
238+
const decimalString = columnValue.toString();
239+
}
240+
241+
if (columnType.typeId === DuckDBTypeId.INTERVAL) {
242+
const intervalMonths = columnValue.months;
243+
const intervalDays = columnValue.days;
244+
const intervalMicros = columnValue.micros; // bigint
245+
const intervalString = columnValue.toString();
244246
}
245247

246-
function replacer(key, value) {
247-
return typeof value === "bigint" ? { $bigint: value.toString() } : value;
248+
if (columnType.typeId === DuckDBTypeId.LIST) {
249+
const listItems = columnValue.items; // array of values
250+
const listString = columnValue.toString();
248251
}
252+
253+
if (columnType.typeId === DuckDBTypeId.MAP) {
254+
const mapEntries = columnValue.entries; // array of { key, value }
255+
const mapString = columnValue.toString();
256+
}
257+
258+
if (columnType.typeId === DuckDBTypeId.STRUCT) {
259+
const structEntries = columnValue.entries; // { name1: value1, name2: value2, ... }
260+
const structString = columnValue.toString();
261+
}
262+
263+
if (columnType.typeId === DuckDBTypeId.TIMESTAMP_MS) {
264+
const timestampMillis = columnValue.milliseconds; // bigint
265+
const timestampMillisString = columnValue.toString();
266+
}
267+
268+
if (columnType.typeId === DuckDBTypeId.TIMESTAMP_NS) {
269+
const timestampNanos = columnValue.nanoseconds; // bigint
270+
const timestampNanosString = columnValue.toString();
271+
}
272+
273+
if (columnType.typeId === DuckDBTypeId.TIMESTAMP_S) {
274+
const timestampSecs = columnValue.seconds; // bigint
275+
const timestampSecsString = columnValue.toString();
276+
}
277+
278+
if (columnType.typeId === DuckDBTypeId.TIMESTAMP_TZ) {
279+
const timestampTZMicros = columnValue.micros; // bigint
280+
const timestampTZString = columnValue.toString();
281+
}
282+
283+
if (columnType.typeId === DuckDBTypeId.TIMESTAMP) {
284+
const timestampMicros = columnValue.micros; // bigint
285+
const timestampString = columnValue.toString();
286+
}
287+
288+
if (columnType.typeId === DuckDBTypeId.TIME_TZ) {
289+
const timeTZMicros = columnValue.microseconds;
290+
const timeTZOffset = columnValue.offset;
291+
const timeTZString = columnValue.toString();
292+
}
293+
294+
if (columnType.typeId === DuckDBTypeId.TIME) {
295+
const timeMicros = columnValue.microseconds; // bigint
296+
const timeString = columnValue.toString();
297+
}
298+
299+
if (columnType.typeId === DuckDBTypeId.UNION) {
300+
const unionTag = columnValue.tag;
301+
const unionValue = columnValue.value;
302+
const unionValueString = columnValue.toString();
303+
}
304+
305+
if (columnType.typeId === DuckDBTypeId.UUID) {
306+
const uuidHugeint = columnValue.hugeint; // bigint
307+
const uuidString = columnValue.toString();
308+
}
309+
310+
// other values are represented as null, boolean, number, bigint, or string
249311
```
250312

251313
### Append To Table

0 commit comments

Comments
 (0)