pqb 0.16.0 → 0.16.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +999 -393
- package/dist/index.js +926 -536
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +926 -536
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -1507,379 +1507,664 @@ declare class OnQueryBuilder<S extends QueryBase = QueryBase, J extends QueryBas
|
|
|
1507
1507
|
_onJsonPathEquals<T extends OnQueryBuilder>(this: T, ...args: OnJsonPathEqualsArgs<T>): T;
|
|
1508
1508
|
}
|
|
1509
1509
|
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
* ```ts
|
|
1530
|
-
* db.table
|
|
1531
|
-
* .search({
|
|
1532
|
-
* as: 'search',
|
|
1533
|
-
* vector: 'textVector',
|
|
1534
|
-
* query: 'query',
|
|
1535
|
-
* })
|
|
1536
|
-
* .select({
|
|
1537
|
-
* // `body` is a column name
|
|
1538
|
-
* highlightedText: (q) => q.headline('search', { text: 'body' }),
|
|
1539
|
-
* });
|
|
1540
|
-
* ```
|
|
1541
|
-
*
|
|
1542
|
-
* `text` can be a raw SQL, here we are joining multiple columns:
|
|
1543
|
-
*
|
|
1544
|
-
* ```ts
|
|
1545
|
-
* import { raw } from 'orchid-orm';
|
|
1546
|
-
*
|
|
1547
|
-
* db.table
|
|
1548
|
-
* .search({
|
|
1549
|
-
* as: 'search',
|
|
1550
|
-
* vector: 'titleAndBodyVector',
|
|
1551
|
-
* query: 'query',
|
|
1552
|
-
* })
|
|
1553
|
-
* .select({
|
|
1554
|
-
* highlightedText: (q) =>
|
|
1555
|
-
* q.headline('search', { text: raw`concat_ws(' ', title, body)` }),
|
|
1556
|
-
* });
|
|
1557
|
-
* ```
|
|
1558
|
-
*
|
|
1559
|
-
* `headline` supports a string for `options`, see details [in Postgres doc](https://www.postgresql.org/docs/current/textsearch-controls.html#TEXTSEARCH-HEADLINE).
|
|
1560
|
-
*
|
|
1561
|
-
* Provide a simple string or a raw SQL:
|
|
1562
|
-
*
|
|
1563
|
-
* ```ts
|
|
1564
|
-
* db.table
|
|
1565
|
-
* .search({
|
|
1566
|
-
* as: 'search',
|
|
1567
|
-
* in: 'body',
|
|
1568
|
-
* query: 'query',
|
|
1569
|
-
* })
|
|
1570
|
-
* .select({
|
|
1571
|
-
* highlightedText: (q) =>
|
|
1572
|
-
* q.headline('search', {
|
|
1573
|
-
* options:
|
|
1574
|
-
* 'MaxFragments=10, MaxWords=7, MinWords=3, StartSel=<<, StopSel=>>',
|
|
1575
|
-
* }),
|
|
1576
|
-
* });
|
|
1577
|
-
* ```
|
|
1578
|
-
*
|
|
1579
|
-
* @param search - name of the search to use the query from
|
|
1580
|
-
* @param options - `text` for a text source, `options` for `ts_headline` options
|
|
1581
|
-
*/
|
|
1582
|
-
headline(search: string | undefined extends T['meta']['tsQuery'] ? never : Exclude<T['meta']['tsQuery'], undefined>, options?: {
|
|
1583
|
-
text?: SelectableOrExpressionOfType<T, TextColumn>;
|
|
1584
|
-
options?: string | Expression;
|
|
1585
|
-
}): ColumnExpression<TextColumn>;
|
|
1586
|
-
}
|
|
1587
|
-
}
|
|
1588
|
-
type SearchArg<T extends QueryBase, As extends string> = {
|
|
1589
|
-
as?: As;
|
|
1590
|
-
order?: OrderTsQueryConfig;
|
|
1591
|
-
} & ({
|
|
1592
|
-
language?: string | Expression;
|
|
1593
|
-
} | {
|
|
1594
|
-
languageColumn?: keyof T['selectable'];
|
|
1595
|
-
}) & ({
|
|
1596
|
-
text: string | Expression;
|
|
1597
|
-
} | {
|
|
1598
|
-
in: MaybeArray<keyof T['selectable']> | {
|
|
1599
|
-
[K in keyof T['selectable']]?: SearchWeight;
|
|
1600
|
-
};
|
|
1601
|
-
} | {
|
|
1602
|
-
vector: {
|
|
1603
|
-
[K in keyof T['selectable']]: T['selectable'][K]['column']['dataType'] extends 'tsvector' ? K : never;
|
|
1604
|
-
}[keyof T['selectable']];
|
|
1605
|
-
}) & ({
|
|
1606
|
-
query: string | Expression;
|
|
1607
|
-
} | {
|
|
1608
|
-
plainQuery: string | Expression;
|
|
1609
|
-
} | {
|
|
1610
|
-
phraseQuery: string | Expression;
|
|
1611
|
-
} | {
|
|
1612
|
-
tsQuery: string | Expression;
|
|
1613
|
-
});
|
|
1614
|
-
type WhereSearchResult<T extends QueryBase, As extends string> = T & {
|
|
1510
|
+
type WhereArg<T extends QueryBase> = {
|
|
1511
|
+
[K in keyof T['selectable'] | 'NOT' | 'OR' | 'IN' | 'EXISTS']?: K extends 'NOT' ? MaybeArray<WhereArg<T>> : K extends 'OR' ? MaybeArray<WhereArg<T>>[] : K extends 'IN' ? MaybeArray<{
|
|
1512
|
+
columns: (keyof T['selectable'])[];
|
|
1513
|
+
values: unknown[][] | Query | Expression;
|
|
1514
|
+
}> : K extends keyof T['selectable'] ? T['selectable'][K]['column']['type'] | null | ColumnOperators<T['selectable'], K> | Expression | Query : never;
|
|
1515
|
+
} | QueryBase | Expression | ((q: WhereQueryBuilder<T>) => WhereQueryBuilder);
|
|
1516
|
+
type WhereArgs<T extends QueryBase> = WhereArg<T>[] | TemplateLiteralArgs;
|
|
1517
|
+
type WhereInColumn<T extends QueryBase> = keyof T['selectable'] | [keyof T['selectable'], ...(keyof T['selectable'])[]];
|
|
1518
|
+
type WhereInValues<T extends QueryBase, Column extends WhereInColumn<T>> = Column extends keyof T['selectable'] ? T['selectable'][Column]['column']['type'][] | Query | Expression : ({
|
|
1519
|
+
[I in keyof Column]: Column[I] extends keyof T['selectable'] ? T['selectable'][Column[I]]['column']['type'] : never;
|
|
1520
|
+
} & {
|
|
1521
|
+
length: Column extends {
|
|
1522
|
+
length: number;
|
|
1523
|
+
} ? Column['length'] : never;
|
|
1524
|
+
})[] | Query | Expression;
|
|
1525
|
+
type WhereInArg<T extends Pick<Query, 'selectable'>> = {
|
|
1526
|
+
[K in keyof T['selectable']]?: T['selectable'][K]['column']['type'][] | Query | Expression;
|
|
1527
|
+
};
|
|
1528
|
+
type WhereResult<T extends QueryBase> = T & {
|
|
1615
1529
|
meta: {
|
|
1616
|
-
|
|
1530
|
+
hasWhere: true;
|
|
1617
1531
|
};
|
|
1618
1532
|
};
|
|
1619
|
-
|
|
1620
|
-
|
|
1533
|
+
/**
|
|
1534
|
+
* Adds `where` arguments to query data: SQL template string is added as `RawSQL` object, other arguments are added as is.
|
|
1535
|
+
*
|
|
1536
|
+
* @param q - query object to add the data to
|
|
1537
|
+
* @param args - `where` arguments, may be a template literal
|
|
1538
|
+
*/
|
|
1539
|
+
declare const addWhere: <T extends QueryBase>(q: T, args: WhereArgs<T>) => WhereResult<T>;
|
|
1540
|
+
/**
|
|
1541
|
+
* Adds `where` arguments to query data with a `NOT` keyword: SQL template string is added as `RawSQL` object, other arguments are added as is.
|
|
1542
|
+
*
|
|
1543
|
+
* @param q - query object to add the data to
|
|
1544
|
+
* @param args - `where` arguments, may be a template literal
|
|
1545
|
+
*/
|
|
1546
|
+
declare const addWhereNot: <T extends QueryBase>(q: T, args: WhereArgs<T>) => WhereResult<T>;
|
|
1547
|
+
/**
|
|
1548
|
+
* Adds `where` arguments to query data. Arguments will be separated from each other with `OR`.
|
|
1549
|
+
*
|
|
1550
|
+
* @param q - query object to add the data to
|
|
1551
|
+
* @param args - `where` arguments, may be a template literal
|
|
1552
|
+
*/
|
|
1553
|
+
declare const addOr: <T extends QueryBase>(q: T, args: WhereArg<T>[]) => WhereResult<T>;
|
|
1554
|
+
/**
|
|
1555
|
+
* Adds `where` arguments to query data with a `NOT` keyword. Arguments will be separated from each other with `OR`.
|
|
1556
|
+
*
|
|
1557
|
+
* @param q - query object to add the data to
|
|
1558
|
+
* @param args - `where` arguments, may be a template literal
|
|
1559
|
+
*/
|
|
1560
|
+
declare const addOrNot: <T extends QueryBase>(q: T, args: WhereArg<T>[]) => WhereResult<T>;
|
|
1561
|
+
/**
|
|
1562
|
+
* Process arguments of `whereIn` to add them to query data properly.
|
|
1563
|
+
*
|
|
1564
|
+
* @param q - query object to add the data to.
|
|
1565
|
+
* @param and - `true` to join arguments with `AND`, `false` to join them with `OR.
|
|
1566
|
+
* @param arg - `whereIn` argument: can be a single column name, tuple of column names, or object with column names and values.
|
|
1567
|
+
* @param values - if the `arg` is a column name or a tuple, `values` are the values for the column/columns. If `arg` is an object, `values` are `undefined`.
|
|
1568
|
+
* @param not - adds the `NOT` keyword.
|
|
1569
|
+
*/
|
|
1570
|
+
declare const addWhereIn: <T extends QueryBase>(q: T, and: boolean, arg: unknown, values: unknown[] | unknown[][] | Query | Expression | undefined, not?: boolean) => WhereResult<T>;
|
|
1571
|
+
declare abstract class Where extends QueryBase {
|
|
1621
1572
|
/**
|
|
1622
|
-
*
|
|
1573
|
+
* Constructing `WHERE` conditions:
|
|
1623
1574
|
*
|
|
1624
|
-
*
|
|
1575
|
+
* ```ts
|
|
1576
|
+
* db.table.where({
|
|
1577
|
+
* // column of the current table
|
|
1578
|
+
* name: 'John',
|
|
1625
1579
|
*
|
|
1626
|
-
*
|
|
1580
|
+
* // table name may be specified, it can be the name of a joined table
|
|
1581
|
+
* 'table.lastName': 'Johnsonuk',
|
|
1627
1582
|
*
|
|
1628
|
-
*
|
|
1629
|
-
*
|
|
1583
|
+
* // object with operators, see the "column operators" section to see a full list of them:
|
|
1584
|
+
* age: {
|
|
1585
|
+
* gt: 30,
|
|
1586
|
+
* lt: 70,
|
|
1587
|
+
* },
|
|
1630
1588
|
*
|
|
1631
|
-
*
|
|
1632
|
-
*
|
|
1589
|
+
* // where column equals to raw SQL
|
|
1590
|
+
* column: db.table.sql`raw expression`,
|
|
1633
1591
|
* });
|
|
1634
1592
|
* ```
|
|
1635
1593
|
*
|
|
1636
|
-
*
|
|
1594
|
+
* `undefined` values are ignored, so you can supply a partial object with conditions:
|
|
1637
1595
|
*
|
|
1638
|
-
* ```
|
|
1639
|
-
*
|
|
1596
|
+
* ```ts
|
|
1597
|
+
* type Params = {
|
|
1598
|
+
* // allow providing exact age, or lower or greate than
|
|
1599
|
+
* age?: number | { lt?: number; gt?: number };
|
|
1600
|
+
* };
|
|
1601
|
+
*
|
|
1602
|
+
* const loadRecords = async (params: Params) => {
|
|
1603
|
+
* // this will load all records if params is an empty object
|
|
1604
|
+
* const records = await db.table.where(params);
|
|
1605
|
+
* };
|
|
1640
1606
|
* ```
|
|
1641
1607
|
*
|
|
1642
|
-
*
|
|
1608
|
+
* It supports a sub-query that is selecting a single value to compare it with a column:
|
|
1643
1609
|
*
|
|
1644
1610
|
* ```ts
|
|
1645
|
-
* db.table.
|
|
1646
|
-
*
|
|
1647
|
-
*
|
|
1648
|
-
* query: 'query',
|
|
1611
|
+
* db.table.where({
|
|
1612
|
+
* // compare `someColumn` in one table with the `column` value returned from another query.
|
|
1613
|
+
* someColumn: db.otherTable.where(...conditions).get('column'),
|
|
1649
1614
|
* });
|
|
1650
1615
|
* ```
|
|
1651
1616
|
*
|
|
1652
|
-
* `
|
|
1653
|
-
*
|
|
1654
|
-
* The language can be stored in the column of this table, then you can use `languageColumn` to use this column for the search:
|
|
1617
|
+
* `where` can accept other queries and merge their conditions:
|
|
1655
1618
|
*
|
|
1656
1619
|
* ```ts
|
|
1657
|
-
* db.table.
|
|
1658
|
-
* // the table has `lang` column, use it for the search
|
|
1659
|
-
* languageColumn: 'lang',
|
|
1660
|
-
* in: 'body',
|
|
1661
|
-
* query: 'query',
|
|
1662
|
-
* });
|
|
1663
|
-
* ```
|
|
1620
|
+
* const otherQuery = db.table.where({ name: 'John' });
|
|
1664
1621
|
*
|
|
1665
|
-
*
|
|
1622
|
+
* db.table.where({ id: 1 }, otherQuery);
|
|
1623
|
+
* // this will produce WHERE "table"."id" = 1 AND "table"."name' = 'John'
|
|
1624
|
+
* ```
|
|
1666
1625
|
*
|
|
1667
|
-
*
|
|
1626
|
+
* `where` supports raw SQL:
|
|
1668
1627
|
*
|
|
1669
1628
|
* ```ts
|
|
1670
|
-
* db.table.
|
|
1671
|
-
*
|
|
1672
|
-
*
|
|
1673
|
-
*
|
|
1674
|
-
* });
|
|
1629
|
+
* db.table.where`a = b`;
|
|
1630
|
+
*
|
|
1631
|
+
* // or
|
|
1632
|
+
* db.table.where(db.table.sql`a = b`);
|
|
1675
1633
|
*
|
|
1634
|
+
* // or
|
|
1676
1635
|
* import { raw } from 'orchid-orm';
|
|
1677
1636
|
*
|
|
1678
|
-
* db.table.
|
|
1679
|
-
*
|
|
1680
|
-
* text: raw`concat_ws(' ', title, body)`,
|
|
1681
|
-
* query: 'query',
|
|
1682
|
-
* });
|
|
1637
|
+
* db.table.where(raw`a = b`);
|
|
1638
|
+
* ```
|
|
1683
1639
|
*
|
|
1684
|
-
*
|
|
1685
|
-
* // search in a single text column
|
|
1686
|
-
* in: 'body',
|
|
1687
|
-
* query: 'query',
|
|
1688
|
-
* });
|
|
1640
|
+
* `where` can accept a callback with a specific query builder containing all "where" methods such as `where`, `or`, `whereNot`, `whereIn`, `whereExists`:
|
|
1689
1641
|
*
|
|
1690
|
-
*
|
|
1691
|
-
*
|
|
1692
|
-
*
|
|
1693
|
-
*
|
|
1694
|
-
* })
|
|
1642
|
+
* ```ts
|
|
1643
|
+
* db.table.where((q) =>
|
|
1644
|
+
* q
|
|
1645
|
+
* .where({ name: 'Name' })
|
|
1646
|
+
* .or({ id: 1 }, { id: 2 })
|
|
1647
|
+
* .whereIn('letter', ['a', 'b', 'c'])
|
|
1648
|
+
* .whereExists(Message, 'authorId', 'id'),
|
|
1649
|
+
* );
|
|
1650
|
+
* ```
|
|
1695
1651
|
*
|
|
1696
|
-
*
|
|
1697
|
-
*
|
|
1698
|
-
*
|
|
1699
|
-
*
|
|
1700
|
-
*
|
|
1701
|
-
* },
|
|
1702
|
-
*
|
|
1703
|
-
*
|
|
1652
|
+
* `where` can accept multiple arguments, conditions are joined with `AND`:
|
|
1653
|
+
*
|
|
1654
|
+
* ```ts
|
|
1655
|
+
* db.table.where(
|
|
1656
|
+
* { id: 1 },
|
|
1657
|
+
* db.table.where({ name: 'John' }),
|
|
1658
|
+
* db.table.sql`a = b`,
|
|
1659
|
+
* );
|
|
1704
1660
|
* ```
|
|
1705
1661
|
*
|
|
1706
|
-
*
|
|
1662
|
+
* ### where special keys
|
|
1663
|
+
*
|
|
1664
|
+
* The object passed to `where` can contain special keys, each of the keys corresponds to its own method and takes the same value as the type of argument of the method.
|
|
1665
|
+
*
|
|
1666
|
+
* For example:
|
|
1707
1667
|
*
|
|
1708
1668
|
* ```ts
|
|
1709
|
-
* db.table.
|
|
1710
|
-
*
|
|
1711
|
-
*
|
|
1669
|
+
* db.table.where({
|
|
1670
|
+
* NOT: { key: 'value' },
|
|
1671
|
+
* OR: [{ name: 'a' }, { name: 'b' }],
|
|
1672
|
+
* IN: {
|
|
1673
|
+
* columns: ['id', 'name'],
|
|
1674
|
+
* values: [
|
|
1675
|
+
* [1, 'a'],
|
|
1676
|
+
* [2, 'b'],
|
|
1677
|
+
* ],
|
|
1678
|
+
* },
|
|
1712
1679
|
* });
|
|
1713
1680
|
* ```
|
|
1714
1681
|
*
|
|
1715
|
-
*
|
|
1682
|
+
* Using methods instead of this is a shorter and cleaner way, but in some cases, such object keys way may be more convenient.
|
|
1716
1683
|
*
|
|
1717
|
-
*
|
|
1684
|
+
* ```ts
|
|
1685
|
+
* db.table.where({
|
|
1686
|
+
* // see .whereNot
|
|
1687
|
+
* NOT: { id: 1 },
|
|
1688
|
+
* // can be an array:
|
|
1689
|
+
* NOT: [{ id: 1 }, { id: 2 }],
|
|
1718
1690
|
*
|
|
1719
|
-
*
|
|
1691
|
+
* // see .or
|
|
1692
|
+
* OR: [{ name: 'a' }, { name: 'b' }],
|
|
1693
|
+
* // can be an array:
|
|
1694
|
+
* // this will give id = 1 AND id = 2 OR id = 3 AND id = 4
|
|
1695
|
+
* OR: [
|
|
1696
|
+
* [{ id: 1 }, { id: 2 }],
|
|
1697
|
+
* [{ id: 3 }, { id: 4 }],
|
|
1698
|
+
* ],
|
|
1720
1699
|
*
|
|
1721
|
-
*
|
|
1722
|
-
*
|
|
1723
|
-
*
|
|
1724
|
-
*
|
|
1700
|
+
* // see .in, the key syntax requires an object with columns and values
|
|
1701
|
+
* IN: {
|
|
1702
|
+
* columns: ['id', 'name'],
|
|
1703
|
+
* values: [
|
|
1704
|
+
* [1, 'a'],
|
|
1705
|
+
* [2, 'b'],
|
|
1706
|
+
* ],
|
|
1707
|
+
* },
|
|
1708
|
+
* // can be an array:
|
|
1709
|
+
* IN: [
|
|
1710
|
+
* {
|
|
1711
|
+
* columns: ['id', 'name'],
|
|
1712
|
+
* values: [
|
|
1713
|
+
* [1, 'a'],
|
|
1714
|
+
* [2, 'b'],
|
|
1715
|
+
* ],
|
|
1716
|
+
* },
|
|
1717
|
+
* { columns: ['someColumn'], values: [['foo', 'bar']] },
|
|
1718
|
+
* ],
|
|
1719
|
+
* });
|
|
1720
|
+
* ```
|
|
1725
1721
|
*
|
|
1726
|
-
*
|
|
1722
|
+
* ## column operators
|
|
1727
1723
|
*
|
|
1728
|
-
*
|
|
1724
|
+
* `where` argument can take an object where the key is the name of the operator and the value is its argument.
|
|
1725
|
+
*
|
|
1726
|
+
* Different types of columns support different sets of operators.
|
|
1727
|
+
*
|
|
1728
|
+
* All column operators can take a value of the same type as the column, a sub-query, or a raw SQL expression:
|
|
1729
1729
|
*
|
|
1730
1730
|
* ```ts
|
|
1731
|
-
*
|
|
1731
|
+
* db.table.where({
|
|
1732
|
+
* numericColumn: {
|
|
1733
|
+
* // lower than 5
|
|
1734
|
+
* lt: 5,
|
|
1732
1735
|
*
|
|
1733
|
-
*
|
|
1734
|
-
*
|
|
1735
|
-
*
|
|
1736
|
-
*
|
|
1736
|
+
* // lower than the value returned by sub-query
|
|
1737
|
+
* lt: OtherTable.select('someNumber').take(),
|
|
1738
|
+
*
|
|
1739
|
+
* // raw SQL expression produces WHERE "numericColumn" < "otherColumn" + 10
|
|
1740
|
+
* lt: db.table.sql`"otherColumn" + 10`,
|
|
1741
|
+
* },
|
|
1737
1742
|
* });
|
|
1738
1743
|
* ```
|
|
1739
1744
|
*
|
|
1740
|
-
*
|
|
1745
|
+
* ### Any type of column operators
|
|
1741
1746
|
*
|
|
1742
|
-
*
|
|
1747
|
+
* `equals` is a simple `=` operator, it may be useful for comparing column value with JSON object:
|
|
1743
1748
|
*
|
|
1744
|
-
*
|
|
1749
|
+
* ```ts
|
|
1750
|
+
* db.table.where({
|
|
1751
|
+
* // this will fail because an object with operators is expected
|
|
1752
|
+
* jsonColumn: someObject,
|
|
1753
|
+
*
|
|
1754
|
+
* // use this instead:
|
|
1755
|
+
* jsonColumn: { equals: someObject },
|
|
1756
|
+
* });
|
|
1757
|
+
* ```
|
|
1758
|
+
*
|
|
1759
|
+
* `not` is `!=` (or `<>`) not equal operator:
|
|
1745
1760
|
*
|
|
1746
1761
|
* ```ts
|
|
1747
|
-
* db.table.
|
|
1748
|
-
*
|
|
1749
|
-
* query: 'query',
|
|
1750
|
-
* // will add ORDER BY ts_rank(to_tsvector('english', body)) DESC
|
|
1751
|
-
* order: true,
|
|
1762
|
+
* db.table.where({
|
|
1763
|
+
* anyColumn: { not: value },
|
|
1752
1764
|
* });
|
|
1753
1765
|
* ```
|
|
1754
1766
|
*
|
|
1755
|
-
*
|
|
1767
|
+
* `in` is for the `IN` operator to check if the column value is included in a list of values.
|
|
1768
|
+
*
|
|
1769
|
+
* Takes an array of the same type as a column, a sub-query that returns a list of values, or a raw SQL expression that returns a list.
|
|
1756
1770
|
*
|
|
1757
1771
|
* ```ts
|
|
1758
|
-
* db.table.
|
|
1759
|
-
*
|
|
1760
|
-
*
|
|
1761
|
-
*
|
|
1762
|
-
*
|
|
1763
|
-
*
|
|
1772
|
+
* db.table.where({
|
|
1773
|
+
* column: {
|
|
1774
|
+
* in: ['a', 'b', 'c'],
|
|
1775
|
+
*
|
|
1776
|
+
* // WHERE "column" IN (SELECT "column" FROM "otherTable")
|
|
1777
|
+
* in: OtherTable.select('column'),
|
|
1778
|
+
*
|
|
1779
|
+
* in: db.table.sql`('a', 'b')`,
|
|
1764
1780
|
* },
|
|
1765
1781
|
* });
|
|
1766
1782
|
* ```
|
|
1767
1783
|
*
|
|
1768
|
-
*
|
|
1784
|
+
* `notIn` is for the `NOT IN` operator, and takes the same arguments as `in`
|
|
1785
|
+
*
|
|
1786
|
+
* ### Numeric, Date, and Time column operators
|
|
1787
|
+
*
|
|
1788
|
+
* To compare numbers, dates, and times.
|
|
1789
|
+
*
|
|
1790
|
+
* `lt` is for `<` (lower than)
|
|
1791
|
+
*
|
|
1792
|
+
* `lte` is for `<=` (lower than or equal)
|
|
1793
|
+
*
|
|
1794
|
+
* `gt` is for `>` (greater than)
|
|
1795
|
+
*
|
|
1796
|
+
* `gte` is for `>=` (greater than or equal)
|
|
1769
1797
|
*
|
|
1770
1798
|
* ```ts
|
|
1771
|
-
* db.table.
|
|
1772
|
-
*
|
|
1773
|
-
*
|
|
1774
|
-
*
|
|
1775
|
-
*
|
|
1776
|
-
*
|
|
1777
|
-
*
|
|
1778
|
-
*
|
|
1779
|
-
*
|
|
1780
|
-
*
|
|
1781
|
-
*
|
|
1799
|
+
* db.table.where({
|
|
1800
|
+
* numericColumn: {
|
|
1801
|
+
* gt: 5,
|
|
1802
|
+
* lt: 10,
|
|
1803
|
+
* },
|
|
1804
|
+
*
|
|
1805
|
+
* date: {
|
|
1806
|
+
* lte: new Date(),
|
|
1807
|
+
* },
|
|
1808
|
+
*
|
|
1809
|
+
* time: {
|
|
1810
|
+
* gte: new Date(),
|
|
1782
1811
|
* },
|
|
1783
1812
|
* });
|
|
1784
1813
|
* ```
|
|
1785
1814
|
*
|
|
1786
|
-
*
|
|
1815
|
+
* `between` also works with numeric, dates, and time columns, it takes an array of two elements.
|
|
1816
|
+
*
|
|
1817
|
+
* Both elements can be of the same type as a column, a sub-query, or a raw SQL expression.
|
|
1787
1818
|
*
|
|
1788
1819
|
* ```ts
|
|
1789
|
-
* db.table
|
|
1790
|
-
*
|
|
1791
|
-
*
|
|
1792
|
-
*
|
|
1793
|
-
*
|
|
1794
|
-
*
|
|
1795
|
-
*
|
|
1796
|
-
*
|
|
1797
|
-
*
|
|
1798
|
-
* // same options as above
|
|
1799
|
-
* coverDensity: true,
|
|
1800
|
-
* weights: [0.1, 0.2, 0.4, 1.0],
|
|
1801
|
-
* normalization: 32,
|
|
1802
|
-
* dir: 'ASC',
|
|
1803
|
-
* },
|
|
1804
|
-
* });
|
|
1820
|
+
* db.table.where({
|
|
1821
|
+
* column: {
|
|
1822
|
+
* // simple values
|
|
1823
|
+
* between: [1, 10],
|
|
1824
|
+
*
|
|
1825
|
+
* // sub-query and raw SQL expression
|
|
1826
|
+
* between: [OtherTable.select('column').take(), db.table.sql`2 + 2`],
|
|
1827
|
+
* },
|
|
1828
|
+
* });
|
|
1805
1829
|
* ```
|
|
1806
1830
|
*
|
|
1807
|
-
*
|
|
1831
|
+
* ### Text column operators
|
|
1832
|
+
*
|
|
1833
|
+
* For `text`, `char`, `varchar`, and `json` columns.
|
|
1834
|
+
*
|
|
1835
|
+
* `json` is stored as text, so it has text operators. Use the `jsonb` type for JSON operators.
|
|
1836
|
+
*
|
|
1837
|
+
* Takes a string, or sub-query returning string, or raw SQL expression as well as other operators.
|
|
1838
|
+
*
|
|
1839
|
+
* ```ts
|
|
1840
|
+
* db.table.where({
|
|
1841
|
+
* textColumn: {
|
|
1842
|
+
* // WHERE "textColumn" LIKE '%string%'
|
|
1843
|
+
* contains: 'string',
|
|
1844
|
+
* // WHERE "textColumn" ILIKE '%string%'
|
|
1845
|
+
* containsInsensitive: 'string',
|
|
1846
|
+
* // WHERE "textColumn" LIKE 'string%'
|
|
1847
|
+
* startsWith: 'string',
|
|
1848
|
+
* // WHERE "textColumn" ILIKE 'string%'
|
|
1849
|
+
* startsWithInsensitive: 'string',
|
|
1850
|
+
* // WHERE "textColumn" LIKE '%string'
|
|
1851
|
+
* endsWith: 'string',
|
|
1852
|
+
* // WHERE "textColumn" ILIKE '%string'
|
|
1853
|
+
* endsWithInsensitive: 'string',
|
|
1854
|
+
* },
|
|
1855
|
+
* });
|
|
1856
|
+
* ```
|
|
1857
|
+
*
|
|
1858
|
+
* ### JSONB column operators
|
|
1859
|
+
*
|
|
1860
|
+
* For the `jsonb` column, note that the `json` type has text operators instead.
|
|
1861
|
+
*
|
|
1862
|
+
* `jsonPath` operator: compare a column value under a given JSON path with the provided value.
|
|
1863
|
+
*
|
|
1864
|
+
* Value can be of any type to compare with JSON value, or it can be a sub-query or a raw SQL expression.
|
|
1865
|
+
*
|
|
1866
|
+
* ```ts
|
|
1867
|
+
* db.table.where({
|
|
1868
|
+
* jsonbColumn: {
|
|
1869
|
+
* jsonPath: [
|
|
1870
|
+
* '$.name', // first element is JSON path
|
|
1871
|
+
* '=', // second argument is comparison operator
|
|
1872
|
+
* 'value', // third argument is a value to compare with
|
|
1873
|
+
* ],
|
|
1874
|
+
* },
|
|
1875
|
+
* });
|
|
1876
|
+
* ```
|
|
1877
|
+
*
|
|
1878
|
+
* `jsonSupersetOf`: check if the column value is a superset of provided value.
|
|
1879
|
+
*
|
|
1880
|
+
* For instance, it is true if the column has JSON `{ "a": 1, "b": 2 }` and provided value is `{ "a": 1 }`.
|
|
1881
|
+
*
|
|
1882
|
+
* Takes the value of any type, or sub query which returns a single value, or a raw SQL expression.
|
|
1883
|
+
*
|
|
1884
|
+
* ```ts
|
|
1885
|
+
* db.table.where({
|
|
1886
|
+
* jsonbColumn: {
|
|
1887
|
+
* jsonSupersetOf: { a: 1 },
|
|
1888
|
+
* },
|
|
1889
|
+
* });
|
|
1890
|
+
* ```
|
|
1891
|
+
*
|
|
1892
|
+
* `jsonSubsetOf`: check if the column value is a subset of provided value.
|
|
1893
|
+
*
|
|
1894
|
+
* For instance, it is true if the column has JSON `{ "a": 1 }` and provided value is `{ "a": 1, "b": 2 }`.
|
|
1895
|
+
*
|
|
1896
|
+
* Takes the value of any type, or sub query which returns a single value, or a raw SQL expression.
|
|
1897
|
+
*
|
|
1898
|
+
* ```ts
|
|
1899
|
+
* db.table.where({
|
|
1900
|
+
* jsonbColumn: {
|
|
1901
|
+
* jsonSupersetOf: { a: 1 },
|
|
1902
|
+
* },
|
|
1903
|
+
* });
|
|
1904
|
+
* ```
|
|
1905
|
+
*
|
|
1906
|
+
* @param args - {@link WhereArgs}
|
|
1808
1907
|
*/
|
|
1809
|
-
search<T extends Query, As extends string>(this: T, arg: SearchArg<T, As>): WhereSearchResult<T, As>;
|
|
1810
|
-
_search<T extends Query, As extends string>(this: T, arg: SearchArg<T, As>): WhereSearchResult<T, As>;
|
|
1811
|
-
}
|
|
1812
|
-
|
|
1813
|
-
type WhereArg<T extends QueryBase> = {
|
|
1814
|
-
[K in keyof T['selectable'] | 'NOT' | 'OR' | 'IN' | 'EXISTS' | 'SEARCH']?: K extends 'NOT' ? MaybeArray<WhereArg<T>> : K extends 'OR' ? MaybeArray<WhereArg<T>>[] : K extends 'IN' ? MaybeArray<{
|
|
1815
|
-
columns: (keyof T['selectable'])[];
|
|
1816
|
-
values: unknown[][] | Query | Expression;
|
|
1817
|
-
}> : K extends 'SEARCH' ? MaybeArray<SearchArg<T, never>> : K extends keyof T['selectable'] ? T['selectable'][K]['column']['type'] | null | ColumnOperators<T['selectable'], K> | Expression : never;
|
|
1818
|
-
} | QueryBase | Expression | ((q: WhereQueryBuilder<T>) => WhereQueryBuilder);
|
|
1819
|
-
type WhereArgs<T extends QueryBase> = WhereArg<T>[] | TemplateLiteralArgs;
|
|
1820
|
-
type WhereInColumn<T extends QueryBase> = keyof T['selectable'] | [keyof T['selectable'], ...(keyof T['selectable'])[]];
|
|
1821
|
-
type WhereInValues<T extends QueryBase, Column extends WhereInColumn<T>> = Column extends keyof T['selectable'] ? T['selectable'][Column]['column']['type'][] | Query | Expression : ({
|
|
1822
|
-
[I in keyof Column]: Column[I] extends keyof T['selectable'] ? T['selectable'][Column[I]]['column']['type'] : never;
|
|
1823
|
-
} & {
|
|
1824
|
-
length: Column extends {
|
|
1825
|
-
length: number;
|
|
1826
|
-
} ? Column['length'] : never;
|
|
1827
|
-
})[] | Query | Expression;
|
|
1828
|
-
type WhereResult<T extends QueryBase> = T & {
|
|
1829
|
-
meta: {
|
|
1830
|
-
hasWhere: true;
|
|
1831
|
-
};
|
|
1832
|
-
};
|
|
1833
|
-
type WhereInArg<T extends Pick<Query, 'selectable'>> = {
|
|
1834
|
-
[K in keyof T['selectable']]?: T['selectable'][K]['column']['type'][] | Query | Expression;
|
|
1835
|
-
};
|
|
1836
|
-
declare const addWhere: <T extends QueryBase>(q: T, args: WhereArgs<T>) => WhereResult<T>;
|
|
1837
|
-
declare const addWhereNot: <T extends QueryBase>(q: T, args: WhereArgs<T>) => WhereResult<T>;
|
|
1838
|
-
declare const addOr: <T extends QueryBase>(q: T, args: WhereArg<T>[]) => WhereResult<T>;
|
|
1839
|
-
declare const addOrNot: <T extends QueryBase>(q: T, args: WhereArg<T>[]) => WhereResult<T>;
|
|
1840
|
-
declare const addWhereIn: <T extends QueryBase>(q: T, and: boolean, arg: unknown, values: unknown[] | unknown[][] | Query | Expression | undefined, not?: boolean) => WhereResult<T>;
|
|
1841
|
-
declare abstract class Where extends QueryBase {
|
|
1842
1908
|
where<T extends Where>(this: T, ...args: WhereArgs<T>): WhereResult<T>;
|
|
1843
1909
|
_where<T extends Where>(this: T, ...args: WhereArgs<T>): WhereResult<T>;
|
|
1910
|
+
/**
|
|
1911
|
+
* `whereNot` takes the same arguments as `where` and prepends them with `NOT` in SQL
|
|
1912
|
+
*
|
|
1913
|
+
* ```ts
|
|
1914
|
+
* // find records of different colors than red
|
|
1915
|
+
* db.table.whereNot({ color: 'red' });
|
|
1916
|
+
* ```
|
|
1917
|
+
*
|
|
1918
|
+
* @param args - {@link WhereArgs}
|
|
1919
|
+
*/
|
|
1844
1920
|
whereNot<T extends Where>(this: T, ...args: WhereArgs<T>): WhereResult<T>;
|
|
1845
1921
|
_whereNot<T extends Where>(this: T, ...args: WhereArgs<T>): WhereResult<T>;
|
|
1922
|
+
/**
|
|
1923
|
+
* `and` is an alias for {@link where} to make it look closer to SQL:
|
|
1924
|
+
*
|
|
1925
|
+
* ```ts
|
|
1926
|
+
* db.table.where({ id: 1 }).and({ name: 'John' });
|
|
1927
|
+
* ```
|
|
1928
|
+
*
|
|
1929
|
+
* @param args - {@link WhereArgs}
|
|
1930
|
+
*/
|
|
1846
1931
|
and<T extends Where>(this: T, ...args: WhereArgs<T>): WhereResult<T>;
|
|
1847
1932
|
_and<T extends Where>(this: T, ...args: WhereArgs<T>): WhereResult<T>;
|
|
1933
|
+
/**
|
|
1934
|
+
* `andNot` is an alias for `whereNot`.
|
|
1935
|
+
*
|
|
1936
|
+
* @param args - {@link WhereArgs}
|
|
1937
|
+
*/
|
|
1848
1938
|
andNot<T extends Where>(this: T, ...args: WhereArgs<T>): WhereResult<T>;
|
|
1849
1939
|
_andNot<T extends Where>(this: T, ...args: WhereArgs<T>): WhereResult<T>;
|
|
1940
|
+
/**
|
|
1941
|
+
* `or` is accepting the same arguments as {@link where}, joining arguments with `OR`.
|
|
1942
|
+
*
|
|
1943
|
+
* Columns in single arguments are still joined with `AND`.
|
|
1944
|
+
*
|
|
1945
|
+
* The database is processing `AND` before `OR`, so this should be intuitively clear.
|
|
1946
|
+
*
|
|
1947
|
+
* ```ts
|
|
1948
|
+
* db.table.or({ id: 1, color: 'red' }, { id: 2, color: 'blue' });
|
|
1949
|
+
* ```
|
|
1950
|
+
*
|
|
1951
|
+
* This query will produce such SQL (simplified):
|
|
1952
|
+
*
|
|
1953
|
+
* ```sql
|
|
1954
|
+
* SELECT * FROM "table"
|
|
1955
|
+
* WHERE id = 1 AND color = 'red'
|
|
1956
|
+
* OR id = 2 AND color = 'blue'
|
|
1957
|
+
* ```
|
|
1958
|
+
*
|
|
1959
|
+
* @param args - {@link WhereArgs} will be joined with `OR`
|
|
1960
|
+
*/
|
|
1850
1961
|
or<T extends Where>(this: T, ...args: WhereArg<T>[]): WhereResult<T>;
|
|
1851
1962
|
_or<T extends Where>(this: T, ...args: WhereArg<T>[]): WhereResult<T>;
|
|
1963
|
+
/**
|
|
1964
|
+
* `orNot` takes the same arguments as {@link or}, and prepends each condition with `NOT` just as {@link whereNot} does.
|
|
1965
|
+
*
|
|
1966
|
+
* @param args - {@link WhereArgs} will be prefixed with `NOT` and joined with `OR`
|
|
1967
|
+
*/
|
|
1852
1968
|
orNot<T extends Where>(this: T, ...args: WhereArg<T>[]): WhereResult<T>;
|
|
1853
1969
|
_orNot<T extends Where>(this: T, ...args: WhereArg<T>[]): WhereResult<T>;
|
|
1970
|
+
/**
|
|
1971
|
+
* `whereIn` and related methods are for the `IN` operator to check for inclusion in a list of values.
|
|
1972
|
+
*
|
|
1973
|
+
* When used with a single column it works equivalent to the `in` column operator:
|
|
1974
|
+
*
|
|
1975
|
+
* ```ts
|
|
1976
|
+
* db.table.whereIn('column', [1, 2, 3]);
|
|
1977
|
+
* // the same as:
|
|
1978
|
+
* db.table.where({ column: [1, 2, 3] });
|
|
1979
|
+
* ```
|
|
1980
|
+
*
|
|
1981
|
+
* `whereIn` can support a tuple of columns, that's what the `in` operator cannot support:
|
|
1982
|
+
*
|
|
1983
|
+
* ```ts
|
|
1984
|
+
* db.table.whereIn(
|
|
1985
|
+
* ['id', 'name'],
|
|
1986
|
+
* [
|
|
1987
|
+
* [1, 'Alice'],
|
|
1988
|
+
* [2, 'Bob'],
|
|
1989
|
+
* ],
|
|
1990
|
+
* );
|
|
1991
|
+
* ```
|
|
1992
|
+
*
|
|
1993
|
+
* It supports sub query which should return records with columns of the same type:
|
|
1994
|
+
*
|
|
1995
|
+
* ```ts
|
|
1996
|
+
* db.table.whereIn(['id', 'name'], OtherTable.select('id', 'name'));
|
|
1997
|
+
* ```
|
|
1998
|
+
*
|
|
1999
|
+
* It supports raw SQL expression:
|
|
2000
|
+
*
|
|
2001
|
+
* ```ts
|
|
2002
|
+
* db.table.whereIn(['id', 'name'], db.table.sql`((1, 'one'), (2, 'two'))`);
|
|
2003
|
+
* ```
|
|
2004
|
+
*
|
|
2005
|
+
* @param column - one column name, or array of column names
|
|
2006
|
+
* @param values - array of values, or a query to load values, or a raw SQL. Tuple of such values in case of multiple columns.
|
|
2007
|
+
*/
|
|
1854
2008
|
whereIn<T extends Where, Column extends WhereInColumn<T>>(this: T, column: Column, values: WhereInValues<T, Column>): WhereResult<T>;
|
|
2009
|
+
/**
|
|
2010
|
+
* See {@link whereIn}.
|
|
2011
|
+
*
|
|
2012
|
+
* @param arg - object where keys are column names, and values are an array of column values, or a query returning column values, or a raw SQL.
|
|
2013
|
+
*/
|
|
1855
2014
|
whereIn<T extends Where>(this: T, arg: WhereInArg<T>): WhereResult<T>;
|
|
1856
2015
|
_whereIn<T extends Where, Column extends WhereInColumn<T>>(this: T, column: Column, values: WhereInValues<T, Column>): WhereResult<T>;
|
|
1857
2016
|
_whereIn<T extends Where>(this: T, arg: WhereInArg<T>): WhereResult<T>;
|
|
2017
|
+
/**
|
|
2018
|
+
* Takes the same arguments as {@link whereIn}.
|
|
2019
|
+
* Add a `WHERE IN` condition prefixed with `OR` to the query:
|
|
2020
|
+
*
|
|
2021
|
+
* ```ts
|
|
2022
|
+
* db.table.whereIn('a', [1, 2, 3]).orWhereIn('b', ['one', 'two']);
|
|
2023
|
+
* ```
|
|
2024
|
+
*
|
|
2025
|
+
* @param column - one column name, or array of column names
|
|
2026
|
+
* @param values - array of values, or a query to load values, or a raw SQL. Tuple of such values in case of multiple columns.
|
|
2027
|
+
*/
|
|
1858
2028
|
orWhereIn<T extends Where, Column extends WhereInColumn<T>>(this: T, column: Column, values: WhereInValues<T, Column>): WhereResult<T>;
|
|
2029
|
+
/**
|
|
2030
|
+
* See {@link orWhereIn}.
|
|
2031
|
+
*
|
|
2032
|
+
* @param arg - object where keys are column names, and values are an array of column values, or a query returning column values, or a raw SQL.
|
|
2033
|
+
*/
|
|
1859
2034
|
orWhereIn<T extends Where>(this: T, arg: WhereInArg<T>): WhereResult<T>;
|
|
1860
2035
|
_orWhereIn<T extends Where, Column extends WhereInColumn<T>>(this: T, column: Column, values: WhereInValues<T, Column>): WhereResult<T>;
|
|
1861
2036
|
_orWhereIn<T extends Where>(this: T, arg: WhereInArg<T>): WhereResult<T>;
|
|
2037
|
+
/**
|
|
2038
|
+
* Acts as `whereIn`, but negates the condition with `NOT`:
|
|
2039
|
+
*
|
|
2040
|
+
* ```ts
|
|
2041
|
+
* db.table.whereNotIn('color', ['red', 'green', 'blue']);
|
|
2042
|
+
* ```
|
|
2043
|
+
*
|
|
2044
|
+
* @param column - one column name, or array of column names
|
|
2045
|
+
* @param values - array of values, or a query to load values, or a raw SQL. Tuple of such values in case of multiple columns.
|
|
2046
|
+
*/
|
|
1862
2047
|
whereNotIn<T extends Where, Column extends WhereInColumn<T>>(this: T, column: Column, values: WhereInValues<T, Column>): WhereResult<T>;
|
|
2048
|
+
/**
|
|
2049
|
+
* See {@link whereNotIn}.
|
|
2050
|
+
*
|
|
2051
|
+
* @param arg - object where keys are column names, and values are an array of column values, or a query returning column values, or a raw SQL.
|
|
2052
|
+
*/
|
|
1863
2053
|
whereNotIn<T extends Where>(this: T, arg: WhereInArg<T>): WhereResult<T>;
|
|
1864
2054
|
_whereNotIn<T extends Where, Column extends WhereInColumn<T>>(this: T, column: Column, values: WhereInValues<T, Column>): WhereResult<T>;
|
|
1865
2055
|
_whereNotIn<T extends Where>(this: T, arg: WhereInArg<T>): WhereResult<T>;
|
|
2056
|
+
/**
|
|
2057
|
+
* Acts as `whereIn`, but prepends `OR` to the condition and negates it with `NOT`:
|
|
2058
|
+
*
|
|
2059
|
+
* ```ts
|
|
2060
|
+
* db.table.whereNotIn('a', [1, 2, 3]).orWhereNoIn('b', ['one', 'two']);
|
|
2061
|
+
* ```
|
|
2062
|
+
*
|
|
2063
|
+
* @param column - one column name, or array of column names
|
|
2064
|
+
* @param values - array of values, or a query to load values, or a raw SQL. Tuple of such values in case of multiple columns.
|
|
2065
|
+
*/
|
|
1866
2066
|
orWhereNotIn<T extends Where, Column extends WhereInColumn<T>>(this: T, column: Column, values: WhereInValues<T, Column>): WhereResult<T>;
|
|
2067
|
+
/**
|
|
2068
|
+
* See {@link orWhereNotIn}.
|
|
2069
|
+
*
|
|
2070
|
+
* @param arg - object where keys are column names, and values are an array of column values, or a query returning column values, or a raw SQL.
|
|
2071
|
+
*/
|
|
1867
2072
|
orWhereNotIn<T extends Where>(this: T, arg: WhereInArg<T>): WhereResult<T>;
|
|
1868
2073
|
_orWhereNotIn<T extends Where, Column extends WhereInColumn<T>>(this: T, column: Column, values: WhereInValues<T, Column>): WhereResult<T>;
|
|
1869
2074
|
_orWhereNotIn<T extends Where>(this: T, arg: WhereInArg<T>): WhereResult<T>;
|
|
2075
|
+
/**
|
|
2076
|
+
* `whereExists` is for support of the `WHERE EXISTS (query)` clause.
|
|
2077
|
+
*
|
|
2078
|
+
* This method is accepting the same arguments as `join`, see the {@link Join.join} section for more details.
|
|
2079
|
+
*
|
|
2080
|
+
* ```ts
|
|
2081
|
+
* // find users who have accounts
|
|
2082
|
+
* // find by a relation name if it's defined
|
|
2083
|
+
* db.user.whereExists('account');
|
|
2084
|
+
*
|
|
2085
|
+
* // find using a table and a join conditions
|
|
2086
|
+
* db.user.whereExists(db.account, 'account.id', 'user.id');
|
|
2087
|
+
*
|
|
2088
|
+
* // find using a query builder in a callback:
|
|
2089
|
+
* db.user.whereExists(db.account, (q) => q.on('account.id', '=', 'user.id'));
|
|
2090
|
+
* ```
|
|
2091
|
+
*
|
|
2092
|
+
* @param arg - relation name, or a query object, or a `with` table alias, or a callback returning a query object.
|
|
2093
|
+
* @param args - no arguments needed when the first argument is a relation name, or conditions to join the table with.
|
|
2094
|
+
*/
|
|
1870
2095
|
whereExists<T extends Where, Arg extends JoinFirstArg<T>>(this: T, arg: Arg, ...args: JoinArgs<T, Arg>): WhereResult<T>;
|
|
2096
|
+
/**
|
|
2097
|
+
* See {@link whereExists}.
|
|
2098
|
+
*
|
|
2099
|
+
* @param arg - relation name, or a query object, or a `with` table alias, or a callback returning a query object.
|
|
2100
|
+
* @param cb - callback with a query builder to join the table.
|
|
2101
|
+
*/
|
|
1871
2102
|
whereExists<T extends Where, Arg extends JoinFirstArg<T>>(this: T, arg: Arg, cb: JoinCallback<T, Arg>): WhereResult<T>;
|
|
1872
2103
|
_whereExists<T extends Where, Arg extends JoinFirstArg<T>>(this: T, arg: Arg, ...args: JoinArgs<T, Arg>): WhereResult<T>;
|
|
1873
2104
|
_whereExists<T extends Where, Arg extends JoinFirstArg<T>>(this: T, arg: Arg, cb: JoinCallback<T, Arg>): WhereResult<T>;
|
|
2105
|
+
/**
|
|
2106
|
+
* Acts as `whereExists`, but prepends the condition with `OR`:
|
|
2107
|
+
*
|
|
2108
|
+
* ```ts
|
|
2109
|
+
* // find users who have an account or a profile,
|
|
2110
|
+
* // imagine that the user has both `account` and `profile` relations defined.
|
|
2111
|
+
* db.user.whereExist('account').orWhereExists('profile');
|
|
2112
|
+
* ```
|
|
2113
|
+
*
|
|
2114
|
+
* @param arg - relation name, or a query object, or a `with` table alias, or a callback returning a query object.
|
|
2115
|
+
* @param args - no arguments needed when the first argument is a relation name, or conditions to join the table with.
|
|
2116
|
+
*/
|
|
1874
2117
|
orWhereExists<T extends Where, Arg extends JoinFirstArg<T>, Args extends JoinArgs<T, Arg>>(this: T, arg: Arg, ...args: Args): WhereResult<T>;
|
|
2118
|
+
/**
|
|
2119
|
+
* See {@link orWhereExists}.
|
|
2120
|
+
*
|
|
2121
|
+
* @param arg - relation name, or a query object, or a `with` table alias, or a callback returning a query object.
|
|
2122
|
+
* @param cb - callback with a query builder to join the table.
|
|
2123
|
+
*/
|
|
1875
2124
|
orWhereExists<T extends Where, Arg extends JoinFirstArg<T>>(this: T, arg: Arg, cb: JoinCallback<T, Arg>): WhereResult<T>;
|
|
1876
2125
|
_orWhereExists<T extends Where, Arg extends JoinFirstArg<T>, Args extends JoinArgs<T, Arg>>(this: T, arg: Arg, ...args: Args): WhereResult<T>;
|
|
1877
2126
|
_orWhereExists<T extends Where, Arg extends JoinFirstArg<T>>(this: T, arg: Arg, cb: JoinCallback<T, Arg>): WhereResult<T>;
|
|
2127
|
+
/**
|
|
2128
|
+
* Acts as `whereExists`, but negates the condition with `NOT`:
|
|
2129
|
+
*
|
|
2130
|
+
* ```ts
|
|
2131
|
+
* // find users who don't have an account,
|
|
2132
|
+
* // image that the user `belongsTo` or `hasOne` account.
|
|
2133
|
+
* db.user.whereNotExist('account');
|
|
2134
|
+
* ```
|
|
2135
|
+
*
|
|
2136
|
+
* @param arg - relation name, or a query object, or a `with` table alias, or a callback returning a query object.
|
|
2137
|
+
* @param args - no arguments needed when the first argument is a relation name, or conditions to join the table with.
|
|
2138
|
+
*/
|
|
1878
2139
|
whereNotExists<T extends Where, Arg extends JoinFirstArg<T>, Args extends JoinArgs<T, Arg>>(this: T, arg: Arg, ...args: Args): WhereResult<T>;
|
|
2140
|
+
/**
|
|
2141
|
+
* See {@link whereNotExists}.
|
|
2142
|
+
*
|
|
2143
|
+
* @param arg - relation name, or a query object, or a `with` table alias, or a callback returning a query object.
|
|
2144
|
+
* @param cb - callback with a query builder to join the table.
|
|
2145
|
+
*/
|
|
1879
2146
|
whereNotExists<T extends Where, Arg extends JoinFirstArg<T>>(this: T, arg: Arg, cb: JoinCallback<T, Arg>): WhereResult<T>;
|
|
1880
2147
|
_whereNotExists<T extends Where, Arg extends JoinFirstArg<T>, Args extends JoinArgs<T, Arg>>(this: T, arg: Arg, ...args: Args): WhereResult<T>;
|
|
1881
2148
|
_whereNotExists<T extends Where, Arg extends JoinFirstArg<T>>(this: T, arg: Arg, cb: JoinCallback<T, Arg>): WhereResult<T>;
|
|
2149
|
+
/**
|
|
2150
|
+
* Acts as `whereExists`, but prepends the condition with `OR` and negates it with `NOT`:
|
|
2151
|
+
*
|
|
2152
|
+
* ```ts
|
|
2153
|
+
* // find users who don't have an account OR who don't have a profile
|
|
2154
|
+
* // imagine that the user has both `account` and `profile` relations defined.
|
|
2155
|
+
* db.user.whereNotExists('account').orWhereNotExists('profile');
|
|
2156
|
+
* ```
|
|
2157
|
+
*
|
|
2158
|
+
* @param arg - relation name, or a query object, or a `with` table alias, or a callback returning a query object.
|
|
2159
|
+
* @param args - no arguments needed when the first argument is a relation name, or conditions to join the table with.
|
|
2160
|
+
*/
|
|
1882
2161
|
orWhereNotExists<T extends Where, Arg extends JoinFirstArg<T>, Args extends JoinArgs<T, Arg>>(this: T, arg: Arg, ...args: Args): WhereResult<T>;
|
|
2162
|
+
/**
|
|
2163
|
+
* See {@link orWhereNotExists}.
|
|
2164
|
+
*
|
|
2165
|
+
* @param arg - relation name, or a query object, or a `with` table alias, or a callback returning a query object.
|
|
2166
|
+
* @param cb - callback with a query builder to join the table.
|
|
2167
|
+
*/
|
|
1883
2168
|
orWhereNotExists<T extends Where, Arg extends JoinFirstArg<T>>(this: T, arg: Arg, cb: JoinCallback<T, Arg>): WhereResult<T>;
|
|
1884
2169
|
_orWhereNotExists<T extends Where, Arg extends JoinFirstArg<T>, Args extends JoinArgs<T, Arg>>(this: T, arg: Arg, ...args: Args): WhereResult<T>;
|
|
1885
2170
|
_orWhereNotExists<T extends Where, Arg extends JoinFirstArg<T>>(this: T, arg: Arg, cb: JoinCallback<T, Arg>): WhereResult<T>;
|
|
@@ -3325,169 +3610,472 @@ declare class Update {
|
|
|
3325
3610
|
*
|
|
3326
3611
|
* If `.select` and `.take`, `.find`, or similar were specified before the update it will return one updated record.
|
|
3327
3612
|
*
|
|
3328
|
-
* For a column value you can provide a specific value, raw SQL, a query object that returns a single value, or a callback with a sub-query.
|
|
3613
|
+
* For a column value you can provide a specific value, raw SQL, a query object that returns a single value, or a callback with a sub-query.
|
|
3614
|
+
*
|
|
3615
|
+
* ```ts
|
|
3616
|
+
* // returns number of updated records by default
|
|
3617
|
+
* const updatedCount = await db.table
|
|
3618
|
+
* .where({ name: 'old name' })
|
|
3619
|
+
* .update({ name: 'new name' });
|
|
3620
|
+
*
|
|
3621
|
+
* // returning only `id`
|
|
3622
|
+
* const id = await db.table.find(1).get('id').update({ name: 'new name' });
|
|
3623
|
+
*
|
|
3624
|
+
* // `selectAll` + `find` will return a full record
|
|
3625
|
+
* const oneFullRecord = await db.table
|
|
3626
|
+
* .selectAll()
|
|
3627
|
+
* .find(1)
|
|
3628
|
+
* .update({ name: 'new name' });
|
|
3629
|
+
*
|
|
3630
|
+
* // `selectAll` + `where` will return array of full records
|
|
3631
|
+
* const recordsArray = await db.table
|
|
3632
|
+
* .select('id', 'name')
|
|
3633
|
+
* .where({ id: 1 })
|
|
3634
|
+
* .update({ name: 'new name' });
|
|
3635
|
+
*
|
|
3636
|
+
* await db.table.where({ ...conditions }).update({
|
|
3637
|
+
* // set the column to a specific value
|
|
3638
|
+
* column1: 123,
|
|
3639
|
+
*
|
|
3640
|
+
* // use raw SQL to update the column
|
|
3641
|
+
* column2: db.table.sql`2 + 2`,
|
|
3642
|
+
*
|
|
3643
|
+
* // use query that returns a single value
|
|
3644
|
+
* // returning multiple values will result in Postgres error
|
|
3645
|
+
* column3: db.otherTable.get('someColumn'),
|
|
3646
|
+
*
|
|
3647
|
+
* // select a single value from a related record
|
|
3648
|
+
* fromRelation: (q) => q.relatedTable.get('someColumn'),
|
|
3649
|
+
*
|
|
3650
|
+
* // set a new value to the `.foo.bar` path into a JSON column
|
|
3651
|
+
* jsonColumn: (q) => q.jsonSet('jsonColumn', ['foo', 'bar'], 'new value'),
|
|
3652
|
+
* });
|
|
3653
|
+
* ```
|
|
3654
|
+
*
|
|
3655
|
+
* `null` value will set a column to `NULL`, but the `undefined` value will be ignored:
|
|
3656
|
+
*
|
|
3657
|
+
* ```ts
|
|
3658
|
+
* db.table.findBy({ id: 1 }).update({
|
|
3659
|
+
* name: null, // updates to null
|
|
3660
|
+
* age: undefined, // skipped, no effect
|
|
3661
|
+
* });
|
|
3662
|
+
* ```
|
|
3663
|
+
*
|
|
3664
|
+
* @param arg - data to update records with, may have specific values, raw SQL, queries, or callbacks with sub-queries.
|
|
3665
|
+
*/
|
|
3666
|
+
update<T extends Query>(this: T, arg: UpdateArg<T>): UpdateResult<T>;
|
|
3667
|
+
_update<T extends Query>(this: T, arg: UpdateArg<T>): UpdateResult<T>;
|
|
3668
|
+
/**
|
|
3669
|
+
* `updateRaw` is for updating records with raw expression.
|
|
3670
|
+
*
|
|
3671
|
+
* The behavior is the same as a regular `update` method has:
|
|
3672
|
+
* `find` or `where` must precede calling this method,
|
|
3673
|
+
* it returns an updated count by default,
|
|
3674
|
+
* you can customize returning data by using `select`.
|
|
3675
|
+
*
|
|
3676
|
+
* ```ts
|
|
3677
|
+
* const value = 'new name';
|
|
3678
|
+
*
|
|
3679
|
+
* // update with SQL template string
|
|
3680
|
+
* const updatedCount = await db.table.find(1).updateRaw`name = ${value}`;
|
|
3681
|
+
*
|
|
3682
|
+
* // or update with `sql` function:
|
|
3683
|
+
* await db.table.find(1).updateRaw(db.table.sql`name = ${value}`);
|
|
3684
|
+
* ```
|
|
3685
|
+
* @param args - raw SQL via a template string or by using a `sql` method
|
|
3686
|
+
*/
|
|
3687
|
+
updateRaw<T extends Query>(this: T, ...args: UpdateRawArgs<T>): UpdateResult<T>;
|
|
3688
|
+
_updateRaw<T extends Query>(this: T, ...args: UpdateRawArgs<T>): UpdateResult<T>;
|
|
3689
|
+
/**
|
|
3690
|
+
* To make sure that at least one row was updated use `updateOrThrow`:
|
|
3691
|
+
*
|
|
3692
|
+
* ```ts
|
|
3693
|
+
* import { NotFoundError } from 'pqb';
|
|
3694
|
+
*
|
|
3695
|
+
* try {
|
|
3696
|
+
* // updatedCount is guaranteed to be greater than 0
|
|
3697
|
+
* const updatedCount = await db.table
|
|
3698
|
+
* .where(conditions)
|
|
3699
|
+
* .updateOrThrow({ name: 'name' });
|
|
3700
|
+
*
|
|
3701
|
+
* // updatedRecords is guaranteed to be a non-empty array
|
|
3702
|
+
* const updatedRecords = await db.table
|
|
3703
|
+
* .where(conditions)
|
|
3704
|
+
* .select('id')
|
|
3705
|
+
* .updateOrThrow({ name: 'name' });
|
|
3706
|
+
* } catch (err) {
|
|
3707
|
+
* if (err instanceof NotFoundError) {
|
|
3708
|
+
* // handle error
|
|
3709
|
+
* }
|
|
3710
|
+
* }
|
|
3711
|
+
* ```
|
|
3712
|
+
*
|
|
3713
|
+
* @param arg - data to update records with, may have specific values, raw SQL, queries, or callbacks with sub-queries.
|
|
3714
|
+
*/
|
|
3715
|
+
updateOrThrow<T extends Query>(this: T, arg: UpdateArg<T>): UpdateResult<T>;
|
|
3716
|
+
_updateOrThrow<T extends Query>(this: T, arg: UpdateArg<T>): UpdateResult<T>;
|
|
3717
|
+
/**
|
|
3718
|
+
* Increments a column value by the specified amount. Optionally takes `returning` argument.
|
|
3719
|
+
*
|
|
3720
|
+
* ```ts
|
|
3721
|
+
* // increment numericColumn column by 1, return updated records
|
|
3722
|
+
* const result = await db.table
|
|
3723
|
+
* .selectAll()
|
|
3724
|
+
* .where(...conditions)
|
|
3725
|
+
* .increment('numericColumn');
|
|
3726
|
+
*
|
|
3727
|
+
* // increment someColumn by 5 and otherColumn by 10, return updated records
|
|
3728
|
+
* const result2 = await db.table
|
|
3729
|
+
* .selectAll()
|
|
3730
|
+
* .where(...conditions)
|
|
3731
|
+
* .increment({
|
|
3732
|
+
* someColumn: 5,
|
|
3733
|
+
* otherColumn: 10,
|
|
3734
|
+
* });
|
|
3735
|
+
* ```
|
|
3736
|
+
*
|
|
3737
|
+
* @param data - name of the column to increment, or an object with columns and values to add
|
|
3738
|
+
*/
|
|
3739
|
+
increment<T extends Query>(this: T, data: ChangeCountArg<T>): UpdateResult<T>;
|
|
3740
|
+
_increment<T extends Query>(this: T, data: ChangeCountArg<T>): UpdateResult<T>;
|
|
3741
|
+
/**
|
|
3742
|
+
* Decrements a column value by the specified amount. Optionally takes `returning` argument.
|
|
3743
|
+
*
|
|
3744
|
+
* ```ts
|
|
3745
|
+
* // decrement numericColumn column by 1, return updated records
|
|
3746
|
+
* const result = await db.table
|
|
3747
|
+
* .selectAll()
|
|
3748
|
+
* .where(...conditions)
|
|
3749
|
+
* .decrement('numericColumn');
|
|
3750
|
+
*
|
|
3751
|
+
* // decrement someColumn by 5 and otherColumn by 10, return updated records
|
|
3752
|
+
* const result2 = await db.table
|
|
3753
|
+
* .selectAll()
|
|
3754
|
+
* .where(...conditions)
|
|
3755
|
+
* .decrement({
|
|
3756
|
+
* someColumn: 5,
|
|
3757
|
+
* otherColumn: 10,
|
|
3758
|
+
* });
|
|
3759
|
+
* ```
|
|
3760
|
+
*
|
|
3761
|
+
* @param data - name of the column to decrement, or an object with columns and values to subtract
|
|
3762
|
+
*/
|
|
3763
|
+
decrement<T extends Query>(this: T, data: ChangeCountArg<T>): UpdateResult<T>;
|
|
3764
|
+
_decrement<T extends Query>(this: T, data: ChangeCountArg<T>): UpdateResult<T>;
|
|
3765
|
+
}
|
|
3766
|
+
|
|
3767
|
+
type IsolationLevel = 'SERIALIZABLE' | 'REPEATABLE READ' | 'READ COMMITTED' | 'READ UNCOMMITTED';
|
|
3768
|
+
type TransactionOptions = {
|
|
3769
|
+
level: IsolationLevel;
|
|
3770
|
+
readOnly?: boolean;
|
|
3771
|
+
deferrable?: boolean;
|
|
3772
|
+
};
|
|
3773
|
+
declare class Transaction {
|
|
3774
|
+
transaction<T extends Query, Result>(this: T, cb: () => Promise<Result>): Promise<Result>;
|
|
3775
|
+
transaction<T extends Query, Result>(this: T, options: IsolationLevel | TransactionOptions, cb: () => Promise<Result>): Promise<Result>;
|
|
3776
|
+
}
|
|
3777
|
+
|
|
3778
|
+
declare module './aggregate' {
|
|
3779
|
+
interface SelectAggMethods<T extends Query> {
|
|
3780
|
+
/**
|
|
3781
|
+
* Give the `as` alias for the search, and it becomes possible to select a text with highlights of the matching words or phrases:
|
|
3782
|
+
*
|
|
3783
|
+
* ```ts
|
|
3784
|
+
* db.table
|
|
3785
|
+
* .search({
|
|
3786
|
+
* as: 'search',
|
|
3787
|
+
* in: 'body',
|
|
3788
|
+
* query: 'query',
|
|
3789
|
+
* })
|
|
3790
|
+
* .select({
|
|
3791
|
+
* highlightedText: (q) => q.headline('search'),
|
|
3792
|
+
* });
|
|
3793
|
+
* ```
|
|
3794
|
+
*
|
|
3795
|
+
* When searching in the generated `tsvector` column, need to provide a text source to the `headline`:
|
|
3796
|
+
*
|
|
3797
|
+
* ```ts
|
|
3798
|
+
* db.table
|
|
3799
|
+
* .search({
|
|
3800
|
+
* as: 'search',
|
|
3801
|
+
* vector: 'textVector',
|
|
3802
|
+
* query: 'query',
|
|
3803
|
+
* })
|
|
3804
|
+
* .select({
|
|
3805
|
+
* // `body` is a column name
|
|
3806
|
+
* highlightedText: (q) => q.headline('search', { text: 'body' }),
|
|
3807
|
+
* });
|
|
3808
|
+
* ```
|
|
3809
|
+
*
|
|
3810
|
+
* `text` can be a raw SQL, here we are joining multiple columns:
|
|
3811
|
+
*
|
|
3812
|
+
* ```ts
|
|
3813
|
+
* import { raw } from 'orchid-orm';
|
|
3814
|
+
*
|
|
3815
|
+
* db.table
|
|
3816
|
+
* .search({
|
|
3817
|
+
* as: 'search',
|
|
3818
|
+
* vector: 'titleAndBodyVector',
|
|
3819
|
+
* query: 'query',
|
|
3820
|
+
* })
|
|
3821
|
+
* .select({
|
|
3822
|
+
* highlightedText: (q) =>
|
|
3823
|
+
* q.headline('search', { text: raw`concat_ws(' ', title, body)` }),
|
|
3824
|
+
* });
|
|
3825
|
+
* ```
|
|
3826
|
+
*
|
|
3827
|
+
* `headline` supports a string for `options`, see details [in Postgres doc](https://www.postgresql.org/docs/current/textsearch-controls.html#TEXTSEARCH-HEADLINE).
|
|
3828
|
+
*
|
|
3829
|
+
* Provide a simple string or a raw SQL:
|
|
3830
|
+
*
|
|
3831
|
+
* ```ts
|
|
3832
|
+
* db.table
|
|
3833
|
+
* .search({
|
|
3834
|
+
* as: 'search',
|
|
3835
|
+
* in: 'body',
|
|
3836
|
+
* query: 'query',
|
|
3837
|
+
* })
|
|
3838
|
+
* .select({
|
|
3839
|
+
* highlightedText: (q) =>
|
|
3840
|
+
* q.headline('search', {
|
|
3841
|
+
* options:
|
|
3842
|
+
* 'MaxFragments=10, MaxWords=7, MinWords=3, StartSel=<<, StopSel=>>',
|
|
3843
|
+
* }),
|
|
3844
|
+
* });
|
|
3845
|
+
* ```
|
|
3846
|
+
*
|
|
3847
|
+
* @param search - name of the search to use the query from
|
|
3848
|
+
* @param options - `text` for a text source, `options` for `ts_headline` options
|
|
3849
|
+
*/
|
|
3850
|
+
headline(search: string | undefined extends T['meta']['tsQuery'] ? never : Exclude<T['meta']['tsQuery'], undefined>, options?: {
|
|
3851
|
+
text?: SelectableOrExpressionOfType<T, TextColumn>;
|
|
3852
|
+
options?: string | Expression;
|
|
3853
|
+
}): ColumnExpression<TextColumn>;
|
|
3854
|
+
}
|
|
3855
|
+
}
|
|
3856
|
+
type SearchArg<T extends QueryBase, As extends string> = {
|
|
3857
|
+
as?: As;
|
|
3858
|
+
order?: OrderTsQueryConfig;
|
|
3859
|
+
} & ({
|
|
3860
|
+
language?: string | Expression;
|
|
3861
|
+
} | {
|
|
3862
|
+
languageColumn?: keyof T['selectable'];
|
|
3863
|
+
}) & ({
|
|
3864
|
+
text: string | Expression;
|
|
3865
|
+
} | {
|
|
3866
|
+
in: MaybeArray<keyof T['selectable']> | {
|
|
3867
|
+
[K in keyof T['selectable']]?: SearchWeight;
|
|
3868
|
+
};
|
|
3869
|
+
} | {
|
|
3870
|
+
vector: {
|
|
3871
|
+
[K in keyof T['selectable']]: T['selectable'][K]['column']['dataType'] extends 'tsvector' ? K : never;
|
|
3872
|
+
}[keyof T['selectable']];
|
|
3873
|
+
}) & ({
|
|
3874
|
+
query: string | Expression;
|
|
3875
|
+
} | {
|
|
3876
|
+
plainQuery: string | Expression;
|
|
3877
|
+
} | {
|
|
3878
|
+
phraseQuery: string | Expression;
|
|
3879
|
+
} | {
|
|
3880
|
+
tsQuery: string | Expression;
|
|
3881
|
+
});
|
|
3882
|
+
type WhereSearchResult<T extends QueryBase, As extends string> = T & {
|
|
3883
|
+
meta: {
|
|
3884
|
+
tsQuery: string extends As ? never : As;
|
|
3885
|
+
};
|
|
3886
|
+
};
|
|
3887
|
+
declare const saveSearchAlias: (q: QueryBase, as: string) => string;
|
|
3888
|
+
declare class SearchMethods {
|
|
3889
|
+
/**
|
|
3890
|
+
* ## language
|
|
3891
|
+
*
|
|
3892
|
+
* By default, the search language is English.
|
|
3893
|
+
*
|
|
3894
|
+
* You can set a different default language in the `createBaseTable` config:
|
|
3895
|
+
*
|
|
3896
|
+
* ```ts
|
|
3897
|
+
* import { createBaseTable } from 'orchid-orm';
|
|
3898
|
+
*
|
|
3899
|
+
* export const BaseTable = createBaseTable({
|
|
3900
|
+
* language: 'swedish',
|
|
3901
|
+
* });
|
|
3902
|
+
* ```
|
|
3903
|
+
*
|
|
3904
|
+
* See the list of supported language configs with the SQL:
|
|
3905
|
+
*
|
|
3906
|
+
* ```sql
|
|
3907
|
+
* SELECT cfgname FROM pg_ts_config;
|
|
3908
|
+
* ```
|
|
3909
|
+
*
|
|
3910
|
+
* When performing a search, you can override the default language:
|
|
3911
|
+
*
|
|
3912
|
+
* ```ts
|
|
3913
|
+
* db.table.search({
|
|
3914
|
+
* language: 'finnish',
|
|
3915
|
+
* in: 'body',
|
|
3916
|
+
* query: 'query',
|
|
3917
|
+
* });
|
|
3918
|
+
* ```
|
|
3919
|
+
*
|
|
3920
|
+
* `language` also accepts a raw SQL.
|
|
3921
|
+
*
|
|
3922
|
+
* The language can be stored in the column of this table, then you can use `languageColumn` to use this column for the search:
|
|
3329
3923
|
*
|
|
3330
3924
|
* ```ts
|
|
3331
|
-
*
|
|
3332
|
-
*
|
|
3333
|
-
*
|
|
3334
|
-
*
|
|
3925
|
+
* db.table.search({
|
|
3926
|
+
* // the table has `lang` column, use it for the search
|
|
3927
|
+
* languageColumn: 'lang',
|
|
3928
|
+
* in: 'body',
|
|
3929
|
+
* query: 'query',
|
|
3930
|
+
* });
|
|
3931
|
+
* ```
|
|
3335
3932
|
*
|
|
3336
|
-
*
|
|
3337
|
-
* const id = await db.table.find(1).get('id').update({ name: 'new name' });
|
|
3933
|
+
* ## text vector to search in
|
|
3338
3934
|
*
|
|
3339
|
-
*
|
|
3340
|
-
* const oneFullRecord = await db.table
|
|
3341
|
-
* .selectAll()
|
|
3342
|
-
* .find(1)
|
|
3343
|
-
* .update({ name: 'new name' });
|
|
3935
|
+
* The text to search in can be a simple string, or a raw SQL, or a text column, or multiple columns:
|
|
3344
3936
|
*
|
|
3345
|
-
*
|
|
3346
|
-
*
|
|
3347
|
-
*
|
|
3348
|
-
*
|
|
3349
|
-
*
|
|
3937
|
+
* ```ts
|
|
3938
|
+
* db.table.search({
|
|
3939
|
+
* // search in the given string
|
|
3940
|
+
* text: 'simply a string to search in',
|
|
3941
|
+
* query: 'query',
|
|
3942
|
+
* });
|
|
3350
3943
|
*
|
|
3351
|
-
*
|
|
3352
|
-
* // set the column to a specific value
|
|
3353
|
-
* column1: 123,
|
|
3944
|
+
* import { raw } from 'orchid-orm';
|
|
3354
3945
|
*
|
|
3355
|
-
*
|
|
3356
|
-
*
|
|
3946
|
+
* db.table.search({
|
|
3947
|
+
* // raw SQL: join text columns with space
|
|
3948
|
+
* text: raw`concat_ws(' ', title, body)`,
|
|
3949
|
+
* query: 'query',
|
|
3950
|
+
* });
|
|
3357
3951
|
*
|
|
3358
|
-
*
|
|
3359
|
-
* //
|
|
3360
|
-
*
|
|
3952
|
+
* db.table.search({
|
|
3953
|
+
* // search in a single text column
|
|
3954
|
+
* in: 'body',
|
|
3955
|
+
* query: 'query',
|
|
3956
|
+
* });
|
|
3361
3957
|
*
|
|
3362
|
-
*
|
|
3363
|
-
*
|
|
3958
|
+
* db.table.search({
|
|
3959
|
+
* // search in multiple columns, they are concatenated with `concat_ws` as shown above
|
|
3960
|
+
* in: ['title', 'body'],
|
|
3961
|
+
* query: 'query',
|
|
3962
|
+
* });
|
|
3364
3963
|
*
|
|
3365
|
-
*
|
|
3366
|
-
*
|
|
3964
|
+
* db.table.search({
|
|
3965
|
+
* // search in multiple columns with different weights. Weight can be A, B, C, or D
|
|
3966
|
+
* in: {
|
|
3967
|
+
* title: 'A',
|
|
3968
|
+
* body: 'B',
|
|
3969
|
+
* },
|
|
3970
|
+
* query: 'query',
|
|
3367
3971
|
* });
|
|
3368
3972
|
* ```
|
|
3369
3973
|
*
|
|
3370
|
-
*
|
|
3974
|
+
* For better performance, define a [generated](/guide/migration-column-methods.html#generated) column of `tsvector` type, and use it in the search with `vector` keyword:
|
|
3371
3975
|
*
|
|
3372
3976
|
* ```ts
|
|
3373
|
-
* db.table.
|
|
3374
|
-
*
|
|
3375
|
-
*
|
|
3977
|
+
* db.table.search({
|
|
3978
|
+
* vector: 'titleAndBodyVector',
|
|
3979
|
+
* query: 'query',
|
|
3376
3980
|
* });
|
|
3377
3981
|
* ```
|
|
3378
3982
|
*
|
|
3379
|
-
*
|
|
3380
|
-
*/
|
|
3381
|
-
update<T extends Query>(this: T, arg: UpdateArg<T>): UpdateResult<T>;
|
|
3382
|
-
_update<T extends Query>(this: T, arg: UpdateArg<T>): UpdateResult<T>;
|
|
3383
|
-
/**
|
|
3384
|
-
* `updateRaw` is for updating records with raw expression.
|
|
3983
|
+
* ## search query
|
|
3385
3984
|
*
|
|
3386
|
-
*
|
|
3387
|
-
* `find` or `where` must precede calling this method,
|
|
3388
|
-
* it returns an updated count by default,
|
|
3389
|
-
* you can customize returning data by using `select`.
|
|
3985
|
+
* Read about different search queries in [this Postgres doc](https://www.postgresql.org/docs/current/textsearch-controls.html#TEXTSEARCH-PARSING-QUERIES).
|
|
3390
3986
|
*
|
|
3391
|
-
*
|
|
3392
|
-
* const value = 'new name';
|
|
3987
|
+
* `search` method can accept one of the following queries:
|
|
3393
3988
|
*
|
|
3394
|
-
*
|
|
3395
|
-
*
|
|
3989
|
+
* - `query`: corresponds to `websearch_to_tsquery` in Postgres, good to use by default
|
|
3990
|
+
* - `plainQuery`: corresponds to `plainto_tsquery`
|
|
3991
|
+
* - `phraseQuery`: corresponds to `phraseto_tsquery`
|
|
3992
|
+
* - `tsQuery`: corresponds to `to_tsquery`
|
|
3396
3993
|
*
|
|
3397
|
-
*
|
|
3398
|
-
* await db.table.find(1).updateRaw(db.table.sql`name = ${value}`);
|
|
3399
|
-
* ```
|
|
3400
|
-
* @param args - raw SQL via a template string or by using a `sql` method
|
|
3401
|
-
*/
|
|
3402
|
-
updateRaw<T extends Query>(this: T, ...args: UpdateRawArgs<T>): UpdateResult<T>;
|
|
3403
|
-
_updateRaw<T extends Query>(this: T, ...args: UpdateRawArgs<T>): UpdateResult<T>;
|
|
3404
|
-
/**
|
|
3405
|
-
* To make sure that at least one row was updated use `updateOrThrow`:
|
|
3994
|
+
* The `query` (`websearch_to_tsquery`) can work with any user input, while other query kinds require a specific format and will fail for invalid input.
|
|
3406
3995
|
*
|
|
3407
|
-
*
|
|
3408
|
-
* import { NotFoundError } from 'pqb';
|
|
3996
|
+
* Each query kind accepts a string or a raw SQL.
|
|
3409
3997
|
*
|
|
3410
|
-
*
|
|
3411
|
-
*
|
|
3412
|
-
* const updatedCount = await db.table
|
|
3413
|
-
* .where(conditions)
|
|
3414
|
-
* .updateOrThrow({ name: 'name' });
|
|
3998
|
+
* ```ts
|
|
3999
|
+
* import { raw } from 'orchid-orm';
|
|
3415
4000
|
*
|
|
3416
|
-
*
|
|
3417
|
-
*
|
|
3418
|
-
*
|
|
3419
|
-
*
|
|
3420
|
-
*
|
|
3421
|
-
* } catch (err) {
|
|
3422
|
-
* if (err instanceof NotFoundError) {
|
|
3423
|
-
* // handle error
|
|
3424
|
-
* }
|
|
3425
|
-
* }
|
|
4001
|
+
* db.table.search({
|
|
4002
|
+
* vector: 'titleAndBodyVector',
|
|
4003
|
+
* // can accept raw SQL:
|
|
4004
|
+
* phraseQuery: raw`'The Fat Rats'`,
|
|
4005
|
+
* });
|
|
3426
4006
|
* ```
|
|
3427
4007
|
*
|
|
3428
|
-
*
|
|
3429
|
-
|
|
3430
|
-
|
|
3431
|
-
|
|
3432
|
-
|
|
3433
|
-
* Increments a column value by the specified amount. Optionally takes `returning` argument.
|
|
4008
|
+
* ## order by search rank
|
|
4009
|
+
*
|
|
4010
|
+
* Read about search ranking in [this Postgres doc](https://www.postgresql.org/docs/current/textsearch-controls.html#TEXTSEARCH-RANKING).
|
|
4011
|
+
*
|
|
4012
|
+
* Set `order: true` to order results by the search rank:
|
|
3434
4013
|
*
|
|
3435
4014
|
* ```ts
|
|
3436
|
-
*
|
|
3437
|
-
*
|
|
3438
|
-
*
|
|
3439
|
-
*
|
|
3440
|
-
*
|
|
4015
|
+
* db.table.search({
|
|
4016
|
+
* in: 'body',
|
|
4017
|
+
* query: 'query',
|
|
4018
|
+
* // will add ORDER BY ts_rank(to_tsvector('english', body)) DESC
|
|
4019
|
+
* order: true,
|
|
4020
|
+
* });
|
|
4021
|
+
* ```
|
|
3441
4022
|
*
|
|
3442
|
-
*
|
|
3443
|
-
*
|
|
3444
|
-
*
|
|
3445
|
-
*
|
|
3446
|
-
*
|
|
3447
|
-
*
|
|
3448
|
-
*
|
|
3449
|
-
*
|
|
4023
|
+
* To order with `ts_rank_cd` instead of `ts_rank`, set `coverDensity: true`:
|
|
4024
|
+
*
|
|
4025
|
+
* ```ts
|
|
4026
|
+
* db.table.search({
|
|
4027
|
+
* in: 'body',
|
|
4028
|
+
* query: 'query',
|
|
4029
|
+
* // will add ORDER BY ts_rank_cd(to_tsvector('english', body)) DESC
|
|
4030
|
+
* order: {
|
|
4031
|
+
* coverDensity: true,
|
|
4032
|
+
* },
|
|
4033
|
+
* });
|
|
3450
4034
|
* ```
|
|
3451
4035
|
*
|
|
3452
|
-
*
|
|
3453
|
-
*/
|
|
3454
|
-
increment<T extends Query>(this: T, data: ChangeCountArg<T>): UpdateResult<T>;
|
|
3455
|
-
_increment<T extends Query>(this: T, data: ChangeCountArg<T>): UpdateResult<T>;
|
|
3456
|
-
/**
|
|
3457
|
-
* Decrements a column value by the specified amount. Optionally takes `returning` argument.
|
|
4036
|
+
* Other options are:
|
|
3458
4037
|
*
|
|
3459
4038
|
* ```ts
|
|
3460
|
-
*
|
|
3461
|
-
*
|
|
3462
|
-
*
|
|
3463
|
-
*
|
|
3464
|
-
*
|
|
4039
|
+
* db.table.search({
|
|
4040
|
+
* in: 'body',
|
|
4041
|
+
* query: 'query',
|
|
4042
|
+
* order: {
|
|
4043
|
+
* // weights for D, C, B, A:
|
|
4044
|
+
* weights: [0.1, 0.2, 0.4, 1],
|
|
4045
|
+
* // by default, rank ignores the document length
|
|
4046
|
+
* // change rank behavior by providing here a special number
|
|
4047
|
+
* normalization: 32,
|
|
4048
|
+
* // it's possible to change the order direction:
|
|
4049
|
+
* dir: 'ASC', // DESC by default
|
|
4050
|
+
* },
|
|
4051
|
+
* });
|
|
4052
|
+
* ```
|
|
3465
4053
|
*
|
|
3466
|
-
*
|
|
3467
|
-
*
|
|
3468
|
-
*
|
|
3469
|
-
*
|
|
3470
|
-
* .
|
|
3471
|
-
*
|
|
3472
|
-
*
|
|
4054
|
+
* Giving the `as` alias for the search allows to set the ordering in the `order` method:
|
|
4055
|
+
*
|
|
4056
|
+
* ```ts
|
|
4057
|
+
* db.table
|
|
4058
|
+
* .search({
|
|
4059
|
+
* as: 'search',
|
|
4060
|
+
* in: 'body',
|
|
4061
|
+
* query: 'query',
|
|
4062
|
+
* })
|
|
4063
|
+
* .order({
|
|
4064
|
+
* // can be `search: true` for defaults
|
|
4065
|
+
* search: {
|
|
4066
|
+
* // same options as above
|
|
4067
|
+
* coverDensity: true,
|
|
4068
|
+
* weights: [0.1, 0.2, 0.4, 1.0],
|
|
4069
|
+
* normalization: 32,
|
|
4070
|
+
* dir: 'ASC',
|
|
4071
|
+
* },
|
|
3473
4072
|
* });
|
|
3474
4073
|
* ```
|
|
3475
4074
|
*
|
|
3476
|
-
* @param
|
|
4075
|
+
* @param arg - search config
|
|
3477
4076
|
*/
|
|
3478
|
-
|
|
3479
|
-
|
|
3480
|
-
}
|
|
3481
|
-
|
|
3482
|
-
type IsolationLevel = 'SERIALIZABLE' | 'REPEATABLE READ' | 'READ COMMITTED' | 'READ UNCOMMITTED';
|
|
3483
|
-
type TransactionOptions = {
|
|
3484
|
-
level: IsolationLevel;
|
|
3485
|
-
readOnly?: boolean;
|
|
3486
|
-
deferrable?: boolean;
|
|
3487
|
-
};
|
|
3488
|
-
declare class Transaction {
|
|
3489
|
-
transaction<T extends Query, Result>(this: T, cb: () => Promise<Result>): Promise<Result>;
|
|
3490
|
-
transaction<T extends Query, Result>(this: T, options: IsolationLevel | TransactionOptions, cb: () => Promise<Result>): Promise<Result>;
|
|
4077
|
+
search<T extends Query, As extends string>(this: T, arg: SearchArg<T, As>): WhereSearchResult<T, As>;
|
|
4078
|
+
_search<T extends Query, As extends string>(this: T, arg: SearchArg<T, As>): WhereSearchResult<T, As>;
|
|
3491
4079
|
}
|
|
3492
4080
|
|
|
3493
4081
|
type UpsertCreateArg<T extends Query> = CreateData<T> | (() => CreateData<T>);
|
|
@@ -4086,37 +4674,46 @@ declare class QueryMethods<CT extends ColumnTypesBase> {
|
|
|
4086
4674
|
distinct<T extends Query>(this: T, ...columns: SelectableOrExpression<T>[]): T;
|
|
4087
4675
|
_distinct<T extends Query>(this: T, ...columns: SelectableOrExpression<T>[]): T;
|
|
4088
4676
|
/**
|
|
4089
|
-
*
|
|
4090
|
-
*
|
|
4677
|
+
* The `find` method is available only for tables which has exactly one primary key.
|
|
4678
|
+
* And also it can accept raw SQL template literal, then the primary key is not required.
|
|
4679
|
+
*
|
|
4680
|
+
* Find record by id, throw [NotFoundError](/guide/error-handling.html) if not found:
|
|
4091
4681
|
*
|
|
4092
4682
|
* ```ts
|
|
4093
|
-
*
|
|
4683
|
+
* await db.table.find(1);
|
|
4094
4684
|
* ```
|
|
4095
4685
|
*
|
|
4096
|
-
*
|
|
4686
|
+
* ```ts
|
|
4687
|
+
* await db.user.find`
|
|
4688
|
+
* age = ${age} AND
|
|
4689
|
+
* name = ${name}
|
|
4690
|
+
* `;
|
|
4691
|
+
* ```
|
|
4692
|
+
*
|
|
4693
|
+
* @param args - primary key value to find by, or a raw SQL
|
|
4097
4694
|
*/
|
|
4098
4695
|
find<T extends Query>(this: T, ...args: FindArgs<T>): SetQueryReturnsOne<WhereResult<T>>;
|
|
4099
4696
|
_find<T extends Query>(this: T, ...args: FindArgs<T>): SetQueryReturnsOne<WhereResult<T>>;
|
|
4100
4697
|
/**
|
|
4101
|
-
* Find a single record by the primary key (id), adds `LIMIT 1
|
|
4698
|
+
* Find a single record by the primary key (id), adds `LIMIT 1`, can accept a raw SQL.
|
|
4102
4699
|
* Returns `undefined` when not found.
|
|
4103
4700
|
*
|
|
4104
4701
|
* ```ts
|
|
4105
4702
|
* const result: TableType | undefined = await db.table.find(123);
|
|
4106
4703
|
* ```
|
|
4107
4704
|
*
|
|
4108
|
-
* @param args - primary key value to find by
|
|
4705
|
+
* @param args - primary key value to find by, or a raw SQL
|
|
4109
4706
|
*/
|
|
4110
4707
|
findOptional<T extends Query>(this: T, ...args: FindArgs<T>): SetQueryReturnsOneOptional<WhereResult<T>>;
|
|
4111
4708
|
_findOptional<T extends Query>(this: T, ...args: FindArgs<T>): SetQueryReturnsOneOptional<WhereResult<T>>;
|
|
4112
4709
|
/**
|
|
4113
4710
|
* The same as `where(conditions).take()`, it will filter records and add a `LIMIT 1`.
|
|
4114
|
-
* Throws
|
|
4711
|
+
* Throws `NotFoundError` if not found.
|
|
4115
4712
|
*
|
|
4116
4713
|
* ```ts
|
|
4117
|
-
* const result: TableType = await db.table.findBy({
|
|
4118
|
-
*
|
|
4119
|
-
* })
|
|
4714
|
+
* const result: TableType = await db.table.findBy({ key: 'value' });
|
|
4715
|
+
* // is equivalent to:
|
|
4716
|
+
* db.table.where({ key: 'value' }).take()
|
|
4120
4717
|
* ```
|
|
4121
4718
|
*
|
|
4122
4719
|
* @param args - `where` conditions
|
|
@@ -4267,6 +4864,15 @@ declare class QueryMethods<CT extends ColumnTypesBase> {
|
|
|
4267
4864
|
*/
|
|
4268
4865
|
offset<T extends Query>(this: T, arg: number | undefined): T;
|
|
4269
4866
|
_offset<T extends Query>(this: T, arg: number | undefined): T;
|
|
4867
|
+
/**
|
|
4868
|
+
* Use `exists()` to check if there is at least one record-matching condition.
|
|
4869
|
+
*
|
|
4870
|
+
* It will discard previous `select` statements if any. Returns a boolean.
|
|
4871
|
+
*
|
|
4872
|
+
* ```ts
|
|
4873
|
+
* const exists: boolean = await db.table.where(...conditions).exists();
|
|
4874
|
+
* ```
|
|
4875
|
+
*/
|
|
4270
4876
|
exists<T extends Query>(this: T): SetQueryReturnsColumn<T, BooleanColumn>;
|
|
4271
4877
|
_exists<T extends Query>(this: T): SetQueryReturnsColumn<T, BooleanColumn>;
|
|
4272
4878
|
/**
|