@maiyunnet/kebab 2.0.7 → 2.0.8

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.
Files changed (83) hide show
  1. package/index.d.ts +11 -1
  2. package/index.js +13 -1
  3. package/lib/buffer.d.ts +25 -0
  4. package/lib/buffer.js +30 -5
  5. package/lib/captcha.d.ts +15 -0
  6. package/lib/captcha.js +20 -0
  7. package/lib/consistent.d.ts +51 -0
  8. package/lib/consistent.js +59 -0
  9. package/lib/core.d.ts +134 -0
  10. package/lib/core.js +176 -0
  11. package/lib/crypto.d.ts +75 -6
  12. package/lib/crypto.js +206 -38
  13. package/lib/db.d.ts +104 -0
  14. package/lib/db.js +126 -0
  15. package/lib/dns.d.ts +51 -0
  16. package/lib/dns.js +54 -2
  17. package/lib/fs.d.ts +100 -0
  18. package/lib/fs.js +118 -0
  19. package/lib/jwt.d.ts +43 -0
  20. package/lib/jwt.js +45 -0
  21. package/lib/kv.d.ts +362 -0
  22. package/lib/kv.js +377 -0
  23. package/lib/lan.d.ts +6 -0
  24. package/lib/lan.js +7 -0
  25. package/lib/net/formdata.d.ts +38 -0
  26. package/lib/net/formdata.js +43 -0
  27. package/lib/net/request.d.ts +62 -0
  28. package/lib/net/request.js +57 -0
  29. package/lib/net/response.d.ts +21 -0
  30. package/lib/net/response.js +16 -0
  31. package/lib/net.d.ts +86 -0
  32. package/lib/net.js +140 -0
  33. package/lib/s3.d.ts +52 -0
  34. package/lib/s3.js +51 -0
  35. package/lib/scan.d.ts +52 -0
  36. package/lib/scan.js +84 -0
  37. package/lib/session.d.ts +31 -0
  38. package/lib/session.js +52 -1
  39. package/lib/sql.d.ts +176 -0
  40. package/lib/sql.js +287 -2
  41. package/lib/ssh/sftp.d.ts +106 -0
  42. package/lib/ssh/sftp.js +106 -0
  43. package/lib/ssh/shell.d.ts +37 -0
  44. package/lib/ssh/shell.js +31 -0
  45. package/lib/ssh.d.ts +32 -0
  46. package/lib/ssh.js +32 -0
  47. package/lib/text.d.ts +131 -0
  48. package/lib/text.js +188 -0
  49. package/lib/time.d.ts +53 -0
  50. package/lib/time.js +55 -0
  51. package/lib/ws.d.ts +68 -0
  52. package/lib/ws.js +74 -0
  53. package/lib/zip.d.ts +53 -0
  54. package/lib/zip.js +73 -0
  55. package/lib/zlib.d.ts +76 -0
  56. package/lib/zlib.js +78 -0
  57. package/main.d.ts +6 -1
  58. package/main.js +11 -1
  59. package/package.json +1 -1
  60. package/sys/child.js +104 -0
  61. package/sys/cmd.js +28 -0
  62. package/sys/ctr.d.ts +166 -0
  63. package/sys/ctr.js +177 -0
  64. package/sys/master.js +63 -0
  65. package/sys/mod.d.ts +266 -0
  66. package/sys/mod.js +335 -0
  67. package/sys/route.d.ts +34 -0
  68. package/sys/route.js +164 -0
  69. package/www/example/ctr/test.d.ts +3 -0
  70. package/www/example/ctr/test.js +63 -1
  71. package/www/example/mod/test.js +14 -0
  72. package/www/example/mod/testdata.js +9 -0
  73. package/www/example/ws/test.js +1 -0
  74. package/.VSCodeCounter/2025-02-14_14-46-44/details.md +0 -82
  75. package/.VSCodeCounter/2025-02-14_14-46-44/diff-details.md +0 -15
  76. package/.VSCodeCounter/2025-02-14_14-46-44/diff.csv +0 -2
  77. package/.VSCodeCounter/2025-02-14_14-46-44/diff.md +0 -19
  78. package/.VSCodeCounter/2025-02-14_14-46-44/diff.txt +0 -22
  79. package/.VSCodeCounter/2025-02-14_14-46-44/results.csv +0 -69
  80. package/.VSCodeCounter/2025-02-14_14-46-44/results.json +0 -1
  81. package/.VSCodeCounter/2025-02-14_14-46-44/results.md +0 -48
  82. package/.VSCodeCounter/2025-02-14_14-46-44/results.txt +0 -118
  83. package/.vscode/tasks.json +0 -15
package/sys/mod.js CHANGED
@@ -33,22 +33,31 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
+ /**
37
+ * Project: Mutton, User: JianSuoQiYue
38
+ * Date: 2019-6-4 21:35
39
+ * 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
40
+ */
36
41
  const lSql = __importStar(require("../lib/sql"));
