Skip to content

Commit

Permalink
support more binds
Browse files Browse the repository at this point in the history
  • Loading branch information
jraymakers committed Jan 14, 2025
1 parent 60d2299 commit e67c944
Show file tree
Hide file tree
Showing 2 changed files with 166 additions and 6 deletions.
17 changes: 11 additions & 6 deletions api/src/DuckDBPreparedStatement.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
import duckdb from '@duckdb/node-bindings';
import { createValue } from './createValue';
import { DuckDBMaterializedResult } from './DuckDBMaterializedResult';
import { DuckDBPendingResult } from './DuckDBPendingResult';
import { DuckDBResult } from './DuckDBResult';
import { DuckDBResultReader } from './DuckDBResultReader';
import { DuckDBTimestampTZType, DuckDBTimeTZType } from './DuckDBType';
import { DuckDBTypeId } from './DuckDBTypeId';
import { StatementType } from './enums';
import {
DuckDBDateValue,
DuckDBDecimalValue,
DuckDBIntervalValue,
DuckDBTimestampTZValue,
DuckDBTimestampValue,
DuckDBTimeTZValue,
DuckDBTimeValue,
} from './values';

Expand Down Expand Up @@ -87,11 +91,16 @@ export class DuckDBPreparedStatement {
public bindTime(parameterIndex: number, value: DuckDBTimeValue) {
duckdb.bind_time(this.prepared_statement, parameterIndex, value);
}
public bindTimeTZ(parameterIndex: number, value: DuckDBTimeTZValue) {
duckdb.bind_value(this.prepared_statement, parameterIndex, createValue(DuckDBTimeTZType.instance, value));
}
public bindTimestamp(parameterIndex: number, value: DuckDBTimestampValue) {
duckdb.bind_timestamp(this.prepared_statement, parameterIndex, value);
}
// TODO: bind TIMESTAMPS_S/_MS/_NS?
// TODO: bind TIME_TZ/TIMESTAMP_TZ?
public bindTimestampTZ(parameterIndex: number, value: DuckDBTimestampTZValue) {
duckdb.bind_value(this.prepared_statement, parameterIndex, createValue(DuckDBTimestampTZType.instance, value));
}
// TODO: bind TIMESTAMPS_S/_MS/_NS?
public bindInterval(parameterIndex: number, value: DuckDBIntervalValue) {
duckdb.bind_interval(this.prepared_statement, parameterIndex, value);
}
Expand All @@ -108,10 +117,6 @@ export class DuckDBPreparedStatement {
public bindNull(parameterIndex: number) {
duckdb.bind_null(this.prepared_statement, parameterIndex);
}
// TODO: expose bindValue, or implement bindList, bindStruct, etc.?
// public bindValue(parameterIndex: number, value: Value) {
// duckdb.bind_value(this.prepared_statement, parameterIndex, value);
// }
public async run(): Promise<DuckDBMaterializedResult> {
return new DuckDBMaterializedResult(await duckdb.execute_prepared(this.prepared_statement));
}
Expand Down
155 changes: 155 additions & 0 deletions api/src/createValue.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
import duckdb, { Value } from '@duckdb/node-bindings';
import { DuckDBType } from './DuckDBType';
import { DuckDBTypeId } from './DuckDBTypeId';
import {
DuckDBBlobValue,
DuckDBDateValue,
DuckDBIntervalValue,
DuckDBTimestampTZValue,
DuckDBTimestampValue,
DuckDBTimeTZValue,
DuckDBTimeValue,
DuckDBValue,
} from './values';

export function createValue(type: DuckDBType, input: DuckDBValue): Value {
switch (type.typeId) {
case DuckDBTypeId.BOOLEAN:
if (typeof input === 'boolean') {
return duckdb.create_bool(input);
}
throw new Error(`input is not a boolean`);
case DuckDBTypeId.TINYINT:
if (typeof input === 'number') {
return duckdb.create_int8(input);
}
throw new Error(`input is not a number`);
case DuckDBTypeId.SMALLINT:
if (typeof input === 'number') {
return duckdb.create_int16(input);
}
throw new Error(`input is not a number`);
case DuckDBTypeId.INTEGER:
if (typeof input === 'number') {
return duckdb.create_int32(input);
}
throw new Error(`input is not a number`);
case DuckDBTypeId.BIGINT:
if (typeof input === 'bigint') {
return duckdb.create_int64(input);
}
throw new Error(`input is not a bigint`);
case DuckDBTypeId.UTINYINT:
if (typeof input === 'number') {
return duckdb.create_uint8(input);
}
throw new Error(`input is not a number`);
case DuckDBTypeId.USMALLINT:
if (typeof input === 'number') {
return duckdb.create_uint16(input);
}
throw new Error(`input is not a number`);
case DuckDBTypeId.UINTEGER:
if (typeof input === 'number') {
return duckdb.create_uint32(input);
}
throw new Error(`input is not a number`);
case DuckDBTypeId.UBIGINT:
if (typeof input === 'bigint') {
return duckdb.create_uint64(input);
}
throw new Error(`input is not a bigint`);
case DuckDBTypeId.FLOAT:
if (typeof input === 'number') {
return duckdb.create_float(input);
}
throw new Error(`input is not a number`);
case DuckDBTypeId.DOUBLE:
if (typeof input === 'number') {
return duckdb.create_double(input);
}
throw new Error(`input is not a number`);
case DuckDBTypeId.TIMESTAMP:
if (input instanceof DuckDBTimestampValue) {
return duckdb.create_timestamp(input);
}
throw new Error(`input is not a DuckDBTimestampValue`);
case DuckDBTypeId.DATE:
if (input instanceof DuckDBDateValue) {
return duckdb.create_date(input);
}
throw new Error(`input is not a DuckDBDateValue`);
case DuckDBTypeId.TIME:
if (input instanceof DuckDBTimeValue) {
return duckdb.create_time(input);
}
throw new Error(`input is not a DuckDBTimeValue`);
case DuckDBTypeId.INTERVAL:
if (input instanceof DuckDBIntervalValue) {
return duckdb.create_interval(input);
}
throw new Error(`input is not a DuckDBIntervalValue`);
case DuckDBTypeId.HUGEINT:
if (typeof input === 'bigint') {
return duckdb.create_hugeint(input);
}
throw new Error(`input is not a bigint`);
case DuckDBTypeId.UHUGEINT:
if (typeof input === 'bigint') {
return duckdb.create_uhugeint(input);
}
throw new Error(`input is not a bigint`);
case DuckDBTypeId.VARCHAR:
if (typeof input === 'string') {
return duckdb.create_varchar(input);
}
throw new Error(`input is not a string`);
case DuckDBTypeId.BLOB:
if (input instanceof DuckDBBlobValue) {
return duckdb.create_blob(input.bytes);
}
throw new Error(`input is not a DuckDBBlobValue`);
case DuckDBTypeId.DECIMAL:
throw new Error(`not yet implemented for DECIMAL`); // TODO: implement when available in 1.2.0
case DuckDBTypeId.TIMESTAMP_S:
throw new Error(`not yet implemented for TIMESTAMP_S`); // TODO: implement when available in 1.2.0
case DuckDBTypeId.TIMESTAMP_MS:
throw new Error(`not yet implemented for TIMESTAMP_MS`); // TODO: implement when available in 1.2.0
case DuckDBTypeId.TIMESTAMP_NS:
throw new Error(`not yet implemented for TIMESTAMP_NS`); // TODO: implement when available in 1.2.0
case DuckDBTypeId.ENUM:
throw new Error(`not yet implemented for ENUM`); // TODO: implement when available in 1.2.0
case DuckDBTypeId.LIST:
throw new Error(`not yet implemented for LIST`); // TODO (need toLogicalType)
case DuckDBTypeId.STRUCT:
throw new Error(`not yet implemented for STRUCT`); // TODO (need toLogicalType)
case DuckDBTypeId.MAP:
throw new Error(`not yet implemented for MAP`); // TODO: implement when available, hopefully in 1.2.0
case DuckDBTypeId.ARRAY:
throw new Error(`not yet implemented for ARRAY`); // TODO (need toLogicalType)
case DuckDBTypeId.UUID:
throw new Error(`not yet implemented for UUID`); // TODO: implement when available in 1.2.0
case DuckDBTypeId.UNION:
throw new Error(`not yet implemented for UNION`); // TODO: implement when available, hopefully in 1.2.0
case DuckDBTypeId.UNION:
throw new Error(`not yet implemented for BIT`); // TODO: implement when available in 1.2.0
case DuckDBTypeId.TIME_TZ:
if (input instanceof DuckDBTimeTZValue) {
return duckdb.create_time_tz_value(input);
}
throw new Error(`input is not a DuckDBTimeTZValue`);
case DuckDBTypeId.TIMESTAMP_TZ:
if (input instanceof DuckDBTimestampTZValue) {
return duckdb.create_timestamp(input); // TODO: change to create_timestamp_tz when available in 1.2.0
}
throw new Error(`input is not a DuckDBTimestampTZValue`);
case DuckDBTypeId.ANY:
throw new Error(`cannot create values of type ANY`);
case DuckDBTypeId.VARINT:
throw new Error(`not yet implemented for VARINT`); // TODO: implement when available in 1.2.0
case DuckDBTypeId.SQLNULL:
throw new Error(`not yet implemented for SQLNUll`); // TODO: implement when available in 1.2.0
default:
throw new Error(`unrecognized type id ${type.typeId}`);
}
}

0 comments on commit e67c944

Please sign in to comment.