@carbonorm/carbonnode 3.0.13 → 3.0.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/C6Constants.d.ts +1 -0
- package/dist/api/builders/sqlBuilder.d.ts +17 -5
- package/dist/api/executors/SqlExecutor.d.ts +38 -6
- package/dist/index.cjs.js +392 -153
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +392 -153
- package/dist/index.esm.js.map +1 -1
- package/package.json +7 -2
- package/scripts/generateRestBindings.cjs +1 -1
- package/scripts/generateRestBindings.ts +1 -1
- package/src/api/C6Constants.ts +1 -0
- package/src/api/builders/sqlBuilder.ts +336 -105
- package/src/api/executors/SqlExecutor.ts +76 -33
- package/src/api/handlers/ExpressHandler.ts +3 -2
- package/src/api/types/ormInterfaces.ts +4 -4
package/dist/index.esm.js
CHANGED
|
@@ -2,6 +2,8 @@ import axios from 'axios';
|
|
|
2
2
|
import Qs from 'qs';
|
|
3
3
|
import { __assign, __awaiter, __generator, __extends, __spreadArray } from 'tslib';
|
|
4
4
|
import { toast } from 'react-toastify';
|
|
5
|
+
import namedPlaceholders from 'named-placeholders';
|
|
6
|
+
import { Buffer as Buffer$1 } from 'buffer';
|
|
5
7
|
|
|
6
8
|
var C6Constants = {
|
|
7
9
|
// try to 1=1 match the Rest abstract class
|
|
@@ -66,6 +68,7 @@ var C6Constants = {
|
|
|
66
68
|
LOCALTIMESTAMP: 'LOCALTIMESTAMP',
|
|
67
69
|
MAKEDATE: 'MAKEDATE',
|
|
68
70
|
MAKETIME: 'MAKETIME',
|
|
71
|
+
MATCH_AGAINST: 'MATCH_AGAINST',
|
|
69
72
|
MONTHNAME: 'MONTHNAME',
|
|
70
73
|
MICROSECOND: 'MICROSECOND',
|
|
71
74
|
MINUTE: 'MINUTE',
|
|
@@ -440,203 +443,400 @@ var Executor = /** @class */ (function () {
|
|
|
440
443
|
var SqlBuilder = /** @class */ (function (_super) {
|
|
441
444
|
__extends(SqlBuilder, _super);
|
|
442
445
|
function SqlBuilder() {
|
|
443
|
-
|
|
446
|
+
var _this = _super !== null && _super.apply(this, arguments) || this;
|
|
447
|
+
/** Flag to determine if named placeholders should be used */
|
|
448
|
+
_this.useNamedParams = false;
|
|
449
|
+
return _this;
|
|
444
450
|
}
|
|
445
|
-
|
|
451
|
+
SqlBuilder.prototype.convertHexIfBinary = function (col, val) {
|
|
452
|
+
var _a;
|
|
453
|
+
var columnDef = (_a = this.config.C6.TABLES[this.config.restModel.TABLE_NAME].TYPE_VALIDATION) === null || _a === void 0 ? void 0 : _a[col];
|
|
454
|
+
if (typeof val === 'string' &&
|
|
455
|
+
/^[0-9a-fA-F]{32}$/.test(val) &&
|
|
456
|
+
typeof columnDef === 'object' &&
|
|
457
|
+
columnDef.MYSQL_TYPE.toUpperCase().includes('BINARY')) {
|
|
458
|
+
return Buffer.from(val, 'hex');
|
|
459
|
+
}
|
|
460
|
+
return val;
|
|
461
|
+
};
|
|
462
|
+
/** Generate nested WHERE/ON conditions with parameter binding (supports AND/OR/NOT) */
|
|
446
463
|
SqlBuilder.prototype.buildBooleanJoinedConditions = function (set, andMode, params) {
|
|
464
|
+
var _this = this;
|
|
447
465
|
if (andMode === void 0) { andMode = true; }
|
|
448
466
|
if (params === void 0) { params = []; }
|
|
449
467
|
var booleanOperator = andMode ? 'AND' : 'OR';
|
|
450
|
-
var OPERATORS = [
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
468
|
+
var OPERATORS = [
|
|
469
|
+
'=', '!=', '<', '<=', '>', '>=', 'LIKE', 'NOT LIKE', 'IN', 'NOT IN', 'IS', 'IS NOT',
|
|
470
|
+
'BETWEEN', 'NOT BETWEEN', C6Constants.MATCH_AGAINST
|
|
471
|
+
];
|
|
454
472
|
var isNumericKeyed = function (obj) {
|
|
455
473
|
return Array.isArray(obj) && Object.keys(obj).every(function (k) { return /^\d+$/.test(k); });
|
|
456
474
|
};
|
|
475
|
+
// Helper to add a single condition with proper parameter binding
|
|
457
476
|
var addCondition = function (column, op, value) {
|
|
458
477
|
var clause;
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
478
|
+
// If using named parameters, generate a unique key; otherwise use positional placeholder
|
|
479
|
+
var addParam = function (val) {
|
|
480
|
+
if (Array.isArray(params)) {
|
|
481
|
+
// Positional (unnamed) parameter
|
|
482
|
+
params.push(_this.convertHexIfBinary(column, val));
|
|
483
|
+
return '?';
|
|
484
|
+
}
|
|
485
|
+
else {
|
|
486
|
+
// Named parameter mode
|
|
487
|
+
var key = "param".concat(Object.keys(params).length);
|
|
488
|
+
params[key] = _this.convertHexIfBinary(column, val);
|
|
489
|
+
return ":".concat(key);
|
|
490
|
+
}
|
|
491
|
+
};
|
|
492
|
+
if ((op === 'IN' || op === 'NOT IN') && Array.isArray(value)) {
|
|
493
|
+
if (value.length === 0) {
|
|
494
|
+
// Edge case: empty IN list - use a condition that's always false
|
|
495
|
+
clause = "( ".concat(column, " ").concat(op, " (NULL) )");
|
|
496
|
+
isVerbose() && console.warn("[WHERE] Empty list for ".concat(op, " on ").concat(column));
|
|
497
|
+
}
|
|
498
|
+
else {
|
|
499
|
+
var placeholders = value.map(function (val) { return addParam(val); }).join(', ');
|
|
500
|
+
clause = "( ".concat(column, " ").concat(op, " (").concat(placeholders, ") )");
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
else if ((op === 'BETWEEN' || op === 'NOT BETWEEN') && Array.isArray(value) && value.length === 2) {
|
|
504
|
+
// BETWEEN expects exactly two values [min, max]
|
|
505
|
+
var minVal = value[0], maxVal = value[1];
|
|
506
|
+
var ph1 = addParam(minVal);
|
|
507
|
+
var ph2 = addParam(maxVal);
|
|
508
|
+
clause = "( ".concat(column, " ").concat(op, " ").concat(ph1, " AND ").concat(ph2, " )");
|
|
509
|
+
}
|
|
510
|
+
else {
|
|
511
|
+
// Default case for single-value operators (including IS, IS NOT, =, etc.)
|
|
512
|
+
// Note: If value is null and op is 'IS' or 'IS NOT', the placeholder will safely bind null.
|
|
513
|
+
var ph = addParam(value);
|
|
514
|
+
clause = "( ".concat(column, " ").concat(op, " ").concat(ph, " )");
|
|
515
|
+
}
|
|
516
|
+
isVerbose() && console.log("[WHERE] \u2795 ".concat(clause));
|
|
467
517
|
return clause;
|
|
468
518
|
};
|
|
469
519
|
var sql;
|
|
470
520
|
if (isNumericKeyed(set)) {
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
521
|
+
// Array of conditions, use opposite boolean mode for combining (AND/OR swap)
|
|
522
|
+
isVerbose() && console.log("[WHERE] Grouping conditions (array) in ".concat(andMode ? 'AND' : 'OR', " mode:"), set);
|
|
523
|
+
if (set.length === 0) {
|
|
524
|
+
sql = ''; // no conditions
|
|
525
|
+
}
|
|
526
|
+
else if (set.length === 1) {
|
|
527
|
+
// Single element array, just build it normally (no boolean operator needed)
|
|
528
|
+
sql = this.buildBooleanJoinedConditions(set[0], true, params);
|
|
529
|
+
}
|
|
530
|
+
else {
|
|
531
|
+
// Multiple conditions: join them with the opposite of current mode
|
|
532
|
+
var subClauses = set.map(function (item) { return _this.buildBooleanJoinedConditions(item, true, params); });
|
|
533
|
+
var op = andMode ? 'OR' : 'AND';
|
|
534
|
+
sql = subClauses.map(function (sc) { return "(".concat(sc, ")"); }).join(" ".concat(op, " "));
|
|
483
535
|
}
|
|
484
536
|
}
|
|
485
|
-
else {
|
|
537
|
+
else if (typeof set === 'object') {
|
|
486
538
|
var parts = [];
|
|
487
539
|
for (var _i = 0, _a = Object.entries(set); _i < _a.length; _i++) {
|
|
488
540
|
var _b = _a[_i], key = _b[0], value = _b[1];
|
|
489
541
|
if (/^\d+$/.test(key)) {
|
|
542
|
+
// Numeric object keys (should not happen because numeric arrays handled above)
|
|
490
543
|
parts.push(this.buildBooleanJoinedConditions(value, !andMode, params));
|
|
491
544
|
}
|
|
492
|
-
else if (
|
|
493
|
-
|
|
545
|
+
else if (key.toUpperCase() === 'NOT') {
|
|
546
|
+
// NOT operator: negate the inner condition(s)
|
|
547
|
+
var negated = this.buildBooleanJoinedConditions(value, true, params);
|
|
548
|
+
parts.push("NOT (".concat(negated, ")"));
|
|
549
|
+
isVerbose() && console.log("[WHERE] NOT block: (".concat(negated, ")"));
|
|
550
|
+
}
|
|
551
|
+
else if (!Array.isArray(value)) {
|
|
552
|
+
if (typeof value === 'object' && value !== null && Object.keys(value).length === 1) {
|
|
553
|
+
var _c = Object.entries(value)[0], op = _c[0], val = _c[1];
|
|
554
|
+
if (OPERATORS.includes(op.toUpperCase())) {
|
|
555
|
+
if (value !== null &&
|
|
556
|
+
C6Constants.MATCH_AGAINST in value &&
|
|
557
|
+
Array.isArray(value[C6Constants.MATCH_AGAINST])) {
|
|
558
|
+
var _d = value[C6Constants.MATCH_AGAINST], search = _d[0], mode = _d[1];
|
|
559
|
+
var paramName = "param".concat(Object.keys(params).length);
|
|
560
|
+
params[paramName] = search;
|
|
561
|
+
var againstClause = void 0;
|
|
562
|
+
switch (mode === null || mode === void 0 ? void 0 : mode.toUpperCase()) {
|
|
563
|
+
case 'BOOLEAN':
|
|
564
|
+
againstClause = "AGAINST(:".concat(paramName, " IN BOOLEAN MODE)");
|
|
565
|
+
break;
|
|
566
|
+
case 'WITH QUERY EXPANSION':
|
|
567
|
+
againstClause = "AGAINST(:".concat(paramName, " WITH QUERY EXPANSION)");
|
|
568
|
+
break;
|
|
569
|
+
case 'NATURAL':
|
|
570
|
+
case undefined:
|
|
571
|
+
case null:
|
|
572
|
+
againstClause = "AGAINST(:".concat(paramName, ")"); // default natural language mode
|
|
573
|
+
break;
|
|
574
|
+
default:
|
|
575
|
+
throw new Error("Unsupported MATCH_AGAINST mode: ".concat(mode));
|
|
576
|
+
}
|
|
577
|
+
parts.push("(MATCH(".concat(key, ") ").concat(againstClause, ")"));
|
|
578
|
+
continue;
|
|
579
|
+
}
|
|
580
|
+
parts.push(addCondition(key, op.toUpperCase(), val));
|
|
581
|
+
}
|
|
582
|
+
else {
|
|
583
|
+
throw new Error("Unsupported operator '".concat(op, "' for key '").concat(key, "'"));
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
else {
|
|
587
|
+
// Fallback: treat as simple equality
|
|
588
|
+
parts.push(addCondition(key, '=', value));
|
|
589
|
+
}
|
|
494
590
|
}
|
|
495
591
|
else if (value.length === 2 && OPERATORS.includes(value[0])) {
|
|
592
|
+
// Two-element array, first is an operator (like ['>', 5])
|
|
496
593
|
parts.push(addCondition(key, value[0], value[1]));
|
|
497
594
|
}
|
|
595
|
+
else if (value.length === 3 && OPERATORS.includes(value[0])) {
|
|
596
|
+
// Three-element array, e.g. ['BETWEEN', min, max]
|
|
597
|
+
parts.push(addCondition(key, value[0], value.slice(1)));
|
|
598
|
+
}
|
|
498
599
|
else {
|
|
499
600
|
throw new Error("Invalid condition for ".concat(key, ": ").concat(JSON.stringify(value)));
|
|
500
601
|
}
|
|
501
602
|
}
|
|
502
|
-
sql = parts.join(" ".concat(booleanOperator, " "));
|
|
603
|
+
sql = parts.length ? parts.join(" ".concat(booleanOperator, " ")) : '';
|
|
604
|
+
}
|
|
605
|
+
else {
|
|
606
|
+
// Primitive type (should not happen normally), treat it as a boolean expression string
|
|
607
|
+
sql = String(set);
|
|
503
608
|
}
|
|
504
|
-
|
|
505
|
-
return "(".concat(sql, ")");
|
|
609
|
+
// Wrap the final combined condition in parentheses to maintain correct precedence
|
|
610
|
+
return sql ? "(".concat(sql, ")") : '';
|
|
506
611
|
};
|
|
507
|
-
/** Translate array or function
|
|
612
|
+
/** Translate array or function call definitions into SQL expressions (supports nested calls) */
|
|
508
613
|
SqlBuilder.prototype.buildAggregateField = function (field) {
|
|
509
|
-
|
|
614
|
+
var _this = this;
|
|
615
|
+
if (typeof field === 'string') {
|
|
510
616
|
return field;
|
|
511
|
-
|
|
512
|
-
|
|
617
|
+
}
|
|
618
|
+
if (!Array.isArray(field) || field.length === 0) {
|
|
619
|
+
throw new Error('Invalid SELECT field entry');
|
|
620
|
+
}
|
|
621
|
+
// e.g. field = [ 'ROUND', [ 'SQRT', 'age' ], 2, 'AS', 'roundedRootAge' ]
|
|
513
622
|
var fn = field[0], args = field.slice(1);
|
|
514
623
|
var alias;
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
args.pop();
|
|
624
|
+
// Handle alias if present in array (e.g. ... 'AS', 'aliasName')
|
|
625
|
+
if (args.length >= 2 && String(args[args.length - 2]).toUpperCase() === 'AS') {
|
|
626
|
+
alias = String(args.pop()); // last element is alias name
|
|
627
|
+
args.pop(); // remove the 'AS'
|
|
518
628
|
}
|
|
519
629
|
var F = String(fn).toUpperCase();
|
|
520
|
-
|
|
521
|
-
|
|
630
|
+
// Map each argument to SQL string, handling nested function arrays recursively
|
|
631
|
+
var argList = args.map(function (arg) {
|
|
632
|
+
if (Array.isArray(arg)) {
|
|
633
|
+
return _this.buildAggregateField(arg);
|
|
634
|
+
}
|
|
635
|
+
else {
|
|
636
|
+
return arg;
|
|
637
|
+
}
|
|
638
|
+
}).join(', ');
|
|
639
|
+
var expr;
|
|
522
640
|
switch (F) {
|
|
523
641
|
case 'DATE_ADD':
|
|
524
|
-
return "DATE_ADD(".concat(args[0], ", ").concat(args[1], ")").concat(alias ? " AS ".concat(alias) : '');
|
|
525
642
|
case 'DATE_SUB':
|
|
526
|
-
|
|
643
|
+
// Functions with comma-separated interval, assume args like [ date, interval_expression ]
|
|
644
|
+
expr = "".concat(F, "(").concat(argList, ")");
|
|
645
|
+
break;
|
|
527
646
|
case 'YEAR':
|
|
528
|
-
return "YEAR(".concat(args[0], ")").concat(alias ? " AS ".concat(alias) : '');
|
|
529
647
|
case 'MONTH':
|
|
530
|
-
return "MONTH(".concat(args[0], ")").concat(alias ? " AS ".concat(alias) : '');
|
|
531
648
|
case 'DAY':
|
|
532
|
-
return "DAY(".concat(args[0], ")").concat(alias ? " AS ".concat(alias) : '');
|
|
533
649
|
case 'ROUND':
|
|
534
650
|
case 'CEIL':
|
|
535
651
|
case 'FLOOR':
|
|
536
652
|
case 'ABS':
|
|
537
653
|
case 'SQRT':
|
|
538
|
-
|
|
654
|
+
case 'UPPER':
|
|
655
|
+
case 'LOWER':
|
|
656
|
+
case 'COALESCE':
|
|
657
|
+
case 'CONCAT':
|
|
658
|
+
case 'IFNULL':
|
|
659
|
+
case 'IF':
|
|
660
|
+
case 'COUNT':
|
|
661
|
+
case 'SUM':
|
|
662
|
+
case 'MIN':
|
|
663
|
+
case 'MAX':
|
|
664
|
+
case 'AVG':
|
|
665
|
+
// Common SQL functions – just format as F(arg1, arg2, ...)
|
|
666
|
+
expr = "".concat(F, "(").concat(argList, ")");
|
|
667
|
+
break;
|
|
539
668
|
case 'ST_DISTANCE':
|
|
540
|
-
|
|
669
|
+
expr = "ST_Distance(".concat(argList, ")");
|
|
670
|
+
break;
|
|
541
671
|
default:
|
|
542
|
-
if (/^[A-Z_]+$/.test(F))
|
|
543
|
-
|
|
544
|
-
|
|
672
|
+
if (/^[A-Z_]+$/.test(F)) {
|
|
673
|
+
// Allow any other SQL function by name (assuming it's a valid function)
|
|
674
|
+
expr = "".concat(F, "(").concat(argList, ")");
|
|
675
|
+
}
|
|
676
|
+
else {
|
|
677
|
+
throw new Error("Unsupported function: ".concat(F));
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
if (alias) {
|
|
681
|
+
expr += " AS ".concat(alias);
|
|
682
|
+
}
|
|
683
|
+
isVerbose() && console.log("[SELECT] ".concat(expr));
|
|
684
|
+
return expr;
|
|
685
|
+
};
|
|
686
|
+
SqlBuilder.prototype.buildJoinClauses = function (joinArgs, params) {
|
|
687
|
+
var sql = '';
|
|
688
|
+
for (var joinType in joinArgs) {
|
|
689
|
+
var jk = joinType.replace('_', ' ').toUpperCase();
|
|
690
|
+
for (var joinTable in joinArgs[joinType]) {
|
|
691
|
+
var onConditions = joinArgs[joinType][joinTable];
|
|
692
|
+
var onClause = this.buildBooleanJoinedConditions(onConditions, true, params);
|
|
693
|
+
sql += " ".concat(jk, " JOIN `").concat(joinTable, "` ON ").concat(onClause);
|
|
694
|
+
isVerbose() && console.log("[JOIN] ".concat(jk, " JOIN ").concat(joinTable, " ON ").concat(onClause));
|
|
695
|
+
}
|
|
545
696
|
}
|
|
697
|
+
return sql;
|
|
698
|
+
};
|
|
699
|
+
SqlBuilder.prototype.buildPaginationClause = function (pagination, _params) {
|
|
700
|
+
var _a;
|
|
701
|
+
var sql = '';
|
|
702
|
+
if (pagination === null || pagination === void 0 ? void 0 : pagination[C6Constants.ORDER]) {
|
|
703
|
+
var orderParts = Object.entries(pagination[C6Constants.ORDER])
|
|
704
|
+
.map(function (_a) {
|
|
705
|
+
var col = _a[0], dir = _a[1];
|
|
706
|
+
return "".concat(col, " ").concat(String(dir).toUpperCase());
|
|
707
|
+
});
|
|
708
|
+
sql += " ORDER BY ".concat(orderParts.join(', '));
|
|
709
|
+
isVerbose() && console.log("[ORDER BY] ".concat(orderParts));
|
|
710
|
+
}
|
|
711
|
+
if ((pagination === null || pagination === void 0 ? void 0 : pagination[C6Constants.LIMIT]) != null) {
|
|
712
|
+
var lim = parseInt(pagination[C6Constants.LIMIT], 10);
|
|
713
|
+
var page = parseInt((_a = pagination[C6Constants.PAGE]) !== null && _a !== void 0 ? _a : 1, 10);
|
|
714
|
+
var offset = (page - 1) * lim;
|
|
715
|
+
sql += " LIMIT ".concat(offset, ", ").concat(lim);
|
|
716
|
+
isVerbose() && console.log("[LIMIT] ".concat(offset, ", ").concat(lim));
|
|
717
|
+
}
|
|
718
|
+
return sql;
|
|
719
|
+
};
|
|
720
|
+
SqlBuilder.prototype.buildWhereClause = function (whereArg, params) {
|
|
721
|
+
var whereClause = this.buildBooleanJoinedConditions(whereArg, true, params);
|
|
722
|
+
if (whereClause) {
|
|
723
|
+
var trimmed = whereClause.replace(/^\((.*)\)$/, '$1');
|
|
724
|
+
isVerbose() && console.log("[WHERE] ".concat(trimmed));
|
|
725
|
+
return " WHERE ".concat(trimmed);
|
|
726
|
+
}
|
|
727
|
+
return '';
|
|
546
728
|
};
|
|
547
|
-
/** Compose a parameterized SELECT query with optional JOIN/WHERE/GROUP/HAVING/PAGINATION */
|
|
548
729
|
SqlBuilder.prototype.buildSelectQuery = function (table, primary, args, isSubSelect) {
|
|
549
730
|
var _this = this;
|
|
550
|
-
var _a, _b, _c
|
|
731
|
+
var _a, _b, _c;
|
|
551
732
|
if (isSubSelect === void 0) { isSubSelect = false; }
|
|
552
733
|
var model = this.config.C6.TABLES[table];
|
|
553
|
-
var params = [];
|
|
554
|
-
// SELECT
|
|
734
|
+
var params = this.useNamedParams ? {} : [];
|
|
555
735
|
var selectList = (_a = args === null || args === void 0 ? void 0 : args[C6Constants.SELECT]) !== null && _a !== void 0 ? _a : ['*'];
|
|
556
736
|
var selectFields = Array.isArray(selectList)
|
|
557
737
|
? selectList.map(function (f) { return _this.buildAggregateField(f); }).join(', ')
|
|
558
|
-
:
|
|
738
|
+
: String(selectList);
|
|
559
739
|
var sql = "SELECT ".concat(selectFields, " FROM ").concat(table);
|
|
560
|
-
isVerbose() && console.log("[SELECT]", selectFields);
|
|
561
|
-
// JOIN
|
|
562
740
|
if (args === null || args === void 0 ? void 0 : args[C6Constants.JOIN]) {
|
|
563
|
-
|
|
564
|
-
var jk = jt.replace('_', ' ').toUpperCase();
|
|
565
|
-
for (var jn in args[C6Constants.JOIN][jt]) {
|
|
566
|
-
var on = this.buildBooleanJoinedConditions(args[C6Constants.JOIN][jt][jn], true, params);
|
|
567
|
-
sql += " ".concat(jk, " JOIN `").concat(jn, "` ON ").concat(on);
|
|
568
|
-
isVerbose() && console.log("[JOIN]", jk, jn, on);
|
|
569
|
-
}
|
|
570
|
-
}
|
|
741
|
+
sql += this.buildJoinClauses(args[C6Constants.JOIN], params);
|
|
571
742
|
}
|
|
572
|
-
// WHERE
|
|
573
743
|
if (args === null || args === void 0 ? void 0 : args[C6Constants.WHERE]) {
|
|
574
|
-
|
|
575
|
-
// Trim leading and trailing parentheses if they fully wrap the condition
|
|
576
|
-
while (wc.startsWith('(') && wc.endsWith(')')) {
|
|
577
|
-
wc = wc.slice(1, -1).trim();
|
|
578
|
-
}
|
|
579
|
-
sql += " WHERE ".concat(wc);
|
|
744
|
+
sql += this.buildWhereClause(args[C6Constants.WHERE], params);
|
|
580
745
|
}
|
|
581
|
-
// GROUP BY
|
|
582
746
|
if (args === null || args === void 0 ? void 0 : args[C6Constants.GROUP_BY]) {
|
|
583
747
|
var gb = Array.isArray(args[C6Constants.GROUP_BY])
|
|
584
748
|
? args[C6Constants.GROUP_BY].join(', ')
|
|
585
749
|
: args[C6Constants.GROUP_BY];
|
|
586
750
|
sql += " GROUP BY ".concat(gb);
|
|
587
|
-
isVerbose() && console.log("[GROUP BY]"
|
|
751
|
+
isVerbose() && console.log("[GROUP BY] ".concat(gb));
|
|
588
752
|
}
|
|
589
|
-
// HAVING
|
|
590
753
|
if (args === null || args === void 0 ? void 0 : args[C6Constants.HAVING]) {
|
|
591
|
-
var
|
|
592
|
-
|
|
754
|
+
var havingClause = this.buildBooleanJoinedConditions(args[C6Constants.HAVING], true, params);
|
|
755
|
+
if (havingClause) {
|
|
756
|
+
sql += " HAVING ".concat(havingClause);
|
|
757
|
+
}
|
|
593
758
|
}
|
|
594
|
-
// PAGINATION
|
|
595
759
|
if (args === null || args === void 0 ? void 0 : args[C6Constants.PAGINATION]) {
|
|
596
|
-
|
|
597
|
-
if (p[C6Constants.ORDER]) {
|
|
598
|
-
var ord = Object.entries(p[C6Constants.ORDER]).map(function (_a) {
|
|
599
|
-
var c = _a[0], d = _a[1];
|
|
600
|
-
return "".concat(c, " ").concat(String(d).toUpperCase());
|
|
601
|
-
});
|
|
602
|
-
sql += " ORDER BY ".concat(ord.join(', '));
|
|
603
|
-
isVerbose() && console.log("[ORDER BY]", ord);
|
|
604
|
-
}
|
|
605
|
-
if (p[C6Constants.LIMIT] != null) {
|
|
606
|
-
var lim = parseInt(p[C6Constants.LIMIT], 10);
|
|
607
|
-
var pg = parseInt((_b = p[C6Constants.PAGE]) !== null && _b !== void 0 ? _b : 1, 10);
|
|
608
|
-
var off = (pg - 1) * lim;
|
|
609
|
-
sql += " LIMIT ".concat(off, ", ").concat(lim);
|
|
610
|
-
isVerbose() && console.log("[LIMIT]", off, lim);
|
|
611
|
-
}
|
|
760
|
+
sql += this.buildPaginationClause(args[C6Constants.PAGINATION], params);
|
|
612
761
|
}
|
|
613
|
-
// Fallback ORDER/LIMIT
|
|
614
762
|
else if (!isSubSelect) {
|
|
615
|
-
var
|
|
616
|
-
if (
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
for (var _i = 0, _e = ['created_at', 'updated_at']; _i < _e.length; _i++) {
|
|
622
|
-
var ts = _e[_i];
|
|
623
|
-
if ((_d = model === null || model === void 0 ? void 0 : model.COLUMNS) === null || _d === void 0 ? void 0 : _d["".concat(table, ".").concat(ts)]) {
|
|
624
|
-
ok = ts;
|
|
763
|
+
var orderKey = primary || ((_b = model === null || model === void 0 ? void 0 : model.PRIMARY_SHORT) === null || _b === void 0 ? void 0 : _b[0]);
|
|
764
|
+
if (!orderKey) {
|
|
765
|
+
for (var _i = 0, _d = ['created_at', 'updated_at']; _i < _d.length; _i++) {
|
|
766
|
+
var ts = _d[_i];
|
|
767
|
+
if ((_c = model === null || model === void 0 ? void 0 : model.COLUMNS) === null || _c === void 0 ? void 0 : _c["".concat(table, ".").concat(ts)]) {
|
|
768
|
+
orderKey = ts;
|
|
625
769
|
break;
|
|
626
770
|
}
|
|
627
771
|
}
|
|
628
|
-
|
|
772
|
+
}
|
|
773
|
+
if (orderKey) {
|
|
629
774
|
var dir = primary ? 'ASC' : 'DESC';
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
isVerbose() && console.log("[ORDER]", ok, dir, lim);
|
|
775
|
+
sql += " ORDER BY ".concat(orderKey, " ").concat(dir, " LIMIT ").concat(primary ? 1 : 100);
|
|
776
|
+
isVerbose() && console.log("[DEFAULT ORDER] ".concat(orderKey, " ").concat(dir));
|
|
633
777
|
}
|
|
634
778
|
else {
|
|
635
779
|
sql += " LIMIT 100";
|
|
636
|
-
isVerbose() && console.warn("[
|
|
780
|
+
isVerbose() && console.warn("[DEFAULT LIMIT] 100 (no order key found)");
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
isVerbose() && console.log("[SQL SELECT]", sql, params);
|
|
784
|
+
return { sql: sql, params: params };
|
|
785
|
+
};
|
|
786
|
+
SqlBuilder.prototype.buildUpdateQuery = function (table, data, args) {
|
|
787
|
+
if (args === void 0) { args = {}; }
|
|
788
|
+
var params = this.useNamedParams ? {} : [];
|
|
789
|
+
var sql = "UPDATE ".concat(table);
|
|
790
|
+
if (args[C6Constants.JOIN]) {
|
|
791
|
+
sql += this.buildJoinClauses(args[C6Constants.JOIN], params);
|
|
792
|
+
}
|
|
793
|
+
var setClauses = [];
|
|
794
|
+
for (var _i = 0, _a = Object.entries(data); _i < _a.length; _i++) {
|
|
795
|
+
var _b = _a[_i], col = _b[0], val = _b[1];
|
|
796
|
+
if (Array.isArray(val)) {
|
|
797
|
+
var expr = this.buildAggregateField(val);
|
|
798
|
+
setClauses.push("`".concat(col, "` = ").concat(expr));
|
|
799
|
+
}
|
|
800
|
+
else {
|
|
801
|
+
var key = "param".concat(Array.isArray(params) ? params.length : Object.keys(params).length);
|
|
802
|
+
if (Array.isArray(params)) {
|
|
803
|
+
params.push(val);
|
|
804
|
+
setClauses.push("`".concat(col, "` = ?"));
|
|
805
|
+
}
|
|
806
|
+
else {
|
|
807
|
+
params[key] = val;
|
|
808
|
+
setClauses.push("`".concat(col, "` = :").concat(key));
|
|
809
|
+
}
|
|
637
810
|
}
|
|
638
811
|
}
|
|
639
|
-
|
|
812
|
+
sql += " SET ".concat(setClauses.join(', '));
|
|
813
|
+
isVerbose() && console.log("[SET] ".concat(setClauses));
|
|
814
|
+
if (args[C6Constants.WHERE]) {
|
|
815
|
+
sql += this.buildWhereClause(args[C6Constants.WHERE], params);
|
|
816
|
+
}
|
|
817
|
+
if (args[C6Constants.PAGINATION]) {
|
|
818
|
+
sql += this.buildPaginationClause(args[C6Constants.PAGINATION], params);
|
|
819
|
+
}
|
|
820
|
+
isVerbose() && console.log("[SQL UPDATE]", sql, params);
|
|
821
|
+
return { sql: sql, params: params };
|
|
822
|
+
};
|
|
823
|
+
/** Compose a DELETE query with optional JOIN and WHERE clauses */
|
|
824
|
+
SqlBuilder.prototype.buildDeleteQuery = function (table, args) {
|
|
825
|
+
if (args === void 0) { args = {}; }
|
|
826
|
+
var params = this.useNamedParams ? {} : [];
|
|
827
|
+
var sql = args[C6Constants.JOIN]
|
|
828
|
+
? "DELETE ".concat(table, " FROM ").concat(table)
|
|
829
|
+
: "DELETE FROM ".concat(table);
|
|
830
|
+
if (args[C6Constants.JOIN]) {
|
|
831
|
+
sql += this.buildJoinClauses(args[C6Constants.JOIN], params);
|
|
832
|
+
}
|
|
833
|
+
if (args[C6Constants.WHERE]) {
|
|
834
|
+
sql += this.buildWhereClause(args[C6Constants.WHERE], params);
|
|
835
|
+
}
|
|
836
|
+
if (args[C6Constants.PAGINATION]) {
|
|
837
|
+
sql += this.buildPaginationClause(args[C6Constants.PAGINATION], params);
|
|
838
|
+
}
|
|
839
|
+
isVerbose() && console.log("[SQL DELETE]", sql, params);
|
|
640
840
|
return { sql: sql, params: params };
|
|
641
841
|
};
|
|
642
842
|
return SqlBuilder;
|
|
@@ -1363,7 +1563,12 @@ var HttpExecutor$1 = /*#__PURE__*/Object.freeze({
|
|
|
1363
1563
|
var SqlExecutor = /** @class */ (function (_super) {
|
|
1364
1564
|
__extends(SqlExecutor, _super);
|
|
1365
1565
|
function SqlExecutor() {
|
|
1366
|
-
|
|
1566
|
+
var _this = _super !== null && _super.apply(this, arguments) || this;
|
|
1567
|
+
_this.serialize = function (row) { return Object.fromEntries(Object.entries(row).map(function (_a) {
|
|
1568
|
+
var k = _a[0], v = _a[1];
|
|
1569
|
+
return [k, Buffer$1.isBuffer(v) ? v.toString('hex').toUpperCase() : v];
|
|
1570
|
+
})); };
|
|
1571
|
+
return _this;
|
|
1367
1572
|
}
|
|
1368
1573
|
SqlExecutor.prototype.execute = function () {
|
|
1369
1574
|
return __awaiter(this, void 0, void 0, function () {
|
|
@@ -1387,7 +1592,7 @@ var SqlExecutor = /** @class */ (function (_super) {
|
|
|
1387
1592
|
case 2:
|
|
1388
1593
|
rest = _b.sent();
|
|
1389
1594
|
console.log("[SQL EXECUTOR] \u2705 GET result:", rest);
|
|
1390
|
-
return [2 /*return*/,
|
|
1595
|
+
return [2 /*return*/, rest];
|
|
1391
1596
|
case 3: return [4 /*yield*/, this.insert(TABLE_NAME, this.request)];
|
|
1392
1597
|
case 4:
|
|
1393
1598
|
result = _b.sent();
|
|
@@ -1398,11 +1603,7 @@ var SqlExecutor = /** @class */ (function (_super) {
|
|
|
1398
1603
|
case 6:
|
|
1399
1604
|
result = _b.sent();
|
|
1400
1605
|
console.log("[SQL EXECUTOR] \u2705 PUT result:", result);
|
|
1401
|
-
updated = {
|
|
1402
|
-
rest: result,
|
|
1403
|
-
updated: true,
|
|
1404
|
-
rowCount: result.affectedRows
|
|
1405
|
-
};
|
|
1606
|
+
updated = __assign(__assign({}, result), { updated: true, rowCount: result.rest.affectedRows });
|
|
1406
1607
|
return [2 /*return*/, updated];
|
|
1407
1608
|
case 7: return [4 /*yield*/, this.delete(TABLE_NAME, [], this.request)];
|
|
1408
1609
|
case 8:
|
|
@@ -1411,7 +1612,7 @@ var SqlExecutor = /** @class */ (function (_super) {
|
|
|
1411
1612
|
deleted = {
|
|
1412
1613
|
rest: result,
|
|
1413
1614
|
deleted: true,
|
|
1414
|
-
rowCount: result.affectedRows
|
|
1615
|
+
rowCount: result.rest.affectedRows
|
|
1415
1616
|
};
|
|
1416
1617
|
return [2 /*return*/, deleted];
|
|
1417
1618
|
case 9: throw new Error("Unsupported request method: ".concat(method));
|
|
@@ -1446,28 +1647,36 @@ var SqlExecutor = /** @class */ (function (_super) {
|
|
|
1446
1647
|
};
|
|
1447
1648
|
SqlExecutor.prototype.select = function (table, primary, args) {
|
|
1448
1649
|
return __awaiter(this, void 0, void 0, function () {
|
|
1449
|
-
var sql,
|
|
1650
|
+
var QueryResult, formatted, toUnnamed, _a, sql, values;
|
|
1450
1651
|
var _this = this;
|
|
1451
|
-
return __generator(this, function (
|
|
1452
|
-
switch (
|
|
1652
|
+
return __generator(this, function (_b) {
|
|
1653
|
+
switch (_b.label) {
|
|
1453
1654
|
case 0:
|
|
1454
|
-
|
|
1455
|
-
console.log("[SQL EXECUTOR] \uD83E\uDDE0 Generated SELECT SQL:",
|
|
1456
|
-
formatted = this.formatSQLWithParams(
|
|
1655
|
+
QueryResult = this.buildSelectQuery(table, primary, args);
|
|
1656
|
+
console.log("[SQL EXECUTOR] \uD83E\uDDE0 Generated SELECT SQL:", QueryResult);
|
|
1657
|
+
formatted = this.formatSQLWithParams(QueryResult.sql, QueryResult.params);
|
|
1457
1658
|
console.log("[SQL EXECUTOR] \uD83E\uDDE0 Formatted SELECT SQL:", formatted);
|
|
1659
|
+
toUnnamed = namedPlaceholders();
|
|
1660
|
+
_a = toUnnamed(QueryResult.sql, QueryResult.params), sql = _a[0], values = _a[1];
|
|
1458
1661
|
return [4 /*yield*/, this.withConnection(function (conn) { return __awaiter(_this, void 0, void 0, function () {
|
|
1459
1662
|
var rows;
|
|
1460
1663
|
return __generator(this, function (_a) {
|
|
1461
1664
|
switch (_a.label) {
|
|
1462
|
-
case 0: return [4 /*yield*/, conn.query(sql
|
|
1665
|
+
case 0: return [4 /*yield*/, conn.query(sql, values)];
|
|
1463
1666
|
case 1:
|
|
1464
1667
|
rows = (_a.sent())[0];
|
|
1465
1668
|
console.log("[SQL EXECUTOR] \uD83D\uDCE6 Rows fetched:", rows);
|
|
1466
|
-
return [2 /*return*/,
|
|
1669
|
+
return [2 /*return*/, {
|
|
1670
|
+
rest: rows.map(this.serialize),
|
|
1671
|
+
sql: {
|
|
1672
|
+
sql: sql,
|
|
1673
|
+
values: values
|
|
1674
|
+
}
|
|
1675
|
+
}];
|
|
1467
1676
|
}
|
|
1468
1677
|
});
|
|
1469
1678
|
}); })];
|
|
1470
|
-
case 1: return [2 /*return*/,
|
|
1679
|
+
case 1: return [2 /*return*/, _b.sent()];
|
|
1471
1680
|
}
|
|
1472
1681
|
});
|
|
1473
1682
|
});
|
|
@@ -1482,7 +1691,7 @@ var SqlExecutor = /** @class */ (function (_super) {
|
|
|
1482
1691
|
keys = Object.keys(data);
|
|
1483
1692
|
values = keys.map(function (k) { return data[k]; });
|
|
1484
1693
|
placeholders = keys.map(function () { return '?'; }).join(', ');
|
|
1485
|
-
sql = "INSERT INTO `".concat(table, "` (").concat(keys.join(', '), ")
|
|
1694
|
+
sql = "INSERT INTO `".concat(table, "` (").concat(keys.join(', '), ")\n VALUES (").concat(placeholders, ")");
|
|
1486
1695
|
console.log("[SQL EXECUTOR] \uD83E\uDDE0 Generated INSERT SQL:", sql);
|
|
1487
1696
|
console.log("[SQL EXECUTOR] \uD83D\uDD22 Values:", values);
|
|
1488
1697
|
return [4 /*yield*/, this.withConnection(function (conn) { return __awaiter(_this, void 0, void 0, function () {
|
|
@@ -1492,7 +1701,13 @@ var SqlExecutor = /** @class */ (function (_super) {
|
|
|
1492
1701
|
case 0: return [4 /*yield*/, conn.execute(sql, values)];
|
|
1493
1702
|
case 1:
|
|
1494
1703
|
result = (_a.sent())[0];
|
|
1495
|
-
return [2 /*return*/,
|
|
1704
|
+
return [2 /*return*/, {
|
|
1705
|
+
rest: result,
|
|
1706
|
+
sql: {
|
|
1707
|
+
sql: sql,
|
|
1708
|
+
placeholders: placeholders
|
|
1709
|
+
}
|
|
1710
|
+
}];
|
|
1496
1711
|
}
|
|
1497
1712
|
});
|
|
1498
1713
|
}); })];
|
|
@@ -1513,7 +1728,7 @@ var SqlExecutor = /** @class */ (function (_super) {
|
|
|
1513
1728
|
keys = Object.keys(data);
|
|
1514
1729
|
values = keys.map(function (k) { return data[k]; });
|
|
1515
1730
|
updates = keys.map(function (k) { return "`".concat(k, "` = ?"); }).join(', ');
|
|
1516
|
-
sql = "UPDATE `".concat(table, "
|
|
1731
|
+
sql = "UPDATE `".concat(table, "`\n SET ").concat(updates, "\n WHERE `").concat(primary[0], "` = ?");
|
|
1517
1732
|
values.push(data[primary[0]]);
|
|
1518
1733
|
console.log("[SQL EXECUTOR] \uD83E\uDDE0 Generated UPDATE SQL:", sql);
|
|
1519
1734
|
console.log("[SQL EXECUTOR] \uD83D\uDD22 Values:", values);
|
|
@@ -1524,7 +1739,13 @@ var SqlExecutor = /** @class */ (function (_super) {
|
|
|
1524
1739
|
case 0: return [4 /*yield*/, conn.execute(sql, values)];
|
|
1525
1740
|
case 1:
|
|
1526
1741
|
result = (_a.sent())[0];
|
|
1527
|
-
return [2 /*return*/,
|
|
1742
|
+
return [2 /*return*/, {
|
|
1743
|
+
rest: result,
|
|
1744
|
+
sql: {
|
|
1745
|
+
sql: sql,
|
|
1746
|
+
values: values
|
|
1747
|
+
}
|
|
1748
|
+
}];
|
|
1528
1749
|
}
|
|
1529
1750
|
});
|
|
1530
1751
|
}); })];
|
|
@@ -1543,7 +1764,7 @@ var SqlExecutor = /** @class */ (function (_super) {
|
|
|
1543
1764
|
key = primary === null || primary === void 0 ? void 0 : primary[0];
|
|
1544
1765
|
if (!key || !(args === null || args === void 0 ? void 0 : args[key]))
|
|
1545
1766
|
throw new Error('Primary key and value required for delete');
|
|
1546
|
-
sql = "DELETE
|
|
1767
|
+
sql = "DELETE\n FROM `".concat(table, "`\n WHERE `").concat(key, "` = ?");
|
|
1547
1768
|
console.log("[SQL EXECUTOR] \uD83E\uDDE0 Generated DELETE SQL:", sql);
|
|
1548
1769
|
console.log("[SQL EXECUTOR] \uD83D\uDD22 Value:", args[key]);
|
|
1549
1770
|
return [4 /*yield*/, this.withConnection(function (conn) { return __awaiter(_this, void 0, void 0, function () {
|
|
@@ -1553,7 +1774,13 @@ var SqlExecutor = /** @class */ (function (_super) {
|
|
|
1553
1774
|
case 0: return [4 /*yield*/, conn.execute(sql, [args[key]])];
|
|
1554
1775
|
case 1:
|
|
1555
1776
|
result = (_a.sent())[0];
|
|
1556
|
-
return [2 /*return*/,
|
|
1777
|
+
return [2 /*return*/, {
|
|
1778
|
+
rest: result,
|
|
1779
|
+
sql: {
|
|
1780
|
+
sql: sql,
|
|
1781
|
+
args: args
|
|
1782
|
+
}
|
|
1783
|
+
}];
|
|
1557
1784
|
}
|
|
1558
1785
|
});
|
|
1559
1786
|
}); })];
|
|
@@ -1563,23 +1790,35 @@ var SqlExecutor = /** @class */ (function (_super) {
|
|
|
1563
1790
|
});
|
|
1564
1791
|
};
|
|
1565
1792
|
SqlExecutor.prototype.formatSQLWithParams = function (sql, params) {
|
|
1566
|
-
var
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1793
|
+
var _this = this;
|
|
1794
|
+
if (Array.isArray(params)) {
|
|
1795
|
+
var index_1 = 0;
|
|
1796
|
+
return sql.replace(/\?/g, function () {
|
|
1797
|
+
if (index_1 >= params.length)
|
|
1798
|
+
return '?';
|
|
1799
|
+
var val = params[index_1++];
|
|
1800
|
+
return _this.formatValue(val);
|
|
1801
|
+
});
|
|
1802
|
+
}
|
|
1803
|
+
else {
|
|
1804
|
+
return sql.replace(/:([a-zA-Z0-9_]+)/g, function (_, key) {
|
|
1805
|
+
var val = params[key];
|
|
1806
|
+
return _this.formatValue(val);
|
|
1807
|
+
});
|
|
1808
|
+
}
|
|
1809
|
+
};
|
|
1810
|
+
SqlExecutor.prototype.formatValue = function (val) {
|
|
1811
|
+
if (val === null || val === undefined)
|
|
1812
|
+
return 'NULL';
|
|
1813
|
+
if (Buffer$1.isBuffer(val))
|
|
1814
|
+
return "UNHEX('".concat(val.toString('hex'), "')");
|
|
1815
|
+
if (typeof val === 'string')
|
|
1816
|
+
return "'".concat(val.replace(/'/g, "''"), "'");
|
|
1817
|
+
if (typeof val === 'number')
|
|
1818
|
+
return val.toString();
|
|
1819
|
+
if (val instanceof Date)
|
|
1820
|
+
return "'".concat(val.toISOString().slice(0, 19).replace('T', ' '), "'");
|
|
1821
|
+
return "'".concat(JSON.stringify(val), "'");
|
|
1583
1822
|
};
|
|
1584
1823
|
return SqlExecutor;
|
|
1585
1824
|
}(SqlBuilder));
|
|
@@ -1633,11 +1872,11 @@ function ExpressHandler(_a) {
|
|
|
1633
1872
|
})(payload)];
|
|
1634
1873
|
case 1:
|
|
1635
1874
|
response = _a.sent();
|
|
1636
|
-
console.log('response', JSON.stringify(response));
|
|
1637
1875
|
res.status(200).json(__assign({ success: true }, response));
|
|
1638
1876
|
return [3 /*break*/, 3];
|
|
1639
1877
|
case 2:
|
|
1640
1878
|
err_1 = _a.sent();
|
|
1879
|
+
res.status(500).json({ success: false });
|
|
1641
1880
|
next(err_1);
|
|
1642
1881
|
return [3 /*break*/, 3];
|
|
1643
1882
|
case 3: return [2 /*return*/];
|