squel 6.2.0 → 6.2.1
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/CHANGELOG.md +2 -0
- package/README.md +114 -0
- package/dist/browser/squel.min.js +1 -1
- package/dist/cjs/index.js +569 -82
- package/dist/cjs/index.js.map +6 -6
- package/dist/esm/index.js +569 -82
- package/dist/esm/index.js.map +6 -6
- package/dist/types/core.d.ts.map +1 -1
- package/dist/types/types.d.ts +55 -1
- package/dist/types/types.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/esm/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// package.json
|
|
2
2
|
var package_default = {
|
|
3
3
|
name: "squel",
|
|
4
|
-
version: "6.2.
|
|
4
|
+
version: "6.2.1",
|
|
5
5
|
description: "SQL query string builder",
|
|
6
6
|
keywords: [
|
|
7
7
|
"sql",
|
|
@@ -107,7 +107,7 @@ function _clone(src) {
|
|
|
107
107
|
if (_isPlainObject(src) || _isArray(src)) {
|
|
108
108
|
const ret = new anySrc.constructor;
|
|
109
109
|
for (const key of Object.getOwnPropertyNames(src)) {
|
|
110
|
-
if (typeof anySrc[key] !== "function") {
|
|
110
|
+
if (typeof anySrc[key] !== "function" && key !== "_queryBuilder") {
|
|
111
111
|
ret[key] = _clone(anySrc[key]);
|
|
112
112
|
}
|
|
113
113
|
}
|
|
@@ -530,6 +530,178 @@ function _buildSquel(flavour = null) {
|
|
|
530
530
|
return { text: totalStr, values: totalValues };
|
|
531
531
|
}
|
|
532
532
|
};
|
|
533
|
+
cls.Over = class extends cls.BaseBuilder {
|
|
534
|
+
_funcExpr;
|
|
535
|
+
_funcParams;
|
|
536
|
+
_partitionFields;
|
|
537
|
+
_orderFields;
|
|
538
|
+
_rows;
|
|
539
|
+
_range;
|
|
540
|
+
constructor(funcExpr, funcParams = [], options) {
|
|
541
|
+
super(options);
|
|
542
|
+
this._funcExpr = funcExpr;
|
|
543
|
+
this._funcParams = funcParams || [];
|
|
544
|
+
this._partitionFields = [];
|
|
545
|
+
this._orderFields = [];
|
|
546
|
+
this._rows = null;
|
|
547
|
+
this._range = null;
|
|
548
|
+
}
|
|
549
|
+
partitionBy(...fields) {
|
|
550
|
+
let flatFields = [];
|
|
551
|
+
for (const field of fields) {
|
|
552
|
+
if (_isArray(field)) {
|
|
553
|
+
flatFields = flatFields.concat(field);
|
|
554
|
+
} else {
|
|
555
|
+
flatFields.push(field);
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
for (const field of flatFields) {
|
|
559
|
+
this._partitionFields.push(this._sanitizeField(field));
|
|
560
|
+
}
|
|
561
|
+
return this;
|
|
562
|
+
}
|
|
563
|
+
orderBy(field, dir, ...values) {
|
|
564
|
+
field = this._sanitizeField(field);
|
|
565
|
+
let direction;
|
|
566
|
+
if (typeof dir === "string") {
|
|
567
|
+
direction = dir;
|
|
568
|
+
} else if (dir === undefined) {
|
|
569
|
+
direction = "ASC";
|
|
570
|
+
} else if (dir === null) {
|
|
571
|
+
direction = null;
|
|
572
|
+
} else {
|
|
573
|
+
direction = dir ? "ASC" : "DESC";
|
|
574
|
+
}
|
|
575
|
+
this._orderFields.push({ field, dir: direction, values: values || [] });
|
|
576
|
+
return this;
|
|
577
|
+
}
|
|
578
|
+
rowsBetween(start, end) {
|
|
579
|
+
if (end === undefined) {
|
|
580
|
+
this._rows = `ROWS BETWEEN ${start}`;
|
|
581
|
+
} else {
|
|
582
|
+
this._rows = `ROWS BETWEEN ${start} AND ${end}`;
|
|
583
|
+
}
|
|
584
|
+
this._range = null;
|
|
585
|
+
return this;
|
|
586
|
+
}
|
|
587
|
+
rangeBetween(start, end) {
|
|
588
|
+
if (end === undefined) {
|
|
589
|
+
this._range = `RANGE BETWEEN ${start}`;
|
|
590
|
+
} else {
|
|
591
|
+
this._range = `RANGE BETWEEN ${start} AND ${end}`;
|
|
592
|
+
}
|
|
593
|
+
this._rows = null;
|
|
594
|
+
return this;
|
|
595
|
+
}
|
|
596
|
+
_toParamString(options = {}) {
|
|
597
|
+
const values = [];
|
|
598
|
+
let funcRet;
|
|
599
|
+
if (cls.isSquelBuilder(this._funcExpr)) {
|
|
600
|
+
funcRet = this._funcExpr._toParamString({
|
|
601
|
+
buildParameterized: options.buildParameterized
|
|
602
|
+
});
|
|
603
|
+
} else {
|
|
604
|
+
funcRet = this._buildString(this._funcExpr, this._funcParams, {
|
|
605
|
+
buildParameterized: options.buildParameterized
|
|
606
|
+
});
|
|
607
|
+
}
|
|
608
|
+
funcRet.values.forEach((v) => values.push(v));
|
|
609
|
+
let overPartsStr = "";
|
|
610
|
+
if (this._partitionFields.length > 0) {
|
|
611
|
+
let partitionStr = "";
|
|
612
|
+
for (const field of this._partitionFields) {
|
|
613
|
+
partitionStr = _pad(partitionStr, ", ");
|
|
614
|
+
if (cls.isSquelBuilder(field)) {
|
|
615
|
+
const ret = field._toParamString({
|
|
616
|
+
buildParameterized: options.buildParameterized
|
|
617
|
+
});
|
|
618
|
+
partitionStr += ret.text;
|
|
619
|
+
ret.values.forEach((v) => values.push(v));
|
|
620
|
+
} else {
|
|
621
|
+
partitionStr += this._formatFieldName(field);
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
overPartsStr = `PARTITION BY ${partitionStr}`;
|
|
625
|
+
}
|
|
626
|
+
if (this._orderFields.length > 0) {
|
|
627
|
+
let orderStr = "";
|
|
628
|
+
for (const { field, dir, values: orderVals } of this._orderFields) {
|
|
629
|
+
orderStr = _pad(orderStr, ", ");
|
|
630
|
+
let ret;
|
|
631
|
+
if (cls.isSquelBuilder(field)) {
|
|
632
|
+
ret = field._toParamString({
|
|
633
|
+
buildParameterized: options.buildParameterized
|
|
634
|
+
});
|
|
635
|
+
} else {
|
|
636
|
+
ret = this._buildString(field, orderVals, {
|
|
637
|
+
buildParameterized: options.buildParameterized
|
|
638
|
+
});
|
|
639
|
+
}
|
|
640
|
+
orderStr += ret.text;
|
|
641
|
+
ret.values.forEach((v) => values.push(v));
|
|
642
|
+
if (dir !== null) {
|
|
643
|
+
orderStr += ` ${dir}`;
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
overPartsStr = _pad(overPartsStr, " ") + `ORDER BY ${orderStr}`;
|
|
647
|
+
}
|
|
648
|
+
const frameClause = this._rows || this._range;
|
|
649
|
+
if (frameClause) {
|
|
650
|
+
overPartsStr = _pad(overPartsStr, " ") + frameClause;
|
|
651
|
+
}
|
|
652
|
+
return {
|
|
653
|
+
text: `${funcRet.text} OVER (${overPartsStr})`,
|
|
654
|
+
values
|
|
655
|
+
};
|
|
656
|
+
}
|
|
657
|
+
};
|
|
658
|
+
cls.JsonExtract = class extends cls.BaseBuilder {
|
|
659
|
+
_field;
|
|
660
|
+
_path;
|
|
661
|
+
constructor(field, path, options) {
|
|
662
|
+
super(options);
|
|
663
|
+
this._field = field;
|
|
664
|
+
this._path = path;
|
|
665
|
+
}
|
|
666
|
+
_toParamString(options = {}) {
|
|
667
|
+
const values = [];
|
|
668
|
+
let fieldStr = "";
|
|
669
|
+
if (cls.isSquelBuilder(this._field)) {
|
|
670
|
+
const ret = this._field._toParamString({
|
|
671
|
+
buildParameterized: options.buildParameterized
|
|
672
|
+
});
|
|
673
|
+
fieldStr = ret.text;
|
|
674
|
+
ret.values.forEach((v) => values.push(v));
|
|
675
|
+
} else {
|
|
676
|
+
fieldStr = this._formatFieldName(this._field);
|
|
677
|
+
}
|
|
678
|
+
let cleanPath = this._path;
|
|
679
|
+
if (cleanPath.startsWith("$")) {
|
|
680
|
+
cleanPath = cleanPath.slice(1);
|
|
681
|
+
}
|
|
682
|
+
if (cleanPath.startsWith(".")) {
|
|
683
|
+
cleanPath = cleanPath.slice(1);
|
|
684
|
+
}
|
|
685
|
+
const parts = cleanPath.split(".").filter(Boolean);
|
|
686
|
+
let sql = "";
|
|
687
|
+
if (flavour === "postgres") {
|
|
688
|
+
if (parts.length === 0) {
|
|
689
|
+
sql = fieldStr;
|
|
690
|
+
} else {
|
|
691
|
+
sql = fieldStr;
|
|
692
|
+
for (let i = 0;i < parts.length; i++) {
|
|
693
|
+
const op = i === parts.length - 1 ? "->>" : "->";
|
|
694
|
+
sql += `${op}'${parts[i]}'`;
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
} else if (flavour === "mssql") {
|
|
698
|
+
sql = `JSON_VALUE(${fieldStr}, '${this._path}')`;
|
|
699
|
+
} else {
|
|
700
|
+
sql = `json_extract(${fieldStr}, '${this._path}')`;
|
|
701
|
+
}
|
|
702
|
+
return { text: sql, values };
|
|
703
|
+
}
|
|
704
|
+
};
|
|
533
705
|
cls.Block = class extends cls.BaseBuilder {
|
|
534
706
|
constructor(options) {
|
|
535
707
|
super(options);
|
|
@@ -1129,12 +1301,93 @@ function _buildSquel(flavour = null) {
|
|
|
1129
1301
|
};
|
|
1130
1302
|
}
|
|
1131
1303
|
};
|
|
1304
|
+
cls.WithBlock = class extends cls.Block {
|
|
1305
|
+
_tables;
|
|
1306
|
+
constructor(options) {
|
|
1307
|
+
super(options);
|
|
1308
|
+
this._tables = [];
|
|
1309
|
+
}
|
|
1310
|
+
with(alias, table) {
|
|
1311
|
+
this._tables.push({ alias, table, recursive: false });
|
|
1312
|
+
}
|
|
1313
|
+
withRecursive(alias, table) {
|
|
1314
|
+
this._tables.push({ alias, table, recursive: true });
|
|
1315
|
+
}
|
|
1316
|
+
_toParamString(options = {}) {
|
|
1317
|
+
const parts = [];
|
|
1318
|
+
const values = [];
|
|
1319
|
+
let anyRecursive = false;
|
|
1320
|
+
for (const { alias, table, recursive } of this._tables) {
|
|
1321
|
+
if (recursive) {
|
|
1322
|
+
anyRecursive = true;
|
|
1323
|
+
}
|
|
1324
|
+
const ret = table._toParamString({
|
|
1325
|
+
buildParameterized: options.buildParameterized,
|
|
1326
|
+
nested: true
|
|
1327
|
+
});
|
|
1328
|
+
parts.push(`${alias} AS ${ret.text}`);
|
|
1329
|
+
ret.values.forEach((v) => values.push(v));
|
|
1330
|
+
}
|
|
1331
|
+
if (!parts.length) {
|
|
1332
|
+
return { text: "", values: [] };
|
|
1333
|
+
}
|
|
1334
|
+
const isMssql = this.options.useRecursiveKeyword === false;
|
|
1335
|
+
const prefix = anyRecursive && !isMssql ? "WITH RECURSIVE" : "WITH";
|
|
1336
|
+
return {
|
|
1337
|
+
text: `${prefix} ${parts.join(", ")}`,
|
|
1338
|
+
values
|
|
1339
|
+
};
|
|
1340
|
+
}
|
|
1341
|
+
};
|
|
1342
|
+
cls.ReturningBlock = class extends cls.Block {
|
|
1343
|
+
_fields;
|
|
1344
|
+
constructor(options) {
|
|
1345
|
+
super(options);
|
|
1346
|
+
this._fields = [];
|
|
1347
|
+
}
|
|
1348
|
+
returning(field, alias = null, options = {}) {
|
|
1349
|
+
alias = alias ? this._sanitizeFieldAlias(alias) : alias;
|
|
1350
|
+
field = this._sanitizeField(field);
|
|
1351
|
+
const existingField = this._fields.filter((f) => f.name === field && f.alias === alias);
|
|
1352
|
+
if (existingField.length)
|
|
1353
|
+
return this;
|
|
1354
|
+
this._fields.push({ name: field, alias, options });
|
|
1355
|
+
}
|
|
1356
|
+
_toParamString(options = {}) {
|
|
1357
|
+
const { buildParameterized } = options;
|
|
1358
|
+
let totalStr = "";
|
|
1359
|
+
const totalValues = [];
|
|
1360
|
+
for (const field of this._fields) {
|
|
1361
|
+
totalStr = _pad(totalStr, ", ");
|
|
1362
|
+
const { name, alias, options: fieldOptions } = field;
|
|
1363
|
+
if (typeof name === "string") {
|
|
1364
|
+
totalStr += this._formatFieldName(name, fieldOptions);
|
|
1365
|
+
} else {
|
|
1366
|
+
const ret = name._toParamString({ nested: true, buildParameterized });
|
|
1367
|
+
totalStr += ret.text;
|
|
1368
|
+
ret.values.forEach((v) => totalValues.push(v));
|
|
1369
|
+
}
|
|
1370
|
+
if (alias)
|
|
1371
|
+
totalStr += ` AS ${this._formatFieldAlias(alias)}`;
|
|
1372
|
+
}
|
|
1373
|
+
return {
|
|
1374
|
+
text: totalStr.length > 0 ? `RETURNING ${totalStr}` : "",
|
|
1375
|
+
values: totalValues
|
|
1376
|
+
};
|
|
1377
|
+
}
|
|
1378
|
+
};
|
|
1132
1379
|
cls.QueryBuilder = class extends cls.BaseBuilder {
|
|
1133
1380
|
blocks;
|
|
1134
1381
|
constructor(options, blocks) {
|
|
1135
1382
|
super(options);
|
|
1136
1383
|
this.blocks = blocks || [];
|
|
1137
1384
|
for (const block of this.blocks) {
|
|
1385
|
+
Object.defineProperty(block, "_queryBuilder", {
|
|
1386
|
+
value: this,
|
|
1387
|
+
enumerable: false,
|
|
1388
|
+
writable: true,
|
|
1389
|
+
configurable: true
|
|
1390
|
+
});
|
|
1138
1391
|
const exposedMethods = block.exposedMethods();
|
|
1139
1392
|
for (const methodName in exposedMethods) {
|
|
1140
1393
|
const methodBody = exposedMethods[methodName];
|
|
@@ -1143,7 +1396,10 @@ function _buildSquel(flavour = null) {
|
|
|
1143
1396
|
}
|
|
1144
1397
|
((b, name, body) => {
|
|
1145
1398
|
this[name] = (...args) => {
|
|
1146
|
-
body.call(b, ...args);
|
|
1399
|
+
const ret = body.call(b, ...args);
|
|
1400
|
+
if (ret !== undefined && ret !== b) {
|
|
1401
|
+
return ret;
|
|
1402
|
+
}
|
|
1147
1403
|
return this;
|
|
1148
1404
|
};
|
|
1149
1405
|
})(block, methodName, methodBody);
|
|
@@ -1199,6 +1455,7 @@ function _buildSquel(flavour = null) {
|
|
|
1199
1455
|
cls.Select = class extends cls.QueryBuilder {
|
|
1200
1456
|
constructor(options, blocks = null) {
|
|
1201
1457
|
blocks = blocks || [
|
|
1458
|
+
new cls.WithBlock(options),
|
|
1202
1459
|
new cls.StringBlock(options, "SELECT"),
|
|
1203
1460
|
new cls.FunctionBlock(options),
|
|
1204
1461
|
new cls.DistinctBlock(options),
|
|
@@ -1220,12 +1477,14 @@ function _buildSquel(flavour = null) {
|
|
|
1220
1477
|
cls.Update = class extends cls.QueryBuilder {
|
|
1221
1478
|
constructor(options, blocks = null) {
|
|
1222
1479
|
blocks = blocks || [
|
|
1480
|
+
new cls.WithBlock(options),
|
|
1223
1481
|
new cls.StringBlock(options, "UPDATE"),
|
|
1224
1482
|
new cls.UpdateTableBlock(options),
|
|
1225
1483
|
new cls.SetFieldBlock(options),
|
|
1226
1484
|
new cls.WhereBlock(options),
|
|
1227
1485
|
new cls.OrderByBlock(options),
|
|
1228
|
-
new cls.LimitBlock(options)
|
|
1486
|
+
new cls.LimitBlock(options),
|
|
1487
|
+
new cls.ReturningBlock(options)
|
|
1229
1488
|
];
|
|
1230
1489
|
super(options, blocks);
|
|
1231
1490
|
}
|
|
@@ -1233,13 +1492,15 @@ function _buildSquel(flavour = null) {
|
|
|
1233
1492
|
cls.Delete = class extends cls.QueryBuilder {
|
|
1234
1493
|
constructor(options, blocks = null) {
|
|
1235
1494
|
blocks = blocks || [
|
|
1495
|
+
new cls.WithBlock(options),
|
|
1236
1496
|
new cls.StringBlock(options, "DELETE"),
|
|
1237
1497
|
new cls.TargetTableBlock(options),
|
|
1238
1498
|
new cls.FromTableBlock(_extend({}, options, { singleTable: true })),
|
|
1239
1499
|
new cls.JoinBlock(options),
|
|
1240
1500
|
new cls.WhereBlock(options),
|
|
1241
1501
|
new cls.OrderByBlock(options),
|
|
1242
|
-
new cls.LimitBlock(options)
|
|
1502
|
+
new cls.LimitBlock(options),
|
|
1503
|
+
new cls.ReturningBlock(options)
|
|
1243
1504
|
];
|
|
1244
1505
|
super(options, blocks);
|
|
1245
1506
|
}
|
|
@@ -1247,10 +1508,12 @@ function _buildSquel(flavour = null) {
|
|
|
1247
1508
|
cls.Insert = class extends cls.QueryBuilder {
|
|
1248
1509
|
constructor(options, blocks = null) {
|
|
1249
1510
|
blocks = blocks || [
|
|
1511
|
+
new cls.WithBlock(options),
|
|
1250
1512
|
new cls.StringBlock(options, "INSERT"),
|
|
1251
1513
|
new cls.IntoTableBlock(options),
|
|
1252
1514
|
new cls.InsertFieldValueBlock(options),
|
|
1253
|
-
new cls.InsertFieldsFromQueryBlock(options)
|
|
1515
|
+
new cls.InsertFieldsFromQueryBlock(options),
|
|
1516
|
+
new cls.ReturningBlock(options)
|
|
1254
1517
|
];
|
|
1255
1518
|
super(options, blocks);
|
|
1256
1519
|
}
|
|
@@ -1274,6 +1537,8 @@ function _buildSquel(flavour = null) {
|
|
|
1274
1537
|
inst.function(...args);
|
|
1275
1538
|
return inst;
|
|
1276
1539
|
},
|
|
1540
|
+
over: (funcExpr, ...funcParams) => new cls.Over(funcExpr, funcParams),
|
|
1541
|
+
jsonExtract: (field, path) => new cls.JsonExtract(field, path),
|
|
1277
1542
|
registerValueHandler: cls.registerValueHandler
|
|
1278
1543
|
};
|
|
1279
1544
|
_squel.remove = _squel.delete;
|
|
@@ -1299,10 +1564,40 @@ var core_default = squel;
|
|
|
1299
1564
|
// src/mysql.ts
|
|
1300
1565
|
squel.flavours.mysql = (_squel) => {
|
|
1301
1566
|
const cls = _squel.cls;
|
|
1567
|
+
|
|
1568
|
+
class MysqlOnDuplicateKeyUpdateHelper {
|
|
1569
|
+
builder;
|
|
1570
|
+
block;
|
|
1571
|
+
constructor(builder, block) {
|
|
1572
|
+
this.builder = builder;
|
|
1573
|
+
this.block = block;
|
|
1574
|
+
}
|
|
1575
|
+
}
|
|
1302
1576
|
cls.MysqlOnDuplicateKeyUpdateBlock = class extends cls.AbstractSetFieldBlock {
|
|
1303
1577
|
onDupUpdate(field, value, options) {
|
|
1304
1578
|
this._set(field, value, options);
|
|
1305
1579
|
}
|
|
1580
|
+
onDuplicateKeyUpdate() {
|
|
1581
|
+
const helper = new MysqlOnDuplicateKeyUpdateHelper(this._queryBuilder, this);
|
|
1582
|
+
return new Proxy(helper, {
|
|
1583
|
+
get(target, prop, receiver) {
|
|
1584
|
+
if (prop === "set") {
|
|
1585
|
+
return (field, value, options) => {
|
|
1586
|
+
target.block._set(field, value, options);
|
|
1587
|
+
return receiver;
|
|
1588
|
+
};
|
|
1589
|
+
}
|
|
1590
|
+
const val = target.builder[prop];
|
|
1591
|
+
if (typeof val === "function") {
|
|
1592
|
+
return (...args) => {
|
|
1593
|
+
const ret = val.apply(target.builder, args);
|
|
1594
|
+
return ret === target.builder ? receiver : ret;
|
|
1595
|
+
};
|
|
1596
|
+
}
|
|
1597
|
+
return val;
|
|
1598
|
+
}
|
|
1599
|
+
});
|
|
1600
|
+
}
|
|
1306
1601
|
_toParamString(options = {}) {
|
|
1307
1602
|
let totalStr = "";
|
|
1308
1603
|
const totalValues = [];
|
|
@@ -1331,6 +1626,7 @@ squel.flavours.mysql = (_squel) => {
|
|
|
1331
1626
|
cls.Insert = class extends cls.QueryBuilder {
|
|
1332
1627
|
constructor(options, blocks = null) {
|
|
1333
1628
|
blocks = blocks || [
|
|
1629
|
+
new cls.WithBlock(options),
|
|
1334
1630
|
new cls.StringBlock(options, "INSERT"),
|
|
1335
1631
|
new cls.IntoTableBlock(options),
|
|
1336
1632
|
new cls.InsertFieldValueBlock(options),
|
|
@@ -1343,6 +1639,7 @@ squel.flavours.mysql = (_squel) => {
|
|
|
1343
1639
|
cls.Replace = class extends cls.QueryBuilder {
|
|
1344
1640
|
constructor(options, blocks = null) {
|
|
1345
1641
|
blocks = blocks || [
|
|
1642
|
+
new cls.WithBlock(options),
|
|
1346
1643
|
new cls.StringBlock(options, "REPLACE"),
|
|
1347
1644
|
new cls.IntoTableBlock(options),
|
|
1348
1645
|
new cls.InsertFieldValueBlock(options),
|
|
@@ -1361,6 +1658,15 @@ squel.flavours.postgres = (_squel) => {
|
|
|
1361
1658
|
cls.DefaultQueryBuilderOptions.numberedParametersStartAt = 1;
|
|
1362
1659
|
cls.DefaultQueryBuilderOptions.autoQuoteAliasNames = false;
|
|
1363
1660
|
cls.DefaultQueryBuilderOptions.useAsForTableAliasNames = true;
|
|
1661
|
+
|
|
1662
|
+
class PostgresOnConflictUpdateHelper {
|
|
1663
|
+
builder;
|
|
1664
|
+
block;
|
|
1665
|
+
constructor(builder, block) {
|
|
1666
|
+
this.builder = builder;
|
|
1667
|
+
this.block = block;
|
|
1668
|
+
}
|
|
1669
|
+
}
|
|
1364
1670
|
cls.PostgresOnConflictKeyUpdateBlock = class extends cls.AbstractSetFieldBlock {
|
|
1365
1671
|
_onConflict;
|
|
1366
1672
|
_dupFields;
|
|
@@ -1371,17 +1677,46 @@ squel.flavours.postgres = (_squel) => {
|
|
|
1371
1677
|
}
|
|
1372
1678
|
onConflict(conflictFields, fields) {
|
|
1373
1679
|
this._onConflict = true;
|
|
1374
|
-
if (
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1680
|
+
if (conflictFields) {
|
|
1681
|
+
if (!_isArray(conflictFields)) {
|
|
1682
|
+
conflictFields = [conflictFields];
|
|
1683
|
+
}
|
|
1684
|
+
this._dupFields = conflictFields.map(this._sanitizeField.bind(this));
|
|
1378
1685
|
}
|
|
1379
|
-
this._dupFields = conflictFields.map(this._sanitizeField.bind(this));
|
|
1380
1686
|
if (fields) {
|
|
1381
1687
|
Object.keys(fields).forEach((key) => {
|
|
1382
1688
|
this._set(key, fields[key]);
|
|
1383
1689
|
});
|
|
1384
1690
|
}
|
|
1691
|
+
return this._queryBuilder;
|
|
1692
|
+
}
|
|
1693
|
+
doUpdate() {
|
|
1694
|
+
const helper = new PostgresOnConflictUpdateHelper(this._queryBuilder, this);
|
|
1695
|
+
return new Proxy(helper, {
|
|
1696
|
+
get(target, prop, receiver) {
|
|
1697
|
+
if (prop === "set") {
|
|
1698
|
+
return (field, value, options) => {
|
|
1699
|
+
target.block._set(field, value, options);
|
|
1700
|
+
return receiver;
|
|
1701
|
+
};
|
|
1702
|
+
}
|
|
1703
|
+
const val = target.builder[prop];
|
|
1704
|
+
if (typeof val === "function") {
|
|
1705
|
+
return (...args) => {
|
|
1706
|
+
const ret = val.apply(target.builder, args);
|
|
1707
|
+
return ret === target.builder ? receiver : ret;
|
|
1708
|
+
};
|
|
1709
|
+
}
|
|
1710
|
+
return val;
|
|
1711
|
+
}
|
|
1712
|
+
});
|
|
1713
|
+
}
|
|
1714
|
+
doNothing() {
|
|
1715
|
+
this._onConflict = true;
|
|
1716
|
+
this._fields = [];
|
|
1717
|
+
this._values = [[]];
|
|
1718
|
+
this._valueOptions = [[]];
|
|
1719
|
+
return this._queryBuilder;
|
|
1385
1720
|
}
|
|
1386
1721
|
_toParamString(options = {}) {
|
|
1387
1722
|
let totalStr = "";
|
|
@@ -1411,69 +1746,6 @@ squel.flavours.postgres = (_squel) => {
|
|
|
1411
1746
|
return returned;
|
|
1412
1747
|
}
|
|
1413
1748
|
};
|
|
1414
|
-
cls.ReturningBlock = class extends cls.Block {
|
|
1415
|
-
_fields;
|
|
1416
|
-
constructor(options) {
|
|
1417
|
-
super(options);
|
|
1418
|
-
this._fields = [];
|
|
1419
|
-
}
|
|
1420
|
-
returning(field, alias = null, options = {}) {
|
|
1421
|
-
alias = alias ? this._sanitizeFieldAlias(alias) : alias;
|
|
1422
|
-
field = this._sanitizeField(field);
|
|
1423
|
-
const existingField = this._fields.filter((f) => f.name === field && f.alias === alias);
|
|
1424
|
-
if (existingField.length)
|
|
1425
|
-
return this;
|
|
1426
|
-
this._fields.push({ name: field, alias, options });
|
|
1427
|
-
}
|
|
1428
|
-
_toParamString(options = {}) {
|
|
1429
|
-
const { buildParameterized } = options;
|
|
1430
|
-
let totalStr = "";
|
|
1431
|
-
const totalValues = [];
|
|
1432
|
-
for (const field of this._fields) {
|
|
1433
|
-
totalStr = _pad(totalStr, ", ");
|
|
1434
|
-
const { name, alias, options: fieldOptions } = field;
|
|
1435
|
-
if (typeof name === "string") {
|
|
1436
|
-
totalStr += this._formatFieldName(name, fieldOptions);
|
|
1437
|
-
} else {
|
|
1438
|
-
const ret = name._toParamString({ nested: true, buildParameterized });
|
|
1439
|
-
totalStr += ret.text;
|
|
1440
|
-
ret.values.forEach((v) => totalValues.push(v));
|
|
1441
|
-
}
|
|
1442
|
-
if (alias)
|
|
1443
|
-
totalStr += ` AS ${this._formatFieldAlias(alias)}`;
|
|
1444
|
-
}
|
|
1445
|
-
return {
|
|
1446
|
-
text: totalStr.length > 0 ? `RETURNING ${totalStr}` : "",
|
|
1447
|
-
values: totalValues
|
|
1448
|
-
};
|
|
1449
|
-
}
|
|
1450
|
-
};
|
|
1451
|
-
cls.WithBlock = class extends cls.Block {
|
|
1452
|
-
_tables;
|
|
1453
|
-
constructor(options) {
|
|
1454
|
-
super(options);
|
|
1455
|
-
this._tables = [];
|
|
1456
|
-
}
|
|
1457
|
-
with(alias, table) {
|
|
1458
|
-
this._tables.push({ alias, table });
|
|
1459
|
-
}
|
|
1460
|
-
_toParamString(options = {}) {
|
|
1461
|
-
const parts = [];
|
|
1462
|
-
const values = [];
|
|
1463
|
-
for (const { alias, table } of this._tables) {
|
|
1464
|
-
const ret = table._toParamString({
|
|
1465
|
-
buildParameterized: options.buildParameterized,
|
|
1466
|
-
nested: true
|
|
1467
|
-
});
|
|
1468
|
-
parts.push(`${alias} AS ${ret.text}`);
|
|
1469
|
-
ret.values.forEach((v) => values.push(v));
|
|
1470
|
-
}
|
|
1471
|
-
return {
|
|
1472
|
-
text: parts.length ? `WITH ${parts.join(", ")}` : "",
|
|
1473
|
-
values
|
|
1474
|
-
};
|
|
1475
|
-
}
|
|
1476
|
-
};
|
|
1477
1749
|
cls.UsingBlock = class extends cls.AbstractTableBlock {
|
|
1478
1750
|
constructor(options) {
|
|
1479
1751
|
super({ ...options, prefix: "USING" });
|
|
@@ -1587,6 +1859,7 @@ squel.flavours.mssql = (_squel) => {
|
|
|
1587
1859
|
cls.DefaultQueryBuilderOptions.replaceSingleQuotes = true;
|
|
1588
1860
|
cls.DefaultQueryBuilderOptions.autoQuoteAliasNames = false;
|
|
1589
1861
|
cls.DefaultQueryBuilderOptions.numberedParametersPrefix = "@";
|
|
1862
|
+
cls.DefaultQueryBuilderOptions.useRecursiveKeyword = false;
|
|
1590
1863
|
_squel.registerValueHandler(Date, (value) => {
|
|
1591
1864
|
const date = value;
|
|
1592
1865
|
return `'${date.getUTCFullYear()}-${date.getUTCMonth() + 1}-${date.getUTCDate()} ${date.getUTCHours()}:${date.getUTCMinutes()}:${date.getUTCSeconds()}'`;
|
|
@@ -1686,19 +1959,36 @@ squel.flavours.mssql = (_squel) => {
|
|
|
1686
1959
|
super(options);
|
|
1687
1960
|
this._outputs = [];
|
|
1688
1961
|
}
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
this.
|
|
1692
|
-
}
|
|
1693
|
-
|
|
1694
|
-
|
|
1962
|
+
outputs(outputs) {
|
|
1963
|
+
for (const output in outputs) {
|
|
1964
|
+
this.output(output, outputs[output]);
|
|
1965
|
+
}
|
|
1966
|
+
}
|
|
1967
|
+
output(output, alias = null) {
|
|
1968
|
+
if (typeof output === "string") {
|
|
1969
|
+
output = this._sanitizeField(output);
|
|
1970
|
+
alias = alias ? this._sanitizeFieldAlias(alias) : alias;
|
|
1971
|
+
this._outputs.push({
|
|
1972
|
+
name: `INSERTED.${output}`,
|
|
1973
|
+
alias
|
|
1974
|
+
});
|
|
1975
|
+
} else if (Array.isArray(output)) {
|
|
1976
|
+
output.forEach((f) => {
|
|
1977
|
+
this.output(f);
|
|
1695
1978
|
});
|
|
1696
1979
|
}
|
|
1697
1980
|
}
|
|
1698
1981
|
_toParamString(options) {
|
|
1699
1982
|
const ret = super._toParamString(options);
|
|
1700
1983
|
if (ret.text.length && this._outputs.length > 0) {
|
|
1701
|
-
const
|
|
1984
|
+
const parts = this._outputs.map((o) => {
|
|
1985
|
+
let str = o.name;
|
|
1986
|
+
if (o.alias) {
|
|
1987
|
+
str += ` AS ${this._formatFieldAlias(o.alias)}`;
|
|
1988
|
+
}
|
|
1989
|
+
return str;
|
|
1990
|
+
});
|
|
1991
|
+
const innerStr = `OUTPUT ${parts.join(", ")} `;
|
|
1702
1992
|
const valuesPos = ret.text.indexOf("VALUES");
|
|
1703
1993
|
ret.text = ret.text.substring(0, valuesPos) + innerStr + ret.text.substring(valuesPos);
|
|
1704
1994
|
}
|
|
@@ -1743,6 +2033,7 @@ squel.flavours.mssql = (_squel) => {
|
|
|
1743
2033
|
constructor(options, blocks = null) {
|
|
1744
2034
|
const limitOffsetTopBlock = new cls.MssqlLimitOffsetTopBlock(options);
|
|
1745
2035
|
blocks = blocks || [
|
|
2036
|
+
new cls.WithBlock(options),
|
|
1746
2037
|
new cls.StringBlock(options, "SELECT"),
|
|
1747
2038
|
new cls.DistinctBlock(options),
|
|
1748
2039
|
limitOffsetTopBlock.TOP(),
|
|
@@ -1763,6 +2054,7 @@ squel.flavours.mssql = (_squel) => {
|
|
|
1763
2054
|
cls.Update = class extends cls.QueryBuilder {
|
|
1764
2055
|
constructor(options, blocks = null) {
|
|
1765
2056
|
blocks = blocks || [
|
|
2057
|
+
new cls.WithBlock(options),
|
|
1766
2058
|
new cls.StringBlock(options, "UPDATE"),
|
|
1767
2059
|
new cls.MssqlUpdateTopBlock(options),
|
|
1768
2060
|
new cls.UpdateTableBlock(options),
|
|
@@ -1776,6 +2068,7 @@ squel.flavours.mssql = (_squel) => {
|
|
|
1776
2068
|
cls.Delete = class extends cls.QueryBuilder {
|
|
1777
2069
|
constructor(options, blocks = null) {
|
|
1778
2070
|
blocks = blocks || [
|
|
2071
|
+
new cls.WithBlock(options),
|
|
1779
2072
|
new cls.StringBlock(options, "DELETE"),
|
|
1780
2073
|
new cls.TargetTableBlock(options),
|
|
1781
2074
|
new cls.FromTableBlock(_extend({}, options, { singleTable: true })),
|
|
@@ -1791,6 +2084,7 @@ squel.flavours.mssql = (_squel) => {
|
|
|
1791
2084
|
cls.Insert = class extends cls.QueryBuilder {
|
|
1792
2085
|
constructor(options, blocks = null) {
|
|
1793
2086
|
blocks = blocks || [
|
|
2087
|
+
new cls.WithBlock(options),
|
|
1794
2088
|
new cls.StringBlock(options, "INSERT"),
|
|
1795
2089
|
new cls.IntoTableBlock(options),
|
|
1796
2090
|
new cls.MssqlInsertFieldValueBlock(options),
|
|
@@ -1799,6 +2093,199 @@ squel.flavours.mssql = (_squel) => {
|
|
|
1799
2093
|
super(options, blocks);
|
|
1800
2094
|
}
|
|
1801
2095
|
};
|
|
2096
|
+
cls.MergeIntoBlock = class extends cls.Block {
|
|
2097
|
+
_table = null;
|
|
2098
|
+
_alias = null;
|
|
2099
|
+
into(table, alias = null) {
|
|
2100
|
+
this._table = this._sanitizeTable(table);
|
|
2101
|
+
this._alias = alias ? this._sanitizeTableAlias(alias) : null;
|
|
2102
|
+
}
|
|
2103
|
+
_toParamString() {
|
|
2104
|
+
if (!this._table)
|
|
2105
|
+
throw new Error("into() needs to be called");
|
|
2106
|
+
let str = this._formatTableName(this._table);
|
|
2107
|
+
if (this._alias) {
|
|
2108
|
+
str += ` AS ${this._formatTableAlias(this._alias)}`;
|
|
2109
|
+
}
|
|
2110
|
+
return { text: str, values: [] };
|
|
2111
|
+
}
|
|
2112
|
+
};
|
|
2113
|
+
cls.MergeUsingBlock = class extends cls.Block {
|
|
2114
|
+
_source = null;
|
|
2115
|
+
_alias = null;
|
|
2116
|
+
_condition = null;
|
|
2117
|
+
using(source, alias = null, condition = null) {
|
|
2118
|
+
this._source = typeof source === "string" ? this._sanitizeTable(source) : this._sanitizeBaseBuilder(source);
|
|
2119
|
+
this._alias = alias ? this._sanitizeTableAlias(alias) : null;
|
|
2120
|
+
this._condition = condition ? this._sanitizeExpression(condition) : null;
|
|
2121
|
+
}
|
|
2122
|
+
_toParamString(options = {}) {
|
|
2123
|
+
if (!this._source)
|
|
2124
|
+
throw new Error("using() needs to be called");
|
|
2125
|
+
let sourceStr = "";
|
|
2126
|
+
const values = [];
|
|
2127
|
+
if (typeof this._source === "string") {
|
|
2128
|
+
sourceStr = this._formatTableName(this._source);
|
|
2129
|
+
} else {
|
|
2130
|
+
const ret = this._source._toParamString({
|
|
2131
|
+
buildParameterized: options.buildParameterized,
|
|
2132
|
+
nested: true
|
|
2133
|
+
});
|
|
2134
|
+
sourceStr = ret.text;
|
|
2135
|
+
ret.values.forEach((v) => values.push(v));
|
|
2136
|
+
}
|
|
2137
|
+
if (this._alias) {
|
|
2138
|
+
sourceStr += ` AS ${this._formatTableAlias(this._alias)}`;
|
|
2139
|
+
}
|
|
2140
|
+
let conditionStr = "";
|
|
2141
|
+
if (this._condition) {
|
|
2142
|
+
let ret;
|
|
2143
|
+
if (typeof this._condition === "string") {
|
|
2144
|
+
ret = this._buildString(this._condition, [], {
|
|
2145
|
+
buildParameterized: options.buildParameterized
|
|
2146
|
+
});
|
|
2147
|
+
} else {
|
|
2148
|
+
ret = this._condition._toParamString({
|
|
2149
|
+
buildParameterized: options.buildParameterized
|
|
2150
|
+
});
|
|
2151
|
+
}
|
|
2152
|
+
conditionStr = ` ON ${this._applyNestingFormatting(ret.text)}`;
|
|
2153
|
+
ret.values.forEach((v) => values.push(v));
|
|
2154
|
+
}
|
|
2155
|
+
return {
|
|
2156
|
+
text: `USING ${sourceStr}${conditionStr}`,
|
|
2157
|
+
values
|
|
2158
|
+
};
|
|
2159
|
+
}
|
|
2160
|
+
};
|
|
2161
|
+
|
|
2162
|
+
class MergeMatchedClauseHelper {
|
|
2163
|
+
builder;
|
|
2164
|
+
clause;
|
|
2165
|
+
constructor(builder, clause) {
|
|
2166
|
+
this.builder = builder;
|
|
2167
|
+
this.clause = clause;
|
|
2168
|
+
}
|
|
2169
|
+
update(fields) {
|
|
2170
|
+
this.clause.action = { type: "UPDATE", fields };
|
|
2171
|
+
return this.builder;
|
|
2172
|
+
}
|
|
2173
|
+
delete() {
|
|
2174
|
+
this.clause.action = { type: "DELETE" };
|
|
2175
|
+
return this.builder;
|
|
2176
|
+
}
|
|
2177
|
+
}
|
|
2178
|
+
|
|
2179
|
+
class MergeNotMatchedClauseHelper {
|
|
2180
|
+
builder;
|
|
2181
|
+
clause;
|
|
2182
|
+
constructor(builder, clause) {
|
|
2183
|
+
this.builder = builder;
|
|
2184
|
+
this.clause = clause;
|
|
2185
|
+
}
|
|
2186
|
+
insert(fields) {
|
|
2187
|
+
this.clause.action = { type: "INSERT", fields };
|
|
2188
|
+
return this.builder;
|
|
2189
|
+
}
|
|
2190
|
+
}
|
|
2191
|
+
cls.MergeWhenBlock = class extends cls.Block {
|
|
2192
|
+
_clauses;
|
|
2193
|
+
constructor(options) {
|
|
2194
|
+
super(options);
|
|
2195
|
+
this._clauses = [];
|
|
2196
|
+
}
|
|
2197
|
+
whenMatched(condition = null) {
|
|
2198
|
+
const clause = { type: "MATCHED", condition, action: null };
|
|
2199
|
+
this._clauses.push(clause);
|
|
2200
|
+
return new MergeMatchedClauseHelper(this._queryBuilder, clause);
|
|
2201
|
+
}
|
|
2202
|
+
whenNotMatched(condition = null) {
|
|
2203
|
+
const clause = { type: "NOT_MATCHED", condition, action: null };
|
|
2204
|
+
this._clauses.push(clause);
|
|
2205
|
+
return new MergeNotMatchedClauseHelper(this._queryBuilder, clause);
|
|
2206
|
+
}
|
|
2207
|
+
_toParamString(options = {}) {
|
|
2208
|
+
let totalStr = "";
|
|
2209
|
+
const totalValues = [];
|
|
2210
|
+
for (const clause of this._clauses) {
|
|
2211
|
+
if (!clause.action)
|
|
2212
|
+
continue;
|
|
2213
|
+
totalStr = _pad(totalStr, " ");
|
|
2214
|
+
let condStr = "";
|
|
2215
|
+
if (clause.condition) {
|
|
2216
|
+
const ret = this._buildString(clause.condition, [], {
|
|
2217
|
+
buildParameterized: options.buildParameterized
|
|
2218
|
+
});
|
|
2219
|
+
condStr = ` AND ${ret.text}`;
|
|
2220
|
+
ret.values.forEach((v) => totalValues.push(v));
|
|
2221
|
+
}
|
|
2222
|
+
let actionStr = "";
|
|
2223
|
+
if (clause.action.type === "UPDATE") {
|
|
2224
|
+
let setStr = "";
|
|
2225
|
+
for (const key of Object.keys(clause.action.fields)) {
|
|
2226
|
+
setStr = _pad(setStr, ", ");
|
|
2227
|
+
const val = clause.action.fields[key];
|
|
2228
|
+
if (val && typeof val._toParamString === "function") {
|
|
2229
|
+
const ret = val._toParamString({
|
|
2230
|
+
buildParameterized: options.buildParameterized
|
|
2231
|
+
});
|
|
2232
|
+
setStr += `${this._formatFieldName(key)} = ${ret.text}`;
|
|
2233
|
+
ret.values.forEach((v) => totalValues.push(v));
|
|
2234
|
+
} else {
|
|
2235
|
+
const ret = this._buildString(`${this._formatFieldName(key)} = ${this.options.parameterCharacter}`, [val], {
|
|
2236
|
+
buildParameterized: options.buildParameterized
|
|
2237
|
+
});
|
|
2238
|
+
setStr += ret.text;
|
|
2239
|
+
ret.values.forEach((v) => totalValues.push(v));
|
|
2240
|
+
}
|
|
2241
|
+
}
|
|
2242
|
+
actionStr = `THEN UPDATE SET ${setStr}`;
|
|
2243
|
+
} else if (clause.action.type === "DELETE") {
|
|
2244
|
+
actionStr = "THEN DELETE";
|
|
2245
|
+
} else if (clause.action.type === "INSERT") {
|
|
2246
|
+
const cols = Object.keys(clause.action.fields).map((c) => this._formatFieldName(c)).join(", ");
|
|
2247
|
+
let valsStr = "";
|
|
2248
|
+
for (const key of Object.keys(clause.action.fields)) {
|
|
2249
|
+
valsStr = _pad(valsStr, ", ");
|
|
2250
|
+
const val = clause.action.fields[key];
|
|
2251
|
+
if (val && typeof val._toParamString === "function") {
|
|
2252
|
+
const ret = val._toParamString({
|
|
2253
|
+
buildParameterized: options.buildParameterized
|
|
2254
|
+
});
|
|
2255
|
+
valsStr += ret.text;
|
|
2256
|
+
ret.values.forEach((v) => totalValues.push(v));
|
|
2257
|
+
} else {
|
|
2258
|
+
const ret = this._buildString(this.options.parameterCharacter, [val], {
|
|
2259
|
+
buildParameterized: options.buildParameterized
|
|
2260
|
+
});
|
|
2261
|
+
valsStr += ret.text;
|
|
2262
|
+
ret.values.forEach((v) => totalValues.push(v));
|
|
2263
|
+
}
|
|
2264
|
+
}
|
|
2265
|
+
actionStr = `THEN INSERT (${cols}) VALUES (${valsStr})`;
|
|
2266
|
+
}
|
|
2267
|
+
const whenWord = clause.type === "MATCHED" ? "WHEN MATCHED" : "WHEN NOT MATCHED";
|
|
2268
|
+
totalStr += `${whenWord}${condStr} ${actionStr}`;
|
|
2269
|
+
}
|
|
2270
|
+
return {
|
|
2271
|
+
text: totalStr.length ? `${totalStr};` : "",
|
|
2272
|
+
values: totalValues
|
|
2273
|
+
};
|
|
2274
|
+
}
|
|
2275
|
+
};
|
|
2276
|
+
cls.Merge = class extends cls.QueryBuilder {
|
|
2277
|
+
constructor(options, blocks = null) {
|
|
2278
|
+
blocks = blocks || [
|
|
2279
|
+
new cls.WithBlock(options),
|
|
2280
|
+
new cls.StringBlock(options, "MERGE INTO"),
|
|
2281
|
+
new cls.MergeIntoBlock(options),
|
|
2282
|
+
new cls.MergeUsingBlock(options),
|
|
2283
|
+
new cls.MergeWhenBlock(options)
|
|
2284
|
+
];
|
|
2285
|
+
super(options, blocks);
|
|
2286
|
+
}
|
|
2287
|
+
};
|
|
2288
|
+
_squel.merge = (options, blocks) => new cls.Merge(options, blocks);
|
|
1802
2289
|
};
|
|
1803
2290
|
|
|
1804
2291
|
// src/index.ts
|
|
@@ -1808,4 +2295,4 @@ export {
|
|
|
1808
2295
|
src_default as default
|
|
1809
2296
|
};
|
|
1810
2297
|
|
|
1811
|
-
//# debugId=
|
|
2298
|
+
//# debugId=4FE4237F5E06625564756E2164756E21
|