@maiyunnet/kebab 4.1.0 → 5.0.0

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/sys/mod.js CHANGED
@@ -4,7 +4,7 @@
4
4
  * Last: 2020-4-14 13:33:51, 2022-07-23 16:01:34, 2022-09-06 22:59:26, 2023-5-24 19:11:37, 2023-6-13 21:47:58, 2023-7-10 18:54:03, 2023-8-23 17:03:16, 2023-12-11 15:21:22, 2023-12-20 23:12:03, 2024-3-8 16:05:29, 2024-3-20 19:58:15, 2024-8-11 21:14:54, 2024-10-5 14:00:22, 2024-12-14 19:58:34, 2025-9-23 11:01:36, 2025-11-5 16:34:31
5
5
  */
6
6
  import * as lSql from '#kebab/lib/sql.js';
7
- import * as lTime from '#kebab/lib/time.js';
7
+ import * as lDb from '#kebab/lib/db.js';
8
8
  import * as lCore from '#kebab/lib/core.js';
9
9
  import * as lText from '#kebab/lib/text.js';
10
10
  import * as sCtr from '#kebab/sys/ctr.js';
@@ -54,8 +54,6 @@ export default class Mod {
54
54
  static { this._$key = ''; }
55
55
  /** --- 若使用 _$key 并且有多个 unique 索引,这里指定 _$key 的索引名 --- */
56
56
  static { this._$index = ''; }
57
- /** ---- 可开启软删软更新软新增 --- */
58
- static { this._$soft = false; }
59
57
  /**
60
58
  * --- 构造函数 ---
61
59
  * @param ctr Ctr 对象
@@ -81,7 +79,9 @@ export default class Mod {
81
79
  /** --- 导入数据库连接 --- */
82
80
  this._db = opt.db;
83
81
  /** --- 新建 sql 对象 --- */
84
- this._sql = lSql.get(opt.pre ?? opt.ctr);
82
+ this._sql = lSql.get(opt.pre ?? opt.ctr, {
83
+ 'service': this._db.getService() ?? lDb.ESERVICE.PGSQL,
84
+ });
85
85
  if (opt.index) {
86
86
  this._index = typeof opt.index === 'string' ? [opt.index] : [...new Set(opt.index)];
87
87
  }
@@ -102,19 +102,6 @@ export default class Mod {
102
102
  (this._index !== null ? ('_' + this._index[0]) : '') +
103
103
  (opt.alias ? ' ' + opt.alias : ''));
104
104
  if (opt.where !== undefined) {
105
- if (this.constructor._soft && !opt.raw) {
106
- if (typeof opt.where === 'string') {
107
- opt.where = opt.where ? ('(' + opt.where + ') AND ') : '`time_remove` = 0';
108
- }
109
- else if (Array.isArray(opt.where)) {
110
- opt.where.push({
111
- 'time_remove': 0
112
- });
113
- }
114
- else {
115
- opt.where['time_remove'] = 0;
116
- }
117
- }
118
105
  this._sql.where(opt.where);
119
106
  }
120
107
  }
