baja-lite 1.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.
Files changed (55) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1 -0
  3. package/cjs/constant.d.ts +13 -0
  4. package/cjs/constant.js +19 -0
  5. package/cjs/error.d.ts +5 -0
  6. package/cjs/error.js +16 -0
  7. package/cjs/fn.d.ts +128 -0
  8. package/cjs/fn.js +169 -0
  9. package/cjs/index.d.ts +8 -0
  10. package/cjs/index.js +24 -0
  11. package/cjs/math.d.ts +69 -0
  12. package/cjs/math.js +435 -0
  13. package/cjs/now.d.ts +7 -0
  14. package/cjs/now.js +26 -0
  15. package/cjs/object.d.ts +77 -0
  16. package/cjs/object.js +212 -0
  17. package/cjs/set-ex.d.ts +171 -0
  18. package/cjs/set-ex.js +336 -0
  19. package/cjs/sql.d.ts +1216 -0
  20. package/cjs/sql.js +3380 -0
  21. package/cjs/string.d.ts +18 -0
  22. package/cjs/string.js +124 -0
  23. package/cjs/test-mysql.d.ts +1 -0
  24. package/cjs/test-mysql.js +108 -0
  25. package/cjs/test-sqlite.d.ts +1 -0
  26. package/cjs/test-sqlite.js +89 -0
  27. package/cjs/test.d.ts +1 -0
  28. package/cjs/test.js +4 -0
  29. package/es/constant.d.ts +13 -0
  30. package/es/constant.js +16 -0
  31. package/es/error.d.ts +5 -0
  32. package/es/error.js +13 -0
  33. package/es/fn.d.ts +128 -0
  34. package/es/fn.js +162 -0
  35. package/es/index.d.ts +8 -0
  36. package/es/index.js +8 -0
  37. package/es/math.d.ts +69 -0
  38. package/es/math.js +414 -0
  39. package/es/now.d.ts +7 -0
  40. package/es/now.js +16 -0
  41. package/es/object.d.ts +77 -0
  42. package/es/object.js +196 -0
  43. package/es/set-ex.d.ts +171 -0
  44. package/es/set-ex.js +332 -0
  45. package/es/sql.d.ts +1216 -0
  46. package/es/sql.js +3338 -0
  47. package/es/string.d.ts +18 -0
  48. package/es/string.js +109 -0
  49. package/es/test-mysql.d.ts +1 -0
  50. package/es/test-mysql.js +106 -0
  51. package/es/test-sqlite.d.ts +1 -0
  52. package/es/test-sqlite.js +87 -0
  53. package/es/test.d.ts +1 -0
  54. package/es/test.js +2 -0
  55. package/package.json +66 -0
