baja-lite 1.0.7 → 1.0.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/sql.ts CHANGED
@@ -5,14 +5,42 @@ import iterare from 'iterare';
5
5
  import { emptyString } from './string';
6
6
  import pino from 'pino';
7
7
  import { excuteSplit, ExcuteSplitMode, sleep } from './fn';
8
- import { add, calc } from './math';
8
+ import { add, calc, ten2Any } from './math';
9
9
  import mustache, { PartialsOrLookupFn } from 'mustache';
10
10
  import { C2P, C2P2, P2C } from './object';
11
- import { format } from 'sql-formatter';
11
+ import { formatDialect, sqlite, mysql, DialectOptions } from 'sql-formatter';
12
12
  import HTML from 'html-parse-stringify';
13
13
  import { XML, convert } from './convert-xml';
14
14
  import { ArrayList } from './list';
15
15
  import LGet from 'lodash.get';
16
+ import { EnumMap } from 'enum';
17
+ import { encode, decode, ExtensionCodec, DecodeError } from "@msgpack/msgpack";
18
+ (BigInt.prototype as any).toJSON = function () { return this.toString() }
19
+
20
+ const BIGINT_EXT_TYPE = 0;
21
+ export const extensionCodec = new ExtensionCodec();
22
+ extensionCodec.register({
23
+ type: BIGINT_EXT_TYPE,
24
+ encode(input: unknown): Uint8Array | null {
25
+ if (typeof input === "bigint") {
26
+ if (input <= Number.MAX_SAFE_INTEGER && input >= Number.MIN_SAFE_INTEGER) {
27
+ return encode(Number(input));
28
+ } else {
29
+ return encode(String(input));
30
+ }
31
+ } else {
32
+ return null;
33
+ }
34
+ },
35
+ decode(data: Uint8Array): bigint {
36
+ const val = decode(data);
37
+ if (!(typeof val === "string" || typeof val === "number")) {
38
+ throw new DecodeError(`unexpected BigInt source: ${val} (${typeof val})`);
39
+ }
40
+ return BigInt(val);
41
+ },
42
+ });
43
+
16
44
 
17
45
  // #region 常量
18
46
  const _daoDBName = Symbol('dbName');
@@ -21,6 +49,7 @@ const _className = Symbol('className');
21
49
  const _ClassName = Symbol('ClassName');
22
50
  const _vueName = Symbol('vueName');
23
51
  const _ids = Symbol('ids');
52
+ const _logicIds = Symbol('logicIds');
24
53
  const _columns = Symbol('columns');
25
54
  const _columnsNoId = Symbol('columnsNoId');
26
55
  const _fields = Symbol('fields');
@@ -29,10 +58,12 @@ const _deleteState = Symbol('deleteState');
29
58
  const _transformer = Symbol('transformer');
30
59
  const _index = Symbol('index');
31
60
  const _def = Symbol('def');
61
+ const _comment = Symbol('comment');
32
62
  export const _sqlCache = Symbol('sqlMap');
33
63
  export const _dao = Symbol('dao');
34
64
  export const _primaryDB = Symbol('primaryDB');
35
65
  const _dbType = Symbol('dbType');
66
+ const _formatDialect = Symbol('FormatDialect');
36
67
  const _sqlite_version = Symbol('sqlite_version');
37
68
  const _daoConnection = Symbol('daoConnection');
38
69
  const _inTransaction = Symbol('inTransaction');
@@ -41,6 +72,7 @@ const _sqliteRemoteName = Symbol('sqliteRemoteName');
41
72
  const _SqlOption = Symbol('SqlOption');
42
73
  const _resultMap = Symbol('resultMap');
43
74
  const _resultMap_SQLID = Symbol('resultMap_SQLID');
75
+ export const _enums = Symbol('_enums');
44
76
  export const _Hump = Symbol('Hump');
45
77
  export const _GlobalSqlOption = Symbol('GlobalSqlOption');
46
78
  export const _EventBus = Symbol('EventBus');
@@ -248,6 +280,8 @@ interface ServiceOption {
248
280
  dbType?: DBType;
249
281
  /** SQLite版本以及升级为该版本时需要执行的SQL,初始版本为0.0.1,切记每个位置不要变为两位数*/
250
282
  sqliteVersion?: string;
283
+ /** 备注 */
284
+ comment?: string;
251
285
  }
252
286
  /**
253
287
  # 全局行为配置文件
@@ -309,6 +343,23 @@ export interface GlobalSqlOptionForWeb {
309
343
  ]
310
344
  */
311
345
  sqlMapperMap?: SqlMappers;
346
+ /** 提供的枚举MAP */
347
+ enums?: EnumMap;
348
+ /**
349
+ * `列名与属性映射` 是否自动将下划线转为驼峰,默认NONE,即不转.
350
+ * 当设置为columnMode.HUMP时,切记将代码生成器中属性名称改对
351
+ * # 自定义sql查询时,无法自动转换哦,可使用标签转换:
352
+ *```
353
+ SELECT
354
+ * {{#hump}} seller_sku2, seller_sku {{/hump}}
355
+ * ```
356
+ * 转换为
357
+ *```
358
+ SELECT
359
+ * {{#hump}} seller_sku2 sellerSku2, seller_sku sellerSku {{/hump}}
360
+ * ```
361
+ */
362
+ columnMode?: ColumnMode;
312
363
  }
313
364
  /**
314
365
  # 全局行为配置文件
@@ -370,12 +421,13 @@ export interface GlobalSqlOption extends GlobalSqlOptionForWeb {
370
421
  export default {
371
422
  'sql_1': 'SELECT * FROM user WHERE username = :username',
372
423
  'sql_2': (options: {
373
- ctx: any;
424
+ ctx?: any;
374
425
  isCount?: boolean;
426
+ isSum?: boolean;
375
427
  limitStart?: number;
376
428
  limitEnd?: number;
377
429
  orderBy?: string;
378
- [k: string]: any;
430
+ params?: Record<string, any>;
379
431
  }) => {
380
432
  return `
381
433
  SELECT * FROM user u LEFT JOIN organ o ON u.orgid = o.orgid
@@ -442,21 +494,7 @@ export interface GlobalSqlOption extends GlobalSqlOptionForWeb {
442
494
  */
443
495
  Redis?: Record<string, Record<string, any>> | Record<string, any>;
444
496
 
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;
497
+
460
498
  /**
461
499
  * 读取查询语句时,是否扫描JS文件?
462
500
  * JS文件需要默认导出一个 SqlModel对象
@@ -474,9 +512,16 @@ interface FieldOption extends Object {
474
512
  index?: boolean;
475
513
  id?: boolean;
476
514
  logicDelete?: string | number;
515
+ /** 是否逻辑唯一,用于导入时检测数据是否存在 */
516
+ logicId?: boolean;
477
517
  /** 仅在生成 表时有效 */
478
518
  notNull?: boolean;
519
+ /** 注释,影响到默认导出导入标题 */
479
520
  comment?: string;
521
+ /** 可以导入的字段,默认TRUE,ID默认FALSE */
522
+ importable?: boolean;
523
+ /** 可以导出的字段,默认TRUE,ID默认FALSE */
524
+ exportable?: boolean;
480
525
  /** sqlite 无效,与UUID只能有一个 */
481
526
  uuidShort?: boolean;
482
527
  /** 与uuidShort只能有一个 */
@@ -493,6 +538,7 @@ interface AField extends FieldOption {
493
538
  [DBType.Mysql]: () => string;
494
539
  [DBType.Sqlite]: () => string;
495
540
  [DBType.SqliteRemote]: () => string;
541
+ Data2SQL: (data: any) => any;
496
542
  }
