w-orm-postgresql 1.0.8 → 1.0.10
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 +16 -16
- package/dist/w-orm-postgresql.umd.js +2 -2
- package/dist/w-orm-postgresql.umd.js.map +1 -1
- package/docs/WOrmPostgresql.html +138 -27
- package/docs/WOrmPostgresql.mjs.html +148 -56
- package/docs/index.html +2 -2
- package/g-basic.mjs +16 -16
- package/package.json +1 -1
- package/src/WOrmPostgresql.mjs +146 -54
- package/test/api-postgresql.test.mjs +513 -46
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
<nav >
|
|
30
30
|
|
|
31
31
|
|
|
32
|
-
<h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="WOrmPostgresql.html">WOrmPostgresql</a><ul class='methods'><li data-type='method'><a href="WOrmPostgresql.html#.createTable">createTable</a></li><li data-type='method'><a href="WOrmPostgresql.html#.del">del</a></li><li data-type='method'><a href="WOrmPostgresql.html#.delAll">delAll</a></li><li data-type='method'><a href="WOrmPostgresql.html#.insert">insert</a></li><li data-type='method'><a href="WOrmPostgresql.html#.save">save</a></li><li data-type='method'><a href="WOrmPostgresql.html#.select">select</a></li><li data-type='method'><a href="WOrmPostgresql.html#.
|
|
32
|
+
<h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="WOrmPostgresql.html">WOrmPostgresql</a><ul class='methods'><li data-type='method'><a href="WOrmPostgresql.html#.createTable">createTable</a></li><li data-type='method'><a href="WOrmPostgresql.html#.del">del</a></li><li data-type='method'><a href="WOrmPostgresql.html#.delAll">delAll</a></li><li data-type='method'><a href="WOrmPostgresql.html#.insert">insert</a></li><li data-type='method'><a href="WOrmPostgresql.html#.save">save</a></li><li data-type='method'><a href="WOrmPostgresql.html#.select">select</a></li><li data-type='method'><a href="WOrmPostgresql.html#.selectByPk">selectByPk</a></li></ul></li></ul>
|
|
33
33
|
|
|
34
34
|
</nav>
|
|
35
35
|
|
|
@@ -73,11 +73,16 @@ import pmSeries from 'wsemi/src/pmSeries.mjs'
|
|
|
73
73
|
/**
|
|
74
74
|
* 操作資料庫(PostgreSQL)
|
|
75
75
|
*
|
|
76
|
+
* 本套件之主鍵欄位由opt.pk指定,預設為time,select以外之五函數皆以此欄位認定主鍵。
|
|
77
|
+
* 因主鍵得為承載業務語義之欄位(如時序資料之觀測時間),insert與save於輸入未帶有效主鍵值時不自動補值,
|
|
78
|
+
* 一律以reject回報;del亦不補值,該筆回ok:0與err。
|
|
79
|
+
*
|
|
76
80
|
* @class
|
|
77
81
|
* @param {Object} [opt={}] 輸入設定物件,預設{}
|
|
78
82
|
* @param {String} [opt.url='postgresql://127.0.0.1:5432'] 輸入連接資料庫字串,預設'postgresql://127.0.0.1:5432'
|
|
79
83
|
* @param {String} [opt.db='worm'] 輸入使用資料庫名稱字串,預設'worm'
|
|
80
84
|
* @param {String} [opt.cl='test'] 輸入使用資料表名稱字串,預設'test'
|
|
85
|
+
* @param {String} [opt.pk='time'] 輸入主鍵欄位名字串,預設'time'
|
|
81
86
|
* @param {Boolean} [opt.useCache=false] 輸入是否使用select快取,適用於單程序操作,預設false
|
|
82
87
|
* @returns {Object} 回傳操作資料庫物件,各事件功能詳見說明
|
|
83
88
|
*/
|
|
@@ -110,6 +115,26 @@ function WOrmPostgresql(opt = {}) {
|
|
|
110
115
|
useCache = false
|
|
111
116
|
}
|
|
112
117
|
|
|
118
|
+
//pkName, 主鍵欄位名, select以外之五函數皆以此欄位認定主鍵, 預設為time
|
|
119
|
+
let pkName = get(opt, 'pk')
|
|
120
|
+
if (!isestr(pkName)) {
|
|
121
|
+
pkName = 'time'
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
//checkPk, 判定主鍵值是否有效
|
|
125
|
+
//因主鍵欄位得由呼叫端指定, 其型別隨欄位而異, 故此處僅要求有給值而不限定型別,
|
|
126
|
+
//型別與欄位不符者由PostgreSQL回報, 各函數再依其規格處置
|
|
127
|
+
function checkPk(pkv) {
|
|
128
|
+
return isestr(pkv) || isnum(pkv) || isbol(pkv) || isDate(pkv)
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
//isErrPkType, 判定錯誤是否為[主鍵值型別與欄位不符]
|
|
132
|
+
//22P02為invalid_text_representation, 22007為invalid_datetime_format
|
|
133
|
+
function isErrPkType(err) {
|
|
134
|
+
let code = get(err, 'code')
|
|
135
|
+
return code === '22P02' || code === '22007'
|
|
136
|
+
}
|
|
137
|
+
|
|
113
138
|
//getValueType
|
|
114
139
|
function getValueType(value) {
|
|
115
140
|
if (isstr(value)) {
|
|
@@ -162,7 +187,7 @@ function WOrmPostgresql(opt = {}) {
|
|
|
162
187
|
let allKeys = keys(obj)
|
|
163
188
|
|
|
164
189
|
//conflictKeys
|
|
165
|
-
let conflictKeys = [
|
|
190
|
+
let conflictKeys = [pkName]
|
|
166
191
|
|
|
167
192
|
//updateKeys
|
|
168
193
|
let updateKeys = filter(allKeys, (k) => {
|
|
@@ -237,14 +262,22 @@ function WOrmPostgresql(opt = {}) {
|
|
|
237
262
|
|
|
238
263
|
/**
|
|
239
264
|
* 創建資料表
|
|
265
|
+
* 註: pk未給時採建構時之opt.pk。因insert與save倚賴主鍵之唯一約束達成原子性,
|
|
266
|
+
* 若給予與opt.pk不同之欄位,將建出其餘函數無法正確操作之資料表,故一般應留空或給予相同值
|
|
240
267
|
*
|
|
241
268
|
* @memberOf WOrmPostgresql
|
|
242
269
|
* @param {String} cl 輸入資料表名字串
|
|
243
|
-
* @param {String} pk
|
|
270
|
+
* @param {String} [pk=opt.pk] 輸入主鍵欄位名字串,預設為建構時之opt.pk
|
|
244
271
|
* @param {Array|Object} arr 輸入數據物件陣列或數據物件
|
|
245
272
|
* @returns {Promise} 回傳Promise,resolve回傳成功訊息,reject回傳錯誤訊息
|
|
246
273
|
*/
|
|
247
274
|
async function createTable(cl, pk, arr) {
|
|
275
|
+
|
|
276
|
+
//pk, 未給時採建構時設定之主鍵欄位
|
|
277
|
+
if (!isestr(pk)) {
|
|
278
|
+
pk = pkName
|
|
279
|
+
}
|
|
280
|
+
|
|
248
281
|
let isErr = false
|
|
249
282
|
let res = null
|
|
250
283
|
|
|
@@ -415,25 +448,29 @@ function WOrmPostgresql(opt = {}) {
|
|
|
415
448
|
}
|
|
416
449
|
|
|
417
450
|
/**
|
|
418
|
-
*
|
|
451
|
+
* 由主鍵查詢單筆數據,因直接由資料表主鍵索引取值,不需如select提取數據至前端再處理,故數據量大時效能較佳
|
|
452
|
+
* 註: 本套件之主鍵欄位由建構時之opt.pk指定,預設為time
|
|
453
|
+
*
|
|
454
|
+
* 主鍵未命中或主鍵值無效皆回傳null而不reject,命中之判定基準與insert、save、del內對既有數據之認定一致。
|
|
455
|
+
* 主鍵值之型別與欄位不符時PostgreSQL回報22P02或22007,亦屬主鍵值無效而回傳null。
|
|
419
456
|
*
|
|
420
457
|
* @memberOf WOrmPostgresql
|
|
421
|
-
* @param {String|Date}
|
|
422
|
-
* @returns {Promise} 回傳Promise,resolve
|
|
458
|
+
* @param {String|Number|Date} pk 輸入主鍵值,即數據之主鍵欄位值
|
|
459
|
+
* @returns {Promise} 回傳Promise,resolve回傳數據物件,若無此主鍵則回傳null,reject回傳錯誤訊息
|
|
423
460
|
*/
|
|
424
|
-
async function
|
|
461
|
+
async function selectByPk(pk) {
|
|
425
462
|
let isErr = false
|
|
426
463
|
let res = null
|
|
427
464
|
|
|
428
465
|
//check
|
|
429
|
-
if (!
|
|
430
|
-
//未給有效主鍵值視為查無數據, 判定基準與insert、save、del
|
|
466
|
+
if (!checkPk(pk)) {
|
|
467
|
+
//未給有效主鍵值視為查無數據, 判定基準與insert、save、del內對主鍵之認定一致
|
|
431
468
|
return null
|
|
432
469
|
}
|
|
433
470
|
|
|
434
|
-
//find,
|
|
471
|
+
//find, 以建構時設定之主鍵欄位查找, 與insert、save、del、genConflictSQL之認定一致
|
|
435
472
|
let find = {
|
|
436
|
-
|
|
473
|
+
[pkName]: pk,
|
|
437
474
|
}
|
|
438
475
|
|
|
439
476
|
//cache, 與select共用快取, 因快取鍵值由find與order組成, 故此處等同select(find)之結果
|
|
@@ -487,7 +524,7 @@ function WOrmPostgresql(opt = {}) {
|
|
|
487
524
|
|
|
488
525
|
//check
|
|
489
526
|
if (!isarr(rows)) {
|
|
490
|
-
throw new Error(`can not select by
|
|
527
|
+
throw new Error(`can not select by pk[${pk}]`)
|
|
491
528
|
}
|
|
492
529
|
|
|
493
530
|
//cache
|
|
@@ -503,14 +540,22 @@ function WOrmPostgresql(opt = {}) {
|
|
|
503
540
|
res = v
|
|
504
541
|
}
|
|
505
542
|
else {
|
|
506
|
-
|
|
543
|
+
//不存在主鍵, 回傳null
|
|
507
544
|
res = null
|
|
508
545
|
}
|
|
509
546
|
|
|
510
547
|
}
|
|
511
548
|
catch (err) {
|
|
512
|
-
|
|
513
|
-
|
|
549
|
+
|
|
550
|
+
//check, 主鍵值之型別與欄位不符者亦屬主鍵值無效, 依規格回傳null而不reject
|
|
551
|
+
if (isErrPkType(err)) {
|
|
552
|
+
res = null
|
|
553
|
+
}
|
|
554
|
+
else {
|
|
555
|
+
isErr = true
|
|
556
|
+
res = err
|
|
557
|
+
}
|
|
558
|
+
|
|
514
559
|
}
|
|
515
560
|
finally {
|
|
516
561
|
await client.end()
|
|
@@ -527,11 +572,15 @@ function WOrmPostgresql(opt = {}) {
|
|
|
527
572
|
}
|
|
528
573
|
|
|
529
574
|
/**
|
|
530
|
-
*
|
|
575
|
+
* 插入數據,僅於主鍵不存在時寫入,已存在者跳過且不覆寫
|
|
576
|
+
*
|
|
577
|
+
* n為輸入筆數,即本次嘗試插入之基準;nInserted為實際插入筆數,全數已存在而nInserted為0屬正常結果,
|
|
578
|
+
* 不視為錯誤。同批含重複主鍵時僅首筆計入nInserted。
|
|
579
|
+
* 因主鍵得承載業務語義,未帶有效主鍵值時不自動補值,一律以reject回報。
|
|
531
580
|
*
|
|
532
581
|
* @memberOf WOrmPostgresql
|
|
533
582
|
* @param {Object|Array} data 輸入數據物件或陣列
|
|
534
|
-
* @returns {Promise} 回傳Promise,resolve
|
|
583
|
+
* @returns {Promise} 回傳Promise,resolve回傳插入結果物件{n,nInserted,ok},reject回傳錯誤訊息
|
|
535
584
|
*/
|
|
536
585
|
async function insert(data) {
|
|
537
586
|
let isErr = false
|
|
@@ -577,10 +626,10 @@ function WOrmPostgresql(opt = {}) {
|
|
|
577
626
|
data = [data]
|
|
578
627
|
}
|
|
579
628
|
|
|
580
|
-
//check
|
|
629
|
+
//check pk, 因主鍵得承載業務語義故不自動補值, 未帶有效主鍵值者屬整批性錯誤
|
|
581
630
|
data = map(data, function(v, k) {
|
|
582
|
-
if (!
|
|
583
|
-
throw new Error(`invalid data[${k}]
|
|
631
|
+
if (!checkPk(get(v, pkName))) {
|
|
632
|
+
throw new Error(`invalid data[${k}].${pkName}[${get(v, pkName)}]`)
|
|
584
633
|
}
|
|
585
634
|
return v
|
|
586
635
|
})
|
|
@@ -595,10 +644,10 @@ function WOrmPostgresql(opt = {}) {
|
|
|
595
644
|
// console.log('mr.query', mr.query)
|
|
596
645
|
// console.log('mr.values', mr.values)
|
|
597
646
|
|
|
598
|
-
//添加conflict,
|
|
599
|
-
//由PostgreSQL於單一語句內原子完成[
|
|
600
|
-
|
|
601
|
-
let sql = `${mr.query} ON CONFLICT (
|
|
647
|
+
//添加conflict, 令已存在主鍵者跳過而不中斷整批插入, 主鍵認定與genConflictSQL一致
|
|
648
|
+
//由PostgreSQL於單一語句內原子完成[檢查主鍵未存在]與[寫入], 併發時同一主鍵僅有一次成功,
|
|
649
|
+
//同批含重複主鍵時亦僅首筆成功, 故不須逐筆插入即可取得實際插入筆數
|
|
650
|
+
let sql = `${mr.query} ON CONFLICT (${pkName}) DO NOTHING`
|
|
602
651
|
|
|
603
652
|
//nAll
|
|
604
653
|
let nAll = size(data)
|
|
@@ -654,13 +703,21 @@ function WOrmPostgresql(opt = {}) {
|
|
|
654
703
|
}
|
|
655
704
|
|
|
656
705
|
/**
|
|
657
|
-
*
|
|
706
|
+
* 儲存數據,以主鍵time為準更新既有數據,未給之欄位保留
|
|
707
|
+
*
|
|
708
|
+
* 回傳陣列恆與輸入等長,輸入單一物件亦回傳長度1之陣列。
|
|
709
|
+
* 各筆之n為主鍵命中筆數,值為0或1,命中(不論內容有無變更)或經插入而產生皆為1;
|
|
710
|
+
* nInserted與nModified恆同時出現,無對應行為時填0。
|
|
711
|
+
* [內容相同]之判定基準為待寫入物件合併進現值後與現值相同,非待寫入物件與現值全等,
|
|
712
|
+
* 故只給部份欄位且該些欄位值皆與現值相同時,合併結果等於現值,nModified為0,
|
|
713
|
+
* 令nModified忠實反映資料庫端是否真的寫入。
|
|
714
|
+
* 因主鍵得承載業務語義,未帶有效主鍵值時不自動補值,一律以reject回報。
|
|
658
715
|
*
|
|
659
716
|
* @memberOf WOrmPostgresql
|
|
660
717
|
* @param {Object|Array} data 輸入數據物件或陣列
|
|
661
718
|
* @param {Object} [option={}] 輸入設定物件,預設為{}
|
|
662
719
|
* @param {boolean} [option.autoInsert=true] 輸入是否於儲存時發現原本無數據,則自動改以插入處理,預設為true
|
|
663
|
-
* @returns {Promise} 回傳Promise,resolve
|
|
720
|
+
* @returns {Promise} 回傳Promise,resolve回傳儲存結果陣列[{n,nInserted,nModified,ok}],reject回傳錯誤訊息
|
|
664
721
|
*/
|
|
665
722
|
async function save(data, option = {}) {
|
|
666
723
|
let isErr = false
|
|
@@ -705,10 +762,10 @@ function WOrmPostgresql(opt = {}) {
|
|
|
705
762
|
data = [data]
|
|
706
763
|
}
|
|
707
764
|
|
|
708
|
-
//check
|
|
765
|
+
//check pk, 因主鍵得承載業務語義故不自動補值, 未帶有效主鍵值者屬整批性錯誤
|
|
709
766
|
data = map(data, function(v, k) {
|
|
710
|
-
if (!
|
|
711
|
-
throw new Error(`invalid data[${k}]
|
|
767
|
+
if (!checkPk(get(v, pkName))) {
|
|
768
|
+
throw new Error(`invalid data[${k}].${pkName}[${get(v, pkName)}]`)
|
|
712
769
|
}
|
|
713
770
|
return v
|
|
714
771
|
})
|
|
@@ -719,6 +776,9 @@ function WOrmPostgresql(opt = {}) {
|
|
|
719
776
|
//rest
|
|
720
777
|
let rest = null
|
|
721
778
|
|
|
779
|
+
//pkv
|
|
780
|
+
let pkv = get(v, pkName)
|
|
781
|
+
|
|
722
782
|
//_v
|
|
723
783
|
let _v = null
|
|
724
784
|
if (true) {
|
|
@@ -728,7 +788,7 @@ function WOrmPostgresql(opt = {}) {
|
|
|
728
788
|
type: 'select',
|
|
729
789
|
table: cl,
|
|
730
790
|
where: {
|
|
731
|
-
|
|
791
|
+
[pkName]: pkv,
|
|
732
792
|
},
|
|
733
793
|
// limit: 10,
|
|
734
794
|
// order,
|
|
@@ -757,19 +817,25 @@ function WOrmPostgresql(opt = {}) {
|
|
|
757
817
|
if (iseobj(_v)) {
|
|
758
818
|
|
|
759
819
|
//_vt
|
|
760
|
-
let _vt = omit(_v,
|
|
820
|
+
let _vt = omit(_v, pkName)
|
|
761
821
|
// console.log('_vt', _vt)
|
|
762
822
|
|
|
763
|
-
//vt
|
|
764
|
-
|
|
823
|
+
//vt, [內容相同]之判定基準為[待寫入物件合併進現值後與現值相同],
|
|
824
|
+
//非[待寫入物件與現值全等], 故只給部份欄位且該些欄位值皆與現值相同時視為相同而不寫入,
|
|
825
|
+
//合併採淺層覆蓋, 與後端以EXCLUDED整欄取代之寫入行為一致
|
|
826
|
+
let vt = {
|
|
827
|
+
..._vt,
|
|
828
|
+
...omit(v, pkName),
|
|
829
|
+
}
|
|
765
830
|
// console.log('vt', vt)
|
|
766
831
|
|
|
767
|
-
if (isEqual(
|
|
832
|
+
if (isEqual(vt, _vt)) {
|
|
768
833
|
//相同時不更新
|
|
769
834
|
|
|
770
835
|
//rest
|
|
771
836
|
rest = {
|
|
772
837
|
n: 1,
|
|
838
|
+
nInserted: 0,
|
|
773
839
|
nModified: 0,
|
|
774
840
|
ok: 1,
|
|
775
841
|
}
|
|
@@ -788,6 +854,7 @@ function WOrmPostgresql(opt = {}) {
|
|
|
788
854
|
//rest
|
|
789
855
|
rest = {
|
|
790
856
|
n: 0,
|
|
857
|
+
nInserted: 0,
|
|
791
858
|
nModified: 0,
|
|
792
859
|
ok: 1,
|
|
793
860
|
}
|
|
@@ -813,11 +880,11 @@ function WOrmPostgresql(opt = {}) {
|
|
|
813
880
|
// console.log('mr.query', mr.query)
|
|
814
881
|
// console.log('mr.values', mr.values)
|
|
815
882
|
|
|
816
|
-
//添加conflict,
|
|
817
|
-
//此時退回DO NOTHING,
|
|
883
|
+
//添加conflict, 僅有主鍵欄位時genConflictSQL無可更新欄位而回傳空字串,
|
|
884
|
+
//此時退回DO NOTHING, 以免併發插入同一主鍵者報錯
|
|
818
885
|
let conflict = genConflictSQL(v)
|
|
819
886
|
if (!isestr(conflict)) {
|
|
820
|
-
conflict =
|
|
887
|
+
conflict = `ON CONFLICT (${pkName}) DO NOTHING`
|
|
821
888
|
}
|
|
822
889
|
|
|
823
890
|
//sql, xmax為0表該列由本語句插入, 非0表係由DO UPDATE更新而來,
|
|
@@ -838,18 +905,20 @@ function WOrmPostgresql(opt = {}) {
|
|
|
838
905
|
//rest
|
|
839
906
|
rest = {
|
|
840
907
|
n: 1,
|
|
908
|
+
nInserted: 0,
|
|
841
909
|
nModified: 0,
|
|
842
910
|
ok: 1,
|
|
843
911
|
}
|
|
844
912
|
|
|
845
913
|
}
|
|
846
914
|
else if (get(rows, '0.inserted') === true) {
|
|
847
|
-
|
|
915
|
+
//原不存在而插入
|
|
848
916
|
|
|
849
917
|
//rest
|
|
850
918
|
rest = {
|
|
851
919
|
n: 1,
|
|
852
920
|
nInserted: 1,
|
|
921
|
+
nModified: 0,
|
|
853
922
|
ok: 1,
|
|
854
923
|
}
|
|
855
924
|
// console.log('之前不存在且可自動插入', rest, v)
|
|
@@ -861,6 +930,7 @@ function WOrmPostgresql(opt = {}) {
|
|
|
861
930
|
//rest
|
|
862
931
|
rest = {
|
|
863
932
|
n: 1,
|
|
933
|
+
nInserted: 0,
|
|
864
934
|
nModified: 1,
|
|
865
935
|
ok: 1,
|
|
866
936
|
}
|
|
@@ -875,6 +945,7 @@ function WOrmPostgresql(opt = {}) {
|
|
|
875
945
|
rest = {
|
|
876
946
|
n: 1,
|
|
877
947
|
nInserted: 0,
|
|
948
|
+
nModified: 0,
|
|
878
949
|
ok: 0,
|
|
879
950
|
err: err.message,
|
|
880
951
|
}
|
|
@@ -884,15 +955,15 @@ function WOrmPostgresql(opt = {}) {
|
|
|
884
955
|
}
|
|
885
956
|
else {
|
|
886
957
|
//未開啟autoInsert則僅能更新既有數據, 不可用INSERT以免無中生有,
|
|
887
|
-
//由UPDATE...WHERE
|
|
958
|
+
//由UPDATE...WHERE主鍵原子完成[查找主鍵]與[更新], 併發時不會遺失更新
|
|
888
959
|
|
|
889
960
|
//mr
|
|
890
961
|
let mr = mongoSql.sql({
|
|
891
962
|
type: 'update',
|
|
892
963
|
table: cl,
|
|
893
|
-
updates: omit(v,
|
|
964
|
+
updates: omit(v, pkName),
|
|
894
965
|
where: {
|
|
895
|
-
|
|
966
|
+
[pkName]: pkv,
|
|
896
967
|
},
|
|
897
968
|
})
|
|
898
969
|
// console.log('mr', mr)
|
|
@@ -910,6 +981,7 @@ function WOrmPostgresql(opt = {}) {
|
|
|
910
981
|
//rest
|
|
911
982
|
rest = {
|
|
912
983
|
n: 1,
|
|
984
|
+
nInserted: 0,
|
|
913
985
|
nModified: 1,
|
|
914
986
|
ok: 1,
|
|
915
987
|
}
|
|
@@ -922,6 +994,7 @@ function WOrmPostgresql(opt = {}) {
|
|
|
922
994
|
//rest
|
|
923
995
|
rest = {
|
|
924
996
|
n: 0,
|
|
997
|
+
nInserted: 0,
|
|
925
998
|
nModified: 0,
|
|
926
999
|
ok: 1,
|
|
927
1000
|
}
|
|
@@ -934,6 +1007,7 @@ function WOrmPostgresql(opt = {}) {
|
|
|
934
1007
|
//rest
|
|
935
1008
|
rest = {
|
|
936
1009
|
n: 1,
|
|
1010
|
+
nInserted: 0,
|
|
937
1011
|
nModified: 0,
|
|
938
1012
|
ok: 0,
|
|
939
1013
|
err: err.message,
|
|
@@ -982,9 +1056,14 @@ function WOrmPostgresql(opt = {}) {
|
|
|
982
1056
|
/**
|
|
983
1057
|
* 刪除數據
|
|
984
1058
|
*
|
|
1059
|
+
* 回傳陣列恆與輸入等長,各筆之n與nDeleted皆為主鍵命中筆數,值為0或1,未命中為0且屬正常結果。
|
|
1060
|
+
* 判斷某筆是否真的被刪除一律以nDeleted為準。
|
|
1061
|
+
* 未帶有效主鍵值者為該筆之輸入問題,回ok:0與err且不送查詢,不中斷其餘筆數,
|
|
1062
|
+
* 以此與[主鍵未命中]之ok:1區辨。
|
|
1063
|
+
*
|
|
985
1064
|
* @memberOf WOrmPostgresql
|
|
986
1065
|
* @param {Object|Array} data 輸入數據物件或陣列
|
|
987
|
-
* @returns {Promise} 回傳Promise,resolve
|
|
1066
|
+
* @returns {Promise} 回傳Promise,resolve回傳刪除結果陣列[{n,nDeleted,ok}],reject回傳錯誤訊息
|
|
988
1067
|
*/
|
|
989
1068
|
async function del(data) {
|
|
990
1069
|
let isErr = false
|
|
@@ -1030,39 +1109,49 @@ function WOrmPostgresql(opt = {}) {
|
|
|
1030
1109
|
data = [data]
|
|
1031
1110
|
}
|
|
1032
1111
|
|
|
1033
|
-
//check time
|
|
1034
|
-
data = map(data, function(v, k) {
|
|
1035
|
-
if (!isDate(v.time)) {
|
|
1036
|
-
throw new Error(`invalid data[${k}].time[${v.time}]`)
|
|
1037
|
-
}
|
|
1038
|
-
return v
|
|
1039
|
-
})
|
|
1040
|
-
|
|
1041
1112
|
//pmSeries
|
|
1042
1113
|
res = await pmSeries(data, async(v) => {
|
|
1043
1114
|
|
|
1044
1115
|
//rest
|
|
1045
1116
|
let rest = null
|
|
1046
1117
|
|
|
1118
|
+
//pkv
|
|
1119
|
+
let pkv = get(v, pkName)
|
|
1120
|
+
|
|
1121
|
+
//check pk, 未帶有效主鍵者不補值亦不送查詢,
|
|
1122
|
+
//因mongo-sql會將無效值轉為null而誤中其他數據, 故直接視為該筆無法處理
|
|
1123
|
+
if (!checkPk(pkv)) {
|
|
1124
|
+
|
|
1125
|
+
//rest
|
|
1126
|
+
rest = {
|
|
1127
|
+
n: 0,
|
|
1128
|
+
nDeleted: 0,
|
|
1129
|
+
ok: 0,
|
|
1130
|
+
err: `invalid ${pkName}[${pkv}]`,
|
|
1131
|
+
}
|
|
1132
|
+
|
|
1133
|
+
return rest
|
|
1134
|
+
}
|
|
1135
|
+
|
|
1047
1136
|
//mr
|
|
1048
1137
|
let mr = mongoSql.sql({
|
|
1049
1138
|
type: 'delete',
|
|
1050
1139
|
table: cl,
|
|
1051
1140
|
where: {
|
|
1052
|
-
|
|
1141
|
+
[pkName]: pkv,
|
|
1053
1142
|
},
|
|
1054
1143
|
})
|
|
1055
1144
|
// console.log('mr', mr)
|
|
1056
1145
|
// console.log('mr.query', mr.query)
|
|
1057
1146
|
// console.log('mr.values', mr.values)
|
|
1058
1147
|
|
|
1059
|
-
//del
|
|
1148
|
+
//del, n與nDeleted皆為主鍵命中筆數, 未命中為0
|
|
1060
1149
|
await client.query(mr.query, mr.values)
|
|
1061
1150
|
.then((r) => {
|
|
1062
1151
|
|
|
1063
1152
|
//res
|
|
1064
1153
|
rest = {
|
|
1065
|
-
n:
|
|
1154
|
+
n: r.rowCount,
|
|
1066
1155
|
nDeleted: r.rowCount,
|
|
1067
1156
|
ok: 1,
|
|
1068
1157
|
}
|
|
@@ -1119,9 +1208,12 @@ function WOrmPostgresql(opt = {}) {
|
|
|
1119
1208
|
/**
|
|
1120
1209
|
* 刪除全部數據,需與del分開,避免未傳數據導致直接刪除全表
|
|
1121
1210
|
*
|
|
1211
|
+
* n與nDeleted皆為實際刪除筆數,不取全表筆數。find未給或為空物件時刪除全部數據,
|
|
1212
|
+
* 條件無命中時回{n:0,nDeleted:0,ok:1},不視為錯誤。
|
|
1213
|
+
*
|
|
1122
1214
|
* @memberOf WOrmPostgresql
|
|
1123
1215
|
* @param {Object} [find={}] 輸入刪除條件物件
|
|
1124
|
-
* @returns {Promise} 回傳Promise,resolve
|
|
1216
|
+
* @returns {Promise} 回傳Promise,resolve回傳刪除結果物件{n,nDeleted,ok},reject回傳錯誤訊息
|
|
1125
1217
|
*/
|
|
1126
1218
|
async function delAll(find = {}) {
|
|
1127
1219
|
let isErr = false
|
|
@@ -1227,7 +1319,7 @@ function WOrmPostgresql(opt = {}) {
|
|
|
1227
1319
|
//save
|
|
1228
1320
|
ee.createTable = createTable
|
|
1229
1321
|
ee.select = select
|
|
1230
|
-
ee.
|
|
1322
|
+
ee.selectByPk = selectByPk
|
|
1231
1323
|
ee.insert = insert
|
|
1232
1324
|
ee.save = save
|
|
1233
1325
|
ee.del = del
|
|
@@ -1252,7 +1344,7 @@ export default WOrmPostgresql
|
|
|
1252
1344
|
<br class="clear">
|
|
1253
1345
|
|
|
1254
1346
|
<footer>
|
|
1255
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Sun Aug 16 2026
|
|
1347
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Sun Aug 16 2026 23:54:17 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
1256
1348
|
</footer>
|
|
1257
1349
|
|
|
1258
1350
|
<script>prettyPrint();</script>
|
package/docs/index.html
CHANGED
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
<nav >
|
|
30
30
|
|
|
31
31
|
|
|
32
|
-
<h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="WOrmPostgresql.html">WOrmPostgresql</a><ul class='methods'><li data-type='method'><a href="WOrmPostgresql.html#.createTable">createTable</a></li><li data-type='method'><a href="WOrmPostgresql.html#.del">del</a></li><li data-type='method'><a href="WOrmPostgresql.html#.delAll">delAll</a></li><li data-type='method'><a href="WOrmPostgresql.html#.insert">insert</a></li><li data-type='method'><a href="WOrmPostgresql.html#.save">save</a></li><li data-type='method'><a href="WOrmPostgresql.html#.select">select</a></li><li data-type='method'><a href="WOrmPostgresql.html#.
|
|
32
|
+
<h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="WOrmPostgresql.html">WOrmPostgresql</a><ul class='methods'><li data-type='method'><a href="WOrmPostgresql.html#.createTable">createTable</a></li><li data-type='method'><a href="WOrmPostgresql.html#.del">del</a></li><li data-type='method'><a href="WOrmPostgresql.html#.delAll">delAll</a></li><li data-type='method'><a href="WOrmPostgresql.html#.insert">insert</a></li><li data-type='method'><a href="WOrmPostgresql.html#.save">save</a></li><li data-type='method'><a href="WOrmPostgresql.html#.select">select</a></li><li data-type='method'><a href="WOrmPostgresql.html#.selectByPk">selectByPk</a></li></ul></li></ul>
|
|
33
33
|
|
|
34
34
|
</nav>
|
|
35
35
|
|
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
<br class="clear">
|
|
72
72
|
|
|
73
73
|
<footer>
|
|
74
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Sun Aug 16 2026
|
|
74
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Sun Aug 16 2026 23:54:17 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
75
75
|
</footer>
|
|
76
76
|
|
|
77
77
|
<script>prettyPrint();</script>
|
package/g-basic.mjs
CHANGED
|
@@ -168,13 +168,13 @@ async function test() {
|
|
|
168
168
|
let so = await wo.select({ name: 'rosemary' })
|
|
169
169
|
console.log('select by name', so)
|
|
170
170
|
|
|
171
|
-
//
|
|
172
|
-
let sb = await wo.
|
|
173
|
-
console.log('
|
|
171
|
+
//selectByPk
|
|
172
|
+
let sb = await wo.selectByPk('2025-01-01T00:10:00Z')
|
|
173
|
+
console.log('selectByPk', sb)
|
|
174
174
|
|
|
175
|
-
//
|
|
176
|
-
let sbn = await wo.
|
|
177
|
-
console.log('
|
|
175
|
+
//selectByPk by pk not existed
|
|
176
|
+
let sbn = await wo.selectByPk('2024-01-01T00:00:00Z')
|
|
177
|
+
console.log('selectByPk by pk not existed', sbn)
|
|
178
178
|
|
|
179
179
|
//select by $and, $gt, $lt
|
|
180
180
|
let spa = await wo.select({ '$and': [{ value: { '$gt': 123 } }, { value: { '$lt': 200 } }] })
|
|
@@ -300,11 +300,11 @@ test()
|
|
|
300
300
|
// insert then { n: 13, nInserted: 13, ok: 1 }
|
|
301
301
|
// change save
|
|
302
302
|
// save then [
|
|
303
|
-
// { n: 1, nModified: 0, ok: 1 },
|
|
304
|
-
// { n: 1, nModified: 1, ok: 1 },
|
|
305
|
-
// { n: 1, nModified: 1, ok: 1 },
|
|
306
|
-
// { n: 1, nModified: 1, ok: 1 },
|
|
307
|
-
// { n: 0, nModified: 0, ok: 1 }
|
|
303
|
+
// { n: 1, nInserted: 0, nModified: 0, ok: 1 },
|
|
304
|
+
// { n: 1, nInserted: 0, nModified: 1, ok: 1 },
|
|
305
|
+
// { n: 1, nInserted: 0, nModified: 1, ok: 1 },
|
|
306
|
+
// { n: 1, nInserted: 0, nModified: 1, ok: 1 },
|
|
307
|
+
// { n: 0, nInserted: 0, nModified: 0, ok: 1 }
|
|
308
308
|
// ]
|
|
309
309
|
// select all [
|
|
310
310
|
// { time: 2025-01-01T00:00:00.000Z, name: 'peter', value: 123 },
|
|
@@ -334,12 +334,12 @@ test()
|
|
|
334
334
|
// { time: 2025-01-01T00:04:00.000Z, name: 'rosemary', value: 123.1236 },
|
|
335
335
|
// { time: 2025-01-01T00:07:00.000Z, name: 'rosemary', value: 124.76 }
|
|
336
336
|
// ]
|
|
337
|
-
//
|
|
337
|
+
// selectByPk {
|
|
338
338
|
// time: 2025-01-01T00:10:00.000Z,
|
|
339
339
|
// name: 'rosemary(modify)',
|
|
340
340
|
// value: 113.98
|
|
341
341
|
// }
|
|
342
|
-
//
|
|
342
|
+
// selectByPk by pk not existed null
|
|
343
343
|
// select by $and, $gt, $lt [
|
|
344
344
|
// { time: 2025-01-01T00:01:00.000Z, name: 'rosemary', value: 123.456 },
|
|
345
345
|
// { time: 2025-01-01T00:04:00.000Z, name: 'rosemary', value: 123.1236 },
|
|
@@ -370,9 +370,9 @@ test()
|
|
|
370
370
|
// }
|
|
371
371
|
// ]
|
|
372
372
|
// change save
|
|
373
|
-
// save then [ { n: 1, nInserted: 1, ok: 1 } ]
|
|
373
|
+
// save then [ { n: 1, nInserted: 1, nModified: 0, ok: 1 } ]
|
|
374
374
|
// change del
|
|
375
|
-
// del then [ { n:
|
|
375
|
+
// del then [ { n: 0, nDeleted: 0, ok: 1 } ]
|
|
376
376
|
// change del
|
|
377
377
|
// del then [
|
|
378
378
|
// { n: 1, nDeleted: 1, ok: 1 },
|
|
@@ -407,7 +407,7 @@ test()
|
|
|
407
407
|
// { time: 2025-01-01T00:01:00.000Z, name: 'rosemary', value: 123.456 },
|
|
408
408
|
// { time: 2025-01-01T00:02:00.000Z, name: 'kettle', value: 456 }
|
|
409
409
|
// ]
|
|
410
|
-
// save (invalidate cache) then [ { n: 1, nModified: 1, ok: 1 } ]
|
|
410
|
+
// save (invalidate cache) then [ { n: 1, nInserted: 0, nModified: 1, ok: 1 } ]
|
|
411
411
|
// select all 3rd (reload after save) [
|
|
412
412
|
// { time: 2025-01-01T00:00:00.000Z, name: 'peter', value: 123 },
|
|
413
413
|
// {
|