pqb 0.51.6 → 0.52.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/dist/index.d.ts +48 -7
- package/dist/index.js +1409 -1336
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1409 -1337
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1274,1507 +1274,1519 @@ const Operators = {
|
|
|
1274
1274
|
array
|
|
1275
1275
|
};
|
|
1276
1276
|
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
}
|
|
1283
|
-
class LimitedTextBaseColumn extends TextBaseColumn {
|
|
1284
|
-
constructor(schema, limit) {
|
|
1277
|
+
const dateTimeEncode = (input) => {
|
|
1278
|
+
return typeof input === "number" ? new Date(input) : input;
|
|
1279
|
+
};
|
|
1280
|
+
class DateBaseColumn extends ColumnType {
|
|
1281
|
+
constructor(schema) {
|
|
1285
1282
|
super(
|
|
1286
1283
|
schema,
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
}
|
|
1291
|
-
toSQL() {
|
|
1292
|
-
return orchidCore.joinTruthy(
|
|
1293
|
-
this.dataType,
|
|
1294
|
-
this.data.maxChars !== void 0 && `(${this.data.maxChars})`
|
|
1284
|
+
schema.stringNumberDate(),
|
|
1285
|
+
schema.stringSchema(),
|
|
1286
|
+
schema.stringNumberDate()
|
|
1295
1287
|
);
|
|
1288
|
+
this.operators = Operators.date;
|
|
1289
|
+
this.asNumber = schema.dateAsNumber;
|
|
1290
|
+
this.asDate = schema.dateAsDate;
|
|
1291
|
+
this.data.encode = dateTimeEncode;
|
|
1296
1292
|
}
|
|
1297
1293
|
}
|
|
1298
|
-
class
|
|
1294
|
+
class DateColumn extends DateBaseColumn {
|
|
1299
1295
|
constructor() {
|
|
1300
1296
|
super(...arguments);
|
|
1301
|
-
this.dataType = "
|
|
1297
|
+
this.dataType = "date";
|
|
1302
1298
|
}
|
|
1303
1299
|
toCode(ctx, key) {
|
|
1304
|
-
const { maxChars } = this.data;
|
|
1305
1300
|
return columnCode(
|
|
1306
1301
|
this,
|
|
1307
1302
|
ctx,
|
|
1308
1303
|
key,
|
|
1309
|
-
`
|
|
1304
|
+
`date()${orchidCore.dateDataToCode(this.data, ctx.migration)}`
|
|
1310
1305
|
);
|
|
1311
1306
|
}
|
|
1312
1307
|
}
|
|
1313
|
-
class
|
|
1314
|
-
constructor(schema,
|
|
1315
|
-
super(schema
|
|
1308
|
+
class DateTimeBaseClass extends DateBaseColumn {
|
|
1309
|
+
constructor(schema, dateTimePrecision) {
|
|
1310
|
+
super(schema);
|
|
1311
|
+
this.data.dateTimePrecision = dateTimePrecision;
|
|
1316
1312
|
}
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1313
|
+
toSQL() {
|
|
1314
|
+
return orchidCore.joinTruthy(
|
|
1315
|
+
this.dataType,
|
|
1316
|
+
this.data.dateTimePrecision !== void 0 && `(${this.data.dateTimePrecision})`
|
|
1317
|
+
);
|
|
1318
|
+
}
|
|
1319
|
+
}
|
|
1320
|
+
class DateTimeTzBaseClass extends DateTimeBaseClass {
|
|
1321
|
+
toSQL() {
|
|
1322
|
+
return orchidCore.joinTruthy(
|
|
1323
|
+
this.baseDataType,
|
|
1324
|
+
this.data.dateTimePrecision !== void 0 && `(${this.data.dateTimePrecision})`,
|
|
1325
|
+
" with time zone"
|
|
1326
|
+
);
|
|
1327
|
+
}
|
|
1328
|
+
}
|
|
1329
|
+
const timestampToCode = (self, ctx, key) => {
|
|
1330
|
+
const { dateTimePrecision: p } = self.data;
|
|
1331
|
+
const { defaultTimestamp } = self.data;
|
|
1332
|
+
if (defaultTimestamp) {
|
|
1333
|
+
const noTz = self instanceof TimestampColumn ? "NoTZ" : "";
|
|
1334
|
+
const def = self.data.default;
|
|
1335
|
+
const modifyQuery = self.data.modifyQuery;
|
|
1336
|
+
self.data.default = void 0;
|
|
1337
|
+
self.data.modifyQuery = void 0;
|
|
1338
|
+
const code = columnCode(
|
|
1339
|
+
self,
|
|
1340
|
+
ctx,
|
|
1341
|
+
key,
|
|
1342
|
+
`timestamps${noTz}(${p && p !== 6 ? p : ""}).${defaultTimestamp}${orchidCore.dateDataToCode(self.data, ctx.migration)}`
|
|
1343
|
+
);
|
|
1344
|
+
self.data.default = def;
|
|
1345
|
+
self.data.modifyQuery = modifyQuery;
|
|
1346
|
+
return code;
|
|
1347
|
+
} else {
|
|
1320
1348
|
return columnCode(
|
|
1321
|
-
|
|
1349
|
+
self,
|
|
1322
1350
|
ctx,
|
|
1323
1351
|
key,
|
|
1324
|
-
|
|
1352
|
+
`${self instanceof TimestampColumn ? "timestampNoTZ" : "timestamp"}(${p && p !== 6 ? p : ""})${orchidCore.dateDataToCode(self.data, ctx.migration)}`
|
|
1325
1353
|
);
|
|
1326
1354
|
}
|
|
1327
|
-
}
|
|
1328
|
-
const textColumnToCode = (column, ctx, key) => {
|
|
1329
|
-
const data = { ...column.data };
|
|
1330
|
-
let args = "";
|
|
1331
|
-
const hasMax = data.maxArg !== void 0 && data.max === data.maxArg;
|
|
1332
|
-
if (data.minArg !== void 0 && data.min === data.minArg || hasMax) {
|
|
1333
|
-
if (data.minArg !== 0 || hasMax && data.max !== Infinity) {
|
|
1334
|
-
args += data.minArg;
|
|
1335
|
-
}
|
|
1336
|
-
delete data.min;
|
|
1337
|
-
if (hasMax) {
|
|
1338
|
-
if (data.maxArg !== Infinity) {
|
|
1339
|
-
args += `, ${data.maxArg}`;
|
|
1340
|
-
}
|
|
1341
|
-
delete data.max;
|
|
1342
|
-
}
|
|
1343
|
-
}
|
|
1344
|
-
return columnCode(
|
|
1345
|
-
column,
|
|
1346
|
-
ctx,
|
|
1347
|
-
key,
|
|
1348
|
-
`${column.dataType}(${args})${orchidCore.stringDataToCode(data, ctx.migration)}`
|
|
1349
|
-
);
|
|
1350
1355
|
};
|
|
1351
|
-
class
|
|
1352
|
-
constructor(
|
|
1353
|
-
super(
|
|
1354
|
-
this.dataType = "
|
|
1355
|
-
}
|
|
1356
|
-
toCode(ctx, key) {
|
|
1357
|
-
return textColumnToCode(this, ctx, key);
|
|
1358
|
-
}
|
|
1359
|
-
}
|
|
1360
|
-
const byteaParse = (val) => typeof val === "string" ? Buffer.from(val.slice(2), "hex") : val;
|
|
1361
|
-
class ByteaColumn extends ColumnType {
|
|
1362
|
-
constructor(schema) {
|
|
1363
|
-
super(schema, schema.buffer());
|
|
1364
|
-
this.dataType = "bytea";
|
|
1365
|
-
this.operators = Operators.text;
|
|
1366
|
-
setColumnDefaultParse(this, byteaParse);
|
|
1356
|
+
class TimestampColumn extends DateTimeBaseClass {
|
|
1357
|
+
constructor() {
|
|
1358
|
+
super(...arguments);
|
|
1359
|
+
this.dataType = "timestamp";
|
|
1367
1360
|
}
|
|
1368
1361
|
toCode(ctx, key) {
|
|
1369
|
-
return
|
|
1362
|
+
return timestampToCode(this, ctx, key);
|
|
1370
1363
|
}
|
|
1371
1364
|
}
|
|
1372
|
-
class
|
|
1373
|
-
constructor(
|
|
1374
|
-
super(
|
|
1375
|
-
this.dataType = "
|
|
1376
|
-
this.
|
|
1365
|
+
class TimestampTZColumn extends DateTimeTzBaseClass {
|
|
1366
|
+
constructor() {
|
|
1367
|
+
super(...arguments);
|
|
1368
|
+
this.dataType = "timestamptz";
|
|
1369
|
+
this.baseDataType = "timestamp";
|
|
1377
1370
|
}
|
|
1378
1371
|
toCode(ctx, key) {
|
|
1379
|
-
return
|
|
1372
|
+
return timestampToCode(this, ctx, key);
|
|
1380
1373
|
}
|
|
1381
1374
|
}
|
|
1382
|
-
class
|
|
1383
|
-
constructor(schema) {
|
|
1375
|
+
class TimeColumn extends ColumnType {
|
|
1376
|
+
constructor(schema, dateTimePrecision) {
|
|
1384
1377
|
super(schema, schema.stringSchema());
|
|
1385
|
-
this.dataType = "
|
|
1386
|
-
this.operators = Operators.
|
|
1378
|
+
this.dataType = "time";
|
|
1379
|
+
this.operators = Operators.time;
|
|
1380
|
+
this.data.dateTimePrecision = dateTimePrecision;
|
|
1387
1381
|
}
|
|
1388
1382
|
toCode(ctx, key) {
|
|
1389
|
-
|
|
1383
|
+
const { dateTimePrecision } = this.data;
|
|
1384
|
+
return columnCode(
|
|
1385
|
+
this,
|
|
1386
|
+
ctx,
|
|
1387
|
+
key,
|
|
1388
|
+
`time(${dateTimePrecision || ""})${orchidCore.dateDataToCode(
|
|
1389
|
+
this.data,
|
|
1390
|
+
ctx.migration
|
|
1391
|
+
)}`
|
|
1392
|
+
);
|
|
1390
1393
|
}
|
|
1391
1394
|
}
|
|
1392
|
-
class
|
|
1393
|
-
constructor(schema) {
|
|
1394
|
-
super(schema, schema.
|
|
1395
|
-
this.dataType = "
|
|
1396
|
-
this.operators = Operators.
|
|
1395
|
+
class IntervalColumn extends ColumnType {
|
|
1396
|
+
constructor(schema, fields, precision) {
|
|
1397
|
+
super(schema, schema.timeInterval());
|
|
1398
|
+
this.dataType = "interval";
|
|
1399
|
+
this.operators = Operators.date;
|
|
1400
|
+
this.data.fields = fields;
|
|
1401
|
+
this.data.precision = precision;
|
|
1397
1402
|
}
|
|
1398
1403
|
toCode(ctx, key) {
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
this.operators = Operators.text;
|
|
1404
|
+
const { fields, precision } = this.data;
|
|
1405
|
+
return columnCode(
|
|
1406
|
+
this,
|
|
1407
|
+
ctx,
|
|
1408
|
+
key,
|
|
1409
|
+
`interval(${[fields && `'${fields}'`, precision && String(precision)].filter((part) => part).join(", ")})`
|
|
1410
|
+
);
|
|
1407
1411
|
}
|
|
1408
|
-
|
|
1409
|
-
return
|
|
1412
|
+
toSQL() {
|
|
1413
|
+
return orchidCore.joinTruthy(
|
|
1414
|
+
this.dataType,
|
|
1415
|
+
this.data.fields && ` ${this.data.fields}`,
|
|
1416
|
+
this.data.precision !== void 0 && ` (${this.data.precision})`
|
|
1417
|
+
);
|
|
1410
1418
|
}
|
|
1411
1419
|
}
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
this.
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
+
|
|
1421
|
+
class ArrayColumn extends ColumnType {
|
|
1422
|
+
constructor(schema, item, inputType, outputType, queryType) {
|
|
1423
|
+
super(schema, inputType, outputType, queryType);
|
|
1424
|
+
this.dataType = "array";
|
|
1425
|
+
this.operators = Operators.array;
|
|
1426
|
+
item.data.isNullable = true;
|
|
1427
|
+
setColumnDefaultParse(this, (input) => parse$1.call(this, input));
|
|
1428
|
+
this.data.item = item instanceof ArrayColumn ? item.data.item : item;
|
|
1429
|
+
this.data.name = item.data.name;
|
|
1430
|
+
this.data.arrayDims = item instanceof ArrayColumn ? item.data.arrayDims + 1 : 1;
|
|
1420
1431
|
}
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
constructor(schema) {
|
|
1424
|
-
super(schema, schema.stringSchema());
|
|
1425
|
-
this.dataType = "polygon";
|
|
1426
|
-
this.operators = Operators.text;
|
|
1432
|
+
toSQL() {
|
|
1433
|
+
return this.data.item.toSQL() + "[]".repeat(this.data.arrayDims);
|
|
1427
1434
|
}
|
|
1428
1435
|
toCode(ctx, key) {
|
|
1429
|
-
|
|
1436
|
+
let open = "array(";
|
|
1437
|
+
let close = ")";
|
|
1438
|
+
for (let i = 1; i < this.data.arrayDims; i++) {
|
|
1439
|
+
open += `${ctx.t}.array(`;
|
|
1440
|
+
close += ")";
|
|
1441
|
+
}
|
|
1442
|
+
const code = [open];
|
|
1443
|
+
const { item } = this.data;
|
|
1444
|
+
const { isNullable } = item.data;
|
|
1445
|
+
delete item.data.isNullable;
|
|
1446
|
+
orchidCore.addCode(code, item.toCode(ctx, key));
|
|
1447
|
+
item.data.isNullable = isNullable;
|
|
1448
|
+
orchidCore.addCode(code, `${close}${orchidCore.arrayDataToCode(this.data, ctx.migration)}`);
|
|
1449
|
+
return columnCode(this, ctx, key, code);
|
|
1430
1450
|
}
|
|
1431
1451
|
}
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1452
|
+
const parse$1 = function(source) {
|
|
1453
|
+
if (typeof source !== "string") return source;
|
|
1454
|
+
const entries = [];
|
|
1455
|
+
parsePostgresArray(source, entries, this.data.item.data.parseItem);
|
|
1456
|
+
return entries;
|
|
1457
|
+
};
|
|
1458
|
+
const parsePostgresArray = (source, entries, transform) => {
|
|
1459
|
+
let pos = 0;
|
|
1460
|
+
if (source[0] === "[") {
|
|
1461
|
+
pos = source.indexOf("=") + 1;
|
|
1462
|
+
if (!pos) pos = source.length;
|
|
1437
1463
|
}
|
|
1438
|
-
|
|
1439
|
-
|
|
1464
|
+
if (source[pos] === "{") pos++;
|
|
1465
|
+
let recorded = "";
|
|
1466
|
+
while (pos < source.length) {
|
|
1467
|
+
const character = source[pos++];
|
|
1468
|
+
if (character === "{") {
|
|
1469
|
+
const innerEntries = [];
|
|
1470
|
+
entries.push(innerEntries);
|
|
1471
|
+
pos += parsePostgresArray(source.slice(pos - 1), innerEntries, transform) - 1;
|
|
1472
|
+
} else if (character === "}") {
|
|
1473
|
+
if (recorded) {
|
|
1474
|
+
entries.push(
|
|
1475
|
+
recorded === "NULL" ? null : transform ? transform(recorded) : recorded
|
|
1476
|
+
);
|
|
1477
|
+
}
|
|
1478
|
+
return pos;
|
|
1479
|
+
} else if (character === '"') {
|
|
1480
|
+
let esc = false;
|
|
1481
|
+
let rec = "";
|
|
1482
|
+
while (pos < source.length) {
|
|
1483
|
+
let char;
|
|
1484
|
+
while ((char = source[pos++]) === "\\") {
|
|
1485
|
+
if (!(esc = !esc)) rec += "\\";
|
|
1486
|
+
}
|
|
1487
|
+
if (esc) {
|
|
1488
|
+
esc = false;
|
|
1489
|
+
} else if (char === '"') {
|
|
1490
|
+
break;
|
|
1491
|
+
}
|
|
1492
|
+
rec += char;
|
|
1493
|
+
}
|
|
1494
|
+
entries.push(transform ? transform(rec) : rec);
|
|
1495
|
+
recorded = "";
|
|
1496
|
+
} else if (character === ",") {
|
|
1497
|
+
if (recorded) {
|
|
1498
|
+
entries.push(
|
|
1499
|
+
recorded === "NULL" ? null : transform ? transform(recorded) : recorded
|
|
1500
|
+
);
|
|
1501
|
+
recorded = "";
|
|
1502
|
+
}
|
|
1503
|
+
} else {
|
|
1504
|
+
recorded += character;
|
|
1505
|
+
}
|
|
1440
1506
|
}
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1507
|
+
return pos;
|
|
1508
|
+
};
|
|
1509
|
+
|
|
1510
|
+
const encode$1 = (x) => x === null ? x : JSON.stringify(x);
|
|
1511
|
+
class JSONColumn extends ColumnType {
|
|
1512
|
+
constructor(schema, inputType) {
|
|
1513
|
+
super(schema, inputType);
|
|
1514
|
+
this.dataType = "jsonb";
|
|
1515
|
+
this.operators = Operators.json;
|
|
1516
|
+
this.data.encode = encode$1;
|
|
1517
|
+
this.data.parseItem = JSON.parse;
|
|
1448
1518
|
}
|
|
1449
1519
|
toCode(ctx, key) {
|
|
1450
|
-
return columnCode(this, ctx, key, `
|
|
1520
|
+
return columnCode(this, ctx, key, `json()`);
|
|
1451
1521
|
}
|
|
1452
1522
|
}
|
|
1453
|
-
|
|
1454
|
-
function(input) {
|
|
1455
|
-
return input === null ? input : parseFloat(input.replace(/,/g, "").replace(/\$/g, ""));
|
|
1456
|
-
},
|
|
1457
|
-
{
|
|
1458
|
-
hideFromCode: true
|
|
1459
|
-
}
|
|
1460
|
-
);
|
|
1461
|
-
class CidrColumn extends ColumnType {
|
|
1523
|
+
class JSONTextColumn extends ColumnType {
|
|
1462
1524
|
constructor(schema) {
|
|
1463
1525
|
super(schema, schema.stringSchema());
|
|
1464
|
-
this.dataType = "
|
|
1526
|
+
this.dataType = "json";
|
|
1465
1527
|
this.operators = Operators.text;
|
|
1466
1528
|
}
|
|
1529
|
+
static get instance() {
|
|
1530
|
+
return this._instance ?? (this._instance = new JSONTextColumn(defaultSchemaConfig));
|
|
1531
|
+
}
|
|
1467
1532
|
toCode(ctx, key) {
|
|
1468
|
-
return columnCode(this, ctx, key, `
|
|
1533
|
+
return columnCode(this, ctx, key, `jsonText()`);
|
|
1469
1534
|
}
|
|
1470
1535
|
}
|
|
1471
|
-
|
|
1536
|
+
|
|
1537
|
+
class NumberBaseColumn extends ColumnType {
|
|
1538
|
+
constructor() {
|
|
1539
|
+
super(...arguments);
|
|
1540
|
+
this.operators = Operators.number;
|
|
1541
|
+
}
|
|
1542
|
+
}
|
|
1543
|
+
class IntegerBaseColumn extends NumberBaseColumn {
|
|
1544
|
+
constructor(schema) {
|
|
1545
|
+
super(schema, schema.int());
|
|
1546
|
+
this.data.int = true;
|
|
1547
|
+
}
|
|
1548
|
+
}
|
|
1549
|
+
class NumberAsStringBaseColumn extends ColumnType {
|
|
1472
1550
|
constructor(schema) {
|
|
1473
1551
|
super(schema, schema.stringSchema());
|
|
1474
|
-
this.
|
|
1475
|
-
this.
|
|
1552
|
+
this.operators = Operators.number;
|
|
1553
|
+
this.data.jsonCast = "text";
|
|
1554
|
+
}
|
|
1555
|
+
}
|
|
1556
|
+
class DecimalColumn extends NumberAsStringBaseColumn {
|
|
1557
|
+
constructor(schema, numericPrecision, numericScale) {
|
|
1558
|
+
super(schema);
|
|
1559
|
+
this.operators = Operators.number;
|
|
1560
|
+
this.dataType = "numeric";
|
|
1561
|
+
this.data.numericPrecision = numericPrecision;
|
|
1562
|
+
this.data.numericScale = numericScale;
|
|
1563
|
+
this.data.alias = "decimal";
|
|
1476
1564
|
}
|
|
1477
1565
|
toCode(ctx, key) {
|
|
1478
|
-
|
|
1566
|
+
const { numericPrecision, numericScale } = this.data;
|
|
1567
|
+
return columnCode(
|
|
1568
|
+
this,
|
|
1569
|
+
ctx,
|
|
1570
|
+
key,
|
|
1571
|
+
`decimal(${numericPrecision || ""}${numericScale ? `, ${numericScale}` : ""})`
|
|
1572
|
+
);
|
|
1573
|
+
}
|
|
1574
|
+
toSQL() {
|
|
1575
|
+
const { numericPrecision, numericScale } = this.data;
|
|
1576
|
+
return orchidCore.joinTruthy(
|
|
1577
|
+
this.dataType,
|
|
1578
|
+
numericPrecision ? numericScale ? `(${numericPrecision}, ${numericScale})` : `(${numericPrecision})` : void 0
|
|
1579
|
+
);
|
|
1479
1580
|
}
|
|
1480
1581
|
}
|
|
1481
|
-
|
|
1582
|
+
const skipNumberMethods = { int: true };
|
|
1583
|
+
const intToCode = (column, ctx, key, alias) => {
|
|
1584
|
+
let code;
|
|
1585
|
+
if (column.data.identity) {
|
|
1586
|
+
code = identityToCode(column.data.identity, alias);
|
|
1587
|
+
} else {
|
|
1588
|
+
code = [`${alias}()`];
|
|
1589
|
+
}
|
|
1590
|
+
orchidCore.addCode(
|
|
1591
|
+
code,
|
|
1592
|
+
orchidCore.numberDataToCode(column.data, ctx.migration, skipNumberMethods)
|
|
1593
|
+
);
|
|
1594
|
+
return columnCode(column, ctx, key, code);
|
|
1595
|
+
};
|
|
1596
|
+
class SmallIntColumn extends IntegerBaseColumn {
|
|
1482
1597
|
constructor(schema) {
|
|
1483
|
-
super(schema
|
|
1484
|
-
this.dataType = "
|
|
1485
|
-
this.
|
|
1598
|
+
super(schema);
|
|
1599
|
+
this.dataType = "int2";
|
|
1600
|
+
this.data.alias = "smallint";
|
|
1601
|
+
this.data.parseItem = parseInt;
|
|
1486
1602
|
}
|
|
1487
1603
|
toCode(ctx, key) {
|
|
1488
|
-
return
|
|
1604
|
+
return intToCode(this, ctx, key, "smallint");
|
|
1605
|
+
}
|
|
1606
|
+
identity(options = {}) {
|
|
1607
|
+
return orchidCore.setColumnData(this, "identity", options);
|
|
1489
1608
|
}
|
|
1490
1609
|
}
|
|
1491
|
-
class
|
|
1610
|
+
class IntegerColumn extends IntegerBaseColumn {
|
|
1492
1611
|
constructor(schema) {
|
|
1493
|
-
super(schema
|
|
1494
|
-
this.dataType = "
|
|
1495
|
-
this.
|
|
1612
|
+
super(schema);
|
|
1613
|
+
this.dataType = "int4";
|
|
1614
|
+
this.data.alias = "integer";
|
|
1615
|
+
this.data.parseItem = parseInt;
|
|
1496
1616
|
}
|
|
1497
1617
|
toCode(ctx, key) {
|
|
1498
|
-
return
|
|
1618
|
+
return intToCode(this, ctx, key, "integer");
|
|
1619
|
+
}
|
|
1620
|
+
identity(options = {}) {
|
|
1621
|
+
return orchidCore.setColumnData(this, "identity", options);
|
|
1499
1622
|
}
|
|
1500
1623
|
}
|
|
1501
|
-
class
|
|
1502
|
-
constructor(schema
|
|
1503
|
-
super(schema
|
|
1504
|
-
this.dataType = "
|
|
1505
|
-
this.
|
|
1506
|
-
this.data.length = length;
|
|
1624
|
+
class BigIntColumn extends NumberAsStringBaseColumn {
|
|
1625
|
+
constructor(schema) {
|
|
1626
|
+
super(schema);
|
|
1627
|
+
this.dataType = "int8";
|
|
1628
|
+
this.data.alias = "bigint";
|
|
1507
1629
|
}
|
|
1508
1630
|
toCode(ctx, key) {
|
|
1509
|
-
|
|
1510
|
-
return columnCode(this, ctx, key, `bit(${length})`);
|
|
1631
|
+
return intToCode(this, ctx, key, "bigint");
|
|
1511
1632
|
}
|
|
1512
|
-
|
|
1513
|
-
return orchidCore.
|
|
1514
|
-
|
|
1515
|
-
|
|
1633
|
+
identity(options = {}) {
|
|
1634
|
+
return orchidCore.setColumnData(this, "identity", options);
|
|
1635
|
+
}
|
|
1636
|
+
}
|
|
1637
|
+
class RealColumn extends NumberBaseColumn {
|
|
1638
|
+
constructor(schema) {
|
|
1639
|
+
super(schema, schema.number());
|
|
1640
|
+
this.dataType = "float4";
|
|
1641
|
+
this.data.alias = "real";
|
|
1642
|
+
this.data.parseItem = parseFloat;
|
|
1643
|
+
}
|
|
1644
|
+
toCode(ctx, key) {
|
|
1645
|
+
return columnCode(
|
|
1646
|
+
this,
|
|
1647
|
+
ctx,
|
|
1648
|
+
key,
|
|
1649
|
+
`real()${orchidCore.numberDataToCode(this.data, ctx.migration)}`
|
|
1516
1650
|
);
|
|
1517
1651
|
}
|
|
1518
1652
|
}
|
|
1519
|
-
class
|
|
1520
|
-
constructor(schema
|
|
1521
|
-
super(schema
|
|
1522
|
-
this.dataType = "
|
|
1523
|
-
this.
|
|
1524
|
-
this.data.length = length;
|
|
1525
|
-
this.data.alias = "bitVarying";
|
|
1653
|
+
class DoublePrecisionColumn extends NumberAsStringBaseColumn {
|
|
1654
|
+
constructor(schema) {
|
|
1655
|
+
super(schema);
|
|
1656
|
+
this.dataType = "float8";
|
|
1657
|
+
this.data.alias = "doublePrecision";
|
|
1526
1658
|
}
|
|
1527
1659
|
toCode(ctx, key) {
|
|
1528
|
-
|
|
1529
|
-
|
|
1660
|
+
return columnCode(this, ctx, key, `doublePrecision()`);
|
|
1661
|
+
}
|
|
1662
|
+
}
|
|
1663
|
+
class SmallSerialColumn extends IntegerBaseColumn {
|
|
1664
|
+
constructor(schema) {
|
|
1665
|
+
super(schema);
|
|
1666
|
+
this.dataType = "int2";
|
|
1667
|
+
this.data.int = true;
|
|
1668
|
+
this.data.alias = "smallSerial";
|
|
1669
|
+
this.data.parseItem = parseInt;
|
|
1530
1670
|
}
|
|
1531
1671
|
toSQL() {
|
|
1532
|
-
return
|
|
1533
|
-
|
|
1534
|
-
|
|
1672
|
+
return "smallserial";
|
|
1673
|
+
}
|
|
1674
|
+
toCode(ctx, key) {
|
|
1675
|
+
return columnCode(
|
|
1676
|
+
this,
|
|
1677
|
+
ctx,
|
|
1678
|
+
key,
|
|
1679
|
+
`smallSerial()${orchidCore.numberDataToCode(
|
|
1680
|
+
this.data,
|
|
1681
|
+
ctx.migration,
|
|
1682
|
+
skipNumberMethods
|
|
1683
|
+
)}`
|
|
1535
1684
|
);
|
|
1536
1685
|
}
|
|
1537
1686
|
}
|
|
1538
|
-
class
|
|
1539
|
-
constructor(schema
|
|
1540
|
-
super(schema
|
|
1541
|
-
this.
|
|
1542
|
-
this.
|
|
1543
|
-
this.
|
|
1687
|
+
class SerialColumn extends IntegerBaseColumn {
|
|
1688
|
+
constructor(schema) {
|
|
1689
|
+
super(schema);
|
|
1690
|
+
this.dataType = "int4";
|
|
1691
|
+
this.data.int = true;
|
|
1692
|
+
this.data.alias = "serial";
|
|
1693
|
+
this.data.parseItem = parseInt;
|
|
1544
1694
|
}
|
|
1545
|
-
|
|
1546
|
-
return
|
|
1547
|
-
}
|
|
1548
|
-
/**
|
|
1549
|
-
* For `tsvector` column type, it can also accept language (optional) and columns:
|
|
1550
|
-
*
|
|
1551
|
-
* ```ts
|
|
1552
|
-
* import { change } from '../dbScript';
|
|
1553
|
-
*
|
|
1554
|
-
* change(async (db) => {
|
|
1555
|
-
* await db.createTable('post', (t) => ({
|
|
1556
|
-
* id: t.id(),
|
|
1557
|
-
* title: t.text(),
|
|
1558
|
-
* body: t.text(),
|
|
1559
|
-
* // join title and body into a single ts_vector
|
|
1560
|
-
* generatedTsVector: t.tsvector().generated(['title', 'body']).searchIndex(),
|
|
1561
|
-
* // with language:
|
|
1562
|
-
* spanishTsVector: t
|
|
1563
|
-
* .tsvector()
|
|
1564
|
-
* .generated('spanish', ['title', 'body'])
|
|
1565
|
-
* .searchIndex(),
|
|
1566
|
-
* }));
|
|
1567
|
-
* });
|
|
1568
|
-
* ```
|
|
1569
|
-
*
|
|
1570
|
-
* @param args
|
|
1571
|
-
*/
|
|
1572
|
-
generated(...args) {
|
|
1573
|
-
const arg = args[0];
|
|
1574
|
-
if (typeof arg === "object" && "raw" in arg) {
|
|
1575
|
-
return super.generated(...args);
|
|
1576
|
-
}
|
|
1577
|
-
const toSQL = (ctx) => {
|
|
1578
|
-
const first = args[0];
|
|
1579
|
-
const target = typeof first === "string" ? args[1] : first;
|
|
1580
|
-
const language = typeof first === "string" ? first : this.defaultLanguage;
|
|
1581
|
-
const { snakeCase } = ctx;
|
|
1582
|
-
let sql;
|
|
1583
|
-
if (Array.isArray(target)) {
|
|
1584
|
-
const columns = target.length === 1 ? `"${snakeCase ? orchidCore.toSnakeCase(target[0]) : target[0]}"` : target.map(
|
|
1585
|
-
(column2) => `coalesce("${snakeCase ? orchidCore.toSnakeCase(column2) : column2}", '')`
|
|
1586
|
-
).join(` || ' ' || `);
|
|
1587
|
-
sql = `to_tsvector('${language}', ${columns})`;
|
|
1588
|
-
} else {
|
|
1589
|
-
for (const key in target) {
|
|
1590
|
-
sql = (sql ? sql + " || " : "(") + `setweight(to_tsvector('${language}', coalesce("${snakeCase ? orchidCore.toSnakeCase(key) : key}", '')), '${target[key]}')`;
|
|
1591
|
-
}
|
|
1592
|
-
if (sql) {
|
|
1593
|
-
sql += ")";
|
|
1594
|
-
} else {
|
|
1595
|
-
throw new Error("Empty target in the text search generated column");
|
|
1596
|
-
}
|
|
1597
|
-
}
|
|
1598
|
-
return sql;
|
|
1599
|
-
};
|
|
1600
|
-
const toCode = () => {
|
|
1601
|
-
let code = ".generated(";
|
|
1602
|
-
const first = args[0];
|
|
1603
|
-
let target;
|
|
1604
|
-
if (typeof first === "string") {
|
|
1605
|
-
code += `'${first}', `;
|
|
1606
|
-
target = args[1];
|
|
1607
|
-
} else {
|
|
1608
|
-
target = args[0];
|
|
1609
|
-
}
|
|
1610
|
-
if (Array.isArray(target)) {
|
|
1611
|
-
code += `[${target.map((x) => `'${x}'`).join(", ")}]`;
|
|
1612
|
-
} else {
|
|
1613
|
-
const pairs = [];
|
|
1614
|
-
for (const key in target) {
|
|
1615
|
-
pairs.push(
|
|
1616
|
-
`${orchidCore.quoteObjectKey(key)}: '${target[key]}'`
|
|
1617
|
-
);
|
|
1618
|
-
}
|
|
1619
|
-
code += `{ ${pairs.join(", ")} }`;
|
|
1620
|
-
}
|
|
1621
|
-
return code + ")";
|
|
1622
|
-
};
|
|
1623
|
-
const column = orchidCore.setColumnData(this, "generated", {
|
|
1624
|
-
toSQL,
|
|
1625
|
-
toCode
|
|
1626
|
-
});
|
|
1627
|
-
column.data.readonly = true;
|
|
1628
|
-
return column;
|
|
1629
|
-
}
|
|
1630
|
-
}
|
|
1631
|
-
class TsQueryColumn extends ColumnType {
|
|
1632
|
-
constructor(schema) {
|
|
1633
|
-
super(schema, schema.stringSchema());
|
|
1634
|
-
this.dataType = "tsquery";
|
|
1635
|
-
this.operators = Operators.text;
|
|
1695
|
+
toSQL() {
|
|
1696
|
+
return "serial";
|
|
1636
1697
|
}
|
|
1637
1698
|
toCode(ctx, key) {
|
|
1638
|
-
return columnCode(
|
|
1699
|
+
return columnCode(
|
|
1700
|
+
this,
|
|
1701
|
+
ctx,
|
|
1702
|
+
key,
|
|
1703
|
+
`serial()${orchidCore.numberDataToCode(
|
|
1704
|
+
this.data,
|
|
1705
|
+
ctx.migration,
|
|
1706
|
+
skipNumberMethods
|
|
1707
|
+
)}`
|
|
1708
|
+
);
|
|
1639
1709
|
}
|
|
1640
1710
|
}
|
|
1641
|
-
|
|
1642
|
-
const uuidDefault = new RawSQL(uuidDefaultSQL);
|
|
1643
|
-
class UUIDColumn extends ColumnType {
|
|
1711
|
+
class BigSerialColumn extends NumberAsStringBaseColumn {
|
|
1644
1712
|
constructor(schema) {
|
|
1645
|
-
super(schema
|
|
1646
|
-
this.dataType = "
|
|
1647
|
-
this.
|
|
1648
|
-
this.data.defaultDefault = uuidDefault;
|
|
1713
|
+
super(schema);
|
|
1714
|
+
this.dataType = "int8";
|
|
1715
|
+
this.data.alias = "bigint";
|
|
1649
1716
|
}
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
*/
|
|
1653
|
-
primaryKey(name) {
|
|
1654
|
-
const column = super.primaryKey(name);
|
|
1655
|
-
if (!column.data.default) column.data.default = uuidDefault;
|
|
1656
|
-
return column;
|
|
1717
|
+
toSQL() {
|
|
1718
|
+
return "bigserial";
|
|
1657
1719
|
}
|
|
1658
1720
|
toCode(ctx, key) {
|
|
1659
|
-
return columnCode(this, ctx, key, `
|
|
1721
|
+
return columnCode(this, ctx, key, `bigSerial()`);
|
|
1660
1722
|
}
|
|
1661
1723
|
}
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1724
|
+
|
|
1725
|
+
const parseDateToDate = (value) => new Date(value);
|
|
1726
|
+
const defaultSchemaConfig = {
|
|
1727
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1728
|
+
parse(fn) {
|
|
1729
|
+
return setColumnParse(this, fn);
|
|
1730
|
+
},
|
|
1731
|
+
parseNull(fn) {
|
|
1732
|
+
return setColumnParseNull(this, fn);
|
|
1733
|
+
},
|
|
1734
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1735
|
+
encode(fn) {
|
|
1736
|
+
return orchidCore.setColumnData(this, "encode", fn);
|
|
1737
|
+
},
|
|
1738
|
+
asType() {
|
|
1739
|
+
return this;
|
|
1740
|
+
},
|
|
1741
|
+
dateAsNumber() {
|
|
1742
|
+
return this.parse(Date.parse);
|
|
1743
|
+
},
|
|
1744
|
+
dateAsDate() {
|
|
1745
|
+
return this.parse(parseDateToDate);
|
|
1746
|
+
},
|
|
1747
|
+
enum(dataType, type) {
|
|
1748
|
+
return new EnumColumn(defaultSchemaConfig, dataType, type, void 0);
|
|
1749
|
+
},
|
|
1750
|
+
array(item) {
|
|
1751
|
+
return new ArrayColumn(defaultSchemaConfig, item, void 0);
|
|
1752
|
+
},
|
|
1753
|
+
boolean: orchidCore.noop,
|
|
1754
|
+
buffer: orchidCore.noop,
|
|
1755
|
+
unknown: orchidCore.noop,
|
|
1756
|
+
never: orchidCore.noop,
|
|
1757
|
+
stringSchema: orchidCore.noop,
|
|
1758
|
+
stringMin: orchidCore.noop,
|
|
1759
|
+
stringMax: orchidCore.noop,
|
|
1760
|
+
stringMinMax: orchidCore.noop,
|
|
1761
|
+
number: orchidCore.noop,
|
|
1762
|
+
int: orchidCore.noop,
|
|
1763
|
+
stringNumberDate: orchidCore.noop,
|
|
1764
|
+
timeInterval: orchidCore.noop,
|
|
1765
|
+
bit: orchidCore.noop,
|
|
1766
|
+
uuid: orchidCore.noop,
|
|
1767
|
+
nullable() {
|
|
1768
|
+
return orchidCore.setColumnData(this, "isNullable", true);
|
|
1769
|
+
},
|
|
1770
|
+
json() {
|
|
1771
|
+
return new JSONColumn(defaultSchemaConfig, void 0);
|
|
1772
|
+
},
|
|
1773
|
+
setErrors: orchidCore.noop,
|
|
1774
|
+
smallint: () => new SmallIntColumn(defaultSchemaConfig),
|
|
1775
|
+
integer: () => new IntegerColumn(defaultSchemaConfig),
|
|
1776
|
+
real: () => new RealColumn(defaultSchemaConfig),
|
|
1777
|
+
smallSerial: () => new SmallSerialColumn(defaultSchemaConfig),
|
|
1778
|
+
serial: () => new SerialColumn(defaultSchemaConfig),
|
|
1779
|
+
bigint: () => new BigIntColumn(defaultSchemaConfig),
|
|
1780
|
+
decimal: (precision, scale) => new DecimalColumn(defaultSchemaConfig, precision, scale),
|
|
1781
|
+
doublePrecision: () => new DoublePrecisionColumn(defaultSchemaConfig),
|
|
1782
|
+
bigSerial: () => new BigSerialColumn(defaultSchemaConfig),
|
|
1783
|
+
money: () => new MoneyColumn(defaultSchemaConfig),
|
|
1784
|
+
varchar: (limit) => new VarCharColumn(defaultSchemaConfig, limit),
|
|
1785
|
+
text: () => new TextColumn(defaultSchemaConfig),
|
|
1786
|
+
string: (limit) => new StringColumn(defaultSchemaConfig, limit),
|
|
1787
|
+
citext: () => new CitextColumn(defaultSchemaConfig),
|
|
1788
|
+
date: () => new DateColumn(defaultSchemaConfig),
|
|
1789
|
+
timestampNoTZ: (precision) => new TimestampColumn(defaultSchemaConfig, precision),
|
|
1790
|
+
timestamp: (precision) => new TimestampTZColumn(defaultSchemaConfig, precision),
|
|
1791
|
+
geographyPointSchema: orchidCore.noop
|
|
1792
|
+
};
|
|
1793
|
+
|
|
1794
|
+
class TextBaseColumn extends ColumnType {
|
|
1795
|
+
constructor(schema, schemaType = schema.stringSchema()) {
|
|
1796
|
+
super(schema, schemaType);
|
|
1666
1797
|
this.operators = Operators.text;
|
|
1667
1798
|
}
|
|
1668
|
-
toCode(ctx, key) {
|
|
1669
|
-
return columnCode(this, ctx, key, `xml()`);
|
|
1670
|
-
}
|
|
1671
|
-
}
|
|
1672
|
-
class CitextColumn extends TextBaseColumn {
|
|
1673
|
-
constructor(schema) {
|
|
1674
|
-
super(schema, schema.stringSchema());
|
|
1675
|
-
this.dataType = "citext";
|
|
1676
|
-
this.data.extension = "citext";
|
|
1677
|
-
}
|
|
1678
|
-
toCode(ctx, key) {
|
|
1679
|
-
return textColumnToCode(this, ctx, key);
|
|
1680
|
-
}
|
|
1681
1799
|
}
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
return typeof input === "number" ? new Date(input) : input;
|
|
1685
|
-
};
|
|
1686
|
-
class DateBaseColumn extends ColumnType {
|
|
1687
|
-
constructor(schema) {
|
|
1800
|
+
class LimitedTextBaseColumn extends TextBaseColumn {
|
|
1801
|
+
constructor(schema, limit) {
|
|
1688
1802
|
super(
|
|
1689
1803
|
schema,
|
|
1690
|
-
schema.
|
|
1691
|
-
|
|
1692
|
-
|
|
1804
|
+
limit !== void 0 ? schema.stringMax(limit) : schema.stringSchema()
|
|
1805
|
+
);
|
|
1806
|
+
this.data.maxChars = limit;
|
|
1807
|
+
}
|
|
1808
|
+
toSQL() {
|
|
1809
|
+
return orchidCore.joinTruthy(
|
|
1810
|
+
this.dataType,
|
|
1811
|
+
this.data.maxChars !== void 0 && `(${this.data.maxChars})`
|
|
1693
1812
|
);
|
|
1694
|
-
this.operators = Operators.date;
|
|
1695
|
-
this.asNumber = schema.dateAsNumber;
|
|
1696
|
-
this.asDate = schema.dateAsDate;
|
|
1697
|
-
this.data.encode = dateTimeEncode;
|
|
1698
1813
|
}
|
|
1699
1814
|
}
|
|
1700
|
-
class
|
|
1815
|
+
class VarCharColumn extends LimitedTextBaseColumn {
|
|
1701
1816
|
constructor() {
|
|
1702
1817
|
super(...arguments);
|
|
1703
|
-
this.dataType = "
|
|
1818
|
+
this.dataType = "varchar";
|
|
1704
1819
|
}
|
|
1705
1820
|
toCode(ctx, key) {
|
|
1821
|
+
const { maxChars } = this.data;
|
|
1706
1822
|
return columnCode(
|
|
1707
1823
|
this,
|
|
1708
1824
|
ctx,
|
|
1709
1825
|
key,
|
|
1710
|
-
`
|
|
1826
|
+
`varchar(${maxChars ?? ""})${orchidCore.stringDataToCode(this.data, ctx.migration)}`
|
|
1711
1827
|
);
|
|
1712
1828
|
}
|
|
1713
1829
|
}
|
|
1714
|
-
class
|
|
1715
|
-
constructor(schema,
|
|
1716
|
-
super(schema);
|
|
1717
|
-
this.data.dateTimePrecision = dateTimePrecision;
|
|
1718
|
-
}
|
|
1719
|
-
toSQL() {
|
|
1720
|
-
return orchidCore.joinTruthy(
|
|
1721
|
-
this.dataType,
|
|
1722
|
-
this.data.dateTimePrecision !== void 0 && `(${this.data.dateTimePrecision})`
|
|
1723
|
-
);
|
|
1830
|
+
class StringColumn extends VarCharColumn {
|
|
1831
|
+
constructor(schema, limit = 255) {
|
|
1832
|
+
super(schema, limit);
|
|
1724
1833
|
}
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
return orchidCore.joinTruthy(
|
|
1729
|
-
this.baseDataType,
|
|
1730
|
-
this.data.dateTimePrecision !== void 0 && `(${this.data.dateTimePrecision})`,
|
|
1731
|
-
" with time zone"
|
|
1732
|
-
);
|
|
1733
|
-
}
|
|
1734
|
-
}
|
|
1735
|
-
const timestampToCode = (self, ctx, key) => {
|
|
1736
|
-
const { dateTimePrecision: p } = self.data;
|
|
1737
|
-
const { defaultTimestamp } = self.data;
|
|
1738
|
-
if (defaultTimestamp) {
|
|
1739
|
-
const noTz = self instanceof TimestampColumn ? "NoTZ" : "";
|
|
1740
|
-
const def = self.data.default;
|
|
1741
|
-
const modifyQuery = self.data.modifyQuery;
|
|
1742
|
-
self.data.default = void 0;
|
|
1743
|
-
self.data.modifyQuery = void 0;
|
|
1744
|
-
const code = columnCode(
|
|
1745
|
-
self,
|
|
1746
|
-
ctx,
|
|
1747
|
-
key,
|
|
1748
|
-
`timestamps${noTz}(${p && p !== 6 ? p : ""}).${defaultTimestamp}${orchidCore.dateDataToCode(self.data, ctx.migration)}`
|
|
1749
|
-
);
|
|
1750
|
-
self.data.default = def;
|
|
1751
|
-
self.data.modifyQuery = modifyQuery;
|
|
1752
|
-
return code;
|
|
1753
|
-
} else {
|
|
1834
|
+
toCode(ctx, key) {
|
|
1835
|
+
let max = this.data.maxChars;
|
|
1836
|
+
if (max === 255) max = void 0;
|
|
1754
1837
|
return columnCode(
|
|
1755
|
-
|
|
1838
|
+
this,
|
|
1756
1839
|
ctx,
|
|
1757
1840
|
key,
|
|
1758
|
-
|
|
1841
|
+
`string(${max ?? ""})${orchidCore.stringDataToCode(this.data, ctx.migration)}`
|
|
1759
1842
|
);
|
|
1760
1843
|
}
|
|
1844
|
+
}
|
|
1845
|
+
const textColumnToCode = (column, ctx, key) => {
|
|
1846
|
+
const data = { ...column.data };
|
|
1847
|
+
let args = "";
|
|
1848
|
+
const hasMax = data.maxArg !== void 0 && data.max === data.maxArg;
|
|
1849
|
+
if (data.minArg !== void 0 && data.min === data.minArg || hasMax) {
|
|
1850
|
+
if (data.minArg !== 0 || hasMax && data.max !== Infinity) {
|
|
1851
|
+
args += data.minArg;
|
|
1852
|
+
}
|
|
1853
|
+
delete data.min;
|
|
1854
|
+
if (hasMax) {
|
|
1855
|
+
if (data.maxArg !== Infinity) {
|
|
1856
|
+
args += `, ${data.maxArg}`;
|
|
1857
|
+
}
|
|
1858
|
+
delete data.max;
|
|
1859
|
+
}
|
|
1860
|
+
}
|
|
1861
|
+
return columnCode(
|
|
1862
|
+
column,
|
|
1863
|
+
ctx,
|
|
1864
|
+
key,
|
|
1865
|
+
`${column.dataType}(${args})${orchidCore.stringDataToCode(data, ctx.migration)}`
|
|
1866
|
+
);
|
|
1761
1867
|
};
|
|
1762
|
-
class
|
|
1763
|
-
constructor() {
|
|
1764
|
-
super(
|
|
1765
|
-
this.dataType = "
|
|
1868
|
+
class TextColumn extends TextBaseColumn {
|
|
1869
|
+
constructor(schema) {
|
|
1870
|
+
super(schema, schema.stringSchema());
|
|
1871
|
+
this.dataType = "text";
|
|
1872
|
+
}
|
|
1873
|
+
static get instance() {
|
|
1874
|
+
return this._instance ?? (this._instance = new TextColumn(defaultSchemaConfig));
|
|
1766
1875
|
}
|
|
1767
1876
|
toCode(ctx, key) {
|
|
1768
|
-
return
|
|
1877
|
+
return textColumnToCode(this, ctx, key);
|
|
1769
1878
|
}
|
|
1770
1879
|
}
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
this.
|
|
1880
|
+
const byteaParse = (val) => typeof val === "string" ? Buffer.from(val.slice(2), "hex") : val;
|
|
1881
|
+
class ByteaColumn extends ColumnType {
|
|
1882
|
+
constructor(schema) {
|
|
1883
|
+
super(schema, schema.buffer());
|
|
1884
|
+
this.dataType = "bytea";
|
|
1885
|
+
this.operators = Operators.text;
|
|
1886
|
+
setColumnDefaultParse(this, byteaParse);
|
|
1776
1887
|
}
|
|
1777
1888
|
toCode(ctx, key) {
|
|
1778
|
-
return
|
|
1889
|
+
return columnCode(this, ctx, key, `bytea()`);
|
|
1779
1890
|
}
|
|
1780
1891
|
}
|
|
1781
|
-
class
|
|
1782
|
-
constructor(schema
|
|
1892
|
+
class PointColumn extends ColumnType {
|
|
1893
|
+
constructor(schema) {
|
|
1783
1894
|
super(schema, schema.stringSchema());
|
|
1784
|
-
this.dataType = "
|
|
1785
|
-
this.operators = Operators.
|
|
1786
|
-
this.data.dateTimePrecision = dateTimePrecision;
|
|
1895
|
+
this.dataType = "point";
|
|
1896
|
+
this.operators = Operators.text;
|
|
1787
1897
|
}
|
|
1788
1898
|
toCode(ctx, key) {
|
|
1789
|
-
|
|
1790
|
-
return columnCode(
|
|
1791
|
-
this,
|
|
1792
|
-
ctx,
|
|
1793
|
-
key,
|
|
1794
|
-
`time(${dateTimePrecision || ""})${orchidCore.dateDataToCode(
|
|
1795
|
-
this.data,
|
|
1796
|
-
ctx.migration
|
|
1797
|
-
)}`
|
|
1798
|
-
);
|
|
1899
|
+
return columnCode(this, ctx, key, `point()`);
|
|
1799
1900
|
}
|
|
1800
1901
|
}
|
|
1801
|
-
class
|
|
1802
|
-
constructor(schema
|
|
1803
|
-
super(schema, schema.
|
|
1804
|
-
this.dataType = "
|
|
1805
|
-
this.operators = Operators.
|
|
1806
|
-
this.data.fields = fields;
|
|
1807
|
-
this.data.precision = precision;
|
|
1902
|
+
class LineColumn extends ColumnType {
|
|
1903
|
+
constructor(schema) {
|
|
1904
|
+
super(schema, schema.stringSchema());
|
|
1905
|
+
this.dataType = "line";
|
|
1906
|
+
this.operators = Operators.text;
|
|
1808
1907
|
}
|
|
1809
1908
|
toCode(ctx, key) {
|
|
1810
|
-
|
|
1811
|
-
return columnCode(
|
|
1812
|
-
this,
|
|
1813
|
-
ctx,
|
|
1814
|
-
key,
|
|
1815
|
-
`interval(${[fields && `'${fields}'`, precision && String(precision)].filter((part) => part).join(", ")})`
|
|
1816
|
-
);
|
|
1817
|
-
}
|
|
1818
|
-
toSQL() {
|
|
1819
|
-
return orchidCore.joinTruthy(
|
|
1820
|
-
this.dataType,
|
|
1821
|
-
this.data.fields && ` ${this.data.fields}`,
|
|
1822
|
-
this.data.precision !== void 0 && ` (${this.data.precision})`
|
|
1823
|
-
);
|
|
1909
|
+
return columnCode(this, ctx, key, `line()`);
|
|
1824
1910
|
}
|
|
1825
1911
|
}
|
|
1826
|
-
|
|
1827
|
-
class BooleanColumn extends ColumnType {
|
|
1912
|
+
class LsegColumn extends ColumnType {
|
|
1828
1913
|
constructor(schema) {
|
|
1829
|
-
super(schema, schema.
|
|
1830
|
-
this.dataType = "
|
|
1831
|
-
this.operators = Operators.
|
|
1832
|
-
this.data.alias = "boolean";
|
|
1833
|
-
this.data.parseItem = parseItem;
|
|
1914
|
+
super(schema, schema.stringSchema());
|
|
1915
|
+
this.dataType = "lseg";
|
|
1916
|
+
this.operators = Operators.text;
|
|
1834
1917
|
}
|
|
1835
1918
|
toCode(ctx, key) {
|
|
1836
|
-
return columnCode(this, ctx, key,
|
|
1919
|
+
return columnCode(this, ctx, key, `lseg()`);
|
|
1837
1920
|
}
|
|
1838
1921
|
}
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
super(schema, inputType);
|
|
1845
|
-
this.dataType = "jsonb";
|
|
1846
|
-
this.operators = Operators.json;
|
|
1847
|
-
this.data.encode = encode$1;
|
|
1848
|
-
this.data.parseItem = JSON.parse;
|
|
1922
|
+
class BoxColumn extends ColumnType {
|
|
1923
|
+
constructor(schema) {
|
|
1924
|
+
super(schema, schema.stringSchema());
|
|
1925
|
+
this.dataType = "box";
|
|
1926
|
+
this.operators = Operators.text;
|
|
1849
1927
|
}
|
|
1850
1928
|
toCode(ctx, key) {
|
|
1851
|
-
return columnCode(this, ctx, key, `
|
|
1929
|
+
return columnCode(this, ctx, key, `box()`);
|
|
1852
1930
|
}
|
|
1853
1931
|
}
|
|
1854
|
-
class
|
|
1932
|
+
class PathColumn extends ColumnType {
|
|
1855
1933
|
constructor(schema) {
|
|
1856
1934
|
super(schema, schema.stringSchema());
|
|
1857
|
-
this.dataType = "
|
|
1935
|
+
this.dataType = "path";
|
|
1858
1936
|
this.operators = Operators.text;
|
|
1859
1937
|
}
|
|
1860
1938
|
toCode(ctx, key) {
|
|
1861
|
-
return columnCode(this, ctx, key, `
|
|
1939
|
+
return columnCode(this, ctx, key, `path()`);
|
|
1862
1940
|
}
|
|
1863
1941
|
}
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
1870
|
-
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
1871
|
-
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), member.set(obj, value), value);
|
|
1872
|
-
var _query, _query2;
|
|
1873
|
-
class OrchidOrmError extends Error {
|
|
1874
|
-
}
|
|
1875
|
-
class NotFoundError extends OrchidOrmError {
|
|
1876
|
-
constructor(query, message = "Record is not found") {
|
|
1877
|
-
super(message);
|
|
1878
|
-
// `#query` is private to prevent it from serializing to not cause problems to test runner reports
|
|
1879
|
-
__privateAdd(this, _query);
|
|
1880
|
-
__privateSet(this, _query, query);
|
|
1942
|
+
class PolygonColumn extends ColumnType {
|
|
1943
|
+
constructor(schema) {
|
|
1944
|
+
super(schema, schema.stringSchema());
|
|
1945
|
+
this.dataType = "polygon";
|
|
1946
|
+
this.operators = Operators.text;
|
|
1881
1947
|
}
|
|
1882
|
-
|
|
1883
|
-
return
|
|
1948
|
+
toCode(ctx, key) {
|
|
1949
|
+
return columnCode(this, ctx, key, `polygon()`);
|
|
1884
1950
|
}
|
|
1885
1951
|
}
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
__privateAdd(this, _query2);
|
|
1892
|
-
__privateSet(this, _query2, query);
|
|
1952
|
+
class CircleColumn extends ColumnType {
|
|
1953
|
+
constructor(schema) {
|
|
1954
|
+
super(schema, schema.stringSchema());
|
|
1955
|
+
this.dataType = "circle";
|
|
1956
|
+
this.operators = Operators.text;
|
|
1893
1957
|
}
|
|
1894
|
-
|
|
1895
|
-
return
|
|
1958
|
+
toCode(ctx, key) {
|
|
1959
|
+
return columnCode(this, ctx, key, `circle()`);
|
|
1896
1960
|
}
|
|
1897
1961
|
}
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1962
|
+
class MoneyColumn extends ColumnType {
|
|
1963
|
+
constructor(schema) {
|
|
1964
|
+
super(schema, schema.number());
|
|
1965
|
+
this.dataType = "money";
|
|
1966
|
+
this.operators = Operators.number;
|
|
1967
|
+
setColumnDefaultParse(this, moneyParse);
|
|
1902
1968
|
}
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
const columns = {};
|
|
1906
|
-
if (this.detail) {
|
|
1907
|
-
const list = this.detail.match(/\((.*)\)=/)?.[1];
|
|
1908
|
-
if (list) {
|
|
1909
|
-
list.split(", ").forEach((item) => {
|
|
1910
|
-
const column = item.startsWith('"') ? item.slice(1, -1) : item;
|
|
1911
|
-
const key = this.query.columnNameToKey(column) ?? column;
|
|
1912
|
-
columns[key] = true;
|
|
1913
|
-
});
|
|
1914
|
-
}
|
|
1915
|
-
}
|
|
1916
|
-
return this.columnsCache = columns;
|
|
1969
|
+
toCode(ctx, key) {
|
|
1970
|
+
return columnCode(this, ctx, key, `money()`);
|
|
1917
1971
|
}
|
|
1918
1972
|
}
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1973
|
+
const moneyParse = Object.assign(
|
|
1974
|
+
function(input) {
|
|
1975
|
+
return input === null ? input : parseFloat(input.replace(/,/g, "").replace(/\$/g, ""));
|
|
1976
|
+
},
|
|
1977
|
+
{
|
|
1978
|
+
hideFromCode: true
|
|
1922
1979
|
}
|
|
1923
|
-
|
|
1924
|
-
class
|
|
1925
|
-
constructor(
|
|
1926
|
-
super(
|
|
1980
|
+
);
|
|
1981
|
+
class CidrColumn extends ColumnType {
|
|
1982
|
+
constructor(schema) {
|
|
1983
|
+
super(schema, schema.stringSchema());
|
|
1984
|
+
this.dataType = "cidr";
|
|
1985
|
+
this.operators = Operators.text;
|
|
1986
|
+
}
|
|
1987
|
+
toCode(ctx, key) {
|
|
1988
|
+
return columnCode(this, ctx, key, `cidr()`);
|
|
1927
1989
|
}
|
|
1928
1990
|
}
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
return q;
|
|
1935
|
-
};
|
|
1936
|
-
const pushQueryValueImmutable = (q, key, value) => {
|
|
1937
|
-
orchidCore.pushOrNewArrayToObjectImmutable(q.q, key, value);
|
|
1938
|
-
return q;
|
|
1939
|
-
};
|
|
1940
|
-
const setQueryObjectValueImmutable = (q, object, key, value) => {
|
|
1941
|
-
q.q[object] = {
|
|
1942
|
-
...q.q[object],
|
|
1943
|
-
[key]: value
|
|
1944
|
-
};
|
|
1945
|
-
return q;
|
|
1946
|
-
};
|
|
1947
|
-
const throwIfNoWhere = (q, method) => {
|
|
1948
|
-
if (!q.q.or && !q.q.and && !q.q.scopes && !q.q.all) {
|
|
1949
|
-
throw new OrchidOrmInternalError(
|
|
1950
|
-
q,
|
|
1951
|
-
`Dangerous ${method} without conditions`
|
|
1952
|
-
);
|
|
1953
|
-
}
|
|
1954
|
-
};
|
|
1955
|
-
const throwIfJoinLateral = (q, method) => {
|
|
1956
|
-
if (q.q.join?.some(
|
|
1957
|
-
(x) => Array.isArray(x) || "s" in x.args && x.args.s
|
|
1958
|
-
)) {
|
|
1959
|
-
throw new OrchidOrmInternalError(
|
|
1960
|
-
q,
|
|
1961
|
-
`Cannot join a complex query in ${method}`
|
|
1962
|
-
);
|
|
1991
|
+
class InetColumn extends ColumnType {
|
|
1992
|
+
constructor(schema) {
|
|
1993
|
+
super(schema, schema.stringSchema());
|
|
1994
|
+
this.dataType = "inet";
|
|
1995
|
+
this.operators = Operators.text;
|
|
1963
1996
|
}
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
const shapes = q.q[key];
|
|
1967
|
-
if (shapes?.[as]) {
|
|
1968
|
-
let suffix = 2;
|
|
1969
|
-
while (shapes[as = `${as}${suffix}`]) {
|
|
1970
|
-
suffix++;
|
|
1971
|
-
}
|
|
1997
|
+
toCode(ctx, key) {
|
|
1998
|
+
return columnCode(this, ctx, key, `inet()`);
|
|
1972
1999
|
}
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
Object.assign(base, methods);
|
|
1980
|
-
const cloned = Object.create(base);
|
|
1981
|
-
cloned.q = getClonedQueryData(q.q);
|
|
1982
|
-
return cloned;
|
|
1983
|
-
};
|
|
1984
|
-
const getPrimaryKeys = (q) => {
|
|
1985
|
-
var _a;
|
|
1986
|
-
return (_a = q.internal).primaryKeys ?? (_a.primaryKeys = collectPrimaryKeys(q));
|
|
1987
|
-
};
|
|
1988
|
-
const collectPrimaryKeys = (q) => {
|
|
1989
|
-
const primaryKeys = [];
|
|
1990
|
-
const { shape } = q.q;
|
|
1991
|
-
for (const key in shape) {
|
|
1992
|
-
if (shape[key].data.primaryKey) {
|
|
1993
|
-
primaryKeys.push(key);
|
|
1994
|
-
}
|
|
2000
|
+
}
|
|
2001
|
+
class MacAddrColumn extends ColumnType {
|
|
2002
|
+
constructor(schema) {
|
|
2003
|
+
super(schema, schema.stringSchema());
|
|
2004
|
+
this.dataType = "macaddr";
|
|
2005
|
+
this.operators = Operators.text;
|
|
1995
2006
|
}
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
primaryKeys.push(...pkey.columns);
|
|
2007
|
+
toCode(ctx, key) {
|
|
2008
|
+
return columnCode(this, ctx, key, `macaddr()`);
|
|
1999
2009
|
}
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
};
|
|
2007
|
-
const _queryTake = (query) => {
|
|
2008
|
-
const q = query.q;
|
|
2009
|
-
switch (q.returnType) {
|
|
2010
|
-
case "valueOrThrow":
|
|
2011
|
-
case "pluck":
|
|
2012
|
-
case "void":
|
|
2013
|
-
break;
|
|
2014
|
-
case "value": {
|
|
2015
|
-
q.returnType = "valueOrThrow";
|
|
2016
|
-
break;
|
|
2017
|
-
}
|
|
2018
|
-
default: {
|
|
2019
|
-
q.returnType = "oneOrThrow";
|
|
2020
|
-
}
|
|
2010
|
+
}
|
|
2011
|
+
class MacAddr8Column extends ColumnType {
|
|
2012
|
+
constructor(schema) {
|
|
2013
|
+
super(schema, schema.stringSchema());
|
|
2014
|
+
this.dataType = "macaddr8";
|
|
2015
|
+
this.operators = Operators.text;
|
|
2021
2016
|
}
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
const _queryTakeOptional = (query) => {
|
|
2025
|
-
const q = query.q;
|
|
2026
|
-
switch (q.returnType) {
|
|
2027
|
-
case "value":
|
|
2028
|
-
case "pluck":
|
|
2029
|
-
case "void":
|
|
2030
|
-
break;
|
|
2031
|
-
case "valueOrThrow": {
|
|
2032
|
-
q.returnType = "value";
|
|
2033
|
-
break;
|
|
2034
|
-
}
|
|
2035
|
-
default: {
|
|
2036
|
-
q.returnType = "one";
|
|
2037
|
-
}
|
|
2017
|
+
toCode(ctx, key) {
|
|
2018
|
+
return columnCode(this, ctx, key, `macaddr8()`);
|
|
2038
2019
|
}
|
|
2039
|
-
return query;
|
|
2040
|
-
};
|
|
2041
|
-
const _queryExec = (q) => {
|
|
2042
|
-
q.q.returnType = "void";
|
|
2043
|
-
return q;
|
|
2044
|
-
};
|
|
2045
|
-
const _queryRows = (q) => {
|
|
2046
|
-
q.q.returnType = "rows";
|
|
2047
|
-
return q;
|
|
2048
|
-
};
|
|
2049
|
-
const getFullColumnTable = (q, column, index, as) => {
|
|
2050
|
-
const table = column.slice(0, index);
|
|
2051
|
-
return as && table !== as && q.q.aliases?.[table] === as ? as : table;
|
|
2052
|
-
};
|
|
2053
|
-
|
|
2054
|
-
function simpleColumnToSQL(ctx, key, column, quotedAs) {
|
|
2055
|
-
if (!column) return `"${key}"`;
|
|
2056
|
-
const { data } = column;
|
|
2057
|
-
return data.computed ? data.computed.toSQL(ctx, quotedAs) : `${quotedAs ? `${quotedAs}.` : ""}"${data.name || key}"`;
|
|
2058
2020
|
}
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
if (index !== -1) {
|
|
2066
|
-
return columnWithDotToSql(
|
|
2067
|
-
ctx,
|
|
2068
|
-
data,
|
|
2069
|
-
shape,
|
|
2070
|
-
column,
|
|
2071
|
-
index,
|
|
2072
|
-
quotedAs,
|
|
2073
|
-
select
|
|
2074
|
-
);
|
|
2021
|
+
class BitColumn extends ColumnType {
|
|
2022
|
+
constructor(schema, length) {
|
|
2023
|
+
super(schema, schema.bit(length));
|
|
2024
|
+
this.dataType = "bit";
|
|
2025
|
+
this.operators = Operators.text;
|
|
2026
|
+
this.data.length = length;
|
|
2075
2027
|
}
|
|
2076
|
-
|
|
2077
|
-
|
|
2028
|
+
toCode(ctx, key) {
|
|
2029
|
+
const { length } = this.data;
|
|
2030
|
+
return columnCode(this, ctx, key, `bit(${length})`);
|
|
2078
2031
|
}
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
return columnWithDotToSql(ctx, data, data.shape, column, index, quotedAs);
|
|
2085
|
-
} else {
|
|
2086
|
-
if (data.joinedShapes?.[column]) {
|
|
2087
|
-
return `"${column}".r`;
|
|
2088
|
-
}
|
|
2089
|
-
if (data.select) {
|
|
2090
|
-
for (const s of data.select) {
|
|
2091
|
-
if (typeof s === "object" && "selectAs" in s) {
|
|
2092
|
-
if (column in s.selectAs) {
|
|
2093
|
-
return simpleColumnToSQL(ctx, column, data.shape[column]);
|
|
2094
|
-
}
|
|
2095
|
-
}
|
|
2096
|
-
}
|
|
2097
|
-
}
|
|
2098
|
-
return simpleColumnToSQL(ctx, column, data.shape[column], quotedAs);
|
|
2032
|
+
toSQL() {
|
|
2033
|
+
return orchidCore.joinTruthy(
|
|
2034
|
+
this.dataType,
|
|
2035
|
+
this.data.length !== void 0 && `(${this.data.length})`
|
|
2036
|
+
);
|
|
2099
2037
|
}
|
|
2100
|
-
}
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2038
|
+
}
|
|
2039
|
+
class BitVaryingColumn extends ColumnType {
|
|
2040
|
+
constructor(schema, length) {
|
|
2041
|
+
super(schema, schema.bit(length));
|
|
2042
|
+
this.dataType = "varbit";
|
|
2043
|
+
this.operators = Operators.text;
|
|
2044
|
+
this.data.length = length;
|
|
2045
|
+
this.data.alias = "bitVarying";
|
|
2107
2046
|
}
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
if (col) {
|
|
2112
|
-
if (col.data.name) {
|
|
2113
|
-
return `"${tableName}"."${col.data.name}"`;
|
|
2114
|
-
}
|
|
2115
|
-
if (col.data.computed) {
|
|
2116
|
-
return col.data.computed.toSQL(ctx, quoted);
|
|
2117
|
-
}
|
|
2118
|
-
return `"${tableName}"."${key}"`;
|
|
2047
|
+
toCode(ctx, key) {
|
|
2048
|
+
const { length } = this.data;
|
|
2049
|
+
return columnCode(this, ctx, key, `bitVarying(${length ?? ""})`);
|
|
2119
2050
|
}
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
ctx,
|
|
2126
|
-
data,
|
|
2127
|
-
column,
|
|
2128
|
-
column.slice(0, index),
|
|
2129
|
-
column.slice(index + 1),
|
|
2130
|
-
as,
|
|
2131
|
-
quotedAs,
|
|
2132
|
-
select,
|
|
2133
|
-
jsonList
|
|
2134
|
-
) : ownColumnToSqlWithAs(ctx, data, column, as, quotedAs, select, jsonList);
|
|
2135
|
-
};
|
|
2136
|
-
const tableColumnToSqlWithAs = (ctx, data, column, table, key, as, quotedAs, select, jsonList) => {
|
|
2137
|
-
if (key === "*") {
|
|
2138
|
-
if (jsonList) jsonList[as] = void 0;
|
|
2139
|
-
const shape = data.joinedShapes?.[table];
|
|
2140
|
-
if (shape) {
|
|
2141
|
-
{
|
|
2142
|
-
return makeRowToJson(table, shape, true) + ` "${as}"`;
|
|
2143
|
-
}
|
|
2144
|
-
}
|
|
2145
|
-
return column;
|
|
2051
|
+
toSQL() {
|
|
2052
|
+
return orchidCore.joinTruthy(
|
|
2053
|
+
this.dataType,
|
|
2054
|
+
this.data.length !== void 0 && `(${this.data.length})`
|
|
2055
|
+
);
|
|
2146
2056
|
}
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2057
|
+
}
|
|
2058
|
+
class TsVectorColumn extends ColumnType {
|
|
2059
|
+
constructor(schema, defaultLanguage = orchidCore.getDefaultLanguage()) {
|
|
2060
|
+
super(schema, schema.stringSchema());
|
|
2061
|
+
this.defaultLanguage = defaultLanguage;
|
|
2062
|
+
this.dataType = "tsvector";
|
|
2063
|
+
this.operators = Operators.text;
|
|
2064
|
+
}
|
|
2065
|
+
toCode(ctx, key) {
|
|
2066
|
+
return columnCode(this, ctx, key, `tsvector()`);
|
|
2067
|
+
}
|
|
2068
|
+
/**
|
|
2069
|
+
* For `tsvector` column type, it can also accept language (optional) and columns:
|
|
2070
|
+
*
|
|
2071
|
+
* ```ts
|
|
2072
|
+
* import { change } from '../dbScript';
|
|
2073
|
+
*
|
|
2074
|
+
* change(async (db) => {
|
|
2075
|
+
* await db.createTable('post', (t) => ({
|
|
2076
|
+
* id: t.id(),
|
|
2077
|
+
* title: t.text(),
|
|
2078
|
+
* body: t.text(),
|
|
2079
|
+
* // join title and body into a single ts_vector
|
|
2080
|
+
* generatedTsVector: t.tsvector().generated(['title', 'body']).searchIndex(),
|
|
2081
|
+
* // with language:
|
|
2082
|
+
* spanishTsVector: t
|
|
2083
|
+
* .tsvector()
|
|
2084
|
+
* .generated('spanish', ['title', 'body'])
|
|
2085
|
+
* .searchIndex(),
|
|
2086
|
+
* }));
|
|
2087
|
+
* });
|
|
2088
|
+
* ```
|
|
2089
|
+
*
|
|
2090
|
+
* @param args
|
|
2091
|
+
*/
|
|
2092
|
+
generated(...args) {
|
|
2093
|
+
const arg = args[0];
|
|
2094
|
+
if (typeof arg === "object" && "raw" in arg) {
|
|
2095
|
+
return super.generated(...args);
|
|
2157
2096
|
}
|
|
2097
|
+
const toSQL = (ctx) => {
|
|
2098
|
+
const first = args[0];
|
|
2099
|
+
const target = typeof first === "string" ? args[1] : first;
|
|
2100
|
+
const language = typeof first === "string" ? first : this.defaultLanguage;
|
|
2101
|
+
const { snakeCase } = ctx;
|
|
2102
|
+
let sql;
|
|
2103
|
+
if (Array.isArray(target)) {
|
|
2104
|
+
const columns = target.length === 1 ? `"${snakeCase ? orchidCore.toSnakeCase(target[0]) : target[0]}"` : target.map(
|
|
2105
|
+
(column2) => `coalesce("${snakeCase ? orchidCore.toSnakeCase(column2) : column2}", '')`
|
|
2106
|
+
).join(` || ' ' || `);
|
|
2107
|
+
sql = `to_tsvector('${language}', ${columns})`;
|
|
2108
|
+
} else {
|
|
2109
|
+
for (const key in target) {
|
|
2110
|
+
sql = (sql ? sql + " || " : "(") + `setweight(to_tsvector('${language}', coalesce("${snakeCase ? orchidCore.toSnakeCase(key) : key}", '')), '${target[key]}')`;
|
|
2111
|
+
}
|
|
2112
|
+
if (sql) {
|
|
2113
|
+
sql += ")";
|
|
2114
|
+
} else {
|
|
2115
|
+
throw new Error("Empty target in the text search generated column");
|
|
2116
|
+
}
|
|
2117
|
+
}
|
|
2118
|
+
return sql;
|
|
2119
|
+
};
|
|
2120
|
+
const toCode = () => {
|
|
2121
|
+
let code = ".generated(";
|
|
2122
|
+
const first = args[0];
|
|
2123
|
+
let target;
|
|
2124
|
+
if (typeof first === "string") {
|
|
2125
|
+
code += `'${first}', `;
|
|
2126
|
+
target = args[1];
|
|
2127
|
+
} else {
|
|
2128
|
+
target = args[0];
|
|
2129
|
+
}
|
|
2130
|
+
if (Array.isArray(target)) {
|
|
2131
|
+
code += `[${target.map((x) => `'${x}'`).join(", ")}]`;
|
|
2132
|
+
} else {
|
|
2133
|
+
const pairs = [];
|
|
2134
|
+
for (const key in target) {
|
|
2135
|
+
pairs.push(
|
|
2136
|
+
`${orchidCore.quoteObjectKey(key)}: '${target[key]}'`
|
|
2137
|
+
);
|
|
2138
|
+
}
|
|
2139
|
+
code += `{ ${pairs.join(", ")} }`;
|
|
2140
|
+
}
|
|
2141
|
+
return code + ")";
|
|
2142
|
+
};
|
|
2143
|
+
const column = orchidCore.setColumnData(this, "generated", {
|
|
2144
|
+
toSQL,
|
|
2145
|
+
toCode
|
|
2146
|
+
});
|
|
2147
|
+
column.data.readonly = true;
|
|
2148
|
+
return column;
|
|
2158
2149
|
}
|
|
2159
|
-
|
|
2150
|
+
}
|
|
2151
|
+
class TsQueryColumn extends ColumnType {
|
|
2152
|
+
constructor(schema) {
|
|
2153
|
+
super(schema, schema.stringSchema());
|
|
2154
|
+
this.dataType = "tsquery";
|
|
2155
|
+
this.operators = Operators.text;
|
|
2156
|
+
}
|
|
2157
|
+
toCode(ctx, key) {
|
|
2158
|
+
return columnCode(this, ctx, key, `tsquery()`);
|
|
2159
|
+
}
|
|
2160
|
+
}
|
|
2161
|
+
const uuidDefaultSQL = "gen_random_uuid()";
|
|
2162
|
+
const uuidDefault = new RawSQL(uuidDefaultSQL);
|
|
2163
|
+
class UUIDColumn extends ColumnType {
|
|
2164
|
+
constructor(schema) {
|
|
2165
|
+
super(schema, schema.uuid());
|
|
2166
|
+
this.dataType = "uuid";
|
|
2167
|
+
this.operators = Operators.text;
|
|
2168
|
+
this.data.defaultDefault = uuidDefault;
|
|
2169
|
+
}
|
|
2170
|
+
/**
|
|
2171
|
+
* see {@link ColumnType.primaryKey}
|
|
2172
|
+
*/
|
|
2173
|
+
primaryKey(name) {
|
|
2174
|
+
const column = super.primaryKey(name);
|
|
2175
|
+
if (!column.data.default) column.data.default = uuidDefault;
|
|
2176
|
+
return column;
|
|
2177
|
+
}
|
|
2178
|
+
toCode(ctx, key) {
|
|
2179
|
+
return columnCode(this, ctx, key, `uuid()`);
|
|
2180
|
+
}
|
|
2181
|
+
}
|
|
2182
|
+
class XMLColumn extends ColumnType {
|
|
2183
|
+
constructor(schema) {
|
|
2184
|
+
super(schema, schema.stringSchema());
|
|
2185
|
+
this.dataType = "xml";
|
|
2186
|
+
this.operators = Operators.text;
|
|
2187
|
+
}
|
|
2188
|
+
static get instance() {
|
|
2189
|
+
return this._instance ?? (this._instance = new XMLColumn(defaultSchemaConfig));
|
|
2190
|
+
}
|
|
2191
|
+
toCode(ctx, key) {
|
|
2192
|
+
return columnCode(this, ctx, key, `xml()`);
|
|
2193
|
+
}
|
|
2194
|
+
}
|
|
2195
|
+
class CitextColumn extends TextBaseColumn {
|
|
2196
|
+
constructor(schema) {
|
|
2197
|
+
super(schema, schema.stringSchema());
|
|
2198
|
+
this.dataType = "citext";
|
|
2199
|
+
this.data.extension = "citext";
|
|
2200
|
+
}
|
|
2201
|
+
toCode(ctx, key) {
|
|
2202
|
+
return textColumnToCode(this, ctx, key);
|
|
2203
|
+
}
|
|
2204
|
+
}
|
|
2205
|
+
|
|
2206
|
+
class BooleanColumn extends ColumnType {
|
|
2207
|
+
constructor(schema) {
|
|
2208
|
+
super(schema, schema.boolean());
|
|
2209
|
+
this.dataType = "bool";
|
|
2210
|
+
this.operators = Operators.boolean;
|
|
2211
|
+
this.data.alias = "boolean";
|
|
2212
|
+
this.data.parseItem = parseItem;
|
|
2213
|
+
}
|
|
2214
|
+
static get instance() {
|
|
2215
|
+
return this._instance ?? (this._instance = new BooleanColumn(defaultSchemaConfig));
|
|
2216
|
+
}
|
|
2217
|
+
toCode(ctx, key) {
|
|
2218
|
+
return columnCode(this, ctx, key, "boolean()");
|
|
2219
|
+
}
|
|
2220
|
+
}
|
|
2221
|
+
const parseItem = (input) => input[0] === "t";
|
|
2222
|
+
|
|
2223
|
+
var __typeError = (msg) => {
|
|
2224
|
+
throw TypeError(msg);
|
|
2160
2225
|
};
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2226
|
+
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
|
|
2227
|
+
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
2228
|
+
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
2229
|
+
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), member.set(obj, value), value);
|
|
2230
|
+
var _query, _query2;
|
|
2231
|
+
class OrchidOrmError extends Error {
|
|
2232
|
+
}
|
|
2233
|
+
class NotFoundError extends OrchidOrmError {
|
|
2234
|
+
constructor(query, message = "Record is not found") {
|
|
2235
|
+
super(message);
|
|
2236
|
+
// `#query` is private to prevent it from serializing to not cause problems to test runner reports
|
|
2237
|
+
__privateAdd(this, _query);
|
|
2238
|
+
__privateSet(this, _query, query);
|
|
2239
|
+
}
|
|
2240
|
+
get query() {
|
|
2241
|
+
return __privateGet(this, _query);
|
|
2242
|
+
}
|
|
2243
|
+
}
|
|
2244
|
+
_query = new WeakMap();
|
|
2245
|
+
class OrchidOrmInternalError extends Error {
|
|
2246
|
+
constructor(query, message) {
|
|
2247
|
+
super(message);
|
|
2248
|
+
// `#query` is private to prevent it from serializing to not cause problems to test runner reports
|
|
2249
|
+
__privateAdd(this, _query2);
|
|
2250
|
+
__privateSet(this, _query2, query);
|
|
2251
|
+
}
|
|
2252
|
+
get query() {
|
|
2253
|
+
return __privateGet(this, _query2);
|
|
2254
|
+
}
|
|
2255
|
+
}
|
|
2256
|
+
_query2 = new WeakMap();
|
|
2257
|
+
class QueryError extends OrchidOrmInternalError {
|
|
2258
|
+
get isUnique() {
|
|
2259
|
+
return this.code === "23505";
|
|
2260
|
+
}
|
|
2261
|
+
get columns() {
|
|
2262
|
+
if (this.columnsCache) return this.columnsCache;
|
|
2263
|
+
const columns = {};
|
|
2264
|
+
if (this.detail) {
|
|
2265
|
+
const list = this.detail.match(/\((.*)\)=/)?.[1];
|
|
2266
|
+
if (list) {
|
|
2267
|
+
list.split(", ").forEach((item) => {
|
|
2268
|
+
const column = item.startsWith('"') ? item.slice(1, -1) : item;
|
|
2269
|
+
const key = this.query.columnNameToKey(column) ?? column;
|
|
2270
|
+
columns[key] = true;
|
|
2271
|
+
});
|
|
2272
|
+
}
|
|
2167
2273
|
}
|
|
2168
|
-
|
|
2169
|
-
|
|
2274
|
+
return this.columnsCache = columns;
|
|
2275
|
+
}
|
|
2276
|
+
}
|
|
2277
|
+
class MoreThanOneRowError extends OrchidOrmInternalError {
|
|
2278
|
+
constructor(query, message) {
|
|
2279
|
+
super(query, message);
|
|
2280
|
+
}
|
|
2281
|
+
}
|
|
2282
|
+
class UnhandledTypeError extends OrchidOrmInternalError {
|
|
2283
|
+
constructor(query, value) {
|
|
2284
|
+
super(query, `Unhandled type: ${JSON.stringify(value)} received`);
|
|
2285
|
+
}
|
|
2286
|
+
}
|
|
2287
|
+
|
|
2288
|
+
const _clone = (q) => q.clone();
|
|
2289
|
+
const pushQueryArrayImmutable = (q, key, value) => {
|
|
2290
|
+
const arr = q.q[key];
|
|
2291
|
+
q.q[key] = arr ? [...arr, ...value] : value;
|
|
2292
|
+
return q;
|
|
2293
|
+
};
|
|
2294
|
+
const pushQueryValueImmutable = (q, key, value) => {
|
|
2295
|
+
orchidCore.pushOrNewArrayToObjectImmutable(q.q, key, value);
|
|
2296
|
+
return q;
|
|
2297
|
+
};
|
|
2298
|
+
const setQueryObjectValueImmutable = (q, object, key, value) => {
|
|
2299
|
+
q.q[object] = {
|
|
2300
|
+
...q.q[object],
|
|
2301
|
+
[key]: value
|
|
2302
|
+
};
|
|
2303
|
+
return q;
|
|
2304
|
+
};
|
|
2305
|
+
const throwIfNoWhere = (q, method) => {
|
|
2306
|
+
if (!q.q.or && !q.q.and && !q.q.scopes && !q.q.all) {
|
|
2307
|
+
throw new OrchidOrmInternalError(
|
|
2308
|
+
q,
|
|
2309
|
+
`Dangerous ${method} without conditions`
|
|
2310
|
+
);
|
|
2311
|
+
}
|
|
2312
|
+
};
|
|
2313
|
+
const throwIfJoinLateral = (q, method) => {
|
|
2314
|
+
if (q.q.join?.some(
|
|
2315
|
+
(x) => Array.isArray(x) || "s" in x.args && x.args.s
|
|
2316
|
+
)) {
|
|
2317
|
+
throw new OrchidOrmInternalError(
|
|
2318
|
+
q,
|
|
2319
|
+
`Cannot join a complex query in ${method}`
|
|
2320
|
+
);
|
|
2321
|
+
}
|
|
2322
|
+
};
|
|
2323
|
+
const saveSearchAlias = (q, as, key) => {
|
|
2324
|
+
const shapes = q.q[key];
|
|
2325
|
+
if (shapes?.[as]) {
|
|
2326
|
+
let suffix = 2;
|
|
2327
|
+
while (shapes[as = `${as}${suffix}`]) {
|
|
2328
|
+
suffix++;
|
|
2170
2329
|
}
|
|
2171
2330
|
}
|
|
2172
|
-
|
|
2331
|
+
setQueryObjectValueImmutable(q, key, as, orchidCore.emptyObject);
|
|
2332
|
+
return as;
|
|
2173
2333
|
};
|
|
2174
|
-
const
|
|
2175
|
-
|
|
2334
|
+
const extendQuery = (q, methods) => {
|
|
2335
|
+
const base = Object.create(q.baseQuery);
|
|
2336
|
+
base.baseQuery = base;
|
|
2337
|
+
Object.assign(base, methods);
|
|
2338
|
+
const cloned = Object.create(base);
|
|
2339
|
+
cloned.q = getClonedQueryData(q.q);
|
|
2340
|
+
return cloned;
|
|
2176
2341
|
};
|
|
2177
|
-
const
|
|
2178
|
-
|
|
2342
|
+
const getPrimaryKeys = (q) => {
|
|
2343
|
+
var _a;
|
|
2344
|
+
return (_a = q.internal).primaryKeys ?? (_a.primaryKeys = collectPrimaryKeys(q));
|
|
2179
2345
|
};
|
|
2180
|
-
const
|
|
2181
|
-
|
|
2182
|
-
const
|
|
2346
|
+
const collectPrimaryKeys = (q) => {
|
|
2347
|
+
const primaryKeys = [];
|
|
2348
|
+
const { shape } = q.q;
|
|
2183
2349
|
for (const key in shape) {
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
continue;
|
|
2187
|
-
}
|
|
2188
|
-
if (aliasName && column.data.name || column.data.jsonCast) {
|
|
2189
|
-
isSimple = false;
|
|
2350
|
+
if (shape[key].data.primaryKey) {
|
|
2351
|
+
primaryKeys.push(key);
|
|
2190
2352
|
}
|
|
2191
|
-
list.push(
|
|
2192
|
-
`'${key}', "${table}"."${aliasName && column.data.name || key}"${column.data.jsonCast ? `::${column.data.jsonCast}` : ""}`
|
|
2193
|
-
);
|
|
2194
2353
|
}
|
|
2195
|
-
|
|
2354
|
+
const pkey = q.internal.tableData.primaryKey;
|
|
2355
|
+
if (pkey) {
|
|
2356
|
+
primaryKeys.push(...pkey.columns);
|
|
2357
|
+
}
|
|
2358
|
+
return primaryKeys;
|
|
2196
2359
|
};
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
value: true,
|
|
2202
|
-
valueOrThrow: true
|
|
2360
|
+
const _queryAll = (q) => {
|
|
2361
|
+
q.q.returnType = "all";
|
|
2362
|
+
q.q.all = true;
|
|
2363
|
+
return q;
|
|
2203
2364
|
};
|
|
2204
|
-
const
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2365
|
+
const _queryTake = (query) => {
|
|
2366
|
+
const q = query.q;
|
|
2367
|
+
switch (q.returnType) {
|
|
2368
|
+
case "valueOrThrow":
|
|
2369
|
+
case "pluck":
|
|
2370
|
+
case "void":
|
|
2371
|
+
break;
|
|
2372
|
+
case "value": {
|
|
2373
|
+
q.returnType = "valueOrThrow";
|
|
2374
|
+
break;
|
|
2375
|
+
}
|
|
2376
|
+
default: {
|
|
2377
|
+
q.returnType = "oneOrThrow";
|
|
2378
|
+
}
|
|
2213
2379
|
}
|
|
2380
|
+
return query;
|
|
2214
2381
|
};
|
|
2215
|
-
|
|
2216
|
-
const
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2382
|
+
const _queryTakeOptional = (query) => {
|
|
2383
|
+
const q = query.q;
|
|
2384
|
+
switch (q.returnType) {
|
|
2385
|
+
case "value":
|
|
2386
|
+
case "pluck":
|
|
2387
|
+
case "void":
|
|
2388
|
+
break;
|
|
2389
|
+
case "valueOrThrow": {
|
|
2390
|
+
q.returnType = "value";
|
|
2391
|
+
break;
|
|
2392
|
+
}
|
|
2393
|
+
default: {
|
|
2394
|
+
q.returnType = "one";
|
|
2395
|
+
}
|
|
2225
2396
|
}
|
|
2397
|
+
return query;
|
|
2226
2398
|
};
|
|
2227
|
-
const
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
async then(resolve, reject) {
|
|
2231
|
-
try {
|
|
2232
|
-
const result = noneResult(this, this.q, this.q.returnType);
|
|
2233
|
-
resolve?.(result);
|
|
2234
|
-
} catch (err) {
|
|
2235
|
-
reject?.(err);
|
|
2236
|
-
}
|
|
2237
|
-
},
|
|
2238
|
-
// `catch` returns a Promise, so it is chainable with then/catch.
|
|
2239
|
-
catch: () => new Promise(orchidCore.noop)
|
|
2399
|
+
const _queryExec = (q) => {
|
|
2400
|
+
q.q.returnType = "void";
|
|
2401
|
+
return q;
|
|
2240
2402
|
};
|
|
2241
|
-
const
|
|
2242
|
-
|
|
2243
|
-
q = extendQuery(q, noneMethods);
|
|
2244
|
-
pushQueryValueImmutable(q, "and", new RawSQL("false"));
|
|
2245
|
-
pushQueryValueImmutable(
|
|
2246
|
-
q,
|
|
2247
|
-
"transform",
|
|
2248
|
-
(_, queryData) => noneResult(q, queryData, queryData.returnType)
|
|
2249
|
-
);
|
|
2403
|
+
const _queryRows = (q) => {
|
|
2404
|
+
q.q.returnType = "rows";
|
|
2250
2405
|
return q;
|
|
2251
2406
|
};
|
|
2252
|
-
const
|
|
2407
|
+
const getFullColumnTable = (q, column, index, as) => {
|
|
2408
|
+
const table = column.slice(0, index);
|
|
2409
|
+
return as && table !== as && q.q.aliases?.[table] === as ? as : table;
|
|
2410
|
+
};
|
|
2253
2411
|
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
}
|
|
2275
|
-
joinKey = q.q.as || q.table;
|
|
2276
|
-
if (joinKey) {
|
|
2277
|
-
shape = getShapeFromSelect(q, joinSubQuery && !!q.q.select);
|
|
2278
|
-
parsers = q.q.parsers;
|
|
2279
|
-
batchParsers = q.q.batchParsers;
|
|
2280
|
-
computeds = q.q.computeds;
|
|
2281
|
-
if (joinSubQuery) {
|
|
2282
|
-
first = q.clone();
|
|
2283
|
-
first.shape = shape;
|
|
2284
|
-
}
|
|
2285
|
-
}
|
|
2286
|
-
} else {
|
|
2287
|
-
joinKey = first;
|
|
2288
|
-
const relation = query.relations[joinKey];
|
|
2289
|
-
if (relation) {
|
|
2290
|
-
shape = getShapeFromSelect(relation.relationConfig.query);
|
|
2291
|
-
const r = relation.relationConfig.query;
|
|
2292
|
-
parsers = r.q.parsers;
|
|
2293
|
-
batchParsers = r.q.batchParsers;
|
|
2294
|
-
computeds = r.q.computeds;
|
|
2295
|
-
} else {
|
|
2296
|
-
const w = query.q.withShapes?.[joinKey];
|
|
2297
|
-
shape = w?.shape;
|
|
2298
|
-
computeds = w?.computeds;
|
|
2299
|
-
if (shape) {
|
|
2300
|
-
if (!require) shape = { ...shape };
|
|
2301
|
-
const arg = { parsers: {} };
|
|
2302
|
-
for (const key in shape) {
|
|
2303
|
-
addColumnParserToQuery(arg, key, shape[key]);
|
|
2304
|
-
}
|
|
2305
|
-
}
|
|
2306
|
-
}
|
|
2307
|
-
}
|
|
2308
|
-
const joinArgs = processJoinArgs(
|
|
2309
|
-
query,
|
|
2310
|
-
first,
|
|
2311
|
-
args,
|
|
2312
|
-
joinSubQuery
|
|
2313
|
-
);
|
|
2314
|
-
if (require && "r" in joinArgs && isQueryNone(joinArgs.r)) {
|
|
2315
|
-
return _queryNone(query);
|
|
2316
|
-
} else if (joinKey && "s" in joinArgs && joinArgs.s) {
|
|
2317
|
-
const j = "j" in joinArgs ? joinArgs.r ?? joinArgs.j : "r" in joinArgs ? joinArgs.r : joinArgs.q;
|
|
2318
|
-
const jq = j.q;
|
|
2319
|
-
if (jq.select || !jq.selectAllColumns) {
|
|
2320
|
-
const { q } = query;
|
|
2321
|
-
const shape2 = getShapeFromSelect(j, true);
|
|
2322
|
-
orchidCore.setObjectValueImmutable(q, "joinedShapes", joinKey, shape2);
|
|
2323
|
-
orchidCore.setObjectValueImmutable(q, "joinedParsers", joinKey, jq.parsers);
|
|
2324
|
-
if (jq.batchParsers) {
|
|
2325
|
-
orchidCore.setObjectValueImmutable(
|
|
2326
|
-
jq,
|
|
2327
|
-
"joinedBatchParsers",
|
|
2328
|
-
joinKey,
|
|
2329
|
-
jq.batchParsers
|
|
2330
|
-
);
|
|
2331
|
-
}
|
|
2332
|
-
orchidCore.setObjectValueImmutable(q, "joinedComputeds", joinKey, jq.computeds);
|
|
2333
|
-
} else {
|
|
2334
|
-
addAllShapesAndParsers(
|
|
2335
|
-
query,
|
|
2336
|
-
joinKey,
|
|
2337
|
-
shape,
|
|
2338
|
-
parsers,
|
|
2339
|
-
batchParsers,
|
|
2340
|
-
computeds
|
|
2341
|
-
);
|
|
2342
|
-
}
|
|
2343
|
-
} else {
|
|
2344
|
-
addAllShapesAndParsers(
|
|
2345
|
-
query,
|
|
2346
|
-
joinKey,
|
|
2347
|
-
shape,
|
|
2348
|
-
parsers,
|
|
2349
|
-
batchParsers,
|
|
2350
|
-
computeds
|
|
2351
|
-
);
|
|
2352
|
-
}
|
|
2353
|
-
pushQueryValueImmutable(query, "join", {
|
|
2354
|
-
type,
|
|
2355
|
-
args: joinArgs
|
|
2356
|
-
});
|
|
2357
|
-
if (query.q.type === "delete") {
|
|
2358
|
-
throwIfJoinLateral(
|
|
2359
|
-
query,
|
|
2360
|
-
query.q.type
|
|
2412
|
+
function simpleColumnToSQL(ctx, key, column, quotedAs) {
|
|
2413
|
+
if (!column) return `"${key}"`;
|
|
2414
|
+
const { data } = column;
|
|
2415
|
+
return data.computed ? data.computed.toSQL(ctx, quotedAs) : `${quotedAs ? `${quotedAs}.` : ""}"${data.name || key}"`;
|
|
2416
|
+
}
|
|
2417
|
+
function simpleExistingColumnToSQL(ctx, key, column, quotedAs) {
|
|
2418
|
+
const { data } = column;
|
|
2419
|
+
return data.computed ? data.computed.toSQL(ctx, quotedAs) : `${quotedAs ? `${quotedAs}.` : ""}"${data.name || key}"`;
|
|
2420
|
+
}
|
|
2421
|
+
const columnToSql = (ctx, data, shape, column, quotedAs, select) => {
|
|
2422
|
+
const index = column.indexOf(".");
|
|
2423
|
+
if (index !== -1) {
|
|
2424
|
+
return columnWithDotToSql(
|
|
2425
|
+
ctx,
|
|
2426
|
+
data,
|
|
2427
|
+
shape,
|
|
2428
|
+
column,
|
|
2429
|
+
index,
|
|
2430
|
+
quotedAs,
|
|
2431
|
+
select
|
|
2361
2432
|
);
|
|
2362
2433
|
}
|
|
2363
|
-
|
|
2364
|
-
}
|
|
2365
|
-
const addAllShapesAndParsers = (query, joinKey, shape, parsers, batchParsers, computeds) => {
|
|
2366
|
-
if (!joinKey) return;
|
|
2367
|
-
const { q } = query;
|
|
2368
|
-
orchidCore.setObjectValueImmutable(q, "joinedShapes", joinKey, shape);
|
|
2369
|
-
orchidCore.setObjectValueImmutable(q, "joinedParsers", joinKey, parsers);
|
|
2370
|
-
if (batchParsers) {
|
|
2371
|
-
orchidCore.setObjectValueImmutable(q, "joinedBatchParsers", joinKey, batchParsers);
|
|
2434
|
+
if (!select && data.joinedShapes?.[column]) {
|
|
2435
|
+
return `"${column}".r`;
|
|
2372
2436
|
}
|
|
2373
|
-
|
|
2437
|
+
return simpleColumnToSQL(ctx, column, shape[column], quotedAs);
|
|
2374
2438
|
};
|
|
2375
|
-
const
|
|
2376
|
-
|
|
2377
|
-
if (
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
shape: w.shape
|
|
2391
|
-
};
|
|
2392
|
-
t.baseQuery = t;
|
|
2393
|
-
arg = t;
|
|
2439
|
+
const maybeSelectedColumnToSql = (ctx, data, column, quotedAs) => {
|
|
2440
|
+
const index = column.indexOf(".");
|
|
2441
|
+
if (index !== -1) {
|
|
2442
|
+
return columnWithDotToSql(ctx, data, data.shape, column, index, quotedAs);
|
|
2443
|
+
} else {
|
|
2444
|
+
if (data.joinedShapes?.[column]) {
|
|
2445
|
+
return `"${column}".r`;
|
|
2446
|
+
}
|
|
2447
|
+
if (data.select) {
|
|
2448
|
+
for (const s of data.select) {
|
|
2449
|
+
if (typeof s === "object" && "selectAs" in s) {
|
|
2450
|
+
if (column in s.selectAs) {
|
|
2451
|
+
return simpleColumnToSQL(ctx, column, data.shape[column]);
|
|
2452
|
+
}
|
|
2453
|
+
}
|
|
2394
2454
|
}
|
|
2395
2455
|
}
|
|
2456
|
+
return simpleColumnToSQL(ctx, column, data.shape[column], quotedAs);
|
|
2396
2457
|
}
|
|
2397
|
-
let result = resolveSubQueryCallbackV2(
|
|
2398
|
-
arg,
|
|
2399
|
-
cb
|
|
2400
|
-
);
|
|
2401
|
-
if (relation) {
|
|
2402
|
-
result = relation.relationConfig.joinQuery(
|
|
2403
|
-
result,
|
|
2404
|
-
q
|
|
2405
|
-
);
|
|
2406
|
-
}
|
|
2407
|
-
return result;
|
|
2408
2458
|
};
|
|
2409
|
-
const
|
|
2410
|
-
const
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
);
|
|
2459
|
+
const columnWithDotToSql = (ctx, data, shape, column, index, quotedAs, select) => {
|
|
2460
|
+
const table = column.slice(0, index);
|
|
2461
|
+
const key = column.slice(index + 1);
|
|
2462
|
+
if (key === "*") {
|
|
2463
|
+
const shape2 = data.joinedShapes?.[table];
|
|
2464
|
+
return shape2 ? select ? makeRowToJson(table, shape2, true) : `"${table}".*` : column;
|
|
2465
|
+
}
|
|
2466
|
+
const tableName = data.aliases?.[table] || table;
|
|
2467
|
+
const quoted = `"${table}"`;
|
|
2468
|
+
const col = quoted === quotedAs ? shape[key] : data.joinedShapes?.[tableName]?.[key];
|
|
2469
|
+
if (col) {
|
|
2470
|
+
if (col.data.name) {
|
|
2471
|
+
return `"${tableName}"."${col.data.name}"`;
|
|
2472
|
+
}
|
|
2473
|
+
if (col.data.computed) {
|
|
2474
|
+
return col.data.computed.toSQL(ctx, quoted);
|
|
2426
2475
|
}
|
|
2476
|
+
return `"${tableName}"."${key}"`;
|
|
2427
2477
|
}
|
|
2428
|
-
|
|
2429
|
-
orchidCore.setObjectValueImmutable(q.q, "joinedComputeds", as, arg.q.computeds);
|
|
2430
|
-
pushQueryValueImmutable(q, "join", [type, arg, as]);
|
|
2431
|
-
return q;
|
|
2478
|
+
return `"${tableName}"."${key}"`;
|
|
2432
2479
|
};
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2480
|
+
const columnToSqlWithAs = (ctx, data, column, as, quotedAs, select, jsonList) => {
|
|
2481
|
+
const index = column.indexOf(".");
|
|
2482
|
+
return index !== -1 ? tableColumnToSqlWithAs(
|
|
2483
|
+
ctx,
|
|
2484
|
+
data,
|
|
2485
|
+
column,
|
|
2486
|
+
column.slice(0, index),
|
|
2487
|
+
column.slice(index + 1),
|
|
2488
|
+
as,
|
|
2489
|
+
quotedAs,
|
|
2490
|
+
select,
|
|
2491
|
+
jsonList
|
|
2492
|
+
) : ownColumnToSqlWithAs(ctx, data, column, as, quotedAs, select, jsonList);
|
|
2493
|
+
};
|
|
2494
|
+
const tableColumnToSqlWithAs = (ctx, data, column, table, key, as, quotedAs, select, jsonList) => {
|
|
2495
|
+
if (key === "*") {
|
|
2496
|
+
if (jsonList) jsonList[as] = void 0;
|
|
2497
|
+
const shape = data.joinedShapes?.[table];
|
|
2498
|
+
if (shape) {
|
|
2499
|
+
{
|
|
2500
|
+
return makeRowToJson(table, shape, true) + ` "${as}"`;
|
|
2501
|
+
}
|
|
2502
|
+
}
|
|
2503
|
+
return column;
|
|
2447
2504
|
}
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2505
|
+
const tableName = data.aliases?.[table] || table;
|
|
2506
|
+
const quoted = `"${table}"`;
|
|
2507
|
+
const col = quoted === quotedAs ? data.shape[key] : data.joinedShapes?.[tableName][key];
|
|
2508
|
+
if (jsonList) jsonList[as] = col;
|
|
2509
|
+
if (col) {
|
|
2510
|
+
if (col.data.name && col.data.name !== key) {
|
|
2511
|
+
return `"${tableName}"."${col.data.name}" "${as}"`;
|
|
2512
|
+
}
|
|
2513
|
+
if (col.data.computed) {
|
|
2514
|
+
return `${col.data.computed.toSQL(ctx, quoted)} "${as}"`;
|
|
2454
2515
|
}
|
|
2455
|
-
const code = [open];
|
|
2456
|
-
const { item } = this.data;
|
|
2457
|
-
const { isNullable } = item.data;
|
|
2458
|
-
delete item.data.isNullable;
|
|
2459
|
-
orchidCore.addCode(code, item.toCode(ctx, key));
|
|
2460
|
-
item.data.isNullable = isNullable;
|
|
2461
|
-
orchidCore.addCode(code, `${close}${orchidCore.arrayDataToCode(this.data, ctx.migration)}`);
|
|
2462
|
-
return columnCode(this, ctx, key, code);
|
|
2463
2516
|
}
|
|
2464
|
-
}
|
|
2465
|
-
const parse$1 = function(source) {
|
|
2466
|
-
if (typeof source !== "string") return source;
|
|
2467
|
-
const entries = [];
|
|
2468
|
-
parsePostgresArray(source, entries, this.data.item.data.parseItem);
|
|
2469
|
-
return entries;
|
|
2517
|
+
return `"${tableName}"."${key}"${key === as ? "" : ` "${as}"`}`;
|
|
2470
2518
|
};
|
|
2471
|
-
const
|
|
2472
|
-
|
|
2473
|
-
if (
|
|
2474
|
-
|
|
2475
|
-
if (
|
|
2519
|
+
const ownColumnToSqlWithAs = (ctx, data, column, as, quotedAs, select, jsonList) => {
|
|
2520
|
+
const col = data.shape[column];
|
|
2521
|
+
if (jsonList) jsonList[as] = col;
|
|
2522
|
+
if (col) {
|
|
2523
|
+
if (col.data.name && col.data.name !== column) {
|
|
2524
|
+
return `${quotedAs ? `${quotedAs}.` : ""}"${col.data.name}"${col.data.name === as ? "" : ` "${as}"`}`;
|
|
2525
|
+
}
|
|
2526
|
+
if (col.data.computed) {
|
|
2527
|
+
return `${col.data.computed.toSQL(ctx, quotedAs)} "${as}"`;
|
|
2528
|
+
}
|
|
2476
2529
|
}
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
}
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
while (pos < source.length) {
|
|
2496
|
-
let char;
|
|
2497
|
-
while ((char = source[pos++]) === "\\") {
|
|
2498
|
-
if (!(esc = !esc)) rec += "\\";
|
|
2499
|
-
}
|
|
2500
|
-
if (esc) {
|
|
2501
|
-
esc = false;
|
|
2502
|
-
} else if (char === '"') {
|
|
2503
|
-
break;
|
|
2504
|
-
}
|
|
2505
|
-
rec += char;
|
|
2506
|
-
}
|
|
2507
|
-
entries.push(transform ? transform(rec) : rec);
|
|
2508
|
-
recorded = "";
|
|
2509
|
-
} else if (character === ",") {
|
|
2510
|
-
if (recorded) {
|
|
2511
|
-
entries.push(
|
|
2512
|
-
recorded === "NULL" ? null : transform ? transform(recorded) : recorded
|
|
2513
|
-
);
|
|
2514
|
-
recorded = "";
|
|
2515
|
-
}
|
|
2516
|
-
} else {
|
|
2517
|
-
recorded += character;
|
|
2530
|
+
return `${quotedAs ? `${quotedAs}.` : ""}"${column}"${column === as ? "" : ` "${as}"`}`;
|
|
2531
|
+
};
|
|
2532
|
+
const rawOrColumnToSql = (ctx, data, expr, quotedAs, shape = data.shape, select) => {
|
|
2533
|
+
return typeof expr === "string" ? columnToSql(ctx, data, shape, expr, quotedAs, select) : expr.toSQL(ctx, quotedAs);
|
|
2534
|
+
};
|
|
2535
|
+
const quoteSchemaAndTable = (schema, table) => {
|
|
2536
|
+
return schema ? `"${schema}"."${table}"` : `"${table}"`;
|
|
2537
|
+
};
|
|
2538
|
+
const makeRowToJson = (table, shape, aliasName) => {
|
|
2539
|
+
let isSimple = true;
|
|
2540
|
+
const list = [];
|
|
2541
|
+
for (const key in shape) {
|
|
2542
|
+
const column = shape[key];
|
|
2543
|
+
if (column.data.explicitSelect) {
|
|
2544
|
+
continue;
|
|
2545
|
+
}
|
|
2546
|
+
if (aliasName && column.data.name || column.data.jsonCast) {
|
|
2547
|
+
isSimple = false;
|
|
2518
2548
|
}
|
|
2549
|
+
list.push(
|
|
2550
|
+
`'${key}', "${table}"."${aliasName && column.data.name || key}"${column.data.jsonCast ? `::${column.data.jsonCast}` : ""}`
|
|
2551
|
+
);
|
|
2519
2552
|
}
|
|
2520
|
-
return
|
|
2553
|
+
return isSimple ? `row_to_json("${table}".*)` : `CASE WHEN "${table}".* IS NULL THEN NULL ELSE json_build_object(` + list.join(", ") + ") END";
|
|
2521
2554
|
};
|
|
2522
2555
|
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
}
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
constructor(schema) {
|
|
2537
|
-
super(schema, schema.stringSchema());
|
|
2538
|
-
this.operators = Operators.number;
|
|
2539
|
-
this.data.jsonCast = "text";
|
|
2540
|
-
}
|
|
2541
|
-
}
|
|
2542
|
-
class DecimalColumn extends NumberAsStringBaseColumn {
|
|
2543
|
-
constructor(schema, numericPrecision, numericScale) {
|
|
2544
|
-
super(schema);
|
|
2545
|
-
this.operators = Operators.number;
|
|
2546
|
-
this.dataType = "numeric";
|
|
2547
|
-
this.data.numericPrecision = numericPrecision;
|
|
2548
|
-
this.data.numericScale = numericScale;
|
|
2549
|
-
this.data.alias = "decimal";
|
|
2550
|
-
}
|
|
2551
|
-
toCode(ctx, key) {
|
|
2552
|
-
const { numericPrecision, numericScale } = this.data;
|
|
2553
|
-
return columnCode(
|
|
2554
|
-
this,
|
|
2555
|
-
ctx,
|
|
2556
|
-
key,
|
|
2557
|
-
`decimal(${numericPrecision || ""}${numericScale ? `, ${numericScale}` : ""})`
|
|
2558
|
-
);
|
|
2559
|
-
}
|
|
2560
|
-
toSQL() {
|
|
2561
|
-
const { numericPrecision, numericScale } = this.data;
|
|
2562
|
-
return orchidCore.joinTruthy(
|
|
2563
|
-
this.dataType,
|
|
2564
|
-
numericPrecision ? numericScale ? `(${numericPrecision}, ${numericScale})` : `(${numericPrecision})` : void 0
|
|
2556
|
+
const queryTypeWithLimitOne = {
|
|
2557
|
+
one: true,
|
|
2558
|
+
oneOrThrow: true,
|
|
2559
|
+
value: true,
|
|
2560
|
+
valueOrThrow: true
|
|
2561
|
+
};
|
|
2562
|
+
const isQueryReturnsAll = (q) => !q.q.returnType || q.q.returnType === "all";
|
|
2563
|
+
|
|
2564
|
+
const pushDistinctSql = (ctx, table, distinct, quotedAs) => {
|
|
2565
|
+
ctx.sql.push("DISTINCT");
|
|
2566
|
+
if (distinct.length) {
|
|
2567
|
+
const columns = distinct?.map(
|
|
2568
|
+
(item) => rawOrColumnToSql(ctx, table.q, item, quotedAs)
|
|
2565
2569
|
);
|
|
2570
|
+
ctx.sql.push(`ON (${columns?.join(", ") || ""})`);
|
|
2566
2571
|
}
|
|
2567
|
-
}
|
|
2568
|
-
|
|
2569
|
-
const
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2572
|
+
};
|
|
2573
|
+
|
|
2574
|
+
const noneResult = (q, queryData, type) => {
|
|
2575
|
+
if (!type || type === "all" || type === "rows" || type === "pluck") {
|
|
2576
|
+
return [];
|
|
2577
|
+
} else if (type === "one" || type === "value" || type === "void") {
|
|
2578
|
+
return queryData.notFoundDefault;
|
|
2579
|
+
} else if (type === "valueOrThrow" && queryData.returning) {
|
|
2580
|
+
return 0;
|
|
2573
2581
|
} else {
|
|
2574
|
-
|
|
2582
|
+
throw new NotFoundError(q);
|
|
2575
2583
|
}
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2584
|
+
};
|
|
2585
|
+
const noneMethods = {
|
|
2586
|
+
// `then` resolves or rejects based on a return type of the query.
|
|
2587
|
+
// It is `async` so it returns a chainable Promise.
|
|
2588
|
+
async then(resolve, reject) {
|
|
2589
|
+
try {
|
|
2590
|
+
const result = noneResult(this, this.q, this.q.returnType);
|
|
2591
|
+
resolve?.(result);
|
|
2592
|
+
} catch (err) {
|
|
2593
|
+
reject?.(err);
|
|
2594
|
+
}
|
|
2595
|
+
},
|
|
2596
|
+
// `catch` returns a Promise, so it is chainable with then/catch.
|
|
2597
|
+
catch: () => new Promise(orchidCore.noop)
|
|
2598
|
+
};
|
|
2599
|
+
const _queryNone = (q) => {
|
|
2600
|
+
if (isQueryNone(q)) return q;
|
|
2601
|
+
q = extendQuery(q, noneMethods);
|
|
2602
|
+
pushQueryValueImmutable(q, "and", new RawSQL("false"));
|
|
2603
|
+
pushQueryValueImmutable(
|
|
2604
|
+
q,
|
|
2605
|
+
"transform",
|
|
2606
|
+
(_, queryData) => noneResult(q, queryData, queryData.returnType)
|
|
2579
2607
|
);
|
|
2580
|
-
return
|
|
2608
|
+
return q;
|
|
2581
2609
|
};
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2610
|
+
const isQueryNone = (q) => q.then === noneMethods.then;
|
|
2611
|
+
|
|
2612
|
+
const _join = (query, require, type, first, args) => {
|
|
2613
|
+
let joinKey;
|
|
2614
|
+
let shape;
|
|
2615
|
+
let parsers;
|
|
2616
|
+
let batchParsers;
|
|
2617
|
+
let computeds;
|
|
2618
|
+
let joinSubQuery = false;
|
|
2619
|
+
first = preprocessJoinArg(query, first);
|
|
2620
|
+
if (typeof first === "object") {
|
|
2621
|
+
let isInternalJoin;
|
|
2622
|
+
if ("_internalJoin" in first) {
|
|
2623
|
+
isInternalJoin = true;
|
|
2624
|
+
first = first._internalJoin;
|
|
2625
|
+
}
|
|
2626
|
+
if (require && isQueryNone(first)) {
|
|
2627
|
+
return _queryNone(query);
|
|
2628
|
+
}
|
|
2629
|
+
const q = first;
|
|
2630
|
+
if (!isInternalJoin) {
|
|
2631
|
+
joinSubQuery = getIsJoinSubQuery(q);
|
|
2632
|
+
}
|
|
2633
|
+
joinKey = q.q.as || q.table;
|
|
2634
|
+
if (joinKey) {
|
|
2635
|
+
shape = getShapeFromSelect(q, joinSubQuery && !!q.q.select);
|
|
2636
|
+
parsers = q.q.parsers;
|
|
2637
|
+
batchParsers = q.q.batchParsers;
|
|
2638
|
+
computeds = q.q.computeds;
|
|
2639
|
+
if (joinSubQuery) {
|
|
2640
|
+
first = q.clone();
|
|
2641
|
+
first.shape = shape;
|
|
2642
|
+
}
|
|
2643
|
+
}
|
|
2644
|
+
} else {
|
|
2645
|
+
joinKey = first;
|
|
2646
|
+
const relation = query.relations[joinKey];
|
|
2647
|
+
if (relation) {
|
|
2648
|
+
shape = getShapeFromSelect(relation.relationConfig.query);
|
|
2649
|
+
const r = relation.relationConfig.query;
|
|
2650
|
+
parsers = r.q.parsers;
|
|
2651
|
+
batchParsers = r.q.batchParsers;
|
|
2652
|
+
computeds = r.q.computeds;
|
|
2653
|
+
} else {
|
|
2654
|
+
const w = query.q.withShapes?.[joinKey];
|
|
2655
|
+
shape = w?.shape;
|
|
2656
|
+
computeds = w?.computeds;
|
|
2657
|
+
if (shape) {
|
|
2658
|
+
if (!require) shape = { ...shape };
|
|
2659
|
+
const arg = { parsers: {} };
|
|
2660
|
+
for (const key in shape) {
|
|
2661
|
+
addColumnParserToQuery(arg, key, shape[key]);
|
|
2662
|
+
}
|
|
2663
|
+
}
|
|
2664
|
+
}
|
|
2629
2665
|
}
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2666
|
+
const joinArgs = processJoinArgs(
|
|
2667
|
+
query,
|
|
2668
|
+
first,
|
|
2669
|
+
args,
|
|
2670
|
+
joinSubQuery
|
|
2671
|
+
);
|
|
2672
|
+
if (require && "r" in joinArgs && isQueryNone(joinArgs.r)) {
|
|
2673
|
+
return _queryNone(query);
|
|
2674
|
+
} else if (joinKey && "s" in joinArgs && joinArgs.s) {
|
|
2675
|
+
const j = "j" in joinArgs ? joinArgs.r ?? joinArgs.j : "r" in joinArgs ? joinArgs.r : joinArgs.q;
|
|
2676
|
+
const jq = j.q;
|
|
2677
|
+
if (jq.select || !jq.selectAllColumns) {
|
|
2678
|
+
const { q } = query;
|
|
2679
|
+
const shape2 = getShapeFromSelect(j, true);
|
|
2680
|
+
orchidCore.setObjectValueImmutable(q, "joinedShapes", joinKey, shape2);
|
|
2681
|
+
orchidCore.setObjectValueImmutable(q, "joinedParsers", joinKey, jq.parsers);
|
|
2682
|
+
if (jq.batchParsers) {
|
|
2683
|
+
orchidCore.setObjectValueImmutable(
|
|
2684
|
+
jq,
|
|
2685
|
+
"joinedBatchParsers",
|
|
2686
|
+
joinKey,
|
|
2687
|
+
jq.batchParsers
|
|
2688
|
+
);
|
|
2689
|
+
}
|
|
2690
|
+
orchidCore.setObjectValueImmutable(q, "joinedComputeds", joinKey, jq.computeds);
|
|
2691
|
+
} else {
|
|
2692
|
+
addAllShapesAndParsers(
|
|
2693
|
+
query,
|
|
2694
|
+
joinKey,
|
|
2695
|
+
shape,
|
|
2696
|
+
parsers,
|
|
2697
|
+
batchParsers,
|
|
2698
|
+
computeds
|
|
2699
|
+
);
|
|
2700
|
+
}
|
|
2701
|
+
} else {
|
|
2702
|
+
addAllShapesAndParsers(
|
|
2703
|
+
query,
|
|
2704
|
+
joinKey,
|
|
2705
|
+
shape,
|
|
2706
|
+
parsers,
|
|
2707
|
+
batchParsers,
|
|
2708
|
+
computeds
|
|
2636
2709
|
);
|
|
2637
2710
|
}
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
return columnCode(this, ctx, key, `doublePrecision()`);
|
|
2647
|
-
}
|
|
2648
|
-
}
|
|
2649
|
-
class SmallSerialColumn extends IntegerBaseColumn {
|
|
2650
|
-
constructor(schema) {
|
|
2651
|
-
super(schema);
|
|
2652
|
-
this.dataType = "int2";
|
|
2653
|
-
this.data.int = true;
|
|
2654
|
-
this.data.alias = "smallSerial";
|
|
2655
|
-
this.data.parseItem = parseInt;
|
|
2656
|
-
}
|
|
2657
|
-
toSQL() {
|
|
2658
|
-
return "smallserial";
|
|
2659
|
-
}
|
|
2660
|
-
toCode(ctx, key) {
|
|
2661
|
-
return columnCode(
|
|
2662
|
-
this,
|
|
2663
|
-
ctx,
|
|
2664
|
-
key,
|
|
2665
|
-
`smallSerial()${orchidCore.numberDataToCode(
|
|
2666
|
-
this.data,
|
|
2667
|
-
ctx.migration,
|
|
2668
|
-
skipNumberMethods
|
|
2669
|
-
)}`
|
|
2711
|
+
pushQueryValueImmutable(query, "join", {
|
|
2712
|
+
type,
|
|
2713
|
+
args: joinArgs
|
|
2714
|
+
});
|
|
2715
|
+
if (query.q.type === "delete") {
|
|
2716
|
+
throwIfJoinLateral(
|
|
2717
|
+
query,
|
|
2718
|
+
query.q.type
|
|
2670
2719
|
);
|
|
2671
2720
|
}
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2721
|
+
return query;
|
|
2722
|
+
};
|
|
2723
|
+
const addAllShapesAndParsers = (query, joinKey, shape, parsers, batchParsers, computeds) => {
|
|
2724
|
+
if (!joinKey) return;
|
|
2725
|
+
const { q } = query;
|
|
2726
|
+
orchidCore.setObjectValueImmutable(q, "joinedShapes", joinKey, shape);
|
|
2727
|
+
orchidCore.setObjectValueImmutable(q, "joinedParsers", joinKey, parsers);
|
|
2728
|
+
if (batchParsers) {
|
|
2729
|
+
orchidCore.setObjectValueImmutable(q, "joinedBatchParsers", joinKey, batchParsers);
|
|
2680
2730
|
}
|
|
2681
|
-
|
|
2682
|
-
|
|
2731
|
+
orchidCore.setObjectValueImmutable(q, "joinedComputeds", joinKey, computeds);
|
|
2732
|
+
};
|
|
2733
|
+
const _joinLateralProcessArg = (q, arg, cb) => {
|
|
2734
|
+
let relation;
|
|
2735
|
+
if (typeof arg === "string") {
|
|
2736
|
+
relation = q.relations[arg];
|
|
2737
|
+
if (relation) {
|
|
2738
|
+
arg = _clone(relation.relationConfig.query);
|
|
2739
|
+
} else {
|
|
2740
|
+
const w = q.q.withShapes?.[arg];
|
|
2741
|
+
if (w) {
|
|
2742
|
+
const t = Object.create(q.queryBuilder);
|
|
2743
|
+
t.table = arg;
|
|
2744
|
+
t.shape = w.shape;
|
|
2745
|
+
t.computeds = w.computeds;
|
|
2746
|
+
t.q = {
|
|
2747
|
+
...t.q,
|
|
2748
|
+
shape: w.shape
|
|
2749
|
+
};
|
|
2750
|
+
t.baseQuery = t;
|
|
2751
|
+
arg = t;
|
|
2752
|
+
}
|
|
2753
|
+
}
|
|
2683
2754
|
}
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
skipNumberMethods
|
|
2693
|
-
)}`
|
|
2755
|
+
let result = resolveSubQueryCallbackV2(
|
|
2756
|
+
arg,
|
|
2757
|
+
cb
|
|
2758
|
+
);
|
|
2759
|
+
if (relation) {
|
|
2760
|
+
result = relation.relationConfig.joinQuery(
|
|
2761
|
+
result,
|
|
2762
|
+
q
|
|
2694
2763
|
);
|
|
2695
2764
|
}
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2765
|
+
return result;
|
|
2766
|
+
};
|
|
2767
|
+
const _joinLateral = (self, type, arg, as) => {
|
|
2768
|
+
const q = self;
|
|
2769
|
+
arg.q.joinTo = q;
|
|
2770
|
+
const joinedAs = getQueryAs(q);
|
|
2771
|
+
orchidCore.setObjectValueImmutable(arg.q, "joinedShapes", joinedAs, q.q.shape);
|
|
2772
|
+
const joinKey = as || arg.q.as || arg.table;
|
|
2773
|
+
if (joinKey) {
|
|
2774
|
+
const shape = getShapeFromSelect(arg, true);
|
|
2775
|
+
orchidCore.setObjectValueImmutable(q.q, "joinedShapes", joinKey, shape);
|
|
2776
|
+
orchidCore.setObjectValueImmutable(q.q, "joinedParsers", joinKey, arg.q.parsers);
|
|
2777
|
+
if (arg.q.batchParsers) {
|
|
2778
|
+
orchidCore.setObjectValueImmutable(
|
|
2779
|
+
q.q,
|
|
2780
|
+
"joinedBatchParsers",
|
|
2781
|
+
joinKey,
|
|
2782
|
+
arg.q.batchParsers
|
|
2783
|
+
);
|
|
2784
|
+
}
|
|
2708
2785
|
}
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2714
|
-
parse(fn) {
|
|
2715
|
-
return setColumnParse(this, fn);
|
|
2716
|
-
},
|
|
2717
|
-
parseNull(fn) {
|
|
2718
|
-
return setColumnParseNull(this, fn);
|
|
2719
|
-
},
|
|
2720
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2721
|
-
encode(fn) {
|
|
2722
|
-
return orchidCore.setColumnData(this, "encode", fn);
|
|
2723
|
-
},
|
|
2724
|
-
asType() {
|
|
2725
|
-
return this;
|
|
2726
|
-
},
|
|
2727
|
-
dateAsNumber() {
|
|
2728
|
-
return this.parse(Date.parse);
|
|
2729
|
-
},
|
|
2730
|
-
dateAsDate() {
|
|
2731
|
-
return this.parse(parseDateToDate);
|
|
2732
|
-
},
|
|
2733
|
-
enum(dataType, type) {
|
|
2734
|
-
return new EnumColumn(defaultSchemaConfig, dataType, type, void 0);
|
|
2735
|
-
},
|
|
2736
|
-
array(item) {
|
|
2737
|
-
return new ArrayColumn(defaultSchemaConfig, item, void 0);
|
|
2738
|
-
},
|
|
2739
|
-
boolean: orchidCore.noop,
|
|
2740
|
-
buffer: orchidCore.noop,
|
|
2741
|
-
unknown: orchidCore.noop,
|
|
2742
|
-
never: orchidCore.noop,
|
|
2743
|
-
stringSchema: orchidCore.noop,
|
|
2744
|
-
stringMin: orchidCore.noop,
|
|
2745
|
-
stringMax: orchidCore.noop,
|
|
2746
|
-
stringMinMax: orchidCore.noop,
|
|
2747
|
-
number: orchidCore.noop,
|
|
2748
|
-
int: orchidCore.noop,
|
|
2749
|
-
stringNumberDate: orchidCore.noop,
|
|
2750
|
-
timeInterval: orchidCore.noop,
|
|
2751
|
-
bit: orchidCore.noop,
|
|
2752
|
-
uuid: orchidCore.noop,
|
|
2753
|
-
nullable() {
|
|
2754
|
-
return orchidCore.setColumnData(this, "isNullable", true);
|
|
2755
|
-
},
|
|
2756
|
-
json() {
|
|
2757
|
-
return new JSONColumn(defaultSchemaConfig, void 0);
|
|
2758
|
-
},
|
|
2759
|
-
setErrors: orchidCore.noop,
|
|
2760
|
-
smallint: () => new SmallIntColumn(defaultSchemaConfig),
|
|
2761
|
-
integer: () => new IntegerColumn(defaultSchemaConfig),
|
|
2762
|
-
real: () => new RealColumn(defaultSchemaConfig),
|
|
2763
|
-
smallSerial: () => new SmallSerialColumn(defaultSchemaConfig),
|
|
2764
|
-
serial: () => new SerialColumn(defaultSchemaConfig),
|
|
2765
|
-
bigint: () => new BigIntColumn(defaultSchemaConfig),
|
|
2766
|
-
decimal: (precision, scale) => new DecimalColumn(defaultSchemaConfig, precision, scale),
|
|
2767
|
-
doublePrecision: () => new DoublePrecisionColumn(defaultSchemaConfig),
|
|
2768
|
-
bigSerial: () => new BigSerialColumn(defaultSchemaConfig),
|
|
2769
|
-
money: () => new MoneyColumn(defaultSchemaConfig),
|
|
2770
|
-
varchar: (limit) => new VarCharColumn(defaultSchemaConfig, limit),
|
|
2771
|
-
text: () => new TextColumn(defaultSchemaConfig),
|
|
2772
|
-
string: (limit) => new StringColumn(defaultSchemaConfig, limit),
|
|
2773
|
-
citext: () => new CitextColumn(defaultSchemaConfig),
|
|
2774
|
-
date: () => new DateColumn(defaultSchemaConfig),
|
|
2775
|
-
timestampNoTZ: (precision) => new TimestampColumn(defaultSchemaConfig, precision),
|
|
2776
|
-
timestamp: (precision) => new TimestampTZColumn(defaultSchemaConfig, precision),
|
|
2777
|
-
geographyPointSchema: orchidCore.noop
|
|
2786
|
+
as || (as = getQueryAs(arg));
|
|
2787
|
+
orchidCore.setObjectValueImmutable(q.q, "joinedComputeds", as, arg.q.computeds);
|
|
2788
|
+
pushQueryValueImmutable(q, "join", [type, arg, as]);
|
|
2789
|
+
return q;
|
|
2778
2790
|
};
|
|
2779
2791
|
|
|
2780
2792
|
const escape = (value, migration, nested) => {
|
|
@@ -2864,14 +2876,25 @@ class AfterCommitError extends OrchidOrmError {
|
|
|
2864
2876
|
this.hookResults = hookResults;
|
|
2865
2877
|
}
|
|
2866
2878
|
}
|
|
2867
|
-
const
|
|
2868
|
-
const
|
|
2869
|
-
if (
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2879
|
+
const _runAfterCommitHooks = async (result, promises, getHookNames, catchAfterCommitErrors) => {
|
|
2880
|
+
const hookResults = await Promise.allSettled(promises);
|
|
2881
|
+
if (hookResults.some((result2) => result2.status === "rejected")) {
|
|
2882
|
+
const hookNames = getHookNames();
|
|
2883
|
+
for (const [i, r] of hookResults.entries()) {
|
|
2884
|
+
r.name = hookNames[i];
|
|
2885
|
+
}
|
|
2886
|
+
const err = new AfterCommitError(result, hookResults);
|
|
2887
|
+
if (!catchAfterCommitErrors) throw err;
|
|
2888
|
+
for (const fn of catchAfterCommitErrors) {
|
|
2889
|
+
try {
|
|
2890
|
+
fn(err);
|
|
2891
|
+
} catch {
|
|
2892
|
+
}
|
|
2893
|
+
}
|
|
2873
2894
|
}
|
|
2874
2895
|
};
|
|
2896
|
+
const isInUserTransaction = (trx) => !!(trx && // when inside test transactions, compare transaction counts to ensure there is a user transaction.
|
|
2897
|
+
(!trx.testTransactionCount || trx.transactionId >= trx.testTransactionCount));
|
|
2875
2898
|
class Transaction {
|
|
2876
2899
|
async transaction(cbOrOptions, cb) {
|
|
2877
2900
|
let options;
|
|
@@ -2914,10 +2937,7 @@ class Transaction {
|
|
|
2914
2937
|
throw err;
|
|
2915
2938
|
});
|
|
2916
2939
|
if (log) log.afterQuery(commitSql$1, logData);
|
|
2917
|
-
|
|
2918
|
-
trx.afterCommit,
|
|
2919
|
-
result
|
|
2920
|
-
);
|
|
2940
|
+
runAfterCommit(trx.afterCommit, result);
|
|
2921
2941
|
return result;
|
|
2922
2942
|
} else {
|
|
2923
2943
|
try {
|
|
@@ -2942,7 +2962,7 @@ class Transaction {
|
|
|
2942
2962
|
if (transactionId === trx.testTransactionCount) {
|
|
2943
2963
|
const { afterCommit } = trx;
|
|
2944
2964
|
trx.afterCommit = void 0;
|
|
2945
|
-
|
|
2965
|
+
runAfterCommit(afterCommit, result);
|
|
2946
2966
|
}
|
|
2947
2967
|
return result;
|
|
2948
2968
|
} finally {
|
|
@@ -2977,42 +2997,95 @@ class Transaction {
|
|
|
2977
2997
|
}
|
|
2978
2998
|
isInTransaction() {
|
|
2979
2999
|
const trx = this.internal.transactionStorage.getStore();
|
|
2980
|
-
return
|
|
3000
|
+
return isInUserTransaction(trx);
|
|
2981
3001
|
}
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
|
|
2985
|
-
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
|
|
3002
|
+
/**
|
|
3003
|
+
* Schedules a hook to run after the outermost transaction commits:
|
|
3004
|
+
*
|
|
3005
|
+
* ```ts
|
|
3006
|
+
* await db.$transaction(async () => {
|
|
3007
|
+
* await db.table.create(data)
|
|
3008
|
+
* await db.table.where({ ...conditions }).update({ key: 'value' })
|
|
3009
|
+
*
|
|
3010
|
+
* db.$afterCommit(() => { // can be sync or async
|
|
3011
|
+
* console.log('after commit')
|
|
3012
|
+
* })
|
|
3013
|
+
* })
|
|
3014
|
+
* ```
|
|
3015
|
+
*
|
|
3016
|
+
* If used outside the transaction, the hook will be executed almost immediately, on the next microtask:
|
|
3017
|
+
*
|
|
3018
|
+
* ```ts
|
|
3019
|
+
* db.$afterCommit(async () => { // can be sync or async
|
|
3020
|
+
* console.log('after commit')
|
|
3021
|
+
* })
|
|
3022
|
+
* ```
|
|
3023
|
+
*
|
|
3024
|
+
* If the callback has no `try/catch` and throws an error,
|
|
3025
|
+
* this will cause `uncaughtException` if the callback is sync and `unhandledRejection` if it is async.
|
|
3026
|
+
*/
|
|
3027
|
+
afterCommit(hook) {
|
|
3028
|
+
const trx = this.internal.transactionStorage.getStore();
|
|
3029
|
+
if (isInUserTransaction(trx)) {
|
|
3030
|
+
(trx.afterCommit ?? (trx.afterCommit = [])).push(hook);
|
|
3031
|
+
} else {
|
|
3032
|
+
queueMicrotask(hook);
|
|
3033
|
+
}
|
|
3034
|
+
}
|
|
3035
|
+
}
|
|
3036
|
+
const runAfterCommit = (afterCommit, result) => {
|
|
3037
|
+
queueMicrotask(async () => {
|
|
3038
|
+
if (afterCommit) {
|
|
3039
|
+
const promises = [];
|
|
3040
|
+
let catchAfterCommitErrors;
|
|
3041
|
+
for (let i = 0, len = afterCommit.length; i < len; ) {
|
|
3042
|
+
const first = afterCommit[i];
|
|
3043
|
+
if (typeof first === "function") {
|
|
3044
|
+
try {
|
|
3045
|
+
promises.push(first());
|
|
3046
|
+
} catch (err) {
|
|
3047
|
+
promises.push(Promise.reject(err));
|
|
3048
|
+
}
|
|
3049
|
+
i++;
|
|
3050
|
+
} else {
|
|
3051
|
+
const q = afterCommit[i + 1];
|
|
3052
|
+
if (q.q.catchAfterCommitErrors) {
|
|
3053
|
+
(catchAfterCommitErrors ?? (catchAfterCommitErrors = [])).push(...q.q.catchAfterCommitErrors);
|
|
3054
|
+
}
|
|
3055
|
+
for (const fn of afterCommit[i + 2]) {
|
|
3056
|
+
try {
|
|
3057
|
+
promises.push(fn(first, q));
|
|
3058
|
+
} catch (err) {
|
|
3059
|
+
promises.push(Promise.reject(err));
|
|
3060
|
+
}
|
|
3061
|
+
}
|
|
3062
|
+
i += 3;
|
|
2998
3063
|
}
|
|
2999
3064
|
}
|
|
3000
|
-
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
|
|
3004
|
-
|
|
3005
|
-
|
|
3006
|
-
|
|
3007
|
-
|
|
3008
|
-
|
|
3009
|
-
|
|
3010
|
-
|
|
3065
|
+
const getHookNames = () => {
|
|
3066
|
+
const hookNames = [];
|
|
3067
|
+
for (let i = 0, len = afterCommit.length; i < len; ) {
|
|
3068
|
+
const first = afterCommit[i];
|
|
3069
|
+
if (typeof first === "function") {
|
|
3070
|
+
hookNames.push(first.name);
|
|
3071
|
+
i++;
|
|
3072
|
+
} else {
|
|
3073
|
+
for (const fn of afterCommit[i + 2]) {
|
|
3074
|
+
hookNames.push(fn.name);
|
|
3075
|
+
}
|
|
3076
|
+
i += 3;
|
|
3077
|
+
}
|
|
3011
3078
|
}
|
|
3012
|
-
|
|
3013
|
-
|
|
3079
|
+
return hookNames;
|
|
3080
|
+
};
|
|
3081
|
+
await _runAfterCommitHooks(
|
|
3082
|
+
result,
|
|
3083
|
+
promises,
|
|
3084
|
+
getHookNames,
|
|
3085
|
+
catchAfterCommitErrors
|
|
3086
|
+
);
|
|
3014
3087
|
}
|
|
3015
|
-
}
|
|
3088
|
+
});
|
|
3016
3089
|
};
|
|
3017
3090
|
|
|
3018
3091
|
const applyBatchTransforms = (q, batches) => {
|
|
@@ -3430,35 +3503,32 @@ const then = async (q, adapter, trx, beforeHooks, afterHooks, afterCommitHooks,
|
|
|
3430
3503
|
);
|
|
3431
3504
|
}
|
|
3432
3505
|
if (afterCommitHooks) {
|
|
3433
|
-
if (trx
|
|
3434
|
-
(!trx.testTransactionCount || trx.transactionId + 1 > trx.testTransactionCount)) {
|
|
3506
|
+
if (isInUserTransaction(trx)) {
|
|
3435
3507
|
(trx.afterCommit ?? (trx.afterCommit = [])).push(
|
|
3436
3508
|
result,
|
|
3437
3509
|
q,
|
|
3438
3510
|
afterCommitHooks
|
|
3439
3511
|
);
|
|
3440
3512
|
} else {
|
|
3441
|
-
const
|
|
3442
|
-
|
|
3443
|
-
|
|
3444
|
-
|
|
3445
|
-
|
|
3446
|
-
|
|
3447
|
-
|
|
3448
|
-
|
|
3513
|
+
const localResult = result;
|
|
3514
|
+
queueMicrotask(async () => {
|
|
3515
|
+
const promises = [];
|
|
3516
|
+
for (const fn of afterCommitHooks) {
|
|
3517
|
+
try {
|
|
3518
|
+
promises.push(
|
|
3519
|
+
fn(localResult, q)
|
|
3520
|
+
);
|
|
3521
|
+
} catch (err) {
|
|
3522
|
+
promises.push(Promise.reject(err));
|
|
3523
|
+
}
|
|
3449
3524
|
}
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
hookResults.map((result2, i) => ({
|
|
3456
|
-
...result2,
|
|
3457
|
-
name: afterCommitHooks[i].name
|
|
3458
|
-
})),
|
|
3459
|
-
q.q.catchAfterCommitError
|
|
3525
|
+
await _runAfterCommitHooks(
|
|
3526
|
+
localResult,
|
|
3527
|
+
promises,
|
|
3528
|
+
() => afterCommitHooks.map((h) => h.name),
|
|
3529
|
+
q.q.catchAfterCommitErrors
|
|
3460
3530
|
);
|
|
3461
|
-
}
|
|
3531
|
+
});
|
|
3462
3532
|
}
|
|
3463
3533
|
}
|
|
3464
3534
|
} else if (query.after) {
|
|
@@ -4327,7 +4397,7 @@ const getShapeFromSelect = (q, isSubQuery) => {
|
|
|
4327
4397
|
const { returnType } = it.q;
|
|
4328
4398
|
if (returnType === "value" || returnType === "valueOrThrow") {
|
|
4329
4399
|
const type = it.q.getColumn;
|
|
4330
|
-
|
|
4400
|
+
result[key] = type || UnknownColumn.instance;
|
|
4331
4401
|
} else {
|
|
4332
4402
|
result[key] = new JSONTextColumn(defaultSchemaConfig);
|
|
4333
4403
|
}
|
|
@@ -7976,7 +8046,7 @@ class AggregateMethods {
|
|
|
7976
8046
|
boolAnd(arg, options) {
|
|
7977
8047
|
return makeFnExpression(
|
|
7978
8048
|
this,
|
|
7979
|
-
|
|
8049
|
+
BooleanColumn.instance,
|
|
7980
8050
|
"bool_and",
|
|
7981
8051
|
[arg],
|
|
7982
8052
|
options
|
|
@@ -8005,7 +8075,7 @@ class AggregateMethods {
|
|
|
8005
8075
|
boolOr(arg, options) {
|
|
8006
8076
|
return makeFnExpression(
|
|
8007
8077
|
this,
|
|
8008
|
-
|
|
8078
|
+
BooleanColumn.instance,
|
|
8009
8079
|
"bool_or",
|
|
8010
8080
|
[arg],
|
|
8011
8081
|
options
|
|
@@ -8017,7 +8087,7 @@ class AggregateMethods {
|
|
|
8017
8087
|
every(arg, options) {
|
|
8018
8088
|
return makeFnExpression(
|
|
8019
8089
|
this,
|
|
8020
|
-
|
|
8090
|
+
BooleanColumn.instance,
|
|
8021
8091
|
"every",
|
|
8022
8092
|
[arg],
|
|
8023
8093
|
options
|
|
@@ -8050,7 +8120,7 @@ class AggregateMethods {
|
|
|
8050
8120
|
jsonAgg(arg, options) {
|
|
8051
8121
|
return makeFnExpression(
|
|
8052
8122
|
this,
|
|
8053
|
-
|
|
8123
|
+
JSONTextColumn.instance,
|
|
8054
8124
|
"json_agg",
|
|
8055
8125
|
[arg],
|
|
8056
8126
|
options
|
|
@@ -8062,7 +8132,7 @@ class AggregateMethods {
|
|
|
8062
8132
|
jsonbAgg(arg, options) {
|
|
8063
8133
|
return makeFnExpression(
|
|
8064
8134
|
this,
|
|
8065
|
-
|
|
8135
|
+
JSONTextColumn.instance,
|
|
8066
8136
|
"jsonb_agg",
|
|
8067
8137
|
[arg],
|
|
8068
8138
|
options
|
|
@@ -8103,7 +8173,7 @@ class AggregateMethods {
|
|
|
8103
8173
|
jsonObjectAgg(arg, options) {
|
|
8104
8174
|
return makeFnExpression(
|
|
8105
8175
|
this,
|
|
8106
|
-
|
|
8176
|
+
JSONTextColumn.instance,
|
|
8107
8177
|
"json_object_agg",
|
|
8108
8178
|
[{ pairs: arg }],
|
|
8109
8179
|
options
|
|
@@ -8115,7 +8185,7 @@ class AggregateMethods {
|
|
|
8115
8185
|
jsonbObjectAgg(arg, options) {
|
|
8116
8186
|
return makeFnExpression(
|
|
8117
8187
|
this,
|
|
8118
|
-
|
|
8188
|
+
JSONTextColumn.instance,
|
|
8119
8189
|
"jsonb_object_agg",
|
|
8120
8190
|
[{ pairs: arg }],
|
|
8121
8191
|
options
|
|
@@ -8146,7 +8216,7 @@ class AggregateMethods {
|
|
|
8146
8216
|
stringAgg(arg, delimiter, options) {
|
|
8147
8217
|
return makeFnExpression(
|
|
8148
8218
|
this,
|
|
8149
|
-
|
|
8219
|
+
TextColumn.instance,
|
|
8150
8220
|
"string_agg",
|
|
8151
8221
|
[arg, { value: delimiter }],
|
|
8152
8222
|
options
|
|
@@ -8172,7 +8242,7 @@ class AggregateMethods {
|
|
|
8172
8242
|
xmlAgg(arg, options) {
|
|
8173
8243
|
return makeFnExpression(
|
|
8174
8244
|
this,
|
|
8175
|
-
|
|
8245
|
+
XMLColumn.instance,
|
|
8176
8246
|
"xmlagg",
|
|
8177
8247
|
[arg],
|
|
8178
8248
|
options
|
|
@@ -9506,7 +9576,9 @@ class QueryHooks {
|
|
|
9506
9576
|
* })
|
|
9507
9577
|
* .catchAfterCommitError((err) => {
|
|
9508
9578
|
* // err is instance of AfterCommitError (see below)
|
|
9509
|
-
* })
|
|
9579
|
+
* })
|
|
9580
|
+
* // can be added multiple times, all catchers will be executed
|
|
9581
|
+
* .catchAfterCommitError((err) => {});
|
|
9510
9582
|
*
|
|
9511
9583
|
* // result is available even if an after commit hook has failed
|
|
9512
9584
|
* result.id;
|
|
@@ -9514,7 +9586,7 @@ class QueryHooks {
|
|
|
9514
9586
|
*/
|
|
9515
9587
|
catchAfterCommitError(fn) {
|
|
9516
9588
|
const q = _clone(this);
|
|
9517
|
-
q
|
|
9589
|
+
pushQueryValueImmutable(q, "catchAfterCommitErrors", fn);
|
|
9518
9590
|
return q;
|
|
9519
9591
|
}
|
|
9520
9592
|
}
|
|
@@ -13296,7 +13368,6 @@ exports.VirtualColumn = VirtualColumn;
|
|
|
13296
13368
|
exports.Where = Where;
|
|
13297
13369
|
exports.WithMethods = WithMethods;
|
|
13298
13370
|
exports.XMLColumn = XMLColumn;
|
|
13299
|
-
exports._afterCommitError = _afterCommitError;
|
|
13300
13371
|
exports._clone = _clone;
|
|
13301
13372
|
exports._getSelectableColumn = _getSelectableColumn;
|
|
13302
13373
|
exports._initQueryBuilder = _initQueryBuilder;
|
|
@@ -13358,6 +13429,7 @@ exports._queryWhereNotOneOf = _queryWhereNotOneOf;
|
|
|
13358
13429
|
exports._queryWhereNotSql = _queryWhereNotSql;
|
|
13359
13430
|
exports._queryWhereOneOf = _queryWhereOneOf;
|
|
13360
13431
|
exports._queryWhereSql = _queryWhereSql;
|
|
13432
|
+
exports._runAfterCommitHooks = _runAfterCommitHooks;
|
|
13361
13433
|
exports.addColumnParserToQuery = addColumnParserToQuery;
|
|
13362
13434
|
exports.addParserForRawExpression = addParserForRawExpression;
|
|
13363
13435
|
exports.addParserForSelectItem = addParserForSelectItem;
|
|
@@ -13402,6 +13474,7 @@ exports.identityToCode = identityToCode;
|
|
|
13402
13474
|
exports.indexInnerToCode = indexInnerToCode;
|
|
13403
13475
|
exports.indexToCode = indexToCode;
|
|
13404
13476
|
exports.isDefaultTimeStamp = isDefaultTimeStamp;
|
|
13477
|
+
exports.isInUserTransaction = isInUserTransaction;
|
|
13405
13478
|
exports.isQueryReturnsAll = isQueryReturnsAll;
|
|
13406
13479
|
exports.isSelectingCount = isSelectingCount;
|
|
13407
13480
|
exports.joinSubQuery = joinSubQuery;
|