w-orm-postgresql 1.0.9 → 1.0.11
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 +9 -8
- package/dist/w-orm-postgresql.umd.js +2 -2
- package/dist/w-orm-postgresql.umd.js.map +1 -1
- package/docs/WOrmPostgresql.html +119 -27
- package/docs/WOrmPostgresql.mjs.html +208 -77
- package/docs/index.html +2 -2
- package/g-basic.mjs +9 -8
- package/package.json +1 -1
- package/src/WOrmPostgresql.mjs +205 -74
- package/test/api-postgresql.test.mjs +408 -36
|
@@ -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
|
|
|
@@ -45,8 +45,7 @@
|
|
|
45
45
|
|
|
46
46
|
<section>
|
|
47
47
|
<article>
|
|
48
|
-
<pre class="prettyprint source linenums"><code>import
|
|
49
|
-
import pg from 'pg'
|
|
48
|
+
<pre class="prettyprint source linenums"><code>import pg from 'pg'
|
|
50
49
|
import mongoSql from 'mongo-sql'
|
|
51
50
|
import size from 'lodash-es/size.js'
|
|
52
51
|
import get from 'lodash-es/get.js'
|
|
@@ -67,17 +66,23 @@ import isint from 'wsemi/src/isint.mjs'
|
|
|
67
66
|
import isbol from 'wsemi/src/isbol.mjs'
|
|
68
67
|
import isDate from 'wsemi/src/isDate.mjs'
|
|
69
68
|
import haskey from 'wsemi/src/haskey.mjs'
|
|
69
|
+
import evem from 'wsemi/src/evem.mjs'
|
|
70
70
|
import pmSeries from 'wsemi/src/pmSeries.mjs'
|
|
71
71
|
|
|
72
72
|
|
|
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) => {
|
|
@@ -195,8 +220,40 @@ function WOrmPostgresql(opt = {}) {
|
|
|
195
220
|
let connectionString = `${url}/${db}`
|
|
196
221
|
// console.log('connectionString', connectionString)
|
|
197
222
|
|
|
198
|
-
//ee
|
|
199
|
-
|
|
223
|
+
//ee, 採eventemitter3而不採Node內建之events.EventEmitter,
|
|
224
|
+
//因後者於'error'無監聽者時會將錯誤直接拋出, 將使操作行為隨呼叫端是否註冊監聽而異
|
|
225
|
+
let ee = evem()
|
|
226
|
+
|
|
227
|
+
//getErrMsg, 取錯誤訊息字串, 供逐筆結果之err欄位與error事件使用
|
|
228
|
+
let getErrMsg = (err) => {
|
|
229
|
+
let m = get(err, 'message')
|
|
230
|
+
if (isestr(m)) {
|
|
231
|
+
return m
|
|
232
|
+
}
|
|
233
|
+
return String(err)
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
//emitChange, 資料實際異動成功後發出, 事件僅為附加通知不承擔回傳義務
|
|
237
|
+
//訂閱函數拋錯不得影響本次操作, 故一律以try/catch包覆, 收斂於此以免逐處遺漏
|
|
238
|
+
let emitChange = (mode, data, res) => {
|
|
239
|
+
try {
|
|
240
|
+
ee.emit('change', mode, data, res)
|
|
241
|
+
}
|
|
242
|
+
catch (errEmit) {
|
|
243
|
+
console.log(errEmit)
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
//emitError, 操作發生錯誤時發出, 錯誤訊息一律轉為字串
|
|
248
|
+
//正常結果(如查無數據、主鍵未命中、內容相同而未寫入)不得發出, 以免監聽者將常態當異常
|
|
249
|
+
let emitError = (mode, data, err) => {
|
|
250
|
+
try {
|
|
251
|
+
ee.emit('error', mode, data, getErrMsg(err))
|
|
252
|
+
}
|
|
253
|
+
catch (errEmit) {
|
|
254
|
+
console.log(errEmit)
|
|
255
|
+
}
|
|
256
|
+
}
|
|
200
257
|
|
|
201
258
|
//PgClient
|
|
202
259
|
let PgClient = pg.Client
|
|
@@ -237,14 +294,22 @@ function WOrmPostgresql(opt = {}) {
|
|
|
237
294
|
|
|
238
295
|
/**
|
|
239
296
|
* 創建資料表
|
|
297
|
+
* 註: pk未給時採建構時之opt.pk。因insert與save倚賴主鍵之唯一約束達成原子性,
|
|
298
|
+
* 若給予與opt.pk不同之欄位,將建出其餘函數無法正確操作之資料表,故一般應留空或給予相同值
|
|
240
299
|
*
|
|
241
300
|
* @memberOf WOrmPostgresql
|
|
242
301
|
* @param {String} cl 輸入資料表名字串
|
|
243
|
-
* @param {String} pk
|
|
302
|
+
* @param {String} [pk=opt.pk] 輸入主鍵欄位名字串,預設為建構時之opt.pk
|
|
244
303
|
* @param {Array|Object} arr 輸入數據物件陣列或數據物件
|
|
245
304
|
* @returns {Promise} 回傳Promise,resolve回傳成功訊息,reject回傳錯誤訊息
|
|
246
305
|
*/
|
|
247
306
|
async function createTable(cl, pk, arr) {
|
|
307
|
+
|
|
308
|
+
//pk, 未給時採建構時設定之主鍵欄位
|
|
309
|
+
if (!isestr(pk)) {
|
|
310
|
+
pk = pkName
|
|
311
|
+
}
|
|
312
|
+
|
|
248
313
|
let isErr = false
|
|
249
314
|
let res = null
|
|
250
315
|
|
|
@@ -266,6 +331,10 @@ function WOrmPostgresql(opt = {}) {
|
|
|
266
331
|
|
|
267
332
|
//check
|
|
268
333
|
if (isErr) {
|
|
334
|
+
|
|
335
|
+
//emit, 整批性錯誤於reject之前發出
|
|
336
|
+
emitError('createTable', arr, res)
|
|
337
|
+
|
|
269
338
|
return Promise.reject(res)
|
|
270
339
|
}
|
|
271
340
|
|
|
@@ -316,6 +385,10 @@ function WOrmPostgresql(opt = {}) {
|
|
|
316
385
|
|
|
317
386
|
//check
|
|
318
387
|
if (isErr) {
|
|
388
|
+
|
|
389
|
+
//emit, 整批性錯誤於reject之前發出
|
|
390
|
+
emitError('createTable', arr, res)
|
|
391
|
+
|
|
319
392
|
return Promise.reject(res)
|
|
320
393
|
}
|
|
321
394
|
|
|
@@ -360,6 +433,10 @@ function WOrmPostgresql(opt = {}) {
|
|
|
360
433
|
|
|
361
434
|
//check
|
|
362
435
|
if (isErr) {
|
|
436
|
+
|
|
437
|
+
//emit, 整批性錯誤於reject之前發出, 讀取函數無輸入數據故data為null
|
|
438
|
+
emitError('select', null, res)
|
|
439
|
+
|
|
363
440
|
return Promise.reject(res)
|
|
364
441
|
}
|
|
365
442
|
|
|
@@ -408,6 +485,10 @@ function WOrmPostgresql(opt = {}) {
|
|
|
408
485
|
|
|
409
486
|
//check
|
|
410
487
|
if (isErr) {
|
|
488
|
+
|
|
489
|
+
//emit, 整批性錯誤於reject之前發出, 讀取函數無輸入數據故data為null
|
|
490
|
+
emitError('select', null, res)
|
|
491
|
+
|
|
411
492
|
return Promise.reject(res)
|
|
412
493
|
}
|
|
413
494
|
|
|
@@ -415,29 +496,29 @@ function WOrmPostgresql(opt = {}) {
|
|
|
415
496
|
}
|
|
416
497
|
|
|
417
498
|
/**
|
|
418
|
-
*
|
|
499
|
+
* 由主鍵查詢單筆數據,因直接由資料表主鍵索引取值,不需如select提取數據至前端再處理,故數據量大時效能較佳
|
|
500
|
+
* 註: 本套件之主鍵欄位由建構時之opt.pk指定,預設為time
|
|
419
501
|
*
|
|
420
|
-
* 函數名依主鍵欄位命名為selectByTime而不另掛selectById別名,因本套件之主鍵為具業務語義之time,
|
|
421
|
-
* 與以無語義識別碼為主鍵者性質不同,該差異須由呼叫端知悉而非由別名掩蓋。
|
|
422
502
|
* 主鍵未命中或主鍵值無效皆回傳null而不reject,命中之判定基準與insert、save、del內對既有數據之認定一致。
|
|
503
|
+
* 主鍵值之型別與欄位不符時PostgreSQL回報22P02或22007,亦屬主鍵值無效而回傳null。
|
|
423
504
|
*
|
|
424
505
|
* @memberOf WOrmPostgresql
|
|
425
|
-
* @param {String|Date}
|
|
426
|
-
* @returns {Promise} 回傳Promise,resolve
|
|
506
|
+
* @param {String|Number|Date} pk 輸入主鍵值,即數據之主鍵欄位值
|
|
507
|
+
* @returns {Promise} 回傳Promise,resolve回傳數據物件,若無此主鍵則回傳null,reject回傳錯誤訊息
|
|
427
508
|
*/
|
|
428
|
-
async function
|
|
509
|
+
async function selectByPk(pk) {
|
|
429
510
|
let isErr = false
|
|
430
511
|
let res = null
|
|
431
512
|
|
|
432
513
|
//check
|
|
433
|
-
if (!
|
|
434
|
-
//未給有效主鍵值視為查無數據, 判定基準與insert、save、del
|
|
514
|
+
if (!checkPk(pk)) {
|
|
515
|
+
//未給有效主鍵值視為查無數據, 判定基準與insert、save、del內對主鍵之認定一致
|
|
435
516
|
return null
|
|
436
517
|
}
|
|
437
518
|
|
|
438
|
-
//find,
|
|
519
|
+
//find, 以建構時設定之主鍵欄位查找, 與insert、save、del、genConflictSQL之認定一致
|
|
439
520
|
let find = {
|
|
440
|
-
|
|
521
|
+
[pkName]: pk,
|
|
441
522
|
}
|
|
442
523
|
|
|
443
524
|
//cache, 與select共用快取, 因快取鍵值由find與order組成, 故此處等同select(find)之結果
|
|
@@ -466,6 +547,10 @@ function WOrmPostgresql(opt = {}) {
|
|
|
466
547
|
|
|
467
548
|
//check
|
|
468
549
|
if (isErr) {
|
|
550
|
+
|
|
551
|
+
//emit, 整批性錯誤於reject之前發出, 讀取函數無輸入數據故data為null
|
|
552
|
+
emitError('selectByPk', null, res)
|
|
553
|
+
|
|
469
554
|
return Promise.reject(res)
|
|
470
555
|
}
|
|
471
556
|
|
|
@@ -491,7 +576,7 @@ function WOrmPostgresql(opt = {}) {
|
|
|
491
576
|
|
|
492
577
|
//check
|
|
493
578
|
if (!isarr(rows)) {
|
|
494
|
-
throw new Error(`can not select by
|
|
579
|
+
throw new Error(`can not select by pk[${pk}]`)
|
|
495
580
|
}
|
|
496
581
|
|
|
497
582
|
//cache
|
|
@@ -507,14 +592,22 @@ function WOrmPostgresql(opt = {}) {
|
|
|
507
592
|
res = v
|
|
508
593
|
}
|
|
509
594
|
else {
|
|
510
|
-
|
|
595
|
+
//不存在主鍵, 回傳null
|
|
511
596
|
res = null
|
|
512
597
|
}
|
|
513
598
|
|
|
514
599
|
}
|
|
515
600
|
catch (err) {
|
|
516
|
-
|
|
517
|
-
|
|
601
|
+
|
|
602
|
+
//check, 主鍵值之型別與欄位不符者亦屬主鍵值無效, 依規格回傳null而不reject
|
|
603
|
+
if (isErrPkType(err)) {
|
|
604
|
+
res = null
|
|
605
|
+
}
|
|
606
|
+
else {
|
|
607
|
+
isErr = true
|
|
608
|
+
res = err
|
|
609
|
+
}
|
|
610
|
+
|
|
518
611
|
}
|
|
519
612
|
finally {
|
|
520
613
|
await client.end()
|
|
@@ -524,6 +617,11 @@ function WOrmPostgresql(opt = {}) {
|
|
|
524
617
|
|
|
525
618
|
//check
|
|
526
619
|
if (isErr) {
|
|
620
|
+
|
|
621
|
+
//emit, 整批性錯誤於reject之前發出, 讀取函數無輸入數據故data為null
|
|
622
|
+
//主鍵未命中與主鍵值無效皆為正常結果而不設isErr, 故不會誤發error
|
|
623
|
+
emitError('selectByPk', null, res)
|
|
624
|
+
|
|
527
625
|
return Promise.reject(res)
|
|
528
626
|
}
|
|
529
627
|
|
|
@@ -531,11 +629,11 @@ function WOrmPostgresql(opt = {}) {
|
|
|
531
629
|
}
|
|
532
630
|
|
|
533
631
|
/**
|
|
534
|
-
*
|
|
632
|
+
* 插入數據,僅於主鍵不存在時寫入,已存在者跳過且不覆寫
|
|
535
633
|
*
|
|
536
634
|
* n為輸入筆數,即本次嘗試插入之基準;nInserted為實際插入筆數,全數已存在而nInserted為0屬正常結果,
|
|
537
|
-
*
|
|
538
|
-
*
|
|
635
|
+
* 不視為錯誤。同批含重複主鍵時僅首筆計入nInserted。
|
|
636
|
+
* 因主鍵得承載業務語義,未帶有效主鍵值時不自動補值,一律以reject回報。
|
|
539
637
|
*
|
|
540
638
|
* @memberOf WOrmPostgresql
|
|
541
639
|
* @param {Object|Array} data 輸入數據物件或陣列
|
|
@@ -575,6 +673,10 @@ function WOrmPostgresql(opt = {}) {
|
|
|
575
673
|
|
|
576
674
|
//check
|
|
577
675
|
if (isErr) {
|
|
676
|
+
|
|
677
|
+
//emit, 整批性錯誤於reject之前發出
|
|
678
|
+
emitError('insert', data, res)
|
|
679
|
+
|
|
578
680
|
return Promise.reject(res)
|
|
579
681
|
}
|
|
580
682
|
|
|
@@ -585,10 +687,10 @@ function WOrmPostgresql(opt = {}) {
|
|
|
585
687
|
data = [data]
|
|
586
688
|
}
|
|
587
689
|
|
|
588
|
-
//check
|
|
690
|
+
//check pk, 因主鍵得承載業務語義故不自動補值, 未帶有效主鍵值者屬整批性錯誤
|
|
589
691
|
data = map(data, function(v, k) {
|
|
590
|
-
if (!
|
|
591
|
-
throw new Error(`invalid data[${k}]
|
|
692
|
+
if (!checkPk(get(v, pkName))) {
|
|
693
|
+
throw new Error(`invalid data[${k}].${pkName}[${get(v, pkName)}]`)
|
|
592
694
|
}
|
|
593
695
|
return v
|
|
594
696
|
})
|
|
@@ -603,10 +705,10 @@ function WOrmPostgresql(opt = {}) {
|
|
|
603
705
|
// console.log('mr.query', mr.query)
|
|
604
706
|
// console.log('mr.values', mr.values)
|
|
605
707
|
|
|
606
|
-
//添加conflict,
|
|
607
|
-
//由PostgreSQL於單一語句內原子完成[
|
|
608
|
-
|
|
609
|
-
let sql = `${mr.query} ON CONFLICT (
|
|
708
|
+
//添加conflict, 令已存在主鍵者跳過而不中斷整批插入, 主鍵認定與genConflictSQL一致
|
|
709
|
+
//由PostgreSQL於單一語句內原子完成[檢查主鍵未存在]與[寫入], 併發時同一主鍵僅有一次成功,
|
|
710
|
+
//同批含重複主鍵時亦僅首筆成功, 故不須逐筆插入即可取得實際插入筆數
|
|
711
|
+
let sql = `${mr.query} ON CONFLICT (${pkName}) DO NOTHING`
|
|
610
712
|
|
|
611
713
|
//nAll
|
|
612
714
|
let nAll = size(data)
|
|
@@ -645,16 +747,15 @@ function WOrmPostgresql(opt = {}) {
|
|
|
645
747
|
|
|
646
748
|
//emit
|
|
647
749
|
if (!isErr) {
|
|
648
|
-
|
|
649
|
-
ee.emit('change', 'insert', data, res)
|
|
650
|
-
}
|
|
651
|
-
catch (err) {
|
|
652
|
-
console.log(err)
|
|
653
|
-
}
|
|
750
|
+
emitChange('insert', data, res)
|
|
654
751
|
}
|
|
655
752
|
|
|
656
753
|
//check
|
|
657
754
|
if (isErr) {
|
|
755
|
+
|
|
756
|
+
//emit, 整批性錯誤於reject之前發出
|
|
757
|
+
emitError('insert', data, res)
|
|
758
|
+
|
|
658
759
|
return Promise.reject(res)
|
|
659
760
|
}
|
|
660
761
|
|
|
@@ -670,7 +771,7 @@ function WOrmPostgresql(opt = {}) {
|
|
|
670
771
|
* [內容相同]之判定基準為待寫入物件合併進現值後與現值相同,非待寫入物件與現值全等,
|
|
671
772
|
* 故只給部份欄位且該些欄位值皆與現值相同時,合併結果等於現值,nModified為0,
|
|
672
773
|
* 令nModified忠實反映資料庫端是否真的寫入。
|
|
673
|
-
*
|
|
774
|
+
* 因主鍵得承載業務語義,未帶有效主鍵值時不自動補值,一律以reject回報。
|
|
674
775
|
*
|
|
675
776
|
* @memberOf WOrmPostgresql
|
|
676
777
|
* @param {Object|Array} data 輸入數據物件或陣列
|
|
@@ -711,6 +812,10 @@ function WOrmPostgresql(opt = {}) {
|
|
|
711
812
|
|
|
712
813
|
//check
|
|
713
814
|
if (isErr) {
|
|
815
|
+
|
|
816
|
+
//emit, 整批性錯誤於reject之前發出
|
|
817
|
+
emitError('save', data, res)
|
|
818
|
+
|
|
714
819
|
return Promise.reject(res)
|
|
715
820
|
}
|
|
716
821
|
|
|
@@ -721,10 +826,10 @@ function WOrmPostgresql(opt = {}) {
|
|
|
721
826
|
data = [data]
|
|
722
827
|
}
|
|
723
828
|
|
|
724
|
-
//check
|
|
829
|
+
//check pk, 因主鍵得承載業務語義故不自動補值, 未帶有效主鍵值者屬整批性錯誤
|
|
725
830
|
data = map(data, function(v, k) {
|
|
726
|
-
if (!
|
|
727
|
-
throw new Error(`invalid data[${k}]
|
|
831
|
+
if (!checkPk(get(v, pkName))) {
|
|
832
|
+
throw new Error(`invalid data[${k}].${pkName}[${get(v, pkName)}]`)
|
|
728
833
|
}
|
|
729
834
|
return v
|
|
730
835
|
})
|
|
@@ -735,6 +840,9 @@ function WOrmPostgresql(opt = {}) {
|
|
|
735
840
|
//rest
|
|
736
841
|
let rest = null
|
|
737
842
|
|
|
843
|
+
//pkv
|
|
844
|
+
let pkv = get(v, pkName)
|
|
845
|
+
|
|
738
846
|
//_v
|
|
739
847
|
let _v = null
|
|
740
848
|
if (true) {
|
|
@@ -744,7 +852,7 @@ function WOrmPostgresql(opt = {}) {
|
|
|
744
852
|
type: 'select',
|
|
745
853
|
table: cl,
|
|
746
854
|
where: {
|
|
747
|
-
|
|
855
|
+
[pkName]: pkv,
|
|
748
856
|
},
|
|
749
857
|
// limit: 10,
|
|
750
858
|
// order,
|
|
@@ -773,7 +881,7 @@ function WOrmPostgresql(opt = {}) {
|
|
|
773
881
|
if (iseobj(_v)) {
|
|
774
882
|
|
|
775
883
|
//_vt
|
|
776
|
-
let _vt = omit(_v,
|
|
884
|
+
let _vt = omit(_v, pkName)
|
|
777
885
|
// console.log('_vt', _vt)
|
|
778
886
|
|
|
779
887
|
//vt, [內容相同]之判定基準為[待寫入物件合併進現值後與現值相同],
|
|
@@ -781,7 +889,7 @@ function WOrmPostgresql(opt = {}) {
|
|
|
781
889
|
//合併採淺層覆蓋, 與後端以EXCLUDED整欄取代之寫入行為一致
|
|
782
890
|
let vt = {
|
|
783
891
|
..._vt,
|
|
784
|
-
...omit(v,
|
|
892
|
+
...omit(v, pkName),
|
|
785
893
|
}
|
|
786
894
|
// console.log('vt', vt)
|
|
787
895
|
|
|
@@ -836,11 +944,11 @@ function WOrmPostgresql(opt = {}) {
|
|
|
836
944
|
// console.log('mr.query', mr.query)
|
|
837
945
|
// console.log('mr.values', mr.values)
|
|
838
946
|
|
|
839
|
-
//添加conflict,
|
|
840
|
-
//此時退回DO NOTHING,
|
|
947
|
+
//添加conflict, 僅有主鍵欄位時genConflictSQL無可更新欄位而回傳空字串,
|
|
948
|
+
//此時退回DO NOTHING, 以免併發插入同一主鍵者報錯
|
|
841
949
|
let conflict = genConflictSQL(v)
|
|
842
950
|
if (!isestr(conflict)) {
|
|
843
|
-
conflict =
|
|
951
|
+
conflict = `ON CONFLICT (${pkName}) DO NOTHING`
|
|
844
952
|
}
|
|
845
953
|
|
|
846
954
|
//sql, xmax為0表該列由本語句插入, 非0表係由DO UPDATE更新而來,
|
|
@@ -911,15 +1019,15 @@ function WOrmPostgresql(opt = {}) {
|
|
|
911
1019
|
}
|
|
912
1020
|
else {
|
|
913
1021
|
//未開啟autoInsert則僅能更新既有數據, 不可用INSERT以免無中生有,
|
|
914
|
-
//由UPDATE...WHERE
|
|
1022
|
+
//由UPDATE...WHERE主鍵原子完成[查找主鍵]與[更新], 併發時不會遺失更新
|
|
915
1023
|
|
|
916
1024
|
//mr
|
|
917
1025
|
let mr = mongoSql.sql({
|
|
918
1026
|
type: 'update',
|
|
919
1027
|
table: cl,
|
|
920
|
-
updates: omit(v,
|
|
1028
|
+
updates: omit(v, pkName),
|
|
921
1029
|
where: {
|
|
922
|
-
|
|
1030
|
+
[pkName]: pkv,
|
|
923
1031
|
},
|
|
924
1032
|
})
|
|
925
1033
|
// console.log('mr', mr)
|
|
@@ -973,6 +1081,16 @@ function WOrmPostgresql(opt = {}) {
|
|
|
973
1081
|
|
|
974
1082
|
}
|
|
975
1083
|
|
|
1084
|
+
//emit, 該筆經插入而產生者另發mode為insert之change事件, 供呼叫端區辨新增與更新
|
|
1085
|
+
if (rest.nInserted === 1) {
|
|
1086
|
+
emitChange('insert', [v], rest)
|
|
1087
|
+
}
|
|
1088
|
+
|
|
1089
|
+
//emit, 逐筆失敗於該筆結果定案後發出, 每筆一次
|
|
1090
|
+
if (rest.ok === 0) {
|
|
1091
|
+
emitError('save', [v], rest.err)
|
|
1092
|
+
}
|
|
1093
|
+
|
|
976
1094
|
return rest
|
|
977
1095
|
})
|
|
978
1096
|
|
|
@@ -993,16 +1111,15 @@ function WOrmPostgresql(opt = {}) {
|
|
|
993
1111
|
|
|
994
1112
|
//emit
|
|
995
1113
|
if (!isErr) {
|
|
996
|
-
|
|
997
|
-
ee.emit('change', 'save', data, res)
|
|
998
|
-
}
|
|
999
|
-
catch (err) {
|
|
1000
|
-
console.log(err)
|
|
1001
|
-
}
|
|
1114
|
+
emitChange('save', data, res)
|
|
1002
1115
|
}
|
|
1003
1116
|
|
|
1004
1117
|
//check
|
|
1005
1118
|
if (isErr) {
|
|
1119
|
+
|
|
1120
|
+
//emit, 整批性錯誤於reject之前發出
|
|
1121
|
+
emitError('save', data, res)
|
|
1122
|
+
|
|
1006
1123
|
return Promise.reject(res)
|
|
1007
1124
|
}
|
|
1008
1125
|
|
|
@@ -1014,7 +1131,7 @@ function WOrmPostgresql(opt = {}) {
|
|
|
1014
1131
|
*
|
|
1015
1132
|
* 回傳陣列恆與輸入等長,各筆之n與nDeleted皆為主鍵命中筆數,值為0或1,未命中為0且屬正常結果。
|
|
1016
1133
|
* 判斷某筆是否真的被刪除一律以nDeleted為準。
|
|
1017
|
-
*
|
|
1134
|
+
* 未帶有效主鍵值者為該筆之輸入問題,回ok:0與err且不送查詢,不中斷其餘筆數,
|
|
1018
1135
|
* 以此與[主鍵未命中]之ok:1區辨。
|
|
1019
1136
|
*
|
|
1020
1137
|
* @memberOf WOrmPostgresql
|
|
@@ -1051,6 +1168,10 @@ function WOrmPostgresql(opt = {}) {
|
|
|
1051
1168
|
|
|
1052
1169
|
//check
|
|
1053
1170
|
if (isErr) {
|
|
1171
|
+
|
|
1172
|
+
//emit, 整批性錯誤於reject之前發出
|
|
1173
|
+
emitError('del', data, res)
|
|
1174
|
+
|
|
1054
1175
|
return Promise.reject(res)
|
|
1055
1176
|
}
|
|
1056
1177
|
|
|
@@ -1071,21 +1192,24 @@ function WOrmPostgresql(opt = {}) {
|
|
|
1071
1192
|
//rest
|
|
1072
1193
|
let rest = null
|
|
1073
1194
|
|
|
1074
|
-
//
|
|
1075
|
-
let
|
|
1195
|
+
//pkv
|
|
1196
|
+
let pkv = get(v, pkName)
|
|
1076
1197
|
|
|
1077
|
-
//check
|
|
1198
|
+
//check pk, 未帶有效主鍵者不補值亦不送查詢,
|
|
1078
1199
|
//因mongo-sql會將無效值轉為null而誤中其他數據, 故直接視為該筆無法處理
|
|
1079
|
-
if (!
|
|
1200
|
+
if (!checkPk(pkv)) {
|
|
1080
1201
|
|
|
1081
1202
|
//rest
|
|
1082
1203
|
rest = {
|
|
1083
1204
|
n: 0,
|
|
1084
1205
|
nDeleted: 0,
|
|
1085
1206
|
ok: 0,
|
|
1086
|
-
err: `invalid
|
|
1207
|
+
err: `invalid ${pkName}[${pkv}]`,
|
|
1087
1208
|
}
|
|
1088
1209
|
|
|
1210
|
+
//emit, 逐筆失敗於該筆結果定案後發出, 每筆一次
|
|
1211
|
+
emitError('del', [v], rest.err)
|
|
1212
|
+
|
|
1089
1213
|
return rest
|
|
1090
1214
|
}
|
|
1091
1215
|
|
|
@@ -1094,7 +1218,7 @@ function WOrmPostgresql(opt = {}) {
|
|
|
1094
1218
|
type: 'delete',
|
|
1095
1219
|
table: cl,
|
|
1096
1220
|
where: {
|
|
1097
|
-
|
|
1221
|
+
[pkName]: pkv,
|
|
1098
1222
|
},
|
|
1099
1223
|
})
|
|
1100
1224
|
// console.log('mr', mr)
|
|
@@ -1125,6 +1249,11 @@ function WOrmPostgresql(opt = {}) {
|
|
|
1125
1249
|
|
|
1126
1250
|
})
|
|
1127
1251
|
|
|
1252
|
+
//emit, 逐筆失敗於該筆結果定案後發出, 每筆一次
|
|
1253
|
+
if (rest.ok === 0) {
|
|
1254
|
+
emitError('del', [v], rest.err)
|
|
1255
|
+
}
|
|
1256
|
+
|
|
1128
1257
|
return rest
|
|
1129
1258
|
})
|
|
1130
1259
|
|
|
@@ -1145,16 +1274,15 @@ function WOrmPostgresql(opt = {}) {
|
|
|
1145
1274
|
|
|
1146
1275
|
//emit
|
|
1147
1276
|
if (!isErr) {
|
|
1148
|
-
|
|
1149
|
-
ee.emit('change', 'del', data, res)
|
|
1150
|
-
}
|
|
1151
|
-
catch (err) {
|
|
1152
|
-
console.log(err)
|
|
1153
|
-
}
|
|
1277
|
+
emitChange('del', data, res)
|
|
1154
1278
|
}
|
|
1155
1279
|
|
|
1156
1280
|
//check
|
|
1157
1281
|
if (isErr) {
|
|
1282
|
+
|
|
1283
|
+
//emit, 整批性錯誤於reject之前發出
|
|
1284
|
+
emitError('del', data, res)
|
|
1285
|
+
|
|
1158
1286
|
return Promise.reject(res)
|
|
1159
1287
|
}
|
|
1160
1288
|
|
|
@@ -1193,6 +1321,10 @@ function WOrmPostgresql(opt = {}) {
|
|
|
1193
1321
|
|
|
1194
1322
|
//check
|
|
1195
1323
|
if (isErr) {
|
|
1324
|
+
|
|
1325
|
+
//emit, 整批性錯誤於reject之前發出, 無輸入數據故data為null
|
|
1326
|
+
emitError('delAll', null, res)
|
|
1327
|
+
|
|
1196
1328
|
return Promise.reject(res)
|
|
1197
1329
|
}
|
|
1198
1330
|
|
|
@@ -1256,16 +1388,15 @@ function WOrmPostgresql(opt = {}) {
|
|
|
1256
1388
|
|
|
1257
1389
|
//emit
|
|
1258
1390
|
if (!isErr) {
|
|
1259
|
-
|
|
1260
|
-
ee.emit('change', 'delAll', null, res)
|
|
1261
|
-
}
|
|
1262
|
-
catch (err) {
|
|
1263
|
-
console.log(err)
|
|
1264
|
-
}
|
|
1391
|
+
emitChange('delAll', null, res)
|
|
1265
1392
|
}
|
|
1266
1393
|
|
|
1267
1394
|
//check
|
|
1268
1395
|
if (isErr) {
|
|
1396
|
+
|
|
1397
|
+
//emit, 整批性錯誤於reject之前發出
|
|
1398
|
+
emitError('delAll', null, res)
|
|
1399
|
+
|
|
1269
1400
|
return Promise.reject(res)
|
|
1270
1401
|
}
|
|
1271
1402
|
|
|
@@ -1275,7 +1406,7 @@ function WOrmPostgresql(opt = {}) {
|
|
|
1275
1406
|
//save
|
|
1276
1407
|
ee.createTable = createTable
|
|
1277
1408
|
ee.select = select
|
|
1278
|
-
ee.
|
|
1409
|
+
ee.selectByPk = selectByPk
|
|
1279
1410
|
ee.insert = insert
|
|
1280
1411
|
ee.save = save
|
|
1281
1412
|
ee.del = del
|
|
@@ -1300,7 +1431,7 @@ export default WOrmPostgresql
|
|
|
1300
1431
|
<br class="clear">
|
|
1301
1432
|
|
|
1302
1433
|
<footer>
|
|
1303
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on
|
|
1434
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Mon Aug 17 2026 09:06:32 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
1304
1435
|
</footer>
|
|
1305
1436
|
|
|
1306
1437
|
<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
|
|
74
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Mon Aug 17 2026 09:06:32 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
75
75
|
</footer>
|
|
76
76
|
|
|
77
77
|
<script>prettyPrint();</script>
|