@avidian/duckdb-bun 0.0.0-stage → 1.0.0
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/LICENSE +22 -0
- package/README.md +284 -2
- package/package.json +95 -4
- package/src/bindings/api/appender.ts +288 -0
- package/src/bindings/api/data-chunk.ts +58 -0
- package/src/bindings/api/database.ts +232 -0
- package/src/bindings/api/datetime.ts +158 -0
- package/src/bindings/api/index.ts +13 -0
- package/src/bindings/api/logical-types.ts +227 -0
- package/src/bindings/api/query.ts +616 -0
- package/src/bindings/api/scalar-function.ts +274 -0
- package/src/bindings/api/table-function.ts +339 -0
- package/src/bindings/api/values.ts +546 -0
- package/src/bindings/api/vector.ts +266 -0
- package/src/bindings/generated/capi.ts +695 -0
- package/src/bindings/generated/contract.ts +162 -0
- package/src/bindings/index.ts +10 -0
- package/src/bindings/runtime/convert.ts +307 -0
- package/src/bindings/runtime/diagnostics.ts +45 -0
- package/src/bindings/runtime/dispatch.ts +200 -0
- package/src/bindings/runtime/exception.ts +103 -0
- package/src/bindings/runtime/flags.ts +19 -0
- package/src/bindings/runtime/handle.ts +217 -0
- package/src/bindings/runtime/kinds.ts +53 -0
- package/src/bindings/runtime/marshal.ts +190 -0
- package/src/bindings/runtime/native.ts +150 -0
- package/src/bindings/runtime/ring.ts +54 -0
- package/src/bindings/runtime/scope.ts +133 -0
- package/src/bindings/runtime/trace.ts +65 -0
- package/src/connection.ts +35 -0
- package/src/database.ts +27 -0
- package/src/errors.ts +30 -0
- package/src/file-assets.d.ts +10 -0
- package/src/index.ts +17 -0
- package/src/library.ts +83 -0
- package/src/neo.ts +16 -0
- package/src/reader.ts +47 -0
- package/src/statement.ts +61 -0
- package/src/types.ts +52 -0
- package/src/version.ts +6 -0
- package/vendor/node-api/LICENSE +7 -0
- package/vendor/node-api/PROVENANCE.md +54 -0
- package/vendor/node-api/node-bindings.d.ts +1669 -0
- package/vendor/node-api/src/DuckDBAppender.ts +237 -0
- package/vendor/node-api/src/DuckDBClientContext.ts +13 -0
- package/vendor/node-api/src/DuckDBConnection.ts +315 -0
- package/vendor/node-api/src/DuckDBDataChunk.ts +412 -0
- package/vendor/node-api/src/DuckDBDataChunkWriter.ts +144 -0
- package/vendor/node-api/src/DuckDBExtractedStatements.ts +37 -0
- package/vendor/node-api/src/DuckDBInstance.ts +35 -0
- package/vendor/node-api/src/DuckDBInstanceCache.ts +29 -0
- package/vendor/node-api/src/DuckDBLogicalType.ts +446 -0
- package/vendor/node-api/src/DuckDBMaterializedResult.ts +39 -0
- package/vendor/node-api/src/DuckDBPendingResult.ts +83 -0
- package/vendor/node-api/src/DuckDBPreparedStatement.ts +376 -0
- package/vendor/node-api/src/DuckDBPreparedStatementCollection.ts +5 -0
- package/vendor/node-api/src/DuckDBPreparedStatementWeakRefCollection.ts +31 -0
- package/vendor/node-api/src/DuckDBResult.ts +403 -0
- package/vendor/node-api/src/DuckDBResultReader.ts +283 -0
- package/vendor/node-api/src/DuckDBScalarFunction.ts +149 -0
- package/vendor/node-api/src/DuckDBScalarFunctionBindInfo.ts +34 -0
- package/vendor/node-api/src/DuckDBScalarFunctionInfo.ts +34 -0
- package/vendor/node-api/src/DuckDBScalarFunctionInitInfo.ts +35 -0
- package/vendor/node-api/src/DuckDBTableFunction.ts +149 -0
- package/vendor/node-api/src/DuckDBTableFunctionBindInfo.ts +56 -0
- package/vendor/node-api/src/DuckDBTableFunctionInfo.ts +36 -0
- package/vendor/node-api/src/DuckDBTableFunctionInitInfo.ts +52 -0
- package/vendor/node-api/src/DuckDBType.ts +1 -0
- package/vendor/node-api/src/DuckDBTypeId.ts +46 -0
- package/vendor/node-api/src/DuckDBValueConverter.ts +23 -0
- package/vendor/node-api/src/DuckDBValueConverters.ts +461 -0
- package/vendor/node-api/src/DuckDBVector.ts +1 -0
- package/vendor/node-api/src/JS.ts +11 -0
- package/vendor/node-api/src/JSDuckDBValueConverter.ts +85 -0
- package/vendor/node-api/src/JSInputTypeForTypeId.ts +101 -0
- package/vendor/node-api/src/JSToDuckDBValueConverter.ts +136 -0
- package/vendor/node-api/src/JSTypeForTypeId.ts +78 -0
- package/vendor/node-api/src/Json.ts +7 -0
- package/vendor/node-api/src/JsonDuckDBValueConverter.ts +72 -0
- package/vendor/node-api/src/JsonTypeForTypeId.ts +86 -0
- package/vendor/node-api/src/ToDuckDBValueConverter.ts +68 -0
- package/vendor/node-api/src/ToDuckDBValueConverters.ts +303 -0
- package/vendor/node-api/src/configurationOptionDescriptions.ts +13 -0
- package/vendor/node-api/src/conversion/bytesFromString.ts +5 -0
- package/vendor/node-api/src/conversion/dateTimeStringConversion.ts +343 -0
- package/vendor/node-api/src/conversion/displayStringForDuckDBValue.ts +12 -0
- package/vendor/node-api/src/conversion/stringFromBlob.ts +48 -0
- package/vendor/node-api/src/conversion/stringFromDecimal.ts +129 -0
- package/vendor/node-api/src/conversion/varintDecode.ts +42 -0
- package/vendor/node-api/src/convertColumnsFromChunks.ts +28 -0
- package/vendor/node-api/src/convertColumnsObjectFromChunks.ts +29 -0
- package/vendor/node-api/src/convertRowObjectsFromChunks.ts +21 -0
- package/vendor/node-api/src/convertRowsFromChunks.ts +16 -0
- package/vendor/node-api/src/createConfig.ts +14 -0
- package/vendor/node-api/src/createDuckDBValueConverter.ts +17 -0
- package/vendor/node-api/src/createResult.ts +15 -0
- package/vendor/node-api/src/createValue.ts +355 -0
- package/vendor/node-api/src/duckdb.ts +51 -0
- package/vendor/node-api/src/enums.ts +7 -0
- package/vendor/node-api/src/getColumnsFromChunks.ts +13 -0
- package/vendor/node-api/src/getColumnsObjectFromChunks.ts +16 -0
- package/vendor/node-api/src/getRowObjectsFromChunks.ts +13 -0
- package/vendor/node-api/src/getRowsFromChunks.ts +12 -0
- package/vendor/node-api/src/index.ts +3 -0
- package/vendor/node-api/src/readValue.ts +31 -0
- package/vendor/node-api/src/sleep.ts +5 -0
- package/vendor/node-api/src/sql.ts +7 -0
- package/vendor/node-api/src/tsconfig.json +7 -0
- package/vendor/node-api/src/typeForValue.ts +144 -0
- package/vendor/node-api/src/types/BaseDuckDBType.ts +31 -0
- package/vendor/node-api/src/types/DuckDBAnyType.ts +13 -0
- package/vendor/node-api/src/types/DuckDBArrayType.ts +43 -0
- package/vendor/node-api/src/types/DuckDBBigIntType.ts +21 -0
- package/vendor/node-api/src/types/DuckDBBigNumType.ts +21 -0
- package/vendor/node-api/src/types/DuckDBBitType.ts +13 -0
- package/vendor/node-api/src/types/DuckDBBlobType.ts +13 -0
- package/vendor/node-api/src/types/DuckDBBooleanType.ts +13 -0
- package/vendor/node-api/src/types/DuckDBDateType.ts +29 -0
- package/vendor/node-api/src/types/DuckDBDecimalType.ts +46 -0
- package/vendor/node-api/src/types/DuckDBDoubleType.ts +21 -0
- package/vendor/node-api/src/types/DuckDBEnumType.ts +111 -0
- package/vendor/node-api/src/types/DuckDBFloatType.ts +21 -0
- package/vendor/node-api/src/types/DuckDBGeometryType.ts +36 -0
- package/vendor/node-api/src/types/DuckDBHugeIntType.ts +21 -0
- package/vendor/node-api/src/types/DuckDBIntegerLiteralType.ts +13 -0
- package/vendor/node-api/src/types/DuckDBIntegerType.ts +21 -0
- package/vendor/node-api/src/types/DuckDBIntervalType.ts +13 -0
- package/vendor/node-api/src/types/DuckDBListType.ts +35 -0
- package/vendor/node-api/src/types/DuckDBMapType.ts +47 -0
- package/vendor/node-api/src/types/DuckDBSQLNullType.ts +17 -0
- package/vendor/node-api/src/types/DuckDBSmallIntType.ts +21 -0
- package/vendor/node-api/src/types/DuckDBStringLiteralType.ts +13 -0
- package/vendor/node-api/src/types/DuckDBStructType.ts +104 -0
- package/vendor/node-api/src/types/DuckDBTimeNSType.ts +20 -0
- package/vendor/node-api/src/types/DuckDBTimeTZType.ts +23 -0
- package/vendor/node-api/src/types/DuckDBTimeType.ts +20 -0
- package/vendor/node-api/src/types/DuckDBTimestampMillisecondsType.ts +29 -0
- package/vendor/node-api/src/types/DuckDBTimestampNanosecondsType.ts +29 -0
- package/vendor/node-api/src/types/DuckDBTimestampSecondsType.ts +29 -0
- package/vendor/node-api/src/types/DuckDBTimestampTZNanosecondsType.ts +32 -0
- package/vendor/node-api/src/types/DuckDBTimestampTZType.ts +32 -0
- package/vendor/node-api/src/types/DuckDBTimestampType.ts +32 -0
- package/vendor/node-api/src/types/DuckDBTinyIntType.ts +21 -0
- package/vendor/node-api/src/types/DuckDBType.ts +86 -0
- package/vendor/node-api/src/types/DuckDBUBigIntType.ts +21 -0
- package/vendor/node-api/src/types/DuckDBUHugeIntType.ts +21 -0
- package/vendor/node-api/src/types/DuckDBUIntegerType.ts +21 -0
- package/vendor/node-api/src/types/DuckDBUSmallIntType.ts +21 -0
- package/vendor/node-api/src/types/DuckDBUTinyIntType.ts +21 -0
- package/vendor/node-api/src/types/DuckDBUUIDType.ts +20 -0
- package/vendor/node-api/src/types/DuckDBUnionType.ts +74 -0
- package/vendor/node-api/src/types/DuckDBVarCharType.ts +13 -0
- package/vendor/node-api/src/types/DuckDBVariantType.ts +13 -0
- package/vendor/node-api/src/types/index.ts +44 -0
- package/vendor/node-api/src/values/DuckDBArrayValue.ts +18 -0
- package/vendor/node-api/src/values/DuckDBBitValue.ts +117 -0
- package/vendor/node-api/src/values/DuckDBBlobValue.ts +26 -0
- package/vendor/node-api/src/values/DuckDBDateValue.ts +43 -0
- package/vendor/node-api/src/values/DuckDBDecimalValue.ts +44 -0
- package/vendor/node-api/src/values/DuckDBGeometryValue.ts +30 -0
- package/vendor/node-api/src/values/DuckDBIntervalValue.ts +22 -0
- package/vendor/node-api/src/values/DuckDBListValue.ts +18 -0
- package/vendor/node-api/src/values/DuckDBMapValue.ts +25 -0
- package/vendor/node-api/src/values/DuckDBStructValue.ts +22 -0
- package/vendor/node-api/src/values/DuckDBTimeNSValue.ts +23 -0
- package/vendor/node-api/src/values/DuckDBTimeTZValue.ts +96 -0
- package/vendor/node-api/src/values/DuckDBTimeValue.ts +34 -0
- package/vendor/node-api/src/values/DuckDBTimestampMillisecondsValue.ts +29 -0
- package/vendor/node-api/src/values/DuckDBTimestampNanosecondsValue.ts +28 -0
- package/vendor/node-api/src/values/DuckDBTimestampSecondsValue.ts +28 -0
- package/vendor/node-api/src/values/DuckDBTimestampTZNanosecondsValue.ts +44 -0
- package/vendor/node-api/src/values/DuckDBTimestampTZValue.ts +54 -0
- package/vendor/node-api/src/values/DuckDBTimestampValue.ts +45 -0
- package/vendor/node-api/src/values/DuckDBTupleValue.ts +22 -0
- package/vendor/node-api/src/values/DuckDBUUIDValue.ts +48 -0
- package/vendor/node-api/src/values/DuckDBUnionValue.ts +22 -0
- package/vendor/node-api/src/values/DuckDBValue.ts +53 -0
- package/vendor/node-api/src/values/DuckDBVariantValue.ts +34 -0
- package/vendor/node-api/src/values/index.ts +24 -0
- package/vendor/node-api/src/vectors/DuckDBArrayVector.ts +107 -0
- package/vendor/node-api/src/vectors/DuckDBBigIntVector.ts +75 -0
- package/vendor/node-api/src/vectors/DuckDBBigNumVector.ts +98 -0
- package/vendor/node-api/src/vectors/DuckDBBitVector.ts +102 -0
- package/vendor/node-api/src/vectors/DuckDBBlobVector.ts +112 -0
- package/vendor/node-api/src/vectors/DuckDBBooleanVector.ts +84 -0
- package/vendor/node-api/src/vectors/DuckDBDateVector.ts +80 -0
- package/vendor/node-api/src/vectors/DuckDBDecimal128Vector.ts +107 -0
- package/vendor/node-api/src/vectors/DuckDBDecimal16Vector.ts +104 -0
- package/vendor/node-api/src/vectors/DuckDBDecimal32Vector.ts +104 -0
- package/vendor/node-api/src/vectors/DuckDBDecimal64Vector.ts +104 -0
- package/vendor/node-api/src/vectors/DuckDBDoubleVector.ts +68 -0
- package/vendor/node-api/src/vectors/DuckDBEnum16Vector.ts +75 -0
- package/vendor/node-api/src/vectors/DuckDBEnum32Vector.ts +75 -0
- package/vendor/node-api/src/vectors/DuckDBEnum8Vector.ts +75 -0
- package/vendor/node-api/src/vectors/DuckDBFloatVector.ts +68 -0
- package/vendor/node-api/src/vectors/DuckDBGeometryVector.ts +97 -0
- package/vendor/node-api/src/vectors/DuckDBHugeIntVector.ts +89 -0
- package/vendor/node-api/src/vectors/DuckDBIntegerVector.ts +75 -0
- package/vendor/node-api/src/vectors/DuckDBIntervalVector.ts +100 -0
- package/vendor/node-api/src/vectors/DuckDBListVector.ts +221 -0
- package/vendor/node-api/src/vectors/DuckDBMapVector.ts +88 -0
- package/vendor/node-api/src/vectors/DuckDBSQLNullVector.ts +53 -0
- package/vendor/node-api/src/vectors/DuckDBSmallIntVector.ts +75 -0
- package/vendor/node-api/src/vectors/DuckDBStructVector.ts +138 -0
- package/vendor/node-api/src/vectors/DuckDBTimeNSVector.ts +80 -0
- package/vendor/node-api/src/vectors/DuckDBTimeTZVector.ts +80 -0
- package/vendor/node-api/src/vectors/DuckDBTimeVector.ts +80 -0
- package/vendor/node-api/src/vectors/DuckDBTimestampMillisecondsVector.ts +88 -0
- package/vendor/node-api/src/vectors/DuckDBTimestampNanosecondsVector.ts +88 -0
- package/vendor/node-api/src/vectors/DuckDBTimestampSecondsVector.ts +88 -0
- package/vendor/node-api/src/vectors/DuckDBTimestampTZNanosecondsVector.ts +88 -0
- package/vendor/node-api/src/vectors/DuckDBTimestampTZVector.ts +86 -0
- package/vendor/node-api/src/vectors/DuckDBTimestampVector.ts +83 -0
- package/vendor/node-api/src/vectors/DuckDBTinyIntVector.ts +75 -0
- package/vendor/node-api/src/vectors/DuckDBTupleVector.ts +125 -0
- package/vendor/node-api/src/vectors/DuckDBUBigIntVector.ts +75 -0
- package/vendor/node-api/src/vectors/DuckDBUHugeIntVector.ts +89 -0
- package/vendor/node-api/src/vectors/DuckDBUIntegerVector.ts +75 -0
- package/vendor/node-api/src/vectors/DuckDBUSmallIntVector.ts +75 -0
- package/vendor/node-api/src/vectors/DuckDBUTinyIntVector.ts +75 -0
- package/vendor/node-api/src/vectors/DuckDBUUIDVector.ts +89 -0
- package/vendor/node-api/src/vectors/DuckDBUnionVector.ts +84 -0
- package/vendor/node-api/src/vectors/DuckDBValidity.ts +104 -0
- package/vendor/node-api/src/vectors/DuckDBVarCharVector.ts +100 -0
- package/vendor/node-api/src/vectors/DuckDBVariantVector.ts +609 -0
- package/vendor/node-api/src/vectors/DuckDBVector.ts +33 -0
- package/vendor/node-api/src/vectors/createVector.ts +269 -0
- package/vendor/node-api/src/vectors/dataAccessors.ts +387 -0
- package/vendor/node-api/src/vectors/index.ts +50 -0
- package/vendor/node-api/src/vectors/vectorRegistry.ts +24 -0
- package/vendor/node-api/src/version.ts +5 -0
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DuckDBArrayType,
|
|
3
|
+
DuckDBDecimalType,
|
|
4
|
+
DuckDBListType,
|
|
5
|
+
DuckDBMapType,
|
|
6
|
+
DuckDBStructType,
|
|
7
|
+
DuckDBType,
|
|
8
|
+
DuckDBUnionType,
|
|
9
|
+
} from './DuckDBType';
|
|
10
|
+
import { ToDuckDBValueConverter } from './ToDuckDBValueConverter';
|
|
11
|
+
import {
|
|
12
|
+
DuckDBBitValue,
|
|
13
|
+
DuckDBBlobValue,
|
|
14
|
+
DuckDBDateValue,
|
|
15
|
+
DuckDBDecimalValue,
|
|
16
|
+
DuckDBGeometryValue,
|
|
17
|
+
DuckDBIntervalValue,
|
|
18
|
+
DuckDBTimeNSValue,
|
|
19
|
+
DuckDBTimeTZValue,
|
|
20
|
+
DuckDBTimeValue,
|
|
21
|
+
DuckDBTimestampMillisecondsValue,
|
|
22
|
+
DuckDBTimestampNanosecondsValue,
|
|
23
|
+
DuckDBTimestampSecondsValue,
|
|
24
|
+
DuckDBTimestampTZValue,
|
|
25
|
+
DuckDBTimestampTZNanosecondsValue,
|
|
26
|
+
DuckDBTimestampValue,
|
|
27
|
+
DuckDBUUIDValue,
|
|
28
|
+
DuckDBValue,
|
|
29
|
+
DuckDBVariantValue,
|
|
30
|
+
arrayValue,
|
|
31
|
+
listValue,
|
|
32
|
+
mapValue,
|
|
33
|
+
structValue,
|
|
34
|
+
tupleValue,
|
|
35
|
+
unionValue,
|
|
36
|
+
variantValue,
|
|
37
|
+
} from './values';
|
|
38
|
+
|
|
39
|
+
const MILLIS_PER_DAY = 24 * 60 * 60 * 1000;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* The epoch milliseconds of `value`, refusing an Invalid Date.
|
|
43
|
+
*
|
|
44
|
+
* Without this, DATE turns NaN into a `DuckDBDateValue(NaN)` and hands it back,
|
|
45
|
+
* while the timestamps reach `BigInt(NaN)` and throw "The number NaN cannot be
|
|
46
|
+
* converted to a BigInt" — neither of which names the real problem.
|
|
47
|
+
*/
|
|
48
|
+
function millisFromDate(value: Date): number {
|
|
49
|
+
const millis = value.getTime();
|
|
50
|
+
if (Number.isNaN(millis)) {
|
|
51
|
+
throw new Error(`Cannot convert an Invalid Date`);
|
|
52
|
+
}
|
|
53
|
+
return millis;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export function unwritableConverter(_: unknown, type: DuckDBType): never {
|
|
57
|
+
throw new Error(`Cannot write values of type: ${type}`);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function nullFromNull(): null {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function valueFromBoolean(value: boolean): boolean {
|
|
65
|
+
return Boolean(value);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export function valueFromNumber(value: number): number {
|
|
69
|
+
return value;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function bigintFromNumeric(value: bigint | number): bigint {
|
|
73
|
+
return typeof value === 'bigint' ? value : BigInt(value);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export function valueFromString(value: string): string {
|
|
77
|
+
return value;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export function blobValueFromBytes(value: Uint8Array): DuckDBBlobValue {
|
|
81
|
+
return new DuckDBBlobValue(value);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export function bitValueFromBytes(value: Uint8Array): DuckDBBitValue {
|
|
85
|
+
return new DuckDBBitValue(value);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export function geometryValueFromBytes(value: Uint8Array): DuckDBGeometryValue {
|
|
89
|
+
return new DuckDBGeometryValue(value);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export function dateValueFromDate(value: Date): DuckDBDateValue {
|
|
93
|
+
// A DATE has no time component; the reader produces midnight UTC, so this is
|
|
94
|
+
// exact for a round trip and truncates toward the earlier day otherwise.
|
|
95
|
+
return new DuckDBDateValue(Math.floor(millisFromDate(value) / MILLIS_PER_DAY));
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export function timeValueFromMicros(value: bigint): DuckDBTimeValue {
|
|
99
|
+
return new DuckDBTimeValue(value);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export function timeNSValueFromNanos(value: bigint): DuckDBTimeNSValue {
|
|
103
|
+
return new DuckDBTimeNSValue(value);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export function timeTZValueFromObject(value: {
|
|
107
|
+
micros: bigint;
|
|
108
|
+
offset: number;
|
|
109
|
+
}): DuckDBTimeTZValue {
|
|
110
|
+
return DuckDBTimeTZValue.fromMicrosAndOffset(value.micros, value.offset);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export function timestampValueFromDate(value: Date): DuckDBTimestampValue {
|
|
114
|
+
return new DuckDBTimestampValue(BigInt(millisFromDate(value)) * 1000n);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export function timestampTZValueFromDate(value: Date): DuckDBTimestampTZValue {
|
|
118
|
+
return new DuckDBTimestampTZValue(BigInt(millisFromDate(value)) * 1000n);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export function timestampTZNanosValueFromDate(
|
|
122
|
+
value: Date
|
|
123
|
+
): DuckDBTimestampTZNanosecondsValue {
|
|
124
|
+
return new DuckDBTimestampTZNanosecondsValue(
|
|
125
|
+
BigInt(millisFromDate(value)) * 1000000n
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export function timestampSecondsValueFromDate(
|
|
130
|
+
value: Date
|
|
131
|
+
): DuckDBTimestampSecondsValue {
|
|
132
|
+
return new DuckDBTimestampSecondsValue(
|
|
133
|
+
BigInt(Math.floor(millisFromDate(value) / 1000))
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export function timestampMillisValueFromDate(
|
|
138
|
+
value: Date
|
|
139
|
+
): DuckDBTimestampMillisecondsValue {
|
|
140
|
+
return new DuckDBTimestampMillisecondsValue(BigInt(millisFromDate(value)));
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export function timestampNanosValueFromDate(
|
|
144
|
+
value: Date
|
|
145
|
+
): DuckDBTimestampNanosecondsValue {
|
|
146
|
+
return new DuckDBTimestampNanosecondsValue(
|
|
147
|
+
BigInt(millisFromDate(value)) * 1000000n
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export function intervalValueFromObject(value: {
|
|
152
|
+
months: number;
|
|
153
|
+
days: number;
|
|
154
|
+
micros: bigint;
|
|
155
|
+
}): DuckDBIntervalValue {
|
|
156
|
+
return new DuckDBIntervalValue(value.months, value.days, value.micros);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export function decimalValueFromNumeric(
|
|
160
|
+
value: number | bigint,
|
|
161
|
+
type: DuckDBType
|
|
162
|
+
): DuckDBDecimalValue {
|
|
163
|
+
if (!(type instanceof DuckDBDecimalType)) {
|
|
164
|
+
throw new Error(`Expected DuckDBDecimalType`);
|
|
165
|
+
}
|
|
166
|
+
return typeof value === 'bigint'
|
|
167
|
+
? new DuckDBDecimalValue(value, type.width, type.scale)
|
|
168
|
+
: DuckDBDecimalValue.fromDouble(value, type.width, type.scale);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
const UUID_PATTERN =
|
|
172
|
+
/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
173
|
+
|
|
174
|
+
export function uuidValueFromString(value: string): DuckDBUUIDValue {
|
|
175
|
+
if (!UUID_PATTERN.test(value)) {
|
|
176
|
+
throw new Error(`Not a UUID string: ${value}`);
|
|
177
|
+
}
|
|
178
|
+
return DuckDBUUIDValue.fromUint128(BigInt(`0x${value.replace(/-/g, '')}`));
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export function listValueFromArray<T>(
|
|
182
|
+
value: readonly T[],
|
|
183
|
+
type: DuckDBType,
|
|
184
|
+
converter: ToDuckDBValueConverter<T>
|
|
185
|
+
): DuckDBValue {
|
|
186
|
+
if (!(type instanceof DuckDBListType)) {
|
|
187
|
+
throw new Error(`Expected DuckDBListType`);
|
|
188
|
+
}
|
|
189
|
+
return listValue(
|
|
190
|
+
value.map((item) => converter(item, type.valueType, converter))
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
export function arrayValueFromArray<T>(
|
|
195
|
+
value: readonly T[],
|
|
196
|
+
type: DuckDBType,
|
|
197
|
+
converter: ToDuckDBValueConverter<T>
|
|
198
|
+
): DuckDBValue {
|
|
199
|
+
if (!(type instanceof DuckDBArrayType)) {
|
|
200
|
+
throw new Error(`Expected DuckDBArrayType`);
|
|
201
|
+
}
|
|
202
|
+
if (value.length !== type.length) {
|
|
203
|
+
throw new Error(
|
|
204
|
+
`Expected ${type.length} items for ${type}, got ${value.length}`
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
return arrayValue(
|
|
208
|
+
value.map((item) => converter(item, type.valueType, converter))
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Converts an object keyed by entry name to a named STRUCT value, or an array
|
|
214
|
+
* of items to a tuple value (see `DuckDBStructType.isTuple`).
|
|
215
|
+
*/
|
|
216
|
+
export function structValueFromObject<T>(
|
|
217
|
+
value: Readonly<Record<string, T>> | readonly T[],
|
|
218
|
+
type: DuckDBType,
|
|
219
|
+
converter: ToDuckDBValueConverter<T>
|
|
220
|
+
): DuckDBValue {
|
|
221
|
+
if (!(type instanceof DuckDBStructType)) {
|
|
222
|
+
throw new Error(`Expected DuckDBStructType`);
|
|
223
|
+
}
|
|
224
|
+
if (type.isTuple) {
|
|
225
|
+
if (!Array.isArray(value)) {
|
|
226
|
+
throw new Error(`Expected an array for ${type}`);
|
|
227
|
+
}
|
|
228
|
+
if (value.length !== type.entryCount) {
|
|
229
|
+
throw new Error(
|
|
230
|
+
`Expected ${type.entryCount} items for ${type}, got ${value.length}`
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
return tupleValue(
|
|
234
|
+
value.map((item, i) => converter(item, type.entryTypes[i], converter))
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
if (Array.isArray(value)) {
|
|
238
|
+
throw new Error(`Expected an object for ${type}`);
|
|
239
|
+
}
|
|
240
|
+
const entryValues = value as Readonly<Record<string, T>>;
|
|
241
|
+
const entries: Record<string, DuckDBValue> = {};
|
|
242
|
+
for (const key of type.entryNames) {
|
|
243
|
+
if (!(key in entryValues)) {
|
|
244
|
+
throw new Error(`Missing entry for struct key: ${key}`);
|
|
245
|
+
}
|
|
246
|
+
entries[key] = converter(
|
|
247
|
+
entryValues[key],
|
|
248
|
+
type.typeForEntry(key),
|
|
249
|
+
converter
|
|
250
|
+
);
|
|
251
|
+
}
|
|
252
|
+
return structValue(entries);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
export function mapValueFromEntries<T>(
|
|
256
|
+
value: readonly { key: T; value: T }[],
|
|
257
|
+
type: DuckDBType,
|
|
258
|
+
converter: ToDuckDBValueConverter<T>
|
|
259
|
+
): DuckDBValue {
|
|
260
|
+
if (!(type instanceof DuckDBMapType)) {
|
|
261
|
+
throw new Error(`Expected DuckDBMapType`);
|
|
262
|
+
}
|
|
263
|
+
return mapValue(
|
|
264
|
+
value.map((entry) => ({
|
|
265
|
+
key: converter(entry.key, type.keyType, converter),
|
|
266
|
+
value: converter(entry.value, type.valueType, converter),
|
|
267
|
+
}))
|
|
268
|
+
);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
export function unionValueFromObject<T>(
|
|
272
|
+
value: { tag: string; value: T },
|
|
273
|
+
type: DuckDBType,
|
|
274
|
+
converter: ToDuckDBValueConverter<T>
|
|
275
|
+
): DuckDBValue {
|
|
276
|
+
if (!(type instanceof DuckDBUnionType)) {
|
|
277
|
+
throw new Error(`Expected DuckDBUnionType`);
|
|
278
|
+
}
|
|
279
|
+
// memberTypeForTag indexes by tag and returns undefined for one it does not
|
|
280
|
+
// have, which would reach the dispatch as an undefined type. Unlike the read
|
|
281
|
+
// path, where the tag comes from a decoded value, here it is caller input.
|
|
282
|
+
if (!(value.tag in type.tagMemberIndexes)) {
|
|
283
|
+
throw new Error(
|
|
284
|
+
`Tag ${JSON.stringify(value.tag)} is not a member of ${type}`
|
|
285
|
+
);
|
|
286
|
+
}
|
|
287
|
+
return unionValue(
|
|
288
|
+
value.tag,
|
|
289
|
+
converter(value.value, type.memberTypeForTag(value.tag), converter)
|
|
290
|
+
);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* A VARIANT carries the type of the value inside it, so writing one means
|
|
295
|
+
* saying what that type is. A `DuckDBVariantValue` already does — pass it
|
|
296
|
+
* through. A bare scalar does not, but is unambiguous enough for
|
|
297
|
+
* `typeForValue` to infer downstream, so wrap it.
|
|
298
|
+
*/
|
|
299
|
+
export function variantValueFromJS(
|
|
300
|
+
value: DuckDBVariantValue | boolean | number | bigint | string
|
|
301
|
+
): DuckDBVariantValue {
|
|
302
|
+
return value instanceof DuckDBVariantValue ? value : variantValue(value);
|
|
303
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import duckdb from "../../../src/bindings/index.ts";
|
|
2
|
+
|
|
3
|
+
export function configurationOptionDescriptions(): Readonly<
|
|
4
|
+
Record<string, string>
|
|
5
|
+
> {
|
|
6
|
+
const descriptions: Record<string, string> = {};
|
|
7
|
+
const count = duckdb.config_count();
|
|
8
|
+
for (let i = 0; i < count; i++) {
|
|
9
|
+
const { name, description } = duckdb.get_config_flag(i);
|
|
10
|
+
descriptions[name] = description;
|
|
11
|
+
}
|
|
12
|
+
return descriptions;
|
|
13
|
+
}
|
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
const DAYS_IN_400_YEARS = 146097; // (((365 * 4 + 1) * 25) - 1) * 4 + 1
|
|
2
|
+
const MILLISECONDS_PER_DAY_NUM = 86400000; // 1000 * 60 * 60 * 24
|
|
3
|
+
|
|
4
|
+
const MICROSECONDS_PER_SECOND = 1000000n;
|
|
5
|
+
const MICROSECONDS_PER_MILLISECOND = 1000n;
|
|
6
|
+
const NANOSECONDS_PER_SECOND = 1000000000n;
|
|
7
|
+
const SECONDS_PER_MINUTE = 60n;
|
|
8
|
+
const MINUTES_PER_HOUR = 60n;
|
|
9
|
+
const MICROSECONDS_PER_DAY = 86400000000n; // 24 * 60 * 60 * 1000000
|
|
10
|
+
const NANOSECONDS_PER_DAY = 86400000000000n; // 24 * 60 * 60 * 1000000000
|
|
11
|
+
|
|
12
|
+
const NEGATIVE_INFINITY_TIMESTAMP = -9223372036854775807n; // -(2^63-1)
|
|
13
|
+
const POSITIVE_INFINITY_TIMESTAMP = 9223372036854775807n; // 2^63-1
|
|
14
|
+
|
|
15
|
+
export function getDuckDBDateStringFromYearMonthDay(
|
|
16
|
+
year: number,
|
|
17
|
+
month: number,
|
|
18
|
+
dayOfMonth: number
|
|
19
|
+
): string {
|
|
20
|
+
const yearStr = String(Math.abs(year)).padStart(4, '0');
|
|
21
|
+
const monthStr = String(month).padStart(2, '0');
|
|
22
|
+
const dayOfMonthStr = String(dayOfMonth).padStart(2, '0');
|
|
23
|
+
return `${yearStr}-${monthStr}-${dayOfMonthStr}${year < 0 ? ' (BC)' : ''}`;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function getDuckDBDateStringFromDays(days: number): string {
|
|
27
|
+
const absDays = Math.abs(days);
|
|
28
|
+
const sign = days < 0 ? -1 : 1;
|
|
29
|
+
// 400 years is the shortest interval with a fixed number of days. (Leap years and different length months can result
|
|
30
|
+
// in shorter intervals having different number of days.) By separating the number of 400 year intervals from the
|
|
31
|
+
// interval covered by the remaining days, we can guarantee that the date resulting from shifting the epoch by the
|
|
32
|
+
// remaining interval is within the valid range of the JS Date object. This allows us to use JS Date to calculate the
|
|
33
|
+
// year, month, and day of month for the date represented by the remaining interval, thus accounting for leap years
|
|
34
|
+
// and different length months. We can then safely add back the years from the 400 year intervals, because the month
|
|
35
|
+
// and day of month won't change when a date is shifted by a whole number of such intervals.
|
|
36
|
+
const num400YearIntervals = Math.floor(absDays / DAYS_IN_400_YEARS);
|
|
37
|
+
const yearsFrom400YearIntervals = sign * num400YearIntervals * 400;
|
|
38
|
+
const absDaysFromRemainingInterval = absDays % DAYS_IN_400_YEARS;
|
|
39
|
+
const millisecondsFromRemainingInterval =
|
|
40
|
+
sign * absDaysFromRemainingInterval * MILLISECONDS_PER_DAY_NUM;
|
|
41
|
+
const date = new Date(millisecondsFromRemainingInterval);
|
|
42
|
+
let year = yearsFrom400YearIntervals + date.getUTCFullYear();
|
|
43
|
+
if (year <= 0) {
|
|
44
|
+
year--; // correct for non-existence of year zero
|
|
45
|
+
}
|
|
46
|
+
const month = date.getUTCMonth() + 1; // getUTCMonth returns zero-indexed month, but we want a one-index month for display
|
|
47
|
+
const dayOfMonth = date.getUTCDate(); // getUTCDate returns one-indexed day-of-month
|
|
48
|
+
return getDuckDBDateStringFromYearMonthDay(year, month, dayOfMonth);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function getTimezoneOffsetString(
|
|
52
|
+
timezoneOffsetInMinutes?: number
|
|
53
|
+
): string | undefined {
|
|
54
|
+
if (timezoneOffsetInMinutes === undefined) {
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
const negative = timezoneOffsetInMinutes < 0;
|
|
58
|
+
const positiveMinutes = Math.abs(timezoneOffsetInMinutes);
|
|
59
|
+
const minutesPart = positiveMinutes % 60;
|
|
60
|
+
const hoursPart = Math.floor(positiveMinutes / 60);
|
|
61
|
+
const minutesStr =
|
|
62
|
+
minutesPart !== 0 ? String(minutesPart).padStart(2, '0') : '';
|
|
63
|
+
const hoursStr = String(hoursPart).padStart(2, '0');
|
|
64
|
+
return `${negative ? '-' : '+'}${hoursStr}${
|
|
65
|
+
minutesStr ? `:${minutesStr}` : ''
|
|
66
|
+
}`;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export function getAbsoluteOffsetStringFromParts(
|
|
70
|
+
hoursPart: number,
|
|
71
|
+
minutesPart: number,
|
|
72
|
+
secondsPart: number
|
|
73
|
+
): string {
|
|
74
|
+
const hoursStr = String(hoursPart).padStart(2, '0');
|
|
75
|
+
const minutesStr =
|
|
76
|
+
minutesPart !== 0 || secondsPart !== 0
|
|
77
|
+
? String(minutesPart).padStart(2, '0')
|
|
78
|
+
: '';
|
|
79
|
+
const secondsStr =
|
|
80
|
+
secondsPart !== 0 ? String(secondsPart).padStart(2, '0') : '';
|
|
81
|
+
let result = hoursStr;
|
|
82
|
+
if (minutesStr) {
|
|
83
|
+
result += `:${minutesStr}`;
|
|
84
|
+
if (secondsStr) {
|
|
85
|
+
result += `:${secondsStr}`;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return result;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export function getOffsetStringFromAbsoluteSeconds(
|
|
92
|
+
absoluteOffsetInSeconds: number
|
|
93
|
+
): string {
|
|
94
|
+
const secondsPart = absoluteOffsetInSeconds % 60;
|
|
95
|
+
const minutes = Math.floor(absoluteOffsetInSeconds / 60);
|
|
96
|
+
const minutesPart = minutes % 60;
|
|
97
|
+
const hoursPart = Math.floor(minutes / 60);
|
|
98
|
+
return getAbsoluteOffsetStringFromParts(hoursPart, minutesPart, secondsPart);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export function getOffsetStringFromSeconds(offsetInSeconds: number): string {
|
|
102
|
+
const negative = offsetInSeconds < 0;
|
|
103
|
+
const absoluteOffsetInSeconds = negative ? -offsetInSeconds : offsetInSeconds;
|
|
104
|
+
const absoluteString = getOffsetStringFromAbsoluteSeconds(
|
|
105
|
+
absoluteOffsetInSeconds
|
|
106
|
+
);
|
|
107
|
+
return `${negative ? '-' : '+'}${absoluteString}`;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export function getDuckDBTimeStringFromParts(
|
|
111
|
+
hoursPart: bigint,
|
|
112
|
+
minutesPart: bigint,
|
|
113
|
+
secondsPart: bigint,
|
|
114
|
+
microsecondsPart: bigint
|
|
115
|
+
): string {
|
|
116
|
+
const hoursStr = String(hoursPart).padStart(2, '0');
|
|
117
|
+
const minutesStr = String(minutesPart).padStart(2, '0');
|
|
118
|
+
const secondsStr = String(secondsPart).padStart(2, '0');
|
|
119
|
+
const microsecondsStr = String(microsecondsPart)
|
|
120
|
+
.padStart(6, '0')
|
|
121
|
+
.replace(/0+$/, '');
|
|
122
|
+
return `${hoursStr}:${minutesStr}:${secondsStr}${
|
|
123
|
+
microsecondsStr.length > 0 ? `.${microsecondsStr}` : ''
|
|
124
|
+
}`;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export function getDuckDBTimeStringFromPartsNS(
|
|
128
|
+
hoursPart: bigint,
|
|
129
|
+
minutesPart: bigint,
|
|
130
|
+
secondsPart: bigint,
|
|
131
|
+
nanosecondsPart: bigint
|
|
132
|
+
): string {
|
|
133
|
+
const hoursStr = String(hoursPart).padStart(2, '0');
|
|
134
|
+
const minutesStr = String(minutesPart).padStart(2, '0');
|
|
135
|
+
const secondsStr = String(secondsPart).padStart(2, '0');
|
|
136
|
+
const nanosecondsStr = String(nanosecondsPart)
|
|
137
|
+
.padStart(9, '0')
|
|
138
|
+
.replace(/0+$/, '');
|
|
139
|
+
return `${hoursStr}:${minutesStr}:${secondsStr}${
|
|
140
|
+
nanosecondsStr.length > 0 ? `.${nanosecondsStr}` : ''
|
|
141
|
+
}`;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export function getDuckDBTimeStringFromPositiveMicroseconds(
|
|
145
|
+
positiveMicroseconds: bigint
|
|
146
|
+
): string {
|
|
147
|
+
const microsecondsPart = positiveMicroseconds % MICROSECONDS_PER_SECOND;
|
|
148
|
+
const seconds = positiveMicroseconds / MICROSECONDS_PER_SECOND;
|
|
149
|
+
const secondsPart = seconds % SECONDS_PER_MINUTE;
|
|
150
|
+
const minutes = seconds / SECONDS_PER_MINUTE;
|
|
151
|
+
const minutesPart = minutes % MINUTES_PER_HOUR;
|
|
152
|
+
const hoursPart = minutes / MINUTES_PER_HOUR;
|
|
153
|
+
return getDuckDBTimeStringFromParts(
|
|
154
|
+
hoursPart,
|
|
155
|
+
minutesPart,
|
|
156
|
+
secondsPart,
|
|
157
|
+
microsecondsPart
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export function getDuckDBTimeStringFromPositiveNanoseconds(
|
|
162
|
+
positiveNanoseconds: bigint
|
|
163
|
+
): string {
|
|
164
|
+
const nanosecondsPart = positiveNanoseconds % NANOSECONDS_PER_SECOND;
|
|
165
|
+
const seconds = positiveNanoseconds / NANOSECONDS_PER_SECOND;
|
|
166
|
+
const secondsPart = seconds % SECONDS_PER_MINUTE;
|
|
167
|
+
const minutes = seconds / SECONDS_PER_MINUTE;
|
|
168
|
+
const minutesPart = minutes % MINUTES_PER_HOUR;
|
|
169
|
+
const hoursPart = minutes / MINUTES_PER_HOUR;
|
|
170
|
+
return getDuckDBTimeStringFromPartsNS(
|
|
171
|
+
hoursPart,
|
|
172
|
+
minutesPart,
|
|
173
|
+
secondsPart,
|
|
174
|
+
nanosecondsPart
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export function getDuckDBTimeStringFromMicrosecondsInDay(
|
|
179
|
+
microsecondsInDay: bigint
|
|
180
|
+
): string {
|
|
181
|
+
const positiveMicroseconds =
|
|
182
|
+
microsecondsInDay < 0
|
|
183
|
+
? microsecondsInDay + MICROSECONDS_PER_DAY
|
|
184
|
+
: microsecondsInDay;
|
|
185
|
+
return getDuckDBTimeStringFromPositiveMicroseconds(positiveMicroseconds);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
export function getDuckDBTimeStringFromNanosecondsInDay(
|
|
189
|
+
nanosecondsInDay: bigint
|
|
190
|
+
): string {
|
|
191
|
+
const positiveNanoseconds =
|
|
192
|
+
nanosecondsInDay < 0
|
|
193
|
+
? nanosecondsInDay + NANOSECONDS_PER_DAY
|
|
194
|
+
: nanosecondsInDay;
|
|
195
|
+
return getDuckDBTimeStringFromPositiveNanoseconds(positiveNanoseconds);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
export function getDuckDBTimeStringFromMicroseconds(
|
|
199
|
+
microseconds: bigint
|
|
200
|
+
): string {
|
|
201
|
+
const negative = microseconds < 0;
|
|
202
|
+
const positiveMicroseconds = negative ? -microseconds : microseconds;
|
|
203
|
+
const positiveString =
|
|
204
|
+
getDuckDBTimeStringFromPositiveMicroseconds(positiveMicroseconds);
|
|
205
|
+
return negative ? `-${positiveString}` : positiveString;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
export function getDuckDBTimestampStringFromDaysAndMicroseconds(
|
|
209
|
+
days: bigint,
|
|
210
|
+
microsecondsInDay: bigint,
|
|
211
|
+
timezonePart?: string
|
|
212
|
+
): string {
|
|
213
|
+
// This conversion of BigInt to Number is safe, because the largest absolute value that `days` can has is 106751991,
|
|
214
|
+
// which fits without loss of precision in a JS Number. (106751991 = (2^63-1) / MICROSECONDS_PER_DAY)
|
|
215
|
+
const dateStr = getDuckDBDateStringFromDays(Number(days));
|
|
216
|
+
const timeStr = getDuckDBTimeStringFromMicrosecondsInDay(microsecondsInDay);
|
|
217
|
+
return `${dateStr} ${timeStr}${timezonePart ?? ''}`;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
export function getDuckDBTimestampStringFromDaysAndNanoseconds(
|
|
221
|
+
days: bigint,
|
|
222
|
+
nanosecondsInDay: bigint,
|
|
223
|
+
timezonePart?: string
|
|
224
|
+
): string {
|
|
225
|
+
// This conversion of BigInt to Number is safe, because the largest absolute value that `days` can has is 106751
|
|
226
|
+
// which fits without loss of precision in a JS Number. (106751 = (2^63-1) / NANOSECONDS_PER_DAY)
|
|
227
|
+
const dateStr = getDuckDBDateStringFromDays(Number(days));
|
|
228
|
+
const timeStr = getDuckDBTimeStringFromNanosecondsInDay(nanosecondsInDay);
|
|
229
|
+
return `${dateStr} ${timeStr}${timezonePart ?? ''}`;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
export function getDuckDBTimestampStringFromMicroseconds(
|
|
233
|
+
microseconds: bigint,
|
|
234
|
+
timezoneOffsetInMinutes?: number
|
|
235
|
+
): string {
|
|
236
|
+
// Note that -infinity and infinity are only representable in TIMESTAMP (and TIMESTAMPTZ), not the other timestamp
|
|
237
|
+
// variants. This is by-design and matches DuckDB.
|
|
238
|
+
if (microseconds === NEGATIVE_INFINITY_TIMESTAMP) {
|
|
239
|
+
return '-infinity';
|
|
240
|
+
}
|
|
241
|
+
if (microseconds === POSITIVE_INFINITY_TIMESTAMP) {
|
|
242
|
+
return 'infinity';
|
|
243
|
+
}
|
|
244
|
+
const offsetMicroseconds =
|
|
245
|
+
timezoneOffsetInMinutes !== undefined
|
|
246
|
+
? microseconds +
|
|
247
|
+
BigInt(timezoneOffsetInMinutes) *
|
|
248
|
+
MICROSECONDS_PER_SECOND *
|
|
249
|
+
SECONDS_PER_MINUTE
|
|
250
|
+
: microseconds;
|
|
251
|
+
let days = offsetMicroseconds / MICROSECONDS_PER_DAY;
|
|
252
|
+
let microsecondsPart = offsetMicroseconds % MICROSECONDS_PER_DAY;
|
|
253
|
+
if (microsecondsPart < 0) {
|
|
254
|
+
days--;
|
|
255
|
+
microsecondsPart += MICROSECONDS_PER_DAY;
|
|
256
|
+
}
|
|
257
|
+
return getDuckDBTimestampStringFromDaysAndMicroseconds(
|
|
258
|
+
days,
|
|
259
|
+
microsecondsPart,
|
|
260
|
+
getTimezoneOffsetString(timezoneOffsetInMinutes)
|
|
261
|
+
);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
export function getDuckDBTimestampStringFromSeconds(seconds: bigint): string {
|
|
265
|
+
return getDuckDBTimestampStringFromMicroseconds(
|
|
266
|
+
seconds * MICROSECONDS_PER_SECOND
|
|
267
|
+
);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
export function getDuckDBTimestampStringFromMilliseconds(
|
|
271
|
+
milliseconds: bigint
|
|
272
|
+
): string {
|
|
273
|
+
return getDuckDBTimestampStringFromMicroseconds(
|
|
274
|
+
milliseconds * MICROSECONDS_PER_MILLISECOND
|
|
275
|
+
);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
export function getDuckDBTimestampStringFromNanoseconds(
|
|
279
|
+
nanoseconds: bigint,
|
|
280
|
+
timezoneOffsetInMinutes?: number
|
|
281
|
+
): string {
|
|
282
|
+
// TIMESTAMP_NS and TIMESTAMPTZ_NS use the same infinity values as TIMESTAMP.
|
|
283
|
+
if (nanoseconds === NEGATIVE_INFINITY_TIMESTAMP) {
|
|
284
|
+
return '-infinity';
|
|
285
|
+
}
|
|
286
|
+
if (nanoseconds === POSITIVE_INFINITY_TIMESTAMP) {
|
|
287
|
+
return 'infinity';
|
|
288
|
+
}
|
|
289
|
+
const offsetNanoseconds =
|
|
290
|
+
timezoneOffsetInMinutes !== undefined
|
|
291
|
+
? nanoseconds +
|
|
292
|
+
BigInt(timezoneOffsetInMinutes) *
|
|
293
|
+
NANOSECONDS_PER_SECOND *
|
|
294
|
+
SECONDS_PER_MINUTE
|
|
295
|
+
: nanoseconds;
|
|
296
|
+
let days = offsetNanoseconds / NANOSECONDS_PER_DAY;
|
|
297
|
+
let nanosecondsPart = offsetNanoseconds % NANOSECONDS_PER_DAY;
|
|
298
|
+
if (nanosecondsPart < 0) {
|
|
299
|
+
days--;
|
|
300
|
+
nanosecondsPart += NANOSECONDS_PER_DAY;
|
|
301
|
+
}
|
|
302
|
+
return getDuckDBTimestampStringFromDaysAndNanoseconds(
|
|
303
|
+
days,
|
|
304
|
+
nanosecondsPart,
|
|
305
|
+
getTimezoneOffsetString(timezoneOffsetInMinutes)
|
|
306
|
+
);
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// Assumes baseUnit can be pluralized by adding an 's'.
|
|
310
|
+
function numberAndUnit(value: number, baseUnit: string): string {
|
|
311
|
+
return `${value} ${baseUnit}${Math.abs(value) !== 1 ? 's' : ''}`;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
export function getDuckDBIntervalString(
|
|
315
|
+
months: number,
|
|
316
|
+
days: number,
|
|
317
|
+
microseconds: bigint
|
|
318
|
+
): string {
|
|
319
|
+
const parts: string[] = [];
|
|
320
|
+
if (months !== 0) {
|
|
321
|
+
const sign = months < 0 ? -1 : 1;
|
|
322
|
+
const absMonths = Math.abs(months);
|
|
323
|
+
const absYears = Math.floor(absMonths / 12);
|
|
324
|
+
const years = sign * absYears;
|
|
325
|
+
const extraMonths = sign * (absMonths - absYears * 12);
|
|
326
|
+
if (years !== 0) {
|
|
327
|
+
parts.push(numberAndUnit(years, 'year'));
|
|
328
|
+
}
|
|
329
|
+
if (extraMonths !== 0) {
|
|
330
|
+
parts.push(numberAndUnit(extraMonths, 'month'));
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
if (days !== 0) {
|
|
334
|
+
parts.push(numberAndUnit(days, 'day'));
|
|
335
|
+
}
|
|
336
|
+
if (microseconds !== 0n) {
|
|
337
|
+
parts.push(getDuckDBTimeStringFromMicroseconds(microseconds));
|
|
338
|
+
}
|
|
339
|
+
if (parts.length > 0) {
|
|
340
|
+
return parts.join(' ');
|
|
341
|
+
}
|
|
342
|
+
return '00:00:00';
|
|
343
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { quotedString } from '../sql';
|
|
2
|
+
import { DuckDBValue } from '../values';
|
|
3
|
+
|
|
4
|
+
export function displayStringForDuckDBValue(value: DuckDBValue): string {
|
|
5
|
+
if (value == null) {
|
|
6
|
+
return 'NULL';
|
|
7
|
+
}
|
|
8
|
+
if (typeof value === 'string') {
|
|
9
|
+
return quotedString(value);
|
|
10
|
+
}
|
|
11
|
+
return value.toString();
|
|
12
|
+
}
|