pqb 0.52.0 → 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}"`}`;
2165
- }
2166
- if (col.data.computed) {
2167
- return `${col.data.computed.toSQL(ctx, quotedAs)} "${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
+ }
2168
2271
  }
2272
+ return this.columnsCache = columns;
2169
2273
  }
2170
- return `${quotedAs ? `${quotedAs}.` : ""}"${column}"${column === as ? "" : ` "${as}"`}`;
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;
2171
2291
  };
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);
2292
+ const pushQueryValueImmutable = (q, key, value) => {
2293
+ pushOrNewArrayToObjectImmutable(q.q, key, value);
2294
+ return q;
2174
2295
  };
2175
- const quoteSchemaAndTable = (schema, table) => {
2176
- return schema ? `"${schema}"."${table}"` : `"${table}"`;
2296
+ const setQueryObjectValueImmutable = (q, object, key, value) => {
2297
+ q.q[object] = {
2298
+ ...q.q[object],
2299
+ [key]: value
2300
+ };
2301
+ return q;
2177
2302
  };
2178
- const makeRowToJson = (table, shape, aliasName) => {
2179
- let isSimple = true;
2180
- const list = [];
2181
- 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;
2188
- }
2189
- list.push(
2190
- `'${key}', "${table}"."${aliasName && column.data.name || key}"${column.data.jsonCast ? `::${column.data.jsonCast}` : ""}`
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`
2191
2308
  );
2192
2309
  }
2193
- return isSimple ? `row_to_json("${table}".*)` : `CASE WHEN "${table}".* IS NULL THEN NULL ELSE json_build_object(` + list.join(", ") + ") END";
2194
- };
2195
-
2196
- const queryTypeWithLimitOne = {
2197
- one: true,
2198
- oneOrThrow: true,
2199
- value: true,
2200
- valueOrThrow: true
2201
2310
  };
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)
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}`
2209
2318
  );
2210
- ctx.sql.push(`ON (${columns?.join(", ") || ""})`);
2211
- }
2212
- };
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);
2223
2319
  }
2224
2320
  };
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);
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++;
2234
2327
  }
2235
- },
2236
- // `catch` returns a Promise, so it is chainable with then/catch.
2237
- catch: () => new Promise(noop)
2328
+ }
2329
+ setQueryObjectValueImmutable(q, key, as, emptyObject);
2330
+ return as;
2238
2331
  };
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
- );
2248
- return q;
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;
2249
2339
  };
2250
- const isQueryNone = (q) => q.then === noneMethods.then;
2251
-
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
2359
- );
2360
- }
2361
- return query;
2340
+ const getPrimaryKeys = (q) => {
2341
+ var _a;
2342
+ return (_a = q.internal).primaryKeys ?? (_a.primaryKeys = collectPrimaryKeys(q));
2362
2343
  };
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);
2344
+ const collectPrimaryKeys = (q) => {
2345
+ const primaryKeys = [];
2346
+ const { shape } = q.q;
2347
+ for (const key in shape) {
2348
+ if (shape[key].data.primaryKey) {
2349
+ primaryKeys.push(key);
2350
+ }
2370
2351
  }
2371
- setObjectValueImmutable(q, "joinedComputeds", joinKey, computeds);
2352
+ const pkey = q.internal.tableData.primaryKey;
2353
+ if (pkey) {
2354
+ primaryKeys.push(...pkey.columns);
2355
+ }
2356
+ return primaryKeys;
2372
2357
  };
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;
2392
- }
2358
+ const _queryAll = (q) => {
2359
+ q.q.returnType = "all";
2360
+ q.q.all = true;
2361
+ return q;
2362
+ };
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";
2393
2376
  }
2394
2377
  }
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;
2378
+ return query;
2406
2379
  };
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
- );
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";
2424
2393
  }
2425
2394
  }
2426
- as || (as = getQueryAs(arg));
2427
- setObjectValueImmutable(q.q, "joinedComputeds", as, arg.q.computeds);
2428
- pushQueryValueImmutable(q, "join", [type, arg, as]);
2395
+ return query;
2396
+ };
2397
+ const _queryExec = (q) => {
2398
+ q.q.returnType = "void";
2429
2399
  return q;
2430
2400
  };
2401
+ const _queryRows = (q) => {
2402
+ q.q.returnType = "rows";
2403
+ return q;
2404
+ };
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
+ };
2431
2409
 
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;
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
2430
+ );
2442
2431
  }
2443
- toSQL() {
2444
- return this.data.item.toSQL() + "[]".repeat(this.data.arrayDims);
2432
+ if (!select && data.joinedShapes?.[column]) {
2433
+ return `"${column}".r`;
2445
2434
  }
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 += ")";
2435
+ return simpleColumnToSQL(ctx, column, shape[column], quotedAs);
2436
+ };
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`;
2452
2444
  }
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);
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
+ }
2452
+ }
2453
+ }
2454
+ return simpleColumnToSQL(ctx, column, data.shape[column], quotedAs);
2461
2455
  }
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;
2468
2456
  };
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;
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;
2474
2463
  }
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 = "";
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);
2473
+ }
2474
+ return `"${tableName}"."${key}"`;
2475
+ }
2476
+ return `"${tableName}"."${key}"`;
2477
+ };
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}"`;
2513
2499
  }
