w-orm-postgresql 1.0.9 → 1.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -8
- package/dist/w-orm-postgresql.umd.js +2 -2
- package/dist/w-orm-postgresql.umd.js.map +1 -1
- package/docs/WOrmPostgresql.html +119 -27
- package/docs/WOrmPostgresql.mjs.html +208 -77
- package/docs/index.html +2 -2
- package/g-basic.mjs +9 -8
- package/package.json +1 -1
- package/src/WOrmPostgresql.mjs +205 -74
- package/test/api-postgresql.test.mjs +408 -36
|
@@ -373,47 +373,47 @@ describe('basic', function() {
|
|
|
373
373
|
})
|
|
374
374
|
vget[6] = rt
|
|
375
375
|
|
|
376
|
-
//
|
|
376
|
+
//selectByPk
|
|
377
377
|
rt = null
|
|
378
378
|
// vans[18] = { time: new Date('2025-01-01T00:10:00.000Z'), name: 'rosemary(modify)', value: 113.98 }
|
|
379
|
-
await wo.
|
|
379
|
+
await wo.selectByPk('2025-01-01T00:10:00Z')
|
|
380
380
|
.then(function(msg) {
|
|
381
|
-
// console.log('
|
|
382
|
-
//
|
|
381
|
+
// console.log('selectByPk then', msg)
|
|
382
|
+
// selectByPk { time: 2025-01-01T00:10:00.000Z, name: 'rosemary(modify)', value: 113.98 }
|
|
383
383
|
rt = msg
|
|
384
384
|
})
|
|
385
385
|
.catch(function(msg) {
|
|
386
|
-
// console.log('
|
|
386
|
+
// console.log('selectByPk catch', msg)
|
|
387
387
|
rt = msg.toString()
|
|
388
388
|
})
|
|
389
389
|
vget[18] = rt
|
|
390
390
|
|
|
391
|
-
//
|
|
391
|
+
//selectByPk by pk not existed
|
|
392
392
|
rt = null
|
|
393
393
|
// vans[19] = null
|
|
394
|
-
await wo.
|
|
394
|
+
await wo.selectByPk('2024-01-01T00:00:00Z')
|
|
395
395
|
.then(function(msg) {
|
|
396
|
-
// console.log('
|
|
397
|
-
//
|
|
396
|
+
// console.log('selectByPk by pk not existed then', msg)
|
|
397
|
+
// selectByPk by pk not existed null
|
|
398
398
|
rt = msg
|
|
399
399
|
})
|
|
400
400
|
.catch(function(msg) {
|
|
401
|
-
// console.log('
|
|
401
|
+
// console.log('selectByPk by pk not existed catch', msg)
|
|
402
402
|
rt = msg.toString()
|
|
403
403
|
})
|
|
404
404
|
vget[19] = rt
|
|
405
405
|
|
|
406
|
-
//
|
|
406
|
+
//selectByPk by pk invalid, 未給有效主鍵值視為查無數據
|
|
407
407
|
rt = null
|
|
408
408
|
// vans[20] = null
|
|
409
|
-
await wo.
|
|
409
|
+
await wo.selectByPk('abc')
|
|
410
410
|
.then(function(msg) {
|
|
411
|
-
// console.log('
|
|
412
|
-
//
|
|
411
|
+
// console.log('selectByPk by pk invalid then', msg)
|
|
412
|
+
// selectByPk by pk invalid null
|
|
413
413
|
rt = msg
|
|
414
414
|
})
|
|
415
415
|
.catch(function(msg) {
|
|
416
|
-
// console.log('
|
|
416
|
+
// console.log('selectByPk by pk invalid catch', msg)
|
|
417
417
|
rt = msg.toString()
|
|
418
418
|
})
|
|
419
419
|
vget[20] = rt
|
|
@@ -674,30 +674,30 @@ describe('basic', function() {
|
|
|
674
674
|
})
|
|
675
675
|
vget[17] = rt
|
|
676
676
|
|
|
677
|
-
//
|
|
677
|
+
//selectByPk (1st time, 從DB讀取並填入快取)
|
|
678
678
|
rt = null
|
|
679
679
|
// vans[21] = { time: new Date('2025-01-01T00:01:00.000Z'), name: 'rosemary(modify)', value: 654.321 }
|
|
680
|
-
await woc.
|
|
680
|
+
await woc.selectByPk('2025-01-01T00:01:00Z')
|
|
681
681
|
.then(function(msg) {
|
|
682
|
-
// console.log('
|
|
682
|
+
// console.log('selectByPk 1st then', msg)
|
|
683
683
|
rt = msg
|
|
684
684
|
})
|
|
685
685
|
.catch(function(msg) {
|
|
686
|
-
// console.log('
|
|
686
|
+
// console.log('selectByPk 1st catch', msg)
|
|
687
687
|
rt = msg.toString()
|
|
688
688
|
})
|
|
689
689
|
vget[21] = rt
|
|
690
690
|
|
|
691
|
-
//
|
|
691
|
+
//selectByPk (2nd time, 命中快取, 內容須與第一次相同)
|
|
692
692
|
rt = null
|
|
693
693
|
// vans[22] = vans[21]
|
|
694
|
-
await woc.
|
|
694
|
+
await woc.selectByPk('2025-01-01T00:01:00Z')
|
|
695
695
|
.then(function(msg) {
|
|
696
|
-
// console.log('
|
|
696
|
+
// console.log('selectByPk 2nd then', msg)
|
|
697
697
|
rt = msg
|
|
698
698
|
})
|
|
699
699
|
.catch(function(msg) {
|
|
700
|
-
// console.log('
|
|
700
|
+
// console.log('selectByPk 2nd catch', msg)
|
|
701
701
|
rt = msg.toString()
|
|
702
702
|
})
|
|
703
703
|
vget[22] = rt
|
|
@@ -758,19 +758,19 @@ describe('basic', function() {
|
|
|
758
758
|
assert.strict.deepStrictEqual(vget[6], vans[6])
|
|
759
759
|
})
|
|
760
760
|
|
|
761
|
-
//vans[18]~vans[22]為後續新增之
|
|
761
|
+
//vans[18]~vans[22]為後續新增之selectByPk, 為不更動既有編號故接續於末號之後
|
|
762
762
|
vans[18] = { time: new Date('2025-01-01T00:10:00.000Z'), name: 'rosemary(modify)', value: 113.98 }
|
|
763
|
-
it(`should get ${JSON.stringify(vans[18])} for
|
|
763
|
+
it(`should get ${JSON.stringify(vans[18])} for selectByPk`, async function() {
|
|
764
764
|
assert.strict.deepStrictEqual(vget[18], vans[18])
|
|
765
765
|
})
|
|
766
766
|
|
|
767
767
|
vans[19] = null
|
|
768
|
-
it(`should get ${JSON.stringify(vans[19])} for
|
|
768
|
+
it(`should get ${JSON.stringify(vans[19])} for selectByPk by pk not existed`, async function() {
|
|
769
769
|
assert.strict.deepStrictEqual(vget[19], vans[19])
|
|
770
770
|
})
|
|
771
771
|
|
|
772
772
|
vans[20] = null
|
|
773
|
-
it(`should get ${JSON.stringify(vans[20])} for
|
|
773
|
+
it(`should get ${JSON.stringify(vans[20])} for selectByPk by pk invalid`, async function() {
|
|
774
774
|
assert.strict.deepStrictEqual(vget[20], vans[20])
|
|
775
775
|
})
|
|
776
776
|
|
|
@@ -877,12 +877,12 @@ describe('basic', function() {
|
|
|
877
877
|
})
|
|
878
878
|
|
|
879
879
|
vans[21] = { time: new Date('2025-01-01T00:01:00.000Z'), name: 'rosemary(modify)', value: 654.321 }
|
|
880
|
-
it(`should get ${JSON.stringify(vans[21])} for
|
|
880
|
+
it(`should get ${JSON.stringify(vans[21])} for selectByPk (1st, fill cache)`, async function() {
|
|
881
881
|
assert.strict.deepStrictEqual(vget[21], vans[21])
|
|
882
882
|
})
|
|
883
883
|
|
|
884
884
|
vans[22] = vans[21]
|
|
885
|
-
it(`should get ${JSON.stringify(vans[22])} for
|
|
885
|
+
it(`should get ${JSON.stringify(vans[22])} for selectByPk (2nd, cache hit)`, async function() {
|
|
886
886
|
assert.strict.deepStrictEqual(vget[22], vans[22])
|
|
887
887
|
})
|
|
888
888
|
|
|
@@ -954,7 +954,7 @@ describe('insert nInserted', function() {
|
|
|
954
954
|
vget[7] = ss.length
|
|
955
955
|
|
|
956
956
|
//同批重複者僅首筆入庫
|
|
957
|
-
let vdup = await wo.
|
|
957
|
+
let vdup = await wo.selectByPk('2025-02-01T00:05:00Z')
|
|
958
958
|
vget[8] = vdup.name
|
|
959
959
|
|
|
960
960
|
})
|
|
@@ -1028,7 +1028,7 @@ describe('save concurrency', function() {
|
|
|
1028
1028
|
wo.save({ time: tMerge, name: 'merge-name' }),
|
|
1029
1029
|
wo.save({ time: tMerge, value: 99 }),
|
|
1030
1030
|
])
|
|
1031
|
-
vget[1] = await wo.
|
|
1031
|
+
vget[1] = await wo.selectByPk(tMerge)
|
|
1032
1032
|
|
|
1033
1033
|
//併發save對全新time, autoInsert僅一次且不得報錯
|
|
1034
1034
|
let tNew = '2025-03-01T00:01:00Z'
|
|
@@ -1048,12 +1048,12 @@ describe('save concurrency', function() {
|
|
|
1048
1048
|
let tDiff = '2025-03-01T00:03:00Z'
|
|
1049
1049
|
await wo.insert({ time: tDiff, name: 'diff', value: 5 })
|
|
1050
1050
|
vget[6] = await wo.save({ time: tDiff, value: 6 })
|
|
1051
|
-
vget[7] = await wo.
|
|
1051
|
+
vget[7] = await wo.selectByPk(tDiff)
|
|
1052
1052
|
|
|
1053
1053
|
//save(autoInsert=false)對不存在之time不得插入
|
|
1054
1054
|
let tNone = '2025-03-01T00:04:00Z'
|
|
1055
1055
|
vget[8] = await wo.save({ time: tNone, name: 'none' }, { autoInsert: false })
|
|
1056
|
-
vget[9] = await wo.
|
|
1056
|
+
vget[9] = await wo.selectByPk(tNone)
|
|
1057
1057
|
|
|
1058
1058
|
//併發save(autoInsert=false)對既有time之不同欄位, 各欄位皆須保留且不得報錯
|
|
1059
1059
|
let tUpd = '2025-03-01T00:05:00Z'
|
|
@@ -1063,7 +1063,7 @@ describe('save concurrency', function() {
|
|
|
1063
1063
|
wo.save({ time: tUpd, value: 88 }, { autoInsert: false }),
|
|
1064
1064
|
])
|
|
1065
1065
|
vget[10] = rsu.filter((v) => v[0].ok !== 1).length
|
|
1066
|
-
vget[11] = await wo.
|
|
1066
|
+
vget[11] = await wo.selectByPk(tUpd)
|
|
1067
1067
|
|
|
1068
1068
|
})
|
|
1069
1069
|
|
|
@@ -1148,7 +1148,7 @@ describe('spec compliance', function() {
|
|
|
1148
1148
|
let tPart = '2025-04-01T00:00:00Z'
|
|
1149
1149
|
await wo.insert({ time: tPart, name: 'peter', value: 5 })
|
|
1150
1150
|
vget[1] = await wo.save({ time: tPart, value: 5 })
|
|
1151
|
-
vget[2] = await wo.
|
|
1151
|
+
vget[2] = await wo.selectByPk(tPart)
|
|
1152
1152
|
|
|
1153
1153
|
//save單筆失敗不中斷整批, 失敗筆須帶err
|
|
1154
1154
|
let tOk = '2025-04-01T00:01:00Z'
|
|
@@ -1302,6 +1302,378 @@ describe('spec compliance', function() {
|
|
|
1302
1302
|
})
|
|
1303
1303
|
|
|
1304
1304
|
|
|
1305
|
+
describe('custom pk', function() {
|
|
1306
|
+
let vans = {}
|
|
1307
|
+
let vget = {}
|
|
1308
|
+
|
|
1309
|
+
before(async function() {
|
|
1310
|
+
this.timeout(120000)
|
|
1311
|
+
|
|
1312
|
+
//wo, 以opt.pk指定主鍵欄位為code, 驗證select以外之五函數皆改以該欄位認定主鍵
|
|
1313
|
+
let cl = 'custompk'
|
|
1314
|
+
let wo = WOrm({
|
|
1315
|
+
...genOpt(cl),
|
|
1316
|
+
pk: 'code',
|
|
1317
|
+
})
|
|
1318
|
+
|
|
1319
|
+
//createTable, pk留空以驗證採用建構時之opt.pk
|
|
1320
|
+
await wo.createTable(cl, null, {
|
|
1321
|
+
code: 'abc',
|
|
1322
|
+
name: 'abc',
|
|
1323
|
+
value: 0.1,
|
|
1324
|
+
}).catch(() => {})
|
|
1325
|
+
await wo.delAll()
|
|
1326
|
+
|
|
1327
|
+
//insert以code認定主鍵
|
|
1328
|
+
vget[1] = await wo.insert([
|
|
1329
|
+
{ code: 'c1', name: 'peter', value: 1 },
|
|
1330
|
+
{ code: 'c2', name: 'rosemary', value: 2 },
|
|
1331
|
+
])
|
|
1332
|
+
|
|
1333
|
+
//insert同code者跳過, 證明ON CONFLICT係以code為衝突目標
|
|
1334
|
+
vget[2] = await wo.insert({ code: 'c1', name: 'other', value: 9 })
|
|
1335
|
+
|
|
1336
|
+
//selectByPk以code查找
|
|
1337
|
+
vget[3] = await wo.selectByPk('c1')
|
|
1338
|
+
|
|
1339
|
+
//selectByPk未命中
|
|
1340
|
+
vget[4] = await wo.selectByPk('notexist')
|
|
1341
|
+
|
|
1342
|
+
//save只給部份欄位且值不同, 未給之欄位須保留
|
|
1343
|
+
vget[5] = await wo.save({ code: 'c1', value: 5 })
|
|
1344
|
+
vget[6] = await wo.selectByPk('c1')
|
|
1345
|
+
|
|
1346
|
+
//save合併後內容相同不更新
|
|
1347
|
+
vget[7] = await wo.save({ code: 'c1', value: 5 })
|
|
1348
|
+
|
|
1349
|
+
//save對不存在之code自動插入
|
|
1350
|
+
vget[8] = await wo.save({ code: 'c3', name: 'sandler' })
|
|
1351
|
+
|
|
1352
|
+
//del以code刪除
|
|
1353
|
+
vget[9] = await wo.del({ code: 'c2' })
|
|
1354
|
+
|
|
1355
|
+
//del未帶有效code
|
|
1356
|
+
let rsd = await wo.del({ name: 'no-code' })
|
|
1357
|
+
vget[10] = {
|
|
1358
|
+
n: rsd[0].n,
|
|
1359
|
+
nDeleted: rsd[0].nDeleted,
|
|
1360
|
+
ok: rsd[0].ok,
|
|
1361
|
+
hasErr: isestr(rsd[0].err),
|
|
1362
|
+
}
|
|
1363
|
+
|
|
1364
|
+
//insert未帶有效code須reject
|
|
1365
|
+
vget[11] = await wo.insert({ name: 'no-code' })
|
|
1366
|
+
.then(() => 'resolved')
|
|
1367
|
+
.catch(() => 'rejected')
|
|
1368
|
+
|
|
1369
|
+
//最終筆數, 僅存c1與c3
|
|
1370
|
+
vget[12] = (await wo.select()).length
|
|
1371
|
+
|
|
1372
|
+
})
|
|
1373
|
+
|
|
1374
|
+
vans[1] = { n: 2, nInserted: 2, ok: 1 }
|
|
1375
|
+
it(`should get ${JSON.stringify(vans[1])} for insert with custom pk`, async function() {
|
|
1376
|
+
assert.strict.deepStrictEqual(vget[1], vans[1])
|
|
1377
|
+
})
|
|
1378
|
+
|
|
1379
|
+
vans[2] = { n: 1, nInserted: 0, ok: 1 }
|
|
1380
|
+
it(`should get ${JSON.stringify(vans[2])} for insert with existed custom pk`, async function() {
|
|
1381
|
+
assert.strict.deepStrictEqual(vget[2], vans[2])
|
|
1382
|
+
})
|
|
1383
|
+
|
|
1384
|
+
vans[3] = { code: 'c1', name: 'peter', value: 1 }
|
|
1385
|
+
it(`should get ${JSON.stringify(vans[3])} for selectByPk with custom pk`, async function() {
|
|
1386
|
+
assert.strict.deepStrictEqual(vget[3], vans[3])
|
|
1387
|
+
})
|
|
1388
|
+
|
|
1389
|
+
vans[4] = null
|
|
1390
|
+
it(`should get ${JSON.stringify(vans[4])} for selectByPk by custom pk not existed`, async function() {
|
|
1391
|
+
assert.strict.deepStrictEqual(vget[4], vans[4])
|
|
1392
|
+
})
|
|
1393
|
+
|
|
1394
|
+
vans[5] = [{ n: 1, nInserted: 0, nModified: 1, ok: 1 }]
|
|
1395
|
+
it(`should get ${JSON.stringify(vans[5])} for save with custom pk`, async function() {
|
|
1396
|
+
assert.strict.deepStrictEqual(vget[5], vans[5])
|
|
1397
|
+
})
|
|
1398
|
+
|
|
1399
|
+
vans[6] = { code: 'c1', name: 'peter', value: 5 }
|
|
1400
|
+
it(`should get ${JSON.stringify(vans[6])} for keeping field not given in save with custom pk`, async function() {
|
|
1401
|
+
assert.strict.deepStrictEqual(vget[6], vans[6])
|
|
1402
|
+
})
|
|
1403
|
+
|
|
1404
|
+
vans[7] = [{ n: 1, nInserted: 0, nModified: 0, ok: 1 }]
|
|
1405
|
+
it(`should get ${JSON.stringify(vans[7])} for save with same content by custom pk`, async function() {
|
|
1406
|
+
assert.strict.deepStrictEqual(vget[7], vans[7])
|
|
1407
|
+
})
|
|
1408
|
+
|
|
1409
|
+
vans[8] = [{ n: 1, nInserted: 1, nModified: 0, ok: 1 }]
|
|
1410
|
+
it(`should get ${JSON.stringify(vans[8])} for save(autoInsert) with custom pk not existed`, async function() {
|
|
1411
|
+
assert.strict.deepStrictEqual(vget[8], vans[8])
|
|
1412
|
+
})
|
|
1413
|
+
|
|
1414
|
+
vans[9] = [{ n: 1, nDeleted: 1, ok: 1 }]
|
|
1415
|
+
it(`should get ${JSON.stringify(vans[9])} for del with custom pk`, async function() {
|
|
1416
|
+
assert.strict.deepStrictEqual(vget[9], vans[9])
|
|
1417
|
+
})
|
|
1418
|
+
|
|
1419
|
+
vans[10] = { n: 0, nDeleted: 0, ok: 0, hasErr: true }
|
|
1420
|
+
it(`should get ${JSON.stringify(vans[10])} for del without valid custom pk`, async function() {
|
|
1421
|
+
assert.strict.deepStrictEqual(vget[10], vans[10])
|
|
1422
|
+
})
|
|
1423
|
+
|
|
1424
|
+
vans[11] = 'rejected'
|
|
1425
|
+
it(`should get ${JSON.stringify(vans[11])} for insert without valid custom pk`, async function() {
|
|
1426
|
+
assert.strict.deepStrictEqual(vget[11], vans[11])
|
|
1427
|
+
})
|
|
1428
|
+
|
|
1429
|
+
vans[12] = 2
|
|
1430
|
+
it(`should get ${JSON.stringify(vans[12])} for records after all operations with custom pk`, async function() {
|
|
1431
|
+
assert.strict.deepStrictEqual(vget[12], vans[12])
|
|
1432
|
+
})
|
|
1433
|
+
|
|
1434
|
+
})
|
|
1435
|
+
|
|
1436
|
+
|
|
1437
|
+
describe('events', function() {
|
|
1438
|
+
let vans = {}
|
|
1439
|
+
let vget = {}
|
|
1440
|
+
|
|
1441
|
+
before(async function() {
|
|
1442
|
+
this.timeout(120000)
|
|
1443
|
+
|
|
1444
|
+
//wo
|
|
1445
|
+
let cl = 'events'
|
|
1446
|
+
let wo = WOrm(genOpt(cl))
|
|
1447
|
+
|
|
1448
|
+
//createTable
|
|
1449
|
+
await wo.createTable(cl, null, {
|
|
1450
|
+
time: '2000-01-01T00:00:00Z',
|
|
1451
|
+
name: 'abc',
|
|
1452
|
+
value: 0.1,
|
|
1453
|
+
}).catch(() => {})
|
|
1454
|
+
await wo.delAll()
|
|
1455
|
+
|
|
1456
|
+
//evChange, evError, 收集事件供斷言
|
|
1457
|
+
let evChange = []
|
|
1458
|
+
let evError = []
|
|
1459
|
+
wo.on('change', (mode, data, res) => {
|
|
1460
|
+
evChange.push({ mode, res })
|
|
1461
|
+
})
|
|
1462
|
+
wo.on('error', (mode, data, err) => {
|
|
1463
|
+
evError.push({ mode, err })
|
|
1464
|
+
})
|
|
1465
|
+
|
|
1466
|
+
//reset
|
|
1467
|
+
let reset = () => {
|
|
1468
|
+
evChange = []
|
|
1469
|
+
evError = []
|
|
1470
|
+
}
|
|
1471
|
+
|
|
1472
|
+
//t
|
|
1473
|
+
let t1 = '2025-07-01T00:00:00Z'
|
|
1474
|
+
let t2 = '2025-07-01T00:01:00Z'
|
|
1475
|
+
let t3 = '2025-07-01T00:02:00Z'
|
|
1476
|
+
let t4 = '2025-07-01T00:03:00Z'
|
|
1477
|
+
let tNone = '2025-07-01T23:00:00Z'
|
|
1478
|
+
|
|
1479
|
+
//insert正常, 發change且不發error
|
|
1480
|
+
reset()
|
|
1481
|
+
await wo.insert([
|
|
1482
|
+
{ time: t1, name: 'peter', value: 1 },
|
|
1483
|
+
{ time: t2, name: 'rosemary', value: 2 },
|
|
1484
|
+
])
|
|
1485
|
+
vget[1] = evChange.map((v) => v.mode)
|
|
1486
|
+
vget[2] = evError.length
|
|
1487
|
+
|
|
1488
|
+
//insert全數已存在為正常結果, 不得發error
|
|
1489
|
+
reset()
|
|
1490
|
+
await wo.insert({ time: t1, name: 'peter', value: 1 })
|
|
1491
|
+
vget[3] = evError.length
|
|
1492
|
+
|
|
1493
|
+
//save之逐筆插入另發mode為insert之change, 整批再發save
|
|
1494
|
+
reset()
|
|
1495
|
+
await wo.save({ time: t3, name: 'sandler' })
|
|
1496
|
+
vget[4] = evChange.map((v) => v.mode)
|
|
1497
|
+
|
|
1498
|
+
//save合併後內容相同為正常結果, 不得發error
|
|
1499
|
+
reset()
|
|
1500
|
+
await wo.save({ time: t3, name: 'sandler' })
|
|
1501
|
+
vget[5] = evError.length
|
|
1502
|
+
|
|
1503
|
+
//save逐筆失敗發error且整批仍resolve
|
|
1504
|
+
reset()
|
|
1505
|
+
let rsf = await wo.save([
|
|
1506
|
+
{ time: t1, name: 'ok' },
|
|
1507
|
+
{ time: t4, notexistcol: 1 },
|
|
1508
|
+
])
|
|
1509
|
+
vget[6] = evError.map((v) => v.mode)
|
|
1510
|
+
vget[7] = isestr(evError[0].err)
|
|
1511
|
+
vget[8] = rsf.length
|
|
1512
|
+
vget[9] = evChange.map((v) => v.mode)
|
|
1513
|
+
|
|
1514
|
+
//del未帶有效主鍵為逐筆失敗, 發error
|
|
1515
|
+
reset()
|
|
1516
|
+
await wo.del([{ name: 'no-pk' }])
|
|
1517
|
+
vget[10] = evError.map((v) => v.mode)
|
|
1518
|
+
|
|
1519
|
+
//del主鍵未命中為正常結果, 不得發error
|
|
1520
|
+
reset()
|
|
1521
|
+
await wo.del({ time: tNone })
|
|
1522
|
+
vget[11] = evError.length
|
|
1523
|
+
|
|
1524
|
+
//selectByPk查無數據為正常結果, 不得發error
|
|
1525
|
+
reset()
|
|
1526
|
+
await wo.selectByPk(tNone)
|
|
1527
|
+
vget[12] = evError.length
|
|
1528
|
+
|
|
1529
|
+
//selectByPk主鍵值無效為正常結果, 不得發error
|
|
1530
|
+
reset()
|
|
1531
|
+
await wo.selectByPk('abc')
|
|
1532
|
+
vget[13] = evError.length
|
|
1533
|
+
|
|
1534
|
+
//delAll條件無命中為正常結果, 不得發error
|
|
1535
|
+
reset()
|
|
1536
|
+
await wo.delAll({ name: 'notexist' })
|
|
1537
|
+
vget[14] = evError.length
|
|
1538
|
+
|
|
1539
|
+
//整批性錯誤於reject之前發出error
|
|
1540
|
+
reset()
|
|
1541
|
+
vget[15] = await wo.insert({ name: 'no-pk' })
|
|
1542
|
+
.then(() => 'resolved')
|
|
1543
|
+
.catch(() => 'rejected')
|
|
1544
|
+
vget[16] = evError.map((v) => v.mode)
|
|
1545
|
+
|
|
1546
|
+
//T10.1第2條, 操作行為不得因監聽者之有無而改變
|
|
1547
|
+
//woNo未註冊任何監聽, woOn註冊error監聽, 兩者之回傳值須完全相同
|
|
1548
|
+
let woNo = WOrm(genOpt(cl))
|
|
1549
|
+
let woOn = WOrm(genOpt(cl))
|
|
1550
|
+
woOn.on('error', () => {})
|
|
1551
|
+
|
|
1552
|
+
//整批性錯誤
|
|
1553
|
+
let rNo1 = await woNo.insert({ name: 'no-pk' })
|
|
1554
|
+
.then(() => 'resolved')
|
|
1555
|
+
.catch((err) => `rejected:${err}`)
|
|
1556
|
+
let rOn1 = await woOn.insert({ name: 'no-pk' })
|
|
1557
|
+
.then(() => 'resolved')
|
|
1558
|
+
.catch((err) => `rejected:${err}`)
|
|
1559
|
+
vget[17] = rNo1 === rOn1
|
|
1560
|
+
vget[18] = rNo1.indexOf('rejected:') === 0
|
|
1561
|
+
|
|
1562
|
+
//逐筆失敗
|
|
1563
|
+
let rNo2 = await woNo.del([{ name: 'no-pk' }])
|
|
1564
|
+
let rOn2 = await woOn.del([{ name: 'no-pk' }])
|
|
1565
|
+
vget[19] = JSON.stringify(rNo2) === JSON.stringify(rOn2)
|
|
1566
|
+
|
|
1567
|
+
//正常操作
|
|
1568
|
+
let rNo3 = await woNo.selectByPk(t1)
|
|
1569
|
+
let rOn3 = await woOn.selectByPk(t1)
|
|
1570
|
+
vget[20] = JSON.stringify(rNo3) === JSON.stringify(rOn3)
|
|
1571
|
+
|
|
1572
|
+
})
|
|
1573
|
+
|
|
1574
|
+
vans[1] = ['insert']
|
|
1575
|
+
it(`should get ${JSON.stringify(vans[1])} for change modes by insert`, async function() {
|
|
1576
|
+
assert.strict.deepStrictEqual(vget[1], vans[1])
|
|
1577
|
+
})
|
|
1578
|
+
|
|
1579
|
+
vans[2] = 0
|
|
1580
|
+
it(`should get ${JSON.stringify(vans[2])} for error count by insert`, async function() {
|
|
1581
|
+
assert.strict.deepStrictEqual(vget[2], vans[2])
|
|
1582
|
+
})
|
|
1583
|
+
|
|
1584
|
+
vans[3] = 0
|
|
1585
|
+
it(`should get ${JSON.stringify(vans[3])} for error count by insert with all existed`, async function() {
|
|
1586
|
+
assert.strict.deepStrictEqual(vget[3], vans[3])
|
|
1587
|
+
})
|
|
1588
|
+
|
|
1589
|
+
vans[4] = ['insert', 'save']
|
|
1590
|
+
it(`should get ${JSON.stringify(vans[4])} for change modes by save with autoInsert`, async function() {
|
|
1591
|
+
assert.strict.deepStrictEqual(vget[4], vans[4])
|
|
1592
|
+
})
|
|
1593
|
+
|
|
1594
|
+
vans[5] = 0
|
|
1595
|
+
it(`should get ${JSON.stringify(vans[5])} for error count by save with same content`, async function() {
|
|
1596
|
+
assert.strict.deepStrictEqual(vget[5], vans[5])
|
|
1597
|
+
})
|
|
1598
|
+
|
|
1599
|
+
vans[6] = ['save']
|
|
1600
|
+
it(`should get ${JSON.stringify(vans[6])} for error modes by save with 1 failed record`, async function() {
|
|
1601
|
+
assert.strict.deepStrictEqual(vget[6], vans[6])
|
|
1602
|
+
})
|
|
1603
|
+
|
|
1604
|
+
vans[7] = true
|
|
1605
|
+
it(`should get ${JSON.stringify(vans[7])} for err of error event being string`, async function() {
|
|
1606
|
+
assert.strict.deepStrictEqual(vget[7], vans[7])
|
|
1607
|
+
})
|
|
1608
|
+
|
|
1609
|
+
vans[8] = 2
|
|
1610
|
+
it(`should get ${JSON.stringify(vans[8])} for length of save result while 1 record failed`, async function() {
|
|
1611
|
+
assert.strict.deepStrictEqual(vget[8], vans[8])
|
|
1612
|
+
})
|
|
1613
|
+
|
|
1614
|
+
vans[9] = ['save']
|
|
1615
|
+
it(`should get ${JSON.stringify(vans[9])} for change modes by save while 1 record failed`, async function() {
|
|
1616
|
+
assert.strict.deepStrictEqual(vget[9], vans[9])
|
|
1617
|
+
})
|
|
1618
|
+
|
|
1619
|
+
vans[10] = ['del']
|
|
1620
|
+
it(`should get ${JSON.stringify(vans[10])} for error modes by del without valid pk`, async function() {
|
|
1621
|
+
assert.strict.deepStrictEqual(vget[10], vans[10])
|
|
1622
|
+
})
|
|
1623
|
+
|
|
1624
|
+
vans[11] = 0
|
|
1625
|
+
it(`should get ${JSON.stringify(vans[11])} for error count by del with pk not existed`, async function() {
|
|
1626
|
+
assert.strict.deepStrictEqual(vget[11], vans[11])
|
|
1627
|
+
})
|
|
1628
|
+
|
|
1629
|
+
vans[12] = 0
|
|
1630
|
+
it(`should get ${JSON.stringify(vans[12])} for error count by selectByPk with pk not existed`, async function() {
|
|
1631
|
+
assert.strict.deepStrictEqual(vget[12], vans[12])
|
|
1632
|
+
})
|
|
1633
|
+
|
|
1634
|
+
vans[13] = 0
|
|
1635
|
+
it(`should get ${JSON.stringify(vans[13])} for error count by selectByPk with pk invalid`, async function() {
|
|
1636
|
+
assert.strict.deepStrictEqual(vget[13], vans[13])
|
|
1637
|
+
})
|
|
1638
|
+
|
|
1639
|
+
vans[14] = 0
|
|
1640
|
+
it(`should get ${JSON.stringify(vans[14])} for error count by delAll with find matched nothing`, async function() {
|
|
1641
|
+
assert.strict.deepStrictEqual(vget[14], vans[14])
|
|
1642
|
+
})
|
|
1643
|
+
|
|
1644
|
+
vans[15] = 'rejected'
|
|
1645
|
+
it(`should get ${JSON.stringify(vans[15])} for insert without valid pk`, async function() {
|
|
1646
|
+
assert.strict.deepStrictEqual(vget[15], vans[15])
|
|
1647
|
+
})
|
|
1648
|
+
|
|
1649
|
+
vans[16] = ['insert']
|
|
1650
|
+
it(`should get ${JSON.stringify(vans[16])} for error modes by insert without valid pk`, async function() {
|
|
1651
|
+
assert.strict.deepStrictEqual(vget[16], vans[16])
|
|
1652
|
+
})
|
|
1653
|
+
|
|
1654
|
+
vans[17] = true
|
|
1655
|
+
it(`should get ${JSON.stringify(vans[17])} for same reject value with and without error listener`, async function() {
|
|
1656
|
+
assert.strict.deepStrictEqual(vget[17], vans[17])
|
|
1657
|
+
})
|
|
1658
|
+
|
|
1659
|
+
vans[18] = true
|
|
1660
|
+
it(`should get ${JSON.stringify(vans[18])} for still rejecting without error listener`, async function() {
|
|
1661
|
+
assert.strict.deepStrictEqual(vget[18], vans[18])
|
|
1662
|
+
})
|
|
1663
|
+
|
|
1664
|
+
vans[19] = true
|
|
1665
|
+
it(`should get ${JSON.stringify(vans[19])} for same del result with and without error listener`, async function() {
|
|
1666
|
+
assert.strict.deepStrictEqual(vget[19], vans[19])
|
|
1667
|
+
})
|
|
1668
|
+
|
|
1669
|
+
vans[20] = true
|
|
1670
|
+
it(`should get ${JSON.stringify(vans[20])} for same selectByPk result with and without error listener`, async function() {
|
|
1671
|
+
assert.strict.deepStrictEqual(vget[20], vans[20])
|
|
1672
|
+
})
|
|
1673
|
+
|
|
1674
|
+
})
|
|
1675
|
+
|
|
1676
|
+
|
|
1305
1677
|
//runProc, 另起行程對同一資料表操作, 用於驗證跨行程之原子性
|
|
1306
1678
|
//子行程以--input-type=module執行, 並以pathToFileURL轉換src路徑, 避免專案路徑含非ASCII字元而無法import
|
|
1307
1679
|
function runProc(tag, opt, mode, payload) {
|
|
@@ -1416,7 +1788,7 @@ describe('cross-process concurrency', function() {
|
|
|
1416
1788
|
vget[5] = rpss.reduce((sum, v) => sum + (v.nInserted || 0), 0)
|
|
1417
1789
|
|
|
1418
1790
|
//10欄須全數保留且值為各自行程之tag
|
|
1419
|
-
let vSav = await woSav.
|
|
1791
|
+
let vSav = await woSav.selectByPk(tSav)
|
|
1420
1792
|
vget[6] = Array.from({ length: 10 }, (v, k) => k)
|
|
1421
1793
|
.filter((k) => {
|
|
1422
1794
|
let tag = k <= 4 ? 'p1' : 'p2'
|