@useairfoil/flight 0.3.0 → 0.4.1
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/chunk-Bp6m_JJh.js +13 -0
- package/dist/{src/index.d.ts → index.d.ts} +96 -67
- package/dist/{src/index.js → index.js} +113 -101
- package/dist/index.js.map +1 -0
- package/dist/proto/Flight.proto +4 -11
- package/package.json +20 -33
- package/src/arrow-flight-client.ts +168 -0
- package/src/arrow-flight-sql-client.ts +147 -0
- package/src/arrow-utils.ts +5 -4
- package/src/flight-client-error.ts +27 -0
- package/src/flight-data-encoder.ts +5 -13
- package/src/index.ts +12 -8
- package/src/proto/google/protobuf/descriptor.ts +12 -1
- package/src/proto/google/protobuf/timestamp.ts +7 -6
- package/src/proto-utils.ts +1 -5
- package/src/record-batch-decoder.ts +32 -66
- package/src/record-batch-with-metadata.ts +6 -0
- package/dist/src/index.js.map +0 -1
- package/dist/test/index.d.ts +0 -30
- package/dist/test/index.js +0 -80
- package/dist/test/index.js.map +0 -1
- package/src/arrow-flight-sql.ts +0 -121
- package/src/arrow-flight.ts +0 -149
|
@@ -45,12 +45,11 @@ import {
|
|
|
45
45
|
import * as metadata from "apache-arrow/ipc/metadata/message";
|
|
46
46
|
import { _InternalEmptyPlaceholderRecordBatch } from "apache-arrow/recordbatch";
|
|
47
47
|
import { bigIntToNumber } from "apache-arrow/util/bigint";
|
|
48
|
-
import {
|
|
49
|
-
CompressedVectorLoader,
|
|
50
|
-
VectorLoader,
|
|
51
|
-
} from "apache-arrow/visitor/vectorloader";
|
|
48
|
+
import { CompressedVectorLoader, VectorLoader } from "apache-arrow/visitor/vectorloader";
|
|
52
49
|
import * as flatbuffers from "flatbuffers";
|
|
50
|
+
|
|
53
51
|
import type { FlightData } from "./proto/Flight";
|
|
52
|
+
import type { RecordBatchWithMetadata } from "./record-batch-with-metadata";
|
|
54
53
|
|
|
55
54
|
const invalidMessageType = (type: MessageHeader) =>
|
|
56
55
|
`Expected ${MessageHeader[type]} Message in stream, but was null or length 0.`;
|
|
@@ -61,10 +60,8 @@ const invalidMessageType = (type: MessageHeader) =>
|
|
|
61
60
|
// const invalidMessageBodyLength = (expected: number, actual: number) =>
|
|
62
61
|
// `Expected to read ${expected} bytes for message body, but only read ${actual}.`;
|
|
63
62
|
|
|
64
|
-
abstract class RecordBatchReaderImpl<T extends TypeMap = any>
|
|
65
|
-
|
|
66
|
-
{
|
|
67
|
-
public declare schema: Schema<T>;
|
|
63
|
+
abstract class RecordBatchReaderImpl<T extends TypeMap = any> implements RecordBatchReaderImpl<T> {
|
|
64
|
+
declare public schema: Schema<T>;
|
|
68
65
|
public closed = false;
|
|
69
66
|
public autoDestroy = true;
|
|
70
67
|
public dictionaries: Map<number, Vector>;
|
|
@@ -105,10 +102,7 @@ abstract class RecordBatchReaderImpl<T extends TypeMap = any>
|
|
|
105
102
|
return this;
|
|
106
103
|
}
|
|
107
104
|
|
|
108
|
-
protected _loadRecordBatch(
|
|
109
|
-
header: metadata.RecordBatch,
|
|
110
|
-
body: Uint8Array,
|
|
111
|
-
): RecordBatch<T> {
|
|
105
|
+
protected _loadRecordBatch(header: metadata.RecordBatch, body: Uint8Array): RecordBatch<T> {
|
|
112
106
|
// Ensure the body buffer is properly aligned for Apache Arrow
|
|
113
107
|
// Apache Arrow requires 8-byte aligned buffers for typed arrays
|
|
114
108
|
const alignedBody = this._ensureAlignedBuffer(body);
|
|
@@ -117,22 +111,9 @@ abstract class RecordBatchReaderImpl<T extends TypeMap = any>
|
|
|
117
111
|
if (header.compression != null) {
|
|
118
112
|
const codec = compressionRegistry.get(header.compression.type);
|
|
119
113
|
if (codec?.decode && typeof codec.decode === "function") {
|
|
120
|
-
const { decommpressedBody, buffers } = this._decompressBuffers(
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
codec,
|
|
124
|
-
);
|
|
125
|
-
children = this._loadCompressedVectors(
|
|
126
|
-
header,
|
|
127
|
-
decommpressedBody,
|
|
128
|
-
this.schema.fields,
|
|
129
|
-
);
|
|
130
|
-
header = new metadata.RecordBatch(
|
|
131
|
-
header.length,
|
|
132
|
-
header.nodes,
|
|
133
|
-
buffers,
|
|
134
|
-
null,
|
|
135
|
-
);
|
|
114
|
+
const { decommpressedBody, buffers } = this._decompressBuffers(header, alignedBody, codec);
|
|
115
|
+
children = this._loadCompressedVectors(header, decommpressedBody, this.schema.fields);
|
|
116
|
+
header = new metadata.RecordBatch(header.length, header.nodes, buffers, null);
|
|
136
117
|
} else {
|
|
137
118
|
throw new Error("Record batch is compressed but codec not found");
|
|
138
119
|
}
|
|
@@ -164,10 +145,7 @@ abstract class RecordBatchReaderImpl<T extends TypeMap = any>
|
|
|
164
145
|
return alignedBuffer;
|
|
165
146
|
}
|
|
166
147
|
|
|
167
|
-
protected _loadDictionaryBatch(
|
|
168
|
-
header: metadata.DictionaryBatch,
|
|
169
|
-
body: Uint8Array,
|
|
170
|
-
) {
|
|
148
|
+
protected _loadDictionaryBatch(header: metadata.DictionaryBatch, body: Uint8Array) {
|
|
171
149
|
const { id, isDelta } = header;
|
|
172
150
|
const { dictionaries, schema } = this;
|
|
173
151
|
const dictionary = dictionaries.get(id);
|
|
@@ -176,21 +154,10 @@ abstract class RecordBatchReaderImpl<T extends TypeMap = any>
|
|
|
176
154
|
if (header.data.compression != null) {
|
|
177
155
|
const codec = compressionRegistry.get(header.data.compression.type);
|
|
178
156
|
if (codec?.decode && typeof codec.decode === "function") {
|
|
179
|
-
const { decommpressedBody, buffers } = this._decompressBuffers(
|
|
180
|
-
|
|
181
|
-
body,
|
|
182
|
-
codec,
|
|
183
|
-
);
|
|
184
|
-
data = this._loadCompressedVectors(header.data, decommpressedBody, [
|
|
185
|
-
type,
|
|
186
|
-
]);
|
|
157
|
+
const { decommpressedBody, buffers } = this._decompressBuffers(header.data, body, codec);
|
|
158
|
+
data = this._loadCompressedVectors(header.data, decommpressedBody, [type]);
|
|
187
159
|
header = new metadata.DictionaryBatch(
|
|
188
|
-
new metadata.RecordBatch(
|
|
189
|
-
header.data.length,
|
|
190
|
-
header.data.nodes,
|
|
191
|
-
buffers,
|
|
192
|
-
null,
|
|
193
|
-
),
|
|
160
|
+
new metadata.RecordBatch(header.data.length, header.data.nodes, buffers, null),
|
|
194
161
|
id,
|
|
195
162
|
isDelta,
|
|
196
163
|
);
|
|
@@ -202,9 +169,7 @@ abstract class RecordBatchReaderImpl<T extends TypeMap = any>
|
|
|
202
169
|
}
|
|
203
170
|
// const data = this._loadVectors(header.data, body, [type]);
|
|
204
171
|
return (
|
|
205
|
-
dictionary && isDelta
|
|
206
|
-
? dictionary.concat(new Vector(data))
|
|
207
|
-
: new Vector(data)
|
|
172
|
+
dictionary && isDelta ? dictionary.concat(new Vector(data)) : new Vector(data)
|
|
208
173
|
).memoize() as Vector;
|
|
209
174
|
}
|
|
210
175
|
|
|
@@ -251,25 +216,19 @@ abstract class RecordBatchReaderImpl<T extends TypeMap = any>
|
|
|
251
216
|
newBufferRegions.push(new metadata.BufferRegion(currentOffset, 0));
|
|
252
217
|
continue;
|
|
253
218
|
}
|
|
254
|
-
const byteBuf = new flatbuffers.ByteBuffer(
|
|
255
|
-
body.subarray(offset, offset + length),
|
|
256
|
-
);
|
|
219
|
+
const byteBuf = new flatbuffers.ByteBuffer(body.subarray(offset, offset + length));
|
|
257
220
|
const uncompressedLenth = bigIntToNumber(byteBuf.readInt64(0));
|
|
258
221
|
|
|
259
222
|
const bytes = byteBuf.bytes().subarray(COMPRESS_LENGTH_PREFIX);
|
|
260
223
|
|
|
261
224
|
const decompressed =
|
|
262
|
-
uncompressedLenth === LENGTH_NO_COMPRESSED_DATA
|
|
263
|
-
? bytes
|
|
264
|
-
: codec.decode!(bytes);
|
|
225
|
+
uncompressedLenth === LENGTH_NO_COMPRESSED_DATA ? bytes : codec.decode!(bytes);
|
|
265
226
|
|
|
266
227
|
decompressedBuffers.push(decompressed);
|
|
267
228
|
|
|
268
229
|
const padding = ((currentOffset + 7) & ~7) - currentOffset;
|
|
269
230
|
currentOffset += padding;
|
|
270
|
-
newBufferRegions.push(
|
|
271
|
-
new metadata.BufferRegion(currentOffset, decompressed.length),
|
|
272
|
-
);
|
|
231
|
+
newBufferRegions.push(new metadata.BufferRegion(currentOffset, decompressed.length));
|
|
273
232
|
currentOffset += decompressed.length;
|
|
274
233
|
}
|
|
275
234
|
|
|
@@ -282,7 +241,7 @@ abstract class RecordBatchReaderImpl<T extends TypeMap = any>
|
|
|
282
241
|
|
|
283
242
|
export class RecordBatchStreamReaderFromFlightData<T extends TypeMap = any>
|
|
284
243
|
extends RecordBatchReaderImpl<T>
|
|
285
|
-
implements AsyncIterableIterator<
|
|
244
|
+
implements AsyncIterableIterator<RecordBatchWithMetadata<T>>
|
|
286
245
|
{
|
|
287
246
|
protected _reader: AsyncIterator<FlightData>;
|
|
288
247
|
|
|
@@ -303,8 +262,8 @@ export class RecordBatchStreamReaderFromFlightData<T extends TypeMap = any>
|
|
|
303
262
|
// return true;
|
|
304
263
|
// }
|
|
305
264
|
|
|
306
|
-
public [Symbol.asyncIterator](): AsyncIterableIterator<
|
|
307
|
-
return this as AsyncIterableIterator<
|
|
265
|
+
public [Symbol.asyncIterator](): AsyncIterableIterator<RecordBatchWithMetadata<T>> {
|
|
266
|
+
return this as AsyncIterableIterator<RecordBatchWithMetadata<T>>;
|
|
308
267
|
}
|
|
309
268
|
|
|
310
269
|
/*
|
|
@@ -362,7 +321,13 @@ export class RecordBatchStreamReaderFromFlightData<T extends TypeMap = any>
|
|
|
362
321
|
this._recordBatchIndex++;
|
|
363
322
|
const header = message.header();
|
|
364
323
|
const recordBatch = this._loadRecordBatch(header, flight.dataBody);
|
|
365
|
-
return {
|
|
324
|
+
return {
|
|
325
|
+
done: false,
|
|
326
|
+
value: {
|
|
327
|
+
batch: recordBatch,
|
|
328
|
+
appMetadata: flight.appMetadata,
|
|
329
|
+
},
|
|
330
|
+
};
|
|
366
331
|
} else if (message.isDictionaryBatch()) {
|
|
367
332
|
this._dictionaryIndex++;
|
|
368
333
|
const header = message.header();
|
|
@@ -375,7 +340,10 @@ export class RecordBatchStreamReaderFromFlightData<T extends TypeMap = any>
|
|
|
375
340
|
this._recordBatchIndex++;
|
|
376
341
|
return {
|
|
377
342
|
done: false,
|
|
378
|
-
value:
|
|
343
|
+
value: {
|
|
344
|
+
batch: new _InternalEmptyPlaceholderRecordBatch<T>(this.schema),
|
|
345
|
+
appMetadata: new Uint8Array(0),
|
|
346
|
+
},
|
|
379
347
|
};
|
|
380
348
|
}
|
|
381
349
|
|
|
@@ -383,9 +351,7 @@ export class RecordBatchStreamReaderFromFlightData<T extends TypeMap = any>
|
|
|
383
351
|
return ITERATOR_DONE;
|
|
384
352
|
}
|
|
385
353
|
|
|
386
|
-
protected async _readNextMessageAndValidate<T extends MessageHeader>(
|
|
387
|
-
type?: T | null,
|
|
388
|
-
) {
|
|
354
|
+
protected async _readNextMessageAndValidate<T extends MessageHeader>(type?: T | null) {
|
|
389
355
|
const { done, value } = await this._reader.next();
|
|
390
356
|
if (done) {
|
|
391
357
|
return null;
|