2514
- } else {
2515
- recorded += character;
2516
2500
  }
2501
+ return column;
2517
2502
  }
2518
- return pos;
2519
- };
2520
-
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";
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}"`;
2513
+ }
2538
2514
  }
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";
2515
+ return `"${tableName}"."${key}"${key === as ? "" : ` "${as}"`}`;
2516
+ };
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
+ }
2548
2527
  }
2549
- toCode(ctx, key) {
2550
- const { numericPrecision, numericScale } = this.data;
2551
- return columnCode(
2552
- this,
2553
- ctx,
2554
- key,
2555
- `decimal(${numericPrecision || ""}${numericScale ? `, ${numericScale}` : ""})`
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;
2546
+ }
2547
+ list.push(
2548
+ `'${key}', "${table}"."${aliasName && column.data.name || key}"${column.data.jsonCast ? `::${column.data.jsonCast}` : ""}`
2556
2549
  );
2557
2550
  }
2558
- toSQL() {
2559
- const { numericPrecision, numericScale } = this.data;
2560
- return joinTruthy(
2561
- this.dataType,
2562
- numericPrecision ? numericScale ? `(${numericPrecision}, ${numericScale})` : `(${numericPrecision})` : void 0
2551
+ return isSimple ? `row_to_json("${table}".*)` : `CASE WHEN "${table}".* IS NULL THEN NULL ELSE json_build_object(` + list.join(", ") + ") END";
2552
+ };
2553
+
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) => {
@@ -4383,7 +4395,7 @@ const getShapeFromSelect = (q, isSubQuery) => {
4383
4395
  const { returnType } = it.q;
4384
4396
  if (returnType === "value" || returnType === "valueOrThrow") {
4385
4397
  const type = it.q.getColumn;
4386
- if (type) result[key] = type;
4398
+ result[key] = type || UnknownColumn.instance;
4387
4399
  } else {
4388
4400
  result[key] = new JSONTextColumn(defaultSchemaConfig);
4389
4401
  }
@@ -8032,7 +8044,7 @@ class AggregateMethods {
8032
8044
  boolAnd(arg, options) {
8033
8045
  return makeFnExpression(
8034
8046
  this,
8035
- emptyObject,
8047
+ BooleanColumn.instance,
8036
8048
  "bool_and",
8037
8049
  [arg],
8038
8050
  options
@@ -8061,7 +8073,7 @@ class AggregateMethods {
8061
8073
  boolOr(arg, options) {
8062
8074
  return makeFnExpression(
8063
8075
  this,
8064
- emptyObject,
8076
+ BooleanColumn.instance,
8065
8077
  "bool_or",
8066
8078
  [arg],
8067
8079
  options
@@ -8073,7 +8085,7 @@ class AggregateMethods {
8073
8085
  every(arg, options) {
8074
8086
  return makeFnExpression(
8075
8087
  this,
8076
- emptyObject,
8088
+ BooleanColumn.instance,
8077
8089
  "every",
8078
8090
  [arg],
8079
8091
  options
@@ -8106,7 +8118,7 @@ class AggregateMethods {
8106
8118
  jsonAgg(arg, options) {
8107
8119
  return makeFnExpression(
8108
8120
  this,
8109
- emptyObject,
8121
+ JSONTextColumn.instance,
8110
8122
  "json_agg",
8111
8123
  [arg],
8112
8124
  options
@@ -8118,7 +8130,7 @@ class AggregateMethods {
8118
8130
  jsonbAgg(arg, options) {
8119
8131
  return makeFnExpression(
8120
8132
  this,
8121
- emptyObject,
8133
+ JSONTextColumn.instance,
8122
8134
  "jsonb_agg",
8123
8135
  [arg],
8124
8136
  options
@@ -8159,7 +8171,7 @@ class AggregateMethods {
8159
8171
  jsonObjectAgg(arg, options) {
8160
8172
  return makeFnExpression(
8161
8173
  this,
8162
- emptyObject,
8174
+ JSONTextColumn.instance,
8163
8175
  "json_object_agg",
8164
8176
  [{ pairs: arg }],
8165
8177
  options
@@ -8171,7 +8183,7 @@ class AggregateMethods {
8171
8183
  jsonbObjectAgg(arg, options) {
8172
8184
  return makeFnExpression(
8173
8185
  this,
8174
- emptyObject,
8186
+ JSONTextColumn.instance,
8175
8187
  "jsonb_object_agg",
8176
8188
  [{ pairs: arg }],
8177
8189
  options
@@ -8202,7 +8214,7 @@ class AggregateMethods {
8202
8214
  stringAgg(arg, delimiter, options) {
8203
8215
  return makeFnExpression(
8204
8216
  this,
8205
- emptyObject,
8217
+ TextColumn.instance,
8206
8218
  "string_agg",
8207
8219
  [arg, { value: delimiter }],
8208
8220
  options
@@ -8228,7 +8240,7 @@ class AggregateMethods {
8228
8240
  xmlAgg(arg, options) {
8229
8241
  return makeFnExpression(
8230
8242
  this,
8231
- emptyObject,
8243
+ XMLColumn.instance,
8232
8244
  "xmlagg",
8233
8245
  [arg],
8234
8246
  options