package/es/sql.js ADDED
@@ -0,0 +1,3338 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ var _a, _b, _c;
11
+ var _d, _e, _f;
12
+ import 'reflect-metadata';
13
+ import { Throw } from './error';
14
+ import tslib from 'tslib';
15
+ import Sqlstring from 'sqlstring';
16
+ import iterare from 'iterare';
17
+ import { emptyString } from './string';
18
+ import pino from 'pino';
19
+ import { excuteSplit, ExcuteSplitMode, sleep } from './fn';
20
+ import { add } from './math';
21
+ // #region 常量
22
+ const _daoDBName = Symbol('dbName');
23
+ const _tableName = Symbol('tableName');
24
+ const _ids = Symbol('ids');
25
+ const _columns = Symbol('columns');
26
+ const _columnsNoId = Symbol('columnsNoId');
27
+ const _fields = Symbol('fields');
28
+ const _stateFileName = Symbol('stateFileName');
29
+ const _deleteState = Symbol('deleteState');
30
+ const _transformer = Symbol('transformer');
31
+ const _index = Symbol('index');
32
+ const _def = Symbol('def');
33
+ const _sqlCache = Symbol('sqlCache');
34
+ const _dao = Symbol('dao');
35
+ const _primaryDB = Symbol('primaryDB');
36
+ const _dbType = Symbol('dbType');
37
+ const _sqlite_version = Symbol('sqlite_version');
38
+ const _daoConnection = Symbol('daoConnection');
39
+ const _inTransaction = Symbol('inTransaction');
40
+ const _daoDB = Symbol('daoDB');
41
+ const _sqliteRemoteName = Symbol('sqliteRemoteName');
42
+ const _SqlOption = Symbol('SqlOption');
43
+ const _GlobalSqlOption = Symbol('GlobalSqlOption');
44
+ const _EventBus = Symbol('EventBus');
45
+ const _path = Symbol('path');
46
+ const _fs = Symbol('fs');
47
+ const logger = pino({
48
+ name: 'sql',
49
+ transport: {
50
+ target: 'pino-pretty'
51
+ }
52
+ });
53
+ // #endregion
54
+ // #region 可选配置
55
+ export var DBType;
56
+ (function (DBType) {
57
+ DBType[DBType["Mysql"] = 0] = "Mysql";
58
+ DBType[DBType["Sqlite"] = 1] = "Sqlite";
59
+ DBType[DBType["Mongo"] = 2] = "Mongo";
60
+ DBType[DBType["SqliteRemote"] = 3] = "SqliteRemote";
61
+ DBType[DBType["Redis"] = 4] = "Redis";
62
+ DBType[DBType["RedisLock"] = 5] = "RedisLock";
63
+ })(DBType || (DBType = {}));
64
+ export var SqlSyncMode;
65
+ (function (SqlSyncMode) {
66
+ /** 同步执行 */
67
+ SqlSyncMode[SqlSyncMode["Sync"] = 0] = "Sync";
68
+ /** 异步执行 */
69
+ SqlSyncMode[SqlSyncMode["Async"] = 1] = "Async";
70
+ })(SqlSyncMode || (SqlSyncMode = {}));
71
+ export var SqlInsertMode;
72
+ (function (SqlInsertMode) {
73
+ /**
74
+ # 默认使用
75
+ ** 支持单个、批量,语法 `INSERT INTO XX VALUES (第一条数据), (第二条数据);`
76
+ ** 批量执行有性能优势,但无法利用数据库的sql预编译功能
77
+ */
78
+ SqlInsertMode[SqlInsertMode["Insert"] = 0] = "Insert";
79
+ /**
80
+ # 利用临时表
81
+ ## 执行步骤
82
+ 1. 建立临时表(从正式表复制)
83
+ 2. 数据全部进入临时表
84
+ 3. 临时表数据转移到正式表: `INSERT INTO 正式表 SELECT * FROM 临时表`
85
+ 4. 删除临时表
86
+ ## 注意
87
+ 1. 适用于:主键不会冲突、非自增
88
+ 2. 临时表的结构复制正式表
89
+ */
90
+ SqlInsertMode[SqlInsertMode["InsertWithTempTable"] = 1] = "InsertWithTempTable";
91
+ SqlInsertMode[SqlInsertMode["InsertIfNotExists"] = 2] = "InsertIfNotExists";
92
+ /**
93
+ # 插入或者更新
94
+ 1. 判断依据是主键
95
+ */
96
+ SqlInsertMode[SqlInsertMode["Replace"] = 3] = "Replace";
97
+ })(SqlInsertMode || (SqlInsertMode = {}));
98
+ export var SqlDelMode;
99
+ (function (SqlDelMode) {
100
+ /**
101
+ ##常规删除 默认
102
+ ### 例一
103
+ `DELETE FROM WHERE (id = 1) OR (id = 2)`
104
+ ### 例二
105
+ `DELETE FROM WHERE (id = 1 AND idx = 11) OR (id = 2 AND idx = 22)`
106
+ */
107
+ SqlDelMode[SqlDelMode["Common"] = 0] = "Common";
108
+ /*
109
+ ## 借助临时表
110
+ ### 注意:必须保证where的字段都相同,否则会漏删数据
111
+ DELETE FROM 正式表 INNER JOIN 临时表 WHERE 字段1 = 字段1 AND 字段2 = 字段2
112
+ */
113
+ SqlDelMode[SqlDelMode["TempTable"] = 1] = "TempTable";
114
+ })(SqlDelMode || (SqlDelMode = {}));
115
+ export var SqlSelectMode;
116
+ (function (SqlSelectMode) {
117
+ /**
118
+ ##常规 默认
119
+ ### 例一
120
+ `SELECT * FROM WHERE (id = 1) OR (id = 2)`
121
+ ### 例二
122
+ `SELECT * FROM WHERE (id = 1 AND idx = 11) OR (id = 2 AND idx = 22)`
123
+ */
124
+ SqlSelectMode[SqlSelectMode["Common"] = 0] = "Common";
125
+ /*
126
+ ## 借助临时表
127
+ ### 注意:必须保证where的字段都相同,否则会漏删数据
128
+ SELECT * FROM 正式表 INNER JOIN 临时表 WHERE 字段1 = 字段1 AND 字段2 = 字段2
129
+ */
130
+ SqlSelectMode[SqlSelectMode["TempTable"] = 1] = "TempTable";
131
+ })(SqlSelectMode || (SqlSelectMode = {}));
132
+ export var SqlTemplateMode;
133
+ (function (SqlTemplateMode) {
134
+ /** 确定返回一个,如果不是一个,将报错,返回类型是T */
135
+ SqlTemplateMode[SqlTemplateMode["AssertOne"] = 0] = "AssertOne";
136
+ /** 可能返回一个,返回类型是T|null */
137
+ SqlTemplateMode[SqlTemplateMode["NotSureOne"] = 1] = "NotSureOne";
138
+ /** 返回多个 */
139
+ SqlTemplateMode[SqlTemplateMode["Many"] = 2] = "Many";
140
+ /** 仅查询记录数量 */
141
+ SqlTemplateMode[SqlTemplateMode["Count"] = 3] = "Count";
142
+ })(SqlTemplateMode || (SqlTemplateMode = {}));
143
+ export var SqlQueryMode;
144
+ (function (SqlQueryMode) {
145
+ SqlQueryMode[SqlQueryMode["One_Row_One_Column_Assert"] = 0] = "One_Row_One_Column_Assert";
146
+ SqlQueryMode[SqlQueryMode["One_Row_One_Column_NotSure"] = 1] = "One_Row_One_Column_NotSure";
147
+ SqlQueryMode[SqlQueryMode["One_Row_Many_Column_Assert"] = 2] = "One_Row_Many_Column_Assert";
148
+ SqlQueryMode[SqlQueryMode["One_Row_Many_Column_NotSure"] = 3] = "One_Row_Many_Column_NotSure";
149
+ SqlQueryMode[SqlQueryMode["Many_Row_One_Column"] = 4] = "Many_Row_One_Column";
150
+ SqlQueryMode[SqlQueryMode["Many_Row_Many_Column"] = 5] = "Many_Row_Many_Column";
151
+ })(SqlQueryMode || (SqlQueryMode = {}));
152
+ export var SqlType;
153
+ (function (SqlType) {
154
+ SqlType[SqlType["bigint"] = 0] = "bigint";
155
+ SqlType[SqlType["char"] = 1] = "char";
156
+ SqlType[SqlType["decimal"] = 2] = "decimal";
157
+ SqlType[SqlType["int"] = 3] = "int";
158
+ SqlType[SqlType["longtext"] = 4] = "longtext";
159
+ SqlType[SqlType["mediumtext"] = 5] = "mediumtext";
160
+ SqlType[SqlType["smallint"] = 6] = "smallint";
161
+ SqlType[SqlType["text"] = 7] = "text";
162
+ SqlType[SqlType["tinyint"] = 8] = "tinyint";
163
+ SqlType[SqlType["varchar"] = 9] = "varchar";
164
+ })(SqlType || (SqlType = {}));
165
+ export const SqliteMemory = ':memory:';
166
+ const _defOption = {
167
+ maxDeal: 500,
168
+ skipUndefined: true,
169
+ skipNull: true,
170
+ skipEmptyString: true
171
+ };
172
+ ;
173
+ class MysqlConnection {
174
+ constructor(conn) {
175
+ this[_a] = false;
176
+ this[_daoConnection] = conn;
177
+ }
178
+ execute(sync, sql, params) {
179
+ logger.debug(sql, params ?? '');
180
+ if (!sql) {
181
+ return { affectedRows: 0, insertId: 0n };
182
+ }
183
+ ;
184
+ if (sync === SqlSyncMode.Sync) {
185
+ logger.warn('MYSQL not suppouted sync mode');
186
+ return { affectedRows: 0, insertId: 0n };
187
+ }
188
+ ;
189
+ if (globalThis[_GlobalSqlOption].log === 'trace') {
190
+ logger.trace(Sqlstring.format(sql, params));
191
+ }
192
+ return new Promise(async (resolve) => {
193
+ try {
194
+ const [_result] = await this[_daoConnection].execute(sql, params);
195
+ const result = _result;
196
+ if (globalThis[_GlobalSqlOption].log === 'trace') {
197
+ logger.trace(result);
198
+ }
199
+ resolve({ affectedRows: result.affectedRows, insertId: result.insertId });
200
+ }
201
+ catch (error) {
202
+ logger.error(`
203
+ error: ${error},
204
+ sql: ${sql},
205
+ params: ${params}
206
+ `);
207
+ throw error;
208
+ }
209
+ });
210
+ }
211
+ pluck(sync, sql, params) {
212
+ logger.debug(sql, params ?? '');
213
+ if (!sql) {
214
+ return null;
215
+ }
216
+ ;
217
+ if (sync === SqlSyncMode.Sync) {
218
+ logger.warn('MYSQL not suppouted sync mode');
219
+ return null;
220
+ }
221
+ ;
222
+ if (globalThis[_GlobalSqlOption].log === 'trace') {
223
+ logger.trace(Sqlstring.format(sql, params));
224
+ }
225
+ return new Promise(async (resolve) => {
226
+ try {
227
+ const [result] = await this[_daoConnection].query(sql, params);
228
+ if (result && result[0]) {
229
+ const r = Object.values(result[0])[0];
230
+ if (r === null)
231
+ resolve(r);
232
+ else
233
+ resolve(r);
234
+ }
235
+ resolve(null);
236
+ }
237
+ catch (error) {
238
+ logger.error(`
239
+ error: ${error},
240
+ sql: ${sql},
241
+ params: ${params}
242
+ `);
243
+ throw error;
244
+ }
245
+ });
246
+ }
247
+ get(sync, sql, params) {
248
+ logger.debug(sql, params ?? '');
249
+ if (!sql) {
250
+ return null;
251
+ }
252
+ ;
253
+ if (sync === SqlSyncMode.Sync) {
254
+ logger.warn('MYSQL not suppouted sync mode');
255
+ return null;
256
+ }
257
+ ;
258
+ if (globalThis[_GlobalSqlOption].log === 'trace') {
259
+ logger.trace(Sqlstring.format(sql, params));
260
+ }
261
+ return new Promise(async (resolve) => {
262
+ try {
263
+ const [result] = await this[_daoConnection].query(sql, params);
264
+ if (globalThis[_GlobalSqlOption].log === 'trace') {
265
+ logger.trace(result);
266
+ }
267
+ if (result && result[0])
268
+ resolve(result[0]);
269
+ resolve(null);
270
+ }
271
+ catch (error) {
272
+ logger.error(`
273
+ error: ${error},
274
+ sql: ${sql},
275
+ params: ${params}
276
+ `);
277
+ throw error;
278
+ }
279
+ });
280
+ }
281
+ raw(sync, sql, params) {
282
+ logger.debug(sql, params ?? '');
283
+ if (!sql) {
284
+ return [];
285
+ }
286
+ ;
287
+ if (sync === SqlSyncMode.Sync) {
288
+ logger.warn('MYSQL not suppouted sync mode');
289
+ return [];
290
+ }
291
+ ;
292
+ if (globalThis[_GlobalSqlOption].log === 'trace') {
293
+ logger.trace(Sqlstring.format(sql, params));
294
+ }
295
+ return new Promise(async (resolve) => {
296
+ try {
297
+ const [result] = await this[_daoConnection].query(sql, params);
298
+ if (globalThis[_GlobalSqlOption].log === 'trace') {
299
+ logger.trace(result);
300
+ }
301
+ if (result)
302
+ resolve(result.map((i) => Object.values(i)[0]));
303
+ resolve([]);
304
+ }
305
+ catch (error) {
306
+ logger.error(`
307
+ error: ${error},
308
+ sql: ${sql},
309
+ params: ${params}
310
+ `);
311
+ throw error;
312
+ }
313
+ });
314
+ }
315
+ query(sync, sql, params) {
316
+ logger.debug(sql, params ?? '');
317
+ if (!sql) {
318
+ return [];
319
+ }
320
+ ;
321
+ if (sync === SqlSyncMode.Sync) {
322
+ logger.warn('MYSQL not suppouted sync mode');
323
+ return [];
324
+ }
325
+ ;
326
+ if (globalThis[_GlobalSqlOption].log === 'trace') {
327
+ logger.trace(Sqlstring.format(sql, params));
328
+ }
329
+ return new Promise(async (resolve) => {
330
+ try {
331
+ const [result] = await this[_daoConnection].query(sql, params);
332
+ if (globalThis[_GlobalSqlOption].log === 'trace') {
333
+ logger.trace(result);
334
+ }
335
+ resolve(result);
336
+ }
337
+ catch (error) {
338
+ logger.error(`
339
+ error: ${error},
340
+ sql: ${sql},
341
+ params: ${params}
342
+ `);
343
+ throw error;
344
+ }
345
+ });
346
+ }
347
+ realse(sync) {
348
+ if (sync === SqlSyncMode.Sync) {
349
+ try {
350
+ this[_daoConnection]?.release();
351
+ }
352
+ catch (error) {
353
+ }
354
+ }
355
+ ;
356
+ }
357
+ }
358
+ _a = _inTransaction;
359
+ class Mysql {
360
+ constructor(pool) {
361
+ this[_daoDB] = pool;
362
+ }
363
+ createConnection(sync) {
364
+ if (sync === SqlSyncMode.Sync) {
365
+ logger.error('MYSQL not suppouted sync mode');
366
+ return null;
367
+ }
368
+ ;
369
+ return new Promise(async (resolve) => {
370
+ const connection = await this[_daoDB].getConnection();
371
+ logger.debug('create new!');
372
+ resolve(new MysqlConnection(connection));
373
+ });
374
+ }
375
+ transaction(sync, fn, conn) {
376
+ if (sync === SqlSyncMode.Sync) {
377
+ logger.warn('MYSQL not suppouted sync mode');
378
+ return null;
379
+ }
380
+ ;
381
+ return new Promise(async (resolve) => {
382
+ let needCommit = false;
383
+ let newConn = false;
384
+ if (!conn) {
385
+ conn = await this.createConnection(SqlSyncMode.Async) ?? undefined;
386
+ newConn = true;
387
+ }
388
+ if (conn?.[_inTransaction] !== true) {
389
+ needCommit = true;
390
+ logger.debug('beginTransaction begin!');
391
+ await conn[_daoConnection].beginTransaction();
392
+ logger.debug('beginTransaction end!');
393
+ }
394
+ conn[_inTransaction] = true;
395
+ try {
396
+ const result = await fn(conn);
397
+ if (needCommit === true) {
398
+ logger.debug('commit begin!');
399
+ await conn[_daoConnection].commit();
400
+ conn[_inTransaction] = false;
401
+ logger.debug('commit end!');
402
+ }
403
+ resolve(result);
404
+ }
405
+ catch (error) {
406
+ logger.debug('rollback begin!');
407
+ await conn[_daoConnection].rollback();
408
+ logger.debug('rollback end!');
409
+ conn[_inTransaction] = false;
410
+ logger.error(error);
411
+ throw error;
412
+ }
413
+ finally {
414
+ try {
415
+ if (needCommit === true) {
416
+ conn[_inTransaction] = false;
417
+ }
418
+ if (newConn === true) {
419
+ logger.debug('release begin!');
420
+ conn[_daoConnection].release();
421
+ logger.debug('release end!');
422
+ }
423
+ }
424
+ catch (error) {
425
+ }
426
+ }
427
+ });
428
+ }
429
+ close(sync) {
430
+ if (sync === SqlSyncMode.Sync) {
431
+ this[_daoDB]?.destroy();
432
+ }
433
+ ;
434
+ }
435
+ backup(sync, name) {
436
+ }
437
+ remove(sync) {
438
+ }
439
+ restore(sync, name) {
440
+ }
441
+ }
442
+ class SqliteConnection {
443
+ constructor(conn) {
444
+ this[_b] = false;
445
+ this[_daoConnection] = conn;
446
+ }
447
+ execute(sync, sql, params) {
448
+ try {
449
+ logger.debug(sql, params ?? '');
450
+ if (!sql) {
451
+ return { affectedRows: 0, insertId: 0n };
452
+ }
453
+ ;
454
+ if (sync === SqlSyncMode.Async) {
455
+ logger.warn(`SQLITE not suppoted async mode`);
456
+ return { affectedRows: 0, insertId: 0n };
457
+ }
458
+ ;
459
+ if (globalThis[_GlobalSqlOption].log === 'trace') {
460
+ logger.trace(Sqlstring.format(sql, params));
461
+ }
462
+ const result = this[_daoConnection].prepare(sql).run(params ?? {});
463
+ if (globalThis[_GlobalSqlOption].log === 'trace') {
464
+ logger.trace(result);
465
+ }
466
+ const { changes, lastInsertRowid } = result;
467
+ return { affectedRows: changes, insertId: lastInsertRowid ? BigInt(lastInsertRowid) : 0n };
468
+ }
469
+ catch (error) {
470
+ logger.error(`
471
+ error: ${error},
472
+ sql: ${sql},
473
+ params: ${params}
474
+ `);
475
+ throw error;
476
+ }
477
+ }
478
+ pluck(sync, sql, params) {
479
+ try {
480
+ logger.debug(sql, params ?? '');
481
+ if (!sql) {
482
+ return null;
483
+ }
484
+ ;
485
+ if (sync === SqlSyncMode.Async) {
486
+ logger.warn(`SQLITE not suppoted async mode`);
487
+ return null;
488
+ }
489
+ ;
490
+ if (globalThis[_GlobalSqlOption].log === 'trace') {
491
+ logger.trace(Sqlstring.format(sql, params));
492
+ }
493
+ return this[_daoConnection].prepare(sql).pluck().get(params ?? {});
494
+ }
495
+ catch (error) {
496
+ logger.error(`
497
+ error: ${error},
498
+ sql: ${sql},
499
+ params: ${params}
500
+ `);
501
+ throw error;
502
+ }
503
+ }
504
+ get(sync, sql, params) {
505
+ try {
506
+ logger.debug(sql, params ?? '');
507
+ if (!sql) {
508
+ return null;
509
+ }
510
+ ;
511
+ if (sync === SqlSyncMode.Async) {
512
+ return null;
513
+ }
514
+ ;
515
+ if (globalThis[_GlobalSqlOption].log === 'trace') {
516
+ logger.trace(Sqlstring.format(sql, params));
517
+ }
518
+ return this[_daoConnection].prepare(sql).get(params ?? {});
519
+ }
520
+ catch (error) {
521
+ logger.error(`
522
+ error: ${error},
523
+ sql: ${sql},
524
+ params: ${params}
525
+ `);
526
+ throw error;
527
+ }
528
+ }
529
+ raw(sync, sql, params) {
530
+ try {
531
+ logger.debug(sql, params ?? '');
532
+ if (!sql) {
533
+ return [];
534
+ }
535
+ ;
536
+ if (sync === SqlSyncMode.Async) {
537
+ logger.warn(`SQLITE not suppoted async mode`);
538
+ return [];
539
+ }
540
+ ;
541
+ if (globalThis[_GlobalSqlOption].log === 'trace') {
542
+ logger.trace(Sqlstring.format(sql, params));
543
+ }
544
+ return this[_daoConnection].prepare(sql).raw().all(params ?? {});
545
+ }
546
+ catch (error) {
547
+ logger.error(`
548
+ error: ${error},
549
+ sql: ${sql},
550
+ params: ${params}
551
+ `);
552
+ throw error;
553
+ }
554
+ }
555
+ query(sync, sql, params) {
556
+ try {
557
+ logger.debug(sql, params ?? '');
558
+ if (!sql) {
559
+ return [];
560
+ }
561
+ ;
562
+ if (sync === SqlSyncMode.Async) {
563
+ logger.warn(`SQLITE not suppoted async mode`);
564
+ return [];
565
+ }
566
+ ;
567
+ if (globalThis[_GlobalSqlOption].log === 'trace') {
568
+ logger.trace(Sqlstring.format(sql, params));
569
+ }
570
+ return this[_daoConnection].prepare(sql).all(params ?? {});
571
+ }
572
+ catch (error) {
573
+ logger.error(`
574
+ error: ${error},
575
+ sql: ${sql},
576
+ params: ${params}
577
+ `);
578
+ throw error;
579
+ }
580
+ }
581
+ realse(sync) {
582
+ }
583
+ }
584
+ _b = _inTransaction;
585
+ class Sqlite {
586
+ constructor(db) {
587
+ this[_daoDB] = db;
588
+ this[_daoDB].pragma('journal_mode = WAL');
589
+ this[_daoDB].exec(`
590
+ CREATE TABLE IF NOT EXISTS DUAL ( ______id INTEGER NOT NULL, PRIMARY KEY ( ______id ));
591
+ DELETE FROM DUAL;
592
+ INSERT INTO DUAL (______id ) VALUES ( 1 );
593
+ CREATE TABLE IF NOT EXISTS TABLE_VERSION (
594
+ ______tableName text NOT NULL,
595
+ ______version text NOT NULL,
596
+ PRIMARY KEY ( ______tableName )
597
+ );
598
+ `);
599
+ }
600
+ createConnection(sync) {
601
+ if (sync === SqlSyncMode.Async) {
602
+ logger.error(`SQLITE not suppoted async mode`);
603
+ return null;
604
+ }
605
+ ;
606
+ return new SqliteConnection(this[_daoDB]);
607
+ }
608
+ transaction(sync, fn, conn) {
609
+ if (sync === SqlSyncMode.Async) {
610
+ logger.warn(`SQLITE not suppoted async mode`);
611
+ return null;
612
+ }
613
+ ;
614
+ if (!conn) {
615
+ conn = this.createConnection(SqlSyncMode.Sync) ?? undefined;
616
+ }
617
+ if (conn[_inTransaction] !== true) {
618
+ return this[_daoDB].transaction(() => {
619
+ conn[_inTransaction] = true;
620
+ const rt = fn(conn);
621
+ conn[_inTransaction] = false;
622
+ return rt;
623
+ })();
624
+ }
625
+ else {
626
+ const rt = fn(conn);
627
+ return rt;
628
+ }
629
+ }
630
+ close(sync) {
631
+ if (sync === SqlSyncMode.Sync) {
632
+ this[_daoDB].close();
633
+ }
634
+ ;
635
+ }
636
+ backup(sync, name) {
637
+ if (sync === SqlSyncMode.Sync) {
638
+ this[_daoDB].backup(name);
639
+ }
640
+ ;
641
+ }
642
+ remove(sync) {
643
+ }
644
+ restore(sync, name) {
645
+ }
646
+ }
647
+ class SqliteRemoteConnection {
648
+ constructor(conn, name) {
649
+ this[_c] = false;
650
+ this[_daoConnection] = conn;
651
+ this[_sqliteRemoteName] = name;
652
+ }
653
+ execute(sync, sql, params) {
654
+ logger.debug(sql, params ?? '');
655
+ if (!sql) {
656
+ return { affectedRows: 0, insertId: 0n };
657
+ }
658
+ ;
659
+ if (sync === SqlSyncMode.Sync) {
660
+ logger.warn('SqliteRemote not suppouted sync mode');
661
+ return { affectedRows: 0, insertId: 0n };
662
+ }
663
+ ;
664
+ if (globalThis[_GlobalSqlOption].log === 'trace') {
665
+ logger.trace(Sqlstring.format(sql, params));
666
+ }
667
+ return new Promise(async (resolve) => {
668
+ try {
669
+ const { affectedRows, insertId } = await this[_daoConnection].execute(this[_sqliteRemoteName], sql, params);
670
+ resolve({ affectedRows, insertId: insertId ? BigInt(insertId) : 0n });
671
+ }
672
+ catch (error) {
673
+ logger.error(`
674
+ error: ${error},
675
+ sql: ${sql},
676
+ params: ${params}
677
+ `);
678
+ throw error;
679
+ }
680
+ });
681
+ }
682
+ pluck(sync, sql, params) {
683
+ logger.debug(sql, params ?? '');
684
+ if (!sql) {
685
+ return null;
686
+ }
687
+ ;
688
+ if (sync === SqlSyncMode.Sync) {
689
+ logger.warn('SqliteRemote not suppouted sync mode');
690
+ return null;
691
+ }
692
+ ;
693
+ if (globalThis[_GlobalSqlOption].log === 'trace') {
694
+ logger.trace(Sqlstring.format(sql, params));
695
+ }
696
+ return new Promise(async (resolve) => {
697
+ try {
698
+ const r = await this[_daoConnection].pluck(this[_sqliteRemoteName], sql, params);
699
+ resolve(r);
700
+ }
701
+ catch (error) {
702
+ logger.error(`
703
+ error: ${error},
704
+ sql: ${sql},
705
+ params: ${params}
706
+ `);
707
+ throw error;
708
+ }
709
+ });
710
+ }
711
+ get(sync, sql, params) {
712
+ logger.debug(sql, params ?? '');
713
+ if (!sql) {
714
+ return null;
715
+ }
716
+ ;
717
+ if (sync === SqlSyncMode.Sync) {
718
+ logger.warn('SqliteRemote not suppouted sync mode');
719
+ return null;
720
+ }
721
+ ;
722
+ if (globalThis[_GlobalSqlOption].log === 'trace') {
723
+ logger.trace(Sqlstring.format(sql, params));
724
+ }
725
+ return new Promise(async (resolve) => {
726
+ try {
727
+ const r = await this[_daoConnection].get(this[_sqliteRemoteName], sql, params);
728
+ resolve(r);
729
+ }
730
+ catch (error) {
731
+ logger.error(`
732
+ error: ${error},
733
+ sql: ${sql},
734
+ params: ${params}
735
+ `);
736
+ throw error;
737
+ }
738
+ });
739
+ }
740
+ raw(sync, sql, params) {
741
+ logger.debug(sql, params ?? '');
742
+ if (!sql) {
743
+ return [];
744
+ }
745
+ ;
746
+ if (sync === SqlSyncMode.Sync) {
747
+ logger.warn('SqliteRemote not suppouted sync mode');
748
+ return [];
749
+ }
750
+ ;
751
+ if (globalThis[_GlobalSqlOption].log === 'trace') {
752
+ logger.trace(Sqlstring.format(sql, params));
753
+ }
754
+ return new Promise(async (resolve) => {
755
+ try {
756
+ const r = await this[_daoConnection].raw(this[_sqliteRemoteName], sql, params);
757
+ resolve(r);
758
+ }
759
+ catch (error) {
760
+ logger.error(`
761
+ error: ${error},
762
+ sql: ${sql},
763
+ params: ${params}
764
+ `);
765
+ throw error;
766
+ }
767
+ });
768
+ }
769
+ query(sync, sql, params) {
770
+ logger.debug(sql, params ?? '');
771
+ if (!sql) {
772
+ return [];
773
+ }
774
+ ;
775
+ if (sync === SqlSyncMode.Sync) {
776
+ logger.warn('SqliteRemote not suppouted sync mode');
777
+ return [];
778
+ }
779
+ ;
780
+ if (globalThis[_GlobalSqlOption].log === 'trace') {
781
+ logger.trace(Sqlstring.format(sql, params));
782
+ }
783
+ return new Promise(async (resolve) => {
784
+ try {
785
+ const r = await this[_daoConnection].query(this[_sqliteRemoteName], sql, params);
786
+ resolve(r);
787
+ }
788
+ catch (error) {
789
+ logger.error(`
790
+ error: ${error},
791
+ sql: ${sql},
792
+ params: ${params}
793
+ `);
794
+ throw error;
795
+ }
796
+ });
797
+ }
798
+ realse(sync) {
799
+ }
800
+ }
801
+ _c = _inTransaction;
802
+ class SqliteRemote {
803
+ constructor(db, name) {
804
+ this[_daoDB] = db;
805
+ this[_sqliteRemoteName] = name;
806
+ }
807
+ createConnection(sync) {
808
+ if (sync === SqlSyncMode.Sync) {
809
+ logger.error('SQLITEREMOTE not suppouted sync mode');
810
+ return null;
811
+ }
812
+ ;
813
+ return new Promise(async (resolve) => {
814
+ resolve(new SqliteRemoteConnection(this[_daoDB], this[_sqliteRemoteName]));
815
+ });
816
+ }
817
+ transaction(sync, fn, conn) {
818
+ logger.warn(`SQLITEREMOTE not suppoted transaction`);
819
+ return null;
820
+ }
821
+ close(sync) {
822
+ if (sync === SqlSyncMode.Async) {
823
+ return new Promise(async () => {
824
+ await this[_daoConnection].close();
825
+ });
826
+ }
827
+ ;
828
+ }
829
+ backup(sync, name) {
830
+ if (sync === SqlSyncMode.Async) {
831
+ return new Promise(async () => {
832
+ await this[_daoConnection].backup(this[_sqliteRemoteName], name);
833
+ });
834
+ }
835
+ ;
836
+ }
837
+ remove(sync) {
838
+ if (sync === SqlSyncMode.Async) {
839
+ return new Promise(async () => {
840
+ await this[_daoConnection].remove();
841
+ });
842
+ }
843
+ ;
844
+ }
845
+ restore(sync, name) {
846
+ if (sync === SqlSyncMode.Async) {
847
+ return new Promise(async () => {
848
+ await this[_daoConnection].restore(this[_sqliteRemoteName], name);
849
+ });
850
+ }
851
+ ;
852
+ }
853
+ }
854
+ class SqlCache {
855
+ constructor() {
856
+ this.cache = {};
857
+ }
858
+ async init(options) {
859
+ if (options.sqlDir) {
860
+ const sqlFis = globalThis[_fs].readdirSync(options.sqlDir);
861
+ for (const modeName of sqlFis) {
862
+ const name = globalThis[_path].basename(modeName, globalThis[_path].extname(modeName));
863
+ const obj = await import(globalThis[_path].join(options.sqlDir, modeName));
864
+ for (const [key, fn] of Object.entries(obj)) {
865
+ this.cache[`${name}.${String(key)}`] = fn;
866
+ }
867
+ }
868
+ }
869
+ else if (options.sqlCache) {
870
+ this.cache = options.sqlCache;
871
+ }
872
+ }
873
+ load(sqlid, params, context, isPage) {
874
+ const sqlSource = this.cache[sqlid];
875
+ Throw.if(!sqlSource, `指定的语句${sqlid}不存在!`);
876
+ if (typeof sqlSource === 'string') {
877
+ return sqlSource;
878
+ }
879
+ else {
880
+ return sqlSource(params, context, isPage);
881
+ }
882
+ }
883
+ }
884
+ // #endregion
885
+ /**
886
+
887
+ ## 所有service中内置方法定义规则
888
+ ** 方法第一个参数必须是 sync: SyncMode
889
+ ** 方法最后一个参数必须是 option
890
+
891
+ ## sync 表示是否是同步方法
892
+
893
+ 因为mysql是异步、sqlite是同步,导致必须通过一个标识来区分,否则将必须为两种数据库设置不同的service,失去了意义
894
+
895
+ ## option 额外控制参数
896
+
897
+ ## length
898
+ 方法的参数数量
899
+ */
900
+ function P(skipConn = false) {
901
+ return (_target, propertyKey, descriptor) => {
902
+ const fn = descriptor.value;
903
+ descriptor.value = function (...args) {
904
+ let needRealseConn = true;
905
+ const startTime = +new Date();
906
+ // option
907
+ const option = args[0] = Object.assign({}, globalThis[_GlobalSqlOption], this[_SqlOption], args[0]);
908
+ option.sync ?? (option.sync = SqlSyncMode.Async);
909
+ const dbName = option?.dbName ?? this[_daoDBName] ?? _primaryDB;
910
+ option.dao = globalThis[_dao][this[_dbType]][dbName];
911
+ Throw.if(!option.dao, `not found db:${String(dbName)}(${this[_dbType]})`);
912
+ option.tableName = option?.tableName ?? this[_tableName];
913
+ const tableES = Sqlstring.escapeId(option.tableName);
914
+ if (this[_dbType] === DBType.Sqlite) {
915
+ Throw.if(option.sync === SqlSyncMode.Async, 'sqlite can not Async!');
916
+ // 连接共享
917
+ if (skipConn === false && !option.conn) {
918
+ option.conn = option.dao.createConnection(SqlSyncMode.Sync);
919
+ }
920
+ else {
921
+ needRealseConn = false;
922
+ }
923
+ if (skipConn === false) {
924
+ const lastVersion = this[_sqlite_version] ?? '0.0.1';
925
+ // 检查表
926
+ const tableCheckResult = option.conn.pluck(SqlSyncMode.Sync, `SELECT COUNT(1) t FROM sqlite_master WHERE TYPE = 'table' AND name = ?`, [option.tableName]);
927
+ if (tableCheckResult) {
928
+ // 旧版本
929
+ const tableVersion = option.conn.pluck(SqlSyncMode.Sync, 'SELECT ______version v from TABLE_VERSION WHERE ______tableName = ?', [option.tableName]);
930
+ if (tableVersion && tableVersion < lastVersion) { // 发现需要升级的版本
931
+ // 更新版本
932
+ const columns = iterare(option.conn.query(SqlSyncMode.Sync, `PRAGMA table_info(${tableES})`))
933
+ .filter(c => this[_fields].hasOwnProperty(c.name))
934
+ .map(c => Sqlstring.escapeId(c.name))
935
+ .join(',');
936
+ const rtable = Sqlstring.escapeId(`${option.tableName}_${tableVersion.replace(/\./, '_')}`);
937
+ option.conn.execute(SqlSyncMode.Sync, `DROP TABLE IF EXISTS ${rtable};`);
938
+ option.conn.execute(SqlSyncMode.Sync, `ALTER TABLE ${tableES} RENAME TO ${rtable};`);
939
+ option.conn.execute(SqlSyncMode.Sync, `
940
+ CREATE TABLE IF NOT EXISTS ${tableES}(
941
+ ${Object.values(this[_fields]).map(K => K[DBType.Sqlite]).join(',')}
942
+ ${this[_ids] && this[_ids].length ? `, PRIMARY KEY (${this[_ids].map(i => this[_fields][i]?.esName).join(',')})` : ''}
943
+ );
944
+ `);
945
+ if (this[_index] && this[_index].length) {
946
+ for (const index of this[_index]) {
947
+ option.conn.execute(SqlSyncMode.Sync, `CREATE INDEX ${Sqlstring.escapeId(`${index}_${Math.random()}`.replace(/\./, ''))} ON ${tableES} ("${index}");`);
948
+ }
949
+ }
950
+ option.conn.execute(SqlSyncMode.Sync, `INSERT INTO ${tableES} (${columns}) SELECT ${columns} FROM ${rtable};`);
951
+ option.conn.execute(SqlSyncMode.Sync, `INSERT INTO ${tableES} (${columns}) SELECT ${columns} FROM ${rtable};`);
952
+ option.conn.execute(SqlSyncMode.Sync, `DROP TABLE IF EXISTS ${rtable};`);
953
+ // 更新完毕,保存版本号
954
+ option.conn.execute(SqlSyncMode.Sync, 'UPDATE TABLE_VERSION SET ______version = ? WHERE ______tableName = ?', [option.tableName, lastVersion]);
955
+ }
956
+ else if (!tableVersion) { // 不需要升级情况:没有旧的版本号
957
+ option.conn.execute(SqlSyncMode.Sync, 'INSERT INTO TABLE_VERSION (______tableName, ______version ) VALUES ( ?, ? )', [option.tableName, lastVersion]);
958
+ }
959
+ }
960
+ else { // 表不存在
961
+ // 创建表
962
+ option.conn.execute(SqlSyncMode.Sync, `
963
+ CREATE TABLE IF NOT EXISTS ${tableES} (
964
+ ${Object.values(this[_fields]).map(K => K[DBType.Sqlite]).join(',')}
965
+ ${this[_ids] && this[_ids].length ? `, PRIMARY KEY (${this[_ids].map(i => this[_fields][i]?.esName).join(',')})` : ''}
966
+
967
+ );
968
+ `);
969
+ if (this[_index] && this[_index].length) {
970
+ for (const index of this[_index]) {
971
+ option.conn.execute(SqlSyncMode.Sync, `CREATE INDEX ${Sqlstring.escapeId(`${index}_${Math.random()}`.replace(/\./, ''))} ON ${tableES} ("${index}");`);
972
+ }
973
+ }
974
+ option.conn.execute(SqlSyncMode.Sync, 'INSERT OR REPLACE INTO TABLE_VERSION (______tableName, ______version ) VALUES ( ?, ? )', [option.tableName, lastVersion]);
975
+ }
976
+ }
977
+ try {
978
+ const result = fn.call(this, ...args);
979
+ logger.info(`${propertyKey}:${option.tableName}:use ${+new Date() - startTime}ms`);
980
+ return result;
981
+ }
982
+ catch (error) {
983
+ try {
984
+ console.error(`service ${propertyKey} have an error:${error}, it's argumens: ${JSON.stringify(args.filter(i => typeof i !== 'object' || (typeof i === 'object' && !i.insert)))}`);
985
+ }
986
+ catch (error) {
987
+ }
988
+ throw error;
989
+ }
990
+ finally {
991
+ if (needRealseConn && option && option.conn) {
992
+ try {
993
+ option.conn.realse(SqlSyncMode.Sync);
994
+ }
995
+ catch (error) {
996
+ }
997
+ }
998
+ }
999
+ }
1000
+ else if (this[_dbType] === DBType.SqliteRemote) {
1001
+ Throw.if(option.sync === SqlSyncMode.Sync, 'SqliteRemote remote can not sync!');
1002
+ return new Promise(async (resolve) => {
1003
+ // 连接共享
1004
+ if (skipConn === false && !option.conn) {
1005
+ (option).conn = await option.dao.createConnection(SqlSyncMode.Async);
1006
+ }
1007
+ else {
1008
+ needRealseConn = false;
1009
+ }
1010
+ if (skipConn === false) {
1011
+ const lastVersion = this[_sqlite_version] ?? '0.0.1';
1012
+ // 检查表
1013
+ const tableCheckResult = await option.conn.pluck(SqlSyncMode.Async, `SELECT COUNT(1) t FROM sqlite_master WHERE TYPE = 'table' AND name = ?`, [option.tableName]);
1014
+ if (tableCheckResult) {
1015
+ // 旧版本
1016
+ const tableVersion = await option.conn.pluck(SqlSyncMode.Async, 'SELECT ______version v from TABLE_VERSION WHERE ______tableName = ?', [option.tableName]);
1017
+ if (tableVersion && tableVersion < lastVersion) { // 发现需要升级的版本
1018
+ // 更新版本
1019
+ const columns = iterare(await option.conn.query(SqlSyncMode.Async, `PRAGMA table_info(${tableES})`))
1020
+ .filter(c => this[_fields].hasOwnProperty(c.name))
1021
+ .map(c => Sqlstring.escapeId(c.name))
1022
+ .join(',');
1023
+ const rtable = `${option.tableName}_${tableVersion.replace(/\./, '_')}`;
1024
+ await option.conn.execute(SqlSyncMode.Async, `DROP TABLE IF EXISTS ${rtable};`);
1025
+ await option.conn.execute(SqlSyncMode.Async, `ALTER TABLE ${tableES} RENAME TO ${rtable};`);
1026
+ await option.conn.execute(SqlSyncMode.Async, `
1027
+ CREATE TABLE IF NOT EXISTS ${tableES}(
1028
+ ${Object.values(this[_fields]).map(K => K[DBType.Sqlite]).join(',')}
1029
+ ${this[_ids] && this[_ids].length ? `, PRIMARY KEY (${this[_ids].map(i => this[_fields][i]?.esName).join(',')})` : ''}
1030
+ );
1031
+ `);
1032
+ if (this[_index] && this[_index].length) {
1033
+ for (const index of this[_index]) {
1034
+ await option.conn.execute(SqlSyncMode.Async, `CREATE INDEX ${Sqlstring.escapeId(`${index}_${Math.random()}`.replace(/\./, ''))} ON ${tableES} ("${index}");`);
1035
+ }
1036
+ }
1037
+ await option.conn.execute(SqlSyncMode.Async, `INSERT INTO ${tableES} (${columns}) SELECT ${columns} FROM ${rtable};`);
1038
+ await option.conn.execute(SqlSyncMode.Async, `INSERT INTO ${tableES} (${columns}) SELECT ${columns} FROM ${rtable};`);
1039
+ await option.conn.execute(SqlSyncMode.Async, `DROP TABLE IF EXISTS ${rtable};`);
1040
+ // 更新完毕,保存版本号
1041
+ await option.conn.execute(SqlSyncMode.Async, 'UPDATE TABLE_VERSION SET ______version = ? WHERE ______tableName = ?', [option.tableName, lastVersion]);
1042
+ }
1043
+ else if (!tableVersion) { // 不需要升级情况:没有旧的版本号
1044
+ await option.conn.execute(SqlSyncMode.Async, 'INSERT INTO TABLE_VERSION (______tableName, ______version ) VALUES ( ?, ? )', [option.tableName, lastVersion]);
1045
+ }
1046
+ }
1047
+ else { // 表不存在
1048
+ // 创建表
1049
+ await option.conn.execute(SqlSyncMode.Async, `
1050
+ CREATE TABLE IF NOT EXISTS ${tableES}(
1051
+ ${Object.values(this[_fields]).map(K => K[DBType.Sqlite]).join(',')}
1052
+ ${this[_ids] && this[_ids].length ? `, PRIMARY KEY (${this[_ids].map(i => this[_fields][i]?.esName).join(',')})` : ''}
1053
+ );
1054
+ `);
1055
+ if (this[_index] && this[_index].length) {
1056
+ for (const index of this[_index]) {
1057
+ await option.conn.execute(SqlSyncMode.Async, `CREATE INDEX ${Sqlstring.escapeId(`${index}_${Math.random()}`.replace(/\./, ''))} ON ${Sqlstring.escapeId(option.tableName)} ("${index}");`);
1058
+ }
1059
+ }
1060
+ await option.conn.execute(SqlSyncMode.Async, 'INSERT OR REPLACE INTO TABLE_VERSION (______tableName, ______version ) VALUES ( ?, ? )', [option.tableName, lastVersion]);
1061
+ }
1062
+ }
1063
+ try {
1064
+ const result = await fn.call(this, ...args);
1065
+ logger.info(`${propertyKey}:${option.tableName}:use ${+new Date() - startTime}ms`);
1066
+ resolve(result);
1067
+ }
1068
+ catch (error) {
1069
+ console.error(`service ${propertyKey} have an error:${error}, it's argumens: ${JSON.stringify(args.filter(i => typeof i !== 'object' || (typeof i === 'object' && !i.insert)))}`);
1070
+ throw error;
1071
+ }
1072
+ finally {
1073
+ if (needRealseConn && option && option.conn) {
1074
+ try {
1075
+ option.conn.realse(SqlSyncMode.Sync);
1076
+ }
1077
+ catch (error) {
1078
+ }
1079
+ }
1080
+ }
1081
+ });
1082
+ }
1083
+ else if (this[_dbType] === DBType.Mysql) {
1084
+ return new Promise(async (resolve) => {
1085
+ try {
1086
+ // 连接共享
1087
+ if (skipConn === false && !option.conn) {
1088
+ (option).conn = await option.dao.createConnection(SqlSyncMode.Async);
1089
+ }
1090
+ else {
1091
+ needRealseConn = false;
1092
+ }
1093
+ const result = await fn.call(this, ...args);
1094
+ logger.info(`${propertyKey}:${option.tableName}:use ${+new Date() - startTime}ms`);
1095
+ resolve(result);
1096
+ }
1097
+ catch (error) {
1098
+ console.error(`service ${propertyKey} have an error:${error}, it's argumens: ${JSON.stringify(args.filter(i => typeof i !== 'object' || (typeof i === 'object' && !i.insert)))}`);
1099
+ throw error;
1100
+ }
1101
+ finally {
1102
+ if (needRealseConn && option && option.conn) {
1103
+ try {
1104
+ option.conn.realse(SqlSyncMode.Sync);
1105
+ }
1106
+ catch (error) {
1107
+ }
1108
+ }
1109
+ }
1110
+ });
1111
+ }
1112
+ };
1113
+ };
1114
+ }
1115
+ const FieldFilter = (K, V, def, option) => {
1116
+ let ret = 0;
1117
+ if (V === null) {
1118
+ if (option?.skipNull !== true) {
1119
+ ret = 1;
1120
+ V = option?.def === true && def && def.hasOwnProperty(K) ? def[K] : null;
1121
+ }
1122
+ }
1123
+ else if (V === undefined) {
1124
+ if (option?.skipUndefined !== true) {
1125
+ ret = 1;
1126
+ V = option?.def === true && def && def.hasOwnProperty(K) ? def[K] : null;
1127
+ }
1128
+ }
1129
+ else if (emptyString(`${V ?? ''}`)) {
1130
+ if (option?.skipEmptyString !== true) {
1131
+ ret = 1;
1132
+ V = option?.def === true && def && def.hasOwnProperty(K) ? def[K] : '';
1133
+ }
1134
+ }
1135
+ else {
1136
+ ret = 1;
1137
+ }
1138
+ if (ret === 1) {
1139
+ option?.finalColumns?.add(K);
1140
+ option?.tempColumns?.push(K);
1141
+ }
1142
+ return [ret, V];
1143
+ };
1144
+ const MYSQLCHARSET = `CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci`;
1145
+ export const Field = (config) => {
1146
+ config.type ?? (config.type = SqlType.varchar);
1147
+ return (object, propertyName) => {
1148
+ const field = config;
1149
+ field.name = propertyName;
1150
+ field.esName = Sqlstring.escapeId(propertyName);
1151
+ const hasDef = field.hasOwnProperty('def') === true;
1152
+ switch (field.type) {
1153
+ case SqlType.bigint: {
1154
+ field[DBType.Mysql] = `${field.esName} bigint ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''} ${MYSQLCHARSET}`;
1155
+ field[DBType.SqliteRemote] = field[DBType.Sqlite] = `${field.esName} integer`;
1156
+ break;
1157
+ }
1158
+ case SqlType.char: {
1159
+ field[DBType.Mysql] = `${field.esName} char(${config.length1 ?? 1}) ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''} ${MYSQLCHARSET}`;
1160
+ field[DBType.SqliteRemote] = field[DBType.Sqlite] = `${field.esName} text`;
1161
+ break;
1162
+ }
1163
+ case SqlType.decimal: {
1164
+ field[DBType.Mysql] = `${field.esName} decimal(${config.length1 ?? 1}, ${config.length2 ?? 2}) ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''} `;
1165
+ field[DBType.SqliteRemote] = field[DBType.Sqlite] = `${field.esName} real`;
1166
+ break;
1167
+ }
1168
+ case SqlType.int: {
1169
+ field[DBType.Mysql] = `${field.esName} int ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''}`;
1170
+ field[DBType.SqliteRemote] = field[DBType.Sqlite] = `${field.esName} integer`;
1171
+ break;
1172
+ }
1173
+ case SqlType.longtext: {
1174
+ field[DBType.Mysql] = `${field.esName} longtext ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''} ${MYSQLCHARSET}`;
1175
+ field[DBType.SqliteRemote] = field[DBType.Sqlite] = `${field.esName} text`;
1176
+ break;
1177
+ }
1178
+ case SqlType.mediumtext: {
1179
+ field[DBType.Mysql] = `${field.esName} mediumtext ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''} ${MYSQLCHARSET}`;
1180
+ field[DBType.SqliteRemote] = field[DBType.Sqlite] = `${field.esName} text`;
1181
+ break;
1182
+ }
1183
+ case SqlType.smallint: {
1184
+ field[DBType.Mysql] = `${field.esName} smallint ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''}`;
1185
+ field[DBType.SqliteRemote] = field[DBType.Sqlite] = `${field.esName} text`;
1186
+ break;
1187
+ }
1188
+ case SqlType.text: {
1189
+ field[DBType.Mysql] = `${field.esName} text ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''} ${MYSQLCHARSET}`;
1190
+ field[DBType.SqliteRemote] = field[DBType.Sqlite] = `${field.esName} text`;
1191
+ break;
1192
+ }
1193
+ case SqlType.tinyint: {
1194
+ field[DBType.Mysql] = `${field.esName} tinyint ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''}`;
1195
+ field[DBType.SqliteRemote] = field[DBType.Sqlite] = `${field.esName} text`;
1196
+ break;
1197
+ }
1198
+ case SqlType.varchar: {
1199
+ field[DBType.Mysql] = `${field.esName} varchar(${config.length1 ?? 1}) ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''} ${MYSQLCHARSET}`;
1200
+ field[DBType.SqliteRemote] = field[DBType.Sqlite] = `${field.esName} text`;
1201
+ break;
1202
+ }
1203
+ }
1204
+ ;
1205
+ let __fields = Reflect.getMetadata(_fields, object);
1206
+ let __columns = Reflect.getMetadata(_columns, object);
1207
+ let __columnsNoId = Reflect.getMetadata(_columnsNoId, object);
1208
+ let __ids = Reflect.getMetadata(_ids, object);
1209
+ let __index = Reflect.getMetadata(_index, object);
1210
+ let __def = Reflect.getMetadata(_def, object);
1211
+ if (!__fields) {
1212
+ __fields = {};
1213
+ __columns = [];
1214
+ __columnsNoId = [];
1215
+ __ids = [];
1216
+ __index = [];
1217
+ __def = {};
1218
+ }
1219
+ __fields[propertyName] = field;
1220
+ __columns.push(propertyName);
1221
+ if (field.id === true) {
1222
+ __ids.push(propertyName);
1223
+ }
1224
+ else {
1225
+ __columnsNoId.push(propertyName);
1226
+ }
1227
+ if (field.index === true) {
1228
+ __index.push(propertyName);
1229
+ }
1230
+ if (hasDef) {
1231
+ __def[propertyName] = field.def;
1232
+ }
1233
+ Reflect.defineMetadata(_fields, __fields, object);
1234
+ Reflect.defineMetadata(_columns, __columns, object);
1235
+ Reflect.defineMetadata(_columnsNoId, __columnsNoId, object);
1236
+ Reflect.defineMetadata(_ids, __ids, object);
1237
+ Reflect.defineMetadata(_index, __index, object);
1238
+ Reflect.defineMetadata(_def, __def, object);
1239
+ if (field.hasOwnProperty('logicDelete')) {
1240
+ Reflect.defineMetadata(_deleteState, field.logicDelete, object);
1241
+ Reflect.defineMetadata(_stateFileName, propertyName, object);
1242
+ }
1243
+ };
1244
+ };
1245
+ export const DB = (config) => {
1246
+ return function (constructor) {
1247
+ var _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
1248
+ const __ids = Reflect.getMetadata(_ids, config.clz.prototype) || new Array;
1249
+ const __fields = Reflect.getMetadata(_fields, config.clz.prototype);
1250
+ const __columns = Reflect.getMetadata(_columns, config.clz.prototype);
1251
+ const __columnsNoId = __columns.filter((c) => __ids.includes(c) === false);
1252
+ const __stateFileName = Reflect.getMetadata(_stateFileName, config.clz.prototype);
1253
+ const __deleteState = Reflect.getMetadata(_deleteState, config.clz.prototype);
1254
+ const __index = Reflect.getMetadata(_index, config.clz.prototype);
1255
+ const __def = Reflect.getMetadata(_def, config.clz.prototype);
1256
+ return _t = class extends constructor {
1257
+ constructor() {
1258
+ super(...arguments);
1259
+ this[_d] = config.tableName;
1260
+ this[_e] = config.dbName;
1261
+ this[_f] = config.dbType ?? DBType.Mysql;
1262
+ this[_g] = config.sqliteVersion;
1263
+ this[_h] = Object.assign({}, _defOption, config);
1264
+ this[_j] = __ids;
1265
+ this[_k] = __fields;
1266
+ this[_l] = __columns;
1267
+ this[_m] = __columnsNoId;
1268
+ this[_o] = __index;
1269
+ this[_p] = __def;
1270
+ this[_q] = __stateFileName;
1271
+ this[_r] = __deleteState;
1272
+ this[_s] = (data, option) => {
1273
+ return Object.fromEntries(iterare(option?.skipId === true ? __columnsNoId : __columns)
1274
+ .map(K => [K, FieldFilter(K, data[K], __def, option)])
1275
+ .filter(data => {
1276
+ if (data[1][0] === 1) {
1277
+ if (option?.onFieldExists) {
1278
+ option.onFieldExists(data[0], data[1][1]);
1279
+ }
1280
+ return true;
1281
+ }
1282
+ else {
1283
+ return false;
1284
+ }
1285
+ })
1286
+ .map(data => [data[0], data[1][1]])
1287
+ .toArray());
1288
+ };
1289
+ }
1290
+ },
1291
+ _d = _tableName,
1292
+ _e = _daoDBName,
1293
+ _f = _dbType,
1294
+ _g = _sqlite_version,
1295
+ _h = _SqlOption,
1296
+ _j = _ids,
1297
+ _k = _fields,
1298
+ _l = _columns,
1299
+ _m = _columnsNoId,
1300
+ _o = _index,
1301
+ _p = _def,
1302
+ _q = _stateFileName,
1303
+ _r = _deleteState,
1304
+ _s = _transformer,
1305
+ _t;
1306
+ };
1307
+ };
1308
+ /**
1309
+ js项目中实体类注解替代品,只要确保函数被执行即可,举例:
1310
+ ```
1311
+ // 声明一个class
1312
+ export class AmaFuck {}
1313
+ DeclareClass(AmaFuck, [
1314
+ { type: "String", name: "SellerSKU" },
1315
+ { type: "String", name: "SellerSKU2" },
1316
+ { type: "String", name: "site" }
1317
+ ]);
1318
+ ```
1319
+ */
1320
+ export function DeclareClass(clz, FieldOptions) {
1321
+ for (const item of FieldOptions) {
1322
+ tslib.__decorate([Field(item)], clz.prototype, item.name, void 0);
1323
+ }
1324
+ }
1325
+ /**
1326
+ JS项目中,service注解代替,举例:
1327
+ ```
1328
+ // 声明一个service,注意这里的let
1329
+ export let AmaService = class AmaService extends SqlService {};
1330
+ AmaService = DeclareService(AmaService, {
1331
+ tableName: "ama_fuck2",
1332
+ clz: AmaFuck,
1333
+ dbType: DBType.Sqlite,
1334
+ sqliteVersion: "0.0.3"
1335
+ });
1336
+ ```
1337
+ */
1338
+ export function DeclareService(clz, config) {
1339
+ return tslib.__decorate([DB(config)], clz);
1340
+ }
1341
+ /**
1342
+ ## 数据库服务
1343
+ ### 注解DB
1344
+
1345
+ ### 泛型 T,同DB注解中的clz
1346
+ ** 服务中所有方法默认以该类型为准
1347
+ **
1348
+
1349
+ */
1350
+ export class SqlService {
1351
+ _insert(datas, option) {
1352
+ const sqls = [];
1353
+ const tableName = Sqlstring.escapeId(option.tableName);
1354
+ switch (option?.mode) {
1355
+ case SqlInsertMode.InsertIfNotExists: {
1356
+ const conditions = option.existConditionOtherThanIds || this[_ids];
1357
+ Throw.if(!conditions, 'not found where condition for insertIfNotExists!');
1358
+ Throw.if(conditions.length === 0, 'insertIfNotExists must have not null where!');
1359
+ const where = iterare(conditions).map(c => `${this[_fields][c]?.esName} = ?`).join(' AND ');
1360
+ const finalColumns = new Set();
1361
+ const whereColumns = conditions;
1362
+ const params = datas
1363
+ .map(data => this[_transformer](data, { ...option, finalColumns, def: true }))
1364
+ .flatMap(data => {
1365
+ const result = [];
1366
+ const questMark = new Array();
1367
+ for (const column of finalColumns) {
1368
+ questMark.push('?');
1369
+ result.push(data.hasOwnProperty(column)
1370
+ ? data[column]
1371
+ : this[_def] && this[_def].hasOwnProperty(column)
1372
+ ? this[_def][column]
1373
+ : null);
1374
+ }
1375
+ for (const column of whereColumns) {
1376
+ questMark.push('?');
1377
+ result.push(data.hasOwnProperty(column)
1378
+ ? data[column]
1379
+ : this[_def] && this[_def].hasOwnProperty(column)
1380
+ ? this[_def][column]
1381
+ : null);
1382
+ }
1383
+ return result;
1384
+ });
1385
+ const quests = new Array(finalColumns.size).fill('?').join(',');
1386
+ const columnNames = iterare(finalColumns).map(i => this[_fields][i]?.esName).join(',');
1387
+ const selects = iterare(new Array(datas.length)).map(() => `SELECT ${quests} FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM ${tableName} WHERE ${where})`).join(' UNION ALL ');
1388
+ const sql = `INSERT INTO
1389
+ ${tableName}
1390
+ (${columnNames})
1391
+ ${selects};`;
1392
+ sqls.push({ sql, params });
1393
+ }
1394
+ case SqlInsertMode.Replace: {
1395
+ const finalColumns = new Set();
1396
+ const params = datas
1397
+ .map(data => this[_transformer](data, { ...option, finalColumns, def: true }))
1398
+ .flatMap(data => {
1399
+ const result = [];
1400
+ const questMark = new Array();
1401
+ for (const column of finalColumns) {
1402
+ questMark.push('?');
1403
+ result.push(data.hasOwnProperty(column)
1404
+ ? data[column]
1405
+ : this[_def] && this[_def].hasOwnProperty(column)
1406
+ ? this[_def][column]
1407
+ : null);
1408
+ }
1409
+ return result;
1410
+ });
1411
+ const quests = new Array(finalColumns.size).fill('?').join(',');
1412
+ const columnNames = iterare(finalColumns).map(i => this[_fields][i]?.esName).join(',');
1413
+ const questMarks = iterare(new Array(datas.length)).map(() => `(${quests})`).join(',');
1414
+ const sql = `
1415
+ ${this[_dbType] === DBType.Mysql ? '' : 'INSERT OR'} REPLACE INTO
1416
+ ${tableName}
1417
+ (${columnNames})
1418
+ VALUES ${questMarks};
1419
+ `;
1420
+ sqls.push({ sql, params });
1421
+ }
1422
+ case SqlInsertMode.Insert: {
1423
+ const finalColumns = new Set();
1424
+ const params = datas
1425
+ .map(data => this[_transformer](data, { ...option, finalColumns, def: true }))
1426
+ .flatMap(data => {
1427
+ const result = [];
1428
+ const questMark = new Array();
1429
+ for (const column of finalColumns) {
1430
+ questMark.push('?');
1431
+ result.push(data.hasOwnProperty(column)
1432
+ ? data[column]
1433
+ : this[_def] && this[_def].hasOwnProperty(column)
1434
+ ? this[_def][column]
1435
+ : null);
1436
+ }
1437
+ return result;
1438
+ });
1439
+ const quests = new Array(finalColumns.size).fill('?').join(',');
1440
+ const columnNames = iterare(finalColumns).map(i => this[_fields][i]?.esName).join(',');
1441
+ const questMarks = iterare(new Array(datas.length)).map(() => `(${quests})`).join(',');
1442
+ const sql = `
1443
+ INSERT INTO
1444
+ ${tableName}
1445
+ (${columnNames})
1446
+ VALUES ${questMarks};
1447
+ `;
1448
+ sqls.push({ sql, params });
1449
+ }
1450
+ case SqlInsertMode.InsertWithTempTable: {
1451
+ const tableTemp = `${option?.tableName}_${Math.random()}`.replace(/\./, '');
1452
+ const tableTempESC = Sqlstring.escapeId(tableTemp);
1453
+ sqls.push({ sql: `DROP TABLE IF EXISTS ${tableTempESC};` });
1454
+ const finalColumns = new Set();
1455
+ const params = datas
1456
+ .map(data => this[_transformer](data, { ...option, finalColumns, def: true }))
1457
+ .flatMap(data => {
1458
+ const result = [];
1459
+ const questMark = new Array();
1460
+ for (const column of finalColumns) {
1461
+ questMark.push('?');
1462
+ result.push(data.hasOwnProperty(column)
1463
+ ? data[column]
1464
+ : this[_def] && this[_def].hasOwnProperty(column)
1465
+ ? this[_def][column]
1466
+ : null);
1467
+ }
1468
+ return result;
1469
+ });
1470
+ const _sqls = this._createTable({ tableName: tableTemp, temp: true, columns: Array.from(finalColumns) });
1471
+ sqls.push(..._sqls);
1472
+ const quests = new Array(finalColumns.size).fill('?').join(',');
1473
+ const columnNames = iterare(finalColumns).map(i => this[_fields][i]?.esName).join(',');
1474
+ const questMarks = iterare(new Array(datas.length)).map(() => `(${quests})`).join(',');
1475
+ sqls.push({
1476
+ sql: `
1477
+ INSERT INTO
1478
+ ${tableTemp}
1479
+ (${columnNames})
1480
+ VALUES ${questMarks};
1481
+ `, params
1482
+ });
1483
+ sqls.push({
1484
+ sql: `INSERT INTO ${Sqlstring.escapeId(option.tableName)} (${columnNames})
1485
+ SELECT ${columnNames} FROM ${tableTemp};`
1486
+ });
1487
+ sqls.push({ sql: `DROP TABLE IF EXISTS ${tableTempESC};` });
1488
+ }
1489
+ }
1490
+ return sqls;
1491
+ }
1492
+ insert(option) {
1493
+ option.mode ?? (option.mode = SqlInsertMode.Insert);
1494
+ const isArray = option.data instanceof Array;
1495
+ const datas = option.data instanceof Array ? option.data : [option.data];
1496
+ if (option.sync === SqlSyncMode.Sync) {
1497
+ const fn = () => {
1498
+ const result = excuteSplit(ExcuteSplitMode.SyncTrust, datas, _data => {
1499
+ const sqls = this._insert(_data, option);
1500
+ let result = 0n;
1501
+ for (const { sql, params } of sqls) {
1502
+ const dd = option.conn.execute(SqlSyncMode.Sync, sql, params);
1503
+ if (dd.insertId) {
1504
+ result += dd.insertId;
1505
+ }
1506
+ }
1507
+ return result;
1508
+ }, { everyLength: option?.every === true ? 1 : option?.maxDeal });
1509
+ if (isArray)
1510
+ return result;
1511
+ else
1512
+ return result[0];
1513
+ };
1514
+ if (option?.conn?.[_inTransaction] === true) {
1515
+ return fn();
1516
+ }
1517
+ else {
1518
+ return option?.dao?.transaction(SqlSyncMode.Sync, fn, option?.conn);
1519
+ }
1520
+ }
1521
+ else if (isArray) {
1522
+ const fn = async () => {
1523
+ return await option?.dao?.transaction(SqlSyncMode.Async, async () => {
1524
+ const result = await excuteSplit(ExcuteSplitMode.AsyncTrust, datas, async (_data) => {
1525
+ const sqls = this._insert(_data, option);
1526
+ let result = 0n;
1527
+ for (const { sql, params } of sqls) {
1528
+ const dd = await option?.conn.execute(SqlSyncMode.Async, sql, params);
1529
+ if (dd.insertId) {
1530
+ result += dd.insertId;
1531
+ }
1532
+ }
1533
+ return result;
1534
+ }, { everyLength: option?.every === true ? 1 : option?.maxDeal });
1535
+ return result;
1536
+ }, option?.conn);
1537
+ };
1538
+ return new Promise(async (resolve) => {
1539
+ if (option?.conn?.[_inTransaction] === true) {
1540
+ resolve((await fn()));
1541
+ }
1542
+ else {
1543
+ await option?.dao?.transaction(SqlSyncMode.Async, async () => resolve((await fn())), option?.conn);
1544
+ }
1545
+ });
1546
+ }
1547
+ else {
1548
+ const fn = async () => {
1549
+ const result = await excuteSplit(ExcuteSplitMode.AsyncTrust, datas, async (_data) => {
1550
+ const sqls = this._insert(_data, option);
1551
+ let result = 0n;
1552
+ for (const { sql, params } of sqls) {
1553
+ const dd = await option.conn.execute(SqlSyncMode.Async, sql, params);
1554
+ if (dd.insertId) {
1555
+ result += dd.insertId;
1556
+ }
1557
+ }
1558
+ return result;
1559
+ }, { everyLength: 1 });
1560
+ return result[0];
1561
+ };
1562
+ return new Promise(async (resolve) => {
1563
+ if (option?.conn?.[_inTransaction] === true) {
1564
+ resolve((await fn()));
1565
+ }
1566
+ else {
1567
+ await option?.dao?.transaction(SqlSyncMode.Async, async () => resolve((await fn())), option?.conn);
1568
+ }
1569
+ });
1570
+ }
1571
+ }
1572
+ _update(datas, option) {
1573
+ const sqls = [];
1574
+ const tableName = Sqlstring.escapeId(option?.tableName);
1575
+ const where = `WHEN ${iterare(this[_ids]).map(c => `${this[_fields][c]?.esName} = ?`).join(' AND ')} THEN ?`;
1576
+ const columnMaps = Object.fromEntries(this[_columnsNoId].map(c => [c, {
1577
+ where: new Array(),
1578
+ params: []
1579
+ }]));
1580
+ const params = [];
1581
+ for (const data of datas) {
1582
+ const ids = this[_ids].map(i => {
1583
+ Throw.if(!data[i], `UPDATE ID NOT EXISTS!${JSON.stringify(data)}`);
1584
+ return data[i];
1585
+ });
1586
+ this[_transformer](data, {
1587
+ ...option,
1588
+ skipId: true,
1589
+ onFieldExists: (K, V) => {
1590
+ columnMaps[K]?.where.push(where);
1591
+ columnMaps[K]?.params.push(...ids, V);
1592
+ }
1593
+ });
1594
+ }
1595
+ const sql = `UPDATE ${tableName} SET ${iterare(this[_columnsNoId])
1596
+ .filter(K => columnMaps[K].where.length > 0)
1597
+ .map(K => {
1598
+ params.push(...columnMaps[K].params);
1599
+ return `${this[_fields][K]?.esName} = CASE ${columnMaps[K].where.join(' ')} ELSE ${this[_fields][K]?.esName} END`;
1600
+ })
1601
+ .join(',')};`;
1602
+ sqls.push({ sql, params });
1603
+ return sqls;
1604
+ }
1605
+ update(option) {
1606
+ Throw.if(!this[_ids] || this[_ids].length === 0, 'not found id');
1607
+ const datas = option.data instanceof Array ? option.data : [option.data];
1608
+ if (option.sync === SqlSyncMode.Sync) {
1609
+ const fn = () => {
1610
+ const result = excuteSplit(ExcuteSplitMode.SyncTrust, datas, _data => {
1611
+ const sqls = this._update(_data, option);
1612
+ let result = 0;
1613
+ for (const { sql, params } of sqls) {
1614
+ const dd = option.conn.execute(SqlSyncMode.Sync, sql, params);
1615
+ if (dd.affectedRows) {
1616
+ result += dd.affectedRows;
1617
+ }
1618
+ }
1619
+ return result;
1620
+ }, { everyLength: option?.maxDeal });
1621
+ return result.reduce((a, b) => a + b);
1622
+ };
1623
+ if (option?.conn?.[_inTransaction] === true) {
1624
+ return fn();
1625
+ }
1626
+ else {
1627
+ return option?.dao?.transaction(SqlSyncMode.Sync, fn, option?.conn);
1628
+ }
1629
+ }
1630
+ else {
1631
+ const fn = async () => {
1632
+ const result = await excuteSplit(ExcuteSplitMode.AsyncTrust, datas, async (_data) => {
1633
+ const sqls = this._update(_data, option);
1634
+ let result = 0;
1635
+ for (const { sql, params } of sqls) {
1636
+ const dd = await option.conn.execute(SqlSyncMode.Async, sql, params);
1637
+ if (dd.affectedRows) {
1638
+ result += dd.affectedRows;
1639
+ }
1640
+ }
1641
+ return result;
1642
+ }, { everyLength: option?.maxDeal });
1643
+ return result.reduce((a, b) => a + b);
1644
+ };
1645
+ return new Promise(async (resolve) => {
1646
+ if (option?.conn?.[_inTransaction] === true) {
1647
+ resolve((await fn()));
1648
+ }
1649
+ else {
1650
+ await option?.dao?.transaction(SqlSyncMode.Async, async () => resolve((await fn())), option?.conn);
1651
+ }
1652
+ });
1653
+ }
1654
+ }
1655
+ delete(option) {
1656
+ Throw.if(!!this[_ids] && this[_ids].length > 1 && !option.where, 'muit id must set where!');
1657
+ Throw.if((!this[_ids] || this[_ids].length === 0) && !option.where, 'if not set id on class, must set where!');
1658
+ Throw.if(!option.id && !option.where, 'not found id or where!');
1659
+ Throw.if(!!option.id && !!this[_ids] && this[_ids].length > 1, 'muit id must set where!');
1660
+ Throw.if(!!option.id && !!option.where, 'id and where only one can set!');
1661
+ option.mode ?? (option.mode = SqlDelMode.Common);
1662
+ const tableTemp = `${option?.tableName}_${Math.random()}`.replace(/\./, '');
1663
+ const tableTempESC = Sqlstring.escapeId(tableTemp);
1664
+ const tableNameESC = Sqlstring.escapeId(option?.tableName);
1665
+ if (option.id) {
1666
+ const idName = this[_ids][0];
1667
+ const ids = option.id instanceof Array ? option.id : [option.id];
1668
+ option.where = ids.map(i => ({ [idName]: i }));
1669
+ }
1670
+ const wheres = option.where instanceof Array ? option.where : [option.where];
1671
+ const sqls = [];
1672
+ if (option.mode === SqlDelMode.Common) {
1673
+ const params = new Array();
1674
+ const whereSql = iterare(wheres).map(where => {
1675
+ return `(
1676
+ ${Object.entries(where).map(([K, V]) => {
1677
+ params.push(V);
1678
+ return `${K} = ?`;
1679
+ }).join(' AND ')}
1680
+ )`;
1681
+ }).join(' OR ');
1682
+ if (this[_stateFileName] !== undefined && option.forceDelete !== true) {
1683
+ sqls.push({
1684
+ sql: `
1685
+ UPDATE ${tableNameESC} SET ${this[_fields][this[_stateFileName]]?.esName} = ${Sqlstring.escape(this[_deleteState])}
1686
+ WHERE ${whereSql};
1687
+ `, params
1688
+ });
1689
+ }
1690
+ else {
1691
+ sqls.push({ sql: `DELETE FROM ${tableNameESC} WHERE ${whereSql};`, params });
1692
+ }
1693
+ }
1694
+ else {
1695
+ sqls.push({ sql: `DROP TABLE IF EXISTS ${tableTempESC};` });
1696
+ const delWhere = Object.keys(wheres[0]);
1697
+ const _sqls = this._createTable({ tableName: tableTemp, temp: true, columns: delWhere, data: wheres, index: 'all', id: 'none' });
1698
+ sqls.push(..._sqls);
1699
+ switch (this[_dbType]) {
1700
+ case DBType.Mysql: {
1701
+ if (this[_stateFileName] !== undefined && option.forceDelete !== true) {
1702
+ sqls.push({
1703
+ sql: `UPDATE ${tableNameESC} a INNER JOIN ${tableTempESC} b ON ${delWhere.map(K => `a.${this[_fields][K]?.esName} = b.${this[_fields][K]?.esName}`).join(' AND ')}
1704
+ SET a.${this[_fields][this[_stateFileName]]?.esName} = ${Sqlstring.escape(this[_deleteState])};`
1705
+ });
1706
+ }
1707
+ else {
1708
+ sqls.push({
1709
+ sql: `DELETE a.* FROM ${tableNameESC} a INNER JOIN ${tableTempESC} b ON ${delWhere.map(K => `a.${this[_fields][K]?.esName} = b.${this[_fields][K]?.esName}`).join(' AND ')};`
1710
+ });
1711
+ }
1712
+ }
1713
+ case DBType.Sqlite:
1714
+ case DBType.SqliteRemote: {
1715
+ const columnNames = iterare(delWhere).map(K => this[_fields][K]?.esName).join(',');
1716
+ if (this[_stateFileName] !== undefined && option.forceDelete !== true) {
1717
+ sqls.push({
1718
+ sql: `UPDATE ${tableNameESC} SET ${this[_fields][this[_stateFileName]]?.esName} = ${Sqlstring.escape(this[_deleteState])}
1719
+ WHERE (${columnNames}) IN (SELECT ${columnNames} FROM ${tableTempESC});`
1720
+ });
1721
+ }
1722
+ else {
1723
+ sqls.push({ sql: `DELETE FROM ${tableNameESC} WHERE (${columnNames}) IN (SELECT ${columnNames} FROM ${tableTempESC});` });
1724
+ }
1725
+ }
1726
+ }
1727
+ sqls.push({ sql: `DROP TABLE IF EXISTS ${tableTempESC};` });
1728
+ }
1729
+ if (option.sync === SqlSyncMode.Sync) {
1730
+ const fn = () => {
1731
+ let result = 0;
1732
+ for (const { sql, params } of sqls) {
1733
+ const dd = option.conn.execute(SqlSyncMode.Sync, sql, params);
1734
+ result += dd.affectedRows;
1735
+ }
1736
+ return result;
1737
+ };
1738
+ if (option?.conn?.[_inTransaction] === true) {
1739
+ return fn();
1740
+ }
1741
+ else {
1742
+ return option?.dao?.transaction(SqlSyncMode.Sync, fn, option?.conn);
1743
+ }
1744
+ }
1745
+ else {
1746
+ const fn = async () => {
1747
+ let result = 0;
1748
+ for (const { sql, params } of sqls) {
1749
+ const dd = await option.conn.execute(SqlSyncMode.Async, sql, params);
1750
+ result += dd.affectedRows;
1751
+ }
1752
+ return result;
1753
+ };
1754
+ return new Promise(async (resolve) => {
1755
+ if (option?.conn?.[_inTransaction] === true) {
1756
+ resolve((await fn()));
1757
+ }
1758
+ else {
1759
+ await option?.dao?.transaction(SqlSyncMode.Async, async () => resolve((await fn())), option?.conn);
1760
+ }
1761
+ });
1762
+ }
1763
+ }
1764
+ _select(resultMode, result, error) {
1765
+ switch (resultMode) {
1766
+ case SqlTemplateMode.AssertOne: {
1767
+ Throw.if(!result || result.length !== 1, error);
1768
+ return result[0];
1769
+ }
1770
+ case SqlTemplateMode.NotSureOne: {
1771
+ Throw.if(!result, error);
1772
+ return result[0] ?? null;
1773
+ }
1774
+ case SqlTemplateMode.Many: {
1775
+ return result;
1776
+ }
1777
+ case SqlTemplateMode.Count: {
1778
+ return result[0].ct;
1779
+ }
1780
+ }
1781
+ }
1782
+ template(option) {
1783
+ Throw.if(!!this[_ids] && this[_ids].length > 1 && !option.where, 'muit id must set where!');
1784
+ Throw.if((!this[_ids] || this[_ids].length === 0) && !option.where, 'if not set id on class, must set where!');
1785
+ Throw.if(!option.id && !option.where, 'not found id or where!');
1786
+ Throw.if(!!option.id && !!this[_ids] && this[_ids].length > 1, 'muit id must set where!');
1787
+ Throw.if(!!option.id && !!option.where, 'id and where only one can set!');
1788
+ option.mode ?? (option.mode = SqlSelectMode.Common);
1789
+ option.resultMode ?? (option.resultMode = SqlTemplateMode.AssertOne);
1790
+ option.error ?? (option.error = 'error data!');
1791
+ const tableTemp = `${option?.tableName}_${Math.random()}`.replace(/\./, '');
1792
+ const tableTempESC = Sqlstring.escapeId(tableTemp);
1793
+ const tableNameESC = Sqlstring.escapeId(option?.tableName);
1794
+ if (option.id) {
1795
+ const idName = this[_ids][0];
1796
+ const ids = option.id instanceof Array ? option.id : [option.id];
1797
+ option.where = ids.map(i => ({ [idName]: i }));
1798
+ }
1799
+ const columns = option.resultMode === SqlTemplateMode.Count ? 'COUNT(1) ct' : iterare((option.columns ?? this[_columns])).map((K) => `a.${this[_fields][K]?.esName}`).join(',');
1800
+ const wheres = option.where instanceof Array ? option.where : [option.where];
1801
+ const sqls = [];
1802
+ let resultIndex = -1;
1803
+ if (option.mode === SqlSelectMode.Common) {
1804
+ const params = new Array();
1805
+ const whereSql = iterare(wheres).map(where => {
1806
+ return `SELECT ${columns} FROM ${tableNameESC} a WHERE
1807
+ ${Object.entries(where).map(([K, V]) => {
1808
+ params.push(V);
1809
+ return `${K} = ?`;
1810
+ }).join(' AND ')}`;
1811
+ }).join(' UNION ALL ');
1812
+ sqls.push({ sql: whereSql, params });
1813
+ resultIndex = 0;
1814
+ }
1815
+ else {
1816
+ sqls.push({ sql: `DROP TABLE IF EXISTS ${tableTempESC};` });
1817
+ const delWhere = Object.keys(wheres[0]);
1818
+ const _sqls = this._createTable({ tableName: tableTemp, temp: true, columns: delWhere, data: wheres, index: 'all', id: 'none' });
1819
+ sqls.push(..._sqls);
1820
+ resultIndex = sqls.length;
1821
+ sqls.push({ sql: `SELECT ${columns} FROM ${tableNameESC} a INNER JOIN ${tableTempESC} b ON ${delWhere.map(K => `a.${this[_fields][K]?.esName} = b.${this[_fields][K]?.esName}`).join(' AND ')};` });
1822
+ sqls.push({ sql: `DROP TABLE IF EXISTS ${tableTempESC};` });
1823
+ }
1824
+ if (option.sync === SqlSyncMode.Sync) {
1825
+ let result;
1826
+ for (let i = 0; i < sqls.length; i++) {
1827
+ if (i === resultIndex) {
1828
+ result = option.conn.query(SqlSyncMode.Sync, sqls[i]?.sql, sqls[i]?.params);
1829
+ }
1830
+ else {
1831
+ option.conn.execute(SqlSyncMode.Sync, sqls[i]?.sql, sqls[i]?.params);
1832
+ }
1833
+ }
1834
+ return this._select(option.resultMode, result, option.error);
1835
+ }
1836
+ else {
1837
+ return new Promise(async (resolve) => {
1838
+ let result;
1839
+ for (let i = 0; i < sqls.length; i++) {
1840
+ if (i === resultIndex) {
1841
+ result = await option.conn.query(SqlSyncMode.Async, sqls[i]?.sql, sqls[i]?.params);
1842
+ }
1843
+ else {
1844
+ await option.conn.execute(SqlSyncMode.Async, sqls[i]?.sql, sqls[i]?.params);
1845
+ }
1846
+ }
1847
+ resolve(this._select(option.resultMode, result, option.error));
1848
+ });
1849
+ }
1850
+ }
1851
+ _query(resultMode, result, def, errorMsg, multiple) {
1852
+ if (multiple === true) {
1853
+ switch (resultMode) {
1854
+ case SqlQueryMode.One_Row_One_Column_NotSure: {
1855
+ try {
1856
+ return result.map((r) => Object.values(r)[0]);
1857
+ }
1858
+ catch (error) {
1859
+ }
1860
+ }
1861
+ case SqlQueryMode.One_Row_One_Column_Assert: {
1862
+ try {
1863
+ return iterare(result).map((r) => Object.values(r)[0]).filter((r) => r !== null).toArray();
1864
+ }
1865
+ catch (error) {
1866
+ }
1867
+ }
1868
+ case SqlQueryMode.One_Row_Many_Column_NotSure: {
1869
+ try {
1870
+ return result.map((r) => r[0]);
1871
+ }
1872
+ catch (error) {
1873
+ }
1874
+ }
1875
+ case SqlQueryMode.One_Row_Many_Column_Assert: {
1876
+ try {
1877
+ return iterare(result).map((r) => r[0]).filter((r) => r !== null).toArray();
1878
+ }
1879
+ catch (error) {
1880
+ }
1881
+ }
1882
+ case SqlQueryMode.Many_Row_One_Column: {
1883
+ try {
1884
+ return result.map((rx) => rx.map((r) => Object.values(r)[0]));
1885
+ }
1886
+ catch (error) {
1887
+ }
1888
+ }
1889
+ case SqlQueryMode.Many_Row_Many_Column: {
1890
+ return result;
1891
+ }
1892
+ }
1893
+ }
1894
+ else {
1895
+ switch (resultMode) {
1896
+ case SqlQueryMode.One_Row_One_Column_NotSure: {
1897
+ try {
1898
+ return Object.values(result[0])[0];
1899
+ }
1900
+ catch (error) {
1901
+ return def;
1902
+ }
1903
+ }
1904
+ case SqlQueryMode.One_Row_One_Column_Assert: {
1905
+ try {
1906
+ return Object.values(result[0])[0];
1907
+ }
1908
+ catch (error) {
1909
+ if (def !== undefined)
1910
+ return def;
1911
+ Throw.now(errorMsg ?? 'not found data!');
1912
+ }
1913
+ }
1914
+ case SqlQueryMode.One_Row_Many_Column_NotSure: {
1915
+ return result[0] ?? null;
1916
+ }
1917
+ case SqlQueryMode.One_Row_Many_Column_Assert: {
1918
+ const data = result[0];
1919
+ Throw.if(data === null, errorMsg ?? 'not found data!');
1920
+ return data ?? null;
1921
+ }
1922
+ case SqlQueryMode.Many_Row_One_Column: {
1923
+ try {
1924
+ return result.map((r) => Object.values(r)[0]);
1925
+ }
1926
+ catch (error) {
1927
+ return def;
1928
+ }
1929
+ }
1930
+ case SqlQueryMode.Many_Row_Many_Column: {
1931
+ return result;
1932
+ }
1933
+ }
1934
+ }
1935
+ }
1936
+ select(option) {
1937
+ Throw.if(!option.sqlId && !option.sql, 'not found sql!');
1938
+ option.resultMode ?? (option.resultMode = SqlQueryMode.Many_Row_Many_Column);
1939
+ option.sql ?? (option.sql = globalThis[_sqlCache].load(option.sqlId, option.context, option.isPage));
1940
+ option.defValue ?? (option.defValue = null);
1941
+ logger.debug(option.sql);
1942
+ const _params = Object.assign({}, option.context, option.params);
1943
+ const params = [];
1944
+ const sql = option.sql?.replace(/\:(\w+)/g, (txt, key) => {
1945
+ if (_params.hasOwnProperty(key)) {
1946
+ const V = _params[key];
1947
+ params.push(V);
1948
+ return Sqlstring.escape(_params[key]);
1949
+ }
1950
+ return txt;
1951
+ });
1952
+ if (option.sync === SqlSyncMode.Sync) {
1953
+ const result = option.conn.query(SqlSyncMode.Sync, sql, params);
1954
+ return this._query(option.resultMode, result, option.defValue, option.errorMsg, option.multiple);
1955
+ }
1956
+ else {
1957
+ return new Promise(async (resolve) => {
1958
+ const result = await option.conn.query(SqlSyncMode.Async, sql, params);
1959
+ resolve(this._query(option.resultMode, result, option.defValue, option.errorMsg, option.multiple));
1960
+ });
1961
+ }
1962
+ }
1963
+ excute(option) {
1964
+ Throw.if(!option.sqlId && !option.sql, 'not found sql!');
1965
+ option.sql ?? (option.sql = globalThis[_sqlCache].load(option.sqlId, option.context));
1966
+ logger.debug(option.sql);
1967
+ const _params = Object.assign({}, option.context, option.params);
1968
+ const params = [];
1969
+ const sql = option.sql?.replace(/\:(\w+)/g, (txt, key) => {
1970
+ if (_params.hasOwnProperty(key)) {
1971
+ const V = _params[key];
1972
+ params.push(V);
1973
+ return Sqlstring.escape(_params[key]);
1974
+ }
1975
+ return txt;
1976
+ });
1977
+ if (option.sync === SqlSyncMode.Sync) {
1978
+ const result = option.conn.execute(SqlSyncMode.Sync, sql, params);
1979
+ return result.affectedRows;
1980
+ }
1981
+ else {
1982
+ return new Promise(async (resolve) => {
1983
+ const result = await option.conn.execute(SqlSyncMode.Async, sql, params);
1984
+ resolve(result.affectedRows);
1985
+ });
1986
+ }
1987
+ }
1988
+ transaction(option) {
1989
+ if (option.sync === SqlSyncMode.Sync) {
1990
+ return option.dao.transaction(SqlSyncMode.Sync, option.fn);
1991
+ }
1992
+ else {
1993
+ return new Promise(async (resolve) => {
1994
+ const rt = await option.dao.transaction(SqlSyncMode.Async, option.fn);
1995
+ resolve(rt);
1996
+ });
1997
+ }
1998
+ }
1999
+ stream(option) {
2000
+ return new StreamQuery(option?.tableName ?? this[_tableName], this);
2001
+ }
2002
+ /**
2003
+ #创建表
2004
+ ** `tableName` 表名称
2005
+ ** `temp` 是否是临时表,默认true
2006
+ ** `columns` 字符串数组,默认是当前实体类全部字段,通过`columns` 可以创建部分字段临时表
2007
+ ** `id` 表的主键设置 4种:
2008
+ 1. `auto`: `columns`中已经在当前实体类配置的ID作为主键 `默认`
2009
+ 2. `all`: `columns`中所有字段全部当主键
2010
+ 3. `none`: 没有主键
2011
+ 4. 自定义字段名称:字符串数组
2012
+ ** `index` 表的索引,设置方式同ID
2013
+ */
2014
+ _createTable({ tableName, temp = true, columns, data, id = 'auto', index = 'auto' } = {}) {
2015
+ const sqls = [];
2016
+ columns = columns || this[_columns];
2017
+ let ids;
2018
+ if (id === 'auto') {
2019
+ ids = this[_ids]?.filter(i => columns?.includes(i));
2020
+ }
2021
+ else if (id === 'all') {
2022
+ ids = columns;
2023
+ }
2024
+ else if (id === 'none') {
2025
+ ids = undefined;
2026
+ }
2027
+ else {
2028
+ ids = id;
2029
+ }
2030
+ let indexs;
2031
+ if (index === 'auto') {
2032
+ indexs = this[_index]?.filter(i => columns?.includes(i));
2033
+ }
2034
+ else if (index === 'all') {
2035
+ indexs = columns;
2036
+ }
2037
+ else if (index === 'none') {
2038
+ indexs = undefined;
2039
+ }
2040
+ else {
2041
+ indexs = index;
2042
+ }
2043
+ tableName = Sqlstring.escapeId(tableName ?? this[_tableName]);
2044
+ switch (this[_dbType]) {
2045
+ case DBType.Mysql: {
2046
+ let sql = `CREATE ${temp === true ? 'TEMPORARY' : ''} TABLE IF NOT EXISTS ${tableName}(
2047
+ ${columns.map(K => this[_fields][K][DBType.Mysql]).join(',')}
2048
+ ${ids && ids.length ? `,PRIMARY KEY (${ids.map(i => this[_fields][i]?.esName).join(',')}) USING BTREE ` : ''}
2049
+ ${indexs && indexs.length ? `,${indexs.map(i => `KEY ${this[_fields][i]?.esName} (${this[_fields][i]?.esName})`).join(',')} ` : ''}
2050
+ ) ENGINE=MEMORY;`;
2051
+ sqls.push({ sql });
2052
+ if (data && data.length > 0) {
2053
+ const params = [];
2054
+ let first = true;
2055
+ sql = `INSERT INTO ${tableName} (${columns.map(c => Sqlstring.escapeId(c)).join(',')})
2056
+ ${(data).map(d => {
2057
+ const r = `SELECT ${Object.entries(d).map(([K, V]) => {
2058
+ params.push(V);
2059
+ return `? ${first ? this[_fields][K]?.esName : ''}`;
2060
+ }).join(',')}`;
2061
+ first = false;
2062
+ return r;
2063
+ }).join(' UNION ALL ')}`;
2064
+ sqls.push({ sql, params });
2065
+ }
2066
+ break;
2067
+ }
2068
+ case DBType.Sqlite:
2069
+ case DBType.SqliteRemote: {
2070
+ let sql = `CREATE ${temp === true ? 'TEMPORARY' : ''} TABLE IF NOT EXISTS ${tableName}(
2071
+ ${columns.map(K => this[_fields][K][DBType.Sqlite]).join(',')}
2072
+ ${ids && ids.length ? `,PRIMARY KEY (${ids.map(i => this[_fields][i]?.esName).join(',')}) ` : ''}
2073
+ );`;
2074
+ sqls.push({ sql });
2075
+ if (indexs) {
2076
+ for (const index of indexs) {
2077
+ sql = `CREATE INDEX ${Sqlstring.escapeId(`${index}_${Math.random()}`.replace(/\./, ''))} ON ${tableName} (${this[_fields][index]?.esName});`;
2078
+ sqls.push({ sql });
2079
+ }
2080
+ }
2081
+ if (data && data.length > 0) {
2082
+ const params = [];
2083
+ let first = true;
2084
+ sql = `INSERT INTO ${tableName} (${columns.map(c => Sqlstring.escapeId(c)).join(',')})
2085
+ ${(data).map(d => {
2086
+ const r = `SELECT ${Object.entries(d).map(([K, V]) => {
2087
+ params.push(V);
2088
+ return `? ${first ? this[_fields][K]?.esName : ''}`;
2089
+ }).join(',')}`;
2090
+ first = false;
2091
+ return r;
2092
+ }).join(' UNION ALL ')}`;
2093
+ sqls.push({ sql, params });
2094
+ }
2095
+ }
2096
+ }
2097
+ return sqls;
2098
+ }
2099
+ }
2100
+ __decorate([
2101
+ P(),
2102
+ __metadata("design:type", Function),
2103
+ __metadata("design:paramtypes", [Object]),
2104
+ __metadata("design:returntype", Object)
2105
+ ], SqlService.prototype, "insert", null);
2106
+ __decorate([
2107
+ P(),
2108
+ __metadata("design:type", Function),
2109
+ __metadata("design:paramtypes", [Object]),
2110
+ __metadata("design:returntype", Object)
2111
+ ], SqlService.prototype, "update", null);
2112
+ __decorate([
2113
+ P(),
2114
+ __metadata("design:type", Function),
2115
+ __metadata("design:paramtypes", [Object]),
2116
+ __metadata("design:returntype", Object)
2117
+ ], SqlService.prototype, "delete", null);
2118
+ __decorate([
2119
+ P(),
2120
+ __metadata("design:type", Function),
2121
+ __metadata("design:paramtypes", [Object]),
2122
+ __metadata("design:returntype", Object)
2123
+ ], SqlService.prototype, "template", null);
2124
+ __decorate([
2125
+ P(),
2126
+ __metadata("design:type", Function),
2127
+ __metadata("design:paramtypes", [Object]),
2128
+ __metadata("design:returntype", Object)
2129
+ ], SqlService.prototype, "select", null);
2130
+ __decorate([
2131
+ P(),
2132
+ __metadata("design:type", Function),
2133
+ __metadata("design:paramtypes", [Object]),
2134
+ __metadata("design:returntype", Object)
2135
+ ], SqlService.prototype, "excute", null);
2136
+ __decorate([
2137
+ P(true),
2138
+ __metadata("design:type", Function),
2139
+ __metadata("design:paramtypes", [Object]),
2140
+ __metadata("design:returntype", Object)
2141
+ ], SqlService.prototype, "transaction", null);
2142
+ /** 是否进行下一个动作 */
2143
+ const IF_PROCEED = function () {
2144
+ return function (_target, _propertyKey, descriptor) {
2145
+ const fn = descriptor.value;
2146
+ descriptor.value = function () {
2147
+ if (this.if_proceed === true) {
2148
+ // eslint-disable-next-line prefer-rest-params
2149
+ const args = Array.from(arguments);
2150
+ fn.call(this, ...args);
2151
+ }
2152
+ else {
2153
+ this.if_proceed = true;
2154
+ }
2155
+ return this;
2156
+ };
2157
+ };
2158
+ };
2159
+ /*** 是否执行最终查询/操作*/
2160
+ const IF_EXEC = function (def) {
2161
+ return function (_target, _propertyKey, descriptor) {
2162
+ const fn = descriptor.value;
2163
+ descriptor.value = async function () {
2164
+ if (this.if_proceed === true && this.if_exec === true) {
2165
+ // eslint-disable-next-line prefer-rest-params
2166
+ const args = Array.from(arguments);
2167
+ return await fn.call(this, ...args);
2168
+ }
2169
+ else {
2170
+ return def;
2171
+ }
2172
+ };
2173
+ };
2174
+ };
2175
+ class StreamCondition {
2176
+ constructor() {
2177
+ this._prefix = 0;
2178
+ this._index = 0;
2179
+ this._wheres = [];
2180
+ this._andQuerys = [];
2181
+ this._orQuerys = [];
2182
+ this._paramKeys = {};
2183
+ this._param = {};
2184
+ this.if_proceed = true;
2185
+ this.if_exec = true;
2186
+ this._prefix = parseInt(`${Math.random() * 1000}`);
2187
+ }
2188
+ /** 将当前stream重置 */
2189
+ reset() {
2190
+ this._index = 0;
2191
+ this._wheres.length = 0;
2192
+ this._param = {};
2193
+ this._paramKeys = {};
2194
+ return this;
2195
+ }
2196
+ /** 为下次链条执行提供条件判断:非异步方法跳过,异步方法不执行并返回默认值 */
2197
+ if(condition) {
2198
+ this.if_proceed = condition;
2199
+ return this;
2200
+ }
2201
+ eq(key, value, { name } = {}) { return this._(key, value, '=', { name }); }
2202
+ eqT(t, { name } = {}) {
2203
+ if (name && this._paramKeys[name]) {
2204
+ for (const [key, pname] of Object.entries(this._paramKeys[name])) {
2205
+ this._param[pname] = t[key];
2206
+ }
2207
+ }
2208
+ else {
2209
+ const paramKeys = {};
2210
+ for (const [key, value] of Object.entries(t)) {
2211
+ const pkey = `p${this._prefix}${this._index++}`;
2212
+ this._wheres.push(`AND ${String(key)} = :${pkey} `);
2213
+ this._param[pkey] = value;
2214
+ if (name) {
2215
+ paramKeys[key] = pkey;
2216
+ }
2217
+ }
2218
+ if (name) {
2219
+ this._paramKeys[name] = paramKeys;
2220
+ }
2221
+ }
2222
+ return this;
2223
+ }
2224
+ notEq(key, value, { name } = {}) { return this._(key, value, '<>', { name }); }
2225
+ eqWith(key1, key2) { return this._key(key1, key2, '='); }
2226
+ notEqWith(key1, key2) { return this._key(key1, key2, '<>'); }
2227
+ regexp(key, regexp, { name } = {}) { return this._(key, regexp, 'REGEXP', { name }); }
2228
+ notRegexp(key, regexp, { name } = {}) { return this._(key, regexp, 'REGEXP', { name, not: 'NOT' }); }
2229
+ /** (key1 << 8) + key2 = value */
2230
+ shiftEq(key1, key2, value, { name } = {}) { return this._shift(key1, key2, value, '=', { name }); }
2231
+ /** (key1 << 8) + key2 <> value */
2232
+ shiftNotEq(key1, key2, value, { name } = {}) { return this._shift(key1, key2, value, '<>', { name }); }
2233
+ grate(key, value, { name } = {}) { return this._(key, value, '>', { name }); }
2234
+ grateEq(key, value, { name } = {}) { return this._(key, value, '>=', { name }); }
2235
+ grateWith(key1, key2) { return this._key(key1, key2, '>'); }
2236
+ grateEqWith(key1, key2) { return this._key(key1, key2, '>='); }
2237
+ less(key, value, { name } = {}) { return this._(key, value, '<', { name }); }
2238
+ lessEq(key, value, { name } = {}) { return this._(key, value, '<=', { name }); }
2239
+ lessWith(key1, key2) { return this._key(key1, key2, '<'); }
2240
+ lessEqWith(key1, key2) { return this._key(key1, key2, '<='); }
2241
+ like(key, value, { name, force } = {}) { return this._like(key, value, { name, left: '%', right: '%', force }); }
2242
+ notLike(key, value, { name, force } = {}) { return this._like(key, value, { name, left: '%', right: '%', not: 'NOT', force }); }
2243
+ leftLike(key, value, { name, force } = {}) { return this._like(key, value, { name, left: '%', force }); }
2244
+ notLeftLike(key, value, { name, force } = {}) { return this._like(key, value, { name, left: '%', not: 'NOT', force }); }
2245
+ rightLike(key, value, { name, force } = {}) { return this._like(key, value, { name, right: '%', force }); }
2246
+ notRightLike(key, value, { name, force } = {}) { return this._like(key, value, { name, right: '%', not: 'NOT', force }); }
2247
+ PreciseLike(key, value, { name, force } = {}) { return this._like(key, value, { name, force }); }
2248
+ notPreciseLike(key, value, { name, force } = {}) { return this._like(key, value, { name, not: 'NOT', force }); }
2249
+ glob(key, value, { name, force } = {}) { return this._like(key, value, { name, left: '%', right: '%', force, op: 'glob' }); }
2250
+ notGlob(key, value, { name, force } = {}) { return this._like(key, value, { name, left: '%', right: '%', not: 'NOT', force, op: 'glob' }); }
2251
+ leftGlob(key, value, { name, force } = {}) { return this._like(key, value, { name, left: '%', force, op: 'glob' }); }
2252
+ notLeftGlob(key, value, { name, force } = {}) { return this._like(key, value, { name, left: '%', not: 'NOT', force, op: 'glob' }); }
2253
+ rightGlob(key, value, { name, force } = {}) { return this._like(key, value, { name, right: '%', force, op: 'glob' }); }
2254
+ notRightGlob(key, value, { name, force } = {}) { return this._like(key, value, { name, right: '%', not: 'NOT', force, op: 'glob' }); }
2255
+ PreciseGlob(key, value, { name, force } = {}) { return this._like(key, value, { name, force, op: 'glob' }); }
2256
+ notPreciseGlob(key, value, { name, force } = {}) { return this._like(key, value, { name, not: 'NOT', force, op: 'glob' }); }
2257
+ in(key, value, { name, force } = {}) { return this._in(key, value, { name, force }); }
2258
+ notIn(key, value, { name, force } = {}) { return this._in(key, value, { name, not: 'NOT', force }); }
2259
+ isNULL(key) { return this._null(key); }
2260
+ isNotNULL(key) { return this._null(key, 'NOT'); }
2261
+ between(key, value1, value2, { name } = {}) { return this._between(key, value1, value2, { name }); }
2262
+ notBetween(key, value1, value2, { name } = {}) { return this._between(key, value1, value2, { name, not: 'NOT' }); }
2263
+ pow(key, value, { name } = {}) { return this._pow(key, value, { name }); }
2264
+ notPow(key, value, { name } = {}) { return this._pow(key, value, { name, not: 'NOT' }); }
2265
+ powWith(key, values, { name } = {}) { return this._pow(key, add(...values.map(value => Math.pow(2, +value))), { name }); }
2266
+ notPowWith(key, values, { name } = {}) { return this._pow(key, add(...values.map(value => Math.pow(2, +value))), { name, not: 'NOT' }); }
2267
+ /** MATCH(key1, key2, key3) AGAINST (value) */
2268
+ match(value, keys, { name } = {}) { return this._match(value, keys, { name }); }
2269
+ /** NOT MATCH(key1, key2, key3) AGAINST (value) */
2270
+ notMatch(value, keys, { name } = {}) { return this._match(value, keys, { name, not: 'NOT' }); }
2271
+ /** MATCH(key1, key2, key3) AGAINST (value) IN BOOLEAN MODE*/
2272
+ matchBoolean(value, keys, { name } = {}) { return this._match(value, keys, { name, append: 'IN BOOLEAN MODE' }); }
2273
+ /** NOT MATCH(key1, key2, key3) AGAINST (value) IN BOOLEAN MODE */
2274
+ notMatchBoolean(value, keys, { name } = {}) { return this._match(value, keys, { name, not: 'NOT', append: 'IN BOOLEAN MODE' }); }
2275
+ /** MATCH(key1, key2, key3) AGAINST (value) WITH QUERY EXPANSION*/
2276
+ matchQuery(value, keys, { name } = {}) { return this._match(value, keys, { name, append: 'WITH QUERY EXPANSION' }); }
2277
+ /** NOT MATCH(key1, key2, key3) AGAINST (value) WITH QUERY EXPANSION*/
2278
+ notMatchQuery(value, keys, { name } = {}) { return this._match(value, keys, { name, not: 'NOT', append: 'WITH QUERY EXPANSION' }); }
2279
+ includes(key, value, { name } = {}) { return this._includes(key, value, { name }); }
2280
+ notIncludes(key, value, { name } = {}) { return this._includes(key, value, { name, not: 'NOT' }); }
2281
+ and(fn) { const stream = new StreamCondition(); const ret = fn(stream); if (ret !== false) {
2282
+ this._andQuerys.push(stream);
2283
+ } return this; }
2284
+ or(fn) { const stream = new StreamCondition(); const ret = fn(stream); if (ret !== false) {
2285
+ this._orQuerys.push(stream);
2286
+ } return this; }
2287
+ where() {
2288
+ const wheres = new Array();
2289
+ const sql = this._wheres.join(' ');
2290
+ if (sql) {
2291
+ wheres.push(`(${sql})`);
2292
+ }
2293
+ if (this._orQuerys.length > 0) {
2294
+ for (const query of this._orQuerys) {
2295
+ const { where, params } = query.where();
2296
+ if (where) {
2297
+ wheres.push(` OR (${where}) `);
2298
+ }
2299
+ Object.assign(this._param, params);
2300
+ }
2301
+ }
2302
+ if (this._andQuerys.length > 0) {
2303
+ for (const query of this._andQuerys) {
2304
+ const { where, params } = query.where();
2305
+ if (where) {
2306
+ wheres.push(` AND (${where}) `);
2307
+ }
2308
+ Object.assign(this._param, params);
2309
+ }
2310
+ }
2311
+ return { where: wheres.join(' '), params: this._param };
2312
+ }
2313
+ _(key, value, op, { not = '', name = '' } = {}) {
2314
+ if (name !== undefined && this._paramKeys.hasOwnProperty(name)) {
2315
+ this._param[this._paramKeys[name]] = value;
2316
+ }
2317
+ else {
2318
+ const pkey = `p${this._prefix}${this._index++}`;
2319
+ this._wheres.push(`AND ${String(key)} ${not} ${op} :${pkey} `);
2320
+ this._param[pkey] = value;
2321
+ if (name) {
2322
+ this._paramKeys[name] = pkey;
2323
+ }
2324
+ }
2325
+ return this;
2326
+ }
2327
+ _null(key, not = '') {
2328
+ this._wheres.push(`AND ${String(key)} is ${not} null`);
2329
+ return this;
2330
+ }
2331
+ _key(key1, key2, op, not = '') {
2332
+ this._wheres.push(`AND ${String(key1)} ${not} ${op} ${String(key2)} `);
2333
+ return this;
2334
+ }
2335
+ _between(key, value1, value2, { not = '', name = '' } = {}) {
2336
+ if (name && this._paramKeys[name]) {
2337
+ this._param[this._paramKeys[name][0]] = value1;
2338
+ this._param[this._paramKeys[name][1]] = value2;
2339
+ }
2340
+ else {
2341
+ const [pkey1, pkey2] = [`p${this._prefix}${this._index++}`, `p${this._prefix}${this._index++}`];
2342
+ this._wheres.push(`AND ${String(key)} ${not} BETWEEN :${pkey1} AND :${pkey2}`);
2343
+ this._param[pkey1] = value1;
2344
+ this._param[pkey2] = value2;
2345
+ if (name) {
2346
+ this._paramKeys[name] = [pkey1, pkey2];
2347
+ }
2348
+ }
2349
+ return this;
2350
+ }
2351
+ _in(key, value, { not = '', name = '', force = false } = {}) {
2352
+ if (value && value.length > 0) {
2353
+ if (name !== undefined && this._paramKeys.hasOwnProperty(name)) {
2354
+ this._param[this._paramKeys[name]] = value;
2355
+ }
2356
+ else {
2357
+ const pkey = `p${this._prefix}${this._index++}`;
2358
+ this._wheres.push(`AND ${String(key)} ${not} IN (:${pkey}) `);
2359
+ this._param[pkey] = value;
2360
+ if (name) {
2361
+ this._paramKeys[name] = pkey;
2362
+ }
2363
+ }
2364
+ }
2365
+ else if (force !== true) {
2366
+ this.if_exec = false;
2367
+ }
2368
+ return this;
2369
+ }
2370
+ _shift(key1, key2, value, op, { not = '', name = '' } = {}) {
2371
+ if (name !== undefined && this._paramKeys.hasOwnProperty(name)) {
2372
+ this._param[this._paramKeys[name]] = value;
2373
+ }
2374
+ else {
2375
+ const pkey = `p${this._prefix}${this._index++}`;
2376
+ this._wheres.push(`AND (${String(key1)} << 8) + ${String(key2)} ${not} ${op} :${pkey} `);
2377
+ this._param[pkey] = value;
2378
+ if (name) {
2379
+ this._paramKeys[name] = pkey;
2380
+ }
2381
+ }
2382
+ return this;
2383
+ }
2384
+ _match(value, keys, { name, not, append } = {}) {
2385
+ if (name !== undefined && this._paramKeys.hasOwnProperty(name)) {
2386
+ this._param[this._paramKeys[name]] = value;
2387
+ }
2388
+ else {
2389
+ const pkey = `p${this._prefix}${this._index++}`;
2390
+ this._wheres.push(`AND MATCH(${keys.join(',')}) AGAINST (:${pkey} ${append ?? ''})`);
2391
+ this._param[pkey] = value;
2392
+ if (name) {
2393
+ this._paramKeys[name] = pkey;
2394
+ }
2395
+ }
2396
+ return this;
2397
+ }
2398
+ _pow(key, value, { name } = {}) {
2399
+ if (name !== undefined && this._paramKeys.hasOwnProperty(name)) {
2400
+ this._param[this._paramKeys[name]] = value;
2401
+ }
2402
+ else {
2403
+ const pkey = `p${this._prefix}${this._index++}`;
2404
+ this._wheres.push(`AND NOT POW(2, ${String(key)}) & :${pkey}`);
2405
+ this._param[pkey] = value;
2406
+ if (name) {
2407
+ this._paramKeys[name] = pkey;
2408
+ }
2409
+ }
2410
+ return this;
2411
+ }
2412
+ _like(key, value, { not = '', left = '', right = '', name = '', op = 'LIKE', force = false } = {}) {
2413
+ if (value !== null && value !== undefined && value !== '') {
2414
+ if (name !== undefined && this._paramKeys.hasOwnProperty(name)) {
2415
+ this._param[this._paramKeys[name]] = value;
2416
+ }
2417
+ else {
2418
+ const pkey = `p${this._prefix}${this._index++}`;
2419
+ this._wheres.push(`AND ${String(key)} ${not} ${op} CONCAT('${left}', :${pkey}, '${right}') `);
2420
+ this._param[pkey] = value;
2421
+ if (name) {
2422
+ this._paramKeys[name] = pkey;
2423
+ }
2424
+ }
2425
+ }
2426
+ else if (force !== true) {
2427
+ this.if_exec = false;
2428
+ }
2429
+ return this;
2430
+ }
2431
+ _includes(key, value, { not = '', name = '' } = {}) {
2432
+ if (name !== undefined && this._paramKeys.hasOwnProperty(name)) {
2433
+ this._param[this._paramKeys[name]] = value;
2434
+ }
2435
+ else {
2436
+ const pkey = `p${this._prefix}${this._index++}`;
2437
+ this._wheres.push(`AND LOCATE(${String(key)}, :${pkey}) ${not ? '=' : ''} 0`);
2438
+ this._param[pkey] = value;
2439
+ if (name) {
2440
+ this._paramKeys[name] = pkey;
2441
+ }
2442
+ }
2443
+ return this;
2444
+ }
2445
+ }
2446
+ __decorate([
2447
+ IF_PROCEED(),
2448
+ __metadata("design:type", Function),
2449
+ __metadata("design:paramtypes", [Boolean]),
2450
+ __metadata("design:returntype", void 0)
2451
+ ], StreamCondition.prototype, "if", null);
2452
+ __decorate([
2453
+ IF_PROCEED(),
2454
+ __metadata("design:type", Function),
2455
+ __metadata("design:paramtypes", [Object, Object, Object]),
2456
+ __metadata("design:returntype", void 0)
2457
+ ], StreamCondition.prototype, "eq", null);
2458
+ __decorate([
2459
+ IF_PROCEED(),
2460
+ __metadata("design:type", Function),
2461
+ __metadata("design:paramtypes", [Object, Object]),
2462
+ __metadata("design:returntype", void 0)
2463
+ ], StreamCondition.prototype, "eqT", null);
2464
+ __decorate([
2465
+ IF_PROCEED(),
2466
+ __metadata("design:type", Function),
2467
+ __metadata("design:paramtypes", [Object, Object, Object]),
2468
+ __metadata("design:returntype", void 0)
2469
+ ], StreamCondition.prototype, "notEq", null);
2470
+ __decorate([
2471
+ IF_PROCEED(),
2472
+ __metadata("design:type", Function),
2473
+ __metadata("design:paramtypes", [Object, Object]),
2474
+ __metadata("design:returntype", void 0)
2475
+ ], StreamCondition.prototype, "eqWith", null);
2476
+ __decorate([
2477
+ IF_PROCEED(),
2478
+ __metadata("design:type", Function),
2479
+ __metadata("design:paramtypes", [Object, Object]),
2480
+ __metadata("design:returntype", void 0)
2481
+ ], StreamCondition.prototype, "notEqWith", null);
2482
+ __decorate([
2483
+ IF_PROCEED(),
2484
+ __metadata("design:type", Function),
2485
+ __metadata("design:paramtypes", [Object, String, Object]),
2486
+ __metadata("design:returntype", void 0)
2487
+ ], StreamCondition.prototype, "regexp", null);
2488
+ __decorate([
2489
+ IF_PROCEED(),
2490
+ __metadata("design:type", Function),
2491
+ __metadata("design:paramtypes", [Object, String, Object]),
2492
+ __metadata("design:returntype", void 0)
2493
+ ], StreamCondition.prototype, "notRegexp", null);
2494
+ __decorate([
2495
+ IF_PROCEED(),
2496
+ __metadata("design:type", Function),
2497
+ __metadata("design:paramtypes", [Object, Object, Number, Object]),
2498
+ __metadata("design:returntype", void 0)
2499
+ ], StreamCondition.prototype, "shiftEq", null);
2500
+ __decorate([
2501
+ IF_PROCEED(),
2502
+ __metadata("design:type", Function),
2503
+ __metadata("design:paramtypes", [Object, Object, Number, Object]),
2504
+ __metadata("design:returntype", void 0)
2505
+ ], StreamCondition.prototype, "shiftNotEq", null);
2506
+ __decorate([
2507
+ IF_PROCEED(),
2508
+ __metadata("design:type", Function),
2509
+ __metadata("design:paramtypes", [Object, Object, Object]),
2510
+ __metadata("design:returntype", void 0)
2511
+ ], StreamCondition.prototype, "grate", null);
2512
+ __decorate([
2513
+ IF_PROCEED(),
2514
+ __metadata("design:type", Function),
2515
+ __metadata("design:paramtypes", [Object, Object, Object]),
2516
+ __metadata("design:returntype", void 0)
2517
+ ], StreamCondition.prototype, "grateEq", null);
2518
+ __decorate([
2519
+ IF_PROCEED(),
2520
+ __metadata("design:type", Function),
2521
+ __metadata("design:paramtypes", [Object, Object]),
2522
+ __metadata("design:returntype", void 0)
2523
+ ], StreamCondition.prototype, "grateWith", null);
2524
+ __decorate([
2525
+ IF_PROCEED(),
2526
+ __metadata("design:type", Function),
2527
+ __metadata("design:paramtypes", [Object, Object]),
2528
+ __metadata("design:returntype", void 0)
2529
+ ], StreamCondition.prototype, "grateEqWith", null);
2530
+ __decorate([
2531
+ IF_PROCEED(),
2532
+ __metadata("design:type", Function),
2533
+ __metadata("design:paramtypes", [Object, Object, Object]),
2534
+ __metadata("design:returntype", void 0)
2535
+ ], StreamCondition.prototype, "less", null);
2536
+ __decorate([
2537
+ IF_PROCEED(),
2538
+ __metadata("design:type", Function),
2539
+ __metadata("design:paramtypes", [Object, Object, Object]),
2540
+ __metadata("design:returntype", void 0)
2541
+ ], StreamCondition.prototype, "lessEq", null);
2542
+ __decorate([
2543
+ IF_PROCEED(),
2544
+ __metadata("design:type", Function),
2545
+ __metadata("design:paramtypes", [Object, Object]),
2546
+ __metadata("design:returntype", void 0)
2547
+ ], StreamCondition.prototype, "lessWith", null);
2548
+ __decorate([
2549
+ IF_PROCEED(),
2550
+ __metadata("design:type", Function),
2551
+ __metadata("design:paramtypes", [Object, Object]),
2552
+ __metadata("design:returntype", void 0)
2553
+ ], StreamCondition.prototype, "lessEqWith", null);
2554
+ __decorate([
2555
+ IF_PROCEED(),
2556
+ __metadata("design:type", Function),
2557
+ __metadata("design:paramtypes", [Object, Object, Object]),
2558
+ __metadata("design:returntype", void 0)
2559
+ ], StreamCondition.prototype, "like", null);
2560
+ __decorate([
2561
+ IF_PROCEED(),
2562
+ __metadata("design:type", Function),
2563
+ __metadata("design:paramtypes", [Object, Object, Object]),
2564
+ __metadata("design:returntype", void 0)
2565
+ ], StreamCondition.prototype, "notLike", null);
2566
+ __decorate([
2567
+ IF_PROCEED(),
2568
+ __metadata("design:type", Function),
2569
+ __metadata("design:paramtypes", [Object, Object, Object]),
2570
+ __metadata("design:returntype", void 0)
2571
+ ], StreamCondition.prototype, "leftLike", null);
2572
+ __decorate([
2573
+ IF_PROCEED(),
2574
+ __metadata("design:type", Function),
2575
+ __metadata("design:paramtypes", [Object, Object, Object]),
2576
+ __metadata("design:returntype", void 0)
2577
+ ], StreamCondition.prototype, "notLeftLike", null);
2578
+ __decorate([
2579
+ IF_PROCEED(),
2580
+ __metadata("design:type", Function),
2581
+ __metadata("design:paramtypes", [Object, Object, Object]),
2582
+ __metadata("design:returntype", void 0)
2583
+ ], StreamCondition.prototype, "rightLike", null);
2584
+ __decorate([
2585
+ IF_PROCEED(),
2586
+ __metadata("design:type", Function),
2587
+ __metadata("design:paramtypes", [Object, Object, Object]),
2588
+ __metadata("design:returntype", void 0)
2589
+ ], StreamCondition.prototype, "notRightLike", null);
2590
+ __decorate([
2591
+ IF_PROCEED(),
2592
+ __metadata("design:type", Function),
2593
+ __metadata("design:paramtypes", [Object, Object, Object]),
2594
+ __metadata("design:returntype", void 0)
2595
+ ], StreamCondition.prototype, "PreciseLike", null);
2596
+ __decorate([
2597
+ IF_PROCEED(),
2598
+ __metadata("design:type", Function),
2599
+ __metadata("design:paramtypes", [Object, Object, Object]),
2600
+ __metadata("design:returntype", void 0)
2601
+ ], StreamCondition.prototype, "notPreciseLike", null);
2602
+ __decorate([
2603
+ IF_PROCEED(),
2604
+ __metadata("design:type", Function),
2605
+ __metadata("design:paramtypes", [Object, Object, Object]),
2606
+ __metadata("design:returntype", void 0)
2607
+ ], StreamCondition.prototype, "glob", null);
2608
+ __decorate([
2609
+ IF_PROCEED(),
2610
+ __metadata("design:type", Function),
2611
+ __metadata("design:paramtypes", [Object, Object, Object]),
2612
+ __metadata("design:returntype", void 0)
2613
+ ], StreamCondition.prototype, "notGlob", null);
2614
+ __decorate([
2615
+ IF_PROCEED(),
2616
+ __metadata("design:type", Function),
2617
+ __metadata("design:paramtypes", [Object, Object, Object]),
2618
+ __metadata("design:returntype", void 0)
2619
+ ], StreamCondition.prototype, "leftGlob", null);
2620
+ __decorate([
2621
+ IF_PROCEED(),
2622
+ __metadata("design:type", Function),
2623
+ __metadata("design:paramtypes", [Object, Object, Object]),
2624
+ __metadata("design:returntype", void 0)
2625
+ ], StreamCondition.prototype, "notLeftGlob", null);
2626
+ __decorate([
2627
+ IF_PROCEED(),
2628
+ __metadata("design:type", Function),
2629
+ __metadata("design:paramtypes", [Object, Object, Object]),
2630
+ __metadata("design:returntype", void 0)
2631
+ ], StreamCondition.prototype, "rightGlob", null);
2632
+ __decorate([
2633
+ IF_PROCEED(),
2634
+ __metadata("design:type", Function),
2635
+ __metadata("design:paramtypes", [Object, Object, Object]),
2636
+ __metadata("design:returntype", void 0)
2637
+ ], StreamCondition.prototype, "notRightGlob", null);
2638
+ __decorate([
2639
+ IF_PROCEED(),
2640
+ __metadata("design:type", Function),
2641
+ __metadata("design:paramtypes", [Object, Object, Object]),
2642
+ __metadata("design:returntype", void 0)
2643
+ ], StreamCondition.prototype, "PreciseGlob", null);
2644
+ __decorate([
2645
+ IF_PROCEED(),
2646
+ __metadata("design:type", Function),
2647
+ __metadata("design:paramtypes", [Object, Object, Object]),
2648
+ __metadata("design:returntype", void 0)
2649
+ ], StreamCondition.prototype, "notPreciseGlob", null);
2650
+ __decorate([
2651
+ IF_PROCEED(),
2652
+ __metadata("design:type", Function),
2653
+ __metadata("design:paramtypes", [Object, Array, Object]),
2654
+ __metadata("design:returntype", void 0)
2655
+ ], StreamCondition.prototype, "in", null);
2656
+ __decorate([
2657
+ IF_PROCEED(),
2658
+ __metadata("design:type", Function),
2659
+ __metadata("design:paramtypes", [Object, Array, Object]),
2660
+ __metadata("design:returntype", void 0)
2661
+ ], StreamCondition.prototype, "notIn", null);
2662
+ __decorate([
2663
+ IF_PROCEED(),
2664
+ __metadata("design:type", Function),
2665
+ __metadata("design:paramtypes", [Object]),
2666
+ __metadata("design:returntype", void 0)
2667
+ ], StreamCondition.prototype, "isNULL", null);
2668
+ __decorate([
2669
+ IF_PROCEED(),
2670
+ __metadata("design:type", Function),
2671
+ __metadata("design:paramtypes", [Object]),
2672
+ __metadata("design:returntype", void 0)
2673
+ ], StreamCondition.prototype, "isNotNULL", null);
2674
+ __decorate([
2675
+ IF_PROCEED(),
2676
+ __metadata("design:type", Function),
2677
+ __metadata("design:paramtypes", [Object, Object, Object, Object]),
2678
+ __metadata("design:returntype", void 0)
2679
+ ], StreamCondition.prototype, "between", null);
2680
+ __decorate([
2681
+ IF_PROCEED(),
2682
+ __metadata("design:type", Function),
2683
+ __metadata("design:paramtypes", [Object, Object, Object, Object]),
2684
+ __metadata("design:returntype", void 0)
2685
+ ], StreamCondition.prototype, "notBetween", null);
2686
+ __decorate([
2687
+ IF_PROCEED(),
2688
+ __metadata("design:type", Function),
2689
+ __metadata("design:paramtypes", [Object, Number, Object]),
2690
+ __metadata("design:returntype", void 0)
2691
+ ], StreamCondition.prototype, "pow", null);
2692
+ __decorate([
2693
+ IF_PROCEED(),
2694
+ __metadata("design:type", Function),
2695
+ __metadata("design:paramtypes", [Object, Number, Object]),
2696
+ __metadata("design:returntype", void 0)
2697
+ ], StreamCondition.prototype, "notPow", null);
2698
+ __decorate([
2699
+ IF_PROCEED(),
2700
+ __metadata("design:type", Function),
2701
+ __metadata("design:paramtypes", [Object, Array, Object]),
2702
+ __metadata("design:returntype", void 0)
2703
+ ], StreamCondition.prototype, "powWith", null);
2704
+ __decorate([
2705
+ IF_PROCEED(),
2706
+ __metadata("design:type", Function),
2707
+ __metadata("design:paramtypes", [Object, Array, Object]),
2708
+ __metadata("design:returntype", void 0)
2709
+ ], StreamCondition.prototype, "notPowWith", null);
2710
+ __decorate([
2711
+ IF_PROCEED(),
2712
+ __metadata("design:type", Function),
2713
+ __metadata("design:paramtypes", [String, Array, Object]),
2714
+ __metadata("design:returntype", void 0)
2715
+ ], StreamCondition.prototype, "match", null);
2716
+ __decorate([
2717
+ IF_PROCEED(),
2718
+ __metadata("design:type", Function),
2719
+ __metadata("design:paramtypes", [String, Array, Object]),
2720
+ __metadata("design:returntype", void 0)
2721
+ ], StreamCondition.prototype, "notMatch", null);
2722
+ __decorate([
2723
+ IF_PROCEED(),
2724
+ __metadata("design:type", Function),
2725
+ __metadata("design:paramtypes", [String, Array, Object]),
2726
+ __metadata("design:returntype", void 0)
2727
+ ], StreamCondition.prototype, "matchBoolean", null);
2728
+ __decorate([
2729
+ IF_PROCEED(),
2730
+ __metadata("design:type", Function),
2731
+ __metadata("design:paramtypes", [String, Array, Object]),
2732
+ __metadata("design:returntype", void 0)
2733
+ ], StreamCondition.prototype, "notMatchBoolean", null);
2734
+ __decorate([
2735
+ IF_PROCEED(),
2736
+ __metadata("design:type", Function),
2737
+ __metadata("design:paramtypes", [String, Array, Object]),
2738
+ __metadata("design:returntype", void 0)
2739
+ ], StreamCondition.prototype, "matchQuery", null);
2740
+ __decorate([
2741
+ IF_PROCEED(),
2742
+ __metadata("design:type", Function),
2743
+ __metadata("design:paramtypes", [String, Array, Object]),
2744
+ __metadata("design:returntype", void 0)
2745
+ ], StreamCondition.prototype, "notMatchQuery", null);
2746
+ __decorate([
2747
+ IF_PROCEED(),
2748
+ __metadata("design:type", Function),
2749
+ __metadata("design:paramtypes", [Object, Object, Object]),
2750
+ __metadata("design:returntype", void 0)
2751
+ ], StreamCondition.prototype, "includes", null);
2752
+ __decorate([
2753
+ IF_PROCEED(),
2754
+ __metadata("design:type", Function),
2755
+ __metadata("design:paramtypes", [Object, Object, Object]),
2756
+ __metadata("design:returntype", void 0)
2757
+ ], StreamCondition.prototype, "notIncludes", null);
2758
+ __decorate([
2759
+ IF_PROCEED(),
2760
+ __metadata("design:type", Function),
2761
+ __metadata("design:paramtypes", [Function]),
2762
+ __metadata("design:returntype", void 0)
2763
+ ], StreamCondition.prototype, "and", null);
2764
+ __decorate([
2765
+ IF_PROCEED(),
2766
+ __metadata("design:type", Function),
2767
+ __metadata("design:paramtypes", [Function]),
2768
+ __metadata("design:returntype", void 0)
2769
+ ], StreamCondition.prototype, "or", null);
2770
+ class StreamBuild extends StreamCondition {
2771
+ constructor(table) {
2772
+ super();
2773
+ this._distinct = false;
2774
+ this._columns = [];
2775
+ this._updateColumns = [];
2776
+ this._groups = [];
2777
+ this._orders = [];
2778
+ this._startRow = 0;
2779
+ this._pageSize = 0;
2780
+ this._table = table;
2781
+ }
2782
+ /** 将当前stream重置 */
2783
+ reset() {
2784
+ super.reset();
2785
+ this._pageSize = 0;
2786
+ this._startRow = 0;
2787
+ this._orders.length = 0;
2788
+ this._groups.length = 0;
2789
+ this._columns.length = 0;
2790
+ this._updateColumns.length = 0;
2791
+ return this;
2792
+ }
2793
+ groupBy(key) { this._groups.push(key); return this; }
2794
+ asc(...keys) { this._orders.push(...keys.map(key => `${String(key)} ASC`)); return this; }
2795
+ desc(...keys) { this._orders.push(...keys.map(key => `${String(key)} DESC`)); return this; }
2796
+ limit(startRow, pageSize) { this._startRow = startRow; this._pageSize = pageSize; return this; }
2797
+ page(pageNumber, pageSize) { this._startRow = ((pageNumber || 1) - 1) * pageSize; this._pageSize = pageSize; return this; }
2798
+ table(_table) { this._table = _table; return this; }
2799
+ distinct(on = true) { this._distinct = on; return this; }
2800
+ count(key, countName, distinct) { this._columns.push(`COUNT(${distinct ? 'DISTINCT' : ''} ${String(key)}) ${countName || `${String(key)}`}`); return this; }
2801
+ sum(key, legName, distinct) { this._columns.push(`SUM(${distinct ? 'DISTINCT' : ''} ${String(key)}) ${legName || `${String(key)}`}`); return this; }
2802
+ avg(key, legName, distinct) { this._columns.push(`AVG(${distinct ? 'DISTINCT' : ''} ${String(key)}) ${legName || `${String(key)}`}`); return this; }
2803
+ max(key, legName, distinct) { this._columns.push(`MAX(${distinct ? 'DISTINCT' : ''} ${String(key)}) ${legName || `${String(key)}`}`); return this; }
2804
+ min(key, legName, distinct) { this._columns.push(`MIN(${distinct ? 'DISTINCT' : ''} ${String(key)}) ${legName || `${String(key)}`}`); return this; }
2805
+ groupConcat(key, param) {
2806
+ this._columns.push(`GROUP_CONCAT(
2807
+ ${param && param.distinct ? 'DISTINCT' : ''} ${String(key)}
2808
+ ${param && param.asc && param.asc.length > 0 ? `ORDER BY ${param.asc.map(i => `${String(i)} ASC`)} ` : ''}
2809
+ ${param && param.desc && param.desc.length > 0 ? `${param && param.asc && param.asc.length > 0 ? '' : 'ORDER BY'} ${param.desc.map(i => `${String(i)} DESC`)} ` : ''}
2810
+ SEPARATOR '${param && param.separator || ','}'
2811
+ ) ${param && param.groupName || `${String(key)}`}`);
2812
+ return this;
2813
+ }
2814
+ selectColumn(...key) { this._columns.push(...(key.map(k => k))); return this; }
2815
+ updateColumn(key, value) { this._updates ?? (this._updates = {}); this._updates[key] = value; return this; }
2816
+ updateT(t) { this._updates ?? (this._updates = {}); Object.assign(this._updates, t); return this; }
2817
+ replace(key, valueToFind, valueToReplace) {
2818
+ const [pkey1, pkey2] = [`p${this._prefix}${this._index++}`, `p${this._prefix}${this._index++}`];
2819
+ this._updateColumns.push(` ${String(key)} = REPLACE(${String(key)}, :${pkey1}, :${pkey2}) `);
2820
+ this._param[pkey1] = valueToFind;
2821
+ this._param[pkey2] = valueToReplace;
2822
+ return this;
2823
+ }
2824
+ }
2825
+ __decorate([
2826
+ IF_PROCEED(),
2827
+ __metadata("design:type", Function),
2828
+ __metadata("design:paramtypes", [Object]),
2829
+ __metadata("design:returntype", void 0)
2830
+ ], StreamBuild.prototype, "groupBy", null);
2831
+ __decorate([
2832
+ IF_PROCEED(),
2833
+ __metadata("design:type", Function),
2834
+ __metadata("design:paramtypes", [Object]),
2835
+ __metadata("design:returntype", void 0)
2836
+ ], StreamBuild.prototype, "asc", null);
2837
+ __decorate([
2838
+ IF_PROCEED(),
2839
+ __metadata("design:type", Function),
2840
+ __metadata("design:paramtypes", [Object]),
2841
+ __metadata("design:returntype", void 0)
2842
+ ], StreamBuild.prototype, "desc", null);
2843
+ __decorate([
2844
+ IF_PROCEED(),
2845
+ __metadata("design:type", Function),
2846
+ __metadata("design:paramtypes", [Number, Number]),
2847
+ __metadata("design:returntype", void 0)
2848
+ ], StreamBuild.prototype, "limit", null);
2849
+ __decorate([
2850
+ IF_PROCEED(),
2851
+ __metadata("design:type", Function),
2852
+ __metadata("design:paramtypes", [Number, Number]),
2853
+ __metadata("design:returntype", void 0)
2854
+ ], StreamBuild.prototype, "page", null);
2855
+ __decorate([
2856
+ IF_PROCEED(),
2857
+ __metadata("design:type", Function),
2858
+ __metadata("design:paramtypes", [String]),
2859
+ __metadata("design:returntype", void 0)
2860
+ ], StreamBuild.prototype, "table", null);
2861
+ __decorate([
2862
+ IF_PROCEED(),
2863
+ __metadata("design:type", Function),
2864
+ __metadata("design:paramtypes", [Object]),
2865
+ __metadata("design:returntype", void 0)
2866
+ ], StreamBuild.prototype, "distinct", null);
2867
+ __decorate([
2868
+ IF_PROCEED(),
2869
+ __metadata("design:type", Function),
2870
+ __metadata("design:paramtypes", [Object, String, Boolean]),
2871
+ __metadata("design:returntype", void 0)
2872
+ ], StreamBuild.prototype, "count", null);
2873
+ __decorate([
2874
+ IF_PROCEED(),
2875
+ __metadata("design:type", Function),
2876
+ __metadata("design:paramtypes", [Object, String, Boolean]),
2877
+ __metadata("design:returntype", void 0)
2878
+ ], StreamBuild.prototype, "sum", null);
2879
+ __decorate([
2880
+ IF_PROCEED(),
2881
+ __metadata("design:type", Function),
2882
+ __metadata("design:paramtypes", [Object, String, Boolean]),
2883
+ __metadata("design:returntype", void 0)
2884
+ ], StreamBuild.prototype, "avg", null);
2885
+ __decorate([
2886
+ IF_PROCEED(),
2887
+ __metadata("design:type", Function),
2888
+ __metadata("design:paramtypes", [Object, String, Boolean]),
2889
+ __metadata("design:returntype", void 0)
2890
+ ], StreamBuild.prototype, "max", null);
2891
+ __decorate([
2892
+ IF_PROCEED(),
2893
+ __metadata("design:type", Function),
2894
+ __metadata("design:paramtypes", [Object, String, Boolean]),
2895
+ __metadata("design:returntype", void 0)
2896
+ ], StreamBuild.prototype, "min", null);
2897
+ __decorate([
2898
+ IF_PROCEED(),
2899
+ __metadata("design:type", Function),
2900
+ __metadata("design:paramtypes", [Object, Object]),
2901
+ __metadata("design:returntype", Object)
2902
+ ], StreamBuild.prototype, "groupConcat", null);
2903
+ __decorate([
2904
+ IF_PROCEED(),
2905
+ __metadata("design:type", Function),
2906
+ __metadata("design:paramtypes", [Object]),
2907
+ __metadata("design:returntype", void 0)
2908
+ ], StreamBuild.prototype, "selectColumn", null);
2909
+ __decorate([
2910
+ IF_PROCEED(),
2911
+ __metadata("design:type", Function),
2912
+ __metadata("design:paramtypes", [Object, Object]),
2913
+ __metadata("design:returntype", void 0)
2914
+ ], StreamBuild.prototype, "updateColumn", null);
2915
+ __decorate([
2916
+ IF_PROCEED(),
2917
+ __metadata("design:type", Function),
2918
+ __metadata("design:paramtypes", [Object]),
2919
+ __metadata("design:returntype", void 0)
2920
+ ], StreamBuild.prototype, "updateT", null);
2921
+ __decorate([
2922
+ IF_PROCEED(),
2923
+ __metadata("design:type", Function),
2924
+ __metadata("design:paramtypes", [Object, Object, Object]),
2925
+ __metadata("design:returntype", void 0)
2926
+ ], StreamBuild.prototype, "replace", null);
2927
+ class StreamQuery extends StreamBuild {
2928
+ constructor(table, service) {
2929
+ super(table);
2930
+ this._service = service;
2931
+ }
2932
+ select(option) {
2933
+ option.sync ?? (option.sync = SqlSyncMode.Async);
2934
+ const { where, params } = this.where();
2935
+ const sql = `
2936
+ SELECT
2937
+ ${this._columns && this._columns.length > 0 ? this._columns.join(',') : '*'}
2938
+ FROM ${this._table}
2939
+ ${where ? ' WHERE ' : ''}
2940
+ ${where}`;
2941
+ if (option.sync === SqlSyncMode.Async) {
2942
+ switch (option.resultMode) {
2943
+ case SqlQueryMode.Many_Row_Many_Column: return this._service.select({ sync: SqlSyncMode.Async, resultMode: SqlQueryMode.Many_Row_Many_Column, errorMsg: option.errorMsg, sql, params });
2944
+ case SqlQueryMode.Many_Row_One_Column: return this._service.select({ sync: SqlSyncMode.Async, resultMode: SqlQueryMode.Many_Row_One_Column, errorMsg: option.errorMsg, sql, params });
2945
+ case SqlQueryMode.One_Row_Many_Column_Assert: return this._service.select({ sync: SqlSyncMode.Async, resultMode: SqlQueryMode.One_Row_Many_Column_Assert, errorMsg: option.errorMsg, sql, params });
2946
+ case SqlQueryMode.One_Row_One_Column_Assert: return this._service.select({ sync: SqlSyncMode.Async, resultMode: SqlQueryMode.One_Row_One_Column_Assert, errorMsg: option.errorMsg, sql, params });
2947
+ case SqlQueryMode.One_Row_Many_Column_NotSure: return this._service.select({ sync: SqlSyncMode.Async, resultMode: SqlQueryMode.One_Row_Many_Column_NotSure, errorMsg: option.errorMsg, sql, params });
2948
+ case SqlQueryMode.One_Row_One_Column_NotSure: return this._service.select({ sync: SqlSyncMode.Async, resultMode: SqlQueryMode.One_Row_One_Column_NotSure, errorMsg: option.errorMsg, sql, params });
2949
+ }
2950
+ }
2951
+ else {
2952
+ switch (option.resultMode) {
2953
+ case SqlQueryMode.Many_Row_Many_Column: return this._service.select({ sync: SqlSyncMode.Sync, resultMode: SqlQueryMode.Many_Row_Many_Column, errorMsg: option.errorMsg, sql, params });
2954
+ case SqlQueryMode.Many_Row_One_Column: return this._service.select({ sync: SqlSyncMode.Sync, resultMode: SqlQueryMode.Many_Row_One_Column, errorMsg: option.errorMsg, sql, params });
2955
+ case SqlQueryMode.One_Row_Many_Column_Assert: return this._service.select({ sync: SqlSyncMode.Sync, resultMode: SqlQueryMode.One_Row_Many_Column_Assert, errorMsg: option.errorMsg, sql, params });
2956
+ case SqlQueryMode.One_Row_One_Column_Assert: return this._service.select({ sync: SqlSyncMode.Sync, resultMode: SqlQueryMode.One_Row_One_Column_Assert, errorMsg: option.errorMsg, sql, params });
2957
+ case SqlQueryMode.One_Row_Many_Column_NotSure: return this._service.select({ sync: SqlSyncMode.Sync, resultMode: SqlQueryMode.One_Row_Many_Column_NotSure, errorMsg: option.errorMsg, sql, params });
2958
+ case SqlQueryMode.One_Row_One_Column_NotSure: return this._service.select({ sync: SqlSyncMode.Sync, resultMode: SqlQueryMode.One_Row_One_Column_NotSure, errorMsg: option.errorMsg, sql, params });
2959
+ }
2960
+ }
2961
+ }
2962
+ update(option) {
2963
+ option.sync ?? (option.sync = SqlSyncMode.Async);
2964
+ const { where, params } = this.where();
2965
+ const sets = new Array(...this._updateColumns);
2966
+ if (this._updates) {
2967
+ for (const [K, V] of Object.entries(this._updates)) {
2968
+ const pkey = `p${this._prefix}${this._index++}`;
2969
+ sets.push(` ${K} = :${pkey} `);
2970
+ params[pkey] = V;
2971
+ }
2972
+ }
2973
+ if (sets.length > 0) {
2974
+ const sql = `UPDATE ${this._table} SET ${sets.join(',')} ${where}`;
2975
+ if (option.sync === SqlSyncMode.Async) {
2976
+ return this._service.excute({ sync: SqlSyncMode.Async, sql, params });
2977
+ }
2978
+ else {
2979
+ return this._service.excute({ sync: SqlSyncMode.Sync, sql, params });
2980
+ }
2981
+ }
2982
+ else {
2983
+ return 0;
2984
+ }
2985
+ }
2986
+ delete(option) {
2987
+ option.sync ?? (option.sync = SqlSyncMode.Async);
2988
+ const { where, params } = this.where();
2989
+ const sql = `DELETE FROM ${this._table} ${where}`;
2990
+ if (option.sync === SqlSyncMode.Async) {
2991
+ return this._service.excute({ sync: SqlSyncMode.Async, sql, params });
2992
+ }
2993
+ else {
2994
+ return this._service.excute({ sync: SqlSyncMode.Sync, sql, params });
2995
+ }
2996
+ }
2997
+ }
2998
+ __decorate([
2999
+ IF_EXEC(null),
3000
+ __metadata("design:type", Function),
3001
+ __metadata("design:paramtypes", [Object]),
3002
+ __metadata("design:returntype", Object)
3003
+ ], StreamQuery.prototype, "select", null);
3004
+ __decorate([
3005
+ IF_EXEC(0),
3006
+ __metadata("design:type", Function),
3007
+ __metadata("design:paramtypes", [Object]),
3008
+ __metadata("design:returntype", Object)
3009
+ ], StreamQuery.prototype, "update", null);
3010
+ __decorate([
3011
+ IF_EXEC(0),
3012
+ __metadata("design:type", Function),
3013
+ __metadata("design:paramtypes", [Object]),
3014
+ __metadata("design:returntype", Object)
3015
+ ], StreamQuery.prototype, "delete", null);
3016
+ /**
3017
+ 获取REDIS客户端,
3018
+ # [查看库的API](https://github.com/redis/ioredis?tab=readme-ov-file)
3019
+ # [REDIS API](http://doc.redisfans.com/)
3020
+ REDIS 的API 可以直接用,将方法名转为小写
3021
+ */
3022
+ export function getRedisDB(db) {
3023
+ const rd = globalThis[_dao][DBType.Redis][db ?? _primaryDB];
3024
+ Throw.if(!rd, 'not found redis!');
3025
+ return rd;
3026
+ }
3027
+ /**
3028
+ redlock
3029
+ */
3030
+ export async function GetRedisLock(key, lockMaxActive) {
3031
+ const lock = globalThis[_dao][DBType.RedisLock];
3032
+ Throw.if(!lock, 'not found lock!');
3033
+ const db = getRedisDB();
3034
+ let initLock;
3035
+ try {
3036
+ initLock = await lock.acquire([`[lockex]${key}`], 5000);
3037
+ const count = await db.get(key);
3038
+ if (count === null || parseInt(count) < (lockMaxActive ?? 1)) {
3039
+ await db.incr(key);
3040
+ return true;
3041
+ }
3042
+ else {
3043
+ return false;
3044
+ }
3045
+ }
3046
+ catch (er) {
3047
+ return await GetRedisLock(key, lockMaxActive);
3048
+ }
3049
+ finally {
3050
+ if (initLock) {
3051
+ try {
3052
+ await initLock.release();
3053
+ // eslint-disable-next-line no-empty
3054
+ }
3055
+ catch (error) {
3056
+ }
3057
+ }
3058
+ }
3059
+ }
3060
+ ;
3061
+ export async function excuteWithLock(config, fn__) {
3062
+ const key = `[lock]${typeof config.key === 'function' ? config.key() : config.key}`;
3063
+ const db = getRedisDB();
3064
+ let wait_time = 0;
3065
+ const fn = async () => {
3066
+ const lock = await GetRedisLock(key, config.lockMaxActive);
3067
+ if (lock === false) {
3068
+ if (config.lockWait !== false && ((config.lockMaxWaitTime ?? 0) === 0 || (wait_time + (config.lockRetryInterval ?? 100)) <= (config.lockMaxWaitTime ?? 0))) {
3069
+ logger.debug(`get lock ${key} fail, retry after ${config.lockRetryInterval ?? 100}ms...`);
3070
+ await sleep(config.lockRetryInterval ?? 100);
3071
+ wait_time += (config.lockRetryInterval ?? 100);
3072
+ return await fn();
3073
+ }
3074
+ else {
3075
+ logger.debug(`get lock ${key} fail`);
3076
+ throw new Error(config.errorMessage || `get lock fail: ${key}`);
3077
+ }
3078
+ }
3079
+ else {
3080
+ logger.debug(`get lock ${key} ok!`);
3081
+ await db.get('other').pexpire(key, config.lockMaxTime ?? 60000);
3082
+ try {
3083
+ return await fn__();
3084
+ }
3085
+ finally {
3086
+ logger.debug(`unlock ${key} ok!`);
3087
+ await db.get('other').decr(key);
3088
+ }
3089
+ }
3090
+ };
3091
+ return await fn();
3092
+ }
3093
+ /** 与缓存共用时,需要在缓存之前:有缓存则返回缓存,否则加锁执行并缓存,后续队列全部返回缓存,跳过执行 */
3094
+ export function MethodLock(config) {
3095
+ return function (target, _propertyKey, descriptor) {
3096
+ const fn__ = descriptor.value;
3097
+ descriptor.value = async function (...args) {
3098
+ config.key = typeof config.key === 'function' ? config.key.call(target, ...args) : config.key;
3099
+ return await excuteWithLock(config, async () => await fn__.call(this, ...args));
3100
+ };
3101
+ };
3102
+ }
3103
+ async function setMethodCache(config, devid) {
3104
+ const db = getRedisDB();
3105
+ if (config.result !== null && config.result !== undefined) {
3106
+ // 映射关系存放
3107
+ if (config.clearKey && config.clearKey.length > 0) {
3108
+ for (const clear of config.clearKey) {
3109
+ await db.sadd(`[cache-parent]${clear}`, config.key);
3110
+ await db.sadd(`[cache-child]${config.key}`, clear);
3111
+ }
3112
+ }
3113
+ if (config.autoClearTime) { // 自动清空
3114
+ await db.set(`[cache]${config.key}`, JSON.stringify(config.result), 'EX', config.autoClearTime * 60);
3115
+ // 订阅:清空 clear list
3116
+ if (config.clearKey && config.clearKey.length > 0) {
3117
+ globalThis[_EventBus].on(`[cache]${config.key}`, async (key) => {
3118
+ await clearChild(key, true);
3119
+ });
3120
+ }
3121
+ }
3122
+ else {
3123
+ await db.set(`[cache]${config.key}`, JSON.stringify(config.result));
3124
+ }
3125
+ if (devid) {
3126
+ // 订阅:清空 clear list
3127
+ globalThis[_EventBus].on(`user-${devid}`, async function (key) {
3128
+ await clearChild(key);
3129
+ });
3130
+ }
3131
+ }
3132
+ }
3133
+ export async function clearMethodCache(key) {
3134
+ const db = getRedisDB();
3135
+ let type = await db.type(`[cache-parent]${key}`);
3136
+ if (type === 'set') {
3137
+ await clearParent(key);
3138
+ }
3139
+ type = await db.type(`[cache]${key}`);
3140
+ if (type !== 'none') {
3141
+ await clearChild(key);
3142
+ }
3143
+ }
3144
+ async function clearChild(key, skipDel = false) {
3145
+ const db = getRedisDB();
3146
+ if (skipDel === false) {
3147
+ await db.del(`[cache]${key}`);
3148
+ }
3149
+ const childtype = await db.type(`[cache-child]${key}`);
3150
+ if (childtype === 'set') {
3151
+ const parentKeys = await db.smembers(`[cache-child]${key}`);
3152
+ for (const clear of parentKeys) {
3153
+ const type = await db.type(`[cache-parent]${clear}`);
3154
+ if (type === 'set') {
3155
+ await db.srem(`[cache-parent]${clear}`, key);
3156
+ }
3157
+ }
3158
+ await db.del(`[cache-child]${key}`);
3159
+ }
3160
+ }
3161
+ async function clearParent(clearKey) {
3162
+ const db = getRedisDB();
3163
+ const keys = await db.smembers(`[cache-parent]${clearKey}`);
3164
+ if (keys) {
3165
+ for (const key of keys) {
3166
+ logger.debug(`cache ${key} cleared!`);
3167
+ await clearChild(key);
3168
+ }
3169
+ }
3170
+ }
3171
+ export async function excuteWithCache(config, fn) {
3172
+ const db = getRedisDB();
3173
+ const cache = await db.get(`[cache]${config.key}`);
3174
+ if (cache) {
3175
+ logger.debug(`cache ${config.key} hit!`);
3176
+ return JSON.parse(cache);
3177
+ }
3178
+ else {
3179
+ logger.debug(`cache ${config.key} miss!`);
3180
+ const result = await fn();
3181
+ await setMethodCache({
3182
+ key: config.key,
3183
+ clearKey: config.clearKey,
3184
+ autoClearTime: config.autoClearTime,
3185
+ result
3186
+ });
3187
+ return result;
3188
+ }
3189
+ }
3190
+ export function MethodCache(config) {
3191
+ return function (target, _propertyKey, descriptor) {
3192
+ const fn = descriptor.value;
3193
+ descriptor.value = async function (...args) {
3194
+ const key = typeof config.key === 'function' ? config.key.call(this, ...args) : config.key;
3195
+ const db = getRedisDB();
3196
+ const cache = await db.get('other').get(`[cache]${key}`);
3197
+ if (cache) {
3198
+ logger.debug(`cache ${key} hit!`);
3199
+ return JSON.parse(cache);
3200
+ }
3201
+ else {
3202
+ logger.debug(`cache ${key} miss!`);
3203
+ const result = await fn.call(this, ...args);
3204
+ const clearKey = config.clearKey ? typeof config.clearKey === 'function' ? config.clearKey.call(this, ...args) : config.clearKey : undefined;
3205
+ await setMethodCache({
3206
+ key,
3207
+ clearKey,
3208
+ autoClearTime: config.autoClearTime,
3209
+ result
3210
+ }, config.clearWithSession && this.ctx.me && this.ctx.me.devid);
3211
+ return result;
3212
+ }
3213
+ };
3214
+ };
3215
+ }
3216
+ export const LetsGo = async function (options) {
3217
+ globalThis[_GlobalSqlOption] = Object.assign({}, _defOption, options);
3218
+ if (options.sqlDir) {
3219
+ globalThis[_path] = import('path');
3220
+ globalThis[_fs] = import('fs');
3221
+ }
3222
+ logger.level = options.log ?? 'info';
3223
+ globalThis[_sqlCache] = new SqlCache();
3224
+ if (options.sqlCache || options.sqlDir) {
3225
+ await globalThis[_sqlCache].init(options);
3226
+ }
3227
+ globalThis[_dao] = {
3228
+ [DBType.Mongo]: {},
3229
+ [DBType.Mysql]: {},
3230
+ [DBType.Sqlite]: {},
3231
+ [DBType.SqliteRemote]: {},
3232
+ [DBType.Redis]: {}
3233
+ };
3234
+ if (options.Mysql) {
3235
+ const { createPool } = await import('mysql2/promise');
3236
+ if (options.Mysql['host']) {
3237
+ globalThis[_dao][DBType.Mysql][_primaryDB] = new Mysql(createPool({
3238
+ ...options.Mysql,
3239
+ multipleStatements: true,
3240
+ decimalNumbers: true,
3241
+ supportBigNumbers: true
3242
+ }));
3243
+ }
3244
+ else {
3245
+ let flag = false;
3246
+ for (const [key, option] of Object.entries(options.Mysql)) {
3247
+ const db = new Mysql(createPool({
3248
+ ...option,
3249
+ multipleStatements: true,
3250
+ decimalNumbers: true,
3251
+ supportBigNumbers: true
3252
+ }));
3253
+ if (flag === false) {
3254
+ globalThis[_dao][DBType.Mysql][_primaryDB] = db;
3255
+ flag = true;
3256
+ }
3257
+ globalThis[_dao][DBType.Mysql][key] = db;
3258
+ }
3259
+ }
3260
+ }
3261
+ if (options.Sqlite) {
3262
+ const BetterSqlite3 = await import('better-sqlite3');
3263
+ if (typeof options.Sqlite === 'string') {
3264
+ globalThis[_dao][DBType.Sqlite][_primaryDB] = new Sqlite(new BetterSqlite3.default(options.Sqlite, { fileMustExist: false }));
3265
+ }
3266
+ else {
3267
+ let flag = false;
3268
+ for (const [key, fileName] of Object.entries(options.Sqlite)) {
3269
+ const db = new Sqlite(new BetterSqlite3.default(fileName, { fileMustExist: false }));
3270
+ if (flag === false) {
3271
+ globalThis[_dao][DBType.Sqlite][_primaryDB] = db;
3272
+ flag = true;
3273
+ }
3274
+ globalThis[_dao][DBType.Sqlite][key] = db;
3275
+ }
3276
+ }
3277
+ }
3278
+ if (options.SqliteRemote) {
3279
+ if (typeof options.SqliteRemote.db === 'string') {
3280
+ await options.SqliteRemote.service.initDB(options.SqliteRemote.db);
3281
+ globalThis[_dao][DBType.SqliteRemote][_primaryDB] = new SqliteRemote(options.SqliteRemote.service, options.SqliteRemote.db);
3282
+ }
3283
+ else {
3284
+ let flag = false;
3285
+ for (const [key, fileName] of Object.entries(options.SqliteRemote.db)) {
3286
+ await options.SqliteRemote.service.initDB(fileName);
3287
+ const db = new SqliteRemote(options.SqliteRemote.service, fileName);
3288
+ if (flag === false) {
3289
+ globalThis[_dao][DBType.SqliteRemote][_primaryDB] = db;
3290
+ flag = true;
3291
+ }
3292
+ globalThis[_dao][DBType.SqliteRemote][key] = db;
3293
+ }
3294
+ }
3295
+ }
3296
+ if (options.Redis) {
3297
+ const { Redis } = await import('ioredis');
3298
+ if (options.Redis['host']) {
3299
+ globalThis[_dao][DBType.Redis][_primaryDB] = new Redis(options.Redis);
3300
+ }
3301
+ else {
3302
+ let flag = false;
3303
+ for (const [key, option] of Object.entries(options.Redis)) {
3304
+ const db = new Redis(option);
3305
+ if (flag === false) {
3306
+ globalThis[_dao][DBType.Redis][_primaryDB] = db;
3307
+ flag = true;
3308
+ }
3309
+ globalThis[_dao][DBType.Redis][key] = db;
3310
+ }
3311
+ }
3312
+ const clients = Object.values(globalThis[_dao][DBType.Redis]);
3313
+ const Redlock = await import('Redlock');
3314
+ globalThis[_dao][DBType.RedisLock] = new Redlock.default(clients, {
3315
+ // The expected clock drift; for more details see:
3316
+ // http://redis.io/topics/distlock
3317
+ driftFactor: 0.01, // multiplied by lock ttl to determine drift time
3318
+ // The max number of times Redlock will attempt to lock a resource
3319
+ // before erroring.
3320
+ retryCount: 10,
3321
+ // the time in ms between attempts
3322
+ retryDelay: 200, // time in ms
3323
+ // the max time in ms randomly added to retries
3324
+ // to improve performance under high contention
3325
+ // see https://www.awsarchitectureblog.com/2015/03/backoff.html
3326
+ retryJitter: 200, // time in ms
3327
+ // The minimum remaining time on a lock before an extension is automatically
3328
+ // attempted with the `using` API.
3329
+ automaticExtensionThreshold: 500, // time in ms
3330
+ });
3331
+ const { EventEmitter } = await import('events');
3332
+ const event = new EventEmitter({ captureRejections: true });
3333
+ event.on('error', error => {
3334
+ logger.error('event-bus', error);
3335
+ });
3336
+ globalThis[_EventBus] = event;
3337
+ }
3338
+ };