flatsql 0.4.3 → 1.0.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/README.md +116 -6
- package/dist/artifacts/builder.d.ts +31 -0
- package/dist/artifacts/builder.d.ts.map +1 -0
- package/dist/artifacts/builder.js +514 -0
- package/dist/artifacts/builder.js.map +1 -0
- package/dist/artifacts/demo-extractors.d.ts +15 -0
- package/dist/artifacts/demo-extractors.d.ts.map +1 -0
- package/dist/artifacts/demo-extractors.js +238 -0
- package/dist/artifacts/demo-extractors.js.map +1 -0
- package/dist/artifacts/index.d.ts +5 -0
- package/dist/artifacts/index.d.ts.map +1 -0
- package/dist/artifacts/index.js +5 -0
- package/dist/artifacts/index.js.map +1 -0
- package/dist/artifacts/standalone-builder.d.ts +62 -0
- package/dist/artifacts/standalone-builder.d.ts.map +1 -0
- package/dist/artifacts/standalone-builder.js +144 -0
- package/dist/artifacts/standalone-builder.js.map +1 -0
- package/dist/artifacts/transport.d.ts +5 -0
- package/dist/artifacts/transport.d.ts.map +1 -0
- package/dist/artifacts/transport.js +45 -0
- package/dist/artifacts/transport.js.map +1 -0
- package/dist/artifacts/types.d.ts +34 -0
- package/dist/artifacts/types.d.ts.map +1 -0
- package/dist/artifacts/types.js +2 -0
- package/dist/artifacts/types.js.map +1 -0
- package/dist/artifacts/worker-client.d.ts +32 -0
- package/dist/artifacts/worker-client.d.ts.map +1 -0
- package/dist/artifacts/worker-client.js +415 -0
- package/dist/artifacts/worker-client.js.map +1 -0
- package/dist/btree/btree.d.ts.map +1 -1
- package/dist/btree/btree.js +13 -14
- package/dist/btree/btree.js.map +1 -1
- package/dist/core/database.d.ts +2 -0
- package/dist/core/database.d.ts.map +1 -1
- package/dist/core/database.js +18 -0
- package/dist/core/database.js.map +1 -1
- package/dist/core/table-store.d.ts +1 -0
- package/dist/core/table-store.d.ts.map +1 -1
- package/dist/core/table-store.js +31 -0
- package/dist/core/table-store.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/response/artifact.d.ts +5 -0
- package/dist/response/artifact.d.ts.map +1 -0
- package/dist/response/artifact.js +102 -0
- package/dist/response/artifact.js.map +1 -0
- package/dist/response/cache-key.d.ts +6 -0
- package/dist/response/cache-key.d.ts.map +1 -0
- package/dist/response/cache-key.js +114 -0
- package/dist/response/cache-key.js.map +1 -0
- package/dist/response/index.d.ts +5 -0
- package/dist/response/index.d.ts.map +1 -0
- package/dist/response/index.js +5 -0
- package/dist/response/index.js.map +1 -0
- package/dist/response/memory-cache.d.ts +17 -0
- package/dist/response/memory-cache.d.ts.map +1 -0
- package/dist/response/memory-cache.js +76 -0
- package/dist/response/memory-cache.js.map +1 -0
- package/dist/response/types.d.ts +51 -0
- package/dist/response/types.d.ts.map +1 -0
- package/dist/response/types.js +2 -0
- package/dist/response/types.js.map +1 -0
- package/dist/standalone/index.d.ts +3 -0
- package/dist/standalone/index.d.ts.map +1 -0
- package/dist/standalone/index.js +3 -0
- package/dist/standalone/index.js.map +1 -0
- package/dist/standalone/process-client.d.ts +85 -0
- package/dist/standalone/process-client.d.ts.map +1 -0
- package/dist/standalone/process-client.js +537 -0
- package/dist/standalone/process-client.js.map +1 -0
- package/dist/standalone/wasmedge-runner.d.ts +19 -0
- package/dist/standalone/wasmedge-runner.d.ts.map +1 -0
- package/dist/standalone/wasmedge-runner.js +108 -0
- package/dist/standalone/wasmedge-runner.js.map +1 -0
- package/dist/stress/aggregate.d.ts +3 -0
- package/dist/stress/aggregate.d.ts.map +1 -0
- package/dist/stress/aggregate.js +61 -0
- package/dist/stress/aggregate.js.map +1 -0
- package/dist/stress/docker-compose.d.ts +17 -0
- package/dist/stress/docker-compose.d.ts.map +1 -0
- package/dist/stress/docker-compose.js +156 -0
- package/dist/stress/docker-compose.js.map +1 -0
- package/dist/stress/index.d.ts +11 -0
- package/dist/stress/index.d.ts.map +1 -0
- package/dist/stress/index.js +11 -0
- package/dist/stress/index.js.map +1 -0
- package/dist/stress/metrics.d.ts +3 -0
- package/dist/stress/metrics.d.ts.map +1 -0
- package/dist/stress/metrics.js +83 -0
- package/dist/stress/metrics.js.map +1 -0
- package/dist/stress/native-publish-event-workload.d.ts +3 -0
- package/dist/stress/native-publish-event-workload.d.ts.map +1 -0
- package/dist/stress/native-publish-event-workload.js +455 -0
- package/dist/stress/native-publish-event-workload.js.map +1 -0
- package/dist/stress/production-gate.d.ts +4 -0
- package/dist/stress/production-gate.d.ts.map +1 -0
- package/dist/stress/production-gate.js +12 -0
- package/dist/stress/production-gate.js.map +1 -0
- package/dist/stress/publish-event-workload.d.ts +3 -0
- package/dist/stress/publish-event-workload.d.ts.map +1 -0
- package/dist/stress/publish-event-workload.js +467 -0
- package/dist/stress/publish-event-workload.js.map +1 -0
- package/dist/stress/report.d.ts +3 -0
- package/dist/stress/report.d.ts.map +1 -0
- package/dist/stress/report.js +174 -0
- package/dist/stress/report.js.map +1 -0
- package/dist/stress/sds-discovery.d.ts +4 -0
- package/dist/stress/sds-discovery.d.ts.map +1 -0
- package/dist/stress/sds-discovery.js +40 -0
- package/dist/stress/sds-discovery.js.map +1 -0
- package/dist/stress/smoke-runner.d.ts +3 -0
- package/dist/stress/smoke-runner.d.ts.map +1 -0
- package/dist/stress/smoke-runner.js +63 -0
- package/dist/stress/smoke-runner.js.map +1 -0
- package/dist/stress/types.d.ts +219 -0
- package/dist/stress/types.d.ts.map +1 -0
- package/dist/stress/types.js +2 -0
- package/dist/stress/types.js.map +1 -0
- package/dist/stress/workload.d.ts +6 -0
- package/dist/stress/workload.d.ts.map +1 -0
- package/dist/stress/workload.js +144 -0
- package/dist/stress/workload.js.map +1 -0
- package/docs/agents/response-artifacts.md +65 -0
- package/docs/response-artifacts.md +86 -0
- package/package.json +36 -6
- package/scripts/stress-docker.sh +279 -0
- package/sdm/flatsql-spatial.wasm +0 -0
- package/stress/docker/Dockerfile +11 -0
- package/stress/docker/docker-compose.yml +51 -0
- package/stress/sds/aggregate.mjs +97 -0
- package/stress/sds/run.mjs +105 -0
- package/stress/sds/write-compose.mjs +96 -0
- package/wasm/flatsql-artifact.worker.js +847 -0
- package/wasm/flatsql-wasi.wasm +0 -0
- package/wasm/flatsql.js +2 -16
- package/wasm/flatsql.wasm +0 -0
- package/wasm/index.d.ts +119 -2
- package/wasm/index.js +450 -60
- package/wasm/native/flatsql_wasmedge_runner.cpp +858 -0
- package/wasm/standalone.d.ts +91 -0
- package/wasm/standalone.js +740 -0
package/wasm/index.js
CHANGED
|
@@ -5,6 +5,14 @@ import FlatSQLModule from './flatsql.js';
|
|
|
5
5
|
|
|
6
6
|
let Module = null;
|
|
7
7
|
let api = null;
|
|
8
|
+
const textEncoder = new TextEncoder();
|
|
9
|
+
|
|
10
|
+
const PARAM_NULL = 0;
|
|
11
|
+
const PARAM_BOOL = 1;
|
|
12
|
+
const PARAM_INT64 = 2;
|
|
13
|
+
const PARAM_FLOAT64 = 3;
|
|
14
|
+
const PARAM_STRING = 4;
|
|
15
|
+
const PARAM_BYTES = 5;
|
|
8
16
|
|
|
9
17
|
// Security: Track if integrity was verified
|
|
10
18
|
let integrityVerified = false;
|
|
@@ -253,6 +261,22 @@ export async function initFlatSQL(moduleFactoryOrOptions) {
|
|
|
253
261
|
|
|
254
262
|
// Query execution
|
|
255
263
|
query: Module.cwrap('flatsql_query', 'number', ['number', 'string']),
|
|
264
|
+
queryParams: Module.cwrap('flatsql_query_params', 'number', ['number', 'string', 'number', 'number', 'number']),
|
|
265
|
+
queryMany: Module.cwrap('flatsql_query_many', 'number', ['number', 'number', 'number', 'number']),
|
|
266
|
+
buildQueryCacheKey: Module.cwrap('flatsql_build_query_cache_key', 'string', ['string', 'string', 'string', 'number', 'number', 'number']),
|
|
267
|
+
buildResponseArtifactCacheKey: Module.cwrap('flatsql_build_response_artifact_cache_key', 'string', ['string', 'string', 'string', 'string', 'string', 'string', 'number', 'number', 'number']),
|
|
268
|
+
registerQueryTemplate: Module.cwrap('flatsql_register_query_template', 'number', ['number', 'string', 'string', 'number']),
|
|
269
|
+
queryTemplate: Module.cwrap('flatsql_query_template', 'number', ['number', 'string', 'number', 'number', 'number']),
|
|
270
|
+
clearQueryCache: Module.cwrap('flatsql_clear_query_cache', null, ['number']),
|
|
271
|
+
configureQueryCache: Module.cwrap('flatsql_configure_query_cache', 'number', ['number', 'number', 'number']),
|
|
272
|
+
queryCacheHits: Module.cwrap('flatsql_query_cache_hits', 'number', ['number']),
|
|
273
|
+
queryCacheMisses: Module.cwrap('flatsql_query_cache_misses', 'number', ['number']),
|
|
274
|
+
queryCacheSize: Module.cwrap('flatsql_query_cache_size', 'number', ['number']),
|
|
275
|
+
queryCacheGeneration: Module.cwrap('flatsql_query_cache_generation', 'number', ['number']),
|
|
276
|
+
queryCacheMaxEntries: Module.cwrap('flatsql_query_cache_max_entries', 'number', ['number']),
|
|
277
|
+
queryCacheMaxRows: Module.cwrap('flatsql_query_cache_max_rows', 'number', ['number']),
|
|
278
|
+
batchResultCount: Module.cwrap('flatsql_batch_result_count', 'number', []),
|
|
279
|
+
selectBatchResult: Module.cwrap('flatsql_select_batch_result', 'number', ['number']),
|
|
256
280
|
getError: Module.cwrap('flatsql_get_error', 'string', []),
|
|
257
281
|
|
|
258
282
|
// Result access
|
|
@@ -264,17 +288,25 @@ export async function initFlatSQL(moduleFactoryOrOptions) {
|
|
|
264
288
|
resultCellString: Module.cwrap('flatsql_result_cell_string', 'string', ['number', 'number']),
|
|
265
289
|
resultCellBlob: Module.cwrap('flatsql_result_cell_blob', 'number', ['number', 'number']),
|
|
266
290
|
resultCellBlobSize: Module.cwrap('flatsql_result_cell_blob_size', 'number', ['number', 'number']),
|
|
291
|
+
queryRawFlatBufferStream: Module.cwrap('flatsql_query_raw_flatbuffer_stream', 'number', ['number', 'string', 'number', 'number', 'number']),
|
|
292
|
+
responseArtifactData: Module.cwrap('flatsql_response_artifact_data', 'number', []),
|
|
293
|
+
responseArtifactSize: Module.cwrap('flatsql_response_artifact_size', 'number', []),
|
|
294
|
+
responseArtifactRowCount: Module.cwrap('flatsql_response_artifact_row_count', 'number', []),
|
|
295
|
+
responseArtifactColumnCount: Module.cwrap('flatsql_response_artifact_column_count', 'number', []),
|
|
267
296
|
|
|
268
297
|
// Export/Import
|
|
269
298
|
exportData: Module.cwrap('flatsql_export_data', 'number', ['number']),
|
|
270
299
|
exportSize: Module.cwrap('flatsql_export_size', 'number', []),
|
|
271
300
|
loadAndRebuild: Module.cwrap('flatsql_load_and_rebuild', null, ['number', 'number', 'number']),
|
|
301
|
+
reserveStorage: Module.cwrap('flatsql_reserve_storage', null, ['number', 'number']),
|
|
302
|
+
loadFromDb: Module.cwrap('flatsql_load_from_db', null, ['number', 'number']),
|
|
272
303
|
|
|
273
304
|
// Test helpers
|
|
274
305
|
createTestUser: Module.cwrap('flatsql_create_test_user', 'number', ['number', 'string', 'string', 'number']),
|
|
275
306
|
createTestPost: Module.cwrap('flatsql_create_test_post', 'number', ['number', 'number', 'string']),
|
|
276
307
|
createTestMPE: Module.cwrap('flatsql_create_test_mpe', 'number', ['string', 'number', 'number', 'number', 'number', 'number', 'number', 'number', 'number', 'number']),
|
|
277
308
|
createTestTelemetry: Module.cwrap('flatsql_create_test_telemetry', 'number', ['number', 'string', 'string', 'string', 'number', 'number', 'number']),
|
|
309
|
+
createTestPublishEvent: Module.cwrap('flatsql_create_test_publish_event', 'number', ['string', 'string', 'number', 'number']),
|
|
278
310
|
testBufferSize: Module.cwrap('flatsql_test_buffer_size', 'number', []),
|
|
279
311
|
|
|
280
312
|
// Stats
|
|
@@ -294,6 +326,15 @@ export async function initFlatSQL(moduleFactoryOrOptions) {
|
|
|
294
326
|
getDeletedCount: Module.cwrap('flatsql_get_deleted_count', 'number', ['number', 'string']),
|
|
295
327
|
clearTombstones: Module.cwrap('flatsql_clear_tombstones', null, ['number', 'string']),
|
|
296
328
|
|
|
329
|
+
// Raw FlatBuffer access
|
|
330
|
+
getFlatBufferById: Module.cwrap('flatsql_get_flatbuffer_by_id', 'number', ['number', 'string', 'number']),
|
|
331
|
+
getFlatBufferByEmail: Module.cwrap('flatsql_get_flatbuffer_by_email', 'number', ['number', 'string', 'string']),
|
|
332
|
+
getFlatBufferByIndex: Module.cwrap('flatsql_get_flatbuffer_by_index', 'number', ['number', 'string', 'string', 'number', 'number', 'number']),
|
|
333
|
+
getRawFlatBufferSize: Module.cwrap('flatsql_get_raw_flatbuffer_size', 'number', []),
|
|
334
|
+
getRawFlatBufferSequence: Module.cwrap('flatsql_get_raw_flatbuffer_sequence', 'number', []),
|
|
335
|
+
getStorageBuffer: Module.cwrap('flatsql_get_storage_buffer', 'number', ['number']),
|
|
336
|
+
getStorageSize: Module.cwrap('flatsql_get_storage_size', 'number', ['number']),
|
|
337
|
+
|
|
297
338
|
// Encryption
|
|
298
339
|
setEncryptionKey: Module.cwrap('flatsql_set_encryption_key', 'number', ['number', 'number', 'number']),
|
|
299
340
|
isEncrypted: Module.cwrap('flatsql_is_encrypted', 'number', ['number']),
|
|
@@ -318,16 +359,166 @@ export function wasIntegrityVerified() {
|
|
|
318
359
|
return integrityVerified;
|
|
319
360
|
}
|
|
320
361
|
|
|
362
|
+
function wasmPointerToByteOffset(ptr) {
|
|
363
|
+
const numeric = Number(ptr);
|
|
364
|
+
if (!Number.isFinite(numeric)) {
|
|
365
|
+
throw new TypeError(`Invalid WASM pointer: ${ptr}`);
|
|
366
|
+
}
|
|
367
|
+
return numeric >>> 0;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
export const __testWasmPointerToByteOffset = wasmPointerToByteOffset;
|
|
371
|
+
|
|
372
|
+
function heapBytes(ptr, size) {
|
|
373
|
+
return new Uint8Array(Module.HEAPU8.buffer, wasmPointerToByteOffset(ptr), size);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
function copyHeapBytes(ptr, size) {
|
|
377
|
+
return heapBytes(ptr, size).slice();
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
function setHeapBytes(data, ptr) {
|
|
381
|
+
Module.HEAPU8.set(data, wasmPointerToByteOffset(ptr));
|
|
382
|
+
}
|
|
383
|
+
|
|
321
384
|
function withHeapBytes(data, callback) {
|
|
322
385
|
const ptr = Module._malloc(data.length);
|
|
323
386
|
try {
|
|
324
|
-
|
|
387
|
+
setHeapBytes(data, ptr);
|
|
325
388
|
return callback(ptr);
|
|
326
389
|
} finally {
|
|
327
390
|
Module._free(ptr);
|
|
328
391
|
}
|
|
329
392
|
}
|
|
330
393
|
|
|
394
|
+
function encodeQueryParams(params) {
|
|
395
|
+
const parts = [];
|
|
396
|
+
let total = 0;
|
|
397
|
+
|
|
398
|
+
for (const value of params) {
|
|
399
|
+
let tag;
|
|
400
|
+
let payload;
|
|
401
|
+
|
|
402
|
+
if (value === null) {
|
|
403
|
+
tag = PARAM_NULL;
|
|
404
|
+
payload = new Uint8Array(0);
|
|
405
|
+
} else if (typeof value === 'boolean') {
|
|
406
|
+
tag = PARAM_BOOL;
|
|
407
|
+
payload = Uint8Array.of(value ? 1 : 0);
|
|
408
|
+
} else if (typeof value === 'number' && Number.isInteger(value)) {
|
|
409
|
+
if (!Number.isSafeInteger(value)) {
|
|
410
|
+
throw new TypeError('Integer query parameters must be safe integers');
|
|
411
|
+
}
|
|
412
|
+
tag = PARAM_INT64;
|
|
413
|
+
payload = new Uint8Array(8);
|
|
414
|
+
new DataView(payload.buffer, payload.byteOffset, payload.byteLength).setBigInt64(0, BigInt(value), true);
|
|
415
|
+
} else if (typeof value === 'number') {
|
|
416
|
+
tag = PARAM_FLOAT64;
|
|
417
|
+
payload = new Uint8Array(8);
|
|
418
|
+
new DataView(payload.buffer, payload.byteOffset, payload.byteLength).setFloat64(0, value, true);
|
|
419
|
+
} else if (typeof value === 'string') {
|
|
420
|
+
tag = PARAM_STRING;
|
|
421
|
+
payload = textEncoder.encode(value);
|
|
422
|
+
} else if (value instanceof Uint8Array) {
|
|
423
|
+
tag = PARAM_BYTES;
|
|
424
|
+
payload = value;
|
|
425
|
+
} else {
|
|
426
|
+
throw new TypeError(`Unsupported query parameter type: ${typeof value}`);
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
const header = new Uint8Array(5);
|
|
430
|
+
const view = new DataView(header.buffer);
|
|
431
|
+
view.setUint8(0, tag);
|
|
432
|
+
view.setUint32(1, payload.length, true);
|
|
433
|
+
|
|
434
|
+
parts.push(header, payload);
|
|
435
|
+
total += header.length + payload.length;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
const encoded = new Uint8Array(total);
|
|
439
|
+
let offset = 0;
|
|
440
|
+
for (const part of parts) {
|
|
441
|
+
encoded.set(part, offset);
|
|
442
|
+
offset += part.length;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
return encoded;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
function encodeQueryRequests(queries) {
|
|
449
|
+
const parts = [];
|
|
450
|
+
let total = 0;
|
|
451
|
+
|
|
452
|
+
for (const query of queries) {
|
|
453
|
+
const sqlBytes = textEncoder.encode(query.sql);
|
|
454
|
+
const paramList = query.params ?? [];
|
|
455
|
+
const paramBytes = encodeQueryParams(paramList);
|
|
456
|
+
const header = new Uint8Array(12);
|
|
457
|
+
const view = new DataView(header.buffer);
|
|
458
|
+
view.setUint32(0, sqlBytes.length, true);
|
|
459
|
+
view.setUint32(4, paramList.length, true);
|
|
460
|
+
view.setUint32(8, paramBytes.length, true);
|
|
461
|
+
|
|
462
|
+
parts.push(header, sqlBytes, paramBytes);
|
|
463
|
+
total += header.length + sqlBytes.length + paramBytes.length;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
const encoded = new Uint8Array(total);
|
|
467
|
+
let offset = 0;
|
|
468
|
+
for (const part of parts) {
|
|
469
|
+
encoded.set(part, offset);
|
|
470
|
+
offset += part.length;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
return encoded;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
function readCellValue(row, col) {
|
|
477
|
+
const type = api.resultCellType(row, col);
|
|
478
|
+
switch (type) {
|
|
479
|
+
case 0:
|
|
480
|
+
return null;
|
|
481
|
+
case 1:
|
|
482
|
+
return api.resultCellNumber(row, col) !== 0;
|
|
483
|
+
case 2:
|
|
484
|
+
case 3:
|
|
485
|
+
case 4:
|
|
486
|
+
return api.resultCellNumber(row, col);
|
|
487
|
+
case 5:
|
|
488
|
+
return api.resultCellString(row, col);
|
|
489
|
+
case 6: {
|
|
490
|
+
const blobPtr = api.resultCellBlob(row, col);
|
|
491
|
+
const blobSize = api.resultCellBlobSize(row, col);
|
|
492
|
+
return blobPtr && blobSize > 0
|
|
493
|
+
? Array.from(copyHeapBytes(blobPtr, blobSize))
|
|
494
|
+
: [];
|
|
495
|
+
}
|
|
496
|
+
default:
|
|
497
|
+
return null;
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
function readQueryResult() {
|
|
502
|
+
const colCount = api.resultColumnCount();
|
|
503
|
+
const rowCount = api.resultRowCount();
|
|
504
|
+
|
|
505
|
+
const columns = [];
|
|
506
|
+
for (let i = 0; i < colCount; i++) {
|
|
507
|
+
columns.push(api.resultColumnName(i));
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
const rows = [];
|
|
511
|
+
for (let r = 0; r < rowCount; r++) {
|
|
512
|
+
const row = [];
|
|
513
|
+
for (let c = 0; c < colCount; c++) {
|
|
514
|
+
row.push(readCellValue(r, c));
|
|
515
|
+
}
|
|
516
|
+
rows.push(row);
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
return { columns, rows };
|
|
520
|
+
}
|
|
521
|
+
|
|
331
522
|
function buildSizePrefixedStream(buffers) {
|
|
332
523
|
let total = 0;
|
|
333
524
|
for (const buffer of buffers) {
|
|
@@ -356,13 +547,19 @@ export class FlatSQL {
|
|
|
356
547
|
createTestUser(id, name, email, age) {
|
|
357
548
|
const ptr = api.createTestUser(id, name, email, age);
|
|
358
549
|
const size = api.testBufferSize();
|
|
359
|
-
return
|
|
550
|
+
return copyHeapBytes(ptr, size);
|
|
360
551
|
}
|
|
361
552
|
|
|
362
553
|
createTestPost(id, userId, title) {
|
|
363
554
|
const ptr = api.createTestPost(id, userId, title);
|
|
364
555
|
const size = api.testBufferSize();
|
|
365
|
-
return
|
|
556
|
+
return copyHeapBytes(ptr, size);
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
createTestPublishEvent(fileId, recordId, eventIndex, payloadSize) {
|
|
560
|
+
const ptr = api.createTestPublishEvent(fileId, recordId, eventIndex, payloadSize);
|
|
561
|
+
const size = api.testBufferSize();
|
|
562
|
+
return copyHeapBytes(ptr, size);
|
|
366
563
|
}
|
|
367
564
|
|
|
368
565
|
createTestMPE(entityId, epoch, meanMotion, eccentricity, inclination,
|
|
@@ -380,13 +577,13 @@ export class FlatSQL {
|
|
|
380
577
|
meanElementTheory
|
|
381
578
|
);
|
|
382
579
|
const size = api.testBufferSize();
|
|
383
|
-
return
|
|
580
|
+
return copyHeapBytes(ptr, size);
|
|
384
581
|
}
|
|
385
582
|
|
|
386
583
|
createTestTelemetry(packetId, spacecraft, subsystem, mode, temperatureC, signalDb, timestampS) {
|
|
387
584
|
const ptr = api.createTestTelemetry(packetId, spacecraft, subsystem, mode, temperatureC, signalDb, timestampS);
|
|
388
585
|
const size = api.testBufferSize();
|
|
389
|
-
return
|
|
586
|
+
return copyHeapBytes(ptr, size);
|
|
390
587
|
}
|
|
391
588
|
|
|
392
589
|
/**
|
|
@@ -396,6 +593,58 @@ export class FlatSQL {
|
|
|
396
593
|
wasIntegrityVerified() {
|
|
397
594
|
return integrityVerified;
|
|
398
595
|
}
|
|
596
|
+
|
|
597
|
+
buildQueryCacheKey(dataset, artifactVersion, queryId, params = []) {
|
|
598
|
+
const encodedParams = encodeQueryParams(params);
|
|
599
|
+
const key = encodedParams.length === 0
|
|
600
|
+
? api.buildQueryCacheKey(dataset, artifactVersion, queryId, 0, 0, 0)
|
|
601
|
+
: withHeapBytes(
|
|
602
|
+
encodedParams,
|
|
603
|
+
(ptr) => api.buildQueryCacheKey(dataset, artifactVersion, queryId, ptr, encodedParams.length, params.length)
|
|
604
|
+
);
|
|
605
|
+
if (!key) {
|
|
606
|
+
throw new Error(api.getError());
|
|
607
|
+
}
|
|
608
|
+
return key;
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
buildResponseArtifactCacheKey(schemaName, schemaVersion, sql, options = {}) {
|
|
612
|
+
const format = options.format ?? 'json';
|
|
613
|
+
const publishEventKey = options.publishEventKey ?? '';
|
|
614
|
+
const projectionList = (options.projection ?? []).join('\n');
|
|
615
|
+
const params = options.params ?? [];
|
|
616
|
+
const encodedParams = encodeQueryParams(params);
|
|
617
|
+
const key = encodedParams.length === 0
|
|
618
|
+
? api.buildResponseArtifactCacheKey(
|
|
619
|
+
schemaName,
|
|
620
|
+
schemaVersion,
|
|
621
|
+
sql,
|
|
622
|
+
format,
|
|
623
|
+
publishEventKey,
|
|
624
|
+
projectionList,
|
|
625
|
+
0,
|
|
626
|
+
0,
|
|
627
|
+
0
|
|
628
|
+
)
|
|
629
|
+
: withHeapBytes(
|
|
630
|
+
encodedParams,
|
|
631
|
+
(ptr) => api.buildResponseArtifactCacheKey(
|
|
632
|
+
schemaName,
|
|
633
|
+
schemaVersion,
|
|
634
|
+
sql,
|
|
635
|
+
format,
|
|
636
|
+
publishEventKey,
|
|
637
|
+
projectionList,
|
|
638
|
+
ptr,
|
|
639
|
+
encodedParams.length,
|
|
640
|
+
params.length
|
|
641
|
+
)
|
|
642
|
+
);
|
|
643
|
+
if (!key) {
|
|
644
|
+
throw new Error(api.getError());
|
|
645
|
+
}
|
|
646
|
+
return key;
|
|
647
|
+
}
|
|
399
648
|
}
|
|
400
649
|
|
|
401
650
|
// Database wrapper class
|
|
@@ -465,73 +714,140 @@ export class FlatSQLDatabase {
|
|
|
465
714
|
return sources;
|
|
466
715
|
}
|
|
467
716
|
|
|
468
|
-
query(sql) {
|
|
469
|
-
const success =
|
|
717
|
+
query(sql, params = undefined) {
|
|
718
|
+
const success = params === undefined
|
|
719
|
+
? api.query(this._handle, sql)
|
|
720
|
+
: (() => {
|
|
721
|
+
const encodedParams = encodeQueryParams(params);
|
|
722
|
+
if (encodedParams.length === 0) {
|
|
723
|
+
return api.queryParams(this._handle, sql, 0, 0, 0);
|
|
724
|
+
}
|
|
725
|
+
return withHeapBytes(
|
|
726
|
+
encodedParams,
|
|
727
|
+
(ptr) => api.queryParams(this._handle, sql, ptr, encodedParams.length, params.length)
|
|
728
|
+
);
|
|
729
|
+
})();
|
|
470
730
|
if (!success) {
|
|
471
731
|
throw new Error(api.getError());
|
|
472
732
|
}
|
|
733
|
+
return readQueryResult();
|
|
734
|
+
}
|
|
473
735
|
|
|
474
|
-
|
|
475
|
-
const
|
|
476
|
-
|
|
736
|
+
registerQueryTemplate(queryId, sql, cacheable = true) {
|
|
737
|
+
const success = api.registerQueryTemplate(this._handle, queryId, sql, cacheable ? 1 : 0);
|
|
738
|
+
if (!success) {
|
|
739
|
+
throw new Error(api.getError());
|
|
740
|
+
}
|
|
741
|
+
}
|
|
477
742
|
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
743
|
+
queryTemplate(queryId, params = []) {
|
|
744
|
+
const encodedParams = encodeQueryParams(params);
|
|
745
|
+
const success = encodedParams.length === 0
|
|
746
|
+
? api.queryTemplate(this._handle, queryId, 0, 0, 0)
|
|
747
|
+
: withHeapBytes(
|
|
748
|
+
encodedParams,
|
|
749
|
+
(ptr) => api.queryTemplate(this._handle, queryId, ptr, encodedParams.length, params.length)
|
|
750
|
+
);
|
|
751
|
+
if (!success) {
|
|
752
|
+
throw new Error(api.getError());
|
|
481
753
|
}
|
|
754
|
+
return readQueryResult();
|
|
755
|
+
}
|
|
482
756
|
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
757
|
+
clearQueryCache() {
|
|
758
|
+
api.clearQueryCache(this._handle);
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
configureQueryCache({ maxEntries, maxRows }) {
|
|
762
|
+
if (!Number.isSafeInteger(maxEntries) || maxEntries <= 0) {
|
|
763
|
+
throw new TypeError(`maxEntries must be a positive safe integer, received: ${maxEntries}`);
|
|
764
|
+
}
|
|
765
|
+
if (!Number.isSafeInteger(maxRows) || maxRows <= 0) {
|
|
766
|
+
throw new TypeError(`maxRows must be a positive safe integer, received: ${maxRows}`);
|
|
767
|
+
}
|
|
768
|
+
const success = api.configureQueryCache(this._handle, maxEntries, maxRows);
|
|
769
|
+
if (!success) {
|
|
770
|
+
throw new Error(api.getError());
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
getQueryCacheStats() {
|
|
775
|
+
return {
|
|
776
|
+
hits: api.queryCacheHits(this._handle),
|
|
777
|
+
misses: api.queryCacheMisses(this._handle),
|
|
778
|
+
size: api.queryCacheSize(this._handle),
|
|
779
|
+
generation: api.queryCacheGeneration(this._handle),
|
|
780
|
+
maxEntries: api.queryCacheMaxEntries(this._handle),
|
|
781
|
+
maxRows: api.queryCacheMaxRows(this._handle)
|
|
782
|
+
};
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
queryMany(queries) {
|
|
786
|
+
if (queries.length === 0) {
|
|
787
|
+
return [];
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
const encodedRequests = encodeQueryRequests(queries);
|
|
791
|
+
const success = withHeapBytes(
|
|
792
|
+
encodedRequests,
|
|
793
|
+
(ptr) => api.queryMany(this._handle, ptr, encodedRequests.length, queries.length)
|
|
794
|
+
);
|
|
795
|
+
if (!success) {
|
|
796
|
+
throw new Error(api.getError());
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
const resultCount = api.batchResultCount();
|
|
800
|
+
const results = [];
|
|
801
|
+
for (let index = 0; index < resultCount; index++) {
|
|
802
|
+
if (!api.selectBatchResult(index)) {
|
|
803
|
+
throw new Error(`Failed to select batch result ${index}`);
|
|
515
804
|
}
|
|
516
|
-
|
|
805
|
+
results.push(readQueryResult());
|
|
517
806
|
}
|
|
807
|
+
return results;
|
|
808
|
+
}
|
|
518
809
|
|
|
519
|
-
|
|
810
|
+
queryRawFlatBufferStream(sql, params = []) {
|
|
811
|
+
const encodedParams = encodeQueryParams(params);
|
|
812
|
+
const success = encodedParams.length === 0
|
|
813
|
+
? api.queryRawFlatBufferStream(this._handle, sql, 0, 0, 0)
|
|
814
|
+
: withHeapBytes(
|
|
815
|
+
encodedParams,
|
|
816
|
+
(ptr) => api.queryRawFlatBufferStream(this._handle, sql, ptr, encodedParams.length, params.length)
|
|
817
|
+
);
|
|
818
|
+
if (!success) {
|
|
819
|
+
throw new Error(api.getError());
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
const ptr = api.responseArtifactData();
|
|
823
|
+
const size = api.responseArtifactSize();
|
|
824
|
+
return ptr && size > 0 ? copyHeapBytes(ptr, size) : new Uint8Array();
|
|
520
825
|
}
|
|
521
826
|
|
|
522
827
|
exportData() {
|
|
523
828
|
const ptr = api.exportData(this._handle);
|
|
524
829
|
const size = api.exportSize();
|
|
525
|
-
return
|
|
830
|
+
return copyHeapBytes(ptr, size);
|
|
526
831
|
}
|
|
527
832
|
|
|
528
833
|
loadAndRebuild(data) {
|
|
529
834
|
const ptr = Module._malloc(data.length);
|
|
530
|
-
|
|
835
|
+
setHeapBytes(data, ptr);
|
|
531
836
|
api.loadAndRebuild(this._handle, ptr, data.length);
|
|
532
837
|
Module._free(ptr);
|
|
533
838
|
}
|
|
534
839
|
|
|
840
|
+
reserveStorageBytes(bytes) {
|
|
841
|
+
api.reserveStorage(this._handle, bytes);
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
loadAndRebuildFrom(sourceDb) {
|
|
845
|
+
if (!sourceDb?._handle) {
|
|
846
|
+
throw new TypeError('loadAndRebuildFrom requires a FlatSQL WASM database.');
|
|
847
|
+
}
|
|
848
|
+
api.loadFromDb(this._handle, sourceDb._handle);
|
|
849
|
+
}
|
|
850
|
+
|
|
535
851
|
getStats() {
|
|
536
852
|
const count = api.getStatsCount(this._handle);
|
|
537
853
|
const stats = [];
|
|
@@ -571,6 +887,80 @@ export class FlatSQLDatabase {
|
|
|
571
887
|
api.clearTombstones(this._handle, tableName);
|
|
572
888
|
}
|
|
573
889
|
|
|
890
|
+
getFlatBufferById(tableName, id) {
|
|
891
|
+
const ptr = api.getFlatBufferById(this._handle, tableName, id);
|
|
892
|
+
if (!ptr) {
|
|
893
|
+
return null;
|
|
894
|
+
}
|
|
895
|
+
return {
|
|
896
|
+
ptr,
|
|
897
|
+
size: api.getRawFlatBufferSize(),
|
|
898
|
+
sequence: api.getRawFlatBufferSequence()
|
|
899
|
+
};
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
getFlatBufferByEmail(tableName, email) {
|
|
903
|
+
const ptr = api.getFlatBufferByEmail(this._handle, tableName, email);
|
|
904
|
+
if (!ptr) {
|
|
905
|
+
return null;
|
|
906
|
+
}
|
|
907
|
+
return {
|
|
908
|
+
ptr,
|
|
909
|
+
size: api.getRawFlatBufferSize(),
|
|
910
|
+
sequence: api.getRawFlatBufferSequence()
|
|
911
|
+
};
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
getFlatBufferByIndex(tableName, columnName, value) {
|
|
915
|
+
const encodedParams = encodeQueryParams([value]);
|
|
916
|
+
const ptr = withHeapBytes(
|
|
917
|
+
encodedParams,
|
|
918
|
+
(paramPtr) => api.getFlatBufferByIndex(
|
|
919
|
+
this._handle,
|
|
920
|
+
tableName,
|
|
921
|
+
columnName,
|
|
922
|
+
paramPtr,
|
|
923
|
+
encodedParams.length,
|
|
924
|
+
1
|
|
925
|
+
)
|
|
926
|
+
);
|
|
927
|
+
if (!ptr) {
|
|
928
|
+
const error = api.getError();
|
|
929
|
+
if (error) {
|
|
930
|
+
throw new Error(error);
|
|
931
|
+
}
|
|
932
|
+
return null;
|
|
933
|
+
}
|
|
934
|
+
return {
|
|
935
|
+
ptr,
|
|
936
|
+
size: api.getRawFlatBufferSize(),
|
|
937
|
+
sequence: api.getRawFlatBufferSequence()
|
|
938
|
+
};
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
getFlatBufferDataById(tableName, id) {
|
|
942
|
+
const record = this.getFlatBufferById(tableName, id);
|
|
943
|
+
if (!record) {
|
|
944
|
+
return null;
|
|
945
|
+
}
|
|
946
|
+
return copyHeapBytes(record.ptr, record.size);
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
getFlatBufferDataByIndex(tableName, columnName, value) {
|
|
950
|
+
const record = this.getFlatBufferByIndex(tableName, columnName, value);
|
|
951
|
+
if (!record) {
|
|
952
|
+
return null;
|
|
953
|
+
}
|
|
954
|
+
return copyHeapBytes(record.ptr, record.size);
|
|
955
|
+
}
|
|
956
|
+
|
|
957
|
+
getStorageInfo() {
|
|
958
|
+
return {
|
|
959
|
+
ptr: api.getStorageBuffer(this._handle),
|
|
960
|
+
size: api.getStorageSize(this._handle)
|
|
961
|
+
};
|
|
962
|
+
}
|
|
963
|
+
|
|
574
964
|
// ==================== Encryption API ====================
|
|
575
965
|
|
|
576
966
|
/**
|
|
@@ -579,7 +969,7 @@ export class FlatSQLDatabase {
|
|
|
579
969
|
*/
|
|
580
970
|
setEncryptionKey(key) {
|
|
581
971
|
const ptr = Module._malloc(key.length);
|
|
582
|
-
|
|
972
|
+
setHeapBytes(key, ptr);
|
|
583
973
|
const result = api.setEncryptionKey(this._handle, ptr, key.length);
|
|
584
974
|
Module._free(ptr);
|
|
585
975
|
if (!result) throw new Error(api.getError());
|
|
@@ -601,11 +991,11 @@ export class FlatSQLDatabase {
|
|
|
601
991
|
*/
|
|
602
992
|
encryptBuffer(buffer, schema) {
|
|
603
993
|
const bufPtr = Module._malloc(buffer.length);
|
|
604
|
-
|
|
994
|
+
setHeapBytes(buffer, bufPtr);
|
|
605
995
|
const schemaPtr = Module._malloc(schema.length);
|
|
606
|
-
|
|
996
|
+
setHeapBytes(schema, schemaPtr);
|
|
607
997
|
const result = api.encryptBuffer(this._handle, bufPtr, buffer.length, schemaPtr, schema.length);
|
|
608
|
-
const encrypted =
|
|
998
|
+
const encrypted = copyHeapBytes(bufPtr, buffer.length);
|
|
609
999
|
Module._free(bufPtr);
|
|
610
1000
|
Module._free(schemaPtr);
|
|
611
1001
|
if (!result) throw new Error(api.getError());
|
|
@@ -620,11 +1010,11 @@ export class FlatSQLDatabase {
|
|
|
620
1010
|
*/
|
|
621
1011
|
decryptBuffer(buffer, schema) {
|
|
622
1012
|
const bufPtr = Module._malloc(buffer.length);
|
|
623
|
-
|
|
1013
|
+
setHeapBytes(buffer, bufPtr);
|
|
624
1014
|
const schemaPtr = Module._malloc(schema.length);
|
|
625
|
-
|
|
1015
|
+
setHeapBytes(schema, schemaPtr);
|
|
626
1016
|
const result = api.decryptBuffer(this._handle, bufPtr, buffer.length, schemaPtr, schema.length);
|
|
627
|
-
const decrypted =
|
|
1017
|
+
const decrypted = copyHeapBytes(bufPtr, buffer.length);
|
|
628
1018
|
Module._free(bufPtr);
|
|
629
1019
|
Module._free(schemaPtr);
|
|
630
1020
|
if (!result) throw new Error(api.getError());
|
|
@@ -658,10 +1048,10 @@ export class FlatSQLDatabase {
|
|
|
658
1048
|
*/
|
|
659
1049
|
computeHMAC(buffer) {
|
|
660
1050
|
const bufPtr = Module._malloc(buffer.length);
|
|
661
|
-
|
|
1051
|
+
setHeapBytes(buffer, bufPtr);
|
|
662
1052
|
const macPtr = Module._malloc(32);
|
|
663
1053
|
const result = api.computeHMAC(this._handle, bufPtr, buffer.length, macPtr);
|
|
664
|
-
const mac =
|
|
1054
|
+
const mac = copyHeapBytes(macPtr, 32);
|
|
665
1055
|
Module._free(bufPtr);
|
|
666
1056
|
Module._free(macPtr);
|
|
667
1057
|
if (!result) throw new Error('HMAC computation failed - is encryption key set?');
|
|
@@ -676,9 +1066,9 @@ export class FlatSQLDatabase {
|
|
|
676
1066
|
*/
|
|
677
1067
|
verifyHMAC(buffer, mac) {
|
|
678
1068
|
const bufPtr = Module._malloc(buffer.length);
|
|
679
|
-
|
|
1069
|
+
setHeapBytes(buffer, bufPtr);
|
|
680
1070
|
const macPtr = Module._malloc(32);
|
|
681
|
-
|
|
1071
|
+
setHeapBytes(mac, macPtr);
|
|
682
1072
|
const result = api.verifyHMAC(this._handle, bufPtr, buffer.length, macPtr);
|
|
683
1073
|
Module._free(bufPtr);
|
|
684
1074
|
Module._free(macPtr);
|