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