sqlmath 2025.8.30 → 2025.9.30
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/.npmignore +4 -1
- package/CHANGELOG.md +16 -0
- package/README.md +6 -9
- package/_sqlmath.cp310-win_amd64.pyd +0 -0
- package/_sqlmath.cp311-win_amd64.pyd +0 -0
- package/_sqlmath.cp312-win_amd64.pyd +0 -0
- package/_sqlmath.cp313-win_amd64.pyd +0 -0
- package/_sqlmath.cp314-win_amd64.pyd +0 -0
- package/_sqlmath.cpython-310-darwin.so +0 -0
- package/_sqlmath.cpython-311-darwin.so +0 -0
- package/_sqlmath.cpython-312-darwin.so +0 -0
- package/_sqlmath.cpython-312-x86_64-linux-gnu.so +0 -0
- package/_sqlmath.cpython-313-darwin.so +0 -0
- package/_sqlmath.cpython-314-darwin.so +0 -0
- package/_sqlmath.cpython-314t-darwin.so +0 -0
- package/_sqlmath.napi6_darwin_arm64.node +0 -0
- package/_sqlmath.napi6_linux_x64.node +0 -0
- package/_sqlmath.napi6_win32_x64.node +0 -0
- package/_sqlmath.shell_darwin_arm64 +0 -0
- package/_sqlmath.shell_linux_x64 +0 -0
- package/_sqlmath.shell_win32_x64.exe +0 -0
- package/jslint.mjs +37 -11
- package/package.json +2 -2
- package/sqlmath.mjs +282 -161
- package/sqlmath_browser.mjs +4768 -0
- package/test.mjs +4176 -0
package/sqlmath.mjs
CHANGED
|
@@ -84,7 +84,13 @@ const SQLITE_OPEN_TRANSIENT_DB = 0x00000400; /* VFS only */
|
|
|
84
84
|
const SQLITE_OPEN_URI = 0x00000040; /* Ok for sqlite3_open_v2() */
|
|
85
85
|
const SQLITE_OPEN_WAL = 0x00080000; /* VFS only */
|
|
86
86
|
|
|
87
|
+
let DB_EXEC_PROFILE_DICT = {};
|
|
88
|
+
let DB_EXEC_PROFILE_MODE;
|
|
89
|
+
let DB_EXEC_PROFILE_SQL_LENGTH;
|
|
90
|
+
let DB_OPEN_INIT;
|
|
87
91
|
let IS_BROWSER;
|
|
92
|
+
let SQLMATH_EXE;
|
|
93
|
+
let SQLMATH_NODE;
|
|
88
94
|
let cModule;
|
|
89
95
|
let cModulePath;
|
|
90
96
|
let consoleError = console.error;
|
|
@@ -122,7 +128,7 @@ let {
|
|
|
122
128
|
let sqlMessageDict = {}; // dict of web-worker-callbacks
|
|
123
129
|
let sqlMessageId = 0;
|
|
124
130
|
let sqlWorker;
|
|
125
|
-
let version = "v2025.
|
|
131
|
+
let version = "v2025.9.30";
|
|
126
132
|
|
|
127
133
|
async function assertErrorThrownAsync(asyncFunc, regexp) {
|
|
128
134
|
|
|
@@ -213,7 +219,7 @@ async function childProcessSpawn2(command, args, option) {
|
|
|
213
219
|
let {
|
|
214
220
|
modeCapture,
|
|
215
221
|
modeDebug,
|
|
216
|
-
stdio
|
|
222
|
+
stdio = []
|
|
217
223
|
} = option;
|
|
218
224
|
if (modeDebug) {
|
|
219
225
|
consoleError(
|
|
@@ -273,43 +279,86 @@ async function childProcessSpawn2(command, args, option) {
|
|
|
273
279
|
if (npm_config_mode_test) {
|
|
274
280
|
resolve = resolve0;
|
|
275
281
|
}
|
|
276
|
-
[
|
|
282
|
+
[
|
|
283
|
+
stdout, stderr
|
|
284
|
+
] = bufList.slice(1).map(function (buf) {
|
|
277
285
|
return (
|
|
278
286
|
typeof modeCapture === "string"
|
|
279
287
|
? Buffer.concat(buf).toString(modeCapture)
|
|
280
288
|
: Buffer.concat(buf)
|
|
281
289
|
);
|
|
282
290
|
});
|
|
283
|
-
resolve(
|
|
291
|
+
resolve([
|
|
292
|
+
exitCode, stdout, stderr
|
|
293
|
+
]);
|
|
284
294
|
});
|
|
285
295
|
});
|
|
286
|
-
|
|
287
296
|
}
|
|
288
297
|
|
|
289
298
|
async function ciBuildExt({
|
|
290
|
-
modeSkip,
|
|
291
299
|
process
|
|
292
300
|
}) {
|
|
293
301
|
|
|
294
302
|
// This function will build sqlmath from c.
|
|
295
303
|
|
|
296
|
-
let
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
304
|
+
let binNodegyp;
|
|
305
|
+
let exitCode;
|
|
306
|
+
binNodegyp = modulePath.resolve(
|
|
307
|
+
modulePath.dirname(process.execPath || ""),
|
|
308
|
+
"node_modules/npm/node_modules/node-gyp/bin/node-gyp.js"
|
|
309
|
+
).replace("/bin/node_modules/", "/lib/node_modules/");
|
|
310
|
+
if (!noop(
|
|
311
|
+
await fsExistsUnlessTest(cModulePath)
|
|
312
|
+
)) {
|
|
313
|
+
await ciBuildExt1NodejsConfigure({
|
|
314
|
+
binNodegyp,
|
|
315
|
+
process
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
consoleError(
|
|
319
|
+
`ciBuildExt2Nodejs - linking lib ${modulePath.resolve(cModulePath)}`
|
|
320
|
+
);
|
|
321
|
+
[
|
|
322
|
+
exitCode
|
|
323
|
+
] = await childProcessSpawn2(
|
|
324
|
+
"sh",
|
|
325
|
+
[
|
|
326
|
+
"-c",
|
|
327
|
+
(`
|
|
328
|
+
(set -e
|
|
329
|
+
# rebuild binding
|
|
330
|
+
rm -rf build/Release/obj/SRC_SQLMATH_CUSTOM/
|
|
331
|
+
node "${binNodegyp}" build --release
|
|
332
|
+
# node "${binNodegyp}" build --release --loglevel=verbose
|
|
333
|
+
mv build/Release/binding.node "${cModulePath}"
|
|
334
|
+
mv build/Release/shell "${SQLMATH_EXE}"
|
|
335
|
+
# ugly-hack - win32-sqlite-shell doesn't like nodejs-builtin-zlib,
|
|
336
|
+
# so link with external-zlib.
|
|
337
|
+
if (uname | grep -q "MING\\|MSYS")
|
|
338
|
+
then
|
|
339
|
+
rm -f ${SQLMATH_EXE}
|
|
340
|
+
python setup.py exe_link \
|
|
341
|
+
./build/Release/SRC_SQLITE_BASE.lib \
|
|
342
|
+
./build/Release/SRC_SQLMATH_CUSTOM.lib \
|
|
343
|
+
./build/Release/obj/shell/sqlmath_external_sqlite.obj \
|
|
344
|
+
./zlib.v1.3.1.vcpkg.x64-windows-static.lib \
|
|
345
|
+
\
|
|
346
|
+
-ltcg \
|
|
347
|
+
-nologo \
|
|
348
|
+
-out:${SQLMATH_EXE} \
|
|
349
|
+
-subsystem:console
|
|
350
|
+
fi
|
|
351
|
+
)
|
|
352
|
+
`)
|
|
353
|
+
],
|
|
354
|
+
{modeDebug: npm_config_mode_debug, stdio: ["ignore", 1, 2]}
|
|
355
|
+
);
|
|
356
|
+
assertOrThrow(!exitCode, `ciBuildExt - exitCode=${exitCode}`);
|
|
308
357
|
}
|
|
309
358
|
|
|
310
359
|
async function ciBuildExt1NodejsConfigure({
|
|
311
|
-
binNodegyp
|
|
312
|
-
|
|
360
|
+
binNodegyp
|
|
361
|
+
// process
|
|
313
362
|
}) {
|
|
314
363
|
|
|
315
364
|
// This function will setup posix/win32 env for building c-extension.
|
|
@@ -340,82 +389,82 @@ SQLMATH_CFLAG_WNO_LIST=" \\
|
|
|
340
389
|
consoleError(`ciBuildExt1Nodejs - configure binding.gyp`);
|
|
341
390
|
await fsWriteFileUnlessTest("binding.gyp", JSON.stringify({
|
|
342
391
|
"target_defaults": {
|
|
343
|
-
"cflags":
|
|
344
|
-
// https://github.com/nodejs/node-gyp/blob/
|
|
392
|
+
"cflags": cflagWallList,
|
|
393
|
+
// https://github.com/nodejs/node-gyp/blob/v10.3.1/gyp/pylib/gyp/MSVSSettings.py
|
|
345
394
|
"msvs_settings": {
|
|
346
395
|
"VCCLCompilerTool": {
|
|
347
396
|
"WarnAsError": 1,
|
|
348
|
-
"WarningLevel":
|
|
397
|
+
"WarningLevel": 4
|
|
349
398
|
}
|
|
350
399
|
},
|
|
351
400
|
"xcode_settings": {
|
|
352
|
-
"OTHER_CFLAGS":
|
|
401
|
+
"OTHER_CFLAGS": cflagWallList
|
|
353
402
|
}
|
|
354
403
|
},
|
|
355
404
|
"targets": [
|
|
356
405
|
{
|
|
406
|
+
"cflags": cflagWnoList,
|
|
357
407
|
"defines": [
|
|
358
|
-
"SRC_SQLITE_BASE_C2"
|
|
359
|
-
"SRC_ZLIB_C2"
|
|
408
|
+
"SRC_SQLITE_BASE_C2"
|
|
360
409
|
],
|
|
410
|
+
"msvs_settings": {
|
|
411
|
+
"VCCLCompilerTool": {
|
|
412
|
+
"WarnAsError": 1,
|
|
413
|
+
"WarningLevel": 2
|
|
414
|
+
}
|
|
415
|
+
},
|
|
361
416
|
"sources": [
|
|
362
|
-
"sqlmath_external_sqlite.c"
|
|
363
|
-
"sqlmath_external_zlib.c"
|
|
417
|
+
"sqlmath_external_sqlite.c"
|
|
364
418
|
],
|
|
365
419
|
"target_name": "SRC_SQLITE_BASE",
|
|
366
|
-
"type": "static_library"
|
|
420
|
+
"type": "static_library",
|
|
421
|
+
"xcode_settings": {
|
|
422
|
+
"OTHER_CFLAGS": cflagWnoList
|
|
423
|
+
}
|
|
367
424
|
},
|
|
368
425
|
{
|
|
369
|
-
"cflags": cflagWallList,
|
|
370
426
|
"defines": [
|
|
371
427
|
"SRC_SQLMATH_BASE_C2",
|
|
372
428
|
"SRC_SQLMATH_CUSTOM_C2"
|
|
373
429
|
],
|
|
374
|
-
"
|
|
375
|
-
"
|
|
376
|
-
|
|
377
|
-
"WarningLevel": 4
|
|
378
|
-
}
|
|
379
|
-
},
|
|
430
|
+
"dependencies": [
|
|
431
|
+
"SRC_SQLITE_BASE"
|
|
432
|
+
],
|
|
380
433
|
"sources": [
|
|
381
434
|
"sqlmath_base.c",
|
|
382
435
|
"sqlmath_custom.c"
|
|
383
436
|
],
|
|
384
437
|
"target_name": "SRC_SQLMATH_CUSTOM",
|
|
385
|
-
"type": "static_library"
|
|
386
|
-
"xcode_settings": {
|
|
387
|
-
"OTHER_CFLAGS": cflagWallList
|
|
388
|
-
}
|
|
438
|
+
"type": "static_library"
|
|
389
439
|
},
|
|
390
440
|
{
|
|
391
|
-
"cflags": cflagWallList,
|
|
392
441
|
"defines": [
|
|
393
442
|
"SRC_SQLMATH_NODEJS_C2"
|
|
394
443
|
],
|
|
395
444
|
"dependencies": [
|
|
396
|
-
"SRC_SQLITE_BASE",
|
|
397
445
|
"SRC_SQLMATH_CUSTOM"
|
|
398
446
|
],
|
|
399
|
-
"msvs_settings": {
|
|
400
|
-
"VCCLCompilerTool": {
|
|
401
|
-
"WarnAsError": 1,
|
|
402
|
-
"WarningLevel": 4
|
|
403
|
-
}
|
|
404
|
-
},
|
|
405
447
|
"sources": [
|
|
406
448
|
"sqlmath_base.c"
|
|
407
449
|
],
|
|
408
|
-
"target_name": "binding"
|
|
409
|
-
"xcode_settings": {
|
|
410
|
-
"OTHER_CFLAGS": cflagWallList
|
|
411
|
-
}
|
|
450
|
+
"target_name": "binding"
|
|
412
451
|
},
|
|
413
452
|
{
|
|
453
|
+
"conditions": [
|
|
454
|
+
[
|
|
455
|
+
"OS==\"win\"",
|
|
456
|
+
{},
|
|
457
|
+
{
|
|
458
|
+
"libraries": [
|
|
459
|
+
"-lz"
|
|
460
|
+
]
|
|
461
|
+
}
|
|
462
|
+
]
|
|
463
|
+
],
|
|
414
464
|
"defines": [
|
|
415
465
|
"SRC_SQLITE_SHELL_C2"
|
|
416
466
|
],
|
|
417
467
|
"dependencies": [
|
|
418
|
-
"SRC_SQLITE_BASE",
|
|
419
468
|
"SRC_SQLMATH_CUSTOM"
|
|
420
469
|
],
|
|
421
470
|
"sources": [
|
|
@@ -437,66 +486,25 @@ SQLMATH_CFLAG_WNO_LIST=" \\
|
|
|
437
486
|
)
|
|
438
487
|
`)
|
|
439
488
|
],
|
|
440
|
-
{modeDebug, stdio: ["ignore", 1, 2]}
|
|
489
|
+
{modeDebug: npm_config_mode_debug, stdio: ["ignore", 1, 2]}
|
|
441
490
|
);
|
|
442
491
|
}
|
|
443
492
|
|
|
444
|
-
async function
|
|
445
|
-
binNodegyp,
|
|
446
|
-
modeDebug
|
|
447
|
-
}) {
|
|
448
|
-
|
|
449
|
-
// This function will archive <fileObj> into <fileLib>
|
|
450
|
-
|
|
451
|
-
if (!noop(
|
|
452
|
-
await fsExistsUnlessTest(cModulePath)
|
|
453
|
-
)) {
|
|
454
|
-
await ciBuildExt1NodejsConfigure({
|
|
455
|
-
binNodegyp,
|
|
456
|
-
modeDebug
|
|
457
|
-
});
|
|
458
|
-
}
|
|
459
|
-
consoleError(
|
|
460
|
-
`ciBuildExt2Nodejs - linking lib ${modulePath.resolve(cModulePath)}`
|
|
461
|
-
);
|
|
462
|
-
await childProcessSpawn2(
|
|
463
|
-
"sh",
|
|
464
|
-
[
|
|
465
|
-
"-c",
|
|
466
|
-
(`
|
|
467
|
-
(set -e
|
|
468
|
-
# rebuild binding
|
|
469
|
-
rm -rf build/Release/obj/SRC_SQLMATH_CUSTOM/
|
|
470
|
-
node "${binNodegyp}" build --release
|
|
471
|
-
mv build/Release/binding.node "${cModulePath}"
|
|
472
|
-
if [ "${process.platform}" = "win32" ]
|
|
473
|
-
then
|
|
474
|
-
mv build/Release/shell \
|
|
475
|
-
"_sqlmath.shell_${process.platform}_${process.arch}.exe"
|
|
476
|
-
else
|
|
477
|
-
mv build/Release/shell \
|
|
478
|
-
"_sqlmath.shell_${process.platform}_${process.arch}"
|
|
479
|
-
fi
|
|
480
|
-
)
|
|
481
|
-
`)
|
|
482
|
-
],
|
|
483
|
-
{modeDebug, stdio: ["ignore", 1, 2]}
|
|
484
|
-
);
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
async function dbCallAsync(baton, argList, mode) {
|
|
493
|
+
async function dbCallAsync(baton, argList, mode, db) {
|
|
488
494
|
|
|
489
495
|
// This function will call c-function dbXxx() with given <funcname>
|
|
490
496
|
// and return [<baton>, ...argList].
|
|
491
497
|
|
|
492
|
-
let db;
|
|
493
498
|
let errStack;
|
|
494
499
|
let funcname;
|
|
495
500
|
let id;
|
|
501
|
+
let profileObj;
|
|
502
|
+
let profileStart;
|
|
496
503
|
let result;
|
|
504
|
+
let sql;
|
|
497
505
|
let timeElapsed;
|
|
498
506
|
// If argList contains <db>, then mark it as busy.
|
|
499
|
-
if (mode === "
|
|
507
|
+
if (mode === "modeDbExec" || mode === "modeDbFile") {
|
|
500
508
|
// init db
|
|
501
509
|
db = argList[0];
|
|
502
510
|
assertOrThrow(
|
|
@@ -507,8 +515,44 @@ async function dbCallAsync(baton, argList, mode) {
|
|
|
507
515
|
db.ptr = db.connPool[db.ii][0];
|
|
508
516
|
// increment db.busy
|
|
509
517
|
db.busy += 1;
|
|
518
|
+
// init profileObj
|
|
519
|
+
if (DB_EXEC_PROFILE_MODE && mode === "modeDbExec") {
|
|
520
|
+
profileStart = Date.now();
|
|
521
|
+
sql = String(argList[1]);
|
|
522
|
+
// sql-hash - remove comment
|
|
523
|
+
sql = sql.replace((/(?:^|\s+?)--.*/gm), "");
|
|
524
|
+
// sql-hash - remove vowel
|
|
525
|
+
sql = sql.replace((/[aeiou]\b/gi), "\u0000$&");
|
|
526
|
+
sql = sql.replace((/([bcdfghjklmnpqrstvwxyz])[aeiou]+/gi), "$1");
|
|
527
|
+
sql = sql.replace((/\u0000([aeiou])\b/gi), "$1");
|
|
528
|
+
// sql-hash - remove underscore
|
|
529
|
+
sql = sql.replace((/_+/g), "");
|
|
530
|
+
// sql-hash - truncate long text
|
|
531
|
+
sql = sql.replace((/(\S{16})\S+/g), "$1");
|
|
532
|
+
// sql-hash - remove whitespace
|
|
533
|
+
sql = sql.replace((/\s+/g), " ");
|
|
534
|
+
sql = sql.trim().slice(0, DB_EXEC_PROFILE_SQL_LENGTH);
|
|
535
|
+
DB_EXEC_PROFILE_DICT[sql] = DB_EXEC_PROFILE_DICT[sql] || {
|
|
536
|
+
busy: 0,
|
|
537
|
+
count: 0,
|
|
538
|
+
sql,
|
|
539
|
+
timeElapsed: 0
|
|
540
|
+
};
|
|
541
|
+
profileObj = DB_EXEC_PROFILE_DICT[sql];
|
|
542
|
+
// increment profileObj.busy
|
|
543
|
+
profileObj.busy += 1;
|
|
544
|
+
profileObj.count += 1;
|
|
545
|
+
}
|
|
510
546
|
try {
|
|
511
|
-
return await dbCallAsync(
|
|
547
|
+
return await dbCallAsync(
|
|
548
|
+
baton,
|
|
549
|
+
[
|
|
550
|
+
db.ptr,
|
|
551
|
+
...argList.slice(1)
|
|
552
|
+
],
|
|
553
|
+
undefined,
|
|
554
|
+
db
|
|
555
|
+
);
|
|
512
556
|
} finally {
|
|
513
557
|
// decrement db.busy
|
|
514
558
|
db.busy -= 1;
|
|
@@ -516,6 +560,18 @@ async function dbCallAsync(baton, argList, mode) {
|
|
|
516
560
|
db.busy >= 0,
|
|
517
561
|
`dbCallAsync - invalid db.busy = ${db.busy}`
|
|
518
562
|
);
|
|
563
|
+
// update profileObj
|
|
564
|
+
if (profileObj) {
|
|
565
|
+
// decrement profileObj.busy
|
|
566
|
+
profileObj.busy -= 1;
|
|
567
|
+
assertOrThrow(
|
|
568
|
+
profileObj.busy >= 0,
|
|
569
|
+
`dbCallAsync - invalid profileObj.busy = ${profileObj.busy}`
|
|
570
|
+
);
|
|
571
|
+
if (profileObj.busy === 0) {
|
|
572
|
+
profileObj.timeElapsed += Date.now() - profileStart;
|
|
573
|
+
}
|
|
574
|
+
}
|
|
519
575
|
}
|
|
520
576
|
}
|
|
521
577
|
// copy argList to avoid side-effect
|
|
@@ -636,6 +692,10 @@ async function dbCallAsync(baton, argList, mode) {
|
|
|
636
692
|
// prepend baton to argList
|
|
637
693
|
return [result.baton, ...result.argList];
|
|
638
694
|
} catch (err) {
|
|
695
|
+
// debug db.filename
|
|
696
|
+
if (db?.filename2 || db?.filename) {
|
|
697
|
+
err.message += ` (from ${db?.filename2 || db?.filename})`;
|
|
698
|
+
}
|
|
639
699
|
err.stack += errStack;
|
|
640
700
|
assertOrThrow(undefined, err);
|
|
641
701
|
}
|
|
@@ -654,71 +714,55 @@ async function dbCloseAsync(db) {
|
|
|
654
714
|
await Promise.all(db.connPool.map(async function (ptr) {
|
|
655
715
|
let val = ptr[0];
|
|
656
716
|
ptr[0] = 0n;
|
|
657
|
-
await dbCallAsync(
|
|
717
|
+
await dbCallAsync(
|
|
718
|
+
jsbatonCreate("_dbClose"),
|
|
719
|
+
[
|
|
720
|
+
val,
|
|
721
|
+
db.filename
|
|
722
|
+
]
|
|
723
|
+
);
|
|
658
724
|
}));
|
|
659
725
|
}
|
|
660
726
|
|
|
661
|
-
function dbExecAndReturnLastBlob({
|
|
662
|
-
bindList = [],
|
|
663
|
-
db,
|
|
664
|
-
sql
|
|
665
|
-
}) {
|
|
727
|
+
function dbExecAndReturnLastBlob(option) {
|
|
666
728
|
|
|
667
729
|
// This function will exec <sql> in <db>,
|
|
668
730
|
// and return last-value retrieved from execution as raw blob/buffer.
|
|
669
731
|
|
|
670
|
-
return dbExecAsync({
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
responseType: "lastblob",
|
|
674
|
-
sql
|
|
675
|
-
});
|
|
732
|
+
return dbExecAsync(Object.assign({
|
|
733
|
+
responseType: "lastblob"
|
|
734
|
+
}, option));
|
|
676
735
|
}
|
|
677
736
|
|
|
678
|
-
async function dbExecAndReturnLastRow({
|
|
679
|
-
bindList = [],
|
|
680
|
-
db,
|
|
681
|
-
sql
|
|
682
|
-
}) {
|
|
737
|
+
async function dbExecAndReturnLastRow(option) {
|
|
683
738
|
|
|
684
739
|
// This function will exec <sql> in <db>,
|
|
685
740
|
// and return last-row or empty-object.
|
|
686
741
|
|
|
687
|
-
let result = await dbExecAsync(
|
|
742
|
+
let result = await dbExecAsync(option);
|
|
688
743
|
result = result[result.length - 1] || [];
|
|
689
744
|
result = result[result.length - 1] || {};
|
|
690
745
|
return result;
|
|
691
746
|
}
|
|
692
747
|
|
|
693
|
-
async function dbExecAndReturnLastTable({
|
|
694
|
-
bindList = [],
|
|
695
|
-
db,
|
|
696
|
-
sql
|
|
697
|
-
}) {
|
|
748
|
+
async function dbExecAndReturnLastTable(option) {
|
|
698
749
|
|
|
699
750
|
// This function will exec <sql> in <db>,
|
|
700
751
|
// and return last-table or empty-list.
|
|
701
752
|
|
|
702
|
-
let result = await dbExecAsync(
|
|
753
|
+
let result = await dbExecAsync(option);
|
|
703
754
|
result = result[result.length - 1] || [];
|
|
704
755
|
return result;
|
|
705
756
|
}
|
|
706
757
|
|
|
707
|
-
function dbExecAndReturnLastValue({
|
|
708
|
-
bindList = [],
|
|
709
|
-
db,
|
|
710
|
-
sql
|
|
711
|
-
}) {
|
|
758
|
+
function dbExecAndReturnLastValue(option) {
|
|
712
759
|
|
|
713
760
|
// This function will exec <sql> in <db>,
|
|
714
761
|
// and return last-json-value.
|
|
715
762
|
|
|
716
|
-
return dbExecAsync({
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
responseType: "lastvalue",
|
|
720
|
-
sql
|
|
721
|
-
});
|
|
763
|
+
return dbExecAsync(Object.assign({
|
|
764
|
+
responseType: "lastvalue"
|
|
765
|
+
}, option));
|
|
722
766
|
}
|
|
723
767
|
|
|
724
768
|
async function dbExecAsync({
|
|
@@ -761,7 +805,9 @@ async function dbExecAsync({
|
|
|
761
805
|
);
|
|
762
806
|
});
|
|
763
807
|
}
|
|
764
|
-
[
|
|
808
|
+
[
|
|
809
|
+
baton, ...result
|
|
810
|
+
] = await dbCallAsync(
|
|
765
811
|
baton,
|
|
766
812
|
[
|
|
767
813
|
// 0. db
|
|
@@ -785,7 +831,7 @@ async function dbExecAsync({
|
|
|
785
831
|
: 0
|
|
786
832
|
)
|
|
787
833
|
],
|
|
788
|
-
"
|
|
834
|
+
"modeDbExec"
|
|
789
835
|
);
|
|
790
836
|
result = result[0];
|
|
791
837
|
if (!IS_BROWSER) {
|
|
@@ -800,12 +846,13 @@ async function dbExecAsync({
|
|
|
800
846
|
switch (responseType) {
|
|
801
847
|
case "arraybuffer":
|
|
802
848
|
case "lastblob":
|
|
803
|
-
|
|
849
|
+
break;
|
|
804
850
|
case "lastvalue":
|
|
805
851
|
case "list":
|
|
806
|
-
|
|
852
|
+
result = jsonParseArraybuffer(result);
|
|
853
|
+
break;
|
|
807
854
|
default:
|
|
808
|
-
|
|
855
|
+
result = jsonParseArraybuffer(result).map(function (table) {
|
|
809
856
|
let colList = table.shift();
|
|
810
857
|
return table.map(function (row) {
|
|
811
858
|
let dict = {};
|
|
@@ -816,6 +863,52 @@ async function dbExecAsync({
|
|
|
816
863
|
});
|
|
817
864
|
});
|
|
818
865
|
}
|
|
866
|
+
return result;
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
function dbExecProfile({
|
|
870
|
+
limit = 20,
|
|
871
|
+
lineLength = 80,
|
|
872
|
+
modeInit,
|
|
873
|
+
sqlLength = 256
|
|
874
|
+
}) {
|
|
875
|
+
|
|
876
|
+
// This function will profile dbExecAsync.
|
|
877
|
+
|
|
878
|
+
let result;
|
|
879
|
+
if (modeInit && !DB_EXEC_PROFILE_MODE) {
|
|
880
|
+
DB_EXEC_PROFILE_MODE = Date.now();
|
|
881
|
+
DB_EXEC_PROFILE_SQL_LENGTH = sqlLength;
|
|
882
|
+
process.on("exit", function () {
|
|
883
|
+
console.error(dbExecProfile({
|
|
884
|
+
limit,
|
|
885
|
+
lineLength
|
|
886
|
+
}));
|
|
887
|
+
});
|
|
888
|
+
return;
|
|
889
|
+
}
|
|
890
|
+
result = Object.values(DB_EXEC_PROFILE_DICT);
|
|
891
|
+
result.sort(function (aa, bb) {
|
|
892
|
+
return ((bb.timeElapsed - aa.timeElapsed) || (bb.count - aa.count));
|
|
893
|
+
});
|
|
894
|
+
result = result.slice(0, limit).map(function ({
|
|
895
|
+
count,
|
|
896
|
+
sql,
|
|
897
|
+
timeElapsed
|
|
898
|
+
}, ii) {
|
|
899
|
+
return String(
|
|
900
|
+
`${Number(ii + 1).toFixed(0).padStart(2, " ")}.`
|
|
901
|
+
+ ` ${timeElapsed.toFixed(0).padStart(4)}`
|
|
902
|
+
+ ` ${count.toFixed(0).padStart(3)}`
|
|
903
|
+
+ " " + JSON.stringify(sql)
|
|
904
|
+
).slice(0, lineLength);
|
|
905
|
+
}).join("\n");
|
|
906
|
+
result = (
|
|
907
|
+
`\ndbExecProfile:\n`
|
|
908
|
+
+ ` # time cnt sql\n`
|
|
909
|
+
+ `${result}\n`
|
|
910
|
+
);
|
|
911
|
+
return result;
|
|
819
912
|
}
|
|
820
913
|
|
|
821
914
|
async function dbFileLoadAsync({
|
|
@@ -844,7 +937,7 @@ async function dbFileLoadAsync({
|
|
|
844
937
|
// 4. dbData - same position as dbOpenAsync
|
|
845
938
|
dbData
|
|
846
939
|
],
|
|
847
|
-
"
|
|
940
|
+
"modeDbFile"
|
|
848
941
|
);
|
|
849
942
|
}
|
|
850
943
|
if (modeNoop) {
|
|
@@ -857,6 +950,7 @@ async function dbFileLoadAsync({
|
|
|
857
950
|
typeof filename === "string" && filename,
|
|
858
951
|
`invalid filename ${filename}`
|
|
859
952
|
);
|
|
953
|
+
db.filename2 = filename;
|
|
860
954
|
// Save to tmpfile and then atomically-rename to actual-filename.
|
|
861
955
|
if (moduleFs && modeSave) {
|
|
862
956
|
filename2 = filename;
|
|
@@ -898,13 +992,16 @@ async function dbNoopAsync(...argList) {
|
|
|
898
992
|
|
|
899
993
|
// This function will do nothing except return <argList>.
|
|
900
994
|
|
|
901
|
-
return await dbCallAsync(
|
|
995
|
+
return await dbCallAsync(
|
|
996
|
+
jsbatonCreate("_dbNoop"),
|
|
997
|
+
argList
|
|
998
|
+
);
|
|
902
999
|
}
|
|
903
1000
|
|
|
904
1001
|
async function dbOpenAsync({
|
|
905
1002
|
afterFinalization,
|
|
906
1003
|
dbData,
|
|
907
|
-
filename,
|
|
1004
|
+
filename = ":memory:",
|
|
908
1005
|
flags,
|
|
909
1006
|
threadCount = 1
|
|
910
1007
|
}) {
|
|
@@ -919,7 +1016,7 @@ async function dbOpenAsync({
|
|
|
919
1016
|
// );
|
|
920
1017
|
let connPool;
|
|
921
1018
|
let db = {busy: 0, filename, ii: 0};
|
|
922
|
-
let
|
|
1019
|
+
let libLgbm;
|
|
923
1020
|
assertOrThrow(typeof filename === "string", `invalid filename ${filename}`);
|
|
924
1021
|
assertOrThrow(
|
|
925
1022
|
!dbData || isExternalBuffer(dbData),
|
|
@@ -950,19 +1047,18 @@ async function dbOpenAsync({
|
|
|
950
1047
|
return ptr;
|
|
951
1048
|
}));
|
|
952
1049
|
db.connPool = connPool;
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
}).catch(noop);
|
|
1050
|
+
if (!IS_BROWSER && !DB_OPEN_INIT) {
|
|
1051
|
+
DB_OPEN_INIT = true;
|
|
1052
|
+
// init lgbm
|
|
1053
|
+
libLgbm = process.platform;
|
|
1054
|
+
libLgbm = libLgbm.replace("darwin", "lib_lightgbm.dylib");
|
|
1055
|
+
libLgbm = libLgbm.replace("win32", "lib_lightgbm.dll");
|
|
1056
|
+
libLgbm = libLgbm.replace(process.platform, "lib_lightgbm.so");
|
|
1057
|
+
libLgbm = `${import.meta.dirname}/sqlmath/${libLgbm}`;
|
|
1058
|
+
await dbExecAsync({
|
|
1059
|
+
db,
|
|
1060
|
+
sql: `SELECT LGBM_DLOPEN('${libLgbm}');`
|
|
1061
|
+
});
|
|
966
1062
|
}
|
|
967
1063
|
return db;
|
|
968
1064
|
}
|
|
@@ -1609,6 +1705,17 @@ async function moduleFsInit() {
|
|
|
1609
1705
|
while (moduleFsInitResolveList.length > 0) {
|
|
1610
1706
|
moduleFsInitResolveList.shift()();
|
|
1611
1707
|
}
|
|
1708
|
+
SQLMATH_NODE = `_sqlmath.napi6_${process.platform}_${process.arch}.node`;
|
|
1709
|
+
SQLMATH_EXE = (
|
|
1710
|
+
`_sqlmath.shell_${process.platform}_${process.arch}`
|
|
1711
|
+
+ process.platform.replace(
|
|
1712
|
+
"win32",
|
|
1713
|
+
".exe"
|
|
1714
|
+
).replace(
|
|
1715
|
+
process.platform,
|
|
1716
|
+
""
|
|
1717
|
+
)
|
|
1718
|
+
);
|
|
1612
1719
|
}
|
|
1613
1720
|
|
|
1614
1721
|
function noop(val) {
|
|
@@ -1654,7 +1761,12 @@ async function sqlmathInit() {
|
|
|
1654
1761
|
// This function will auto-close any open sqlite3-db-pointer,
|
|
1655
1762
|
// after its js-wrapper has been garbage-collected.
|
|
1656
1763
|
|
|
1657
|
-
dbCallAsync(
|
|
1764
|
+
dbCallAsync(
|
|
1765
|
+
jsbatonCreate("_dbClose"),
|
|
1766
|
+
[
|
|
1767
|
+
ptr[0]
|
|
1768
|
+
]
|
|
1769
|
+
);
|
|
1658
1770
|
if (afterFinalization) {
|
|
1659
1771
|
afterFinalization();
|
|
1660
1772
|
}
|
|
@@ -1683,7 +1795,7 @@ async function sqlmathInit() {
|
|
|
1683
1795
|
moduleChildProcessSpawn = moduleChildProcess.spawn;
|
|
1684
1796
|
cModulePath = moduleUrl.fileURLToPath(import.meta.url).replace(
|
|
1685
1797
|
(/\bsqlmath\.mjs$/),
|
|
1686
|
-
|
|
1798
|
+
SQLMATH_NODE
|
|
1687
1799
|
);
|
|
1688
1800
|
|
|
1689
1801
|
// Import napi c-addon.
|
|
@@ -1755,7 +1867,12 @@ function sqlmathWebworkerInit({
|
|
|
1755
1867
|
});
|
|
1756
1868
|
};
|
|
1757
1869
|
// test dbCallAsync handling-behavior
|
|
1758
|
-
dbCallAsync(
|
|
1870
|
+
dbCallAsync(
|
|
1871
|
+
jsbatonCreate("testTimeElapsed"),
|
|
1872
|
+
[
|
|
1873
|
+
true
|
|
1874
|
+
]
|
|
1875
|
+
);
|
|
1759
1876
|
// test dbFileLoadAsync handling-behavior
|
|
1760
1877
|
dbFileLoadAsync({db, filename: "aa", modeTest});
|
|
1761
1878
|
// test jsonParseArraybuffer handling-behavior
|
|
@@ -1779,6 +1896,7 @@ await sqlmathInit();
|
|
|
1779
1896
|
sqlmathInit(); // coverage-hack
|
|
1780
1897
|
|
|
1781
1898
|
export {
|
|
1899
|
+
DB_EXEC_PROFILE_DICT,
|
|
1782
1900
|
LGBM_DTYPE_FLOAT32,
|
|
1783
1901
|
LGBM_DTYPE_FLOAT64,
|
|
1784
1902
|
LGBM_DTYPE_INT32,
|
|
@@ -1812,6 +1930,8 @@ export {
|
|
|
1812
1930
|
SQLITE_OPEN_TRANSIENT_DB,
|
|
1813
1931
|
SQLITE_OPEN_URI,
|
|
1814
1932
|
SQLITE_OPEN_WAL,
|
|
1933
|
+
SQLMATH_EXE,
|
|
1934
|
+
SQLMATH_NODE,
|
|
1815
1935
|
assertErrorThrownAsync,
|
|
1816
1936
|
assertInt64,
|
|
1817
1937
|
assertJsonEqual,
|
|
@@ -1825,6 +1945,7 @@ export {
|
|
|
1825
1945
|
dbExecAndReturnLastTable,
|
|
1826
1946
|
dbExecAndReturnLastValue,
|
|
1827
1947
|
dbExecAsync,
|
|
1948
|
+
dbExecProfile,
|
|
1828
1949
|
dbFileLoadAsync,
|
|
1829
1950
|
dbFileSaveAsync,
|
|
1830
1951
|
dbNoopAsync,
|