w-orm-mongodb 1.1.40 → 1.1.41
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 +37 -0
- package/dist/w-orm-mongodb.umd.js +2 -2
- package/dist/w-orm-mongodb.umd.js.map +1 -1
- package/docs/WOrmMongodb.html +11 -11
- package/docs/WOrmMongodb.mjs.html +157 -56
- package/docs/index.html +1 -1
- package/package.json +1 -1
- package/src/WOrmMongodb.mjs +155 -54
- package/test/api-basic.test.mjs +245 -0
- package/test/api-gfs.test.mjs +107 -0
package/src/WOrmMongodb.mjs
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import events from 'events'
|
|
2
1
|
import mongodb from 'mongodb'
|
|
3
2
|
import stream from 'stream'
|
|
4
3
|
import cloneDeep from 'lodash-es/cloneDeep.js'
|
|
@@ -7,6 +6,7 @@ import get from 'lodash-es/get.js'
|
|
|
7
6
|
import map from 'lodash-es/map.js'
|
|
8
7
|
import omit from 'lodash-es/omit.js'
|
|
9
8
|
import size from 'lodash-es/size.js'
|
|
9
|
+
import evem from 'wsemi/src/evem.mjs'
|
|
10
10
|
import genPm from 'wsemi/src/genPm.mjs'
|
|
11
11
|
import genID from 'wsemi/src/genID.mjs'
|
|
12
12
|
import isbol from 'wsemi/src/isbol.mjs'
|
|
@@ -63,8 +63,9 @@ function WOrmMongodb(opt = {}) {
|
|
|
63
63
|
let _indexGfsReady = false
|
|
64
64
|
|
|
65
65
|
|
|
66
|
-
//ee
|
|
67
|
-
|
|
66
|
+
//ee, 採wsemi之evem(即eventemitter3), 其於'error'無監聽者時僅回傳false而不拋出,
|
|
67
|
+
//故本套件之操作行為不因呼叫端有無註冊監聽而改變; Node內建之EventEmitter具該拋出語義, 不可用
|
|
68
|
+
let ee = evem()
|
|
68
69
|
|
|
69
70
|
|
|
70
71
|
//MongoClient
|
|
@@ -78,7 +79,7 @@ function WOrmMongodb(opt = {}) {
|
|
|
78
79
|
* @param {Error|String} err 輸入錯誤物件或字串
|
|
79
80
|
* @returns {String} 回傳錯誤訊息字串
|
|
80
81
|
*/
|
|
81
|
-
function
|
|
82
|
+
function getErrMsg(err) {
|
|
82
83
|
|
|
83
84
|
//message
|
|
84
85
|
let message = get(err, 'message')
|
|
@@ -109,6 +110,28 @@ function WOrmMongodb(opt = {}) {
|
|
|
109
110
|
}
|
|
110
111
|
|
|
111
112
|
|
|
113
|
+
/**
|
|
114
|
+
* 發出error事件,操作發生錯誤時發出,錯誤訊息一律轉為字串
|
|
115
|
+
* 註: 事件僅為附加通知,所送出之資訊必另有正規管道——整批性錯誤經Promise.reject,逐筆失敗經該筆之err欄位
|
|
116
|
+
* 註: 訂閱函數拋錯不得影響本次操作之結果,故另包try並自行吞掉
|
|
117
|
+
* 註: 正常結果不得發出本事件,如insert全數已存在、save合併後內容相同、del主鍵未命中、selectByPk查無數據
|
|
118
|
+
*
|
|
119
|
+
* @ignore
|
|
120
|
+
* @param {String} mode 輸入操作別字串
|
|
121
|
+
* @param {Array|null} data 輸入本次操作之數據
|
|
122
|
+
* @param {Error|String} err 輸入錯誤物件或字串
|
|
123
|
+
* @returns {undefined} 無回傳值
|
|
124
|
+
*/
|
|
125
|
+
function emitError(mode, data, err) {
|
|
126
|
+
try {
|
|
127
|
+
ee.emit('error', mode, data, getErrMsg(err))
|
|
128
|
+
}
|
|
129
|
+
catch (errEmit) {
|
|
130
|
+
console.log(errEmit)
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
|
|
112
135
|
/**
|
|
113
136
|
* 檢查並補齊單筆數據之主鍵
|
|
114
137
|
* autoGenPk為true時未帶有效id者自動產生,為false時往外拋
|
|
@@ -310,7 +333,12 @@ function WOrmMongodb(opt = {}) {
|
|
|
310
333
|
client = null
|
|
311
334
|
}
|
|
312
335
|
|
|
336
|
+
//check
|
|
313
337
|
if (isErr) {
|
|
338
|
+
|
|
339
|
+
//emit, 整批性錯誤須於reject之前發出
|
|
340
|
+
emitError('select', null, res)
|
|
341
|
+
|
|
314
342
|
return Promise.reject(res)
|
|
315
343
|
}
|
|
316
344
|
return res
|
|
@@ -368,7 +396,12 @@ function WOrmMongodb(opt = {}) {
|
|
|
368
396
|
client = null
|
|
369
397
|
}
|
|
370
398
|
|
|
399
|
+
//check
|
|
371
400
|
if (isErr) {
|
|
401
|
+
|
|
402
|
+
//emit, 整批性錯誤須於reject之前發出
|
|
403
|
+
emitError('selectByPk', null, res)
|
|
404
|
+
|
|
372
405
|
return Promise.reject(res)
|
|
373
406
|
}
|
|
374
407
|
return res
|
|
@@ -469,7 +502,12 @@ function WOrmMongodb(opt = {}) {
|
|
|
469
502
|
emitChange('insert', data, res)
|
|
470
503
|
}
|
|
471
504
|
|
|
505
|
+
//check
|
|
472
506
|
if (isErr) {
|
|
507
|
+
|
|
508
|
+
//emit, 整批性錯誤須於reject之前發出
|
|
509
|
+
emitError('insert', data, res)
|
|
510
|
+
|
|
473
511
|
return Promise.reject(res)
|
|
474
512
|
}
|
|
475
513
|
return res
|
|
@@ -574,7 +612,7 @@ function WOrmMongodb(opt = {}) {
|
|
|
574
612
|
nInserted: 0,
|
|
575
613
|
nModified: 0,
|
|
576
614
|
ok: 0,
|
|
577
|
-
err:
|
|
615
|
+
err: getErrMsg(err),
|
|
578
616
|
}
|
|
579
617
|
|
|
580
618
|
break
|
|
@@ -587,6 +625,11 @@ function WOrmMongodb(opt = {}) {
|
|
|
587
625
|
emitChange('insert', [v], rest)
|
|
588
626
|
}
|
|
589
627
|
|
|
628
|
+
//emit, 逐筆失敗須於該筆結果定案後發出, 每筆一次
|
|
629
|
+
if (rest.ok === 0) {
|
|
630
|
+
emitError('save', [v], rest.err)
|
|
631
|
+
}
|
|
632
|
+
|
|
590
633
|
return rest
|
|
591
634
|
}
|
|
592
635
|
|
|
@@ -662,7 +705,12 @@ function WOrmMongodb(opt = {}) {
|
|
|
662
705
|
emitChange('save', data, res)
|
|
663
706
|
}
|
|
664
707
|
|
|
708
|
+
//check
|
|
665
709
|
if (isErr) {
|
|
710
|
+
|
|
711
|
+
//emit, 整批性錯誤須於reject之前發出
|
|
712
|
+
emitError('save', data, res)
|
|
713
|
+
|
|
666
714
|
return Promise.reject(res)
|
|
667
715
|
}
|
|
668
716
|
return res
|
|
@@ -714,49 +762,60 @@ function WOrmMongodb(opt = {}) {
|
|
|
714
762
|
//id, del不補值, 未帶有效id者視為本筆無法處理
|
|
715
763
|
let id = get(v, 'id')
|
|
716
764
|
|
|
765
|
+
//rest
|
|
766
|
+
let rest = null
|
|
767
|
+
|
|
717
768
|
//check, 不得將無效id送進查詢條件, 因undefined經序列化為null會誤中id為null之數據
|
|
718
769
|
if (!isestr(id)) {
|
|
719
|
-
|
|
770
|
+
|
|
771
|
+
//rest
|
|
772
|
+
rest = {
|
|
720
773
|
n: 0,
|
|
721
774
|
nDeleted: 0,
|
|
722
775
|
ok: 0,
|
|
723
776
|
err: `invalid id[${id}]`,
|
|
724
777
|
}
|
|
778
|
+
|
|
725
779
|
}
|
|
780
|
+
else {
|
|
726
781
|
|
|
727
|
-
|
|
728
|
-
let rest = null
|
|
782
|
+
try {
|
|
729
783
|
|
|
730
|
-
|
|
784
|
+
//deleteOne
|
|
785
|
+
let r = await collection.deleteOne({ id })
|
|
731
786
|
|
|
732
|
-
|
|
733
|
-
|
|
787
|
+
//nDeleted
|
|
788
|
+
let nDeleted = get(r, 'deletedCount', 0)
|
|
734
789
|
|
|
735
|
-
|
|
736
|
-
|
|
790
|
+
//rest, 未命中時nDeleted為0, 屬正常結果
|
|
791
|
+
rest = {
|
|
792
|
+
n: nDeleted,
|
|
793
|
+
nDeleted,
|
|
794
|
+
ok: 1,
|
|
795
|
+
}
|
|
737
796
|
|
|
738
|
-
//rest, 未命中時nDeleted為0, 屬正常結果
|
|
739
|
-
rest = {
|
|
740
|
-
n: nDeleted,
|
|
741
|
-
nDeleted,
|
|
742
|
-
ok: 1,
|
|
743
797
|
}
|
|
798
|
+
catch (err) {
|
|
744
799
|
|
|
745
|
-
|
|
746
|
-
catch (err) {
|
|
800
|
+
//本筆失敗不中斷整批
|
|
747
801
|
|
|
748
|
-
|
|
802
|
+
//rest
|
|
803
|
+
rest = {
|
|
804
|
+
n: 1,
|
|
805
|
+
nDeleted: 0,
|
|
806
|
+
ok: 0,
|
|
807
|
+
err: getErrMsg(err),
|
|
808
|
+
}
|
|
749
809
|
|
|
750
|
-
//rest
|
|
751
|
-
rest = {
|
|
752
|
-
n: 1,
|
|
753
|
-
nDeleted: 0,
|
|
754
|
-
ok: 0,
|
|
755
|
-
err: genErrMsg(err),
|
|
756
810
|
}
|
|
757
811
|
|
|
758
812
|
}
|
|
759
813
|
|
|
814
|
+
//emit, 逐筆失敗須於該筆結果定案後發出, 每筆一次
|
|
815
|
+
if (rest.ok === 0) {
|
|
816
|
+
emitError('del', [v], rest.err)
|
|
817
|
+
}
|
|
818
|
+
|
|
760
819
|
return rest
|
|
761
820
|
})
|
|
762
821
|
|
|
@@ -775,7 +834,12 @@ function WOrmMongodb(opt = {}) {
|
|
|
775
834
|
emitChange('del', data, res)
|
|
776
835
|
}
|
|
777
836
|
|
|
837
|
+
//check
|
|
778
838
|
if (isErr) {
|
|
839
|
+
|
|
840
|
+
//emit, 整批性錯誤須於reject之前發出
|
|
841
|
+
emitError('del', data, res)
|
|
842
|
+
|
|
779
843
|
return Promise.reject(res)
|
|
780
844
|
}
|
|
781
845
|
return res
|
|
@@ -832,7 +896,12 @@ function WOrmMongodb(opt = {}) {
|
|
|
832
896
|
emitChange('delAll', null, res)
|
|
833
897
|
}
|
|
834
898
|
|
|
899
|
+
//check
|
|
835
900
|
if (isErr) {
|
|
901
|
+
|
|
902
|
+
//emit, 整批性錯誤須於reject之前發出
|
|
903
|
+
emitError('delAll', null, res)
|
|
904
|
+
|
|
836
905
|
return Promise.reject(res)
|
|
837
906
|
}
|
|
838
907
|
return res
|
|
@@ -937,7 +1006,12 @@ function WOrmMongodb(opt = {}) {
|
|
|
937
1006
|
emitChange('insertGfs', data, res)
|
|
938
1007
|
}
|
|
939
1008
|
|
|
1009
|
+
//check
|
|
940
1010
|
if (isErr) {
|
|
1011
|
+
|
|
1012
|
+
//emit, 整批性錯誤須於reject之前發出
|
|
1013
|
+
emitError('insertGfs', data, res)
|
|
1014
|
+
|
|
941
1015
|
return Promise.reject(res)
|
|
942
1016
|
}
|
|
943
1017
|
return res
|
|
@@ -1042,13 +1116,19 @@ function WOrmMongodb(opt = {}) {
|
|
|
1042
1116
|
client = null
|
|
1043
1117
|
}
|
|
1044
1118
|
|
|
1119
|
+
//check, 查無檔案已於catch內判定為正常結果而未設isErr, 故不會誤發error事件
|
|
1045
1120
|
if (isErr) {
|
|
1121
|
+
|
|
1122
|
+
//emit, 整批性錯誤須於reject之前發出
|
|
1123
|
+
emitError('selectByPkGfs', null, res)
|
|
1124
|
+
|
|
1046
1125
|
return Promise.reject(res)
|
|
1047
1126
|
}
|
|
1048
1127
|
return res
|
|
1049
1128
|
}
|
|
1050
1129
|
|
|
1051
1130
|
|
|
1131
|
+
//_findGfs, 內部查找函數, 其reject由delGfs與delAllGfs之catch接住並於該處發出error事件, 故本函數不自行發出
|
|
1052
1132
|
async function _findGfs(find = {}, bucket) {
|
|
1053
1133
|
let isErr = false
|
|
1054
1134
|
|
|
@@ -1122,54 +1202,65 @@ function WOrmMongodb(opt = {}) {
|
|
|
1122
1202
|
//id, delGfs不補值, 未帶有效id者視為本筆無法處理
|
|
1123
1203
|
let id = get(v, 'id')
|
|
1124
1204
|
|
|
1205
|
+
//rest
|
|
1206
|
+
let rest = null
|
|
1207
|
+
|
|
1125
1208
|
//check, 判定基準與del一致
|
|
1126
1209
|
if (!isestr(id)) {
|
|
1127
|
-
|
|
1210
|
+
|
|
1211
|
+
//rest
|
|
1212
|
+
rest = {
|
|
1128
1213
|
n: 0,
|
|
1129
1214
|
nDeleted: 0,
|
|
1130
1215
|
ok: 0,
|
|
1131
1216
|
err: `invalid id[${id}]`,
|
|
1132
1217
|
}
|
|
1218
|
+
|
|
1133
1219
|
}
|
|
1220
|
+
else {
|
|
1134
1221
|
|
|
1135
|
-
|
|
1136
|
-
let rest = null
|
|
1222
|
+
try {
|
|
1137
1223
|
|
|
1138
|
-
|
|
1224
|
+
//_findGfs
|
|
1225
|
+
let ltdt = await _findGfs({ filename: id }, bucket)
|
|
1139
1226
|
|
|
1140
|
-
|
|
1141
|
-
|
|
1227
|
+
//delete, 建立唯一索引後同一id至多一筆,
|
|
1228
|
+
//既有數據若尚存重複id則一併刪除並如實回報nDeleted
|
|
1229
|
+
let nDeleted = 0
|
|
1230
|
+
for (let vv of ltdt) {
|
|
1231
|
+
await bucket.delete(vv._id)
|
|
1232
|
+
nDeleted++
|
|
1233
|
+
}
|
|
1142
1234
|
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
}
|
|
1235
|
+
//rest, n為命中與否, 未命中時兩者皆為0且屬正常結果
|
|
1236
|
+
rest = {
|
|
1237
|
+
n: nDeleted > 0 ? 1 : 0,
|
|
1238
|
+
nDeleted,
|
|
1239
|
+
ok: 1,
|
|
1240
|
+
}
|
|
1150
1241
|
|
|
1151
|
-
//rest, n為命中與否, 未命中時兩者皆為0且屬正常結果
|
|
1152
|
-
rest = {
|
|
1153
|
-
n: nDeleted > 0 ? 1 : 0,
|
|
1154
|
-
nDeleted,
|
|
1155
|
-
ok: 1,
|
|
1156
1242
|
}
|
|
1243
|
+
catch (err) {
|
|
1157
1244
|
|
|
1158
|
-
|
|
1159
|
-
catch (err) {
|
|
1245
|
+
//本筆失敗不中斷整批
|
|
1160
1246
|
|
|
1161
|
-
|
|
1247
|
+
//rest
|
|
1248
|
+
rest = {
|
|
1249
|
+
n: 1,
|
|
1250
|
+
nDeleted: 0,
|
|
1251
|
+
ok: 0,
|
|
1252
|
+
err: getErrMsg(err),
|
|
1253
|
+
}
|
|
1162
1254
|
|
|
1163
|
-
//rest
|
|
1164
|
-
rest = {
|
|
1165
|
-
n: 1,
|
|
1166
|
-
nDeleted: 0,
|
|
1167
|
-
ok: 0,
|
|
1168
|
-
err: genErrMsg(err),
|
|
1169
1255
|
}
|
|
1170
1256
|
|
|
1171
1257
|
}
|
|
1172
1258
|
|
|
1259
|
+
//emit, 逐筆失敗須於該筆結果定案後發出, 每筆一次
|
|
1260
|
+
if (rest.ok === 0) {
|
|
1261
|
+
emitError('delGfs', [v], rest.err)
|
|
1262
|
+
}
|
|
1263
|
+
|
|
1173
1264
|
return rest
|
|
1174
1265
|
})
|
|
1175
1266
|
|
|
@@ -1188,7 +1279,12 @@ function WOrmMongodb(opt = {}) {
|
|
|
1188
1279
|
emitChange('delGfs', data, res)
|
|
1189
1280
|
}
|
|
1190
1281
|
|
|
1282
|
+
//check
|
|
1191
1283
|
if (isErr) {
|
|
1284
|
+
|
|
1285
|
+
//emit, 整批性錯誤須於reject之前發出
|
|
1286
|
+
emitError('delGfs', data, res)
|
|
1287
|
+
|
|
1192
1288
|
return Promise.reject(res)
|
|
1193
1289
|
}
|
|
1194
1290
|
return res
|
|
@@ -1268,7 +1364,12 @@ function WOrmMongodb(opt = {}) {
|
|
|
1268
1364
|
emitChange('delAllGfs', null, res)
|
|
1269
1365
|
}
|
|
1270
1366
|
|
|
1367
|
+
//check
|
|
1271
1368
|
if (isErr) {
|
|
1369
|
+
|
|
1370
|
+
//emit, 整批性錯誤須於reject之前發出
|
|
1371
|
+
emitError('delAllGfs', null, res)
|
|
1372
|
+
|
|
1272
1373
|
return Promise.reject(res)
|
|
1273
1374
|
}
|
|
1274
1375
|
return res
|
package/test/api-basic.test.mjs
CHANGED
|
@@ -1087,6 +1087,251 @@ describe('delAll', function() {
|
|
|
1087
1087
|
})
|
|
1088
1088
|
|
|
1089
1089
|
|
|
1090
|
+
describe('error event', function() {
|
|
1091
|
+
let vans = {}
|
|
1092
|
+
let vget = {}
|
|
1093
|
+
|
|
1094
|
+
before(async function() {
|
|
1095
|
+
this.timeout(120000)
|
|
1096
|
+
|
|
1097
|
+
//collect, 收集事件
|
|
1098
|
+
let collect = (wo) => {
|
|
1099
|
+
let evs = []
|
|
1100
|
+
wo.on('error', function(mode, data, err) {
|
|
1101
|
+
evs.push({ mode, data, err })
|
|
1102
|
+
})
|
|
1103
|
+
return evs
|
|
1104
|
+
}
|
|
1105
|
+
|
|
1106
|
+
//整批性錯誤須於reject前發出, 且err與reject訊息一致
|
|
1107
|
+
let woB = WOrm(genOptPk('everrbatch', false))
|
|
1108
|
+
await woB.delAll()
|
|
1109
|
+
let evsB = collect(woB)
|
|
1110
|
+
let msgB = null
|
|
1111
|
+
await woB.insert({ name: 'no-id' }).catch((err) => {
|
|
1112
|
+
msgB = err.toString()
|
|
1113
|
+
})
|
|
1114
|
+
vget[1] = evsB.length
|
|
1115
|
+
vget[2] = evsB[0].mode
|
|
1116
|
+
vget[3] = typeof evsB[0].err
|
|
1117
|
+
vget[4] = msgB.indexOf(evsB[0].err) >= 0
|
|
1118
|
+
|
|
1119
|
+
//save之整批性錯誤
|
|
1120
|
+
evsB.length = 0
|
|
1121
|
+
await woB.save({ name: 'no-id' }).catch(() => {})
|
|
1122
|
+
vget[5] = evsB.map((v) => v.mode)
|
|
1123
|
+
|
|
1124
|
+
//逐筆失敗須於該筆定案後發出, 每筆一次, err與該筆err欄位一致
|
|
1125
|
+
let woS = WOrm(genOpt('everrsave'))
|
|
1126
|
+
await woS.delAll()
|
|
1127
|
+
await woS.insert([{ id: 'f1' }, { id: 'f2' }, { id: 'f3' }])
|
|
1128
|
+
let evsS = collect(woS)
|
|
1129
|
+
let rs = await woS.save([
|
|
1130
|
+
{ id: 'f1', name: 'ok1' },
|
|
1131
|
+
{ id: 'f2', $bad: 1 },
|
|
1132
|
+
{ id: 'f3', name: 'ok3' },
|
|
1133
|
+
])
|
|
1134
|
+
vget[6] = evsS.length
|
|
1135
|
+
vget[7] = evsS[0].mode
|
|
1136
|
+
vget[8] = evsS[0].err === rs[1].err
|
|
1137
|
+
|
|
1138
|
+
//del之逐筆失敗, 未帶有效id者亦須發出
|
|
1139
|
+
let woD = WOrm(genOpt('everrdel'))
|
|
1140
|
+
await woD.delAll()
|
|
1141
|
+
await woD.insert({ id: 'd1' })
|
|
1142
|
+
let evsD = collect(woD)
|
|
1143
|
+
let rd = await woD.del([{ id: 'd1' }, { name: 'no-id' }])
|
|
1144
|
+
vget[9] = evsD.length
|
|
1145
|
+
vget[10] = evsD[0].mode
|
|
1146
|
+
vget[11] = evsD[0].err === rd[1].err
|
|
1147
|
+
|
|
1148
|
+
//正常結果不得發出error
|
|
1149
|
+
let woN = WOrm(genOpt('everrnormal'))
|
|
1150
|
+
await woN.delAll()
|
|
1151
|
+
let evsN = collect(woN)
|
|
1152
|
+
await woN.insert({ id: 'n1', name: 'a' })
|
|
1153
|
+
await woN.insert({ id: 'n1', name: 'a' }) //全數已存在
|
|
1154
|
+
await woN.save({ id: 'n1', name: 'a' }) //合併後內容相同
|
|
1155
|
+
await woN.del({ id: 'n-not-existed' }) //主鍵未命中
|
|
1156
|
+
await woN.delAll({ name: 'not-existed' }) //條件無命中
|
|
1157
|
+
await woN.selectByPk('n-not-existed') //查無數據
|
|
1158
|
+
await woN.selectByPk('') //主鍵值無效
|
|
1159
|
+
await woN.select({ name: 'not-existed' }) //無符合數據
|
|
1160
|
+
vget[12] = evsN.length
|
|
1161
|
+
|
|
1162
|
+
//同批既有逐筆失敗又整批resolve時, 逐筆error先於整批change
|
|
1163
|
+
let woO = WOrm(genOpt('everrorder'))
|
|
1164
|
+
await woO.delAll()
|
|
1165
|
+
await woO.insert([{ id: 'o1' }, { id: 'o2' }])
|
|
1166
|
+
let seq = []
|
|
1167
|
+
woO.on('error', function(mode) {
|
|
1168
|
+
seq.push(`error:${mode}`)
|
|
1169
|
+
})
|
|
1170
|
+
woO.on('change', function(mode) {
|
|
1171
|
+
seq.push(`change:${mode}`)
|
|
1172
|
+
})
|
|
1173
|
+
await woO.save([{ id: 'o1', name: 'ok' }, { id: 'o2', $bad: 1 }])
|
|
1174
|
+
vget[13] = seq
|
|
1175
|
+
|
|
1176
|
+
//訂閱函數拋錯不得影響本次操作之結果
|
|
1177
|
+
let woT = WOrm(genOpt('everrthrow'))
|
|
1178
|
+
await woT.delAll()
|
|
1179
|
+
woT.on('error', function() {
|
|
1180
|
+
throw new Error('訂閱者拋錯')
|
|
1181
|
+
})
|
|
1182
|
+
await woT.insert({ id: 't1' })
|
|
1183
|
+
vget[14] = await woT.del([{ id: 't1' }, { name: 'no-id' }])
|
|
1184
|
+
|
|
1185
|
+
})
|
|
1186
|
+
|
|
1187
|
+
vans[1] = 1
|
|
1188
|
+
it(`should get ${JSON.stringify(vans[1])} for count of error event in batch error`, async function() {
|
|
1189
|
+
assert.strict.deepStrictEqual(vget[1], vans[1])
|
|
1190
|
+
})
|
|
1191
|
+
|
|
1192
|
+
vans[2] = 'insert'
|
|
1193
|
+
it(`should get ${JSON.stringify(vans[2])} for mode of error event in batch error`, async function() {
|
|
1194
|
+
assert.strict.deepStrictEqual(vget[2], vans[2])
|
|
1195
|
+
})
|
|
1196
|
+
|
|
1197
|
+
vans[3] = 'string'
|
|
1198
|
+
it(`should get ${JSON.stringify(vans[3])} for type of err in error event`, async function() {
|
|
1199
|
+
assert.strict.deepStrictEqual(vget[3], vans[3])
|
|
1200
|
+
})
|
|
1201
|
+
|
|
1202
|
+
vans[4] = true
|
|
1203
|
+
it(`should get ${JSON.stringify(vans[4])} for same err between error event and reject`, async function() {
|
|
1204
|
+
assert.strict.deepStrictEqual(vget[4], vans[4])
|
|
1205
|
+
})
|
|
1206
|
+
|
|
1207
|
+
vans[5] = ['save']
|
|
1208
|
+
it(`should get ${JSON.stringify(vans[5])} for mode of error event in save batch error`, async function() {
|
|
1209
|
+
assert.strict.deepStrictEqual(vget[5], vans[5])
|
|
1210
|
+
})
|
|
1211
|
+
|
|
1212
|
+
vans[6] = 1
|
|
1213
|
+
it(`should get ${JSON.stringify(vans[6])} for count of error event in save single failure`, async function() {
|
|
1214
|
+
assert.strict.deepStrictEqual(vget[6], vans[6])
|
|
1215
|
+
})
|
|
1216
|
+
|
|
1217
|
+
vans[7] = 'save'
|
|
1218
|
+
it(`should get ${JSON.stringify(vans[7])} for mode of error event in save single failure`, async function() {
|
|
1219
|
+
assert.strict.deepStrictEqual(vget[7], vans[7])
|
|
1220
|
+
})
|
|
1221
|
+
|
|
1222
|
+
vans[8] = true
|
|
1223
|
+
it(`should get ${JSON.stringify(vans[8])} for same err between error event and result of save`, async function() {
|
|
1224
|
+
assert.strict.deepStrictEqual(vget[8], vans[8])
|
|
1225
|
+
})
|
|
1226
|
+
|
|
1227
|
+
vans[9] = 1
|
|
1228
|
+
it(`should get ${JSON.stringify(vans[9])} for count of error event in del single failure`, async function() {
|
|
1229
|
+
assert.strict.deepStrictEqual(vget[9], vans[9])
|
|
1230
|
+
})
|
|
1231
|
+
|
|
1232
|
+
vans[10] = 'del'
|
|
1233
|
+
it(`should get ${JSON.stringify(vans[10])} for mode of error event in del single failure`, async function() {
|
|
1234
|
+
assert.strict.deepStrictEqual(vget[10], vans[10])
|
|
1235
|
+
})
|
|
1236
|
+
|
|
1237
|
+
vans[11] = true
|
|
1238
|
+
it(`should get ${JSON.stringify(vans[11])} for same err between error event and result of del`, async function() {
|
|
1239
|
+
assert.strict.deepStrictEqual(vget[11], vans[11])
|
|
1240
|
+
})
|
|
1241
|
+
|
|
1242
|
+
vans[12] = 0
|
|
1243
|
+
it(`should get ${JSON.stringify(vans[12])} for count of error event in normal results`, async function() {
|
|
1244
|
+
assert.strict.deepStrictEqual(vget[12], vans[12])
|
|
1245
|
+
})
|
|
1246
|
+
|
|
1247
|
+
vans[13] = ['error:save', 'change:save']
|
|
1248
|
+
it(`should get ${JSON.stringify(vans[13])} for order of error and change`, async function() {
|
|
1249
|
+
assert.strict.deepStrictEqual(vget[13], vans[13])
|
|
1250
|
+
})
|
|
1251
|
+
|
|
1252
|
+
vans[14] = [
|
|
1253
|
+
{ n: 1, nDeleted: 1, ok: 1 },
|
|
1254
|
+
{ n: 0, nDeleted: 0, ok: 0, err: 'invalid id[undefined]' }
|
|
1255
|
+
]
|
|
1256
|
+
it(`should get ${JSON.stringify(vans[14])} for result with throwing error listener`, async function() {
|
|
1257
|
+
assert.strict.deepStrictEqual(vget[14], vans[14])
|
|
1258
|
+
})
|
|
1259
|
+
|
|
1260
|
+
})
|
|
1261
|
+
|
|
1262
|
+
|
|
1263
|
+
describe('error listener does not change behavior', function() {
|
|
1264
|
+
let vans = {}
|
|
1265
|
+
let vget = {}
|
|
1266
|
+
|
|
1267
|
+
before(async function() {
|
|
1268
|
+
this.timeout(120000)
|
|
1269
|
+
|
|
1270
|
+
//run, 以同一組操作跑兩次, 差別僅在有無註冊error監聽
|
|
1271
|
+
//T10.1第2條: 操作行為不得因監聽者之有無而改變
|
|
1272
|
+
let run = async (cl, withListener) => {
|
|
1273
|
+
let wo = WOrm(genOpt(cl))
|
|
1274
|
+
if (withListener) {
|
|
1275
|
+
wo.on('error', function() {})
|
|
1276
|
+
}
|
|
1277
|
+
await wo.delAll()
|
|
1278
|
+
|
|
1279
|
+
let out = []
|
|
1280
|
+
|
|
1281
|
+
//整批性錯誤
|
|
1282
|
+
let woOff = WOrm(genOptPk(`${cl}off`, false))
|
|
1283
|
+
if (withListener) {
|
|
1284
|
+
woOff.on('error', function() {})
|
|
1285
|
+
}
|
|
1286
|
+
await woOff.delAll()
|
|
1287
|
+
await woOff.insert({ name: 'no-id' })
|
|
1288
|
+
.then((r) => out.push({ t: 'resolve', r }))
|
|
1289
|
+
.catch((e) => out.push({ t: 'reject', e: e.toString() }))
|
|
1290
|
+
|
|
1291
|
+
//逐筆失敗
|
|
1292
|
+
await wo.insert([{ id: 'a1' }, { id: 'a2' }])
|
|
1293
|
+
let rs = await wo.save([{ id: 'a1', name: 'ok' }, { id: 'a2', $bad: 1 }])
|
|
1294
|
+
out.push({ t: 'save', ok: rs.map((v) => v.ok), n: rs.map((v) => v.n) })
|
|
1295
|
+
|
|
1296
|
+
//del逐筆失敗
|
|
1297
|
+
let rd = await wo.del([{ id: 'a1' }, { name: 'no-id' }])
|
|
1298
|
+
out.push({ t: 'del', r: rd })
|
|
1299
|
+
|
|
1300
|
+
//讀取函數之整批性錯誤
|
|
1301
|
+
await wo.selectByPk('not-existed')
|
|
1302
|
+
.then((r) => out.push({ t: 'selectByPk', r }))
|
|
1303
|
+
.catch((e) => out.push({ t: 'selectByPkReject', e: e.toString() }))
|
|
1304
|
+
|
|
1305
|
+
return out
|
|
1306
|
+
}
|
|
1307
|
+
|
|
1308
|
+
let a = await run('evnolisten', false)
|
|
1309
|
+
let b = await run('evlisten', true)
|
|
1310
|
+
|
|
1311
|
+
vget[1] = JSON.stringify(a) === JSON.stringify(b)
|
|
1312
|
+
vget[2] = a[0].t
|
|
1313
|
+
vget[3] = a[1].ok
|
|
1314
|
+
|
|
1315
|
+
})
|
|
1316
|
+
|
|
1317
|
+
vans[1] = true
|
|
1318
|
+
it(`should get ${JSON.stringify(vans[1])} for same result with and without error listener`, async function() {
|
|
1319
|
+
assert.strict.deepStrictEqual(vget[1], vans[1])
|
|
1320
|
+
})
|
|
1321
|
+
|
|
1322
|
+
vans[2] = 'reject'
|
|
1323
|
+
it(`should get ${JSON.stringify(vans[2])} for reject without error listener`, async function() {
|
|
1324
|
+
assert.strict.deepStrictEqual(vget[2], vans[2])
|
|
1325
|
+
})
|
|
1326
|
+
|
|
1327
|
+
vans[3] = [1, 0]
|
|
1328
|
+
it(`should get ${JSON.stringify(vans[3])} for ok of save without error listener`, async function() {
|
|
1329
|
+
assert.strict.deepStrictEqual(vget[3], vans[3])
|
|
1330
|
+
})
|
|
1331
|
+
|
|
1332
|
+
})
|
|
1333
|
+
|
|
1334
|
+
|
|
1090
1335
|
describe('change event', function() {
|
|
1091
1336
|
let vans = {}
|
|
1092
1337
|
let vget = {}
|