37
42
  const lTime = __importStar(require("../lib/time"));
38
43
  const lCore = __importStar(require("../lib/core"));
39
44
  const lText = __importStar(require("../lib/text"));
40
45
  const sCtr = __importStar(require("../sys/ctr"));
46
+ /** --- 条数列表 --- */
41
47
  class Rows {
42
48
  constructor(initialItems = []) {
43
49
  this._items = [];
44
50
  this._items = initialItems;
45
51
  }
52
+ /** --- 总行数 --- */
46
53
  get length() {
47
54
  return this._items.length;
48
55
  }
56
+ /** --- 通过索引获取一个对象 --- */
49
57
  item(index) {
50
58
  return this._items[index];
51
59
  }
60
+ /** --- 转换为数组对象 --- */
52
61
  toArray() {
53
62
  const arr = [];
54
63
  for (const item of this._items) {
@@ -56,6 +65,7 @@ class Rows {
56
65
  }
57
66
  return arr;
58
67
  }
68
+ /** --- 根据规则筛掉项,predicate 返回 true 代表保留 --- */
59
69
  filter(predicate) {
60
70
  const items = [];
61
71
  for (let i = 0; i < this._items.length; ++i) {
@@ -66,6 +76,7 @@ class Rows {
66
76
  }
67
77
  return new Rows(items);
68
78
  }
79
+ /** --- 重塑对象内容 --- */
69
80
  map(allbackfn) {
70
81
  const items = [];
71
82
  for (let i = 0; i < this._items.length; ++i) {
@@ -93,17 +104,35 @@ class Rows {
93
104
  };
94
105
  }
95
106
  }
107
+ /**
108
+ * --- 开启软更需要在表添加字段:ALTER TABLE `table_name` ADD `time_remove` bigint NOT NULL DEFAULT '0' AFTER `xxx`; ---
109
+ */
96
110
  class Mod {
111
+ /**
112
+ * --- 构造函数 ---
113
+ * @param ctr Ctr 对象
114
+ * @param opt 选项
115
+ */
97
116
  constructor(opt) {
117
+ /** --- 要 update 的内容 --- */
98
118
  this._updates = {};
119
+ /** --- 模型获取的属性 --- */
99
120
  this._data = {};
121
+ /** --- 当前选择的分表 _ 后缀,多个代表联查 --- */
100
122
  this._index = null;
123
+ /** --- 必须追加的数据筛选 key 与 values,仅单表模式有效 --- */
101
124
  this._contain = null;
125
+ /** --- 已算出的 total --- */
102
126
  this._total = [];
127
+ /** --- ctr 对象, Mutton: false, Kebab: true --- */
103
128
  this._ctr = undefined;
129
+ /** --- 设置的 limit --- */
104
130
  this._limit = [0, 0];
131
+ /** --- 导入 ctr 对象 --- */
105
132
  this._ctr = opt.ctr;
133
+ /** --- 导入数据库连接 --- */
106
134
  this._db = opt.db;
135
+ /** --- 新建 sql 对象 --- */
107
136
  this._sql = lSql.get(opt.pre ?? opt.ctr);
108
137
  if (opt.index) {
109
138
  this._index = typeof opt.index === 'string' ? [opt.index] : [...new Set(opt.index)];
@@ -111,6 +140,7 @@ class Mod {
111
140
  if (opt.contain) {
112
141
  this._contain = opt.contain;
113
142
  }
143
+ // --- 第三个参数用于内部数据导入,将 data 数据合并到本实例化类 ---
114
144
  if (opt.row) {
115
145
  for (const k in opt.row) {
116
146
  const v = opt.row[k];
@@ -118,6 +148,7 @@ class Mod {
118
148
  this[k] = v;
119
149
  }
120
150
  }
151
+ /** --- 是否有 select --- */
121
152
  const select = opt.select ?? (opt.where ? '*' : '');
122
153
  if (select) {
123
154
  this._sql.select(select, this.constructor._$table +
@@ -141,9 +172,18 @@ class Mod {
141
172
  this._sql.where(opt.where);
142
173
  }
143
174
  }
175
+ // --- 静态方法 ---
176
+ /** --- 创建字段对象 --- */
144
177
  static column(field) {
145
178
  return lSql.column(field);
146
179
  }
180
+ /**
181
+ * --- 添加一个序列 ---
182
+ * @param db 数据库对象
183
+ * @param cs 字段列表
184
+ * @param vs 数据列表
185
+ * @param opt 选项
186
+ */
147
187
  static async insert(db, cs, vs, opt = {}) {
148
188
  const sq = lSql.get(opt.pre);
149
189
  sq.insert(this._$table + (opt.index ? ('_' + opt.index) : '')).values(cs, vs);
@@ -167,11 +207,24 @@ class Mod {
167
207
  return null;
168
208
  }
169
209
  }
210
+ /**
211
+ * --- 获取添加一个序列的模拟 SQL ---
212
+ * @param cs 字段列表
213
+ * @param vs 数据列表
214
+ * @param opt 选项
215
+ */
170
216
  static insertSql(cs, vs, opt = {}) {
171
217
  const sq = lSql.get(opt.pre);
172
218
  sq.insert(this._$table + (opt.index ? ('_' + opt.index) : '')).values(cs, vs);
173
219
  return sq.format();
174
220
  }
221
+ /**
222
+ * --- 插入数据如果唯一键冲突则更新 ---
223
+ * @param db 数据库对象
224
+ * @param data 要插入的数据
225
+ * @param update 要更新的数据
226
+ * @param opt 选项
227
+ */
175
228
  static async insertDuplicate(db, data, update, opt = {}) {
176
229
  const sq = lSql.get(opt.pre);
177
230
  sq.insert(this._$table + (opt.index ? ('_' + opt.index) : '')).values(data).duplicate(update);
@@ -195,10 +248,17 @@ class Mod {
195
248
  return null;
196
249
  }
197
250
  }
251
+ /**
252
+ * --- 根据条件移除条目 ---
253
+ * @param db 数据库对象
254
+ * @param where 筛选条件
255
+ * @param opt 选项
256
+ */
198
257
  static async removeByWhere(db, where, opt = {}) {
199
258
  const tim = lTime.stamp();
200
259
  const sq = lSql.get(opt.pre);
201
260
  if (this._$soft && !opt.raw) {
261
+ // --- 软删除 ---
202
262
  sq.update(this._$table + (opt.index ? ('_' + opt.index) : ''), [{
203
263
  'time_remove': tim
204
264
  }]);
@@ -215,6 +275,7 @@ class Mod {
215
275
  }
216
276
  }
217
277
  else {
278
+ // --- 真删除 ---
218
279
  sq.delete(this._$table + (opt.index ? ('_' + opt.index) : ''));
219
280
  }
220
281
  sq.where(where);
@@ -242,10 +303,17 @@ class Mod {
242
303
  }
243
304
  return null;
244
305
  }
306
+ /**
307
+ * --- 根据条件移除条目(仅获取 SQL 对象) ---
308
+ * @param db 数据库对象
309
+ * @param where 筛选条件
310
+ * @param opt 选项
311
+ */
245
312
  static removeByWhereSql(db, where, opt = {}) {
246
313
  const tim = lTime.stamp();
247
314
  const sq = lSql.get(opt.pre);
248
315
  if (this._$soft && !opt.raw) {
316
+ // --- 软删除 ---
249
317
  sq.update(this._$table + (opt.index ? ('_' + opt.index) : ''), [{
250
318
  'time_remove': tim
251
319
  }]);
@@ -262,6 +330,7 @@ class Mod {
262
330
  }
263
331
  }
264
332
  else {
333
+ // --- 真删除 ---
265
334
  sq.delete(this._$table + (opt.index ? ('_' + opt.index) : ''));
266
335
  }
267
336
  sq.where(where);
@@ -273,6 +342,13 @@ class Mod {
273
342
  }
274
343
  return sq;
275
344
  }
345
+ /**
346
+ * --- 根据条件更新数据 ---
347
+ * @param db 数据库对象
348
+ * @param data 要更新的数据
349
+ * @param where 筛选条件
350
+ * @param opt 选项
351
+ */
276
352
  static async updateByWhere(db, data, where, opt = {}) {
277
353
  if (typeof opt.index === 'string') {
278
354
  opt.index = [opt.index];
@@ -323,6 +399,12 @@ class Mod {
323
399
  }
324
400
  return ar ? ar : null;
325
401
  }
402
+ /**
403
+ * --- 根据条件更新数据(仅获取 SQL 对象) ---
404
+ * @param data 要更新的数据
405
+ * @param where 筛选条件
406
+ * @param opt 选项
407
+ */
326
408
  static updateByWhereSql(data, where, opt = {}) {
327
409
  const sq = lSql.get(opt.pre);
328
410
  sq.update(this._$table + (opt.index ? ('_' + opt.index) : ''), data);
@@ -348,6 +430,12 @@ class Mod {
348
430
  }
349
431
  return sq;
350
432
  }
433
+ /**
434
+ * --- select 自定字段 ---
435
+ * @param db 数据库对象
436
+ * @param c 字段字符串或字段数组
437
+ * @param opt 选项
438
+ */
351
439
  static select(db, c, opt = {}) {
352
440
  return new this({
353
441
  'db': db,
@@ -359,6 +447,12 @@ class Mod {
359
447
  'contain': opt.contain
360
448
  });
361
449
  }
450
+ /**
451
+ * --- 通过 where 条件获取模型 ---
452
+ * @param db 数据库对象
453
+ * @param s 筛选条件数组或字符串
454
+ * @param opt 选项
455
+ */
362
456
  static where(db, s = '', opt = {}) {
363
457
  return new this({
364
458
  'db': db,
@@ -370,6 +464,11 @@ class Mod {
370
464
  'contain': opt.contain
371
465
  });
372
466
  }
467
+ /**
468
+ * --- 获取创建对象,通常用于新建数据库条目 ---
469
+ * @param db 数据库对象
470
+ * @param opt 选项
471
+ */
373
472
  static getCreate(db, opt = {}) {
374
473
  return new this({
375
474
  'db': db,
@@ -378,6 +477,13 @@ class Mod {
378
477
  'index': opt.index
379
478
  });
380
479
  }
480
+ /**
481
+ * --- 根据主键获取对象 ---
482
+ * @param db 数据库对象
483
+ * @param val 主键值
484
+ * @param lock 是否加锁
485
+ * @param opt 选项
486
+ */
381
487
  static find(db, val, opt = {}) {
382
488
  return new this({
383
489
  'db': db,
@@ -390,6 +496,12 @@ class Mod {
390
496
  'index': opt.index
391
497
  }).first(opt.lock);
392
498
  }
499
+ /**
500
+ * --- 通过 where 条件筛选单条数据 ---
501
+ * @param db 数据库对象
502
+ * @param s 筛选条件数组或字符串
503
+ * @param opt 选项
504
+ */
393
505
  static async one(db, s, opt = {}) {
394
506
  if (!opt.index) {
395
507
  const o = new this({
@@ -426,16 +538,30 @@ class Mod {
426
538
  if (rowr === false) {
427
539
  return false;
428
540
  }
541
+ // --- 如果是 null 再去下个 index 找一下 ---
429
542
  }
430
543
  return null;
431
544
  }
545
+ /**
546
+ * --- 通过 where 条件筛选单条数据返回原生对象 ---
547
+ * @param db 数据库对象
548
+ * @param s 筛选条件数组或字符串
549
+ * @param opt 选项
550
+ */
432
551
  static async oneArray(db, s, opt = {}) {
433
552
  opt.array = true;
434
553
  return this.one(db, s, opt);
435
554
  }
555
+ /**
556
+ * --- 根据 where 条件获取主键值列表 ---
557
+ * @param db 数据库对象
558
+ * @param where where 条件
559
+ * @param opt 选项
560
+ */
436
561
  static async primarys(db, where = '', opt = {}) {
437
562
  const sq = lSql.get(opt.pre ?? opt.ctr);
438
563
  if (this._$soft && !opt.raw) {
564
+ // --- 不包含已删除 ---
439
565
  if (typeof where === 'string') {
440
566
  if (where !== '') {
441
567
  where = '(' + where + ') AND `time_remove` = 0';
@@ -470,6 +596,10 @@ class Mod {
470
596
  }
471
597
  return primarys;
472
598
  }
599
+ /**
600
+ * --- 将 key val 组成的数据列表转换为原生对象模式 ---
601
+ * @param obj 要转换的 kv 数据列表
602
+ */
473
603
  static toArrayByRecord(obj) {
474
604
  const rtn = {};
475
605
  for (const key in obj) {
@@ -477,19 +607,27 @@ class Mod {
477
607
  }
478
608
  return rtn;
479
609
  }
610
+ /**
611
+ * --- 设置一个/多个属性 ---
612
+ * @param n 字符串或键/值
613
+ * @param v 可能是数字
614
+ */
480
615
  set(n, v) {
481
616
  if (typeof n === 'object') {
617
+ // --- { x: y } ---
482
618
  for (const k in n) {
483
619
  const v = n[k];
484
620
  if (v === undefined) {
485
621
  continue;
486
622
  }
623
+ // --- 强制更新,因为有的可能就是要强制更新既然设置了 ---
487
624
  this._updates[k] = true;
488
625
  this._data[k] = v;
489
626
  this[k] = v;
490
627
  }
491
628
  }
492
629
  else {
630
+ // --- x, y ---
493
631
  if (v === undefined) {
494
632
  return;
495
633
  }
@@ -501,9 +639,18 @@ class Mod {
501
639
  this[n] = v;
502
640
  }
503
641
  }
642
+ /**
643
+ * --- 获取一个字段值
644
+ * @param n 字段名
645
+ */
504
646
  get(n) {
505
647
  return this._data[n];
506
648
  }
649
+ /**
650
+ * --- 创建数据 ---
651
+ * @param notWhere 若要不存在才成功,则要传入限定条件
652
+ * @param table 可对限定条件传入适当的表
653
+ */
507
654
  async create(notWhere, table) {
508
655
  const cstr = this.constructor;
509
656
  const updates = {};
@@ -583,6 +730,9 @@ class Mod {
583
730
  return false;
584
731
  }
585
732
  }
733
+ /**
734
+ * --- 唯一键冲突则替换,不冲突则创建数据 ---
735
+ */
586
736
  async replace() {
587
737
  const cstr = this.constructor;
588
738
  const updates = {};
@@ -613,6 +763,10 @@ class Mod {
613
763
  return false;
614
764
  }
615
765
  }
766
+ /**
767
+ * --- 刷新当前模型获取最新数据 ---
768
+ * @param lock 是否加锁
769
+ */
616
770
  async refresh(lock = false) {
617
771
  const cstr = this.constructor;
618
772
  this._sql.select('*', cstr._$table + (this._index ? ('_' + this._index[0]) : '')).where([{
@@ -644,6 +798,9 @@ class Mod {
644
798
  }
645
799
  return true;
646
800
  }
801
+ /**
802
+ * --- 更新 set 的数据到数据库,有未保存数据时才保存 ---
803
+ */
647
804
  async save() {
648
805
  if (Object.keys(this._updates).length === 0) {
649
806
  return true;
@@ -677,6 +834,10 @@ class Mod {
677
834
  return false;
678
835
  }
679
836
  }
837
+ /**
838
+ * --- 移除本条目 ---
839
+ * @param raw 是否真实移除
840
+ */
680
841
  async remove(raw = false) {
681
842
  const tim = lTime.stamp();
682
843
  const cstr = this.constructor;
@@ -713,6 +874,11 @@ class Mod {
713
874
  return false;
714
875
  }
715
876
  }
877
+ /**
878
+ * --- 获取数据库第一个对象 ---
879
+ * @param lock 是否加锁
880
+ * @param array 是否返回原生对象
881
+ */
716
882
  async first(lock = false, array = false) {
717
883
  this._sql.limit(1);
718
884
  if (lock) {
@@ -744,9 +910,18 @@ class Mod {
744
910
  }
745
911
  return this;
746
912
  }
913
+ /**
914
+ * --- 获取数据库第一个原生对象 ---
915
+ * @param lock 是否加锁
916
+ */
747
917
  async firstArray(lock = false) {
748
918
  return this.first(lock, true);
749
919
  }
920
+ /**
921
+ * --- 联合查询表数据 ---
922
+ * @param f 要联合查询的表列表、单个表、sql 对象
923
+ * @param type 类型
924
+ */
750
925
  union(f, type = '') {
751
926
  if (f instanceof lSql.Sql) {
752
927
  this._sql.union(f, type);
@@ -772,6 +947,10 @@ class Mod {
772
947
  }
773
948
  return this;
774
949
  }
950
+ /**
951
+ * --- 所有联合查询表数据 ---
952
+ * @param f 要联合查询的表列表、单个表、sql 对象
953
+ */
775
954
  unionAll(f) {
776
955
  if (f instanceof lSql.Sql) {
777
956
  this._sql.unionAll(f);
@@ -797,15 +976,25 @@ class Mod {
797
976
  }
798
977
  return this;
799
978
  }
979
+ /**
980
+ * --- 获取列表 ---
981
+ * @param key 是否以某个字段为主键
982
+ */
800
983
  async all(key) {
801
984
  this._total.length = 0;
802
985
  if (this._index && this._index.length > 1) {
986
+ // --- 多表 ---
803
987
  let sql = this._sql.getSql();
988
+ /** --- 返回的最终 list --- */
804
989
  const list = key ? {} : [];
990
+ /** --- 用户传输的起始值 --- */
805
991
  const limit = [this._limit[0] ?? 0, this._limit[1] ?? 200];
992
+ /** --- 已过的 offset,-1 代表不再计算 offset 了 --- */
806
993
  let offset = 0;
994
+ /** --- 剩余条数 --- */
807
995
  let remain = limit[1];
808
996
  for (let i = 0; i < this._index.length; ++i) {
997
+ // --- 先计算 total ---
809
998
  if (i > 0) {
810
999
  sql = sql.replace(/(FROM [a-zA-Z0-9`_.]+?_)[0-9_]+/, '$1' + this._index[i]);
811
1000
  }
@@ -820,8 +1009,11 @@ class Mod {
820
1009
  }
821
1010
  this._total.push(count);
822
1011
  if (remain === 0) {
1012
+ // --- 下一个表需要接着执行 total 计算,所以不能 break ---
823
1013
  continue;
824
1014
  }
1015
+ // --- 开始查数据 ---
1016
+ /** --- 差值 --- */
825
1017
  let cz = 0;
826
1018
  if (offset > -1) {
827
1019
  cz = limit[0] - offset;
@@ -873,6 +1065,7 @@ class Mod {
873
1065
  }
874
1066
  return Array.isArray(list) ? new Rows(list) : list;
875
1067
  }
1068
+ // --- 单表 ---
876
1069
  const contain = this._contain ? lCore.clone(this._contain.list) : null;
877
1070
  const r = await this._db.query(this._sql.getSql(), this._sql.getData());
878
1071
  if (r.rows === null) {
@@ -887,6 +1080,7 @@ class Mod {
887
1080
  }, '[all, mod] ' + lText.stringifyJson(r.error?.message ?? '').slice(1, -1).replace(/"/g, '""'), '-error');
888
1081
  return false;
889
1082
  }
1083
+ // --- 检查没被查到的必包含项 ---
890
1084
  for (const row of r.rows) {
891
1085
  if (this._contain && contain) {
892
1086
  const io = contain.indexOf(row[this._contain.key]);
@@ -916,6 +1110,7 @@ class Mod {
916
1110
  });
917
1111
  list[row[key]] = obj;
918
1112
  }
1113
+ // --- 有没有必须包含的项 ---
919
1114
  if (cr?.rows) {
920
1115
  for (const crow of cr.rows) {
921
1116
  const obj = new this.constructor({
@@ -941,6 +1136,7 @@ class Mod {
941
1136
  });
942
1137
  list.push(obj);
943
1138
  }
1139
+ // --- 有没有必须包含的项 ---
944
1140
  if (cr?.rows) {
945
1141
  for (const crow of cr.rows) {
946
1142
  const obj = new this.constructor({
@@ -955,15 +1151,25 @@ class Mod {
955
1151
  }
956
1152
  return new Rows(list);
957
1153
  }
1154
+ /**
1155
+ * --- 获取列表(得到的为原生对象或数组,不是模型) ---
1156
+ * @param key 是否以某个字段为主键
1157
+ */
958
1158
  async allArray(key) {
959
1159
  this._total.length = 0;
960
1160
  if (this._index && this._index.length > 1) {
1161
+ // --- 多表 ---
961
1162
  let sql = this._sql.getSql();
1163
+ /** --- 返回的最终 list --- */
962
1164
  const list = key ? {} : [];
1165
+ /** --- 用户传输的起始值 --- */
963
1166
  const limit = [this._limit[0] ?? 0, this._limit[1] ?? 200];
1167
+ /** --- 已过的 offset,-1 代表不再计算 offset 了 --- */
964
1168
  let offset = 0;
1169
+ /** --- 剩余条数 --- */
965
1170
  let remain = limit[1];
966
1171
  for (let i = 0; i < this._index.length; ++i) {
1172
+ // --- 先计算 total ---
967
1173
  if (i > 0) {
968
1174
  sql = sql.replace(/(FROM [a-zA-Z0-9`_.]+?_)[0-9_]+/, '$1' + this._index[i]);
969
1175
  }
@@ -978,8 +1184,11 @@ class Mod {
978
1184
  }
979
1185
  this._total.push(count);
980
1186
  if (remain === 0) {
1187
+ // --- 下一个表需要接着执行 total 计算,所以不能 break ---
981
1188
  continue;
982
1189
  }
1190
+ // --- 开始查数据 ---
1191
+ /** --- 差值 --- */
983
1192
  let cz = 0;
984
1193
  if (offset > -1) {
985
1194
  cz = limit[0] - offset;
@@ -987,6 +1196,7 @@ class Mod {
987
1196
  offset += count;
988
1197
  continue;
989
1198
  }
1199
+ // --- 在本表开始找之后,后面表无需再跳过 ---
990
1200
  offset = -1;
991
1201
  }
992
1202
  const lsql = sql.replace(/ LIMIT [0-9 ,]+/g, ` LIMIT ${cz}, ${remain}`);
@@ -1018,6 +1228,7 @@ class Mod {
1018
1228
  }
1019
1229
  return list;
1020
1230
  }
1231
+ // --- 单表 ---
1021
1232
  const contain = this._contain ? lCore.clone(this._contain.list) : null;
1022
1233
  const r = await this._db.query(this._sql.getSql(), this._sql.getData());
1023
1234
  if (r.rows === null) {
@@ -1032,6 +1243,7 @@ class Mod {
1032
1243
  }, '[allArray, mod] ' + lText.stringifyJson(r.error?.message ?? '').slice(1, -1).replace(/"/g, '""'), '-error');
1033
1244
  return false;
1034
1245
  }
1246
+ // --- 检查没被查到的必包含项 ---
1035
1247
  for (const row of r.rows) {
1036
1248
  if (this._contain && contain) {
1037
1249
  const io = contain.indexOf(row[this._contain.key]);
@@ -1054,6 +1266,7 @@ class Mod {
1054
1266
  for (const row of r.rows) {
1055
1267
  list[row[key]] = row;
1056
1268
  }
1269
+ // --- 有没有必须包含的项 ---
1057
1270
  if (cr?.rows) {
1058
1271
  for (const crow of cr.rows) {
1059
1272
  list[crow[key]] = crow;
@@ -1061,6 +1274,7 @@ class Mod {
1061
1274
  }
1062
1275
  return list;
1063
1276
  }
1277
+ // --- 有没有必须包含的项 ---
1064
1278
  if (cr?.rows) {
1065
1279
  for (const crow of cr.rows) {
1066
1280
  r.rows.push(crow);
@@ -1068,6 +1282,10 @@ class Mod {
1068
1282
  }
1069
1283
  return r.rows;
1070
1284
  }
1285
+ /**
1286
+ * --- 获取数查询(SELECT)扫描情况,获取字符串或kv数组 ---
1287
+ * @param all 是否获取完全的情况,默认不获取,只返回扫描情况
1288
+ */
1071
1289
  async explain(all = false) {
1072
1290
  const r = await this._db.query('EXPLAIN ' + this._sql.getSql(), this._sql.getData());
1073
1291
  if (r.rows === null) {
@@ -1100,6 +1318,9 @@ class Mod {
1100
1318
  return sql
1101
1319
  .replace(/SELECT .+? FROM/g, 'SELECT COUNT(' + this._sql.field(f) + ') AS `count` FROM');
1102
1320
  }
1321
+ /**
1322
+ * --- 获取总条数,自动抛弃 LIMIT,仅用于获取数据的情况(select) ---
1323
+ */
1103
1324
  async total(f = '*') {
1104
1325
  if (this._total.length) {
1105
1326
  let count = 0;
@@ -1128,6 +1349,9 @@ class Mod {
1128
1349
  }
1129
1350
  return count;
1130
1351
  }
1352
+ /**
1353
+ * --- 根据当前条件,筛选出当前条目该有的数据条数 ---
1354
+ */
1131
1355
  async count() {
1132
1356
  const sql = this._sql.getSql().replace(/SELECT .+? FROM/, 'SELECT COUNT(*) AS `count` FROM');
1133
1357
  const r = await this._db.query(sql, this._sql.getData());
@@ -1149,34 +1373,80 @@ class Mod {
1149
1373
  }
1150
1374
  return count;
1151
1375
  }
1376
+ /**
1377
+ * @param f 表名
1378
+ * @param s ON 信息
1379
+ * @param type 类型
1380
+ * @param index 给本表增加 index 分表项
1381
+ * @param pre 前缀
1382
+ */
1152
1383
  join(f, s = [], type = 'INNER', index = '', pre = '') {
1153
1384
  this._sql.join(f, s, type, index ? '_' + index : '', pre);
1154
1385
  return this;
1155
1386
  }
1387
+ /**
1388
+ * --- left join 方法 ---
1389
+ * @param f 表名
1390
+ * @param s ON 信息
1391
+ * @param index 给本表增加 index 分表项
1392
+ */
1156
1393
  leftJoin(f, s, index = '', pre = '') {
1157
1394
  this._sql.leftJoin(f, s, index ? '_' + index : '', pre);
1158
1395
  return this;
1159
1396
  }
1397
+ /**
1398
+ * --- right join 方法 ---
1399
+ * @param f 表名
1400
+ * @param s ON 信息
1401
+ * @param index 给本表增加 index 分表项
1402
+ */
1160
1403
  rightJoin(f, s, index = '', pre = '') {
1161
1404
  this._sql.rightJoin(f, s, index ? '_' + index : '', pre);
1162
1405
  return this;
1163
1406
  }
1407
+ /**
1408
+ * --- inner join 方法 ---
1409
+ * @param f 表名
1410
+ * @param s ON 信息
1411
+ * @param index 给本表增加 index 分表项
1412
+ */
1164
1413
  innerJoin(f, s, index = '', pre = '') {
1165
1414
  this._sql.innerJoin(f, s, index ? '_' + index : '', pre);
1166
1415
  return this;
1167
1416
  }
1417
+ /**
1418
+ * --- full join 方法 ---
1419
+ * @param f 表名
1420
+ * @param s ON 信息
1421
+ * @param index 给本表增加 index 分表项
1422
+ */
1168
1423
  fullJoin(f, s, index = '', pre = '') {
1169
1424
  this._sql.fullJoin(f, s, index ? '_' + index : '', pre);
1170
1425
  return this;
1171
1426
  }
1427
+ /**
1428
+ * --- cross join 方法 ---
1429
+ * @param f 表名
1430
+ * @param s ON 信息
1431
+ * @param index 给本表增加 index 分表项
1432
+ */
1172
1433
  crossJoin(f, s, index = '', pre = '') {
1173
1434
  this._sql.crossJoin(f, s, index ? '_' + index : '', pre);
1174
1435
  return this;
1175
1436
  }
1437
+ /**
1438
+ * --- 筛选器 ---
1439
+ * @param s 筛选条件数组或字符串
1440
+ */
1176
1441
  having(s) {
1177
1442
  this._sql.having(s);
1178
1443
  return this;
1179
1444
  }
1445
+ /**
1446
+ * --- 筛选器 ---
1447
+ * @param s 筛选条件数组或字符串
1448
+ * @param raw 是否包含已被软删除的数据
1449
+ */
1180
1450
  filter(s, raw = false) {
1181
1451
  const cstr = this.constructor;
1182
1452
  if (cstr._soft && !raw) {
@@ -1195,48 +1465,97 @@ class Mod {
1195
1465
  this._sql.where(s);
1196
1466
  return this;
1197
1467
  }
1468
+ /**
1469
+ * --- 是 filter 的别名 ---
1470
+ * @param s 筛选条件数组或字符串
1471
+ * @param raw 是否包含已被软删除的数据
1472
+ */
1198
1473
  where(s, raw = false) {
1199
1474
  return this.filter(s, raw);
1200
1475
  }
1476
+ /**
1477
+ * --- ORDER BY ---
1478
+ * @param c 字段字符串或数组
1479
+ * @param d 排序规则
1480
+ */
1201
1481
  by(c, d = 'DESC') {
1202
1482
  this._sql.by(c, d);
1203
1483
  return this;
1204
1484
  }
1485
+ /**
1486
+ * --- GROUP BY ---
1487
+ * @param c 字段字符串或数组
1488
+ */
1205
1489
  group(c) {
1206
1490
  this._sql.group(c);
1207
1491
  return this;
1208
1492
  }
1493
+ /**
1494
+ * --- LIMIT ---
1495
+ * @param a 起始
1496
+ * @param b 长度
1497
+ */
1209
1498
  limit(a, b = 0) {
1210
1499
  this._sql.limit(a, b);
1211
1500
  this._limit = [a, b];
1212
1501
  return this;
1213
1502
  }
1503
+ /**
1504
+ * --- 分页 ---
1505
+ * @param count 每页条数
1506
+ * @param page 当前页数
1507
+ */
1214
1508
  page(count, page = 1) {
1215
1509
  const a = count * (page - 1);
1216
1510
  this._sql.limit(a, count);
1217
1511
  this._limit = [a, count];
1218
1512
  return this;
1219
1513
  }
1514
+ /**
1515
+ * --- 在 sql 最后追加字符串 ---
1516
+ * @param sql
1517
+ */
1220
1518
  append(sql) {
1221
1519
  this._sql.append(sql);
1222
1520
  return this;
1223
1521
  }
1522
+ /**
1523
+ * --- 设置闭包含数据 ---
1524
+ * @param contain 设置项
1525
+ */
1224
1526
  contain(contain) {
1225
1527
  this._contain = contain;
1226
1528
  return this;
1227
1529
  }
1530
+ /**
1531
+ * --- 获取 sql 语句 ---
1532
+ */
1228
1533
  getSql() {
1229
1534
  return this._sql.getSql();
1230
1535
  }
1536
+ /**
1537
+ * --- 获取全部 data ---
1538
+ */
1231
1539
  getData() {
1232
1540
  return this._sql.getData();
1233
1541
  }
1542
+ /**
1543
+ * --- 获取带 data 的 sql 语句 ---
1544
+ * @param sql sql 语句
1545
+ * @param data 数据
1546
+ */
1234
1547
  format(sql, data) {
1235
1548
  return this._sql.format(sql, data);
1236
1549
  }
1550
+ /**
1551
+ * --- 获取值对象 ---
1552
+ */
1237
1553
  toArray() {
1238
1554
  return this._data;
1239
1555
  }
1556
+ /**
1557
+ * --- 获取当前设置要提交的数据 ---
1558
+ */
1240
1559
  updates() {
1241
1560
  const updates = {};
1242
1561
  for (const k in this._updates) {
@@ -1244,9 +1563,17 @@ class Mod {
1244
1563
  }
1245
1564
  return updates;
1246
1565
  }
1566
+ /**
1567
+ * --- 当前是否设置了未保存 --=
1568
+ */
1247
1569
  unsaved() {
1248
1570
  return Object.keys(this._updates).length ? true : false;
1249
1571
  }
1572
+ /**
1573
+ * --- 获取字段的可用语种文本 ---
1574
+ * @param col 字段名
1575
+ * @param lang 当前请求语种,如 sc
1576
+ */
1250
1577
  langText(col, lang) {
1251
1578
  const key = `${col}_${lang}`;
1252
1579
  if (this._data[key]) {
@@ -1257,17 +1584,25 @@ class Mod {
1257
1584
  }
1258
1585
  for (const k in this._data) {
1259
1586
  if (k.startsWith(`${col}_`) && this._data[k]) {
1587
+ // --- 符合要求的字段并且字段有值(不为空) ---
1260
1588
  return this._data[k];
1261
1589
  }
1262
1590
  }
1263
1591
  return '';
1264
1592
  }
1593
+ /**
1594
+ * --- 当 _key 不为空时,则依据继承此方法的方法自动生成填充 key ---
1595
+ */
1265
1596
  _keyGenerator() {
1266
1597
  return '';
1267
1598
  }
1268
1599
  }
1600
+ /** --- 表名 --- */
1269
1601
  Mod._$table = '';
1602
+ /** --- 主键字段名 --- */
1270
1603
  Mod._$primary = 'id';
1604
+ /** --- 设置后将由 _keyGenerator 函数生成唯一字段 --- */
1271
1605
  Mod._$key = '';
1606
+ /** ---- 可开启软删软更新软新增 --- */
1272
1607
  Mod._$soft = false;
1273
1608
  exports.default = Mod;