baja-lite 1.6.4 → 1.6.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/boot-remote.d.ts +2 -0
  2. package/{src/boot-remote.ts → boot-remote.js} +66 -64
  3. package/boot.d.ts +2 -0
  4. package/{src/boot.ts → boot.js} +166 -170
  5. package/code.d.ts +2 -0
  6. package/{src/code.ts → code.js} +405 -414
  7. package/convert-xml.d.ts +10 -0
  8. package/{src/convert-xml.ts → convert-xml.js} +410 -460
  9. package/error.d.ts +5 -0
  10. package/error.js +13 -0
  11. package/event.d.ts +10 -0
  12. package/event.js +38 -0
  13. package/fn.d.ts +128 -0
  14. package/fn.js +172 -0
  15. package/{src/index.ts → index.d.ts} +10 -11
  16. package/index.js +10 -0
  17. package/math.d.ts +83 -0
  18. package/math.js +451 -0
  19. package/object.d.ts +126 -0
  20. package/object.js +321 -0
  21. package/package.json +13 -13
  22. package/snowflake.d.ts +12 -0
  23. package/{src/snowflake.ts → snowflake.js} +108 -127
  24. package/sql.d.ts +2151 -0
  25. package/sql.js +5371 -0
  26. package/sqlite.d.ts +32 -0
  27. package/{src/sqlite.ts → sqlite.js} +156 -157
  28. package/string.d.ts +17 -0
  29. package/string.js +105 -0
  30. package/test-mysql.d.ts +2 -0
  31. package/test-mysql.js +114 -0
  32. package/test-postgresql.d.ts +2 -0
  33. package/{src/test-postgresql.ts → test-postgresql.js} +91 -80
  34. package/test-sqlite.d.ts +1 -0
  35. package/{src/test-sqlite.ts → test-sqlite.js} +90 -80
  36. package/test-xml.d.ts +1 -0
  37. package/{src/test-xml.ts → test-xml.js} +2 -2
  38. package/test.d.ts +1 -0
  39. package/{src/test.ts → test.js} +2 -3
  40. package/wx/base.d.ts +11 -0
  41. package/wx/base.js +78 -0
  42. package/wx/mini.d.ts +52 -0
  43. package/wx/mini.js +112 -0
  44. package/wx/organ.d.ts +65 -0
  45. package/wx/organ.js +171 -0
  46. package/{src/wx/types.ts → wx/types.d.ts} +560 -549
  47. package/wx/types.js +1 -0
  48. package/{src/wx.ts → wx.d.ts} +3 -3
  49. package/wx.js +3 -0
  50. package/.eslintignore +0 -7
  51. package/.eslintrc.cjs +0 -89
  52. package/.prettierrc +0 -7
  53. package/.vscode/settings.json +0 -9
  54. package/ci.js +0 -33
  55. package/package-cjs.json +0 -17
  56. package/pnpm-lock.yaml +0 -2840
  57. package/pnpm-workspace.yaml +0 -2
  58. package/src/error.ts +0 -11
  59. package/src/event.ts +0 -34
  60. package/src/fn.ts +0 -295
  61. package/src/math.ts +0 -405
  62. package/src/object.ts +0 -342
  63. package/src/sql.ts +0 -5529
  64. package/src/string.ts +0 -111
  65. package/src/test-mysql.ts +0 -148
  66. package/src/wx/base.ts +0 -77
  67. package/src/wx/mini.ts +0 -147
  68. package/src/wx/organ.ts +0 -290
  69. package/tsconfig.cjs.json +0 -42
  70. package/tsconfig.json +0 -44
  71. package/xml/event-report.xml +0 -13
  72. package/yarn.lock +0 -1977
  73. /package/{Readme.md → README.md} +0 -0
