w-orm-mongodb 1.1.38 → 1.1.40

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.
@@ -10,7 +10,7 @@ let ctDb = 'worm'
10
10
  let ctPort = null //容器對外埠, 由startContainer動態取得
11
11
 
12
12
 
13
- //genOpt
13
+ //genOpt, 不帶autoGenPk以驗證其預設值
14
14
  let genOpt = (cl) => {
15
15
  return {
16
16
  url: genUrl(ctPort),
@@ -19,6 +19,16 @@ let genOpt = (cl) => {
19
19
  }
20
20
  }
21
21
 
22
+ //genOptPk, 明確指定autoGenPk
23
+ let genOptPk = (cl, autoGenPk) => {
24
+ return {
25
+ url: genUrl(ctPort),
26
+ db: ctDb,
27
+ cl,
28
+ autoGenPk,
29
+ }
30
+ }
31
+
22
32
  //genKeys, 取回傳物件之鍵集合, 用於驗證鍵集合固定
23
33
  let genKeys = (v) => {
24
34
  return Object.keys(v).sort().join(',')
@@ -296,10 +306,10 @@ describe('basic', function() {
296
306
  // vans[17] = []
297
307
  vget[17] = await wo.select({ name: 'not-existed' })
298
308
 
299
- //selectById, 由id直接查找單筆
309
+ //selectByPk, 由id直接查找單筆
300
310
  rt = null
301
311
  // vans[10] = { id: 'id-rosemary', name: 'rosemary(modify)', value: 123.456 }
302
- await wo.selectById('id-rosemary')
312
+ await wo.selectByPk('id-rosemary')
303
313
  .then(function(msg) {
304
314
  rt = msg
305
315
  })
@@ -308,16 +318,16 @@ describe('basic', function() {
308
318
  })
309
319
  vget[10] = rt
310
320
 
311
- //selectById, 與select(find)取得同一筆之內容須一致
321
+ //selectByPk, 與select(find)取得同一筆之內容須一致
312
322
  // vans[11] = true
313
- let sbi = await wo.selectById('id-peter')
323
+ let sbi = await wo.selectByPk('id-peter')
314
324
  let sbf = await wo.select({ id: 'id-peter' })
315
325
  vget[11] = JSON.stringify(sbi) === JSON.stringify(sbf[0])
316
326
 
317
- //selectById by id not existed
327
+ //selectByPk by id not existed
318
328
  rt = null
319
329
  // vans[12] = null
320
- await wo.selectById('id-not-existed')
330
+ await wo.selectByPk('id-not-existed')
321
331
  .then(function(msg) {
322
332
  rt = msg
323
333
  })
@@ -326,12 +336,12 @@ describe('basic', function() {
326
336
  })
327
337
  vget[12] = rt
328
338
 
329
- //selectById by id invalid, 未給有效id視為查無數據
339
+ //selectByPk by id invalid, 未給有效id視為查無數據
330
340
  // vans[13] = [null, null, null]
331
341
  vget[13] = [
332
- await wo.selectById(''),
333
- await wo.selectById(123),
334
- await wo.selectById(null),
342
+ await wo.selectByPk(''),
343
+ await wo.selectByPk(123),
344
+ await wo.selectByPk(null),
335
345
  ]
336
346
 
337
347
  //del
@@ -349,9 +359,9 @@ describe('basic', function() {
349
359
  })
350
360
  vget[14] = rt
351
361
 
352
- //selectById, 已刪除者須回傳null
362
+ //selectByPk, 已刪除者須回傳null
353
363
  // vans[15] = null
354
- vget[15] = await wo.selectById(d[0].id)
364
+ vget[15] = await wo.selectByPk(d[0].id)
355
365
 
356
366
  })
357
367
 
@@ -422,22 +432,22 @@ describe('basic', function() {
422
432
  })
423
433
 
424
434
  vans[10] = { id: 'id-rosemary', name: 'rosemary(modify)', value: 123.456 }
425
- it(`should get ${JSON.stringify(vans[10])} for selectById`, async function() {
435
+ it(`should get ${JSON.stringify(vans[10])} for selectByPk`, async function() {
426
436
  assert.strict.deepStrictEqual(vget[10], vans[10])
427
437
  })
428
438
 
429
439
  vans[11] = true
430
- it(`should get ${JSON.stringify(vans[11])} for same content between selectById and select`, async function() {
440
+ it(`should get ${JSON.stringify(vans[11])} for same content between selectByPk and select`, async function() {
431
441
  assert.strict.deepStrictEqual(vget[11], vans[11])
432
442
  })
433
443
 
434
444
  vans[12] = null
435
- it(`should get ${JSON.stringify(vans[12])} for selectById by id not existed`, async function() {
445
+ it(`should get ${JSON.stringify(vans[12])} for selectByPk by id not existed`, async function() {
436
446
  assert.strict.deepStrictEqual(vget[12], vans[12])
437
447
  })
438
448
 
439
449
  vans[13] = [null, null, null]
440
- it(`should get ${JSON.stringify(vans[13])} for selectById by id invalid`, async function() {
450
+ it(`should get ${JSON.stringify(vans[13])} for selectByPk by id invalid`, async function() {
441
451
  assert.strict.deepStrictEqual(vget[13], vans[13])
442
452
  })
443
453
 
@@ -447,7 +457,7 @@ describe('basic', function() {
447
457
  })
448
458
 
449
459
  vans[15] = null
450
- it(`should get ${JSON.stringify(vans[15])} for selectById after del`, async function() {
460
+ it(`should get ${JSON.stringify(vans[15])} for selectByPk after del`, async function() {
451
461
  assert.strict.deepStrictEqual(vget[15], vans[15])
452
462
  })
453
463
 
@@ -510,10 +520,10 @@ describe('insert', function() {
510
520
  vget[7] = (await wo.select()).length
511
521
 
512
522
  //同批重複者僅首筆入庫
513
- vget[8] = (await wo.selectById('i-dup')).name
523
+ vget[8] = (await wo.selectByPk('i-dup')).name
514
524
 
515
525
  //已存在id不得被insert覆寫
516
- vget[9] = await wo.selectById('i2')
526
+ vget[9] = await wo.selectByPk('i2')
517
527
 
518
528
  //併發後僅存單筆
519
529
  vget[10] = (await wo.select({ id: 'i-race' })).length
@@ -605,7 +615,7 @@ describe('save', function() {
605
615
  await Promise.all(Array.from({ length: 10 }, (v, k) => {
606
616
  return wo.save({ id: 'u1', [`f${k}`]: k })
607
617
  }))
608
- let vu1 = await wo.selectById('u1')
618
+ let vu1 = await wo.selectByPk('u1')
609
619
  vget[1] = Object.keys(vu1).filter((k) => k.indexOf('f') === 0).length
610
620
  vget[2] = vu1.base
611
621
 
@@ -616,7 +626,7 @@ describe('save', function() {
616
626
  vget[3] = rsn.filter((v) => v[0].nInserted === 1).length
617
627
  vget[4] = rsn.filter((v) => v[0].ok !== 1).length
618
628
  vget[5] = (await wo.select({ id: 'w1' })).length
619
- vget[6] = Object.keys(await wo.selectById('w1')).filter((k) => k.indexOf('g') === 0).length
629
+ vget[6] = Object.keys(await wo.selectByPk('w1')).filter((k) => k.indexOf('g') === 0).length
620
630
 
621
631
  //save內容相同不更新, 由MongoDB於伺服器端比對合併後結果與現值
622
632
  await wo.insert({ id: 's1', name: 'same', value: 5 })
@@ -633,11 +643,11 @@ describe('save', function() {
633
643
  //save內容不同須更新, 未給之欄位須保留
634
644
  await wo.insert({ id: 'd1', name: 'diff', value: 5 })
635
645
  vget[8] = await wo.save({ id: 'd1', value: 6 })
636
- vget[9] = await wo.selectById('d1')
646
+ vget[9] = await wo.selectByPk('d1')
637
647
 
638
648
  //save(autoInsert=false)對不存在之id不得插入
639
649
  vget[10] = await wo.save({ id: 'n1', name: 'none' }, { autoInsert: false })
640
- vget[11] = await wo.selectById('n1')
650
+ vget[11] = await wo.selectByPk('n1')
641
651
 
642
652
  //併發save(autoInsert=false)對既有id之不同欄位, 各欄位皆須保留且不得報錯
643
653
  await wo.insert({ id: 'p1', name: 'origin', value: 1 })
@@ -646,7 +656,7 @@ describe('save', function() {
646
656
  wo.save({ id: 'p1', value: 88 }, { autoInsert: false }),
647
657
  ])
648
658
  vget[12] = rsu.filter((v) => v[0].ok !== 1).length
649
- vget[13] = await wo.selectById('p1')
659
+ vget[13] = await wo.selectByPk('p1')
650
660
 
651
661
  //change事件, autoInsert時仍須發出insert事件
652
662
  let woEv = WOrm(genOpt('saveevent'))
@@ -812,10 +822,10 @@ describe('save single failure', function() {
812
822
  }
813
823
 
814
824
  //單筆失敗不得中斷整批, 後續筆仍須寫入
815
- vget[7] = (await wo.selectById('f3')).name
825
+ vget[7] = (await wo.selectByPk('f3')).name
816
826
 
817
827
  //失敗筆不得被寫入
818
- vget[8] = await wo.selectById('f2')
828
+ vget[8] = await wo.selectByPk('f2')
819
829
 
820
830
  })
821
831
 
@@ -920,7 +930,7 @@ describe('del', function() {
920
930
  vget[15] = typeof rbig[0].err === 'string' && rbig[0].err.length > 0
921
931
 
922
932
  //單筆失敗不得中斷整批, 後續筆仍須刪除
923
- vget[16] = await wo.selectById('k3')
933
+ vget[16] = await wo.selectByPk('k3')
924
934
 
925
935
  })
926
936
 
@@ -1094,7 +1104,7 @@ describe('change event', function() {
1094
1104
  })
1095
1105
 
1096
1106
  vget[1] = await wo.insert({ id: 'e1', name: 'a' })
1097
- vget[2] = await wo.selectById('e1')
1107
+ vget[2] = await wo.selectByPk('e1')
1098
1108
  vget[3] = await wo.save({ id: 'e1', name: 'b' })
1099
1109
  vget[4] = await wo.del({ id: 'e1' })
1100
1110
  vget[5] = await wo.delAll()
@@ -1129,6 +1139,224 @@ describe('change event', function() {
1129
1139
  })
1130
1140
 
1131
1141
 
1142
+ describe('autoGenPk', function() {
1143
+ let rt = null
1144
+ let vans = {}
1145
+ let vget = {}
1146
+
1147
+ before(async function() {
1148
+ this.timeout(120000)
1149
+
1150
+ //woDef, 未給autoGenPk以驗證其預設值為true
1151
+ let woDef = WOrm(genOpt('pkdefault'))
1152
+ await woDef.delAll()
1153
+
1154
+ //預設未帶id者須自動產生, 且產生之id須為有效字串
1155
+ vget[1] = await woDef.insert({ name: 'no-id' })
1156
+ let ssDef = await woDef.select()
1157
+ vget[2] = ssDef.length
1158
+ vget[3] = typeof ssDef[0].id === 'string' && ssDef[0].id.length > 0
1159
+
1160
+ //預設之save未帶id者亦須自動產生
1161
+ vget[4] = await woDef.save({ name: 'no-id-save' })
1162
+ vget[5] = (await woDef.select()).length
1163
+
1164
+ //woOn, 明確開啟
1165
+ let woOn = WOrm(genOptPk('pkon', true))
1166
+ await woOn.delAll()
1167
+ vget[6] = await woOn.insert({ name: 'no-id' })
1168
+ vget[7] = (await woOn.select()).length
1169
+
1170
+ //woOff, 關閉後主鍵須由呼叫端自備
1171
+ let woOff = WOrm(genOptPk('pkoff', false))
1172
+ await woOff.delAll()
1173
+
1174
+ //帶id者正常寫入
1175
+ vget[8] = await woOff.insert({ id: 'p1', name: 'given' })
1176
+ vget[9] = await woOff.selectByPk('p1')
1177
+
1178
+ //未帶id者須reject, 屬整批性錯誤而不進入逐筆結果
1179
+ rt = null
1180
+ // vans[10] = 'Error: invalid data[0].id, autoGenPk is false'
1181
+ await woOff.insert({ name: 'no-id' })
1182
+ .then(function(msg) {
1183
+ rt = `不應resolve: ${JSON.stringify(msg)}`
1184
+ })
1185
+ .catch(function(msg) {
1186
+ rt = msg.toString()
1187
+ })
1188
+ vget[10] = rt
1189
+
1190
+ //save未帶id者亦須reject, autoInsert兩種取值皆同
1191
+ rt = null
1192
+ // vans[11] = 'Error: invalid data[0].id, autoGenPk is false'
1193
+ await woOff.save({ name: 'no-id' })
1194
+ .then(function(msg) {
1195
+ rt = `不應resolve: ${JSON.stringify(msg)}`
1196
+ })
1197
+ .catch(function(msg) {
1198
+ rt = msg.toString()
1199
+ })
1200
+ vget[11] = rt
1201
+
1202
+ rt = null
1203
+ // vans[12] = 'Error: invalid data[0].id, autoGenPk is false'
1204
+ await woOff.save({ name: 'no-id' }, { autoInsert: false })
1205
+ .then(function(msg) {
1206
+ rt = `不應resolve: ${JSON.stringify(msg)}`
1207
+ })
1208
+ .catch(function(msg) {
1209
+ rt = msg.toString()
1210
+ })
1211
+ vget[12] = rt
1212
+
1213
+ //整批reject時, 同批之有效筆數亦不得被寫入
1214
+ rt = null
1215
+ // vans[13] = 'Error: invalid data[1].id, autoGenPk is false'
1216
+ await woOff.insert([
1217
+ { id: 'p-ok1', name: 'ok1' },
1218
+ { name: 'no-id' },
1219
+ { id: 'p-ok2', name: 'ok2' },
1220
+ ])
1221
+ .then(function(msg) {
1222
+ rt = `不應resolve: ${JSON.stringify(msg)}`
1223
+ })
1224
+ .catch(function(msg) {
1225
+ rt = msg.toString()
1226
+ })
1227
+ vget[13] = rt
1228
+ vget[14] = [
1229
+ await woOff.selectByPk('p-ok1'),
1230
+ await woOff.selectByPk('p-ok2'),
1231
+ ]
1232
+
1233
+ //save之整批reject亦同
1234
+ await woOff.insert({ id: 'p-base', name: 'base' })
1235
+ await woOff.save([
1236
+ { id: 'p-base', name: 'should-not-write' },
1237
+ { name: 'no-id' },
1238
+ ]).catch(() => {})
1239
+ vget[15] = (await woOff.selectByPk('p-base')).name
1240
+
1241
+ //del不受autoGenPk影響, 未帶有效id仍為該筆ok為0而非reject
1242
+ vget[16] = await woOff.del({ name: 'no-id' })
1243
+
1244
+ //autoGenPk為建構層設定, 不得於option逐次覆寫
1245
+ rt = null
1246
+ // vans[17] = 'Error: invalid data[0].id, autoGenPk is false'
1247
+ await woOff.save({ name: 'no-id' }, { autoGenPk: true })
1248
+ .then(function(msg) {
1249
+ rt = `不應resolve: ${JSON.stringify(msg)}`
1250
+ })
1251
+ .catch(function(msg) {
1252
+ rt = msg.toString()
1253
+ })
1254
+ vget[17] = rt
1255
+
1256
+ //輸入無效仍依T5回空結果, 不因autoGenPk為false而reject
1257
+ vget[18] = await woOff.insert(null)
1258
+ vget[19] = await woOff.save(null)
1259
+
1260
+ })
1261
+
1262
+ vans[1] = { n: 1, nInserted: 1, ok: 1 }
1263
+ it(`should get ${JSON.stringify(vans[1])} for insert without id by default autoGenPk`, async function() {
1264
+ assert.strict.deepStrictEqual(vget[1], vans[1])
1265
+ })
1266
+
1267
+ vans[2] = 1
1268
+ it(`should get ${JSON.stringify(vans[2])} for records after insert without id by default autoGenPk`, async function() {
1269
+ assert.strict.deepStrictEqual(vget[2], vans[2])
1270
+ })
1271
+
1272
+ vans[3] = true
1273
+ it(`should get ${JSON.stringify(vans[3])} for generated id by default autoGenPk`, async function() {
1274
+ assert.strict.deepStrictEqual(vget[3], vans[3])
1275
+ })
1276
+
1277
+ vans[4] = [{ n: 1, nInserted: 1, nModified: 0, ok: 1 }]
1278
+ it(`should get ${JSON.stringify(vans[4])} for save without id by default autoGenPk`, async function() {
1279
+ assert.strict.deepStrictEqual(vget[4], vans[4])
1280
+ })
1281
+
1282
+ vans[5] = 2
1283
+ it(`should get ${JSON.stringify(vans[5])} for records after save without id by default autoGenPk`, async function() {
1284
+ assert.strict.deepStrictEqual(vget[5], vans[5])
1285
+ })
1286
+
1287
+ vans[6] = { n: 1, nInserted: 1, ok: 1 }
1288
+ it(`should get ${JSON.stringify(vans[6])} for insert without id by autoGenPk=true`, async function() {
1289
+ assert.strict.deepStrictEqual(vget[6], vans[6])
1290
+ })
1291
+
1292
+ vans[7] = 1
1293
+ it(`should get ${JSON.stringify(vans[7])} for records after insert without id by autoGenPk=true`, async function() {
1294
+ assert.strict.deepStrictEqual(vget[7], vans[7])
1295
+ })
1296
+
1297
+ vans[8] = { n: 1, nInserted: 1, ok: 1 }
1298
+ it(`should get ${JSON.stringify(vans[8])} for insert with id by autoGenPk=false`, async function() {
1299
+ assert.strict.deepStrictEqual(vget[8], vans[8])
1300
+ })
1301
+
1302
+ vans[9] = { id: 'p1', name: 'given' }
1303
+ it(`should get ${JSON.stringify(vans[9])} for record after insert with id by autoGenPk=false`, async function() {
1304
+ assert.strict.deepStrictEqual(vget[9], vans[9])
1305
+ })
1306
+
1307
+ vans[10] = 'Error: invalid data[0].id, autoGenPk is false'
1308
+ it(`should get ${JSON.stringify(vans[10])} for insert without id by autoGenPk=false`, async function() {
1309
+ assert.strict.deepStrictEqual(vget[10], vans[10])
1310
+ })
1311
+
1312
+ vans[11] = 'Error: invalid data[0].id, autoGenPk is false'
1313
+ it(`should get ${JSON.stringify(vans[11])} for save without id by autoGenPk=false`, async function() {
1314
+ assert.strict.deepStrictEqual(vget[11], vans[11])
1315
+ })
1316
+
1317
+ vans[12] = 'Error: invalid data[0].id, autoGenPk is false'
1318
+ it(`should get ${JSON.stringify(vans[12])} for save(autoInsert=false) without id by autoGenPk=false`, async function() {
1319
+ assert.strict.deepStrictEqual(vget[12], vans[12])
1320
+ })
1321
+
1322
+ vans[13] = 'Error: invalid data[1].id, autoGenPk is false'
1323
+ it(`should get ${JSON.stringify(vans[13])} for insert with 1 record without id by autoGenPk=false`, async function() {
1324
+ assert.strict.deepStrictEqual(vget[13], vans[13])
1325
+ })
1326
+
1327
+ vans[14] = [null, null]
1328
+ it(`should get ${JSON.stringify(vans[14])} for not writing valid records in rejected batch`, async function() {
1329
+ assert.strict.deepStrictEqual(vget[14], vans[14])
1330
+ })
1331
+
1332
+ vans[15] = 'base'
1333
+ it(`should get ${JSON.stringify(vans[15])} for not writing valid records in rejected save batch`, async function() {
1334
+ assert.strict.deepStrictEqual(vget[15], vans[15])
1335
+ })
1336
+
1337
+ vans[16] = [{ n: 0, nDeleted: 0, ok: 0, err: 'invalid id[undefined]' }]
1338
+ it(`should get ${JSON.stringify(vans[16])} for del without id by autoGenPk=false`, async function() {
1339
+ assert.strict.deepStrictEqual(vget[16], vans[16])
1340
+ })
1341
+
1342
+ vans[17] = 'Error: invalid data[0].id, autoGenPk is false'
1343
+ it(`should get ${JSON.stringify(vans[17])} for not overriding autoGenPk by option`, async function() {
1344
+ assert.strict.deepStrictEqual(vget[17], vans[17])
1345
+ })
1346
+
1347
+ vans[18] = { n: 0, nInserted: 0, ok: 1 }
1348
+ it(`should get ${JSON.stringify(vans[18])} for insert with invalid data by autoGenPk=false`, async function() {
1349
+ assert.strict.deepStrictEqual(vget[18], vans[18])
1350
+ })
1351
+
1352
+ vans[19] = []
1353
+ it(`should get ${JSON.stringify(vans[19])} for save with invalid data by autoGenPk=false`, async function() {
1354
+ assert.strict.deepStrictEqual(vget[19], vans[19])
1355
+ })
1356
+
1357
+ })
1358
+
1359
+
1132
1360
  describe('cross process concurrency', function() {
1133
1361
  let vans = {}
1134
1362
  let vget = {}
@@ -1160,7 +1388,7 @@ describe('cross process concurrency', function() {
1160
1388
  runProc('P1', clSav, 'save', keys),
1161
1389
  runProc('P2', clSav, 'save', keys),
1162
1390
  ])
1163
- let vx1 = await woSav.selectById('x1')
1391
+ let vx1 = await woSav.selectByPk('x1')
1164
1392
  vget[4] = Object.keys(vx1).filter((k) => k.indexOf('P1k') === 0 || k.indexOf('P2k') === 0).length
1165
1393
  vget[5] = vx1.base
1166
1394
  vget[6] = (await woSav.select()).length
@@ -20,6 +20,16 @@ let genOpt = (cl) => {
20
20
  }
21
21
  }
22
22
 
23
+ //genOptPk, 明確指定autoGenPk
24
+ let genOptPk = (cl, autoGenPk) => {
25
+ return {
26
+ url: genUrl(ctPort),
27
+ db: ctDb,
28
+ cl,
29
+ autoGenPk,
30
+ }
31
+ }
32
+
23
33
  //genKeys, 取回傳物件之鍵集合, 用於驗證鍵集合固定
24
34
  let genKeys = (v) => {
25
35
  return Object.keys(v).sort().join(',')
@@ -139,10 +149,10 @@ describe('gfs basic', function() {
139
149
  // vans[3] = { files: 1, chunks: 2 }
140
150
  vget[3] = await countDocs(cl)
141
151
 
142
- //selectByIdGfs, 取回內容須與來源逐位元組相同, 且形狀與insertGfs所收之數據物件一致
152
+ //selectByPkGfs, 取回內容須與來源逐位元組相同, 且形狀與insertGfs所收之數據物件一致
143
153
  rt = null
144
154
  // vans[4] = { keys: 'id,u8a', id: 'g-big', length: nSize, hash, b0: 0, b1: 1, b255: 255, b256: 0 }
145
- await wo.selectByIdGfs('g-big')
155
+ await wo.selectByPkGfs('g-big')
146
156
  .then(function(msg) {
147
157
  rt = {
148
158
  keys: genKeys(msg),
@@ -160,10 +170,10 @@ describe('gfs basic', function() {
160
170
  })
161
171
  vget[4] = rt
162
172
 
163
- //selectByIdGfs by id not existed
173
+ //selectByPkGfs by id not existed
164
174
  rt = null
165
175
  // vans[5] = null
166
- await wo.selectByIdGfs('id-not-existed')
176
+ await wo.selectByPkGfs('id-not-existed')
167
177
  .then(function(msg) {
168
178
  rt = msg
169
179
  })
@@ -172,12 +182,12 @@ describe('gfs basic', function() {
172
182
  })
173
183
  vget[5] = rt
174
184
 
175
- //selectByIdGfs by id invalid, 未給有效id視為查無數據
185
+ //selectByPkGfs by id invalid, 未給有效id視為查無數據
176
186
  // vans[6] = [null, null, null]
177
187
  vget[6] = [
178
- await wo.selectByIdGfs(''),
179
- await wo.selectByIdGfs(123),
180
- await wo.selectByIdGfs(null),
188
+ await wo.selectByPkGfs(''),
189
+ await wo.selectByPkGfs(123),
190
+ await wo.selectByPkGfs(null),
181
191
  ]
182
192
 
183
193
  //insertGfs未給id時自動產生
@@ -284,17 +294,17 @@ describe('gfs basic', function() {
284
294
  b255: 255,
285
295
  b256: 0,
286
296
  }
287
- it(`should get same content for selectByIdGfs`, async function() {
297
+ it(`should get same content for selectByPkGfs`, async function() {
288
298
  assert.strict.deepStrictEqual(vget[4], vans[4])
289
299
  })
290
300
 
291
301
  vans[5] = null
292
- it(`should get ${JSON.stringify(vans[5])} for selectByIdGfs by id not existed`, async function() {
302
+ it(`should get ${JSON.stringify(vans[5])} for selectByPkGfs by id not existed`, async function() {
293
303
  assert.strict.deepStrictEqual(vget[5], vans[5])
294
304
  })
295
305
 
296
306
  vans[6] = [null, null, null]
297
- it(`should get ${JSON.stringify(vans[6])} for selectByIdGfs by id invalid`, async function() {
307
+ it(`should get ${JSON.stringify(vans[6])} for selectByPkGfs by id invalid`, async function() {
298
308
  assert.strict.deepStrictEqual(vget[6], vans[6])
299
309
  })
300
310
 
@@ -395,7 +405,7 @@ describe('gfs insert', function() {
395
405
  vget[3] = { files: c2.files - c1.files, chunks: c2.chunks - c1.chunks }
396
406
 
397
407
  //已存在id不得被覆寫, 內容須為首次所給
398
- let vi1 = await wo.selectByIdGfs('i1')
408
+ let vi1 = await wo.selectByPkGfs('i1')
399
409
  vget[4] = genHash(vi1.u8a) === genHash(genU8a(100, 1))
400
410
 
401
411
  //部份重複, 1筆已存在2筆為新
@@ -411,7 +421,7 @@ describe('gfs insert', function() {
411
421
  { id: 'i-dup', u8a: genU8a(100, 7) },
412
422
  { id: 'i-uniq', u8a: genU8a(100, 8) },
413
423
  ])
414
- let vdup = await wo.selectByIdGfs('i-dup')
424
+ let vdup = await wo.selectByPkGfs('i-dup')
415
425
  vget[7] = genHash(vdup.u8a) === genHash(genU8a(100, 6))
416
426
 
417
427
  //併發對同一id插入10次, nInserted總和須為1
@@ -528,6 +538,128 @@ describe('gfs legacy duplicated id', function() {
528
538
  })
529
539
 
530
540
 
541
+ describe('gfs autoGenPk', function() {
542
+ let rt = null
543
+ let vans = {}
544
+ let vget = {}
545
+
546
+ before(async function() {
547
+ this.timeout(300000)
548
+
549
+ //woDef, 未給autoGenPk以驗證其預設值為true
550
+ let clDef = 'pkdefaultGfs'
551
+ let woDef = WOrm(genOpt(clDef))
552
+ await woDef.delAllGfs()
553
+
554
+ //預設未帶id者須自動產生
555
+ vget[1] = await woDef.insertGfs({ u8a: genU8a(100, 1) })
556
+ vget[2] = (await countDocs(clDef)).files
557
+
558
+ //woOff, 關閉後主鍵須由呼叫端自備
559
+ let clOff = 'pkoffGfs'
560
+ let woOff = WOrm(genOptPk(clOff, false))
561
+ await woOff.delAllGfs()
562
+
563
+ //帶id者正常寫入
564
+ vget[3] = await woOff.insertGfs({ id: 'g1', u8a: genU8a(100, 2) })
565
+ vget[4] = genHash((await woOff.selectByPkGfs('g1')).u8a) === genHash(genU8a(100, 2))
566
+
567
+ //未帶id者須reject
568
+ rt = null
569
+ // vans[5] = 'Error: invalid data[0].id, autoGenPk is false'
570
+ await woOff.insertGfs({ u8a: genU8a(100, 3) })
571
+ .then(function(msg) {
572
+ rt = `不應resolve: ${JSON.stringify(msg)}`
573
+ })
574
+ .catch(function(msg) {
575
+ rt = msg.toString()
576
+ })
577
+ vget[5] = rt
578
+
579
+ //整批reject時, 同批之有效筆數亦不得被寫入
580
+ let cBefore = await countDocs(clOff)
581
+ rt = null
582
+ // vans[6] = 'Error: invalid data[1].id, autoGenPk is false'
583
+ await woOff.insertGfs([
584
+ { id: 'g-ok1', u8a: genU8a(100, 4) },
585
+ { u8a: genU8a(100, 5) },
586
+ { id: 'g-ok2', u8a: genU8a(100, 6) },
587
+ ])
588
+ .then(function(msg) {
589
+ rt = `不應resolve: ${JSON.stringify(msg)}`
590
+ })
591
+ .catch(function(msg) {
592
+ rt = msg.toString()
593
+ })
594
+ vget[6] = rt
595
+ let cAfter = await countDocs(clOff)
596
+ vget[7] = { files: cAfter.files - cBefore.files, chunks: cAfter.chunks - cBefore.chunks }
597
+ vget[8] = [
598
+ await woOff.selectByPkGfs('g-ok1'),
599
+ await woOff.selectByPkGfs('g-ok2'),
600
+ ]
601
+
602
+ //delGfs不受autoGenPk影響, 未帶有效id仍為該筆ok為0而非reject
603
+ vget[9] = await woOff.delGfs({ u8a: genU8a(10) })
604
+
605
+ //輸入無效仍依T5回空結果
606
+ vget[10] = await woOff.insertGfs(null)
607
+
608
+ })
609
+
610
+ vans[1] = { n: 1, nInserted: 1, ok: 1 }
611
+ it(`should get ${JSON.stringify(vans[1])} for insertGfs without id by default autoGenPk`, async function() {
612
+ assert.strict.deepStrictEqual(vget[1], vans[1])
613
+ })
614
+
615
+ vans[2] = 1
616
+ it(`should get ${JSON.stringify(vans[2])} for files after insertGfs without id by default autoGenPk`, async function() {
617
+ assert.strict.deepStrictEqual(vget[2], vans[2])
618
+ })
619
+
620
+ vans[3] = { n: 1, nInserted: 1, ok: 1 }
621
+ it(`should get ${JSON.stringify(vans[3])} for insertGfs with id by autoGenPk=false`, async function() {
622
+ assert.strict.deepStrictEqual(vget[3], vans[3])
623
+ })
624
+
625
+ vans[4] = true
626
+ it(`should get ${JSON.stringify(vans[4])} for content after insertGfs with id by autoGenPk=false`, async function() {
627
+ assert.strict.deepStrictEqual(vget[4], vans[4])
628
+ })
629
+
630
+ vans[5] = 'Error: invalid data[0].id, autoGenPk is false'
631
+ it(`should get ${JSON.stringify(vans[5])} for insertGfs without id by autoGenPk=false`, async function() {
632
+ assert.strict.deepStrictEqual(vget[5], vans[5])
633
+ })
634
+
635
+ vans[6] = 'Error: invalid data[1].id, autoGenPk is false'
636
+ it(`should get ${JSON.stringify(vans[6])} for insertGfs with 1 record without id by autoGenPk=false`, async function() {
637
+ assert.strict.deepStrictEqual(vget[6], vans[6])
638
+ })
639
+
640
+ vans[7] = { files: 0, chunks: 0 }
641
+ it(`should get ${JSON.stringify(vans[7])} for not writing valid records in rejected insertGfs batch`, async function() {
642
+ assert.strict.deepStrictEqual(vget[7], vans[7])
643
+ })
644
+
645
+ vans[8] = [null, null]
646
+ it(`should get ${JSON.stringify(vans[8])} for records after rejected insertGfs batch`, async function() {
647
+ assert.strict.deepStrictEqual(vget[8], vans[8])
648
+ })
649
+
650
+ vans[9] = [{ n: 0, nDeleted: 0, ok: 0, err: 'invalid id[undefined]' }]
651
+ it(`should get ${JSON.stringify(vans[9])} for delGfs without id by autoGenPk=false`, async function() {
652
+ assert.strict.deepStrictEqual(vget[9], vans[9])
653
+ })
654
+
655
+ vans[10] = { n: 0, nInserted: 0, ok: 1 }
656
+ it(`should get ${JSON.stringify(vans[10])} for insertGfs with invalid data by autoGenPk=false`, async function() {
657
+ assert.strict.deepStrictEqual(vget[10], vans[10])
658
+ })
659
+
660
+ })
661
+
662
+
531
663
  describe('gfs change event', function() {
532
664
  let vans = {}
533
665
  let vget = {}
@@ -545,7 +677,7 @@ describe('gfs change event', function() {
545
677
  })
546
678
 
547
679
  vget[1] = await wo.insertGfs({ id: 'e1', u8a: genU8a(100, 1) })
548
- vget[2] = genHash((await wo.selectByIdGfs('e1')).u8a) === genHash(genU8a(100, 1))
680
+ vget[2] = genHash((await wo.selectByPkGfs('e1')).u8a) === genHash(genU8a(100, 1))
549
681
  vget[3] = await wo.delGfs({ id: 'e1' })
550
682
  vget[4] = await wo.delAllGfs()
551
683