w-orm-lmdb 1.0.16 → 1.0.18
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 +15 -0
- package/dist/req-mingo.umd.js +1 -1
- package/dist/w-orm-lmdb.umd.js +2 -2
- package/dist/w-orm-lmdb.umd.js.map +1 -1
- package/docs/WOrmLmdb.html +63 -9
- package/docs/WOrmLmdb.mjs.html +139 -78
- package/docs/index.html +1 -1
- package/g-basic.mjs +15 -0
- package/package.json +1 -1
- package/src/WOrmLmdb.mjs +138 -77
- package/test/unit-autogenpk.test.mjs +188 -0
- package/test/unit-event.test.mjs +242 -0
- package//350/263/207/346/226/231/345/272/253/345/207/275/346/225/270/345/233/236/345/202/263/345/256/232/347/276/251/350/250/210/347/256/227.md +165 -22
package/src/WOrmLmdb.mjs
CHANGED
|
@@ -23,12 +23,30 @@ import waitFun from 'wsemi/src/waitFun.mjs'
|
|
|
23
23
|
/**
|
|
24
24
|
* 操作資料庫(LMDB)
|
|
25
25
|
*
|
|
26
|
+
* 回傳物件為EventEmitter,除各操作函數外另發出change與error兩事件,供呼叫端於單一處集中觀察資料異動與失敗。
|
|
27
|
+
* 事件僅為附加通知,其所送出之資訊皆另有正規管道(操作結果經resolve、整批性錯誤經reject、逐筆失敗經該筆之err欄位),
|
|
28
|
+
* 故不監聽亦能取得完整資訊,且監聽與否不改變任何操作之回傳值。
|
|
29
|
+
*
|
|
30
|
+
* change事件,參數為(mode, data, res),於資料實際異動成功後發出:
|
|
31
|
+
* mode為操作別字串,可為'insert'、'save'、'del'、'delAll';save內若逐筆走自動插入則該筆另發出mode為'insert'之事件。
|
|
32
|
+
* data為本次操作之輸入數據,delAll固定為null。
|
|
33
|
+
* res為本次操作之回傳結果。
|
|
34
|
+
* 逐筆函數以整批為單位發出一次而不逐筆發出,select與selectByPk不發出本事件。
|
|
35
|
+
*
|
|
36
|
+
* error事件,參數為(mode, data, err),於操作發生錯誤時發出:
|
|
37
|
+
* mode為操作別字串,可為'select'、'selectByPk'、'insert'、'save'、'del'、'delAll'。
|
|
38
|
+
* data為本次操作之輸入數據,無輸入數據者為null。
|
|
39
|
+
* err為錯誤訊息字串,內容與正規管道所送出者一致。
|
|
40
|
+
* 整批性錯誤於reject之前發出;逐筆失敗於該筆結果定案後發出,每筆一次。
|
|
41
|
+
* 註: 逐筆失敗時整批仍resolve,故收到本事件不表示該次呼叫失敗;正常結果(如查無數據、主鍵未命中、全數已存在)不發出本事件。
|
|
42
|
+
*
|
|
26
43
|
* @class
|
|
27
44
|
* @param {Object} [opt={}] 輸入設定物件,預設{}
|
|
28
45
|
* @param {String} [opt.url='_db'] 輸入資料庫用資料夾字串,預設'_db'
|
|
29
46
|
* @param {String} [opt.db='worm'] 輸入使用資料庫名稱字串,預設'worm'
|
|
30
47
|
* @param {String} [opt.cl='test'] 輸入使用資料表名稱字串,預設'test'
|
|
31
48
|
* @param {Boolean} [opt.useCache=false] 輸入是否使用select快取,適用於單程序操作,預設false
|
|
49
|
+
* @param {Boolean} [opt.autoGenPk=true] 輸入insert與save於數據未帶有效主鍵(本套件為id欄位)時是否自動產生主鍵值,預設true;給false代表主鍵改由呼叫端自備,套件不產生亦不檢查其唯一性與格式,未帶有效主鍵者將reject
|
|
32
50
|
* @returns {Object} 回傳操作資料庫物件,各事件功能詳見說明
|
|
33
51
|
*/
|
|
34
52
|
function WOrmLmdb(opt = {}) {
|
|
@@ -60,6 +78,13 @@ function WOrmLmdb(opt = {}) {
|
|
|
60
78
|
useCache = false
|
|
61
79
|
}
|
|
62
80
|
|
|
81
|
+
//autoGenPk, 主鍵由誰產生為整個資料表之政策, 故為建構層設定, 不可於insert與save之option逐次覆寫,
|
|
82
|
+
//否則同一資料表將混入兩種來源之主鍵而難以追溯
|
|
83
|
+
let autoGenPk = get(opt, 'autoGenPk')
|
|
84
|
+
if (!isbol(autoGenPk)) {
|
|
85
|
+
autoGenPk = true
|
|
86
|
+
}
|
|
87
|
+
|
|
63
88
|
//storage
|
|
64
89
|
let storage = `${url}/${db}/${cl}`
|
|
65
90
|
// console.log('storage',storage)
|
|
@@ -110,7 +135,30 @@ function WOrmLmdb(opt = {}) {
|
|
|
110
135
|
})
|
|
111
136
|
}
|
|
112
137
|
|
|
113
|
-
//
|
|
138
|
+
//emitChange, 資料實際異動成功後發出, 事件僅為附加通知不承擔回傳義務
|
|
139
|
+
//一律包try/catch, 令訂閱函數自身拋錯不影響本次操作之結果
|
|
140
|
+
let emitChange = (mode, data, res) => {
|
|
141
|
+
try {
|
|
142
|
+
ee.emit('change', mode, data, res)
|
|
143
|
+
}
|
|
144
|
+
catch (err) {
|
|
145
|
+
console.log(err)
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
//emitError, 操作發生錯誤時發出, 錯誤訊息一律轉為字串
|
|
150
|
+
//此try/catch除攔訂閱函數之例外外另有必要: Node之EventEmitter於'error'無監聽者時會將錯誤直接拋出,
|
|
151
|
+
//若不攔則同一次操作會因呼叫端有無註冊監聽而走向不同結果
|
|
152
|
+
let emitError = (mode, data, err) => {
|
|
153
|
+
try {
|
|
154
|
+
ee.emit('error', mode, data, getErrMsg(err))
|
|
155
|
+
}
|
|
156
|
+
catch (errEmit) {
|
|
157
|
+
console.log(errEmit)
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
//getErrMsg, 取錯誤訊息字串, 供逐筆結果之err欄位與error事件使用
|
|
114
162
|
let getErrMsg = (err) => {
|
|
115
163
|
let m = get(err, 'message')
|
|
116
164
|
if (isestr(m)) {
|
|
@@ -119,6 +167,26 @@ function WOrmLmdb(opt = {}) {
|
|
|
119
167
|
return String(err)
|
|
120
168
|
}
|
|
121
169
|
|
|
170
|
+
//procPk, 依autoGenPk處理各數據之主鍵, 供insert與save共用
|
|
171
|
+
//autoGenPk為true時補值; 為false時不補值, 未帶有效主鍵者屬呼叫端未履行契約, 拋出為整批性錯誤,
|
|
172
|
+
//且檢查於任何寫入之前完成, 故不會有部份筆數已寫入而整批失敗之情形
|
|
173
|
+
let procPk = (data, fnName) => {
|
|
174
|
+
if (autoGenPk) {
|
|
175
|
+
return map(data, function(v) {
|
|
176
|
+
if (!isestr(v.id)) {
|
|
177
|
+
v.id = genIDSeq()
|
|
178
|
+
}
|
|
179
|
+
return v
|
|
180
|
+
})
|
|
181
|
+
}
|
|
182
|
+
each(data, function(v, k) {
|
|
183
|
+
if (!isestr(get(v, 'id'))) {
|
|
184
|
+
throw new Error(`can not ${fnName} by data[${k}] without valid id when autoGenPk is false`)
|
|
185
|
+
}
|
|
186
|
+
})
|
|
187
|
+
return data
|
|
188
|
+
}
|
|
189
|
+
|
|
122
190
|
//getValue
|
|
123
191
|
let getValue = async (key) => {
|
|
124
192
|
let value = null
|
|
@@ -184,6 +252,10 @@ function WOrmLmdb(opt = {}) {
|
|
|
184
252
|
|
|
185
253
|
//check
|
|
186
254
|
if (isErr) {
|
|
255
|
+
|
|
256
|
+
//emit, 整批性錯誤須於reject之前發出
|
|
257
|
+
emitError('select', null, res)
|
|
258
|
+
|
|
187
259
|
return Promise.reject(res)
|
|
188
260
|
}
|
|
189
261
|
|
|
@@ -233,6 +305,10 @@ function WOrmLmdb(opt = {}) {
|
|
|
233
305
|
|
|
234
306
|
//check
|
|
235
307
|
if (isErr) {
|
|
308
|
+
|
|
309
|
+
//emit, 整批性錯誤須於reject之前發出
|
|
310
|
+
emitError('selectByPk', null, res)
|
|
311
|
+
|
|
236
312
|
return Promise.reject(res)
|
|
237
313
|
}
|
|
238
314
|
|
|
@@ -271,12 +347,7 @@ function WOrmLmdb(opt = {}) {
|
|
|
271
347
|
}
|
|
272
348
|
|
|
273
349
|
//check id
|
|
274
|
-
data =
|
|
275
|
-
if (!isestr(v.id)) {
|
|
276
|
-
v.id = genIDSeq()
|
|
277
|
-
}
|
|
278
|
-
return v
|
|
279
|
-
})
|
|
350
|
+
data = procPk(data, 'insert')
|
|
280
351
|
|
|
281
352
|
//each
|
|
282
353
|
//ifNoExists, 由LMDB於同一寫交易內原子完成[檢查v.id未存在]與[寫入], 併發時同一v.id僅有一次成功,
|
|
@@ -321,19 +392,15 @@ function WOrmLmdb(opt = {}) {
|
|
|
321
392
|
|
|
322
393
|
//emit, 於change可能須使用select, 故須放在重設快取之後
|
|
323
394
|
if (!isErr) {
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
//emit
|
|
327
|
-
ee.emit('change', 'insert', data, res)
|
|
328
|
-
|
|
329
|
-
}
|
|
330
|
-
catch (err) {
|
|
331
|
-
console.log(err)
|
|
332
|
-
}
|
|
395
|
+
emitChange('insert', data, res)
|
|
333
396
|
}
|
|
334
397
|
|
|
335
398
|
//check
|
|
336
399
|
if (isErr) {
|
|
400
|
+
|
|
401
|
+
//emit, 整批性錯誤須於reject之前發出
|
|
402
|
+
emitError('insert', data, res)
|
|
403
|
+
|
|
337
404
|
return Promise.reject(res)
|
|
338
405
|
}
|
|
339
406
|
|
|
@@ -373,12 +440,7 @@ function WOrmLmdb(opt = {}) {
|
|
|
373
440
|
}
|
|
374
441
|
|
|
375
442
|
//check id
|
|
376
|
-
data =
|
|
377
|
-
if (!isestr(v.id)) {
|
|
378
|
-
v.id = genIDSeq()
|
|
379
|
-
}
|
|
380
|
-
return v
|
|
381
|
-
})
|
|
443
|
+
data = procPk(data, 'save')
|
|
382
444
|
|
|
383
445
|
//pmSeries
|
|
384
446
|
res = await pmSeries(data, async(v) => {
|
|
@@ -507,16 +569,15 @@ function WOrmLmdb(opt = {}) {
|
|
|
507
569
|
//update, 不能保證插入多少, 一律重設快取
|
|
508
570
|
_cache = null
|
|
509
571
|
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
//emit
|
|
513
|
-
ee.emit('change', 'insert', [v], rest)
|
|
572
|
+
//emit
|
|
573
|
+
emitChange('insert', [v], rest)
|
|
514
574
|
|
|
515
|
-
|
|
516
|
-
catch (err) {
|
|
517
|
-
console.log(err)
|
|
518
|
-
}
|
|
575
|
+
}
|
|
519
576
|
|
|
577
|
+
//emit, 逐筆失敗於該筆結果定案後發出, 每筆一次
|
|
578
|
+
//此事件之發出不表示整批失敗, 整批仍resolve, 該筆以ok為0回報
|
|
579
|
+
if (rest.ok === 0) {
|
|
580
|
+
emitError('save', [v], rest.err)
|
|
520
581
|
}
|
|
521
582
|
|
|
522
583
|
return rest
|
|
@@ -532,20 +593,17 @@ function WOrmLmdb(opt = {}) {
|
|
|
532
593
|
_cache = null
|
|
533
594
|
|
|
534
595
|
//emit, 於change可能須使用select, 故須放在重設快取之後
|
|
596
|
+
//逐筆失敗之error事件已於各筆定案時發出, 故必早於本整批change
|
|
535
597
|
if (!isErr) {
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
//emit
|
|
539
|
-
ee.emit('change', 'save', data, res)
|
|
540
|
-
|
|
541
|
-
}
|
|
542
|
-
catch (err) {
|
|
543
|
-
console.log(err)
|
|
544
|
-
}
|
|
598
|
+
emitChange('save', data, res)
|
|
545
599
|
}
|
|
546
600
|
|
|
547
601
|
//check
|
|
548
602
|
if (isErr) {
|
|
603
|
+
|
|
604
|
+
//emit, 整批性錯誤須於reject之前發出
|
|
605
|
+
emitError('save', data, res)
|
|
606
|
+
|
|
549
607
|
return Promise.reject(res)
|
|
550
608
|
}
|
|
551
609
|
|
|
@@ -594,38 +652,42 @@ function WOrmLmdb(opt = {}) {
|
|
|
594
652
|
if (!isestr(id)) {
|
|
595
653
|
//未給有效v.id視為該筆數據有問題而無法處理, 以ok為0並附err回報,
|
|
596
654
|
//與[已給v.id但查無數據]之ok為1有別, 二者須可由ok分辨
|
|
597
|
-
return
|
|
655
|
+
//註: 此處不可直接return, 否則會跳過本回調末尾之error事件發出
|
|
656
|
+
rest = {
|
|
598
657
|
n: 0,
|
|
599
658
|
nDeleted: 0,
|
|
600
659
|
ok: 0,
|
|
601
660
|
err: `can not delete by invalid id[${id}]`,
|
|
602
661
|
}
|
|
603
662
|
}
|
|
663
|
+
else {
|
|
604
664
|
|
|
605
|
-
|
|
606
|
-
|
|
665
|
+
//查找資料表內v.id
|
|
666
|
+
let vv = await getValue(id) //不會有catch
|
|
607
667
|
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
668
|
+
//check
|
|
669
|
+
if (iseobj(vv)) {
|
|
670
|
+
//已存在v.id則須刪除
|
|
611
671
|
|
|
612
|
-
|
|
613
|
-
|
|
672
|
+
//del
|
|
673
|
+
await client.del(id)
|
|
674
|
+
|
|
675
|
+
//rest
|
|
676
|
+
rest = {
|
|
677
|
+
n: 1,
|
|
678
|
+
nDeleted: 1,
|
|
679
|
+
ok: 1,
|
|
680
|
+
}
|
|
614
681
|
|
|
615
|
-
//rest
|
|
616
|
-
rest = {
|
|
617
|
-
n: 1,
|
|
618
|
-
nDeleted: 1,
|
|
619
|
-
ok: 1,
|
|
620
682
|
}
|
|
683
|
+
else {
|
|
684
|
+
//不存在v.id則不刪除, 未命中故n為0
|
|
685
|
+
rest = {
|
|
686
|
+
n: 0,
|
|
687
|
+
nDeleted: 0,
|
|
688
|
+
ok: 1,
|
|
689
|
+
}
|
|
621
690
|
|
|
622
|
-
}
|
|
623
|
-
else {
|
|
624
|
-
//不存在v.id則不刪除, 未命中故n為0
|
|
625
|
-
rest = {
|
|
626
|
-
n: 0,
|
|
627
|
-
nDeleted: 0,
|
|
628
|
-
ok: 1,
|
|
629
691
|
}
|
|
630
692
|
|
|
631
693
|
}
|
|
@@ -643,6 +705,12 @@ function WOrmLmdb(opt = {}) {
|
|
|
643
705
|
|
|
644
706
|
}
|
|
645
707
|
|
|
708
|
+
//emit, 逐筆失敗於該筆結果定案後發出, 每筆一次
|
|
709
|
+
//此事件之發出不表示整批失敗, 整批仍resolve, 該筆以ok為0回報
|
|
710
|
+
if (rest.ok === 0) {
|
|
711
|
+
emitError('del', [v], rest.err)
|
|
712
|
+
}
|
|
713
|
+
|
|
646
714
|
return rest
|
|
647
715
|
})
|
|
648
716
|
|
|
@@ -656,20 +724,17 @@ function WOrmLmdb(opt = {}) {
|
|
|
656
724
|
_cache = null
|
|
657
725
|
|
|
658
726
|
//emit, 於change可能須使用select, 故須放在重設快取之後
|
|
727
|
+
//逐筆失敗之error事件已於各筆定案時發出, 故必早於本整批change
|
|
659
728
|
if (!isErr) {
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
//emit
|
|
663
|
-
ee.emit('change', 'del', data, res)
|
|
664
|
-
|
|
665
|
-
}
|
|
666
|
-
catch (err) {
|
|
667
|
-
console.log(err)
|
|
668
|
-
}
|
|
729
|
+
emitChange('del', data, res)
|
|
669
730
|
}
|
|
670
731
|
|
|
671
732
|
//check
|
|
672
733
|
if (isErr) {
|
|
734
|
+
|
|
735
|
+
//emit, 整批性錯誤須於reject之前發出
|
|
736
|
+
emitError('del', data, res)
|
|
737
|
+
|
|
673
738
|
return Promise.reject(res)
|
|
674
739
|
}
|
|
675
740
|
|
|
@@ -771,19 +836,15 @@ function WOrmLmdb(opt = {}) {
|
|
|
771
836
|
|
|
772
837
|
//emit, 於change可能須使用select, 故須放在重設快取之後
|
|
773
838
|
if (!isErr) {
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
//emit
|
|
777
|
-
ee.emit('change', 'delAll', null, res)
|
|
778
|
-
|
|
779
|
-
}
|
|
780
|
-
catch (err) {
|
|
781
|
-
console.log(err)
|
|
782
|
-
}
|
|
839
|
+
emitChange('delAll', null, res)
|
|
783
840
|
}
|
|
784
841
|
|
|
785
842
|
//check
|
|
786
843
|
if (isErr) {
|
|
844
|
+
|
|
845
|
+
//emit, 整批性錯誤須於reject之前發出
|
|
846
|
+
emitError('delAll', null, res)
|
|
847
|
+
|
|
787
848
|
return Promise.reject(res)
|
|
788
849
|
}
|
|
789
850
|
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import assert from 'assert'
|
|
2
|
+
import _ from 'lodash-es'
|
|
3
|
+
import w from 'wsemi'
|
|
4
|
+
import WOrm from '../src/WOrmLmdb.mjs'
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
describe('autoGenPk', function() {
|
|
8
|
+
let rt = null
|
|
9
|
+
let vans = {}
|
|
10
|
+
let vget = {}
|
|
11
|
+
|
|
12
|
+
before(async function() {
|
|
13
|
+
|
|
14
|
+
w.fsDeleteFolder('./_db_autogenpk')
|
|
15
|
+
|
|
16
|
+
let url = './_db_autogenpk'
|
|
17
|
+
|
|
18
|
+
//預設值須為true, 未帶id者自動補值
|
|
19
|
+
let woDef = WOrm({ url, db: 'worm', cl: 'def' })
|
|
20
|
+
await woDef.insert({ name: 'peter' })
|
|
21
|
+
let rsDef = await woDef.select()
|
|
22
|
+
vget[1] = _.size(rsDef)
|
|
23
|
+
vget[2] = w.isestr(_.get(rsDef, '0.id'))
|
|
24
|
+
await woDef.close()
|
|
25
|
+
|
|
26
|
+
//明確給true, 行為須與預設相同
|
|
27
|
+
let woTrue = WOrm({ url, db: 'worm', cl: 'ptrue', autoGenPk: true })
|
|
28
|
+
rt = null
|
|
29
|
+
// vans[3] = { n: 2, nInserted: 2, ok: 1 }
|
|
30
|
+
await woTrue.insert([{ name: 'a' }, { name: 'b' }])
|
|
31
|
+
.then(function(msg) {
|
|
32
|
+
rt = msg
|
|
33
|
+
})
|
|
34
|
+
.catch(function(msg) {
|
|
35
|
+
rt = 'reject: ' + msg.toString()
|
|
36
|
+
})
|
|
37
|
+
vget[3] = rt
|
|
38
|
+
vget[4] = _.size(_.filter(await woTrue.select(), function(v) {
|
|
39
|
+
return w.isestr(v.id)
|
|
40
|
+
}))
|
|
41
|
+
await woTrue.close()
|
|
42
|
+
|
|
43
|
+
//給false且自備id, 須正常寫入且沿用呼叫端所給之id
|
|
44
|
+
let woFalse = WOrm({ url, db: 'worm', cl: 'pfalse', autoGenPk: false })
|
|
45
|
+
rt = null
|
|
46
|
+
// vans[5] = { n: 2, nInserted: 2, ok: 1 }
|
|
47
|
+
await woFalse.insert([{ id: 'own-1', name: 'a' }, { id: 'own-2', name: 'b' }])
|
|
48
|
+
.then(function(msg) {
|
|
49
|
+
rt = msg
|
|
50
|
+
})
|
|
51
|
+
.catch(function(msg) {
|
|
52
|
+
rt = 'reject: ' + msg.toString()
|
|
53
|
+
})
|
|
54
|
+
vget[5] = rt
|
|
55
|
+
vget[6] = _.map(_.sortBy(await woFalse.select(), 'id'), 'id')
|
|
56
|
+
|
|
57
|
+
//給false且save自備id, 須正常處理
|
|
58
|
+
rt = null
|
|
59
|
+
// vans[7] = [{ n: 1, nInserted: 0, nModified: 1, ok: 1 }]
|
|
60
|
+
await woFalse.save({ id: 'own-1', name: 'a2' })
|
|
61
|
+
.then(function(msg) {
|
|
62
|
+
rt = msg
|
|
63
|
+
})
|
|
64
|
+
.catch(function(msg) {
|
|
65
|
+
rt = 'reject: ' + msg.toString()
|
|
66
|
+
})
|
|
67
|
+
vget[7] = rt
|
|
68
|
+
|
|
69
|
+
//給false而insert未帶有效id, 須reject且不得有任何寫入
|
|
70
|
+
rt = null
|
|
71
|
+
await woFalse.insert({ name: 'no-id' })
|
|
72
|
+
.then(function(msg) {
|
|
73
|
+
rt = 'resolve: ' + JSON.stringify(msg)
|
|
74
|
+
})
|
|
75
|
+
.catch(function(msg) {
|
|
76
|
+
rt = 'reject'
|
|
77
|
+
})
|
|
78
|
+
vget[8] = rt
|
|
79
|
+
|
|
80
|
+
//給false而save未帶有效id, 須reject
|
|
81
|
+
rt = null
|
|
82
|
+
await woFalse.save({ name: 'no-id' })
|
|
83
|
+
.then(function(msg) {
|
|
84
|
+
rt = 'resolve: ' + JSON.stringify(msg)
|
|
85
|
+
})
|
|
86
|
+
.catch(function(msg) {
|
|
87
|
+
rt = 'reject'
|
|
88
|
+
})
|
|
89
|
+
vget[9] = rt
|
|
90
|
+
|
|
91
|
+
//給false而整批內僅部份未帶有效id, 須整批reject且不得有部份筆數已寫入
|
|
92
|
+
rt = null
|
|
93
|
+
await woFalse.insert([{ id: 'own-3', name: 'c' }, { name: 'no-id' }])
|
|
94
|
+
.then(function(msg) {
|
|
95
|
+
rt = 'resolve: ' + JSON.stringify(msg)
|
|
96
|
+
})
|
|
97
|
+
.catch(function(msg) {
|
|
98
|
+
rt = 'reject'
|
|
99
|
+
})
|
|
100
|
+
vget[10] = rt
|
|
101
|
+
vget[11] = _.map(_.sortBy(await woFalse.select(), 'id'), 'id')
|
|
102
|
+
await woFalse.close()
|
|
103
|
+
|
|
104
|
+
//del不受autoGenPk影響, 未帶有效id者為該筆問題而非整批性錯誤
|
|
105
|
+
let woDel = WOrm({ url, db: 'worm', cl: 'pdel', autoGenPk: false })
|
|
106
|
+
await woDel.insert({ id: 'd1', name: 'x' })
|
|
107
|
+
rt = null
|
|
108
|
+
await woDel.del([{ id: 'd1' }, { name: 'no-id' }])
|
|
109
|
+
.then(function(msg) {
|
|
110
|
+
rt = _.map(msg, function(v) {
|
|
111
|
+
return _.omit(v, 'err')
|
|
112
|
+
})
|
|
113
|
+
})
|
|
114
|
+
.catch(function(msg) {
|
|
115
|
+
rt = 'reject: ' + msg.toString()
|
|
116
|
+
})
|
|
117
|
+
vget[12] = rt
|
|
118
|
+
await woDel.close()
|
|
119
|
+
|
|
120
|
+
})
|
|
121
|
+
|
|
122
|
+
vans[1] = 1
|
|
123
|
+
it(`should get ${JSON.stringify(vans[1])} for records by insert without id in default`, async function() {
|
|
124
|
+
assert.strict.deepStrictEqual(vget[1], vans[1])
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
vans[2] = true
|
|
128
|
+
it(`should get ${JSON.stringify(vans[2])} for id generated by default`, async function() {
|
|
129
|
+
assert.strict.deepStrictEqual(vget[2], vans[2])
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
vans[3] = { n: 2, nInserted: 2, ok: 1 }
|
|
133
|
+
it(`should get ${JSON.stringify(vans[3])} for insert without id by autoGenPk=true`, async function() {
|
|
134
|
+
assert.strict.deepStrictEqual(vget[3], vans[3])
|
|
135
|
+
})
|
|
136
|
+
|
|
137
|
+
vans[4] = 2
|
|
138
|
+
it(`should get ${JSON.stringify(vans[4])} for records with generated id by autoGenPk=true`, async function() {
|
|
139
|
+
assert.strict.deepStrictEqual(vget[4], vans[4])
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
vans[5] = { n: 2, nInserted: 2, ok: 1 }
|
|
143
|
+
it(`should get ${JSON.stringify(vans[5])} for insert with own id by autoGenPk=false`, async function() {
|
|
144
|
+
assert.strict.deepStrictEqual(vget[5], vans[5])
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
vans[6] = ['own-1', 'own-2']
|
|
148
|
+
it(`should get ${JSON.stringify(vans[6])} for keeping own id by autoGenPk=false`, async function() {
|
|
149
|
+
assert.strict.deepStrictEqual(vget[6], vans[6])
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
vans[7] = [{ n: 1, nInserted: 0, nModified: 1, ok: 1 }]
|
|
153
|
+
it(`should get ${JSON.stringify(vans[7])} for save with own id by autoGenPk=false`, async function() {
|
|
154
|
+
assert.strict.deepStrictEqual(vget[7], vans[7])
|
|
155
|
+
})
|
|
156
|
+
|
|
157
|
+
//autoGenPk為false而未帶有效主鍵屬呼叫端未履行契約, 須為整批性錯誤而非該筆ok為0
|
|
158
|
+
vans[8] = 'reject'
|
|
159
|
+
it(`should get ${JSON.stringify(vans[8])} for insert without id by autoGenPk=false`, async function() {
|
|
160
|
+
assert.strict.deepStrictEqual(vget[8], vans[8])
|
|
161
|
+
})
|
|
162
|
+
|
|
163
|
+
vans[9] = 'reject'
|
|
164
|
+
it(`should get ${JSON.stringify(vans[9])} for save without id by autoGenPk=false`, async function() {
|
|
165
|
+
assert.strict.deepStrictEqual(vget[9], vans[9])
|
|
166
|
+
})
|
|
167
|
+
|
|
168
|
+
vans[10] = 'reject'
|
|
169
|
+
it(`should get ${JSON.stringify(vans[10])} for insert by array partially without id by autoGenPk=false`, async function() {
|
|
170
|
+
assert.strict.deepStrictEqual(vget[10], vans[10])
|
|
171
|
+
})
|
|
172
|
+
|
|
173
|
+
//檢查須於任何寫入之前完成, 故整批reject時同批之有效筆數亦不得被寫入
|
|
174
|
+
vans[11] = ['own-1', 'own-2']
|
|
175
|
+
it(`should get ${JSON.stringify(vans[11])} for no partial writing when batch rejected`, async function() {
|
|
176
|
+
assert.strict.deepStrictEqual(vget[11], vans[11])
|
|
177
|
+
})
|
|
178
|
+
|
|
179
|
+
//del不受autoGenPk影響
|
|
180
|
+
vans[12] = [
|
|
181
|
+
{ n: 1, nDeleted: 1, ok: 1 },
|
|
182
|
+
{ n: 0, nDeleted: 0, ok: 0 },
|
|
183
|
+
]
|
|
184
|
+
it(`should get ${JSON.stringify(vans[12])} for del not affected by autoGenPk=false`, async function() {
|
|
185
|
+
assert.strict.deepStrictEqual(vget[12], vans[12])
|
|
186
|
+
})
|
|
187
|
+
|
|
188
|
+
})
|