@@ -1,460 +1,410 @@
1
- import { LGet } from 'baja-lite-field';
2
- export interface XML {
3
- type: 'tag' | 'text';
4
- name: string;
5
- id?: string;
6
- voidElement: boolean;
7
- attrs: Record<string, string>;
8
- children: XML[];
9
- content: string;
10
- }
11
- export const convert = function (childrens: XML[], param: Record<string, any>, parentIds: string[], myBatisMapper: Record<string, XML[]>) {
12
- let statement = '';
13
- for (let i = 0, children: XML; children = childrens[i]!; i++) {
14
- // Convert SQL statement recursively
15
- statement += convertChildren(children, param, parentIds, myBatisMapper);
16
- }
17
- // Check not converted Parameters
18
- const regexList = ['\\#{\\S*}', '\\${\\S*}'];
19
- for (let i = 0, regexString: string; regexString = regexList[i]!; i++) {
20
- var checkParam = statement.match(regexString);
21
- if (checkParam != null && checkParam.length > 0) {
22
- throw new Error("Parameter " + checkParam.join(",") + " is not converted.");
23
- }
24
- }
25
- return statement;
26
- }
27
- const convertChildren = function (children: XML, param: Record<string, any>, parentIds: string[], myBatisMapper: Record<string, XML[]>) {
28
- param ??= {};
29
- if (!isDict(param)) {
30
- throw new Error('Parameter argument should be Key-Value type or Null.');
31
- }
32
- if (children.type == 'text') {
33
- // Convert Parameters
34
- return convertParameters(children, param);
35
-
36
- } else if (children.type == 'tag') {
37
- switch (children.name.toLowerCase()) {
38
- case 'if':
39
- return convertIf(children, param, parentIds, myBatisMapper);
40
- case 'choose':
41
- return convertChoose(children, param, parentIds, myBatisMapper);
42
- case 'trim':
43
- case 'where':
44
- return convertTrimWhere(children, param, parentIds, myBatisMapper);
45
- case 'set':
46
- return convertSet(children, param, parentIds, myBatisMapper);
47
- case 'foreach':
48
- return convertForeach(children, param, parentIds, myBatisMapper);
49
- case 'bind':
50
- param = convertBind(children, param);
51
- return '';
52
- case 'include':
53
- return convertInclude(children, param, parentIds, myBatisMapper);
54
- default:
55
- throw new Error('XML is not well-formed character or markup. Consider using CDATA section.');
56
- }
57
- } else {
58
- return '';
59
- }
60
- }
61
-
62
- const convertParameters = function (children: XML, param: Record<string, any>) {
63
- let convertString = children.content;
64
-
65
- try {
66
- convertString = convertParametersInner('#', convertString, param);
67
- convertString = convertParametersInner('$', convertString, param);
68
- } catch (err) {
69
- throw new Error('Error occurred during convert parameters.');
70
- }
71
-
72
- try {
73
- // convert CDATA string
74
- convertString = convertString.replace(/(\&amp\;)/g, '&');
75
- convertString = convertString.replace(/(\&lt\;)/g, '<');
76
- convertString = convertString.replace(/(\&gt\;)/g, '>');
77
- convertString = convertString.replace(/(\&quot\;)/g, '"');
78
- } catch (err) {
79
- throw new Error('Error occurred during convert CDATA section.');
80
- }
81
-
82
- return convertString;
83
- }
84
-
85
- const isObject = function (variable: any) {
86
- return typeof variable === 'object' && variable !== null;
87
- }
88
-
89
- const isArray = function (variable: any) {
90
- return isObject(variable) && variable.hasOwnProperty('length');
91
- }
92
-
93
- const convertParametersInner = function (change: string, convertString: string, param: Record<string, any>) {
94
- const stringReg = new RegExp('(\\' + change + '\\{[a-zA-Z0-9._\\$]+\\})', 'g');
95
- let stringTarget = convertString.match(stringReg);
96
-
97
- if (stringTarget != null && stringTarget.length > 0) {
98
- const _stringTarget = uniqueArray(stringTarget);
99
-
100
- let target: string | undefined;
101
- for (let i = 0; i < _stringTarget.length; i++) {
102
- target = _stringTarget[i];
103
- const t = target!.replace(change + '{', '').replace('}', '');
104
- let tempParamKey = LGet(param, t);
105
- if (tempParamKey !== undefined) {
106
- const reg = new RegExp('\\' + change + '{' + t + '}', 'g');
107
-
108
- if (tempParamKey === null) {
109
- tempParamKey = 'NULL';
110
- convertString = convertString.replace(reg, tempParamKey);
111
- } else {
112
- if (change == '#') {
113
- // processing JSON fields structures
114
- if (isObject(tempParamKey) || isArray(tempParamKey)) {
115
- tempParamKey = JSON.stringify(tempParamKey);
116
- } else {
117
- tempParamKey = tempParamKey.toString().replace(/"/g, '\\\"');
118
- tempParamKey = mysqlRealEscapeParam(tempParamKey);
119
- }
120
-
121
- tempParamKey = tempParamKey.replace(/'/g, "''");
122
- const replaceWith = "'" + tempParamKey + "'"
123
- convertString = convertString.replace(reg, () => replaceWith);
124
- } else if (change == '$') {
125
- convertString = convertString.replace(reg, tempParamKey);
126
- }
127
- }
128
- }
129
- }
130
- }
131
- return convertString;
132
- }
133
-
134
- const convertIf = function (children: XML, param: Record<string, any>, parentIds: string[], myBatisMapper: Record<string, XML[]>) {
135
- let evalString = children.attrs['test']!;
136
- try {
137
- // Create Evaluate string
138
- evalString = replaceEvalString(evalString, param);
139
-
140
- evalString = evalString.replace(/ and /gi, ' && ');
141
- evalString = evalString.replace(/ or /gi, ' || ');
142
-
143
- // replace == to === for strict evaluate
144
- // TODO: fix != null & != ''
145
- // evalString = evalString.replace(/==/g, '===');
146
- // evalString = evalString.replace(/!=/g, '!==');
147
-
148
- evalString = evalString.replace(/^'(.*?)'\.equalsIgnoreCase\( ([a-zA-Z]+\.[a-zA-Z]+) \)/i, `($2 && $2.toUpperCase() === '$1'.toUpperCase())`);
149
- evalString = evalString.replace(/\('(.*?)'\.equalsIgnoreCase\( ([a-zA-Z]+\.[a-zA-Z]+) \)/i, `(($2 && $2.toUpperCase() === '$1'.toUpperCase())`);
150
-
151
- } catch (err) {
152
- throw new Error('Error occurred during convert <if> element.');
153
- }
154
-
155
- // Execute Evaluate string
156
- try {
157
- if (eval(evalString)) {
158
- let convertString = '';
159
- for (let i = 0, nextChildren: XML; nextChildren = children['children'][i]!; i++) {
160
- convertString += convertChildren(nextChildren, param, parentIds, myBatisMapper);
161
- }
162
- return convertString;
163
-
164
- } else {
165
- return '';
166
- }
167
- } catch (e) {
168
- return '';
169
- }
170
- }
171
-
172
- const convertForeach = function (children: XML, param: Record<string, any>, parentIds: string[], myBatisMapper: Record<string, XML[]>) {
173
- try {
174
- const collection = eval('param.' + children.attrs['collection']);
175
- const item = children.attrs['item']!;
176
- const open = (children.attrs['open'] == null) ? '' : children.attrs['open'];
177
- const close = (children.attrs['close'] == null) ? '' : children.attrs['close'];
178
- const separator = (children.attrs['separator'] == null) ? '' : children.attrs['separator'];
179
-
180
- const foreachTexts: string[] = [];
181
- let coll = null;
182
- for (let j = 0; j < collection.length; j++) {
183
- coll = collection[j];
184
- const foreachParam = param;
185
- foreachParam[item] = coll;
186
-
187
- let foreachText = '';
188
- for (let k = 0, nextChildren: XML; nextChildren = children.children[k]!; k++) {
189
- let fText = convertChildren(nextChildren, foreachParam, parentIds, myBatisMapper);
190
- fText = fText.replace(/^\s*$/g, '');
191
- if (fText != null && fText.length > 0) {
192
- foreachText += fText;
193
- }
194
- }
195
-
196
- if (foreachText != null && foreachText.length > 0) {
197
- foreachTexts.push(foreachText);
198
- }
199
- }
200
-
201
- return (open + foreachTexts.join(separator) + close);
202
- } catch (err) {
203
- throw new Error('Error occurred during convert <foreach> element.');
204
- }
205
- }
206
-
207
- const convertChoose = function (children: XML, param: Record<string, any>, parentIds: string[], myBatisMapper: Record<string, XML[]>) {
208
- try {
209
- for (let i = 0, whenChildren; whenChildren = children.children[i]; i++) {
210
- if (whenChildren.type == 'tag' && whenChildren.name.toLowerCase() == 'when') {
211
- let evalString = whenChildren.attrs.test;
212
-
213
- // Create Evaluate string
214
- evalString = replaceEvalString(evalString, param);
215
-
216
- evalString = evalString.replace(/ and /gi, ' && ');
217
- evalString = evalString.replace(/ or /gi, ' || ');
218
-
219
- // Execute Evaluate string
220
- try {
221
- if (eval(evalString)) {
222
- // If <when> condition is true, do it.
223
- let convertString = '';
224
- for (let k = 0, nextChildren: XML; nextChildren = whenChildren.children[k]; k++) {
225
- convertString += convertChildren(nextChildren, param, parentIds, myBatisMapper);
226
- }
227
- return convertString;
228
- } else {
229
- continue;
230
- }
231
- } catch (e) {
232
- continue;
233
- }
234
- } else if (whenChildren.type == 'tag' && whenChildren.name.toLowerCase() == 'otherwise') {
235
- // If reached <otherwise> tag, do it.
236
- let convertString = '';
237
- for (let k = 0, nextChildren: XML; nextChildren = whenChildren.children[k]; k++) {
238
- convertString += convertChildren(nextChildren, param, parentIds, myBatisMapper);
239
- }
240
- return convertString;
241
- }
242
- }
243
-
244
- // If there is no suitable when and otherwise, just return null.
245
- return '';
246
-
247
- } catch (err) {
248
- throw new Error('Error occurred during convert <choose> element.');
249
- }
250
- }
251
-
252
- const convertTrimWhere = function (children: XML, param: Record<string, any>, parentIds: string[], myBatisMapper: Record<string, XML[]>) {
253
- let convertString = '';
254
- let prefix: string | undefined;
255
- let prefixOverrides: string | undefined;
256
- let suffix: string | undefined;
257
- let suffixOverrides: string | undefined;
258
- let globalSet: string | undefined;
259
-
260
- try {
261
- switch (children.name.toLowerCase()) {
262
- case 'trim':
263
- prefix = children.attrs["prefix"];
264
- prefixOverrides = children.attrs["prefixOverrides"];
265
- suffix = children.attrs["suffix"];
266
- suffixOverrides = children.attrs["suffixOverrides"];
267
- globalSet = 'g';
268
- break;
269
- case 'where':
270
- prefix = 'WHERE';
271
- prefixOverrides = 'and|or';
272
- globalSet = 'gi';
273
- break;
274
- default:
275
- throw new Error('Error occurred during convert <trim/where> element.');
276
- }
277
-
278
- // Convert children first.
279
- for (let j = 0, nextChildren: XML; nextChildren = children.children[j]!; j++) {
280
- convertString += convertChildren(nextChildren, param, parentIds, myBatisMapper);
281
- }
282
-
283
- // Remove prefixOverrides
284
- let trimRegex = new RegExp('(^)([\\s]*?)(' + prefixOverrides + ')', globalSet);
285
- convertString = convertString.replace(trimRegex, '');
286
- // Remove suffixOverrides
287
- trimRegex = new RegExp('(' + suffixOverrides + ')([\\s]*?)($)', globalSet);
288
- convertString = convertString.replace(trimRegex, '');
289
-
290
- if (children.name.toLowerCase() != 'trim') {
291
- trimRegex = new RegExp('(' + prefixOverrides + ')([\\s]*?)($)', globalSet);
292
- convertString = convertString.replace(trimRegex, '');
293
- }
294
-
295
- // Add Prefix if String is not empty.
296
- trimRegex = new RegExp('([a-zA-Z])', 'g');
297
- const w = convertString.match(trimRegex);
298
-
299
- if (w != null && w.length > 0) {
300
- convertString = prefix + ' ' + convertString;
301
- if (suffix) {
302
- convertString = convertString + ' ' + suffix
303
- }
304
- }
305
-
306
- // Remove comma(,) before WHERE
307
- if (children.name.toLowerCase() != 'where') {
308
- const regex = new RegExp('(,)([\\s]*?)(where)', 'gi');
309
- convertString = convertString.replace(regex, ' WHERE ');
310
- }
311
-
312
- return convertString;
313
- } catch (err) {
314
- throw new Error('Error occurred during convert <' + children.name.toLowerCase() + '> element.');
315
- }
316
- }
317
-
318
- const convertSet = function (children: XML, param: Record<string, any>, parentIds: string[], myBatisMapper: Record<string, XML[]>) {
319
- let convertString = '';
320
-
321
- try {
322
- // Convert children first.
323
- for (let j = 0, nextChildren: XML; nextChildren = children.children[j]!; j++) {
324
- convertString += convertChildren(nextChildren, param, parentIds, myBatisMapper);
325
- }
326
-
327
- // Remove comma repeated more than 2.
328
- let regex = new RegExp('(,)(,|\\s){2,}', 'g');
329
- convertString = convertString.replace(regex, ',\n');
330
-
331
- // Remove first comma if exists.
332
- regex = new RegExp('(^)([\\s]*?)(,)', 'g');
333
- convertString = convertString.replace(regex, '');
334
-
335
- // Remove last comma if exists.
336
- regex = new RegExp('(,)([\\s]*?)($)', 'g');
337
- convertString = convertString.replace(regex, '');
338
-
339
- convertString = ' SET ' + convertString;
340
- return convertString;
341
- } catch (err) {
342
- throw new Error('Error occurred during convert <set> element.');
343
- }
344
- }
345
-
346
- const convertBind = function (children: XML, param: Record<string, any>) {
347
- let evalString = children.attrs["value"]!;
348
-
349
- // Create Evaluate string
350
- evalString = replaceEvalString(evalString, param);
351
-
352
- param[children.attrs["name"]!] = eval(evalString);
353
-
354
- return param;
355
- }
356
-
357
- const convertInclude = function (children: XML, param: Record<string, any>, parentIds: string[], myBatisMapper: Record<string, XML[]>) {
358
- try {
359
- // Add Properties to param
360
- for (let j = 0, nextChildren: XML; nextChildren = children.children[j]!; j++) {
361
- if (nextChildren.type == 'tag' && nextChildren.name == 'property') {
362
- param[nextChildren.attrs['name']!] = nextChildren.attrs['value'];
363
- }
364
- }
365
- } catch (err) {
366
- throw new Error('Error occurred during read <property> element in <include> element.');
367
- }
368
-
369
- try {
370
- let refid = convertParametersInner('#', children.attrs['refid']!, param);
371
- refid = convertParametersInner('$', refid, param);
372
- let mapper: XML[] | undefined;
373
- for (const psqlid of parentIds) {
374
- mapper = myBatisMapper[`${psqlid}.${refid}`];
375
- if (mapper) {
376
- break;
377
- }
378
- }
379
- let statement = '';
380
- for (let i = 0, children: XML; children = mapper![i]!; i++) {
381
- statement += convertChildren(children, param, parentIds, myBatisMapper);
382
- }
383
- return statement;
384
- } catch (err) {
385
- throw new Error('Error occurred during convert refid attribute in <include> element.');
386
- }
387
-
388
- }
389
-
390
- const isDict = function (v: any) {
391
- return typeof v === 'object' && v !== null && !(v instanceof Array) && !(v instanceof Date);
392
- }
393
-
394
- const replaceEvalString = function (evalString: string, param: Record<string, any>) {
395
- const keys = Object.keys(param);
396
-
397
- for (let i = 0; i < keys.length; i++) {
398
- let replacePrefix = '';
399
- let replacePostfix = '';
400
- let paramRegex: RegExp | undefined;
401
-
402
- if (isDict(param[keys[i]!])) {
403
- replacePrefix = ' param.';
404
- replacePostfix = '';
405
-
406
- paramRegex = new RegExp('(^|[^a-zA-Z0-9_])(' + keys[i] + '\\.)([a-zA-Z0-9_]+)', 'g');
407
- } else {
408
- replacePrefix = ' param.';
409
- replacePostfix = ' ';
410
- paramRegex = new RegExp('(^|[^a-zA-Z0-9_])(' + keys[i] + ')($|[^a-zA-Z0-9_])', 'g');
411
- }
412
- evalString = evalString.replace(paramRegex, ('$1' + replacePrefix + '$2' + replacePostfix + '$3'));
413
- }
414
- return evalString;
415
- }
416
-
417
- const uniqueArray = function (a: RegExpMatchArray) {
418
- const seen = {};
419
- const out: string[] = [];
420
- const len = a.length;
421
- let j = 0;
422
- for (let i = 0; i < len; i++) {
423
- const item = a[i]!;
424
- if (seen[item] !== 1) {
425
- seen[item] = 1;
426
- out[j++] = item;
427
- }
428
- }
429
- return out;
430
- }
431
-
432
- const mysqlRealEscapeParam = function (param) {
433
- if (typeof param != 'string')
434
- return param;
435
-
436
- return param.replace(/[\0\x08\x09\x1a\n\r''\\\%]/g, function (char) {
437
- switch (char) {
438
- case '\0':
439
- return '\\0';
440
- case '\x08':
441
- return '\\b';
442
- case '\x09':
443
- return '\\t';
444
- case '\x1a':
445
- return '\\z';
446
- case '\n':
447
- return '\\n';
448
- case '\r':
449
- return '\\r';
450
- case '\'':
451
- case `'`:
452
- case '\\':
453
- case '%':
454
- return '\\' + char;
455
- default:
456
- return char;
457
- }
458
- });
459
- }
460
-
1
+ import { LGet } from 'baja-lite-field';
2
+ export const convert = function (childrens, param, parentIds, myBatisMapper) {
3
+ let statement = '';
4
+ for (let i = 0, children; children = childrens[i]; i++) {
5
+ // Convert SQL statement recursively
6
+ statement += convertChildren(children, param, parentIds, myBatisMapper);
7
+ }
8
+ // Check not converted Parameters
9
+ const regexList = ['\\#{\\S*}', '\\${\\S*}'];
10
+ for (let i = 0, regexString; regexString = regexList[i]; i++) {
11
+ var checkParam = statement.match(regexString);
12
+ if (checkParam != null && checkParam.length > 0) {
13
+ throw new Error("Parameter " + checkParam.join(",") + " is not converted.");
14
+ }
15
+ }
16
+ return statement;
17
+ };
18
+ const convertChildren = function (children, param, parentIds, myBatisMapper) {
19
+ param ?? (param = {});
20
+ if (!isDict(param)) {
21
+ throw new Error('Parameter argument should be Key-Value type or Null.');
22
+ }
23
+ if (children.type == 'text') {
24
+ // Convert Parameters
25
+ return convertParameters(children, param);
26
+ }
27
+ else if (children.type == 'tag') {
28
+ switch (children.name.toLowerCase()) {
29
+ case 'if':
30
+ return convertIf(children, param, parentIds, myBatisMapper);
31
+ case 'choose':
32
+ return convertChoose(children, param, parentIds, myBatisMapper);
33
+ case 'trim':
34
+ case 'where':
35
+ return convertTrimWhere(children, param, parentIds, myBatisMapper);
36
+ case 'set':
37
+ return convertSet(children, param, parentIds, myBatisMapper);
38
+ case 'foreach':
39
+ return convertForeach(children, param, parentIds, myBatisMapper);
40
+ case 'bind':
41
+ param = convertBind(children, param);
42
+ return '';
43
+ case 'include':
44
+ return convertInclude(children, param, parentIds, myBatisMapper);
45
+ default:
46
+ throw new Error('XML is not well-formed character or markup. Consider using CDATA section.');
47
+ }
48
+ }
49
+ else {
50
+ return '';
51
+ }
52
+ };
53
+ const convertParameters = function (children, param) {
54
+ let convertString = children.content;
55
+ try {
56
+ convertString = convertParametersInner('#', convertString, param);
57
+ convertString = convertParametersInner('$', convertString, param);
58
+ }
59
+ catch (err) {
60
+ throw new Error('Error occurred during convert parameters.');
61
+ }
62
+ try {
63
+ // convert CDATA string
64
+ convertString = convertString.replace(/(\&amp\;)/g, '&');
65
+ convertString = convertString.replace(/(\&lt\;)/g, '<');
66
+ convertString = convertString.replace(/(\&gt\;)/g, '>');
67
+ convertString = convertString.replace(/(\&quot\;)/g, '"');
68
+ }
69
+ catch (err) {
70
+ throw new Error('Error occurred during convert CDATA section.');
71
+ }
72
+ return convertString;
73
+ };
74
+ const isObject = function (variable) {
75
+ return typeof variable === 'object' && variable !== null;
76
+ };
77
+ const isArray = function (variable) {
78
+ return isObject(variable) && variable.hasOwnProperty('length');
79
+ };
80
+ const convertParametersInner = function (change, convertString, param) {
81
+ const stringReg = new RegExp('(\\' + change + '\\{[a-zA-Z0-9._\\$]+\\})', 'g');
82
+ let stringTarget = convertString.match(stringReg);
83
+ if (stringTarget != null && stringTarget.length > 0) {
84
+ const _stringTarget = uniqueArray(stringTarget);
85
+ let target;
86
+ for (let i = 0; i < _stringTarget.length; i++) {
87
+ target = _stringTarget[i];
88
+ const t = target.replace(change + '{', '').replace('}', '');
89
+ let tempParamKey = LGet(param, t);
90
+ if (tempParamKey !== undefined) {
91
+ const reg = new RegExp('\\' + change + '{' + t + '}', 'g');
92
+ if (tempParamKey === null) {
93
+ tempParamKey = 'NULL';
94
+ convertString = convertString.replace(reg, tempParamKey);
95
+ }
96
+ else {
97
+ if (change == '#') {
98
+ // processing JSON fields structures
99
+ if (isObject(tempParamKey) || isArray(tempParamKey)) {
100
+ tempParamKey = JSON.stringify(tempParamKey);
101
+ }
102
+ else {
103
+ tempParamKey = tempParamKey.toString().replace(/"/g, '\\\"');
104
+ tempParamKey = mysqlRealEscapeParam(tempParamKey);
105
+ }
106
+ tempParamKey = tempParamKey.replace(/'/g, "''");
107
+ const replaceWith = "'" + tempParamKey + "'";
108
+ convertString = convertString.replace(reg, () => replaceWith);
109
+ }
110
+ else if (change == '$') {
111
+ convertString = convertString.replace(reg, tempParamKey);
112
+ }
113
+ }
114
+ }
115
+ }
116
+ }
117
+ return convertString;
118
+ };
119
+ const convertIf = function (children, param, parentIds, myBatisMapper) {
120
+ let evalString = children.attrs['test'];
121
+ try {
122
+ // Create Evaluate string
123
+ evalString = replaceEvalString(evalString, param);
124
+ evalString = evalString.replace(/ and /gi, ' && ');
125
+ evalString = evalString.replace(/ or /gi, ' || ');
126
+ // replace == to === for strict evaluate
127
+ // TODO: fix != null & != ''
128
+ // evalString = evalString.replace(/==/g, '===');
129
+ // evalString = evalString.replace(/!=/g, '!==');
130
+ evalString = evalString.replace(/^'(.*?)'\.equalsIgnoreCase\( ([a-zA-Z]+\.[a-zA-Z]+) \)/i, `($2 && $2.toUpperCase() === '$1'.toUpperCase())`);
131
+ evalString = evalString.replace(/\('(.*?)'\.equalsIgnoreCase\( ([a-zA-Z]+\.[a-zA-Z]+) \)/i, `(($2 && $2.toUpperCase() === '$1'.toUpperCase())`);
132
+ }
133
+ catch (err) {
134
+ throw new Error('Error occurred during convert <if> element.');
135
+ }
136
+ // Execute Evaluate string
137
+ try {
138
+ if (eval(evalString)) {
139
+ let convertString = '';
140
+ for (let i = 0, nextChildren; nextChildren = children['children'][i]; i++) {
141
+ convertString += convertChildren(nextChildren, param, parentIds, myBatisMapper);
142
+ }
143
+ return convertString;
144
+ }
145
+ else {
146
+ return '';
147
+ }
148
+ }
149
+ catch (e) {
150
+ return '';
151
+ }
152
+ };
153
+ const convertForeach = function (children, param, parentIds, myBatisMapper) {
154
+ try {
155
+ const collection = eval('param.' + children.attrs['collection']);
156
+ const item = children.attrs['item'];
157
+ const open = (children.attrs['open'] == null) ? '' : children.attrs['open'];
158
+ const close = (children.attrs['close'] == null) ? '' : children.attrs['close'];
159
+ const separator = (children.attrs['separator'] == null) ? '' : children.attrs['separator'];
160
+ const foreachTexts = [];
161
+ let coll = null;
162
+ for (let j = 0; j < collection.length; j++) {
163
+ coll = collection[j];
164
+ const foreachParam = param;
165
+ foreachParam[item] = coll;
166
+ let foreachText = '';
167
+ for (let k = 0, nextChildren; nextChildren = children.children[k]; k++) {
168
+ let fText = convertChildren(nextChildren, foreachParam, parentIds, myBatisMapper);
169
+ fText = fText.replace(/^\s*$/g, '');
170
+ if (fText != null && fText.length > 0) {
171
+ foreachText += fText;
172
+ }
173
+ }
174
+ if (foreachText != null && foreachText.length > 0) {
175
+ foreachTexts.push(foreachText);
176
+ }
177
+ }
178
+ return (open + foreachTexts.join(separator) + close);
179
+ }
180
+ catch (err) {
181
+ throw new Error('Error occurred during convert <foreach> element.');
182
+ }
183
+ };
184
+ const convertChoose = function (children, param, parentIds, myBatisMapper) {
185
+ try {
186
+ for (let i = 0, whenChildren; whenChildren = children.children[i]; i++) {
187
+ if (whenChildren.type == 'tag' && whenChildren.name.toLowerCase() == 'when') {
188
+ let evalString = whenChildren.attrs.test;
189
+ // Create Evaluate string
190
+ evalString = replaceEvalString(evalString, param);
191
+ evalString = evalString.replace(/ and /gi, ' && ');
192
+ evalString = evalString.replace(/ or /gi, ' || ');
193
+ // Execute Evaluate string
194
+ try {
195
+ if (eval(evalString)) {
196
+ // If <when> condition is true, do it.
197
+ let convertString = '';
198
+ for (let k = 0, nextChildren; nextChildren = whenChildren.children[k]; k++) {
199
+ convertString += convertChildren(nextChildren, param, parentIds, myBatisMapper);
200
+ }
201
+ return convertString;
202
+ }
203
+ else {
204
+ continue;
205
+ }
206
+ }
207
+ catch (e) {
208
+ continue;
209
+ }
210
+ }
211
+ else if (whenChildren.type == 'tag' && whenChildren.name.toLowerCase() == 'otherwise') {
212
+ // If reached <otherwise> tag, do it.
213
+ let convertString = '';
214
+ for (let k = 0, nextChildren; nextChildren = whenChildren.children[k]; k++) {
215
+ convertString += convertChildren(nextChildren, param, parentIds, myBatisMapper);
216
+ }
217
+ return convertString;
218
+ }
219
+ }
220
+ // If there is no suitable when and otherwise, just return null.
221
+ return '';
222
+ }
223
+ catch (err) {
224
+ throw new Error('Error occurred during convert <choose> element.');
225
+ }
226
+ };
227
+ const convertTrimWhere = function (children, param, parentIds, myBatisMapper) {
228
+ let convertString = '';
229
+ let prefix;
230
+ let prefixOverrides;
231
+ let suffix;
232
+ let suffixOverrides;
233
+ let globalSet;
234
+ try {
235
+ switch (children.name.toLowerCase()) {
236
+ case 'trim':
237
+ prefix = children.attrs["prefix"];
238
+ prefixOverrides = children.attrs["prefixOverrides"];
239
+ suffix = children.attrs["suffix"];
240
+ suffixOverrides = children.attrs["suffixOverrides"];
241
+ globalSet = 'g';
242
+ break;
243
+ case 'where':
244
+ prefix = 'WHERE';
245
+ prefixOverrides = 'and|or';
246
+ globalSet = 'gi';
247
+ break;
248
+ default:
249
+ throw new Error('Error occurred during convert <trim/where> element.');
250
+ }
251
+ // Convert children first.
252
+ for (let j = 0, nextChildren; nextChildren = children.children[j]; j++) {
253
+ convertString += convertChildren(nextChildren, param, parentIds, myBatisMapper);
254
+ }
255
+ // Remove prefixOverrides
256
+ let trimRegex = new RegExp('(^)([\\s]*?)(' + prefixOverrides + ')', globalSet);
257
+ convertString = convertString.replace(trimRegex, '');
258
+ // Remove suffixOverrides
259
+ trimRegex = new RegExp('(' + suffixOverrides + ')([\\s]*?)($)', globalSet);
260
+ convertString = convertString.replace(trimRegex, '');
261
+ if (children.name.toLowerCase() != 'trim') {
262
+ trimRegex = new RegExp('(' + prefixOverrides + ')([\\s]*?)($)', globalSet);
263
+ convertString = convertString.replace(trimRegex, '');
264
+ }
265
+ // Add Prefix if String is not empty.
266
+ trimRegex = new RegExp('([a-zA-Z])', 'g');
267
+ const w = convertString.match(trimRegex);
268
+ if (w != null && w.length > 0) {
269
+ convertString = prefix + ' ' + convertString;
270
+ if (suffix) {
271
+ convertString = convertString + ' ' + suffix;
272
+ }
273
+ }
274
+ // Remove comma(,) before WHERE
275
+ if (children.name.toLowerCase() != 'where') {
276
+ const regex = new RegExp('(,)([\\s]*?)(where)', 'gi');
277
+ convertString = convertString.replace(regex, ' WHERE ');
278
+ }
279
+ return convertString;
280
+ }
281
+ catch (err) {
282
+ throw new Error('Error occurred during convert <' + children.name.toLowerCase() + '> element.');
283
+ }
284
+ };
285
+ const convertSet = function (children, param, parentIds, myBatisMapper) {
286
+ let convertString = '';
287
+ try {
288
+ // Convert children first.
289
+ for (let j = 0, nextChildren; nextChildren = children.children[j]; j++) {
290
+ convertString += convertChildren(nextChildren, param, parentIds, myBatisMapper);
291
+ }
292
+ // Remove comma repeated more than 2.
293
+ let regex = new RegExp('(,)(,|\\s){2,}', 'g');
294
+ convertString = convertString.replace(regex, ',\n');
295
+ // Remove first comma if exists.
296
+ regex = new RegExp('(^)([\\s]*?)(,)', 'g');
297
+ convertString = convertString.replace(regex, '');
298
+ // Remove last comma if exists.
299
+ regex = new RegExp('(,)([\\s]*?)($)', 'g');
300
+ convertString = convertString.replace(regex, '');
301
+ convertString = ' SET ' + convertString;
302
+ return convertString;
303
+ }
304
+ catch (err) {
305
+ throw new Error('Error occurred during convert <set> element.');
306
+ }
307
+ };
308
+ const convertBind = function (children, param) {
309
+ let evalString = children.attrs["value"];
310
+ // Create Evaluate string
311
+ evalString = replaceEvalString(evalString, param);
312
+ param[children.attrs["name"]] = eval(evalString);
313
+ return param;
314
+ };
315
+ const convertInclude = function (children, param, parentIds, myBatisMapper) {
316
+ try {
317
+ // Add Properties to param
318
+ for (let j = 0, nextChildren; nextChildren = children.children[j]; j++) {
319
+ if (nextChildren.type == 'tag' && nextChildren.name == 'property') {
320
+ param[nextChildren.attrs['name']] = nextChildren.attrs['value'];
321
+ }
322
+ }
323
+ }
324
+ catch (err) {
325
+ throw new Error('Error occurred during read <property> element in <include> element.');
326
+ }
327
+ try {
328
+ let refid = convertParametersInner('#', children.attrs['refid'], param);
329
+ refid = convertParametersInner('$', refid, param);
330
+ let mapper;
331
+ for (const psqlid of parentIds) {
332
+ mapper = myBatisMapper[`${psqlid}.${refid}`];
333
+ if (mapper) {
334
+ break;
335
+ }
336
+ }
337
+ let statement = '';
338
+ for (let i = 0, children; children = mapper[i]; i++) {
339
+ statement += convertChildren(children, param, parentIds, myBatisMapper);
340
+ }
341
+ return statement;
342
+ }
343
+ catch (err) {
344
+ throw new Error('Error occurred during convert refid attribute in <include> element.');
345
+ }
346
+ };
347
+ const isDict = function (v) {
348
+ return typeof v === 'object' && v !== null && !(v instanceof Array) && !(v instanceof Date);
349
+ };
350
+ const replaceEvalString = function (evalString, param) {
351
+ const keys = Object.keys(param);
352
+ for (let i = 0; i < keys.length; i++) {
353
+ let replacePrefix = '';
354
+ let replacePostfix = '';
355
+ let paramRegex;
356
+ if (isDict(param[keys[i]])) {
357
+ replacePrefix = ' param.';
358
+ replacePostfix = '';
359
+ paramRegex = new RegExp('(^|[^a-zA-Z0-9_])(' + keys[i] + '\\.)([a-zA-Z0-9_]+)', 'g');
360
+ }
361
+ else {
362
+ replacePrefix = ' param.';
363
+ replacePostfix = ' ';
364
+ paramRegex = new RegExp('(^|[^a-zA-Z0-9_])(' + keys[i] + ')($|[^a-zA-Z0-9_])', 'g');
365
+ }
366
+ evalString = evalString.replace(paramRegex, ('$1' + replacePrefix + '$2' + replacePostfix + '$3'));
367
+ }
368
+ return evalString;
369
+ };
370
+ const uniqueArray = function (a) {
371
+ const seen = {};
372
+ const out = [];
373
+ const len = a.length;
374
+ let j = 0;
375
+ for (let i = 0; i < len; i++) {
376
+ const item = a[i];
377
+ if (seen[item] !== 1) {
378
+ seen[item] = 1;
379
+ out[j++] = item;
380
+ }
381
+ }
382
+ return out;
383
+ };
384
+ const mysqlRealEscapeParam = function (param) {
385
+ if (typeof param != 'string')
386
+ return param;
387
+ return param.replace(/[\0\x08\x09\x1a\n\r''\\\%]/g, function (char) {
388
+ switch (char) {
389
+ case '\0':
390
+ return '\\0';
391
+ case '\x08':
392
+ return '\\b';
393
+ case '\x09':
394
+ return '\\t';
395
+ case '\x1a':
396
+ return '\\z';
397
+ case '\n':
398
+ return '\\n';
399
+ case '\r':
400
+ return '\\r';
401
+ case '\'':
402
+ case `'`:
403
+ case '\\':
404
+ case '%':
405
+ return '\\' + char;
406
+ default:
407
+ return char;
408
+ }
409
+ });
410
+ };