@@ -131,7 +118,9 @@ export default class Mod {
131
118
  * @param opt 选项
132
119
  */
133
120
  static async insert(db, cs, vs, opt = {}) {
134
- const sq = lSql.get(opt.pre);
121
+ const sq = lSql.get(opt.pre, {
122
+ 'service': db.getService() ?? lDb.ESERVICE.PGSQL,
123
+ });
135
124
  if (!vs) {
136
125
  // --- 单行 ---
137
126
  sq.insert(this._$table + (opt.index ? ('_' + opt.index) : ''));
@@ -141,7 +130,7 @@ export default class Mod {
141
130
  lCore.log(opt.pre instanceof sCtr.Ctr ? opt.pre : {}, '[insert, mod] ' + lText.stringifyJson(r.error?.message ?? '').slice(1, -1), '-error');
142
131
  return false;
143
132
  }
144
- return r.packet.affectedRows > 0 ? true : null;
133
+ return r.packet.affected ? true : null;
145
134
  }
146
135
  // --- 可能是多行 ---
147
136
  if (vs.some(item => !Array.isArray(item))) {
@@ -161,7 +150,7 @@ export default class Mod {
161
150
  lCore.log(opt.pre instanceof sCtr.Ctr ? opt.pre : {}, '[insert, mod] ' + lText.stringifyJson(r.error?.message ?? '').slice(1, -1), '-error');
162
151
  return false;
163
152
  }
164
- if (r.packet.affectedRows > 0) {
153
+ if (r.packet.affected) {
165
154
  continue;
166
155
  }
167
156
  return null;
@@ -170,37 +159,18 @@ export default class Mod {
170
159
  }
171
160
  /**
172
161
  * --- 获取添加一个序列的模拟 SQL ---
162
+ * @param db 数据库对象
173
163
  * @param cs 字段列表
174
164
  * @param vs 数据列表
175
165
  * @param opt 选项
176
166
  */
177
- static insertSql(cs, vs, opt = {}) {
178
- const sq = lSql.get(opt.pre);
167
+ static insertSql(db, cs, vs, opt = {}) {
168
+ const sq = lSql.get(opt.pre, {
169
+ 'service': db.getService() ?? lDb.ESERVICE.PGSQL,
170
+ });
179
171
  sq.insert(this._$table + (opt.index ? ('_' + opt.index) : '')).values(cs, vs);
180
172
  return sq.format();
181
173
  }
182
- /**
183
- * --- 插入数据如果唯一键冲突则更新 ---
184
- * @param db 数据库对象
185
- * @param data 要插入的数据
186
- * @param update 要更新的数据
187
- * @param opt 选项
188
- */
189
- static async insertDuplicate(db, data, update, opt = {}) {
190
- const sq = lSql.get(opt.pre);
191
- sq.insert(this._$table + (opt.index ? ('_' + opt.index) : '')).values(data).duplicate(update);
192
- const r = await db.execute(sq.getSql(), sq.getData());
193
- if (r.packet === null) {
194
- lCore.log(opt.pre instanceof sCtr.Ctr ? opt.pre : {}, '[insertDuplicate, mod] ' + lText.stringifyJson(r.error?.message ?? '').slice(1, -1).replace(/"/g, '""'), '-error');
195
- return false;
196
- }
197
- if (r.packet.affectedRows > 0) {
198
- return true;
199
- }
200
- else {
201
- return null;
202
- }
203
- }
204
174
  /**
205
175
  * --- 根据条件移除条目 ---
206
176
  * @param db 数据库对象
@@ -208,36 +178,13 @@ export default class Mod {
208
178
  * @param opt 选项
209
179
  */
210
180
  static async removeByWhere(db, where, opt = {}) {
211
- const tim = lTime.stamp();
212
181
  const indexs = opt.index ? (typeof opt.index === 'string' ? [opt.index] : [...new Set(opt.index)]) : [''];
213
- if (this._$soft && !opt.raw) {
214
- // --- 软删除 ---
215
- if (typeof where === 'string') {
216
- where = '(' + where + ') AND `time_remove` = 0';
217
- }
218
- else if (Array.isArray(where)) {
219
- where.push({
220
- 'time_remove': 0
221
- });
222
- }
223
- else {
224
- where['time_remove'] = 0;
225
- }
226
- }
227
182
  let ar = 0;
228
183
  for (const index of indexs) {
229
- const sq = lSql.get(opt.pre);
230
- if (this._$soft && !opt.raw) {
231
- // --- 软删除 ---
232
- sq.update(this._$table + (index ? ('_' + index) : ''), [{
233
- 'time_remove': tim,
234
- }]);
235
- }
236
- else {
237
- // --- 真删除 ---
238
- sq.delete(this._$table + (index ? ('_' + index) : ''));
239
- }
240
- sq.where(where);
184
+ const sq = lSql.get(opt.pre, {
185
+ 'service': db.getService() ?? lDb.ESERVICE.PGSQL,
186
+ });
187
+ sq.delete(this._$table + (index ? ('_' + index) : '')).where(where);
241
188
  if (opt.by) {
242
189
  sq.by(opt.by[0], opt.by[1]);
243
190
  }
@@ -246,11 +193,11 @@ export default class Mod {
246
193
  }
247
194
  const r = await db.execute(sq.getSql(), sq.getData());
248
195
  if (r.packet === null) {
249
- lCore.log(opt.pre instanceof sCtr.Ctr ? opt.pre : {}, '[removeByWhere, mod] ' + lText.stringifyJson(r.error?.message ?? '').slice(1, -1).replace(/"/g, '""'), '-error');
196
+ lCore.log(opt.pre instanceof sCtr.Ctr ? opt.pre : {}, '[MOD][removeByWhere] ' + lText.stringifyJson(r.error?.message ?? '').slice(1, -1).replace(/"/g, '""'), '-error');
250
197
  return false;
251
198
  }
252
- if (r.packet.affectedRows > 0) {
253
- ar += r.packet.affectedRows;
199
+ if (r.packet.affected) {
200
+ ar += r.packet.affected;
254
201
  }
255
202
  }
256
203
  return ar ? ar : null;
@@ -262,30 +209,10 @@ export default class Mod {
262
209
  * @param opt 选项
263
210
  */
264
211
  static removeByWhereSql(db, where, opt = {}) {
265
- const tim = lTime.stamp();
266
- const sq = lSql.get(opt.pre);
267
- if (this._$soft && !opt.raw) {
268
- // --- 软删除 ---
269
- sq.update(this._$table + (opt.index ? ('_' + opt.index) : ''), [{
270
- 'time_remove': tim
271
- }]);
272
- if (typeof where === 'string') {
273
- where = '(' + where + ') AND `time_remove` = 0';
274
- }
275
- else if (Array.isArray(where)) {
276
- where.push({
277
- 'time_remove': 0
278
- });
279
- }
280
- else {
281
- where['time_remove'] = 0;
282
- }
283
- }
284
- else {
285
- // --- 真删除 ---
286
- sq.delete(this._$table + (opt.index ? ('_' + opt.index) : ''));
287
- }
288
- sq.where(where);
212
+ const sq = lSql.get(opt.pre, {
213
+ 'service': db.getService() ?? lDb.ESERVICE.PGSQL,
214
+ });
215
+ sq.delete(this._$table + (opt.index ? ('_' + opt.index) : '')).where(where);
289
216
  if (opt.by) {
290
217
  sq.by(opt.by[0], opt.by[1]);
291
218
  }
@@ -303,24 +230,12 @@ export default class Mod {
303
230
  */
304
231
  static async updateByWhere(db, data, where, opt = {}) {
305
232
  const indexs = opt.index ? (typeof opt.index === 'string' ? [opt.index] : [...new Set(opt.index)]) : [''];
306
- if (this._$soft && !opt.raw) {
307
- if (typeof where === 'string') {
308
- where = '(' + where + ') AND `time_remove` = 0';
309
- }
310
- else if (Array.isArray(where)) {
311
- where.push({
312
- 'time_remove': 0
313
- });
314
- }
315
- else {
316
- where['time_remove'] = 0;
317
- }
318
- }
319
233
  let ar = 0;
320
234
  for (const index of indexs) {
321
- const sq = lSql.get(opt.pre);
322
- sq.update(this._$table + (index ? ('_' + index) : ''), data);
323
- sq.where(where);
235
+ const sq = lSql.get(opt.pre, {
236
+ 'service': db.getService() ?? lDb.ESERVICE.PGSQL,
237
+ });
238
+ sq.update(this._$table + (index ? ('_' + index) : ''), data).where(where);
324
239
  if (opt.by) {
325
240
  sq.by(opt.by[0], opt.by[1]);
326
241
  }
@@ -329,38 +244,27 @@ export default class Mod {
329
244
  }
330
245
  const r = await db.execute(sq.getSql(), sq.getData());
331
246
  if (r.packet === null) {
332
- lCore.log(opt.pre instanceof sCtr.Ctr ? opt.pre : {}, '[updateByWhere, mod] ' + lText.stringifyJson(r.error?.message ?? '').slice(1, -1).replace(/"/g, '""'), '-error');
247
+ lCore.log(opt.pre instanceof sCtr.Ctr ? opt.pre : {}, '[MOD][updateByWhere] ' + lText.stringifyJson(r.error?.message ?? '').slice(1, -1).replace(/"/g, '""'), '-error');
333
248
  return false;
334
249
  }
335
- if (r.packet.affectedRows > 0) {
336
- ar += r.packet.affectedRows;
250
+ if (r.packet.affected) {
251
+ ar += r.packet.affected;
337
252
  }
338
253
  }
339
254
  return ar ? ar : null;
340
255
  }
341
256
  /**
342
257
  * --- 根据条件更新数据(仅获取 SQL 对象) ---
258
+ * @param db 数据库对象
343
259
  * @param data 要更新的数据
344
260
  * @param where 筛选条件
345
261
  * @param opt 选项
346
262
  */
347
- static updateByWhereSql(data, where, opt = {}) {
348
- const sq = lSql.get(opt.pre);
349
- sq.update(this._$table + (opt.index ? ('_' + opt.index) : ''), data);
350
- if (this._$soft && !opt.raw) {
351
- if (typeof where === 'string') {
352
- where = '(' + where + ') AND `time_remove` = 0';
353
- }
354
- else if (Array.isArray(where)) {
355
- where.push({
356
- 'time_remove': 0
357
- });
358
- }
359
- else {
360
- where['time_remove'] = 0;
361
- }
362
- }
363
- sq.where(where);
263
+ static updateByWhereSql(db, data, where, opt = {}) {
264
+ const sq = lSql.get(opt.pre, {
265
+ 'service': db.getService() ?? lDb.ESERVICE.PGSQL,
266
+ });
267
+ sq.update(this._$table + (opt.index ? ('_' + opt.index) : ''), data).where(where);
364
268
  if (opt.by) {
365
269
  sq.by(opt.by[0], opt.by[1]);
366
270
  }
@@ -504,23 +408,9 @@ export default class Mod {
504
408
  * @param opt 选项
505
409
  */
506
410
  static async primarys(db, where = '', opt = {}) {
507
- const sq = lSql.get(opt.pre ?? opt.ctr);
508
- if (this._$soft && !opt.raw) {
509
- // --- 不包含已删除 ---
510
- if (typeof where === 'string') {
511
- if (where !== '') {
512
- where = '(' + where + ') AND `time_remove` = 0';
513
- }
514
- }
515
- else if (Array.isArray(where)) {
516
- where.push({
517
- 'time_remove': 0
518
- });
519
- }
520
- else {
521
- where['time_remove'] = 0;
522
- }
523
- }
411
+ const sq = lSql.get(opt.pre ?? opt.ctr, {
412
+ 'service': db.getService() ?? lDb.ESERVICE.PGSQL,
413
+ });
524
414
  sq.select(this._$primary, this._$table + (opt.index ? ('_' + opt.index) : '')).where(where);
525
415
  const r = await db.query(sq.getSql(), sq.getData());
526
416
  if (r.rows === null) {
@@ -585,16 +475,13 @@ export default class Mod {
585
475
  }
586
476
  /**
587
477
  * --- 创建数据 ---
588
- * @param notWhere 若要不存在才成功,则要传入限定条件
589
- * @param table 可对限定条件传入适当的表
590
478
  */
591
- async create(notWhere, table) {
479
+ async create() {
592
480
  const cstr = this.constructor;
593
481
  const updates = {};
594
482
  for (const k in this._updates) {
595
483
  updates[k] = this._data[k];
596
484
  }
597
- table ??= cstr._$table + (this._index ? ('_' + this._index[0]) : '');
598
485
  let r = null;
599
486
  if ((cstr._$key !== '') && (updates[cstr._$key] === undefined)) {
600
487
  let count = 0;
@@ -606,12 +493,7 @@ export default class Mod {
606
493
  this._data[cstr._$key] = updates[cstr._$key];
607
494
  this[cstr._$key] = updates[cstr._$key];
608
495
  this._sql.insert(cstr._$table + (this._index ? ('_' + this._index[0]) : ''));
609
- if (notWhere) {
610
- this._sql.notExists(table, updates, notWhere);
611
- }
612
- else {
613
- this._sql.values(updates);
614
- }
496
+ this._sql.values(updates);
615
497
  r = await this._db.execute(this._sql.getSql(), this._sql.getData());
616
498
  ++count;
617
499
  if (!r.error) {
@@ -623,63 +505,45 @@ export default class Mod {
623
505
  // --- 没设置 index,那就当做是本次生成的 key 重复了 ---
624
506
  continue;
625
507
  }
626
- const match = /for key '([\w.]+)'/.exec(r.error.message);
627
- if (match?.[1].includes(cstr._$index)) {
628
- // --- 确实重复了 ---
629
- continue;
508
+ if (this._db.getService() === lDb.ESERVICE.MYSQL) {
509
+ // --- MYSQL ---
510
+ const match = /for key '([\w.]+)'/.exec(r.error.message);
511
+ if (match?.[1].includes(cstr._$index)) {
512
+ continue;
513
+ }
514
+ }
515
+ else {
516
+ // --- PGSQL ---
517
+ const match = /constraint "([\w.]+)"/.exec(r.error.message);
518
+ if (match?.[1].includes(cstr._$index)) {
519
+ continue;
520
+ }
630
521
  }
631
522
  // --- 1062 非 index 冲突,那需要用户自行处理(可能不允许重复的邮箱) ---
632
523
  return false;
633
524
  }
634
525
  // --- 未处理的错误 ---
635
- lCore.log(this._ctr ?? {}, '[create0, mod] [' + table + '] ' + lText.stringifyJson(r.error?.message ?? '').slice(1, -1).replace(/"/g, '""'), '-error');
526
+ const service = this._db.getService();
527
+ lCore.debug('[MOD][create0][' + cstr._$table + ']', service !== null ? lDb.ESERVICE[service] : 'NONE', r);
528
+ lCore.log(this._ctr ?? {}, '[MOD][create0][' + cstr._$table + '] ' + lText.stringifyJson(r.error?.message ?? '').slice(1, -1).replace(/"/g, '""'), '-error');
636
529
  return false;
637
530
  }
638
531
  }
639
532
  else {
640
533
  this._sql.insert(cstr._$table + (this._index ? ('_' + this._index[0]) : ''));
641
- if (notWhere) {
642
- this._sql.notExists(table, updates, notWhere);
643
- }
644
- else {
645
- this._sql.values(updates);
646
- }
534
+ this._sql.values(updates);
647
535
  r = await this._db.execute(this._sql.getSql(), this._sql.getData());
648
536
  if (r.error) {
649
537
  if (r.error.errno !== 1062) {
650
- lCore.log(this._ctr ?? {}, '[create1, mod] [' + table + '] ' + lText.stringifyJson(r.error?.message ?? '').slice(1, -1).replace(/"/g, '""'), '-error');
538
+ lCore.debug('[MOD][create1][' + cstr._$table + ']', r);
539
+ lCore.log(this._ctr ?? {}, '[MOD][create1][' + cstr._$table + '] ' + lText.stringifyJson(r.error?.message ?? '').slice(1, -1).replace(/"/g, '""'), '-error');
651
540
  }
652
541
  return false;
653
542
  }
654
543
  }
655
- if (r?.packet?.affectedRows && r?.packet?.affectedRows > 0) {
544
+ if (r.packet?.affected) {
656
545
  this._updates = {};
657
- this._data[cstr._$primary] = r.packet.insertId;
658
- this[cstr._$primary] = this._data[cstr._$primary];
659
- return true;
660
- }
661
- else {
662
- return false;
663
- }
664
- }
665
- /**
666
- * --- 唯一键冲突则替换,不冲突则创建数据 ---
667
- */
668
- async replace() {
669
- const cstr = this.constructor;
670
- const updates = {};
671
- for (const k in this._updates) {
672
- updates[k] = this._data[k];
673
- }
674
- this._sql.replace(cstr._$table + (this._index ? ('_' + this._index[0]) : '')).values(updates);
675
- const r = await this._db.execute(this._sql.getSql(), this._sql.getData());
676
- if (r.packet === null) {
677
- lCore.log(this._ctr ?? {}, '[replace, mod] ' + lText.stringifyJson(r.error?.message ?? '').slice(1, -1).replace(/"/g, '""'), '-error');
678
- return false;
679
- }
680
- if (r.packet.affectedRows > 0) {
681
- this._updates = {};
682
- this._data[cstr._$primary] = r.packet.insertId;
546
+ this._data[cstr._$primary] = r.packet.insert;
683
547
  this[cstr._$primary] = this._data[cstr._$primary];
684
548
  return true;
685
549
  }
@@ -734,7 +598,7 @@ export default class Mod {
734
598
  lCore.log(this._ctr ?? {}, '[save, mod] ' + lText.stringifyJson(r.error?.message ?? '').slice(1, -1).replace(/"/g, '""'), '-error');
735
599
  return false;
736
600
  }
737
- if (r.packet.affectedRows > 0) {
601
+ if (r.packet.affected) {
738
602
  this._updates = {};
739
603
  return true;
740
604
  }
@@ -744,30 +608,18 @@ export default class Mod {
744
608
  }
745
609
  /**
746
610
  * --- 移除本条目 ---
747
- * @param raw 是否真实移除
748
611
  */
749
- async remove(raw = false) {
750
- const tim = lTime.stamp();
612
+ async remove() {
751
613
  const cstr = this.constructor;
752
- if (cstr._$soft && !raw) {
753
- this._sql.update(cstr._$table + (this._index ? ('_' + this._index[0]) : ''), [{
754
- 'time_remove': tim
755
- }]).where([{
756
- [cstr._$primary]: this._data[cstr._$primary],
757
- 'time_remove': 0
758
- }]);
759
- }
760
- else {
761
- this._sql.delete(cstr._$table + (this._index ? ('_' + this._index[0]) : '')).where([{
762
- [cstr._$primary]: this._data[cstr._$primary]
763
- }]);
764
- }
614
+ this._sql.delete(cstr._$table + (this._index ? ('_' + this._index[0]) : '')).where([{
615
+ [cstr._$primary]: this._data[cstr._$primary]
616
+ }]);
765
617
  const r = await this._db.execute(this._sql.getSql(), this._sql.getData());
766
618
  if (r.packet === null) {
767
619
  lCore.log(this._ctr ?? {}, '[remove, mod] ' + lText.stringifyJson(r.error?.message ?? '').slice(1, -1).replace(/"/g, '""'), '-error');
768
620
  return false;
769
621
  }
770
- if (r.packet.affectedRows > 0) {
622
+ if (r.packet.affected) {
771
623
  return true;
772
624
  }
773
625
  else {
@@ -888,7 +740,7 @@ export default class Mod {
888
740
  for (let i = 0; i < this._index.length; ++i) {
889
741
  // --- 先计算 total ---
890
742
  if (i > 0) {
891
- sql = sql.replace(/(FROM [a-zA-Z0-9`_.]+?_)[0-9_]+/, '$1' + this._index[i]);
743
+ sql = sql.replace(/(FROM [a-zA-Z0-9`"_.]+?_)[0-9_]+/, '$1' + this._index[i]);
892
744
  }
893
745
  const tsql = this._formatTotal(sql);
894
746
  const tr = await this._db.query(tsql, this._sql.getData());
@@ -914,10 +766,10 @@ export default class Mod {
914
766
  continue;
915
767
  }
916
768
  }
917
- const lsql = sql.replace(/ LIMIT [0-9 ,]/g, ` LIMIT ${cz}, ${remain}`);
769
+ const lsql = sql.replace(/ LIMIT [0-9 ,]+(OFFSET [0-9]+)?/g, ` LIMIT ${remain} OFFSET ${cz}`);
918
770
  const r = await this._db.query(lsql, this._sql.getData());
919
771
  if (r.rows === null) {
920
- lCore.log(this._ctr ?? {}, '[all, mod] ' + lText.stringifyJson(r.error?.message ?? '').slice(1, -1).replace(/"/g, '""'), '-error');
772
+ lCore.log(this._ctr ?? {}, '[MOD][all] ' + lText.stringifyJson(r.error?.message ?? '').slice(1, -1).replace(/"/g, '""'), '-error');
921
773
  return false;
922
774
  }
923
775
  if (key) {
@@ -927,7 +779,7 @@ export default class Mod {
927
779
  'ctr': this._ctr,
928
780
  'pre': this._sql.getPre(),
929
781
  'row': row,
930
- 'index': this._index
782
+ 'index': this._index,
931
783
  });
932
784
  list[row[key]] = obj;
933
785
  --remain;
@@ -940,7 +792,7 @@ export default class Mod {
940
792
  'ctr': this._ctr,
941
793
  'pre': this._sql.getPre(),
942
794
  'row': row,
943
- 'index': this._index
795
+ 'index': this._index,
944
796
  });
945
797
  list.push(obj);
946
798
  --remain;
@@ -954,7 +806,7 @@ export default class Mod {
954
806
  const contain = this._contain ? lCore.clone(this._contain.list) : null;
955
807
  const r = await this._db.query(this._sql.getSql(), this._sql.getData());
956
808
  if (r.rows === null) {
957
- lCore.log(this._ctr ?? {}, '[all, mod] ' + lText.stringifyJson(r.error?.message ?? '').slice(1, -1).replace(/"/g, '""'), '-error');
809
+ lCore.log(this._ctr ?? {}, '[MOD][all] ' + lText.stringifyJson(r.error?.message ?? '').slice(1, -1).replace(/"/g, '""'), '-error');
958
810
  return false;
959
811
  }
960
812
  // --- 检查没被查到的必包含项 ---
@@ -983,7 +835,7 @@ export default class Mod {
983
835
  'ctr': this._ctr,
984
836
  'pre': this._sql.getPre(),
985
837
  'row': row,
986
- 'index': this._index
838
+ 'index': this._index,
987
839
  });
988
840
  list[row[key]] = obj;
989
841
  }
@@ -995,7 +847,7 @@ export default class Mod {
995
847
  'ctr': this._ctr,
996
848
  'pre': this._sql.getPre(),
997
849
  'row': crow,
998
- 'index': this._index
850
+ 'index': this._index,
999
851
  });
1000
852
  list[crow[key]] = obj;
1001
853
  }
@@ -1048,7 +900,7 @@ export default class Mod {
1048
900
  for (let i = 0; i < this._index.length; ++i) {
1049
901
  // --- 先计算 total ---
1050
902
  if (i > 0) {
1051
- sql = sql.replace(/(FROM [a-zA-Z0-9`_.]+?_)[0-9_]+/, '$1' + this._index[i]);
903
+ sql = sql.replace(/(FROM [a-zA-Z0-9`"_.]+?_)[0-9_]+/, '$1' + this._index[i]);
1052
904
  }
1053
905
  const tsql = this._formatTotal(sql);
1054
906
  const tr = await this._db.query(tsql, this._sql.getData());
@@ -1076,10 +928,10 @@ export default class Mod {
1076
928
  // --- 在本表开始找之后,后面表无需再跳过 ---
1077
929
  offset = -1;
1078
930
  }
1079
- const lsql = sql.replace(/ LIMIT [0-9 ,]+/g, ` LIMIT ${cz}, ${remain}`);
931
+ const lsql = sql.replace(/ LIMIT [0-9 ,]+(OFFSET [0-9]+)?/g, ` LIMIT ${remain} OFFSET ${cz}`);
1080
932
  const r = await this._db.query(lsql, this._sql.getData());
1081
933
  if (r.rows === null) {
1082
- lCore.log(this._ctr ?? {}, '[allArray, mod] ' + lText.stringifyJson(r.error?.message ?? '').slice(1, -1).replace(/"/g, '""'), '-error');
934
+ lCore.log(this._ctr ?? {}, '[MOD][allArray] ' + lText.stringifyJson(r.error?.message ?? '').slice(1, -1).replace(/"/g, '""'), '-error');
1083
935
  return false;
1084
936
  }
1085
937
  if (key) {
@@ -1101,7 +953,7 @@ export default class Mod {
1101
953
  const contain = this._contain ? lCore.clone(this._contain.list) : null;
1102
954
  const r = await this._db.query(this._sql.getSql(), this._sql.getData());
1103
955
  if (r.rows === null) {
1104
- lCore.log(this._ctr ?? {}, '[allArray, mod] ' + lText.stringifyJson(r.error?.message ?? '').slice(1, -1).replace(/"/g, '""'), '-error');
956
+ lCore.log(this._ctr ?? {}, '[MOD][allArray] ' + lText.stringifyJson(r.error?.message ?? '').slice(1, -1).replace(/"/g, '""'), '-error');
1105
957
  return false;
1106
958
  }
1107
959
  // --- 检查没被查到的必包含项 ---
@@ -1144,32 +996,40 @@ export default class Mod {
1144
996
  return r.rows;
1145
997
  }
1146
998
  /**
1147
- * --- 获取数查询(SELECT)扫描情况,获取字符串或kv数组 ---
999
+ * --- 获取数查询(SELECT)扫描情况,获取字符串或对象 ---
1148
1000
  * @param all 是否获取完全的情况,默认不获取,只返回扫描情况
1149
1001
  */
1150
1002
  async explain(all = false) {
1151
1003
  const r = await this._db.query('EXPLAIN ' + this._sql.getSql(), this._sql.getData());
1152
1004
  if (r.rows === null) {
1153
- lCore.log(this._ctr ?? {}, '[explain, mod] ' + lText.stringifyJson(r.error?.message ?? '').slice(1, -1).replace(/"/g, '""'), '-error');
1005
+ lCore.log(this._ctr ?? {}, '[MOD][explain] ' + lText.stringifyJson(r.error?.message ?? '').slice(1, -1).replace(/"/g, '""'), '-error');
1154
1006
  return false;
1155
1007
  }
1156
1008
  if (!r.rows[0]) {
1157
1009
  return false;
1158
1010
  }
1159
1011
  if (!all) {
1160
- return r.rows[0].type;
1161
- }
1162
- return r.rows[0];
1012
+ return this._db.getService() === lDb.ESERVICE.MYSQL ?
1013
+ r.rows[0].type :
1014
+ r.rows[0]['QUERY PLAN'];
1015
+ }
1016
+ return this._db.getService() === lDb.ESERVICE.MYSQL ?
1017
+ r.rows[0] :
1018
+ {
1019
+ 'scan': r.rows[0]['QUERY PLAN'],
1020
+ 'filter': r.rows[1]['QUERY PLAN'],
1021
+ };
1163
1022
  }
1164
1023
  _formatTotal(sql, f = '*') {
1024
+ const q = this._db.getService() === lDb.ESERVICE.MYSQL ? '`' : '"';
1165
1025
  sql = sql
1166
- .replace(/ LIMIT [0-9 ,]+/g, '')
1167
- .replace(/ ORDER BY [\w`,. ]+(DESC|ASC)?/g, '');
1026
+ .replace(/ LIMIT [0-9 ,]+(OFFSET [0-9]+)?/g, '')
1027
+ .replace(/ ORDER BY [\w`",. ]+(DESC|ASC)?/g, '');
1168
1028
  if (sql.includes(' GROUP BY ')) {
1169
1029
  return 'SELECT COUNT(0) AS `count` FROM(' + sql + ') AS `f`';
1170
1030
  }
1171
1031
  return sql
1172
- .replace(/SELECT .+? FROM/g, 'SELECT COUNT(' + this._sql.field(f) + ') AS `count` FROM');
1032
+ .replace(/SELECT .+? FROM/g, `SELECT COUNT(${this._sql.field(f)}) AS ${q}count${q} FROM`);
1173
1033
  }
1174
1034
  /**
1175
1035
  * --- 获取总条数,自动抛弃 LIMIT,仅用于获取数据的情况(select) ---
@@ -1185,7 +1045,7 @@ export default class Mod {
1185
1045
  const sql = this._formatTotal(this._sql.getSql(), f);
1186
1046
  const r = await this._db.query(sql, this._sql.getData());
1187
1047
  if (r.rows === null) {
1188
- lCore.log(this._ctr ?? {}, '[total, mod] ' + lText.stringifyJson(r.error?.message ?? '').slice(1, -1).replace(/"/g, '""'), '-error');
1048
+ lCore.log(this._ctr ?? {}, '[MOD][total] ' + lText.stringifyJson(r.error?.message ?? '').slice(1, -1).replace(/"/g, '""'), '-error');
1189
1049
  return 0;
1190
1050
  }
1191
1051
  let count = 0;
@@ -1198,10 +1058,12 @@ export default class Mod {
1198
1058
  * --- 根据当前条件,筛选出当前条目该有的数据条数 ---
1199
1059
  */
1200
1060
  async count() {
1201
- const sql = this._sql.getSql().replace(/SELECT .+? FROM/, 'SELECT COUNT(0) AS `count` FROM');
1061
+ const sql = this._sql.getSql().replace(/SELECT .+? FROM/, this._db.getService() === lDb.ESERVICE.MYSQL ?
1062
+ 'SELECT COUNT(0) AS `count` FROM' :
1063
+ 'SELECT COUNT(0) AS "count" FROM');
1202
1064
  const r = await this._db.query(sql, this._sql.getData());
1203
1065
  if (r.rows === null) {
1204
- lCore.log(this._ctr ?? {}, '[count, mod] ' + lText.stringifyJson(r.error?.message ?? '').slice(1, -1).replace(/"/g, '""'), '-error');
1066
+ lCore.log(this._ctr ?? {}, '[MOD][count] ' + lText.stringifyJson(r.error?.message ?? '').slice(1, -1).replace(/"/g, '""'), '-error');
1205
1067
  return 0;
1206
1068
  }
1207
1069
  let count = 0;
@@ -1214,7 +1076,8 @@ export default class Mod {
1214
1076
  * --- 获取当前条件下的 count 的 SQL 语句 ---
1215
1077
  */
1216
1078
  countSql() {
1217
- const sql = this._sql.getSql().replace(/SELECT .+? FROM/, 'SELECT COUNT(0) AS `count` FROM');
1079
+ const sql = this._sql.getSql().replace(/SELECT .+? FROM/, this._db.getService() === lDb.ESERVICE.MYSQL ?
1080
+ 'SELECT COUNT(0) AS `count` FROM' : 'SELECT COUNT(0) AS "count" FROM');
1218
1081
  return this._sql.format(sql, this._sql.getData());
1219
1082
  }
1220
1083
  /**
@@ -1291,21 +1154,7 @@ export default class Mod {
1291
1154
  * @param s 筛选条件数组或字符串
1292
1155
  * @param raw 是否包含已被软删除的数据
1293
1156
  */
1294
- filter(s, raw = false) {
1295
- const cstr = this.constructor;
1296
- if (cstr._soft && !raw) {
1297
- if (typeof s === 'string') {
1298
- s = '(' + s + ') AND `time_remove` = 0';
1299
- }
1300
- else if (Array.isArray(s)) {
1301
- s.push({
1302
- 'time_remove': 0
1303
- });
1304
- }
1305
- else {
1306
- s['time_remove'] = 0;
1307
- }
1308
- }
1157
+ filter(s) {
1309
1158
  this._sql.where(s);
1310
1159
  return this;
1311
1160
  }
@@ -1314,8 +1163,8 @@ export default class Mod {
1314
1163
  * @param s 筛选条件数组或字符串
1315
1164
  * @param raw 是否包含已被软删除的数据
1316
1165
  */
1317
- where(s, raw = false) {
1318
- return this.filter(s, raw);
1166
+ where(s) {
1167
+ return this.filter(s);
1319
1168
  }
1320
1169
  /**
1321
1170
  * --- ORDER BY ---