baja-lite 1.8.8 → 1.8.9

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 (47) hide show
  1. package/boot-remote.d.ts +1 -1
  2. package/boot-remote.js +6 -1
  3. package/boot.d.ts +1 -1
  4. package/boot.js +6 -1
  5. package/cache.d.ts +91 -0
  6. package/cache.js +515 -0
  7. package/const/index.d.ts +2 -0
  8. package/const/index.js +2 -0
  9. package/const/symbols.d.ts +73 -0
  10. package/const/symbols.js +78 -0
  11. package/const/types.d.ts +504 -0
  12. package/const/types.js +127 -0
  13. package/db/dao/format-dialects.d.ts +6 -0
  14. package/db/dao/format-dialects.js +8 -0
  15. package/db/dao/mysql.d.ts +44 -0
  16. package/db/dao/mysql.js +303 -0
  17. package/db/dao/postgresql.d.ts +44 -0
  18. package/db/dao/postgresql.js +322 -0
  19. package/db/dao/sqlite-remote.d.ts +46 -0
  20. package/db/dao/sqlite-remote.js +226 -0
  21. package/db/dao/sqlite.d.ts +41 -0
  22. package/db/dao/sqlite.js +237 -0
  23. package/db/index.d.ts +8 -0
  24. package/db/index.js +8 -0
  25. package/db/service.d.ts +778 -0
  26. package/db/service.js +1651 -0
  27. package/db/sql-template.d.ts +46 -0
  28. package/db/sql-template.js +660 -0
  29. package/db/stream-query.d.ts +607 -0
  30. package/db/stream-query.js +1626 -0
  31. package/index.d.ts +4 -1
  32. package/index.js +4 -1
  33. package/logger.d.ts +46 -0
  34. package/logger.js +35 -0
  35. package/package.json +1 -1
  36. package/sqlite.d.ts +1 -1
  37. package/sqlite.js +2 -1
  38. package/{test-mysql.js → test/test-mysql.js} +3 -2
  39. package/{test-postgresql.js → test/test-postgresql.js} +3 -2
  40. package/{test-sqlite.js → test/test-sqlite.js} +3 -2
  41. package/sql.d.ts +0 -2222
  42. package/sql.js +0 -5503
  43. /package/{test-mysql.d.ts → test/test-mysql.d.ts} +0 -0
  44. /package/{test-postgresql.d.ts → test/test-postgresql.d.ts} +0 -0
  45. /package/{test-sqlite.d.ts → test/test-sqlite.d.ts} +0 -0
  46. /package/{test-xml.d.ts → test/test-xml.d.ts} +0 -0
  47. /package/{test-xml.js → test/test-xml.js} +0 -0
