baja-lite 1.0.4 → 1.0.6

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 (85) hide show
  1. package/cjs/boot-remote.d.ts +2 -0
  2. package/cjs/boot-remote.js +35 -0
  3. package/cjs/boot.d.ts +2 -0
  4. package/cjs/boot.js +152 -0
  5. package/cjs/code.d.ts +1 -0
  6. package/cjs/code.js +359 -1
  7. package/cjs/convert-xml.d.ts +10 -0
  8. package/cjs/convert-xml.js +414 -0
  9. package/cjs/enum.d.ts +10 -0
  10. package/cjs/enum.js +32 -0
  11. package/cjs/error.js +1 -1
  12. package/cjs/fn.js +3 -3
  13. package/cjs/index.d.ts +3 -0
  14. package/cjs/index.js +3 -0
  15. package/cjs/list.d.ts +10 -0
  16. package/cjs/list.js +36 -0
  17. package/cjs/object.d.ts +7 -1
  18. package/cjs/object.js +36 -2
  19. package/cjs/set-ex.d.ts +41 -15
  20. package/cjs/set-ex.js +68 -52
  21. package/cjs/sql.d.ts +760 -305
  22. package/cjs/sql.js +1702 -1041
  23. package/cjs/sqlite.d.ts +38 -0
  24. package/cjs/sqlite.js +194 -0
  25. package/cjs/test-mysql.d.ts +2 -1
  26. package/cjs/test-mysql.js +85 -63
  27. package/cjs/test-sqlite.d.ts +1 -1
  28. package/cjs/test-sqlite.js +3 -1
  29. package/cjs/test-xml.d.ts +1 -0
  30. package/cjs/test-xml.js +75 -0
  31. package/es/boot-remote.d.ts +2 -0
  32. package/es/boot-remote.js +31 -0
  33. package/es/boot.d.ts +2 -0
  34. package/es/boot.js +125 -0
  35. package/es/code.d.ts +1 -0
  36. package/es/code.js +355 -2
  37. package/es/convert-xml.d.ts +10 -0
  38. package/es/convert-xml.js +410 -0
  39. package/es/enum.d.ts +10 -0
  40. package/es/enum.js +28 -0
  41. package/es/error.js +1 -1
  42. package/es/index.d.ts +3 -0
  43. package/es/index.js +3 -0
  44. package/es/list.d.ts +10 -0
  45. package/es/list.js +32 -0
  46. package/es/object.d.ts +7 -1
  47. package/es/object.js +28 -1
  48. package/es/set-ex.d.ts +41 -15
  49. package/es/set-ex.js +68 -52
  50. package/es/sql.d.ts +760 -305
  51. package/es/sql.js +1573 -917
  52. package/es/sqlite.d.ts +38 -0
  53. package/es/sqlite.js +164 -0
  54. package/es/test-mysql.d.ts +2 -1
  55. package/es/test-mysql.js +85 -64
  56. package/es/test-sqlite.d.ts +1 -1
  57. package/es/test-sqlite.js +3 -1
  58. package/es/test-xml.d.ts +1 -0
  59. package/es/test-xml.js +70 -0
  60. package/package.json +15 -10
  61. package/src/boot-remote.ts +31 -0
  62. package/src/boot.ts +129 -0
  63. package/src/code.ts +342 -1
  64. package/src/convert-xml.ts +462 -0
  65. package/src/enum.ts +31 -0
  66. package/src/error.ts +1 -1
  67. package/src/index.ts +4 -1
  68. package/src/list.ts +31 -0
  69. package/src/object.ts +48 -14
  70. package/src/set-ex.ts +91 -70
  71. package/src/sql.ts +1652 -965
  72. package/src/sqlite.ts +161 -0
  73. package/src/test-mysql.ts +93 -65
  74. package/src/test-sqlite.ts +3 -1
  75. package/src/test-xml.ts +70 -0
  76. package/cjs/constant.d.ts +0 -13
  77. package/cjs/constant.js +0 -19
  78. package/cjs/redis.d.ts +0 -0
  79. package/cjs/redis.js +0 -1
  80. package/es/constant.d.ts +0 -13
  81. package/es/constant.js +0 -16
  82. package/es/redis.d.ts +0 -0
  83. package/es/redis.js +0 -1
  84. package/src/constant.ts +0 -14
  85. package/src/redis.ts +0 -0
package/src/sql.ts CHANGED
@@ -1,4 +1,3 @@
1
- import 'reflect-metadata';
2
1
  import { Throw } from './error';
3
2
  import tslib from 'tslib';
4
3
  import Sqlstring from 'sqlstring';
@@ -6,12 +5,21 @@ import iterare from 'iterare';
6
5
  import { emptyString } from './string';
7
6
  import pino from 'pino';
8
7
  import { excuteSplit, ExcuteSplitMode, sleep } from './fn';
9
- import { add } from './math';
8
+ import { add, calc } from './math';
10
9
  import mustache, { PartialsOrLookupFn } from 'mustache';
10
+ import { C2P, C2P2, P2C } from './object';
11
+ import { format } from 'sql-formatter';
12
+ import HTML from 'html-parse-stringify';
13
+ import { XML, convert } from './convert-xml';
14
+ import { ArrayList } from './list';
15
+ import LGet from 'lodash.get';
11
16
 
12
17
  // #region 常量
13
18
  const _daoDBName = Symbol('dbName');
14
19
  const _tableName = Symbol('tableName');
20
+ const _className = Symbol('className');
21
+ const _ClassName = Symbol('ClassName');
22
+ const _vueName = Symbol('vueName');
15
23
  const _ids = Symbol('ids');
16
24
  const _columns = Symbol('columns');
17
25
  const _columnsNoId = Symbol('columnsNoId');
@@ -21,9 +29,9 @@ const _deleteState = Symbol('deleteState');
21
29
  const _transformer = Symbol('transformer');
22
30
  const _index = Symbol('index');
23
31
  const _def = Symbol('def');
24
- const _sqlCache = Symbol('sqlMap');
25
- const _dao = Symbol('dao');
26
- const _primaryDB = Symbol('primaryDB');
32
+ export const _sqlCache = Symbol('sqlMap');
33
+ export const _dao = Symbol('dao');
34
+ export const _primaryDB = Symbol('primaryDB');
27
35
  const _dbType = Symbol('dbType');
28
36
  const _sqlite_version = Symbol('sqlite_version');
29
37
  const _daoConnection = Symbol('daoConnection');
@@ -31,20 +39,26 @@ const _inTransaction = Symbol('inTransaction');
31
39
  const _daoDB = Symbol('daoDB');
32
40
  const _sqliteRemoteName = Symbol('sqliteRemoteName');
33
41
  const _SqlOption = Symbol('SqlOption');
34
- const _GlobalSqlOption = Symbol('GlobalSqlOption');
35
- const _EventBus = Symbol('EventBus');
36
- const _path = Symbol('path');
37
- const _fs = Symbol('fs');
38
- const logger = pino({
39
- name: 'sql',
40
- transport: {
41
- target: 'pino-pretty'
42
- }
43
- });
42
+ const _resultMap = Symbol('resultMap');
43
+ const _resultMap_SQLID = Symbol('resultMap_SQLID');
44
+ export const _Hump = Symbol('Hump');
45
+ export const _GlobalSqlOption = Symbol('GlobalSqlOption');
46
+ export const _EventBus = Symbol('EventBus');
47
+ export const _path = Symbol('path');
48
+ export const _fs = Symbol('fs');
49
+ export const logger =
50
+ process.env['NODE_ENV'] !== 'production' ? pino({
51
+ name: 'sql',
52
+ transport: {
53
+ target: 'pino-pretty'
54
+ }
55
+ }) : pino({ name: 'sql' });
56
+ globalThis[_resultMap_SQLID] = {};
44
57
  // #endregion
45
58
 
46
59
  // #region 可选配置
