baja-lite 1.0.2 → 1.0.4

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/es/sql.js CHANGED
@@ -18,6 +18,7 @@ import { emptyString } from './string';
18
18
  import pino from 'pino';
19
19
  import { excuteSplit, ExcuteSplitMode, sleep } from './fn';
20
20
  import { add } from './math';
21
+ import mustache from 'mustache';
21
22
  // #region 常量
22
23
  const _daoDBName = Symbol('dbName');
23
24
  const _tableName = Symbol('tableName');
@@ -30,7 +31,7 @@ const _deleteState = Symbol('deleteState');
30
31
  const _transformer = Symbol('transformer');
31
32
  const _index = Symbol('index');
32
33
  const _def = Symbol('def');
33
- const _sqlCache = Symbol('sqlCache');
34
+ const _sqlCache = Symbol('sqlMap');
34
35
  const _dao = Symbol('dao');
35
36
  const _primaryDB = Symbol('primaryDB');
36
37
  const _dbType = Symbol('dbType');
@@ -213,7 +214,7 @@ class MysqlConnection {
213
214
  if (globalThis[_GlobalSqlOption].log === 'trace') {
214
215
  logger.trace(Sqlstring.format(sql, params));
215
216
  }
216
- return new Promise(async (resolve) => {
217
+ return new Promise(async (resolve, reject) => {
217
218
  try {
218
219
  const [_result] = await this[_daoConnection].execute(sql, params);
219
220
  const result = _result;
@@ -228,7 +229,7 @@ class MysqlConnection {
228
229
  sql: ${sql},
229
230
  params: ${params}
230
231
  `);
231
- throw error;
232
+ reject(error);
232
233
  }
233
234
  });
234
235
  }
@@ -246,7 +247,7 @@ class MysqlConnection {
246
247
  if (globalThis[_GlobalSqlOption].log === 'trace') {
247
248
  logger.trace(Sqlstring.format(sql, params));
248
249
  }
249
- return new Promise(async (resolve) => {
250
+ return new Promise(async (resolve, reject) => {
250
251
  try {
251
252
  const [result] = await this[_daoConnection].query(sql, params);
252
253
  if (result && result[0]) {
@@ -264,7 +265,7 @@ class MysqlConnection {
264
265
  sql: ${sql},
265
266
  params: ${params}
266
267
  `);
267
- throw error;
268
+ reject(error);
268
269
  }
269
270
  });
270
271
  }
@@ -282,7 +283,7 @@ class MysqlConnection {
282
283
  if (globalThis[_GlobalSqlOption].log === 'trace') {
283
284
  logger.trace(Sqlstring.format(sql, params));
284
285
  }
285
- return new Promise(async (resolve) => {
286
+ return new Promise(async (resolve, reject) => {
286
287
  try {
287
288
  const [result] = await this[_daoConnection].query(sql, params);
288
289
  if (globalThis[_GlobalSqlOption].log === 'trace') {
@@ -298,7 +299,7 @@ class MysqlConnection {
298
299
  sql: ${sql},
299
300
  params: ${params}
300
301
  `);
301
- throw error;
302
+ reject(error);
302
303
  }
303
304
  });
304
305
  }
@@ -316,7 +317,7 @@ class MysqlConnection {
316
317
  if (globalThis[_GlobalSqlOption].log === 'trace') {
317
318
  logger.trace(Sqlstring.format(sql, params));
318
319
  }
319
- return new Promise(async (resolve) => {
320
+ return new Promise(async (resolve, reject) => {
320
321
  try {
321
322
  const [result] = await this[_daoConnection].query(sql, params);
322
323
  if (globalThis[_GlobalSqlOption].log === 'trace') {
@@ -332,7 +333,7 @@ class MysqlConnection {
332
333
  sql: ${sql},
333
334
  params: ${params}
334
335
  `);
335
- throw error;
336
+ reject(error);
336
337
  }
337
338
  });
338
339
  }
@@ -350,7 +351,7 @@ class MysqlConnection {
350
351
  if (globalThis[_GlobalSqlOption].log === 'trace') {
351
352
  logger.trace(Sqlstring.format(sql, params));
352
353
  }
353
- return new Promise(async (resolve) => {
354
+ return new Promise(async (resolve, reject) => {
354
355
  try {
355
356
  const [result] = await this[_daoConnection].query(sql, params);
356
357
  if (globalThis[_GlobalSqlOption].log === 'trace') {
@@ -364,7 +365,7 @@ class MysqlConnection {
364
365
  sql: ${sql},
365
366
  params: ${params}
366
367
  `);
367
- throw error;
368
+ reject(error);
368
369
  }
369
370
  });
370
371
  }
@@ -390,10 +391,15 @@ class Mysql {
390
391
  return null;
391
392
  }
392
393
  ;
393
- return new Promise(async (resolve) => {
394
- const connection = await this[_daoDB].getConnection();
395
- logger.debug('create new!');
396
- resolve(new MysqlConnection(connection));
394
+ return new Promise(async (resolve, reject) => {
395
+ try {
396
+ const connection = await this[_daoDB].getConnection();
397
+ logger.debug('create new!');
398
+ resolve(new MysqlConnection(connection));
399
+ }
400
+ catch (error) {
401
+ reject(error);
402
+ }
397
403
  });
398
404
  }
399
405
  transaction(sync, fn, conn) {
@@ -402,7 +408,7 @@ class Mysql {
402
408
  return null;
403
409
  }
404
410
  ;
405
- return new Promise(async (resolve) => {
411
+ return new Promise(async (resolve, reject) => {
406
412
  let needCommit = false;
407
413
  let newConn = false;
408
414
  if (!conn) {
@@ -432,7 +438,7 @@ class Mysql {
432
438
  logger.debug('rollback end!');
433
439
  conn[_inTransaction] = false;
434
440
  logger.error(error);
435
- throw error;
441
+ reject(error);
436
442
  }
437
443
  finally {
438
444
  try {
@@ -688,7 +694,7 @@ class SqliteRemoteConnection {
688
694
  if (globalThis[_GlobalSqlOption].log === 'trace') {
689
695
  logger.trace(Sqlstring.format(sql, params));
690
696
  }
691
- return new Promise(async (resolve) => {
697
+ return new Promise(async (resolve, reject) => {
692
698
  try {
693
699
  const { affectedRows, insertId } = await this[_daoConnection].execute(this[_sqliteRemoteName], sql, params);
694
700
  resolve({ affectedRows, insertId: insertId ? BigInt(insertId) : 0n });
@@ -699,7 +705,7 @@ class SqliteRemoteConnection {
699
705
  sql: ${sql},
700
706
  params: ${params}
701
707
  `);
702
- throw error;
708
+ reject(error);
703
709
  }
704
710
  });
705
711
  }
@@ -717,7 +723,7 @@ class SqliteRemoteConnection {
717
723
  if (globalThis[_GlobalSqlOption].log === 'trace') {
718
724
  logger.trace(Sqlstring.format(sql, params));
719
725
  }
720
- return new Promise(async (resolve) => {
726
+ return new Promise(async (resolve, reject) => {
721
727
  try {
722
728
  const r = await this[_daoConnection].pluck(this[_sqliteRemoteName], sql, params);
723
729
  resolve(r);
@@ -728,7 +734,7 @@ class SqliteRemoteConnection {
728
734
  sql: ${sql},
729
735
  params: ${params}
730
736
  `);
731
- throw error;
737
+ reject(error);
732
738
  }
733
739
  });
734
740
  }
@@ -746,7 +752,7 @@ class SqliteRemoteConnection {
746
752
  if (globalThis[_GlobalSqlOption].log === 'trace') {
747
753
  logger.trace(Sqlstring.format(sql, params));
748
754
  }
749
- return new Promise(async (resolve) => {
755
+ return new Promise(async (resolve, reject) => {
750
756
  try {
751
757
  const r = await this[_daoConnection].get(this[_sqliteRemoteName], sql, params);
752
758
  resolve(r);
@@ -757,7 +763,7 @@ class SqliteRemoteConnection {
757
763
  sql: ${sql},
758
764
  params: ${params}
759
765
  `);
760
- throw error;
766
+ reject(error);
761
767
  }
762
768
  });
763
769
  }
@@ -775,7 +781,7 @@ class SqliteRemoteConnection {
775
781
  if (globalThis[_GlobalSqlOption].log === 'trace') {
776
782
  logger.trace(Sqlstring.format(sql, params));
777
783
  }
778
- return new Promise(async (resolve) => {
784
+ return new Promise(async (resolve, reject) => {
779
785
  try {
780
786
  const r = await this[_daoConnection].raw(this[_sqliteRemoteName], sql, params);
781
787
  resolve(r);
@@ -786,7 +792,7 @@ class SqliteRemoteConnection {
786
792
  sql: ${sql},
787
793
  params: ${params}
788
794
  `);
789
- throw error;
795
+ reject(error);
790
796
  }
791
797
  });
792
798
  }
@@ -804,7 +810,7 @@ class SqliteRemoteConnection {
804
810
  if (globalThis[_GlobalSqlOption].log === 'trace') {
805
811
  logger.trace(Sqlstring.format(sql, params));
806
812
  }
807
- return new Promise(async (resolve) => {
813
+ return new Promise(async (resolve, reject) => {
808
814
  try {
809
815
  const r = await this[_daoConnection].query(this[_sqliteRemoteName], sql, params);
810
816
  resolve(r);
@@ -815,7 +821,7 @@ class SqliteRemoteConnection {
815
821
  sql: ${sql},
816
822
  params: ${params}
817
823
  `);
818
- throw error;
824
+ reject(error);
819
825
  }
820
826
  });
821
827
  }
@@ -875,34 +881,301 @@ class SqliteRemote {
875
881
  ;
876
882
  }
877
883
  }
884
+ class Build {
885
+ /**
886
+ *
887
+ * @param count 是否是count查询
888
+ * @param isSum 是否是sum查询
889
+ * @param param
890
+ */
891
+ constructor(isCount, isSum, param = {}) {
892
+ this.brage = { haveOrderBy: false, haveLimit: false };
893
+ this.isCount = isCount;
894
+ this.isSum = isSum;
895
+ Object.assign(this, param);
896
+ }
897
+ /**
898
+ *
899
+ * 当分页时将函数内包含的内容替换为COUNT(1)
900
+ * @returns
901
+ * @memberof Build
902
+ */
903
+ pageTag() {
904
+ return (text, render) => {
905
+ if (this.isCount === true) {
906
+ return Build.page;
907
+ }
908
+ else if (this.isSum !== true) {
909
+ return render(text);
910
+ }
911
+ };
912
+ }
913
+ /**
914
+ *
915
+ * 汇总查询专用
916
+ * @returns
917
+ * @memberof Build
918
+ */
919
+ sumTag() {
920
+ return (text, render) => {
921
+ if (this.isSum !== true) {
922
+ return '';
923
+ }
924
+ else {
925
+ return render(text);
926
+ }
927
+ };
928
+ }
929
+ /**
930
+ *
931
+ * 当分页时、汇总时忽略函数内包含的内容
932
+ * @returns
933
+ * @memberof Build
934
+ */
935
+ pageIgnoreTag() {
936
+ return (text, render) => {
937
+ if (this.isCount === true || this.isSum === true) {
938
+ return '';
939
+ }
940
+ else {
941
+ return render(text);
942
+ }
943
+ };
944
+ }
945
+ /**
946
+ *
947
+ * 将查询条件包起来,如果条件内容不为空,则自动添加WHERE,同时将第一个条件的and、or替换为空
948
+ * 例如:
949
+ * {{#whereTag}}
950
+ * and name = 1
951
+ * and page = 2
952
+ * {{/whereTag}}
953
+ * 输出
954
+ * where name = 1 and page = 2
955
+ * @returns
956
+ * @memberof Build
957
+ */
958
+ where() {
959
+ return (text, render) => {
960
+ let data = render(text);
961
+ data = data.trim();
962
+ if (data) {
963
+ data = data.replace(/and|or/i, '');
964
+ return ` WHERE ${data} `;
965
+ }
966
+ else {
967
+ return '';
968
+ }
969
+ };
970
+ }
971
+ /**
972
+ * 删除第一个and、or
973
+ * 删除最后一个,
974
+ * 删除最后一个;
975
+ * @memberof Build
976
+ */
977
+ trim() {
978
+ return (text, render) => {
979
+ let data = render(text);
980
+ data = data.trim();
981
+ if (data) {
982
+ data = data.replace(/(^and\s)|(^or\s)|(,$)|(;$)/i, '');
983
+ return data;
984
+ }
985
+ else {
986
+ return '';
987
+ }
988
+ };
989
+ }
990
+ /**
991
+ * 分页时将排序部分代码用此函数包起来,可以自动拼接order by
992
+ * 查询条数时,自动忽略此部分
993
+ * etc
994
+ * {{#orderTag}} name desc, age asc {{/orderTag}}
995
+ * ===
996
+ * ORDER BY name desc, age asc
997
+ * @returns
998
+ * @memberof Build
999
+ */
1000
+ orderTag() {
1001
+ return (text, render) => {
1002
+ if (this.isCount === true || this.isSum === true) {
1003
+ return '';
1004
+ }
1005
+ else {
1006
+ this.brage.haveOrderBy = true;
1007
+ const orderBy = new Array();
1008
+ const renderOrder = render(text);
1009
+ if (/\S/.test(renderOrder)) {
1010
+ orderBy.push(renderOrder);
1011
+ }
1012
+ return orderBy.length > 0 ? ` ORDER BY ${orderBy.join(',')} ` : '';
1013
+ }
1014
+ };
1015
+ }
1016
+ limitTag() {
1017
+ return (text, render) => {
1018
+ if (this.isCount === true || this.isSum === true) {
1019
+ return '';
1020
+ }
1021
+ else {
1022
+ this.brage.haveOrderBy = true;
1023
+ const orderBy = new Array();
1024
+ const renderOrder = render(text);
1025
+ if (/\S/.test(renderOrder)) {
1026
+ orderBy.push(renderOrder);
1027
+ }
1028
+ return orderBy.length > 0 ? ` ORDER BY ${orderBy.join(',')} ` : '';
1029
+ }
1030
+ };
1031
+ }
1032
+ /**
1033
+ *
1034
+ * 分页时将分组部分代码用此函数包起来,可以自动拼接GROUP BY
1035
+ * 当分页时、汇总时,自动忽略此部分
1036
+ * etc
1037
+ * {{#groupTag}} name, age {{/groupTag}}
1038
+ * ===
1039
+ * group by name.age
1040
+ * @returns
1041
+ * @memberof Build
1042
+ */
1043
+ groupTag() {
1044
+ return (text, render) => {
1045
+ if (this.isCount === true || this.isSum === true) {
1046
+ return '';
1047
+ }
1048
+ else {
1049
+ const groupBy = render(text) || '';
1050
+ return /\S/.test(groupBy) ? ` GROUP BY ${groupBy} ` : '';
1051
+ }
1052
+ };
1053
+ }
1054
+ /**
1055
+ *
1056
+ * beetween and
1057
+ * etc.
1058
+ * {{#between}} AND t.createtime | ({{createtime}}) {{/between}}
1059
+ * createtime: 1,2
1060
+ * ===
1061
+ * AND t.createtime BETWEEN 1 AND 2
1062
+ * @returns
1063
+ * @memberof Build
1064
+ */
1065
+ between() {
1066
+ return (text, render) => {
1067
+ const result = render(text);
1068
+ if (/\(([\w\W]+)\)/.exec(result)) {
1069
+ return render(text).replace(/\(([\w\W]+)\)/, (a, b) => {
1070
+ if (a && b) {
1071
+ const xx = b.split(',');
1072
+ return `'${xx[0]}' AND '${xx[1]}'`;
1073
+ }
1074
+ else {
1075
+ return '';
1076
+ }
1077
+ }).replace(/\|/, ' BETWEEN ');
1078
+ }
1079
+ else {
1080
+ return '';
1081
+ }
1082
+ };
1083
+ }
1084
+ /**
1085
+ *
1086
+ * 距离计算,单位米
1087
+ * etc
1088
+ * {{#distanceTag}} (t.longitude, t.latitude), ({{longitude}}, {{latitude}}) {{/distanceTag}}
1089
+ * ===
1090
+ * ROUND(ST_DISTANCE(POINT(longitude1, latitude1), POINT({{longitude}}, {{latitude}}))*111195, 2)
1091
+ * 可根据需求自行将数据转换为千米,例如
1092
+ * {{#distanceTag}} (t.longitude, t.latitude), ({{longitude}}, {{latitude}}) {{/distanceTag}} / 1000
1093
+ * @returns
1094
+ * @memberof Build
1095
+ */
1096
+ distanceTag() {
1097
+ return (text, render) => {
1098
+ const result = render(text);
1099
+ if (/\(([^()]+)\)/.exec(result)) {
1100
+ let index = 0;
1101
+ return render(text).replace(/\(([^()]+)\)/g, (a, b) => {
1102
+ if (a && b) {
1103
+ const xx = b.split(',');
1104
+ if (index === 0) {
1105
+ index++;
1106
+ return ` ROUND(ST_DISTANCE(POINT(${xx[0]}, ${xx[1]}) `;
1107
+ }
1108
+ else {
1109
+ return ` POINT(${xx[0]}, ${xx[1]}))*111195, 2)`;
1110
+ }
1111
+ }
1112
+ else {
1113
+ return '';
1114
+ }
1115
+ });
1116
+ }
1117
+ else {
1118
+ return '';
1119
+ }
1120
+ };
1121
+ }
1122
+ }
1123
+ Build.page = 'COUNT(1) zccw1986 ';
878
1124
  class SqlCache {
879
1125
  constructor() {
880
- this.cache = {};
1126
+ this.sqlMap = {};
1127
+ this.sqlFNMap = {};
881
1128
  }
882
1129
  async init(options) {
1130
+ if (options.sqlMap) {
1131
+ this.sqlMap = options.sqlMap;
1132
+ }
883
1133
  if (options.sqlDir) {
884
1134
  const sqlFis = globalThis[_fs].readdirSync(options.sqlDir);
885
1135
  for (const modeName of sqlFis) {
886
- const name = globalThis[_path].basename(modeName, globalThis[_path].extname(modeName));
887
- const obj = await import(globalThis[_path].join(options.sqlDir, modeName));
888
- for (const [key, fn] of Object.entries(obj)) {
889
- this.cache[`${name}.${String(key)}`] = fn;
1136
+ const extname = globalThis[_path].extname(modeName);
1137
+ const name = globalThis[_path].basename(modeName, extname);
1138
+ const file = globalThis[_path].join(options.sqlDir, modeName);
1139
+ if (extname === 'mu') {
1140
+ const parser = new MUParser(name, globalThis[_fs].readFileSync(file, { encoding: 'utf-8' }).toString());
1141
+ let source = parser.next();
1142
+ while (source != null) {
1143
+ this.sqlMap[source[0]] = source[1];
1144
+ logger.debug(`sql: ${source[0]} found!`);
1145
+ source = parser.next();
1146
+ }
1147
+ }
1148
+ else if (extname === '.js') {
1149
+ const obj = (await import(globalThis[_path].join(options.sqlDir, modeName))).default;
1150
+ for (const [key, fn] of Object.entries(obj)) {
1151
+ this.sqlMap[`${name}.${String(key)}`] = fn;
1152
+ }
890
1153
  }
891
1154
  }
892
1155
  }
893
- else if (options.sqlCache) {
894
- this.cache = options.sqlCache;
1156
+ if (options.sqlFNMap) {
1157
+ this.sqlFNMap = options.sqlFNMap;
1158
+ }
1159
+ if (options.sqlFNDir) {
1160
+ const sqlFis = globalThis[_fs].readdirSync(options.sqlDir);
1161
+ for (const modeName of sqlFis) {
1162
+ const extname = globalThis[_path].extname(modeName);
1163
+ const name = globalThis[_path].basename(modeName, extname);
1164
+ const file = globalThis[_path].join(options.sqlDir, modeName);
1165
+ if (extname === 'mu') {
1166
+ this.sqlFNMap[name] = globalThis[_fs].readFileSync(file, { encoding: 'utf-8' }).toString();
1167
+ }
1168
+ }
895
1169
  }
896
1170
  }
897
- load(sqlid, params, context, isPage) {
898
- const sqlSource = this.cache[sqlid];
1171
+ load(sqlid, options) {
1172
+ const sqlSource = this.sqlMap[sqlid];
899
1173
  Throw.if(!sqlSource, `指定的语句${sqlid}不存在!`);
900
- if (typeof sqlSource === 'string') {
901
- return sqlSource;
902
- }
903
- else {
904
- return sqlSource(params, context, isPage);
905
- }
1174
+ const _sql = typeof sqlSource === 'function' ? sqlSource(options) : sqlSource;
1175
+ const buildParam = new Build(options.isCount === true, options.isSum === true, options);
1176
+ const sql = mustache.render(_sql, buildParam, this.sqlFNMap);
1177
+ logger.debug(sqlid, sql);
1178
+ return sql;
906
1179
  }
907
1180
  }
908
1181
  // #endregion
@@ -1023,7 +1296,7 @@ function P(skipConn = false) {
1023
1296
  }
1024
1297
  else if (this[_dbType] === DBType.SqliteRemote) {
1025
1298
  Throw.if(option.sync === SyncMode.Sync, 'SqliteRemote remote can not sync!');
1026
- return new Promise(async (resolve) => {
1299
+ return new Promise(async (resolve, reject) => {
1027
1300
  // 连接共享
1028
1301
  if (skipConn === false && !option.conn) {
1029
1302
  (option).conn = await option.dao.createConnection(SyncMode.Async);
@@ -1091,7 +1364,7 @@ function P(skipConn = false) {
1091
1364
  }
1092
1365
  catch (error) {
1093
1366
  console.error(`service ${propertyKey} have an error:${error}, it's argumens: ${JSON.stringify(args.filter(i => typeof i !== 'object' || (typeof i === 'object' && !i.insert)))}`);
1094
- throw error;
1367
+ reject(error);
1095
1368
  }
1096
1369
  finally {
1097
1370
  if (needRealseConn && option && option.conn) {
@@ -1105,7 +1378,7 @@ function P(skipConn = false) {
1105
1378
  });
1106
1379
  }
1107
1380
  else if (this[_dbType] === DBType.Mysql) {
1108
- return new Promise(async (resolve) => {
1381
+ return new Promise(async (resolve, reject) => {
1109
1382
  try {
1110
1383
  // 连接共享
1111
1384
  if (skipConn === false && !option.conn) {
@@ -1120,7 +1393,7 @@ function P(skipConn = false) {
1120
1393
  }
1121
1394
  catch (error) {
1122
1395
  console.error(`service ${propertyKey} have an error:${error}, it's argumens: ${JSON.stringify(args.filter(i => typeof i !== 'object' || (typeof i === 'object' && !i.insert)))}`);
1123
- throw error;
1396
+ reject(error);
1124
1397
  }
1125
1398
  finally {
1126
1399
  if (needRealseConn && option && option.conn) {
@@ -1200,17 +1473,17 @@ export const Field = (config) => {
1200
1473
  break;
1201
1474
  }
1202
1475
  case SqlType.float: {
1203
- field[DBType.Mysql] = `${field.esName} float(${config.length1 ?? 1}, ${config.length2 ?? 2}) ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''} `;
1476
+ field[DBType.Mysql] = `${field.esName} float(${config.length ?? 1}, ${config.scale ?? 2}) ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''} `;
1204
1477
  field[DBType.SqliteRemote] = field[DBType.Sqlite] = `${field.esName} real`;
1205
1478
  break;
1206
1479
  }
1207
1480
  case SqlType.double: {
1208
- field[DBType.Mysql] = `${field.esName} double(${config.length1 ?? 1}, ${config.length2 ?? 2}) ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''} `;
1481
+ field[DBType.Mysql] = `${field.esName} double(${config.length ?? 1}, ${config.scale ?? 2}) ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''} `;
1209
1482
  field[DBType.SqliteRemote] = field[DBType.Sqlite] = `${field.esName} real`;
1210
1483
  break;
1211
1484
  }
1212
1485
  case SqlType.decimal: {
1213
- field[DBType.Mysql] = `${field.esName} decimal(${config.length1 ?? 1}, ${config.length2 ?? 2}) ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''} `;
1486
+ field[DBType.Mysql] = `${field.esName} decimal(${config.length ?? 1}, ${config.scale ?? 2}) ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''} `;
1214
1487
  field[DBType.SqliteRemote] = field[DBType.Sqlite] = `${field.esName} real`;
1215
1488
  break;
1216
1489
  }
@@ -1255,12 +1528,12 @@ export const Field = (config) => {
1255
1528
  break;
1256
1529
  }
1257
1530
  case SqlType.char: {
1258
- field[DBType.Mysql] = `${field.esName} char(${config.length1 ?? 1}) ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''} ${MYSQLCHARSET}`;
1531
+ field[DBType.Mysql] = `${field.esName} char(${config.length ?? 1}) ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''} ${MYSQLCHARSET}`;
1259
1532
  field[DBType.SqliteRemote] = field[DBType.Sqlite] = `${field.esName} text`;
1260
1533
  break;
1261
1534
  }
1262
1535
  case SqlType.varchar: {
1263
- field[DBType.Mysql] = `${field.esName} varchar(${config.length1 ?? 1}) ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''} ${MYSQLCHARSET}`;
1536
+ field[DBType.Mysql] = `${field.esName} varchar(${config.length ?? 1}) ${config.notNull === true ? 'NOT NULL' : ''} ${hasDef ? field.def : ''} ${MYSQLCHARSET}`;
1264
1537
  field[DBType.SqliteRemote] = field[DBType.Sqlite] = `${field.esName} text`;
1265
1538
  break;
1266
1539
  }
@@ -2095,10 +2368,10 @@ export class SqlService {
2095
2368
  select(option) {
2096
2369
  Throw.if(!option.sqlId && !option.sql, 'not found sql!');
2097
2370
  option.selectResult ?? (option.selectResult = SelectResult.Many_Row_Many_Column);
2098
- option.sql ?? (option.sql = globalThis[_sqlCache].load(option.sqlId, option.context, option.isPage));
2099
2371
  option.defValue ?? (option.defValue = null);
2100
- logger.debug(option.sql);
2101
2372
  const _params = Object.assign({}, option.context, option.params);
2373
+ option.sql ?? (option.sql = globalThis[_sqlCache].load(option.sqlId, { ctx: option.context, isCount: option.isCount, ..._params }));
2374
+ logger.debug(option.sql);
2102
2375
  const params = [];
2103
2376
  const sql = option.sql?.replace(/\:(\w+)/g, (txt, key) => {
2104
2377
  if (_params.hasOwnProperty(key)) {
@@ -2121,9 +2394,9 @@ export class SqlService {
2121
2394
  }
2122
2395
  excute(option) {
2123
2396
  Throw.if(!option.sqlId && !option.sql, 'not found sql!');
2124
- option.sql ?? (option.sql = globalThis[_sqlCache].load(option.sqlId, option.context));
2125
- logger.debug(option.sql);
2126
2397
  const _params = Object.assign({}, option.context, option.params);
2398
+ option.sql ?? (option.sql = globalThis[_sqlCache].load(option.sqlId, { ctx: option.context, ..._params }));
2399
+ logger.debug(option.sql);
2127
2400
  const params = [];
2128
2401
  const sql = option.sql?.replace(/\:(\w+)/g, (txt, key) => {
2129
2402
  if (_params.hasOwnProperty(key)) {
@@ -3372,15 +3645,137 @@ export function MethodCache(config) {
3372
3645
  };
3373
3646
  };
3374
3647
  }
3648
+ class MUParser {
3649
+ constructor(modelName, file) {
3650
+ this.linNumber = 0;
3651
+ this.status = 0;
3652
+ this.lineSeparator = '\n';
3653
+ this.modelName = modelName;
3654
+ this.files = file.replace(/\r/g, '').split(this.lineSeparator);
3655
+ this.skipHeader();
3656
+ }
3657
+ next() {
3658
+ let sqlId = this.readSqlId();
3659
+ if (this.status === MUParser.END || !sqlId) {
3660
+ return null;
3661
+ }
3662
+ // 去掉可能的尾部空格
3663
+ sqlId = sqlId.trim();
3664
+ this.skipComment();
3665
+ if (this.status === MUParser.END) {
3666
+ return null;
3667
+ }
3668
+ const sql = this.readSql();
3669
+ return [`${this.modelName}.${sqlId}`, sql];
3670
+ }
3671
+ skipHeader() {
3672
+ while (true) {
3673
+ const line = this.nextLine();
3674
+ if (!line) {
3675
+ return;
3676
+ }
3677
+ if (this.status === MUParser.END) {
3678
+ return;
3679
+ }
3680
+ if (line.startsWith('===')) {
3681
+ return;
3682
+ }
3683
+ }
3684
+ }
3685
+ nextLine() {
3686
+ const line = this.files[this.linNumber];
3687
+ this.linNumber++;
3688
+ if (line === undefined) {
3689
+ this.status = MUParser.END;
3690
+ }
3691
+ // 保存最后读的俩行
3692
+ this.lastlastLine = this.lastLine;
3693
+ this.lastLine = line;
3694
+ return line;
3695
+ }
3696
+ readSqlId() {
3697
+ return this.lastlastLine;
3698
+ }
3699
+ skipComment() {
3700
+ let findComment = false;
3701
+ while (true) {
3702
+ let line = this.nextLine();
3703
+ if (this.status === MUParser.END || !line) {
3704
+ return;
3705
+ }
3706
+ line = line.trim();
3707
+ if (!findComment && line.length === 0) {
3708
+ continue;
3709
+ }
3710
+ if (line.startsWith('*')) {
3711
+ // 注释符号
3712
+ findComment = true;
3713
+ continue;
3714
+ }
3715
+ else {
3716
+ if (line.length === 0) {
3717
+ continue;
3718
+ }
3719
+ else if (line.startsWith('```') || line.startsWith('~~~')) {
3720
+ // 忽略以code block开头的符号
3721
+ continue;
3722
+ }
3723
+ else {
3724
+ // 注释结束
3725
+ return;
3726
+ }
3727
+ }
3728
+ }
3729
+ }
3730
+ readSql() {
3731
+ const list = [];
3732
+ if (this.lastLine) {
3733
+ list.push(this.lastLine);
3734
+ while (true) {
3735
+ const line = this.nextLine();
3736
+ if (line) {
3737
+ if (this.status === MUParser.END) {
3738
+ return this.getBuildSql(list);
3739
+ }
3740
+ if (line.startsWith('===')) {
3741
+ // 删除下一个sqlId表示
3742
+ list.pop();
3743
+ return this.getBuildSql(list);
3744
+ }
3745
+ list.push(line);
3746
+ }
3747
+ else {
3748
+ return '';
3749
+ }
3750
+ }
3751
+ }
3752
+ else {
3753
+ return '';
3754
+ }
3755
+ }
3756
+ getBuildSql(list) {
3757
+ const sb = [];
3758
+ for (const str of list) {
3759
+ const s = str.trim();
3760
+ if (s.startsWith('```') || s.startsWith('~~~')) {
3761
+ // 忽略以code block开头的符号
3762
+ continue;
3763
+ }
3764
+ sb.push(str);
3765
+ }
3766
+ return sb.join(this.lineSeparator);
3767
+ }
3768
+ }
3769
+ MUParser.END = 1;
3375
3770
  export const Boot = async function (options) {
3376
3771
  globalThis[_GlobalSqlOption] = Object.assign({}, _defOption, options);
3377
3772
  if (options.sqlDir) {
3378
- globalThis[_path] = import('path');
3379
- globalThis[_fs] = import('fs');
3773
+ globalThis[_path] = await import('path');
3774
+ globalThis[_fs] = await import('fs');
3380
3775
  }
3381
3776
  logger.level = options.log ?? 'info';
3382
3777
  globalThis[_sqlCache] = new SqlCache();
3383
- if (options.sqlCache || options.sqlDir) {
3778
+ if (options.sqlMap || options.sqlDir) {
3384
3779
  await globalThis[_sqlCache].init(options);
3385
3780
  }
3386
3781
  globalThis[_dao] = {