497
543
  export interface PageQuery<L> {
498
544
  sum?: Record<string, number>;
@@ -505,12 +551,11 @@ export interface PageQuery<L> {
505
551
  // #region 数据方言
506
552
  /** sqlite electron服务端需要支持的接口 */
507
553
  export interface SqliteRemoteInterface {
508
- execute(dbName: string, sql?: string, params?: any): | Promise<{ affectedRows: number; insertId: bigint; }>
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>;
511
- raw<Many_Row_One_Column = any>(dbName: string, sql?: string, params?: any): Promise<Many_Row_One_Column[]>;
512
- query<Many_Row_Many_Column = any>(dbName: string, sql?: string, params?: any): Promise<Many_Row_Many_Column[]>;
513
-
554
+ execute(inData: Uint8Array): | Promise<Uint8Array>
555
+ pluck(inData: Uint8Array): Promise<Uint8Array>;
556
+ get(inData: Uint8Array): Promise<Uint8Array>;
557
+ raw(inData: Uint8Array): Promise<Uint8Array>;
558
+ query(inData: Uint8Array): Promise<Uint8Array>;
514
559
  initDB(dbName: string): Promise<void>;
515
560
  export(dbName: string): Promise<void>;
516
561
  restore(dbName: string, fromName: string): Promise<void>;
@@ -1059,7 +1104,8 @@ export class SqliteRemoteConnection implements Connection {
1059
1104
  }
1060
1105
  return new Promise<{ affectedRows: number; insertId: bigint; }>(async (resolve, reject) => {
1061
1106
  try {
1062
- const { affectedRows, insertId } = await this[_daoConnection].execute(this[_sqliteRemoteName], sql, params);
1107
+ const data = await this[_daoConnection].execute(encode([this[_sqliteRemoteName], sql, params], { extensionCodec }));
1108
+ const { affectedRows, insertId } = decode(data, { extensionCodec }) as { affectedRows: number; insertId: bigint; };
1063
1109
  resolve({ affectedRows, insertId: insertId ? BigInt(insertId) : 0n });
1064
1110
  } catch (error) {
1065
1111
  logger.error(`
@@ -1086,7 +1132,8 @@ export class SqliteRemoteConnection implements Connection {
1086
1132
  }
1087
1133
  return new Promise<T | null>(async (resolve, reject) => {
1088
1134
  try {
1089
- const r = await this[_daoConnection].pluck(this[_sqliteRemoteName], sql, params);
1135
+ const data = await this[_daoConnection].pluck(encode([this[_sqliteRemoteName], sql, params], { extensionCodec }));
1136
+ const r = decode(data, { extensionCodec }) as T;
1090
1137
  resolve(r);
1091
1138
  } catch (error) {
1092
1139
  logger.error(`
@@ -1113,7 +1160,8 @@ export class SqliteRemoteConnection implements Connection {
1113
1160
  }
1114
1161
  return new Promise<T | null>(async (resolve, reject) => {
1115
1162
  try {
1116
- const r = await this[_daoConnection].get(this[_sqliteRemoteName], sql, params);
1163
+ const data = await this[_daoConnection].get(encode([this[_sqliteRemoteName], sql, params], { extensionCodec }));
1164
+ const r = decode(data, { extensionCodec }) as T;
1117
1165
  resolve(r);
1118
1166
  } catch (error) {
1119
1167
  logger.error(`
@@ -1140,7 +1188,8 @@ export class SqliteRemoteConnection implements Connection {
1140
1188
  }
1141
1189
  return new Promise<T[]>(async (resolve, reject) => {
1142
1190
  try {
1143
- const r = await this[_daoConnection].raw(this[_sqliteRemoteName], sql, params);
1191
+ const data = await this[_daoConnection].raw(encode([this[_sqliteRemoteName], sql, params], { extensionCodec }));
1192
+ const r = decode(data, { extensionCodec }) as T[];
1144
1193
  resolve(r);
1145
1194
  } catch (error) {
1146
1195
  logger.error(`
@@ -1167,7 +1216,8 @@ export class SqliteRemoteConnection implements Connection {
1167
1216
  }
1168
1217
  return new Promise<T[]>(async (resolve, reject) => {
1169
1218
  try {
1170
- const r = await this[_daoConnection].query(this[_sqliteRemoteName], sql, params);
1219
+ const data = await this[_daoConnection].query(encode([this[_sqliteRemoteName], sql, params], { extensionCodec }));
1220
+ const r = decode(data, { extensionCodec }) as T[];
1171
1221
  resolve(r);
1172
1222
  } catch (error) {
1173
1223
  logger.error(`
@@ -1188,6 +1238,7 @@ export class SqliteRemoteConnection implements Connection {
1188
1238
  export class SqliteRemote implements Dao {
1189
1239
  [_sqliteRemoteName]: string;
1190
1240
  [_daoDB]: SqliteRemoteInterface;
1241
+ private connection?: SqliteRemoteConnection;
1191
1242
 
1192
1243
  constructor(db: SqliteRemoteInterface, name: string) {
1193
1244
  this[_daoDB] = db;
@@ -1203,8 +1254,11 @@ export class SqliteRemote implements Dao {
1203
1254
  return null;
1204
1255
  };
1205
1256
  return new Promise<Connection>(async (resolve, reject) => {
1257
+ if (!this.connection) {
1258
+ this.connection = new SqliteRemoteConnection(this[_daoDB], this[_sqliteRemoteName]);
1259
+ }
1206
1260
  try {
1207
- resolve(new SqliteRemoteConnection(this[_daoDB], this[_sqliteRemoteName]));
1261
+ resolve(this.connection);
1208
1262
  } catch (error) {
1209
1263
  reject(error);
1210
1264
  }
@@ -1282,24 +1336,24 @@ export type SqlMapper = ([string, string[], any?])[];
1282
1336
  export type SqlMappers = Record<string, SqlMapper>;
1283
1337
  export type SqlModel = Record<string, string | (
1284
1338
  (options: {
1285
- ctx: any;
1339
+ ctx?: any;
1286
1340
  isCount?: boolean;
1287
1341
  isSum?: boolean;
1288
1342
  limitStart?: number;
1289
1343
  limitEnd?: number;
1290
1344
  orderBy?: string;
1291
- [k: string]: any;
1345
+ params?: any;
1292
1346
  }) => string
1293
1347
  )>;
1294
1348
  type _SqlModel = Record<string, string | (
1295
1349
  (options: {
1296
- ctx: any;
1350
+ ctx?: any;
1297
1351
  isCount?: boolean;
1298
1352
  isSum?: boolean;
1299
1353
  limitStart?: number;
1300
1354
  limitEnd?: number;
1301
1355
  orderBy?: string;
1302
- [k: string]: any;
1356
+ params?: any;
1303
1357
  }) => string
1304
1358
  ) | XML[]>;
1305
1359
  class Build {
@@ -1563,6 +1617,31 @@ class Build {
1563
1617
  }
1564
1618
  };
1565
1619
  }
1620
+ /**
1621
+ * * PROBLEM_TYPE = 枚举名
1622
+ * * t.problemtype = 列名
1623
+ *
1624
+ * ```
1625
+ * {{#enumTag}} PROBLEM_TYPE(t.problemtype) {{/enumTag}}
1626
+ * ```
1627
+ */
1628
+ enum() {
1629
+ return (text: string) => {
1630
+ const matchs = text.match(/([a-zA-Z_]+)\(([^()]+)\)/);
1631
+ if (matchs) {
1632
+ const [_a, MapName, Column] = matchs;
1633
+ if (MapName && Column) {
1634
+ const map = globalThis[_enums].GlobalMap[MapName.trim()];
1635
+ if (map) {
1636
+ return ` CASE
1637
+ ${Object.entries(map).map(([k, v]) => `WHEN ${Column} = '${k}' THEN '${v}'`).join(' ')}
1638
+ END `;
1639
+ }
1640
+ }
1641
+ }
1642
+ return "''";
1643
+ };
1644
+ }
1566
1645
  }
1567
1646
 
1568
1647
  function replaceCdata(rawText: string) {
@@ -1767,7 +1846,7 @@ export class SqlCache {
1767
1846
  }
1768
1847
  }
1769
1848
  load(sqlids: string[], options: {
1770
- ctx: any;
1849
+ ctx?: any;
1771
1850
  isCount?: boolean;
1772
1851
  isSum?: boolean;
1773
1852
  limitStart?: number;
@@ -1787,17 +1866,12 @@ export class SqlCache {
1787
1866
  const buildParam = new Build(options.isCount === true, options.isSum === true, options);
1788
1867
  if (typeof sqlSource === 'function') {
1789
1868
  const _sql = sqlSource(options);
1790
- const sql = mustache.render(_sql, buildParam, this.sqlFNMap);
1791
- return format(sql);
1869
+ return mustache.render(_sql, buildParam, this.sqlFNMap);
1792
1870
  } else if (typeof sqlSource === 'string') {
1793
- const sql = mustache.render(sqlSource, buildParam, this.sqlFNMap);
1794
- return format(sql);
1871
+ return mustache.render(sqlSource, buildParam, this.sqlFNMap);
1795
1872
  } else if (typeof sqlSource === 'object') {
1796
1873
  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);
1874
+ return mustache.render(_sql, buildParam, this.sqlFNMap);
1801
1875
  }
1802
1876
  return '';
1803
1877
  }
@@ -1829,12 +1903,9 @@ function P<T extends object>(skipConn = false) {
1829
1903
  const option = args[0] = Object.assign({}, globalThis[_GlobalSqlOption], this[_SqlOption], args[0]) as (MethodOption & { sync?: SyncMode; });
1830
1904
  option.sync ??= SyncMode.Async;
1831
1905
  const dbName = option?.dbName ?? this[_daoDBName] ?? _primaryDB;
1832
- const dddx = this[_dbType];
1833
- logger.info(dddx);
1834
1906
  option!.dao = globalThis[_dao][this[_dbType]!][dbName] as Dao;
1835
1907
  Throw.if(!option!.dao, `not found db:${String(dbName)}(${this[_dbType]})`);
1836
1908
  option!.tableName = option?.tableName ?? this[_tableName];
1837
- const tableES = Sqlstring.escapeId(option!.tableName);
1838
1909
  if (this[_dbType] === DBType.Sqlite) {
1839
1910
  Throw.if(option.sync === SyncMode.Async, 'sqlite can not Async!')
1840
1911
  // 连接共享
@@ -1843,59 +1914,6 @@ function P<T extends object>(skipConn = false) {
1843
1914
  } else {
1844
1915
  needRealseConn = false;
1845
1916
  }
1846
- if (skipConn === false) {
1847
- const lastVersion = this[_sqlite_version] ?? '0.0.1';
1848
- // 检查表
1849
- const tableCheckResult = option!.conn!.pluck<number>(SyncMode.Sync, `SELECT COUNT(1) t FROM sqlite_master WHERE TYPE = 'table' AND name = ?`, [option!.tableName]);
1850
- if (tableCheckResult) {
1851
- // 旧版本
1852
- const tableVersion = option!.conn!.pluck<string>(SyncMode.Sync, 'SELECT ______version v from TABLE_VERSION WHERE ______tableName = ?', [option!.tableName]);
1853
- if (tableVersion && tableVersion < lastVersion) { // 发现需要升级的版本
1854
- // 更新版本
1855
- const columns = iterare<{ name: string }>(option!.conn!.query(SyncMode.Sync, `PRAGMA table_info(${tableES})`))
1856
- .filter(c => this[_fields]!.hasOwnProperty(C2P(c.name, globalThis[_Hump])))
1857
- .map(c => Sqlstring.escapeId(c.name))
1858
- .join(',');
1859
-
1860
- const rtable = Sqlstring.escapeId(`${option!.tableName}_${tableVersion.replace(/\./, '_')}`);
1861
- option!.conn!.execute(SyncMode.Sync, `DROP TABLE IF EXISTS ${rtable};`);
1862
- option!.conn!.execute(SyncMode.Sync, `ALTER TABLE ${tableES} RENAME TO ${rtable};`);
1863
- option!.conn!.execute(SyncMode.Sync, `
1864
- CREATE TABLE IF NOT EXISTS ${tableES}(
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(',')})` : ''}
1867
- );
1868
- `);
1869
- if (this[_index] && this[_index].length) {
1870
- for (const index of this[_index]) {
1871
- option!.conn!.execute(SyncMode.Sync, `CREATE INDEX ${Sqlstring.escapeId(`${index}_${Math.random()}`.replace(/\./, ''))} ON ${tableES} ("${this[_fields]![index]?.C2()}");`);
1872
- }
1873
- }
1874
- option!.conn!.execute(SyncMode.Sync, `INSERT INTO ${tableES} (${columns}) SELECT ${columns} FROM ${rtable};`);
1875
- option!.conn!.execute(SyncMode.Sync, `INSERT INTO ${tableES} (${columns}) SELECT ${columns} FROM ${rtable};`);
1876
- option!.conn!.execute(SyncMode.Sync, `DROP TABLE IF EXISTS ${rtable};`);
1877
- // 更新完毕,保存版本号
1878
- option!.conn!.execute(SyncMode.Sync, 'UPDATE TABLE_VERSION SET ______version = ? WHERE ______tableName = ?', [option!.tableName, lastVersion]);
1879
- } else if (!tableVersion) { // 不需要升级情况:没有旧的版本号
1880
- option!.conn!.execute(SyncMode.Sync, 'INSERT INTO TABLE_VERSION (______tableName, ______version ) VALUES ( ?, ? )', [option!.tableName, lastVersion]);
1881
- }
1882
- } else { // 表不存在
1883
- // 创建表
1884
- option!.conn!.execute(SyncMode.Sync, `
1885
- CREATE TABLE IF NOT EXISTS ${tableES} (
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(',')})` : ''}
1888
-
1889
- );
1890
- `);
1891
- if (this[_index] && this[_index].length) {
1892
- for (const index of this[_index]) {
1893
- option!.conn!.execute(SyncMode.Sync, `CREATE INDEX ${Sqlstring.escapeId(`${index}_${Math.random()}`.replace(/\./, ''))} ON ${tableES} ("${this[_fields]![index]?.C2()}");`);
1894
- }
1895
- }
1896
- option!.conn!.execute(SyncMode.Sync, 'INSERT OR REPLACE INTO TABLE_VERSION (______tableName, ______version ) VALUES ( ?, ? )', [option!.tableName, lastVersion]);
1897
- }
1898
- }
1899
1917
  try {
1900
1918
  const result = fn.call(this, ...args);
1901
1919
  logger.info(`${propertyKey}:${option!.tableName}:use ${+new Date() - startTime}ms`);
@@ -1924,58 +1942,6 @@ function P<T extends object>(skipConn = false) {
1924
1942
  } else {
1925
1943
  needRealseConn = false;
1926
1944
  }
1927
- if (skipConn === false) {
1928
- const lastVersion = this[_sqlite_version] ?? '0.0.1';
1929
- // 检查表
1930
- const tableCheckResult = await option!.conn!.pluck<number>(SyncMode.Async, `SELECT COUNT(1) t FROM sqlite_master WHERE TYPE = 'table' AND name = ?`, [option!.tableName]);
1931
- if (tableCheckResult) {
1932
- // 旧版本
1933
- const tableVersion = await option!.conn!.pluck<string>(SyncMode.Async, 'SELECT ______version v from TABLE_VERSION WHERE ______tableName = ?', [option!.tableName]);
1934
- if (tableVersion && tableVersion < lastVersion) { // 发现需要升级的版本
1935
- // 更新版本
1936
- const columns = iterare<{ name: string }>(await option!.conn!.query(SyncMode.Async, `PRAGMA table_info(${tableES})`))
1937
- .filter(c => this[_fields]!.hasOwnProperty(C2P(c.name, globalThis[_Hump])))
1938
- .map(c => Sqlstring.escapeId(c.name))
1939
- .join(',');
1940
-
1941
- const rtable = `${option!.tableName}_${tableVersion.replace(/\./, '_')}`;
1942
- await option!.conn!.execute(SyncMode.Async, `DROP TABLE IF EXISTS ${rtable};`);
1943
- await option!.conn!.execute(SyncMode.Async, `ALTER TABLE ${tableES} RENAME TO ${rtable};`);
1944
- await option!.conn!.execute(SyncMode.Async, `
1945
- CREATE TABLE IF NOT EXISTS ${tableES}(
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(',')})` : ''}
1948
- );
1949
- `);
1950
- if (this[_index] && this[_index].length) {
1951
- for (const index of this[_index]) {
1952
- await option!.conn!.execute(SyncMode.Async, `CREATE INDEX ${Sqlstring.escapeId(`${index}_${Math.random()}`.replace(/\./, ''))} ON ${tableES} ("${this[_fields]![index]?.C2()}");`);
1953
- }
1954
- }
1955
- await option!.conn!.execute(SyncMode.Async, `INSERT INTO ${tableES} (${columns}) SELECT ${columns} FROM ${rtable};`);
1956
- await option!.conn!.execute(SyncMode.Async, `INSERT INTO ${tableES} (${columns}) SELECT ${columns} FROM ${rtable};`);
1957
- await option!.conn!.execute(SyncMode.Async, `DROP TABLE IF EXISTS ${rtable};`);
1958
- // 更新完毕,保存版本号
1959
- await option!.conn!.execute(SyncMode.Async, 'UPDATE TABLE_VERSION SET ______version = ? WHERE ______tableName = ?', [option!.tableName, lastVersion]);
1960
- } else if (!tableVersion) { // 不需要升级情况:没有旧的版本号
1961
- await option!.conn!.execute(SyncMode.Async, 'INSERT INTO TABLE_VERSION (______tableName, ______version ) VALUES ( ?, ? )', [option!.tableName, lastVersion]);
1962
- }
1963
- } else { // 表不存在
1964
- // 创建表
1965
- await option!.conn!.execute(SyncMode.Async, `
1966
- CREATE TABLE IF NOT EXISTS ${tableES}(
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(',')})` : ''}
1969
- );
1970
- `);
1971
- if (this[_index] && this[_index].length) {
1972
- for (const index of this[_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()}");`);
1974
- }
1975
- }
1976
- await option!.conn!.execute(SyncMode.Async, 'INSERT OR REPLACE INTO TABLE_VERSION (______tableName, ______version ) VALUES ( ?, ? )', [option!.tableName, lastVersion]);
1977
- }
1978
- }
1979
1945
  try {
1980
1946
  const result = await fn.call(this, ...args);
1981
1947
  logger.info(`${propertyKey}:${option!.tableName}:use ${+new Date() - startTime}ms`);
@@ -2099,6 +2065,7 @@ export const Field = (config: FieldOption) => {
2099
2065
  case SqlType.bigint: {
2100
2066
  field[DBType.Mysql] = () => `${field.C2()} bigint ${config.notNull === true ? 'NOT NULL' : ''} ${MYSQLCHARSET} ${hasDef ? `DEFAULT '${field.def}'` : ''}`;
2101
2067
  field[DBType.SqliteRemote] = field[DBType.Sqlite] = () => `${field.C2()} integer`;
2068
+ field.Data2SQL = (data: any) => BigInt(data ?? 0);
2102
2069
  break;
2103
2070
  }
2104
2071
  case SqlType.float: {
@@ -2135,26 +2102,31 @@ export const Field = (config: FieldOption) => {
2135
2102
  case SqlType.date: {
2136
2103
  field[DBType.Mysql] = () => `${field.C2()} date ${config.notNull === true ? 'NOT NULL' : ''} ${MYSQLCHARSET} ${hasDef ? `DEFAULT '${field.def}'` : ''}`;
2137
2104
  field[DBType.SqliteRemote] = field[DBType.Sqlite] = () => `${field.C2()} text`;
2105
+ field.Data2SQL = (data: any) => typeof data === 'string' ? new Date(data) : data;
2138
2106
  break;
2139
2107
  }
2140
2108
  case SqlType.time: {
2141
2109
  field[DBType.Mysql] = () => `${field.C2()} time ${config.notNull === true ? 'NOT NULL' : ''} ${MYSQLCHARSET} ${hasDef ? `DEFAULT '${field.def}'` : ''}`;
2142
2110
  field[DBType.SqliteRemote] = field[DBType.Sqlite] = () => `${field.C2()} text`;
2111
+ field.Data2SQL = (data: any) => typeof data === 'string' ? new Date(data) : data;
2143
2112
  break;
2144
2113
  }
2145
2114
  case SqlType.year: {
2146
2115
  field[DBType.Mysql] = () => `${field.C2()} year ${config.notNull === true ? 'NOT NULL' : ''} ${MYSQLCHARSET} ${hasDef ? `DEFAULT '${field.def}'` : ''}`;
2147
2116
  field[DBType.SqliteRemote] = field[DBType.Sqlite] = () => `${field.C2()} text`;
2117
+ field.Data2SQL = (data: any) => typeof data === 'string' ? new Date(data) : data;
2148
2118
  break;
2149
2119
  }
2150
2120
  case SqlType.datetime: {
2151
2121
  field[DBType.Mysql] = () => `${field.C2()} datetime ${config.notNull === true ? 'NOT NULL' : ''} ${MYSQLCHARSET} ${hasDef ? `DEFAULT '${field.def}'` : ''}`;
2152
2122
  field[DBType.SqliteRemote] = field[DBType.Sqlite] = () => `${field.C2()} text`;
2123
+ field.Data2SQL = (data: any) => typeof data === 'string' ? new Date(data) : data;
2153
2124
  break;
2154
2125
  }
2155
2126
  case SqlType.timestamp: {
2156
2127
  field[DBType.Mysql] = () => `${field.C2()} timestamp ${config.notNull === true ? 'NOT NULL' : ''} ${MYSQLCHARSET} ${hasDef ? `DEFAULT '${field.def}'` : ''}`;
2157
2128
  field[DBType.SqliteRemote] = field[DBType.Sqlite] = () => `${field.C2()} integer`;
2129
+ field.Data2SQL = (data: any) => typeof data === 'string' ? +new Date(data) : data;
2158
2130
  break;
2159
2131
  }
2160
2132
  case SqlType.char: {
@@ -2269,6 +2241,7 @@ export const Field = (config: FieldOption) => {
2269
2241
  let __columns = Reflect.getMetadata(_columns, object);
2270
2242
  let __columnsNoId = Reflect.getMetadata(_columnsNoId, object);
2271
2243
  let __ids = Reflect.getMetadata(_ids, object);
2244
+ let __logicIds = Reflect.getMetadata(_logicIds, object);
2272
2245
  let __index = Reflect.getMetadata(_index, object);
2273
2246
  let __def = Reflect.getMetadata(_def, object);
2274
2247
 
@@ -2287,16 +2260,23 @@ export const Field = (config: FieldOption) => {
2287
2260
  } else {
2288
2261
  __columnsNoId.push(propertyName);
2289
2262
  }
2263
+ if (field.logicId === true) {
2264
+ __logicIds.push(propertyName);
2265
+ }
2290
2266
  if (field.index === true) {
2291
2267
  __index.push(propertyName);
2292
2268
  }
2293
2269
  if (hasDef) {
2294
2270
  __def[propertyName] = field.def;
2295
2271
  }
2272
+ if (field.comment) {
2273
+ __def[propertyName] = field.comment;
2274
+ }
2296
2275
  Reflect.defineMetadata(_fields, __fields, object);
2297
2276
  Reflect.defineMetadata(_columns, __columns, object);
2298
2277
  Reflect.defineMetadata(_columnsNoId, __columnsNoId, object);
2299
2278
  Reflect.defineMetadata(_ids, __ids, object);
2279
+ Reflect.defineMetadata(_logicIds, __logicIds, object);
2300
2280
  Reflect.defineMetadata(_index, __index, object);
2301
2281
  Reflect.defineMetadata(_def, __def, object);
2302
2282
  if (field.hasOwnProperty('logicDelete')) {
@@ -2305,16 +2285,24 @@ export const Field = (config: FieldOption) => {
2305
2285
  }
2306
2286
  };
2307
2287
  }
2288
+ const formatDialects = {
2289
+ [DBType.Mysql]: mysql,
2290
+ [DBType.Sqlite]: sqlite,
2291
+ [DBType.SqliteRemote]: sqlite
2292
+ };
2308
2293
  export const DB = (config: ServiceOption) => {
2309
2294
  return function <C extends { new(...args: any[]): {} }>(constructor: C) {
2310
2295
  const __ids = Reflect.getMetadata(_ids, config.clz.prototype) || new Array<string>;
2296
+ const __logicIds = Reflect.getMetadata(_logicIds, config.clz.prototype) || new Array<string>;
2311
2297
  const __fields = Reflect.getMetadata(_fields, config.clz.prototype);
2312
2298
  const __columns = Reflect.getMetadata(_columns, config.clz.prototype);
2313
- const __columnsNoId = __columns.filter((c: string) => __ids.includes(c) === false);
2299
+ const __columnsNoId = Reflect.getMetadata(_columnsNoId, config.clz.prototype);
2314
2300
  const __stateFileName = Reflect.getMetadata(_stateFileName, config.clz.prototype);
2315
2301
  const __deleteState = Reflect.getMetadata(_deleteState, config.clz.prototype);
2316
2302
  const __index = Reflect.getMetadata(_index, config.clz.prototype);
2317
2303
  const __def = Reflect.getMetadata(_def, config.clz.prototype);
2304
+ const __dbType = config.dbType ?? DBType.Mysql;
2305
+ const __formatDialect = formatDialects[__dbType];
2318
2306
  const className = config.tableName?.replace(/_(\w)/g, (a: string, b: string) => b.toUpperCase());
2319
2307
  const ClassName = className?.replace(/\w/, (v: string) => v.toUpperCase());
2320
2308
  const vueName = config.tableName?.replace(/_/g, '-');
@@ -2323,17 +2311,21 @@ export const DB = (config: ServiceOption) => {
2323
2311
  [_className] = className;
2324
2312
  [_ClassName] = ClassName;
2325
2313
  [_vueName] = vueName;
2314
+
2326
2315
  [_daoDBName] = config.dbName;
2327
- [_dbType] = config.dbType ?? DBType.Mysql;
2316
+ [_dbType] = __dbType;
2317
+ [_formatDialect] = __formatDialect;
2328
2318
  [_sqlite_version] = config.sqliteVersion;
2329
2319
  [_SqlOption] = Object.assign({}, _defOption, config);
2330
2320
 
2331
2321
  [_ids] = __ids;
2322
+ [_logicIds] = __logicIds;
2332
2323
  [_fields] = __fields;
2333
2324
  [_columns] = __columns;
2334
2325
  [_columnsNoId] = __columnsNoId;
2335
2326
  [_index] = __index;
2336
2327
  [_def] = __def;
2328
+ [_comment] = config.comment;
2337
2329
  [_stateFileName] = __stateFileName;
2338
2330
  [_deleteState] = __deleteState;
2339
2331
 
@@ -2355,6 +2347,9 @@ export const DB = (config: ServiceOption) => {
2355
2347
  .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)])
2356
2348
  .filter(data => {
2357
2349
  if ((data[1] as any)[0] === 1) {
2350
+ if (__fields[data[0] as string].Data2SQL) {
2351
+ (data[1] as any)[1] = __fields[data[0] as string].Data2SQL((data[1] as any)[1]);
2352
+ }
2358
2353
  if (option?.onFieldExists) {
2359
2354
  option.onFieldExists(data[0] as string, (data[1] as any)[1]);
2360
2355
  }
@@ -2418,7 +2413,9 @@ export class SqlService<T extends object> {
2418
2413
  private [_ClassName]?: string;
2419
2414
  private [_vueName]?: string;
2420
2415
  private [_daoDBName]?: string;
2416
+ private [_comment]?: string;
2421
2417
  private [_ids]?: string[];
2418
+ // private [_logicIds]?: string[];
2422
2419
  private [_fields]?: Record<string, AField>;
2423
2420
  private [_columns]?: string[];
2424
2421
  private [_columnsNoId]?: string[];
@@ -2426,6 +2423,7 @@ export class SqlService<T extends object> {
2426
2423
  private [_deleteState]?: string;
2427
2424
  private [_SqlOption]?: ServiceOption;
2428
2425
  private [_dbType]?: DBType;
2426
+ private [_formatDialect]?: DialectOptions;
2429
2427
  private [_sqlite_version]?: string;
2430
2428
  private [_index]?: string[];
2431
2429
  private [_def]?: Partial<T>;
@@ -2445,6 +2443,7 @@ export class SqlService<T extends object> {
2445
2443
  existConditionOtherThanIds?: (keyof T)[];
2446
2444
  replaceWithDef?: boolean;
2447
2445
  }): { sql: string; params?: any[] }[] {
2446
+
2448
2447
  const sqls: { sql: string; params?: any[] }[] = [];
2449
2448
  const tableName = Sqlstring.escapeId(option!.tableName);
2450
2449
  switch (option?.mode) {
@@ -2493,10 +2492,10 @@ export class SqlService<T extends object> {
2493
2492
  return `SELECT ${questMark.join(',')} FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM ${tableName} WHERE ${where})`;
2494
2493
  });
2495
2494
  const columnNames = iterare<string>(finalColumns).map(i => this[_fields]![i]?.C2()).join(',');
2496
- const sql = format(`INSERT INTO
2495
+ const sql = formatDialect(`INSERT INTO
2497
2496
  ${tableName}
2498
2497
  (${columnNames})
2499
- ${questMarks.join(' UNION ALL ')};`);
2498
+ ${questMarks.join(' UNION ALL ')};`, { dialect: this[_formatDialect]! });
2500
2499
  sqls.push({ sql, params });
2501
2500
  break;
2502
2501
  }
@@ -2531,12 +2530,12 @@ export class SqlService<T extends object> {
2531
2530
  return `(${questMark.join(',')})`;
2532
2531
  });
2533
2532
  const columnNames = iterare(finalColumns).map(i => this[_fields]![i]?.C2()).join(',');
2534
- const sql = format(`
2533
+ const sql = formatDialect(`
2535
2534
  ${this[_dbType] === DBType.Mysql ? '' : 'INSERT OR'} REPLACE INTO
2536
2535
  ${tableName}
2537
2536
  (${columnNames})
2538
2537
  VALUES ${questMarks};
2539
- `);
2538
+ `, { dialect: this[_formatDialect]! });
2540
2539
  sqls.push({ sql, params });
2541
2540
  break;
2542
2541
  }
@@ -2571,12 +2570,12 @@ export class SqlService<T extends object> {
2571
2570
  return `(${questMark.join(',')})`;
2572
2571
  });
2573
2572
  const columnNames = iterare(finalColumns).map(i => this[_fields]![i]?.C2()).join(',');
2574
- const sql = format(`
2573
+ const sql = formatDialect(`
2575
2574
  INSERT INTO
2576
2575
  ${tableName}
2577
2576
  (${columnNames})
2578
2577
  VALUES ${questMarks};
2579
- `);
2578
+ `, { dialect: this[_formatDialect]! });
2580
2579
 
2581
2580
  sqls.push({ sql, params });
2582
2581
  break;
@@ -2618,16 +2617,16 @@ export class SqlService<T extends object> {
2618
2617
  sqls.push(..._sqls);
2619
2618
  const columnNames = iterare(finalColumns).map(i => this[_fields]![i]?.C2()).join(',');
2620
2619
  sqls.push({
2621
- sql: format(`
2620
+ sql: formatDialect(`
2622
2621
  INSERT INTO
2623
2622
  ${tableTemp}
2624
2623
  (${columnNames})
2625
2624
  VALUES ${questMarks};
2626
- `), params
2625
+ `, { dialect: this[_formatDialect]! }), params
2627
2626
  });
2628
2627
  sqls.push({
2629
- sql: format(`INSERT INTO ${Sqlstring.escapeId(option.tableName)} (${columnNames})
2630
- SELECT ${columnNames} FROM ${tableTemp};`)
2628
+ sql: formatDialect(`INSERT INTO ${Sqlstring.escapeId(option.tableName)} (${columnNames})
2629
+ SELECT ${columnNames} FROM ${tableTemp};`, { dialect: this[_formatDialect]! })
2631
2630
  });
2632
2631
  sqls.push({ sql: `DROP TABLE IF EXISTS ${tableTempESC};` });
2633
2632
  break;
@@ -2698,23 +2697,21 @@ export class SqlService<T extends object> {
2698
2697
  }
2699
2698
  } else if (isArray) {
2700
2699
  const fn = async () => {
2701
- return await option?.dao?.transaction(SyncMode.Async, async () => {
2702
- const result = await excuteSplit<Partial<T>, bigint>(
2703
- ExcuteSplitMode.AsyncTrust,
2704
- datas,
2705
- async _data => {
2706
- const sqls = this._insert(_data, option);
2707
- let result = 0n;
2708
- for (const { sql, params } of sqls) {
2709
- const dd = await option?.conn!.execute(SyncMode.Async, sql, params);
2710
- if (dd.insertId) { result += dd.insertId; }
2711
- }
2712
- return result;
2713
- },
2714
- { everyLength: option?.every === true ? 1 : option?.maxDeal }
2715
- );
2716
- return result;
2717
- }, option?.conn);
2700
+ const result = await excuteSplit<Partial<T>, bigint>(
2701
+ ExcuteSplitMode.AsyncTrust,
2702
+ datas,
2703
+ async _data => {
2704
+ const sqls = this._insert(_data, option);
2705
+ let result = 0n;
2706
+ for (const { sql, params } of sqls) {
2707
+ const dd = await option!.conn!.execute(SyncMode.Async, sql, params);
2708
+ if (dd.insertId) { result += dd.insertId; }
2709
+ }
2710
+ return result;
2711
+ },
2712
+ { everyLength: option?.every === true ? 1 : option?.maxDeal }
2713
+ );
2714
+ return result;
2718
2715
  };
2719
2716
  return new Promise<bigint[]>(async (resolve, reject) => {
2720
2717
  try {
@@ -2787,13 +2784,13 @@ export class SqlService<T extends object> {
2787
2784
  }
2788
2785
  );
2789
2786
  }
2790
- const sql = format(`UPDATE ${tableName} SET ${iterare(this[_columnsNoId]!)
2787
+ const sql = formatDialect(`UPDATE ${tableName} SET ${iterare(this[_columnsNoId]!)
2791
2788
  .filter(K => columnMaps[K]!.where.length > 0)
2792
2789
  .map(K => {
2793
2790
  params.push(...columnMaps[K]!.params);
2794
2791
  return `${this[_fields]![K]?.C2()} = CASE ${columnMaps[K]!.where.join(' ')} ELSE ${this[_fields]![K]?.C2()} END`
2795
2792
  })
2796
- .join(',')};`);
2793
+ .join(',')};`, { dialect: this[_formatDialect]! });
2797
2794
  sqls.push({ sql, params });
2798
2795
  return sqls;
2799
2796
  }
@@ -2939,13 +2936,13 @@ export class SqlService<T extends object> {
2939
2936
  if (this[_stateFileName] !== undefined && option.forceDelete !== true) {
2940
2937
  params.unshift(this[_deleteState]);
2941
2938
  sqls.push({
2942
- sql: format(`
2939
+ sql: formatDialect(`
2943
2940
  UPDATE ${tableNameESC} SET ${this[_fields]![this[_stateFileName]]?.C2()} = ?
2944
2941
  WHERE ${whereSql};
2945
- `), params
2942
+ `, { dialect: this[_formatDialect]! }), params
2946
2943
  });
2947
2944
  } else {
2948
- sqls.push({ sql: format(`DELETE FROM ${tableNameESC} WHERE ${whereSql};`), params });
2945
+ sqls.push({ sql: formatDialect(`DELETE FROM ${tableNameESC} WHERE ${whereSql};`, { dialect: this[_formatDialect]! }), params });
2949
2946
  }
2950
2947
  } else {
2951
2948
  sqls.push({ sql: `DROP TABLE IF EXISTS ${tableTempESC};` });
@@ -2956,13 +2953,13 @@ export class SqlService<T extends object> {
2956
2953
  case DBType.Mysql: {
2957
2954
  if (this[_stateFileName] !== undefined && option.forceDelete !== true) {
2958
2955
  sqls.push({
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()} = ?;`),
2956
+ sql: formatDialect(`UPDATE ${tableNameESC} a INNER JOIN ${tableTempESC} b ON ${delWhere.map(K => `a.${this[_fields]![K]?.C2()} = b.${this[_fields]![K]?.C2()}`).join(' AND ')}
2957
+ SET a.${this[_fields]![this[_stateFileName]]?.C2()} = ?;`, { dialect: this[_formatDialect]! }),
2961
2958
  params: [this[_deleteState]]
2962
2959
  });
2963
2960
  } else {
2964
2961
  sqls.push({
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 ')};`)
2962
+ sql: formatDialect(`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 ')};`, { dialect: this[_formatDialect]! })
2966
2963
  });
2967
2964
  }
2968
2965
  break;
@@ -2972,12 +2969,12 @@ export class SqlService<T extends object> {
2972
2969
  const columnNames = iterare(delWhere).map(K => this[_fields]![K]?.C2()).join(',');
2973
2970
  if (this[_stateFileName] !== undefined && option.forceDelete !== true) {
2974
2971
  sqls.push({
2975
- sql: format(`UPDATE ${tableNameESC} SET ${this[_fields]![this[_stateFileName]]?.C2()} = ?
2976
- WHERE (${columnNames}) IN (SELECT ${columnNames} FROM ${tableTempESC});`),
2972
+ sql: formatDialect(`UPDATE ${tableNameESC} SET ${this[_fields]![this[_stateFileName]]?.C2()} = ?
2973
+ WHERE (${columnNames}) IN (SELECT ${columnNames} FROM ${tableTempESC});`, { dialect: this[_formatDialect]! }),
2977
2974
  params: [this[_deleteState]]
2978
2975
  });
2979
2976
  } else {
2980
- sqls.push({ sql: format(`DELETE FROM ${tableNameESC} WHERE (${columnNames}) IN (SELECT ${columnNames} FROM ${tableTempESC});`) });
2977
+ sqls.push({ sql: formatDialect(`DELETE FROM ${tableNameESC} WHERE (${columnNames}) IN (SELECT ${columnNames} FROM ${tableTempESC});`, { dialect: this[_formatDialect]! }) });
2981
2978
  }
2982
2979
  break;
2983
2980
  }
@@ -3029,8 +3026,7 @@ export class SqlService<T extends object> {
3029
3026
  return result[0] as T;
3030
3027
  }
3031
3028
  case TemplateResult.NotSureOne: {
3032
- Throw.if(!result, error);
3033
- return (result[0] as T) ?? null;
3029
+ return result && result.length > 0 ? (result[0] as T) ?? null : null;
3034
3030
  }
3035
3031
  case TemplateResult.Many: {
3036
3032
  return result;
@@ -3102,13 +3098,13 @@ export class SqlService<T extends object> {
3102
3098
  let resultIndex = -1;
3103
3099
  if (option.mode === SelectMode.Common) {
3104
3100
  const params = new Array<any>();
3105
- const whereSql = format(iterare(wheres).map(where => this[_transformer]!(where, option)).map(where => {
3101
+ const whereSql = formatDialect(iterare(wheres).map(where => this[_transformer]!(where, option)).map(where => {
3106
3102
  return `SELECT ${columns} FROM ${tableNameESC} a WHERE
3107
3103
  ${Object.entries(where).map(([K, V]) => {
3108
3104
  params.push(V);
3109
3105
  return `${this[_fields]![K]?.C2()} = ?`;
3110
3106
  }).join(' AND ')}`;
3111
- }).join(' UNION ALL '));
3107
+ }).join(' UNION ALL '), { dialect: this[_formatDialect]! });
3112
3108
  sqls.push({ sql: whereSql, params });
3113
3109
  resultIndex = 0;
3114
3110
  } else {
@@ -3117,7 +3113,7 @@ export class SqlService<T extends object> {
3117
3113
  const _sqls = this._createTable<L>({ tableName: tableTemp, temp: true, columns: delWhere, data: wheres, index: 'all', id: 'none' })!;
3118
3114
  sqls.push(..._sqls);
3119
3115
  resultIndex = sqls.length;
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 ')};`) });
3116
+ sqls.push({ sql: formatDialect(`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 ')};`, { dialect: this[_formatDialect]! }) });
3121
3117
  sqls.push({ sql: `DROP TABLE IF EXISTS ${tableTempESC};` });
3122
3118
  }
3123
3119
 
@@ -3270,7 +3266,7 @@ export class SqlService<T extends object> {
3270
3266
  const _params = Object.assign({}, option.context, option.params);
3271
3267
  option.sql ??= globalThis[_sqlCache].load(this._matchSqlid(option.sqlId), { ctx: option.context, isCount: option.isCount, ..._params });
3272
3268
  const params: any[] = [];
3273
- const sql = option.sql?.replace(/\:([A-Za-z0-9._]+)/g, (txt, key) => {
3269
+ const sql = formatDialect(option.sql?.replace(/\:([A-Za-z0-9._]+)/g, (txt, key) => {
3274
3270
  let V = LGet(_params, key);
3275
3271
  if (V) {
3276
3272
  if (V !== undefined) {
@@ -3295,7 +3291,7 @@ export class SqlService<T extends object> {
3295
3291
  return '?';
3296
3292
  }
3297
3293
  return txt;
3298
- });
3294
+ })!, { dialect: this[_formatDialect]! });
3299
3295
  if (option.sync === SyncMode.Sync) {
3300
3296
  const result = option!.conn!.query(SyncMode.Sync, sql, params);
3301
3297
  return this._select<L>(option.selectResult, result, option.defValue, option.errorMsg, option.hump, option.mapper, option.mapperIfUndefined);
@@ -3334,7 +3330,7 @@ export class SqlService<T extends object> {
3334
3330
  const _params = Object.assign({}, option.context, option.params);
3335
3331
  option.sql ??= globalThis[_sqlCache].load(this._matchSqlid(option.sqlId), { ctx: option.context, ..._params });
3336
3332
  const params: any[] = [];
3337
- const sql = option.sql?.replace(/\:(\w+)/g, (txt, key) => {
3333
+ const sql = formatDialect(option.sql?.replace(/\:(\w+)/g, (txt, key) => {
3338
3334
  let V = LGet(_params, key);
3339
3335
  if (V) {
3340
3336
  if (V !== undefined) {
@@ -3359,7 +3355,7 @@ export class SqlService<T extends object> {
3359
3355
  return '?';
3360
3356
  }
3361
3357
  return txt;
3362
- });
3358
+ })!, { dialect: this[_formatDialect]! });
3363
3359
  if (option.sync === SyncMode.Sync) {
3364
3360
  const result = option!.conn!.execute(SyncMode.Sync, sql, params);
3365
3361
  return result.affectedRows;
@@ -3414,17 +3410,18 @@ export class SqlService<T extends object> {
3414
3410
  return new StreamQuery<L>(option?.tableName ?? this[_tableName]!, this as any, this[_fields]!, this[_columns]!);
3415
3411
  }
3416
3412
 
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>;
3413
+ 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>>;
3414
+ 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
3415
  @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>> {
3416
+ 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
3417
  const result: PageQuery<L> = {
3423
3418
  sum: {},
3424
3419
  records: [],
3425
3420
  size: 0,
3426
3421
  total: 0
3427
3422
  };
3423
+ option.pageNumber ??= 1;
3424
+ option.pageSize ??= 0;
3428
3425
  Object.assign(option.params, {
3429
3426
  limitStart: calc(option.pageNumber).sub(1).mul(option.pageSize).over(),
3430
3427
  limitEnd: calc(option.pageSize).over(),
@@ -3495,7 +3492,7 @@ export class SqlService<T extends object> {
3495
3492
  selectResult: SelectResult.R_C_Assert
3496
3493
  });
3497
3494
  result.size = calc(result.total)
3498
- .add(option.pageSize - 1)
3495
+ .add(option.pageSize ?? 10 - 1)
3499
3496
  .div(option.pageSize)
3500
3497
  .round(0, 2)
3501
3498
  .over();
@@ -3524,6 +3521,177 @@ export class SqlService<T extends object> {
3524
3521
  }
3525
3522
  }
3526
3523
 
3524
+ /**
3525
+ * 导出数据,可以为EJS-EXCEL直接使用
3526
+ * @param list
3527
+ * @returns
3528
+ */
3529
+ exp<L = T>(list: L[]) {
3530
+ Throw.if(list.length === 0, 'not found data!');
3531
+ const columnTitles = new Array<string>();
3532
+ const keys = this[_fields] ?
3533
+ iterare(Object.entries(this[_fields]))
3534
+ .filter(([K, F]) => (F.id !== true && F.exportable !== false) || (F.id === true && F.exportable === true))
3535
+ .map(([K, F]) => {
3536
+ columnTitles.push(F.comment ?? K);
3537
+ return K;
3538
+ }).toArray()
3539
+ : Object.keys(list[0]!).filter(K => !this[_ids]?.includes(K));
3540
+ const title = this[_comment] ?? this[_tableName];
3541
+ const titleSpan = `A1:${ten2Any(keys.length)}1`;
3542
+ const datas = list.map(data => keys.map(k => data[k] ?? ''));
3543
+ return { title, titleSpan, columnTitles, datas };
3544
+ }
3545
+ /**
3546
+ * 导入数据的模板
3547
+ * @returns
3548
+ */
3549
+ imp() {
3550
+ Throw.if(!this[_fields], 'not set fields!');
3551
+ const columnTitles = new Array<string>();
3552
+ const keys = iterare(Object.entries(this[_fields]!))
3553
+ .filter(([K, F]) => (F.id !== true && F.exportable !== false) || (F.id === true && F.exportable === true))
3554
+ .map(([K, F]) => {
3555
+ columnTitles.push(F.comment ?? K);
3556
+ return K;
3557
+ }).toArray();
3558
+ const title = this[_comment] ?? this[_tableName];
3559
+ const titleSpan = `A1:${ten2Any(keys.length)}1`;
3560
+ return { title, titleSpan, columnTitles };
3561
+ }
3562
+
3563
+ /**
3564
+ * 初始化表结构
3565
+ * 只有sqlite、sqliteremote需要
3566
+ * force: 是否强制,默认false, 强制时会删除再创建
3567
+ * @param option
3568
+ */
3569
+ init(option?: MethodOption & { sync?: SyncMode.Async; force?: boolean }): Promise<void>;
3570
+ init(option: MethodOption & { sync: SyncMode.Sync; force?: boolean }): void;
3571
+ @P<T>()
3572
+ init(option?: MethodOption & { sync?: SyncMode; force?: boolean }): void | Promise<void> {
3573
+ const tableES = Sqlstring.escapeId(option!.tableName);
3574
+ option!.force ??= false;
3575
+ if (this[_dbType] === DBType.Sqlite) {
3576
+ if (option?.force) {
3577
+ option!.conn!.execute(SyncMode.Sync, `DROP TABLE IF EXISTS ${tableES};`);
3578
+ }
3579
+ const lastVersion = this[_sqlite_version] ?? '0.0.1';
3580
+ // 检查表
3581
+ const tableCheckResult = option!.conn!.pluck<number>(SyncMode.Sync, `SELECT COUNT(1) t FROM sqlite_master WHERE TYPE = 'table' AND name = ?`, [option!.tableName]);
3582
+ if (tableCheckResult) {
3583
+ // 旧版本
3584
+ const tableVersion = option!.conn!.pluck<string>(SyncMode.Sync, 'SELECT ______version v from TABLE_VERSION WHERE ______tableName = ?', [option!.tableName]);
3585
+ if (tableVersion && tableVersion < lastVersion) { // 发现需要升级的版本
3586
+ // 更新版本
3587
+ const columns = iterare<{ name: string }>(option!.conn!.query(SyncMode.Sync, `PRAGMA table_info(${tableES})`))
3588
+ .filter(c => this[_fields]!.hasOwnProperty(C2P(c.name, globalThis[_Hump])))
3589
+ .map(c => Sqlstring.escapeId(c.name))
3590
+ .join(',');
3591
+
3592
+ const rtable = Sqlstring.escapeId(`${option!.tableName}_${tableVersion.replace(/\./, '_')}`);
3593
+ option!.conn!.execute(SyncMode.Sync, `DROP TABLE IF EXISTS ${rtable};`);
3594
+ option!.conn!.execute(SyncMode.Sync, `ALTER TABLE ${tableES} RENAME TO ${rtable};`);
3595
+ option!.conn!.execute(SyncMode.Sync, `
3596
+ CREATE TABLE IF NOT EXISTS ${tableES}(
3597
+ ${Object.values(this[_fields]!).map(K => K[DBType.Sqlite]()).join(',')}
3598
+ ${this[_ids] && this[_ids].length ? `, PRIMARY KEY (${this[_ids].map(i => this[_fields]![i]?.C2()).join(',')})` : ''}
3599
+ );
3600
+ `);
3601
+ if (this[_index] && this[_index].length) {
3602
+ for (const index of this[_index]) {
3603
+ option!.conn!.execute(SyncMode.Sync, `CREATE INDEX ${Sqlstring.escapeId(`${index}_${Math.random()}`.replace(/\./, ''))} ON ${tableES} ("${this[_fields]![index]?.C2()}");`);
3604
+ }
3605
+ }
3606
+ option!.conn!.execute(SyncMode.Sync, `INSERT INTO ${tableES} (${columns}) SELECT ${columns} FROM ${rtable};`);
3607
+ option!.conn!.execute(SyncMode.Sync, `INSERT INTO ${tableES} (${columns}) SELECT ${columns} FROM ${rtable};`);
3608
+ option!.conn!.execute(SyncMode.Sync, `DROP TABLE IF EXISTS ${rtable};`);
3609
+ // 更新完毕,保存版本号
3610
+ option!.conn!.execute(SyncMode.Sync, 'UPDATE TABLE_VERSION SET ______version = ? WHERE ______tableName = ?', [option!.tableName, lastVersion]);
3611
+ } else if (!tableVersion) { // 不需要升级情况:没有旧的版本号
3612
+ option!.conn!.execute(SyncMode.Sync, 'INSERT INTO TABLE_VERSION (______tableName, ______version ) VALUES ( ?, ? )', [option!.tableName, lastVersion]);
3613
+ }
3614
+ } else { // 表不存在
3615
+ // 创建表
3616
+ option!.conn!.execute(SyncMode.Sync, `
3617
+ CREATE TABLE IF NOT EXISTS ${tableES} (
3618
+ ${Object.values(this[_fields]!).map(K => K[DBType.Sqlite]()).join(',')}
3619
+ ${this[_ids] && this[_ids].length ? `, PRIMARY KEY (${this[_ids].map(i => this[_fields]![i]?.C2()).join(',')})` : ''}
3620
+
3621
+ );
3622
+ `);
3623
+ if (this[_index] && this[_index].length) {
3624
+ for (const index of this[_index]) {
3625
+ option!.conn!.execute(SyncMode.Sync, `CREATE INDEX ${Sqlstring.escapeId(`${index}_${Math.random()}`.replace(/\./, ''))} ON ${tableES} ("${this[_fields]![index]?.C2()}");`);
3626
+ }
3627
+ }
3628
+ option!.conn!.execute(SyncMode.Sync, 'INSERT OR REPLACE INTO TABLE_VERSION (______tableName, ______version ) VALUES ( ?, ? )', [option!.tableName, lastVersion]);
3629
+ }
3630
+ } else if (this[_dbType] === DBType.SqliteRemote) {
3631
+
3632
+ return new Promise(async (resolve, reject) => {
3633
+ try {
3634
+ if (option?.force) {
3635
+ await option!.conn!.execute(SyncMode.Async, `DROP TABLE IF EXISTS ${tableES};`);
3636
+ }
3637
+ const lastVersion = this[_sqlite_version] ?? '0.0.1';
3638
+ // 检查表
3639
+ const tableCheckResult = await option!.conn!.pluck<number>(SyncMode.Async, `SELECT COUNT(1) t FROM sqlite_master WHERE TYPE = 'table' AND name = ?`, [option!.tableName]);
3640
+ if (tableCheckResult) {
3641
+ // 旧版本
3642
+ const tableVersion = await option!.conn!.pluck<string>(SyncMode.Async, 'SELECT ______version v from TABLE_VERSION WHERE ______tableName = ?', [option!.tableName]);
3643
+ if (tableVersion && tableVersion < lastVersion) { // 发现需要升级的版本
3644
+ // 更新版本
3645
+ const columns = iterare<{ name: string }>(await option!.conn!.query(SyncMode.Async, `PRAGMA table_info(${tableES})`))
3646
+ .filter(c => this[_fields]!.hasOwnProperty(C2P(c.name, globalThis[_Hump])))
3647
+ .map(c => Sqlstring.escapeId(c.name))
3648
+ .join(',');
3649
+
3650
+ const rtable = `${option!.tableName}_${tableVersion.replace(/\./, '_')}`;
3651
+ await option!.conn!.execute(SyncMode.Async, `DROP TABLE IF EXISTS ${rtable};`);
3652
+ await option!.conn!.execute(SyncMode.Async, `ALTER TABLE ${tableES} RENAME TO ${rtable};`);
3653
+ await option!.conn!.execute(SyncMode.Async, `
3654
+ CREATE TABLE IF NOT EXISTS ${tableES}(
3655
+ ${Object.values(this[_fields]!).map(K => K[DBType.Sqlite]()).join(',')}
3656
+ ${this[_ids] && this[_ids].length ? `, PRIMARY KEY (${this[_ids].map(i => this[_fields]![i]?.C2()).join(',')})` : ''}
3657
+ );
3658
+ `);
3659
+ if (this[_index] && this[_index].length) {
3660
+ for (const index of this[_index]) {
3661
+ await option!.conn!.execute(SyncMode.Async, `CREATE INDEX ${Sqlstring.escapeId(`${index}_${Math.random()}`.replace(/\./, ''))} ON ${tableES} ("${this[_fields]![index]?.C2()}");`);
3662
+ }
3663
+ }
3664
+ await option!.conn!.execute(SyncMode.Async, `INSERT INTO ${tableES} (${columns}) SELECT ${columns} FROM ${rtable};`);
3665
+ await option!.conn!.execute(SyncMode.Async, `INSERT INTO ${tableES} (${columns}) SELECT ${columns} FROM ${rtable};`);
3666
+ await option!.conn!.execute(SyncMode.Async, `DROP TABLE IF EXISTS ${rtable};`);
3667
+ // 更新完毕,保存版本号
3668
+ await option!.conn!.execute(SyncMode.Async, 'UPDATE TABLE_VERSION SET ______version = ? WHERE ______tableName = ?', [option!.tableName, lastVersion]);
3669
+ } else if (!tableVersion) { // 不需要升级情况:没有旧的版本号
3670
+ await option!.conn!.execute(SyncMode.Async, 'INSERT INTO TABLE_VERSION (______tableName, ______version ) VALUES ( ?, ? )', [option!.tableName, lastVersion]);
3671
+ }
3672
+ } else { // 表不存在
3673
+ // 创建表
3674
+ await option!.conn!.execute(SyncMode.Async, `
3675
+ CREATE TABLE IF NOT EXISTS ${tableES}(
3676
+ ${Object.values(this[_fields]!).map(K => K[DBType.Sqlite]()).join(',')}
3677
+ ${this[_ids] && this[_ids].length ? `, PRIMARY KEY (${this[_ids].map(i => this[_fields]![i]?.C2()).join(',')})` : ''}
3678
+ );
3679
+ `);
3680
+ if (this[_index] && this[_index].length) {
3681
+ for (const index of this[_index]) {
3682
+ await option!.conn!.execute(SyncMode.Async, `CREATE INDEX ${Sqlstring.escapeId(`${index}_${Math.random()}`.replace(/\./, ''))} ON ${Sqlstring.escapeId(option!.tableName)} ("${this[_fields]![index]?.C2()}");`);
3683
+ }
3684
+ }
3685
+ await option!.conn!.execute(SyncMode.Async, 'INSERT OR REPLACE INTO TABLE_VERSION (______tableName, ______version ) VALUES ( ?, ? )', [option!.tableName, lastVersion]);
3686
+ }
3687
+ resolve();
3688
+ } catch (error) {
3689
+ reject(error);
3690
+ }
3691
+ });
3692
+ }
3693
+ }
3694
+
3527
3695
  /**
3528
3696
  #创建表
3529
3697
  ** `tableName` 表名称
@@ -3569,16 +3737,16 @@ export class SqlService<T extends object> {
3569
3737
  tableName = Sqlstring.escapeId(tableName ?? this[_tableName]);
3570
3738
  switch (this[_dbType]) {
3571
3739
  case DBType.Mysql: {
3572
- let sql = format(`CREATE ${temp === true ? 'TEMPORARY' : ''} TABLE IF NOT EXISTS ${tableName}(
3740
+ let sql = formatDialect(`CREATE ${temp === true ? 'TEMPORARY' : ''} TABLE IF NOT EXISTS ${tableName}(
3573
3741
  ${columns.map(K => this[_fields]![K]![DBType.Mysql]()).join(',')}
3574
3742
  ${ids && ids.length ? `,PRIMARY KEY (${ids.map(i => this[_fields]![i]?.C2()).join(',')}) USING BTREE ` : ''}
3575
3743
  ${indexs && indexs.length ? `,${indexs.map(i => `KEY ${this[_fields]![i]?.C2()} (${this[_fields]![i]?.C2()})`).join(',')} ` : ''}
3576
- ) ENGINE=MEMORY;`);
3744
+ ) ENGINE=MEMORY;`, { dialect: this[_formatDialect]! });
3577
3745
  sqls.push({ sql });
3578
3746
  if (data && data.length > 0) {
3579
3747
  const params: any[] = [];
3580
3748
  let first = true;
3581
- sql = format(`INSERT INTO ${tableName} (${columns.map(c => this[_fields]![c]?.C2()).join(',')})
3749
+ sql = formatDialect(`INSERT INTO ${tableName} (${columns.map(c => this[_fields]![c]?.C2()).join(',')})
3582
3750
  ${(data).map(d => {
3583
3751
  const r = `SELECT ${Object.entries(d).map(([K, V]) => {
3584
3752
  params.push(V);
@@ -3586,28 +3754,28 @@ export class SqlService<T extends object> {
3586
3754
  }).join(',')}`;
3587
3755
  first = false;
3588
3756
  return r;
3589
- }).join(' UNION ALL ')}`);
3757
+ }).join(' UNION ALL ')}`, { dialect: this[_formatDialect]! });
3590
3758
  sqls.push({ sql, params });
3591
3759
  }
3592
3760
  break;
3593
3761
  }
3594
3762
  case DBType.Sqlite:
3595
3763
  case DBType.SqliteRemote: {
3596
- let sql = format(`CREATE ${temp === true ? 'TEMPORARY' : ''} TABLE IF NOT EXISTS ${tableName}(
3764
+ let sql = formatDialect(`CREATE ${temp === true ? 'TEMPORARY' : ''} TABLE IF NOT EXISTS ${tableName}(
3597
3765
  ${columns.map(K => this[_fields]![K]![DBType.Sqlite]()).join(',')}
3598
3766
  ${ids && ids.length ? `,PRIMARY KEY (${ids.map(i => this[_fields]![i]?.C2()).join(',')}) ` : ''}
3599
- );`);
3767
+ );`, { dialect: this[_formatDialect]! });
3600
3768
  sqls.push({ sql });
3601
3769
  if (indexs) {
3602
3770
  for (const index of indexs) {
3603
- sql = format(`CREATE INDEX ${Sqlstring.escapeId(`${index}_${Math.random()}`.replace(/\./, ''))} ON ${tableName} (${this[_fields]![index]?.C2()});`);
3771
+ sql = formatDialect(`CREATE INDEX ${Sqlstring.escapeId(`${index}_${Math.random()}`.replace(/\./, ''))} ON ${tableName} (${this[_fields]![index]?.C2()});`, { dialect: this[_formatDialect]! });
3604
3772
  sqls.push({ sql });
3605
3773
  }
3606
3774
  }
3607
3775
  if (data && data.length > 0) {
3608
3776
  const params: any[] = [];
3609
3777
  let first = true;
3610
- sql = format(`INSERT INTO ${tableName} (${columns.map(c => this[_fields]![c]?.C2()).join(',')})
3778
+ sql = formatDialect(`INSERT INTO ${tableName} (${columns.map(c => this[_fields]![c]?.C2()).join(',')})
3611
3779
  ${(data).map(d => {
3612
3780
  const r = `SELECT ${Object.entries(d).map(([K, V]) => {
3613
3781
  params.push(V);
@@ -3615,7 +3783,7 @@ export class SqlService<T extends object> {
3615
3783
  }).join(',')}`;
3616
3784
  first = false;
3617
3785
  return r;
3618
- }).join(' UNION ALL ')}`);
3786
+ }).join(' UNION ALL ')}`, { dialect: this[_formatDialect]! });
3619
3787
  sqls.push({ sql, params });
3620
3788
  }
3621
3789
  break;
@@ -4100,7 +4268,10 @@ class StreamQuery<T extends object> {
4100
4268
  }
4101
4269
  }
4102
4270
  if (sets.length > 0) {
4103
- const sql = `UPDATE ${this._table} SET ${sets.join(',')} ${where}`;
4271
+ const sql = `UPDATE ${this._table} SET ${sets.join(',')}
4272
+ ${where ? ' WHERE ' : ''}
4273
+ ${where}
4274
+ `;
4104
4275
  if (option.sync === SyncMode.Async) {
4105
4276
  return this._service.excute({ sync: SyncMode.Async, sql, params });
4106
4277
  } else {
@@ -4117,7 +4288,10 @@ class StreamQuery<T extends object> {
4117
4288
  option ??= {};
4118
4289
  option.sync ??= SyncMode.Async;
4119
4290
  const { where, params } = this._where();
4120
- const sql = `DELETE FROM ${this._table} ${where}`;
4291
+ const sql = `DELETE FROM ${this._table}
4292
+ ${where ? ' WHERE ' : ''}
4293
+ ${where}
4294
+ `;
4121
4295
  if (option.sync === SyncMode.Async) {
4122
4296
  return this._service.excute({ sync: SyncMode.Async, sql, params });
4123
4297
  } else {