oak-db 2.2.6 → 2.2.8

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.
@@ -1,895 +1,895 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SqlTranslator = void 0;
4
- var tslib_1 = require("tslib");
5
- var assert_1 = tslib_1.__importDefault(require("assert"));
6
- var lodash_1 = require("lodash");
7
- var types_1 = require("oak-domain/lib/types");
8
- var relation_1 = require("oak-domain/lib/store/relation");
9
- ;
10
- ;
11
- var SqlTranslator = /** @class */ (function () {
12
- function SqlTranslator(schema) {
13
- this.schema = this.makeFullSchema(schema);
14
- }
15
- SqlTranslator.prototype.makeFullSchema = function (schema2) {
16
- var schema = (0, lodash_1.cloneDeep)(schema2);
17
- for (var entity in schema) {
18
- var _a = schema[entity], attributes = _a.attributes, indexes = _a.indexes;
19
- // 增加默认的属性
20
- (0, lodash_1.assign)(attributes, {
21
- id: {
22
- type: 'char',
23
- params: {
24
- length: 36,
25
- },
26
- },
27
- $$seq$$: {
28
- type: 'sequence',
29
- sequenceStart: 10000,
30
- },
31
- $$createAt$$: {
32
- type: 'datetime',
33
- notNull: true,
34
- },
35
- $$updateAt$$: {
36
- type: 'datetime',
37
- notNull: true,
38
- },
39
- $$deleteAt$$: {
40
- type: 'datetime',
41
- },
42
- $$triggerData$$: {
43
- type: 'object',
44
- },
45
- $$triggerTimestamp$$: {
46
- type: 'datetime',
47
- },
48
- });
49
- // 增加默认的索引
50
- var intrinsticIndexes = [
51
- {
52
- name: "".concat(entity, "_create_at_auto_create"),
53
- attributes: [{
54
- name: '$$createAt$$',
55
- }, {
56
- name: '$$deleteAt$$',
57
- }]
58
- }, {
59
- name: "".concat(entity, "_update_at_auto_create"),
60
- attributes: [{
61
- name: '$$updateAt$$',
62
- }, {
63
- name: '$$deleteAt$$',
64
- }],
65
- }, {
66
- name: "".concat(entity, "_trigger_ts_auto_create"),
67
- attributes: [{
68
- name: '$$triggerTimestamp$$',
69
- }, {
70
- name: '$$deleteAt$$',
71
- }],
72
- }
73
- ];
74
- var _loop_1 = function (attr) {
75
- if (attributes[attr].type === 'ref') {
76
- if (!(indexes === null || indexes === void 0 ? void 0 : indexes.find(function (ele) { return ele.attributes[0].name === attr; }))) {
77
- intrinsticIndexes.push({
78
- name: "".concat(entity, "_fk_").concat(attr, "_auto_create"),
79
- attributes: [{
80
- name: attr,
81
- }, {
82
- name: '$$deleteAt$$',
83
- }]
84
- });
85
- }
86
- }
87
- if (attr === 'entity' && attributes[attr].type === 'varchar') {
88
- var entityIdDef = attributes.entityId;
89
- if ((entityIdDef === null || entityIdDef === void 0 ? void 0 : entityIdDef.type) === 'varchar') {
90
- if (!(indexes === null || indexes === void 0 ? void 0 : indexes.find(function (ele) { var _a; return ele.attributes[0].name === 'entity' && ((_a = ele.attributes[1]) === null || _a === void 0 ? void 0 : _a.name) === 'entityId'; }))) {
91
- intrinsticIndexes.push({
92
- name: "".concat(entity, "_fk_entity_entityId_auto_create"),
93
- attributes: [{
94
- name: 'entity',
95
- }, {
96
- name: 'entityId',
97
- }, {
98
- name: '$$deleteAt$$',
99
- }]
100
- });
101
- }
102
- }
103
- }
104
- if (attr.endsWith('State') && attributes[attr].type === 'varchar') {
105
- if (!(indexes === null || indexes === void 0 ? void 0 : indexes.find(function (ele) { return ele.attributes[0].name === attr; }))) {
106
- intrinsticIndexes.push({
107
- name: "".concat(entity, "_").concat(attr, "_auto_create"),
108
- attributes: [{
109
- name: attr,
110
- }, {
111
- name: '$$deleteAt$$',
112
- }]
113
- });
114
- }
115
- }
116
- if (attr === 'expired' && attributes[attr].type === 'boolean') {
117
- var expiresAtDef = attributes.expiresAt;
118
- if ((expiresAtDef === null || expiresAtDef === void 0 ? void 0 : expiresAtDef.type) === 'datetime') {
119
- if (!(indexes === null || indexes === void 0 ? void 0 : indexes.find(function (ele) { var _a; return ele.attributes[0].name === 'expired' && ((_a = ele.attributes[1]) === null || _a === void 0 ? void 0 : _a.name) === 'expiresAt'; }))) {
120
- intrinsticIndexes.push({
121
- name: "".concat(entity, "_expires_expiredAt_auto_create"),
122
- attributes: [{
123
- name: 'expired',
124
- }, {
125
- name: 'expiresAt',
126
- }, {
127
- name: '$$deleteAt$$',
128
- }]
129
- });
130
- }
131
- }
132
- }
133
- };
134
- // 增加外键等相关属性上的索引
135
- for (var attr in attributes) {
136
- _loop_1(attr);
137
- }
138
- if (indexes) {
139
- indexes.push.apply(indexes, intrinsticIndexes);
140
- }
141
- else {
142
- (0, lodash_1.assign)(schema[entity], {
143
- indexes: intrinsticIndexes,
144
- });
145
- }
146
- }
147
- return schema;
148
- };
149
- SqlTranslator.prototype.getStorageName = function (entity) {
150
- var storageName = this.schema[entity].storageName;
151
- return (storageName || entity);
152
- };
153
- SqlTranslator.prototype.translateInsert = function (entity, data) {
154
- var _this = this;
155
- var schema = this.schema;
156
- var _a = schema[entity], attributes = _a.attributes, _b = _a.storageName, storageName = _b === void 0 ? entity : _b;
157
- var sql = "insert into `".concat(storageName, "`(");
158
- /**
159
- * 这里的attrs要用所有行的union集合
160
- */
161
- var dataFull = data.reduce(function (prev, cur) { return Object.assign({}, cur, prev); }, {});
162
- var attrs = Object.keys(dataFull).filter(function (ele) { return attributes.hasOwnProperty(ele); });
163
- attrs.forEach(function (attr, idx) {
164
- sql += " `".concat(attr, "`");
165
- if (idx < attrs.length - 1) {
166
- sql += ',';
167
- }
168
- });
169
- sql += ') values ';
170
- data.forEach(function (d, dataIndex) {
171
- sql += '(';
172
- attrs.forEach(function (attr, attrIdx) {
173
- var attrDef = attributes[attr];
174
- var dataType = attrDef.type;
175
- var value = _this.translateAttrValue(dataType, d[attr]);
176
- sql += value;
177
- if (attrIdx < attrs.length - 1) {
178
- sql += ',';
179
- }
180
- });
181
- if (dataIndex < data.length - 1) {
182
- sql += '),';
183
- }
184
- else {
185
- sql += ')';
186
- }
187
- });
188
- return sql;
189
- };
190
- /**
191
- * analyze the join relations in projection/query/sort
192
- * 所有的层次关系都当成left join处理,如果有内表为空的情况,请手动处理
193
- * {
194
- * b: {
195
- * name: {
196
- * $exists: false,
197
- * }
198
- * }
199
- * }
200
- * 这样的query会把内表为空的行也返回
201
- * @param param0
202
- */
203
- SqlTranslator.prototype.analyzeJoin = function (entity, _a, initialNumber) {
204
- var _this = this;
205
- var projection = _a.projection, filter = _a.filter, sorter = _a.sorter, aggregation = _a.aggregation;
206
- var schema = this.schema;
207
- var number = initialNumber || 1;
208
- var projectionRefAlias = {};
209
- var filterRefAlias = {};
210
- var extraWhere = '';
211
- var alias = "".concat(entity, "_").concat(number++);
212
- var from = " `".concat(this.getStorageName(entity), "` `").concat(alias, "` ");
213
- var aliasDict = {
214
- './': alias,
215
- };
216
- var analyzeFilterNode = function (_a) {
217
- var _b;
218
- var node = _a.node, path = _a.path, entityName = _a.entityName, alias = _a.alias;
219
- Object.keys(node).forEach(function (op) {
220
- var _a, _b;
221
- if (['$and', '$or'].includes(op)) {
222
- node[op].forEach(function (subNode) { return analyzeFilterNode({
223
- node: subNode,
224
- path: path,
225
- entityName: entityName,
226
- alias: alias,
227
- }); });
228
- }
229
- else if (['$not'].includes(op)) {
230
- analyzeFilterNode({
231
- node: node[op],
232
- path: path,
233
- entityName: entityName,
234
- alias: alias,
235
- });
236
- }
237
- else if (['$text'].includes(op)) {
238
- }
239
- else {
240
- var rel = (0, relation_1.judgeRelation)(_this.schema, entityName, op);
241
- if (typeof rel === 'string') {
242
- var alias2 = void 0;
243
- var pathAttr = "".concat(path).concat(op, "/");
244
- if (!aliasDict.hasOwnProperty(pathAttr)) {
245
- alias2 = "".concat(rel, "_").concat(number++);
246
- (0, lodash_1.assign)(aliasDict, (_a = {},
247
- _a[pathAttr] = alias2,
248
- _a));
249
- from += " left join `".concat(_this.getStorageName(rel), "` `").concat(alias2, "` on `").concat(alias, "`.`").concat(op, "Id` = `").concat(alias2, "`.`id`");
250
- }
251
- else {
252
- alias2 = aliasDict[pathAttr];
253
- }
254
- analyzeFilterNode({
255
- node: node[op],
256
- path: pathAttr,
257
- entityName: rel,
258
- alias: alias2,
259
- });
260
- }
261
- else if (rel === 2) {
262
- var alias2 = void 0;
263
- var pathAttr = "".concat(path).concat(op, "/");
264
- if (!aliasDict.hasOwnProperty(pathAttr)) {
265
- alias2 = "".concat(op, "_").concat(number++);
266
- (0, lodash_1.assign)(aliasDict, (_b = {},
267
- _b[pathAttr] = alias2,
268
- _b));
269
- from += " left join `".concat(_this.getStorageName(op), "` `").concat(alias2, "` on `").concat(alias, "`.`entityId` = `").concat(alias2, "`.`id` and `").concat(alias, "`.`entity` = '").concat(op, "'");
270
- }
271
- else {
272
- alias2 = aliasDict[pathAttr];
273
- }
274
- analyzeFilterNode({
275
- node: node[op],
276
- path: pathAttr,
277
- entityName: op,
278
- alias: alias2,
279
- });
280
- }
281
- else {
282
- // 不支持一对多
283
- (0, assert_1.default)(rel === 0 || rel === 1);
284
- }
285
- }
286
- });
287
- if (node['#id']) {
288
- (0, assert_1.default)(!filterRefAlias[node['#id']]);
289
- (0, lodash_1.assign)(filterRefAlias, (_b = {},
290
- _b[node['#id']] = [alias, entityName],
291
- _b));
292
- }
293
- };
294
- if (filter) {
295
- analyzeFilterNode({
296
- node: filter,
297
- path: './',
298
- entityName: entity,
299
- alias: alias,
300
- });
301
- }
302
- var analyzeSortNode = function (_a) {
303
- var _b, _c;
304
- var node = _a.node, path = _a.path, entityName = _a.entityName, alias = _a.alias;
305
- var attr = (0, lodash_1.keys)(node)[0];
306
- var rel = (0, relation_1.judgeRelation)(_this.schema, entityName, attr);
307
- if (typeof rel === 'string') {
308
- var pathAttr = "".concat(path).concat(attr, "/");
309
- var alias2 = void 0;
310
- if (!aliasDict.hasOwnProperty(pathAttr)) {
311
- alias2 = "".concat(rel, "_").concat(number++);
312
- (0, lodash_1.assign)(aliasDict, (_b = {},
313
- _b[pathAttr] = alias2,
314
- _b));
315
- from += " left join `".concat(_this.getStorageName(rel), "` `").concat(alias2, "` on `").concat(alias, "`.`").concat(attr, "Id` = `").concat(alias2, "`.`id`");
316
- }
317
- else {
318
- alias2 = aliasDict[pathAttr];
319
- }
320
- analyzeSortNode({
321
- node: node[attr],
322
- path: pathAttr,
323
- entityName: rel,
324
- alias: alias2,
325
- });
326
- }
327
- else if (rel === 2) {
328
- var pathAttr = "".concat(path).concat(attr, "/");
329
- var alias2 = void 0;
330
- if (!aliasDict.hasOwnProperty(pathAttr)) {
331
- alias2 = "".concat(attr, "_").concat(number++);
332
- (0, lodash_1.assign)(aliasDict, (_c = {},
333
- _c[pathAttr] = alias2,
334
- _c));
335
- from += " left join `".concat(_this.getStorageName(attr), "` `").concat(alias2, "` on `").concat(alias, "`.`entityId` = `").concat(alias2, "`.`id` and `").concat(alias, "`.`entity` = '").concat(attr, "'");
336
- }
337
- else {
338
- alias2 = aliasDict[pathAttr];
339
- }
340
- analyzeSortNode({
341
- node: node[attr],
342
- path: pathAttr,
343
- entityName: attr,
344
- alias: alias2,
345
- });
346
- }
347
- else {
348
- (0, assert_1.default)(rel === 0 || rel === 1);
349
- }
350
- };
351
- if (sorter) {
352
- sorter.forEach(function (sortNode) {
353
- analyzeSortNode({
354
- node: sortNode.$attr,
355
- path: './',
356
- entityName: entity,
357
- alias: alias,
358
- });
359
- });
360
- }
361
- var analyzeProjectionNode = function (_a) {
362
- var _b;
363
- var node = _a.node, path = _a.path, entityName = _a.entityName, alias = _a.alias;
364
- var attributes = schema[entityName].attributes;
365
- Object.keys(node).forEach(function (attr) {
366
- var _a, _b;
367
- var rel = (0, relation_1.judgeRelation)(_this.schema, entityName, attr);
368
- if (typeof rel === 'string') {
369
- var pathAttr = "".concat(path).concat(attr, "/");
370
- var alias2 = void 0;
371
- if (!aliasDict.hasOwnProperty(pathAttr)) {
372
- alias2 = "".concat(rel, "_").concat(number++);
373
- (0, lodash_1.assign)(aliasDict, (_a = {},
374
- _a[pathAttr] = alias2,
375
- _a));
376
- from += " left join `".concat(_this.getStorageName(rel), "` `").concat(alias2, "` on `").concat(alias, "`.`").concat(attr, "Id` = `").concat(alias2, "`.`id`");
377
- }
378
- else {
379
- alias2 = aliasDict[pathAttr];
380
- }
381
- analyzeProjectionNode({
382
- node: node[attr],
383
- path: pathAttr,
384
- entityName: rel,
385
- alias: alias2,
386
- });
387
- }
388
- else if (rel === 2) {
389
- var pathAttr = "".concat(path).concat(attr, "/");
390
- var alias2 = void 0;
391
- if (!aliasDict.hasOwnProperty(pathAttr)) {
392
- alias2 = "".concat(attr, "_").concat(number++);
393
- (0, lodash_1.assign)(aliasDict, (_b = {},
394
- _b[pathAttr] = alias2,
395
- _b));
396
- from += " left join `".concat(_this.getStorageName(attr), "` `").concat(alias2, "` on `").concat(alias, "`.`entityId` = `").concat(alias2, "`.`id` and `").concat(alias, "`.`entity` = '").concat(attr, "'");
397
- }
398
- else {
399
- alias2 = aliasDict[pathAttr];
400
- }
401
- analyzeProjectionNode({
402
- node: node[attr],
403
- path: pathAttr,
404
- entityName: attr,
405
- alias: alias2,
406
- });
407
- }
408
- });
409
- if (node['#id']) {
410
- (0, assert_1.default)(!projectionRefAlias[node['#id']], "projection\u4E0A\u6709\u91CD\u590D\u7684#id\u5B9A\u4E49\u300C".concat(node['#id'], "\u300D"));
411
- (0, lodash_1.assign)(projectionRefAlias, (_b = {},
412
- _b[node['#id']] = [alias, entityName],
413
- _b));
414
- }
415
- };
416
- if (projection) {
417
- analyzeProjectionNode({ node: projection, path: './', entityName: entity, alias: alias });
418
- }
419
- else if (aggregation) {
420
- for (var k in aggregation) {
421
- analyzeProjectionNode({
422
- node: aggregation[k],
423
- path: './',
424
- entityName: entity,
425
- alias: alias,
426
- });
427
- }
428
- }
429
- return {
430
- aliasDict: aliasDict,
431
- from: from,
432
- projectionRefAlias: projectionRefAlias,
433
- filterRefAlias: filterRefAlias,
434
- extraWhere: extraWhere,
435
- currentNumber: number,
436
- };
437
- };
438
- SqlTranslator.prototype.translateComparison = function (attr, value, type) {
439
- var SQL_OP = {
440
- $gt: '>',
441
- $lt: '<',
442
- $gte: '>=',
443
- $lte: '<=',
444
- $eq: '=',
445
- $ne: '<>',
446
- };
447
- if (Object.keys(SQL_OP).includes(attr)) {
448
- return " ".concat(SQL_OP[attr], " ").concat(this.translateAttrValue(type, value));
449
- }
450
- switch (attr) {
451
- case '$startsWith': {
452
- return " like '".concat(value, "%'");
453
- }
454
- case '$endsWith': {
455
- return " like '%".concat(value, "'");
456
- }
457
- case '$includes': {
458
- return " like '%".concat(value, "%'");
459
- }
460
- default: {
461
- throw new Error("unrecoganized comparison operator ".concat(attr));
462
- }
463
- }
464
- };
465
- SqlTranslator.prototype.translateElement = function (attr, value) {
466
- (0, assert_1.default)(attr === '$exists'); // only support one operator now
467
- if (value) {
468
- return ' is not null';
469
- }
470
- return ' is null';
471
- };
472
- SqlTranslator.prototype.translateEvaluation = function (attr, value, entity, alias, type, initialNumber, refAlias) {
473
- switch (attr) {
474
- case '$text': {
475
- // fulltext search
476
- return {
477
- stmt: this.translateFullTextSearch(value, entity, alias),
478
- currentNumber: initialNumber,
479
- };
480
- }
481
- case '$in':
482
- case '$nin': {
483
- var IN_OP = {
484
- $in: 'in',
485
- $nin: 'not in',
486
- };
487
- if (value instanceof Array) {
488
- var values = value.map(function (v) {
489
- if (['varchar', 'char', 'text', 'nvarchar', 'ref'].includes(type)) {
490
- return "'".concat(v, "'");
491
- }
492
- else {
493
- return "".concat(v);
494
- }
495
- });
496
- if (values.length > 0) {
497
- return {
498
- stmt: " ".concat(IN_OP[attr], "(").concat(values.join(','), ")"),
499
- currentNumber: initialNumber,
500
- };
501
- }
502
- else {
503
- if (attr === '$in') {
504
- return {
505
- stmt: ' in (null)',
506
- currentNumber: initialNumber,
507
- };
508
- }
509
- else {
510
- return {
511
- stmt: ' is not null',
512
- currentNumber: initialNumber,
513
- };
514
- }
515
- }
516
- }
517
- else {
518
- // sub query
519
- var _a = this.translateSelectInner(value.entity, value, initialNumber, refAlias, undefined), subQueryStmt = _a.stmt, currentNumber = _a.currentNumber;
520
- return {
521
- stmt: " ".concat(IN_OP[attr], "(").concat(subQueryStmt, ")"),
522
- currentNumber: currentNumber,
523
- };
524
- }
525
- }
526
- default: {
527
- (0, assert_1.default)('$between' === attr);
528
- var values = value.map(function (v) {
529
- if (['varchar', 'char', 'text', 'nvarchar', 'ref'].includes(type)) {
530
- return "'".concat(v, "'");
531
- }
532
- else {
533
- return "".concat(v);
534
- }
535
- });
536
- return {
537
- stmt: " between ".concat(values[0], " and ").concat(values[1]),
538
- currentNumber: initialNumber,
539
- };
540
- }
541
- }
542
- };
543
- SqlTranslator.prototype.translateFilter = function (entity, selection, aliasDict, filterRefAlias, initialNumber, extraWhere, option) {
544
- var _this = this;
545
- var schema = this.schema;
546
- var filter = selection.filter;
547
- var currentNumber = initialNumber;
548
- var translateInner = function (entity2, path, filter2, type) {
549
- var alias = aliasDict[path];
550
- var attributes = schema[entity2].attributes;
551
- var whereText = type ? '' : _this.getDefaultSelectFilter(alias, option);
552
- if (filter2) {
553
- var attrs = Object.keys(filter2).filter(function (ele) { return !ele.startsWith('#'); });
554
- attrs.forEach(function (attr) {
555
- if (whereText) {
556
- whereText += ' and ';
557
- }
558
- if (['$and', '$or', '$xor', '$not'].includes(attr)) {
559
- var result = '';
560
- whereText += '(';
561
- switch (attr) {
562
- case '$and':
563
- case '$or':
564
- case '$xor': {
565
- var logicQueries_1 = filter2[attr];
566
- logicQueries_1.forEach(function (logicQuery, index) {
567
- var sql = translateInner(entity2, path, logicQuery);
568
- if (sql) {
569
- whereText += " (".concat(sql, ")");
570
- if (index < logicQueries_1.length - 1) {
571
- whereText += " ".concat(attr.slice(1));
572
- }
573
- }
574
- });
575
- break;
576
- }
577
- default: {
578
- (0, assert_1.default)(attr === '$not');
579
- var logicQuery = filter2[attr];
580
- var sql = translateInner(entity2, path, logicQuery);
581
- if (sql) {
582
- whereText += " not (".concat(translateInner(entity2, path, logicQuery), ")");
583
- break;
584
- }
585
- }
586
- }
587
- whereText += ')';
588
- }
589
- else if (attr.toLowerCase().startsWith(types_1.EXPRESSION_PREFIX)) {
590
- // expression
591
- whereText += " (".concat(_this.translateExpression(entity2, alias, filter2[attr], filterRefAlias), ")");
592
- }
593
- else if (['$gt', '$gte', '$lt', '$lte', '$eq', '$ne', '$startsWith', '$endsWith', '$includes'].includes(attr)) {
594
- whereText += _this.translateComparison(attr, filter2[attr], type);
595
- }
596
- else if (['$exists'].includes(attr)) {
597
- whereText += _this.translateElement(attr, filter2[attr]);
598
- }
599
- else if (['$text', '$in', '$nin', '$between'].includes(attr)) {
600
- var _a = _this.translateEvaluation(attr, filter2[attr], entity2, alias, type, initialNumber, filterRefAlias), stmt = _a.stmt, cn2 = _a.currentNumber;
601
- whereText += stmt;
602
- currentNumber = cn2;
603
- }
604
- else {
605
- var rel = (0, relation_1.judgeRelation)(_this.schema, entity2, attr);
606
- if (rel === 2) {
607
- whereText += " (".concat(translateInner(attr, "".concat(path).concat(attr, "/"), filter2[attr]), ")");
608
- }
609
- else if (typeof rel === 'string') {
610
- whereText += " (".concat(translateInner(rel, "".concat(path).concat(attr, "/"), filter2[attr]), ")");
611
- }
612
- else {
613
- (0, assert_1.default)(attributes.hasOwnProperty(attr), "\u975E\u6CD5\u7684\u5C5E\u6027".concat(attr));
614
- var type2 = attributes[attr].type;
615
- // assert (type2 !== 'ref');
616
- if (typeof filter2[attr] === 'object' && Object.keys(filter2[attr])[0] && Object.keys(filter2[attr])[0].startsWith('$')) {
617
- whereText += " (`".concat(alias, "`.`").concat(attr, "` ").concat(translateInner(entity2, path, filter2[attr], type2), ")");
618
- }
619
- else {
620
- whereText += " (`".concat(alias, "`.`").concat(attr, "` = ").concat(_this.translateAttrValue(type2, filter2[attr]), ")");
621
- }
622
- }
623
- }
624
- });
625
- }
626
- if (!whereText) {
627
- whereText = 'true'; // 如果为空就赋一个永真条件,以便处理and
628
- }
629
- return whereText;
630
- };
631
- var where = translateInner(entity, './', filter);
632
- if (extraWhere && where) {
633
- return {
634
- stmt: "".concat(extraWhere, " and ").concat(where),
635
- currentNumber: currentNumber,
636
- };
637
- }
638
- return {
639
- stmt: extraWhere || where,
640
- currentNumber: currentNumber,
641
- };
642
- };
643
- SqlTranslator.prototype.translateSorter = function (entity, sorter, aliasDict) {
644
- var _this = this;
645
- var translateInner = function (entity2, sortAttr, path) {
646
- (0, assert_1.default)(Object.keys(sortAttr).length === 1);
647
- var attr = Object.keys(sortAttr)[0];
648
- var alias = aliasDict[path];
649
- if (attr.toLocaleLowerCase().startsWith(types_1.EXPRESSION_PREFIX)) {
650
- return _this.translateExpression(entity2, alias, sortAttr[attr], {});
651
- }
652
- else if (sortAttr[attr] === 1) {
653
- return "`".concat(alias, "`.`").concat(attr, "`");
654
- }
655
- else {
656
- var rel = (0, relation_1.judgeRelation)(_this.schema, entity2, attr);
657
- if (typeof rel === 'string') {
658
- return translateInner(rel, sortAttr[attr], "".concat(path).concat(attr, "/"));
659
- }
660
- else {
661
- (0, assert_1.default)(rel === 2);
662
- return translateInner(attr, sortAttr[attr], "".concat(path).concat(attr, "/"));
663
- }
664
- }
665
- };
666
- var sortText = '';
667
- sorter.forEach(function (sortNode, index) {
668
- var $attr = sortNode.$attr, $direction = sortNode.$direction;
669
- sortText += translateInner(entity, $attr, './');
670
- if ($direction) {
671
- sortText += " ".concat($direction);
672
- }
673
- if (index < sorter.length - 1) {
674
- sortText += ',';
675
- }
676
- });
677
- return sortText;
678
- };
679
- SqlTranslator.prototype.translateProjection = function (entity, projection, aliasDict, projectionRefAlias, commonPrefix, disableAs) {
680
- var _this = this;
681
- var schema = this.schema;
682
- var as = '';
683
- var translateInner = function (entity2, projection2, path) {
684
- var alias = aliasDict[path];
685
- var attributes = schema[entity2].attributes;
686
- var projText = '';
687
- var prefix = path.slice(2).replace(/\//g, '.');
688
- var attrs = Object.keys(projection2).filter(function (attr) {
689
- if (attr.toLowerCase().startsWith(types_1.EXPRESSION_PREFIX)) {
690
- return true;
691
- }
692
- var rel = (0, relation_1.judgeRelation)(_this.schema, entity2, attr);
693
- return [1, 2].includes(rel) || typeof rel === 'string';
694
- });
695
- attrs.forEach(function (attr, idx) {
696
- var prefix2 = commonPrefix ? "".concat(commonPrefix, ".").concat(prefix) : prefix;
697
- if (attr.toLowerCase().startsWith(types_1.EXPRESSION_PREFIX)) {
698
- var exprText = _this.translateExpression(entity2, alias, projection2[attr], projectionRefAlias);
699
- if (disableAs) {
700
- projText += " ".concat(exprText);
701
- }
702
- else {
703
- projText += " ".concat(exprText, " as `").concat(prefix2).concat(attr, "`");
704
- if (!as) {
705
- as = "`".concat(prefix2).concat(attr, "`");
706
- }
707
- else {
708
- as += ", `".concat(prefix2).concat(attr, "`");
709
- }
710
- }
711
- }
712
- else {
713
- var rel = (0, relation_1.judgeRelation)(_this.schema, entity2, attr);
714
- if (typeof rel === 'string') {
715
- projText += translateInner(rel, projection2[attr], "".concat(path).concat(attr, "/"));
716
- }
717
- else if (rel === 2) {
718
- projText += translateInner(attr, projection2[attr], "".concat(path).concat(attr, "/"));
719
- }
720
- else if (rel === 1) {
721
- var type = attributes[attr].type;
722
- if (projection2[attr] === 1) {
723
- if (disableAs) {
724
- projText += " ".concat(_this.translateAttrProjection(type, alias, attr));
725
- }
726
- else {
727
- projText += " ".concat(_this.translateAttrProjection(type, alias, attr), " as `").concat(prefix2).concat(attr, "`");
728
- if (!as) {
729
- as = "`".concat(prefix2).concat(attr, "`");
730
- }
731
- else {
732
- as += ", `".concat(prefix2).concat(attr, "`");
733
- }
734
- }
735
- }
736
- else {
737
- (0, assert_1.default)(typeof projection2 === 'string');
738
- if (disableAs) {
739
- projText += " ".concat(_this.translateAttrProjection(type, alias, attr));
740
- }
741
- else {
742
- projText += " ".concat(_this.translateAttrProjection(type, alias, attr), " as `").concat(prefix2).concat(projection2[attr], "`");
743
- if (!as) {
744
- as = "`".concat(prefix2).concat(projection2[attr], "`");
745
- }
746
- else {
747
- as += "`".concat(prefix2).concat(projection2[attr], "`");
748
- }
749
- }
750
- }
751
- }
752
- }
753
- if (idx < attrs.length - 1) {
754
- projText += ',';
755
- }
756
- });
757
- return projText;
758
- };
759
- return {
760
- projText: translateInner(entity, projection, './'),
761
- as: as,
762
- };
763
- };
764
- SqlTranslator.prototype.translateSelectInner = function (entity, selection, initialNumber, refAlias, option) {
765
- var data = selection.data, filter = selection.filter, sorter = selection.sorter, indexFrom = selection.indexFrom, count = selection.count;
766
- var _a = this.analyzeJoin(entity, {
767
- projection: data,
768
- filter: filter,
769
- sorter: sorter,
770
- }, initialNumber), fromText = _a.from, aliasDict = _a.aliasDict, projectionRefAlias = _a.projectionRefAlias, extraWhere = _a.extraWhere, filterRefAlias = _a.filterRefAlias, currentNumber = _a.currentNumber;
771
- (0, assert_1.default)((0, lodash_1.intersection)((0, lodash_1.keys)(refAlias), (0, lodash_1.keys)(filterRefAlias)).length === 0, 'filter中的#node结点定义有重复');
772
- (0, lodash_1.assign)(refAlias, filterRefAlias);
773
- var projText = this.translateProjection(entity, data, aliasDict, projectionRefAlias).projText;
774
- var _b = this.translateFilter(entity, selection, aliasDict, refAlias, currentNumber, extraWhere, option), filterText = _b.stmt, currentNumber2 = _b.currentNumber;
775
- var sorterText = sorter && this.translateSorter(entity, sorter, aliasDict);
776
- return {
777
- stmt: this.populateSelectStmt(projText, fromText, aliasDict, filterText, sorterText, undefined, indexFrom, count, option, selection),
778
- currentNumber: currentNumber2,
779
- };
780
- };
781
- SqlTranslator.prototype.translateSelect = function (entity, selection, option) {
782
- var stmt = this.translateSelectInner(entity, selection, 1, {}, option).stmt;
783
- return stmt;
784
- };
785
- SqlTranslator.prototype.translateAggregate = function (entity, aggregation, option) {
786
- var data = aggregation.data, filter = aggregation.filter, sorter = aggregation.sorter, indexFrom = aggregation.indexFrom, count = aggregation.count;
787
- var _a = this.analyzeJoin(entity, {
788
- aggregation: data,
789
- filter: filter,
790
- sorter: sorter,
791
- }, 1), fromText = _a.from, aliasDict = _a.aliasDict, projectionRefAlias = _a.projectionRefAlias, extraWhere = _a.extraWhere, filterRefAlias = _a.filterRefAlias, currentNumber = _a.currentNumber;
792
- var projText = '';
793
- var groupByText = '';
794
- for (var k in data) {
795
- if (k === '#aggr') {
796
- var _b = this.translateProjection(entity, data[k], aliasDict, projectionRefAlias, '#data'), projSubText = _b.projText, as = _b.as;
797
- if (!projText) {
798
- projText = projSubText;
799
- }
800
- else {
801
- projText += ", ".concat(projSubText);
802
- }
803
- groupByText = as;
804
- }
805
- else {
806
- var projSubText = this.translateProjection(entity, data[k], aliasDict, projectionRefAlias, undefined, true).projText;
807
- var projSubText2 = '';
808
- if (k.startsWith('#max')) {
809
- projSubText2 = "max(".concat(projSubText, ") as `").concat(k, "`");
810
- }
811
- else if (k.startsWith('#min')) {
812
- projSubText2 = "min(".concat(projSubText, ") as `").concat(k, "`");
813
- }
814
- else if (k.startsWith('#count')) {
815
- projSubText2 = "count(".concat(projSubText, ") as `").concat(k, "`");
816
- }
817
- else if (k.startsWith('#sum')) {
818
- projSubText2 = "sum(".concat(projSubText, ") as `").concat(k, "`");
819
- }
820
- else {
821
- (0, assert_1.default)(k.startsWith('#avg'));
822
- projSubText2 = "avg(".concat(projSubText, ") as `").concat(k, "`");
823
- }
824
- if (!projText) {
825
- projText = projSubText2;
826
- }
827
- else {
828
- projText += ", ".concat(projSubText2);
829
- }
830
- }
831
- }
832
- var filterText = this.translateFilter(entity, aggregation, aliasDict, {}, currentNumber, extraWhere, option).stmt;
833
- var sorterText = sorter && this.translateSorter(entity, sorter, aliasDict);
834
- return this.populateSelectStmt(projText, fromText, aliasDict, filterText, sorterText, groupByText, indexFrom, count, option, undefined, aggregation);
835
- };
836
- SqlTranslator.prototype.translateCount = function (entity, selection, option) {
837
- var filter = selection.filter, count = selection.count;
838
- var _a = this.analyzeJoin(entity, {
839
- filter: filter,
840
- }), fromText = _a.from, aliasDict = _a.aliasDict, extraWhere = _a.extraWhere, filterRefAlias = _a.filterRefAlias, currentNumber = _a.currentNumber;
841
- var projText = 'count(1) cnt';
842
- var filterText = this.translateFilter(entity, selection, aliasDict, filterRefAlias, currentNumber, extraWhere, option).stmt;
843
- if (count) {
844
- var subQuerySql = this.populateSelectStmt('1', fromText, aliasDict, filterText, undefined, undefined, undefined, undefined, option, Object.assign({}, selection, { indexFrom: 0, count: count }));
845
- return "select count(1) cnt from (".concat(subQuerySql, ") __tmp");
846
- }
847
- return this.populateSelectStmt(projText, fromText, aliasDict, filterText, undefined, undefined, undefined, undefined, option, selection);
848
- };
849
- SqlTranslator.prototype.translateRemove = function (entity, operation, option) {
850
- var filter = operation.filter, sorter = operation.sorter, indexFrom = operation.indexFrom, count = operation.count;
851
- (0, assert_1.default)(!sorter, '当前remove不支持sorter行为');
852
- var _a = this.analyzeJoin(entity, { filter: filter, sorter: sorter }), aliasDict = _a.aliasDict, filterRefAlias = _a.filterRefAlias, extraWhere = _a.extraWhere, fromText = _a.from, currentNumber = _a.currentNumber;
853
- var alias = aliasDict['./'];
854
- var filterText = this.translateFilter(entity, operation, aliasDict, filterRefAlias, currentNumber, extraWhere, { includedDeleted: true }).stmt;
855
- // const sorterText = sorter && sorter.length > 0 ? this.translateSorter(entity, sorter, aliasDict) : undefined;
856
- return this.populateRemoveStmt(alias, fromText, aliasDict, filterText, /* sorterText */ undefined, indexFrom, count, option);
857
- };
858
- SqlTranslator.prototype.translateUpdate = function (entity, operation, option) {
859
- var attributes = this.schema[entity].attributes;
860
- var filter = operation.filter, sorter = operation.sorter, indexFrom = operation.indexFrom, count = operation.count, data = operation.data;
861
- (0, assert_1.default)(!sorter, '当前update不支持sorter行为');
862
- var _a = this.analyzeJoin(entity, { filter: filter, sorter: sorter }), aliasDict = _a.aliasDict, filterRefAlias = _a.filterRefAlias, extraWhere = _a.extraWhere, fromText = _a.from, currentNumber = _a.currentNumber;
863
- var alias = aliasDict['./'];
864
- var updateText = '';
865
- for (var attr in data) {
866
- if (updateText) {
867
- updateText += ',';
868
- }
869
- (0, assert_1.default)(attributes.hasOwnProperty(attr));
870
- var value = this.translateAttrValue(attributes[attr].type, data[attr]);
871
- updateText += "`".concat(alias, "`.`").concat(attr, "` = ").concat(value);
872
- }
873
- var filterText = this.translateFilter(entity, operation, aliasDict, filterRefAlias, currentNumber, extraWhere).stmt;
874
- // const sorterText = sorter && this.translateSorter(entity, sorter, aliasDict);
875
- return this.populateUpdateStmt(updateText, fromText, aliasDict, filterText, /* sorterText */ undefined, indexFrom, count, option);
876
- };
877
- SqlTranslator.prototype.translateDestroyEntity = function (entity, truncate) {
878
- var schema = this.schema;
879
- var _a = schema[entity], _b = _a.storageName, storageName = _b === void 0 ? entity : _b, view = _a.view;
880
- var sql;
881
- if (view) {
882
- sql = "drop view if exists `".concat(storageName, "`");
883
- }
884
- else {
885
- sql = truncate ? "truncate table `".concat(storageName, "`") : "drop table if exists `".concat(storageName, "`");
886
- }
887
- return sql;
888
- };
889
- SqlTranslator.prototype.escapeStringValue = function (value) {
890
- var result = "'".concat(value.replace(/'/g, '\\\''), "'");
891
- return result;
892
- };
893
- return SqlTranslator;
894
- }());
895
- exports.SqlTranslator = SqlTranslator;
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SqlTranslator = void 0;
4
+ var tslib_1 = require("tslib");
5
+ var assert_1 = tslib_1.__importDefault(require("assert"));
6
+ var lodash_1 = require("lodash");
7
+ var types_1 = require("oak-domain/lib/types");
8
+ var relation_1 = require("oak-domain/lib/store/relation");
9
+ ;
10
+ ;
11
+ var SqlTranslator = /** @class */ (function () {
12
+ function SqlTranslator(schema) {
13
+ this.schema = this.makeFullSchema(schema);
14
+ }
15
+ SqlTranslator.prototype.makeFullSchema = function (schema2) {
16
+ var schema = (0, lodash_1.cloneDeep)(schema2);
17
+ for (var entity in schema) {
18
+ var _a = schema[entity], attributes = _a.attributes, indexes = _a.indexes;
19
+ // 增加默认的属性
20
+ (0, lodash_1.assign)(attributes, {
21
+ id: {
22
+ type: 'char',
23
+ params: {
24
+ length: 36,
25
+ },
26
+ },
27
+ $$seq$$: {
28
+ type: 'sequence',
29
+ sequenceStart: 10000,
30
+ },
31
+ $$createAt$$: {
32
+ type: 'datetime',
33
+ notNull: true,
34
+ },
35
+ $$updateAt$$: {
36
+ type: 'datetime',
37
+ notNull: true,
38
+ },
39
+ $$deleteAt$$: {
40
+ type: 'datetime',
41
+ },
42
+ $$triggerData$$: {
43
+ type: 'object',
44
+ },
45
+ $$triggerTimestamp$$: {
46
+ type: 'datetime',
47
+ },
48
+ });
49
+ // 增加默认的索引
50
+ var intrinsticIndexes = [
51
+ {
52
+ name: "".concat(entity, "_create_at_auto_create"),
53
+ attributes: [{
54
+ name: '$$createAt$$',
55
+ }, {
56
+ name: '$$deleteAt$$',
57
+ }]
58
+ }, {
59
+ name: "".concat(entity, "_update_at_auto_create"),
60
+ attributes: [{
61
+ name: '$$updateAt$$',
62
+ }, {
63
+ name: '$$deleteAt$$',
64
+ }],
65
+ }, {
66
+ name: "".concat(entity, "_trigger_ts_auto_create"),
67
+ attributes: [{
68
+ name: '$$triggerTimestamp$$',
69
+ }, {
70
+ name: '$$deleteAt$$',
71
+ }],
72
+ }
73
+ ];
74
+ var _loop_1 = function (attr) {
75
+ if (attributes[attr].type === 'ref') {
76
+ if (!(indexes === null || indexes === void 0 ? void 0 : indexes.find(function (ele) { return ele.attributes[0].name === attr; }))) {
77
+ intrinsticIndexes.push({
78
+ name: "".concat(entity, "_fk_").concat(attr, "_auto_create"),
79
+ attributes: [{
80
+ name: attr,
81
+ }, {
82
+ name: '$$deleteAt$$',
83
+ }]
84
+ });
85
+ }
86
+ }
87
+ if (attr === 'entity' && attributes[attr].type === 'varchar') {
88
+ var entityIdDef = attributes.entityId;
89
+ if ((entityIdDef === null || entityIdDef === void 0 ? void 0 : entityIdDef.type) === 'varchar') {
90
+ if (!(indexes === null || indexes === void 0 ? void 0 : indexes.find(function (ele) { var _a; return ele.attributes[0].name === 'entity' && ((_a = ele.attributes[1]) === null || _a === void 0 ? void 0 : _a.name) === 'entityId'; }))) {
91
+ intrinsticIndexes.push({
92
+ name: "".concat(entity, "_fk_entity_entityId_auto_create"),
93
+ attributes: [{
94
+ name: 'entity',
95
+ }, {
96
+ name: 'entityId',
97
+ }, {
98
+ name: '$$deleteAt$$',
99
+ }]
100
+ });
101
+ }
102
+ }
103
+ }
104
+ if (attr.endsWith('State') && attributes[attr].type === 'varchar') {
105
+ if (!(indexes === null || indexes === void 0 ? void 0 : indexes.find(function (ele) { return ele.attributes[0].name === attr; }))) {
106
+ intrinsticIndexes.push({
107
+ name: "".concat(entity, "_").concat(attr, "_auto_create"),
108
+ attributes: [{
109
+ name: attr,
110
+ }, {
111
+ name: '$$deleteAt$$',
112
+ }]
113
+ });
114
+ }
115
+ }
116
+ if (attr === 'expired' && attributes[attr].type === 'boolean') {
117
+ var expiresAtDef = attributes.expiresAt;
118
+ if ((expiresAtDef === null || expiresAtDef === void 0 ? void 0 : expiresAtDef.type) === 'datetime') {
119
+ if (!(indexes === null || indexes === void 0 ? void 0 : indexes.find(function (ele) { var _a; return ele.attributes[0].name === 'expired' && ((_a = ele.attributes[1]) === null || _a === void 0 ? void 0 : _a.name) === 'expiresAt'; }))) {
120
+ intrinsticIndexes.push({
121
+ name: "".concat(entity, "_expires_expiredAt_auto_create"),
122
+ attributes: [{
123
+ name: 'expired',
124
+ }, {
125
+ name: 'expiresAt',
126
+ }, {
127
+ name: '$$deleteAt$$',
128
+ }]
129
+ });
130
+ }
131
+ }
132
+ }
133
+ };
134
+ // 增加外键等相关属性上的索引
135
+ for (var attr in attributes) {
136
+ _loop_1(attr);
137
+ }
138
+ if (indexes) {
139
+ indexes.push.apply(indexes, intrinsticIndexes);
140
+ }
141
+ else {
142
+ (0, lodash_1.assign)(schema[entity], {
143
+ indexes: intrinsticIndexes,
144
+ });
145
+ }
146
+ }
147
+ return schema;
148
+ };
149
+ SqlTranslator.prototype.getStorageName = function (entity) {
150
+ var storageName = this.schema[entity].storageName;
151
+ return (storageName || entity);
152
+ };
153
+ SqlTranslator.prototype.translateInsert = function (entity, data) {
154
+ var _this = this;
155
+ var schema = this.schema;
156
+ var _a = schema[entity], attributes = _a.attributes, _b = _a.storageName, storageName = _b === void 0 ? entity : _b;
157
+ var sql = "insert into `".concat(storageName, "`(");
158
+ /**
159
+ * 这里的attrs要用所有行的union集合
160
+ */
161
+ var dataFull = data.reduce(function (prev, cur) { return Object.assign({}, cur, prev); }, {});
162
+ var attrs = Object.keys(dataFull).filter(function (ele) { return attributes.hasOwnProperty(ele); });
163
+ attrs.forEach(function (attr, idx) {
164
+ sql += " `".concat(attr, "`");
165
+ if (idx < attrs.length - 1) {
166
+ sql += ',';
167
+ }
168
+ });
169
+ sql += ') values ';
170
+ data.forEach(function (d, dataIndex) {
171
+ sql += '(';
172
+ attrs.forEach(function (attr, attrIdx) {
173
+ var attrDef = attributes[attr];
174
+ var dataType = attrDef.type;
175
+ var value = _this.translateAttrValue(dataType, d[attr]);
176
+ sql += value;
177
+ if (attrIdx < attrs.length - 1) {
178
+ sql += ',';
179
+ }
180
+ });
181
+ if (dataIndex < data.length - 1) {
182
+ sql += '),';
183
+ }
184
+ else {
185
+ sql += ')';
186
+ }
187
+ });
188
+ return sql;
189
+ };
190
+ /**
191
+ * analyze the join relations in projection/query/sort
192
+ * 所有的层次关系都当成left join处理,如果有内表为空的情况,请手动处理
193
+ * {
194
+ * b: {
195
+ * name: {
196
+ * $exists: false,
197
+ * }
198
+ * }
199
+ * }
200
+ * 这样的query会把内表为空的行也返回
201
+ * @param param0
202
+ */
203
+ SqlTranslator.prototype.analyzeJoin = function (entity, _a, initialNumber) {
204
+ var _this = this;
205
+ var projection = _a.projection, filter = _a.filter, sorter = _a.sorter, aggregation = _a.aggregation;
206
+ var schema = this.schema;
207
+ var number = initialNumber || 1;
208
+ var projectionRefAlias = {};
209
+ var filterRefAlias = {};
210
+ var extraWhere = '';
211
+ var alias = "".concat(entity, "_").concat(number++);
212
+ var from = " `".concat(this.getStorageName(entity), "` `").concat(alias, "` ");
213
+ var aliasDict = {
214
+ './': alias,
215
+ };
216
+ var analyzeFilterNode = function (_a) {
217
+ var _b;
218
+ var node = _a.node, path = _a.path, entityName = _a.entityName, alias = _a.alias;
219
+ Object.keys(node).forEach(function (op) {
220
+ var _a, _b;
221
+ if (['$and', '$or'].includes(op)) {
222
+ node[op].forEach(function (subNode) { return analyzeFilterNode({
223
+ node: subNode,
224
+ path: path,
225
+ entityName: entityName,
226
+ alias: alias,
227
+ }); });
228
+ }
229
+ else if (['$not'].includes(op)) {
230
+ analyzeFilterNode({
231
+ node: node[op],
232
+ path: path,
233
+ entityName: entityName,
234
+ alias: alias,
235
+ });
236
+ }
237
+ else if (['$text'].includes(op)) {
238
+ }
239
+ else {
240
+ var rel = (0, relation_1.judgeRelation)(_this.schema, entityName, op);
241
+ if (typeof rel === 'string') {
242
+ var alias2 = void 0;
243
+ var pathAttr = "".concat(path).concat(op, "/");
244
+ if (!aliasDict.hasOwnProperty(pathAttr)) {
245
+ alias2 = "".concat(rel, "_").concat(number++);
246
+ (0, lodash_1.assign)(aliasDict, (_a = {},
247
+ _a[pathAttr] = alias2,
248
+ _a));
249
+ from += " left join `".concat(_this.getStorageName(rel), "` `").concat(alias2, "` on `").concat(alias, "`.`").concat(op, "Id` = `").concat(alias2, "`.`id`");
250
+ }
251
+ else {
252
+ alias2 = aliasDict[pathAttr];
253
+ }
254
+ analyzeFilterNode({
255
+ node: node[op],
256
+ path: pathAttr,
257
+ entityName: rel,
258
+ alias: alias2,
259
+ });
260
+ }
261
+ else if (rel === 2) {
262
+ var alias2 = void 0;
263
+ var pathAttr = "".concat(path).concat(op, "/");
264
+ if (!aliasDict.hasOwnProperty(pathAttr)) {
265
+ alias2 = "".concat(op, "_").concat(number++);
266
+ (0, lodash_1.assign)(aliasDict, (_b = {},
267
+ _b[pathAttr] = alias2,
268
+ _b));
269
+ from += " left join `".concat(_this.getStorageName(op), "` `").concat(alias2, "` on `").concat(alias, "`.`entityId` = `").concat(alias2, "`.`id` and `").concat(alias, "`.`entity` = '").concat(op, "'");
270
+ }
271
+ else {
272
+ alias2 = aliasDict[pathAttr];
273
+ }
274
+ analyzeFilterNode({
275
+ node: node[op],
276
+ path: pathAttr,
277
+ entityName: op,
278
+ alias: alias2,
279
+ });
280
+ }
281
+ else {
282
+ // 不支持一对多
283
+ (0, assert_1.default)(rel === 0 || rel === 1);
284
+ }
285
+ }
286
+ });
287
+ if (node['#id']) {
288
+ (0, assert_1.default)(!filterRefAlias[node['#id']]);
289
+ (0, lodash_1.assign)(filterRefAlias, (_b = {},
290
+ _b[node['#id']] = [alias, entityName],
291
+ _b));
292
+ }
293
+ };
294
+ if (filter) {
295
+ analyzeFilterNode({
296
+ node: filter,
297
+ path: './',
298
+ entityName: entity,
299
+ alias: alias,
300
+ });
301
+ }
302
+ var analyzeSortNode = function (_a) {
303
+ var _b, _c;
304
+ var node = _a.node, path = _a.path, entityName = _a.entityName, alias = _a.alias;
305
+ var attr = (0, lodash_1.keys)(node)[0];
306
+ var rel = (0, relation_1.judgeRelation)(_this.schema, entityName, attr);
307
+ if (typeof rel === 'string') {
308
+ var pathAttr = "".concat(path).concat(attr, "/");
309
+ var alias2 = void 0;
310
+ if (!aliasDict.hasOwnProperty(pathAttr)) {
311
+ alias2 = "".concat(rel, "_").concat(number++);
312
+ (0, lodash_1.assign)(aliasDict, (_b = {},
313
+ _b[pathAttr] = alias2,
314
+ _b));
315
+ from += " left join `".concat(_this.getStorageName(rel), "` `").concat(alias2, "` on `").concat(alias, "`.`").concat(attr, "Id` = `").concat(alias2, "`.`id`");
316
+ }
317
+ else {
318
+ alias2 = aliasDict[pathAttr];
319
+ }
320
+ analyzeSortNode({
321
+ node: node[attr],
322
+ path: pathAttr,
323
+ entityName: rel,
324
+ alias: alias2,
325
+ });
326
+ }
327
+ else if (rel === 2) {
328
+ var pathAttr = "".concat(path).concat(attr, "/");
329
+ var alias2 = void 0;
330
+ if (!aliasDict.hasOwnProperty(pathAttr)) {
331
+ alias2 = "".concat(attr, "_").concat(number++);
332
+ (0, lodash_1.assign)(aliasDict, (_c = {},
333
+ _c[pathAttr] = alias2,
334
+ _c));
335
+ from += " left join `".concat(_this.getStorageName(attr), "` `").concat(alias2, "` on `").concat(alias, "`.`entityId` = `").concat(alias2, "`.`id` and `").concat(alias, "`.`entity` = '").concat(attr, "'");
336
+ }
337
+ else {
338
+ alias2 = aliasDict[pathAttr];
339
+ }
340
+ analyzeSortNode({
341
+ node: node[attr],
342
+ path: pathAttr,
343
+ entityName: attr,
344
+ alias: alias2,
345
+ });
346
+ }
347
+ else {
348
+ (0, assert_1.default)(rel === 0 || rel === 1);
349
+ }
350
+ };
351
+ if (sorter) {
352
+ sorter.forEach(function (sortNode) {
353
+ analyzeSortNode({
354
+ node: sortNode.$attr,
355
+ path: './',
356
+ entityName: entity,
357
+ alias: alias,
358
+ });
359
+ });
360
+ }
361
+ var analyzeProjectionNode = function (_a) {
362
+ var _b;
363
+ var node = _a.node, path = _a.path, entityName = _a.entityName, alias = _a.alias;
364
+ var attributes = schema[entityName].attributes;
365
+ Object.keys(node).forEach(function (attr) {
366
+ var _a, _b;
367
+ var rel = (0, relation_1.judgeRelation)(_this.schema, entityName, attr);
368
+ if (typeof rel === 'string') {
369
+ var pathAttr = "".concat(path).concat(attr, "/");
370
+ var alias2 = void 0;
371
+ if (!aliasDict.hasOwnProperty(pathAttr)) {
372
+ alias2 = "".concat(rel, "_").concat(number++);
373
+ (0, lodash_1.assign)(aliasDict, (_a = {},
374
+ _a[pathAttr] = alias2,
375
+ _a));
376
+ from += " left join `".concat(_this.getStorageName(rel), "` `").concat(alias2, "` on `").concat(alias, "`.`").concat(attr, "Id` = `").concat(alias2, "`.`id`");
377
+ }
378
+ else {
379
+ alias2 = aliasDict[pathAttr];
380
+ }
381
+ analyzeProjectionNode({
382
+ node: node[attr],
383
+ path: pathAttr,
384
+ entityName: rel,
385
+ alias: alias2,
386
+ });
387
+ }
388
+ else if (rel === 2) {
389
+ var pathAttr = "".concat(path).concat(attr, "/");
390
+ var alias2 = void 0;
391
+ if (!aliasDict.hasOwnProperty(pathAttr)) {
392
+ alias2 = "".concat(attr, "_").concat(number++);
393
+ (0, lodash_1.assign)(aliasDict, (_b = {},
394
+ _b[pathAttr] = alias2,
395
+ _b));
396
+ from += " left join `".concat(_this.getStorageName(attr), "` `").concat(alias2, "` on `").concat(alias, "`.`entityId` = `").concat(alias2, "`.`id` and `").concat(alias, "`.`entity` = '").concat(attr, "'");
397
+ }
398
+ else {
399
+ alias2 = aliasDict[pathAttr];
400
+ }
401
+ analyzeProjectionNode({
402
+ node: node[attr],
403
+ path: pathAttr,
404
+ entityName: attr,
405
+ alias: alias2,
406
+ });
407
+ }
408
+ });
409
+ if (node['#id']) {
410
+ (0, assert_1.default)(!projectionRefAlias[node['#id']], "projection\u4E0A\u6709\u91CD\u590D\u7684#id\u5B9A\u4E49\u300C".concat(node['#id'], "\u300D"));
411
+ (0, lodash_1.assign)(projectionRefAlias, (_b = {},
412
+ _b[node['#id']] = [alias, entityName],
413
+ _b));
414
+ }
415
+ };
416
+ if (projection) {
417
+ analyzeProjectionNode({ node: projection, path: './', entityName: entity, alias: alias });
418
+ }
419
+ else if (aggregation) {
420
+ for (var k in aggregation) {
421
+ analyzeProjectionNode({
422
+ node: aggregation[k],
423
+ path: './',
424
+ entityName: entity,
425
+ alias: alias,
426
+ });
427
+ }
428
+ }
429
+ return {
430
+ aliasDict: aliasDict,
431
+ from: from,
432
+ projectionRefAlias: projectionRefAlias,
433
+ filterRefAlias: filterRefAlias,
434
+ extraWhere: extraWhere,
435
+ currentNumber: number,
436
+ };
437
+ };
438
+ SqlTranslator.prototype.translateComparison = function (attr, value, type) {
439
+ var SQL_OP = {
440
+ $gt: '>',
441
+ $lt: '<',
442
+ $gte: '>=',
443
+ $lte: '<=',
444
+ $eq: '=',
445
+ $ne: '<>',
446
+ };
447
+ if (Object.keys(SQL_OP).includes(attr)) {
448
+ return " ".concat(SQL_OP[attr], " ").concat(this.translateAttrValue(type, value));
449
+ }
450
+ switch (attr) {
451
+ case '$startsWith': {
452
+ return " like '".concat(value, "%'");
453
+ }
454
+ case '$endsWith': {
455
+ return " like '%".concat(value, "'");
456
+ }
457
+ case '$includes': {
458
+ return " like '%".concat(value, "%'");
459
+ }
460
+ default: {
461
+ throw new Error("unrecoganized comparison operator ".concat(attr));
462
+ }
463
+ }
464
+ };
465
+ SqlTranslator.prototype.translateElement = function (attr, value) {
466
+ (0, assert_1.default)(attr === '$exists'); // only support one operator now
467
+ if (value) {
468
+ return ' is not null';
469
+ }
470
+ return ' is null';
471
+ };
472
+ SqlTranslator.prototype.translateEvaluation = function (attr, value, entity, alias, type, initialNumber, refAlias) {
473
+ switch (attr) {
474
+ case '$text': {
475
+ // fulltext search
476
+ return {
477
+ stmt: this.translateFullTextSearch(value, entity, alias),
478
+ currentNumber: initialNumber,
479
+ };
480
+ }
481
+ case '$in':
482
+ case '$nin': {
483
+ var IN_OP = {
484
+ $in: 'in',
485
+ $nin: 'not in',
486
+ };
487
+ if (value instanceof Array) {
488
+ var values = value.map(function (v) {
489
+ if (['varchar', 'char', 'text', 'nvarchar', 'ref', 'enum'].includes(type)) {
490
+ return "'".concat(v, "'");
491
+ }
492
+ else {
493
+ return "".concat(v);
494
+ }
495
+ });
496
+ if (values.length > 0) {
497
+ return {
498
+ stmt: " ".concat(IN_OP[attr], "(").concat(values.join(','), ")"),
499
+ currentNumber: initialNumber,
500
+ };
501
+ }
502
+ else {
503
+ if (attr === '$in') {
504
+ return {
505
+ stmt: ' in (null)',
506
+ currentNumber: initialNumber,
507
+ };
508
+ }
509
+ else {
510
+ return {
511
+ stmt: ' is not null',
512
+ currentNumber: initialNumber,
513
+ };
514
+ }
515
+ }
516
+ }
517
+ else {
518
+ // sub query
519
+ var _a = this.translateSelectInner(value.entity, value, initialNumber, refAlias, undefined), subQueryStmt = _a.stmt, currentNumber = _a.currentNumber;
520
+ return {
521
+ stmt: " ".concat(IN_OP[attr], "(").concat(subQueryStmt, ")"),
522
+ currentNumber: currentNumber,
523
+ };
524
+ }
525
+ }
526
+ default: {
527
+ (0, assert_1.default)('$between' === attr);
528
+ var values = value.map(function (v) {
529
+ if (['varchar', 'char', 'text', 'nvarchar', 'ref'].includes(type)) {
530
+ return "'".concat(v, "'");
531
+ }
532
+ else {
533
+ return "".concat(v);
534
+ }
535
+ });
536
+ return {
537
+ stmt: " between ".concat(values[0], " and ").concat(values[1]),
538
+ currentNumber: initialNumber,
539
+ };
540
+ }
541
+ }
542
+ };
543
+ SqlTranslator.prototype.translateFilter = function (entity, selection, aliasDict, filterRefAlias, initialNumber, extraWhere, option) {
544
+ var _this = this;
545
+ var schema = this.schema;
546
+ var filter = selection.filter;
547
+ var currentNumber = initialNumber;
548
+ var translateInner = function (entity2, path, filter2, type) {
549
+ var alias = aliasDict[path];
550
+ var attributes = schema[entity2].attributes;
551
+ var whereText = type ? '' : _this.getDefaultSelectFilter(alias, option);
552
+ if (filter2) {
553
+ var attrs = Object.keys(filter2).filter(function (ele) { return !ele.startsWith('#'); });
554
+ attrs.forEach(function (attr) {
555
+ if (whereText) {
556
+ whereText += ' and ';
557
+ }
558
+ if (['$and', '$or', '$xor', '$not'].includes(attr)) {
559
+ var result = '';
560
+ whereText += '(';
561
+ switch (attr) {
562
+ case '$and':
563
+ case '$or':
564
+ case '$xor': {
565
+ var logicQueries_1 = filter2[attr];
566
+ logicQueries_1.forEach(function (logicQuery, index) {
567
+ var sql = translateInner(entity2, path, logicQuery);
568
+ if (sql) {
569
+ whereText += " (".concat(sql, ")");
570
+ if (index < logicQueries_1.length - 1) {
571
+ whereText += " ".concat(attr.slice(1));
572
+ }
573
+ }
574
+ });
575
+ break;
576
+ }
577
+ default: {
578
+ (0, assert_1.default)(attr === '$not');
579
+ var logicQuery = filter2[attr];
580
+ var sql = translateInner(entity2, path, logicQuery);
581
+ if (sql) {
582
+ whereText += " not (".concat(translateInner(entity2, path, logicQuery), ")");
583
+ break;
584
+ }
585
+ }
586
+ }
587
+ whereText += ')';
588
+ }
589
+ else if (attr.toLowerCase().startsWith(types_1.EXPRESSION_PREFIX)) {
590
+ // expression
591
+ whereText += " (".concat(_this.translateExpression(entity2, alias, filter2[attr], filterRefAlias), ")");
592
+ }
593
+ else if (['$gt', '$gte', '$lt', '$lte', '$eq', '$ne', '$startsWith', '$endsWith', '$includes'].includes(attr)) {
594
+ whereText += _this.translateComparison(attr, filter2[attr], type);
595
+ }
596
+ else if (['$exists'].includes(attr)) {
597
+ whereText += _this.translateElement(attr, filter2[attr]);
598
+ }
599
+ else if (['$text', '$in', '$nin', '$between'].includes(attr)) {
600
+ var _a = _this.translateEvaluation(attr, filter2[attr], entity2, alias, type, initialNumber, filterRefAlias), stmt = _a.stmt, cn2 = _a.currentNumber;
601
+ whereText += stmt;
602
+ currentNumber = cn2;
603
+ }
604
+ else {
605
+ var rel = (0, relation_1.judgeRelation)(_this.schema, entity2, attr);
606
+ if (rel === 2) {
607
+ whereText += " (".concat(translateInner(attr, "".concat(path).concat(attr, "/"), filter2[attr]), ")");
608
+ }
609
+ else if (typeof rel === 'string') {
610
+ whereText += " (".concat(translateInner(rel, "".concat(path).concat(attr, "/"), filter2[attr]), ")");
611
+ }
612
+ else {
613
+ (0, assert_1.default)(attributes.hasOwnProperty(attr), "\u975E\u6CD5\u7684\u5C5E\u6027".concat(attr));
614
+ var type2 = attributes[attr].type;
615
+ // assert (type2 !== 'ref');
616
+ if (typeof filter2[attr] === 'object' && Object.keys(filter2[attr])[0] && Object.keys(filter2[attr])[0].startsWith('$')) {
617
+ whereText += " (`".concat(alias, "`.`").concat(attr, "` ").concat(translateInner(entity2, path, filter2[attr], type2), ")");
618
+ }
619
+ else {
620
+ whereText += " (`".concat(alias, "`.`").concat(attr, "` = ").concat(_this.translateAttrValue(type2, filter2[attr]), ")");
621
+ }
622
+ }
623
+ }
624
+ });
625
+ }
626
+ if (!whereText) {
627
+ whereText = 'true'; // 如果为空就赋一个永真条件,以便处理and
628
+ }
629
+ return whereText;
630
+ };
631
+ var where = translateInner(entity, './', filter);
632
+ if (extraWhere && where) {
633
+ return {
634
+ stmt: "".concat(extraWhere, " and ").concat(where),
635
+ currentNumber: currentNumber,
636
+ };
637
+ }
638
+ return {
639
+ stmt: extraWhere || where,
640
+ currentNumber: currentNumber,
641
+ };
642
+ };
643
+ SqlTranslator.prototype.translateSorter = function (entity, sorter, aliasDict) {
644
+ var _this = this;
645
+ var translateInner = function (entity2, sortAttr, path) {
646
+ (0, assert_1.default)(Object.keys(sortAttr).length === 1);
647
+ var attr = Object.keys(sortAttr)[0];
648
+ var alias = aliasDict[path];
649
+ if (attr.toLocaleLowerCase().startsWith(types_1.EXPRESSION_PREFIX)) {
650
+ return _this.translateExpression(entity2, alias, sortAttr[attr], {});
651
+ }
652
+ else if (sortAttr[attr] === 1) {
653
+ return "`".concat(alias, "`.`").concat(attr, "`");
654
+ }
655
+ else {
656
+ var rel = (0, relation_1.judgeRelation)(_this.schema, entity2, attr);
657
+ if (typeof rel === 'string') {
658
+ return translateInner(rel, sortAttr[attr], "".concat(path).concat(attr, "/"));
659
+ }
660
+ else {
661
+ (0, assert_1.default)(rel === 2);
662
+ return translateInner(attr, sortAttr[attr], "".concat(path).concat(attr, "/"));
663
+ }
664
+ }
665
+ };
666
+ var sortText = '';
667
+ sorter.forEach(function (sortNode, index) {
668
+ var $attr = sortNode.$attr, $direction = sortNode.$direction;
669
+ sortText += translateInner(entity, $attr, './');
670
+ if ($direction) {
671
+ sortText += " ".concat($direction);
672
+ }
673
+ if (index < sorter.length - 1) {
674
+ sortText += ',';
675
+ }
676
+ });
677
+ return sortText;
678
+ };
679
+ SqlTranslator.prototype.translateProjection = function (entity, projection, aliasDict, projectionRefAlias, commonPrefix, disableAs) {
680
+ var _this = this;
681
+ var schema = this.schema;
682
+ var as = '';
683
+ var translateInner = function (entity2, projection2, path) {
684
+ var alias = aliasDict[path];
685
+ var attributes = schema[entity2].attributes;
686
+ var projText = '';
687
+ var prefix = path.slice(2).replace(/\//g, '.');
688
+ var attrs = Object.keys(projection2).filter(function (attr) {
689
+ if (attr.toLowerCase().startsWith(types_1.EXPRESSION_PREFIX)) {
690
+ return true;
691
+ }
692
+ var rel = (0, relation_1.judgeRelation)(_this.schema, entity2, attr);
693
+ return [1, 2].includes(rel) || typeof rel === 'string';
694
+ });
695
+ attrs.forEach(function (attr, idx) {
696
+ var prefix2 = commonPrefix ? "".concat(commonPrefix, ".").concat(prefix) : prefix;
697
+ if (attr.toLowerCase().startsWith(types_1.EXPRESSION_PREFIX)) {
698
+ var exprText = _this.translateExpression(entity2, alias, projection2[attr], projectionRefAlias);
699
+ if (disableAs) {
700
+ projText += " ".concat(exprText);
701
+ }
702
+ else {
703
+ projText += " ".concat(exprText, " as `").concat(prefix2).concat(attr, "`");
704
+ if (!as) {
705
+ as = "`".concat(prefix2).concat(attr, "`");
706
+ }
707
+ else {
708
+ as += ", `".concat(prefix2).concat(attr, "`");
709
+ }
710
+ }
711
+ }
712
+ else {
713
+ var rel = (0, relation_1.judgeRelation)(_this.schema, entity2, attr);
714
+ if (typeof rel === 'string') {
715
+ projText += translateInner(rel, projection2[attr], "".concat(path).concat(attr, "/"));
716
+ }
717
+ else if (rel === 2) {
718
+ projText += translateInner(attr, projection2[attr], "".concat(path).concat(attr, "/"));
719
+ }
720
+ else if (rel === 1) {
721
+ var type = attributes[attr].type;
722
+ if (projection2[attr] === 1) {
723
+ if (disableAs) {
724
+ projText += " ".concat(_this.translateAttrProjection(type, alias, attr));
725
+ }
726
+ else {
727
+ projText += " ".concat(_this.translateAttrProjection(type, alias, attr), " as `").concat(prefix2).concat(attr, "`");
728
+ if (!as) {
729
+ as = "`".concat(prefix2).concat(attr, "`");
730
+ }
731
+ else {
732
+ as += ", `".concat(prefix2).concat(attr, "`");
733
+ }
734
+ }
735
+ }
736
+ else {
737
+ (0, assert_1.default)(typeof projection2 === 'string');
738
+ if (disableAs) {
739
+ projText += " ".concat(_this.translateAttrProjection(type, alias, attr));
740
+ }
741
+ else {
742
+ projText += " ".concat(_this.translateAttrProjection(type, alias, attr), " as `").concat(prefix2).concat(projection2[attr], "`");
743
+ if (!as) {
744
+ as = "`".concat(prefix2).concat(projection2[attr], "`");
745
+ }
746
+ else {
747
+ as += "`".concat(prefix2).concat(projection2[attr], "`");
748
+ }
749
+ }
750
+ }
751
+ }
752
+ }
753
+ if (idx < attrs.length - 1) {
754
+ projText += ',';
755
+ }
756
+ });
757
+ return projText;
758
+ };
759
+ return {
760
+ projText: translateInner(entity, projection, './'),
761
+ as: as,
762
+ };
763
+ };
764
+ SqlTranslator.prototype.translateSelectInner = function (entity, selection, initialNumber, refAlias, option) {
765
+ var data = selection.data, filter = selection.filter, sorter = selection.sorter, indexFrom = selection.indexFrom, count = selection.count;
766
+ var _a = this.analyzeJoin(entity, {
767
+ projection: data,
768
+ filter: filter,
769
+ sorter: sorter,
770
+ }, initialNumber), fromText = _a.from, aliasDict = _a.aliasDict, projectionRefAlias = _a.projectionRefAlias, extraWhere = _a.extraWhere, filterRefAlias = _a.filterRefAlias, currentNumber = _a.currentNumber;
771
+ (0, assert_1.default)((0, lodash_1.intersection)((0, lodash_1.keys)(refAlias), (0, lodash_1.keys)(filterRefAlias)).length === 0, 'filter中的#node结点定义有重复');
772
+ (0, lodash_1.assign)(refAlias, filterRefAlias);
773
+ var projText = this.translateProjection(entity, data, aliasDict, projectionRefAlias).projText;
774
+ var _b = this.translateFilter(entity, selection, aliasDict, refAlias, currentNumber, extraWhere, option), filterText = _b.stmt, currentNumber2 = _b.currentNumber;
775
+ var sorterText = sorter && this.translateSorter(entity, sorter, aliasDict);
776
+ return {
777
+ stmt: this.populateSelectStmt(projText, fromText, aliasDict, filterText, sorterText, undefined, indexFrom, count, option, selection),
778
+ currentNumber: currentNumber2,
779
+ };
780
+ };
781
+ SqlTranslator.prototype.translateSelect = function (entity, selection, option) {
782
+ var stmt = this.translateSelectInner(entity, selection, 1, {}, option).stmt;
783
+ return stmt;
784
+ };
785
+ SqlTranslator.prototype.translateAggregate = function (entity, aggregation, option) {
786
+ var data = aggregation.data, filter = aggregation.filter, sorter = aggregation.sorter, indexFrom = aggregation.indexFrom, count = aggregation.count;
787
+ var _a = this.analyzeJoin(entity, {
788
+ aggregation: data,
789
+ filter: filter,
790
+ sorter: sorter,
791
+ }, 1), fromText = _a.from, aliasDict = _a.aliasDict, projectionRefAlias = _a.projectionRefAlias, extraWhere = _a.extraWhere, filterRefAlias = _a.filterRefAlias, currentNumber = _a.currentNumber;
792
+ var projText = '';
793
+ var groupByText = '';
794
+ for (var k in data) {
795
+ if (k === '#aggr') {
796
+ var _b = this.translateProjection(entity, data[k], aliasDict, projectionRefAlias, '#data'), projSubText = _b.projText, as = _b.as;
797
+ if (!projText) {
798
+ projText = projSubText;
799
+ }
800
+ else {
801
+ projText += ", ".concat(projSubText);
802
+ }
803
+ groupByText = as;
804
+ }
805
+ else {
806
+ var projSubText = this.translateProjection(entity, data[k], aliasDict, projectionRefAlias, undefined, true).projText;
807
+ var projSubText2 = '';
808
+ if (k.startsWith('#max')) {
809
+ projSubText2 = "max(".concat(projSubText, ") as `").concat(k, "`");
810
+ }
811
+ else if (k.startsWith('#min')) {
812
+ projSubText2 = "min(".concat(projSubText, ") as `").concat(k, "`");
813
+ }
814
+ else if (k.startsWith('#count')) {
815
+ projSubText2 = "count(".concat(projSubText, ") as `").concat(k, "`");
816
+ }
817
+ else if (k.startsWith('#sum')) {
818
+ projSubText2 = "sum(".concat(projSubText, ") as `").concat(k, "`");
819
+ }
820
+ else {
821
+ (0, assert_1.default)(k.startsWith('#avg'));
822
+ projSubText2 = "avg(".concat(projSubText, ") as `").concat(k, "`");
823
+ }
824
+ if (!projText) {
825
+ projText = projSubText2;
826
+ }
827
+ else {
828
+ projText += ", ".concat(projSubText2);
829
+ }
830
+ }
831
+ }
832
+ var filterText = this.translateFilter(entity, aggregation, aliasDict, {}, currentNumber, extraWhere, option).stmt;
833
+ var sorterText = sorter && this.translateSorter(entity, sorter, aliasDict);
834
+ return this.populateSelectStmt(projText, fromText, aliasDict, filterText, sorterText, groupByText, indexFrom, count, option, undefined, aggregation);
835
+ };
836
+ SqlTranslator.prototype.translateCount = function (entity, selection, option) {
837
+ var filter = selection.filter, count = selection.count;
838
+ var _a = this.analyzeJoin(entity, {
839
+ filter: filter,
840
+ }), fromText = _a.from, aliasDict = _a.aliasDict, extraWhere = _a.extraWhere, filterRefAlias = _a.filterRefAlias, currentNumber = _a.currentNumber;
841
+ var projText = 'count(1) cnt';
842
+ var filterText = this.translateFilter(entity, selection, aliasDict, filterRefAlias, currentNumber, extraWhere, option).stmt;
843
+ if (count) {
844
+ var subQuerySql = this.populateSelectStmt('1', fromText, aliasDict, filterText, undefined, undefined, undefined, undefined, option, Object.assign({}, selection, { indexFrom: 0, count: count }));
845
+ return "select count(1) cnt from (".concat(subQuerySql, ") __tmp");
846
+ }
847
+ return this.populateSelectStmt(projText, fromText, aliasDict, filterText, undefined, undefined, undefined, undefined, option, selection);
848
+ };
849
+ SqlTranslator.prototype.translateRemove = function (entity, operation, option) {
850
+ var filter = operation.filter, sorter = operation.sorter, indexFrom = operation.indexFrom, count = operation.count;
851
+ (0, assert_1.default)(!sorter, '当前remove不支持sorter行为');
852
+ var _a = this.analyzeJoin(entity, { filter: filter, sorter: sorter }), aliasDict = _a.aliasDict, filterRefAlias = _a.filterRefAlias, extraWhere = _a.extraWhere, fromText = _a.from, currentNumber = _a.currentNumber;
853
+ var alias = aliasDict['./'];
854
+ var filterText = this.translateFilter(entity, operation, aliasDict, filterRefAlias, currentNumber, extraWhere, { includedDeleted: true }).stmt;
855
+ // const sorterText = sorter && sorter.length > 0 ? this.translateSorter(entity, sorter, aliasDict) : undefined;
856
+ return this.populateRemoveStmt(alias, fromText, aliasDict, filterText, /* sorterText */ undefined, indexFrom, count, option);
857
+ };
858
+ SqlTranslator.prototype.translateUpdate = function (entity, operation, option) {
859
+ var attributes = this.schema[entity].attributes;
860
+ var filter = operation.filter, sorter = operation.sorter, indexFrom = operation.indexFrom, count = operation.count, data = operation.data;
861
+ (0, assert_1.default)(!sorter, '当前update不支持sorter行为');
862
+ var _a = this.analyzeJoin(entity, { filter: filter, sorter: sorter }), aliasDict = _a.aliasDict, filterRefAlias = _a.filterRefAlias, extraWhere = _a.extraWhere, fromText = _a.from, currentNumber = _a.currentNumber;
863
+ var alias = aliasDict['./'];
864
+ var updateText = '';
865
+ for (var attr in data) {
866
+ if (updateText) {
867
+ updateText += ',';
868
+ }
869
+ (0, assert_1.default)(attributes.hasOwnProperty(attr));
870
+ var value = this.translateAttrValue(attributes[attr].type, data[attr]);
871
+ updateText += "`".concat(alias, "`.`").concat(attr, "` = ").concat(value);
872
+ }
873
+ var filterText = this.translateFilter(entity, operation, aliasDict, filterRefAlias, currentNumber, extraWhere).stmt;
874
+ // const sorterText = sorter && this.translateSorter(entity, sorter, aliasDict);
875
+ return this.populateUpdateStmt(updateText, fromText, aliasDict, filterText, /* sorterText */ undefined, indexFrom, count, option);
876
+ };
877
+ SqlTranslator.prototype.translateDestroyEntity = function (entity, truncate) {
878
+ var schema = this.schema;
879
+ var _a = schema[entity], _b = _a.storageName, storageName = _b === void 0 ? entity : _b, view = _a.view;
880
+ var sql;
881
+ if (view) {
882
+ sql = "drop view if exists `".concat(storageName, "`");
883
+ }
884
+ else {
885
+ sql = truncate ? "truncate table `".concat(storageName, "`") : "drop table if exists `".concat(storageName, "`");
886
+ }
887
+ return sql;
888
+ };
889
+ SqlTranslator.prototype.escapeStringValue = function (value) {
890
+ var result = "'".concat(value.replace(/'/g, '\\\''), "'");
891
+ return result;
892
+ };
893
+ return SqlTranslator;
894
+ }());
895
+ exports.SqlTranslator = SqlTranslator;