w-orm-reladb 1.1.8 → 1.1.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 +61 -28
- package/dist/w-orm-reladb.umd.js +2 -2
- package/dist/w-orm-reladb.umd.js.map +1 -1
- package/docs/WOrmReladb.html +52 -30
- package/docs/WOrmReladb.mjs.html +84 -30
- package/docs/cvFind.mjs.html +349 -382
- package/docs/global.html +49 -12
- package/docs/importModels.mjs.html +1 -1
- package/docs/index.html +1 -1
- package/g-mssql-transaction-commit.mjs +1 -1
- package/g-mssql-transaction-rollback.mjs +1 -1
- package/g-mssql.mjs +4 -4
- package/g-sqlite-encryption-transaction-commit.mjs +1 -1
- package/g-sqlite-encryption.mjs +4 -4
- package/g-sqlite-transaction-commit.mjs +1 -1
- package/g-sqlite-transaction-rollback.mjs +1 -1
- package/g-sqlite.mjs +4 -4
- package/models/tfind.js +50 -0
- package/package.json +2 -2
- package/src/WOrmReladb.mjs +83 -29
- package/src/cvFind.mjs +348 -381
- package/test/api-find-whitelist.mjs +390 -0
- package/test/api-models.test.mjs +23 -0
- package/test/api-mssql.test.mjs +2 -0
- package/test/api-sqlite.test.mjs +2 -0
- package/test/api-suite.mjs +560 -76
- package/test/unit-cvfind.test.mjs +928 -104
package/docs/global.html
CHANGED
|
@@ -141,15 +141,16 @@
|
|
|
141
141
|
|
|
142
142
|
<dt class="tag-description">Description:</dt>
|
|
143
143
|
<dd class="tag-description"><ul class="dummy"><li><p>將查詢條件轉為sequelize之where, 供select與delAll共用, 令同一find於兩函數由同一SQL謂詞決定命中</p>
|
|
144
|
-
<p>註:
|
|
145
|
-
|
|
146
|
-
註:
|
|
144
|
+
<p>註: 第一步經chkFindShape(wsemi之cvOrmFind)依系列白名單檢核並取複本, 其後只走訪複本; 白名單: 欄位等值{欄:純量|null}、
|
|
145
|
+
$eq $ne $gt $gte $lt $lte(純量)、$in $nin(純量陣列)、$and $or(條件物件之非空陣列); 其餘(含$not $nor $regex $options $exists、RegExp、Symbol鍵、陣列值)一律拋錯
|
|
146
|
+
註: 未給、undefined或{}回傳{}(全部); 其餘非條件物件(null、陣列、字串、數值等)拋錯, 不再視為{}
|
|
147
|
+
註: 與欄位型別不符之純量、不存在之欄一律拋錯, 不得交sequelize之型別stringify(見本檔之chkScalar); NULL依SQL三值邏輯</p></li></ul></dd>
|
|
147
148
|
|
|
148
149
|
|
|
149
150
|
|
|
150
151
|
<dt class="tag-source">Source:</dt>
|
|
151
152
|
<dd class="tag-source"><ul class="dummy"><li>
|
|
152
|
-
<a href="cvFind.mjs.html">cvFind.mjs</a>, <a href="cvFind.mjs.html#
|
|
153
|
+
<a href="cvFind.mjs.html">cvFind.mjs</a>, <a href="cvFind.mjs.html#line730">line 730</a>
|
|
153
154
|
</li></ul></dd>
|
|
154
155
|
|
|
155
156
|
|
|
@@ -306,6 +307,8 @@
|
|
|
306
307
|
|
|
307
308
|
<td class="attributes">
|
|
308
309
|
|
|
310
|
+
<optional><br>
|
|
311
|
+
|
|
309
312
|
|
|
310
313
|
|
|
311
314
|
|
|
@@ -315,7 +318,7 @@
|
|
|
315
318
|
|
|
316
319
|
|
|
317
320
|
|
|
318
|
-
<td class="description last"><p
|
|
321
|
+
<td class="description last"><p>已不使用(原供$regex之LIKE字面常值; 第33項批1移除$regex), 保留接受以相容既有呼叫端</p></td>
|
|
319
322
|
</tr>
|
|
320
323
|
|
|
321
324
|
|
|
@@ -349,7 +352,7 @@
|
|
|
349
352
|
|
|
350
353
|
|
|
351
354
|
|
|
352
|
-
<td class="description last"><p
|
|
355
|
+
<td class="description last"><p>輸入執行where之model之rawAttributes, 供欄名解析(嚴格鍵: 鍵須與屬性名或資料庫欄名完全相符, 其餘拒收)、依欄位型別檢核純量與取得實際欄名; 未給時不解析鍵、不檢型別而交資料庫(見CLAUDE_rulebook.md之R4)</p></td>
|
|
353
356
|
</tr>
|
|
354
357
|
|
|
355
358
|
|
|
@@ -383,7 +386,7 @@
|
|
|
383
386
|
|
|
384
387
|
|
|
385
388
|
|
|
386
|
-
<td class="description last"><p
|
|
389
|
+
<td class="description last"><p>已不使用(原供判定sqlite之LOWER僅折疊ASCII), 保留接受以相容既有呼叫端</p></td>
|
|
387
390
|
</tr>
|
|
388
391
|
|
|
389
392
|
|
|
@@ -421,6 +424,40 @@
|
|
|
421
424
|
</tr>
|
|
422
425
|
|
|
423
426
|
|
|
427
|
+
|
|
428
|
+
<tr>
|
|
429
|
+
|
|
430
|
+
<td class="name"><code>dateNoTz</code></td>
|
|
431
|
+
|
|
432
|
+
|
|
433
|
+
<td class="type">
|
|
434
|
+
|
|
435
|
+
|
|
436
|
+
<span class="param-type">String</span>
|
|
437
|
+
|
|
438
|
+
|
|
439
|
+
|
|
440
|
+
|
|
441
|
+
</td>
|
|
442
|
+
|
|
443
|
+
|
|
444
|
+
<td class="attributes">
|
|
445
|
+
|
|
446
|
+
<optional><br>
|
|
447
|
+
|
|
448
|
+
|
|
449
|
+
|
|
450
|
+
|
|
451
|
+
|
|
452
|
+
</td>
|
|
453
|
+
|
|
454
|
+
|
|
455
|
+
|
|
456
|
+
|
|
457
|
+
<td class="description last"><p>輸入無時區日期時間字串之處置, 僅接受undefined(預設, 無時區者拒收)或'local'(依主機時區解析, 與以本地時間分量建構之Date同義), 其餘值拋錯; 僅作用於DATE欄, 供Jet等無時區後端之呼叫端明示啟用</p></td>
|
|
458
|
+
</tr>
|
|
459
|
+
|
|
460
|
+
|
|
424
461
|
</tbody>
|
|
425
462
|
</table>
|
|
426
463
|
|
|
@@ -493,7 +530,7 @@
|
|
|
493
530
|
|
|
494
531
|
<dt class="tag-source">Source:</dt>
|
|
495
532
|
<dd class="tag-source"><ul class="dummy"><li>
|
|
496
|
-
<a href="cvFind.mjs.html">cvFind.mjs</a>, <a href="cvFind.mjs.html#
|
|
533
|
+
<a href="cvFind.mjs.html">cvFind.mjs</a>, <a href="cvFind.mjs.html#line155">line 155</a>
|
|
497
534
|
</li></ul></dd>
|
|
498
535
|
|
|
499
536
|
|
|
@@ -675,7 +712,7 @@
|
|
|
675
712
|
|
|
676
713
|
<dt class="tag-source">Source:</dt>
|
|
677
714
|
<dd class="tag-source"><ul class="dummy"><li>
|
|
678
|
-
<a href="cvFind.mjs.html">cvFind.mjs</a>, <a href="cvFind.mjs.html#
|
|
715
|
+
<a href="cvFind.mjs.html">cvFind.mjs</a>, <a href="cvFind.mjs.html#line333">line 333</a>
|
|
679
716
|
</li></ul></dd>
|
|
680
717
|
|
|
681
718
|
|
|
@@ -1260,7 +1297,7 @@
|
|
|
1260
1297
|
|
|
1261
1298
|
<dt class="tag-source">Source:</dt>
|
|
1262
1299
|
<dd class="tag-source"><ul class="dummy"><li>
|
|
1263
|
-
<a href="cvFind.mjs.html">cvFind.mjs</a>, <a href="cvFind.mjs.html#
|
|
1300
|
+
<a href="cvFind.mjs.html">cvFind.mjs</a>, <a href="cvFind.mjs.html#line355">line 355</a>
|
|
1264
1301
|
</li></ul></dd>
|
|
1265
1302
|
|
|
1266
1303
|
|
|
@@ -1451,7 +1488,7 @@ DECIMAL主鍵欄之值小數位多於scale者寫入時會被四捨五入而改
|
|
|
1451
1488
|
|
|
1452
1489
|
<dt class="tag-source">Source:</dt>
|
|
1453
1490
|
<dd class="tag-source"><ul class="dummy"><li>
|
|
1454
|
-
<a href="cvFind.mjs.html">cvFind.mjs</a>, <a href="cvFind.mjs.html#
|
|
1491
|
+
<a href="cvFind.mjs.html">cvFind.mjs</a>, <a href="cvFind.mjs.html#line448">line 448</a>
|
|
1455
1492
|
</li></ul></dd>
|
|
1456
1493
|
|
|
1457
1494
|
|
|
@@ -1703,7 +1740,7 @@ DECIMAL主鍵欄之值小數位多於scale者寫入時會被四捨五入而改
|
|
|
1703
1740
|
<br class="clear">
|
|
1704
1741
|
|
|
1705
1742
|
<footer>
|
|
1706
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on
|
|
1743
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Mon Oct 19 2026 18:54:43 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
1707
1744
|
</footer>
|
|
1708
1745
|
|
|
1709
1746
|
<script>prettyPrint();</script>
|
|
@@ -242,7 +242,7 @@ export default importModels
|
|
|
242
242
|
<br class="clear">
|
|
243
243
|
|
|
244
244
|
<footer>
|
|
245
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on
|
|
245
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Mon Oct 19 2026 18:54:43 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
246
246
|
</footer>
|
|
247
247
|
|
|
248
248
|
<script>prettyPrint();</script>
|
package/docs/index.html
CHANGED
|
@@ -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 Oct 19 2026 18:54:43 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
75
75
|
</footer>
|
|
76
76
|
|
|
77
77
|
<script>prettyPrint();</script>
|
|
@@ -129,7 +129,7 @@ async function testCommit() {
|
|
|
129
129
|
|
|
130
130
|
|
|
131
131
|
//select all
|
|
132
|
-
let ssBeforeCommit = await w.select(
|
|
132
|
+
let ssBeforeCommit = await w.select({}, connState)
|
|
133
133
|
console.log('select all (before commit)', ssBeforeCommit) //此時select可查到暫時有效的數據
|
|
134
134
|
// => [
|
|
135
135
|
// { id: 'id-peter', name: 'peter(modify)', value: 123 },
|
|
@@ -129,7 +129,7 @@ async function testRollback() {
|
|
|
129
129
|
|
|
130
130
|
|
|
131
131
|
//select all
|
|
132
|
-
let ssBeforeRollback = await w.select(
|
|
132
|
+
let ssBeforeRollback = await w.select({}, connState)
|
|
133
133
|
console.log('select all (before rollback)', ssBeforeRollback) //此時select可查到暫時有效的數據
|
|
134
134
|
// => [
|
|
135
135
|
// { id: 'id-peter', name: 'peter(modify)', value: 123 },
|
package/g-mssql.mjs
CHANGED
|
@@ -133,9 +133,9 @@ async function test() {
|
|
|
133
133
|
console.log('select by $or, $and, $ne, $in, $nin', spc)
|
|
134
134
|
|
|
135
135
|
|
|
136
|
-
//select by
|
|
137
|
-
let sr = await w.select({ name:
|
|
138
|
-
console.log('
|
|
136
|
+
//select by equality (there is no pattern matching: filter in memory for substrings)
|
|
137
|
+
let sr = await w.select({ name: 'peter(modify)' })
|
|
138
|
+
console.log('selectEq', sr)
|
|
139
139
|
|
|
140
140
|
|
|
141
141
|
//del
|
|
@@ -189,7 +189,7 @@ test()
|
|
|
189
189
|
// { id: 'id-rosemary', name: 'rosemary(modify)', value: 123.456 },
|
|
190
190
|
// { id: '{random id}', name: 'kettle', value: 456 }
|
|
191
191
|
// ]
|
|
192
|
-
//
|
|
192
|
+
// selectEq [
|
|
193
193
|
// { id: 'id-peter', name: 'peter(modify)', value: 123 }
|
|
194
194
|
// ]
|
|
195
195
|
// change del
|
|
@@ -137,7 +137,7 @@
|
|
|
137
137
|
|
|
138
138
|
|
|
139
139
|
// //select all
|
|
140
|
-
// let ssBeforeCommit = await w.select(
|
|
140
|
+
// let ssBeforeCommit = await w.select({}, connState)
|
|
141
141
|
// console.log('select all (before commit)', ssBeforeCommit) //此時select可查到暫時有效的數據
|
|
142
142
|
// // => [
|
|
143
143
|
// // { id: 'id-peter', name: 'peter(modify)', value: 123 },
|
package/g-sqlite-encryption.mjs
CHANGED
|
@@ -148,9 +148,9 @@ async function test() {
|
|
|
148
148
|
console.log('select by $or, $and, $ne, $in, $nin', spc)
|
|
149
149
|
|
|
150
150
|
|
|
151
|
-
//select by
|
|
152
|
-
let sr = await w.select({ name:
|
|
153
|
-
console.log('
|
|
151
|
+
//select by equality (there is no pattern matching: filter in memory for substrings)
|
|
152
|
+
let sr = await w.select({ name: 'peter(modify)' })
|
|
153
|
+
console.log('selectEq', sr)
|
|
154
154
|
|
|
155
155
|
|
|
156
156
|
//del
|
|
@@ -204,7 +204,7 @@ test()
|
|
|
204
204
|
// { id: 'id-rosemary', name: 'rosemary(modify)', value: 123.456 },
|
|
205
205
|
// { id: '{random id}', name: 'kettle', value: 456 }
|
|
206
206
|
// ]
|
|
207
|
-
//
|
|
207
|
+
// selectEq [
|
|
208
208
|
// { id: 'id-peter', name: 'peter(modify)', value: 123 }
|
|
209
209
|
// ]
|
|
210
210
|
// change del
|
|
@@ -136,7 +136,7 @@ async function testCommit() {
|
|
|
136
136
|
|
|
137
137
|
|
|
138
138
|
//select all
|
|
139
|
-
let ssBeforeCommit = await w.select(
|
|
139
|
+
let ssBeforeCommit = await w.select({}, connState)
|
|
140
140
|
console.log('select all (before commit)', ssBeforeCommit) //此時select可查到暫時有效的數據
|
|
141
141
|
// => [
|
|
142
142
|
// { id: 'id-peter', name: 'peter(modify)', value: 123 },
|
|
@@ -136,7 +136,7 @@ async function testRollback() {
|
|
|
136
136
|
|
|
137
137
|
|
|
138
138
|
//select all
|
|
139
|
-
let ssBeforeRollback = await w.select(
|
|
139
|
+
let ssBeforeRollback = await w.select({}, connState)
|
|
140
140
|
console.log('select all (before rollback)', ssBeforeRollback) //此時select可查到暫時有效的數據
|
|
141
141
|
// => [
|
|
142
142
|
// { id: 'id-peter', name: 'peter(modify)', value: 123 },
|
package/g-sqlite.mjs
CHANGED
|
@@ -141,9 +141,9 @@ async function test() {
|
|
|
141
141
|
console.log('select by $or, $and, $ne, $in, $nin', spc)
|
|
142
142
|
|
|
143
143
|
|
|
144
|
-
//select by
|
|
145
|
-
let sr = await w.select({ name:
|
|
146
|
-
console.log('
|
|
144
|
+
//select by equality (there is no pattern matching: filter in memory for substrings)
|
|
145
|
+
let sr = await w.select({ name: 'peter(modify)' })
|
|
146
|
+
console.log('selectEq', sr)
|
|
147
147
|
|
|
148
148
|
|
|
149
149
|
//del
|
|
@@ -197,7 +197,7 @@ test()
|
|
|
197
197
|
// { id: 'id-rosemary', name: 'rosemary(modify)', value: 123.456 },
|
|
198
198
|
// { id: '{random id}', name: 'kettle', value: 456 }
|
|
199
199
|
// ]
|
|
200
|
-
//
|
|
200
|
+
// selectEq [
|
|
201
201
|
// { id: 'id-peter', name: 'peter(modify)', value: 123 }
|
|
202
202
|
// ]
|
|
203
203
|
// change del
|
package/models/tfind.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/* jshint indent: 1 */
|
|
2
|
+
module.exports = function(sequelize, DataTypes) {
|
|
3
|
+
return sequelize.define('tfind', {
|
|
4
|
+
'id': {
|
|
5
|
+
type: DataTypes.STRING,
|
|
6
|
+
allowNull: false,
|
|
7
|
+
primaryKey: true,
|
|
8
|
+
autoIncrement: false,
|
|
9
|
+
comment: null
|
|
10
|
+
},
|
|
11
|
+
'name': {
|
|
12
|
+
type: DataTypes.STRING,
|
|
13
|
+
allowNull: true,
|
|
14
|
+
autoIncrement: false,
|
|
15
|
+
comment: null
|
|
16
|
+
},
|
|
17
|
+
'age': {
|
|
18
|
+
type: DataTypes.INTEGER,
|
|
19
|
+
allowNull: true,
|
|
20
|
+
autoIncrement: false,
|
|
21
|
+
comment: null
|
|
22
|
+
},
|
|
23
|
+
'g': {
|
|
24
|
+
type: DataTypes.STRING,
|
|
25
|
+
allowNull: true,
|
|
26
|
+
autoIncrement: false,
|
|
27
|
+
comment: null
|
|
28
|
+
},
|
|
29
|
+
't': {
|
|
30
|
+
type: DataTypes.STRING,
|
|
31
|
+
allowNull: true,
|
|
32
|
+
autoIncrement: false,
|
|
33
|
+
comment: null
|
|
34
|
+
},
|
|
35
|
+
'flag': {
|
|
36
|
+
type: DataTypes.BOOLEAN,
|
|
37
|
+
allowNull: true,
|
|
38
|
+
autoIncrement: false,
|
|
39
|
+
comment: null
|
|
40
|
+
},
|
|
41
|
+
'd': {
|
|
42
|
+
type: DataTypes.DATE,
|
|
43
|
+
allowNull: true,
|
|
44
|
+
autoIncrement: false,
|
|
45
|
+
comment: null
|
|
46
|
+
}
|
|
47
|
+
}, {
|
|
48
|
+
tableName: 'tfind'
|
|
49
|
+
});
|
|
50
|
+
};
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "w-orm-reladb",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.10",
|
|
4
4
|
"main": "dist/w-orm-reladb.umd.js",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"json5": "^2.2.3",
|
|
7
7
|
"sqlite3": "^6.0.1",
|
|
8
8
|
"tedious": "^19.2.2",
|
|
9
9
|
"w-auto-sequelize": "^1.0.48",
|
|
10
|
-
"wsemi": "^1.9.
|
|
10
|
+
"wsemi": "^1.9.20"
|
|
11
11
|
},
|
|
12
12
|
"dependenciesTemp": {
|
|
13
13
|
"@journeyapps/sqlcipher": "^5.3.1",
|
package/src/WOrmReladb.mjs
CHANGED
|
@@ -25,7 +25,7 @@ import pmQueue from 'wsemi/src/pmQueue.mjs'
|
|
|
25
25
|
import WAutoSequelize from 'w-auto-sequelize/src/WAutoSequelize.mjs'
|
|
26
26
|
import importModels from './importModels.mjs'
|
|
27
27
|
import _genModelsByTabs from './genModelsByTabs.mjs'
|
|
28
|
-
import cvFind, { getColKind, getColScale, normPk } from './cvFind.mjs'
|
|
28
|
+
import cvFind, { getColKind, getColScale, normPk, chkFindShape } from './cvFind.mjs'
|
|
29
29
|
|
|
30
30
|
|
|
31
31
|
//放置於全域宣告, 若使用useStable=true才可於當創建多實例時仍能全域控管
|
|
@@ -307,18 +307,15 @@ function WOrmReladb(opt = {}) {
|
|
|
307
307
|
|
|
308
308
|
/**
|
|
309
309
|
* 取cvFind所需之依賴物件
|
|
310
|
-
* 註:
|
|
311
|
-
* pk令主鍵欄之條件值依normPk正規化而與主鍵函數一致
|
|
310
|
+
* 註: attrs供欄名解析(嚴格鍵)與依欄位型別檢核條件之純量, pk令主鍵欄之條件值依normPk正規化而與主鍵函數一致
|
|
312
311
|
*
|
|
313
312
|
* @ignore
|
|
314
313
|
* @param {Object} md 輸入資料表model物件
|
|
315
|
-
* @returns {Object} 回傳{
|
|
314
|
+
* @returns {Object} 回傳{attrs, pk}
|
|
316
315
|
*/
|
|
317
316
|
function getFindCtx(md) {
|
|
318
317
|
return {
|
|
319
|
-
escape: (v) => md.sequelize.escape(v),
|
|
320
318
|
attrs: get(md, 'rawAttributes', {}),
|
|
321
|
-
dialect,
|
|
322
319
|
pk: opt.pk,
|
|
323
320
|
}
|
|
324
321
|
}
|
|
@@ -328,6 +325,10 @@ function WOrmReladb(opt = {}) {
|
|
|
328
325
|
* 檢查model之預設scope是否會使select與delAll之對象分歧
|
|
329
326
|
* 註: defaultScope帶limit或offset時, select依其order取前幾筆, 而sequelize之限量刪除不採order(sqlite為rowid IN子查詢),
|
|
330
327
|
* 兩者命中之數據不同而會刪錯列, 故delAll遇此類model即拒絕
|
|
328
|
+
* 註: defaultScope帶group或having時, findAll套用而destroy不套用(having過濾後只回部分列, 卻刪除全部符合where者);
|
|
329
|
+
* 帶非空之include時, findAll以INNER JOIN篩列(required)而destroy不JOIN; 兩者亦拒絕
|
|
330
|
+
* 註: defaultScope.where含Op.and時, sequelize以Object.assign合併scope與cvFind輸出之where, 後者頂層恆為Op.and而覆寫scope之條件(select與delAll皆然),
|
|
331
|
+
* delAll會刪到scope範圍外之列, 故拒絕; 其他鍵(含Op.or)與cvFind輸出之Op.and並存而以AND結合, 不受影響
|
|
331
332
|
*
|
|
332
333
|
* @ignore
|
|
333
334
|
* @param {Object} md 輸入資料表model物件
|
|
@@ -335,8 +336,27 @@ function WOrmReladb(opt = {}) {
|
|
|
335
336
|
*/
|
|
336
337
|
function chkScopeForDelAll(md) {
|
|
337
338
|
let sc = get(md, '_scope', {})
|
|
338
|
-
|
|
339
|
-
|
|
339
|
+
let bads = []
|
|
340
|
+
for (let k of ['limit', 'offset']) {
|
|
341
|
+
if (get(sc, k) !== undefined) {
|
|
342
|
+
bads.push(k)
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
for (let k of ['group', 'having']) {
|
|
346
|
+
let v = get(sc, k)
|
|
347
|
+
if (v !== undefined && v !== null && !(Array.isArray(v) && v.length === 0)) {
|
|
348
|
+
bads.push(k)
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
if (isearr(get(sc, 'include'))) {
|
|
352
|
+
bads.push('include')
|
|
353
|
+
}
|
|
354
|
+
let w = get(sc, 'where')
|
|
355
|
+
if (w !== null && typeof w === 'object' && Object.prototype.hasOwnProperty.call(w, Sequelize.Op.and)) {
|
|
356
|
+
bads.push('where[Op.and]')
|
|
357
|
+
}
|
|
358
|
+
if (bads.length > 0) {
|
|
359
|
+
throw new Error(`model [${opt.cl}] has defaultScope with ${bads.join(', ')}, delAll can not delete the same rows as select`)
|
|
340
360
|
}
|
|
341
361
|
}
|
|
342
362
|
|
|
@@ -533,18 +553,25 @@ function WOrmReladb(opt = {}) {
|
|
|
533
553
|
/**
|
|
534
554
|
* 查詢數據
|
|
535
555
|
*
|
|
536
|
-
*
|
|
537
|
-
*
|
|
538
|
-
*
|
|
539
|
-
*
|
|
540
|
-
*
|
|
541
|
-
*
|
|
542
|
-
*
|
|
543
|
-
*
|
|
556
|
+
* 使用須知(條件find為系列白名單, 規則同delAll, 見CLAUDE_rulebook.md之R11):
|
|
557
|
+
* 1. 不給條件即查詢全部數據: find未給、為undefined或為{}時回傳全部數據; 給了條件才是部分查詢。
|
|
558
|
+
* 2. 傳了值卻不是條件物件(null、陣列含[]與[{...}]、字串、數值、布林、函數、Date、RegExp、Map、Set、類別實例等)
|
|
559
|
+
* 一律整批reject, 不視為{}。
|
|
560
|
+
* 3. 條件僅支援系列白名單: 欄位等值{欄:純量}(多欄為AND)、欄位運算子$eq $ne $gt $gte $lt $lte(值為純量)與
|
|
561
|
+
* $in $nin(值為純量陣列)、文件層$and $or(值為條件物件之非空陣列, 最多999項)。純量為字串、有限數字、布林、有效Date;
|
|
562
|
+
* null僅可用於欄位等值、$eq、$ne。白名單外之運算子($not $nor $regex $options $exists $where $expr $like $ilike等)、
|
|
563
|
+
* sequelize之Op Symbol、RegExp值、陣列值(請改用$in)、欄位層$and/$or、函數值、Symbol鍵、undefined值、空的$nin/$and/$or等
|
|
564
|
+
* 一律整批reject, 訊息為invalid find: 原因 at [路徑], 且於載入model與連線前即檢核。
|
|
565
|
+
* 4. 欄名須完全等於model之屬性名或資料庫欄名(區分大小寫), 且為字母或底線開頭之字母/數字/底線(最多128字元);
|
|
566
|
+
* 純量須符合欄位型別(如數值欄給'abc'會reject); 主鍵欄之條件值依主鍵欄型別正規化(字串類主鍵欄之{id:123}即{id:'123'})。
|
|
567
|
+
* 5. 與delAll共用同一檢核與同一條件, select(find)命中之數據即delAll(find)刪除之數據。
|
|
568
|
+
* 6. 語意差異(SQL式): $ne/$nin不命中欄位為NULL之數據(三值邏輯)。需明確表達時可用可攜寫法:
|
|
569
|
+
* 排除NULL為{$and:[{f:{$ne:null}},{f:{$ne:x}}]}, 含NULL為{$or:[{f:null},{f:{$ne:x}}]}; 字串比對之大小寫依資料庫定序。
|
|
570
|
+
*
|
|
544
571
|
* 註: 恆回傳陣列, 無符合數據回傳空陣列
|
|
545
572
|
*
|
|
546
573
|
* @memberOf WOrmReladb
|
|
547
|
-
* @param {Object} [find={}] 輸入查詢條件物件
|
|
574
|
+
* @param {Object} [find={}] 輸入查詢條件物件(系列白名單, 規則同delAll之使用須知第1-4點); 未給、undefined或{}回傳全部數據; 非條件物件或白名單外運算子整批reject
|
|
548
575
|
* @param {Object} [option={}] 輸入設定物件,預設為{}
|
|
549
576
|
* @param {Object} [option.instance=null] 輸入實例instance物件,預設為null
|
|
550
577
|
* @param {Object} [option.transaction=null] 輸入交易(transaction)物件,預設為null
|
|
@@ -572,13 +599,20 @@ function WOrmReladb(opt = {}) {
|
|
|
572
599
|
//si
|
|
573
600
|
let si = instance
|
|
574
601
|
|
|
602
|
+
//inited, 本次呼叫是否已進入initSequelize(僅此時finally才關閉sequelize; 預檢失敗於其前者不得關閉呼叫端先前持有之連線)
|
|
603
|
+
let inited = false
|
|
604
|
+
|
|
575
605
|
try {
|
|
576
606
|
|
|
577
607
|
//check, 實例已關閉屬整批性錯誤, 於入口快速失敗
|
|
578
608
|
procClosed(instance)
|
|
579
609
|
|
|
610
|
+
//chkFindShape, 條件形狀不合法者(系列白名單, R11)於載入model與建立sequelize實例之前即拋錯: 不連線、不送出任何SQL, reject並發出error事件; 其後只使用檢核後之複本
|
|
611
|
+
let fd = chkFindShape(find)
|
|
612
|
+
|
|
580
613
|
//initSequelize, 內部自動初始化須在try內: 其例外(如驅動缺失)與si.err同屬整批性錯誤, 方能於reject前發出error事件, 已建構之sequelize亦由finally關閉
|
|
581
614
|
if (instance === null) {
|
|
615
|
+
inited = true
|
|
582
616
|
si = await initSequelize()
|
|
583
617
|
}
|
|
584
618
|
|
|
@@ -590,8 +624,8 @@ function WOrmReladb(opt = {}) {
|
|
|
590
624
|
//md
|
|
591
625
|
let md = si.mds[opt.cl]
|
|
592
626
|
|
|
593
|
-
//useFind, 與delAll共用cvFind,
|
|
594
|
-
let useFind = cvFind(
|
|
627
|
+
//useFind, 與delAll共用cvFind(對複本再檢核一次, 冪等), 欄名、欄位型別等翻譯層不合法者於此拋錯而reject並發出error事件
|
|
628
|
+
let useFind = cvFind(fd, getFindCtx(md))
|
|
595
629
|
|
|
596
630
|
//setting, raw令回傳純數據物件而不含資料庫內部欄位
|
|
597
631
|
let setting = {
|
|
@@ -616,7 +650,7 @@ function WOrmReladb(opt = {}) {
|
|
|
616
650
|
finally {
|
|
617
651
|
|
|
618
652
|
//closeSequelize
|
|
619
|
-
if (instance === null) { //內部自動初始化得close
|
|
653
|
+
if (instance === null && inited) { //內部自動初始化得close
|
|
620
654
|
await closeSequelize('select')
|
|
621
655
|
}
|
|
622
656
|
|
|
@@ -1577,16 +1611,29 @@ function WOrmReladb(opt = {}) {
|
|
|
1577
1611
|
|
|
1578
1612
|
|
|
1579
1613
|
/**
|
|
1580
|
-
*
|
|
1614
|
+
* 依條件刪除多筆數據(破壞性操作, 須審慎使用, 非必要不用; 刪除單筆請用del), 需與del分開,避免未傳數據導致直接刪除全表
|
|
1615
|
+
*
|
|
1616
|
+
* 使用須知:
|
|
1617
|
+
* 1. 不給條件即刪除全部數據: find未給、為undefined或為{}時, 刪除資料表內全部數據, 不另行確認。給了條件才是部分刪除。
|
|
1618
|
+
* 2. 傳了值卻不是條件物件(null、陣列含[]與[{...}]、字串、數值、布林、函數、Date、RegExp、Map、Set、類別實例等)
|
|
1619
|
+
* 一律整批reject, 不視為{}, 不刪除任何數據。
|
|
1620
|
+
* 3. 條件僅支援系列白名單: 欄位等值{欄:純量}(多欄為AND)、欄位運算子$eq $ne $gt $gte $lt $lte(值為純量)與
|
|
1621
|
+
* $in $nin(值為純量陣列)、文件層$and $or(值為條件物件之非空陣列, 最多999項)。純量為字串、有限數字、布林、有效Date;
|
|
1622
|
+
* null僅可用於欄位等值、$eq、$ne。白名單外之運算子($not $nor $regex $options $exists $where $expr $like $ilike等)、
|
|
1623
|
+
* sequelize之Op Symbol、RegExp值、陣列值(請改用$in)、欄位層$and/$or、子查詢、函數值、Symbol鍵、undefined值、
|
|
1624
|
+
* 空的$nin/$and/$or等一律整批reject, 訊息為invalid find: 原因 at [路徑], 且不刪除任何數據。
|
|
1625
|
+
* 4. 與select共用同一檢核與同一條件, select(find)命中之數據即本函數刪除之數據; 建議先以select(find)確認命中範圍再刪除。
|
|
1626
|
+
* 欄名須完全等於model之屬性名或資料庫欄名(區分大小寫); 純量須符合欄位型別; 主鍵欄之條件值依主鍵欄型別正規化。
|
|
1627
|
+
* 5. 條件值若來自可能為undefined、null或空陣列之變數, 呼叫端須先自行判斷; undefined值會reject而非被忽略,
|
|
1628
|
+
* 空的$nin會reject, $in:[]則為恆假(刪除0筆)。
|
|
1629
|
+
* 6. 語意差異(SQL式): $ne/$nin不命中欄位為NULL之數據(三值邏輯)。需明確表達時可用可攜寫法:
|
|
1630
|
+
* 排除NULL為{$and:[{f:{$ne:null}},{f:{$ne:x}}]}, 含NULL為{$or:[{f:null},{f:{$ne:x}}]}; 字串比對之大小寫依資料庫定序。
|
|
1581
1631
|
*
|
|
1582
1632
|
* 註: n與nDeleted皆為實際刪除筆數,兩者恆相等,n不得取全表筆數
|
|
1583
|
-
* 註:
|
|
1584
|
-
* 註: find由cvFind轉譯且與select共用,刪除之數據即select(find)命中之數據;支援之條件與限制同select
|
|
1585
|
-
* 註: 不支援之運算子、非純量之值、與欄位型別不符之純量一律reject並發出error事件,不刪除任何數據;主鍵欄之條件值依主鍵欄型別正規化,同select
|
|
1586
|
-
* 註: find非物件(null、陣列、字串、數字)時刪除全部數據,此為現況保留,系列規格另案處理
|
|
1633
|
+
* 註: 條件無命中時回{n:0,nDeleted:0,ok:1},不視為錯誤
|
|
1587
1634
|
*
|
|
1588
1635
|
* @memberOf WOrmReladb
|
|
1589
|
-
* @param {Object} [find={}]
|
|
1636
|
+
* @param {Object} [find={}] 輸入刪除條件物件(系列白名單, 見使用須知),不給予find則代表刪除全部數據
|
|
1590
1637
|
* @param {Object} [option={}] 輸入設定物件,預設為{}
|
|
1591
1638
|
* @param {Object} [option.instance=null] 輸入實例instance物件,預設為null
|
|
1592
1639
|
* @param {Object} [option.transaction=null] 輸入交易(transaction)物件,預設為null
|
|
@@ -1614,13 +1661,20 @@ function WOrmReladb(opt = {}) {
|
|
|
1614
1661
|
//si
|
|
1615
1662
|
let si = instance
|
|
1616
1663
|
|
|
1664
|
+
//inited, 本次呼叫是否已進入initSequelize(僅此時finally才關閉sequelize; 預檢失敗於其前者不得關閉呼叫端先前持有之連線)
|
|
1665
|
+
let inited = false
|
|
1666
|
+
|
|
1617
1667
|
try {
|
|
1618
1668
|
|
|
1619
1669
|
//check, 實例已關閉屬整批性錯誤, 於入口快速失敗
|
|
1620
1670
|
procClosed(instance)
|
|
1621
1671
|
|
|
1672
|
+
//chkFindShape, 條件形狀不合法者(系列白名單, R11)於載入model與建立sequelize實例之前即拋錯: 不連線、不送出任何SQL、不刪除任何數據; 其後只使用檢核後之複本
|
|
1673
|
+
let fd = chkFindShape(find)
|
|
1674
|
+
|
|
1622
1675
|
//initSequelize, 內部自動初始化須在try內: 其例外(如驅動缺失)與si.err同屬整批性錯誤, 方能於reject前發出error事件, 已建構之sequelize亦由finally關閉
|
|
1623
1676
|
if (instance === null) {
|
|
1677
|
+
inited = true
|
|
1624
1678
|
si = await initSequelize()
|
|
1625
1679
|
}
|
|
1626
1680
|
|
|
@@ -1632,8 +1686,8 @@ function WOrmReladb(opt = {}) {
|
|
|
1632
1686
|
//md
|
|
1633
1687
|
let md = si.mds[opt.cl]
|
|
1634
1688
|
|
|
1635
|
-
//useFind, 與select共用cvFind, 令刪除之數據即select命中之數據;
|
|
1636
|
-
let useFind = cvFind(
|
|
1689
|
+
//useFind, 與select共用cvFind(對複本再檢核一次, 冪等), 令刪除之數據即select命中之數據; 翻譯層不合法者於此拋錯而不刪除任何數據
|
|
1690
|
+
let useFind = cvFind(fd, getFindCtx(md))
|
|
1637
1691
|
|
|
1638
1692
|
//chkScopeForDelAll, model之預設scope會使刪除對象與select分歧者拒絕
|
|
1639
1693
|
chkScopeForDelAll(md)
|
|
@@ -1665,7 +1719,7 @@ function WOrmReladb(opt = {}) {
|
|
|
1665
1719
|
finally {
|
|
1666
1720
|
|
|
1667
1721
|
//closeSequelize
|
|
1668
|
-
if (instance === null) { //內部自動初始化得close
|
|
1722
|
+
if (instance === null && inited) { //內部自動初始化得close
|
|
1669
1723
|
await closeSequelize('delAll')
|
|
1670
1724
|
}
|
|
1671
1725
|
|