sqlmath 2021.11.20 → 2022.5.20

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
@@ -1,11 +1,32 @@
1
+ // MIT License
2
+ //
3
+ // Copyright (c) 2021 Kai Zhu
4
+ //
5
+ // Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ // of this software and associated documentation files (the "Software"), to deal
7
+ // in the Software without restriction, including without limitation the rights
8
+ // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ // copies of the Software, and to permit persons to whom the Software is
10
+ // furnished to do so, subject to the following conditions:
11
+ //
12
+ // The above copyright notice and this permission notice shall be included in
13
+ // all copies or substantial portions of the Software.
14
+ //
15
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ // SOFTWARE.
22
+
23
+
1
24
  /*jslint beta, bitwise, name, node*/
2
25
  "use strict";
3
26
  import {createRequire} from "module";
4
27
  import jslint from "./jslint.mjs";
5
28
 
6
29
  let {
7
- assertErrorThrownAsync,
8
- assertJsonEqual,
9
30
  assertOrThrow,
10
31
  debugInline,
11
32
  noop
@@ -17,7 +38,7 @@ function assertNumericalEqual(aa, bb, message) {
17
38
  // This function will assert aa - bb <= Number.EPSILON
18
39
 
19
40
  assertOrThrow(aa, "value cannot be 0 or falsy");
20
- if (!(Math.abs(aa - bb) <= Number.EPSILON)) {
41
+ if (!(Math.abs((aa - bb) / Math.max(aa, bb)) <= 256 * Number.EPSILON)) {
21
42
  throw new Error(
22
43
  JSON.stringify(aa) + " != " + JSON.stringify(bb) + (
23
44
  message
@@ -58,10 +79,9 @@ file sqlmath.js
58
79
  let SQLITE_OPEN_URI = 0x00000040; /* Ok for sqlite3_open_v2() */
59
80
  let SQLITE_OPEN_WAL = 0x00080000; /* VFS only */
60
81
  let addon;
61
- let dbDict = new WeakMap();
82
+ let consoleError = console.error;
83
+ let dbDict = new WeakMap(); // private map of sqlite-database-connections
62
84
  let requireCjs = createRequire(import.meta.url);
63
- let testList;
64
- // private map of sqlite-database-connections
65
85
 
66
86
  function cCall(func, argList) {
67
87
  // this function will serialize <argList> to a c <baton>,
@@ -168,8 +188,12 @@ file sqlmath.js
168
188
  bindList = [],
169
189
  db,
170
190
  responseType,
171
- rowList,
172
- sql
191
+ sql,
192
+ tmpColList,
193
+ tmpColListPriority,
194
+ tmpCsv,
195
+ tmpRowList,
196
+ tmpTableName
173
197
  }) {
174
198
  // this function will exec <sql> in <db> and return <result>
175
199
  let bindByKey = !Array.isArray(bindList);
@@ -180,10 +204,14 @@ file sqlmath.js
180
204
  );
181
205
  let result;
182
206
  let serialize = jsToSqlSerializer();
183
- if (rowList) {
207
+ if (tmpCsv || tmpRowList) {
184
208
  await dbTableInsertAsync({
209
+ colList: tmpColList,
210
+ colListPriority: tmpColListPriority,
211
+ csv: tmpCsv,
185
212
  db,
186
- rowList
213
+ rowList: tmpRowList,
214
+ tableName: tmpTableName
187
215
  });
188
216
  }
189
217
  Object.entries(bindList).forEach(function ([
@@ -202,8 +230,6 @@ file sqlmath.js
202
230
  (
203
231
  responseType === "lastBlob"
204
232
  ? 1
205
- : responseType === "lastMatrixDouble"
206
- ? 2
207
233
  : 0
208
234
  )
209
235
  ].concat(serialize.bufSharedList));
@@ -212,8 +238,6 @@ file sqlmath.js
212
238
  case "arraybuffer":
213
239
  case "lastBlob":
214
240
  return result;
215
- case "lastMatrixDouble":
216
- return new Float64Array(result);
217
241
  case "list":
218
242
  return JSON.parse(new TextDecoder().decode(result));
219
243
  default:
@@ -231,6 +255,28 @@ file sqlmath.js
231
255
  }
232
256
  }
233
257
 
258
+ async function dbExecWithRetryAsync(option) {
259
+ // this function will exec <sql> in <db> and return <result> with <retryLimit>
260
+ let retry = option.retryLimit || 1;
261
+ while (true) {
262
+ try {
263
+ return await dbExecAsync(option);
264
+ } catch (err) {
265
+ assertOrThrow(retry > 0, err);
266
+ consoleError(err);
267
+ consoleError(
268
+ "dbExecWithRetryAsync - retry failed sql-query with "
269
+ + retry
270
+ + " remaining retry"
271
+ );
272
+ retry -= 1;
273
+ await new Promise(function (resolve) {
274
+ setTimeout(resolve, 50);
275
+ });
276
+ }
277
+ }
278
+ }
279
+
234
280
  function dbGetLastBlobAsync({
235
281
  bindList = [],
236
282
  db,
@@ -246,21 +292,6 @@ file sqlmath.js
246
292
  });
247
293
  }
248
294
 
249
- function dbGetLastMatrixDouble({
250
- bindList = [],
251
- db,
252
- sql
253
- }) {
254
- // this function will exec <sql> in <db> and return last SELECT-statement
255
- // from execution as row x col matrix of doubles
256
- return dbExecAsync({
257
- bindList,
258
- db,
259
- responseType: "lastMatrixDouble",
260
- sql
261
- });
262
- }
263
-
264
295
  async function dbMemoryLoadAsync({
265
296
  db,
266
297
  filename
@@ -296,7 +327,9 @@ file sqlmath.js
296
327
  // const char *zVfs /* Name of VFS module to use */
297
328
  // );
298
329
  let connPool;
299
- let db = {};
330
+ let db = {
331
+ filename
332
+ };
300
333
  assertOrThrow(
301
334
  typeof filename === "string",
302
335
  "invalid filename " + filename
@@ -306,9 +339,12 @@ file sqlmath.js
306
339
  ), async function () {
307
340
  let finalizer;
308
341
  let ptr = await cCall("__dbOpenAsync", [
309
- String(filename), undefined, flags ?? (
342
+ String(filename),
343
+ undefined,
344
+ flags ?? (
310
345
  SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE | SQLITE_OPEN_URI
311
- ), undefined
346
+ ),
347
+ undefined
312
348
  ]);
313
349
  ptr = ptr[0][0];
314
350
  finalizer = new BigInt64Array(addon.__dbFinalizerCreate());
@@ -318,6 +354,7 @@ file sqlmath.js
318
354
  dbDict.set(db, {
319
355
  busy: 0,
320
356
  connPool,
357
+ filename,
321
358
  ii: 0,
322
359
  ptr: 0n
323
360
  });
@@ -330,13 +367,14 @@ file sqlmath.js
330
367
  csv,
331
368
  db,
332
369
  rowList,
333
- tableName = "tmp1"
370
+ tableName
334
371
  }) {
335
372
  // this function will create-or-replace temp <tablename> with <rowList>
336
373
  let serialize = jsToSqlSerializer();
337
374
  let sqlCreateTable;
338
375
  let sqlInsertRow;
339
376
  // normalize and validate tableName
377
+ tableName = tableName || "__tmp1";
340
378
  tableName = "temp." + JSON.stringify(tableName.replace((
341
379
  /^temp\./
342
380
  ), ""));
@@ -429,9 +467,6 @@ file sqlmath.js
429
467
  }
430
468
  function bufferSetBuffer(aa, bb, offset) {
431
469
  // this function will set buffer <bb> to buffer <aa> at <offset>
432
- if (typeof bb === "string") {
433
- bb = new TextEncoder().encode(bb);
434
- }
435
470
  aa = new Uint8Array(aa.buffer, aa.byteOffset, aa.byteLength);
436
471
  bb = new Uint8Array(bb.buffer, bb.byteOffset, bb.byteLength);
437
472
  aa.set(bb, offset);
@@ -827,832 +862,6 @@ Definition of the CSV Format
827
862
  return rowList;
828
863
  }
829
864
 
830
- function testAll() {
831
- // this function will run all tests
832
- testList.forEach(function (testFunc) {
833
- testFunc();
834
- });
835
- }
836
-
837
- function testAssertXxx() {
838
- // this function will test assertXxx's handling-behavior
839
- // test assertNumericalEqual's handling-behavior
840
- assertNumericalEqual(1, 1);
841
- assertErrorThrownAsync(function () {
842
- assertNumericalEqual(0, 0);
843
- }, "value cannot be 0 or falsy");
844
- assertErrorThrownAsync(function () {
845
- assertNumericalEqual(1, 2);
846
- }, "1 != 2");
847
- assertErrorThrownAsync(function () {
848
- assertNumericalEqual(1, 2, "aa");
849
- }, "aa");
850
- }
851
-
852
- function testCcall() {
853
- // this function will test cCall's handling-behavior
854
- [
855
- [-0, "0"],
856
- [-Infinity, "0"],
857
- [0, "0"],
858
- [1 / 0, "0"],
859
- [Infinity, "0"],
860
- [false, "0"],
861
- [null, "0"],
862
- [true, "1"],
863
- [undefined, "0"],
864
- [{}, "0"]
865
- ].forEach(async function ([
866
- aa, bb
867
- ]) {
868
- let cc;
869
- cc = String(
870
- await cCall("noopAsync", [
871
- aa
872
- ])
873
- )[0][0];
874
- assertOrThrow(bb === cc, [aa, bb, cc]);
875
- cc = String(cCall("noopSync", [
876
- aa
877
- ]))[0][0];
878
- assertOrThrow(bb === cc, [aa, bb, cc]);
879
- });
880
- }
881
-
882
- async function testDbBind() {
883
- // this function will test db's bind handling-behavior
884
- let db = await dbOpenAsync({
885
- filename: ":memory:"
886
- });
887
- async function testDbGetLastBlobAsync(val) {
888
- return await dbGetLastBlobAsync({
889
- bindList: [
890
- val
891
- ],
892
- db,
893
- sql: "SELECT 1, 2, 3; SELECT 1, 2, ?"
894
- });
895
- }
896
- // test bigint-error handling-behavior
897
- noop([
898
- -(2n ** 63n),
899
- 2n ** 63n
900
- ]).forEach(function (val) {
901
- assertErrorThrownAsync(testDbGetLastBlobAsync.bind(undefined, val));
902
- });
903
- // test datatype handling-behavior
904
- [
905
- // -1. SharedArrayBuffer
906
- // new SharedArrayBuffer(0), null,
907
- // 1. bigint
908
- -0n, -0,
909
- -0x7fffffffffffffffn, "-9223372036854775807",
910
- -1n, -1,
911
- -2n, -2,
912
- 0n, 0,
913
- 0x7fffffffffffffffn, "9223372036854775807",
914
- 1n, 1,
915
- 2n, 2,
916
- // 2. boolean
917
- false, 0,
918
- true, 1,
919
- // 3. function
920
- noop, null,
921
- // 4. number
922
- -0, 0,
923
- -1 / 0, null,
924
- -1e-999, 0,
925
- -1e999, null,
926
- -2, -2,
927
- -Infinity, null,
928
- -NaN, 0,
929
- 0, 0,
930
- 1 / 0, null,
931
- 1e-999, 0,
932
- 1e999, null,
933
- 2, 2,
934
- Infinity, null,
935
- NaN, 0,
936
- // 5. object
937
- new Uint8Array(0), null,
938
- new TextEncoder().encode(""), null,
939
- new TextEncoder().encode("\u0000"), null,
940
- new TextEncoder().encode("\u0000\u{1f600}\u0000"), null,
941
- [], "[]",
942
- new Date(0), "1970-01-01T00:00:00.000Z",
943
- new RegExp(), "{}",
944
- null, null,
945
- {}, "{}",
946
- // 6. string
947
- "", "",
948
- "0", "0",
949
- "1", "1",
950
- "2", "2",
951
- "\u0000", "\u0000",
952
- "\u0000\u{1f600}\u0000", "\u0000\u{1f600}\u0000",
953
- "a".repeat(9999), "a".repeat(9999),
954
- // 7. symbol
955
- Symbol(), null,
956
- // 8. undefined
957
- undefined, null
958
- ].forEach(function (aa, ii, list) {
959
- let bb = list[ii + 1];
960
- if (ii % 2 === 1) {
961
- return;
962
- }
963
- ii *= 0.5;
964
- // test dbGetLastBlobAsync's bind handling-behavior
965
- [
966
- aa
967
- ].forEach(async function (aa) {
968
- let cc = String(bb);
969
- let dd = new TextDecoder().decode(
970
- await testDbGetLastBlobAsync(aa)
971
- );
972
- switch (typeof(aa)) {
973
- case "bigint":
974
- aa = Number(aa);
975
- break;
976
- case "function":
977
- case "symbol":
978
- case "undefined":
979
- cc = "";
980
- break;
981
- case "number":
982
- switch (aa) {
983
- case -2:
984
- cc = "-2.0";
985
- break;
986
- case -Infinity:
987
- cc = "-Inf";
988
- break;
989
- case 2:
990
- cc = "2.0";
991
- break;
992
- case Infinity:
993
- cc = "Inf";
994
- break;
995
- }
996
- break;
997
- case "object":
998
- if (ArrayBuffer.isView(aa)) {
999
- cc = new TextDecoder().decode(aa);
1000
- break;
1001
- }
1002
- if (aa === null) {
1003
- cc = "";
1004
- }
1005
- break;
1006
- }
1007
- // debugInline(ii, aa, bb, cc, dd);
1008
- assertJsonEqual(cc, dd, {
1009
- ii,
1010
- aa, //jslint-quiet
1011
- bb,
1012
- cc,
1013
- dd
1014
- });
1015
- });
1016
- // test dbGetLastMatrixDouble's bind handling-behavior
1017
- [
1018
- aa
1019
- ].forEach(async function (aa) {
1020
- let cc = Number(
1021
- typeof aa === "symbol"
1022
- ? 0
1023
- : aa
1024
- ) || 0;
1025
- let dd = await dbGetLastMatrixDouble({
1026
- bindList: [
1027
- aa
1028
- ],
1029
- db,
1030
- sql: "SELECT 1, 2, 3; SELECT 1, 2, ?"
1031
- });
1032
- switch (typeof(aa)) {
1033
- case "bigint":
1034
- aa = String(aa);
1035
- break;
1036
- case "object":
1037
- if (typeof aa?.getUTCFullYear === "function") {
1038
- cc = aa.getUTCFullYear();
1039
- }
1040
- break;
1041
- }
1042
- cc = new Float64Array([
1043
- 1, 3, 1, 2, cc
1044
- ]);
1045
- // debugInline(ii, aa, bb, cc, dd);
1046
- cc.forEach(function (val, jj) {
1047
- assertJsonEqual(
1048
- val,
1049
- dd[jj],
1050
- {
1051
- ii,
1052
- aa, //jslint-quiet
1053
- bb,
1054
- cc,
1055
- dd
1056
- }
1057
- );
1058
- });
1059
- });
1060
- // test dbExecAsync's responseType handling-behavior
1061
- [
1062
- "arraybuffer",
1063
- "list",
1064
- undefined
1065
- ].forEach(async function (responseType) {
1066
- let cc = noop(
1067
- await dbExecAsync({
1068
- bindList: [
1069
- aa
1070
- ],
1071
- db,
1072
- responseType,
1073
- sql: "SELECT ? AS val"
1074
- })
1075
- );
1076
- // debugInline(ii, responseType, aa, bb, cc);
1077
- switch (responseType) {
1078
- case "arraybuffer":
1079
- cc = JSON.parse(new TextDecoder().decode(cc))[0][1][0];
1080
- break;
1081
- case "list":
1082
- cc = cc[0][1][0];
1083
- break;
1084
- default:
1085
- cc = cc[0][0].val;
1086
- }
1087
- assertJsonEqual(bb, cc, {
1088
- aa,
1089
- bb,
1090
- cc
1091
- });
1092
- });
1093
- // test dbExecAsync's bind handling-behavior
1094
- [
1095
- [
1096
- [
1097
- bb, bb, 0
1098
- ],
1099
- (
1100
- "SELECT 0;"
1101
- + " SELECT ? AS c1, ? AS c2, ? AS c3, ? AS c4"
1102
- + " UNION ALL SELECT ?1, ?2, ?3, ?4"
1103
- + " UNION ALL SELECT ?1, ?2, ?3, ?4"
1104
- )
1105
- ], [
1106
- {
1107
- k1: bb,
1108
- k2: bb,
1109
- k3: 0
1110
- },
1111
- (
1112
- "SELECT 0;"
1113
- + " SELECT $k1 AS c1, $k2 AS c2, $k3 AS c3, $k4 AS c4"
1114
- + " UNION ALL SELECT :k1, :k2, :k3, :k4"
1115
- + " UNION ALL SELECT @k1, @k2, @k3, @k4"
1116
- )
1117
- ]
1118
- ].forEach(async function ([
1119
- bindList, sql
1120
- ]) {
1121
- let cc = noop(
1122
- await dbExecAsync({
1123
- bindList,
1124
- db,
1125
- responseType: "list",
1126
- sql
1127
- })
1128
- );
1129
- // debugInline(ii, aa, bb, cc);
1130
- assertJsonEqual(
1131
- [
1132
- [
1133
- [
1134
- "0"
1135
- ], [
1136
- 0
1137
- ]
1138
- ], [
1139
- [
1140
- "c1", "c2", "c3", "c4"
1141
- ], [
1142
- bb, bb, 0, undefined
1143
- ], [
1144
- bb, bb, 0, undefined
1145
- ], [
1146
- bb, bb, 0, undefined
1147
- ]
1148
- ]
1149
- ],
1150
- cc
1151
- );
1152
- });
1153
- // test dbTableInsertAsync's bind handling-behavior
1154
- [
1155
- {
1156
- // test list-of-list handling-behavior
1157
- rowList: [
1158
- [
1159
- "c1", "c2", "c3"
1160
- ],
1161
- [
1162
- aa, aa
1163
- ]
1164
- ]
1165
- }, {
1166
- // test list-of-dict handling-behavior
1167
- rowList: [
1168
- {
1169
- "c1": aa,
1170
- "c2": aa,
1171
- "c3": undefined
1172
- }
1173
- ]
1174
- }, {
1175
- // test colList and list-of-list handling-behavior
1176
- colList: [
1177
- "c1", "c2", "c3"
1178
- ],
1179
- rowList: [
1180
- [
1181
- aa, aa
1182
- ]
1183
- ]
1184
- }, {
1185
- // test colList and list-of-dict handling-behavior
1186
- colList: [
1187
- "c1", "c2", "c3"
1188
- ],
1189
- rowList: [
1190
- {
1191
- "c1": aa,
1192
- "c2": aa,
1193
- "c3": undefined
1194
- }
1195
- ]
1196
- }, {
1197
- // test colList and list-of-list handling-behavior
1198
- colList: [
1199
- "c1", "c3", "c2"
1200
- ],
1201
- colListPriority: [
1202
- "c1", "c2"
1203
- ],
1204
- rowList: [
1205
- [
1206
- aa, undefined, aa
1207
- ]
1208
- ]
1209
- }
1210
- ].forEach(async function ({
1211
- colList,
1212
- colListPriority,
1213
- rowList
1214
- }, jj) {
1215
- let cc;
1216
- await dbTableInsertAsync({
1217
- colList,
1218
- colListPriority,
1219
- db,
1220
- rowList,
1221
- tableName: "datatype_" + ii + "_" + jj
1222
- });
1223
- cc = noop(
1224
- await dbExecAsync({
1225
- db,
1226
- responseType: "list",
1227
- sql: "SELECT * FROM datatype_" + ii + "_" + jj
1228
- })
1229
- )[0];
1230
- // debugInline(ii, jj, aa, bb, cc);
1231
- assertJsonEqual([
1232
- [
1233
- "c1", "c2", "c3"
1234
- ], [
1235
- bb, bb, undefined
1236
- ]
1237
- ], cc);
1238
- });
1239
- });
1240
- }
1241
-
1242
- async function testDbCloseAsync() {
1243
- // this function will test dbCloseAsync's handling-behavior
1244
- let db = await dbOpenAsync({
1245
- filename: ":memory:"
1246
- });
1247
- // test null-case handling-behavior
1248
- assertErrorThrownAsync(function () {
1249
- return dbCloseAsync({});
1250
- }, "invalid or closed db");
1251
- // test close handling-behavior
1252
- await dbCloseAsync({
1253
- db
1254
- });
1255
- }
1256
-
1257
- async function testDbExecAsync() {
1258
- // this function will test dbExecAsync's handling-behavior
1259
- let db = await dbOpenAsync({
1260
- filename: ":memory:"
1261
- });
1262
- // test null-case handling-behavior
1263
- assertErrorThrownAsync(function () {
1264
- return dbExecAsync({
1265
- db,
1266
- sql: undefined
1267
- });
1268
- }, "near \"undefined\": syntax error");
1269
- // test race-condition handling-behavior
1270
- Array.from(new Array(4)).forEach(async function () {
1271
- let result;
1272
- try {
1273
- result = JSON.stringify(
1274
- await dbExecAsync({
1275
- bindList: [
1276
- new TextEncoder().encode("foob"),
1277
- new TextEncoder().encode("fooba"),
1278
- new TextEncoder().encode("foobar")
1279
- ],
1280
- db,
1281
- responseType: "list",
1282
- sql: (`
1283
- CREATE TABLE testDbExecAsync1 AS
1284
- SELECT 101 AS c101, 102 AS c102
1285
- UNION ALL
1286
- VALUES
1287
- (201, 202),
1288
- (301, NULL);
1289
- CREATE TABLE testDbExecAsync2 AS
1290
- SELECT 401 AS c401, 402 AS c402, 403 AS c403
1291
- UNION ALL
1292
- VALUES
1293
- (501, 502.0123, 5030123456789),
1294
- (601, '602', '603_\"\x01\x08\x09\x0a\x0b\x0c\x0d\x0e'),
1295
- (?1, ?2, ?3),
1296
- (tostring(?1), tostring(?2), tostring(?3)),
1297
- (tobase64(?1), tobase64(?2), tobase64(?3)),
1298
- (
1299
- tobase64(uncompress(compress(?1))),
1300
- tobase64(uncompress(compress(?2))),
1301
- tobase64(uncompress(compress(?3)))
1302
- );
1303
- SELECT * FROM testDbExecAsync1;
1304
- SELECT * FROM testDbExecAsync2;
1305
- `)
1306
- })
1307
- );
1308
- assertJsonEqual(result, JSON.stringify([
1309
- [
1310
- ["c101", "c102"],
1311
- [101, 102],
1312
- [201, 202],
1313
- [301, null]
1314
- ],
1315
- [
1316
- ["c401", "c402", "c403"],
1317
- [401, 402, 403],
1318
- [501, 502.0123, 5030123456789],
1319
- [601, "602", "603_\"\u0001\b\t\n\u000b\f\r\u000e"],
1320
- [
1321
- null, null, null
1322
- ],
1323
- [
1324
- "foob", "fooba", "foobar"
1325
- ],
1326
- [
1327
- "Zm9vYg==", "Zm9vYmE=", "Zm9vYmFy"
1328
- ],
1329
- [
1330
- "Zm9vYg==", "Zm9vYmE=", "Zm9vYmFy"
1331
- ]
1332
- ]
1333
- ]));
1334
- } catch (err) {
1335
- assertOrThrow(
1336
- err.message.indexOf(
1337
- "table testDbExecAsync1 already exists"
1338
- ) >= 0,
1339
- err
1340
- );
1341
- }
1342
- });
1343
- // test close-while-busy handling-behavior
1344
- assertErrorThrownAsync(function () {
1345
- return dbCloseAsync({
1346
- db
1347
- });
1348
- }, (
1349
- /db cannot close with \d+? actions pending/
1350
- ));
1351
- // test sqlmath-defined-func handling-behavior
1352
- [
1353
- "COT('-1')", -0.642092615934331,
1354
- "COT('0')", null,
1355
- "COT('1')", 0.642092615934331,
1356
- "COT(-1)", -0.642092615934331,
1357
- "COT(0)", null,
1358
- "COT(1)", 0.642092615934331,
1359
- "COTH('-1')", -1.31303528549933,
1360
- "COTH('0')", null,
1361
- "COTH('1')", 1.31303528549933,
1362
- "COTH(-1)", -1.31303528549933,
1363
- "COTH(0)", null,
1364
- "COTH(1)", 1.31303528549933,
1365
- "SIGN('-1')", -1,
1366
- "SIGN('0')", 0,
1367
- "SIGN('1')", 1,
1368
- "SIGN(-0x7fffffffffffffff)", -1,
1369
- "SIGN(-1)", -1,
1370
- "SIGN(-1e999)", -1,
1371
- "SIGN(0)", 0,
1372
- "SIGN(0x7fffffffffffffff)", 1,
1373
- "SIGN(0x8000000000000000)", -1,
1374
- "SIGN(0xffffffffffffffff)", -1,
1375
- "SIGN(1)", 1,
1376
- "SIGN(1e999)", 1,
1377
- "SIGN(NULL)", null,
1378
- // sentinel
1379
- "NULL", null
1380
- ].forEach(async function (sql, ii, list) {
1381
- let bb = list[ii + 1];
1382
- let cc;
1383
- if (ii % 2 === 1) {
1384
- return;
1385
- }
1386
- ii *= 0.5;
1387
- cc = noop(
1388
- await dbExecAsync({
1389
- db,
1390
- responseType: "dict",
1391
- sql: "SELECT " + sql + " AS val"
1392
- })
1393
- )[0][0].val;
1394
- assertOrThrow(bb === cc, JSON.stringify([
1395
- ii, sql, bb, cc
1396
- ]));
1397
- });
1398
- }
1399
-
1400
- async function testDbMemoryXxx() {
1401
- // this function will test dbMemoryXxx's handling-behavior
1402
- let data;
1403
- let db = await dbOpenAsync({
1404
- filename: ":memory:"
1405
- });
1406
- // test null-case handling-behavior
1407
- assertErrorThrownAsync(function () {
1408
- return dbMemoryLoadAsync({
1409
- db
1410
- });
1411
- }, "invalid filename undefined");
1412
- assertErrorThrownAsync(function () {
1413
- return dbMemorySaveAsync({
1414
- db
1415
- });
1416
- }, "invalid filename undefined");
1417
- await dbExecAsync({
1418
- db,
1419
- sql: "CREATE TABLE t01 AS SELECT 1 AS c01"
1420
- });
1421
- await dbMemorySaveAsync({
1422
- db,
1423
- filename: ".testDbMemoryXxx.sqlite"
1424
- });
1425
- db = await dbOpenAsync({
1426
- filename: ":memory:"
1427
- });
1428
- await dbMemoryLoadAsync({
1429
- db,
1430
- filename: ".testDbMemoryXxx.sqlite"
1431
- });
1432
- data = await dbExecAsync({
1433
- db,
1434
- sql: "SELECT * FROM t01"
1435
- });
1436
- assertJsonEqual(data, [
1437
- [
1438
- {
1439
- c01: 1
1440
- }
1441
- ]
1442
- ]);
1443
- }
1444
-
1445
- function testDbOpenAsync() {
1446
- // this function will test dbOpenAsync's handling-behavior
1447
- // test null-case handling-behavior
1448
- assertErrorThrownAsync(function () {
1449
- return dbOpenAsync({});
1450
- }, "invalid filename undefined");
1451
- }
1452
-
1453
- async function testDbTableInsertAsync() {
1454
- // this function will test dbTableInsertAsync's handling-behavior
1455
- let db = await dbOpenAsync({
1456
- filename: ":memory:"
1457
- });
1458
- // test error handling-behavior
1459
- [
1460
- [
1461
- undefined,
1462
- (
1463
- /invalid rowList undefined/
1464
- )
1465
- ], [
1466
- [
1467
- []
1468
- ],
1469
- (
1470
- /invalid colList \[\]/
1471
- )
1472
- ], [
1473
- [
1474
- {}
1475
- ],
1476
- (
1477
- /invalid colList \[\]/
1478
- )
1479
- ]
1480
- ].forEach(function ([
1481
- rowList, rgx
1482
- ]) {
1483
- assertErrorThrownAsync(function () {
1484
- return dbTableInsertAsync({
1485
- rowList
1486
- });
1487
- }, rgx);
1488
- });
1489
- // test csv handling-behavior
1490
- [
1491
- [
1492
- "0", undefined
1493
- ],
1494
- [
1495
- "0,0,0\n1,1,1",
1496
- [
1497
- [
1498
- "c_0", "c_0_2", "c_0_3"
1499
- ], [
1500
- "1", "1", "1"
1501
- ]
1502
- ]
1503
- ],
1504
- [
1505
- (
1506
- "c1,c1,c2\n"
1507
- + "1, 2 \n"
1508
- + `"1","""2""","3\r\n"\n`
1509
- + "\n"
1510
- + "1,2,3\n"
1511
- ),
1512
- [
1513
- [
1514
- "c1", "c1_2", "c2"
1515
- ], [
1516
- "1", " 2 ", null
1517
- ], [
1518
- "1", "\"2\"", "3\n"
1519
- ], [
1520
- "", null, null
1521
- ], [
1522
- "1", "2", "3"
1523
- ]
1524
- ]
1525
- ]
1526
- ].forEach(async function ([
1527
- aa, bb
1528
- ], ii) {
1529
- let cc;
1530
- await dbTableInsertAsync({
1531
- csv: aa,
1532
- db,
1533
- tableName: "csv_" + ii
1534
- });
1535
- cc = noop(
1536
- await dbExecAsync({
1537
- db,
1538
- responseType: "list",
1539
- sql: "SELECT * FROM temp.csv_" + ii
1540
- })
1541
- )[0];
1542
- assertOrThrow(
1543
- JSON.stringify(bb) === JSON.stringify(cc),
1544
- JSON.stringify([
1545
- ii, aa, bb, cc
1546
- ], undefined, 4)
1547
- );
1548
- });
1549
- }
1550
-
1551
- async function testSqlError() {
1552
- // this function will test sql-error's handling-behavior
1553
- let db = await dbOpenAsync({
1554
- filename: ":memory:"
1555
- });
1556
- [
1557
- 1, "SQL logic error",
1558
- 2, "unknown error",
1559
- 3, "access permission denied",
1560
- 4, "query aborted",
1561
- 5, "database is locked",
1562
- 6, "database table is locked",
1563
- 7, "out of memory",
1564
- 8, "attempt to write a readonly database",
1565
- 9, "interrupted",
1566
- 10, "disk I/O error",
1567
- 11, "database disk image is malformed",
1568
- 12, "unknown operation",
1569
- 13, "database or disk is full",
1570
- 14, "unable to open database file",
1571
- 15, "locking protocol",
1572
- 16, "unknown error",
1573
- 17, "database schema has changed",
1574
- 18, "string or blob too big",
1575
- 19, "constraint failed",
1576
- 20, "datatype mismatch",
1577
- 21, "bad parameter or other API misuse",
1578
- 22, "unknown error",
1579
- 23, "authorization denied",
1580
- 24, "unknown error",
1581
- 25, "column index out of range",
1582
- 26, "file is not a database",
1583
- 27, "notification message",
1584
- 28, "warning message",
1585
- 100, "unknown error",
1586
- 101, "unknown error"
1587
- ].forEach(function (sql, ii, list) {
1588
- let bb = list[ii + 1];
1589
- if (ii % 2 === 1) {
1590
- return;
1591
- }
1592
- ii *= 0.5;
1593
- sql = "SELECT throwerror(" + sql + ")";
1594
- assertErrorThrownAsync(function () {
1595
- return dbExecAsync({
1596
- db,
1597
- sql
1598
- });
1599
- }, bb);
1600
- });
1601
- }
1602
-
1603
- async function testSqlExt() {
1604
- // this function will test sql-ext's handling-behavior
1605
- let db = await dbOpenAsync({
1606
- filename: ":memory:"
1607
- });
1608
- [
1609
- {
1610
- aa: [
1611
- [
1612
- {
1613
- "c01": ""
1614
- }
1615
- ]
1616
- ],
1617
- sql: "SELECT tobase64(NULL) AS c01"
1618
- },
1619
- {
1620
- aa: [
1621
- [
1622
- {
1623
- "c01": ""
1624
- }
1625
- ]
1626
- ],
1627
- sql: "SELECT tobase64(?) AS c01"
1628
- },
1629
- {
1630
- aa: [
1631
- [
1632
- {
1633
- "c01": "AAAAAAAAAAA="
1634
- }
1635
- ]
1636
- ],
1637
- bindList: [
1638
- new Uint8Array(8)
1639
- ],
1640
- sql: "SELECT tobase64(uncompress(compress(?))) AS c01"
1641
- }
1642
- ].forEach(async function ({
1643
- aa,
1644
- bindList,
1645
- sql
1646
- }) {
1647
- let bb = await dbExecAsync({
1648
- bindList,
1649
- db,
1650
- sql
1651
- });
1652
- assertJsonEqual(aa, bb);
1653
- });
1654
- }
1655
-
1656
865
  addon = requireCjs(
1657
866
  "./_binary_sqlmath"
1658
867
  + "_napi8"
@@ -1660,19 +869,7 @@ SELECT * FROM testDbExecAsync2;
1660
869
  + "_" + process.arch
1661
870
  + ".node"
1662
871
  );
1663
- testList = [
1664
- testAssertXxx,
1665
- testCcall,
1666
- testDbBind,
1667
- testDbCloseAsync,
1668
- testDbExecAsync,
1669
- testDbMemoryXxx,
1670
- testDbOpenAsync,
1671
- testDbTableInsertAsync,
1672
- testSqlError,
1673
- testSqlExt
1674
- ];
1675
- Object.assign(local, {
872
+ Object.assign(local, jslint, {
1676
873
  SQLITE_MAX_LENGTH2,
1677
874
  SQLITE_OPEN_AUTOPROXY,
1678
875
  SQLITE_OPEN_CREATE,
@@ -1695,19 +892,22 @@ SELECT * FROM testDbExecAsync2;
1695
892
  SQLITE_OPEN_TRANSIENT_DB,
1696
893
  SQLITE_OPEN_URI,
1697
894
  SQLITE_OPEN_WAL,
1698
- assertErrorThrownAsync,
1699
895
  assertNumericalEqual,
896
+ cCall,
1700
897
  dbCloseAsync,
1701
898
  dbExecAsync,
899
+ dbExecWithRetryAsync,
1702
900
  dbGetLastBlobAsync,
1703
901
  dbMemoryLoadAsync,
1704
902
  dbMemorySaveAsync,
1705
903
  dbOpenAsync,
1706
904
  dbTableInsertAsync,
1707
- debugInline,
1708
- testAll,
1709
- testList
905
+ debugInline
1710
906
  });
907
+ if (process.env.npm_config_mode_test) {
908
+ // mock consoleError
909
+ consoleError = noop;
910
+ }
1711
911
  }());
1712
912
 
1713
913
  export default Object.freeze(local);