sqlmath 2026.4.30 → 2026.6.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 +1 -1
- package/CHANGELOG.md +22 -0
- package/README.md +6 -6
- package/_sqlmath.napi6_darwin_arm64.node +0 -0
- package/_sqlmath.napi6_darwin_x64.node +0 -0
- package/_sqlmath.napi6_win32_x64.node +0 -0
- package/_sqlmath.shell_darwin_arm64 +0 -0
- package/_sqlmath.shell_darwin_x64 +0 -0
- package/_sqlmath.shell_win32_x64.exe +0 -0
- package/jslint.mjs +1937 -1526
- package/package.json +1 -1
- package/sqlmath.mjs +244 -159
- package/sqlmath_browser.mjs +10 -59
- package/sqlmath_wasm.js +2 -2
- package/test.mjs +22 -12
- /package/{lib_lightgbm_darwin_arm64.dylib → sqlmath/lib_lightgbm_darwin_arm64.dylib} +0 -0
- /package/{lib_lightgbm_darwin_x64.dylib → sqlmath/lib_lightgbm_darwin_x64.dylib} +0 -0
- /package/{lib_lightgbm_linux_x64.so → sqlmath/lib_lightgbm_linux_x64.so} +0 -0
- /package/{lib_lightgbm_win32_x64.dll → sqlmath/lib_lightgbm_win32_x64.dll} +0 -0
package/package.json
CHANGED
package/sqlmath.mjs
CHANGED
|
@@ -20,6 +20,11 @@
|
|
|
20
20
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
21
|
// SOFTWARE.
|
|
22
22
|
|
|
23
|
+
/*
|
|
24
|
+
sh one-liner:
|
|
25
|
+
sh jslint_ci.sh shCiBuildWasm
|
|
26
|
+
sh jslint_ci.sh shSqlmathUpdate
|
|
27
|
+
*/
|
|
23
28
|
|
|
24
29
|
/*jslint beta, bitwise, name, node*/
|
|
25
30
|
/*global FinalizationRegistry*/
|
|
@@ -100,14 +105,14 @@ let debugInline = (function () {
|
|
|
100
105
|
let __consoleError = function () {
|
|
101
106
|
return;
|
|
102
107
|
};
|
|
103
|
-
function debug(...
|
|
108
|
+
function debug(...argList) {
|
|
104
109
|
|
|
105
|
-
// This function will print <
|
|
110
|
+
// This function will print <argList> to stderr and then return <argList>[0].
|
|
106
111
|
|
|
107
112
|
__consoleError("\n\ndebugInline");
|
|
108
|
-
__consoleError(...
|
|
113
|
+
__consoleError(...argList);
|
|
109
114
|
__consoleError("\n");
|
|
110
|
-
return
|
|
115
|
+
return argList[0];
|
|
111
116
|
}
|
|
112
117
|
debug(); // Coverage-hack.
|
|
113
118
|
__consoleError = console.error; //jslint-ignore-line
|
|
@@ -128,7 +133,7 @@ let {
|
|
|
128
133
|
let sqlMessageDict = {}; // dict of web-worker-callbacks
|
|
129
134
|
let sqlMessageId = 0;
|
|
130
135
|
let sqlWorker;
|
|
131
|
-
let version = "v2026.
|
|
136
|
+
let version = "v2026.6.30";
|
|
132
137
|
|
|
133
138
|
async function assertErrorThrownAsync(asyncFunc, regexp) {
|
|
134
139
|
|
|
@@ -487,6 +492,197 @@ SQLMATH_CFLAG_WNO_LIST=" \\
|
|
|
487
492
|
);
|
|
488
493
|
}
|
|
489
494
|
|
|
495
|
+
function csvFromListofList({
|
|
496
|
+
colList,
|
|
497
|
+
rowList
|
|
498
|
+
}) {
|
|
499
|
+
// this function will convert json <rowList> to csv with given <colList>
|
|
500
|
+
let data = JSON.stringify([[colList], rowList].flat(), undefined, 1);
|
|
501
|
+
// convert data to csv
|
|
502
|
+
data = data.replace((
|
|
503
|
+
/\n /g
|
|
504
|
+
), "");
|
|
505
|
+
data = data.replace((
|
|
506
|
+
/\n \[/g
|
|
507
|
+
), "");
|
|
508
|
+
data = data.replace((
|
|
509
|
+
/\n \],?/g
|
|
510
|
+
), "\r\n");
|
|
511
|
+
data = data.slice(1, -2);
|
|
512
|
+
// sqlite-strings are c-strings which should never contain null-char
|
|
513
|
+
data = data.replace((
|
|
514
|
+
/\u0000/g
|
|
515
|
+
), "");
|
|
516
|
+
// hide double-backslash `\\\\` as null-char
|
|
517
|
+
data = data.replace((
|
|
518
|
+
/\\\\/g
|
|
519
|
+
), "\u0000");
|
|
520
|
+
// escape double-quote `\\"` to `""`
|
|
521
|
+
data = data.replace((
|
|
522
|
+
/\\"/g
|
|
523
|
+
), "\"\"");
|
|
524
|
+
// replace newline with space
|
|
525
|
+
data = data.replace((
|
|
526
|
+
/\\r\\n|\\r|\\n/g
|
|
527
|
+
), " ");
|
|
528
|
+
// restore double-backslash `\\\\` from null-char
|
|
529
|
+
data = data.replace((
|
|
530
|
+
/\u0000/g
|
|
531
|
+
), "\\\\");
|
|
532
|
+
return data;
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
function csvToListofList({
|
|
536
|
+
csv
|
|
537
|
+
}) {
|
|
538
|
+
// This function will convert <csv>-text to json list-of-list.
|
|
539
|
+
//
|
|
540
|
+
// https://tools.ietf.org/html/rfc4180#section-2
|
|
541
|
+
// Definition of the CSV Format
|
|
542
|
+
// While there are various specifications and implementations for the
|
|
543
|
+
// CSV format (for ex. [4], [5], [6] and [7]), there is no formal
|
|
544
|
+
// specification in existence, which allows for a wide variety of
|
|
545
|
+
// interpretations of CSV files. This section documents the format that
|
|
546
|
+
// seems to be followed by most implementations:
|
|
547
|
+
//
|
|
548
|
+
// 1. Each record is located on a separate line, delimited by a line
|
|
549
|
+
// break (CRLF). For example:
|
|
550
|
+
// aaa,bbb,ccc CRLF
|
|
551
|
+
// zzz,yyy,xxx CRLF
|
|
552
|
+
//
|
|
553
|
+
// 2. The last record in the file may or may not have an ending line
|
|
554
|
+
// break. For example:
|
|
555
|
+
// aaa,bbb,ccc CRLF
|
|
556
|
+
// zzz,yyy,xxx
|
|
557
|
+
//
|
|
558
|
+
// 3. There maybe an optional header line appearing as the first line
|
|
559
|
+
// of the file with the same format as normal record lines. This
|
|
560
|
+
// header will contain names corresponding to the fields in the file
|
|
561
|
+
// and should contain the same number of fields as the records in
|
|
562
|
+
// the rest of the file (the presence or absence of the header line
|
|
563
|
+
// should be indicated via the optional "header" parameter of this
|
|
564
|
+
// MIME type). For example:
|
|
565
|
+
// field_name,field_name,field_name CRLF
|
|
566
|
+
// aaa,bbb,ccc CRLF
|
|
567
|
+
// zzz,yyy,xxx CRLF
|
|
568
|
+
//
|
|
569
|
+
// 4. Within the header and each record, there may be one or more
|
|
570
|
+
// fields, separated by commas. Each line should contain the same
|
|
571
|
+
// number of fields throughout the file. Spaces are considered part
|
|
572
|
+
// of a field and should not be ignored. The last field in the
|
|
573
|
+
// record must not be followed by a comma. For example:
|
|
574
|
+
// aaa,bbb,ccc
|
|
575
|
+
//
|
|
576
|
+
// 5. Each field may or may not be enclosed in double quotes (however
|
|
577
|
+
// some programs, such as Microsoft Excel, do not use double quotes
|
|
578
|
+
// at all). If fields are not enclosed with double quotes, then
|
|
579
|
+
// double quotes may not appear inside the fields. For example:
|
|
580
|
+
// "aaa","bbb","ccc" CRLF
|
|
581
|
+
// zzz,yyy,xxx
|
|
582
|
+
//
|
|
583
|
+
// 6. Fields containing line breaks (CRLF), double quotes, and commas
|
|
584
|
+
// should be enclosed in double-quotes. For example:
|
|
585
|
+
// "aaa","b CRLF
|
|
586
|
+
// bb","ccc" CRLF
|
|
587
|
+
// zzz,yyy,xxx
|
|
588
|
+
//
|
|
589
|
+
// 7. If double-quotes are used to enclose fields, then a double-quote
|
|
590
|
+
// appearing inside a field must be escaped by preceding it with
|
|
591
|
+
// another double quote. For example:
|
|
592
|
+
// "aaa","b""bb","ccc"
|
|
593
|
+
let match;
|
|
594
|
+
let quote;
|
|
595
|
+
let rgx;
|
|
596
|
+
let row;
|
|
597
|
+
let rowList;
|
|
598
|
+
let val;
|
|
599
|
+
// normalize "\r\n" to "\n"
|
|
600
|
+
csv = csv.trimEnd().replace((
|
|
601
|
+
/\r\n?/gu
|
|
602
|
+
), "\n") + "\n";
|
|
603
|
+
rgx = (
|
|
604
|
+
/(.*?)(""|"|,|\n)/gu
|
|
605
|
+
);
|
|
606
|
+
rowList = [];
|
|
607
|
+
// reset row
|
|
608
|
+
row = [];
|
|
609
|
+
val = "";
|
|
610
|
+
while (true) {
|
|
611
|
+
match = rgx.exec(csv);
|
|
612
|
+
if (!match) {
|
|
613
|
+
// 2. The last record in the file may or may not have an ending line
|
|
614
|
+
// break. For example:
|
|
615
|
+
// aaa,bbb,ccc CRLF
|
|
616
|
+
// zzz,yyy,xxx
|
|
617
|
+
if (!row.length) {
|
|
618
|
+
break;
|
|
619
|
+
}
|
|
620
|
+
// // if eof missing crlf, then mock it
|
|
621
|
+
// rgx.lastIndex = csv.length;
|
|
622
|
+
// match = [
|
|
623
|
+
// "\n", "", "\n"
|
|
624
|
+
// ];
|
|
625
|
+
}
|
|
626
|
+
// build val
|
|
627
|
+
val += match[1];
|
|
628
|
+
if (match[2] === "\"") {
|
|
629
|
+
// 5. Each field may or may not be enclosed in double quotes (however
|
|
630
|
+
// some programs, such as Microsoft Excel, do not use double quotes
|
|
631
|
+
// at all). If fields are not enclosed with double quotes, then
|
|
632
|
+
// double quotes may not appear inside the fields. For example:
|
|
633
|
+
// "aaa","bbb","ccc" CRLF
|
|
634
|
+
// zzz,yyy,xxx
|
|
635
|
+
quote = !quote;
|
|
636
|
+
} else if (quote) {
|
|
637
|
+
// 7. If double-quotes are used to enclose fields, then a double-quote
|
|
638
|
+
// appearing inside a field must be escaped by preceding it with
|
|
639
|
+
// another double quote. For example:
|
|
640
|
+
// "aaa","b""bb","ccc"
|
|
641
|
+
if (match[2] === "\"\"") {
|
|
642
|
+
val += "\"";
|
|
643
|
+
// 6. Fields containing line breaks (CRLF), double quotes, and commas
|
|
644
|
+
// should be enclosed in double-quotes. For example:
|
|
645
|
+
// "aaa","b CRLF
|
|
646
|
+
// bb","ccc" CRLF
|
|
647
|
+
// zzz,yyy,xxx
|
|
648
|
+
} else {
|
|
649
|
+
val += match[2];
|
|
650
|
+
}
|
|
651
|
+
} else if (match[2] === ",") {
|
|
652
|
+
// 4. Within the header and each record, there may be one or more
|
|
653
|
+
// fields, separated by commas. Each line should contain the same
|
|
654
|
+
// number of fields throughout the file. Spaces are considered part
|
|
655
|
+
// of a field and should not be ignored. The last field in the
|
|
656
|
+
// record must not be followed by a comma. For example:
|
|
657
|
+
// aaa,bbb,ccc
|
|
658
|
+
// delimit val
|
|
659
|
+
row.push(val);
|
|
660
|
+
val = "";
|
|
661
|
+
} else if (match[2] === "\n") {
|
|
662
|
+
// 1. Each record is located on a separate line, delimited by a line
|
|
663
|
+
// break (CRLF). For example:
|
|
664
|
+
// aaa,bbb,ccc CRLF
|
|
665
|
+
// zzz,yyy,xxx CRLF
|
|
666
|
+
// delimit val
|
|
667
|
+
row.push(val);
|
|
668
|
+
val = "";
|
|
669
|
+
// append row
|
|
670
|
+
rowList.push(row);
|
|
671
|
+
// reset row
|
|
672
|
+
row = [];
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
// // append val
|
|
676
|
+
// if (val) {
|
|
677
|
+
// row.push(val);
|
|
678
|
+
// }
|
|
679
|
+
// // append row
|
|
680
|
+
// if (row.length) {
|
|
681
|
+
// rowList.push(row);
|
|
682
|
+
// }
|
|
683
|
+
return rowList;
|
|
684
|
+
}
|
|
685
|
+
|
|
490
686
|
async function dbCallAsync(baton, argList, mode, db) {
|
|
491
687
|
|
|
492
688
|
// This function will call c-function dbXxx() with given <funcname>
|
|
@@ -517,7 +713,7 @@ async function dbCallAsync(baton, argList, mode, db) {
|
|
|
517
713
|
profileStart = Date.now();
|
|
518
714
|
sql = String(argList[1]);
|
|
519
715
|
// sql-hash - remove comment
|
|
520
|
-
sql = sql.replace((
|
|
716
|
+
sql = sql.replace((/\s*?--.*?$/gm), "");
|
|
521
717
|
// sql-hash - remove vowel
|
|
522
718
|
sql = sql.replace((/[aeiou]\b/gi), "\u0000$&");
|
|
523
719
|
sql = sql.replace((/([bcdfghjklmnpqrstvwxyz])[aeiou]+/gi), "$1");
|
|
@@ -1093,7 +1289,7 @@ async function dbTableImportAsync({
|
|
|
1093
1289
|
}
|
|
1094
1290
|
switch (mode) {
|
|
1095
1291
|
case "csv":
|
|
1096
|
-
rowList =
|
|
1292
|
+
rowList = csvToListofList({
|
|
1097
1293
|
csv: textData
|
|
1098
1294
|
});
|
|
1099
1295
|
break;
|
|
@@ -1215,7 +1411,7 @@ async function fsExistsUnlessTest(file, mode) {
|
|
|
1215
1411
|
return false;
|
|
1216
1412
|
}
|
|
1217
1413
|
try {
|
|
1218
|
-
await moduleFs.promises.access(file);
|
|
1414
|
+
await moduleFs.promises.access(file, moduleFs.promises.constants.F_OK);
|
|
1219
1415
|
return true;
|
|
1220
1416
|
} catch (ignore) {
|
|
1221
1417
|
return false;
|
|
@@ -1521,157 +1717,6 @@ function jsonParseArraybuffer(buf) {
|
|
|
1521
1717
|
);
|
|
1522
1718
|
}
|
|
1523
1719
|
|
|
1524
|
-
function jsonRowListFromCsv({
|
|
1525
|
-
csv
|
|
1526
|
-
}) {
|
|
1527
|
-
// This function will convert <csv>-text to json list-of-list.
|
|
1528
|
-
//
|
|
1529
|
-
// https://tools.ietf.org/html/rfc4180#section-2
|
|
1530
|
-
// Definition of the CSV Format
|
|
1531
|
-
// While there are various specifications and implementations for the
|
|
1532
|
-
// CSV format (for ex. [4], [5], [6] and [7]), there is no formal
|
|
1533
|
-
// specification in existence, which allows for a wide variety of
|
|
1534
|
-
// interpretations of CSV files. This section documents the format that
|
|
1535
|
-
// seems to be followed by most implementations:
|
|
1536
|
-
//
|
|
1537
|
-
// 1. Each record is located on a separate line, delimited by a line
|
|
1538
|
-
// break (CRLF). For example:
|
|
1539
|
-
// aaa,bbb,ccc CRLF
|
|
1540
|
-
// zzz,yyy,xxx CRLF
|
|
1541
|
-
//
|
|
1542
|
-
// 2. The last record in the file may or may not have an ending line
|
|
1543
|
-
// break. For example:
|
|
1544
|
-
// aaa,bbb,ccc CRLF
|
|
1545
|
-
// zzz,yyy,xxx
|
|
1546
|
-
//
|
|
1547
|
-
// 3. There maybe an optional header line appearing as the first line
|
|
1548
|
-
// of the file with the same format as normal record lines. This
|
|
1549
|
-
// header will contain names corresponding to the fields in the file
|
|
1550
|
-
// and should contain the same number of fields as the records in
|
|
1551
|
-
// the rest of the file (the presence or absence of the header line
|
|
1552
|
-
// should be indicated via the optional "header" parameter of this
|
|
1553
|
-
// MIME type). For example:
|
|
1554
|
-
// field_name,field_name,field_name CRLF
|
|
1555
|
-
// aaa,bbb,ccc CRLF
|
|
1556
|
-
// zzz,yyy,xxx CRLF
|
|
1557
|
-
//
|
|
1558
|
-
// 4. Within the header and each record, there may be one or more
|
|
1559
|
-
// fields, separated by commas. Each line should contain the same
|
|
1560
|
-
// number of fields throughout the file. Spaces are considered part
|
|
1561
|
-
// of a field and should not be ignored. The last field in the
|
|
1562
|
-
// record must not be followed by a comma. For example:
|
|
1563
|
-
// aaa,bbb,ccc
|
|
1564
|
-
//
|
|
1565
|
-
// 5. Each field may or may not be enclosed in double quotes (however
|
|
1566
|
-
// some programs, such as Microsoft Excel, do not use double quotes
|
|
1567
|
-
// at all). If fields are not enclosed with double quotes, then
|
|
1568
|
-
// double quotes may not appear inside the fields. For example:
|
|
1569
|
-
// "aaa","bbb","ccc" CRLF
|
|
1570
|
-
// zzz,yyy,xxx
|
|
1571
|
-
//
|
|
1572
|
-
// 6. Fields containing line breaks (CRLF), double quotes, and commas
|
|
1573
|
-
// should be enclosed in double-quotes. For example:
|
|
1574
|
-
// "aaa","b CRLF
|
|
1575
|
-
// bb","ccc" CRLF
|
|
1576
|
-
// zzz,yyy,xxx
|
|
1577
|
-
//
|
|
1578
|
-
// 7. If double-quotes are used to enclose fields, then a double-quote
|
|
1579
|
-
// appearing inside a field must be escaped by preceding it with
|
|
1580
|
-
// another double quote. For example:
|
|
1581
|
-
// "aaa","b""bb","ccc"
|
|
1582
|
-
let match;
|
|
1583
|
-
let quote;
|
|
1584
|
-
let rgx;
|
|
1585
|
-
let row;
|
|
1586
|
-
let rowList;
|
|
1587
|
-
let val;
|
|
1588
|
-
// normalize "\r\n" to "\n"
|
|
1589
|
-
csv = csv.trimEnd().replace((
|
|
1590
|
-
/\r\n?/gu
|
|
1591
|
-
), "\n") + "\n";
|
|
1592
|
-
rgx = (
|
|
1593
|
-
/(.*?)(""|"|,|\n)/gu
|
|
1594
|
-
);
|
|
1595
|
-
rowList = [];
|
|
1596
|
-
// reset row
|
|
1597
|
-
row = [];
|
|
1598
|
-
val = "";
|
|
1599
|
-
while (true) {
|
|
1600
|
-
match = rgx.exec(csv);
|
|
1601
|
-
if (!match) {
|
|
1602
|
-
// 2. The last record in the file may or may not have an ending line
|
|
1603
|
-
// break. For example:
|
|
1604
|
-
// aaa,bbb,ccc CRLF
|
|
1605
|
-
// zzz,yyy,xxx
|
|
1606
|
-
if (!row.length) {
|
|
1607
|
-
break;
|
|
1608
|
-
}
|
|
1609
|
-
// // if eof missing crlf, then mock it
|
|
1610
|
-
// rgx.lastIndex = csv.length;
|
|
1611
|
-
// match = [
|
|
1612
|
-
// "\n", "", "\n"
|
|
1613
|
-
// ];
|
|
1614
|
-
}
|
|
1615
|
-
// build val
|
|
1616
|
-
val += match[1];
|
|
1617
|
-
if (match[2] === "\"") {
|
|
1618
|
-
// 5. Each field may or may not be enclosed in double quotes (however
|
|
1619
|
-
// some programs, such as Microsoft Excel, do not use double quotes
|
|
1620
|
-
// at all). If fields are not enclosed with double quotes, then
|
|
1621
|
-
// double quotes may not appear inside the fields. For example:
|
|
1622
|
-
// "aaa","bbb","ccc" CRLF
|
|
1623
|
-
// zzz,yyy,xxx
|
|
1624
|
-
quote = !quote;
|
|
1625
|
-
} else if (quote) {
|
|
1626
|
-
// 7. If double-quotes are used to enclose fields, then a double-quote
|
|
1627
|
-
// appearing inside a field must be escaped by preceding it with
|
|
1628
|
-
// another double quote. For example:
|
|
1629
|
-
// "aaa","b""bb","ccc"
|
|
1630
|
-
if (match[2] === "\"\"") {
|
|
1631
|
-
val += "\"";
|
|
1632
|
-
// 6. Fields containing line breaks (CRLF), double quotes, and commas
|
|
1633
|
-
// should be enclosed in double-quotes. For example:
|
|
1634
|
-
// "aaa","b CRLF
|
|
1635
|
-
// bb","ccc" CRLF
|
|
1636
|
-
// zzz,yyy,xxx
|
|
1637
|
-
} else {
|
|
1638
|
-
val += match[2];
|
|
1639
|
-
}
|
|
1640
|
-
} else if (match[2] === ",") {
|
|
1641
|
-
// 4. Within the header and each record, there may be one or more
|
|
1642
|
-
// fields, separated by commas. Each line should contain the same
|
|
1643
|
-
// number of fields throughout the file. Spaces are considered part
|
|
1644
|
-
// of a field and should not be ignored. The last field in the
|
|
1645
|
-
// record must not be followed by a comma. For example:
|
|
1646
|
-
// aaa,bbb,ccc
|
|
1647
|
-
// delimit val
|
|
1648
|
-
row.push(val);
|
|
1649
|
-
val = "";
|
|
1650
|
-
} else if (match[2] === "\n") {
|
|
1651
|
-
// 1. Each record is located on a separate line, delimited by a line
|
|
1652
|
-
// break (CRLF). For example:
|
|
1653
|
-
// aaa,bbb,ccc CRLF
|
|
1654
|
-
// zzz,yyy,xxx CRLF
|
|
1655
|
-
// delimit val
|
|
1656
|
-
row.push(val);
|
|
1657
|
-
val = "";
|
|
1658
|
-
// append row
|
|
1659
|
-
rowList.push(row);
|
|
1660
|
-
// reset row
|
|
1661
|
-
row = [];
|
|
1662
|
-
}
|
|
1663
|
-
}
|
|
1664
|
-
// // append val
|
|
1665
|
-
// if (val) {
|
|
1666
|
-
// row.push(val);
|
|
1667
|
-
// }
|
|
1668
|
-
// // append row
|
|
1669
|
-
// if (row.length) {
|
|
1670
|
-
// rowList.push(row);
|
|
1671
|
-
// }
|
|
1672
|
-
return rowList;
|
|
1673
|
-
}
|
|
1674
|
-
|
|
1675
1720
|
function libPlatformArchExt() {
|
|
1676
1721
|
let libArch = process.arch;
|
|
1677
1722
|
let libExt = process.platform;
|
|
@@ -1904,6 +1949,43 @@ function sqlmathWebworkerInit({
|
|
|
1904
1949
|
}
|
|
1905
1950
|
}
|
|
1906
1951
|
|
|
1952
|
+
async function uvthreadpoolsizeGet() {
|
|
1953
|
+
|
|
1954
|
+
// This function will guess how many logical-processors on current-host.
|
|
1955
|
+
|
|
1956
|
+
let uvthreadpoolsize;
|
|
1957
|
+
await new Promise(function (resolve) {
|
|
1958
|
+
let child;
|
|
1959
|
+
child = moduleChildProcess.spawn(
|
|
1960
|
+
"sh",
|
|
1961
|
+
["-c", (`
|
|
1962
|
+
case "$(uname)" in
|
|
1963
|
+
Darwin)
|
|
1964
|
+
sysctl -n hw.logicalcpu
|
|
1965
|
+
;;
|
|
1966
|
+
Linux)
|
|
1967
|
+
nproc
|
|
1968
|
+
;;
|
|
1969
|
+
*NT*)
|
|
1970
|
+
wmic cpu get NumberOfLogicalProcessors | \
|
|
1971
|
+
grep -v "NumberOfLogicalProcessors"
|
|
1972
|
+
;;
|
|
1973
|
+
esac
|
|
1974
|
+
`)],
|
|
1975
|
+
{stdio: ["ignore", "pipe", "ignore"]}
|
|
1976
|
+
);
|
|
1977
|
+
child.stdout.setEncoding("utf8");
|
|
1978
|
+
child.stdout.on("data", function (chunk) {
|
|
1979
|
+
uvthreadpoolsize = Number(chunk);
|
|
1980
|
+
});
|
|
1981
|
+
child.on("exit", resolve);
|
|
1982
|
+
});
|
|
1983
|
+
if (npm_config_mode_test) {
|
|
1984
|
+
uvthreadpoolsize = undefined;
|
|
1985
|
+
}
|
|
1986
|
+
return uvthreadpoolsize || 4;
|
|
1987
|
+
}
|
|
1988
|
+
|
|
1907
1989
|
function waitAsync(timeout) {
|
|
1908
1990
|
|
|
1909
1991
|
// This function will wait <timeout> ms.
|
|
@@ -1966,6 +2048,8 @@ export {
|
|
|
1966
2048
|
assertOrThrow,
|
|
1967
2049
|
childProcessSpawn2,
|
|
1968
2050
|
ciBuildExt,
|
|
2051
|
+
csvFromListofList,
|
|
2052
|
+
csvToListofList,
|
|
1969
2053
|
dbCloseAsync,
|
|
1970
2054
|
dbExecAndReturnLastBlob,
|
|
1971
2055
|
dbExecAndReturnLastRow,
|
|
@@ -1990,6 +2074,7 @@ export {
|
|
|
1990
2074
|
noop,
|
|
1991
2075
|
objectDeepCopyWithKeysSorted,
|
|
1992
2076
|
sqlmathWebworkerInit,
|
|
2077
|
+
uvthreadpoolsizeGet,
|
|
1993
2078
|
version,
|
|
1994
2079
|
waitAsync
|
|
1995
2080
|
};
|
package/sqlmath_browser.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/*jslint beta, bitwise, browser, devel, nomen*/
|
|
2
2
|
import {
|
|
3
3
|
assertOrThrow,
|
|
4
|
+
csvFromListofList,
|
|
4
5
|
dbCloseAsync,
|
|
5
6
|
dbExecAsync,
|
|
6
7
|
dbFileSaveAsync,
|
|
@@ -337,22 +338,11 @@ INSERT INTO tradebot_tech_intra_day
|
|
|
337
338
|
*
|
|
338
339
|
FROM (
|
|
339
340
|
SELECT
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
JOIN (
|
|
346
|
-
SELECT '1a_stk_pct' AS tname
|
|
347
|
-
--
|
|
348
|
-
UNION ALL
|
|
349
|
-
--
|
|
350
|
-
SELECT '1b_stk_lmt' AS tname
|
|
351
|
-
)
|
|
352
|
-
--
|
|
353
|
-
UNION ALL
|
|
354
|
-
--
|
|
355
|
-
SELECT '1a_stk_pct', xdate, xdate2, stk_pct FROM tradebot_tech_intra
|
|
341
|
+
'1a_stk_pct' AS tname,
|
|
342
|
+
xdate,
|
|
343
|
+
xdate2,
|
|
344
|
+
stk_pct AS tval
|
|
345
|
+
FROM tradebot_tech_intra
|
|
356
346
|
--
|
|
357
347
|
UNION ALL
|
|
358
348
|
--
|
|
@@ -984,7 +974,7 @@ INSERT INTO chart._{{ii}}_tradebot_buysell_history (
|
|
|
984
974
|
? "unixepochToTimeutc"
|
|
985
975
|
: "juliandayToDate"
|
|
986
976
|
),
|
|
987
|
-
yaxisTitle: "percent
|
|
977
|
+
yaxisTitle: "percent gain",
|
|
988
978
|
yvalueSuffix: " %"
|
|
989
979
|
};
|
|
990
980
|
return (`
|
|
@@ -1574,7 +1564,8 @@ async function onDbAction(evt) {
|
|
|
1574
1564
|
case "dbtableRename":
|
|
1575
1565
|
title = target.textContent.trim().replace(/\s+/g, " ");
|
|
1576
1566
|
UI_CRUD.querySelector(".modalTitle").innerHTML = (
|
|
1577
|
-
`${stringHtmlSafe(baton.dbtableFullname)}<br
|
|
1567
|
+
`${stringHtmlSafe(baton.dbtableFullname)}<br>` +
|
|
1568
|
+
`${stringHtmlSafe(title)}`
|
|
1578
1569
|
);
|
|
1579
1570
|
UI_CRUD.querySelector("tbody").innerHTML = (
|
|
1580
1571
|
(`
|
|
@@ -1839,7 +1830,7 @@ DELETE FROM ${baton.dbtableName} WHERE rowid = ${baton.rowid};
|
|
|
1839
1830
|
});
|
|
1840
1831
|
data = data[0] || [];
|
|
1841
1832
|
data.shift();
|
|
1842
|
-
data =
|
|
1833
|
+
data = csvFromListofList({
|
|
1843
1834
|
colList: baton.colList,
|
|
1844
1835
|
rowList: data
|
|
1845
1836
|
});
|
|
@@ -2101,46 +2092,6 @@ function onResize() {
|
|
|
2101
2092
|
uitableInitWithinView({});
|
|
2102
2093
|
}
|
|
2103
2094
|
|
|
2104
|
-
function rowListToCsv({
|
|
2105
|
-
colList,
|
|
2106
|
-
rowList
|
|
2107
|
-
}) {
|
|
2108
|
-
// this function will convert json <rowList> to csv with given <colList>
|
|
2109
|
-
let data = JSON.stringify([[colList], rowList].flat(), undefined, 1);
|
|
2110
|
-
// convert data to csv
|
|
2111
|
-
data = data.replace((
|
|
2112
|
-
/\n /g
|
|
2113
|
-
), "");
|
|
2114
|
-
data = data.replace((
|
|
2115
|
-
/\n \[/g
|
|
2116
|
-
), "");
|
|
2117
|
-
data = data.replace((
|
|
2118
|
-
/\n \],?/g
|
|
2119
|
-
), "\r\n");
|
|
2120
|
-
data = data.slice(1, -2);
|
|
2121
|
-
// sqlite-strings are c-strings which should never contain null-char
|
|
2122
|
-
data = data.replace((
|
|
2123
|
-
/\u0000/g
|
|
2124
|
-
), "");
|
|
2125
|
-
// hide double-backslash `\\\\` as null-char
|
|
2126
|
-
data = data.replace((
|
|
2127
|
-
/\\\\/g
|
|
2128
|
-
), "\u0000");
|
|
2129
|
-
// escape double-quote `\\"` to `""`
|
|
2130
|
-
data = data.replace((
|
|
2131
|
-
/\\"/g
|
|
2132
|
-
), "\"\"");
|
|
2133
|
-
// replace newline with space
|
|
2134
|
-
data = data.replace((
|
|
2135
|
-
/\\r\\n|\\r|\\n/g
|
|
2136
|
-
), " ");
|
|
2137
|
-
// restore double-backslash `\\\\` from null-char
|
|
2138
|
-
data = data.replace((
|
|
2139
|
-
/\u0000/g
|
|
2140
|
-
), "\\\\");
|
|
2141
|
-
return data;
|
|
2142
|
-
}
|
|
2143
|
-
|
|
2144
2095
|
function stringHtmlSafe(str) {
|
|
2145
2096
|
// this function will make <str> html-safe
|
|
2146
2097
|
// https://stackoverflow.com/questions/7381974
|
package/sqlmath_wasm.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/*jslint-disable*/
|
|
2
2
|
// Copyright (c) 2021 Kai Zhu
|
|
3
3
|
// SPDX-License-Identifier: MIT
|
|
4
|
-
// 2026-
|
|
4
|
+
// 2026-07-01T23:02:00+0000
|
|
5
5
|
(function () {
|
|
6
6
|
"use strict";
|
|
7
7
|
|
|
8
|
-
var g;g||(g=typeof Module !== 'undefined' ? Module : {});var aa=Object.assign;
|
|
8
|
+
var g;g||(g=typeof Module !== 'undefined' ? Module : {});var aa=Object.assign;function ba(a){return a&&a.constructor===ArrayBuffer}
|
|
9
9
|
(async function(){let a=h("dbFileLoadOrSave","number",["number","string","number"]),b=h("jsbatonGetErrmsg","string",["number"]),c=h("jsbatonGetString","string",["number","number"]),d=h("sqlite3_errmsg","string",["number"]),e;globalThis.onmessage=async function({data:f}){await e;f.batonPtr=0;try{a:{let G=f.FILENAME_DBTMP;var k=f.JSBATON_OFFSET_ALL;let Rb=f.JSBATON_OFFSET_BUFV,P=f.argList,Q=new Uint8Array(f.baton.buffer),C=0,A=P[4],Sb=0,ea="",W=f.funcname,Va=P[2];switch(W){case "_dbClose":case "_dbExec":case "_dbFileLoad":case "_dbNoop":case "_dbOpen":C=
|
|
10
10
|
ca(Q.byteLength);f.batonPtr=C;l.set(Q,C);switch(W){case "_dbClose":console.error(`_dbClose("${c(C,1)}")`);break;case "_dbFileLoad":Va||da(G,new Uint8Array(A));break;case "_dbOpen":console.error(`_dbOpen("${c(C,0)}")`)}fa(C);ea=b(C);Q.set(l.subarray(C,C+k));switch(!ea&&W){case "_dbExec":A=new BigInt64Array(Q.buffer,Rb);P[0]=l.slice(Number(A[0]),Number(A[0]+A[1])).buffer;ha(Number(A[0]));break;case "_dbFileLoad":if(Va){k=G;var m=m||0;var p=p||"binary";if("utf8"!==p&&"binary"!==p)throw Error('Invalid encoding type "'+
|
|
11
11
|
p+'"');var q,t=n(k,m),v=r(k).size,H=new Uint8Array(v);ia(t,H,0,v,0);"utf8"===p?q=u(H,0):"binary"===p&&(q=H);ja(t);P[0]=q.buffer;ka(G)}break;case "_dbOpen":A&&(da(G,new Uint8Array(A)),A=Number(la(C,0)),(Sb=a(A,G,0))&&(ea=d(A)),ka(G))}postMessage({argList:P,baton:new DataView(Q.buffer),errmsg:ea,funcname:W,id:f.id},[Q.buffer,...P.filter(ba)]);var Tb=void 0;break a}throw Error(`invalid funcname "${W}"`);}await Tb}catch(G){postMessage({errmsg:G.stack,id:f.id})}finally{ha(f.batonPtr)}};e=new Promise(function(f){g.postRun=
|
package/test.mjs
CHANGED
|
@@ -39,6 +39,7 @@ import {
|
|
|
39
39
|
assertOrThrow,
|
|
40
40
|
childProcessSpawn2,
|
|
41
41
|
ciBuildExt,
|
|
42
|
+
csvFromListofList,
|
|
42
43
|
dbCloseAsync,
|
|
43
44
|
dbExecAndReturnLastBlob,
|
|
44
45
|
dbExecAndReturnLastRow,
|
|
@@ -61,6 +62,7 @@ import {
|
|
|
61
62
|
listOrEmptyList,
|
|
62
63
|
noop,
|
|
63
64
|
sqlmathWebworkerInit,
|
|
65
|
+
uvthreadpoolsizeGet,
|
|
64
66
|
version,
|
|
65
67
|
waitAsync
|
|
66
68
|
} from "./sqlmath.mjs";
|
|
@@ -168,7 +170,8 @@ SELECT
|
|
|
168
170
|
);
|
|
169
171
|
result = result.stdout.trim();
|
|
170
172
|
assertJsonEqual(result, "abcd1234|abcd1234");
|
|
171
|
-
}())
|
|
173
|
+
}()),
|
|
174
|
+
uvthreadpoolsizeGet()
|
|
172
175
|
]);
|
|
173
176
|
});
|
|
174
177
|
});
|
|
@@ -3927,10 +3930,17 @@ SELECT
|
|
|
3927
3930
|
) USING (ii);
|
|
3928
3931
|
`)
|
|
3929
3932
|
});
|
|
3930
|
-
valActual = (
|
|
3931
|
-
|
|
3932
|
-
|
|
3933
|
-
|
|
3933
|
+
valActual = csvFromListofList({
|
|
3934
|
+
colList: [
|
|
3935
|
+
"date",
|
|
3936
|
+
"saa",
|
|
3937
|
+
"sww",
|
|
3938
|
+
"spp",
|
|
3939
|
+
"ii",
|
|
3940
|
+
"linear_residual",
|
|
3941
|
+
"predict_sine"
|
|
3942
|
+
],
|
|
3943
|
+
rowList: valActual.map(function (elem) {
|
|
3934
3944
|
return [
|
|
3935
3945
|
elem.date,
|
|
3936
3946
|
elem.saa,
|
|
@@ -3945,13 +3955,13 @@ SELECT
|
|
|
3945
3955
|
? num.toFixed(4)
|
|
3946
3956
|
: num
|
|
3947
3957
|
);
|
|
3948
|
-
})
|
|
3949
|
-
})
|
|
3950
|
-
);
|
|
3951
|
-
valActual = valActual.replace((/
|
|
3952
|
-
valActual = valActual.replace((
|
|
3953
|
-
valActual = valActual.replace((/
|
|
3954
|
-
valActual = valActual.
|
|
3958
|
+
});
|
|
3959
|
+
})
|
|
3960
|
+
});
|
|
3961
|
+
valActual = valActual.replace((/"/g), "");
|
|
3962
|
+
valActual = valActual.replace((/,,/g), ",null,");
|
|
3963
|
+
valActual = valActual.replace((/\r\n/g), "\n");
|
|
3964
|
+
valActual = valActual.replace((/,/g), "\t");
|
|
3955
3965
|
await fsWriteFileUnlessTest(
|
|
3956
3966
|
"test_data_sinefit.csv",
|
|
3957
3967
|
valActual,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|