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.js CHANGED
@@ -1274,1507 +1274,1519 @@ const Operators = {
1274
1274
  array
1275
1275
  };
1276
1276
 
1277
- class TextBaseColumn extends ColumnType {
1278
- constructor(schema, schemaType = schema.stringSchema()) {
1279
- super(schema, schemaType);
1280
- this.operators = Operators.text;
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
- limit !== void 0 ? schema.stringMax(limit) : schema.stringSchema()
1288
- );
1289
- this.data.maxChars = limit;
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 VarCharColumn extends LimitedTextBaseColumn {
1294
+ class DateColumn extends DateBaseColumn {
1299
1295
  constructor() {
1300
1296
  super(...arguments);
1301
- this.dataType = "varchar";
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
- `varchar(${maxChars ?? ""})${orchidCore.stringDataToCode(this.data, ctx.migration)}`
1304
+ `date()${orchidCore.dateDataToCode(this.data, ctx.migration)}`
1310
1305
  );
1311
1306
  }
1312
1307
  }
1313
- class StringColumn extends VarCharColumn {
1314
- constructor(schema, limit = 255) {
1315
- super(schema, limit);
1308
+ class DateTimeBaseClass extends DateBaseColumn {
1309
+ constructor(schema, dateTimePrecision) {
1310
+ super(schema);
1311
+ this.data.dateTimePrecision = dateTimePrecision;
1316
1312
  }
1317
- toCode(ctx, key) {
1318
- let max = this.data.maxChars;
1319
- if (max === 255) max = void 0;
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
- this,
1349
+ self,
1322
1350
  ctx,
1323
1351
  key,
1324
- `string(${max ?? ""})${orchidCore.stringDataToCode(this.data, ctx.migration)}`
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 TextColumn extends TextBaseColumn {
1352
- constructor(schema) {
1353
- super(schema, schema.stringSchema());
1354
- this.dataType = "text";
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 columnCode(this, ctx, key, `bytea()`);
1362
+ return timestampToCode(this, ctx, key);
1370
1363
  }
1371
1364
  }
1372
- class PointColumn extends ColumnType {
1373
- constructor(schema) {
1374
- super(schema, schema.stringSchema());
1375
- this.dataType = "point";
1376
- this.operators = Operators.text;
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 columnCode(this, ctx, key, `point()`);
1372
+ return timestampToCode(this, ctx, key);
1380
1373
  }
1381
1374
  }
1382
- class LineColumn extends ColumnType {
1383
- constructor(schema) {
1375
+ class TimeColumn extends ColumnType {
1376
+ constructor(schema, dateTimePrecision) {
1384
1377
  super(schema, schema.stringSchema());
1385
- this.dataType = "line";
1386
- this.operators = Operators.text;
1378
+ this.dataType = "time";
1379
+ this.operators = Operators.time;
1380
+ this.data.dateTimePrecision = dateTimePrecision;
1387
1381
  }
1388
1382
  toCode(ctx, key) {
1389
- return columnCode(this, ctx, key, `line()`);
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 LsegColumn extends ColumnType {
1393
- constructor(schema) {
1394
- super(schema, schema.stringSchema());
1395
- this.dataType = "lseg";
1396
- this.operators = Operators.text;
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
- return columnCode(this, ctx, key, `lseg()`);
1400
- }
1401
- }
1402
- class BoxColumn extends ColumnType {
1403
- constructor(schema) {
1404
- super(schema, schema.stringSchema());
1405
- this.dataType = "box";
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
- toCode(ctx, key) {
1409
- return columnCode(this, ctx, key, `box()`);
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
- class PathColumn extends ColumnType {
1413
- constructor(schema) {
1414
- super(schema, schema.stringSchema());
1415
- this.dataType = "path";
1416
- this.operators = Operators.text;
1417
- }
1418
- toCode(ctx, key) {
1419
- return columnCode(this, ctx, key, `path()`);
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
- class PolygonColumn extends ColumnType {
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
- return columnCode(this, ctx, key, `polygon()`);
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
- class CircleColumn extends ColumnType {
1433
- constructor(schema) {
1434
- super(schema, schema.stringSchema());
1435
- this.dataType = "circle";
1436
- this.operators = Operators.text;
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
- toCode(ctx, key) {
1439
- return columnCode(this, ctx, key, `circle()`);
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
- class MoneyColumn extends ColumnType {
1443
- constructor(schema) {
1444
- super(schema, schema.number());
1445
- this.dataType = "money";
1446
- this.operators = Operators.number;
1447
- setColumnDefaultParse(this, moneyParse);
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, `money()`);
1520
+ return columnCode(this, ctx, key, `json()`);
1451
1521
  }
1452
1522
  }
1453
- const moneyParse = Object.assign(
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 = "cidr";
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, `cidr()`);
1533
+ return columnCode(this, ctx, key, `jsonText()`);
1469
1534
  }
1470
1535
  }
1471
- class InetColumn extends ColumnType {
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.dataType = "inet";
1475
- this.operators = Operators.text;
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
- return columnCode(this, ctx, key, `inet()`);
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
- class MacAddrColumn extends ColumnType {
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, schema.stringSchema());
1484
- this.dataType = "macaddr";
1485
- this.operators = Operators.text;
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 columnCode(this, ctx, key, `macaddr()`);
1604
+ return intToCode(this, ctx, key, "smallint");
1605
+ }
1606
+ identity(options = {}) {
1607
+ return orchidCore.setColumnData(this, "identity", options);
1489
1608
  }
1490
1609
  }
1491
- class MacAddr8Column extends ColumnType {
1610
+ class IntegerColumn extends IntegerBaseColumn {
1492
1611
  constructor(schema) {
1493
- super(schema, schema.stringSchema());
1494
- this.dataType = "macaddr8";
1495
- this.operators = Operators.text;
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 columnCode(this, ctx, key, `macaddr8()`);
1618
+ return intToCode(this, ctx, key, "integer");
1619
+ }
1620
+ identity(options = {}) {
1621
+ return orchidCore.setColumnData(this, "identity", options);
1499
1622
  }
1500
1623
  }
1501
- class BitColumn extends ColumnType {
1502
- constructor(schema, length) {
1503
- super(schema, schema.bit(length));
1504
- this.dataType = "bit";
1505
- this.operators = Operators.text;
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
- const { length } = this.data;
1510
- return columnCode(this, ctx, key, `bit(${length})`);
1631
+ return intToCode(this, ctx, key, "bigint");
1511
1632
  }
1512
- toSQL() {
1513
- return orchidCore.joinTruthy(
1514
- this.dataType,
1515
- this.data.length !== void 0 && `(${this.data.length})`
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 BitVaryingColumn extends ColumnType {
1520
- constructor(schema, length) {
1521
- super(schema, schema.bit(length));
1522
- this.dataType = "varbit";
1523
- this.operators = Operators.text;
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
- const { length } = this.data;
1529
- return columnCode(this, ctx, key, `bitVarying(${length ?? ""})`);
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 orchidCore.joinTruthy(
1533
- this.dataType,
1534
- this.data.length !== void 0 && `(${this.data.length})`
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 TsVectorColumn extends ColumnType {
1539
- constructor(schema, defaultLanguage = orchidCore.getDefaultLanguage()) {
1540
- super(schema, schema.stringSchema());
1541
- this.defaultLanguage = defaultLanguage;
1542
- this.dataType = "tsvector";
1543
- this.operators = Operators.text;
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
- toCode(ctx, key) {
1546
- return columnCode(this, ctx, key, `tsvector()`);
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(this, ctx, key, `tsquery()`);
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
- const uuidDefaultSQL = "gen_random_uuid()";
1642
- const uuidDefault = new RawSQL(uuidDefaultSQL);
1643
- class UUIDColumn extends ColumnType {
1711
+ class BigSerialColumn extends NumberAsStringBaseColumn {
1644
1712
  constructor(schema) {
1645
- super(schema, schema.uuid());
1646
- this.dataType = "uuid";
1647
- this.operators = Operators.text;
1648
- this.data.defaultDefault = uuidDefault;
1713
+ super(schema);
1714
+ this.dataType = "int8";
1715
+ this.data.alias = "bigint";
1649
1716
  }
1650
- /**
1651
- * see {@link ColumnType.primaryKey}
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, `uuid()`);
1721
+ return columnCode(this, ctx, key, `bigSerial()`);
1660
1722
  }
1661
1723
  }
1662
- class XMLColumn extends ColumnType {
1663
- constructor(schema) {
1664
- super(schema, schema.stringSchema());
1665
- this.dataType = "xml";
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
- const dateTimeEncode = (input) => {
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.stringNumberDate(),
1691
- schema.stringSchema(),
1692
- schema.stringNumberDate()
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 DateColumn extends DateBaseColumn {
1815
+ class VarCharColumn extends LimitedTextBaseColumn {
1701
1816
  constructor() {
1702
1817
  super(...arguments);
1703
- this.dataType = "date";
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
- `date()${orchidCore.dateDataToCode(this.data, ctx.migration)}`
1826
+ `varchar(${maxChars ?? ""})${orchidCore.stringDataToCode(this.data, ctx.migration)}`
1711
1827
  );
1712
1828
  }
1713
1829
  }
1714
- class DateTimeBaseClass extends DateBaseColumn {
1715
- constructor(schema, dateTimePrecision) {
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
- class DateTimeTzBaseClass extends DateTimeBaseClass {
1727
- toSQL() {
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
- self,
1838
+ this,
1756
1839
  ctx,
1757
1840
  key,
1758
- `${self instanceof TimestampColumn ? "timestampNoTZ" : "timestamp"}(${p && p !== 6 ? p : ""})${orchidCore.dateDataToCode(self.data, ctx.migration)}`
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 TimestampColumn extends DateTimeBaseClass {
1763
- constructor() {
1764
- super(...arguments);
1765
- this.dataType = "timestamp";
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 timestampToCode(this, ctx, key);
1877
+ return textColumnToCode(this, ctx, key);
1769
1878
  }
1770
1879
  }
1771
- class TimestampTZColumn extends DateTimeTzBaseClass {
1772
- constructor() {
1773
- super(...arguments);
1774
- this.dataType = "timestamptz";
1775
- this.baseDataType = "timestamp";
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 timestampToCode(this, ctx, key);
1889
+ return columnCode(this, ctx, key, `bytea()`);
1779
1890
  }
1780
1891
  }
1781
- class TimeColumn extends ColumnType {
1782
- constructor(schema, dateTimePrecision) {
1892
+ class PointColumn extends ColumnType {
1893
+ constructor(schema) {
1783
1894
  super(schema, schema.stringSchema());
1784
- this.dataType = "time";
1785
- this.operators = Operators.time;
1786
- this.data.dateTimePrecision = dateTimePrecision;
1895
+ this.dataType = "point";
1896
+ this.operators = Operators.text;
1787
1897
  }
1788
1898
  toCode(ctx, key) {
1789
- const { dateTimePrecision } = this.data;
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 IntervalColumn extends ColumnType {
1802
- constructor(schema, fields, precision) {
1803
- super(schema, schema.timeInterval());
1804
- this.dataType = "interval";
1805
- this.operators = Operators.date;
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
- const { fields, precision } = this.data;
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.boolean());
1830
- this.dataType = "bool";
1831
- this.operators = Operators.boolean;
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, "boolean()");
1919
+ return columnCode(this, ctx, key, `lseg()`);
1837
1920
  }
1838
1921
  }
1839
- const parseItem = (input) => input[0] === "t";
1840
-
1841
- const encode$1 = (x) => x === null ? x : JSON.stringify(x);
1842
- class JSONColumn extends ColumnType {
1843
- constructor(schema, inputType) {
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, `json()`);
1929
+ return columnCode(this, ctx, key, `box()`);
1852
1930
  }
1853
1931
  }
1854
- class JSONTextColumn extends ColumnType {
1932
+ class PathColumn extends ColumnType {
1855
1933
  constructor(schema) {
1856
1934
  super(schema, schema.stringSchema());
1857
- this.dataType = "json";
1935
+ this.dataType = "path";
1858
1936
  this.operators = Operators.text;
1859
1937
  }
1860
1938
  toCode(ctx, key) {
1861
- return columnCode(this, ctx, key, `jsonText()`);
1939
+ return columnCode(this, ctx, key, `path()`);
1862
1940
  }
1863
1941
  }
1864
-
1865
- var __typeError = (msg) => {
1866
- throw TypeError(msg);
1867
- };
1868
- var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
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
- get query() {
1883
- return __privateGet(this, _query);
1948
+ toCode(ctx, key) {
1949
+ return columnCode(this, ctx, key, `polygon()`);
1884
1950
  }
1885
1951
  }
1886
- _query = new WeakMap();
1887
- class OrchidOrmInternalError extends Error {
1888
- constructor(query, message) {
1889
- super(message);
1890
- // `#query` is private to prevent it from serializing to not cause problems to test runner reports
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
- get query() {
1895
- return __privateGet(this, _query2);
1958
+ toCode(ctx, key) {
1959
+ return columnCode(this, ctx, key, `circle()`);
1896
1960
  }
1897
1961
  }
1898
- _query2 = new WeakMap();
1899
- class QueryError extends OrchidOrmInternalError {
1900
- get isUnique() {
1901
- return this.code === "23505";
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
- get columns() {
1904
- if (this.columnsCache) return this.columnsCache;
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
- class MoreThanOneRowError extends OrchidOrmInternalError {
1920
- constructor(query, message) {
1921
- super(query, message);
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 UnhandledTypeError extends OrchidOrmInternalError {
1925
- constructor(query, value) {
1926
- super(query, `Unhandled type: ${JSON.stringify(value)} received`);
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
- const _clone = (q) => q.clone();
1931
- const pushQueryArrayImmutable = (q, key, value) => {
1932
- const arr = q.q[key];
1933
- q.q[key] = arr ? [...arr, ...value] : value;
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
- const saveSearchAlias = (q, as, key) => {
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
- setQueryObjectValueImmutable(q, key, as, orchidCore.emptyObject);
1974
- return as;
1975
- };
1976
- const extendQuery = (q, methods) => {
1977
- const base = Object.create(q.baseQuery);
1978
- base.baseQuery = base;
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
- const pkey = q.internal.tableData.primaryKey;
1997
- if (pkey) {
1998
- primaryKeys.push(...pkey.columns);
2007
+ toCode(ctx, key) {
2008
+ return columnCode(this, ctx, key, `macaddr()`);
1999
2009
  }
2000
- return primaryKeys;
2001
- };
2002
- const _queryAll = (q) => {
2003
- q.q.returnType = "all";
2004
- q.q.all = true;
2005
- return q;
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
- return query;
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
- function simpleExistingColumnToSQL(ctx, key, column, quotedAs) {
2060
- const { data } = column;
2061
- return data.computed ? data.computed.toSQL(ctx, quotedAs) : `${quotedAs ? `${quotedAs}.` : ""}"${data.name || key}"`;
2062
- }
2063
- const columnToSql = (ctx, data, shape, column, quotedAs, select) => {
2064
- const index = column.indexOf(".");
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
- if (!select && data.joinedShapes?.[column]) {
2077
- return `"${column}".r`;
2028
+ toCode(ctx, key) {
2029
+ const { length } = this.data;
2030
+ return columnCode(this, ctx, key, `bit(${length})`);
2078
2031
  }
2079
- return simpleColumnToSQL(ctx, column, shape[column], quotedAs);
2080
- };
2081
- const maybeSelectedColumnToSql = (ctx, data, column, quotedAs) => {
2082
- const index = column.indexOf(".");
2083
- if (index !== -1) {
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
- const columnWithDotToSql = (ctx, data, shape, column, index, quotedAs, select) => {
2102
- const table = column.slice(0, index);
2103
- const key = column.slice(index + 1);
2104
- if (key === "*") {
2105
- const shape2 = data.joinedShapes?.[table];
2106
- return shape2 ? select ? makeRowToJson(table, shape2, true) : `"${table}".*` : column;
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
- const tableName = data.aliases?.[table] || table;
2109
- const quoted = `"${table}"`;
2110
- const col = quoted === quotedAs ? shape[key] : data.joinedShapes?.[tableName]?.[key];
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
- return `"${tableName}"."${key}"`;
2121
- };
2122
- const columnToSqlWithAs = (ctx, data, column, as, quotedAs, select, jsonList) => {
2123
- const index = column.indexOf(".");
2124
- return index !== -1 ? tableColumnToSqlWithAs(
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
- const tableName = data.aliases?.[table] || table;
2148
- const quoted = `"${table}"`;
2149
- const col = quoted === quotedAs ? data.shape[key] : data.joinedShapes?.[tableName][key];
2150
- if (jsonList) jsonList[as] = col;
2151
- if (col) {
2152
- if (col.data.name && col.data.name !== key) {
2153
- return `"${tableName}"."${col.data.name}" "${as}"`;
2154
- }
2155
- if (col.data.computed) {
2156
- return `${col.data.computed.toSQL(ctx, quoted)} "${as}"`;
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
- return `"${tableName}"."${key}"${key === as ? "" : ` "${as}"`}`;
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
- const ownColumnToSqlWithAs = (ctx, data, column, as, quotedAs, select, jsonList) => {
2162
- const col = data.shape[column];
2163
- if (jsonList) jsonList[as] = col;
2164
- if (col) {
2165
- if (col.data.name && col.data.name !== column) {
2166
- return `${quotedAs ? `${quotedAs}.` : ""}"${col.data.name}"${col.data.name === as ? "" : ` "${as}"`}`;
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
- if (col.data.computed) {
2169
- return `${col.data.computed.toSQL(ctx, quotedAs)} "${as}"`;
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
- return `${quotedAs ? `${quotedAs}.` : ""}"${column}"${column === as ? "" : ` "${as}"`}`;
2331
+ setQueryObjectValueImmutable(q, key, as, orchidCore.emptyObject);
2332
+ return as;
2173
2333
  };
2174
- const rawOrColumnToSql = (ctx, data, expr, quotedAs, shape = data.shape, select) => {
2175
- return typeof expr === "string" ? columnToSql(ctx, data, shape, expr, quotedAs, select) : expr.toSQL(ctx, quotedAs);
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 quoteSchemaAndTable = (schema, table) => {
2178
- return schema ? `"${schema}"."${table}"` : `"${table}"`;
2342
+ const getPrimaryKeys = (q) => {
2343
+ var _a;
2344
+ return (_a = q.internal).primaryKeys ?? (_a.primaryKeys = collectPrimaryKeys(q));
2179
2345
  };
2180
- const makeRowToJson = (table, shape, aliasName) => {
2181
- let isSimple = true;
2182
- const list = [];
2346
+ const collectPrimaryKeys = (q) => {
2347
+ const primaryKeys = [];
2348
+ const { shape } = q.q;
2183
2349
  for (const key in shape) {
2184
- const column = shape[key];
2185
- if (column.data.explicitSelect) {
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
- return isSimple ? `row_to_json("${table}".*)` : `CASE WHEN "${table}".* IS NULL THEN NULL ELSE json_build_object(` + list.join(", ") + ") END";
2354
+ const pkey = q.internal.tableData.primaryKey;
2355
+ if (pkey) {
2356
+ primaryKeys.push(...pkey.columns);
2357
+ }
2358
+ return primaryKeys;
2196
2359
  };
2197
-
2198
- const queryTypeWithLimitOne = {
2199
- one: true,
2200
- oneOrThrow: true,
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 isQueryReturnsAll = (q) => !q.q.returnType || q.q.returnType === "all";
2205
-
2206
- const pushDistinctSql = (ctx, table, distinct, quotedAs) => {
2207
- ctx.sql.push("DISTINCT");
2208
- if (distinct.length) {
2209
- const columns = distinct?.map(
2210
- (item) => rawOrColumnToSql(ctx, table.q, item, quotedAs)
2211
- );
2212
- ctx.sql.push(`ON (${columns?.join(", ") || ""})`);
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 noneResult = (q, queryData, type) => {
2217
- if (!type || type === "all" || type === "rows" || type === "pluck") {
2218
- return [];
2219
- } else if (type === "one" || type === "value" || type === "void") {
2220
- return queryData.notFoundDefault;
2221
- } else if (type === "valueOrThrow" && queryData.returning) {
2222
- return 0;
2223
- } else {
2224
- throw new NotFoundError(q);
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 noneMethods = {
2228
- // `then` resolves or rejects based on a return type of the query.
2229
- // It is `async` so it returns a chainable Promise.
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 _queryNone = (q) => {
2242
- if (isQueryNone(q)) return q;
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 isQueryNone = (q) => q.then === noneMethods.then;
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
- const _join = (query, require, type, first, args) => {
2255
- let joinKey;
2256
- let shape;
2257
- let parsers;
2258
- let batchParsers;
2259
- let computeds;
2260
- let joinSubQuery = false;
2261
- first = preprocessJoinArg(query, first);
2262
- if (typeof first === "object") {
2263
- let isInternalJoin;
2264
- if ("_internalJoin" in first) {
2265
- isInternalJoin = true;
2266
- first = first._internalJoin;
2267
- }
2268
- if (require && isQueryNone(first)) {
2269
- return _queryNone(query);
2270
- }
2271
- const q = first;
2272
- if (!isInternalJoin) {
2273
- joinSubQuery = getIsJoinSubQuery(q);
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
- return query;
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
- orchidCore.setObjectValueImmutable(q, "joinedComputeds", joinKey, computeds);
2437
+ return simpleColumnToSQL(ctx, column, shape[column], quotedAs);
2374
2438
  };
2375
- const _joinLateralProcessArg = (q, arg, cb) => {
2376
- let relation;
2377
- if (typeof arg === "string") {
2378
- relation = q.relations[arg];
2379
- if (relation) {
2380
- arg = _clone(relation.relationConfig.query);
2381
- } else {
2382
- const w = q.q.withShapes?.[arg];
2383
- if (w) {
2384
- const t = Object.create(q.queryBuilder);
2385
- t.table = arg;
2386
- t.shape = w.shape;
2387
- t.computeds = w.computeds;
2388
- t.q = {
2389
- ...t.q,
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 _joinLateral = (self, type, arg, as) => {
2410
- const q = self;
2411
- arg.q.joinTo = q;
2412
- const joinedAs = getQueryAs(q);
2413
- orchidCore.setObjectValueImmutable(arg.q, "joinedShapes", joinedAs, q.q.shape);
2414
- const joinKey = as || arg.q.as || arg.table;
2415
- if (joinKey) {
2416
- const shape = getShapeFromSelect(arg, true);
2417
- orchidCore.setObjectValueImmutable(q.q, "joinedShapes", joinKey, shape);
2418
- orchidCore.setObjectValueImmutable(q.q, "joinedParsers", joinKey, arg.q.parsers);
2419
- if (arg.q.batchParsers) {
2420
- orchidCore.setObjectValueImmutable(
2421
- q.q,
2422
- "joinedBatchParsers",
2423
- joinKey,
2424
- arg.q.batchParsers
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
- as || (as = getQueryAs(arg));
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
- class ArrayColumn extends ColumnType {
2435
- constructor(schema, item, inputType, outputType, queryType) {
2436
- super(schema, inputType, outputType, queryType);
2437
- this.dataType = "array";
2438
- this.operators = Operators.array;
2439
- item.data.isNullable = true;
2440
- setColumnDefaultParse(this, (input) => parse$1.call(this, input));
2441
- this.data.item = item instanceof ArrayColumn ? item.data.item : item;
2442
- this.data.name = item.data.name;
2443
- this.data.arrayDims = item instanceof ArrayColumn ? item.data.arrayDims + 1 : 1;
2444
- }
2445
- toSQL() {
2446
- return this.data.item.toSQL() + "[]".repeat(this.data.arrayDims);
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
- toCode(ctx, key) {
2449
- let open = "array(";
2450
- let close = ")";
2451
- for (let i = 1; i < this.data.arrayDims; i++) {
2452
- open += `${ctx.t}.array(`;
2453
- close += ")";
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 parsePostgresArray = (source, entries, transform) => {
2472
- let pos = 0;
2473
- if (source[0] === "[") {
2474
- pos = source.indexOf("=") + 1;
2475
- if (!pos) pos = source.length;
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
- if (source[pos] === "{") pos++;
2478
- let recorded = "";
2479
- while (pos < source.length) {
2480
- const character = source[pos++];
2481
- if (character === "{") {
2482
- const innerEntries = [];
2483
- entries.push(innerEntries);
2484
- pos += parsePostgresArray(source.slice(pos - 1), innerEntries, transform) - 1;
2485
- } else if (character === "}") {
2486
- if (recorded) {
2487
- entries.push(
2488
- recorded === "NULL" ? null : transform ? transform(recorded) : recorded
2489
- );
2490
- }
2491
- return pos;
2492
- } else if (character === '"') {
2493
- let esc = false;
2494
- let rec = "";
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 pos;
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
- class NumberBaseColumn extends ColumnType {
2524
- constructor() {
2525
- super(...arguments);
2526
- this.operators = Operators.number;
2527
- }
2528
- }
2529
- class IntegerBaseColumn extends NumberBaseColumn {
2530
- constructor(schema) {
2531
- super(schema, schema.int());
2532
- this.data.int = true;
2533
- }
2534
- }
2535
- class NumberAsStringBaseColumn extends ColumnType {
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
- const skipNumberMethods = { int: true };
2569
- const intToCode = (column, ctx, key, alias) => {
2570
- let code;
2571
- if (column.data.identity) {
2572
- code = identityToCode(column.data.identity, alias);
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
- code = [`${alias}()`];
2582
+ throw new NotFoundError(q);
2575
2583
  }
2576
- orchidCore.addCode(
2577
- code,
2578
- orchidCore.numberDataToCode(column.data, ctx.migration, skipNumberMethods)
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 columnCode(column, ctx, key, code);
2608
+ return q;
2581
2609
  };
2582
- class SmallIntColumn extends IntegerBaseColumn {
2583
- constructor(schema) {
2584
- super(schema);
2585
- this.dataType = "int2";
2586
- this.data.alias = "smallint";
2587
- this.data.parseItem = parseInt;
2588
- }
2589
- toCode(ctx, key) {
2590
- return intToCode(this, ctx, key, "smallint");
2591
- }
2592
- identity(options = {}) {
2593
- return orchidCore.setColumnData(this, "identity", options);
2594
- }
2595
- }
2596
- class IntegerColumn extends IntegerBaseColumn {
2597
- constructor(schema) {
2598
- super(schema);
2599
- this.dataType = "int4";
2600
- this.data.alias = "integer";
2601
- this.data.parseItem = parseInt;
2602
- }
2603
- toCode(ctx, key) {
2604
- return intToCode(this, ctx, key, "integer");
2605
- }
2606
- identity(options = {}) {
2607
- return orchidCore.setColumnData(this, "identity", options);
2608
- }
2609
- }
2610
- class BigIntColumn extends NumberAsStringBaseColumn {
2611
- constructor(schema) {
2612
- super(schema);
2613
- this.dataType = "int8";
2614
- this.data.alias = "bigint";
2615
- }
2616
- toCode(ctx, key) {
2617
- return intToCode(this, ctx, key, "bigint");
2618
- }
2619
- identity(options = {}) {
2620
- return orchidCore.setColumnData(this, "identity", options);
2621
- }
2622
- }
2623
- class RealColumn extends NumberBaseColumn {
2624
- constructor(schema) {
2625
- super(schema, schema.number());
2626
- this.dataType = "float4";
2627
- this.data.alias = "real";
2628
- this.data.parseItem = parseFloat;
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
- toCode(ctx, key) {
2631
- return columnCode(
2632
- this,
2633
- ctx,
2634
- key,
2635
- `real()${orchidCore.numberDataToCode(this.data, ctx.migration)}`
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
- class DoublePrecisionColumn extends NumberAsStringBaseColumn {
2640
- constructor(schema) {
2641
- super(schema);
2642
- this.dataType = "float8";
2643
- this.data.alias = "doublePrecision";
2644
- }
2645
- toCode(ctx, key) {
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
- class SerialColumn extends IntegerBaseColumn {
2674
- constructor(schema) {
2675
- super(schema);
2676
- this.dataType = "int4";
2677
- this.data.int = true;
2678
- this.data.alias = "serial";
2679
- this.data.parseItem = parseInt;
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
- toSQL() {
2682
- return "serial";
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
- toCode(ctx, key) {
2685
- return columnCode(
2686
- this,
2687
- ctx,
2688
- key,
2689
- `serial()${orchidCore.numberDataToCode(
2690
- this.data,
2691
- ctx.migration,
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
- class BigSerialColumn extends NumberAsStringBaseColumn {
2698
- constructor(schema) {
2699
- super(schema);
2700
- this.dataType = "int8";
2701
- this.data.alias = "bigint";
2702
- }
2703
- toSQL() {
2704
- return "bigserial";
2705
- }
2706
- toCode(ctx, key) {
2707
- return columnCode(this, ctx, key, `bigSerial()`);
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
- const parseDateToDate = (value) => new Date(value);
2712
- const defaultSchemaConfig = {
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 _afterCommitError = (result, hookResults, catchAfterCommitError) => {
2868
- const err = new AfterCommitError(result, hookResults);
2869
- if (catchAfterCommitError) {
2870
- catchAfterCommitError(err);
2871
- } else {
2872
- throw err;
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
- await runAfterCommit(
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
- await runAfterCommit(afterCommit, result);
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 !!(trx && (!trx.testTransactionCount || trx.transactionId >= trx.testTransactionCount));
3000
+ return isInUserTransaction(trx);
2981
3001
  }
2982
- }
2983
- const runAfterCommit = async (afterCommit, result) => {
2984
- if (afterCommit) {
2985
- const promises = [];
2986
- let catchAfterCommitError;
2987
- for (let i = 0, len = afterCommit.length; i < len; i += 3) {
2988
- const result2 = afterCommit[i];
2989
- const q = afterCommit[i + 1];
2990
- if (q.q.catchAfterCommitError) {
2991
- catchAfterCommitError = q.q.catchAfterCommitError;
2992
- }
2993
- for (const fn of afterCommit[i + 2]) {
2994
- try {
2995
- promises.push(fn(result2, q));
2996
- } catch (err) {
2997
- promises.push(Promise.reject(err));
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
- const hookResults = await Promise.allSettled(promises);
3002
- if (hookResults.some((result2) => result2.status === "rejected")) {
3003
- const resultsWithNames = [];
3004
- let r = 0;
3005
- for (let i = 0, len = afterCommit.length; i < len; i += 3) {
3006
- for (const fn of afterCommit[i + 2]) {
3007
- resultsWithNames.push({
3008
- ...hookResults[r++],
3009
- name: fn.name
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
- _afterCommitError(result, resultsWithNames, catchAfterCommitError);
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 && // when inside test transactions, push to a transaction only unless it's the outer user transaction.
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 promises = [];
3442
- for (const fn of afterCommitHooks) {
3443
- try {
3444
- promises.push(
3445
- fn(result, q)
3446
- );
3447
- } catch (err) {
3448
- promises.push(Promise.reject(err));
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
- const hookResults = await Promise.allSettled(promises);
3452
- if (hookResults.some((result2) => result2.status === "rejected")) {
3453
- _afterCommitError(
3454
- result,
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
- if (type) result[key] = type;
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
- orchidCore.emptyObject,
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
- orchidCore.emptyObject,
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
- orchidCore.emptyObject,
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
- orchidCore.emptyObject,
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
- orchidCore.emptyObject,
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
- orchidCore.emptyObject,
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
- orchidCore.emptyObject,
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
- orchidCore.emptyObject,
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
- orchidCore.emptyObject,
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.q.catchAfterCommitError = fn;
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;