sqlmath 2023.9.25 → 2023.10.25

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/sqlmath.mjs CHANGED
@@ -25,20 +25,28 @@
25
25
  /*global FinalizationRegistry*/
26
26
  "use strict";
27
27
 
28
- let FILENAME_DBTMP = "/tmp/__dbtmp1";
29
- let IS_BROWSER;
30
- let JSBATON_ARGC = 16;
28
+ let JSBATON_ARGC = 8;
29
+ let JSBATON_OFFSET_ALL = 256;
30
+ let JSBATON_OFFSET_ARGV = 128;
31
+ let JSBATON_OFFSET_BUFV = 192;
32
+ let JSBATON_OFFSET_FUNCNAME = 8;
33
+ let JS_MAX_SAFE_INTEGER = 0x1f_ffff_ffff_ffff;
34
+ let JS_MIN_SAFE_INTEGER = -0x1f_ffff_ffff_ffff;
35
+ let SIZEOF_BLOB_MAX = 1_000_000_000;
36
+ let SIZEOF_FUNCNAME = 16;
31
37
  let SQLITE_DATATYPE_BLOB = 0x04;
38
+ let SQLITE_DATATYPE_EXTERNALBUFFER = 0x71;
32
39
  let SQLITE_DATATYPE_FLOAT = 0x02;
33
40
  let SQLITE_DATATYPE_INTEGER = 0x01;
34
- let SQLITE_DATATYPE_INTEGER_0 = 0x11;
41
+ let SQLITE_DATATYPE_INTEGER_0 = 0x00;
35
42
  let SQLITE_DATATYPE_INTEGER_1 = 0x21;
36
43
  let SQLITE_DATATYPE_NULL = 0x05;
37
- let SQLITE_DATATYPE_OFFSET = 768;
38
- let SQLITE_DATATYPE_SHAREDARRAYBUFFER = 0x71;
39
44
  let SQLITE_DATATYPE_TEXT = 0x03;
40
45
  let SQLITE_DATATYPE_TEXT_0 = 0x13;
41
- let SQLITE_MAX_LENGTH2 = 1_000_000_000;
46
+ let SQLITE_RESPONSETYPE_LASTBLOB = 1;
47
+
48
+ let FILENAME_DBTMP = "/tmp/__dbtmp1"; //jslint-ignore-line
49
+ let IS_BROWSER;
42
50
  let SQLITE_OPEN_AUTOPROXY = 0x00000020; /* VFS only */
43
51
  let SQLITE_OPEN_CREATE = 0x00000004; /* Ok for sqlite3_open_v2() */
44
52
  let SQLITE_OPEN_DELETEONCLOSE = 0x00000008; /* VFS only */
@@ -63,7 +71,6 @@ let SQLITE_OPEN_WAL = 0x00080000; /* VFS only */
63
71
  let cModule;
64
72
  let cModulePath;
65
73
  let consoleError = console.error;
66
- let dbDict = new WeakMap(); // private-dict of sqlite-database-connections
67
74
  let dbFinalizationRegistry;
68
75
  // init debugInline