@@ -0,0 +1,46 @@
1
+ import { MapperIfUndefined, SqlMapper, SqlMappers, _SqlModel } from '../const/types.js';
2
+ /**
3
+ * ifUndefined默认是MapperIfUndefined.Skip
4
+ */
5
+ export declare function flatData<M>(options: {
6
+ data: any;
7
+ mapper: string | SqlMapper;
8
+ mapperIfUndefined?: MapperIfUndefined;
9
+ }): M;
10
+ export declare class SqlCache {
11
+ private sqlMap;
12
+ private sqlFNMap;
13
+ private _read;
14
+ /**
15
+ *
16
+ * ```
17
+ // 第一个元素=列名,第二个元素是属性路径,
18
+ [
19
+ ['dit_id', ['id']], // 列名ditid,对应属性id
20
+ ['event_id', ['eventMainInfo', 'id']] // 列名event_id对应属性eventMainInfo.id
21
+ ]
22
+ * ```
23
+ * @param am
24
+ * @param keys
25
+ */
26
+ private readResultMap;
27
+ init(options: {
28
+ sqlMap?: _SqlModel;
29
+ sqlDir?: string;
30
+ sqlFNMap?: Record<string, string>;
31
+ sqlFNDir?: string;
32
+ sqlMapperMap?: SqlMappers;
33
+ sqlMapperDir?: string;
34
+ jsMode?: boolean;
35
+ }): Promise<void>;
36
+ load(sqlids: string[], options: {
37
+ ctx?: any;
38
+ isCount?: boolean;
39
+ isSum?: boolean;
40
+ limitStart?: number;
41
+ limitEnd?: number;
42
+ sortName?: string;
43
+ sortType?: string;
44
+ [k: string]: any;
45
+ }): string;
46
+ }
@@ -0,0 +1,660 @@
1
+ import HTML from 'html-parse-stringify';
2
+ import mustache from 'mustache';
3
+ import { convert } from '../convert-xml.js';
4
+ import { Throw } from '../error.js';
5
+ import { _enum, _fs, _LoggerService, _path, _resultMap, _resultMap_SQLID, } from '../const/symbols.js';
6
+ import { MapperIfUndefined, } from '../const/types.js';
7
+ class Build {
8
+ /**
9
+ *
10
+ * @param count 是否是count查询
11
+ * @param isSum 是否是sum查询
12
+ * @param param
13
+ */
14
+ constructor(isCount, isSum, param = {}) {
15
+ this.orderSeted = false;
16
+ this.isCount = isCount;
17
+ this.isSum = isSum;
18
+ this.orderBy = param.sortName ? `${param.sortName} ${param.sortType ?? 'ASC'}` : '';
19
+ Object.assign(this, param);
20
+ }
21
+ /**
22
+ *
23
+ * 当分页时将函数内包含的内容替换为COUNT(1)
24
+ * @returns
25
+ * @memberof Build
26
+ */
27
+ page() {
28
+ return (text, render) => {
29
+ if (this.isCount) {
30
+ return Build.page;
31
+ }
32
+ else if (this.isSum !== true) {
33
+ return render(text);
34
+ }
35
+ };
36
+ }
37
+ /**
38
+ *
39
+ * 包含的内容只在汇总查询时有效,否则是空白
40
+ * @returns
41
+ * @memberof Build
42
+ */
43
+ sum() {
44
+ return (text, render) => {
45
+ if (this.isSum !== true) {
46
+ return '';
47
+ }
48
+ else {
49
+ return render(text);
50
+ }
51
+ };
52
+ }
53
+ /**
54
+ *
55
+ * 当分页时、汇总时忽略函数内包含的内容
56
+ * @returns
57
+ * @memberof Build
58
+ */
59
+ notPage() {
60
+ return (text, render) => {
61
+ if (this.isCount || this.isSum) {
62
+ return '';
63
+ }
64
+ else {
65
+ return render(text);
66
+ }
67
+ };
68
+ }
69
+ /**
70
+ *
71
+ * 将查询条件包起来,如果条件内容不为空,则自动添加WHERE,同时将第一个条件的and、or替换为空
72
+ * 例如:
73
+ * {{#whereTag}}
74
+ * and name = 1
75
+ * and page = 2
76
+ * {{/whereTag}}
77
+ * 输出
78
+ * where name = 1 and page = 2
79
+ * @returns
80
+ * @memberof Build
81
+ */
82
+ where() {
83
+ return (text, render) => {
84
+ let data = render(text).trim();
85
+ if (data) {
86
+ data = data.replace(/and|or/i, '');
87
+ return ` WHERE ${data} `;
88
+ }
89
+ else {
90
+ return '';
91
+ }
92
+ };
93
+ }
94
+ /**
95
+ * ```
96
+ * SELECT
97
+ * {{#hump}}
98
+ * a.event_id, a.event_name eventName
99
+ * {{/hump}}
100
+ * FROM...
101
+ * ```
102
+ * 编译后:
103
+ * ```
104
+ * SELECT
105
+ * a.event_id eventId, a.event_name eventName
106
+ * FROM...
107
+ * ```
108
+ */
109
+ hump() {
110
+ return (text, render) => {
111
+ let data = render(text).trim();
112
+ const datas = data.split(',');
113
+ for (let i = 0; i < datas.length; i++) {
114
+ if (datas[i]?.match(/\s|\t/) === null) {
115
+ datas[i] = `${datas[i]} ${datas[i].replace(/[a-zA-Z0-9]+\./, '').replace(/_([a-z])/g, (a, b, c) => b.toUpperCase())}`;
116
+ }
117
+ }
118
+ return ` ${datas.join(',')} `;
119
+ };
120
+ }
121
+ /**
122
+ * 删除第一个and、or
123
+ * 删除最后一个,
124
+ * 删除最后一个;
125
+ * @memberof Build
126
+ */
127
+ trim() {
128
+ return (text, render) => {
129
+ let data = render(text);
130
+ data = data.trim();
131
+ if (data) {
132
+ data = data.replace(/(^and\s)|(^or\s)|(,$)|(;$)/i, '');
133
+ return data;
134
+ }
135
+ else {
136
+ return '';
137
+ }
138
+ };
139
+ }
140
+ /**
141
+ * 分页时将排序部分代码用此函数包起来,可以自动拼接order by
142
+ * 查询条数时,自动忽略此部分
143
+ * etc
144
+ * {{#order}} name desc, age asc {{/order}}
145
+ * ===
146
+ * ORDER BY name desc, age asc
147
+ * @returns
148
+ * @memberof Build
149
+ */
150
+ order() {
151
+ return (text, render) => {
152
+ if (this.isCount || this.isSum) {
153
+ return '';
154
+ }
155
+ else {
156
+ this.orderSeted = true;
157
+ const orderBy = new Array();
158
+ if (this.orderBy) {
159
+ orderBy.push(this.orderBy);
160
+ }
161
+ const renderOrder = render(text);
162
+ if (/\S/.test(renderOrder)) {
163
+ orderBy.push(renderOrder);
164
+ }
165
+ return orderBy.length > 0 ? ` ORDER BY ${orderBy.join(',')} ` : '';
166
+ }
167
+ };
168
+ }
169
+ /**
170
+ *
171
+ * 分页时将分组部分代码用此函数包起来,可以自动拼接GROUP BY
172
+ * 当分页时、汇总时,自动忽略此部分
173
+ * etc
174
+ * {{#between}} name, age {{/between}}
175
+ * ===
176
+ * group by name.age
177
+ * @returns
178
+ * @memberof Build
179
+ */
180
+ group() {
181
+ return (text, render) => {
182
+ if (this.isCount || this.isSum) {
183
+ return '';
184
+ }
185
+ else {
186
+ const groupBy = render(text) || '';
187
+ return /\S/.test(groupBy) ? ` GROUP BY ${groupBy} ` : '';
188
+ }
189
+ };
190
+ }
191
+ /**
192
+ *
193
+ * # beetween and
194
+ * ## etc.
195
+ * ```
196
+ * {{#between}} AND t.createtime ({{createtime}}) {{/between}}
197
+ * // 其中:
198
+ * createtime = '1,2'
199
+ * // 或者
200
+ * createtime = ['1', '2']
201
+ * // 将生成:
202
+ * AND t.createtime BETWEEN '1' AND '2'
203
+ * ```
204
+ * @returns
205
+ * @memberof Build
206
+ */
207
+ between() {
208
+ return (text, render) => {
209
+ const result = render(text);
210
+ if (/\(([\w\W]+)\)/.exec(result)) {
211
+ return render(text).replace(/\(([\w\W]+)\)/, (a, b) => {
212
+ if (a && b) {
213
+ if (typeof b === 'string') {
214
+ const xx = b.split(',');
215
+ return ` BETWEEN '${xx[0]}' AND '${xx[1]}'`;
216
+ }
217
+ else {
218
+ return ` BETWEEN '${b[0]}' AND '${b[1]}'`;
219
+ }
220
+ }
221
+ else {
222
+ return '';
223
+ }
224
+ }).replace(/\|/, ' BETWEEN ');
225
+ }
226
+ else {
227
+ return '';
228
+ }
229
+ };
230
+ }
231
+ /**
232
+ *
233
+ * 距离计算,单位米
234
+ * etc
235
+ * {{#distance}} (t.longitude, t.latitude), ({{longitude}}, {{latitude}}) {{/distance}}
236
+ * ===
237
+ * ROUND(ST_DISTANCE(POINT(longitude1, latitude1), POINT({{longitude}}, {{latitude}}))*111195, 2)
238
+ * 可根据需求自行将数据转换为千米,例如
239
+ * {{#distance}} (t.longitude, t.latitude), ({{longitude}}, {{latitude}}) {{/distance}} / 1000
240
+ * @returns
241
+ * @memberof Build
242
+ */
243
+ distance() {
244
+ return (text, render) => {
245
+ const result = render(text);
246
+ if (/\(([^()]+)\)/.exec(result)) {
247
+ let index = 0;
248
+ return render(text).replace(/\(([^()]+)\)/g, (a, b) => {
249
+ if (a && b) {
250
+ const xx = b.split(',');
251
+ if (index === 0) {
252
+ index++;
253
+ return ` ROUND(ST_DISTANCE(POINT(${xx[0]}, ${xx[1]}) `;
254
+ }
255
+ else {
256
+ return ` POINT(${xx[0]}, ${xx[1]}))*111195, 2)`;
257
+ }
258
+ }
259
+ else {
260
+ return '';
261
+ }
262
+ });
263
+ }
264
+ else {
265
+ return '';
266
+ }
267
+ };
268
+ }
269
+ /**
270
+ * * PROBLEM_TYPE = 枚举名
271
+ * * t.problemtype = 列名
272
+ *
273
+ * ```
274
+ * {{#enumTag}} PROBLEM_TYPE(t.problemtype) {{/enumTag}}
275
+ * ```
276
+ */
277
+ enum() {
278
+ return (text) => {
279
+ const matchs = text.match(/([a-zA-Z_]+)\(([^()]+)\)/);
280
+ if (matchs) {
281
+ const [_a, MapName, Column] = matchs;
282
+ if (MapName && Column) {
283
+ const map = globalThis[_enum].EnumMap(MapName.trim());
284
+ if (map) {
285
+ return ` CASE
286
+ ${Object.entries(map).map(([k, v]) => `WHEN ${Column} = '${k}' THEN '${v}'`).join(' ')}
287
+ END `;
288
+ }
289
+ }
290
+ }
291
+ return "''";
292
+ };
293
+ }
294
+ get OrderSeted() {
295
+ return this.orderSeted;
296
+ }
297
+ get OrderBy() {
298
+ return this.orderBy;
299
+ }
300
+ }
301
+ Build.page = 'COUNT(1) zccw1986 ';
302
+ function replaceCdata(rawText) {
303
+ var cdataRegex = new RegExp('(<!\\[CDATA\\[)([\\s\\S]*?)(\\]\\]>)', 'g');
304
+ var matches = rawText.match(cdataRegex);
305
+ if (matches != null && matches.length > 0) {
306
+ for (var z = 0; z < matches.length; z++) {
307
+ var regex = new RegExp('(<!\\[CDATA\\[)([\\s\\S]*?)(\\]\\]>)', 'g');
308
+ var m = regex.exec(matches[z]);
309
+ var cdataText = m[2];
310
+ cdataText = cdataText.replace(/\&/g, '&amp;');
311
+ cdataText = cdataText.replace(/\</g, '&lt;');
312
+ cdataText = cdataText.replace(/\>/g, '&gt;');
313
+ cdataText = cdataText.replace(/\"/g, '&quot;');
314
+ rawText = rawText.replace(m[0], cdataText);
315
+ }
316
+ }
317
+ return rawText;
318
+ }
319
+ function _flatData(result, i, length, keys, V, convert) {
320
+ var _b;
321
+ const key = keys[i];
322
+ if (i < length) {
323
+ result[_b = key] ?? (result[_b] = {});
324
+ i++;
325
+ _flatData(result[key], i, length, keys, V);
326
+ }
327
+ else {
328
+ if (convert) {
329
+ result[key] = convert(V);
330
+ }
331
+ else {
332
+ result[key] = V;
333
+ }
334
+ }
335
+ }
336
+ /**
337
+ * ifUndefined默认是MapperIfUndefined.Skip
338
+ */
339
+ export function flatData(options) {
340
+ if (typeof options.mapper === 'string') {
341
+ const name = options.mapper;
342
+ options.mapper = globalThis[_resultMap][name];
343
+ Throw.if(!options.mapper, `not found mapper!${name}`);
344
+ }
345
+ options.mapperIfUndefined ?? (options.mapperIfUndefined = MapperIfUndefined.Skip);
346
+ options.mapper = options.mapper;
347
+ const result = {};
348
+ for (const { columnName, mapNames, def, convert } of options.mapper) {
349
+ let V = options.data[columnName];
350
+ if (V === undefined) {
351
+ if (options.mapperIfUndefined === MapperIfUndefined.Null) {
352
+ V = null;
353
+ }
354
+ else if (options.mapperIfUndefined === MapperIfUndefined.Zero) {
355
+ V = 0;
356
+ }
357
+ else if (options.mapperIfUndefined === MapperIfUndefined.EmptyString) {
358
+ V = '';
359
+ }
360
+ else if (def !== undefined) {
361
+ V = def;
362
+ }
363
+ else {
364
+ continue;
365
+ }
366
+ }
367
+ _flatData(result, 0, mapNames.length - 1, mapNames, V, convert);
368
+ }
369
+ return result;
370
+ }
371
+ export class SqlCache {
372
+ constructor() {
373
+ this.sqlMap = {};
374
+ this.sqlFNMap = {};
375
+ }
376
+ async _read(jsMode, sqlDir, queryTypes, rootName) {
377
+ const sqlFis = globalThis[_fs].readdirSync(sqlDir);
378
+ for (const modeName of sqlFis) {
379
+ const file = globalThis[_path].join(sqlDir, modeName);
380
+ const stat = globalThis[_fs].statSync(file);
381
+ if (stat.isDirectory()) {
382
+ await this._read(jsMode, file, queryTypes, modeName);
383
+ }
384
+ else {
385
+ const extname = globalThis[_path].extname(modeName);
386
+ const name = globalThis[_path].basename(modeName, extname);
387
+ let ct = 0;
388
+ if (extname === '.mu') {
389
+ globalThis[_LoggerService].debug?.(`sql: ${file} start explain!`);
390
+ const parser = new MUParser(rootName || name, globalThis[_fs].readFileSync(file, { encoding: 'utf-8' }).toString());
391
+ let source = parser.next();
392
+ while (source != null) {
393
+ ct++;
394
+ this.sqlMap[source[0]] = source[1];
395
+ globalThis[_LoggerService].debug?.(`sql: ${source[0]} found!`);
396
+ source = parser.next();
397
+ }
398
+ globalThis[_LoggerService].debug?.(`sql: ${file} explain over[${ct}]!`);
399
+ }
400
+ else if (jsMode && extname === '.js') {
401
+ globalThis[_LoggerService].debug?.(`sql: ${file} start explain!`);
402
+ const obj = (await import(globalThis[_path].join(sqlDir, modeName))).default;
403
+ for (const [key, fn] of Object.entries(obj)) {
404
+ ct++;
405
+ this.sqlMap[`${rootName || name}.${String(key)}`] = fn;
406
+ }
407
+ globalThis[_LoggerService].debug?.(`sql: ${file} explain over[${ct}]!`);
408
+ }
409
+ else if (extname === '.xml') {
410
+ globalThis[_LoggerService].debug?.(`sql: ${file} start explain!`);
411
+ const root = HTML.parse(replaceCdata(globalThis[_fs].readFileSync(file, { encoding: 'utf-8' }).toString()))[0];
412
+ if (root) {
413
+ const mappers = root.children;
414
+ for (const mapper of mappers) {
415
+ if (mapper.type === 'tag' && mapper.name === 'mapper') {
416
+ for (const am of mapper.children) {
417
+ if (am.type === 'tag') {
418
+ Throw.if(!queryTypes.includes(am.name), `${rootName} ${name}错误,${am.name}不支持!`);
419
+ am.id = am.attrs['id'];
420
+ Throw.if(!am.id, `${rootName} ${name}错误,没有为此块设置id:${am}`);
421
+ if (am.name === 'resultMap') {
422
+ ct++;
423
+ globalThis[_resultMap] ?? (globalThis[_resultMap] = {});
424
+ const keys = [];
425
+ this.readResultMap(am.children, keys, []);
426
+ globalThis[_resultMap][`${rootName || name}.${am.id}`] = keys;
427
+ globalThis[_LoggerService].debug?.(`sql_resultMap: ${`${rootName || name}.${am.id}`} found!`);
428
+ }
429
+ else {
430
+ this.sqlMap[`${rootName || name}.${am.id}`] = am.children;
431
+ if (am.attrs['resultMap']) {
432
+ globalThis[_resultMap_SQLID][`${rootName || name}.${am.id}`] = am.attrs['resultMap'];
433
+ globalThis[_LoggerService].debug?.(`sql: autoMapper: ${rootName || name}.${am.id}-${am.attrs['resultMap']}`);
434
+ }
435
+ globalThis[_LoggerService].debug?.(`sql: ${rootName || name}.${am.id} found!`);
436
+ ct++;
437
+ }
438
+ }
439
+ }
440
+ }
441
+ }
442
+ }
443
+ globalThis[_LoggerService].debug?.(`sql: ${file} explain over[${ct}]!`);
444
+ }
445
+ }
446
+ }
447
+ }
448
+ /**
449
+ *
450
+ * ```
451
+ // 第一个元素=列名,第二个元素是属性路径,
452
+ [
453
+ ['dit_id', ['id']], // 列名ditid,对应属性id
454
+ ['event_id', ['eventMainInfo', 'id']] // 列名event_id对应属性eventMainInfo.id
455
+ ]
456
+ * ```
457
+ * @param am
458
+ * @param keys
459
+ */
460
+ readResultMap(ams, keys, key) {
461
+ for (const am of ams) {
462
+ if (am.type === 'tag') {
463
+ if (am.name === 'result' || am.name === 'id') {
464
+ keys.push({
465
+ columnName: am.attrs['column'],
466
+ mapNames: [...key, am.attrs['property']]
467
+ });
468
+ }
469
+ else {
470
+ this.readResultMap(am.children, keys, [...key, am.attrs['property']]);
471
+ }
472
+ }
473
+ }
474
+ }
475
+ async init(options) {
476
+ if (options.sqlMap) {
477
+ this.sqlMap = options.sqlMap;
478
+ }
479
+ const queryTypes = ['sql', 'select', 'insert', 'update', 'delete', 'resultMap'];
480
+ if (options.sqlDir) {
481
+ await this._read(options.jsMode === true, options.sqlDir, queryTypes, '');
482
+ }
483
+ if (options.sqlFNMap) {
484
+ this.sqlFNMap = options.sqlFNMap;
485
+ }
486
+ if (options.sqlFNDir) {
487
+ const sqlFis = globalThis[_fs].readdirSync(options.sqlFNDir);
488
+ for (const modeName of sqlFis) {
489
+ const extname = globalThis[_path].extname(modeName);
490
+ const name = globalThis[_path].basename(modeName, extname);
491
+ const file = globalThis[_path].join(options.sqlFNDir, modeName);
492
+ if (extname === '.mu') {
493
+ this.sqlFNMap[name] = globalThis[_fs].readFileSync(file, { encoding: 'utf-8' }).toString();
494
+ }
495
+ }
496
+ }
497
+ if (options.sqlMapperMap) {
498
+ globalThis[_resultMap] = options.sqlMapperMap;
499
+ }
500
+ if (options.sqlMapperDir) {
501
+ const sqlFis = globalThis[_fs].readdirSync(options.sqlMapperDir);
502
+ globalThis[_resultMap] ?? (globalThis[_resultMap] = {});
503
+ for (const modeName of sqlFis) {
504
+ const extname = globalThis[_path].extname(modeName);
505
+ const name = globalThis[_path].basename(modeName, extname);
506
+ const file = globalThis[_path].join(options.sqlMapperDir, modeName);
507
+ if (extname === '.json') {
508
+ globalThis[_resultMap][name] = JSON.parse(globalThis[_fs].readFileSync(file, { encoding: 'utf-8' }).toString());
509
+ }
510
+ }
511
+ }
512
+ }
513
+ load(sqlids, options) {
514
+ let sqlSource;
515
+ for (const sqlid of sqlids) {
516
+ sqlSource = this.sqlMap[sqlid];
517
+ if (sqlSource) {
518
+ break;
519
+ }
520
+ }
521
+ const matchSqlid = sqlids.map(i => i.split('.')[0]);
522
+ Throw.if(!sqlSource, `指定的语句${sqlids.join('|')}不存在!`);
523
+ const buildParam = new Build(options.isCount === true, options.isSum === true, options);
524
+ if (typeof sqlSource === 'function') {
525
+ const _sql = sqlSource(options);
526
+ let sql = mustache.render(_sql, buildParam, this.sqlFNMap);
527
+ if (buildParam.OrderSeted === false && buildParam.OrderBy && options.isCount !== true && options.isSum !== true) {
528
+ sql += ` ORDER BY ${buildParam.OrderBy}`;
529
+ }
530
+ return sql;
531
+ }
532
+ else if (typeof sqlSource === 'string') {
533
+ let sql = mustache.render(sqlSource, buildParam, this.sqlFNMap);
534
+ if (buildParam.OrderSeted === false && buildParam.OrderBy && options.isCount !== true && options.isSum !== true) {
535
+ sql += ` ORDER BY ${buildParam.OrderBy}`;
536
+ }
537
+ return sql;
538
+ }
539
+ else if (typeof sqlSource === 'object') {
540
+ const _sql = convert(sqlSource, options, matchSqlid, this.sqlMap);
541
+ let sql = mustache.render(_sql, buildParam, this.sqlFNMap);
542
+ if (buildParam.OrderSeted === false && buildParam.OrderBy && options.isCount !== true && options.isSum !== true) {
543
+ sql += ` ORDER BY ${buildParam.OrderBy}`;
544
+ }
545
+ return sql;
546
+ }
547
+ return '';
548
+ }
549
+ }
550
+ class MUParser {
551
+ constructor(modelName, file) {
552
+ this.linNumber = 0;
553
+ this.lastLine = '';
554
+ this.lastlastLine = '';
555
+ this.status = 0;
556
+ this.lineSeparator = '\n';
557
+ this.modelName = modelName;
558
+ this.files = file.replace(/\r/g, '').split(this.lineSeparator);
559
+ this.skipHeader();
560
+ }
561
+ next() {
562
+ let sqlId = this.readSqlId();
563
+ if (this.status === MUParser.END) {
564
+ return null;
565
+ }
566
+ // 去掉可能的尾部空格
567
+ sqlId = sqlId.trim();
568
+ this.skipComment();
569
+ if (this.status === MUParser.END) {
570
+ return null;
571
+ }
572
+ const sql = this.readSql();
573
+ return [`${this.modelName}.${sqlId}`, sql];
574
+ }
575
+ skipHeader() {
576
+ while (true) {
577
+ const line = this.nextLine();
578
+ if (this.status === MUParser.END) {
579
+ return;
580
+ }
581
+ if (line.startsWith('===')) {
582
+ return;
583
+ }
584
+ }
585
+ }
586
+ nextLine() {
587
+ const line = this.files[this.linNumber];
588
+ this.linNumber++;
589
+ if (line === undefined) {
590
+ this.status = MUParser.END;
591
+ }
592
+ // 保存最后读的俩行
593
+ this.lastlastLine = this.lastLine;
594
+ this.lastLine = line;
595
+ return line;
596
+ }
597
+ readSqlId() {
598
+ return this.lastlastLine;
599
+ }
600
+ skipComment() {
601
+ let findComment = false;
602
+ while (true) {
603
+ let line = this.nextLine();
604
+ if (this.status === MUParser.END) {
605
+ return;
606
+ }
607
+ line = line.trim();
608
+ if (!findComment && line.length === 0) {
609
+ continue;
610
+ }
611
+ if (line.startsWith('*')) {
612
+ // 注释符号
613
+ findComment = true;
614
+ continue;
615
+ }
616
+ else {
617
+ if (line.length === 0) {
618
+ continue;
619
+ }
620
+ else if (line.startsWith('```') || line.startsWith('~~~')) {
621
+ // 忽略以code block开头的符号
622
+ continue;
623
+ }
624
+ else {
625
+ // 注释结束
626
+ return;
627
+ }
628
+ }
629
+ }
630
+ }
631
+ readSql() {
632
+ const list = [];
633
+ list.push(this.lastLine);
634
+ while (true) {
635
+ const line = this.nextLine();
636
+ if (this.status === MUParser.END) {
637
+ return this.getBuildSql(list);
638
+ }
639
+ if (line.startsWith('===')) {
640
+ // 删除下一个sqlId表示
641
+ list.pop();
642
+ return this.getBuildSql(list);
643
+ }
644
+ list.push(line);
645
+ }
646
+ }
647
+ getBuildSql(list) {
648
+ const sb = [];
649
+ for (const str of list) {
650
+ const s = str.trim();
651
+ if (s.startsWith('```') || s.startsWith('~~~')) {
652
+ // 忽略以code block开头的符号
653
+ continue;
654
+ }
655
+ sb.push(str);
656
+ }
657
+ return sb.join(this.lineSeparator);
658
+ }
659
+ }
660
+ MUParser.END = 1;