47
- export enum DBType { Mysql, Sqlite, Mongo, SqliteRemote, Redis, RedisLock }
60
+ export enum DBType { Mysql, Sqlite, Mongo, SqliteRemote, Redis, RedisLock };
61
+ export enum MapperIfUndefined { Null, Skip, Zero, EmptyString };
48
62
  export enum SyncMode {
49
63
  /** 同步执行 */
50
64
  Sync,
@@ -116,16 +130,28 @@ export enum TemplateResult {
116
130
  NotSureOne,
117
131
  /** 返回多条记录 */
118
132
  Many,
133
+ /** 返回多条记录并封装ArrayList */
134
+ ManyList,
119
135
  /** 仅查询记录数量 */
120
136
  Count
121
137
  }
122
138
  export enum SelectResult {
123
- One_Row_One_Column_Assert,
124
- One_Row_One_Column_NotSure,
125
- One_Row_Many_Column_Assert,
126
- One_Row_Many_Column_NotSure,
127
- Many_Row_One_Column,
128
- Many_Row_Many_Column
139
+ /** 一行一列 确定非空 */
140
+ R_C_Assert,
141
+ /** 一行一列 可能空 */
142
+ R_C_NotSure,
143
+ /** 一行多列 确定非空 */
144
+ R_CS_Assert,
145
+ /** 一行多列 可能空 */
146
+ R_CS_NotSure,
147
+ /** 多行一列 */
148
+ RS_C,
149
+ /** 多行一列并封装ArrayList */
150
+ RS_C_List,
151
+ /** 多行多列 */
152
+ RS_CS,
153
+ /** 多行多列并封装ArrayList */
154
+ RS_CS_List
129
155
  }
130
156
  export enum SqlType {
131
157
  tinyint,
@@ -171,6 +197,9 @@ export enum SqlType {
171
197
  geometrycollection
172
198
 
173
199
  }
200
+ export enum ColumnMode {
201
+ NONE, HUMP
202
+ }
174
203
  export const SqliteMemory = ':memory:';
175
204
  // #endregion
176
205
 
@@ -186,7 +215,7 @@ interface MethodOption {
186
215
  /** 调用时,仅在开启事务时需要主动传入,传入方式: */
187
216
  conn?: Connection | null;
188
217
  }
189
- const _defOption = {
218
+ export const _defOption = {
190
219
  maxDeal: 500,
191
220
  skipUndefined: true,
192
221
  skipNull: true,
@@ -232,7 +261,7 @@ interface ServiceOption {
232
261
  ```
233
262
  可以继承该接口来约束格式
234
263
  */
235
- interface GlobalSqlOption {
264
+ export interface GlobalSqlOptionForWeb {
236
265
  /** 增改忽略Undefined */
237
266
  skipUndefined?: boolean;
238
267
  /** 增改忽略NULL */
@@ -241,6 +270,59 @@ interface GlobalSqlOption {
241
270
  skipEmptyString?: boolean;
242
271
  /** 批量增改时,每次执行最多处理的记录数量 */
243
272
  maxDeal?: number;
273
+ SqliteRemote?: {
274
+ /**
275
+ ## 单一数据源
276
+ ```
277
+ db: 'd:/1.db'
278
+ ```
279
+ ## 多数据源:传入多个Mysql2的连接配置
280
+ ```
281
+ db: {
282
+ db1: 'd:/1.db',
283
+ db2: 'd:/2.db'
284
+ }
285
+ ```
286
+ 不支持 `SqliteMemory`
287
+ */
288
+ db: Record<string, string> | string,
289
+ /** 远程SQLITE接口实现,适用于Electron, 采用Ipc 的handel机制实现 */
290
+ service: SqliteRemoteInterface
291
+ },
292
+ /** 日志等级 */
293
+ log?: 'trace' | 'debug' | 'info' | 'warn',
294
+ /**
295
+ 作用与sqlDir类似,不同在于sqlMap`不需要`目录,而是直接指定一个sqlModel对象,对象的格式和sqlDir的文件内容一样。
296
+ ** 适用于简单使用
297
+ */
298
+ sqlMap?: _SqlModel;
299
+ /**
300
+ 作用与sqlFnDir类似,不同在于sqlFNMap`不需要`目录,而是直接指定一个 Record<string, string>,对象的格式和sqlFnDir的文件内容一样。
301
+ ** 适用于简单使用
302
+ */
303
+ sqlFNMap?: Record<string, string>;
304
+ /**
305
+ // 第一个元素=列名,第二个元素是属性路径,
306
+ [
307
+ ['dit_id', ['id']], // 列名ditid,对应属性id
308
+ ['event_id', ['eventMainInfo', 'id']] // 列名event_id对应属性eventMainInfo.id
309
+ ]
310
+ */
311
+ sqlMapperMap?: SqlMappers;
312
+ }
313
+ /**
314
+ # 全局行为配置文件
315
+ MYSQL编码: 'utf8mb4', utf8mb4_general_ci'
316
+ ### `sqlDir?: string;` 数据库查询语句存放目录.存放格式为 export.default 的js、ts, 存放内容满足格式:
317
+
318
+ ```
319
+ interface SqlModel {
320
+ [key: string]: string | ((params: { [k: string]: any }, context: any, isCount?: boolean) => string)
321
+ }
322
+ ```
323
+ 可以继承该接口来约束格式
324
+ */
325
+ export interface GlobalSqlOption extends GlobalSqlOptionForWeb {
244
326
  /**
245
327
  初始化MYSQL链接 支持多数据源
246
328
  ## 单一数据源: 直接传入Mysql2的连接配置
@@ -282,27 +364,6 @@ interface GlobalSqlOption {
282
364
  路径 = `SqliteMemory` 将创建内存库
283
365
  */
284
366
  Sqlite?: Record<string, string> | string,
285
- SqliteRemote?: {
286
- /**
287
- ## 单一数据源
288
- ```
289
- db: 'd:/1.db'
290
- ```
291
- ## 多数据源:传入多个Mysql2的连接配置
292
- ```
293
- db: {
294
- db1: 'd:/1.db',
295
- db2: 'd:/2.db'
296
- }
297
- ```
298
- 不支持 `SqliteMemory`
299
- */
300
- db: Record<string, string> | string,
301
- /** 远程SQLITE接口实现,适用于Electron, 采用Ipc 的handel机制实现 */
302
- service: SqliteRemoteInterface
303
- },
304
- /** 日志等级 */
305
- log?: 'trace' | 'debug' | 'info' | 'warn',
306
367
  /**
307
368
  ## 日志文件存放路径,该目录下文件名是模块名,例如有一个文件名为 `user.js`,内容为:
308
369
  ```
@@ -335,22 +396,27 @@ interface GlobalSqlOption {
335
396
  ## 也支持.mu文件,格式略
336
397
  */
337
398
  sqlDir?: string;
338
- /**
339
- 作用与sqlDir类似,不同在于sqlMap`不需要`目录,而是直接指定一个sqlModel对象,对象的格式和sqlDir的文件内容一样。
340
- ** 适用于简单使用
341
- */
342
- sqlMap?: SqlModel;
343
399
  /**
344
400
  ## [mustache](https://mustache.github.io/) 编译时的[模板](https://github.com/janl/mustache.js#:~:text=requires%20only%20this%3A-,%7B%7B%3E%20next_more%7D%7D,-Why%3F%20Because%20the)
345
- ** 文件名就是模板名
401
+ ## 文件名就是模板名
346
402
  */
347
403
  sqlFNDir?: string;
404
+
348
405
  /**
349
- 作用与sqlFnDir类似,不同在于sqlFNMap`不需要`目录,而是直接指定一个 Record<string, string>,对象的格式和sqlFnDir的文件内容一样。
350
- ** 适用于简单使用
406
+ ## 映射数据为对象,文件名就是模板名
407
+ ```
408
+ // 第一个元素=列名,第二个元素是属性路径,
409
+ // 该目录下可存放json文件,内容如下
410
+ //
411
+ // 可以在查询时使用,优先级高于hump
412
+ // 例如:
413
+ [
414
+ ['dit_id', ['id'], 可选的默认值], // 列名ditid,对应属性id,当未查询返回时,使用默认值
415
+ ['event_id', ['eventMainInfo', 'id']] // 列名event_id对应属性eventMainInfo.id,当未查询返回时,该属性不存在
416
+ ]
417
+ ```
351
418
  */
352
- sqlFNMap?: Record<string, string>;
353
-
419
+ sqlMapperDir?: string;
354
420
  /**
355
421
  [REDIS初始化文档](https://github.com/redis/ioredis?tab=readme-ov-file#:~:text=connect%20to%20by%3A-,new%20Redis()%3B,-//%20Connect%20to%20127.0.0.1)
356
422
  ```
@@ -375,23 +441,64 @@ interface GlobalSqlOption {
375
441
  ```
376
442
  */
377
443
  Redis?: Record<string, Record<string, any>> | Record<string, any>;
444
+
445
+ /**
446
+ * `列名与属性映射` 是否自动将下划线转为驼峰,默认NONE,即不转.
447
+ * 当设置为columnMode.HUMP时,切记将代码生成器中属性名称改对
448
+ * # 自定义sql查询时,无法自动转换哦,可使用标签转换:
449
+ *```
450
+ SELECT
451
+ * {{#hump}} seller_sku2, seller_sku {{/hump}}
452
+ * ```
453
+ * 转换为
454
+ *```
455
+ SELECT
456
+ * {{#hump}} seller_sku2 sellerSku2, seller_sku sellerSku {{/hump}}
457
+ * ```
458
+ */
459
+ columnMode?: ColumnMode;
460
+ /**
461
+ * 读取查询语句时,是否扫描JS文件?
462
+ * JS文件需要默认导出一个 SqlModel对象
463
+ */
464
+ jsMode?: boolean;
378
465
  }
466
+
379
467
  interface FieldOption extends Object {
380
468
  type?: SqlType;
381
- name?: string;
469
+ /** @deprecated 属性名称:TS注解不需要,JS手动注入需要 */
470
+ P?: string;
382
471
  length?: number;
383
472
  scale?: number;
384
473
  def?: any;
385
474
  index?: boolean;
386
475
  id?: boolean;
387
- logicDelete?: string;
476
+ logicDelete?: string | number;
477
+ /** 仅在生成 表时有效 */
388
478
  notNull?: boolean;
479
+ comment?: string;
480
+ /** sqlite 无效,与UUID只能有一个 */
481
+ uuidShort?: boolean;
482
+ /** 与uuidShort只能有一个 */
483
+ uuid?: boolean;
389
484
  }
390
485
  interface AField extends FieldOption {
391
- esName: string;
392
- [DBType.Mysql]: string;
393
- [DBType.Sqlite]: string;
394
- [DBType.SqliteRemote]: string;
486
+ /** 安全列名 */
487
+ C2: () => string;
488
+ /** @deprecated 数据列名称 */
489
+ C?: () => string;
490
+ /** 查询用:b_id bId */
491
+ C3: () => string;
492
+
493
+ [DBType.Mysql]: () => string;
494
+ [DBType.Sqlite]: () => string;
495
+ [DBType.SqliteRemote]: () => string;
496
+ }
497
+ export interface PageQuery<L> {
498
+ sum?: Record<string, number>;
499
+ total?: number;
500
+ size?: number;
501
+ records?: L[];
395
502
  }
396
503
  // #endregion
397
504
 
@@ -399,14 +506,14 @@ interface AField extends FieldOption {
399
506
  /** sqlite electron服务端需要支持的接口 */
400
507
  export interface SqliteRemoteInterface {
401
508
  execute(dbName: string, sql?: string, params?: any): | Promise<{ affectedRows: number; insertId: bigint; }>
402
- pluck<One_Row_Many_Column = any>(dbName: string, sql?: string, params?: any): Promise<One_Row_Many_Column | undefined>;
403
- get<One_Row_Many_Column = any>(dbName: string, sql?: string, params?: any): Promise<One_Row_Many_Column | undefined>;
509
+ pluck<One_Row_Many_Column = any>(dbName: string, sql?: string, params?: any): Promise<One_Row_Many_Column | null>;
510
+ get<One_Row_Many_Column = any>(dbName: string, sql?: string, params?: any): Promise<One_Row_Many_Column | null>;
404
511
  raw<Many_Row_One_Column = any>(dbName: string, sql?: string, params?: any): Promise<Many_Row_One_Column[]>;
405
512
  query<Many_Row_Many_Column = any>(dbName: string, sql?: string, params?: any): Promise<Many_Row_Many_Column[]>;
406
513
 
407
514
  initDB(dbName: string): Promise<void>;
408
- backup(dbName: string, name: string): Promise<void>;
409
- restore(dbName: string, name: string): Promise<void>;
515
+ export(dbName: string): Promise<void>;
516
+ restore(dbName: string, fromName: string): Promise<void>;
410
517
  };
411
518
  interface Connection {
412
519
  [_daoConnection]: any;
@@ -617,7 +724,7 @@ class MysqlConnection implements Connection {
617
724
  };
618
725
  }
619
726
  }
620
- class Mysql implements Dao {
727
+ export class Mysql implements Dao {
621
728
  [_daoDB]: any;
622
729
  constructor(pool: any) {
623
730
  this[_daoDB] = pool;
@@ -633,7 +740,7 @@ class Mysql implements Dao {
633
740
  return new Promise<Connection>(async (resolve, reject) => {
634
741
  try {
635
742
  const connection = await this[_daoDB].getConnection();
636
- logger.debug('create new!');
743
+ logger.debug('create new connection!');
637
744
  resolve(new MysqlConnection(connection));
638
745
  } catch (error) {
639
746
  reject(error);
@@ -851,7 +958,7 @@ class SqliteConnection implements Connection {
851
958
  realse(sync: SyncMode): Promise<void> | void {
852
959
  }
853
960
  }
854
- class Sqlite implements Dao {
961
+ export class Sqlite implements Dao {
855
962
  [_daoDB]: any;
856
963
  constructor(db: any) {
857
964
  this[_daoDB] = db;
@@ -929,7 +1036,7 @@ class Sqlite implements Dao {
929
1036
  restore(sync: SyncMode, name: string): Promise<void> | void {
930
1037
  }
931
1038
  }
932
- class SqliteRemoteConnection implements Connection {
1039
+ export class SqliteRemoteConnection implements Connection {
933
1040
  [_daoConnection]: SqliteRemoteInterface;
934
1041
  [_sqliteRemoteName]: string;
935
1042
  [_inTransaction] = false;
@@ -1078,7 +1185,7 @@ class SqliteRemoteConnection implements Connection {
1078
1185
  realse(sync: SyncMode): Promise<void> | void {
1079
1186
  }
1080
1187
  }
1081
- class SqliteRemote implements Dao {
1188
+ export class SqliteRemote implements Dao {
1082
1189
  [_sqliteRemoteName]: string;
1083
1190
  [_daoDB]: SqliteRemoteInterface;
1084
1191
 
@@ -1095,8 +1202,12 @@ class SqliteRemote implements Dao {
1095
1202
  logger.error('SQLITEREMOTE not suppouted sync mode');
1096
1203
  return null;
1097
1204
  };
1098
- return new Promise<Connection>(async resolve => {
1099
- resolve(new SqliteRemoteConnection(this[_daoDB], this[_sqliteRemoteName]));
1205
+ return new Promise<Connection>(async (resolve, reject) => {
1206
+ try {
1207
+ resolve(new SqliteRemoteConnection(this[_daoDB], this[_sqliteRemoteName]));
1208
+ } catch (error) {
1209
+ reject(error);
1210
+ }
1100
1211
  });
1101
1212
  }
1102
1213
 
@@ -1112,8 +1223,12 @@ class SqliteRemote implements Dao {
1112
1223
  close(sync: SyncMode.Async): Promise<void>;
1113
1224
  close(sync: SyncMode): Promise<void> | void {
1114
1225
  if (sync === SyncMode.Async) {
1115
- return new Promise(async () => {
1116
- await this[_daoConnection].close();
1226
+ return new Promise(async (resolve, reject) => {
1227
+ try {
1228
+ await this[_daoConnection].close();
1229
+ } catch (error) {
1230
+ reject(error);
1231
+ }
1117
1232
  });
1118
1233
  };
1119
1234
  }
@@ -1122,8 +1237,12 @@ class SqliteRemote implements Dao {
1122
1237
  backup(sync: SyncMode.Async, name: string): Promise<void>;
1123
1238
  backup(sync: SyncMode, name: string): Promise<void> | void {
1124
1239
  if (sync === SyncMode.Async) {
1125
- return new Promise(async () => {
1126
- await this[_daoConnection].backup(this[_sqliteRemoteName], name);
1240
+ return new Promise(async (resolve, reject) => {
1241
+ try {
1242
+ await this[_daoConnection].backup(this[_sqliteRemoteName], name);
1243
+ } catch (error) {
1244
+ reject(error);
1245
+ }
1127
1246
  });
1128
1247
  };
1129
1248
  }
@@ -1132,8 +1251,12 @@ class SqliteRemote implements Dao {
1132
1251
  remove(sync: SyncMode.Async): Promise<void>;
1133
1252
  remove(sync: SyncMode): Promise<void> | void {
1134
1253
  if (sync === SyncMode.Async) {
1135
- return new Promise(async () => {
1136
- await this[_daoConnection].remove();
1254
+ return new Promise(async (resolve, reject) => {
1255
+ try {
1256
+ await this[_daoConnection].remove();
1257
+ } catch (error) {
1258
+ reject(error);
1259
+ }
1137
1260
  });
1138
1261
  };
1139
1262
  }
@@ -1142,8 +1265,12 @@ class SqliteRemote implements Dao {
1142
1265
  restore(sync: SyncMode.Async, name: string): Promise<void>;
1143
1266
  restore(sync: SyncMode, name: string): Promise<void> | void {
1144
1267
  if (sync === SyncMode.Async) {
1145
- return new Promise(async () => {
1146
- await this[_daoConnection].restore(this[_sqliteRemoteName], name);
1268
+ return new Promise(async (resolve, reject) => {
1269
+ try {
1270
+ await this[_daoConnection].restore(this[_sqliteRemoteName], name);
1271
+ } catch (error) {
1272
+ reject(error);
1273
+ }
1147
1274
  });
1148
1275
  };
1149
1276
  }
@@ -1151,6 +1278,8 @@ class SqliteRemote implements Dao {
1151
1278
  // #endregion
1152
1279
 
1153
1280
  // #region 查询sql
1281
+ export type SqlMapper = ([string, string[], any?])[];
1282
+ export type SqlMappers = Record<string, SqlMapper>;
1154
1283
  export type SqlModel = Record<string, string | (
1155
1284
  (options: {
1156
1285
  ctx: any;
@@ -1162,6 +1291,17 @@ export type SqlModel = Record<string, string | (
1162
1291
  [k: string]: any;
1163
1292
  }) => string
1164
1293
  )>;
1294
+ type _SqlModel = Record<string, string | (
1295
+ (options: {
1296
+ ctx: any;
1297
+ isCount?: boolean;
1298
+ isSum?: boolean;
1299
+ limitStart?: number;
1300
+ limitEnd?: number;
1301
+ orderBy?: string;
1302
+ [k: string]: any;
1303
+ }) => string
1304
+ ) | XML[]>;
1165
1305
  class Build {
1166
1306
  private static page = 'COUNT(1) zccw1986 ';
1167
1307
  private isCount: boolean;
@@ -1188,7 +1328,7 @@ class Build {
1188
1328
  * @returns
1189
1329
  * @memberof Build
1190
1330
  */
1191
- pageTag() {
1331
+ page() {
1192
1332
  return (text: string, render: (text: string) => string) => {
1193
1333
  if (this.isCount === true) {
1194
1334
  return Build.page;
@@ -1199,11 +1339,11 @@ class Build {
1199
1339
  }
1200
1340
  /**
1201
1341
  *
1202
- * 汇总查询专用
1342
+ * 包含的内容只在汇总查询时有效,否则是空白
1203
1343
  * @returns
1204
1344
  * @memberof Build
1205
1345
  */
1206
- sumTag() {
1346
+ sum() {
1207
1347
  return (text: string, render: (text: string) => string) => {
1208
1348
  if (this.isSum !== true) {
1209
1349
  return '';
@@ -1212,13 +1352,14 @@ class Build {
1212
1352
  }
1213
1353
  };
1214
1354
  }
1355
+
1215
1356
  /**
1216
1357
  *
1217
1358
  * 当分页时、汇总时忽略函数内包含的内容
1218
1359
  * @returns
1219
1360
  * @memberof Build
1220
1361
  */
1221
- pageIgnoreTag() {
1362
+ notPage() {
1222
1363
  return (text: string, render: (text: string) => string) => {
1223
1364
  if (this.isCount === true || this.isSum === true) {
1224
1365
  return '';
@@ -1242,8 +1383,7 @@ class Build {
1242
1383
  */
1243
1384
  where() {
1244
1385
  return (text: string, render: (text: string) => string) => {
1245
- let data = render(text);
1246
- data = data.trim();
1386
+ let data = render(text).trim();
1247
1387
  if (data) {
1248
1388
  data = data.replace(/and|or/i, '');
1249
1389
  return ` WHERE ${data} `;
@@ -1252,6 +1392,33 @@ class Build {
1252
1392
  }
1253
1393
  };
1254
1394
  }
1395
+ /**
1396
+ * ```
1397
+ * SELECT
1398
+ * {{#hump}}
1399
+ * a.event_id, a.event_name eventName
1400
+ * {{/hump}}
1401
+ * FROM...
1402
+ * ```
1403
+ * 编译后:
1404
+ * ```
1405
+ * SELECT
1406
+ * a.event_id eventId, a.event_name eventName
1407
+ * FROM...
1408
+ * ```
1409
+ */
1410
+ hump() {
1411
+ return (text: string, render: (text: string) => string) => {
1412
+ let data = render(text).trim();
1413
+ const datas = data.split(',');
1414
+ for (let i = 0; i < datas.length; i++) {
1415
+ if (datas[i]?.match(/\s|\t/) === null) {
1416
+ datas[i] = `${datas[i]} ${datas[i]!.replace(/[a-zA-Z0-9]+\./, '').replace(/_([a-z])/g, (a, b, c) => b.toUpperCase())}`;
1417
+ }
1418
+ }
1419
+ return datas.join(',');
1420
+ };
1421
+ }
1255
1422
  /**
1256
1423
  * 删除第一个and、or
1257
1424
  * 删除最后一个,
@@ -1274,13 +1441,13 @@ class Build {
1274
1441
  * 分页时将排序部分代码用此函数包起来,可以自动拼接order by
1275
1442
  * 查询条数时,自动忽略此部分
1276
1443
  * etc
1277
- * {{#orderTag}} name desc, age asc {{/orderTag}}
1444
+ * {{#order}} name desc, age asc {{/order}}
1278
1445
  * ===
1279
1446
  * ORDER BY name desc, age asc
1280
1447
  * @returns
1281
1448
  * @memberof Build
1282
1449
  */
1283
- orderTag() {
1450
+ order() {
1284
1451
  return (text: string, render: (text: string) => string) => {
1285
1452
  if (this.isCount === true || this.isSum === true) {
1286
1453
  return '';
@@ -1295,7 +1462,7 @@ class Build {
1295
1462
  }
1296
1463
  };
1297
1464
  }
1298
- limitTag() {
1465
+ limit() {
1299
1466
  return (text: string, render: (text: string) => string) => {
1300
1467
  if (this.isCount === true || this.isSum === true) {
1301
1468
  return '';
@@ -1315,13 +1482,13 @@ class Build {
1315
1482
  * 分页时将分组部分代码用此函数包起来,可以自动拼接GROUP BY
1316
1483
  * 当分页时、汇总时,自动忽略此部分
1317
1484
  * etc
1318
- * {{#groupTag}} name, age {{/groupTag}}
1485
+ * {{#between}} name, age {{/between}}
1319
1486
  * ===
1320
1487
  * group by name.age
1321
1488
  * @returns
1322
1489
  * @memberof Build
1323
1490
  */
1324
- groupTag() {
1491
+ group() {
1325
1492
  return (text: string, render: (text: string) => string) => {
1326
1493
  if (this.isCount === true || this.isSum === true) {
1327
1494
  return '';
@@ -1365,15 +1532,15 @@ class Build {
1365
1532
  *
1366
1533
  * 距离计算,单位米
1367
1534
  * etc
1368
- * {{#distanceTag}} (t.longitude, t.latitude), ({{longitude}}, {{latitude}}) {{/distanceTag}}
1535
+ * {{#distance}} (t.longitude, t.latitude), ({{longitude}}, {{latitude}}) {{/distance}}
1369
1536
  * ===
1370
1537
  * ROUND(ST_DISTANCE(POINT(longitude1, latitude1), POINT({{longitude}}, {{latitude}}))*111195, 2)
1371
1538
  * 可根据需求自行将数据转换为千米,例如
1372
- * {{#distanceTag}} (t.longitude, t.latitude), ({{longitude}}, {{latitude}}) {{/distanceTag}} / 1000
1539
+ * {{#distance}} (t.longitude, t.latitude), ({{longitude}}, {{latitude}}) {{/distance}} / 1000
1373
1540
  * @returns
1374
1541
  * @memberof Build
1375
1542
  */
1376
- distanceTag() {
1543
+ distance() {
1377
1544
  return (text: string, render: (text: string) => string) => {
1378
1545
  const result = render(text);
1379
1546
  if (/\(([^()]+)\)/.exec(result)) {
@@ -1397,38 +1564,178 @@ class Build {
1397
1564
  };
1398
1565
  }
1399
1566
  }
1400
- class SqlCache {
1401
- private sqlMap: SqlModel = {};
1402
- private sqlFNMap: PartialsOrLookupFn = {};
1403
- async init(options: {
1404
- sqlMap?: SqlModel; sqlDir?: string;
1405
- sqlFNMap?: Record<string, string>; sqlFNDir?: string;
1406
- }) {
1407
- if (options.sqlMap) {
1408
- this.sqlMap = options.sqlMap;
1567
+
1568
+ function replaceCdata(rawText: string) {
1569
+ var cdataRegex = new RegExp('(<!\\[CDATA\\[)([\\s\\S]*?)(\\]\\]>)', 'g');
1570
+ var matches = rawText.match(cdataRegex);
1571
+
1572
+ if (matches != null && matches.length > 0) {
1573
+ for (var z = 0; z < matches.length; z++) {
1574
+ var regex = new RegExp('(<!\\[CDATA\\[)([\\s\\S]*?)(\\]\\]>)', 'g');
1575
+ var m = regex.exec(matches[z]!);
1576
+
1577
+ var cdataText = m![2];
1578
+ cdataText = cdataText!.replace(/\&/g, '&amp;');
1579
+ cdataText = cdataText!.replace(/\</g, '&lt;');
1580
+ cdataText = cdataText!.replace(/\>/g, '&gt;');
1581
+ cdataText = cdataText!.replace(/\"/g, '&quot;');
1582
+
1583
+ rawText = rawText.replace(m![0], cdataText);
1409
1584
  }
1410
- if (options.sqlDir) {
1411
- const sqlFis = globalThis[_fs].readdirSync(options.sqlDir);
1412
- for (const modeName of sqlFis) {
1585
+ }
1586
+ return rawText;
1587
+ }
1588
+ function _flatData(result: any, i: number, length: number, keys: string[], V: any) {
1589
+ const key = keys[i];
1590
+ if (i < length) {
1591
+ result[key!] ??= {};
1592
+ i++;
1593
+ _flatData(result[key!], i, length, keys, V);
1594
+ } else {
1595
+ result[key!] = V;
1596
+ }
1597
+ }
1598
+ /**
1599
+ * ifUndefined默认是MapperIfUndefined.Skip
1600
+ */
1601
+ export function flatData<M>(options: { data: any; mapper: string | SqlMapper; mapperIfUndefined?: MapperIfUndefined; }): M {
1602
+ if (typeof options.mapper === 'string') {
1603
+ const name = options.mapper;
1604
+ options.mapper = globalThis[_resultMap][name];
1605
+ Throw.if(!options.mapper, `not found mapper!${name}`);
1606
+ }
1607
+ options.mapperIfUndefined ??= MapperIfUndefined.Skip;
1608
+ options.mapper = options.mapper as SqlMapper;
1609
+ const result: any = {};
1610
+ for (const [columnName, keys, def] of options.mapper) {
1611
+ let V = options.data[columnName];
1612
+ if (V === undefined) {
1613
+ if (options.mapperIfUndefined === MapperIfUndefined.Null) {
1614
+ V = null;
1615
+ } else if (options.mapperIfUndefined === MapperIfUndefined.Zero) {
1616
+ V = 0;
1617
+ } else if (options.mapperIfUndefined === MapperIfUndefined.EmptyString) {
1618
+ V = '';
1619
+ } else if (def !== undefined) {
1620
+ V = def;
1621
+ } else {
1622
+ continue;
1623
+ }
1624
+ }
1625
+ _flatData(result, 0, keys.length - 1, keys, V);
1626
+ }
1627
+ return result;
1628
+ }
1629
+
1630
+ export class SqlCache {
1631
+ private sqlMap: _SqlModel = {};
1632
+ private sqlFNMap: PartialsOrLookupFn = {};
1633
+ private async _read(jsMode: boolean, sqlDir: string, queryTypes: string[], rootName: string) {
1634
+ const sqlFis = globalThis[_fs].readdirSync(sqlDir);
1635
+ for (const modeName of sqlFis) {
1636
+ const file = globalThis[_path].join(sqlDir, modeName);
1637
+ const stat = globalThis[_fs].statSync(file);
1638
+ if (stat.isDirectory()) {
1639
+ await this._read(jsMode, file, queryTypes, modeName);
1640
+ } else {
1413
1641
  const extname = globalThis[_path].extname(modeName);
1414
1642
  const name = globalThis[_path].basename(modeName, extname);
1415
- const file = globalThis[_path].join(options.sqlDir, modeName);
1416
- if (extname === 'mu') {
1417
- const parser = new MUParser(name, globalThis[_fs].readFileSync(file, { encoding: 'utf-8' }).toString());
1643
+ let ct = 0;
1644
+ if (extname === '.mu') {
1645
+ logger.debug(`sql: ${file} start explain!`);
1646
+ const parser = new MUParser(rootName || name, globalThis[_fs].readFileSync(file, { encoding: 'utf-8' }).toString());
1418
1647
  let source = parser.next();
1419
1648
  while (source != null) {
1649
+ ct++;
1420
1650
  this.sqlMap[source[0]] = source[1];
1421
1651
  logger.debug(`sql: ${source[0]} found!`);
1422
1652
  source = parser.next();
1423
1653
  }
1424
- } else if (extname === '.js') {
1425
- const obj = (await import(globalThis[_path].join(options.sqlDir, modeName))).default as SqlModel;
1654
+ logger.debug(`sql: ${file} explain over[${ct}]!`);
1655
+ } else if (jsMode === true && extname === '.js') {
1656
+ logger.debug(`sql: ${file} start explain!`);
1657
+ const obj = (await import(globalThis[_path].join(sqlDir, modeName))).default as _SqlModel;
1426
1658
  for (const [key, fn] of Object.entries(obj)) {
1427
- this.sqlMap[`${name}.${String(key)}`] = fn;
1659
+ ct++;
1660
+
1661
+ this.sqlMap[`${rootName || name}.${String(key)}`] = fn;
1662
+ }
1663
+ logger.debug(`sql: ${file} explain over[${ct}]!`);
1664
+ } else if (extname === '.xml') {
1665
+ logger.debug(`sql: ${file} start explain!`);
1666
+ const root = (HTML.parse(replaceCdata(globalThis[_fs].readFileSync(file, { encoding: 'utf-8' }).toString())) as XML[])[0];
1667
+ if (root) {
1668
+ const mappers = root.children;
1669
+ for (const mapper of mappers) {
1670
+ if (mapper.type === 'tag' && mapper.name === 'mapper') {
1671
+ for (const am of mapper.children) {
1672
+ if (am.type === 'tag') {
1673
+ Throw.if(!queryTypes.includes(am.name), `${rootName} ${name}错误,${am.name}不支持!`);
1674
+ am.id = am.attrs['id'];
1675
+ Throw.if(!am.id, `${rootName} ${name}错误,没有为此块设置id:${am}`);
1676
+ if (am.name === 'resultMap') {
1677
+ ct++;
1678
+ globalThis[_resultMap] ??= {};
1679
+ const keys: SqlMapper = [];
1680
+ this.readResultMap(am.children, keys, []);
1681
+ globalThis[_resultMap][am.id!] = keys;
1682
+ logger.debug(`sql_resultMap: ${am.id!} found!`);
1683
+ } else {
1684
+ this.sqlMap[`${rootName || name}.${am.id!}`] = am.children;
1685
+ if (am.attrs['resultMap']) {
1686
+ globalThis[_resultMap_SQLID][`${rootName || name}.${am.id!}`] = am.attrs['resultMap'];
1687
+ logger.debug(`sql: autoMapper: ${rootName || name}.${am.id!}-${am.attrs['resultMap']}`);
1688
+ }
1689
+ logger.debug(`sql: ${rootName || name}.${am.id!} found!`);
1690
+ ct++;
1691
+ }
1692
+ }
1693
+ }
1694
+ }
1695
+ }
1428
1696
  }
1697
+ logger.debug(`sql: ${file} explain over[${ct}]!`);
1698
+ }
1699
+
1700
+ }
1701
+ }
1702
+ }
1703
+ /**
1704
+ *
1705
+ * ```
1706
+ // 第一个元素=列名,第二个元素是属性路径,
1707
+ [
1708
+ ['dit_id', ['id']], // 列名ditid,对应属性id
1709
+ ['event_id', ['eventMainInfo', 'id']] // 列名event_id对应属性eventMainInfo.id
1710
+ ]
1711
+ * ```
1712
+ * @param am
1713
+ * @param keys
1714
+ */
1715
+ private readResultMap(ams: XML[], keys: SqlMapper, key: string[]) {
1716
+ for (const am of ams) {
1717
+ if (am.type === 'tag') {
1718
+ if (am.name === 'result' || am.name === 'id') {
1719
+ keys.push([am.attrs['column']!, [...key, am.attrs['property']!]]);
1720
+ } else {
1721
+ this.readResultMap(am.children, keys, [...key, am.attrs['property']!])
1429
1722
  }
1430
1723
  }
1431
1724
  }
1725
+ }
1726
+ async init(options: {
1727
+ sqlMap?: _SqlModel; sqlDir?: string;
1728
+ sqlFNMap?: Record<string, string>; sqlFNDir?: string;
1729
+ sqlMapperMap?: SqlMappers; sqlMapperDir?: string;
1730
+ jsMode?: boolean;
1731
+ }) {
1732
+ if (options.sqlMap) {
1733
+ this.sqlMap = options.sqlMap;
1734
+ }
1735
+ const queryTypes = ['sql', 'select', 'insert', 'update', 'delete', 'resultMap'];
1736
+ if (options.sqlDir) {
1737
+ await this._read(options.jsMode === true, options.sqlDir, queryTypes, '');
1738
+ }
1432
1739
  if (options.sqlFNMap) {
1433
1740
  this.sqlFNMap = options.sqlFNMap;
1434
1741
  }
@@ -1443,8 +1750,23 @@ class SqlCache {
1443
1750
  }
1444
1751
  }
1445
1752
  }
1753
+ if (options.sqlMapperMap) {
1754
+ globalThis[_resultMap] = options.sqlFNMap;
1755
+ }
1756
+ if (options.sqlMapperDir) {
1757
+ const sqlFis = globalThis[_fs].readdirSync(options.sqlDir);
1758
+ globalThis[_resultMap] ??= {};
1759
+ for (const modeName of sqlFis) {
1760
+ const extname = globalThis[_path].extname(modeName);
1761
+ const name = globalThis[_path].basename(modeName, extname);
1762
+ const file = globalThis[_path].join(options.sqlDir, modeName);
1763
+ if (extname === 'json') {
1764
+ globalThis[_resultMap][name] = JSON.parse(globalThis[_fs].readFileSync(file, { encoding: 'utf-8' }).toString());
1765
+ }
1766
+ }
1767
+ }
1446
1768
  }
1447
- load(sqlid: string, options: {
1769
+ load(sqlids: string[], options: {
1448
1770
  ctx: any;
1449
1771
  isCount?: boolean;
1450
1772
  isSum?: boolean;
@@ -1453,13 +1775,31 @@ class SqlCache {
1453
1775
  orderBy?: string;
1454
1776
  [k: string]: any;
1455
1777
  }): string {
1456
- const sqlSource = this.sqlMap[sqlid];
1457
- Throw.if(!sqlSource, `指定的语句${sqlid}不存在!`);
1458
- const _sql = typeof sqlSource === 'function' ? sqlSource(options) : sqlSource!;
1778
+ let sqlSource: any;
1779
+ for (const sqlid of sqlids) {
1780
+ sqlSource = this.sqlMap[sqlid];
1781
+ if (sqlSource) {
1782
+ break;
1783
+ }
1784
+ }
1785
+ const matchSqlid = sqlids.map(i => i.split('.')[0]!);
1786
+ Throw.if(!sqlSource, `指定的语句${sqlids.join('|')}不存在!`);
1459
1787
  const buildParam = new Build(options.isCount === true, options.isSum === true, options);
1460
- const sql = mustache.render(_sql, buildParam, this.sqlFNMap);
1461
- logger.debug(sqlid, sql);
1462
- return sql;
1788
+ if (typeof sqlSource === 'function') {
1789
+ const _sql = sqlSource(options);
1790
+ const sql = mustache.render(_sql, buildParam, this.sqlFNMap);
1791
+ return format(sql);
1792
+ } else if (typeof sqlSource === 'string') {
1793
+ const sql = mustache.render(sqlSource, buildParam, this.sqlFNMap);
1794
+ return format(sql);
1795
+ } else if (typeof sqlSource === 'object') {
1796
+ const _sql = convert(sqlSource, options, matchSqlid, this.sqlMap as Record<string, XML[]>);
1797
+ console.log(_sql);
1798
+ const sql = mustache.render(_sql, buildParam, this.sqlFNMap);
1799
+ console.log(sql);
1800
+ return format(sql);
1801
+ }
1802
+ return '';
1463
1803
  }
1464
1804
  }
1465
1805
  // #endregion
@@ -1489,6 +1829,8 @@ function P<T extends object>(skipConn = false) {
1489
1829
  const option = args[0] = Object.assign({}, globalThis[_GlobalSqlOption], this[_SqlOption], args[0]) as (MethodOption & { sync?: SyncMode; });
1490
1830
  option.sync ??= SyncMode.Async;
1491
1831
  const dbName = option?.dbName ?? this[_daoDBName] ?? _primaryDB;
1832
+ const dddx = this[_dbType];
1833
+ logger.info(dddx);
1492
1834
  option!.dao = globalThis[_dao][this[_dbType]!][dbName] as Dao;
1493
1835
  Throw.if(!option!.dao, `not found db:${String(dbName)}(${this[_dbType]})`);
1494
1836
  option!.tableName = option?.tableName ?? this[_tableName];
@@ -1511,7 +1853,7 @@ function P<T extends object>(skipConn = false) {
1511
1853
  if (tableVersion && tableVersion < lastVersion) { // 发现需要升级的版本
1512
1854
  // 更新版本
1513
1855
  const columns = iterare<{ name: string }>(option!.conn!.query(SyncMode.Sync, `PRAGMA table_info(${tableES})`))
1514
- .filter(c => this[_fields]!.hasOwnProperty(c.name))
1856
+ .filter(c => this[_fields]!.hasOwnProperty(C2P(c.name, globalThis[_Hump])))
1515
1857
  .map(c => Sqlstring.escapeId(c.name))
1516
1858
  .join(',');
1517
1859
 
@@ -1520,13 +1862,13 @@ function P<T extends object>(skipConn = false) {
1520
1862
  option!.conn!.execute(SyncMode.Sync, `ALTER TABLE ${tableES} RENAME TO ${rtable};`);
1521
1863
  option!.conn!.execute(SyncMode.Sync, `
1522
1864
  CREATE TABLE IF NOT EXISTS ${tableES}(
1523
- ${Object.values(this[_fields]!).map(K => K[DBType.Sqlite]).join(',')}
1524
- ${this[_ids] && this[_ids].length ? `, PRIMARY KEY (${this[_ids].map(i => this[_fields]![i]?.esName).join(',')})` : ''}
1865
+ ${Object.values(this[_fields]!).map(K => K[DBType.Sqlite]()).join(',')}
1866
+ ${this[_ids] && this[_ids].length ? `, PRIMARY KEY (${this[_ids].map(i => this[_fields]![i]?.C2()).join(',')})` : ''}
1525
1867
  );
1526
1868
  `);
1527
1869
  if (this[_index] && this[_index].length) {
1528
1870
  for (const index of this[_index]) {
1529
- option!.conn!.execute(SyncMode.Sync, `CREATE INDEX ${Sqlstring.escapeId(`${index}_${Math.random()}`.replace(/\./, ''))} ON ${tableES} ("${index}");`);
1871
+ option!.conn!.execute(SyncMode.Sync, `CREATE INDEX ${Sqlstring.escapeId(`${index}_${Math.random()}`.replace(/\./, ''))} ON ${tableES} ("${this[_fields]![index]?.C2()}");`);
1530
1872
  }
1531
1873
  }
1532
1874
  option!.conn!.execute(SyncMode.Sync, `INSERT INTO ${tableES} (${columns}) SELECT ${columns} FROM ${rtable};`);
@@ -1541,14 +1883,14 @@ function P<T extends object>(skipConn = false) {
1541
1883
  // 创建表
1542
1884
  option!.conn!.execute(SyncMode.Sync, `
1543
1885
  CREATE TABLE IF NOT EXISTS ${tableES} (
1544
- ${Object.values(this[_fields]!).map(K => K[DBType.Sqlite]).join(',')}
1545
- ${this[_ids] && this[_ids].length ? `, PRIMARY KEY (${this[_ids].map(i => this[_fields]![i]?.esName).join(',')})` : ''}
1886
+ ${Object.values(this[_fields]!).map(K => K[DBType.Sqlite]()).join(',')}
1887
+ ${this[_ids] && this[_ids].length ? `, PRIMARY KEY (${this[_ids].map(i => this[_fields]![i]?.C2()).join(',')})` : ''}
1546
1888
 
1547
1889
  );
1548
1890
  `);
1549
1891
  if (this[_index] && this[_index].length) {
1550
1892
  for (const index of this[_index]) {
1551
- option!.conn!.execute(SyncMode.Sync, `CREATE INDEX ${Sqlstring.escapeId(`${index}_${Math.random()}`.replace(/\./, ''))} ON ${tableES} ("${index}");`);
1893
+ option!.conn!.execute(SyncMode.Sync, `CREATE INDEX ${Sqlstring.escapeId(`${index}_${Math.random()}`.replace(/\./, ''))} ON ${tableES} ("${this[_fields]![index]?.C2()}");`);
1552
1894
  }
1553
1895
  }
1554
1896
  option!.conn!.execute(SyncMode.Sync, 'INSERT OR REPLACE INTO TABLE_VERSION (______tableName, ______version ) VALUES ( ?, ? )', [option!.tableName, lastVersion]);
@@ -1592,7 +1934,7 @@ function P<T extends object>(skipConn = false) {
1592
1934
  if (tableVersion && tableVersion < lastVersion) { // 发现需要升级的版本
1593
1935
  // 更新版本
1594
1936
  const columns = iterare<{ name: string }>(await option!.conn!.query(SyncMode.Async, `PRAGMA table_info(${tableES})`))
1595
- .filter(c => this[_fields]!.hasOwnProperty(c.name))
1937
+ .filter(c => this[_fields]!.hasOwnProperty(C2P(c.name, globalThis[_Hump])))
1596
1938
  .map(c => Sqlstring.escapeId(c.name))
1597
1939
  .join(',');
1598
1940
 
@@ -1601,13 +1943,13 @@ function P<T extends object>(skipConn = false) {
1601
1943
  await option!.conn!.execute(SyncMode.Async, `ALTER TABLE ${tableES} RENAME TO ${rtable};`);
1602
1944
  await option!.conn!.execute(SyncMode.Async, `
1603
1945
  CREATE TABLE IF NOT EXISTS ${tableES}(
1604
- ${Object.values(this[_fields]!).map(K => K[DBType.Sqlite]).join(',')}
1605
- ${this[_ids] && this[_ids].length ? `, PRIMARY KEY (${this[_ids].map(i => this[_fields]![i]?.esName).join(',')})` : ''}
1946
+ ${Object.values(this[_fields]!).map(K => K[DBType.Sqlite]()).join(',')}
1947
+ ${this[_ids] && this[_ids].length ? `, PRIMARY KEY (${this[_ids].map(i => this[_fields]![i]?.C2()).join(',')})` : ''}
1606
1948
  );
1607
1949
  `);
1608
1950
  if (this[_index] && this[_index].length) {
1609
1951
  for (const index of this[_index]) {
1610
- await option!.conn!.execute(SyncMode.Async, `CREATE INDEX ${Sqlstring.escapeId(`${index}_${Math.random()}`.replace(/\./, ''))} ON ${tableES} ("${index}");`);
1952
+ await option!.conn!.execute(SyncMode.Async, `CREATE INDEX ${Sqlstring.escapeId(`${index}_${Math.random()}`.replace(/\./, ''))} ON ${tableES} ("${this[_fields]![index]?.C2()}");`);
1611
1953
  }
1612
1954
  }
1613
1955
  await option!.conn!.execute(SyncMode.Async, `INSERT INTO ${tableES} (${columns}) SELECT ${columns} FROM ${rtable};`);
@@ -1622,13 +1964,13 @@ function P<T extends object>(skipConn = false) {
1622
1964
  // 创建表
1623
1965
  await option!.conn!.execute(SyncMode.Async, `
1624
1966
  CREATE TABLE IF NOT EXISTS ${tableES}(
1625
- ${Object.values(this[_fields]!).map(K => K[DBType.Sqlite]).join(',')}
1626
- ${this[_ids] && this[_ids].length ? `, PRIMARY KEY (${this[_ids].map(i => this[_fields]![i]?.esName).join(',')})` : ''}
1967
+ ${Object.values(this[_fields]!).map(K => K[DBType.Sqlite]()).join(',')}
1968
+ ${this[_ids] && this[_ids].length ? `, PRIMARY KEY (${this[_ids].map(i => this[_fields]![i]?.C2()).join(',')})` : ''}
1627
1969
  );
1628
1970
  `);
1629
1971
  if (this[_index] && this[_index].length) {
1630
1972
  for (const index of this[_index]) {
1631
- await option!.conn!.execute(SyncMode.Async, `CREATE INDEX ${Sqlstring.escapeId(`${index}_${Math.random()}`.replace(/\./, ''))} ON ${Sqlstring.escapeId(option!.tableName)} ("${index}");`);
1973
+ await option!.conn!.execute(SyncMode.Async, `CREATE INDEX ${Sqlstring.escapeId(`${index}_${Math.random()}`.replace(/\./, ''))} ON ${Sqlstring.escapeId(option!.tableName)} ("${this[_fields]![index]?.C2()}");`);
1632
1974
  }
1633
1975
  }
1634
1976
  await option!.conn!.execute(SyncMode.Async, 'INSERT OR REPLACE INTO TABLE_VERSION (______tableName, ______version ) VALUES ( ?, ? )', [option!.tableName, lastVersion]);
@@ -1682,27 +2024,40 @@ function P<T extends object>(skipConn = false) {
1682
2024
  };
1683
2025
  }
1684
2026
  const FieldFilter = (
1685
- K: string, V: any, def: any,
1686
- option?: MethodOption & { finalColumns?: Set<string>; tempColumns?: Array<string>; def?: boolean; skipUndefined?: boolean; skipNull?: boolean; skipEmptyString?: boolean; }
2027
+ K: string, V: any, def: any, uuidColumn: boolean,
2028
+ option?: MethodOption & { finalColumns?: Set<string>; tempColumns?: Array<string>; insert?: boolean; skipUndefined?: boolean; skipNull?: boolean; skipEmptyString?: boolean; }
1687
2029
  ) => {
1688
2030
  let ret = 0;
1689
- if (V === null) {
1690
- if (option?.skipNull !== true) {
1691
- ret = 1;
1692
- V = option?.def === true && def && def.hasOwnProperty(K) ? def[K] : null;
1693
- }
1694
- } else if (V === undefined) {
1695
- if (option?.skipUndefined !== true) {
2031
+ // 如果是插入操作且字段是UUID,则不进行空值检查
2032
+ // 只有在非插入或者非UUID时,进行空置检查
2033
+ if (option?.insert === true && uuidColumn === true) {
2034
+ ret = 1;
2035
+ if (V === undefined) {
2036
+ V = null;
2037
+ } else if (emptyString(`${V ?? ''}`)) {
2038
+ V = '';
2039
+ } else {
1696
2040
  ret = 1;
1697
- V = option?.def === true && def && def.hasOwnProperty(K) ? def[K] : null;
1698
2041
  }
1699
- } else if (emptyString(`${V ?? ''}`)) {
1700
- if (option?.skipEmptyString !== true) {
2042
+ } else {
2043
+ if (V === null) {
2044
+ if (option?.skipNull !== true) {
2045
+ ret = 1;
2046
+ V = option?.insert === true && def && def.hasOwnProperty(K) ? def[K] : null;
2047
+ }
2048
+ } else if (V === undefined) {
2049
+ if (option?.skipUndefined !== true) {
2050
+ ret = 1;
2051
+ V = option?.insert === true && def && def.hasOwnProperty(K) ? def[K] : null;
2052
+ }
2053
+ } else if (emptyString(`${V ?? ''}`)) {
2054
+ if (option?.skipEmptyString !== true) {
2055
+ ret = 1;
2056
+ V = option?.insert === true && def && def.hasOwnProperty(K) ? def[K] : '';
2057
+ }
2058
+ } else {
1701
2059
  ret = 1;
1702
- V = option?.def === true && def && def.hasOwnProperty(K) ? def[K] : '';
1703
2060
  }
1704
- } else {
1705
- ret = 1;
1706
2061
  }
1707
2062
  if (ret === 1) {
1708
2063
  option?.finalColumns?.add(K);
@@ -1710,204 +2065,203 @@ const FieldFilter = (
1710
2065
  }
1711
2066
  return [ret, V];
1712
2067
  }
1713
- const MYSQLCHARSET = `CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci`
2068
+ const MYSQLCHARSET = `CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci`;
1714
2069
  export const Field = (config: FieldOption) => {
1715
2070
  config.type ??= SqlType.varchar;
1716
2071
  return (object: object, propertyName: string) => {
1717
2072
  const field = config as AField;
1718
- field.name = propertyName;
1719
- field.esName = Sqlstring.escapeId(propertyName);
2073
+ field.P = propertyName;
2074
+ field.C = () => P2C(propertyName, globalThis[_Hump]);
2075
+ field.C2 = () => Sqlstring.escapeId(P2C(propertyName, globalThis[_Hump]));
2076
+ field.C3 = () => `${Sqlstring.escapeId(P2C(propertyName, globalThis[_Hump]))} ${propertyName}`;
1720
2077
  const hasDef = field.hasOwnProperty('def') === true;
1721
2078
  switch (field.type) {
1722
2079
  case SqlType.tinyint: {
1723
- field[DBType.Mysql] = `${field.esName} tinyint ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''}`;
1724
- field[DBType.SqliteRemote] = field[DBType.Sqlite] = `${field.esName} integer`;
2080
+ field[DBType.Mysql] = () => `${field.C2()} tinyint ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? `DEFAULT '${field.def}'` : ''}`;
2081
+ field[DBType.SqliteRemote] = field[DBType.Sqlite] = () => `${field.C2()} integer`;
1725
2082
  break;
1726
2083
  }
1727
2084
  case SqlType.smallint: {
1728
- field[DBType.Mysql] = `${field.esName} smallint ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''}`;
1729
- field[DBType.SqliteRemote] = field[DBType.Sqlite] = `${field.esName} integer`;
2085
+ field[DBType.Mysql] = () => `${field.C2()} smallint ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? `DEFAULT '${field.def}'` : ''}`;
2086
+ field[DBType.SqliteRemote] = field[DBType.Sqlite] = () => `${field.C2()} integer`;
1730
2087
  break;
1731
2088
  }
1732
2089
  case SqlType.mediumint: {
1733
- field[DBType.Mysql] = `${field.esName} smallint ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''}`;
1734
- field[DBType.SqliteRemote] = field[DBType.Sqlite] = `${field.esName} integer`;
2090
+ field[DBType.Mysql] = () => `${field.C2()} smallint ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? `DEFAULT '${field.def}'` : ''}`;
2091
+ field[DBType.SqliteRemote] = field[DBType.Sqlite] = () => `${field.C2()} integer`;
1735
2092
  break;
1736
2093
  }
1737
2094
  case SqlType.int: {
1738
- field[DBType.Mysql] = `${field.esName} int ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''}`;
1739
- field[DBType.SqliteRemote] = field[DBType.Sqlite] = `${field.esName} integer`;
2095
+ field[DBType.Mysql] = () => `${field.C2()} int ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? `DEFAULT '${field.def}'` : ''}`;
2096
+ field[DBType.SqliteRemote] = field[DBType.Sqlite] = () => `${field.C2()} integer`;
1740
2097
  break;
1741
2098
  }
1742
2099
  case SqlType.bigint: {
1743
- field[DBType.Mysql] = `${field.esName} bigint ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''} ${MYSQLCHARSET}`;
1744
- field[DBType.SqliteRemote] = field[DBType.Sqlite] = `${field.esName} integer`;
2100
+ field[DBType.Mysql] = () => `${field.C2()} bigint ${config.notNull === true ? 'NOT NULL' : ''} ${MYSQLCHARSET} ${hasDef ? `DEFAULT '${field.def}'` : ''}`;
2101
+ field[DBType.SqliteRemote] = field[DBType.Sqlite] = () => `${field.C2()} integer`;
1745
2102
  break;
1746
2103
  }
1747
-
1748
2104
  case SqlType.float: {
1749
- field[DBType.Mysql] = `${field.esName} float(${config.length ?? 1}, ${config.scale ?? 2}) ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''} `;
1750
- field[DBType.SqliteRemote] = field[DBType.Sqlite] = `${field.esName} real`;
2105
+ field[DBType.Mysql] = () => `${field.C2()} float(${config.length ?? 1}, ${config.scale ?? 2}) ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? `DEFAULT '${field.def}'` : ''} `;
2106
+ field[DBType.SqliteRemote] = field[DBType.Sqlite] = () => `${field.C2()} real`;
1751
2107
  break;
1752
2108
  }
1753
2109
  case SqlType.double: {
1754
- field[DBType.Mysql] = `${field.esName} double(${config.length ?? 1}, ${config.scale ?? 2}) ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''} `;
1755
- field[DBType.SqliteRemote] = field[DBType.Sqlite] = `${field.esName} real`;
2110
+ field[DBType.Mysql] = () => `${field.C2()} double(${config.length ?? 1}, ${config.scale ?? 2}) ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? `DEFAULT '${field.def}'` : ''} `;
2111
+ field[DBType.SqliteRemote] = field[DBType.Sqlite] = () => `${field.C2()} real`;
1756
2112
  break;
1757
2113
  }
1758
2114
  case SqlType.decimal: {
1759
- field[DBType.Mysql] = `${field.esName} decimal(${config.length ?? 1}, ${config.scale ?? 2}) ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''} `;
1760
- field[DBType.SqliteRemote] = field[DBType.Sqlite] = `${field.esName} real`;
2115
+ field[DBType.Mysql] = () => `${field.C2()} decimal(${config.length ?? 1}, ${config.scale ?? 2}) ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? `DEFAULT '${field.def}'` : ''} `;
2116
+ field[DBType.SqliteRemote] = field[DBType.Sqlite] = () => `${field.C2()} real`;
1761
2117
  break;
1762
2118
  }
1763
2119
 
1764
2120
  case SqlType.longtext: {
1765
- field[DBType.Mysql] = `${field.esName} longtext ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''} ${MYSQLCHARSET}`;
1766
- field[DBType.SqliteRemote] = field[DBType.Sqlite] = `${field.esName} text`;
2121
+ field[DBType.Mysql] = () => `${field.C2()} longtext ${config.notNull === true ? 'NOT NULL' : ''} ${MYSQLCHARSET} ${hasDef ? `DEFAULT '${field.def}'` : ''}`;
2122
+ field[DBType.SqliteRemote] = field[DBType.Sqlite] = () => `${field.C2()} text`;
1767
2123
  break;
1768
2124
  }
1769
2125
  case SqlType.mediumtext: {
1770
- field[DBType.Mysql] = `${field.esName} mediumtext ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''} ${MYSQLCHARSET}`;
1771
- field[DBType.SqliteRemote] = field[DBType.Sqlite] = `${field.esName} text`;
2126
+ field[DBType.Mysql] = () => `${field.C2()} mediumtext ${config.notNull === true ? 'NOT NULL' : ''} ${MYSQLCHARSET} ${hasDef ? `DEFAULT '${field.def}'` : ''}`;
2127
+ field[DBType.SqliteRemote] = field[DBType.Sqlite] = () => `${field.C2()} text`;
1772
2128
  break;
1773
2129
  }
1774
2130
  case SqlType.text: {
1775
- field[DBType.Mysql] = `${field.esName} text ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''} ${MYSQLCHARSET}`;
1776
- field[DBType.SqliteRemote] = field[DBType.Sqlite] = `${field.esName} text`;
2131
+ field[DBType.Mysql] = () => `${field.C2()} text ${config.notNull === true ? 'NOT NULL' : ''} ${MYSQLCHARSET} ${hasDef ? `DEFAULT '${field.def}'` : ''}`;
2132
+ field[DBType.SqliteRemote] = field[DBType.Sqlite] = () => `${field.C2()} text`;
1777
2133
  break;
1778
2134
  }
1779
-
1780
2135
  case SqlType.date: {
1781
- field[DBType.Mysql] = `${field.esName} date ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''} ${MYSQLCHARSET}`;
1782
- field[DBType.SqliteRemote] = field[DBType.Sqlite] = `${field.esName} text`;
2136
+ field[DBType.Mysql] = () => `${field.C2()} date ${config.notNull === true ? 'NOT NULL' : ''} ${MYSQLCHARSET} ${hasDef ? `DEFAULT '${field.def}'` : ''}`;
2137
+ field[DBType.SqliteRemote] = field[DBType.Sqlite] = () => `${field.C2()} text`;
1783
2138
  break;
1784
2139
  }
1785
2140
  case SqlType.time: {
1786
- field[DBType.Mysql] = `${field.esName} time ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''} ${MYSQLCHARSET}`;
1787
- field[DBType.SqliteRemote] = field[DBType.Sqlite] = `${field.esName} text`;
2141
+ field[DBType.Mysql] = () => `${field.C2()} time ${config.notNull === true ? 'NOT NULL' : ''} ${MYSQLCHARSET} ${hasDef ? `DEFAULT '${field.def}'` : ''}`;
2142
+ field[DBType.SqliteRemote] = field[DBType.Sqlite] = () => `${field.C2()} text`;
1788
2143
  break;
1789
2144
  }
1790
2145
  case SqlType.year: {
1791
- field[DBType.Mysql] = `${field.esName} year ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''} ${MYSQLCHARSET}`;
1792
- field[DBType.SqliteRemote] = field[DBType.Sqlite] = `${field.esName} text`;
2146
+ field[DBType.Mysql] = () => `${field.C2()} year ${config.notNull === true ? 'NOT NULL' : ''} ${MYSQLCHARSET} ${hasDef ? `DEFAULT '${field.def}'` : ''}`;
2147
+ field[DBType.SqliteRemote] = field[DBType.Sqlite] = () => `${field.C2()} text`;
1793
2148
  break;
1794
2149
  }
1795
2150
  case SqlType.datetime: {
1796
- field[DBType.Mysql] = `${field.esName} datetime ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''} ${MYSQLCHARSET}`;
1797
- field[DBType.SqliteRemote] = field[DBType.Sqlite] = `${field.esName} text`;
2151
+ field[DBType.Mysql] = () => `${field.C2()} datetime ${config.notNull === true ? 'NOT NULL' : ''} ${MYSQLCHARSET} ${hasDef ? `DEFAULT '${field.def}'` : ''}`;
2152
+ field[DBType.SqliteRemote] = field[DBType.Sqlite] = () => `${field.C2()} text`;
1798
2153
  break;
1799
2154
  }
1800
2155
  case SqlType.timestamp: {
1801
- field[DBType.Mysql] = `${field.esName} timestamp ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''} ${MYSQLCHARSET}`;
1802
- field[DBType.SqliteRemote] = field[DBType.Sqlite] = `${field.esName} integer`;
2156
+ field[DBType.Mysql] = () => `${field.C2()} timestamp ${config.notNull === true ? 'NOT NULL' : ''} ${MYSQLCHARSET} ${hasDef ? `DEFAULT '${field.def}'` : ''}`;
2157
+ field[DBType.SqliteRemote] = field[DBType.Sqlite] = () => `${field.C2()} integer`;
1803
2158
  break;
1804
2159
  }
1805
-
1806
2160
  case SqlType.char: {
1807
- field[DBType.Mysql] = `${field.esName} char(${config.length ?? 1}) ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''} ${MYSQLCHARSET}`;
1808
- field[DBType.SqliteRemote] = field[DBType.Sqlite] = `${field.esName} text`;
2161
+ field[DBType.Mysql] = () => `${field.C2()} char(${config.length ?? 1}) ${config.notNull === true ? 'NOT NULL' : ''} ${MYSQLCHARSET} ${hasDef ? `DEFAULT '${field.def}'` : ''}`;
2162
+ field[DBType.SqliteRemote] = field[DBType.Sqlite] = () => `${field.C2()} text`;
1809
2163
  break;
1810
2164
  }
1811
2165
  case SqlType.varchar: {
1812
- field[DBType.Mysql] = `${field.esName} varchar(${config.length ?? 1}) ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''} ${MYSQLCHARSET}`;
1813
- field[DBType.SqliteRemote] = field[DBType.Sqlite] = `${field.esName} text`;
2166
+ field[DBType.Mysql] = () => `${field.C2()} varchar(${config.length ?? 1}) ${config.notNull === true ? 'NOT NULL' : ''} ${MYSQLCHARSET} ${hasDef ? `DEFAULT '${field.def}'` : ''}`;
2167
+ field[DBType.SqliteRemote] = field[DBType.Sqlite] = () => `${field.C2()} text`;
1814
2168
  break;
1815
2169
  }
1816
2170
  case SqlType.tinyblob: {
1817
- field[DBType.Mysql] = `${field.esName} tinyblob ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''} ${MYSQLCHARSET}`;
1818
- field[DBType.SqliteRemote] = field[DBType.Sqlite] = `${field.esName} text`;
2171
+ field[DBType.Mysql] = () => `${field.C2()} tinyblob ${config.notNull === true ? 'NOT NULL' : ''} ${MYSQLCHARSET} ${hasDef ? `DEFAULT '${field.def}'` : ''}`;
2172
+ field[DBType.SqliteRemote] = field[DBType.Sqlite] = () => `${field.C2()} text`;
1819
2173
  break;
1820
2174
  }
1821
2175
  case SqlType.tinytext: {
1822
- field[DBType.Mysql] = `${field.esName} tinytext ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''} ${MYSQLCHARSET}`;
1823
- field[DBType.SqliteRemote] = field[DBType.Sqlite] = `${field.esName} text`;
2176
+ field[DBType.Mysql] = () => `${field.C2()} tinytext ${config.notNull === true ? 'NOT NULL' : ''} ${MYSQLCHARSET} ${hasDef ? `DEFAULT '${field.def}'` : ''}`;
2177
+ field[DBType.SqliteRemote] = field[DBType.Sqlite] = () => `${field.C2()} text`;
1824
2178
  break;
1825
2179
  }
1826
2180
  case SqlType.blob: {
1827
- field[DBType.Mysql] = `${field.esName} binary ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''} ${MYSQLCHARSET}`;
1828
- field[DBType.SqliteRemote] = field[DBType.Sqlite] = `${field.esName} text`;
2181
+ field[DBType.Mysql] = () => `${field.C2()} binary ${config.notNull === true ? 'NOT NULL' : ''} ${MYSQLCHARSET} ${hasDef ? `DEFAULT '${field.def}'` : ''}`;
2182
+ field[DBType.SqliteRemote] = field[DBType.Sqlite] = () => `${field.C2()} text`;
1829
2183
  break;
1830
2184
  }
1831
2185
  case SqlType.text: {
1832
- field[DBType.Mysql] = `${field.esName} text ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''} ${MYSQLCHARSET}`;
1833
- field[DBType.SqliteRemote] = field[DBType.Sqlite] = `${field.esName} text`;
2186
+ field[DBType.Mysql] = () => `${field.C2()} text ${config.notNull === true ? 'NOT NULL' : ''} ${MYSQLCHARSET} ${hasDef ? `DEFAULT '${field.def}'` : ''}`;
2187
+ field[DBType.SqliteRemote] = field[DBType.Sqlite] = () => `${field.C2()} text`;
1834
2188
  break;
1835
2189
  }
1836
2190
  case SqlType.mediumblob: {
1837
- field[DBType.Mysql] = `${field.esName} mediumblob ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''} ${MYSQLCHARSET}`;
1838
- field[DBType.SqliteRemote] = field[DBType.Sqlite] = `${field.esName} text`;
2191
+ field[DBType.Mysql] = () => `${field.C2()} mediumblob ${config.notNull === true ? 'NOT NULL' : ''} ${MYSQLCHARSET} ${hasDef ? `DEFAULT '${field.def}'` : ''}`;
2192
+ field[DBType.SqliteRemote] = field[DBType.Sqlite] = () => `${field.C2()} text`;
1839
2193
  break;
1840
2194
  }
1841
2195
  case SqlType.mediumtext: {
1842
- field[DBType.Mysql] = `${field.esName} mediumtext ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''} ${MYSQLCHARSET}`;
1843
- field[DBType.SqliteRemote] = field[DBType.Sqlite] = `${field.esName} text`;
2196
+ field[DBType.Mysql] = () => `${field.C2()} mediumtext ${config.notNull === true ? 'NOT NULL' : ''} ${MYSQLCHARSET} ${hasDef ? `DEFAULT '${field.def}'` : ''}`;
2197
+ field[DBType.SqliteRemote] = field[DBType.Sqlite] = () => `${field.C2()} text`;
1844
2198
  break;
1845
2199
  }
1846
2200
  case SqlType.longblob: {
1847
- field[DBType.Mysql] = `${field.esName} longblob ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''} ${MYSQLCHARSET}`;
1848
- field[DBType.SqliteRemote] = field[DBType.Sqlite] = `${field.esName} text`;
2201
+ field[DBType.Mysql] = () => `${field.C2()} longblob ${config.notNull === true ? 'NOT NULL' : ''} ${MYSQLCHARSET} ${hasDef ? `DEFAULT '${field.def}'` : ''}`;
2202
+ field[DBType.SqliteRemote] = field[DBType.Sqlite] = () => `${field.C2()} text`;
1849
2203
  break;
1850
2204
  }
1851
2205
  case SqlType.longtext: {
1852
- field[DBType.Mysql] = `${field.esName} longtext ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''} ${MYSQLCHARSET}`;
1853
- field[DBType.SqliteRemote] = field[DBType.Sqlite] = `${field.esName} text`;
2206
+ field[DBType.Mysql] = () => `${field.C2()} longtext ${config.notNull === true ? 'NOT NULL' : ''} ${MYSQLCHARSET} ${hasDef ? `DEFAULT '${field.def}'` : ''}`;
2207
+ field[DBType.SqliteRemote] = field[DBType.Sqlite] = () => `${field.C2()} text`;
1854
2208
  break;
1855
2209
  }
1856
2210
 
1857
2211
  case SqlType.set: {
1858
- field[DBType.Mysql] = `${field.esName} set ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''} ${MYSQLCHARSET}`;
1859
- field[DBType.SqliteRemote] = field[DBType.Sqlite] = `${field.esName} text`;
2212
+ field[DBType.Mysql] = () => `${field.C2()} set ${config.notNull === true ? 'NOT NULL' : ''} ${MYSQLCHARSET} ${hasDef ? `DEFAULT '${field.def}'` : ''}`;
2213
+ field[DBType.SqliteRemote] = field[DBType.Sqlite] = () => `${field.C2()} text`;
1860
2214
  break;
1861
2215
  }
1862
2216
  case SqlType.enum: {
1863
- field[DBType.Mysql] = `${field.esName} enum ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''} ${MYSQLCHARSET}`;
1864
- field[DBType.SqliteRemote] = field[DBType.Sqlite] = `${field.esName} text`;
2217
+ field[DBType.Mysql] = () => `${field.C2()} enum ${config.notNull === true ? 'NOT NULL' : ''} ${MYSQLCHARSET} ${hasDef ? `DEFAULT '${field.def}'` : ''}`;
2218
+ field[DBType.SqliteRemote] = field[DBType.Sqlite] = () => `${field.C2()} text`;
1865
2219
  break;
1866
2220
  }
1867
2221
  case SqlType.json: {
1868
- field[DBType.Mysql] = `${field.esName} json ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''} ${MYSQLCHARSET}`;
1869
- field[DBType.SqliteRemote] = field[DBType.Sqlite] = `${field.esName} text`;
2222
+ field[DBType.Mysql] = () => `${field.C2()} json ${config.notNull === true ? 'NOT NULL' : ''} ${MYSQLCHARSET} ${hasDef ? `DEFAULT '${field.def}'` : ''}`;
2223
+ field[DBType.SqliteRemote] = field[DBType.Sqlite] = () => `${field.C2()} text`;
1870
2224
  break;
1871
2225
  }
1872
2226
 
1873
2227
  case SqlType.geometry: {
1874
- field[DBType.Mysql] = `${field.esName} geometry ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''} ${MYSQLCHARSET}`;
1875
- field[DBType.SqliteRemote] = field[DBType.Sqlite] = `${field.esName} text`;
2228
+ field[DBType.Mysql] = () => `${field.C2()} geometry ${config.notNull === true ? 'NOT NULL' : ''} ${MYSQLCHARSET} ${hasDef ? `DEFAULT '${field.def}'` : ''}`;
2229
+ field[DBType.SqliteRemote] = field[DBType.Sqlite] = () => `${field.C2()} text`;
1876
2230
  break;
1877
2231
  }
1878
2232
  case SqlType.point: {
1879
- field[DBType.Mysql] = `${field.esName} point ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''} ${MYSQLCHARSET}`;
1880
- field[DBType.SqliteRemote] = field[DBType.Sqlite] = `${field.esName} text`;
2233
+ field[DBType.Mysql] = () => `${field.C2()} point ${config.notNull === true ? 'NOT NULL' : ''} ${MYSQLCHARSET} ${hasDef ? `DEFAULT '${field.def}'` : ''}`;
2234
+ field[DBType.SqliteRemote] = field[DBType.Sqlite] = () => `${field.C2()} text`;
1881
2235
  break;
1882
2236
  }
1883
2237
  case SqlType.linestring: {
1884
- field[DBType.Mysql] = `${field.esName} linestring ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''} ${MYSQLCHARSET}`;
1885
- field[DBType.SqliteRemote] = field[DBType.Sqlite] = `${field.esName} text`;
2238
+ field[DBType.Mysql] = () => `${field.C2()} linestring ${config.notNull === true ? 'NOT NULL' : ''} ${MYSQLCHARSET} ${hasDef ? `DEFAULT '${field.def}'` : ''}`;
2239
+ field[DBType.SqliteRemote] = field[DBType.Sqlite] = () => `${field.C2()} text`;
1886
2240
  break;
1887
2241
  }
1888
2242
  case SqlType.polygon: {
1889
- field[DBType.Mysql] = `${field.esName} polygon ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''} ${MYSQLCHARSET}`;
1890
- field[DBType.SqliteRemote] = field[DBType.Sqlite] = `${field.esName} text`;
2243
+ field[DBType.Mysql] = () => `${field.C2()} polygon ${config.notNull === true ? 'NOT NULL' : ''} ${MYSQLCHARSET} ${hasDef ? `DEFAULT '${field.def}'` : ''}`;
2244
+ field[DBType.SqliteRemote] = field[DBType.Sqlite] = () => `${field.C2()} text`;
1891
2245
  break;
1892
2246
  }
1893
2247
  case SqlType.multipoint: {
1894
- field[DBType.Mysql] = `${field.esName} multipoint ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''} ${MYSQLCHARSET}`;
1895
- field[DBType.SqliteRemote] = field[DBType.Sqlite] = `${field.esName} text`;
2248
+ field[DBType.Mysql] = () => `${field.C2()} multipoint ${config.notNull === true ? 'NOT NULL' : ''} ${MYSQLCHARSET} ${hasDef ? `DEFAULT '${field.def}'` : ''}`;
2249
+ field[DBType.SqliteRemote] = field[DBType.Sqlite] = () => `${field.C2()} text`;
1896
2250
  break;
1897
2251
  }
1898
2252
  case SqlType.multilinestring: {
1899
- field[DBType.Mysql] = `${field.esName} multilinestring ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''} ${MYSQLCHARSET}`;
1900
- field[DBType.SqliteRemote] = field[DBType.Sqlite] = `${field.esName} text`;
2253
+ field[DBType.Mysql] = () => `${field.C2()} multilinestring ${config.notNull === true ? 'NOT NULL' : ''} ${MYSQLCHARSET} ${hasDef ? `DEFAULT '${field.def}'` : ''}`;
2254
+ field[DBType.SqliteRemote] = field[DBType.Sqlite] = () => `${field.C2()} text`;
1901
2255
  break;
1902
2256
  }
1903
2257
  case SqlType.multipolygon: {
1904
- field[DBType.Mysql] = `${field.esName} multipolygon ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''} ${MYSQLCHARSET}`;
1905
- field[DBType.SqliteRemote] = field[DBType.Sqlite] = `${field.esName} text`;
2258
+ field[DBType.Mysql] = () => `${field.C2()} multipolygon ${config.notNull === true ? 'NOT NULL' : ''} ${MYSQLCHARSET} ${hasDef ? `DEFAULT '${field.def}'` : ''}`;
2259
+ field[DBType.SqliteRemote] = field[DBType.Sqlite] = () => `${field.C2()} text`;
1906
2260
  break;
1907
2261
  }
1908
2262
  case SqlType.geometrycollection: {
1909
- field[DBType.Mysql] = `${field.esName} geometrycollection ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''} ${MYSQLCHARSET}`;
1910
- field[DBType.SqliteRemote] = field[DBType.Sqlite] = `${field.esName} text`;
2263
+ field[DBType.Mysql] = () => `${field.C2()} geometrycollection ${config.notNull === true ? 'NOT NULL' : ''} ${MYSQLCHARSET} ${hasDef ? `DEFAULT '${field.def}'` : ''}`;
2264
+ field[DBType.SqliteRemote] = field[DBType.Sqlite] = () => `${field.C2()} text`;
1911
2265
  break;
1912
2266
  }
1913
2267
  };
@@ -1939,7 +2293,6 @@ export const Field = (config: FieldOption) => {
1939
2293
  if (hasDef) {
1940
2294
  __def[propertyName] = field.def;
1941
2295
  }
1942
-
1943
2296
  Reflect.defineMetadata(_fields, __fields, object);
1944
2297
  Reflect.defineMetadata(_columns, __columns, object);
1945
2298
  Reflect.defineMetadata(_columnsNoId, __columnsNoId, object);
@@ -1962,8 +2315,14 @@ export const DB = (config: ServiceOption) => {
1962
2315
  const __deleteState = Reflect.getMetadata(_deleteState, config.clz.prototype);
1963
2316
  const __index = Reflect.getMetadata(_index, config.clz.prototype);
1964
2317
  const __def = Reflect.getMetadata(_def, config.clz.prototype);
2318
+ const className = config.tableName?.replace(/_(\w)/g, (a: string, b: string) => b.toUpperCase());
2319
+ const ClassName = className?.replace(/\w/, (v: string) => v.toUpperCase());
2320
+ const vueName = config.tableName?.replace(/_/g, '-');
1965
2321
  return class extends constructor {
1966
2322
  [_tableName] = config.tableName;
2323
+ [_className] = className;
2324
+ [_ClassName] = ClassName;
2325
+ [_vueName] = vueName;
1967
2326
  [_daoDBName] = config.dbName;
1968
2327
  [_dbType] = config.dbType ?? DBType.Mysql;
1969
2328
  [_sqlite_version] = config.sqliteVersion;
@@ -1983,14 +2342,17 @@ export const DB = (config: ServiceOption) => {
1983
2342
  option?: MethodOption & {
1984
2343
  finalColumns?: Set<string>;
1985
2344
  tempColumns?: Array<string>;
1986
- def?: boolean;
2345
+ insert?: boolean;
1987
2346
  skipId?: boolean;
2347
+ skipNull?: boolean;
2348
+ skipUndefined?: boolean;
2349
+ skipEmptyString?: boolean;
1988
2350
  onFieldExists?: (K: string, V: any) => void;
1989
2351
  }
1990
2352
  ) => {
1991
2353
  return Object.fromEntries(
1992
2354
  iterare(option?.skipId === true ? __columnsNoId : __columns)
1993
- .map(K => [K, FieldFilter(K as string, data[K as string], __def, option)])
2355
+ .map(K => [K, FieldFilter(K as string, data[K as string], __def, __fields[K as string].uuid === true || __fields[K as string].uuidShort === true, option)])
1994
2356
  .filter(data => {
1995
2357
  if ((data[1] as any)[0] === 1) {
1996
2358
  if (option?.onFieldExists) {
@@ -2022,7 +2384,7 @@ export const DB = (config: ServiceOption) => {
2022
2384
  */
2023
2385
  export function DeclareClass(clz: any, FieldOptions: FieldOption[]) {
2024
2386
  for (const item of FieldOptions) {
2025
- tslib.__decorate([Field(item)], clz.prototype, item.name, void 0);
2387
+ tslib.__decorate([Field(item)], clz.prototype, item.P, void 0);
2026
2388
  }
2027
2389
  }
2028
2390
  /**
@@ -2052,6 +2414,9 @@ export function DeclareService(clz: any, config: ServiceOption) {
2052
2414
  */
2053
2415
  export class SqlService<T extends object> {
2054
2416
  private [_tableName]?: string;
2417
+ private [_className]?: string;
2418
+ private [_ClassName]?: string;
2419
+ private [_vueName]?: string;
2055
2420
  private [_daoDBName]?: string;
2056
2421
  private [_ids]?: string[];
2057
2422
  private [_fields]?: Record<string, AField>;
@@ -2064,12 +2429,21 @@ export class SqlService<T extends object> {
2064
2429
  private [_sqlite_version]?: string;
2065
2430
  private [_index]?: string[];
2066
2431
  private [_def]?: Partial<T>;
2067
- private [_transformer]?: (data: Partial<T>, option?: MethodOption & { finalColumns?: Set<string>; def?: boolean; skipId?: boolean; onFieldExists?: (K: string, V: any) => void; }) => Partial<T>;
2432
+ public [_transformer]?: <L = T>(data: Partial<L>, option?: MethodOption & {
2433
+ finalColumns?: Set<string>;
2434
+ insert?: boolean;
2435
+ skipId?: boolean;
2436
+ skipNull?: boolean;
2437
+ skipUndefined?: boolean;
2438
+ skipEmptyString?: boolean;
2439
+ onFieldExists?: (K: string, V: any) => void;
2440
+ }) => Partial<T>;
2068
2441
  private _insert(
2069
2442
  datas: Partial<T>[],
2070
2443
  option: MethodOption & {
2071
2444
  mode?: InsertMode;
2072
2445
  existConditionOtherThanIds?: (keyof T)[];
2446
+ replaceWithDef?: boolean;
2073
2447
  }): { sql: string; params?: any[] }[] {
2074
2448
  const sqls: { sql: string; params?: any[] }[] = [];
2075
2449
  const tableName = Sqlstring.escapeId(option!.tableName);
@@ -2078,28 +2452,37 @@ export class SqlService<T extends object> {
2078
2452
  const conditions = option!.existConditionOtherThanIds || this[_ids];
2079
2453
  Throw.if(!conditions, 'not found where condition for insertIfNotExists!');
2080
2454
  Throw.if(conditions!.length === 0, 'insertIfNotExists must have not null where!');
2081
- const where = iterare<string>(conditions! as string[]).map(c => `${this[_fields]![c]?.esName} = ?`).join(' AND ');
2455
+ const where = iterare<string>(conditions! as string[]).map(c => `${this[_fields]![c]?.C2()} = ?`).join(' AND ');
2082
2456
  const finalColumns = new Set<string>();
2083
2457
  const whereColumns = conditions! as string[];
2084
- const params = datas
2085
- .map(data => this[_transformer]!(data, { ...option, finalColumns, def: true }))
2086
- .flatMap(data => {
2087
- const result: any[] = [];
2458
+ const params: any[] = [];
2459
+ const questMarks = datas
2460
+ .map(data => this[_transformer]!(data, { ...option, finalColumns, insert: true }))
2461
+ .map(data => {
2088
2462
  const questMark = new Array<string>();
2089
2463
  for (const column of finalColumns) {
2090
- questMark.push('?');
2091
- result.push(
2092
- data.hasOwnProperty(column)
2093
- ? data[column]
2094
- : this[_def] && this[_def].hasOwnProperty(column)
2095
- ? this[_def][column]
2096
- : null
2097
- );
2464
+ const V = data.hasOwnProperty(column)
2465
+ ? data[column]
2466
+ : this[_def] && this[_def].hasOwnProperty(column)
2467
+ ? this[_def][column]
2468
+ : null;
2469
+ if (V === null) {
2470
+ const field = this[_fields]![column];
2471
+ if (field?.uuid) {
2472
+ questMark.push('UUID()');
2473
+ } else if (field?.uuidShort && this[_dbType] === DBType.Mysql) {
2474
+ questMark.push('UUID_SHORT()');
2475
+ } else {
2476
+ questMark.push('?');
2477
+ params.push(V);
2478
+ }
2479
+ } else {
2480
+ questMark.push('?');
2481
+ params.push(V);
2482
+ }
2098
2483
  }
2099
-
2100
2484
  for (const column of whereColumns) {
2101
- questMark.push('?');
2102
- result.push(
2485
+ params.push(
2103
2486
  data.hasOwnProperty(column)
2104
2487
  ? data[column]
2105
2488
  : this[_def] && this[_def].hasOwnProperty(column)
@@ -2107,118 +2490,147 @@ export class SqlService<T extends object> {
2107
2490
  : null
2108
2491
  );
2109
2492
  }
2110
- return result;
2493
+ return `SELECT ${questMark.join(',')} FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM ${tableName} WHERE ${where})`;
2111
2494
  });
2112
- const quests = new Array<string>(finalColumns.size).fill('?').join(',');
2113
- const columnNames = iterare<string>(finalColumns).map(i => this[_fields]![i]?.esName).join(',');
2114
- const selects = iterare<string>(new Array<string>(datas.length)).map(() => `SELECT ${quests} FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM ${tableName} WHERE ${where})`).join(' UNION ALL ');
2115
- const sql = `INSERT INTO
2116
- ${tableName}
2117
- (${columnNames})
2118
- ${selects};`;
2495
+ const columnNames = iterare<string>(finalColumns).map(i => this[_fields]![i]?.C2()).join(',');
2496
+ const sql = format(`INSERT INTO
2497
+ ${tableName}
2498
+ (${columnNames})
2499
+ ${questMarks.join(' UNION ALL ')};`);
2119
2500
  sqls.push({ sql, params });
2501
+ break;
2120
2502
  }
2121
2503
  case InsertMode.Replace: {
2122
2504
  const finalColumns = new Set<string>();
2123
- const params = datas
2124
- .map(data => this[_transformer]!(data, { ...option, finalColumns, def: true }))
2125
- .flatMap(data => {
2126
- const result: any[] = [];
2505
+ const params: any[] = [];
2506
+ const questMarks = datas
2507
+ .map(data => this[_transformer]!(data, { ...option, finalColumns, insert: true }))
2508
+ .map(data => {
2127
2509
  const questMark = new Array<string>();
2128
2510
  for (const column of finalColumns) {
2129
- questMark.push('?');
2130
- result.push(
2131
- data.hasOwnProperty(column)
2132
- ? data[column]
2133
- : this[_def] && this[_def].hasOwnProperty(column)
2134
- ? this[_def][column]
2135
- : null
2136
- );
2511
+ const V = data.hasOwnProperty(column)
2512
+ ? data[column]
2513
+ : this[_def] && this[_def].hasOwnProperty(column)
2514
+ ? this[_def][column]
2515
+ : null;
2516
+ if (V === null) {
2517
+ const field = this[_fields]![column];
2518
+ if (field?.uuid) {
2519
+ questMark.push('UUID()');
2520
+ } else if (field?.uuidShort && this[_dbType] === DBType.Mysql) {
2521
+ questMark.push('UUID_SHORT()');
2522
+ } else {
2523
+ questMark.push('?');
2524
+ params.push(V);
2525
+ }
2526
+ } else {
2527
+ questMark.push('?');
2528
+ params.push(V);
2529
+ }
2137
2530
  }
2138
- return result;
2531
+ return `(${questMark.join(',')})`;
2139
2532
  });
2140
- const quests = new Array<string>(finalColumns.size).fill('?').join(',');
2141
- const columnNames = iterare<string>(finalColumns).map(i => this[_fields]![i]?.esName).join(',');
2142
- const questMarks = iterare<string>(new Array<string>(datas.length)).map(() => `(${quests})`).join(',');
2143
- const sql = `
2533
+ const columnNames = iterare(finalColumns).map(i => this[_fields]![i]?.C2()).join(',');
2534
+ const sql = format(`
2144
2535
  ${this[_dbType] === DBType.Mysql ? '' : 'INSERT OR'} REPLACE INTO
2145
2536
  ${tableName}
2146
2537
  (${columnNames})
2147
2538
  VALUES ${questMarks};
2148
- `;
2539
+ `);
2149
2540
  sqls.push({ sql, params });
2541
+ break;
2150
2542
  }
2151
2543
  case InsertMode.Insert: {
2152
2544
  const finalColumns = new Set<string>();
2153
- const params = datas
2154
- .map(data => this[_transformer]!(data, { ...option, finalColumns, def: true }))
2155
- .flatMap(data => {
2156
- const result: any[] = [];
2545
+ const params: any[] = [];
2546
+ const questMarks = datas
2547
+ .map(data => this[_transformer]!(data, { ...option, finalColumns, insert: true }))
2548
+ .map(data => {
2157
2549
  const questMark = new Array<string>();
2158
2550
  for (const column of finalColumns) {
2159
- questMark.push('?');
2160
- result.push(
2161
- data.hasOwnProperty(column)
2162
- ? data[column]
2163
- : this[_def] && this[_def].hasOwnProperty(column)
2164
- ? this[_def][column]
2165
- : null
2166
- );
2551
+ const V = data.hasOwnProperty(column)
2552
+ ? data[column]
2553
+ : this[_def] && this[_def].hasOwnProperty(column)
2554
+ ? this[_def][column]
2555
+ : null;
2556
+ if (V === null) {
2557
+ const field = this[_fields]![column];
2558
+ if (field?.uuid) {
2559
+ questMark.push('UUID()');
2560
+ } else if (field?.uuidShort && this[_dbType] === DBType.Mysql) {
2561
+ questMark.push('UUID_SHORT()');
2562
+ } else {
2563
+ questMark.push('?');
2564
+ params.push(V);
2565
+ }
2566
+ } else {
2567
+ questMark.push('?');
2568
+ params.push(V);
2569
+ }
2167
2570
  }
2168
- return result;
2571
+ return `(${questMark.join(',')})`;
2169
2572
  });
2170
- const quests = new Array<string>(finalColumns.size).fill('?').join(',');
2171
- const columnNames = iterare(finalColumns).map(i => this[_fields]![i]?.esName).join(',');
2172
- const questMarks = iterare(new Array<string>(datas.length)).map(() => `(${quests})`).join(',');
2173
- const sql = `
2573
+ const columnNames = iterare(finalColumns).map(i => this[_fields]![i]?.C2()).join(',');
2574
+ const sql = format(`
2174
2575
  INSERT INTO
2175
2576
  ${tableName}
2176
2577
  (${columnNames})
2177
2578
  VALUES ${questMarks};
2178
- `;
2579
+ `);
2580
+
2179
2581
  sqls.push({ sql, params });
2582
+ break;
2180
2583
  }
2181
2584
  case InsertMode.InsertWithTempTable: {
2182
2585
  const tableTemp = `${option?.tableName}_${Math.random()}`.replace(/\./, '');
2183
2586
  const tableTempESC = Sqlstring.escapeId(tableTemp);
2184
2587
  sqls.push({ sql: `DROP TABLE IF EXISTS ${tableTempESC};` });
2185
2588
  const finalColumns = new Set<string>();
2186
- const params = datas
2187
- .map(data => this[_transformer]!(data, { ...option, finalColumns, def: true }))
2188
- .flatMap(data => {
2189
- const result: any[] = [];
2589
+ const params: any[] = [];
2590
+ const questMarks = datas
2591
+ .map(data => this[_transformer]!(data, { ...option, finalColumns, insert: true }))
2592
+ .map(data => {
2190
2593
  const questMark = new Array<string>();
2191
2594
  for (const column of finalColumns) {
2192
- questMark.push('?');
2193
- result.push(
2194
- data.hasOwnProperty(column)
2195
- ? data[column]
2196
- : this[_def] && this[_def].hasOwnProperty(column)
2197
- ? this[_def][column]
2198
- : null
2199
- );
2200
- }
2201
- return result;
2595
+ const V = data.hasOwnProperty(column)
2596
+ ? data[column]
2597
+ : this[_def] && this[_def].hasOwnProperty(column)
2598
+ ? this[_def][column]
2599
+ : null;
2600
+ if (V === null) {
2601
+ const field = this[_fields]![column];
2602
+ if (field?.uuid) {
2603
+ questMark.push('UUID()');
2604
+ } else if (field?.uuidShort && this[_dbType] === DBType.Mysql) {
2605
+ questMark.push('UUID_SHORT()');
2606
+ } else {
2607
+ questMark.push('?');
2608
+ params.push(V);
2609
+ }
2610
+ } else {
2611
+ questMark.push('?');
2612
+ params.push(V);
2613
+ }
2614
+ }
2615
+ return `(${questMark.join(',')})`
2202
2616
  });
2203
2617
  const _sqls = this._createTable({ tableName: tableTemp, temp: true, columns: Array.from(finalColumns) })!;
2204
2618
  sqls.push(..._sqls);
2205
-
2206
- const quests = new Array<string>(finalColumns.size).fill('?').join(',');
2207
- const columnNames = iterare(finalColumns).map(i => this[_fields]![i]?.esName).join(',');
2208
- const questMarks = iterare(new Array<string>(datas.length)).map(() => `(${quests})`).join(',');
2619
+ const columnNames = iterare(finalColumns).map(i => this[_fields]![i]?.C2()).join(',');
2209
2620
  sqls.push({
2210
- sql: `
2621
+ sql: format(`
2211
2622
  INSERT INTO
2212
2623
  ${tableTemp}
2213
2624
  (${columnNames})
2214
2625
  VALUES ${questMarks};
2215
- `, params
2626
+ `), params
2216
2627
  });
2217
2628
  sqls.push({
2218
- sql: `INSERT INTO ${Sqlstring.escapeId(option.tableName)} (${columnNames})
2219
- SELECT ${columnNames} FROM ${tableTemp};`
2629
+ sql: format(`INSERT INTO ${Sqlstring.escapeId(option.tableName)} (${columnNames})
2630
+ SELECT ${columnNames} FROM ${tableTemp};`)
2220
2631
  });
2221
2632
  sqls.push({ sql: `DROP TABLE IF EXISTS ${tableTempESC};` });
2633
+ break;
2222
2634
  }
2223
2635
  }
2224
2636
  return sqls;
@@ -2244,18 +2656,19 @@ export class SqlService<T extends object> {
2244
2656
  2. `insertIfNotExists`: 通过主键或者existConditionOtherThanIds字段判断数据是否存在,不存在才插入,存在则不执行
2245
2657
  3. `replace`: 只支持用主键判断, 存在更新, 不存在插入
2246
2658
  11. `existConditionOtherThanIds`: insertIfNotExists时判断同一记录的字段名称,默认情况下按照ID判断,设置existConditionOtherThanIds后,不用id
2659
+ 12. `replaceWithDef` replace时,是否带入默认值? 默认true
2247
2660
  ### 返回值是最后一次插入的主键ID,对于自增ID表适用
2248
2661
  1. 如果主键是自增批量操作,且期望返回所有记录的ID,那么需要设置 `option 中的 every = true`,此时效率降低
2249
2662
  * @param {{[P in keyof T]?: T[P]}} data
2250
2663
  * @param {MethodOption} [option]
2251
2664
  * @memberof SqlServer
2252
2665
  */
2253
- insert(option: MethodOption & { data: Partial<T>; sync?: SyncMode.Async; mode?: InsertMode; existConditionOtherThanIds?: (keyof T)[]; every?: boolean; temp?: boolean; skipUndefined?: boolean; skipNull?: boolean; skipEmptyString?: boolean; maxDeal?: number; }): Promise<bigint>;
2254
- insert(option: MethodOption & { data: Partial<T>[]; sync?: SyncMode.Async; mode?: InsertMode; existConditionOtherThanIds?: (keyof T)[]; every?: boolean; temp?: boolean; skipUndefined?: boolean; skipNull?: boolean; skipEmptyString?: boolean; maxDeal?: number; }): Promise<bigint[]>;
2255
- insert(option: MethodOption & { data: Partial<T>; sync: SyncMode.Sync; mode?: InsertMode; existConditionOtherThanIds?: (keyof T)[]; every?: boolean; temp?: boolean; skipUndefined?: boolean; skipNull?: boolean; skipEmptyString?: boolean; maxDeal?: number; }): bigint;
2256
- insert(option: MethodOption & { data: Partial<T>[]; sync: SyncMode.Sync; mode?: InsertMode; existConditionOtherThanIds?: (keyof T)[]; every?: boolean; temp?: boolean; skipUndefined?: boolean; skipNull?: boolean; skipEmptyString?: boolean; maxDeal?: number; }): bigint[];
2666
+ insert(option: MethodOption & { data: Partial<T>; sync?: SyncMode.Async; mode?: InsertMode; existConditionOtherThanIds?: (keyof T)[]; every?: boolean; temp?: boolean; skipUndefined?: boolean; skipNull?: boolean; skipEmptyString?: boolean; maxDeal?: number; replaceWithDef?: boolean; }): Promise<bigint>;
2667
+ insert(option: MethodOption & { data: Partial<T>[]; sync?: SyncMode.Async; mode?: InsertMode; existConditionOtherThanIds?: (keyof T)[]; every?: boolean; temp?: boolean; skipUndefined?: boolean; skipNull?: boolean; skipEmptyString?: boolean; maxDeal?: number; replaceWithDef?: boolean; }): Promise<bigint[]>;
2668
+ insert(option: MethodOption & { data: Partial<T>; sync: SyncMode.Sync; mode?: InsertMode; existConditionOtherThanIds?: (keyof T)[]; every?: boolean; temp?: boolean; skipUndefined?: boolean; skipNull?: boolean; skipEmptyString?: boolean; maxDeal?: number; replaceWithDef?: boolean; }): bigint;
2669
+ insert(option: MethodOption & { data: Partial<T>[]; sync: SyncMode.Sync; mode?: InsertMode; existConditionOtherThanIds?: (keyof T)[]; every?: boolean; temp?: boolean; skipUndefined?: boolean; skipNull?: boolean; skipEmptyString?: boolean; maxDeal?: number; replaceWithDef?: boolean; }): bigint[];
2257
2670
  @P<T>()
2258
- insert(option: MethodOption & { data: Partial<T> | Array<Partial<T>>; sync?: SyncMode; mode?: InsertMode; existConditionOtherThanIds?: (keyof T)[]; every?: boolean; temp?: boolean; skipUndefined?: boolean; skipNull?: boolean; skipEmptyString?: boolean; maxDeal?: number; }): bigint | bigint[] | Promise<bigint> | Promise<bigint[]> {
2671
+ insert(option: MethodOption & { data: Partial<T> | Array<Partial<T>>; sync?: SyncMode; mode?: InsertMode; existConditionOtherThanIds?: (keyof T)[]; every?: boolean; temp?: boolean; skipUndefined?: boolean; skipNull?: boolean; skipEmptyString?: boolean; maxDeal?: number; replaceWithDef?: boolean; }): bigint | bigint[] | Promise<bigint> | Promise<bigint[]> {
2259
2672
  option.mode ??= InsertMode.Insert;
2260
2673
  const isArray = option.data instanceof Array;
2261
2674
  const datas = option.data instanceof Array ? option.data : [option.data];
@@ -2278,7 +2691,7 @@ export class SqlService<T extends object> {
2278
2691
  if (isArray) return result;
2279
2692
  else return result[0]!;
2280
2693
  };
2281
- if (option?.conn?.[_inTransaction] === true) {
2694
+ if (this[_dbType] === DBType.SqliteRemote || option?.conn?.[_inTransaction] === true) {
2282
2695
  return fn();
2283
2696
  } else {
2284
2697
  return option?.dao?.transaction(SyncMode.Sync, fn, option?.conn)!;
@@ -2303,11 +2716,15 @@ export class SqlService<T extends object> {
2303
2716
  return result;
2304
2717
  }, option?.conn);
2305
2718
  };
2306
- return new Promise<bigint[]>(async (resolve) => {
2307
- if (option?.conn?.[_inTransaction] === true) {
2308
- resolve((await fn())!);
2309
- } else {
2310
- await option?.dao?.transaction(SyncMode.Async, async () => resolve((await fn())!), option?.conn);
2719
+ return new Promise<bigint[]>(async (resolve, reject) => {
2720
+ try {
2721
+ if (this[_dbType] === DBType.SqliteRemote || option?.conn?.[_inTransaction] === true) {
2722
+ resolve((await fn())!);
2723
+ } else {
2724
+ await option?.dao?.transaction(SyncMode.Async, async () => resolve((await fn())!), option?.conn);
2725
+ }
2726
+ } catch (error) {
2727
+ reject(error);
2311
2728
  }
2312
2729
  });
2313
2730
  } else {
@@ -2328,11 +2745,15 @@ export class SqlService<T extends object> {
2328
2745
  );
2329
2746
  return result[0]!;
2330
2747
  };
2331
- return new Promise<bigint>(async (resolve) => {
2332
- if (option?.conn?.[_inTransaction] === true) {
2333
- resolve((await fn())!);
2334
- } else {
2335
- await option?.dao?.transaction(SyncMode.Async, async () => resolve((await fn())!), option?.conn);
2748
+ return new Promise<bigint>(async (resolve, reject) => {
2749
+ try {
2750
+ if (this[_dbType] === DBType.SqliteRemote || option?.conn?.[_inTransaction] === true) {
2751
+ resolve((await fn())!);
2752
+ } else {
2753
+ await option?.dao?.transaction(SyncMode.Async, async () => resolve((await fn())!), option?.conn);
2754
+ }
2755
+ } catch (error) {
2756
+ reject(error);
2336
2757
  }
2337
2758
  });
2338
2759
  }
@@ -2341,7 +2762,7 @@ export class SqlService<T extends object> {
2341
2762
  private _update(datas: Array<Partial<T>>, option: MethodOption): { sql: string; params?: any[] }[] {
2342
2763
  const sqls: { sql: string; params?: any[] }[] = [];
2343
2764
  const tableName = Sqlstring.escapeId(option?.tableName);
2344
- const where = `WHEN ${iterare(this[_ids]!).map(c => `${this[_fields]![c]?.esName} = ?`).join(' AND ')} THEN ?`;
2765
+ const where = `WHEN ${iterare(this[_ids]!).map(c => `${this[_fields]![c]?.C2()} = ?`).join(' AND ')} THEN ?`;
2345
2766
  const columnMaps: Record<string, {
2346
2767
  where: string[];
2347
2768
  params: any[];
@@ -2366,13 +2787,13 @@ export class SqlService<T extends object> {
2366
2787
  }
2367
2788
  );
2368
2789
  }
2369
- const sql = `UPDATE ${tableName} SET ${iterare(this[_columnsNoId]!)
2790
+ const sql = format(`UPDATE ${tableName} SET ${iterare(this[_columnsNoId]!)
2370
2791
  .filter(K => columnMaps[K]!.where.length > 0)
2371
2792
  .map(K => {
2372
2793
  params.push(...columnMaps[K]!.params);
2373
- return `${this[_fields]![K]?.esName} = CASE ${columnMaps[K]!.where.join(' ')} ELSE ${this[_fields]![K]?.esName} END`
2794
+ return `${this[_fields]![K]?.C2()} = CASE ${columnMaps[K]!.where.join(' ')} ELSE ${this[_fields]![K]?.C2()} END`
2374
2795
  })
2375
- .join(',')};`
2796
+ .join(',')};`);
2376
2797
  sqls.push({ sql, params });
2377
2798
  return sqls;
2378
2799
  }
@@ -2418,7 +2839,7 @@ export class SqlService<T extends object> {
2418
2839
  );
2419
2840
  return result.reduce((a, b) => a + b);
2420
2841
  };
2421
- if (option?.conn?.[_inTransaction] === true) {
2842
+ if (this[_dbType] === DBType.SqliteRemote || option?.conn?.[_inTransaction] === true) {
2422
2843
  return fn();
2423
2844
  } else {
2424
2845
  return option?.dao?.transaction(SyncMode.Sync, fn, option?.conn)!;
@@ -2441,11 +2862,15 @@ export class SqlService<T extends object> {
2441
2862
  );
2442
2863
  return result.reduce((a, b) => a + b);
2443
2864
  };
2444
- return new Promise<number>(async (resolve) => {
2445
- if (option?.conn?.[_inTransaction] === true) {
2446
- resolve((await fn())!);
2447
- } else {
2448
- await option?.dao?.transaction(SyncMode.Async, async () => resolve((await fn())!), option?.conn);
2865
+ return new Promise<number>(async (resolve, reject) => {
2866
+ try {
2867
+ if (this[_dbType] === DBType.SqliteRemote || option?.conn?.[_inTransaction] === true) {
2868
+ resolve((await fn())!);
2869
+ } else {
2870
+ await option?.dao?.transaction(SyncMode.Async, async () => resolve((await fn())!), option?.conn);
2871
+ }
2872
+ } catch (error) {
2873
+ reject(error);
2449
2874
  }
2450
2875
  });
2451
2876
  }
@@ -2507,19 +2932,20 @@ export class SqlService<T extends object> {
2507
2932
  return `(
2508
2933
  ${Object.entries(where).map(([K, V]) => {
2509
2934
  params.push(V);
2510
- return `${K} = ?`;
2935
+ return `${this[_fields]![K]?.C2()} = ?`;
2511
2936
  }).join(' AND ')}
2512
2937
  )`;
2513
2938
  }).join(' OR ');
2514
2939
  if (this[_stateFileName] !== undefined && option.forceDelete !== true) {
2940
+ params.unshift(this[_deleteState]);
2515
2941
  sqls.push({
2516
- sql: `
2517
- UPDATE ${tableNameESC} SET ${this[_fields]![this[_stateFileName]]?.esName} = ${Sqlstring.escape(this[_deleteState])}
2942
+ sql: format(`
2943
+ UPDATE ${tableNameESC} SET ${this[_fields]![this[_stateFileName]]?.C2()} = ?
2518
2944
  WHERE ${whereSql};
2519
- `, params
2945
+ `), params
2520
2946
  });
2521
2947
  } else {
2522
- sqls.push({ sql: `DELETE FROM ${tableNameESC} WHERE ${whereSql};`, params });
2948
+ sqls.push({ sql: format(`DELETE FROM ${tableNameESC} WHERE ${whereSql};`), params });
2523
2949
  }
2524
2950
  } else {
2525
2951
  sqls.push({ sql: `DROP TABLE IF EXISTS ${tableTempESC};` });
@@ -2530,26 +2956,30 @@ export class SqlService<T extends object> {
2530
2956
  case DBType.Mysql: {
2531
2957
  if (this[_stateFileName] !== undefined && option.forceDelete !== true) {
2532
2958
  sqls.push({
2533
- sql: `UPDATE ${tableNameESC} a INNER JOIN ${tableTempESC} b ON ${delWhere.map(K => `a.${this[_fields]![K]?.esName} = b.${this[_fields]![K]?.esName}`).join(' AND ')}
2534
- SET a.${this[_fields]![this[_stateFileName]]?.esName} = ${Sqlstring.escape(this[_deleteState])};`
2959
+ sql: format(`UPDATE ${tableNameESC} a INNER JOIN ${tableTempESC} b ON ${delWhere.map(K => `a.${this[_fields]![K]?.C2()} = b.${this[_fields]![K]?.C2()}`).join(' AND ')}
2960
+ SET a.${this[_fields]![this[_stateFileName]]?.C2()} = ?;`),
2961
+ params: [this[_deleteState]]
2535
2962
  });
2536
2963
  } else {
2537
2964
  sqls.push({
2538
- 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 ')};`
2965
+ sql: format(`DELETE a.* FROM ${tableNameESC} a INNER JOIN ${tableTempESC} b ON ${delWhere.map(K => `a.${this[_fields]![K]?.C2()} = b.${this[_fields]![K]?.C2()}`).join(' AND ')};`)
2539
2966
  });
2540
2967
  }
2968
+ break;
2541
2969
  }
2542
2970
  case DBType.Sqlite:
2543
2971
  case DBType.SqliteRemote: {
2544
- const columnNames = iterare(delWhere).map(K => this[_fields]![K]?.esName).join(',');
2972
+ const columnNames = iterare(delWhere).map(K => this[_fields]![K]?.C2()).join(',');
2545
2973
  if (this[_stateFileName] !== undefined && option.forceDelete !== true) {
2546
2974
  sqls.push({
2547
- sql: `UPDATE ${tableNameESC} SET ${this[_fields]![this[_stateFileName]]?.esName} = ${Sqlstring.escape(this[_deleteState])}
2548
- WHERE (${columnNames}) IN (SELECT ${columnNames} FROM ${tableTempESC});`
2975
+ sql: format(`UPDATE ${tableNameESC} SET ${this[_fields]![this[_stateFileName]]?.C2()} = ?
2976
+ WHERE (${columnNames}) IN (SELECT ${columnNames} FROM ${tableTempESC});`),
2977
+ params: [this[_deleteState]]
2549
2978
  });
2550
2979
  } else {
2551
- sqls.push({ sql: `DELETE FROM ${tableNameESC} WHERE (${columnNames}) IN (SELECT ${columnNames} FROM ${tableTempESC});` });
2980
+ sqls.push({ sql: format(`DELETE FROM ${tableNameESC} WHERE (${columnNames}) IN (SELECT ${columnNames} FROM ${tableTempESC});`) });
2552
2981
  }
2982
+ break;
2553
2983
  }
2554
2984
  }
2555
2985
  sqls.push({ sql: `DROP TABLE IF EXISTS ${tableTempESC};` });
@@ -2564,7 +2994,7 @@ export class SqlService<T extends object> {
2564
2994
  }
2565
2995
  return result;
2566
2996
  };
2567
- if (option?.conn?.[_inTransaction] === true) {
2997
+ if (this[_dbType] === DBType.SqliteRemote || option?.conn?.[_inTransaction] === true) {
2568
2998
  return fn();
2569
2999
  } else {
2570
3000
  return option?.dao?.transaction(SyncMode.Sync, fn, option?.conn)!;
@@ -2578,11 +3008,15 @@ export class SqlService<T extends object> {
2578
3008
  }
2579
3009
  return result;
2580
3010
  };
2581
- return new Promise<number>(async (resolve) => {
2582
- if (option?.conn?.[_inTransaction] === true) {
2583
- resolve((await fn())!);
2584
- } else {
2585
- await option?.dao?.transaction(SyncMode.Async, async () => resolve((await fn())!), option?.conn);
3011
+ return new Promise<number>(async (resolve, reject) => {
3012
+ try {
3013
+ if (this[_dbType] === DBType.SqliteRemote || option?.conn?.[_inTransaction] === true) {
3014
+ resolve((await fn())!);
3015
+ } else {
3016
+ await option?.dao?.transaction(SyncMode.Async, async () => resolve((await fn())!), option?.conn);
3017
+ }
3018
+ } catch (error) {
3019
+ reject(error);
2586
3020
  }
2587
3021
  });
2588
3022
  }
@@ -2604,6 +3038,9 @@ export class SqlService<T extends object> {
2604
3038
  case TemplateResult.Count: {
2605
3039
  return result[0].ct;
2606
3040
  }
3041
+ case TemplateResult.ManyList: {
3042
+ return new ArrayList(result[0]);
3043
+ }
2607
3044
  }
2608
3045
  }
2609
3046
  /**
@@ -2629,20 +3066,18 @@ export class SqlService<T extends object> {
2629
3066
  8. `dao`: 永远不需要传入该值
2630
3067
 
2631
3068
  */
2632
- template(option: MethodOption & { templateResult?: TemplateResult.AssertOne; id?: string | number | Array<string | number>; where?: Partial<T> | Array<Partial<T>>; mode?: SelectMode; error?: string; columns?: (keyof T)[]; }): Promise<T>;
2633
- template(option: MethodOption & { sync: SyncMode.Sync; templateResult?: TemplateResult.AssertOne; id?: string | number | Array<string | number>; where?: Partial<T> | Array<Partial<T>>; mode?: SelectMode; error?: string; columns?: (keyof T)[]; }): T;
2634
- template(option: MethodOption & { sync: SyncMode.Async; templateResult?: TemplateResult.AssertOne; id?: string | number | Array<string | number>; where?: Partial<T> | Array<Partial<T>>; mode?: SelectMode; error?: string; columns?: (keyof T)[]; }): Promise<T>;
2635
- template(option: MethodOption & { templateResult: TemplateResult.Count; id?: string | number | Array<string | number>; where?: Partial<T> | Array<Partial<T>>; mode?: SelectMode; error?: string; columns?: (keyof T)[]; }): Promise<number>;
2636
- template(option: MethodOption & { sync: SyncMode.Sync; templateResult: TemplateResult.Count; id?: string | number | Array<string | number>; where?: Partial<T> | Array<Partial<T>>; mode?: SelectMode; error?: string; columns?: (keyof T)[]; }): number;
2637
- template(option: MethodOption & { sync: SyncMode.Async; templateResult: TemplateResult.Count; id?: string | number | Array<string | number>; where?: Partial<T> | Array<Partial<T>>; mode?: SelectMode; error?: string; columns?: (keyof T)[]; }): Promise<number>;
2638
- template(option: MethodOption & { templateResult: TemplateResult.NotSureOne; id?: string | number | Array<string | number>; where?: Partial<T> | Array<Partial<T>>; mode?: SelectMode; error?: string; columns?: (keyof T)[]; }): Promise<T | null>;
2639
- template(option: MethodOption & { sync: SyncMode.Sync; templateResult: TemplateResult.NotSureOne; id?: string | number | Array<string | number>; where?: Partial<T> | Array<Partial<T>>; mode?: SelectMode; error?: string; columns?: (keyof T)[]; }): T | null;
2640
- template(option: MethodOption & { sync: SyncMode.Async; templateResult: TemplateResult.NotSureOne; id?: string | number | Array<string | number>; where?: Partial<T> | Array<Partial<T>>; mode?: SelectMode; error?: string; columns?: (keyof T)[]; }): Promise<T | null>;
2641
- template(option: MethodOption & { templateResult: TemplateResult.Many; id?: string | number | Array<string | number>; where?: Partial<T> | Array<Partial<T>>; mode?: SelectMode; error?: string; columns?: (keyof T)[]; }): Promise<T[]>;
2642
- template(option: MethodOption & { sync: SyncMode.Sync; templateResult: TemplateResult.Many; id?: string | number | Array<string | number>; where?: Partial<T> | Array<Partial<T>>; mode?: SelectMode; error?: string; columns?: (keyof T)[]; }): T[];
2643
- template(option: MethodOption & { sync: SyncMode.Async; templateResult: TemplateResult.Many; id?: string | number | Array<string | number>; where?: Partial<T> | Array<Partial<T>>; mode?: SelectMode; error?: string; columns?: (keyof T)[]; }): Promise<T[]>;
3069
+ template<L = T>(option: MethodOption & { sync: SyncMode.Sync; templateResult?: TemplateResult.AssertOne; id?: string | number | Array<string | number>; where?: Partial<L> | Array<Partial<L>>; skipUndefined?: boolean; skipNull?: boolean; skipEmptyString?: boolean; mode?: SelectMode; error?: string; columns?: (keyof L)[]; }): L;
3070
+ template<L = T>(option: MethodOption & { sync?: SyncMode.Async; templateResult?: TemplateResult.AssertOne; id?: string | number | Array<string | number>; where?: Partial<L> | Array<Partial<L>>; skipUndefined?: boolean; skipNull?: boolean; skipEmptyString?: boolean; mode?: SelectMode; error?: string; columns?: (keyof L)[]; }): Promise<L>;
3071
+ template<L = T>(option: MethodOption & { sync: SyncMode.Sync; templateResult: TemplateResult.Count; id?: string | number | Array<string | number>; where?: Partial<L> | Array<Partial<L>>; skipUndefined?: boolean; skipNull?: boolean; skipEmptyString?: boolean; mode?: SelectMode; error?: string; columns?: (keyof L)[]; }): number;
3072
+ template<L = T>(option: MethodOption & { sync?: SyncMode.Async; templateResult: TemplateResult.Count; id?: string | number | Array<string | number>; where?: Partial<L> | Array<Partial<L>>; skipUndefined?: boolean; skipNull?: boolean; skipEmptyString?: boolean; mode?: SelectMode; error?: string; columns?: (keyof L)[]; }): Promise<number>;
3073
+ template<L = T>(option: MethodOption & { sync: SyncMode.Sync; templateResult: TemplateResult.NotSureOne; id?: string | number | Array<string | number>; where?: Partial<L> | Array<Partial<L>>; skipUndefined?: boolean; skipNull?: boolean; skipEmptyString?: boolean; mode?: SelectMode; error?: string; columns?: (keyof L)[]; }): L | null;
3074
+ template<L = T>(option: MethodOption & { sync?: SyncMode.Async; templateResult: TemplateResult.NotSureOne; id?: string | number | Array<string | number>; where?: Partial<L> | Array<Partial<L>>; skipUndefined?: boolean; skipNull?: boolean; skipEmptyString?: boolean; mode?: SelectMode; error?: string; columns?: (keyof L)[]; }): Promise<L | null>;
3075
+ template<L = T>(option: MethodOption & { sync: SyncMode.Sync; templateResult: TemplateResult.Many; id?: string | number | Array<string | number>; where?: Partial<L> | Array<Partial<L>>; skipUndefined?: boolean; skipNull?: boolean; skipEmptyString?: boolean; mode?: SelectMode; error?: string; columns?: (keyof L)[]; }): L[];
3076
+ template<L = T>(option: MethodOption & { sync?: SyncMode.Async; templateResult: TemplateResult.Many; id?: string | number | Array<string | number>; where?: Partial<L> | Array<Partial<L>>; skipUndefined?: boolean; skipNull?: boolean; skipEmptyString?: boolean; mode?: SelectMode; error?: string; columns?: (keyof L)[]; }): Promise<L[]>;
3077
+ template<L = T>(option: MethodOption & { sync: SyncMode.Sync; templateResult: TemplateResult.ManyList; id?: string | number | Array<string | number>; where?: Partial<L> | Array<Partial<L>>; skipUndefined?: boolean; skipNull?: boolean; skipEmptyString?: boolean; mode?: SelectMode; error?: string; columns?: (keyof L)[]; }): ArrayList<L>;
3078
+ template<L = T>(option: MethodOption & { sync?: SyncMode.Async; templateResult: TemplateResult.ManyList; id?: string | number | Array<string | number>; where?: Partial<L> | Array<Partial<L>>; skipUndefined?: boolean; skipNull?: boolean; skipEmptyString?: boolean; mode?: SelectMode; error?: string; columns?: (keyof L)[]; }): Promise<ArrayList<L>>;
2644
3079
  @P<T>()
2645
- template(option: MethodOption & { sync?: SyncMode; templateResult?: TemplateResult; id?: string | number | Array<string | number>; where?: Partial<T> | Array<Partial<T>>; mode?: SelectMode; error?: string; columns?: (keyof T)[]; }): number | T | null | T[] | Promise<number | T | null | T[]> {
3080
+ template<L = T>(option: MethodOption & { sync?: SyncMode; templateResult?: TemplateResult; id?: string | number | Array<string | number>; where?: Partial<L> | Array<Partial<L>>; skipUndefined?: boolean; skipNull?: boolean; skipEmptyString?: boolean; mode?: SelectMode; error?: string; columns?: (keyof L)[]; }): number | L | null | L[] | ArrayList<L> | Promise<number | L | null | L[] | ArrayList<L>> {
2646
3081
  Throw.if(!!this[_ids] && this[_ids].length > 1 && !option.where, 'muit id must set where!');
2647
3082
  Throw.if((!this[_ids] || this[_ids].length === 0) && !option.where, 'if not set id on class, must set where!');
2648
3083
  Throw.if(!option.id && !option.where, 'not found id or where!');
@@ -2659,30 +3094,30 @@ export class SqlService<T extends object> {
2659
3094
  if (option.id) {
2660
3095
  const idName = this[_ids]![0]!;
2661
3096
  const ids = option.id instanceof Array ? option.id : [option.id];
2662
- option.where = ids.map(i => ({ [idName]: i })) as Array<Partial<T>>;
3097
+ option.where = ids.map(i => ({ [idName]: i })) as Array<Partial<L>>;
2663
3098
  }
2664
- const columns = option.templateResult === TemplateResult.Count ? 'COUNT(1) ct' : iterare((option.columns as unknown as string[] ?? this[_columns])!).map((K: any) => `a.${this[_fields]![K]?.esName}`).join(',');
3099
+ const columns = option.templateResult === TemplateResult.Count ? 'COUNT(1) ct' : iterare((option.columns as unknown as string[] ?? this[_columns])!).map((K: any) => `a.${this[_fields]![K]?.C3()}`).join(',');
2665
3100
  const wheres = option.where instanceof Array ? option.where : [option.where!];
2666
3101
  const sqls: { sql: string; params?: any[] }[] = [];
2667
3102
  let resultIndex = -1;
2668
3103
  if (option.mode === SelectMode.Common) {
2669
3104
  const params = new Array<any>();
2670
- const whereSql = iterare(wheres).map(where => {
3105
+ const whereSql = format(iterare(wheres).map(where => this[_transformer]!(where, option)).map(where => {
2671
3106
  return `SELECT ${columns} FROM ${tableNameESC} a WHERE
2672
3107
  ${Object.entries(where).map(([K, V]) => {
2673
3108
  params.push(V);
2674
- return `${K} = ?`;
3109
+ return `${this[_fields]![K]?.C2()} = ?`;
2675
3110
  }).join(' AND ')}`;
2676
- }).join(' UNION ALL ');
3111
+ }).join(' UNION ALL '));
2677
3112
  sqls.push({ sql: whereSql, params });
2678
3113
  resultIndex = 0;
2679
3114
  } else {
2680
3115
  sqls.push({ sql: `DROP TABLE IF EXISTS ${tableTempESC};` });
2681
3116
  const delWhere = Object.keys(wheres[0] as unknown as any);
2682
- const _sqls = this._createTable({ tableName: tableTemp, temp: true, columns: delWhere, data: wheres, index: 'all', id: 'none' })!;
3117
+ const _sqls = this._createTable<L>({ tableName: tableTemp, temp: true, columns: delWhere, data: wheres, index: 'all', id: 'none' })!;
2683
3118
  sqls.push(..._sqls);
2684
3119
  resultIndex = sqls.length;
2685
- 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 ')};` });
3120
+ sqls.push({ sql: format(`SELECT ${columns} FROM ${tableNameESC} a INNER JOIN ${tableTempESC} b ON ${delWhere.map(K => `a.${this[_fields]![K]?.C2()} = b.${this[_fields]![K]?.C2()}`).join(' AND ')};`) });
2686
3121
  sqls.push({ sql: `DROP TABLE IF EXISTS ${tableTempESC};` });
2687
3122
  }
2688
3123
 
@@ -2697,112 +3132,113 @@ export class SqlService<T extends object> {
2697
3132
  }
2698
3133
  return this._template(option.templateResult, result, option.error);
2699
3134
  } else {
2700
- return new Promise<T | null | T[]>(async (resolve) => {
2701
- let result: any;
2702
- for (let i = 0; i < sqls.length; i++) {
2703
- if (i === resultIndex) {
2704
- result = await option!.conn!.query(SyncMode.Async, sqls[i]?.sql, sqls[i]?.params);
2705
- } else {
2706
- await option!.conn!.execute(SyncMode.Async, sqls[i]?.sql, sqls[i]?.params);
3135
+ return new Promise<L | null | L[]>(async (resolve, reject) => {
3136
+ try {
3137
+ let result: any;
3138
+ for (let i = 0; i < sqls.length; i++) {
3139
+ if (i === resultIndex) {
3140
+ result = await option!.conn!.query(SyncMode.Async, sqls[i]?.sql, sqls[i]?.params);
3141
+ } else {
3142
+ await option!.conn!.execute(SyncMode.Async, sqls[i]?.sql, sqls[i]?.params);
3143
+ }
2707
3144
  }
3145
+ resolve(this._template(option.templateResult!, result, option.error));
3146
+ } catch (error) {
3147
+ reject(error);
2708
3148
  }
2709
- resolve(this._template(option.templateResult!, result, option.error));
2710
3149
  });
2711
3150
  }
2712
3151
  }
2713
3152
 
2714
- private _select<L = T>(templateResult: SelectResult, result: any, def: L | null, errorMsg?: string, multiple?: boolean) {
2715
- if (multiple === true) {
2716
- switch (templateResult) {
2717
- case SelectResult.One_Row_One_Column_NotSure: {
2718
- try {
2719
- return result.map((r: any) => Object.values(r)[0] as L);
2720
- } catch (error) {
2721
- }
2722
- }
2723
- case SelectResult.One_Row_One_Column_Assert: {
2724
- try {
2725
- return iterare(result).map((r: any) => Object.values(r)[0] as L).filter((r: L) => r !== null).toArray();
2726
- } catch (error) {
2727
- }
2728
- }
2729
- case SelectResult.One_Row_Many_Column_NotSure: {
2730
- try {
2731
- return result.map((r: any) => r[0] as L);
2732
- } catch (error) {
2733
- }
2734
- }
2735
- case SelectResult.One_Row_Many_Column_Assert: {
2736
- try {
2737
- return iterare(result).map((r: any) => r[0] as L).filter((r: L) => r !== null).toArray();
2738
- } catch (error) {
2739
- }
2740
- }
2741
- case SelectResult.Many_Row_One_Column: {
2742
- try {
2743
- return result.map((rx: any) => rx.map((r: any) => Object.values(r)[0] as L));
2744
- } catch (error) {
2745
- }
2746
- }
2747
- case SelectResult.Many_Row_Many_Column: {
2748
- return result as L[];
3153
+
3154
+ private _select<L = T>(templateResult: SelectResult, result: any, def: L | null, errorMsg?: string, hump?: boolean, mapper?: string | SqlMapper, mapperIfUndefined?: MapperIfUndefined) {
3155
+ switch (templateResult) {
3156
+ case SelectResult.R_C_NotSure: {
3157
+ try {
3158
+ return Object.values(result[0])[0] as L;
3159
+ } catch (error) {
3160
+ return def;
2749
3161
  }
2750
3162
  }
2751
- } else {
2752
- switch (templateResult) {
2753
- case SelectResult.One_Row_One_Column_NotSure: {
2754
- try {
2755
- return Object.values(result[0])[0] as L;
2756
- } catch (error) {
2757
- return def;
2758
- }
2759
- }
2760
- case SelectResult.One_Row_One_Column_Assert: {
2761
- try {
2762
- return Object.values(result[0])[0] as L;
2763
- } catch (error) {
2764
- if (def !== undefined) return def;
2765
- Throw.now(errorMsg ?? 'not found data!');
2766
- }
3163
+ case SelectResult.R_C_Assert: {
3164
+ try {
3165
+ return Object.values(result[0])[0] as L;
3166
+ } catch (error) {
3167
+ if (def !== undefined) return def;
3168
+ Throw.now(errorMsg ?? 'not found data!');
2767
3169
  }
2768
- case SelectResult.One_Row_Many_Column_NotSure: {
3170
+ }
3171
+ case SelectResult.R_CS_NotSure: {
3172
+ if (mapper) {
3173
+ return flatData<L>({ data: result[0], mapper, mapperIfUndefined });
3174
+ } else if (hump === true || (hump === undefined && globalThis[_Hump] === true)) {
3175
+ return (C2P2(result[0]) as L) ?? null;
3176
+ } else {
2769
3177
  return (result[0] as L) ?? null;
2770
3178
  }
2771
- case SelectResult.One_Row_Many_Column_Assert: {
2772
- const data = result[0] as L;
2773
- Throw.if(data === null, errorMsg ?? 'not found data!');
3179
+
3180
+ }
3181
+ case SelectResult.R_CS_Assert: {
3182
+ const data = result[0] as L;
3183
+ Throw.if(data === null || data === undefined, errorMsg ?? 'not found data!');
3184
+ if (mapper) {
3185
+ return flatData<L>({ data, mapper, mapperIfUndefined });
3186
+ } else if (hump === true || (hump === undefined && globalThis[_Hump] === true)) {
3187
+ return C2P2(data as any) ?? null;
3188
+ } else {
2774
3189
  return data ?? null;
2775
3190
  }
2776
- case SelectResult.Many_Row_One_Column: {
2777
- try {
2778
- return result.map((r: any) => Object.values(r)[0] as L);
2779
- } catch (error) {
2780
- return def;
2781
- }
3191
+ }
3192
+ case SelectResult.RS_C: {
3193
+ try {
3194
+ return result.map((r: any) => Object.values(r)[0] as L);
3195
+ } catch (error) {
3196
+ return result as L[];
2782
3197
  }
2783
- case SelectResult.Many_Row_Many_Column: {
3198
+ }
3199
+ case SelectResult.RS_CS: {
3200
+ if (mapper) {
3201
+ return iterare(result).map((data: any) => flatData<L>({ data, mapper, mapperIfUndefined })).toArray();
3202
+ } else if (hump === true || (hump === undefined && globalThis[_Hump] === true)) {
3203
+ return iterare(result).map((r: any) => C2P2(r) as L).toArray();
3204
+ } else {
2784
3205
  return result as L[];
2785
3206
  }
2786
3207
  }
3208
+ case SelectResult.RS_C_List: {
3209
+ try {
3210
+ return new ArrayList<L>(result.map((r: any) => Object.values(r)[0] as L));
3211
+ } catch (error) {
3212
+ return new ArrayList<L>();
3213
+ }
3214
+ }
3215
+ case SelectResult.RS_CS_List: {
3216
+ if (mapper) {
3217
+ return new ArrayList<L>(iterare(result).map((data: any) => flatData<L>({ data, mapper, mapperIfUndefined })).toArray());
3218
+ } else if (hump === true || (hump === undefined && globalThis[_Hump] === true)) {
3219
+ return new ArrayList<L>(iterare(result).map((r: any) => C2P2(r) as L).toArray());
3220
+ } else {
3221
+ return new ArrayList<L>();
3222
+ }
3223
+ }
2787
3224
  }
2788
3225
  }
2789
3226
  /**
2790
3227
  # 自由查询
2791
3228
  0. `sync`: 同步(sqlite)或者异步(mysql、remote),影响返回值类型,默认`异步模式`
2792
- 1. `templateResult`: 返回值类型断言,三种
2793
- 1. One_Row_One_Column_Assert,
2794
- 2. One_Row_One_Column_NotSure,
2795
- 3. One_Row_Many_Column_Assert,
2796
- 4. One_Row_Many_Column_NotSure,
2797
- 5. Many_Row_One_Column,
2798
- 6. Many_Row_Many_Column[默认]
3229
+ 1. `templateResult`: 返回值类型断言,6种, R表示行,C表示列,带S表示复数
3230
+ 1. R_C_Assert,
3231
+ 2. R_C_NotSure,
3232
+ 3. R_CS_Assert,
3233
+ 4. R_CS_NotSure,
3234
+ 5. RS_C,
3235
+ 6. RS_C_List
3236
+ 7. RS_CS[默认]
3237
+ 8. RS_CS_List
2799
3238
  2. `sql` 或者 `sqlid`
2800
3239
  3. `params`
2801
3240
  4. `defValue`: One_Row_One_Column 时有效
2802
- 5. `multiple`: = true 时表示多重sql查询,且每个sql的结果都是相同的resultMode, 此时 `One_Row_One_Column` `Many_Row_One_Column` `One_Row_Many_Column` 将按多重数组解析,`Many_Row_Many_Column` 不变,此时需要自己手动指定返回类型.
2803
- 此时 `One_Row_One_Column` 将返回多个单值组成的数组: `[1, 'ok', 3]`
2804
- `One_Row_Many_Column` 将返回多个对象组成的数组: `[{ob1}, {ob2}, {ob3}]`
2805
- `Many_Row_One_Column` 将返回多个单值数组组成的数组: `[[1,2,3], ['a', 'b']]`
3241
+ 5. 禁止一次查询多个语句
2806
3242
  6. `dbName`: 默认使用service注解的`dbName`,可以在某个方法中覆盖
2807
3243
  7. `conn`: 仅在开启事务时需要主动传入,传入示例:
2808
3244
  ```
@@ -2811,38 +3247,66 @@ export class SqlService<T extends object> {
2811
3247
  });
2812
3248
  ```
2813
3249
  9. `dao`: 永远不需要传入该值
3250
+ 10. `hump`: 是否将列名改为驼峰写法?默认情况下按照全局配置
3251
+ 11. `mapper`: 列名-属性 映射工具,优先级高于hump
2814
3252
 
2815
3253
  */
2816
- select<L = T>(option: MethodOption & { sync?: SyncMode.Async; selectResult?: SelectResult.Many_Row_Many_Column | SelectResult.Many_Row_One_Column; sqlId?: string; sql?: string; params?: Record<string, any>; context?: any; isCount?: boolean; defValue?: L | null; multiple?: boolean; errorMsg?: string }): Promise<L[]>;
2817
- select<L = T>(option: MethodOption & { sync?: SyncMode.Async; selectResult: SelectResult.One_Row_Many_Column_Assert | SelectResult.One_Row_One_Column_Assert; sqlId?: string; sql?: string; params?: Record<string, any>; context?: any; isCount?: boolean; defValue?: L | null; multiple?: boolean; errorMsg?: string; }): Promise<L>;
2818
- select<L = T>(option: MethodOption & { sync?: SyncMode.Async; selectResult: SelectResult.One_Row_Many_Column_NotSure | SelectResult.One_Row_One_Column_NotSure; sqlId?: string; sql?: string; params?: Record<string, any>; context?: any; isCount?: boolean; defValue?: L | null; multiple?: boolean; errorMsg?: string }): Promise<L | null>;
2819
- select<L = T>(option: MethodOption & { sync: SyncMode.Sync; selectResult?: SelectResult.Many_Row_Many_Column | SelectResult.Many_Row_One_Column; sqlId?: string; sql?: string; params?: Record<string, any>; context?: any; isCount?: boolean; defValue?: L | null; multiple?: boolean; errorMsg?: string }): L[];
2820
- select<L = T>(option: MethodOption & { sync: SyncMode.Sync; selectResult: SelectResult.One_Row_Many_Column_Assert | SelectResult.One_Row_One_Column_Assert; sqlId?: string; sql?: string; params?: Record<string, any>; context?: any; isCount?: boolean; defValue?: L | null; multiple?: boolean; errorMsg?: string; }): L;
2821
- select<L = T>(option: MethodOption & { sync: SyncMode.Sync; selectResult: SelectResult.One_Row_Many_Column_NotSure | SelectResult.One_Row_One_Column_NotSure; sqlId?: string; sql?: string; params?: Record<string, any>; context?: any; isCount?: boolean; defValue?: L | null; multiple?: boolean; errorMsg?: string }): L | null;
3254
+ select<L = T>(option: MethodOption & { sync?: SyncMode.Async; selectResult?: SelectResult.RS_CS | SelectResult.RS_C; sqlId?: string; sql?: string; params?: Record<string, any>; context?: any; isCount?: boolean; defValue?: L | null; errorMsg?: string; hump?: boolean; mapper?: string | SqlMapper; mapperIfUndefined?: MapperIfUndefined; }): Promise<L[]>;
3255
+ select<L = T>(option: MethodOption & { sync?: SyncMode.Async; selectResult: SelectResult.RS_CS_List | SelectResult.RS_C_List; sqlId?: string; sql?: string; params?: Record<string, any>; context?: any; isCount?: boolean; defValue?: L | null; errorMsg?: string; hump?: boolean; mapper?: string | SqlMapper; mapperIfUndefined?: MapperIfUndefined; }): Promise<ArrayList<L>>;
3256
+ select<L = T>(option: MethodOption & { sync?: SyncMode.Async; selectResult: SelectResult.R_CS_Assert | SelectResult.R_C_Assert; sqlId?: string; sql?: string; params?: Record<string, any>; context?: any; isCount?: boolean; defValue?: L | null; errorMsg?: string; hump?: boolean; mapper?: string | SqlMapper; mapperIfUndefined?: MapperIfUndefined; }): Promise<L>;
3257
+ select<L = T>(option: MethodOption & { sync?: SyncMode.Async; selectResult: SelectResult.R_CS_NotSure | SelectResult.R_C_NotSure; sqlId?: string; sql?: string; params?: Record<string, any>; context?: any; isCount?: boolean; defValue?: L | null; errorMsg?: string; hump?: boolean; mapper?: string | SqlMapper; mapperIfUndefined?: MapperIfUndefined; }): Promise<L | null>;
3258
+ select<L = T>(option: MethodOption & { sync: SyncMode.Sync; selectResult?: SelectResult.RS_CS | SelectResult.RS_C; sqlId?: string; sql?: string; params?: Record<string, any>; context?: any; isCount?: boolean; defValue?: L | null; errorMsg?: string; hump?: boolean; mapper?: string | SqlMapper; mapperIfUndefined?: MapperIfUndefined; }): L[];
3259
+ select<L = T>(option: MethodOption & { sync: SyncMode.Sync; selectResult: SelectResult.RS_CS_List | SelectResult.RS_C_List; sqlId?: string; sql?: string; params?: Record<string, any>; context?: any; isCount?: boolean; defValue?: L | null; errorMsg?: string; hump?: boolean; mapper?: string | SqlMapper; mapperIfUndefined?: MapperIfUndefined; }): ArrayList<L>;
3260
+ select<L = T>(option: MethodOption & { sync: SyncMode.Sync; selectResult: SelectResult.R_CS_Assert | SelectResult.R_C_Assert; sqlId?: string; sql?: string; params?: Record<string, any>; context?: any; isCount?: boolean; defValue?: L | null; errorMsg?: string; hump?: boolean; mapper?: string | SqlMapper; mapperIfUndefined?: MapperIfUndefined; }): L;
3261
+ select<L = T>(option: MethodOption & { sync: SyncMode.Sync; selectResult: SelectResult.R_CS_NotSure | SelectResult.R_C_NotSure; sqlId?: string; sql?: string; params?: Record<string, any>; context?: any; isCount?: boolean; defValue?: L | null; errorMsg?: string; hump?: boolean; mapper?: string | SqlMapper; mapperIfUndefined?: MapperIfUndefined; }): L | null;
2822
3262
  @P<T>()
2823
- select<L = T>(option: MethodOption & { sync?: SyncMode; selectResult?: SelectResult; sqlId?: string; sql?: string; params?: Record<string, any>; context?: any; isCount?: boolean; defValue?: L | null; multiple?: boolean; errorMsg?: string; }): null | L | L[] | Promise<null | L | L[]> {
3263
+ select<L = T>(option: MethodOption & { sync?: SyncMode; selectResult?: SelectResult; sqlId?: string; sql?: string; params?: Record<string, any>; context?: any; isCount?: boolean; defValue?: L | null; errorMsg?: string; hump?: boolean; mapper?: string | SqlMapper; mapperIfUndefined?: MapperIfUndefined; }): null | L | L[] | ArrayList<L> | Promise<null | L | L[] | ArrayList<L>> {
2824
3264
  Throw.if(!option.sqlId && !option.sql, 'not found sql!');
2825
- option.selectResult ??= SelectResult.Many_Row_Many_Column;
3265
+ option.selectResult ??= SelectResult.RS_CS;
2826
3266
  option.defValue ??= null;
3267
+ if (option.sqlId && globalThis[_resultMap_SQLID][option.sqlId] && !option.mapper) {
3268
+ option.mapper = globalThis[_resultMap_SQLID][option.sqlId];
3269
+ }
2827
3270
  const _params = Object.assign({}, option.context, option.params);
2828
- option.sql ??= globalThis[_sqlCache].load(option.sqlId, { ctx: option.context, isCount: option.isCount, ..._params });
2829
- logger.debug(option.sql);
3271
+ option.sql ??= globalThis[_sqlCache].load(this._matchSqlid(option.sqlId), { ctx: option.context, isCount: option.isCount, ..._params });
2830
3272
  const params: any[] = [];
2831
- const sql = option.sql?.replace(/\:(\w+)/g, (txt, key) => {
2832
- if (_params.hasOwnProperty(key)) {
2833
- const V = _params[key];
2834
- params.push(V);
2835
- return Sqlstring.escape(_params[key]);
3273
+ const sql = option.sql?.replace(/\:([A-Za-z0-9._]+)/g, (txt, key) => {
3274
+ let V = LGet(_params, key);
3275
+ if (V) {
3276
+ if (V !== undefined) {
3277
+ params.push(V);
3278
+ }
3279
+ return '?';
3280
+ }
3281
+ const _key = C2P(key);
3282
+ V = LGet(_params, _key);
3283
+ if (V) {
3284
+ if (V !== undefined) {
3285
+ params.push(V);
3286
+ }
3287
+ return '?';
3288
+ }
3289
+ const __key = P2C(key);
3290
+ V = LGet(_params, __key);
3291
+ if (V) {
3292
+ if (V !== undefined) {
3293
+ params.push(V);
3294
+ }
3295
+ return '?';
2836
3296
  }
2837
3297
  return txt;
2838
3298
  });
2839
3299
  if (option.sync === SyncMode.Sync) {
2840
3300
  const result = option!.conn!.query(SyncMode.Sync, sql, params);
2841
- return this._select<L>(option.selectResult, result, option.defValue, option.errorMsg, option.multiple);
3301
+ return this._select<L>(option.selectResult, result, option.defValue, option.errorMsg, option.hump, option.mapper, option.mapperIfUndefined);
2842
3302
  } else {
2843
- return new Promise<L | null | L[]>(async (resolve) => {
2844
- const result = await option!.conn!.query(SyncMode.Async, sql, params);
2845
- resolve(this._select<L>(option.selectResult!, result, option.defValue!, option.errorMsg, option.multiple));
3303
+ return new Promise<L | null | L[]>(async (resolve, reject) => {
3304
+ try {
3305
+ const result = await option!.conn!.query(SyncMode.Async, sql, params);
3306
+ resolve(this._select<L>(option.selectResult!, result, option.defValue!, option.errorMsg, option.hump, option.mapper, option.mapperIfUndefined));
3307
+ } catch (error) {
3308
+ reject(error);
3309
+ }
2846
3310
  });
2847
3311
  }
2848
3312
  }
@@ -2860,7 +3324,7 @@ export class SqlService<T extends object> {
2860
3324
  });
2861
3325
  ```
2862
3326
  5. `dao`: 永远不需要传入该值
2863
-
3327
+
2864
3328
  */
2865
3329
  excute<L = T>(option: MethodOption & { sync?: SyncMode.Async; sqlId?: string; sql?: string; params?: Record<string, any>; context?: any; }): Promise<number>;
2866
3330
  excute<L = T>(option: MethodOption & { sync: SyncMode.Sync; sqlId?: string; sql?: string; params?: Record<string, any>; context?: any; }): number;
@@ -2868,14 +3332,31 @@ export class SqlService<T extends object> {
2868
3332
  excute<L = T>(option: MethodOption & { sync?: SyncMode; sqlId?: string; sql?: string; params?: Record<string, any>; context?: any; }): number | Promise<number> {
2869
3333
  Throw.if(!option.sqlId && !option.sql, 'not found sql!');
2870
3334
  const _params = Object.assign({}, option.context, option.params);
2871
- option.sql ??= globalThis[_sqlCache].load(option.sqlId, { ctx: option.context, ..._params });
2872
- logger.debug(option.sql);
3335
+ option.sql ??= globalThis[_sqlCache].load(this._matchSqlid(option.sqlId), { ctx: option.context, ..._params });
2873
3336
  const params: any[] = [];
2874
3337
  const sql = option.sql?.replace(/\:(\w+)/g, (txt, key) => {
2875
- if (_params.hasOwnProperty(key)) {
2876
- const V = _params[key];
2877
- params.push(V);
2878
- return Sqlstring.escape(_params[key]);
3338
+ let V = LGet(_params, key);
3339
+ if (V) {
3340
+ if (V !== undefined) {
3341
+ params.push(V);
3342
+ }
3343
+ return '?';
3344
+ }
3345
+ const _key = C2P(key);
3346
+ V = LGet(_params, _key);
3347
+ if (V) {
3348
+ if (V !== undefined) {
3349
+ params.push(V);
3350
+ }
3351
+ return '?';
3352
+ }
3353
+ const __key = P2C(key);
3354
+ V = LGet(_params, __key);
3355
+ if (V) {
3356
+ if (V !== undefined) {
3357
+ params.push(V);
3358
+ }
3359
+ return '?';
2879
3360
  }
2880
3361
  return txt;
2881
3362
  });
@@ -2883,9 +3364,13 @@ export class SqlService<T extends object> {
2883
3364
  const result = option!.conn!.execute(SyncMode.Sync, sql, params);
2884
3365
  return result.affectedRows;
2885
3366
  } else {
2886
- return new Promise<number>(async (resolve) => {
2887
- const result = await option!.conn!.execute(SyncMode.Async, sql, params);
2888
- resolve(result.affectedRows);
3367
+ return new Promise<number>(async (resolve, reject) => {
3368
+ try {
3369
+ const result = await option!.conn!.execute(SyncMode.Async, sql, params);
3370
+ resolve(result.affectedRows);
3371
+ } catch (error) {
3372
+ reject(error);
3373
+ }
2889
3374
  });
2890
3375
  }
2891
3376
  }
@@ -2914,15 +3399,129 @@ export class SqlService<T extends object> {
2914
3399
  if (option.sync === SyncMode.Sync) {
2915
3400
  return option!.dao!.transaction(SyncMode.Sync, option.fn as (conn: Connection) => L)!;
2916
3401
  } else {
2917
- return new Promise(async (resolve) => {
2918
- const rt = await option!.dao!.transaction(SyncMode.Async, option.fn as (conn: Connection) => Promise<L>);
2919
- resolve(rt);
3402
+ return new Promise(async (resolve, reject) => {
3403
+ try {
3404
+ const rt = await option!.dao!.transaction(SyncMode.Async, option.fn as (conn: Connection) => Promise<L>);
3405
+ resolve(rt);
3406
+ } catch (error) {
3407
+ reject(error);
3408
+ }
2920
3409
  });
2921
3410
  }
2922
3411
  }
2923
3412
 
2924
- stream(option?: MethodOption) {
2925
- return new StreamQuery(option?.tableName ?? this[_tableName]!, this);
3413
+ stream<L extends object = T>(option?: MethodOption) {
3414
+ return new StreamQuery<L>(option?.tableName ?? this[_tableName]!, this as any, this[_fields]!, this[_columns]!);
3415
+ }
3416
+
3417
+
3418
+ page<L = T>(option: MethodOption & { sync?: SyncMode.Async; sqlId: string; context?: any; params: Record<string, any>; pageSize: number; pageNumber: number; limitSelf?: boolean; countSelf?: boolean; sumSelf?: boolean; orderBy?: string; hump?: boolean; mapper?: string | SqlMapper; mapperIfUndefined?: MapperIfUndefined; }): Promise<PageQuery<L>>;
3419
+ page<L = T>(option: MethodOption & { sync: SyncMode.Sync; sqlId: string; context?: any; params: Record<string, any>; pageSize: number; pageNumber: number; limitSelf?: boolean; countSelf?: boolean; sumSelf?: boolean; orderBy?: string; hump?: boolean; mapper?: string | SqlMapper; mapperIfUndefined?: MapperIfUndefined; }): PageQuery<L>;
3420
+ @P<T>()
3421
+ page<L = T>(option: MethodOption & { sync?: SyncMode; sqlId: string; context?: any; params: Record<string, any>; pageSize: number; pageNumber: number; limitSelf?: boolean; countSelf?: boolean; sumSelf?: boolean; orderBy?: string; hump?: boolean; mapper?: string | SqlMapper; mapperIfUndefined?: MapperIfUndefined; }): PageQuery<L> | Promise<PageQuery<L>> {
3422
+ const result: PageQuery<L> = {
3423
+ sum: {},
3424
+ records: [],
3425
+ size: 0,
3426
+ total: 0
3427
+ };
3428
+ Object.assign(option.params, {
3429
+ limitStart: calc(option.pageNumber).sub(1).mul(option.pageSize).over(),
3430
+ limitEnd: calc(option.pageSize).over(),
3431
+ orderBy: option.orderBy
3432
+ });
3433
+ let sql = globalThis[_sqlCache].load(this._matchSqlid(option.sqlId), { ctx: option.context, isCount: false, ...option.params });
3434
+ let sqlSum = '';
3435
+ let sqlCount = '';
3436
+ if (option.sumSelf === true) {
3437
+ sqlSum = globalThis[_sqlCache].load(this._matchSqlid(option.sqlId), { ctx: option.context, isCount: false, isSum: true, ...option.params });
3438
+ }
3439
+ if (option.limitSelf !== true) {
3440
+ if (option.countSelf !== true) {
3441
+ }
3442
+ if (option.orderBy) {
3443
+ sql = `${sql} ORDER BY ${option.orderBy}`;
3444
+ }
3445
+ if (option.pageSize > 0) {
3446
+ sql = `${sql} LIMIT ${option.params['limitStart']}, ${option.pageSize}`;
3447
+ }
3448
+ }
3449
+ if (option.pageSize > 0) {
3450
+ if (option.countSelf === true) {
3451
+ sqlCount = globalThis[_sqlCache].load(this._matchSqlid(`${option.sqlId}_count`), { ctx: option.context, isCount: true, isSum: false, ...option.params });
3452
+ } else {
3453
+ sqlCount = globalThis[_sqlCache].load(this._matchSqlid(option.sqlId), { ctx: option.context, isCount: true, isSum: false, ...option.params });
3454
+ }
3455
+ }
3456
+ if (option.sync === SyncMode.Sync) {
3457
+ if (sqlCount) {
3458
+ result.total = this.select<number>({
3459
+ ...option,
3460
+ sql: sqlCount,
3461
+ sync: SyncMode.Sync,
3462
+ selectResult: SelectResult.R_C_Assert
3463
+ });
3464
+ result.size = calc(result.total)
3465
+ .add(option.pageSize - 1)
3466
+ .div(option.pageSize)
3467
+ .round(0, 2)
3468
+ .over();
3469
+ }
3470
+ if (sqlSum) {
3471
+ result.sum = this.select<Record<string, number>>({
3472
+ ...option,
3473
+ sql: sqlSum,
3474
+ sync: SyncMode.Sync,
3475
+ selectResult: SelectResult.R_CS_Assert
3476
+ });
3477
+ }
3478
+ if (sql) {
3479
+ result.records = this.select<L>({
3480
+ ...option,
3481
+ sql,
3482
+ sync: SyncMode.Sync,
3483
+ selectResult: SelectResult.RS_CS
3484
+ });
3485
+ }
3486
+ return result;
3487
+ } else {
3488
+ return new Promise<PageQuery<L>>(async (resolve, reject) => {
3489
+ try {
3490
+ if (sqlCount) {
3491
+ result.total = await this.select<number>({
3492
+ ...option,
3493
+ sql: sqlCount,
3494
+ sync: SyncMode.Async,
3495
+ selectResult: SelectResult.R_C_Assert
3496
+ });
3497
+ result.size = calc(result.total)
3498
+ .add(option.pageSize - 1)
3499
+ .div(option.pageSize)
3500
+ .round(0, 2)
3501
+ .over();
3502
+ }
3503
+ if (sqlSum) {
3504
+ result.sum = await this.select<Record<string, number>>({
3505
+ ...option,
3506
+ sql: sqlSum,
3507
+ sync: SyncMode.Async,
3508
+ selectResult: SelectResult.R_CS_Assert
3509
+ });
3510
+ }
3511
+ if (sql) {
3512
+ result.records = await this.select<L>({
3513
+ ...option,
3514
+ sql,
3515
+ sync: SyncMode.Async,
3516
+ selectResult: SelectResult.RS_CS
3517
+ });
3518
+ }
3519
+ resolve(result);
3520
+ } catch (error) {
3521
+ reject(error);
3522
+ }
3523
+ });
3524
+ }
2926
3525
  }
2927
3526
 
2928
3527
  /**
@@ -2937,11 +3536,11 @@ export class SqlService<T extends object> {
2937
3536
  4. 自定义字段名称:字符串数组
2938
3537
  ** `index` 表的索引,设置方式同ID
2939
3538
  */
2940
- private _createTable({ tableName, temp = true, columns, data, id = 'auto', index = 'auto' }: {
3539
+ private _createTable<L = T>({ tableName, temp = true, columns, data, id = 'auto', index = 'auto' }: {
2941
3540
  tableName?: string;
2942
3541
  temp?: boolean,
2943
3542
  columns?: string[];
2944
- data?: Array<Partial<T>>;
3543
+ data?: Array<Partial<L>>;
2945
3544
  id?: 'auto' | 'all' | 'none' | string[];
2946
3545
  index?: 'auto' | 'all' | 'none' | string[];
2947
3546
  } = {}): { sql: string; params?: any[] }[] {
@@ -2970,66 +3569,73 @@ export class SqlService<T extends object> {
2970
3569
  tableName = Sqlstring.escapeId(tableName ?? this[_tableName]);
2971
3570
  switch (this[_dbType]) {
2972
3571
  case DBType.Mysql: {
2973
- let sql = `CREATE ${temp === true ? 'TEMPORARY' : ''} TABLE IF NOT EXISTS ${tableName}(
2974
- ${columns.map(K => this[_fields]![K]![DBType.Mysql]).join(',')}
2975
- ${ids && ids.length ? `,PRIMARY KEY (${ids.map(i => this[_fields]![i]?.esName).join(',')}) USING BTREE ` : ''}
2976
- ${indexs && indexs.length ? `,${indexs.map(i => `KEY ${this[_fields]![i]?.esName} (${this[_fields]![i]?.esName})`).join(',')} ` : ''}
2977
- ) ENGINE=MEMORY;`;
3572
+ let sql = format(`CREATE ${temp === true ? 'TEMPORARY' : ''} TABLE IF NOT EXISTS ${tableName}(
3573
+ ${columns.map(K => this[_fields]![K]![DBType.Mysql]()).join(',')}
3574
+ ${ids && ids.length ? `,PRIMARY KEY (${ids.map(i => this[_fields]![i]?.C2()).join(',')}) USING BTREE ` : ''}
3575
+ ${indexs && indexs.length ? `,${indexs.map(i => `KEY ${this[_fields]![i]?.C2()} (${this[_fields]![i]?.C2()})`).join(',')} ` : ''}
3576
+ ) ENGINE=MEMORY;`);
2978
3577
  sqls.push({ sql });
2979
3578
  if (data && data.length > 0) {
2980
3579
  const params: any[] = [];
2981
3580
  let first = true;
2982
- sql = `INSERT INTO ${tableName} (${columns.map(c => Sqlstring.escapeId(c)).join(',')})
3581
+ sql = format(`INSERT INTO ${tableName} (${columns.map(c => this[_fields]![c]?.C2()).join(',')})
2983
3582
  ${(data).map(d => {
2984
3583
  const r = `SELECT ${Object.entries(d).map(([K, V]) => {
2985
3584
  params.push(V);
2986
- return `? ${first ? this[_fields]![K]?.esName : ''}`;
3585
+ return `? ${first ? this[_fields]![K]?.C2() : ''}`;
2987
3586
  }).join(',')}`;
2988
3587
  first = false;
2989
3588
  return r;
2990
- }).join(' UNION ALL ')}`;
3589
+ }).join(' UNION ALL ')}`);
2991
3590
  sqls.push({ sql, params });
2992
3591
  }
2993
3592
  break;
2994
3593
  }
2995
3594
  case DBType.Sqlite:
2996
3595
  case DBType.SqliteRemote: {
2997
- let sql = `CREATE ${temp === true ? 'TEMPORARY' : ''} TABLE IF NOT EXISTS ${tableName}(
2998
- ${columns.map(K => this[_fields]![K]![DBType.Sqlite]).join(',')}
2999
- ${ids && ids.length ? `,PRIMARY KEY (${ids.map(i => this[_fields]![i]?.esName).join(',')}) ` : ''}
3000
- );`;
3596
+ let sql = format(`CREATE ${temp === true ? 'TEMPORARY' : ''} TABLE IF NOT EXISTS ${tableName}(
3597
+ ${columns.map(K => this[_fields]![K]![DBType.Sqlite]()).join(',')}
3598
+ ${ids && ids.length ? `,PRIMARY KEY (${ids.map(i => this[_fields]![i]?.C2()).join(',')}) ` : ''}
3599
+ );`);
3001
3600
  sqls.push({ sql });
3002
3601
  if (indexs) {
3003
3602
  for (const index of indexs) {
3004
- sql = `CREATE INDEX ${Sqlstring.escapeId(`${index}_${Math.random()}`.replace(/\./, ''))} ON ${tableName} (${this[_fields]![index]?.esName});`;
3603
+ sql = format(`CREATE INDEX ${Sqlstring.escapeId(`${index}_${Math.random()}`.replace(/\./, ''))} ON ${tableName} (${this[_fields]![index]?.C2()});`);
3005
3604
  sqls.push({ sql });
3006
3605
  }
3007
3606
  }
3008
3607
  if (data && data.length > 0) {
3009
3608
  const params: any[] = [];
3010
3609
  let first = true;
3011
- sql = `INSERT INTO ${tableName} (${columns.map(c => Sqlstring.escapeId(c)).join(',')})
3610
+ sql = format(`INSERT INTO ${tableName} (${columns.map(c => this[_fields]![c]?.C2()).join(',')})
3012
3611
  ${(data).map(d => {
3013
3612
  const r = `SELECT ${Object.entries(d).map(([K, V]) => {
3014
3613
  params.push(V);
3015
- return `? ${first ? this[_fields]![K]?.esName : ''}`;
3614
+ return `? ${first ? this[_fields]![K]?.C2() : ''}`;
3016
3615
  }).join(',')}`;
3017
3616
  first = false;
3018
3617
  return r;
3019
- }).join(' UNION ALL ')}`;
3618
+ }).join(' UNION ALL ')}`);
3020
3619
  sqls.push({ sql, params });
3021
3620
  }
3621
+ break;
3022
3622
  }
3023
3623
  }
3024
3624
  return sqls;
3025
3625
  }
3026
3626
 
3627
+ private _matchSqlid(sqlid?: string) {
3628
+ sqlid ??= '';
3629
+ if (sqlid.includes('.')) return [sqlid];
3630
+ else return [`${this[_tableName]}.${sqlid}`, `${this[_className]}.${sqlid}`, `${this[_ClassName]}.${sqlid}`, `${this[_vueName]}.${sqlid}`];
3631
+ }
3632
+
3027
3633
  }
3028
3634
  /** 是否进行下一个动作 */
3029
3635
  const IF_PROCEED = function <T extends object>() {
3030
3636
  return function (_target: any, _propertyKey: string, descriptor: PropertyDescriptor) {
3031
3637
  const fn = descriptor.value;
3032
- descriptor.value = function (this: StreamCondition<T>) {
3638
+ descriptor.value = function (this: StreamQuery<T>) {
3033
3639
  if (this.if_proceed === true) {
3034
3640
  // eslint-disable-next-line prefer-rest-params
3035
3641
  const args = Array.from(arguments);
@@ -3056,21 +3662,42 @@ const IF_EXEC = function <T extends object>(def: any) {
3056
3662
  };
3057
3663
  };
3058
3664
  };
3059
- class StreamCondition<T extends object> {
3060
- protected _prefix = 0;
3061
- protected _index = 0;
3665
+ class StreamQuery<T extends object> {
3666
+ private _prefix = 0;
3667
+ private _index = 0;
3062
3668
 
3063
- protected _wheres: string[] = [];
3669
+ private _wheres: string[] = [];
3064
3670
 
3065
- protected _andQuerys: StreamCondition<T>[] = [];
3066
- protected _orQuerys: StreamCondition<T>[] = [];
3671
+ private _andQuerys: StreamQuery<T>[] = [];
3672
+ private _orQuerys: StreamQuery<T>[] = [];
3067
3673
 
3068
- protected _paramKeys: Record<string, string[] | Record<string, string> | string> = {};
3069
- protected _param: Record<string, any> = {};
3674
+ private _paramKeys: Record<string, string[] | Record<string, string> | string> = {};
3675
+ private _param: Record<string, any> = {};
3070
3676
  public if_proceed = true;
3071
3677
  public if_exec = true;
3072
- constructor() {
3678
+ private _table: string;
3679
+
3680
+ private _distinct = false;
3681
+ private _columns: string[] = [];
3682
+
3683
+ private _updates?: Partial<T>;
3684
+ private _updateColumns: string[] = [];
3685
+
3686
+ private _groups: string[] = [];
3687
+ private _orders: string[] = [];
3688
+
3689
+ private _startRow = 0;
3690
+ private _pageSize = 0;
3691
+
3692
+ private _service: SqlService<T>;
3693
+ private [_fields]: Record<string, AField>;
3694
+ private [_columns]: string[];
3695
+ constructor(table: string, service: SqlService<T>, __fields: Record<string, AField>, __columns: string[]) {
3073
3696
  this._prefix = parseInt(`${Math.random() * 1000}`);
3697
+ this._table = table;
3698
+ this._service = service;
3699
+ this[_fields] = __fields;
3700
+ this[_columns] = __columns;
3074
3701
  }
3075
3702
  /** 将当前stream重置 */
3076
3703
  reset() {
@@ -3078,8 +3705,15 @@ class StreamCondition<T extends object> {
3078
3705
  this._wheres.length = 0;
3079
3706
  this._param = {};
3080
3707
  this._paramKeys = {};
3708
+ this._pageSize = 0;
3709
+ this._startRow = 0;
3710
+ this._orders.length = 0;
3711
+ this._groups.length = 0;
3712
+ this._columns.length = 0;
3713
+ this._updateColumns.length = 0;
3081
3714
  return this;
3082
3715
  }
3716
+ // #region 条件
3083
3717
  /** 为下次链条执行提供条件判断:非异步方法跳过,异步方法不执行并返回默认值 */
3084
3718
  @IF_PROCEED<T>()
3085
3719
  if(condition: boolean) {
@@ -3087,148 +3721,418 @@ class StreamCondition<T extends object> {
3087
3721
  return this;
3088
3722
  }
3089
3723
  @IF_PROCEED<T>()
3090
- eq(key: keyof T, value: string | number, { name }: { name?: string } = {}) { return this._(key, value, '=', { name }); }
3724
+ eq(key: keyof T, value: string | number, { paramName = '', skipEmptyString = true, breakExcuteIfSkip = false } = {}) { return this._(key, value, '=', { paramName, skipEmptyString, breakExcuteIfSkip }); }
3091
3725
  @IF_PROCEED<T>()
3092
- eqT(t: Partial<T>, { name }: { name?: string } = {}) {
3093
- if (name && this._paramKeys[name]) {
3094
- for (const [key, pname] of Object.entries(this._paramKeys[name] as Record<string, string>)) {
3095
- this._param[pname as string] = t[key];
3096
- }
3097
- } else {
3098
- const paramKeys: Record<string, string> = {};
3099
- for (const [key, value] of Object.entries(t)) {
3100
- const pkey = `p${this._prefix}${this._index++}`;
3101
- this._wheres.push(`AND ${String(key)} = :${pkey} `);
3102
- this._param[pkey] = value;
3103
- if (name) {
3104
- paramKeys[key] = pkey;
3726
+ eqT(t: Partial<T>, { name: paramName = '', breakExcuteIfSkip = false } = {}) {
3727
+ let exe = false;
3728
+ if (t) {
3729
+ t = this._service[_transformer]!(t, {
3730
+ skipNull: true,
3731
+ skipUndefined: true,
3732
+ skipEmptyString: true
3733
+ });
3734
+ const keys = Object.keys(t);
3735
+ if (keys.length > 0) {
3736
+ if (paramName && this._paramKeys[paramName]) {
3737
+ for (const [key, pname] of Object.entries(this._paramKeys[paramName] as Record<string, string>)) {
3738
+ this._param[pname as string] = t[key];
3739
+ }
3740
+ } else {
3741
+ const paramKeys: Record<string, string> = {};
3742
+ for (const [key, value] of Object.entries(t)) {
3743
+ const pkey = `p${this._prefix}${this._index++}`;
3744
+ this._wheres.push(`AND ${this[_fields]![String(key)]?.C2()} = :${pkey} `);
3745
+ this._param[pkey] = value;
3746
+ if (paramName) {
3747
+ paramKeys[key] = pkey;
3748
+ }
3749
+ }
3750
+ if (paramName) {
3751
+ this._paramKeys[paramName] = paramKeys;
3752
+ }
3105
3753
  }
3754
+ exe = true;
3106
3755
  }
3107
- if (name) {
3108
- this._paramKeys[name] = paramKeys;
3109
- }
3756
+ }
3757
+ if (breakExcuteIfSkip === true && exe === false) {
3758
+ this.if_exec = false;
3110
3759
  }
3111
3760
  return this;
3112
3761
  }
3113
3762
  @IF_PROCEED<T>()
3114
- notEq(key: keyof T, value: string | number, { name }: { name?: string } = {}) { return this._(key, value, '<>', { name }); }
3763
+ notEq(key: keyof T, value: string | number, { paramName = '', skipEmptyString = true, breakExcuteIfSkip = false } = {}) { return this._(key, value, '<>', { paramName, skipEmptyString, breakExcuteIfSkip }); }
3115
3764
  @IF_PROCEED<T>()
3116
3765
  eqWith(key1: keyof T, key2: keyof T) { return this._key(key1, key2, '='); }
3117
3766
  @IF_PROCEED<T>()
3118
3767
  notEqWith(key1: keyof T, key2: keyof T) { return this._key(key1, key2, '<>'); }
3119
3768
  @IF_PROCEED<T>()
3120
- regexp(key: keyof T, regexp: string, { name }: { name?: string } = {}) { return this._(key, regexp, 'REGEXP', { name }); }
3769
+ regexp(key: keyof T, regexp: string, { paramName = '', breakExcuteIfSkip = false } = {}) { return this._(key, regexp, 'REGEXP', { paramName, skipEmptyString: true, breakExcuteIfSkip }); }
3121
3770
  @IF_PROCEED<T>()
3122
- notRegexp(key: keyof T, regexp: string, { name }: { name?: string } = {}) { return this._(key, regexp, 'REGEXP', { name, not: 'NOT' }); }
3771
+ notRegexp(key: keyof T, regexp: string, { paramName = '', breakExcuteIfSkip = false } = {}) { return this._(key, regexp, 'REGEXP', { paramName, skipEmptyString: true, not: 'NOT', breakExcuteIfSkip }); }
3123
3772
  /** (key1 << 8) + key2 = value */
3124
3773
  @IF_PROCEED<T>()
3125
- shiftEq(key1: keyof T, key2: keyof T, value: number, { name }: { name?: string } = {}) { return this._shift(key1, key2, value, '=', { name }); }
3774
+ shiftEq(key1: keyof T, key2: keyof T, value: number, { paramName = '', breakExcuteIfSkip = false } = {}) { return this._shift(key1, key2, value, '=', { paramName, breakExcuteIfSkip }); }
3126
3775
  /** (key1 << 8) + key2 <> value */
3127
3776
  @IF_PROCEED<T>()
3128
- shiftNotEq(key1: keyof T, key2: keyof T, value: number, { name }: { name?: string } = {}) { return this._shift(key1, key2, value, '<>', { name }); }
3777
+ shiftNotEq(key1: keyof T, key2: keyof T, value: number, { paramName = '', breakExcuteIfSkip = false } = {}) { return this._shift(key1, key2, value, '<>', { paramName, breakExcuteIfSkip }); }
3129
3778
  @IF_PROCEED<T>()
3130
- grate(key: keyof T, value: string | number, { name }: { name?: string } = {}) { return this._(key, value, '>', { name }); }
3779
+ grate(key: keyof T, value: string | number, { paramName = '', breakExcuteIfSkip = false } = {}) { return this._(key, value, '>', { paramName, skipEmptyString: true, breakExcuteIfSkip }); }
3131
3780
  @IF_PROCEED<T>()
3132
- grateEq(key: keyof T, value: string | number, { name }: { name?: string } = {}) { return this._(key, value, '>=', { name }); }
3781
+ grateEq(key: keyof T, value: string | number, { paramName = '', breakExcuteIfSkip = false } = {}) { return this._(key, value, '>=', { paramName, skipEmptyString: true, breakExcuteIfSkip }); }
3133
3782
  @IF_PROCEED<T>()
3134
3783
  grateWith(key1: keyof T, key2: keyof T) { return this._key(key1, key2, '>'); }
3135
3784
  @IF_PROCEED<T>()
3136
3785
  grateEqWith(key1: keyof T, key2: keyof T) { return this._key(key1, key2, '>='); }
3137
3786
  @IF_PROCEED<T>()
3138
- less(key: keyof T, value: string | number, { name }: { name?: string } = {}) { return this._(key, value, '<', { name }); }
3787
+ less(key: keyof T, value: string | number, { paramName = '', breakExcuteIfSkip = false } = {}) { return this._(key, value, '<', { paramName, skipEmptyString: true, breakExcuteIfSkip }); }
3139
3788
  @IF_PROCEED<T>()
3140
- lessEq(key: keyof T, value: string | number, { name }: { name?: string } = {}) { return this._(key, value, '<=', { name }); }
3789
+ lessEq(key: keyof T, value: string | number, { paramName = '', breakExcuteIfSkip = false } = {}) { return this._(key, value, '<=', { paramName, skipEmptyString: true, breakExcuteIfSkip }); }
3141
3790
  @IF_PROCEED<T>()
3142
3791
  lessWith(key1: keyof T, key2: keyof T) { return this._key(key1, key2, '<'); }
3143
3792
  @IF_PROCEED<T>()
3144
3793
  lessEqWith(key1: keyof T, key2: keyof T) { return this._key(key1, key2, '<='); }
3145
3794
  @IF_PROCEED<T>()
3146
- like(key: keyof T, value: string | number, { name, force }: { name?: string; force?: boolean; } = {}) { return this._like(key, value, { name, left: '%', right: '%', force }); }
3795
+ like(key: keyof T, value: string | number, { paramName = '', skipEmptyString = true, breakExcuteIfSkip = false } = {}) { return this._like(key, value, { paramName, skipEmptyString, left: '%', right: '%', breakExcuteIfSkip }); }
3147
3796
  @IF_PROCEED<T>()
3148
- notLike(key: keyof T, value: string | number, { name, force }: { name?: string; force?: boolean; } = {}) { return this._like(key, value, { name, left: '%', right: '%', not: 'NOT', force }); }
3797
+ notLike(key: keyof T, value: string | number, { paramName = '', skipEmptyString = true, breakExcuteIfSkip = false } = {}) { return this._like(key, value, { paramName, skipEmptyString, left: '%', right: '%', not: 'NOT', breakExcuteIfSkip }); }
3149
3798
  @IF_PROCEED<T>()
3150
- leftLike(key: keyof T, value: string | number, { name, force }: { name?: string; force?: boolean; } = {}) { return this._like(key, value, { name, left: '%', force }); }
3799
+ leftLike(key: keyof T, value: string | number, { paramName = '', skipEmptyString = true, breakExcuteIfSkip = false } = {}) { return this._like(key, value, { paramName, skipEmptyString, left: '%', breakExcuteIfSkip }); }
3151
3800
  @IF_PROCEED<T>()
3152
- notLeftLike(key: keyof T, value: string | number, { name, force }: { name?: string; force?: boolean; } = {}) { return this._like(key, value, { name, left: '%', not: 'NOT', force }); }
3801
+ notLeftLike(key: keyof T, value: string | number, { paramName = '', skipEmptyString = true, breakExcuteIfSkip = false } = {}) { return this._like(key, value, { paramName, skipEmptyString, left: '%', not: 'NOT', breakExcuteIfSkip }); }
3153
3802
  @IF_PROCEED<T>()
3154
- rightLike(key: keyof T, value: string | number, { name, force }: { name?: string; force?: boolean; } = {}) { return this._like(key, value, { name, right: '%', force }); }
3803
+ rightLike(key: keyof T, value: string | number, { paramName = '', skipEmptyString = true, breakExcuteIfSkip = false } = {}) { return this._like(key, value, { paramName, skipEmptyString, right: '%', breakExcuteIfSkip }); }
3155
3804
  @IF_PROCEED<T>()
3156
- notRightLike(key: keyof T, value: string | number, { name, force }: { name?: string; force?: boolean; } = {}) { return this._like(key, value, { name, right: '%', not: 'NOT', force }); }
3805
+ notRightLike(key: keyof T, value: string | number, { paramName = '', skipEmptyString = true, breakExcuteIfSkip = false } = {}) { return this._like(key, value, { paramName, skipEmptyString, right: '%', not: 'NOT', breakExcuteIfSkip }); }
3157
3806
  @IF_PROCEED<T>()
3158
- PreciseLike(key: keyof T, value: string | number, { name, force }: { name?: string; force?: boolean; } = {}) { return this._like(key, value, { name, force }); }
3807
+ PreciseLike(key: keyof T, value: string | number, { paramName = '', skipEmptyString = true, breakExcuteIfSkip = false } = {}) { return this._like(key, value, { paramName, skipEmptyString, breakExcuteIfSkip }); }
3159
3808
  @IF_PROCEED<T>()
3160
- notPreciseLike(key: keyof T, value: string | number, { name, force }: { name?: string; force?: boolean; } = {}) { return this._like(key, value, { name, not: 'NOT', force }); }
3809
+ notPreciseLike(key: keyof T, value: string | number, { paramName = '', skipEmptyString = true, breakExcuteIfSkip = false } = {}) { return this._like(key, value, { paramName, skipEmptyString, not: 'NOT', breakExcuteIfSkip }); }
3161
3810
  @IF_PROCEED<T>()
3162
- glob(key: keyof T, value: string | number, { name, force }: { name?: string; force?: boolean; } = {}) { return this._like(key, value, { name, left: '%', right: '%', force, op: 'glob' }); }
3811
+ glob(key: keyof T, value: string | number, { paramName = '', skipEmptyString = true, breakExcuteIfSkip = false } = {}) { return this._like(key, value, { paramName, skipEmptyString, left: '%', right: '%', breakExcuteIfSkip, op: 'GLOB' }); }
3163
3812
  @IF_PROCEED<T>()
3164
- notGlob(key: keyof T, value: string | number, { name, force }: { name?: string; force?: boolean; } = {}) { return this._like(key, value, { name, left: '%', right: '%', not: 'NOT', force, op: 'glob' }); }
3813
+ notGlob(key: keyof T, value: string | number, { paramName = '', skipEmptyString = true, breakExcuteIfSkip = false } = {}) { return this._like(key, value, { paramName, skipEmptyString, left: '%', right: '%', not: 'NOT', breakExcuteIfSkip, op: 'GLOB' }); }
3165
3814
  @IF_PROCEED<T>()
3166
- leftGlob(key: keyof T, value: string | number, { name, force }: { name?: string; force?: boolean; } = {}) { return this._like(key, value, { name, left: '%', force, op: 'glob' }); }
3815
+ leftGlob(key: keyof T, value: string | number, { paramName = '', skipEmptyString = true, breakExcuteIfSkip = false } = {}) { return this._like(key, value, { paramName, skipEmptyString, left: '%', breakExcuteIfSkip, op: 'GLOB' }); }
3167
3816
  @IF_PROCEED<T>()
3168
- notLeftGlob(key: keyof T, value: string | number, { name, force }: { name?: string; force?: boolean; } = {}) { return this._like(key, value, { name, left: '%', not: 'NOT', force, op: 'glob' }); }
3817
+ notLeftGlob(key: keyof T, value: string | number, { paramName = '', skipEmptyString = true, breakExcuteIfSkip = false } = {}) { return this._like(key, value, { paramName, skipEmptyString, left: '%', not: 'NOT', breakExcuteIfSkip, op: 'GLOB' }); }
3169
3818
  @IF_PROCEED<T>()
3170
- rightGlob(key: keyof T, value: string | number, { name, force }: { name?: string; force?: boolean; } = {}) { return this._like(key, value, { name, right: '%', force, op: 'glob' }); }
3819
+ rightGlob(key: keyof T, value: string | number, { paramName = '', skipEmptyString = true, breakExcuteIfSkip = false } = {}) { return this._like(key, value, { paramName, skipEmptyString, right: '%', breakExcuteIfSkip, op: 'GLOB' }); }
3171
3820
  @IF_PROCEED<T>()
3172
- notRightGlob(key: keyof T, value: string | number, { name, force }: { name?: string; force?: boolean; } = {}) { return this._like(key, value, { name, right: '%', not: 'NOT', force, op: 'glob' }); }
3821
+ notRightGlob(key: keyof T, value: string | number, { paramName = '', skipEmptyString = true, breakExcuteIfSkip = false } = {}) { return this._like(key, value, { paramName, skipEmptyString, right: '%', not: 'NOT', breakExcuteIfSkip, op: 'GLOB' }); }
3173
3822
  @IF_PROCEED<T>()
3174
- PreciseGlob(key: keyof T, value: string | number, { name, force }: { name?: string; force?: boolean; } = {}) { return this._like(key, value, { name, force, op: 'glob' }); }
3823
+ PreciseGlob(key: keyof T, value: string | number, { paramName = '', skipEmptyString = true, breakExcuteIfSkip = false } = {}) { return this._like(key, value, { paramName, skipEmptyString, breakExcuteIfSkip, op: 'GLOB' }); }
3175
3824
  @IF_PROCEED<T>()
3176
- notPreciseGlob(key: keyof T, value: string | number, { name, force }: { name?: string; force?: boolean; } = {}) { return this._like(key, value, { name, not: 'NOT', force, op: 'glob' }); }
3825
+ notPreciseGlob(key: keyof T, value: string | number, { paramName = '', skipEmptyString = true, breakExcuteIfSkip = false } = {}) { return this._like(key, value, { paramName, skipEmptyString, not: 'NOT', breakExcuteIfSkip, op: 'GLOB' }); }
3177
3826
  @IF_PROCEED<T>()
3178
- in(key: keyof T, value: Array<string | number>, { name, force }: { name?: string; force?: boolean; } = {}) { return this._in(key, value, { name, force }); }
3827
+ in(key: keyof T, value: Array<string | number>, { paramName = '', breakExcuteIfSkip = false } = {}) { return this._in(key, value, { paramName, breakExcuteIfSkip }); }
3179
3828
  @IF_PROCEED<T>()
3180
- notIn(key: keyof T, value: Array<string | number>, { name, force }: { name?: string; force?: boolean; } = {}) { return this._in(key, value, { name, not: 'NOT', force }); }
3829
+ notIn(key: keyof T, value: Array<string | number>, { paramName = '', skipEmptyString = true, breakExcuteIfSkip = false } = {}) { return this._in(key, value, { paramName, skipEmptyString, not: 'NOT', breakExcuteIfSkip }); }
3181
3830
  @IF_PROCEED<T>()
3182
3831
  isNULL(key: keyof T) { return this._null(key); }
3183
3832
  @IF_PROCEED<T>()
3184
3833
  isNotNULL(key: keyof T) { return this._null(key, 'NOT'); }
3185
3834
  @IF_PROCEED<T>()
3186
- between(key: keyof T, value1: string | number, value2: string | number, { name }: { name?: string } = {}) { return this._between(key, value1, value2, { name }); }
3835
+ between(key: keyof T, value1: string | number, value2: string | number, { paramName = '', skipEmptyString = true, breakExcuteIfSkip = false } = {}) { return this._between(key, value1, value2, { paramName, skipEmptyString, breakExcuteIfSkip }); }
3187
3836
  @IF_PROCEED<T>()
3188
- notBetween(key: keyof T, value1: string | number, value2: string | number, { name }: { name?: string } = {}) { return this._between(key, value1, value2, { name, not: 'NOT' }); }
3837
+ notBetween(key: keyof T, value1: string | number, value2: string | number, { paramName = '', skipEmptyString = true, breakExcuteIfSkip = false } = {}) { return this._between(key, value1, value2, { paramName, skipEmptyString, not: 'NOT', breakExcuteIfSkip }); }
3189
3838
  @IF_PROCEED<T>()
3190
- pow(key: keyof T, value: number, { name }: { name?: string } = {}) { return this._pow(key, value, { name }); }
3839
+ pow(key: keyof T, value: number, { paramName = '', breakExcuteIfSkip = false } = {}) { return this._pow(key, value, { paramName, breakExcuteIfSkip }); }
3191
3840
  @IF_PROCEED<T>()
3192
- notPow(key: keyof T, value: number, { name }: { name?: string } = {}) { return this._pow(key, value, { name, not: 'NOT' }); }
3841
+ notPow(key: keyof T, value: number, { paramName = '', breakExcuteIfSkip = false } = {}) { return this._pow(key, value, { paramName, not: 'NOT', breakExcuteIfSkip }); }
3193
3842
  @IF_PROCEED<T>()
3194
- powWith(key: keyof T, values: Array<number | string>, { name }: { name?: string } = {}) { return this._pow(key, add(...values.map(value => Math.pow(2, +value))), { name }); }
3843
+ powWith(key: keyof T, values: Array<number | string>, { paramName = '', breakExcuteIfSkip = false } = {}) { return this._pow(key, add(...values.map(value => Math.pow(2, +value))), { paramName, breakExcuteIfSkip }); }
3195
3844
  @IF_PROCEED<T>()
3196
- notPowWith(key: keyof T, values: Array<number | string>, { name }: { name?: string } = {}) { return this._pow(key, add(...values.map(value => Math.pow(2, +value))), { name, not: 'NOT' }); }
3845
+ notPowWith(key: keyof T, values: Array<number | string>, { paramName = '', breakExcuteIfSkip = false } = {}) { return this._pow(key, add(...values.map(value => Math.pow(2, +value))), { paramName, not: 'NOT', breakExcuteIfSkip }); }
3197
3846
  /** MATCH(key1, key2, key3) AGAINST (value) */
3198
3847
  @IF_PROCEED<T>()
3199
- match(value: string, keys: (keyof T)[], { name }: { name?: string } = {}) { return this._match(value, keys, { name }); }
3848
+ match(value: string, keys: (keyof T)[], { paramName = '', skipEmptyString = true, breakExcuteIfSkip = false } = {}) { return this._match(value, keys, { paramName, skipEmptyString, breakExcuteIfSkip }); }
3200
3849
  /** NOT MATCH(key1, key2, key3) AGAINST (value) */
3201
3850
  @IF_PROCEED<T>()
3202
- notMatch(value: string, keys: (keyof T)[], { name }: { name?: string } = {}) { return this._match(value, keys, { name, not: 'NOT' }); }
3851
+ notMatch(value: string, keys: (keyof T)[], { paramName = '', skipEmptyString = true, breakExcuteIfSkip = false } = {}) { return this._match(value, keys, { paramName, skipEmptyString, not: 'NOT', breakExcuteIfSkip }); }
3203
3852
  /** MATCH(key1, key2, key3) AGAINST (value) IN BOOLEAN MODE*/
3204
3853
  @IF_PROCEED<T>()
3205
- matchBoolean(value: string, keys: (keyof T)[], { name }: { name?: string } = {}) { return this._match(value, keys, { name, append: 'IN BOOLEAN MODE' }); }
3854
+ matchBoolean(value: string, keys: (keyof T)[], { paramName = '', skipEmptyString = true, breakExcuteIfSkip = false } = {}) { return this._match(value, keys, { paramName, skipEmptyString, breakExcuteIfSkip, append: 'IN BOOLEAN MODE' }); }
3206
3855
  /** NOT MATCH(key1, key2, key3) AGAINST (value) IN BOOLEAN MODE */
3207
3856
  @IF_PROCEED<T>()
3208
- notMatchBoolean(value: string, keys: (keyof T)[], { name }: { name?: string } = {}) { return this._match(value, keys, { name, not: 'NOT', append: 'IN BOOLEAN MODE' }); }
3857
+ notMatchBoolean(value: string, keys: (keyof T)[], { paramName = '', skipEmptyString = true, breakExcuteIfSkip = false } = {}) { return this._match(value, keys, { paramName, skipEmptyString, breakExcuteIfSkip, not: 'NOT', append: 'IN BOOLEAN MODE' }); }
3209
3858
  /** MATCH(key1, key2, key3) AGAINST (value) WITH QUERY EXPANSION*/
3210
3859
  @IF_PROCEED<T>()
3211
- matchQuery(value: string, keys: (keyof T)[], { name }: { name?: string } = {}) { return this._match(value, keys, { name, append: 'WITH QUERY EXPANSION' }); }
3860
+ matchQuery(value: string, keys: (keyof T)[], { paramName = '', skipEmptyString = true, breakExcuteIfSkip = false } = {}) { return this._match(value, keys, { paramName, skipEmptyString, breakExcuteIfSkip, append: 'WITH QUERY EXPANSION' }); }
3212
3861
  /** NOT MATCH(key1, key2, key3) AGAINST (value) WITH QUERY EXPANSION*/
3213
3862
  @IF_PROCEED<T>()
3214
- notMatchQuery(value: string, keys: (keyof T)[], { name }: { name?: string } = {}) { return this._match(value, keys, { name, not: 'NOT', append: 'WITH QUERY EXPANSION' }); }
3863
+ notMatchQuery(value: string, keys: (keyof T)[], { paramName = '', skipEmptyString = true, breakExcuteIfSkip = false } = {}) { return this._match(value, keys, { paramName, skipEmptyString, breakExcuteIfSkip, not: 'NOT', append: 'WITH QUERY EXPANSION' }); }
3215
3864
  @IF_PROCEED<T>()
3216
- includes(key: keyof T, value: string | number, { name }: { name?: string } = {}) { return this._includes(key, value, { name }); }
3865
+ includes(key: keyof T, value: string | number, { paramName = '', skipEmptyString = true, breakExcuteIfSkip = false } = {}) { return this._includes(key, value, { paramName, skipEmptyString, breakExcuteIfSkip }); }
3217
3866
  @IF_PROCEED<T>()
3218
- notIncludes(key: keyof T, value: string | number, { name }: { name?: string } = {}) { return this._includes(key, value, { name, not: 'NOT' }); }
3867
+ notIncludes(key: keyof T, value: string | number, { paramName = '', skipEmptyString = true, breakExcuteIfSkip = false } = {}) { return this._includes(key, value, { paramName, skipEmptyString, not: 'NOT', breakExcuteIfSkip }); }
3219
3868
  @IF_PROCEED<T>()
3220
- and(fn: (stream: StreamCondition<T>) => boolean | void) { const stream = new StreamCondition<T>(); const ret = fn(stream); if (ret !== false) { this._andQuerys.push(stream); } return this; }
3869
+ and(fn: StreamQuery<T> | ((stream: StreamQuery<T>) => boolean | void)) {
3870
+ if (fn instanceof StreamQuery) {
3871
+ this._andQuerys.push(fn);
3872
+ } else {
3873
+ const stream = new StreamQuery<T>(this._table, this._service, this[_fields], this[_columns]);
3874
+ const ret = fn(stream);
3875
+ if (ret !== false) { this._andQuerys.push(stream); }
3876
+ }
3877
+ return this;
3878
+ }
3879
+ @IF_PROCEED<T>()
3880
+ or(fn: StreamQuery<T> | ((stream: StreamQuery<T>) => boolean | void)) {
3881
+ if (fn instanceof StreamQuery) {
3882
+ this._andQuerys.push(fn);
3883
+ } else {
3884
+ const stream = new StreamQuery<T>(this._table, this._service, this[_fields], this[_columns]!);
3885
+ const ret = fn(stream);
3886
+ if (ret !== false) { this._orQuerys.push(stream); }
3887
+ }
3888
+ return this;
3889
+ }
3890
+
3891
+ @IF_PROCEED<T>()
3892
+ groupBy(...keys: (keyof T)[]) { this._groups.push(...keys.map(key => `${this[_fields]![String(key)]?.C2()}`)); return this; }
3893
+ @IF_PROCEED<T>()
3894
+ groupBy2(...keys: string[]) { this._groups.push(...keys); return this; }
3895
+ @IF_PROCEED<T>()
3896
+ asc(...keys: (keyof T)[]) { this._orders.push(...keys.map(key => `${this[_fields]![String(key)]?.C2()} ASC`)); return this; }
3897
+ @IF_PROCEED<T>()
3898
+ asc2(...keys: string[]) { this._orders.push(...keys.map(key => `${key} ASC`)); return this; }
3899
+ @IF_PROCEED<T>()
3900
+ desc(...keys: (keyof T)[]) { this._orders.push(...keys.map(key => `${this[_fields]![String(key)]?.C2()} DESC`)); return this; }
3901
+ @IF_PROCEED<T>()
3902
+ desc2(...keys: string[]) { this._orders.push(...keys.map(key => `${key} ASC`)); return this; }
3903
+ @IF_PROCEED<T>()
3904
+ limit(startRow: number, pageSize: number) { this._startRow = startRow; this._pageSize = pageSize; return this; }
3221
3905
  @IF_PROCEED<T>()
3222
- or(fn: (stream: StreamCondition<T>) => boolean | void) { const stream = new StreamCondition<T>(); const ret = fn(stream); if (ret !== false) { this._orQuerys.push(stream); } return this; }
3223
- protected where() {
3906
+ page(pageNumber: number, pageSize: number) { this._startRow = ((pageNumber || 1) - 1) * pageSize; this._pageSize = pageSize; return this; }
3907
+ @IF_PROCEED<T>()
3908
+ table(_table: string) { this._table = _table; return this; }
3909
+ @IF_PROCEED<T>()
3910
+ distinct(on = true) { this._distinct = on; return this; }
3911
+ @IF_PROCEED<T>()
3912
+ countDistinct(key: keyof T, countName?: string,) { this._columns.push(`COUNT(DISTINCT ${this[_fields]![String(key)]?.C2()}) ${countName || `${this[_fields]![String(key)]?.C2()}`}`); return this; }
3913
+ @IF_PROCEED<T>()
3914
+ count(countName?: string) { this._columns.push(`COUNT(1) ${countName ?? 'ct'}`); return this; }
3915
+ @IF_PROCEED<T>()
3916
+ sum(key: keyof T, legName?: string, distinct?: boolean) { this._columns.push(`SUM(${distinct ? 'DISTINCT' : ''} ${this[_fields]![String(key)]?.C2()}) ${legName || `${this[_fields]![String(key)]?.C2()}`}`); return this; }
3917
+ @IF_PROCEED<T>()
3918
+ avg(key: keyof T, legName?: string, distinct?: boolean) { this._columns.push(`AVG(${distinct ? 'DISTINCT' : ''} ${this[_fields]![String(key)]?.C2()}) ${legName || `${this[_fields]![String(key)]?.C2()}`}`); return this; }
3919
+ @IF_PROCEED<T>()
3920
+ max(key: keyof T, legName?: string, distinct?: boolean) { this._columns.push(`MAX(${distinct ? 'DISTINCT' : ''} ${this[_fields]![String(key)]?.C2()}) ${legName || `${this[_fields]![String(key)]?.C2()}`}`); return this; }
3921
+ @IF_PROCEED<T>()
3922
+ min(key: keyof T, legName?: string, distinct?: boolean) { this._columns.push(`MIN(${distinct ? 'DISTINCT' : ''} ${this[_fields]![String(key)]?.C2()}) ${legName || `${this[_fields]![String(key)]?.C2()}`}`); return this; }
3923
+ @IF_PROCEED<T>()
3924
+ groupConcat(key: keyof T, param?: { distinct?: boolean, separator?: string, asc?: (keyof T)[], desc?: (keyof T)[], groupName?: string }): this {
3925
+ this._columns.push(`GROUP_CONCAT(
3926
+ ${param && param.distinct ? 'DISTINCT' : ''} ${this[_fields]![String(key)]?.C2()}
3927
+ ${param && param.asc && param.asc.length > 0 ? `ORDER BY ${param.asc.map(i => `${this[_fields]![String(i)]?.C2()} ASC`)} ` : ''}
3928
+ ${param && param.desc && param.desc.length > 0 ? `${param && param.asc && param.asc.length > 0 ? '' : 'ORDER BY'} ${param.desc.map(i => `${this[_fields]![String(i)]?.C2()} DESC`)} ` : ''}
3929
+ SEPARATOR '${param && param.separator || ','}'
3930
+ ) ${param && param.groupName || `${this[_fields]![String(key)]?.C2()}`}`);
3931
+ return this;
3932
+ }
3933
+ @IF_PROCEED<T>()
3934
+ select(...key: (keyof T)[]) { this._columns.push(...(key.map(k => this[_fields]![String(k)]!.C3()))); return this; }
3935
+ @IF_PROCEED<T>()
3936
+ select2(sql: string, param?: Record<string, any>) { this._columns.push(`${sql}`); Object.assign(this._param, param); return this; }
3937
+ @IF_PROCEED<T>()
3938
+ update(key: keyof T, value: T[keyof T]) { this._updates ??= {}; this._updates[key] = value; return this; }
3939
+ @IF_PROCEED<T>()
3940
+ update2(sql: string, param?: Record<string, any>) { this._updateColumns.push(sql); Object.assign(this._param, param); return this; }
3941
+ @IF_PROCEED<T>()
3942
+ updateT(t: Partial<T>) { this._updates ??= {}; Object.assign(this._updates, t); return this; }
3943
+ @IF_PROCEED<T>()
3944
+ replace(key: keyof T, valueToFind: T[keyof T], valueToReplace: T[keyof T]) {
3945
+ const [pkey1, pkey2] = [`p${this._prefix}${this._index++}`, `p${this._prefix}${this._index++}`];
3946
+ this._updateColumns.push(` ${this[_fields]![String(key)]?.C2()} = REPLACE(${this[_fields]![String(key)]?.C2()}, :${pkey1}, :${pkey2}) `);
3947
+ this._param[pkey1] = valueToFind as any;
3948
+ this._param[pkey2] = valueToReplace as any;
3949
+ return this;
3950
+ }
3951
+ // #endregion
3952
+
3953
+ excuteSelect<L = T>(option?: MethodOption & { sync?: SyncMode.Async; selectResult?: SelectResult.RS_CS | SelectResult.RS_C; hump?: boolean; mapper?: string | SqlMapper; mapperIfUndefined?: MapperIfUndefined; }): Promise<L[]>;
3954
+ excuteSelect<L = T>(option?: MethodOption & { sync?: SyncMode.Async; selectResult?: SelectResult.RS_CS_List | SelectResult.RS_C_List; hump?: boolean; mapper?: string | SqlMapper; mapperIfUndefined?: MapperIfUndefined; }): Promise<ArrayList<L>>;
3955
+ excuteSelect<L = T>(option: MethodOption & { sync?: SyncMode.Async; selectResult: SelectResult.R_CS_Assert | SelectResult.R_C_Assert; errorMsg?: string; hump?: boolean; mapper?: string | SqlMapper; mapperIfUndefined?: MapperIfUndefined; }): Promise<L>;
3956
+ excuteSelect<L = T>(option: MethodOption & { sync?: SyncMode.Async; selectResult: SelectResult.R_CS_NotSure | SelectResult.R_C_NotSure; hump?: boolean; mapper?: string | SqlMapper; mapperIfUndefined?: MapperIfUndefined; }): Promise<L | null>;
3957
+ excuteSelect<L = T>(option: MethodOption & { sync: SyncMode.Sync; selectResult: SelectResult.RS_CS | SelectResult.RS_C; hump?: boolean; mapper?: string | SqlMapper; mapperIfUndefined?: MapperIfUndefined; }): L[];
3958
+ excuteSelect<L = T>(option: MethodOption & { sync: SyncMode.Sync; selectResult: SelectResult.RS_CS_List | SelectResult.RS_C_List; hump?: boolean; mapper?: string | SqlMapper; mapperIfUndefined?: MapperIfUndefined; }): ArrayList<L>;
3959
+ excuteSelect<L = T>(option: MethodOption & { sync: SyncMode.Sync; selectResult: SelectResult.R_CS_Assert | SelectResult.R_C_Assert; errorMsg?: string; hump?: boolean; mapper?: string | SqlMapper; mapperIfUndefined?: MapperIfUndefined; }): L;
3960
+ excuteSelect<L = T>(option: MethodOption & { sync: SyncMode.Sync; selectResult: SelectResult.R_CS_NotSure | SelectResult.R_C_NotSure; hump?: boolean; mapper?: string | SqlMapper; mapperIfUndefined?: MapperIfUndefined; }): L | null;
3961
+ @IF_EXEC<T>(null)
3962
+ excuteSelect<L = T>(option?: MethodOption & { sync?: SyncMode; selectResult?: SelectResult; errorMsg?: string; hump?: boolean; mapper?: string | SqlMapper; mapperIfUndefined?: MapperIfUndefined; }): null | L | L[] | ArrayList<L> | Promise<null | L | L[] | ArrayList<L>> {
3963
+ option ??= {};
3964
+ option.sync ??= SyncMode.Async;
3965
+ option.selectResult ??= SelectResult.RS_CS;
3966
+ const { where, params } = this._where();
3967
+ let sql = `
3968
+ SELECT
3969
+ ${this._distinct ? 'DISTINCT' : ''} ${this._columns && this._columns.length > 0 ? this._columns.join(',') : this[_columns].map(key => this[_fields]![String(key)]?.C3()).join(',')}
3970
+ FROM ${this._table}
3971
+ ${where ? ' WHERE ' : ''}
3972
+ ${where}
3973
+ ${this._groups.length > 0 ? `GROUP BY ${this._groups.join(',')} ` : ''}
3974
+ ${this._orders.length > 0 ? `ORDER BY ${this._orders.join(',')} ` : ''}
3975
+ `;
3976
+ if (this._startRow && this._pageSize) {
3977
+ sql += `LIMIT ${this._startRow}, ${this._pageSize}`;
3978
+ } else if (this._startRow) {
3979
+ sql += `LIMIT ${this._startRow}`;
3980
+ }
3981
+ if (option.sync === SyncMode.Async) {
3982
+ switch (option.selectResult) {
3983
+ case SelectResult.RS_CS: return this._service.select<L>({ ...option, sync: SyncMode.Async, selectResult: SelectResult.RS_CS, sql, params });
3984
+ case SelectResult.RS_C: return this._service.select<L>({ ...option, sync: SyncMode.Async, selectResult: SelectResult.RS_C, sql, params });
3985
+ case SelectResult.RS_CS_List: return this._service.select<L>({ ...option, sync: SyncMode.Async, selectResult: SelectResult.RS_CS_List, sql, params });
3986
+ case SelectResult.RS_C_List: return this._service.select<L>({ ...option, sync: SyncMode.Async, selectResult: SelectResult.RS_C_List, sql, params });
3987
+ case SelectResult.R_CS_Assert: return this._service.select<L>({ ...option, sync: SyncMode.Async, selectResult: SelectResult.R_CS_Assert, sql, params });
3988
+ case SelectResult.R_C_Assert: return this._service.select<L>({ ...option, sync: SyncMode.Async, selectResult: SelectResult.R_C_Assert, sql, params });
3989
+ case SelectResult.R_CS_NotSure: return this._service.select<L>({ ...option, sync: SyncMode.Async, selectResult: SelectResult.R_CS_NotSure, sql, params });
3990
+ case SelectResult.R_C_NotSure: return this._service.select<L>({ ...option, sync: SyncMode.Async, selectResult: SelectResult.R_C_NotSure, sql, params });
3991
+ }
3992
+ } else {
3993
+ switch (option.selectResult) {
3994
+ case SelectResult.RS_CS: return this._service.select<L>({ ...option, sync: SyncMode.Sync, selectResult: SelectResult.RS_CS, sql, params });
3995
+ case SelectResult.RS_C: return this._service.select<L>({ ...option, sync: SyncMode.Sync, selectResult: SelectResult.RS_C, sql, params });
3996
+ case SelectResult.RS_CS_List: return this._service.select<L>({ ...option, sync: SyncMode.Sync, selectResult: SelectResult.RS_CS_List, sql, params });
3997
+ case SelectResult.RS_C_List: return this._service.select<L>({ ...option, sync: SyncMode.Sync, selectResult: SelectResult.RS_C_List, sql, params });
3998
+ case SelectResult.R_CS_Assert: return this._service.select<L>({ ...option, sync: SyncMode.Sync, selectResult: SelectResult.R_CS_Assert, sql, params });
3999
+ case SelectResult.R_C_Assert: return this._service.select<L>({ ...option, sync: SyncMode.Sync, selectResult: SelectResult.R_C_Assert, sql, params });
4000
+ case SelectResult.R_CS_NotSure: return this._service.select<L>({ ...option, sync: SyncMode.Sync, selectResult: SelectResult.R_CS_NotSure, sql, params });
4001
+ case SelectResult.R_C_NotSure: return this._service.select<L>({ ...option, sync: SyncMode.Sync, selectResult: SelectResult.R_C_NotSure, sql, params });
4002
+ }
4003
+ }
4004
+ }
4005
+ @IF_EXEC<T>(null)
4006
+ excutePage<L = T>(option?: MethodOption & { sync?: SyncMode; hump?: boolean; mapper?: string | SqlMapper; mapperIfUndefined?: MapperIfUndefined; }): PageQuery<L> | Promise<PageQuery<L>> {
4007
+ option ??= {};
4008
+ option.sync ??= SyncMode.Async;
4009
+ const { where, params } = this._where();
4010
+ const result: PageQuery<L> = {
4011
+ records: [],
4012
+ size: 0,
4013
+ total: 0
4014
+ };
4015
+ let sql = `
4016
+ SELECT
4017
+ ${this._distinct ? 'DISTINCT' : ''} ${this._columns && this._columns.length > 0 ? this._columns.join(',') : this[_columns].map(key => this[_fields]![String(key)]?.C3()).join(',')}
4018
+ FROM ${this._table}
4019
+ ${where ? ' WHERE ' : ''}
4020
+ ${where}
4021
+ ${this._groups.length > 0 ? `GROUP BY ${this._groups.join(',')} ` : ''}
4022
+ ${this._orders.length > 0 ? `ORDER BY ${this._orders.join(',')} ` : ''}
4023
+ `;
4024
+ if (this._startRow && this._pageSize) {
4025
+ sql += `LIMIT ${this._startRow}, ${this._pageSize}`;
4026
+ } else if (this._startRow) {
4027
+ sql += `LIMIT ${this._startRow}`;
4028
+ }
4029
+ const sqlCount = `
4030
+ SELECT COUNT(1)
4031
+ FROM ${this._table}
4032
+ ${where ? ' WHERE ' : ''}
4033
+ ${where}
4034
+ ${this._groups.length > 0 ? `GROUP BY ${this._groups.join(',')} ` : ''}
4035
+ ${this._orders.length > 0 ? `ORDER BY ${this._orders.join(',')} ` : ''}
4036
+ `;
4037
+ if (option.sync === SyncMode.Sync) {
4038
+ result.total = this._service.select<number>({
4039
+ ...option,
4040
+ params,
4041
+ sql: sqlCount,
4042
+ sync: SyncMode.Sync,
4043
+ selectResult: SelectResult.R_C_Assert
4044
+ });
4045
+ result.size = calc(result.total)
4046
+ .add(this._pageSize - 1)
4047
+ .div(this._pageSize)
4048
+ .round(0, 2)
4049
+ .over();
4050
+ result.records = this._service.select<L>({
4051
+ ...option,
4052
+ params,
4053
+ sql,
4054
+ sync: SyncMode.Sync,
4055
+ selectResult: SelectResult.RS_CS
4056
+ });
4057
+ return result;
4058
+ } else {
4059
+ return new Promise<PageQuery<L>>(async (resolve, reject) => {
4060
+ try {
4061
+ result.total = await this._service.select<number>({
4062
+ ...option,
4063
+ params,
4064
+ sql: sqlCount,
4065
+ sync: SyncMode.Async,
4066
+ selectResult: SelectResult.R_C_Assert
4067
+ });
4068
+ result.size = calc(result.total)
4069
+ .add(this._pageSize - 1)
4070
+ .div(this._pageSize)
4071
+ .round(0, 2)
4072
+ .over();
4073
+ result.records = await this._service.select<L>({
4074
+ ...option,
4075
+ params,
4076
+ sql,
4077
+ sync: SyncMode.Async,
4078
+ selectResult: SelectResult.RS_CS
4079
+ });
4080
+ resolve(result);
4081
+ } catch (error) {
4082
+ reject(error);
4083
+ }
4084
+ });
4085
+ }
4086
+ }
4087
+ excuteUpdate(option?: MethodOption & { sync?: SyncMode.Async }): Promise<number>;
4088
+ excuteUpdate(option: MethodOption & { sync: SyncMode.Sync }): number;
4089
+ @IF_EXEC<T>(0)
4090
+ excuteUpdate(option?: MethodOption & { sync?: SyncMode }): number | Promise<number> {
4091
+ option ??= {};
4092
+ option.sync ??= SyncMode.Async;
4093
+ const { where, params } = this._where();
4094
+ const sets = new Array<string>(...this._updateColumns);
4095
+ if (this._updates) {
4096
+ for (const [K, V] of Object.entries(this._updates)) {
4097
+ const pkey = `p${this._prefix}${this._index++}`;
4098
+ sets.push(` ${K} = :${pkey} `);
4099
+ params[pkey] = V;
4100
+ }
4101
+ }
4102
+ if (sets.length > 0) {
4103
+ const sql = `UPDATE ${this._table} SET ${sets.join(',')} ${where}`;
4104
+ if (option.sync === SyncMode.Async) {
4105
+ return this._service.excute({ sync: SyncMode.Async, sql, params });
4106
+ } else {
4107
+ return this._service.excute({ sync: SyncMode.Sync, sql, params });
4108
+ }
4109
+ } else {
4110
+ return 0;
4111
+ }
4112
+ }
4113
+ excuteDelete(option?: MethodOption & { sync?: SyncMode.Async }): Promise<number>;
4114
+ excuteDelete(option: MethodOption & { sync: SyncMode.Sync }): number;
4115
+ @IF_EXEC<T>(0)
4116
+ excuteDelete(option?: MethodOption & { sync?: SyncMode }): number | Promise<number> {
4117
+ option ??= {};
4118
+ option.sync ??= SyncMode.Async;
4119
+ const { where, params } = this._where();
4120
+ const sql = `DELETE FROM ${this._table} ${where}`;
4121
+ if (option.sync === SyncMode.Async) {
4122
+ return this._service.excute({ sync: SyncMode.Async, sql, params });
4123
+ } else {
4124
+ return this._service.excute({ sync: SyncMode.Sync, sql, params });
4125
+ }
4126
+ }
4127
+ private _where() {
3224
4128
  const wheres = new Array<string>();
3225
4129
  const sql = this._wheres.join(' ');
3226
4130
  if (sql) {
3227
- wheres.push(`(${sql})`);
4131
+ wheres.push(`(${sql.replace(/^and|^or/i, '')})`);
3228
4132
  }
3229
4133
  if (this._orQuerys.length > 0) {
3230
4134
  for (const query of this._orQuerys) {
3231
- const { where, params } = query.where();
4135
+ const { where, params } = query._where();
3232
4136
  if (where) {
3233
4137
  wheres.push(` OR (${where}) `);
3234
4138
  }
@@ -3237,7 +4141,7 @@ class StreamCondition<T extends object> {
3237
4141
  }
3238
4142
  if (this._andQuerys.length > 0) {
3239
4143
  for (const query of this._andQuerys) {
3240
- const { where, params } = query.where();
4144
+ const { where, params } = query._where();
3241
4145
  if (where) {
3242
4146
  wheres.push(` AND (${where}) `);
3243
4147
  }
@@ -3246,288 +4150,198 @@ class StreamCondition<T extends object> {
3246
4150
  }
3247
4151
  return { where: wheres.join(' '), params: this._param };
3248
4152
  }
3249
- private _(key: keyof T, value: any, op: string, { not = '', name = '' } = {}) {
3250
- if (name !== undefined && this._paramKeys.hasOwnProperty(name)) {
3251
- this._param[this._paramKeys[name] as string] = value;
4153
+ private _(key: keyof T, value: any, op: string, { not = '', paramName = '', skipEmptyString = true, breakExcuteIfSkip = false } = {}) {
4154
+ if (
4155
+ value === null
4156
+ || value === undefined
4157
+ || (emptyString(`${value ?? ''}`) && skipEmptyString === true)
4158
+ ) {
4159
+ if (breakExcuteIfSkip === true) {
4160
+ this.if_exec = false;
4161
+ }
4162
+ return this;
4163
+ }
4164
+ if (paramName !== undefined && this._paramKeys.hasOwnProperty(paramName)) {
4165
+ this._param[this._paramKeys[paramName] as string] = value;
3252
4166
  } else {
4167
+ paramName
3253
4168
  const pkey = `p${this._prefix}${this._index++}`;
3254
- this._wheres.push(`AND ${String(key)} ${not} ${op} :${pkey} `);
4169
+ this._wheres.push(`AND ${this[_fields]![String(key)]?.C2()} ${not} ${op} :${pkey} `);
3255
4170
  this._param[pkey] = value;
3256
- if (name) {
3257
- this._paramKeys[name] = pkey;
4171
+ if (paramName) {
4172
+ this._paramKeys[paramName] = pkey;
3258
4173
  }
3259
4174
  }
3260
4175
  return this;
3261
4176
  }
3262
4177
  private _null(key: keyof T, not = ''): this {
3263
- this._wheres.push(`AND ${String(key)} is ${not} null`);
4178
+ this._wheres.push(`AND ${this[_fields]![String(key)]?.C2()} IS ${not} NULL`);
3264
4179
  return this;
3265
4180
  }
3266
4181
  private _key(key1: keyof T, key2: keyof T, op: string, not = '') {
3267
- this._wheres.push(`AND ${String(key1)} ${not} ${op} ${String(key2)} `);
4182
+ this._wheres.push(`AND ${this[_fields]![String(key1)]?.C2()} ${not} ${op} ${this[_fields]![String(key2)]?.C2()} `);
3268
4183
  return this;
3269
4184
  }
3270
- private _between(key: keyof T, value1: string | number, value2: string | number, { not = '', name = '' } = {}) {
3271
- if (name && this._paramKeys[name]) {
3272
- this._param[this._paramKeys[name]![0]] = value1;
3273
- this._param[this._paramKeys[name]![1]] = value2;
4185
+ private _between(key: keyof T, value1: string | number, value2: string | number, { not = '', paramName = '', skipEmptyString = true, breakExcuteIfSkip = false } = {}) {
4186
+ if (
4187
+ value1 === null
4188
+ || value1 === undefined
4189
+ || (emptyString(`${value1 ?? ''}`) && skipEmptyString === true)
4190
+ || value2 === null
4191
+ || value2 === undefined
4192
+ || (emptyString(`${value2 ?? ''}`) && skipEmptyString === true)
4193
+ ) {
4194
+ if (breakExcuteIfSkip === true) {
4195
+ this.if_exec = false;
4196
+ }
4197
+ return this;
4198
+ }
4199
+ if (paramName && this._paramKeys[paramName]) {
4200
+ this._param[this._paramKeys[paramName]![0]] = value1;
4201
+ this._param[this._paramKeys[paramName]![1]] = value2;
3274
4202
  } else {
3275
4203
  const [pkey1, pkey2] = [`p${this._prefix}${this._index++}`, `p${this._prefix}${this._index++}`];
3276
- this._wheres.push(`AND ${String(key)} ${not} BETWEEN :${pkey1} AND :${pkey2}`);
4204
+ this._wheres.push(`AND ${this[_fields]![String(key)]?.C2()} ${not} BETWEEN :${pkey1} AND :${pkey2}`);
3277
4205
  this._param[pkey1] = value1;
3278
4206
  this._param[pkey2] = value2;
3279
- if (name) {
3280
- this._paramKeys[name] = [pkey1, pkey2];
4207
+ if (paramName) {
4208
+ this._paramKeys[paramName] = [pkey1, pkey2];
3281
4209
  }
3282
4210
  }
3283
4211
  return this;
3284
4212
  }
3285
- private _in(key: keyof T, value: any, { not = '', name = '', force = false } = {}) {
4213
+ private _in(key: keyof T, value: any, { not = '', paramName = '', skipEmptyString = true, breakExcuteIfSkip = false } = {}) {
3286
4214
  if (value && value.length > 0) {
3287
- if (name !== undefined && this._paramKeys.hasOwnProperty(name)) {
3288
- this._param[this._paramKeys[name] as string] = value;
4215
+ if (paramName !== undefined && this._paramKeys.hasOwnProperty(paramName)) {
4216
+ this._param[this._paramKeys[paramName] as string] = value;
3289
4217
  } else {
3290
4218
  const pkey = `p${this._prefix}${this._index++}`;
3291
- this._wheres.push(`AND ${String(key)} ${not} IN (:${pkey}) `);
4219
+ this._wheres.push(`AND ${this[_fields]![String(key)]?.C2()} ${not} IN (:${pkey}) `);
3292
4220
  this._param[pkey] = value;
3293
- if (name) {
3294
- this._paramKeys[name] = pkey;
4221
+ if (paramName) {
4222
+ this._paramKeys[paramName] = pkey;
3295
4223
  }
3296
4224
  }
3297
- } else if (force !== true) {
4225
+ } else if (breakExcuteIfSkip !== true) {
3298
4226
  this.if_exec = false;
3299
4227
  }
3300
4228
  return this;
3301
4229
  }
3302
- private _shift(key1: keyof T, key2: keyof T, value: number, op: string, { not = '', name = '' } = {}) {
3303
- if (name !== undefined && this._paramKeys.hasOwnProperty(name)) {
3304
- this._param[this._paramKeys[name] as string] = value;
3305
- } else {
3306
- const pkey = `p${this._prefix}${this._index++}`;
3307
- this._wheres.push(`AND (${String(key1)} << 8) + ${String(key2)} ${not} ${op} :${pkey} `);
3308
- this._param[pkey] = value;
3309
- if (name) {
3310
- this._paramKeys[name] = pkey;
4230
+ private _shift(key1: keyof T, key2: keyof T, value: number, op: string, { not = '', paramName = '', breakExcuteIfSkip = false } = {}) {
4231
+ if (
4232
+ value === null
4233
+ || value === undefined
4234
+ || emptyString(`${value ?? ''}`)
4235
+ ) {
4236
+ if (breakExcuteIfSkip === true) {
4237
+ this.if_exec = false;
3311
4238
  }
4239
+ return this;
3312
4240
  }
3313
- return this;
3314
- }
3315
- private _match(value: string, keys: (keyof T)[], { name, not, append }: { name?: string; not?: string; append?: string; } = {}) {
3316
- if (name !== undefined && this._paramKeys.hasOwnProperty(name)) {
3317
- this._param[this._paramKeys[name] as string] = value;
4241
+ if (paramName !== undefined && this._paramKeys.hasOwnProperty(paramName)) {
4242
+ this._param[this._paramKeys[paramName] as string] = value;
3318
4243
  } else {
3319
4244
  const pkey = `p${this._prefix}${this._index++}`;
3320
- this._wheres.push(`AND MATCH(${keys.join(',')}) AGAINST (:${pkey} ${append ?? ''})`);
4245
+ this._wheres.push(`AND (${this[_fields]![String(key1)]?.C2()} << 8) + ${this[_fields]![String(key2)]?.C2()} ${not} ${op} :${pkey} `);
3321
4246
  this._param[pkey] = value;
3322
- if (name) {
3323
- this._paramKeys[name] = pkey;
4247
+ if (paramName) {
4248
+ this._paramKeys[paramName] = pkey;
3324
4249
  }
3325
4250
  }
3326
4251
  return this;
3327
4252
  }
3328
- private _pow(key: keyof T, value: number, { name }: { name?: string; not?: string; } = {}) {
3329
- if (name !== undefined && this._paramKeys.hasOwnProperty(name)) {
3330
- this._param[this._paramKeys[name] as string] = value;
4253
+ private _match(value: string, keys: (keyof T)[], { paramName = '', not = '', append = '', skipEmptyString = true, breakExcuteIfSkip = false } = {}) {
4254
+ if (
4255
+ value === null
4256
+ || value === undefined
4257
+ || emptyString(`${value ?? ''}`)
4258
+ ) {
4259
+ if (breakExcuteIfSkip === true) {
4260
+ this.if_exec = false;
4261
+ }
4262
+ return this;
4263
+ }
4264
+ if (paramName !== undefined && this._paramKeys.hasOwnProperty(paramName)) {
4265
+ this._param[this._paramKeys[paramName] as string] = value;
3331
4266
  } else {
3332
4267
  const pkey = `p${this._prefix}${this._index++}`;
3333
- this._wheres.push(`AND NOT POW(2, ${String(key)}) & :${pkey}`);
4268
+ this._wheres.push(`AND ${not} MATCH(${keys.map(key => this[_fields]![String(key)]?.C2()).join(',')}) AGAINST (:${pkey} ${append ?? ''})`);
3334
4269
  this._param[pkey] = value;
3335
- if (name) {
3336
- this._paramKeys[name] = pkey;
4270
+ if (paramName) {
4271
+ this._paramKeys[paramName] = pkey;
3337
4272
  }
3338
4273
  }
3339
4274
  return this;
3340
4275
  }
3341
- private _like(key: keyof T, value: any, { not = '', left = '', right = '', name = '', op = 'LIKE', force = false } = {}) {
3342
- if (value !== null && value !== undefined && value !== '') {
3343
- if (name !== undefined && this._paramKeys.hasOwnProperty(name)) {
3344
- this._param[this._paramKeys[name] as string] = value;
3345
- } else {
3346
- const pkey = `p${this._prefix}${this._index++}`;
3347
- this._wheres.push(`AND ${String(key)} ${not} ${op} CONCAT('${left}', :${pkey}, '${right}') `);
3348
- this._param[pkey] = value;
3349
- if (name) {
3350
- this._paramKeys[name] = pkey;
3351
- }
4276
+ private _pow(key: keyof T, value: number, { not = '', paramName = '', breakExcuteIfSkip = false } = {}) {
4277
+ if (
4278
+ value === null
4279
+ || value === undefined
4280
+ || emptyString(`${value ?? ''}`)
4281
+ ) {
4282
+ if (breakExcuteIfSkip === true) {
4283
+ this.if_exec = false;
3352
4284
  }
3353
- } else if (force !== true) {
3354
- this.if_exec = false;
4285
+ return this;
3355
4286
  }
3356
- return this;
3357
- }
3358
- private _includes(key: keyof T, value: any, { not = '', name = '' } = {}) {
3359
- if (name !== undefined && this._paramKeys.hasOwnProperty(name)) {
3360
- this._param[this._paramKeys[name] as string] = value;
4287
+ if (paramName !== undefined && this._paramKeys.hasOwnProperty(paramName)) {
4288
+ this._param[this._paramKeys[paramName] as string] = value;
3361
4289
  } else {
3362
4290
  const pkey = `p${this._prefix}${this._index++}`;
3363
- this._wheres.push(`AND LOCATE(${String(key)}, :${pkey}) ${not ? '=' : ''} 0`);
4291
+ this._wheres.push(`AND ${not} POW(2, ${this[_fields]![String(key)]?.C2()}) & :${pkey}`);
3364
4292
  this._param[pkey] = value;
3365
- if (name) {
3366
- this._paramKeys[name] = pkey;
4293
+ if (paramName) {
4294
+ this._paramKeys[paramName] = pkey;
3367
4295
  }
3368
4296
  }
3369
4297
  return this;
3370
4298
  }
3371
- }
3372
- class StreamBuild<T extends object> extends StreamCondition<T>{
3373
- protected _table: string;
3374
-
3375
- protected _distinct = false;
3376
- protected _columns: string[] = [];
3377
-
3378
- protected _updates?: Partial<T>;
3379
- protected _updateColumns: string[] = [];
3380
-
3381
- protected _groups: (keyof T)[] = [];
3382
- protected _orders: string[] = [];
3383
-
3384
- protected _startRow = 0;
3385
- protected _pageSize = 0;
3386
-
3387
- constructor(table: string) {
3388
- super();
3389
- this._table = table;
3390
- }
3391
- /** 将当前stream重置 */
3392
- reset() {
3393
- super.reset();
3394
- this._pageSize = 0;
3395
- this._startRow = 0;
3396
- this._orders.length = 0;
3397
- this._groups.length = 0;
3398
- this._columns.length = 0;
3399
- this._updateColumns.length = 0;
3400
- return this;
3401
- }
3402
- @IF_PROCEED<T>()
3403
- groupBy(key: keyof T) { this._groups.push(key); return this; }
3404
- @IF_PROCEED<T>()
3405
- asc(...keys: (keyof T)[]) { this._orders.push(...keys.map(key => `${String(key)} ASC`)); return this; }
3406
- @IF_PROCEED<T>()
3407
- desc(...keys: (keyof T)[]) { this._orders.push(...keys.map(key => `${String(key)} DESC`)); return this; }
3408
- @IF_PROCEED<T>()
3409
- limit(startRow: number, pageSize: number) { this._startRow = startRow; this._pageSize = pageSize; return this; }
3410
- @IF_PROCEED<T>()
3411
- page(pageNumber: number, pageSize: number) { this._startRow = ((pageNumber || 1) - 1) * pageSize; this._pageSize = pageSize; return this; }
3412
- @IF_PROCEED<T>()
3413
- table(_table: string) { this._table = _table; return this; }
3414
- @IF_PROCEED<T>()
3415
- distinct(on = true) { this._distinct = on; return this; }
3416
- @IF_PROCEED<T>()
3417
- count(key: keyof T, countName?: string, distinct?: boolean) { this._columns.push(`COUNT(${distinct ? 'DISTINCT' : ''} ${String(key)}) ${countName || `${String(key)}`}`); return this; }
3418
- @IF_PROCEED<T>()
3419
- sum(key: keyof T, legName?: string, distinct?: boolean) { this._columns.push(`SUM(${distinct ? 'DISTINCT' : ''} ${String(key)}) ${legName || `${String(key)}`}`); return this; }
3420
- @IF_PROCEED<T>()
3421
- avg(key: keyof T, legName?: string, distinct?: boolean) { this._columns.push(`AVG(${distinct ? 'DISTINCT' : ''} ${String(key)}) ${legName || `${String(key)}`}`); return this; }
3422
- @IF_PROCEED<T>()
3423
- max(key: keyof T, legName?: string, distinct?: boolean) { this._columns.push(`MAX(${distinct ? 'DISTINCT' : ''} ${String(key)}) ${legName || `${String(key)}`}`); return this; }
3424
- @IF_PROCEED<T>()
3425
- min(key: keyof T, legName?: string, distinct?: boolean) { this._columns.push(`MIN(${distinct ? 'DISTINCT' : ''} ${String(key)}) ${legName || `${String(key)}`}`); return this; }
3426
- @IF_PROCEED<T>()
3427
- groupConcat(key: keyof T, param?: { distinct?: boolean, separator?: string, asc?: (keyof T)[], desc?: (keyof T)[], groupName?: string }): this {
3428
- this._columns.push(`GROUP_CONCAT(
3429
- ${param && param.distinct ? 'DISTINCT' : ''} ${String(key)}
3430
- ${param && param.asc && param.asc.length > 0 ? `ORDER BY ${param.asc.map(i => `${String(i)} ASC`)} ` : ''}
3431
- ${param && param.desc && param.desc.length > 0 ? `${param && param.asc && param.asc.length > 0 ? '' : 'ORDER BY'} ${param.desc.map(i => `${String(i)} DESC`)} ` : ''}
3432
- SEPARATOR '${param && param.separator || ','}'
3433
- ) ${param && param.groupName || `${String(key)}`}`);
3434
- return this;
3435
- }
3436
- @IF_PROCEED<T>()
3437
- selectColumn(...key: (keyof T)[]) { this._columns.push(...(key.map(k => k as string))); return this; }
3438
- @IF_PROCEED<T>()
3439
- updateColumn(key: keyof T, value: T[keyof T]) { this._updates ??= {}; this._updates[key] = value; return this; }
3440
- @IF_PROCEED<T>()
3441
- updateT(t: Partial<T>) { this._updates ??= {}; Object.assign(this._updates, t); return this; }
3442
- @IF_PROCEED<T>()
3443
- replace(key: keyof T, valueToFind: T[keyof T], valueToReplace: T[keyof T]) {
3444
- const [pkey1, pkey2] = [`p${this._prefix}${this._index++}`, `p${this._prefix}${this._index++}`];
3445
- this._updateColumns.push(` ${String(key)} = REPLACE(${String(key)}, :${pkey1}, :${pkey2}) `);
3446
- this._param[pkey1] = valueToFind as any;
3447
- this._param[pkey2] = valueToReplace as any;
3448
- return this;
3449
- }
3450
- }
3451
- class StreamQuery<T extends object> extends StreamBuild<T>{
3452
- private _service: SqlService<T>;
3453
- constructor(table: string, service: SqlService<T>) {
3454
- super(table);
3455
- this._service = service;
3456
- }
3457
- select<L = T>(option: { sync?: SyncMode.Async; selectResult: SelectResult.Many_Row_Many_Column | SelectResult.Many_Row_One_Column; }): Promise<L[]>;
3458
- select<L = T>(option: { sync?: SyncMode.Async; selectResult: SelectResult.One_Row_Many_Column_Assert | SelectResult.One_Row_One_Column_Assert; errorMsg?: string; }): Promise<L>;
3459
- select<L = T>(option: { sync?: SyncMode.Async; selectResult: SelectResult.One_Row_Many_Column_NotSure | SelectResult.One_Row_One_Column_NotSure; }): Promise<L | null>;
3460
- select<L = T>(option: { sync: SyncMode.Sync; selectResult: SelectResult.Many_Row_Many_Column | SelectResult.Many_Row_One_Column; }): L[];
3461
- select<L = T>(option: { sync: SyncMode.Sync; selectResult: SelectResult.One_Row_Many_Column_Assert | SelectResult.One_Row_One_Column_Assert; errorMsg?: string; }): L;
3462
- select<L = T>(option: { sync: SyncMode.Sync; selectResult: SelectResult.One_Row_Many_Column_NotSure | SelectResult.One_Row_One_Column_NotSure; }): L | null;
3463
- @IF_EXEC<T>(null)
3464
- select<L = T>(option: { sync?: SyncMode; selectResult: SelectResult; errorMsg?: string; }): null | L | L[] | Promise<null | L | L[]> {
3465
- option.sync ??= SyncMode.Async;
3466
- const { where, params } = this.where();
3467
- const sql = `
3468
- SELECT
3469
- ${this._columns && this._columns.length > 0 ? this._columns.join(',') : '*'}
3470
- FROM ${this._table}
3471
- ${where ? ' WHERE ' : ''}
3472
- ${where}`;
3473
-
3474
- if (option.sync === SyncMode.Async) {
3475
- switch (option.selectResult) {
3476
- case SelectResult.Many_Row_Many_Column: return this._service.select<L>({ sync: SyncMode.Async, selectResult: SelectResult.Many_Row_Many_Column, errorMsg: option.errorMsg, sql, params });
3477
- case SelectResult.Many_Row_One_Column: return this._service.select<L>({ sync: SyncMode.Async, selectResult: SelectResult.Many_Row_One_Column, errorMsg: option.errorMsg, sql, params });
3478
- case SelectResult.One_Row_Many_Column_Assert: return this._service.select<L>({ sync: SyncMode.Async, selectResult: SelectResult.One_Row_Many_Column_Assert, errorMsg: option.errorMsg, sql, params });
3479
- case SelectResult.One_Row_One_Column_Assert: return this._service.select<L>({ sync: SyncMode.Async, selectResult: SelectResult.One_Row_One_Column_Assert, errorMsg: option.errorMsg, sql, params });
3480
- case SelectResult.One_Row_Many_Column_NotSure: return this._service.select<L>({ sync: SyncMode.Async, selectResult: SelectResult.One_Row_Many_Column_NotSure, errorMsg: option.errorMsg, sql, params });
3481
- case SelectResult.One_Row_One_Column_NotSure: return this._service.select<L>({ sync: SyncMode.Async, selectResult: SelectResult.One_Row_One_Column_NotSure, errorMsg: option.errorMsg, sql, params });
4299
+ private _like(key: keyof T, value: any, { not = '', left = '', right = '', paramName = '', op = 'LIKE', skipEmptyString = true, breakExcuteIfSkip = false } = {}) {
4300
+ if (
4301
+ value === null
4302
+ || value === undefined
4303
+ || (emptyString(`${value ?? ''}`) && skipEmptyString === true)
4304
+ ) {
4305
+ if (breakExcuteIfSkip === true) {
4306
+ this.if_exec = false;
3482
4307
  }
4308
+ return this;
4309
+ }
4310
+
4311
+ if (paramName !== undefined && this._paramKeys.hasOwnProperty(paramName)) {
4312
+ this._param[this._paramKeys[paramName] as string] = value;
3483
4313
  } else {
3484
- switch (option.selectResult) {
3485
- case SelectResult.Many_Row_Many_Column: return this._service.select<L>({ sync: SyncMode.Sync, selectResult: SelectResult.Many_Row_Many_Column, errorMsg: option.errorMsg, sql, params });
3486
- case SelectResult.Many_Row_One_Column: return this._service.select<L>({ sync: SyncMode.Sync, selectResult: SelectResult.Many_Row_One_Column, errorMsg: option.errorMsg, sql, params });
3487
- case SelectResult.One_Row_Many_Column_Assert: return this._service.select<L>({ sync: SyncMode.Sync, selectResult: SelectResult.One_Row_Many_Column_Assert, errorMsg: option.errorMsg, sql, params });
3488
- case SelectResult.One_Row_One_Column_Assert: return this._service.select<L>({ sync: SyncMode.Sync, selectResult: SelectResult.One_Row_One_Column_Assert, errorMsg: option.errorMsg, sql, params });
3489
- case SelectResult.One_Row_Many_Column_NotSure: return this._service.select<L>({ sync: SyncMode.Sync, selectResult: SelectResult.One_Row_Many_Column_NotSure, errorMsg: option.errorMsg, sql, params });
3490
- case SelectResult.One_Row_One_Column_NotSure: return this._service.select<L>({ sync: SyncMode.Sync, selectResult: SelectResult.One_Row_One_Column_NotSure, errorMsg: option.errorMsg, sql, params });
4314
+ const pkey = `p${this._prefix}${this._index++}`;
4315
+ this._wheres.push(`AND ${this[_fields]![String(key)]?.C2()} ${not} ${op} CONCAT('${left}', :${pkey}, '${right}') `);
4316
+ this._param[pkey] = value;
4317
+ if (paramName) {
4318
+ this._paramKeys[paramName] = pkey;
3491
4319
  }
3492
4320
  }
4321
+ return this;
3493
4322
  }
3494
- update(option: { sync?: SyncMode.Async }): Promise<number>;
3495
- update(option: { sync: SyncMode.Sync }): number;
3496
- @IF_EXEC<T>(0)
3497
- update(option: { sync?: SyncMode }): number | Promise<number> {
3498
- option.sync ??= SyncMode.Async;
3499
- const { where, params } = this.where();
3500
- const sets = new Array<string>(...this._updateColumns);
3501
- if (this._updates) {
3502
- for (const [K, V] of Object.entries(this._updates)) {
3503
- const pkey = `p${this._prefix}${this._index++}`;
3504
- sets.push(` ${K} = :${pkey} `);
3505
- params[pkey] = V;
4323
+ private _includes(key: keyof T, value: any, { not = '', paramName = '', skipEmptyString = true, breakExcuteIfSkip = true } = {}) {
4324
+ if (
4325
+ value === null
4326
+ || value === undefined
4327
+ || (emptyString(`${value ?? ''}`) && skipEmptyString === true)
4328
+ ) {
4329
+ if (breakExcuteIfSkip === true) {
4330
+ this.if_exec = false;
3506
4331
  }
4332
+ return this;
3507
4333
  }
3508
- if (sets.length > 0) {
3509
- const sql = `UPDATE ${this._table} SET ${sets.join(',')} ${where}`;
3510
- if (option.sync === SyncMode.Async) {
3511
- return this._service.excute({ sync: SyncMode.Async, sql, params });
3512
- } else {
3513
- return this._service.excute({ sync: SyncMode.Sync, sql, params });
3514
- }
3515
- } else {
3516
- return 0;
3517
- }
3518
- }
3519
- delete(option: { sync?: SyncMode.Async }): Promise<number>;
3520
- delete(option: { sync: SyncMode.Sync }): number;
3521
- @IF_EXEC<T>(0)
3522
- delete(option: { sync?: SyncMode }): number | Promise<number> {
3523
- option.sync ??= SyncMode.Async;
3524
- const { where, params } = this.where();
3525
- const sql = `DELETE FROM ${this._table} ${where}`;
3526
- if (option.sync === SyncMode.Async) {
3527
- return this._service.excute({ sync: SyncMode.Async, sql, params });
4334
+ if (paramName !== undefined && this._paramKeys.hasOwnProperty(paramName)) {
4335
+ this._param[this._paramKeys[paramName] as string] = value;
3528
4336
  } else {
3529
- return this._service.excute({ sync: SyncMode.Sync, sql, params });
4337
+ const pkey = `p${this._prefix}${this._index++}`;
4338
+ this._wheres.push(`AND LOCATE(${this[_fields]![String(key)]?.C2()}, :${pkey}) ${not ? '=' : '>'} 0`);
4339
+ this._param[pkey] = value;
4340
+ if (paramName) {
4341
+ this._paramKeys[paramName] = pkey;
4342
+ }
3530
4343
  }
4344
+ return this;
3531
4345
  }
3532
4346
  }
3533
4347
  /**
@@ -3535,11 +4349,15 @@ class StreamQuery<T extends object> extends StreamBuild<T>{
3535
4349
  # [查看库的API](https://github.com/redis/ioredis?tab=readme-ov-file)
3536
4350
  # [REDIS API](http://doc.redisfans.com/)
3537
4351
  REDIS 的API 可以直接用,将方法名转为小写
4352
+ ```
4353
+ // 设置<Redis>来获得代码提示
4354
+ getRedisDB<Redis>('').exists(?)
4355
+ ```
3538
4356
  */
3539
- export function getRedisDB(db?: string) {
4357
+ export function getRedisDB<T = any>(db?: string): T {
3540
4358
  const rd = globalThis[_dao][DBType.Redis][db ?? _primaryDB];
3541
4359
  Throw.if(!rd, 'not found redis!');
3542
- return rd;
4360
+ return rd as T;
3543
4361
  }
3544
4362
  /**
3545
4363
  redlock
@@ -3776,13 +4594,12 @@ export function MethodCache<T = any>(config: {
3776
4594
  };
3777
4595
  };
3778
4596
  }
3779
-
3780
4597
  class MUParser {
3781
4598
  static END = 1;
3782
4599
  private modelName: string;
3783
4600
  private linNumber = 0;
3784
- private lastLine?: string;
3785
- private lastlastLine?: string;
4601
+ private lastLine: string = '';
4602
+ private lastlastLine: string = '';
3786
4603
  private status = 0;
3787
4604
  private lineSeparator = '\n';
3788
4605
  private files: string[];
@@ -3792,8 +4609,8 @@ class MUParser {
3792
4609
  this.skipHeader();
3793
4610
  }
3794
4611
  next(): [string, string] | null {
3795
- let sqlId: string | undefined = this.readSqlId();
3796
- if (this.status === MUParser.END || !sqlId) {
4612
+ let sqlId: string = this.readSqlId();
4613
+ if (this.status === MUParser.END) {
3797
4614
  return null;
3798
4615
  }
3799
4616
  // 去掉可能的尾部空格
@@ -3807,14 +4624,17 @@ class MUParser {
3807
4624
  }
3808
4625
  private skipHeader(): void {
3809
4626
  while (true) {
3810
- const line: string | undefined = this.nextLine();
3811
- if (!line) { return; }
3812
- if (this.status === MUParser.END) { return; }
3813
- if (line.startsWith('===')) { return; }
4627
+ const line: string = this.nextLine();
4628
+ if (this.status === MUParser.END) {
4629
+ return;
4630
+ }
4631
+ if (line.startsWith('===')) {
4632
+ return;
4633
+ }
3814
4634
  }
3815
4635
  }
3816
- private nextLine(): string | undefined {
3817
- const line: string | undefined = this.files[this.linNumber];
4636
+ private nextLine(): string {
4637
+ const line: string = this.files[this.linNumber]!;
3818
4638
  this.linNumber++;
3819
4639
  if (line === undefined) {
3820
4640
  this.status = MUParser.END;
@@ -3824,14 +4644,14 @@ class MUParser {
3824
4644
  this.lastLine = line;
3825
4645
  return line;
3826
4646
  }
3827
- private readSqlId(): string | undefined {
4647
+ private readSqlId(): string {
3828
4648
  return this.lastlastLine;
3829
4649
  }
3830
4650
  private skipComment(): void {
3831
4651
  let findComment = false;
3832
4652
  while (true) {
3833
- let line: string | undefined = this.nextLine();
3834
- if (this.status === MUParser.END || !line) {
4653
+ let line: string = this.nextLine();
4654
+ if (this.status === MUParser.END) {
3835
4655
  return;
3836
4656
  }
3837
4657
  line = line.trim();
@@ -3857,26 +4677,20 @@ class MUParser {
3857
4677
  }
3858
4678
  private readSql(): string {
3859
4679
  const list: string[] = [];
3860
- if (this.lastLine) {
3861
- list.push(this.lastLine);
3862
- while (true) {
3863
- const line: string | undefined = this.nextLine();
3864
- if (line) {
3865
- if (this.status === MUParser.END) {
3866
- return this.getBuildSql(list);
3867
- }
3868
- if (line.startsWith('===')) {
3869
- // 删除下一个sqlId表示
3870
- list.pop();
3871
- return this.getBuildSql(list);
3872
- }
3873
- list.push(line);
3874
- } else {
3875
- return '';
3876
- }
4680
+ list.push(this.lastLine);
4681
+ while (true) {
4682
+ const line: string = this.nextLine();
4683
+
4684
+ if (this.status === MUParser.END) {
4685
+ return this.getBuildSql(list);
3877
4686
  }
3878
- } else {
3879
- return '';
4687
+
4688
+ if (line.startsWith('===')) {
4689
+ // 删除下一个sqlId表示
4690
+ list.pop();
4691
+ return this.getBuildSql(list);
4692
+ }
4693
+ list.push(line);
3880
4694
  }
3881
4695
  }
3882
4696
  private getBuildSql(list: string[]): string {
@@ -3892,130 +4706,3 @@ class MUParser {
3892
4706
  return sb.join(this.lineSeparator);
3893
4707
  }
3894
4708
  }
3895
-
3896
- export const Boot = async function (options: GlobalSqlOption) {
3897
- globalThis[_GlobalSqlOption] = Object.assign({}, _defOption, options);
3898
- if (options.sqlDir) {
3899
- globalThis[_path] = await import('path');
3900
- globalThis[_fs] = await import('fs');
3901
- }
3902
- logger.level = options.log ?? 'info';
3903
- globalThis[_sqlCache] = new SqlCache();
3904
- if (options.sqlMap || options.sqlDir) {
3905
- await globalThis[_sqlCache].init(options);
3906
- }
3907
- globalThis[_dao] = {
3908
- [DBType.Mongo]: {},
3909
- [DBType.Mysql]: {},
3910
- [DBType.Sqlite]: {},
3911
- [DBType.SqliteRemote]: {},
3912
- [DBType.Redis]: {}
3913
- };
3914
- if (options.Mysql) {
3915
- const { createPool } = await import('mysql2/promise');
3916
- if (options.Mysql['host']) {
3917
- globalThis[_dao][DBType.Mysql][_primaryDB] = new Mysql(createPool({
3918
- ...options.Mysql,
3919
- multipleStatements: true,
3920
- decimalNumbers: true,
3921
- supportBigNumbers: true
3922
- }));
3923
- } else {
3924
- let flag = false;
3925
- for (const [key, option] of Object.entries(options.Mysql)) {
3926
- const db = new Mysql(createPool({
3927
- ...option,
3928
- multipleStatements: true,
3929
- decimalNumbers: true,
3930
- supportBigNumbers: true
3931
- }));
3932
- if (flag === false) {
3933
- globalThis[_dao][DBType.Mysql][_primaryDB] = db;
3934
- flag = true;
3935
- }
3936
- globalThis[_dao][DBType.Mysql][key] = db;
3937
- }
3938
- }
3939
- }
3940
- if (options.Sqlite) {
3941
- const BetterSqlite3 = await import('better-sqlite3');
3942
- if (typeof options.Sqlite === 'string') {
3943
- globalThis[_dao][DBType.Sqlite][_primaryDB] = new Sqlite(new BetterSqlite3.default(options.Sqlite, { fileMustExist: false }));
3944
- } else {
3945
- let flag = false;
3946
- for (const [key, fileName] of Object.entries(options.Sqlite)) {
3947
- const db = new Sqlite(new BetterSqlite3.default(fileName, { fileMustExist: false }));
3948
- if (flag === false) {
3949
- globalThis[_dao][DBType.Sqlite][_primaryDB] = db;
3950
- flag = true;
3951
- }
3952
- globalThis[_dao][DBType.Sqlite][key] = db;
3953
- }
3954
- }
3955
- }
3956
- if (options.SqliteRemote) {
3957
- if (typeof options.SqliteRemote.db === 'string') {
3958
- await options.SqliteRemote.service.initDB(options.SqliteRemote.db);
3959
- globalThis[_dao][DBType.SqliteRemote][_primaryDB] = new SqliteRemote(options.SqliteRemote.service, options.SqliteRemote.db);
3960
- } else {
3961
- let flag = false;
3962
- for (const [key, fileName] of Object.entries(options.SqliteRemote.db)) {
3963
- await options.SqliteRemote.service.initDB(fileName);
3964
- const db = new SqliteRemote(options.SqliteRemote.service, fileName);
3965
- if (flag === false) {
3966
- globalThis[_dao][DBType.SqliteRemote][_primaryDB] = db;
3967
- flag = true;
3968
- }
3969
- globalThis[_dao][DBType.SqliteRemote][key] = db;
3970
- }
3971
- }
3972
- }
3973
- if (options.Redis) {
3974
- const { Redis } = await import('ioredis');
3975
- if (options.Redis['host']) {
3976
- globalThis[_dao][DBType.Redis][_primaryDB] = new Redis(options.Redis);
3977
- } else {
3978
- let flag = false;
3979
- for (const [key, option] of Object.entries(options.Redis)) {
3980
- const db = new Redis(option);
3981
- if (flag === false) {
3982
- globalThis[_dao][DBType.Redis][_primaryDB] = db;
3983
- flag = true;
3984
- }
3985
- globalThis[_dao][DBType.Redis][key] = db;
3986
- }
3987
- }
3988
- const clients = Object.values(globalThis[_dao][DBType.Redis]) as any;
3989
- const Redlock = await import('redlock');
3990
- globalThis[_dao][DBType.RedisLock] = new Redlock.default(
3991
- clients,
3992
- {
3993
- // The expected clock drift; for more details see:
3994
- // http://redis.io/topics/distlock
3995
- driftFactor: 0.01, // multiplied by lock ttl to determine drift time
3996
-
3997
- // The max number of times Redlock will attempt to lock a resource
3998
- // before erroring.
3999
- retryCount: 10,
4000
-
4001
- // the time in ms between attempts
4002
- retryDelay: 200, // time in ms
4003
-
4004
- // the max time in ms randomly added to retries
4005
- // to improve performance under high contention
4006
- // see https://www.awsarchitectureblog.com/2015/03/backoff.html
4007
- retryJitter: 200, // time in ms
4008
-
4009
- // The minimum remaining time on a lock before an extension is automatically
4010
- // attempted with the `using` API.
4011
- automaticExtensionThreshold: 500, // time in ms
4012
- }
4013
- );
4014
- const { EventEmitter } = await import('events');
4015
- const event = new EventEmitter({ captureRejections: true });
4016
- event.on('error', error => {
4017
- logger.error('event-bus', error);
4018
- });
4019
- globalThis[_EventBus] = event;
4020
- }
4021
- }