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