69
76
  let debugInline = (function () {
@@ -97,7 +104,20 @@ let {
97
104
  let sqlMessageDict = {}; // dict of web-worker-callbacks
98
105
  let sqlMessageId = 0;
99
106
  let sqlWorker;
100
- let version = "v2023.9.25";
107
+ let version = "v2023.10.25";
108
+
109
+ function assertInt64(val) {
110
+ // This function will assert <val> is within range of c99-signed-long-long.
111
+ val = BigInt(val);
112
+ if (!(
113
+ -9_223_372_036_854_775_808n <= val && val <= 9_223_372_036_854_775_807n
114
+ )) {
115
+ throw new Error(
116
+ `integer ${val} outside signed-64-bit inclusive-range`
117
+ + " -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807"
118
+ );
119
+ }
120
+ }
101
121
 
102
122
  function assertJsonEqual(aa, bb, message) {
103
123
 
@@ -148,97 +168,6 @@ function assertOrThrow(condition, message) {
148
168
  }
149
169
  }
150
170
 
151
- async function cCallAsync(baton, cFuncName, ...argList) {
152
-
153
- // This function will serialize <argList> to a c <baton>,
154
- // suitable for passing into napi.
155
-
156
- let argi = 0;
157
- let errStack;
158
- assertOrThrow(
159
- argList.length < 16,
160
- "cCallAsync - argList.length must be less than than 16"
161
- );
162
- baton = baton || jsbatonCreate();
163
- // pad argList to length JSBATON_ARGC
164
- while (argList.length < 2 * JSBATON_ARGC) {
165
- argList.push(0n);
166
- }
167
- // serialize js-value to c-value
168
- argList = argList.map(function (value, ii) {
169
- argi = ii;
170
- switch (typeof value) {
171
- case "bigint":
172
- case "boolean":
173
- baton.setBigInt64(8 + argi * 8, BigInt(value), true);
174
- return value;
175
- case "number":
176
- // check for min/max safe-integer
177
- assertOrThrow(
178
- (
179
- -9_007_199_254_740_991 <= value
180
- && value <= 9_007_199_254_740_991
181
- ),
182
- (
183
- "non-bigint integer must be within inclusive-range"
184
- + " -9,007,199,254,740,991 to 9,007,199,254,740,991"
185
- )
186
- );
187
- baton.setBigInt64(8 + argi * 8, BigInt(value), true);
188
- return value;
189
- // case "object":
190
- // break;
191
- case "string":
192
- baton = jsbatonValuePush({
193
- argi,
194
- baton,
195
- value: (
196
- value.endsWith("\u0000")
197
- ? value
198
- // append null-terminator to string
199
- : value + "\u0000"
200
- )
201
- });
202
- return;
203
- }
204
- if (ArrayBuffer.isView(value)) {
205
- return new DataView(
206
- value.buffer,
207
- value.byteOffset,
208
- value.byteLength
209
- );
210
- }
211
- if (isExternalBuffer(value)) {
212
- return value;
213
- }
214
- });
215
- // encode cFuncName into baton
216
- argi += 1;
217
- baton = jsbatonValuePush({
218
- argi,
219
- baton,
220
- value: cFuncName + "\u0000"
221
- });
222
- // prepend baton, cFuncName to argList
223
- argList = [
224
- baton, cFuncName, ...argList
225
- ];
226
- // preserve stack-trace
227
- errStack = new Error().stack.replace((
228
- /.*$/m
229
- ), "");
230
- try {
231
- return (
232
- IS_BROWSER
233
- ? await sqlMessagePost(...argList)
234
- : await cModule[cFuncName](argList)
235
- );
236
- } catch (err) {
237
- err.stack += errStack;
238
- assertOrThrow(undefined, err);
239
- }
240
- }
241
-
242
171
  async function childProcessSpawn2(command, args, option) {
243
172
 
244
173
  // This function will run child_process.spawn as a promise.
@@ -360,11 +289,18 @@ async function ciBuildExt1NodejsConfigure({
360
289
  consoleError(`ciBuildExt1Nodejs - configure binding.gyp`);
361
290
  await fsWriteFileUnlessTest("binding.gyp", JSON.stringify({
362
291
  "target_defaults": {
363
- "cflags": ["-Wextra", "-std=c11"],
292
+ "cflags": [
293
+ "-Wextra",
294
+ "-std=c11"
295
+ ],
364
296
  "conditions": [
365
297
  [
366
- "OS == \u0027win\u0027",
367
- {"defines": ["WIN32"]}
298
+ "OS == 'win'",
299
+ {
300
+ "defines": [
301
+ "WIN32"
302
+ ]
303
+ }
368
304
  ]
369
305
  ],
370
306
  // https://github.com/nodejs/node-gyp/blob/v9.3.1/gyp/pylib/gyp/MSVSSettings.py
@@ -373,29 +309,45 @@ async function ciBuildExt1NodejsConfigure({
373
309
  "WarningLevel": 3
374
310
  }
375
311
  },
376
- "xcode_settings": {"OTHER_CFLAGS": ["-Wextra", "-std=c11"]}
312
+ "xcode_settings": {
313
+ "OTHER_CFLAGS": [
314
+ "-Wextra",
315
+ "-std=c11"
316
+ ]
317
+ }
377
318
  },
378
319
  "targets": [
379
320
  {
380
321
  "cflags": cflagsNowarning,
322
+ "defines": [
323
+ "SRC_SQLITE_BASE_C2"
324
+ ],
381
325
  "sources": [
382
- "build/SRC_ZLIB_BASE.c",
383
- "build/SRC_SQLITE_BASE.c",
384
- "build/SQLMATH_BASE.c"
326
+ "sqlmath_base.c",
327
+ "sqlmath_external_pcre2.c",
328
+ "sqlmath_external_sqlite.c",
329
+ "sqlmath_external_zlib.c"
385
330
  ],
386
331
  "target_name": "SRC_SQLITE_BASE",
387
332
  "type": "static_library",
388
- "xcode_settings": {"OTHER_CFLAGS": cflagsNowarning}
333
+ "xcode_settings": {
334
+ "OTHER_CFLAGS": cflagsNowarning
335
+ }
389
336
  },
390
337
  {
338
+ "defines": [
339
+ "SQLMATH_CUSTOM"
340
+ ],
391
341
  "sources": [
392
- "build/SQLMATH_CUSTOM.c"
342
+ "sqlmath_custom.c"
393
343
  ],
394
344
  "target_name": "SQLMATH_CUSTOM",
395
345
  "type": "static_library"
396
346
  },
397
347
  {
398
- "defines": ["SQLMATH_NODEJS_C2"],
348
+ "defines": [
349
+ "SQLMATH_NODEJS_C2"
350
+ ],
399
351
  "dependencies": [
400
352
  "SQLMATH_CUSTOM",
401
353
  "SRC_SQLITE_BASE"
@@ -408,19 +360,20 @@ async function ciBuildExt1NodejsConfigure({
408
360
  {
409
361
  "cflags": cflagsNowarning,
410
362
  "defines": [
411
- "SQLITE3_SHELL_C2"
363
+ "SRC_SQLITE_SHELL_C2"
412
364
  ],
413
365
  "dependencies": [
414
366
  "SQLMATH_CUSTOM",
415
367
  "SRC_SQLITE_BASE"
416
368
  ],
417
369
  "sources": [
418
- "sqlmath_base.c",
419
- "build/SRC_SQLITE_SHELL.c"
370
+ "sqlmath_external_sqlite.c"
420
371
  ],
421
372
  "target_name": "shell",
422
373
  "type": "executable",
423
- "xcode_settings": {"OTHER_CFLAGS": cflagsNowarning}
374
+ "xcode_settings": {
375
+ "OTHER_CFLAGS": cflagsNowarning
376
+ }
424
377
  }
425
378
  ]
426
379
  }, undefined, 4) + "\n");
@@ -482,62 +435,178 @@ async function ciBuildExt2NodejsBuild({
482
435
  );
483
436
  }
484
437
 
485
- function dbCallAsync(baton, cFuncName, db, ...argList) {
438
+ async function dbCallAsync(baton, argList, mode) {
486
439
 
487
- // This function will call <cFuncName> using db <argList>[0].
440
+ // This function will call c-function dbXxx() with given <funcname>
441
+ // and return [<baton>, ...argList].
488
442
 
489
- let __db = dbDeref(db);
490
- // increment __db.busy
491
- __db.busy += 1;
492
- return cCallAsync(
493
- baton,
494
- cFuncName,
495
- __db.ptr,
496
- ...argList
497
- ).finally(function () {
498
- // decrement __db.busy
499
- __db.busy -= 1;
500
- assertOrThrow(__db.busy >= 0, `invalid __db.busy ${__db.busy}`);
443
+ let db;
444
+ let errStack;
445
+ let funcname;
446
+ let id;
447
+ let result;
448
+ let timeElapsed;
449
+ // If argList contains <db>, then mark it as busy.
450
+ if (mode === "modeDb") {
451
+ // init db
452
+ db = argList[0];
453
+ assertOrThrow(
454
+ db.busy >= 0,
455
+ `dbCallAsync - invalid db.busy = ${db.busy}`
456
+ );
457
+ db.ii = (db.ii + 1) % db.connPool.length;
458
+ db.ptr = db.connPool[db.ii][0];
459
+ // increment db.busy
460
+ db.busy += 1;
461
+ try {
462
+ return await dbCallAsync(baton, [db.ptr, ...argList.slice(1)]);
463
+ } finally {
464
+ // decrement db.busy
465
+ db.busy -= 1;
466
+ assertOrThrow(
467
+ db.busy >= 0,
468
+ `dbCallAsync - invalid db.busy = ${db.busy}`
469
+ );
470
+ }
471
+ }
472
+ // copy argList to avoid side-effect
473
+ argList = [...argList];
474
+ assertOrThrow(
475
+ argList.length <= JSBATON_ARGC,
476
+ `dbCallAsync - argList.length must be less than than ${JSBATON_ARGC}`
477
+ );
478
+ // pad argList to length JSBATON_ARGC
479
+ while (argList.length < JSBATON_ARGC) {
480
+ argList.push(0n);
481
+ }
482
+ // serialize js-value to c-value
483
+ argList = argList.map(function (val, argi) {
484
+ if (val === null || val === undefined) {
485
+ val = 0;
486
+ }
487
+ switch (typeof val) {
488
+ case "bigint":
489
+ case "boolean":
490
+ case "number":
491
+ // check for min/max safe-integer
492
+ assertOrThrow(
493
+ (
494
+ (JS_MIN_SAFE_INTEGER <= val && val <= JS_MAX_SAFE_INTEGER)
495
+ || typeof val === "bigint"
496
+ ),
497
+ (
498
+ "dbCallAsync - "
499
+ + "non-bigint-integer must be within inclusive-range"
500
+ + ` ${JS_MIN_SAFE_INTEGER} to ${JS_MAX_SAFE_INTEGER}`
501
+ )
502
+ );
503
+ val = BigInt(val);
504
+ assertInt64(val);
505
+ baton.setBigInt64(JSBATON_OFFSET_ARGV + argi * 8, val, true);
506
+ return val;
507
+ // case "object":
508
+ // break;
509
+ case "string":
510
+ baton = jsbatonSetValue(baton, argi, (
511
+ val.endsWith("\u0000")
512
+ ? val
513
+ // append null-terminator to string
514
+ : val + "\u0000"
515
+ ));
516
+ return;
517
+ }
518
+ assertOrThrow(
519
+ !ArrayBuffer.isView(val) || val.byteOffset === 0,
520
+ (
521
+ "dbCallAsync - argList cannot contain arraybuffer-views"
522
+ + " with non-zero byteOffset"
523
+ )
524
+ );
525
+ if (isExternalBuffer(val)) {
526
+ return val;
527
+ }
528
+ throw new Error(`dbCallAsync - invalid arg-type "${typeof val}"`);
529
+ });
530
+ // assert byteOffset === 0
531
+ [baton, ...argList].forEach(function (arg) {
532
+ assertOrThrow(!ArrayBuffer.isView(arg) || arg.byteOffset === 0, arg);
501
533
  });
534
+ // extract funcname
535
+ funcname = new TextDecoder().decode(
536
+ new DataView(baton.buffer, JSBATON_OFFSET_FUNCNAME, SIZEOF_FUNCNAME)
537
+ ).replace((/\u0000/g), "");
538
+ // preserve stack-trace
539
+ errStack = new Error().stack.replace((/.*$/m), "");
540
+ try {
541
+
542
+ // Dispatch to nodejs-napi.
543
+
544
+ if (!IS_BROWSER) {
545
+ await cModule._jspromiseCreate(baton.buffer, argList, funcname);
546
+ // prepend baton to argList
547
+ return [baton, ...argList];
548
+ }
549
+
550
+ // Dispatch to web-worker.
551
+
552
+ // increment sqlMessageId
553
+ sqlMessageId += 1;
554
+ id = sqlMessageId;
555
+ // postMessage to web-worker
556
+ sqlWorker.postMessage(
557
+ {
558
+ FILENAME_DBTMP,
559
+ JSBATON_OFFSET_ALL,
560
+ JSBATON_OFFSET_BUFV,
561
+ argList,
562
+ baton,
563
+ funcname,
564
+ id
565
+ },
566
+ // transfer arraybuffer without copying
567
+ [baton.buffer, ...argList.filter(isExternalBuffer)]
568
+ );
569
+ // init timeElapsed
570
+ timeElapsed = Date.now();
571
+ // await result from web-worker
572
+ result = await new Promise(function (resolve) {
573
+ sqlMessageDict[id] = resolve;
574
+ });
575
+ // cleanup sqlMessageDict
576
+ delete sqlMessageDict[id];
577
+ // debug slow postMessage
578
+ timeElapsed = Date.now() - timeElapsed;
579
+ if (timeElapsed > 500 || funcname === "testTimeElapsed") {
580
+ consoleError(
581
+ "sqlMessagePost - "
582
+ + JSON.stringify({funcname, timeElapsed})
583
+ + errStack
584
+ );
585
+ }
586
+ assertOrThrow(!result.errmsg, result.errmsg);
587
+ // prepend baton to argList
588
+ return [result.baton, ...result.argList];
589
+ } catch (err) {
590
+ err.stack += errStack;
591
+ assertOrThrow(undefined, err);
592
+ }
502
593
  }
503
594
 
504
- async function dbCloseAsync({
505
- db
506
- }) {
595
+ async function dbCloseAsync(db) {
507
596
 
508
597
  // This function will close sqlite-database-connection <db>.
509
598
 
510
- let __db = dbDeref(db);
511
599
  // prevent segfault - do not close db if actions are pending
512
600
  assertOrThrow(
513
- __db.busy === 0,
514
- "db cannot close with " + __db.busy + " actions pending"
601
+ db.busy === 0,
602
+ `dbCloseAsync - cannot close db with ${db.busy} actions pending`
515
603
  );
516
604
  // cleanup connPool
517
- await Promise.all(__db.connPool.map(async function (ptr) {
605
+ await Promise.all(db.connPool.map(async function (ptr) {
518
606
  let val = ptr[0];
519
607
  ptr[0] = 0n;
520
- await cCallAsync(
521
- undefined,
522
- "_dbClose",
523
- val,
524
- __db.filename
525
- );
608
+ await dbCallAsync(jsbatonCreate("_dbClose"), [val, db.filename]);
526
609
  }));
527
- dbDict.delete(db);
528
- }
529
-
530
- function dbDeref(db) {
531
-
532
- // This function will get private-object mapped to <db>.
533
-
534
- let __db = dbDict.get(db);
535
- assertOrThrow(__db?.connPool[0] > 0, "invalid or closed db");
536
- assertOrThrow(__db.busy >= 0, "invalid db.busy " + __db.busy);
537
- __db.ii = (__db.ii + 1) % __db.connPool.length;
538
- __db.ptr = __db.connPool[__db.ii][0];
539
- assertOrThrow(__db.ptr > 0n, "invalid or closed db");
540
- return __db;
541
610
  }
542
611
 
543
612
  function dbExecAndReturnLastBlobAsync({
@@ -552,7 +621,7 @@ function dbExecAndReturnLastBlobAsync({
552
621
  return dbExecAsync({
553
622
  bindList,
554
623
  db,
555
- responseType: "lastBlob",
624
+ responseType: "lastblob",
556
625
  sql
557
626
  });
558
627
  }
@@ -560,92 +629,83 @@ function dbExecAndReturnLastBlobAsync({
560
629
  async function dbExecAsync({
561
630
  bindList = [],
562
631
  db,
563
- modeRetry,
564
632
  responseType,
565
633
  sql
566
634
  }) {
567
635
 
568
636
  // This function will exec <sql> in <db> and return <result>.
569
637
 
570
- let baton;
571
- let bindByKey;
572
- let bindListLength;
573
- let externalbufferList;
638
+ let baton = jsbatonCreate("_dbExec");
639
+ let bindByKey = !Array.isArray(bindList);
640
+ let bufi = [0];
641
+ let referenceList = [];
574
642
  let result;
575
- while (modeRetry > 0) {
576
- try {
577
- return await dbExecAsync({
578
- bindList,
579
- db,
580
- responseType,
581
- sql
582
- });
583
- } catch (err) {
584
- assertOrThrow(modeRetry > 0, err);
585
- consoleError(err);
586
- consoleError(
587
- "dbExecAsync - retry failed sql-query with "
588
- + modeRetry
589
- + " remaining retries"
643
+ if (bindByKey) {
644
+ Object.entries(bindList).forEach(function ([key, val]) {
645
+ baton = jsbatonSetValue(baton, undefined, `:${key}\u0000`);
646
+ baton = jsbatonSetValue(
647
+ baton,
648
+ undefined,
649
+ val,
650
+ bufi,
651
+ referenceList
590
652
  );
591
- modeRetry -= 1;
592
- await new Promise(function (resolve) {
593
- setTimeout(resolve, 5_000 * !npm_config_mode_test);
594
- });
595
- }
596
- }
597
- baton = jsbatonCreate();
598
- bindByKey = !Array.isArray(bindList);
599
- bindListLength = (
600
- Array.isArray(bindList)
601
- ? bindList.length
602
- : Object.keys(bindList).length
603
- );
604
- externalbufferList = [];
605
- Object.entries(bindList).forEach(function ([
606
- key, val
607
- ]) {
608
- if (bindByKey) {
609
- baton = jsbatonValuePush({
653
+ });
654
+ } else {
655
+ bindList.forEach(function (val) {
656
+ baton = jsbatonSetValue(
610
657
  baton,
611
- value: ":" + key + "\u0000"
612
- });
613
- }
614
- baton = jsbatonValuePush({
615
- baton,
616
- externalbufferList,
617
- value: val
658
+ undefined,
659
+ val,
660
+ bufi,
661
+ referenceList
662
+ );
618
663
  });
619
- });
620
- result = await dbCallAsync(
664
+ }
665
+ [baton, ...result] = await dbCallAsync(
621
666
  baton,
622
- "_dbExec",
623
- db, // 0
624
- String(sql) + "\n;\nPRAGMA noop", // 1
625
- bindListLength, // 2
626
- bindByKey, // 3
627
- ( // 4
628
- responseType === "lastBlob"
629
- ? 1
630
- : 0
631
- ),
632
- undefined, // 5
633
- undefined, // 6
634
- undefined, // 7 - response
635
- ...externalbufferList // 8
667
+ [
668
+ // 0. db
669
+ db,
670
+ // 1. sql
671
+ String(sql) + "\n;\nPRAGMA noop",
672
+ // 2. bindList.length
673
+ (
674
+ bindByKey
675
+ ? Object.keys(bindList).length
676
+ : bindList.length
677
+ ),
678
+ // 3. bindByKey
679
+ bindByKey,
680
+ // 4. responseType
681
+ (
682
+ responseType === "lastblob"
683
+ ? SQLITE_RESPONSETYPE_LASTBLOB
684
+ : 0
685
+ )
686
+ ],
687
+ "modeDb"
636
688
  );
637
- result = result[2 + 7];
689
+ result = result[0];
690
+ if (!IS_BROWSER) {
691
+ result = cModule._jsbatonStealCbuffer(
692
+ baton.buffer,
693
+ 0,
694
+ Number(
695
+ responseType !== "arraybuffer" && responseType !== "lastblob"
696
+ )
697
+ );
698
+ }
638
699
  switch (responseType) {
639
700
  case "arraybuffer":
640
- case "lastBlob":
701
+ case "lastblob":
641
702
  return result;
642
703
  case "list":
643
- return JSON.parse(new TextDecoder().decode(result));
704
+ return jsonParseArraybuffer(result);
644
705
  default:
645
- result = JSON.parse(new TextDecoder().decode(result));
646
- return result.map(function (rowList) {
647
- let colList = rowList.shift();
648
- return rowList.map(function (row) {
706
+ return jsonParseArraybuffer(result).map(function (table) {
707
+ let colList = table.shift();
708
+ return table.map(function (row) {
649
709
  let dict = {};
650
710
  colList.forEach(function (key, ii) {
651
711
  dict[key] = row[ii];
@@ -656,15 +716,15 @@ async function dbExecAsync({
656
716
  }
657
717
  }
658
718
 
659
- async function dbFileExportAsync({
719
+ async function dbFileLoadAsync({
660
720
  db,
661
721
  dbData,
662
722
  filename,
663
- modeExport = 1,
664
- modeNoop
723
+ modeNoop,
724
+ modeSave = 0
665
725
  }) {
666
726
 
667
- // This function will export <db> to <filename>.
727
+ // This function will load <filename> to <db>.
668
728
 
669
729
  if (modeNoop) {
670
730
  return;
@@ -676,38 +736,46 @@ async function dbFileExportAsync({
676
736
  typeof filename === "string" && filename,
677
737
  `invalid filename ${filename}`
678
738
  );
679
- return await dbCallAsync(
680
- undefined,
681
- "_dbFileImportOrExport",
682
- db, // 0. sqlite3 * pInMemory,
683
- String(filename), // 1. char *zFilename,
684
- modeExport, // 2. const int isSave
685
- undefined, // 3. undefined
686
- dbData // 4. dbData
739
+ dbData = await dbCallAsync(
740
+ jsbatonCreate("_dbFileLoad"),
741
+ [
742
+ // 0. sqlite3 * pInMemory
743
+ db,
744
+ // 1. char *zFilename
745
+ filename,
746
+ // 2. const int isSave
747
+ modeSave,
748
+ // 3. undefined
749
+ undefined,
750
+ // 4. dbData - same position as dbOpenAsync
751
+ dbData
752
+ ],
753
+ "modeDb"
687
754
  );
755
+ return dbData[1 + 0];
688
756
  }
689
757
 
690
- async function dbFileImportAsync({
758
+ async function dbFileSaveAsync({
691
759
  db,
692
760
  dbData,
693
761
  filename
694
762
  }) {
695
763
 
696
- // This function will import <filename> to <db>.
764
+ // This function will save <db> to <filename>.
697
765
 
698
- await dbFileExportAsync({
766
+ return await dbFileLoadAsync({
699
767
  db,
700
768
  dbData,
701
769
  filename,
702
- modeExport: 0
770
+ modeSave: 1
703
771
  });
704
772
  }
705
773
 
706
774
  async function dbNoopAsync(...argList) {
707
775
 
708
- // This function will do nothing except return argList.
776
+ // This function will do nothing except return <argList>.
709
777
 
710
- return await cCallAsync(undefined, "_dbNoop", ...argList);
778
+ return await dbCallAsync(jsbatonCreate("_dbNoop"), argList);
711
779
  }
712
780
 
713
781
  async function dbOpenAsync({
@@ -727,13 +795,8 @@ async function dbOpenAsync({
727
795
  // const char *zVfs /* Name of VFS module to use */
728
796
  // );
729
797
  let connPool;
730
- let db = {
731
- filename
732
- };
733
- assertOrThrow(
734
- typeof filename === "string",
735
- `invalid filename ${filename}`
736
- );
798
+ let db = {busy: 0, filename, ii: 0};
799
+ assertOrThrow(typeof filename === "string", `invalid filename ${filename}`);
737
800
  assertOrThrow(
738
801
  !dbData || isExternalBuffer(dbData),
739
802
  "dbData must be ArrayBuffer"
@@ -741,37 +804,28 @@ async function dbOpenAsync({
741
804
  connPool = await Promise.all(Array.from(new Array(
742
805
  threadCount
743
806
  ), async function () {
744
- let ptr = await cCallAsync(
745
- undefined,
746
- "_dbOpen",
747
- // 0. const char *filename, Database filename (UTF-8)
748
- String(filename),
749
- // 1. sqlite3 **ppDb, OUT: SQLite db handle
750
- undefined,
751
- // 2. int flags, Flags
752
- flags ?? (
753
- SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE | SQLITE_OPEN_URI
754
- ),
755
- // 3. const char *zVfs Name of VFS module to use
756
- undefined,
757
- // 4. wasm-only - arraybuffer of raw sqlite-database to open in wasm
758
- dbData
807
+ let [ptr] = await dbCallAsync(
808
+ jsbatonCreate("_dbOpen"),
809
+ [
810
+ // 0. const char *filename, Database filename (UTF-8)
811
+ filename,
812
+ // 1. sqlite3 **ppDb, OUT: SQLite db handle
813
+ undefined,
814
+ // 2. int flags, Flags
815
+ flags ?? (
816
+ SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE | SQLITE_OPEN_URI
817
+ ),
818
+ // 3. const char *zVfs Name of VFS module to use
819
+ undefined,
820
+ // 4. wasm-only - arraybuffer of raw sqlite-database
821
+ dbData
822
+ ]
759
823
  );
760
- ptr = [
761
- ptr[0].getBigInt64(4 + 4, true)
762
- ];
763
- dbFinalizationRegistry.register(db, {
764
- afterFinalization,
765
- ptr
766
- });
824
+ ptr = [ptr.getBigInt64(JSBATON_OFFSET_ARGV + 0, true)];
825
+ dbFinalizationRegistry.register(db, {afterFinalization, ptr});
767
826
  return ptr;
768
827
  }));
769
- dbDict.set(db, {
770
- busy: 0,
771
- connPool,
772
- filename,
773
- ii: 0
774
- });
828
+ db.connPool = connPool;
775
829
  return db;
776
830
  }
777
831
 
@@ -825,35 +879,50 @@ async function fsWriteFileUnlessTest(file, data, mode) {
825
879
 
826
880
  function isExternalBuffer(buf) {
827
881
 
828
- // This function will check if <buf> is ArrayBuffer or SharedArrayBuffer.
882
+ // This function will check if <buf> is ArrayBuffer.
829
883
 
830
- return buf && (
831
- buf.constructor === ArrayBuffer
832
- || (
833
- typeof SharedArrayBuffer === "function"
834
- && buf.constructor === SharedArrayBuffer
835
- )
836
- );
884
+ return buf && buf.constructor === ArrayBuffer;
837
885
  }
838
886
 
839
- function jsbatonCreate() {
887
+ function jsbatonCreate(funcname) {
840
888
 
841
889
  // This function will create buffer <baton>.
842
890
 
843
- let baton = new DataView(new ArrayBuffer(1024));
844
- // offset nalloc, nused
845
- baton.setInt32(4, SQLITE_DATATYPE_OFFSET, true);
891
+ let baton = new DataView(new ArrayBuffer(JSBATON_OFFSET_ALL));
892
+ // init nallc, nused
893
+ baton.setInt32(4, JSBATON_OFFSET_ALL, true);
894
+ // copy funcname into baton
895
+ new Uint8Array(
896
+ baton.buffer,
897
+ baton.byteOffset + JSBATON_OFFSET_FUNCNAME,
898
+ SIZEOF_FUNCNAME - 1
899
+ ).set(new TextEncoder().encode(funcname));
846
900
  return baton;
847
901
  }
848
902
 
849
- function jsbatonValuePush({
850
- argi,
851
- baton,
852
- externalbufferList,
853
- value
854
- }) {
903
+ function jsbatonGetInt64(baton, argi) {
904
+
905
+ // This function will return int64-value from <baton> at <argi>.
906
+
907
+ return baton.getBigInt64(JSBATON_OFFSET_ARGV + argi * 8, true);
908
+ }
909
+
910
+ function jsbatonGetString(baton, argi) {
911
+
912
+ // This function will return string-value from <baton> at <argi>.
913
+
914
+ let offset = baton.getInt32(JSBATON_OFFSET_ARGV + argi * 8, true);
915
+ return new TextDecoder().decode(new Uint8Array(
916
+ baton.buffer,
917
+ baton.byteOffset + offset + 1 + 4,
918
+ // remove null-terminator from string
919
+ baton.getInt32(offset + 1, true) - 1
920
+ ));
921
+ }
855
922
 
856
- // This function will push <value> to buffer <baton>.
923
+ function jsbatonSetValue(baton, argi, val, bufi, referenceList) {
924
+
925
+ // This function will set <val> to buffer <baton>.
857
926
 
858
927
  let nn;
859
928
  let nused;
@@ -862,126 +931,130 @@ function jsbatonValuePush({
862
931
  let vtype;
863
932
  /*
864
933
  #define SQLITE_DATATYPE_BLOB 0x04
934
+ #define SQLITE_DATATYPE_EXTERNALBUFFER 0x71
865
935
  #define SQLITE_DATATYPE_FLOAT 0x02
866
936
  #define SQLITE_DATATYPE_INTEGER 0x01
867
- #define SQLITE_DATATYPE_INTEGER_0 0x11
937
+ #define SQLITE_DATATYPE_INTEGER_0 0x00
868
938
  #define SQLITE_DATATYPE_INTEGER_1 0x21
869
939
  #define SQLITE_DATATYPE_NULL 0x05
870
- #define SQLITE_DATATYPE_OFFSET 768
871
- #define SQLITE_DATATYPE_SHAREDARRAYBUFFER 0x71
872
940
  #define SQLITE_DATATYPE_TEXT 0x03
873
941
  #define SQLITE_DATATYPE_TEXT_0 0x13
874
- // 1. false.bigint
875
- // 2. false.boolean
876
- // 3. false.function
877
- // 4. false.number
878
- // 5. false.object
879
- // 6. false.string
880
- // 7. false.symbol
881
- // 8. false.undefined
882
- // 9. true.bigint
883
- // 10. true.boolean
884
- // 11. true.function
885
- // 12. true.number
886
- // 13. true.object
887
- // 14. true.string
888
- // 15. true.symbol
889
- // 16. true.undefined
890
- // 17. true.buffer
891
- // 18. true.externalbuffer
942
+ // 1. 0.bigint
943
+ // 2. 0.boolean
944
+ // 3. 0.function
945
+ // 4. 0.number
946
+ // 5. 0.object
947
+ // 6. 0.string
948
+ // 7. 0.symbol
949
+ // 8. 0.undefined
950
+ // 9. 1.bigint
951
+ // 10. 1.boolean
952
+ // 11. 1.function
953
+ // 12. 1.number
954
+ // 13. 1.object
955
+ // 14. 1.string
956
+ // 15. 1.symbol
957
+ // 16. 1.undefined
958
+ // 17. 1.buffer
959
+ // 18. 1.externalbuffer
892
960
  */
893
- // 10. true.boolean
894
- if (value === 1 || value === 1n) {
895
- value = true;
961
+ // 10. 1.boolean
962
+ if (val === 1 || val === 1n) {
963
+ val = true;
896
964
  }
897
- switch (Boolean(value) + "." + typeof(value)) {
898
- // 1. false.bigint
899
- case "false.bigint":
900
- // 2. false.boolean
901
- case "false.boolean":
902
- // 4. false.number
903
- case "false.number":
965
+ switch (
966
+ val
967
+ ? "1." + typeof(val)
968
+ : "0." + typeof(val)
969
+ ) {
970
+ // 1. 0.bigint
971
+ case "0.bigint":
972
+ // 2. 0.boolean
973
+ case "0.boolean":
974
+ // 4. 0.number
975
+ case "0.number":
976
+ if (Number.isNaN(val)) {
977
+ vtype = SQLITE_DATATYPE_NULL;
978
+ vsize = 0;
979
+ break;
980
+ }
904
981
  vtype = SQLITE_DATATYPE_INTEGER_0;
905
982
  vsize = 0;
906
983
  break;
907
- // 3. false.function
908
- // case "false.function":
909
- // 5. false.object
910
- case "false.object":
911
- // 7. false.symbol
912
- case "false.symbol":
913
- // 8. false.undefined
914
- case "false.undefined":
915
- // 11. true.function
916
- case "true.function":
917
- // 15. true.symbol
918
- case "true.symbol":
919
- // 16. true.undefined
920
- // case "true.undefined":
984
+ // 3. 0.function
985
+ // case "0.function":
986
+ // 5. 0.object
987
+ case "0.object":
988
+ // 7. 0.symbol
989
+ case "0.symbol":
990
+ // 8. 0.undefined
991
+ case "0.undefined":
992
+ // 11. 1.function
993
+ case "1.function":
994
+ // 15. 1.symbol
995
+ case "1.symbol":
996
+ // 16. 1.undefined
997
+ // case "1.undefined":
921
998
  vtype = SQLITE_DATATYPE_NULL;
922
999
  vsize = 0;
923
1000
  break;
924
- // 6. false.string
925
- case "false.string":
1001
+ // 6. 0.string
1002
+ case "0.string":
926
1003
  vtype = SQLITE_DATATYPE_TEXT_0;
927
1004
  vsize = 0;
928
1005
  break;
929
- // 9. true.bigint
930
- case "true.bigint":
1006
+ // 9. 1.bigint
1007
+ case "1.bigint":
931
1008
  vtype = SQLITE_DATATYPE_INTEGER;
932
1009
  vsize = 8;
933
1010
  break;
934
- // 10. true.boolean
935
- case "true.boolean":
1011
+ // 10. 1.boolean
1012
+ case "1.boolean":
936
1013
  vtype = SQLITE_DATATYPE_INTEGER_1;
937
1014
  vsize = 0;
938
1015
  break;
939
- // 12. true.number
940
- case "true.number":
1016
+ // 12. 1.number
1017
+ case "1.number":
941
1018
  vtype = SQLITE_DATATYPE_FLOAT;
942
1019
  vsize = 8;
943
1020
  break;
944
- // 13. true.object
945
- // 14. true.string
1021
+ // 14. 1.string
1022
+ case "1.string":
1023
+ val = new TextEncoder().encode(val);
1024
+ vtype = SQLITE_DATATYPE_TEXT;
1025
+ vsize = 4 + val.byteLength;
1026
+ break;
1027
+ // 13. 1.object
946
1028
  default:
947
- // 18. true.externalbuffer
948
- if (isExternalBuffer(value)) {
1029
+ // 18. 1.externalbuffer
1030
+ if (val.constructor === ArrayBuffer) {
949
1031
  assertOrThrow(
950
1032
  !IS_BROWSER,
951
1033
  "external ArrayBuffer cannot be passed directly to wasm"
952
1034
  );
953
- assertOrThrow(
954
- externalbufferList.length <= 8,
955
- "externalbufferList.length must be less than 8"
956
- );
957
- externalbufferList.push(new DataView(value));
958
- vtype = SQLITE_DATATYPE_SHAREDARRAYBUFFER;
1035
+ vtype = SQLITE_DATATYPE_EXTERNALBUFFER;
959
1036
  vsize = 4;
960
1037
  break;
961
1038
  }
962
- // 17. true.buffer
963
- if (ArrayBuffer.isView(value)) {
964
- if (value.byteLength === 0) {
1039
+ // 17. 1.buffer
1040
+ if (ArrayBuffer.isView(val)) {
1041
+ if (val.byteLength === 0) {
965
1042
  vtype = SQLITE_DATATYPE_NULL;
966
1043
  vsize = 0;
967
1044
  break;
968
1045
  }
969
1046
  vtype = SQLITE_DATATYPE_BLOB;
970
- vsize = 4 + value.byteLength;
1047
+ vsize = 4 + val.byteLength;
971
1048
  break;
972
1049
  }
973
- // 13. true.object
974
- value = String(
975
- typeof value === "string"
976
- ? value
977
- : typeof value.toJSON === "function"
978
- ? value.toJSON()
979
- : JSON.stringify(value)
1050
+ // 13. 1.object
1051
+ val = new TextEncoder().encode(
1052
+ typeof val.toJSON === "function"
1053
+ ? val.toJSON()
1054
+ : JSON.stringify(val)
980
1055
  );
981
- // 14. true.string
982
- value = new TextEncoder().encode(value);
983
1056
  vtype = SQLITE_DATATYPE_TEXT;
984
- vsize = 4 + value.byteLength;
1057
+ vsize = 4 + val.byteLength;
985
1058
  }
986
1059
  nused = baton.getInt32(4, true);
987
1060
  nn = nused + 1 + vsize;
@@ -995,16 +1068,14 @@ function jsbatonValuePush({
995
1068
  baton = new DataView(new ArrayBuffer(
996
1069
  Math.min(2 ** Math.ceil(Math.log2(nn)), 0x7fff_ffff)
997
1070
  ));
998
- // update nalloc
1071
+ // update nallc
999
1072
  baton.setInt32(0, baton.byteLength, true);
1000
- // copy tmp to baton
1001
- new Uint8Array(
1002
- baton.buffer,
1003
- baton.byteOffset,
1004
- nused
1005
- ).set(new Uint8Array(tmp.buffer, tmp.byteOffset, nused), 0);
1073
+ // copy old-baton into new-baton
1074
+ new Uint8Array(baton.buffer, baton.byteOffset, nused).set(
1075
+ new Uint8Array(tmp.buffer, tmp.byteOffset, nused)
1076
+ );
1006
1077
  }
1007
- // push vtype
1078
+ // push vtype - 1-byte
1008
1079
  baton.setUint8(nused, vtype);
1009
1080
  // update nused
1010
1081
  baton.setInt32(4, nused + 1 + vsize, true);
@@ -1014,70 +1085,69 @@ function jsbatonValuePush({
1014
1085
  case SQLITE_DATATYPE_TEXT:
1015
1086
  // set argv[ii] to blob/text location
1016
1087
  if (argi !== undefined) {
1017
- baton.setInt32(8 + argi * 8, nused, true);
1088
+ baton.setInt32(JSBATON_OFFSET_ARGV + argi * 8, nused, true);
1018
1089
  }
1019
1090
  vsize -= 4;
1020
- // push vsize
1021
1091
  assertOrThrow(
1022
- 0 <= vsize && vsize <= 1_000_000_000,
1092
+ 0 <= vsize && vsize <= SIZEOF_BLOB_MAX,
1023
1093
  (
1024
1094
  "sqlite-blob byte-length must be within inclusive-range"
1025
- + " 0 to 1,000,000,000"
1095
+ + ` 0 to ${SIZEOF_BLOB_MAX}`
1026
1096
  )
1027
1097
  );
1098
+ // push vsize - 4-byte
1028
1099
  baton.setInt32(nused + 1, vsize, true);
1100
+ // push SQLITE-BLOB/TEXT - vsize-byte
1029
1101
  new Uint8Array(
1030
1102
  baton.buffer,
1031
- nused + 1 + 4,
1103
+ baton.byteOffset + nused + 1 + 4,
1032
1104
  vsize
1033
- ).set(new Uint8Array(value.buffer, value.byteOffset, vsize), 0);
1034
- break;
1035
- case SQLITE_DATATYPE_FLOAT:
1036
- baton.setFloat64(nused + 1, value, true);
1105
+ ).set(new Uint8Array(val.buffer, val.byteOffset, vsize));
1037
1106
  break;
1038
- case SQLITE_DATATYPE_INTEGER:
1107
+ case SQLITE_DATATYPE_EXTERNALBUFFER:
1108
+ vsize = val.byteLength;
1039
1109
  assertOrThrow(
1110
+ 0 <= vsize && vsize <= SIZEOF_BLOB_MAX,
1040
1111
  (
1041
- -9_223_372_036_854_775_808n <= value
1042
- && value <= 9_223_372_036_854_775_807n
1043
- ),
1044
- (
1045
- "sqlite-integer must be within inclusive-range "
1046
- + "-9,223,372,036,854,775,808 to 9,223,372,036,854,775,807"
1112
+ "sqlite-blob byte-length must be within inclusive-range"
1113
+ + ` 0 to ${SIZEOF_BLOB_MAX}`
1047
1114
  )
1048
1115
  );
1049
- baton.setBigInt64(nused + 1, value, true);
1050
- break;
1051
- case SQLITE_DATATYPE_SHAREDARRAYBUFFER:
1052
- vsize = value.byteLength;
1053
- // push vsize
1054
1116
  assertOrThrow(
1055
- 0 <= vsize && vsize <= 1_000_000_000,
1056
- (
1057
- "sqlite-blob byte-length must be within inclusive-range"
1058
- + " 0 to 1,000,000,000"
1059
- )
1117
+ bufi[0] < JSBATON_ARGC,
1118
+ `cannot pass more than ${JSBATON_ARGC} arraybuffers`
1060
1119
  );
1061
- baton.setInt32(nused + 1, vsize, true);
1120
+ // push externalbuffer - 4-byte
1121
+ baton.setInt32(nused + 1, bufi[0], true);
1122
+ // set buffer
1123
+ cModule._jsbatonSetArraybuffer(baton.buffer, bufi[0], val);
1124
+ // increment bufi
1125
+ bufi[0] += 1;
1126
+ // add buffer to reference_list to prevent gc during db_call.
1127
+ referenceList.push(val);
1128
+ break;
1129
+ case SQLITE_DATATYPE_FLOAT:
1130
+ // push SQLITE-REAL - 8-byte
1131
+ baton.setFloat64(nused + 1, val, true);
1132
+ break;
1133
+ case SQLITE_DATATYPE_INTEGER:
1134
+ assertInt64(val);
1135
+ // push SQLITE-INTEGER - 8-byte
1136
+ baton.setBigInt64(nused + 1, val, true);
1062
1137
  break;
1063
1138
  }
1064
1139
  return baton;
1065
1140
  }
1066
1141
 
1067
- function jsbatonValueString({
1068
- argi,
1069
- baton
1070
- }) {
1142
+ function jsonParseArraybuffer(buf) {
1071
1143
 
1072
- // This function will return string-value from <baton> at given <offset>.
1144
+ // This function will JSON.parse arraybuffer <buf>.
1073
1145
 
1074
- let offset = baton.getInt32(4 + 4 + argi * 8, true);
1075
- return new TextDecoder().decode(new Uint8Array(
1076
- baton.buffer,
1077
- offset + 1 + 4,
1078
- // remove null-terminator from string
1079
- baton.getInt32(offset + 1, true) - 1
1080
- ));
1146
+ return JSON.parse(
1147
+ IS_BROWSER
1148
+ ? new TextDecoder().decode(buf)
1149
+ : buf
1150
+ );
1081
1151
  }
1082
1152
 
1083
1153
  async function moduleFsInit() {
@@ -1149,59 +1219,6 @@ function objectDeepCopyWithKeysSorted(obj) {
1149
1219
  return sorted;
1150
1220
  }
1151
1221
 
1152
- async function sqlMessagePost(baton, cFuncName, ...argList) {
1153
-
1154
- // This function will post msg to <sqlWorker> and return result.
1155
-
1156
- let errStack;
1157
- let id;
1158
- let result;
1159
- let timeElapsed = Date.now();
1160
- // increment sqlMessageId
1161
- sqlMessageId += 1;
1162
- id = sqlMessageId;
1163
- // postMessage to web-worker
1164
- sqlWorker.postMessage(
1165
- {
1166
- argList,
1167
- baton,
1168
- cFuncName,
1169
- id
1170
- },
1171
- // transfer arraybuffer without copying
1172
- [
1173
- baton.buffer,
1174
- ...argList.filter(function (elem) {
1175
- return elem && elem.constructor === ArrayBuffer;
1176
- })
1177
- ]
1178
- );
1179
- // preserve stack-trace
1180
- errStack = new Error().stack.replace((
1181
- /.*$/m
1182
- ), "");
1183
- // await result from web-worker
1184
- result = await new Promise(function (resolve) {
1185
- sqlMessageDict[id] = resolve;
1186
- });
1187
- // cleanup sqlMessageDict
1188
- delete sqlMessageDict[id];
1189
- // debug slow postMessage
1190
- timeElapsed = Date.now() - timeElapsed;
1191
- if (timeElapsed > 500 || cFuncName === "testTimeElapsed") {
1192
- consoleError(
1193
- "sqlMessagePost - " + JSON.stringify({
1194
- cFuncName,
1195
- timeElapsed
1196
- }) + errStack
1197
- );
1198
- }
1199
- assertOrThrow(!result.errmsg, result.errmsg);
1200
- return [
1201
- result.baton, result.cFuncName, ...result.argList
1202
- ];
1203
- }
1204
-
1205
1222
  async function sqlmathInit() {
1206
1223
 
1207
1224
  // This function will init sqlmath.
@@ -1209,15 +1226,12 @@ async function sqlmathInit() {
1209
1226
  let moduleModule;
1210
1227
  dbFinalizationRegistry = (
1211
1228
  dbFinalizationRegistry
1212
- ) || new FinalizationRegistry(function ({
1213
- afterFinalization,
1214
- ptr
1215
- }) {
1229
+ ) || new FinalizationRegistry(function ({afterFinalization, ptr}) {
1216
1230
 
1217
1231
  // This function will auto-close any open sqlite3-db-pointer,
1218
1232
  // after its js-wrapper has been garbage-collected.
1219
1233
 
1220
- cCallAsync(undefined, "_dbClose", ptr[0]);
1234
+ dbCallAsync(jsbatonCreate("_dbClose"), [ptr[0]]);
1221
1235
  if (afterFinalization) {
1222
1236
  afterFinalization();
1223
1237
  }
@@ -1226,10 +1240,8 @@ async function sqlmathInit() {
1226
1240
  // Feature-detect nodejs.
1227
1241
 
1228
1242
  if (
1229
- !(
1230
- typeof process === "object"
1231
- && typeof process?.versions?.node === "string"
1232
- )
1243
+ typeof process !== "object"
1244
+ || typeof process?.versions?.node !== "string"
1233
1245
  || cModule
1234
1246
  ) {
1235
1247
  return;
@@ -1316,19 +1328,15 @@ function sqlmathWebworkerInit({
1316
1328
  if (modeTest) {
1317
1329
  sqlWorker.postMessage = function (data) {
1318
1330
  setTimeout(function () {
1319
- sqlWorker.onmessage({
1320
- data
1321
- });
1331
+ sqlWorker.onmessage({data});
1322
1332
  });
1323
1333
  };
1324
- // test cCallAsync handling-behavior
1325
- cCallAsync(undefined, "testTimeElapsed", true);
1326
- // test dbFileExportAsync handling-behavior
1327
- dbFileExportAsync({
1328
- db,
1329
- filename: "aa",
1330
- modeTest
1331
- });
1334
+ // test dbCallAsync handling-behavior
1335
+ dbCallAsync(jsbatonCreate("testTimeElapsed"), [true]);
1336
+ // test dbFileLoadAsync handling-behavior
1337
+ dbFileLoadAsync({db, filename: "aa", modeTest});
1338
+ // test jsonParseArraybuffer handling-behavior
1339
+ jsonParseArraybuffer(new TextEncoder().encode("0"));
1332
1340
  // revert IS_BROWSER
1333
1341
  IS_BROWSER = undefined;
1334
1342
  }
@@ -1339,7 +1347,6 @@ await sqlmathInit();
1339
1347
  sqlmathInit(); // coverage-hack
1340
1348
 
1341
1349
  export {
1342
- SQLITE_MAX_LENGTH2,
1343
1350
  SQLITE_OPEN_AUTOPROXY,
1344
1351
  SQLITE_OPEN_CREATE,
1345
1352
  SQLITE_OPEN_DELETEONCLOSE,
@@ -1361,6 +1368,7 @@ export {
1361
1368
  SQLITE_OPEN_TRANSIENT_DB,
1362
1369
  SQLITE_OPEN_URI,
1363
1370
  SQLITE_OPEN_WAL,
1371
+ assertInt64,
1364
1372
  assertJsonEqual,
1365
1373
  assertNumericalEqual,
1366
1374
  assertOrThrow,
@@ -1369,8 +1377,8 @@ export {
1369
1377
  dbCloseAsync,
1370
1378
  dbExecAndReturnLastBlobAsync,
1371
1379
  dbExecAsync,
1372
- dbFileExportAsync,
1373
- dbFileImportAsync,
1380
+ dbFileLoadAsync,
1381
+ dbFileSaveAsync,
1374
1382
  dbNoopAsync,
1375
1383
  dbOpenAsync,
1376
1384
  debugInline,
@@ -1378,7 +1386,8 @@ export {
1378
1386
  fsExistsUnlessTest,
1379
1387
  fsReadFileUnlessTest,
1380
1388
  fsWriteFileUnlessTest,
1381
- jsbatonValueString,
1389
+ jsbatonGetInt64,
1390
+ jsbatonGetString,
1382
1391
  noop,
1383
1392
  objectDeepCopyWithKeysSorted,
1384
1393
  sqlmathWebworkerInit,