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.
@@ -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#.selectByTime">selectByTime</a></li></ul></li></ul>
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 = ['time']
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
- * 由主鍵time查詢單筆數據,因直接由資料表主鍵索引取值,不需如select提取數據至前端再處理,故數據量大時效能較佳
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} time 輸入主鍵time值,本套件以time欄位為主鍵
422
- * @returns {Promise} 回傳Promise,resolve回傳數據物件,若無此time則回傳null,reject回傳錯誤訊息
458
+ * @param {String|Number|Date} pk 輸入主鍵值,即數據之主鍵欄位值
459
+ * @returns {Promise} 回傳Promise,resolve回傳數據物件,若無此主鍵則回傳null,reject回傳錯誤訊息
423
460
  */
424
- async function selectByTime(time) {
461
+ async function selectByPk(pk) {
425
462
  let isErr = false
426
463
  let res = null
427
464
 
428
465
  //check
429
- if (!isDate(time)) {
430
- //未給有效主鍵值視為查無數據, 判定基準與insert、save、del內對time之認定一致
466
+ if (!checkPk(pk)) {
467
+ //未給有效主鍵值視為查無數據, 判定基準與insert、save、del內對主鍵之認定一致
431
468
  return null
432
469
  }
433
470
 
434
- //find, 本套件以time欄位為主鍵, 與save、del、genConflictSQL之認定一致
471
+ //find, 以建構時設定之主鍵欄位查找,insert、save、del、genConflictSQL之認定一致
435
472
  let find = {
436
- time,
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 time[${time}]`)
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
- //不存在time, 回傳null
543
+ //不存在主鍵, 回傳null
507
544
  res = null
508
545
  }
509
546
 
510
547
  }
511
548
  catch (err) {
512
- isErr = true
513
- res = err
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回傳插入結果,reject回傳錯誤訊息
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 time
629
+ //check pk, 因主鍵得承載業務語義故不自動補值, 未帶有效主鍵值者屬整批性錯誤
581
630
  data = map(data, function(v, k) {
582
- if (!isDate(v.time)) {
583
- throw new Error(`invalid data[${k}].time[${v.time}]`)
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, 令已存在time者跳過而不中斷整批插入, 主鍵認定與genConflictSQL一致
599
- //由PostgreSQL於單一語句內原子完成[檢查time未存在]與[寫入], 併發時同一time僅有一次成功,
600
- //同批含重複time時亦僅首筆成功, 故不須逐筆插入即可取得實際插入筆數
601
- let sql = `${mr.query} ON CONFLICT (time) DO NOTHING`
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回傳儲存結果,reject回傳錯誤訊息
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 time
765
+ //check pk, 因主鍵得承載業務語義故不自動補值, 未帶有效主鍵值者屬整批性錯誤
709
766
  data = map(data, function(v, k) {
710
- if (!isDate(v.time)) {
711
- throw new Error(`invalid data[${k}].time[${v.time}]`)
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
- time: v.time,
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, 'time')
820
+ let _vt = omit(_v, pkName)
761
821
  // console.log('_vt', _vt)
762
822
 
763
- //vt
764
- let vt = omit(v, 'time')
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(_vt, vt)) {
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, 僅有time欄位時genConflictSQL無可更新欄位而回傳空字串,
817
- //此時退回DO NOTHING, 以免併發插入同一time者報錯
883
+ //添加conflict, 僅有主鍵欄位時genConflictSQL無可更新欄位而回傳空字串,
884
+ //此時退回DO NOTHING, 以免併發插入同一主鍵者報錯
818
885
  let conflict = genConflictSQL(v)
819
886
  if (!isestr(conflict)) {
820
- conflict = 'ON CONFLICT (time) DO NOTHING'
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
- //原不存在而插入, 回傳形狀同insert
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 time原子完成[查找time]與[更新], 併發時不會遺失更新
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, 'time'),
964
+ updates: omit(v, pkName),
894
965
  where: {
895
- time: v.time,
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回傳刪除結果,reject回傳錯誤訊息
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
- time: v.time,
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: 1,
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回傳刪除結果,reject回傳錯誤訊息
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.selectByTime = selectByTime
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 17:59:38 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
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#.selectByTime">selectByTime</a></li></ul></li></ul>
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 17:59:38 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
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
- //selectByTime
172
- let sb = await wo.selectByTime('2025-01-01T00:10:00Z')
173
- console.log('selectByTime', sb)
171
+ //selectByPk
172
+ let sb = await wo.selectByPk('2025-01-01T00:10:00Z')
173
+ console.log('selectByPk', sb)
174
174
 
175
- //selectByTime by time not existed
176
- let sbn = await wo.selectByTime('2024-01-01T00:00:00Z')
177
- console.log('selectByTime by time not existed', sbn)
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
- // selectByTime {
337
+ // selectByPk {
338
338
  // time: 2025-01-01T00:10:00.000Z,
339
339
  // name: 'rosemary(modify)',
340
340
  // value: 113.98
341
341
  // }
342
- // selectByTime by time not existed null
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: 1, nDeleted: 0, ok: 1 } ]
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
  // {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "w-orm-postgresql",
3
- "version": "1.0.8",
3
+ "version": "1.0.10",
4
4
  "main": "dist/w-orm-postgresql.umd.js",
5
5
  "dependencies": {
6
6
  "mongo-sql": "^6.2.0",