@minnowdb/core 0.7.0 → 0.7.2
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/dist/block-format/block.js +254 -325
- package/dist/block-format/checksum.js +30 -52
- package/dist/block-format/codecs.js +112 -125
- package/dist/block-format/column.js +187 -205
- package/dist/block-format/index.js +5 -1
- package/dist/block-format/physical.js +371 -387
- package/dist/block-format/types.js +4 -1
- package/dist/block-format/unicode.js +30 -39
- package/dist/date-value.js +67 -78
- package/dist/engine/artifact-cache.js +106 -116
- package/dist/engine/batch.js +36 -44
- package/dist/engine/buffered-writer.js +156 -158
- package/dist/engine/byte-estimates.js +20 -22
- package/dist/engine/cache-limits.js +24 -25
- package/dist/engine/cancellation.js +5 -3
- package/dist/engine/catalog.js +64 -73
- package/dist/engine/client.js +715 -780
- package/dist/engine/database.js +15942 -19313
- package/dist/engine/defaults.js +104 -111
- package/dist/engine/errors.js +113 -128
- package/dist/engine/fts.js +233 -280
- package/dist/engine/group-index.js +287 -321
- package/dist/engine/index.js +23 -12
- package/dist/engine/join-index.js +177 -186
- package/dist/engine/keyed-live.js +168 -173
- package/dist/engine/live-api.js +0 -1
- package/dist/engine/live-equal.js +32 -37
- package/dist/engine/live.js +603 -647
- package/dist/engine/memory.js +109 -111
- package/dist/engine/optimizer.d.ts +19 -1
- package/dist/engine/optimizer.js +2691 -2933
- package/dist/engine/point-read.js +122 -182
- package/dist/engine/query-api.js +12 -3
- package/dist/engine/query-cache.js +61 -69
- package/dist/engine/query.d.ts +6 -0
- package/dist/engine/query.js +8511 -9980
- package/dist/engine/result-wire.js +221 -252
- package/dist/engine/schema-wire.js +97 -112
- package/dist/engine/schema.js +1099 -1254
- package/dist/engine/sort-keys.js +315 -389
- package/dist/engine/sql-domains.js +646 -769
- package/dist/engine/sql-driver.js +0 -1
- package/dist/engine/sql-functions.js +1031 -1125
- package/dist/engine/sql-json.js +199 -218
- package/dist/engine/sql-semantics.js +572 -639
- package/dist/engine/typed-live.js +271 -293
- package/dist/engine/vector.js +4484 -5145
- package/dist/engine/worker-host.d.ts +8 -63
- package/dist/engine/worker-host.js +28 -1130
- package/dist/engine/worker-indexeddb.d.ts +1 -0
- package/dist/engine/worker-indexeddb.js +3 -0
- package/dist/engine/worker-memory.d.ts +1 -0
- package/dist/engine/worker-memory.js +3 -0
- package/dist/engine/worker-opfs.d.ts +1 -0
- package/dist/engine/worker-opfs.js +3 -0
- package/dist/engine/worker-server.d.ts +93 -0
- package/dist/engine/worker-server.js +999 -0
- package/dist/engine/worker-store-indexeddb.d.ts +2 -0
- package/dist/engine/worker-store-indexeddb.js +11 -0
- package/dist/engine/worker-store-memory.d.ts +2 -0
- package/dist/engine/worker-store-memory.js +6 -0
- package/dist/engine/worker-store-opfs.d.ts +2 -0
- package/dist/engine/worker-store-opfs.js +9 -0
- package/dist/engine/worker.js +0 -12
- package/dist/engine/write-block-planner.js +93 -100
- package/dist/plan/index.js +15 -16
- package/dist/plan/model.d.ts +6 -0
- package/dist/plan/model.js +20 -27
- package/dist/storage/index.js +0 -12
- package/dist/storage/indexeddb.js +11784 -13171
- package/dist/storage/memory.js +1198 -1241
- package/dist/storage/opfs/files.js +238 -295
- package/dist/storage/opfs/index.js +9 -3
- package/dist/storage/opfs/leader.js +4386 -4856
- package/dist/storage/opfs/rpc.js +223 -259
- package/dist/storage/opfs/snapshot-ledger.js +219 -260
- package/dist/storage/opfs/store.js +884 -1003
- package/dist/storage/persistence.js +59 -74
- package/dist/storage/snapshot-stream.js +788 -826
- package/dist/storage/snapshot.js +36 -37
- package/dist/storage/toolkit/extents.js +444 -520
- package/dist/storage/toolkit/index.js +28 -29
- package/dist/storage/toolkit/record-core.js +5804 -6377
- package/dist/storage/toolkit/sync-file.js +34 -42
- package/dist/storage/toolkit/wal.js +92 -127
- package/dist/storage/toolkit/wire.js +232 -256
- package/dist/storage/types.js +2948 -3250
- package/dist/testing/block-store-conformance.js +1556 -1629
- package/dist/testing/index.js +310 -291
- package/dist/testing/opfs-shim.js +280 -312
- package/dist/testing/simulator.js +496 -534
- package/dist/testing/sqllogictest.js +425 -365
- package/dist/transactions/index.js +1464 -1712
- package/dist/worker-protocol/index.js +70 -69
- package/package.json +20 -2
- package/sql-feature-matrix.json +2 -2
|
@@ -3,230 +3,212 @@ import { physicalColumnByteLength, validatePhysicalColumn } from "./physical.js"
|
|
|
3
3
|
import { wellFormedUtf8ByteLength } from "./unicode.js";
|
|
4
4
|
const textEncoder = new TextEncoder();
|
|
5
5
|
const textDecoder = new TextDecoder("utf-8", { fatal: true });
|
|
6
|
-
// The on-disk format is little-endian; bulk Float64 writes use platform order when they match.
|
|
7
6
|
const PLATFORM_LITTLE_ENDIAN = new Uint8Array(new Uint32Array([1]).buffer)[0] === 1;
|
|
8
7
|
function bitmapLength(rows) {
|
|
9
|
-
|
|
8
|
+
return Math.ceil(rows / 8);
|
|
10
9
|
}
|
|
11
10
|
function setBit(bitmap, index) {
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
const byte = index >>> 3;
|
|
12
|
+
bitmap[byte] = (bitmap[byte] ?? 0) | 1 << (index & 7);
|
|
14
13
|
}
|
|
15
14
|
function hasBit(bitmap, index) {
|
|
16
|
-
|
|
15
|
+
return ((bitmap[index >>> 3] ?? 0) & 1 << (index & 7)) !== 0;
|
|
17
16
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
// Variable-width output still needs an exact sizing pass before allocation. The encode pass
|
|
31
|
-
// below revalidates the local value it writes, so a changing accessor cannot smuggle invalid
|
|
32
|
-
// UTF-16 or make offsets disagree with the content buffer.
|
|
33
|
-
for (let index = 0; index < rowCount; index += 1) {
|
|
34
|
-
const value = input.values[index];
|
|
35
|
-
if (value === undefined)
|
|
36
|
-
throw new TypeError("Column values cannot be undefined");
|
|
37
|
-
if (value !== null) {
|
|
38
|
-
if (typeof value !== "string") {
|
|
39
|
-
throw new TypeError("String columns accept only strings or null");
|
|
40
|
-
}
|
|
41
|
-
stringContentByteLength += wellFormedUtf8ByteLength(value);
|
|
42
|
-
if (!Number.isSafeInteger(stringContentByteLength)) {
|
|
43
|
-
throw new RangeError("Invalid string content byte length");
|
|
44
|
-
}
|
|
45
|
-
}
|
|
17
|
+
function encodeColumn(input) {
|
|
18
|
+
const rowCount = input.values.length;
|
|
19
|
+
physicalColumnByteLength(input.type, rowCount);
|
|
20
|
+
let stringContentByteLength = 0;
|
|
21
|
+
if (input.type === "string") {
|
|
22
|
+
for (let index = 0; index < rowCount; index += 1) {
|
|
23
|
+
const value = input.values[index];
|
|
24
|
+
if (value === void 0)
|
|
25
|
+
throw new TypeError("Column values cannot be undefined");
|
|
26
|
+
if (value !== null) {
|
|
27
|
+
if (typeof value !== "string") {
|
|
28
|
+
throw new TypeError("String columns accept only strings or null");
|
|
46
29
|
}
|
|
30
|
+
stringContentByteLength += wellFormedUtf8ByteLength(value);
|
|
31
|
+
if (!Number.isSafeInteger(stringContentByteLength)) {
|
|
32
|
+
throw new RangeError("Invalid string content byte length");
|
|
33
|
+
}
|
|
34
|
+
}
|
|
47
35
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
if (value === null)
|
|
62
|
-
nullCount += 1;
|
|
63
|
-
else {
|
|
64
|
-
setBit(validity, index);
|
|
65
|
-
if (value)
|
|
66
|
-
setBit(values, index);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
return { bytes: join(validity, values), metadata: {}, nullCount };
|
|
36
|
+
}
|
|
37
|
+
physicalColumnByteLength(input.type, rowCount, stringContentByteLength);
|
|
38
|
+
const validity = new Uint8Array(bitmapLength(rowCount));
|
|
39
|
+
switch (input.type) {
|
|
40
|
+
case "boolean": {
|
|
41
|
+
const values = new Uint8Array(bitmapLength(rowCount));
|
|
42
|
+
let nullCount = 0;
|
|
43
|
+
for (let index = 0; index < rowCount; index += 1) {
|
|
44
|
+
const value = input.values[index];
|
|
45
|
+
if (value === void 0)
|
|
46
|
+
throw new TypeError("Column values cannot be undefined");
|
|
47
|
+
if (value !== null && typeof value !== "boolean") {
|
|
48
|
+
throw new TypeError("Boolean columns accept only booleans or null");
|
|
70
49
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
for (let index = 0; index < rowCount; index += 1) {
|
|
78
|
-
const value = input.values[index];
|
|
79
|
-
if (value === undefined)
|
|
80
|
-
throw new TypeError("Column values cannot be undefined");
|
|
81
|
-
if (value === null) {
|
|
82
|
-
nullCount += 1;
|
|
83
|
-
continue;
|
|
84
|
-
}
|
|
85
|
-
if (typeof value !== "number") {
|
|
86
|
-
throw new TypeError("Number columns accept only numbers or null");
|
|
87
|
-
}
|
|
88
|
-
if (!Number.isFinite(value))
|
|
89
|
-
throw new TypeError("Number values must be finite");
|
|
90
|
-
setBit(validity, index);
|
|
91
|
-
if (view === undefined)
|
|
92
|
-
values[index] = value;
|
|
93
|
-
else
|
|
94
|
-
view.setFloat64(index * 8, value, true);
|
|
95
|
-
min = Math.min(min, value);
|
|
96
|
-
max = Math.max(max, value);
|
|
97
|
-
}
|
|
98
|
-
const metadata = min === Number.POSITIVE_INFINITY ? {} : { zoneMap: { min, max } };
|
|
99
|
-
return { bytes: join(validity, new Uint8Array(values.buffer)), metadata, nullCount };
|
|
50
|
+
if (value === null)
|
|
51
|
+
nullCount += 1;
|
|
52
|
+
else {
|
|
53
|
+
setBit(validity, index);
|
|
54
|
+
if (value)
|
|
55
|
+
setBit(values, index);
|
|
100
56
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
}
|
|
118
|
-
const milliseconds = dateMilliseconds(value);
|
|
119
|
-
if (!Number.isFinite(milliseconds))
|
|
120
|
-
throw new TypeError("Datetime values must be valid Dates");
|
|
121
|
-
setBit(validity, index);
|
|
122
|
-
if (view === undefined)
|
|
123
|
-
values[index] = milliseconds;
|
|
124
|
-
else
|
|
125
|
-
view.setFloat64(index * 8, milliseconds, true);
|
|
126
|
-
min = Math.min(min, milliseconds);
|
|
127
|
-
max = Math.max(max, milliseconds);
|
|
128
|
-
}
|
|
129
|
-
const metadata = min === Number.POSITIVE_INFINITY ? {} : { zoneMap: { min, max } };
|
|
130
|
-
return { bytes: join(validity, new Uint8Array(values.buffer)), metadata, nullCount };
|
|
57
|
+
}
|
|
58
|
+
return { bytes: join(validity, values), metadata: {}, nullCount };
|
|
59
|
+
}
|
|
60
|
+
case "number": {
|
|
61
|
+
const values = new Float64Array(rowCount);
|
|
62
|
+
const view = PLATFORM_LITTLE_ENDIAN ? void 0 : new DataView(values.buffer);
|
|
63
|
+
let nullCount = 0;
|
|
64
|
+
let min = Number.POSITIVE_INFINITY;
|
|
65
|
+
let max = Number.NEGATIVE_INFINITY;
|
|
66
|
+
for (let index = 0; index < rowCount; index += 1) {
|
|
67
|
+
const value = input.values[index];
|
|
68
|
+
if (value === void 0)
|
|
69
|
+
throw new TypeError("Column values cannot be undefined");
|
|
70
|
+
if (value === null) {
|
|
71
|
+
nullCount += 1;
|
|
72
|
+
continue;
|
|
131
73
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
// the former 3x worst-case scratch for ASCII-heavy data. The complete 64 MiB format bound is
|
|
135
|
-
// checked before the content or offset arrays are allocated.
|
|
136
|
-
const offsets = new Uint32Array(rowCount + 1);
|
|
137
|
-
// Some native encodeInto implementations stop at an internal chunk boundary when the
|
|
138
|
-
// destination has exactly two or three bytes left, even though the final code point fits.
|
|
139
|
-
// Three bytes of non-persisted tail room keeps the native fast path reliable; the returned
|
|
140
|
-
// physical payload still contains exactly `contentByteLength` content bytes.
|
|
141
|
-
const content = new Uint8Array(stringContentByteLength + 3);
|
|
142
|
-
let offset = 0;
|
|
143
|
-
let nullCount = 0;
|
|
144
|
-
for (let index = 0; index < rowCount; index += 1) {
|
|
145
|
-
const value = input.values[index];
|
|
146
|
-
if (value === undefined)
|
|
147
|
-
throw new TypeError("Column values cannot be undefined");
|
|
148
|
-
if (value === null)
|
|
149
|
-
nullCount += 1;
|
|
150
|
-
else {
|
|
151
|
-
if (typeof value !== "string") {
|
|
152
|
-
throw new TypeError("String columns accept only strings or null");
|
|
153
|
-
}
|
|
154
|
-
const localByteLength = wellFormedUtf8ByteLength(value);
|
|
155
|
-
setBit(validity, index);
|
|
156
|
-
const result = textEncoder.encodeInto(value, content.subarray(offset));
|
|
157
|
-
if (result.read !== value.length)
|
|
158
|
-
throw new Error("UTF-8 output sizing mismatch");
|
|
159
|
-
if (result.written !== localByteLength)
|
|
160
|
-
throw new Error("UTF-8 output sizing mismatch");
|
|
161
|
-
offset += result.written;
|
|
162
|
-
}
|
|
163
|
-
offsets[index + 1] = offset;
|
|
164
|
-
}
|
|
165
|
-
if (offset !== stringContentByteLength)
|
|
166
|
-
throw new Error("UTF-8 output sizing mismatch");
|
|
167
|
-
return {
|
|
168
|
-
bytes: join(validity, new Uint8Array(offsets.buffer), content.subarray(0, offset)),
|
|
169
|
-
metadata: {},
|
|
170
|
-
nullCount,
|
|
171
|
-
};
|
|
74
|
+
if (typeof value !== "number") {
|
|
75
|
+
throw new TypeError("Number columns accept only numbers or null");
|
|
172
76
|
}
|
|
77
|
+
if (!Number.isFinite(value))
|
|
78
|
+
throw new TypeError("Number values must be finite");
|
|
79
|
+
setBit(validity, index);
|
|
80
|
+
if (view === void 0)
|
|
81
|
+
values[index] = value;
|
|
82
|
+
else
|
|
83
|
+
view.setFloat64(index * 8, value, true);
|
|
84
|
+
min = Math.min(min, value);
|
|
85
|
+
max = Math.max(max, value);
|
|
86
|
+
}
|
|
87
|
+
const metadata = min === Number.POSITIVE_INFINITY ? {} : { zoneMap: { min, max } };
|
|
88
|
+
return { bytes: join(validity, new Uint8Array(values.buffer)), metadata, nullCount };
|
|
173
89
|
}
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
throw new Error("Invalid boolean payload");
|
|
188
|
-
for (let index = 0; index < rowCount; index += 1) {
|
|
189
|
-
values.push(hasBit(validity, index) ? hasBit(payload, index) : null);
|
|
90
|
+
case "datetime": {
|
|
91
|
+
const values = new Float64Array(rowCount);
|
|
92
|
+
const view = PLATFORM_LITTLE_ENDIAN ? void 0 : new DataView(values.buffer);
|
|
93
|
+
let nullCount = 0;
|
|
94
|
+
let min = Number.POSITIVE_INFINITY;
|
|
95
|
+
let max = Number.NEGATIVE_INFINITY;
|
|
96
|
+
for (let index = 0; index < rowCount; index += 1) {
|
|
97
|
+
const value = input.values[index];
|
|
98
|
+
if (value === void 0)
|
|
99
|
+
throw new TypeError("Column values cannot be undefined");
|
|
100
|
+
if (value === null) {
|
|
101
|
+
nullCount += 1;
|
|
102
|
+
continue;
|
|
190
103
|
}
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
if (payload.byteLength !== rowCount * 8)
|
|
194
|
-
throw new Error(`Invalid ${type} payload`);
|
|
195
|
-
const view = new DataView(payload.buffer, payload.byteOffset, payload.byteLength);
|
|
196
|
-
for (let index = 0; index < rowCount; index += 1) {
|
|
197
|
-
const value = view.getFloat64(index * 8, true);
|
|
198
|
-
values.push(hasBit(validity, index) ? (type === "datetime" ? new Date(value) : value) : null);
|
|
104
|
+
if (!(value instanceof Date)) {
|
|
105
|
+
throw new TypeError("Datetime columns accept only Date objects or null");
|
|
199
106
|
}
|
|
107
|
+
const milliseconds = dateMilliseconds(value);
|
|
108
|
+
if (!Number.isFinite(milliseconds))
|
|
109
|
+
throw new TypeError("Datetime values must be valid Dates");
|
|
110
|
+
setBit(validity, index);
|
|
111
|
+
if (view === void 0)
|
|
112
|
+
values[index] = milliseconds;
|
|
113
|
+
else
|
|
114
|
+
view.setFloat64(index * 8, milliseconds, true);
|
|
115
|
+
min = Math.min(min, milliseconds);
|
|
116
|
+
max = Math.max(max, milliseconds);
|
|
117
|
+
}
|
|
118
|
+
const metadata = min === Number.POSITIVE_INFINITY ? {} : { zoneMap: { min, max } };
|
|
119
|
+
return { bytes: join(validity, new Uint8Array(values.buffer)), metadata, nullCount };
|
|
200
120
|
}
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
121
|
+
case "string": {
|
|
122
|
+
const offsets = new Uint32Array(rowCount + 1);
|
|
123
|
+
const content = new Uint8Array(stringContentByteLength + 3);
|
|
124
|
+
let offset = 0;
|
|
125
|
+
let nullCount = 0;
|
|
126
|
+
for (let index = 0; index < rowCount; index += 1) {
|
|
127
|
+
const value = input.values[index];
|
|
128
|
+
if (value === void 0)
|
|
129
|
+
throw new TypeError("Column values cannot be undefined");
|
|
130
|
+
if (value === null)
|
|
131
|
+
nullCount += 1;
|
|
132
|
+
else {
|
|
133
|
+
if (typeof value !== "string") {
|
|
134
|
+
throw new TypeError("String columns accept only strings or null");
|
|
135
|
+
}
|
|
136
|
+
const localByteLength = wellFormedUtf8ByteLength(value);
|
|
137
|
+
setBit(validity, index);
|
|
138
|
+
const result = textEncoder.encodeInto(value, content.subarray(offset));
|
|
139
|
+
if (result.read !== value.length)
|
|
140
|
+
throw new Error("UTF-8 output sizing mismatch");
|
|
141
|
+
if (result.written !== localByteLength)
|
|
142
|
+
throw new Error("UTF-8 output sizing mismatch");
|
|
143
|
+
offset += result.written;
|
|
218
144
|
}
|
|
219
|
-
|
|
220
|
-
|
|
145
|
+
offsets[index + 1] = offset;
|
|
146
|
+
}
|
|
147
|
+
if (offset !== stringContentByteLength)
|
|
148
|
+
throw new Error("UTF-8 output sizing mismatch");
|
|
149
|
+
return {
|
|
150
|
+
bytes: join(validity, new Uint8Array(offsets.buffer), content.subarray(0, offset)),
|
|
151
|
+
metadata: {},
|
|
152
|
+
nullCount
|
|
153
|
+
};
|
|
221
154
|
}
|
|
222
|
-
|
|
155
|
+
}
|
|
223
156
|
}
|
|
224
|
-
function
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
157
|
+
function decodeColumn(type, bytes, rowCount) {
|
|
158
|
+
return decodeValidatedColumn(validatePhysicalColumn({ type, bytes, rowCount }));
|
|
159
|
+
}
|
|
160
|
+
function decodeValidatedColumn(column) {
|
|
161
|
+
const { type, bytes, rowCount } = column;
|
|
162
|
+
const validityLength = bitmapLength(rowCount);
|
|
163
|
+
const validity = bytes.subarray(0, validityLength);
|
|
164
|
+
const payload = bytes.subarray(validityLength);
|
|
165
|
+
const values = [];
|
|
166
|
+
if (type === "boolean") {
|
|
167
|
+
if (payload.byteLength !== bitmapLength(rowCount))
|
|
168
|
+
throw new Error("Invalid boolean payload");
|
|
169
|
+
for (let index = 0; index < rowCount; index += 1) {
|
|
170
|
+
values.push(hasBit(validity, index) ? hasBit(payload, index) : null);
|
|
171
|
+
}
|
|
172
|
+
} else if (type === "number" || type === "datetime") {
|
|
173
|
+
if (payload.byteLength !== rowCount * 8)
|
|
174
|
+
throw new Error(`Invalid ${type} payload`);
|
|
175
|
+
const view = new DataView(payload.buffer, payload.byteOffset, payload.byteLength);
|
|
176
|
+
for (let index = 0; index < rowCount; index += 1) {
|
|
177
|
+
const value = view.getFloat64(index * 8, true);
|
|
178
|
+
values.push(hasBit(validity, index) ? type === "datetime" ? new Date(value) : value : null);
|
|
179
|
+
}
|
|
180
|
+
} else {
|
|
181
|
+
const offsetsLength = (rowCount + 1) * 4;
|
|
182
|
+
if (payload.byteLength < offsetsLength)
|
|
183
|
+
throw new Error("Invalid string offsets");
|
|
184
|
+
const offsets = new DataView(payload.buffer, payload.byteOffset, offsetsLength);
|
|
185
|
+
const content = payload.subarray(offsetsLength);
|
|
186
|
+
let previous = 0;
|
|
187
|
+
for (let index = 0; index <= rowCount; index += 1) {
|
|
188
|
+
const current = offsets.getUint32(index * 4, true);
|
|
189
|
+
if (current < previous || current > content.byteLength)
|
|
190
|
+
throw new Error("Invalid string offset");
|
|
191
|
+
if (index > 0) {
|
|
192
|
+
values.push(hasBit(validity, index - 1) ? textDecoder.decode(content.subarray(previous, current)) : null);
|
|
193
|
+
}
|
|
194
|
+
previous = current;
|
|
230
195
|
}
|
|
231
|
-
|
|
196
|
+
if (previous !== content.byteLength)
|
|
197
|
+
throw new Error("Unreferenced string bytes");
|
|
198
|
+
}
|
|
199
|
+
return { type, values };
|
|
200
|
+
}
|
|
201
|
+
function join(...parts) {
|
|
202
|
+
const output = new Uint8Array(parts.reduce((total, part) => total + part.byteLength, 0));
|
|
203
|
+
let offset = 0;
|
|
204
|
+
for (const part of parts) {
|
|
205
|
+
output.set(part, offset);
|
|
206
|
+
offset += part.byteLength;
|
|
207
|
+
}
|
|
208
|
+
return output;
|
|
232
209
|
}
|
|
210
|
+
export {
|
|
211
|
+
decodeColumn,
|
|
212
|
+
decodeValidatedColumn,
|
|
213
|
+
encodeColumn
|
|
214
|
+
};
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
export * from "./block.js";
|
|
2
2
|
export * from "./checksum.js";
|
|
3
3
|
export * from "./codecs.js";
|
|
4
|
-
|
|
4
|
+
import { decodeColumn, encodeColumn } from "./column.js";
|
|
5
5
|
export * from "./physical.js";
|
|
6
6
|
export * from "./types.js";
|
|
7
7
|
export * from "./unicode.js";
|
|
8
|
+
export {
|
|
9
|
+
decodeColumn,
|
|
10
|
+
encodeColumn
|
|
11
|
+
};
|