pqb 0.17.0 → 0.17.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as orchid_core from 'orchid-core';
2
- import { QueryResultRow, AdapterBase, QueryInput, Sql, ColumnTypesBase, ColumnShapeOutput, DefaultSelectColumns, DbBase, QueryThen, QueryCatch, TransactionState, SQLQueryArgs, QueryBaseCommon, ColumnsShapeBase, QueryInternal, QueryMetaBase, EmptyObject, ColumnTypeBase, Expression, MaybeArray, TemplateLiteralArgs, ColumnsParsers, getValueKey, StringKey, NullableColumn, EmptyTuple, SetOptional, MergeObjects, RawSQLBase, RawSQLValues, RawSQLArgs, Spread, ColumnOperatorBase, ColumnOperatorFnBase, Code, ArrayMethodsData, arrayTypeMethods, JSONType, JSONUnknown, JSONTypes, StringTypeData, PrimaryKeyColumn, stringTypeMethods, ForeignKeyTable, name, ColumnNameOfTable, BaseNumberData, NumberTypeMethods, ColumnWithDefault, DateTypeMethods, DateColumnData, EncodeColumn, ParseColumn, ValidationContext, ErrorMessage, ColumnDataBase } from 'orchid-core';
2
+ import { QueryResultRow, AdapterBase, QueryInput, Sql, QueryBaseCommon, ColumnsShapeBase, QueryInternal, QueryMetaBase, EmptyObject, StringKey, ColumnTypesBase, ColumnShapeOutput, DefaultSelectColumns, DbBase, QueryThen, QueryCatch, TransactionState, SQLQueryArgs, ColumnTypeBase, Expression, MaybeArray, TemplateLiteralArgs, ColumnsParsers, getValueKey, NullableColumn, SetOptional, EmptyTuple, MergeObjects, RawSQLBase, RawSQLValues, RawSQLArgs, Spread, ColumnOperatorBase, ColumnOperatorFnBase, Code, ArrayMethodsData, arrayTypeMethods, JSONType, JSONUnknown, JSONTypes, StringTypeData, PrimaryKeyColumn, stringTypeMethods, ForeignKeyTable, name, ColumnNameOfTable, BaseNumberData, NumberTypeMethods, ColumnWithDefault, DateTypeMethods, DateColumnData, EncodeColumn, ParseColumn, ValidationContext, ErrorMessage, ColumnDataBase } from 'orchid-core';
3
3
  import { PoolConfig, Pool, PoolClient } from 'pg';
4
4
  import { inspect } from 'util';
5
5
  import { AsyncLocalStorage } from 'node:async_hooks';
@@ -108,6 +108,79 @@ declare class UnhandledTypeError extends OrchidOrmInternalError {
108
108
  constructor(query: Query, value: never);
109
109
  }
110
110
 
111
+ declare abstract class QueryBase implements QueryBaseCommon {
112
+ /**
113
+ * Clones the current query chain, useful for re-using partial query snippets in other queries without mutating the original.
114
+ *
115
+ * Used under the hood, and not really needed on the app side.
116
+ */
117
+ clone<T extends QueryBase>(this: T): T;
118
+ abstract result: ColumnsShapeBase;
119
+ q: QueryData;
120
+ table?: string;
121
+ selectable: SelectableBase;
122
+ shape: ColumnsShapeBase;
123
+ relations: RelationsBase;
124
+ withData: WithDataBase;
125
+ baseQuery: Query;
126
+ internal: QueryInternal;
127
+ meta: QueryMetaBase;
128
+ returnType: QueryReturnType;
129
+ }
130
+
131
+ /**
132
+ * Used to build relation sub queries where agg methods such as `count` can be chained with column operators such as `gt`, `lt`.
133
+ * See {@link RelationSubQueries}.
134
+ */
135
+ type SubQueryBuilder<T extends Query, Agg = SelectAggMethods<T>> = Omit<T, keyof Agg> & Agg;
136
+ /**
137
+ * Build and memoize a query builder to use in the argument of select callback.
138
+ * See {@link SubQueryBuilder}
139
+ *
140
+ * @param q - query object to base the query builder upon
141
+ */
142
+ declare const getSubQueryBuilder: <T extends Query>(q: T) => SubQueryBuilder<T, SelectAggMethods<T>>;
143
+
144
+ type RelationConfigBase = {
145
+ table: QueryWithTable;
146
+ query: QueryWithTable;
147
+ joinQuery(fromQuery: QueryBase, toQuery: Query): Query;
148
+ one: boolean;
149
+ required: boolean;
150
+ omitForeignKeyInCreate: PropertyKey;
151
+ dataForCreate: unknown;
152
+ dataForUpdate: unknown;
153
+ dataForUpdateOne: unknown;
154
+ params: Record<string, unknown>;
155
+ populate: string;
156
+ chainedCreate: boolean;
157
+ chainedDelete: boolean;
158
+ };
159
+ type RelationsBase = Record<string, RelationQueryBase>;
160
+ type RelationQueryBase = Query & {
161
+ relationConfig: RelationConfigBase;
162
+ };
163
+ type RelationQuery<Name extends PropertyKey = PropertyKey, Config extends RelationConfigBase = RelationConfigBase, T extends Query = Query, Q extends Query = (Config['chainedCreate'] extends true ? T : T & {
164
+ [K in CreateMethodsNames]: never;
165
+ }) & (Config['chainedDelete'] extends true ? EmptyObject : {
166
+ [K in DeleteMethodsNames]: never;
167
+ })> = ((params: Config['params']) => Q) & Q & {
168
+ meta: Omit<T['meta'], 'as'> & {
169
+ as: StringKey<Name>;
170
+ defaults: Record<Config['populate'], true>;
171
+ hasWhere: true;
172
+ };
173
+ relationConfig: Config;
174
+ join<T extends Query>(this: T): T;
175
+ };
176
+ /**
177
+ * Map relations into a Record where each relation aggregate methods can be chained with column operators.
178
+ * Used in `where` callback argument, see {@link WhereQueryBuilder}.
179
+ */
180
+ type RelationSubQueries<T extends QueryBase> = {
181
+ [K in keyof T['relations']]: SubQueryBuilder<T['relations'][K]>;
182
+ };
183
+
111
184
  type NoPrimaryKeyOption = 'error' | 'warning' | 'ignore';
112
185
  type DbOptions<CT extends ColumnTypesBase> = ({
113
186
  adapter: Adapter;
@@ -126,7 +199,7 @@ type DbTableOptions = {
126
199
  language?: string;
127
200
  } & QueryLogOptions;
128
201
  declare const anyShape: Record<string, ColumnType<unknown, BaseOperators, unknown, unknown, unknown>>;
129
- interface Db<Table extends string | undefined = undefined, Shape extends ColumnsShape = Record<string, never>, Relations extends Query['relations'] = Query['relations'], CT extends ColumnTypesBase = DefaultColumnTypes, Data = Pick<ColumnShapeOutput<Shape>, DefaultSelectColumns<Shape>[number]>[]> extends DbBase<Adapter, Table, Shape, CT>, QueryMethods<CT> {
202
+ interface Db<Table extends string | undefined = undefined, Shape extends ColumnsShape = Record<string, never>, Relations extends RelationsBase = EmptyObject, CT extends ColumnTypesBase = DefaultColumnTypes, Data = Pick<ColumnShapeOutput<Shape>, DefaultSelectColumns<Shape>[number]>[]> extends DbBase<Adapter, Table, Shape, CT>, QueryMethods<CT> {
130
203
  new (adapter: Adapter, queryBuilder: Db<Table, Shape, Relations, CT>, table?: Table, shape?: Shape, options?: DbTableOptions): this;
131
204
  internal: Query['internal'];
132
205
  queryBuilder: Db;
@@ -140,7 +213,6 @@ interface Db<Table extends string | undefined = undefined, Shape extends Columns
140
213
  windows: Query['windows'];
141
214
  defaultSelectColumns: DefaultSelectColumns<Shape>;
142
215
  relations: Relations;
143
- relationsQueries: Record<string, Query>;
144
216
  withData: Query['withData'];
145
217
  error: new (message: string, length: number, name: QueryErrorName) => QueryError<this>;
146
218
  isSubQuery: false;
@@ -151,7 +223,7 @@ interface Db<Table extends string | undefined = undefined, Shape extends Columns
151
223
  }[keyof Shape], true>;
152
224
  };
153
225
  }
154
- declare class Db<Table extends string | undefined = undefined, Shape extends ColumnsShape = Record<string, never>, Relations extends Query['relations'] = Query['relations'], CT extends ColumnTypesBase = DefaultColumnTypes> implements Query {
226
+ declare class Db<Table extends string | undefined = undefined, Shape extends ColumnsShape = Record<string, never>, Relations extends RelationsBase = EmptyObject, CT extends ColumnTypesBase = DefaultColumnTypes> implements Query {
155
227
  adapter: Adapter;
156
228
  queryBuilder: Db;
157
229
  table: Table;
@@ -217,8 +289,8 @@ declare class Db<Table extends string | undefined = undefined, Shape extends Col
217
289
  */
218
290
  queryArrays<R extends any[] = any[]>(...args: SQLQueryArgs): Promise<QueryArraysResult<R>>;
219
291
  }
220
- type DbResult<CT extends ColumnTypesBase> = Db<string, Record<string, never>, Query['relations'], ColumnTypesBase extends CT ? DefaultColumnTypes : CT> & {
221
- <Table extends string, Shape extends ColumnsShape = ColumnsShape>(table: Table, shape?: ((t: ColumnTypesBase extends CT ? DefaultColumnTypes : CT) => Shape) | Shape, options?: DbTableOptions): Db<Table, Shape>;
292
+ type DbResult<CT extends ColumnTypesBase> = Db<string, Record<string, never>, EmptyObject, ColumnTypesBase extends CT ? DefaultColumnTypes : CT> & {
293
+ <Table extends string, Shape extends ColumnsShape = ColumnsShape>(table: Table, shape?: ((t: ColumnTypesBase extends CT ? DefaultColumnTypes : CT) => Shape) | Shape, options?: DbTableOptions): Db<Table, Shape, EmptyObject>;
222
294
  adapter: Adapter;
223
295
  close: Adapter['close'];
224
296
  };
@@ -242,135 +314,6 @@ type ToSqlOptionsInternal = ToSQLOptions & {
242
314
  declare const toSQL: (table: Query, options?: ToSQLOptions) => Sql;
243
315
  declare const makeSQL: (table: Query, options?: ToSqlOptionsInternal) => Sql;
244
316
 
245
- declare abstract class QueryBase implements QueryBaseCommon {
246
- /**
247
- * Clones the current query chain, useful for re-using partial query snippets in other queries without mutating the original.
248
- *
249
- * Used under the hood, and not really needed on the app side.
250
- */
251
- clone<T extends QueryBase>(this: T): T;
252
- abstract result: ColumnsShapeBase;
253
- q: QueryData;
254
- table?: string;
255
- selectable: SelectableBase;
256
- shape: ColumnsShapeBase;
257
- relations: RelationsBase;
258
- withData: WithDataBase;
259
- baseQuery: Query;
260
- internal: QueryInternal;
261
- meta: QueryMetaBase;
262
- returnType: QueryReturnType;
263
- }
264
-
265
- /**
266
- * Used to build relation sub queries where agg methods such as `count` can be chained with column operators such as `gt`, `lt`.
267
- * See {@link RelationSubQueries}.
268
- */
269
- type SubQueryBuilder<T extends Query, Agg = SelectAggMethods<T>> = Omit<T, keyof Agg> & Agg;
270
- /**
271
- * Build and memoize a query builder to use in the argument of select callback.
272
- * See {@link SubQueryBuilder}
273
- *
274
- * @param q - query object to base the query builder upon
275
- */
276
- declare const getSubQueryBuilder: <T extends Query>(q: T) => SubQueryBuilder<T, SelectAggMethods<T>>;
277
-
278
- type BaseRelation = {
279
- type: string;
280
- key: string;
281
- table: QueryWithTable;
282
- query: QueryWithTable;
283
- joinQuery(fromQuery: QueryBase, toQuery: Query): Query;
284
- nestedCreateQuery: Query;
285
- primaryKey: string;
286
- options: {
287
- scope?(q: QueryWithTable): QueryWithTable;
288
- required?: boolean;
289
- };
290
- };
291
- interface BelongsToRelation extends BaseRelation {
292
- type: 'belongsTo';
293
- returns: 'one';
294
- options: BaseRelation['options'] & {
295
- primaryKey: string;
296
- foreignKey: string;
297
- };
298
- }
299
- interface HasOneRelation extends BaseRelation {
300
- type: 'hasOne';
301
- returns: 'one';
302
- options: BaseRelation['options'] & ({
303
- primaryKey: string;
304
- foreignKey: string;
305
- } | {
306
- through: string;
307
- source: string;
308
- });
309
- }
310
- interface HasManyRelation extends BaseRelation {
311
- type: 'hasMany';
312
- returns: 'many';
313
- options: BaseRelation['options'] & ({
314
- primaryKey: string;
315
- foreignKey: string;
316
- } | {
317
- through: string;
318
- source: string;
319
- });
320
- }
321
- interface HasAndBelongsToManyRelation extends BaseRelation {
322
- type: 'hasAndBelongsToMany';
323
- returns: 'many';
324
- options: BaseRelation['options'] & {
325
- primaryKey: string;
326
- foreignKey: string;
327
- associationPrimaryKey: string;
328
- associationForeignKey: string;
329
- joinTable: string;
330
- };
331
- }
332
- type Relation = BelongsToRelation | HasOneRelation | HasManyRelation | HasAndBelongsToManyRelation;
333
- type RelationsBase = Record<never, Relation>;
334
- type relationQueryKey = typeof relationQueryKey;
335
- declare const relationQueryKey: unique symbol;
336
- type isRequiredRelationKey = typeof isRequiredRelationKey;
337
- declare const isRequiredRelationKey: unique symbol;
338
- type RelationQueryData = {
339
- relationName: string;
340
- sourceQuery: Query;
341
- relationQuery: Query;
342
- joinQuery(fromQuery: Query, toQuery: Query): Query;
343
- };
344
- type RelationQueryBase = Query & {
345
- [relationQueryKey]: RelationQueryData;
346
- [isRequiredRelationKey]: boolean;
347
- };
348
- type PrepareRelationQuery<T extends Query, RelationName extends PropertyKey, Required extends boolean, Populate extends string> = Omit<T, 'meta'> & {
349
- meta: Omit<T['meta'], 'as'> & {
350
- as: RelationName extends string ? RelationName : never;
351
- defaults: Record<Populate, true>;
352
- };
353
- [isRequiredRelationKey]: Required;
354
- [relationQueryKey]: RelationQueryData;
355
- };
356
- type RelationQuery<Name extends PropertyKey = string, Params extends Record<string, unknown> = never, Populate extends string = never, T extends Query = Query, Required extends boolean = boolean, ChainedCreate extends boolean = false, ChainedDelete extends boolean = false, Q extends RelationQueryBase = (ChainedCreate extends true ? PrepareRelationQuery<T, Name, Required, Populate> : PrepareRelationQuery<T, Name, Required, Populate> & {
357
- [K in CreateMethodsNames]: never;
358
- }) & (ChainedDelete extends true ? EmptyObject : {
359
- [K in DeleteMethodsNames]: never;
360
- })> = ((params: Params) => Q) & Q & {
361
- meta: {
362
- hasWhere: true;
363
- };
364
- join<T extends Query>(this: T): T;
365
- };
366
- /**
367
- * Map relations into a Record where each relation aggregate methods can be chained with column operators.
368
- * Used in `where` callback argument, see {@link WhereQueryBuilder}.
369
- */
370
- type RelationSubQueries<T extends QueryBase> = {
371
- [K in keyof T['relations']]: T[K] extends Query ? SubQueryBuilder<T[K]> : never;
372
- };
373
-
374
317
  type AggregateOptions<T extends Query> = {
375
318
  distinct?: boolean;
376
319
  order?: OrderArg<T> | OrderArg<T>[];
@@ -578,7 +521,6 @@ type CommonQueryData = {
578
521
  patchResult?(q: Query, queryResult: QueryResult): Promise<void>;
579
522
  handleResult(q: Query, returnType: QueryReturnType, result: QueryResult, isSubQuery?: true): unknown;
580
523
  returnType: QueryReturnType;
581
- [relationQueryKey]?: RelationQueryData;
582
524
  wrapInTransaction?: boolean;
583
525
  throwOnNotFound?: boolean;
584
526
  with?: WithItem[];
@@ -1398,1774 +1340,1738 @@ declare class CopyMethods {
1398
1340
  _copy<T extends Query>(this: T, arg: CopyArg<T>): CopyResult<T>;
1399
1341
  }
1400
1342
 
1401
- type WithSelectable<T extends QueryBase, W extends keyof T['withData']> = T['withData'][W] extends WithDataItem ? StringKey<keyof T['withData'][W]['shape']> | `${T['withData'][W]['table']}.${StringKey<keyof T['withData'][W]['shape']>}` : never;
1402
- /**
1403
- * The first argument of all `join` and `joinLateral` methods.
1404
- * See argument of {@link Join.join}.
1405
- */
1406
- type JoinFirstArg<T extends QueryBase> = Query | keyof T['relations'] | keyof T['withData'] | ((q: Pick<T, keyof T['relations']>) => Query);
1407
- /**
1408
- * Arguments of `join` methods (not `joinLateral`).
1409
- * See {@link Join.join}
1410
- */
1411
- type JoinArgs<T extends QueryBase, Arg extends JoinFirstArg<T>> = Arg extends Query ? JoinQueryArgs<T, Arg> : Arg extends keyof T['relations'] ? EmptyTuple : Arg extends keyof T['withData'] ? JoinWithArgs<T, Arg> : never;
1412
- /**
1413
- * Column names of the joined table that can be used to join.
1414
- * Derived from 'result', not from 'shape',
1415
- * because if the joined table has a specific selection, it will be wrapped like:
1416
- * ```sql
1417
- * JOIN (SELECT something FROM joined) joined ON joined.something = ...
1418
- * ```
1419
- * And the selection becomes available to use in the `ON` and to select from the joined table.
1420
- */
1421
- type JoinSelectable<Q extends Query> = keyof Q['result'] | `${AliasOrTable<Q>}.${StringKey<keyof Q['result']>}`;
1422
- type JoinQueryArgs<T extends QueryBase, Q extends Query> = [
1423
- conditions: Record<JoinSelectable<Q>, Selectable<T> | Expression> | Expression | true
1424
- ] | [
1425
- leftColumn: JoinSelectable<Q> | Expression,
1426
- rightColumn: Selectable<T> | Expression
1427
- ] | [
1428
- leftColumn: JoinSelectable<Q> | Expression,
1429
- op: string,
1430
- rightColumn: Selectable<T> | Expression
1431
- ];
1432
- type JoinWithArgs<T extends QueryBase, W extends keyof T['withData']> = [
1433
- conditions: Record<WithSelectable<T, W>, Selectable<T> | Expression> | Expression
1434
- ] | [
1435
- leftColumn: WithSelectable<T, W> | Expression,
1436
- rightColumn: Selectable<T> | Expression
1437
- ] | [
1438
- leftColumn: WithSelectable<T, W> | Expression,
1439
- op: string,
1440
- rightColumn: Selectable<T> | Expression
1441
- ];
1442
- /**
1443
- * Result of all `join` methods, not `joinLateral`.
1444
- * Adds joined table columns from its 'result' to the 'selectable' of the query.
1445
- *
1446
- * @param T - query type to join to
1447
- * @param Arg - first arg of join, see {@link JoinFirstArg}
1448
- * @param RequireJoined - when false, joined table shape will be mapped to make all columns optional
1449
- * @param RequireMain - when false, main table shape will be mapped to make all columns optional (for right and full join)
1450
- */
1451
- type JoinResult<T extends Query, Arg extends JoinFirstArg<T>, RequireJoined extends boolean, RequireMain extends boolean, Cb extends (q: never) => {
1452
- meta: QueryMetaBase;
1453
- } = () => {
1454
- meta: QueryMetaBase;
1455
- }, J extends Pick<Query, 'result' | 'table' | 'meta'> = Arg extends Query ? Arg : T['relations'] extends Record<string, Relation> ? Arg extends keyof T['relations'] ? T['relations'][Arg]['table'] : Arg extends (q: never) => Query ? ReturnType<Arg> : Arg extends keyof T['withData'] ? T['withData'][Arg] extends WithDataItem ? {
1456
- table: T['withData'][Arg]['table'];
1457
- result: T['withData'][Arg]['shape'];
1458
- meta: QueryBase['meta'];
1459
- } : never : never : never, Selectable extends SelectableBase = JoinResultSelectable<J, RequireJoined, ReturnType<Cb>>> = RequireMain extends true ? JoinAddSelectable<T, Selectable> : JoinOptionalMain<T, Selectable>;
1460
- /**
1461
- * Result of all `joinLateral` methods.
1462
- * Adds joined table columns from its 'result' to the 'selectable' of the query.
1463
- *
1464
- * @param T - query type to join to
1465
- * @param Arg - first arg of join, see {@link JoinFirstArg}
1466
- * @param RequireJoined - when false, joined table shape will be mapped to make all columns optional
1467
- */
1468
- type JoinLateralResult<T extends Query, R extends QueryBase, RequireJoined extends boolean, Selectable extends SelectableBase = JoinResultSelectable<R, RequireJoined, {
1469
- meta: QueryMetaBase;
1470
- }>> = JoinAddSelectable<T, Selectable>;
1343
+ type CreateData<T extends Query, Data = SetOptional<{
1344
+ [K in keyof T['inputType']]: CreateColumn<T, K>;
1345
+ }, keyof T['meta']['defaults']>> = [keyof T['relations']] extends [never] ? Data : OmitForeignKeysForRelations<T['relations'], Data> & CreateRelationsData<T>;
1346
+ type CreateColumn<T extends Query, Key extends keyof T['inputType']> = Expression | T['inputType'][Key] | {
1347
+ [K in keyof Query]: K extends 'then' ? QueryThen<T['inputType'][Key]> : Query[K];
1348
+ };
1471
1349
  /**
1472
- * Build `selectable` type for joined table.
1473
- *
1474
- * When `RequireJoined` parameter is false,
1475
- * the result type of the joined table will be mapped to make all columns optional.
1476
- *
1477
- * Callback may override the joined table alias.
1478
- *
1479
- * The resulting selectable receives all joined table columns prefixed with the table name or alias,
1480
- * and a star prefixed with the table name or alias to select all joined columns.
1350
+ * Omit `belongsTo` foreign keys, see {@link BaseRelation.omitForeignKeyInCreate}.
1481
1351
  */
1482
- type JoinResultSelectable<J extends Pick<Query, 'result' | 'table' | 'meta'>, RequireJoined extends boolean, CbResult extends {
1483
- meta: QueryMetaBase;
1484
- }, Result extends ColumnsShapeBase = RequireJoined extends true ? J['result'] : {
1485
- [K in keyof J['result']]: NullableColumn<J['result'][K]>;
1486
- }, As extends string = CbResult extends {
1487
- meta: QueryMetaBase & {
1488
- as: string;
1489
- };
1490
- } ? CbResult['meta']['as'] : AliasOrTable<J>> = {
1491
- [K in keyof Result as `${As}.${StringKey<K>}`]: {
1492
- as: K;
1493
- column: Result[K];
1494
- };
1495
- } & {
1496
- [K in As as `${As}.*`]: {
1497
- as: K;
1498
- column: RequireJoined extends true ? ColumnsObject<J['result']> : NullableColumn<ColumnsObject<J['result']>>;
1352
+ type OmitForeignKeysForRelations<R extends RelationsBase, Data> = Omit<Data, {
1353
+ [K in keyof R]: R[K]['relationConfig']['omitForeignKeyInCreate'];
1354
+ }[keyof R]>;
1355
+ type CreateRelationsData<T extends Query> = {
1356
+ [K in keyof T['relations']]: CreateRelationData<T, K, T['relations'][K]['relationConfig']>;
1357
+ }[keyof T['relations']];
1358
+ type CreateRelationData<T extends Query, K extends PropertyKey, R extends RelationConfigBase> = [R['omitForeignKeyInCreate']] extends [never] ? CreateRelationDataWithoutFKeys<K, R> : CreateRelationDataWithFKeys<T, K, R>;
1359
+ type CreateRelationDataWithFKeys<T extends Query, K extends PropertyKey, R extends RelationConfigBase, FKeys = {
1360
+ [K in R['omitForeignKeyInCreate']]: R['omitForeignKeyInCreate'] extends keyof T['inputType'] ? T['inputType'][R['omitForeignKeyInCreate']] : never;
1361
+ }> = {
1362
+ [K in keyof FKeys]: K extends keyof T['meta']['defaults'] ? {
1363
+ [L in K]?: FKeys[L];
1364
+ } : {
1365
+ [L in K]: FKeys[L];
1499
1366
  };
1367
+ }[keyof FKeys] | {
1368
+ [Key in K]: R['dataForCreate'];
1500
1369
  };
1501
- type JoinAddSelectable<T extends Query, Selectable extends SelectableBase> = {
1502
- [K in keyof T]: K extends 'selectable' ? T['selectable'] & Selectable : T[K];
1370
+ type CreateRelationDataWithoutFKeys<K extends PropertyKey, R extends RelationConfigBase> = {
1371
+ [Key in K]?: R['dataForCreate'];
1503
1372
  };
1504
- type JoinOptionalMain<T extends Query, Selectable extends SelectableBase, Result extends ColumnsShapeBase = {
1505
- [K in keyof T['result']]: NullableColumn<T['result'][K]>;
1506
- }, Data = GetQueryResult<T['returnType'], Result>> = {
1507
- [K in keyof T]: K extends 'selectable' ? {
1508
- [K in keyof T['selectable']]: {
1509
- as: T['selectable'][K]['as'];
1510
- column: NullableColumn<T['selectable'][K]['column']>;
1511
- };
1512
- } & Selectable : K extends 'result' ? Result : K extends 'then' ? QueryThen<Data> : K extends 'catch' ? QueryCatch<Data> : T[K];
1373
+ type CreateResult<T extends Query> = T extends {
1374
+ isCount: true;
1375
+ } ? SetQueryKind<T, 'create'> : QueryReturnsAll<T['returnType']> extends true ? SetQueryReturnsOne<SetQueryKind<T, 'create'>> : SetQueryKind<T, 'create'>;
1376
+ type CreateManyResult<T extends Query> = T extends {
1377
+ isCount: true;
1378
+ } ? SetQueryKind<T, 'create'> : T['returnType'] extends 'one' | 'oneOrThrow' ? SetQueryReturnsAll<SetQueryKind<T, 'create'>> : SetQueryKind<T, 'create'>;
1379
+ type CreateRawData<T extends Query> = {
1380
+ columns: (keyof T['shape'])[];
1381
+ values: Expression;
1513
1382
  };
1514
- /**
1515
- * Map the `with` table first argument of `join` or `joinLateral` to a query type.
1516
- * Constructs `selectable` based on `with` table shape, and adds generic types to conform the `QueryBase` type.
1517
- */
1518
- type JoinWithArgToQuery<With extends WithDataItem, Selectable extends SelectableBase = {
1519
- [K in keyof With['shape']]: {
1520
- as: StringKey<K>;
1521
- column: With['shape'][K];
1522
- };
1523
- }> = {
1524
- q: QueryData;
1525
- table: With['table'];
1526
- clone<T extends QueryBase>(this: T): T;
1527
- selectable: Selectable & {
1528
- [K in keyof Selectable as `${With['table']}.${StringKey<K>}`]: Selectable[K];
1529
- };
1530
- shape: With['shape'];
1531
- result: With['shape'];
1532
- baseQuery: Query;
1533
- relations: RelationsBase;
1534
- withData: WithDataBase;
1535
- meta: QueryBase['meta'];
1536
- internal: QueryInternal;
1537
- returnType: QueryReturnType;
1383
+ type CreateManyRawData<T extends Query> = {
1384
+ columns: (keyof T['shape'])[];
1385
+ values: Expression[];
1538
1386
  };
1539
- /**
1540
- * Map the first argument of `join` or `joinLateral` to a query type.
1541
- *
1542
- * `with` table arg is mapped into `QueryBase`,
1543
- * query arg is returned as is,
1544
- * relation name is replaced with a relation table.
1545
- */
1546
- type JoinArgToQuery<T extends QueryBase, Arg extends JoinFirstArg<T>> = Arg extends keyof T['withData'] ? T['withData'][Arg] extends WithDataItem ? JoinWithArgToQuery<T['withData'][Arg]> : never : Arg extends Query ? Arg : Arg extends keyof T['relations'] ? T['relations'][Arg] extends Relation ? T['relations'][Arg]['table'] : never : never;
1547
- /**
1548
- * Type of the `join` callback (not `joinLateral`).
1549
- *
1550
- * Receives a query builder that can access columns of both the main and the joined table.
1551
- *
1552
- * The query builder is limited to `or` and `where` methods only.
1553
- *
1554
- * Callback must return a query builder.
1555
- */
1556
- type JoinCallback<T extends QueryBase, Arg extends JoinFirstArg<T>> = (q: OnQueryBuilder<T, JoinArgToQuery<T, Arg>>) => OnQueryBuilder;
1557
- /**
1558
- * Type of the `joinLateral`.
1559
- *
1560
- * Receives a query builder that can access columns of both the main and the joined table.
1561
- *
1562
- * Query builder inside callback is the query derived from the `joinLateral` first argument,
1563
- * all query methods are allowed, `on` methods are available.
1564
- *
1565
- * The callback must return a query object. Its resulting type will become a type of the joined table.
1566
- */
1567
- type JoinLateralCallback<T extends QueryBase, Arg extends JoinFirstArg<T>, R extends QueryBase, Q extends QueryBase = JoinArgToQuery<T, Arg>> = (q: Q & OnQueryBuilder<T, Q>) => R;
1568
- declare class Join {
1569
- /**
1570
- * TODO: write docs
1571
- *
1572
- * @param arg - can be a query object, a name of a relation, a name of `with` table, or a callback to join a relation
1573
- * @param args - arguments depend on the first argument, it can be object with columns, list of columns, `true` literal.
1574
- */
1575
- join<T extends Query, Arg extends JoinFirstArg<T>, Args extends JoinArgs<T, Arg>>(this: T, arg: Arg, ...args: Args): JoinResult<T, Arg, true, true>;
1576
- join<T extends Query, Arg extends JoinFirstArg<T>, Cb extends JoinCallback<T, Arg>>(this: T, arg: Arg, cb: Cb): JoinResult<T, Arg, true, true, Cb>;
1577
- _join<T extends Query, Arg extends JoinFirstArg<T>, Args extends JoinArgs<T, Arg>>(this: T, arg: Arg, ...args: Args): JoinResult<T, Arg, true, true>;
1578
- _join<T extends Query, Arg extends JoinFirstArg<T>, Cb extends JoinCallback<T, Arg>>(this: T, arg: Arg, cb: Cb): JoinResult<T, Arg, true, true, Cb>;
1579
- leftJoin<T extends Query, Arg extends JoinFirstArg<T>, Args extends JoinArgs<T, Arg>>(this: T, arg: Arg, ...args: Args): JoinResult<T, Arg, false, true>;
1580
- leftJoin<T extends Query, Arg extends JoinFirstArg<T>, Cb extends JoinCallback<T, Arg>>(this: T, arg: Arg, cb: Cb): JoinResult<T, Arg, false, true, Cb>;
1581
- _leftJoin<T extends Query, Arg extends JoinFirstArg<T>, Args extends JoinArgs<T, Arg>>(this: T, arg: Arg, ...args: Args): JoinResult<T, Arg, false, true>;
1582
- _leftJoin<T extends Query, Arg extends JoinFirstArg<T>, Cb extends JoinCallback<T, Arg>>(this: T, arg: Arg, cb: Cb): JoinResult<T, Arg, false, true, Cb>;
1583
- rightJoin<T extends Query, Arg extends JoinFirstArg<T>, Args extends JoinArgs<T, Arg>>(this: T, arg: Arg, ...args: Args): JoinResult<T, Arg, true, false>;
1584
- rightJoin<T extends Query, Arg extends JoinFirstArg<T>, Cb extends JoinCallback<T, Arg>>(this: T, arg: Arg, cb: Cb): JoinResult<T, Arg, true, false, Cb>;
1585
- _rightJoin<T extends Query, Arg extends JoinFirstArg<T>, Args extends JoinArgs<T, Arg>>(this: T, arg: Arg, ...args: Args): JoinResult<T, Arg, true, false>;
1586
- _rightJoin<T extends Query, Arg extends JoinFirstArg<T>, Cb extends JoinCallback<T, Arg>>(this: T, arg: Arg, cb: Cb): JoinResult<T, Arg, true, false, Cb>;
1587
- fullJoin<T extends Query, Arg extends JoinFirstArg<T>, Args extends JoinArgs<T, Arg>>(this: T, arg: Arg, ...args: Args): JoinResult<T, Arg, false, false>;
1588
- fullJoin<T extends Query, Arg extends JoinFirstArg<T>, Cb extends JoinCallback<T, Arg>>(this: T, arg: Arg, cb: Cb): JoinResult<T, Arg, false, false, Cb>;
1589
- _fullJoin<T extends Query, Arg extends JoinFirstArg<T>, Args extends JoinArgs<T, Arg>>(this: T, arg: Arg, ...args: Args): JoinResult<T, Arg, false, false>;
1590
- _fullJoin<T extends Query, Arg extends JoinFirstArg<T>, Cb extends JoinCallback<T, Arg>>(this: T, arg: Arg, cb: Cb): JoinResult<T, Arg, false, false, Cb>;
1591
- joinLateral<T extends Query, Arg extends JoinFirstArg<T>, R extends QueryBase>(this: T, arg: Arg, cb: JoinLateralCallback<T, Arg, R>): JoinLateralResult<T, R, true>;
1592
- _joinLateral<T extends Query, Arg extends JoinFirstArg<T>, R extends QueryBase>(this: T, arg: Arg, cb: JoinLateralCallback<T, Arg, R>): JoinLateralResult<T, R, true>;
1593
- leftJoinLateral<T extends Query, Arg extends JoinFirstArg<T>, R extends QueryBase>(this: T, arg: Arg, cb: JoinLateralCallback<T, Arg, R>): JoinLateralResult<T, R, false>;
1594
- _leftJoinLateral<T extends Query, Arg extends JoinFirstArg<T>, R extends QueryBase>(this: T, arg: Arg, cb: JoinLateralCallback<T, Arg, R>): JoinLateralResult<T, R, false>;
1595
- }
1596
- type OnArgs<Q extends {
1597
- selectable: SelectableBase;
1598
- }> = [leftColumn: keyof Q['selectable'], rightColumn: keyof Q['selectable']] | [
1599
- leftColumn: keyof Q['selectable'],
1600
- op: string,
1601
- rightColumn: keyof Q['selectable']
1602
- ];
1603
- declare const pushQueryOn: <T extends QueryBase>(q: T, joinFrom: QueryBase, joinTo: QueryBase, ...on: OnArgs<QueryBase>) => T;
1604
- declare const pushQueryOrOn: typeof pushQueryOn;
1605
- declare const addQueryOn: <T extends QueryBase>(q: T, joinFrom: QueryBase, joinTo: QueryBase, ...args: OnArgs<QueryBase>) => T;
1606
- declare const addQueryOrOn: typeof pushQueryOrOn;
1607
- type OnJsonPathEqualsArgs<T extends QueryBase> = [
1608
- leftColumn: keyof T['selectable'],
1609
- leftPath: string,
1610
- rightColumn: keyof T['selectable'],
1611
- rightPath: string
1612
- ];
1613
- declare class OnQueryBuilder<S extends QueryBase = QueryBase, J extends QueryBase = QueryBase> extends WhereQueryBase {
1614
- selectable: J['selectable'] & Omit<S['selectable'], keyof S['shape']>;
1615
- relations: J['relations'];
1616
- result: J['result'];
1617
- shape: J['shape'];
1618
- baseQuery: Query;
1619
- withData: {};
1620
- internal: QueryInternal;
1621
- constructor(q: QueryBase, { shape, joinedShapes }: Pick<QueryData, 'shape' | 'joinedShapes'>, joinTo: QueryBase);
1622
- on<T extends OnQueryBuilder>(this: T, ...args: OnArgs<T>): T;
1623
- _on<T extends OnQueryBuilder>(this: T, ...args: OnArgs<T>): T;
1624
- orOn<T extends OnQueryBuilder>(this: T, ...args: OnArgs<T>): T;
1625
- _orOn<T extends OnQueryBuilder>(this: T, ...args: OnArgs<T>): T;
1626
- onJsonPathEquals<T extends OnQueryBuilder>(this: T, ...args: OnJsonPathEqualsArgs<T>): T;
1627
- _onJsonPathEquals<T extends OnQueryBuilder>(this: T, ...args: OnJsonPathEqualsArgs<T>): T;
1628
- }
1629
-
1630
- type WhereArg<T extends WhereQueryBase> = {
1631
- [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<{
1632
- columns: (keyof T['selectable'])[];
1633
- values: unknown[][] | Query | Expression;
1634
- }> : K extends keyof T['selectable'] ? T['selectable'][K]['column']['queryType'] | null | ColumnOperators<T['selectable'], K> | Expression | Query : never;
1635
- } | QueryBase | Expression | ((q: WhereQueryBuilder<T>) => QueryBase | ColumnExpression<BooleanNullable>);
1636
- /**
1637
- * Callback argument of `where`.
1638
- * It has `where` methods (`where`, `whereNot`, `whereExists`, etc.),
1639
- * and it has relations that you can aggregate and use a boolean comparison with, such as:
1640
- * ```ts
1641
- * db.table.where((q) => q.relation.count().equals(10))
1642
- * ```
1643
- */
1644
- type WhereQueryBuilder<T extends WhereQueryBase> = Pick<T, keyof WhereQueryBase> & RelationSubQueries<T>;
1645
- type WhereArgs<T extends WhereQueryBase> = WhereArg<T>[] | TemplateLiteralArgs;
1646
- type WhereInColumn<T extends QueryBase> = keyof T['selectable'] | [keyof T['selectable'], ...(keyof T['selectable'])[]];
1647
- type WhereInValues<T extends QueryBase, Column extends WhereInColumn<T>> = Column extends keyof T['selectable'] ? T['selectable'][Column]['column']['queryType'][] | Query | Expression : ({
1648
- [I in keyof Column]: Column[I] extends keyof T['selectable'] ? T['selectable'][Column[I]]['column']['queryType'] : never;
1649
- } & {
1650
- length: Column extends {
1651
- length: number;
1652
- } ? Column['length'] : never;
1653
- })[] | Query | Expression;
1654
- type WhereInArg<T extends Pick<Query, 'selectable'>> = {
1655
- [K in keyof T['selectable']]?: T['selectable'][K]['column']['queryType'][] | Query | Expression;
1387
+ type RawRequiredColumns<T extends Query> = {
1388
+ [K in keyof T['inputType'] as K extends keyof T['meta']['defaults'] ? never : null extends T['inputType'][K] ? never : undefined extends T['inputType'][K] ? never : K]: true;
1656
1389
  };
1657
- type WhereResult<T extends QueryBase> = T & {
1658
- meta: {
1659
- hasWhere: true;
1660
- };
1390
+ type CreateRawArgs<T extends Query, Arg extends {
1391
+ columns: (keyof T['shape'])[];
1392
+ }> = keyof RawRequiredColumns<T> extends Arg['columns'][number] ? [data: Arg] : [
1393
+ `Missing required columns: ${Exclude<StringKey<keyof RawRequiredColumns<T>>, Arg['columns'][number]>}`
1394
+ ];
1395
+ type OnConflictArg<T extends Query> = keyof T['shape'] | (keyof T['shape'])[] | Expression;
1396
+ type CreateCtx = {
1397
+ columns: Map<string, number>;
1398
+ returnTypeAll?: true;
1399
+ resultAll: Record<string, unknown>[];
1661
1400
  };
1662
- /**
1663
- * Adds `where` arguments to query data: SQL template string is added as `RawSQL` object, other arguments are added as is.
1664
- *
1665
- * @param q - query object to add the data to
1666
- * @param args - `where` arguments, may be a template literal
1667
- */
1668
- declare const addWhere: <T extends WhereQueryBase>(q: T, args: WhereArgs<T>) => WhereResult<T>;
1669
- /**
1670
- * Adds `where` arguments to query data with a `NOT` keyword: SQL template string is added as `RawSQL` object, other arguments are added as is.
1671
- *
1672
- * @param q - query object to add the data to
1673
- * @param args - `where` arguments, may be a template literal
1674
- */
1675
- declare const addWhereNot: <T extends WhereQueryBase>(q: T, args: WhereArgs<T>) => WhereResult<T>;
1676
- /**
1677
- * Adds `where` arguments to query data. Arguments will be separated from each other with `OR`.
1678
- *
1679
- * @param q - query object to add the data to
1680
- * @param args - `where` arguments, may be a template literal
1681
- */
1682
- declare const addOr: <T extends WhereQueryBase>(q: T, args: WhereArg<T>[]) => WhereResult<T>;
1683
- /**
1684
- * Adds `where` arguments to query data with a `NOT` keyword. Arguments will be separated from each other with `OR`.
1685
- *
1686
- * @param q - query object to add the data to
1687
- * @param args - `where` arguments, may be a template literal
1688
- */
1689
- declare const addOrNot: <T extends WhereQueryBase>(q: T, args: WhereArg<T>[]) => WhereResult<T>;
1690
- /**
1691
- * Process arguments of `whereIn` to add them to query data properly.
1692
- *
1693
- * @param q - query object to add the data to.
1694
- * @param and - `true` to join arguments with `AND`, `false` to join them with `OR.
1695
- * @param arg - `whereIn` argument: can be a single column name, tuple of column names, or object with column names and values.
1696
- * @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`.
1697
- * @param not - adds the `NOT` keyword.
1698
- */
1699
- declare const addWhereIn: <T extends QueryBase>(q: T, and: boolean, arg: unknown, values: unknown[] | unknown[][] | Query | Expression | undefined, not?: boolean) => WhereResult<T>;
1700
- declare abstract class Where {
1401
+ type CreateMethodsNames = 'create' | '_create' | 'createMany' | '_createMany' | 'createRaw' | '_createRaw' | 'createFrom' | '_createFrom';
1402
+ declare class Create {
1701
1403
  /**
1702
- * Constructing `WHERE` conditions:
1404
+ * `create` will create one record.
1405
+ *
1406
+ * Each column may accept a specific value, a raw SQL, or a query that returns a single value.
1703
1407
  *
1704
1408
  * ```ts
1705
- * db.table.where({
1706
- * // column of the current table
1409
+ * const oneRecord = await db.table.create({
1707
1410
  * name: 'John',
1411
+ * password: '1234',
1412
+ * });
1708
1413
  *
1709
- * // table name may be specified, it can be the name of a joined table
1710
- * 'table.lastName': 'Johnsonuk',
1711
- *
1712
- * // object with operators, see the "column operators" section to see a full list of them:
1713
- * age: {
1714
- * gt: 30,
1715
- * lt: 70,
1716
- * },
1414
+ * await db.table.create({
1415
+ * // raw SQL
1416
+ * column1: db.table.sql`'John' | 'Doe'`,
1717
1417
  *
1718
- * // where column equals to raw SQL
1719
- * column: db.table.sql`raw expression`,
1418
+ * // query that returns a single value
1419
+ * // returning multiple values will result in Postgres error
1420
+ * column2: db.otherTable.get('someColumn'),
1720
1421
  * });
1721
1422
  * ```
1722
1423
  *
1723
- * `undefined` values are ignored, so you can supply a partial object with conditions:
1724
- *
1725
- * ```ts
1726
- * type Params = {
1727
- * // allow providing exact age, or lower or greate than
1728
- * age?: number | { lt?: number; gt?: number };
1729
- * };
1424
+ * @param data - data for the record, may have values, raw SQL, queries, relation operations
1425
+ */
1426
+ create<T extends Query>(this: T, data: CreateData<T>): CreateResult<T>;
1427
+ _create<T extends Query>(this: T, data: CreateData<T>): CreateResult<T>;
1428
+ /**
1429
+ * `createMany` will create a batch of records.
1730
1430
  *
1731
- * const loadRecords = async (params: Params) => {
1732
- * // this will load all records if params is an empty object
1733
- * const records = await db.table.where(params);
1734
- * };
1735
- * ```
1431
+ * Each column may be set with a specific value, a raw SQL, or a query, the same as in [create](#create).
1736
1432
  *
1737
- * It supports a sub-query that is selecting a single value to compare it with a column:
1433
+ * In case one of the objects has fewer fields, the `DEFAULT` SQL keyword will be placed in its place in the `VALUES` statement.
1738
1434
  *
1739
1435
  * ```ts
1740
- * db.table.where({
1741
- * // compare `someColumn` in one table with the `column` value returned from another query.
1742
- * someColumn: db.otherTable.where(...conditions).get('column'),
1743
- * });
1436
+ * const manyRecords = await db.table.createMany([
1437
+ * { key: 'value', otherKey: 'other value' },
1438
+ * { key: 'value' }, // default will be used for `otherKey`
1439
+ * ]);
1744
1440
  * ```
1745
1441
  *
1746
- * `where` can accept other queries and merge their conditions:
1442
+ * @param data - data for the record, may have values, raw SQL, queries, relation operations
1443
+ */
1444
+ createMany<T extends Query>(this: T, data: CreateData<T>[]): CreateManyResult<T>;
1445
+ _createMany<T extends Query>(this: T, data: CreateData<T>[]): CreateManyResult<T>;
1446
+ /**
1447
+ * `createRaw` is for creating one record with a raw expression.
1747
1448
  *
1748
- * ```ts
1749
- * const otherQuery = db.table.where({ name: 'John' });
1449
+ * Provided SQL will be wrapped into parens for a single `VALUES` record.
1750
1450
  *
1751
- * db.table.where({ id: 1 }, otherQuery);
1752
- * // this will produce WHERE "table"."id" = 1 AND "table"."name' = 'John'
1753
- * ```
1451
+ * If the table has a column with runtime defaults (defined with callbacks), the value will be appended to your SQL.
1754
1452
  *
1755
- * `where` supports raw SQL:
1453
+ * `columns` are type-checked to contain all required columns.
1756
1454
  *
1757
1455
  * ```ts
1758
- * db.table.where`a = b`;
1456
+ * const oneRecord = await db.table.createRaw({
1457
+ * columns: ['name', 'amount'],
1458
+ * values: db.table.sql`'name', random()`,
1459
+ * });
1460
+ * ```
1759
1461
  *
1760
- * // or
1761
- * db.table.where(db.table.sql`a = b`);
1462
+ * @param args - object with columns list and raw SQL for values
1463
+ */
1464
+ createRaw<T extends Query, Arg extends CreateRawData<T>>(this: T, ...args: CreateRawArgs<T, Arg>): CreateResult<T>;
1465
+ _createRaw<T extends Query, Arg extends CreateRawData<T>>(this: T, ...args: CreateRawArgs<T, Arg>): CreateResult<T>;
1466
+ /**
1467
+ * `createRaw` is for creating many record with raw expressions.
1762
1468
  *
1763
- * // or
1764
- * import { raw } from 'orchid-orm';
1469
+ * Takes array of SQL expressions, each of them will be wrapped into parens for `VALUES` records.
1765
1470
  *
1766
- * db.table.where(raw`a = b`);
1767
- * ```
1471
+ * If the table has a column with runtime defaults (defined with callbacks), function will be called for each SQL and the value will be appended.
1768
1472
  *
1769
- * `where` can accept a callback with a specific query builder containing all "where" methods such as `where`, `or`, `whereNot`, `whereIn`, `whereExists`:
1473
+ * `columns` are type-checked to contain all required columns.
1770
1474
  *
1771
1475
  * ```ts
1772
- * db.table.where((q) =>
1773
- * q
1774
- * .where({ name: 'Name' })
1775
- * .or({ id: 1 }, { id: 2 })
1776
- * .whereIn('letter', ['a', 'b', 'c'])
1777
- * .whereExists(Message, 'authorId', 'id'),
1778
- * );
1476
+ * const manyRecords = await db.table.createManyRaw({
1477
+ * columns: ['name', 'amount'],
1478
+ * values: [db.table.sql`'one', 2`, db.table.sql`'three', 4`],
1479
+ * });
1779
1480
  * ```
1780
1481
  *
1781
- * `where` can accept multiple arguments, conditions are joined with `AND`:
1482
+ * @param args - object with columns list and array of raw SQL for values
1483
+ */
1484
+ createManyRaw<T extends Query, Arg extends CreateManyRawData<T>>(this: T, ...args: CreateRawArgs<T, Arg>): CreateManyResult<T>;
1485
+ _createManyRaw<T extends Query, Arg extends CreateManyRawData<T>>(this: T, ...args: CreateRawArgs<T, Arg>): CreateManyResult<T>;
1486
+ /**
1487
+ * This method is for creating a single record, for batch creating see `createManyFrom`.
1782
1488
  *
1783
- * ```ts
1784
- * db.table.where(
1785
- * { id: 1 },
1786
- * db.table.where({ name: 'John' }),
1787
- * db.table.sql`a = b`,
1788
- * );
1789
- * ```
1489
+ * `createFrom` is to perform the `INSERT ... SELECT ...` SQL statement, it does select and insert in a single query.
1790
1490
  *
1791
- * ## where sub query
1491
+ * The first argument is a query for a **single** record, it should have `find`, `take`, or similar.
1792
1492
  *
1793
- * `where` handles a special callback where you can query a relation to get some value and filter by that value.
1493
+ * The second optional argument is a data which will be merged with columns returned from the select query.
1794
1494
  *
1795
- * It is useful for a faceted search. For instance, posts have tags, and we want to find all posts that have all the given tags.
1495
+ * The data for the second argument is the same as in [create](#create) and [createMany](#createMany).
1796
1496
  *
1797
- * ```ts
1798
- * const givenTags = ['typescript', 'node.js'];
1497
+ * Columns with runtime defaults (defined with a callback) are supported here.
1498
+ * The value for such a column will be injected unless selected from a related table or provided in a data object.
1799
1499
  *
1800
- * const posts = await db.post.where(
1801
- * (post) =>
1802
- * post.tags // query tags of the post
1803
- * .whereIn('tagName', givenTags) // where name of the tag is inside array
1804
- * .count() // count how many such tags were found
1805
- * .equals(wantedTags.length), // the count must be exactly the length of array
1806
- * // if the post has ony `typescript` tag but not the `node.js` it will be omitted
1500
+ * ```ts
1501
+ * const oneRecord = await db.table.createFrom(
1502
+ * // In the select, key is a related table column, value is a column to insert as
1503
+ * RelatedTable.select({ relatedId: 'id' }).findBy({ key: 'value' }),
1504
+ * // optional argument:
1505
+ * {
1506
+ * key: 'value',
1507
+ * },
1807
1508
  * );
1808
1509
  * ```
1809
1510
  *
1810
- * This will produce an efficient SQL query:
1511
+ * The query above will produce such SQL:
1811
1512
  *
1812
1513
  * ```sql
1813
- * SELECT * FROM "post"
1814
- * WHERE (
1815
- * SELECT count(*) = 3
1816
- * FROM "tag" AS "tags"
1817
- * WHERE "tag"."tagName" IN ('typescript', 'node.js')
1818
- * -- join tags to the post via "postTag" table
1819
- * AND EXISTS (
1820
- * SELECT 1 FROM "postTag"
1821
- * WHERE "postTag"."postId" = "post"."id"
1822
- * AND "postTag"."tagId" = "tag"."id"
1823
- * )
1824
- * )
1514
+ * INSERT INTO "table"("relatedId", "key")
1515
+ * SELECT "relatedTable"."id" AS "relatedId", 'value'
1516
+ * FROM "relatedTable"
1517
+ * WHERE "relatedTable"."key" = 'value'
1518
+ * LIMIT 1
1519
+ * RETURNING *
1825
1520
  * ```
1826
1521
  *
1827
- * In the example above we use `count()`, you can also use any other aggregate method instead, such as `min`, `max`, `avg`.
1828
- *
1829
- * The `count()` is chained with `equals` to check for a strict equality, any other operation is also allowed, such as `not`, `lt`, `gt`.
1830
- *
1831
- * ## where special keys
1832
- *
1833
- * 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.
1522
+ * @param query - query to create new records from
1523
+ * @param data - additionally you can set some columns
1524
+ */
1525
+ createFrom<T extends Query, Q extends Query & {
1526
+ returnType: 'one' | 'oneOrThrow';
1527
+ }>(this: T, query: Q, data?: Omit<CreateData<T>, keyof Q['result']>): CreateResult<T>;
1528
+ _createFrom<T extends Query, Q extends Query & {
1529
+ returnType: 'one' | 'oneOrThrow';
1530
+ }>(this: T, query: Q, data?: Omit<CreateData<T>, keyof Q['result']>): CreateResult<T>;
1531
+ /**
1532
+ * Similar to `createFrom`, but intended to create many records.
1834
1533
  *
1835
- * For example:
1534
+ * Unlike `createFrom`, it doesn't accept second argument with data, and runtime defaults cannot work with it.
1836
1535
  *
1837
1536
  * ```ts
1838
- * db.table.where({
1839
- * NOT: { key: 'value' },
1840
- * OR: [{ name: 'a' }, { name: 'b' }],
1841
- * IN: {
1842
- * columns: ['id', 'name'],
1843
- * values: [
1844
- * [1, 'a'],
1845
- * [2, 'b'],
1846
- * ],
1847
- * },
1848
- * });
1537
+ * const manyRecords = await db.table.createManyFrom(
1538
+ * RelatedTable.select({ relatedId: 'id' }).where({ key: 'value' }),
1539
+ * );
1849
1540
  * ```
1850
1541
  *
1851
- * Using methods `whereNot`, `or`, `whereIn` instead of this is a shorter and cleaner way, but in some cases, such object keys way may be more convenient.
1542
+ * @param query - query to create new records from
1543
+ */
1544
+ createManyFrom<T extends Query, Q extends Query>(this: T, query: Q): CreateManyResult<T>;
1545
+ _createManyFrom<T extends Query, Q extends Query>(this: T, query: Q): CreateManyResult<T>;
1546
+ /**
1547
+ * `defaults` allows setting values that will be used later in `create`.
1852
1548
  *
1853
- * ```ts
1854
- * db.table.where({
1855
- * // see .whereNot
1856
- * NOT: { id: 1 },
1857
- * // can be an array:
1858
- * NOT: [{ id: 1 }, { id: 2 }],
1549
+ * Columns provided in `defaults` are marked as optional in the following `create`.
1859
1550
  *
1860
- * // see .or
1861
- * OR: [{ name: 'a' }, { name: 'b' }],
1862
- * // can be an array:
1863
- * // this will give id = 1 AND id = 2 OR id = 3 AND id = 4
1864
- * OR: [
1865
- * [{ id: 1 }, { id: 2 }],
1866
- * [{ id: 3 }, { id: 4 }],
1867
- * ],
1551
+ * Default data is the same as in [create](#create) and [createMany](#createMany),
1552
+ * so you can provide a raw SQL, or a query with a query.
1868
1553
  *
1869
- * // see .in, the key syntax requires an object with columns and values
1870
- * IN: {
1871
- * columns: ['id', 'name'],
1872
- * values: [
1873
- * [1, 'a'],
1874
- * [2, 'b'],
1875
- * ],
1876
- * },
1877
- * // can be an array:
1878
- * IN: [
1879
- * {
1880
- * columns: ['id', 'name'],
1881
- * values: [
1882
- * [1, 'a'],
1883
- * [2, 'b'],
1884
- * ],
1885
- * },
1886
- * { columns: ['someColumn'], values: [['foo', 'bar']] },
1887
- * ],
1888
- * });
1554
+ * ```ts
1555
+ * // Will use firstName from defaults and lastName from create argument:
1556
+ * db.table
1557
+ * .defaults({
1558
+ * firstName: 'first name',
1559
+ * lastName: 'last name',
1560
+ * })
1561
+ * .create({
1562
+ * lastName: 'override the last name',
1563
+ * });
1889
1564
  * ```
1890
1565
  *
1891
- * ## column operators
1892
- *
1893
- * `where` argument can take an object where the key is the name of the operator and the value is its argument.
1894
- *
1895
- * Different types of columns support different sets of operators.
1896
- *
1897
- * All column operators can take a value of the same type as the column, a sub-query, or a raw SQL expression:
1566
+ * @param data - default values for `create` and `createMany` which will follow `defaults`
1567
+ */
1568
+ defaults<T extends Query, Data extends Partial<CreateData<T>>>(this: T, data: Data): T & {
1569
+ meta: {
1570
+ defaults: Record<keyof Data, true>;
1571
+ };
1572
+ };
1573
+ _defaults<T extends Query, Data extends Partial<CreateData<T>>>(this: T, data: Data): T & {
1574
+ meta: {
1575
+ defaults: Record<keyof Data, true>;
1576
+ };
1577
+ };
1578
+ /**
1579
+ * A modifier for creating queries that specify alternative behavior in the case of a conflict.
1580
+ * A conflict occurs when a table has a `PRIMARY KEY` or a `UNIQUE` index on a column
1581
+ * (or a composite index on a set of columns) and a row being created has the same value as a row
1582
+ * that already exists in the table in this column(s).
1583
+ * The default behavior in case of conflict is to raise an error and abort the query.
1584
+ * Using this method you can change this behavior to either silently ignore the error by using .onConflict().ignore()
1585
+ * or to update the existing row with new data (perform an "UPSERT") by using .onConflict().merge().
1898
1586
  *
1899
1587
  * ```ts
1900
- * import { sql } from 'orchid-orm';
1588
+ * // leave without argument to ignore or merge on any conflict
1589
+ * Target.create(data).onConflict().ignore();
1901
1590
  *
1902
- * db.table.where({
1903
- * numericColumn: {
1904
- * // lower than 5
1905
- * lt: 5,
1591
+ * // single column:
1592
+ * db.table.create(data).onConfict('email');
1906
1593
  *
1907
- * // lower than the value returned by sub-query
1908
- * lt: OtherTable.select('someNumber').take(),
1594
+ * // array of columns:
1595
+ * db.table.create(data).onConfict(['email', 'name']);
1909
1596
  *
1910
- * // raw SQL expression produces WHERE "numericColumn" < "otherColumn" + 10
1911
- * lt: sql`"otherColumn" + 10`,
1912
- * },
1913
- * });
1597
+ * // raw expression:
1598
+ * db.table.create(data).onConfict(db.table.sql`(email) where condition`);
1914
1599
  * ```
1915
1600
  *
1916
- * ### Any type of column operators
1601
+ * ::: info
1602
+ * The column(s) specified by this method must either be the table's PRIMARY KEY or have a UNIQUE index on them, or the query will fail to execute.
1603
+ * When specifying multiple columns, they must be a composite PRIMARY KEY or have a composite UNIQUE index.
1917
1604
  *
1918
- * `equals` is a simple `=` operator, it may be useful for comparing column value with JSON object:
1605
+ * You can use the db.table.sql function in onConflict.
1606
+ * It can be useful to specify a condition when you have a partial index:
1919
1607
  *
1920
1608
  * ```ts
1921
- * db.table.where({
1922
- * // when searching for an exact same JSON value, this won't work:
1923
- * jsonColumn: someObject,
1924
- *
1925
- * // use `{ equals: ... }` instead:
1926
- * jsonColumn: { equals: someObject },
1927
- * });
1609
+ * db.table
1610
+ * .create({
1611
+ * email: 'ignore@example.com',
1612
+ * name: 'John Doe',
1613
+ * active: true,
1614
+ * })
1615
+ * // ignore only on email conflict and active is true.
1616
+ * .onConflict(db.table.sql`(email) where active`)
1617
+ * .ignore();
1928
1618
  * ```
1929
1619
  *
1930
- * `not` is `!=` (aka `<>`) not equal operator:
1620
+ * :::
1931
1621
  *
1932
- * ```ts
1933
- * db.table.where({
1934
- * anyColumn: { not: value },
1935
- * });
1936
- * ```
1622
+ * See the documentation on the .ignore() and .merge() methods for more details.
1937
1623
  *
1938
- * `in` is for the `IN` operator to check if the column value is included in a list of values.
1624
+ * @param arg - optionally provide an array of columns
1625
+ */
1626
+ onConflict<T extends Query, Arg extends OnConflictArg<T>>(this: T, arg?: Arg): OnConflictQueryBuilder<T, Arg>;
1627
+ _onConflict<T extends Query, Arg extends OnConflictArg<T> | undefined = undefined>(this: T, arg?: Arg): OnConflictQueryBuilder<T, Arg>;
1628
+ }
1629
+ declare class OnConflictQueryBuilder<T extends Query, Arg extends OnConflictArg<T> | undefined> {
1630
+ private query;
1631
+ private onConflict;
1632
+ constructor(query: T, onConflict: Arg);
1633
+ /**
1634
+ * Available only after `onConflict`.
1939
1635
  *
1940
- * 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.
1636
+ * Modifies a create query, and causes it to be silently dropped without an error if a conflict occurs.
1941
1637
  *
1942
- * ```ts
1943
- * db.table.where({
1944
- * column: {
1945
- * in: ['a', 'b', 'c'],
1638
+ * Adds the `ON CONFLICT (columns) DO NOTHING` clause to the insert statement.
1946
1639
  *
1947
- * // WHERE "column" IN (SELECT "column" FROM "otherTable")
1948
- * in: OtherTable.select('column'),
1640
+ * It produces `ON CONFLICT DO NOTHING` when no `onConflict` argument provided.
1949
1641
  *
1950
- * in: db.table.sql`('a', 'b')`,
1951
- * },
1952
- * });
1642
+ * ```ts
1643
+ * db.table
1644
+ * .create({
1645
+ * email: 'ignore@example.com',
1646
+ * name: 'John Doe',
1647
+ * })
1648
+ * .onConflict('email')
1649
+ * .ignore();
1953
1650
  * ```
1651
+ */
1652
+ ignore(): T;
1653
+ /**
1654
+ * Available only after `onConflict`.
1954
1655
  *
1955
- * `notIn` is for the `NOT IN` operator, and takes the same arguments as `in`
1656
+ * Modifies a create query, to turn it into an 'upsert' operation.
1956
1657
  *
1957
- * ### Numeric, Date, and Time column operators
1658
+ * Adds an `ON CONFLICT (columns) DO UPDATE` clause to the insert statement.
1958
1659
  *
1959
- * To compare numbers, dates, and times.
1660
+ * When no `onConflict` argument provided,
1661
+ * it will automatically collect all table columns that have unique index and use them as a conflict target.
1960
1662
  *
1961
- * `lt` is for `<` (lower than)
1663
+ * ```ts
1664
+ * db.table
1665
+ * .create({
1666
+ * email: 'ignore@example.com',
1667
+ * name: 'John Doe',
1668
+ * })
1669
+ * .onConflict('email')
1670
+ * .merge();
1671
+ * ```
1962
1672
  *
1963
- * `lte` is for `<=` (lower than or equal)
1673
+ * This also works with batch creates:
1964
1674
  *
1965
- * `gt` is for `>` (greater than)
1675
+ * ```ts
1676
+ * db.table
1677
+ * .createMany([
1678
+ * { email: 'john@example.com', name: 'John Doe' },
1679
+ * { email: 'jane@example.com', name: 'Jane Doe' },
1680
+ * { email: 'alex@example.com', name: 'Alex Doe' },
1681
+ * ])
1682
+ * .onConflict('email')
1683
+ * .merge();
1684
+ * ```
1966
1685
  *
1967
- * `gte` is for `>=` (greater than or equal)
1686
+ * It is also possible to specify a subset of the columns to merge when a conflict occurs.
1687
+ * For example, you may want to set a `createdAt` column when creating but would prefer not to update it if the row already exists:
1968
1688
  *
1969
1689
  * ```ts
1970
- * db.table.where({
1971
- * numericColumn: {
1972
- * gt: 5,
1973
- * lt: 10,
1974
- * },
1975
- *
1976
- * date: {
1977
- * lte: new Date(),
1978
- * },
1690
+ * const timestamp = Date.now();
1979
1691
  *
1980
- * time: {
1981
- * gte: new Date(),
1982
- * },
1983
- * });
1692
+ * db.table
1693
+ * .create({
1694
+ * email: 'ignore@example.com',
1695
+ * name: 'John Doe',
1696
+ * createdAt: timestamp,
1697
+ * updatedAt: timestamp,
1698
+ * })
1699
+ * .onConflict('email')
1700
+ * // string argument for a single column:
1701
+ * .merge('email')
1702
+ * // array of strings for multiple columns:
1703
+ * .merge(['email', 'name', 'updatedAt']);
1984
1704
  * ```
1985
1705
  *
1986
- * `between` also works with numeric, dates, and time columns, it takes an array of two elements.
1987
- *
1988
- * Both elements can be of the same type as a column, a sub-query, or a raw SQL expression.
1706
+ * It is also possible to specify data to update separately from the data to create.
1707
+ * This is useful if you want to make an update with different data than in creating.
1708
+ * For example, you may want to change a value if the row already exists:
1989
1709
  *
1990
1710
  * ```ts
1991
- * db.table.where({
1992
- * column: {
1993
- * // simple values
1994
- * between: [1, 10],
1711
+ * const timestamp = Date.now();
1995
1712
  *
1996
- * // sub-query and raw SQL expression
1997
- * between: [OtherTable.select('column').take(), db.table.sql`2 + 2`],
1998
- * },
1999
- * });
1713
+ * db.table
1714
+ * .create({
1715
+ * email: 'ignore@example.com',
1716
+ * name: 'John Doe',
1717
+ * createdAt: timestamp,
1718
+ * updatedAt: timestamp,
1719
+ * })
1720
+ * .onConflict('email')
1721
+ * .merge({
1722
+ * name: 'John Doe The Second',
1723
+ * });
2000
1724
  * ```
2001
1725
  *
2002
- * ### Text column operators
1726
+ * It is also possible to add a WHERE clause to conditionally update only the matching rows:
2003
1727
  *
2004
- * For `text`, `char`, `varchar`, and `json` columns.
1728
+ * ```ts
1729
+ * const timestamp = Date.now();
2005
1730
  *
2006
- * `json` is stored as text, so it has text operators. Use the `jsonb` type for JSON operators.
1731
+ * db.table
1732
+ * .create({
1733
+ * email: 'ignore@example.com',
1734
+ * name: 'John Doe',
1735
+ * createdAt: timestamp,
1736
+ * updatedAt: timestamp,
1737
+ * })
1738
+ * .onConflict('email')
1739
+ * .merge({
1740
+ * name: 'John Doe',
1741
+ * updatedAt: timestamp,
1742
+ * })
1743
+ * .where({ updatedAt: { lt: timestamp } });
1744
+ * ```
2007
1745
  *
2008
- * Takes a string, or sub-query returning string, or raw SQL expression as well as other operators.
1746
+ * `merge` also accepts raw expression:
2009
1747
  *
2010
1748
  * ```ts
2011
- * db.table.where({
2012
- * textColumn: {
2013
- * // WHERE "textColumn" LIKE '%string%'
2014
- * contains: 'string',
2015
- * // WHERE "textColumn" ILIKE '%string%'
2016
- * containsInsensitive: 'string',
2017
- * // WHERE "textColumn" LIKE 'string%'
2018
- * startsWith: 'string',
2019
- * // WHERE "textColumn" ILIKE 'string%'
2020
- * startsWithInsensitive: 'string',
2021
- * // WHERE "textColumn" LIKE '%string'
2022
- * endsWith: 'string',
2023
- * // WHERE "textColumn" ILIKE '%string'
2024
- * endsWithInsensitive: 'string',
2025
- * },
2026
- * });
1749
+ * db.table
1750
+ * .create(data)
1751
+ * .onConflict()
1752
+ * .merge(db.table.sql`raw SQL expression`);
2027
1753
  * ```
2028
1754
  *
2029
- * ### JSONB column operators
1755
+ * @param update - column, or array of columns, or object for new column values, or raw SQL
1756
+ */
1757
+ merge(update?: keyof T['shape'] | (keyof T['shape'])[] | Partial<T['inputType']> | Expression): T;
1758
+ }
1759
+
1760
+ type DeleteMethodsNames = 'del' | '_del' | 'delete' | '_delete';
1761
+ type DeleteArgs<T extends Query> = T['meta']['hasWhere'] extends true ? [] : [never];
1762
+ type DeleteResult<T extends Query> = T['meta']['hasSelect'] extends true ? SetQueryKind<T, 'delete'> : SetQueryReturnsRowCount<SetQueryKind<T, 'delete'>>;
1763
+ declare class Delete {
1764
+ /**
1765
+ * Alias for `delete` method
1766
+ */
1767
+ del<T extends Query>(this: T, ..._args: DeleteArgs<T>): DeleteResult<T>;
1768
+ _del<T extends Query>(this: T, ..._args: DeleteArgs<T>): DeleteResult<T>;
1769
+ /**
1770
+ * It is aliased to `del` because `delete` is a reserved word in JavaScript.
2030
1771
  *
2031
- * For the `jsonb` column, note that the `json` type has text operators instead.
1772
+ * This method deletes one or more rows, based on other conditions specified in the query.
2032
1773
  *
2033
- * `jsonPath` operator: compare a column value under a given JSON path with the provided value.
1774
+ * By default, `delete` will return a count of deleted records.
2034
1775
  *
2035
- * Value can be of any type to compare with JSON value, or it can be a sub-query or a raw SQL expression.
1776
+ * Place `select`, `selectAll`, or `get` before `delete` to specify returning columns.
1777
+ *
1778
+ * Need to provide `where`, `findBy`, or `find` conditions before calling `delete`.
1779
+ * To prevent accidental deletion of all records, deleting without where will result in TypeScript and a runtime error.
1780
+ *
1781
+ * Use `all()` to delete ALL records without conditions:
2036
1782
  *
2037
1783
  * ```ts
2038
- * db.table.where({
2039
- * jsonbColumn: {
2040
- * jsonPath: [
2041
- * '$.name', // first element is JSON path
2042
- * '=', // second argument is comparison operator
2043
- * 'value', // third argument is a value to compare with
2044
- * ],
2045
- * },
2046
- * });
1784
+ * await db.table.all().delete();
2047
1785
  * ```
2048
1786
  *
2049
- * `jsonSupersetOf`: check if the column value is a superset of provided value.
1787
+ * ```ts
1788
+ * // deletedCount is the number of deleted records
1789
+ * const deletedCount = await db.table.where(...conditions).delete();
1790
+ *
1791
+ * // returns a single value, throws if not found
1792
+ * const id: number | undefined = await db.table
1793
+ * .findBy(...conditions)
1794
+ * .get('id')
1795
+ * .delete();
1796
+ *
1797
+ * // returns an array of records with specified columns
1798
+ * const deletedRecord = await db.table
1799
+ * .select('id', 'name', 'age')
1800
+ * .where(...conditions)
1801
+ * .delete();
2050
1802
  *
2051
- * For instance, it is true if the column has JSON `{ "a": 1, "b": 2 }` and provided value is `{ "a": 1 }`.
1803
+ * // returns an array of fully deleted records
1804
+ * const deletedUsersFull = await db.table
1805
+ * .selectAll()
1806
+ * .where(...conditions)
1807
+ * .delete();
1808
+ * ```
2052
1809
  *
2053
- * Takes the value of any type, or sub query which returns a single value, or a raw SQL expression.
1810
+ * `delete` supports joining, under the hood the join is transformed to `USING` and `WHERE` statements:
2054
1811
  *
2055
1812
  * ```ts
2056
- * db.table.where({
2057
- * jsonbColumn: {
2058
- * jsonSupersetOf: { a: 1 },
2059
- * },
2060
- * });
1813
+ * // delete all users who have corresponding profile records:
1814
+ * db.table.join(Profile, 'profile.userId', 'user.id').all().delete();
2061
1815
  * ```
1816
+ */
1817
+ delete<T extends Query>(this: T, ..._args: DeleteArgs<T>): DeleteResult<T>;
1818
+ _delete<T extends Query>(this: T, ..._args: DeleteArgs<T>): DeleteResult<T>;
1819
+ }
1820
+
1821
+ type ForQueryBuilder<Q extends Query> = Q & {
1822
+ noWait<T extends ForQueryBuilder<Q>>(this: T): T;
1823
+ _noWait<T extends ForQueryBuilder<Q>>(this: T): T;
1824
+ skipLocked<T extends ForQueryBuilder<Q>>(this: T): T;
1825
+ _skipLocked<T extends ForQueryBuilder<Q>>(this: T): T;
1826
+ };
1827
+ declare class For {
1828
+ forUpdate<T extends Query>(this: T, tableNames?: string[] | Expression): ForQueryBuilder<T>;
1829
+ _forUpdate<T extends Query>(this: T, tableNames?: string[] | Expression): ForQueryBuilder<T>;
1830
+ forNoKeyUpdate<T extends Query>(this: T, tableNames?: string[] | Expression): ForQueryBuilder<T>;
1831
+ _forNoKeyUpdate<T extends Query>(this: T, tableNames?: string[] | Expression): ForQueryBuilder<T>;
1832
+ forShare<T extends Query>(this: T, tableNames?: string[] | Expression): ForQueryBuilder<T>;
1833
+ _forShare<T extends Query>(this: T, tableNames?: string[] | Expression): ForQueryBuilder<T>;
1834
+ forKeyShare<T extends Query>(this: T, tableNames?: string[] | Expression): ForQueryBuilder<T>;
1835
+ _forKeyShare<T extends Query>(this: T, tableNames?: string[] | Expression): ForQueryBuilder<T>;
1836
+ }
1837
+
1838
+ type FromArgs<T extends Query> = [
1839
+ first: Query | Expression | Exclude<keyof T['withData'], symbol | number>,
1840
+ second?: {
1841
+ only?: boolean;
1842
+ }
1843
+ ] | TemplateLiteralArgs;
1844
+ type FromResult<T extends Query, Args extends FromArgs<T>> = Args extends TemplateStringsArray ? T : Args[0] extends string ? T['withData'] extends Record<string, WithDataItem> ? Args[0] extends keyof T['withData'] ? Omit<T, 'meta' | 'selectable'> & {
1845
+ meta: Omit<T['meta'], 'as'> & {
1846
+ as?: string;
1847
+ };
1848
+ selectable: SelectableFromShape<T['withData'][Args[0]]['shape'], Args[0]>;
1849
+ } : SetQueryTableAlias<T, Args[0]> : SetQueryTableAlias<T, Args[0]> : Args[0] extends Query ? FromQueryResult<T, Args[0]> : T;
1850
+ type FromQueryResult<T extends Query, Q extends Query, Selectable extends SelectableBase = {
1851
+ [K in keyof Q['result']]: K extends string ? {
1852
+ as: K;
1853
+ column: Q['result'][K];
1854
+ } : never;
1855
+ }, Data = GetQueryResult<T['returnType'], Q['result']>> = {
1856
+ [K in keyof T]: K extends 'meta' ? Omit<T['meta'], 'hasSelect' | 'as'> & {
1857
+ as: AliasOrTable<Q>;
1858
+ } : K extends 'selectable' ? Selectable : K extends 'result' | 'shape' ? Q['result'] : K extends 'then' ? QueryThen<Data> : K extends 'catch' ? QueryCatch<Data> : T[K];
1859
+ };
1860
+ declare class From {
1861
+ /**
1862
+ * Set the `FROM` value, by default the table name is used.
2062
1863
  *
2063
- * `jsonSubsetOf`: check if the column value is a subset of provided value.
1864
+ * ```ts
1865
+ * // accepts sub-query:
1866
+ * db.table.from(Otherdb.table.select('foo', 'bar'));
2064
1867
  *
2065
- * For instance, it is true if the column has JSON `{ "a": 1 }` and provided value is `{ "a": 1, "b": 2 }`.
1868
+ * // accepts raw sql by template literal:
1869
+ * const value = 123;
1870
+ * db.table.from`value = ${value}`;
2066
1871
  *
2067
- * Takes the value of any type, or sub query which returns a single value, or a raw SQL expression.
1872
+ * // accepts raw sql:
1873
+ * db.table.from(db.table.sql`value = ${value}`);
1874
+ *
1875
+ * // accepts alias of `WITH` expression:
1876
+ * q.with('foo', Otherdb.table.select('id', 'name')).from('foo');
1877
+ * ```
1878
+ *
1879
+ * Optionally takes a second argument of type `{ only?: boolean }`, (see `FROM ONLY` in Postgres docs, this is related to table inheritance).
2068
1880
  *
2069
1881
  * ```ts
2070
- * db.table.where({
2071
- * jsonbColumn: {
2072
- * jsonSupersetOf: { a: 1 },
2073
- * },
1882
+ * db.table.from(Otherdb.table.select('foo', 'bar'), {
1883
+ * only: true,
2074
1884
  * });
2075
1885
  * ```
2076
1886
  *
2077
- * @param args - {@link WhereArgs}
1887
+ * @param args - query, raw SQL, name of CTE table, or a template string
2078
1888
  */
2079
- where<T extends WhereQueryBase>(this: T, ...args: WhereArgs<T>): WhereResult<T>;
2080
- _where<T extends WhereQueryBase>(this: T, ...args: WhereArgs<T>): WhereResult<T>;
1889
+ from<T extends Query, Args extends FromArgs<T>>(this: T, ...args: Args): FromResult<T, Args>;
1890
+ _from<T extends Query, Args extends FromArgs<T>>(this: T, ...args: Args): FromResult<T, Args>;
1891
+ }
1892
+
1893
+ type GetArg<T extends QueryBase> = GetStringArg<T> | Expression;
1894
+ type GetStringArg<T extends QueryBase> = StringKey<keyof T['selectable']>;
1895
+ type GetResult<T extends Query, Arg extends GetArg<T>> = Arg extends GetStringArg<T> ? SetQueryReturnsValue<T, Arg> : Arg extends Expression ? SetQueryReturnsColumn<T, Arg['_type']> : never;
1896
+ type GetResultOptional<T extends Query, Arg extends GetArg<T>> = Arg extends GetStringArg<T> ? SetQueryReturnsValueOptional<T, Arg> : Arg extends Expression ? SetQueryReturnsColumnOptional<T, Arg['_type']> : never;
1897
+ declare class QueryGet {
2081
1898
  /**
2082
- * `whereNot` takes the same arguments as `where` and prepends them with `NOT` in SQL
1899
+ * `.get` returns a single value, it will add `LIMIT 1` to the query, and accepts a column name or a raw expression.
1900
+ * It will throw `NotFoundError` when not found.
2083
1901
  *
2084
1902
  * ```ts
2085
- * // find records of different colors than red
2086
- * db.table.whereNot({ color: 'red' });
1903
+ * import { NumberColumn } from 'pqb';
1904
+ *
1905
+ * const firstName: string = await db.table.get('name');
1906
+ *
1907
+ * const rawResult: number = await db.table.get(
1908
+ * db.table.sql((t) => t.integer())`1 + 1`,
1909
+ * );
2087
1910
  * ```
2088
1911
  *
2089
- * @param args - {@link WhereArgs}
1912
+ * @param arg - string for a column to get, or a raw SQL
2090
1913
  */
2091
- whereNot<T extends WhereQueryBase>(this: T, ...args: WhereArgs<T>): WhereResult<T>;
2092
- _whereNot<T extends WhereQueryBase>(this: T, ...args: WhereArgs<T>): WhereResult<T>;
1914
+ get<T extends Query, Arg extends GetArg<T>>(this: T, arg: Arg): GetResult<T, Arg>;
1915
+ _get<T extends Query, Arg extends GetArg<T>>(this: T, arg: Arg): GetResult<T, Arg>;
2093
1916
  /**
2094
- * `and` is an alias for {@link where} to make it look closer to SQL:
1917
+ * `.getOptional` returns a single value or undefined when not found:
2095
1918
  *
2096
1919
  * ```ts
2097
- * db.table.where({ id: 1 }).and({ name: 'John' });
1920
+ * const firstName: string | undefined = await db.table.getOptional('name');
2098
1921
  * ```
2099
1922
  *
2100
- * @param args - {@link WhereArgs}
2101
- */
2102
- and<T extends WhereQueryBase>(this: T, ...args: WhereArgs<T>): WhereResult<T>;
2103
- _and<T extends WhereQueryBase>(this: T, ...args: WhereArgs<T>): WhereResult<T>;
2104
- /**
2105
- * `andNot` is an alias for `whereNot`.
2106
- *
2107
- * @param args - {@link WhereArgs}
1923
+ * @param arg - string for a column to get, or a raw SQL
2108
1924
  */
2109
- andNot<T extends WhereQueryBase>(this: T, ...args: WhereArgs<T>): WhereResult<T>;
2110
- _andNot<T extends WhereQueryBase>(this: T, ...args: WhereArgs<T>): WhereResult<T>;
1925
+ getOptional<T extends Query, Arg extends GetArg<T>>(this: T, arg: Arg): GetResultOptional<T, Arg>;
1926
+ _getOptional<T extends Query, Arg extends GetArg<T>>(this: T, arg: Arg): GetResultOptional<T, Arg>;
1927
+ }
1928
+
1929
+ type HavingArgs<T extends Query> = TemplateLiteralArgs | HavingArgFn<T>[];
1930
+ type HavingArgFn<T extends Query> = (q: SelectAggMethods<T>) => Expression<ColumnTypeBase<boolean | null>>;
1931
+ declare class Having {
2111
1932
  /**
2112
- * `or` is accepting the same arguments as {@link where}, joining arguments with `OR`.
2113
- *
2114
- * Columns in single arguments are still joined with `AND`.
1933
+ * Build a `HAVING` clause to the query to filter records by results of [aggregate functions](#aggregate-functions).
2115
1934
  *
2116
- * The database is processing `AND` before `OR`, so this should be intuitively clear.
1935
+ * The argument of `having` is a function where you call the aggregate function and compare it with some value by using [column operators](/guide/where.html#column-operators).
2117
1936
  *
2118
1937
  * ```ts
2119
- * db.table.or({ id: 1, color: 'red' }, { id: 2, color: 'blue' });
2120
- * ```
2121
- *
2122
- * This query will produce such SQL (simplified):
2123
- *
2124
- * ```sql
2125
- * SELECT * FROM "table"
2126
- * WHERE id = 1 AND color = 'red'
2127
- * OR id = 2 AND color = 'blue'
1938
+ * db.table.having((q) => q.count().gte(10));
1939
+ * // HAVING count(*) >= 10
2128
1940
  * ```
2129
1941
  *
2130
- * @param args - {@link WhereArgs} will be joined with `OR`
2131
- */
2132
- or<T extends WhereQueryBase>(this: T, ...args: WhereArg<T>[]): WhereResult<T>;
2133
- _or<T extends WhereQueryBase>(this: T, ...args: WhereArg<T>[]): WhereResult<T>;
2134
- /**
2135
- * `orNot` takes the same arguments as {@link or}, and prepends each condition with `NOT` just as {@link whereNot} does.
2136
- *
2137
- * @param args - {@link WhereArgs} will be prefixed with `NOT` and joined with `OR`
2138
- */
2139
- orNot<T extends WhereQueryBase>(this: T, ...args: WhereArg<T>[]): WhereResult<T>;
2140
- _orNot<T extends WhereQueryBase>(this: T, ...args: WhereArg<T>[]): WhereResult<T>;
2141
- /**
2142
- * `whereIn` and related methods are for the `IN` operator to check for inclusion in a list of values.
2143
- *
2144
- * When used with a single column it works equivalent to the `in` column operator:
1942
+ * Alternatively, it accepts a raw SQL template:
2145
1943
  *
2146
1944
  * ```ts
2147
- * db.table.whereIn('column', [1, 2, 3]);
2148
- * // the same as:
2149
- * db.table.where({ column: [1, 2, 3] });
1945
+ * db.table.having`count(*) >= ${10}`;
2150
1946
  * ```
2151
1947
  *
2152
- * `whereIn` can support a tuple of columns, that's what the `in` operator cannot support:
1948
+ * Multiple having conditions will be combined with `AND`:
2153
1949
  *
2154
1950
  * ```ts
2155
- * db.table.whereIn(
2156
- * ['id', 'name'],
2157
- * [
2158
- * [1, 'Alice'],
2159
- * [2, 'Bob'],
2160
- * ],
1951
+ * db.table.having(
1952
+ * (q) => q.sum('column').gt(5),
1953
+ * (q) => q.avg('column').lt(10),
2161
1954
  * );
1955
+ * // HAVING sum(column) > 5 AND avg(column) < 10
2162
1956
  * ```
2163
1957
  *
2164
- * It supports sub query which should return records with columns of the same type:
1958
+ * After applying a comparison, `or` and `and` methods become available:
2165
1959
  *
2166
1960
  * ```ts
2167
- * db.table.whereIn(['id', 'name'], OtherTable.select('id', 'name'));
1961
+ * db.table.having((q) =>
1962
+ * q.sum('column').equals(5).or(q.min('column').gt(1), q.max('column').lt(10)),
1963
+ * );
1964
+ * // HAVING (sum(column) = 5) OR (min(column) > 1 AND max(column) < 10)
2168
1965
  * ```
2169
1966
  *
2170
- * It supports raw SQL expression:
1967
+ * Aggregate functions are exactly the same functions described in [aggregate functions](#aggregate-functions), they can accept aggregation options:
2171
1968
  *
2172
1969
  * ```ts
2173
- * db.table.whereIn(['id', 'name'], db.table.sql`((1, 'one'), (2, 'two'))`);
1970
+ * db.table.having((q) =>
1971
+ * q
1972
+ * .count('id', {
1973
+ * distinct: true,
1974
+ * order: { createdAt: 'DESC', filter: { someColumn: { not: null } } },
1975
+ * })
1976
+ * .gte(10),
1977
+ * );
2174
1978
  * ```
2175
1979
  *
2176
- * @param column - one column name, or array of column names
2177
- * @param values - array of values, or a query to load values, or a raw SQL. Tuple of such values in case of multiple columns.
2178
- */
2179
- whereIn<T extends WhereQueryBase, Column extends WhereInColumn<T>>(this: T, column: Column, values: WhereInValues<T, Column>): WhereResult<T>;
2180
- /**
2181
- * See {@link whereIn}.
2182
- *
2183
- * @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.
2184
- */
2185
- whereIn<T extends WhereQueryBase>(this: T, arg: WhereInArg<T>): WhereResult<T>;
2186
- _whereIn<T extends WhereQueryBase, Column extends WhereInColumn<T>>(this: T, column: Column, values: WhereInValues<T, Column>): WhereResult<T>;
2187
- _whereIn<T extends WhereQueryBase>(this: T, arg: WhereInArg<T>): WhereResult<T>;
2188
- /**
2189
- * Takes the same arguments as {@link whereIn}.
2190
- * Add a `WHERE IN` condition prefixed with `OR` to the query:
1980
+ * Arguments of the aggregate function and of the comparison can be raw SQL:
2191
1981
  *
2192
1982
  * ```ts
2193
- * db.table.whereIn('a', [1, 2, 3]).orWhereIn('b', ['one', 'two']);
1983
+ * db.table.having((q) => q.count(q.sql('coalesce(one, two)')).gte(q.sql`2 + 2`));
2194
1984
  * ```
2195
1985
  *
2196
- * @param column - one column name, or array of column names
2197
- * @param values - array of values, or a query to load values, or a raw SQL. Tuple of such values in case of multiple columns.
2198
- */
2199
- orWhereIn<T extends WhereQueryBase, Column extends WhereInColumn<T>>(this: T, column: Column, values: WhereInValues<T, Column>): WhereResult<T>;
2200
- /**
2201
- * See {@link orWhereIn}.
2202
- *
2203
- * @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.
1986
+ * @param args - raw SQL template string or one or multiple callbacks returning a boolean expression
2204
1987
  */
2205
- orWhereIn<T extends WhereQueryBase>(this: T, arg: WhereInArg<T>): WhereResult<T>;
2206
- _orWhereIn<T extends WhereQueryBase, Column extends WhereInColumn<T>>(this: T, column: Column, values: WhereInValues<T, Column>): WhereResult<T>;
2207
- _orWhereIn<T extends WhereQueryBase>(this: T, arg: WhereInArg<T>): WhereResult<T>;
1988
+ having<T extends Query>(this: T, ...args: HavingArgs<T>): T;
1989
+ _having<T extends Query>(this: T, ...args: HavingArgs<T>): T;
1990
+ }
1991
+
1992
+ type AfterHook<Select extends PropertyKey[], Shape extends ColumnsShapeBase, Selected extends ColumnsShapeBase = Pick<Shape, StringKey<Select[number]>>, Item = {
1993
+ [K in keyof Selected]: Selected[K]['outputType'];
1994
+ }> = QueryAfterHook<Item[]>;
1995
+ type HookSelect<T extends QueryBase> = (keyof T['shape'])[];
1996
+ type HookAction = 'Create' | 'Update' | 'Delete';
1997
+ declare abstract class QueryHooks extends QueryBase {
2208
1998
  /**
2209
- * Acts as `whereIn`, but negates the condition with `NOT`:
2210
- *
2211
- * ```ts
2212
- * db.table.whereNotIn('color', ['red', 'green', 'blue']);
2213
- * ```
1999
+ * Run the function before any kind of query.
2214
2000
  *
2215
- * @param column - one column name, or array of column names
2216
- * @param values - array of values, or a query to load values, or a raw SQL. Tuple of such values in case of multiple columns.
2001
+ * @param cb - function to call, first argument is a query object
2217
2002
  */
2218
- whereNotIn<T extends WhereQueryBase, Column extends WhereInColumn<T>>(this: T, column: Column, values: WhereInValues<T, Column>): WhereResult<T>;
2003
+ beforeQuery<T extends QueryHooks>(this: T, cb: QueryBeforeHook): T;
2004
+ _beforeQuery<T extends QueryBase>(this: T, cb: QueryBeforeHook): T;
2219
2005
  /**
2220
- * See {@link whereNotIn}.
2006
+ * Run the function after any kind of query.
2007
+ * Enforces wrapping the query into a transaction.
2008
+ * The function will run after the query is succeeded, but before the transaction commit.
2221
2009
  *
2222
- * @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.
2010
+ * @param cb - function to call, first argument is the query result of type `unknown`, second argument is a query object
2223
2011
  */
2224
- whereNotIn<T extends WhereQueryBase>(this: T, arg: WhereInArg<T>): WhereResult<T>;
2225
- _whereNotIn<T extends WhereQueryBase, Column extends WhereInColumn<T>>(this: T, column: Column, values: WhereInValues<T, Column>): WhereResult<T>;
2226
- _whereNotIn<T extends WhereQueryBase>(this: T, arg: WhereInArg<T>): WhereResult<T>;
2012
+ afterQuery<T extends QueryHooks>(this: T, cb: QueryAfterHook): T;
2013
+ _afterQuery<T extends QueryBase>(this: T, cb: QueryAfterHook): T;
2227
2014
  /**
2228
- * Acts as `whereIn`, but prepends `OR` to the condition and negates it with `NOT`:
2229
- *
2230
- * ```ts
2231
- * db.table.whereNotIn('a', [1, 2, 3]).orWhereNoIn('b', ['one', 'two']);
2232
- * ```
2015
+ * Run the function before a `create` kind of query.
2233
2016
  *
2234
- * @param column - one column name, or array of column names
2235
- * @param values - array of values, or a query to load values, or a raw SQL. Tuple of such values in case of multiple columns.
2017
+ * @param cb - function to call, first argument is a query object
2236
2018
  */
2237
- orWhereNotIn<T extends WhereQueryBase, Column extends WhereInColumn<T>>(this: T, column: Column, values: WhereInValues<T, Column>): WhereResult<T>;
2019
+ beforeCreate<T extends QueryHooks>(this: T, cb: QueryBeforeHook): T;
2020
+ _beforeCreate<T extends QueryBase>(this: T, cb: QueryBeforeHook): T;
2238
2021
  /**
2239
- * See {@link orWhereNotIn}.
2022
+ * Run the function after a `create` kind of query.
2023
+ * Enforces wrapping the query into a transaction.
2024
+ * The function will run after the query is succeeded, but before the transaction commit.
2025
+ * Queries inside the function will run in the same transaction as the target query.
2240
2026
  *
2241
- * @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.
2027
+ * @param select - list of columns to select for the hook
2028
+ * @param cb - function to call, first argument is the query result with selected columns, second argument is a query object
2242
2029
  */
2243
- orWhereNotIn<T extends WhereQueryBase>(this: T, arg: WhereInArg<T>): WhereResult<T>;
2244
- _orWhereNotIn<T extends WhereQueryBase, Column extends WhereInColumn<T>>(this: T, column: Column, values: WhereInValues<T, Column>): WhereResult<T>;
2245
- _orWhereNotIn<T extends WhereQueryBase>(this: T, arg: WhereInArg<T>): WhereResult<T>;
2030
+ afterCreate<T extends QueryHooks, S extends HookSelect<T>>(this: T, select: S, cb: AfterHook<S, T['shape']>): T;
2031
+ _afterCreate<T extends QueryBase, S extends HookSelect<T>>(this: T, select: S, cb: AfterHook<S, T['shape']>): T;
2246
2032
  /**
2247
- * `whereExists` is for support of the `WHERE EXISTS (query)` clause.
2248
- *
2249
- * This method is accepting the same arguments as `join`, see the {@link Join.join} section for more details.
2250
- *
2251
- * ```ts
2252
- * // find users who have accounts
2253
- * // find by a relation name if it's defined
2254
- * db.user.whereExists('account');
2255
- *
2256
- * // find using a table and a join conditions
2257
- * db.user.whereExists(db.account, 'account.id', 'user.id');
2258
- *
2259
- * // find using a query builder in a callback:
2260
- * db.user.whereExists(db.account, (q) => q.on('account.id', '=', 'user.id'));
2261
- * ```
2033
+ * Run the function after transaction for a `create` kind of query will be committed.
2034
+ * If the query wasn't wrapped in a transaction, will run after the query.
2262
2035
  *
2263
- * @param arg - relation name, or a query object, or a `with` table alias, or a callback returning a query object.
2264
- * @param args - no arguments needed when the first argument is a relation name, or conditions to join the table with.
2036
+ * @param select - list of columns to select for the hook
2037
+ * @param cb - function to call, first argument is the query result with selected columns, second argument is a query object
2265
2038
  */
2266
- whereExists<T extends WhereQueryBase, Arg extends JoinFirstArg<T>>(this: T, arg: Arg, ...args: JoinArgs<T, Arg>): WhereResult<T>;
2039
+ afterCreateCommit<T extends QueryHooks, S extends HookSelect<T>>(this: T, select: S, cb: AfterHook<S, T['shape']>): T;
2040
+ _afterCreateCommit<T extends QueryHooks, S extends HookSelect<T>>(this: T, select: S, cb: AfterHook<S, T['shape']>): T;
2267
2041
  /**
2268
- * See {@link whereExists}.
2042
+ * Run the function before an `update` kind of query.
2269
2043
  *
2270
- * @param arg - relation name, or a query object, or a `with` table alias, or a callback returning a query object.
2271
- * @param cb - callback with a query builder to join the table.
2044
+ * @param cb - function to call, first argument is a query object
2272
2045
  */
2273
- whereExists<T extends WhereQueryBase, Arg extends JoinFirstArg<T>>(this: T, arg: Arg, cb: JoinCallback<T, Arg>): WhereResult<T>;
2274
- _whereExists<T extends WhereQueryBase, Arg extends JoinFirstArg<T>>(this: T, arg: Arg, ...args: JoinArgs<T, Arg>): WhereResult<T>;
2275
- _whereExists<T extends WhereQueryBase, Arg extends JoinFirstArg<T>>(this: T, arg: Arg, cb: JoinCallback<T, Arg>): WhereResult<T>;
2046
+ beforeUpdate<T extends QueryHooks>(this: T, cb: QueryBeforeHook): T;
2047
+ _beforeUpdate<T extends QueryHooks>(this: T, cb: QueryBeforeHook): T;
2276
2048
  /**
2277
- * Acts as `whereExists`, but prepends the condition with `OR`:
2278
- *
2279
- * ```ts
2280
- * // find users who have an account or a profile,
2281
- * // imagine that the user has both `account` and `profile` relations defined.
2282
- * db.user.whereExist('account').orWhereExists('profile');
2283
- * ```
2049
+ * Run the function after an `update` kind of query.
2050
+ * Enforces wrapping the query into a transaction.
2051
+ * The function will run after the query is succeeded, but before the transaction commit.
2052
+ * Queries inside the function will run in the same transaction as the target query.
2053
+ * If no records were updated, the hook *won't* run.
2284
2054
  *
2285
- * @param arg - relation name, or a query object, or a `with` table alias, or a callback returning a query object.
2286
- * @param args - no arguments needed when the first argument is a relation name, or conditions to join the table with.
2055
+ * @param select - list of columns to select for the hook
2056
+ * @param cb - function to call, first argument is the query result with selected columns, second argument is a query object
2287
2057
  */
2288
- orWhereExists<T extends WhereQueryBase, Arg extends JoinFirstArg<T>, Args extends JoinArgs<T, Arg>>(this: T, arg: Arg, ...args: Args): WhereResult<T>;
2058
+ afterUpdate<T extends QueryHooks, S extends HookSelect<T>>(this: T, select: S, cb: AfterHook<S, T['shape']>): T;
2059
+ _afterUpdate<T extends QueryHooks, S extends HookSelect<T>>(this: T, select: S, cb: AfterHook<S, T['shape']>): T;
2289
2060
  /**
2290
- * See {@link orWhereExists}.
2061
+ * Run the function after transaction for an `update` kind of query will be committed.
2062
+ * If the query wasn't wrapped in a transaction, will run after the query.
2063
+ * If no records were updated, the hook *won't* run.
2291
2064
  *
2292
- * @param arg - relation name, or a query object, or a `with` table alias, or a callback returning a query object.
2293
- * @param cb - callback with a query builder to join the table.
2065
+ * @param select - list of columns to select for the hook
2066
+ * @param cb - function to call, first argument is the query result with selected columns, second argument is a query object
2294
2067
  */
2295
- orWhereExists<T extends WhereQueryBase, Arg extends JoinFirstArg<T>>(this: T, arg: Arg, cb: JoinCallback<T, Arg>): WhereResult<T>;
2296
- _orWhereExists<T extends WhereQueryBase, Arg extends JoinFirstArg<T>, Args extends JoinArgs<T, Arg>>(this: T, arg: Arg, ...args: Args): WhereResult<T>;
2297
- _orWhereExists<T extends WhereQueryBase, Arg extends JoinFirstArg<T>>(this: T, arg: Arg, cb: JoinCallback<T, Arg>): WhereResult<T>;
2068
+ afterUpdateCommit<T extends QueryHooks, S extends HookSelect<T>>(this: T, select: S, cb: AfterHook<S, T['shape']>): T;
2069
+ _afterUpdateCommit<T extends QueryHooks, S extends HookSelect<T>>(this: T, select: S, cb: AfterHook<S, T['shape']>): T;
2298
2070
  /**
2299
- * Acts as `whereExists`, but negates the condition with `NOT`:
2071
+ * Run the function before a `create` or an `update` kind of query.
2300
2072
  *
2301
- * ```ts
2302
- * // find users who don't have an account,
2303
- * // image that the user `belongsTo` or `hasOne` account.
2304
- * db.user.whereNotExist('account');
2305
- * ```
2073
+ * @param cb - function to call, first argument is a query object
2074
+ */
2075
+ beforeSave<T extends QueryHooks>(this: T, cb: QueryBeforeHook): T;
2076
+ _beforeSave<T extends QueryHooks>(this: T, cb: QueryBeforeHook): T;
2077
+ /**
2078
+ * Run the function after a `create` or an `update` kind of query.
2079
+ * Enforces wrapping the query into a transaction.
2080
+ * The function will run after the query is succeeded, but before the transaction commit.
2081
+ * Queries inside the function will run in the same transaction as the target query.
2082
+ * For the `update` query, if no records were updated, the hook *won't* run.
2306
2083
  *
2307
- * @param arg - relation name, or a query object, or a `with` table alias, or a callback returning a query object.
2308
- * @param args - no arguments needed when the first argument is a relation name, or conditions to join the table with.
2084
+ * @param select - list of columns to select for the hook
2085
+ * @param cb - function to call, first argument is the query result with selected columns, second argument is a query object
2309
2086
  */
2310
- whereNotExists<T extends WhereQueryBase, Arg extends JoinFirstArg<T>, Args extends JoinArgs<T, Arg>>(this: T, arg: Arg, ...args: Args): WhereResult<T>;
2087
+ afterSave<T extends QueryHooks, S extends HookSelect<T>>(this: T, select: S, cb: AfterHook<S, T['shape']>): T;
2088
+ _afterSave<T extends QueryHooks, S extends HookSelect<T>>(this: T, select: S, cb: AfterHook<S, T['shape']>): T;
2311
2089
  /**
2312
- * See {@link whereNotExists}.
2090
+ * Run the function after transaction for a `create` or an `update` kind of query will be committed.
2091
+ * If the query wasn't wrapped in a transaction, will run after the query.
2092
+ * For the `update` query, if no records were updated, the hook *won't* run.
2313
2093
  *
2314
- * @param arg - relation name, or a query object, or a `with` table alias, or a callback returning a query object.
2315
- * @param cb - callback with a query builder to join the table.
2094
+ * @param select - list of columns to select for the hook
2095
+ * @param cb - function to call, first argument is the query result with selected columns, second argument is a query object
2316
2096
  */
2317
- whereNotExists<T extends WhereQueryBase, Arg extends JoinFirstArg<T>>(this: T, arg: Arg, cb: JoinCallback<T, Arg>): WhereResult<T>;
2318
- _whereNotExists<T extends WhereQueryBase, Arg extends JoinFirstArg<T>, Args extends JoinArgs<T, Arg>>(this: T, arg: Arg, ...args: Args): WhereResult<T>;
2319
- _whereNotExists<T extends WhereQueryBase, Arg extends JoinFirstArg<T>>(this: T, arg: Arg, cb: JoinCallback<T, Arg>): WhereResult<T>;
2097
+ afterSaveCommit<T extends QueryHooks, S extends HookSelect<T>>(this: T, select: S, cb: AfterHook<S, T['shape']>): T;
2098
+ _afterSaveCommit<T extends QueryHooks, S extends HookSelect<T>>(this: T, select: S, cb: AfterHook<S, T['shape']>): T;
2320
2099
  /**
2321
- * Acts as `whereExists`, but prepends the condition with `OR` and negates it with `NOT`:
2100
+ * Run the function before a `delete` kind of query.
2322
2101
  *
2323
- * ```ts
2324
- * // find users who don't have an account OR who don't have a profile
2325
- * // imagine that the user has both `account` and `profile` relations defined.
2326
- * db.user.whereNotExists('account').orWhereNotExists('profile');
2327
- * ```
2102
+ * @param cb - function to call, first argument is a query object
2103
+ */
2104
+ beforeDelete<T extends QueryHooks>(this: T, cb: QueryBeforeHook): T;
2105
+ _beforeDelete<T extends QueryHooks>(this: T, cb: QueryBeforeHook): T;
2106
+ /**
2107
+ * Run the function after a `delete` kind of query.
2108
+ * Enforces wrapping the query into a transaction.
2109
+ * The function will run after the query is succeeded, but before the transaction commit.
2110
+ * Queries inside the function will run in the same transaction as the target query.
2111
+ * If no records were deleted, the hook *won't* run.
2328
2112
  *
2329
- * @param arg - relation name, or a query object, or a `with` table alias, or a callback returning a query object.
2330
- * @param args - no arguments needed when the first argument is a relation name, or conditions to join the table with.
2113
+ * @param select - list of columns to select for the hook
2114
+ * @param cb - function to call, first argument is the query result with selected columns, second argument is a query object
2331
2115
  */
2332
- orWhereNotExists<T extends WhereQueryBase, Arg extends JoinFirstArg<T>, Args extends JoinArgs<T, Arg>>(this: T, arg: Arg, ...args: Args): WhereResult<T>;
2116
+ afterDelete<T extends QueryHooks, S extends HookSelect<T>>(this: T, select: S, cb: AfterHook<S, T['shape']>): T;
2117
+ _afterDelete<T extends QueryHooks, S extends HookSelect<T>>(this: T, select: S, cb: AfterHook<S, T['shape']>): T;
2333
2118
  /**
2334
- * See {@link orWhereNotExists}.
2119
+ * Run the function after transaction for a `delete` kind of query will be committed.
2120
+ * If the query wasn't wrapped in a transaction, will run after the query.
2121
+ * If no records were deleted, the hook *won't* run.
2335
2122
  *
2336
- * @param arg - relation name, or a query object, or a `with` table alias, or a callback returning a query object.
2337
- * @param cb - callback with a query builder to join the table.
2123
+ * @param select - list of columns to select for the hook
2124
+ * @param cb - function to call, first argument is the query result with selected columns, second argument is a query object
2338
2125
  */
2339
- orWhereNotExists<T extends WhereQueryBase, Arg extends JoinFirstArg<T>>(this: T, arg: Arg, cb: JoinCallback<T, Arg>): WhereResult<T>;
2340
- _orWhereNotExists<T extends WhereQueryBase, Arg extends JoinFirstArg<T>, Args extends JoinArgs<T, Arg>>(this: T, arg: Arg, ...args: Args): WhereResult<T>;
2341
- _orWhereNotExists<T extends WhereQueryBase, Arg extends JoinFirstArg<T>>(this: T, arg: Arg, cb: JoinCallback<T, Arg>): WhereResult<T>;
2342
- }
2343
- interface WhereQueryBase extends Where, QueryBase {
2344
- }
2345
- declare abstract class WhereQueryBase extends QueryBase {
2126
+ afterDeleteCommit<T extends QueryHooks, S extends HookSelect<T>>(this: T, select: S, cb: AfterHook<S, T['shape']>): T;
2127
+ _afterDeleteCommit<T extends QueryHooks, S extends HookSelect<T>>(this: T, select: S, cb: AfterHook<S, T['shape']>): T;
2346
2128
  }
2347
2129
 
2348
- type CreateData<T extends Query, Data = SetOptional<{
2349
- [K in keyof T['inputType']]: CreateColumn<T, K>;
2350
- }, keyof T['meta']['defaults']>> = [keyof T['relations']] extends [never] ? Data : OmitBelongsToForeignKeys<T['relations'], Data> & CreateRelationData<T>;
2351
- type CreateColumn<T extends Query, Key extends keyof T['inputType']> = Expression | T['inputType'][Key] | {
2352
- [K in keyof Query]: K extends 'then' ? QueryThen<T['inputType'][Key]> : Query[K];
2353
- };
2354
- type OmitBelongsToForeignKeys<R extends RelationsBase, Data> = Omit<Data, {
2355
- [K in keyof R]: R[K] extends BelongsToRelation ? R[K]['options']['foreignKey'] : never;
2356
- }[keyof R]>;
2357
- type CreateRelationData<T extends Query> = {
2358
- [K in keyof T['relations']]: T['relations'][K] extends BelongsToRelation ? CreateBelongsToData<T, K, T['relations'][K]> : T['relations'][K] extends HasOneRelation ? CreateHasOneData<T, K, T['relations'][K]> : T['relations'][K] extends HasManyRelation | HasAndBelongsToManyRelation ? CreateHasManyData<T, K, T['relations'][K]> : EmptyObject;
2359
- }[keyof T['relations']];
2360
- type CreateBelongsToData<T extends Query, Key extends keyof T['relations'], Rel extends BelongsToRelation, FKeys = {
2361
- [K in Rel['options']['foreignKey']]: Rel['options']['foreignKey'] extends keyof T['inputType'] ? T['inputType'][Rel['options']['foreignKey']] : never;
2362
- }> = {
2363
- [K in keyof FKeys]: K extends keyof T['meta']['defaults'] ? {
2364
- [L in K]?: FKeys[L];
2365
- } : {
2366
- [L in K]: FKeys[L];
2367
- };
2368
- }[keyof FKeys] | {
2369
- [K in Key]: {
2370
- create: CreateData<Rel['nestedCreateQuery']>;
2371
- connect?: never;
2372
- connectOrCreate?: never;
2373
- } | {
2374
- create?: never;
2375
- connect: WhereArg<Rel['table']>;
2376
- connectOrCreate?: never;
2377
- } | {
2378
- create?: never;
2379
- connect?: never;
2380
- connectOrCreate: {
2381
- where: WhereArg<Rel['table']>;
2382
- create: CreateData<Rel['nestedCreateQuery']>;
2383
- };
2384
- };
2385
- };
2386
- type CreateHasOneData<T extends Query, Key extends keyof T['relations'], Rel extends HasOneRelation> = 'through' extends Rel['options'] ? {} : {
2387
- [K in Key]?: {
2388
- create: CreateData<Rel['nestedCreateQuery']>;
2389
- connect?: never;
2390
- connectOrCreate?: never;
2391
- } | {
2392
- create?: never;
2393
- connect: WhereArg<Rel['table']>;
2394
- connectOrCreate?: never;
2395
- } | {
2396
- create?: never;
2397
- connect?: never;
2398
- connectOrCreate: {
2399
- where?: WhereArg<Rel['table']>;
2400
- create?: CreateData<Rel['nestedCreateQuery']>;
2401
- };
2402
- };
2403
- };
2404
- type CreateHasManyData<T extends Query, Key extends keyof T['relations'], Rel extends HasManyRelation | HasAndBelongsToManyRelation> = 'through' extends Rel['options'] ? {} : {
2405
- [K in Key]?: {
2406
- create?: CreateData<Rel['nestedCreateQuery']>[];
2407
- connect?: WhereArg<Rel['table']>[];
2408
- connectOrCreate?: {
2409
- where: WhereArg<Rel['table']>;
2410
- create: CreateData<Rel['nestedCreateQuery']>;
2411
- }[];
2412
- };
2413
- };
2414
- type CreateResult<T extends Query> = T extends {
2415
- isCount: true;
2416
- } ? SetQueryKind<T, 'create'> : QueryReturnsAll<T['returnType']> extends true ? SetQueryReturnsOne<SetQueryKind<T, 'create'>> : SetQueryKind<T, 'create'>;
2417
- type CreateManyResult<T extends Query> = T extends {
2418
- isCount: true;
2419
- } ? SetQueryKind<T, 'create'> : T['returnType'] extends 'one' | 'oneOrThrow' ? SetQueryReturnsAll<SetQueryKind<T, 'create'>> : SetQueryKind<T, 'create'>;
2420
- type CreateRawData<T extends Query> = {
2421
- columns: (keyof T['shape'])[];
2422
- values: Expression;
2423
- };
2424
- type CreateManyRawData<T extends Query> = {
2425
- columns: (keyof T['shape'])[];
2426
- values: Expression[];
2427
- };
2428
- type RawRequiredColumns<T extends Query> = {
2429
- [K in keyof T['inputType'] as K extends keyof T['meta']['defaults'] ? never : null extends T['inputType'][K] ? never : undefined extends T['inputType'][K] ? never : K]: true;
2430
- };
2431
- type CreateRawArgs<T extends Query, Arg extends {
2432
- columns: (keyof T['shape'])[];
2433
- }> = keyof RawRequiredColumns<T> extends Arg['columns'][number] ? [data: Arg] : [
2434
- `Missing required columns: ${Exclude<StringKey<keyof RawRequiredColumns<T>>, Arg['columns'][number]>}`
2435
- ];
2436
- type OnConflictArg<T extends Query> = keyof T['shape'] | (keyof T['shape'])[] | Expression;
2437
- type CreateCtx = {
2438
- columns: Map<string, number>;
2439
- returnTypeAll?: true;
2440
- resultAll: Record<string, unknown>[];
2130
+ type WhereArg<T extends WhereQueryBase> = {
2131
+ [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<{
2132
+ columns: (keyof T['selectable'])[];
2133
+ values: unknown[][] | Query | Expression;
2134
+ }> : K extends keyof T['selectable'] ? T['selectable'][K]['column']['queryType'] | null | ColumnOperators<T['selectable'], K> | Expression | Query : never;
2135
+ } | QueryBase | Expression | ((q: WhereQueryBuilder<T>) => QueryBase | ColumnExpression<BooleanNullable>);
2136
+ /**
2137
+ * Callback argument of `where`.
2138
+ * It has `where` methods (`where`, `whereNot`, `whereExists`, etc.),
2139
+ * and it has relations that you can aggregate and use a boolean comparison with, such as:
2140
+ * ```ts
2141
+ * db.table.where((q) => q.relation.count().equals(10))
2142
+ * ```
2143
+ */
2144
+ type WhereQueryBuilder<T extends WhereQueryBase> = Pick<T, keyof WhereQueryBase> & RelationSubQueries<T>;
2145
+ type WhereArgs<T extends WhereQueryBase> = WhereArg<T>[] | TemplateLiteralArgs;
2146
+ type WhereInColumn<T extends QueryBase> = keyof T['selectable'] | [keyof T['selectable'], ...(keyof T['selectable'])[]];
2147
+ type WhereInValues<T extends QueryBase, Column extends WhereInColumn<T>> = Column extends keyof T['selectable'] ? T['selectable'][Column]['column']['queryType'][] | Query | Expression : ({
2148
+ [I in keyof Column]: Column[I] extends keyof T['selectable'] ? T['selectable'][Column[I]]['column']['queryType'] : never;
2149
+ } & {
2150
+ length: Column extends {
2151
+ length: number;
2152
+ } ? Column['length'] : never;
2153
+ })[] | Query | Expression;
2154
+ type WhereInArg<T extends Pick<Query, 'selectable'>> = {
2155
+ [K in keyof T['selectable']]?: T['selectable'][K]['column']['queryType'][] | Query | Expression;
2441
2156
  };
2442
- type CreateMethodsNames = 'create' | '_create' | 'createMany' | '_createMany' | 'createRaw' | '_createRaw' | 'createFrom' | '_createFrom';
2443
- declare class Create {
2157
+ type WhereResult<T extends QueryBase> = T & {
2158
+ meta: {
2159
+ hasWhere: true;
2160
+ };
2161
+ };
2162
+ /**
2163
+ * Adds `where` arguments to query data: SQL template string is added as `RawSQL` object, other arguments are added as is.
2164
+ *
2165
+ * @param q - query object to add the data to
2166
+ * @param args - `where` arguments, may be a template literal
2167
+ */
2168
+ declare const addWhere: <T extends WhereQueryBase>(q: T, args: WhereArgs<T>) => WhereResult<T>;
2169
+ /**
2170
+ * Adds `where` arguments to query data with a `NOT` keyword: SQL template string is added as `RawSQL` object, other arguments are added as is.
2171
+ *
2172
+ * @param q - query object to add the data to
2173
+ * @param args - `where` arguments, may be a template literal
2174
+ */
2175
+ declare const addWhereNot: <T extends WhereQueryBase>(q: T, args: WhereArgs<T>) => WhereResult<T>;
2176
+ /**
2177
+ * Adds `where` arguments to query data. Arguments will be separated from each other with `OR`.
2178
+ *
2179
+ * @param q - query object to add the data to
2180
+ * @param args - `where` arguments, may be a template literal
2181
+ */
2182
+ declare const addOr: <T extends WhereQueryBase>(q: T, args: WhereArg<T>[]) => WhereResult<T>;
2183
+ /**
2184
+ * Adds `where` arguments to query data with a `NOT` keyword. Arguments will be separated from each other with `OR`.
2185
+ *
2186
+ * @param q - query object to add the data to
2187
+ * @param args - `where` arguments, may be a template literal
2188
+ */
2189
+ declare const addOrNot: <T extends WhereQueryBase>(q: T, args: WhereArg<T>[]) => WhereResult<T>;
2190
+ /**
2191
+ * Process arguments of `whereIn` to add them to query data properly.
2192
+ *
2193
+ * @param q - query object to add the data to.
2194
+ * @param and - `true` to join arguments with `AND`, `false` to join them with `OR.
2195
+ * @param arg - `whereIn` argument: can be a single column name, tuple of column names, or object with column names and values.
2196
+ * @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`.
2197
+ * @param not - adds the `NOT` keyword.
2198
+ */
2199
+ declare const addWhereIn: <T extends QueryBase>(q: T, and: boolean, arg: unknown, values: unknown[] | unknown[][] | Query | Expression | undefined, not?: boolean) => WhereResult<T>;
2200
+ declare abstract class Where {
2444
2201
  /**
2445
- * `create` will create one record.
2446
- *
2447
- * Each column may accept a specific value, a raw SQL, or a query that returns a single value.
2202
+ * Constructing `WHERE` conditions:
2448
2203
  *
2449
2204
  * ```ts
2450
- * const oneRecord = await db.table.create({
2205
+ * db.table.where({
2206
+ * // column of the current table
2451
2207
  * name: 'John',
2452
- * password: '1234',
2453
- * });
2454
2208
  *
2455
- * await db.table.create({
2456
- * // raw SQL
2457
- * column1: db.table.sql`'John' | 'Doe'`,
2209
+ * // table name may be specified, it can be the name of a joined table
2210
+ * 'table.lastName': 'Johnsonuk',
2458
2211
  *
2459
- * // query that returns a single value
2460
- * // returning multiple values will result in Postgres error
2461
- * column2: db.otherTable.get('someColumn'),
2212
+ * // object with operators, see the "column operators" section to see a full list of them:
2213
+ * age: {
2214
+ * gt: 30,
2215
+ * lt: 70,
2216
+ * },
2217
+ *
2218
+ * // where column equals to raw SQL
2219
+ * column: db.table.sql`raw expression`,
2462
2220
  * });
2463
2221
  * ```
2464
2222
  *
2465
- * @param data - data for the record, may have values, raw SQL, queries, relation operations
2466
- */
2467
- create<T extends Query>(this: T, data: CreateData<T>): CreateResult<T>;
2468
- _create<T extends Query>(this: T, data: CreateData<T>): CreateResult<T>;
2469
- /**
2470
- * `createMany` will create a batch of records.
2471
- *
2472
- * Each column may be set with a specific value, a raw SQL, or a query, the same as in [create](#create).
2473
- *
2474
- * In case one of the objects has fewer fields, the `DEFAULT` SQL keyword will be placed in its place in the `VALUES` statement.
2223
+ * `undefined` values are ignored, so you can supply a partial object with conditions:
2475
2224
  *
2476
2225
  * ```ts
2477
- * const manyRecords = await db.table.createMany([
2478
- * { key: 'value', otherKey: 'other value' },
2479
- * { key: 'value' }, // default will be used for `otherKey`
2480
- * ]);
2481
- * ```
2482
- *
2483
- * @param data - data for the record, may have values, raw SQL, queries, relation operations
2484
- */
2485
- createMany<T extends Query>(this: T, data: CreateData<T>[]): CreateManyResult<T>;
2486
- _createMany<T extends Query>(this: T, data: CreateData<T>[]): CreateManyResult<T>;
2487
- /**
2488
- * `createRaw` is for creating one record with a raw expression.
2489
- *
2490
- * Provided SQL will be wrapped into parens for a single `VALUES` record.
2226
+ * type Params = {
2227
+ * // allow providing exact age, or lower or greate than
2228
+ * age?: number | { lt?: number; gt?: number };
2229
+ * };
2491
2230
  *
2492
- * If the table has a column with runtime defaults (defined with callbacks), the value will be appended to your SQL.
2231
+ * const loadRecords = async (params: Params) => {
2232
+ * // this will load all records if params is an empty object
2233
+ * const records = await db.table.where(params);
2234
+ * };
2235
+ * ```
2493
2236
  *
2494
- * `columns` are type-checked to contain all required columns.
2237
+ * It supports a sub-query that is selecting a single value to compare it with a column:
2495
2238
  *
2496
2239
  * ```ts
2497
- * const oneRecord = await db.table.createRaw({
2498
- * columns: ['name', 'amount'],
2499
- * values: db.table.sql`'name', random()`,
2240
+ * db.table.where({
2241
+ * // compare `someColumn` in one table with the `column` value returned from another query.
2242
+ * someColumn: db.otherTable.where(...conditions).get('column'),
2500
2243
  * });
2501
2244
  * ```
2502
2245
  *
2503
- * @param args - object with columns list and raw SQL for values
2504
- */
2505
- createRaw<T extends Query, Arg extends CreateRawData<T>>(this: T, ...args: CreateRawArgs<T, Arg>): CreateResult<T>;
2506
- _createRaw<T extends Query, Arg extends CreateRawData<T>>(this: T, ...args: CreateRawArgs<T, Arg>): CreateResult<T>;
2507
- /**
2508
- * `createRaw` is for creating many record with raw expressions.
2509
- *
2510
- * Takes array of SQL expressions, each of them will be wrapped into parens for `VALUES` records.
2511
- *
2512
- * If the table has a column with runtime defaults (defined with callbacks), function will be called for each SQL and the value will be appended.
2513
- *
2514
- * `columns` are type-checked to contain all required columns.
2246
+ * `where` can accept other queries and merge their conditions:
2515
2247
  *
2516
2248
  * ```ts
2517
- * const manyRecords = await db.table.createManyRaw({
2518
- * columns: ['name', 'amount'],
2519
- * values: [db.table.sql`'one', 2`, db.table.sql`'three', 4`],
2520
- * });
2249
+ * const otherQuery = db.table.where({ name: 'John' });
2250
+ *
2251
+ * db.table.where({ id: 1 }, otherQuery);
2252
+ * // this will produce WHERE "table"."id" = 1 AND "table"."name' = 'John'
2521
2253
  * ```
2522
2254
  *
2523
- * @param args - object with columns list and array of raw SQL for values
2524
- */
2525
- createManyRaw<T extends Query, Arg extends CreateManyRawData<T>>(this: T, ...args: CreateRawArgs<T, Arg>): CreateManyResult<T>;
2526
- _createManyRaw<T extends Query, Arg extends CreateManyRawData<T>>(this: T, ...args: CreateRawArgs<T, Arg>): CreateManyResult<T>;
2527
- /**
2528
- * This method is for creating a single record, for batch creating see `createManyFrom`.
2255
+ * `where` supports raw SQL:
2529
2256
  *
2530
- * `createFrom` is to perform the `INSERT ... SELECT ...` SQL statement, it does select and insert in a single query.
2257
+ * ```ts
2258
+ * db.table.where`a = b`;
2531
2259
  *
2532
- * The first argument is a query for a **single** record, it should have `find`, `take`, or similar.
2260
+ * // or
2261
+ * db.table.where(db.table.sql`a = b`);
2533
2262
  *
2534
- * The second optional argument is a data which will be merged with columns returned from the select query.
2263
+ * // or
2264
+ * import { raw } from 'orchid-orm';
2535
2265
  *
2536
- * The data for the second argument is the same as in [create](#create) and [createMany](#createMany).
2266
+ * db.table.where(raw`a = b`);
2267
+ * ```
2537
2268
  *
2538
- * Columns with runtime defaults (defined with a callback) are supported here.
2539
- * The value for such a column will be injected unless selected from a related table or provided in a data object.
2269
+ * `where` can accept a callback with a specific query builder containing all "where" methods such as `where`, `or`, `whereNot`, `whereIn`, `whereExists`:
2540
2270
  *
2541
2271
  * ```ts
2542
- * const oneRecord = await db.table.createFrom(
2543
- * // In the select, key is a related table column, value is a column to insert as
2544
- * RelatedTable.select({ relatedId: 'id' }).findBy({ key: 'value' }),
2545
- * // optional argument:
2546
- * {
2547
- * key: 'value',
2548
- * },
2272
+ * db.table.where((q) =>
2273
+ * q
2274
+ * .where({ name: 'Name' })
2275
+ * .or({ id: 1 }, { id: 2 })
2276
+ * .whereIn('letter', ['a', 'b', 'c'])
2277
+ * .whereExists(Message, 'authorId', 'id'),
2549
2278
  * );
2550
2279
  * ```
2551
2280
  *
2552
- * The query above will produce such SQL:
2553
- *
2554
- * ```sql
2555
- * INSERT INTO "table"("relatedId", "key")
2556
- * SELECT "relatedTable"."id" AS "relatedId", 'value'
2557
- * FROM "relatedTable"
2558
- * WHERE "relatedTable"."key" = 'value'
2559
- * LIMIT 1
2560
- * RETURNING *
2561
- * ```
2562
- *
2563
- * @param query - query to create new records from
2564
- * @param data - additionally you can set some columns
2565
- */
2566
- createFrom<T extends Query, Q extends Query & {
2567
- returnType: 'one' | 'oneOrThrow';
2568
- }>(this: T, query: Q, data?: Omit<CreateData<T>, keyof Q['result']>): CreateResult<T>;
2569
- _createFrom<T extends Query, Q extends Query & {
2570
- returnType: 'one' | 'oneOrThrow';
2571
- }>(this: T, query: Q, data?: Omit<CreateData<T>, keyof Q['result']>): CreateResult<T>;
2572
- /**
2573
- * Similar to `createFrom`, but intended to create many records.
2574
- *
2575
- * Unlike `createFrom`, it doesn't accept second argument with data, and runtime defaults cannot work with it.
2281
+ * `where` can accept multiple arguments, conditions are joined with `AND`:
2576
2282
  *
2577
2283
  * ```ts
2578
- * const manyRecords = await db.table.createManyFrom(
2579
- * RelatedTable.select({ relatedId: 'id' }).where({ key: 'value' }),
2284
+ * db.table.where(
2285
+ * { id: 1 },
2286
+ * db.table.where({ name: 'John' }),
2287
+ * db.table.sql`a = b`,
2580
2288
  * );
2581
2289
  * ```
2582
2290
  *
2583
- * @param query - query to create new records from
2584
- */
2585
- createManyFrom<T extends Query, Q extends Query>(this: T, query: Q): CreateManyResult<T>;
2586
- _createManyFrom<T extends Query, Q extends Query>(this: T, query: Q): CreateManyResult<T>;
2587
- /**
2588
- * `defaults` allows setting values that will be used later in `create`.
2291
+ * ## where sub query
2589
2292
  *
2590
- * Columns provided in `defaults` are marked as optional in the following `create`.
2293
+ * `where` handles a special callback where you can query a relation to get some value and filter by that value.
2591
2294
  *
2592
- * Default data is the same as in [create](#create) and [createMany](#createMany),
2593
- * so you can provide a raw SQL, or a query with a query.
2295
+ * It is useful for a faceted search. For instance, posts have tags, and we want to find all posts that have all the given tags.
2594
2296
  *
2595
2297
  * ```ts
2596
- * // Will use firstName from defaults and lastName from create argument:
2597
- * db.table
2598
- * .defaults({
2599
- * firstName: 'first name',
2600
- * lastName: 'last name',
2601
- * })
2602
- * .create({
2603
- * lastName: 'override the last name',
2604
- * });
2605
- * ```
2298
+ * const givenTags = ['typescript', 'node.js'];
2606
2299
  *
2607
- * @param data - default values for `create` and `createMany` which will follow `defaults`
2608
- */
2609
- defaults<T extends Query, Data extends Partial<CreateData<T>>>(this: T, data: Data): T & {
2610
- meta: {
2611
- defaults: Record<keyof Data, true>;
2612
- };
2613
- };
2614
- _defaults<T extends Query, Data extends Partial<CreateData<T>>>(this: T, data: Data): T & {
2615
- meta: {
2616
- defaults: Record<keyof Data, true>;
2617
- };
2618
- };
2619
- /**
2620
- * A modifier for creating queries that specify alternative behavior in the case of a conflict.
2621
- * A conflict occurs when a table has a `PRIMARY KEY` or a `UNIQUE` index on a column
2622
- * (or a composite index on a set of columns) and a row being created has the same value as a row
2623
- * that already exists in the table in this column(s).
2624
- * The default behavior in case of conflict is to raise an error and abort the query.
2625
- * Using this method you can change this behavior to either silently ignore the error by using .onConflict().ignore()
2626
- * or to update the existing row with new data (perform an "UPSERT") by using .onConflict().merge().
2300
+ * const posts = await db.post.where(
2301
+ * (post) =>
2302
+ * post.tags // query tags of the post
2303
+ * .whereIn('tagName', givenTags) // where name of the tag is inside array
2304
+ * .count() // count how many such tags were found
2305
+ * .equals(wantedTags.length), // the count must be exactly the length of array
2306
+ * // if the post has ony `typescript` tag but not the `node.js` it will be omitted
2307
+ * );
2308
+ * ```
2627
2309
  *
2628
- * ```ts
2629
- * // leave without argument to ignore or merge on any conflict
2630
- * Target.create(data).onConflict().ignore();
2310
+ * This will produce an efficient SQL query:
2631
2311
  *
2632
- * // single column:
2633
- * db.table.create(data).onConfict('email');
2312
+ * ```sql
2313
+ * SELECT * FROM "post"
2314
+ * WHERE (
2315
+ * SELECT count(*) = 3
2316
+ * FROM "tag" AS "tags"
2317
+ * WHERE "tag"."tagName" IN ('typescript', 'node.js')
2318
+ * -- join tags to the post via "postTag" table
2319
+ * AND EXISTS (
2320
+ * SELECT 1 FROM "postTag"
2321
+ * WHERE "postTag"."postId" = "post"."id"
2322
+ * AND "postTag"."tagId" = "tag"."id"
2323
+ * )
2324
+ * )
2325
+ * ```
2634
2326
  *
2635
- * // array of columns:
2636
- * db.table.create(data).onConfict(['email', 'name']);
2327
+ * In the example above we use `count()`, you can also use any other aggregate method instead, such as `min`, `max`, `avg`.
2637
2328
  *
2638
- * // raw expression:
2639
- * db.table.create(data).onConfict(db.table.sql`(email) where condition`);
2640
- * ```
2329
+ * The `count()` is chained with `equals` to check for a strict equality, any other operation is also allowed, such as `not`, `lt`, `gt`.
2641
2330
  *
2642
- * ::: info
2643
- * The column(s) specified by this method must either be the table's PRIMARY KEY or have a UNIQUE index on them, or the query will fail to execute.
2644
- * When specifying multiple columns, they must be a composite PRIMARY KEY or have a composite UNIQUE index.
2331
+ * ## where special keys
2645
2332
  *
2646
- * You can use the db.table.sql function in onConflict.
2647
- * It can be useful to specify a condition when you have a partial index:
2333
+ * 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.
2334
+ *
2335
+ * For example:
2648
2336
  *
2649
2337
  * ```ts
2650
- * db.table
2651
- * .create({
2652
- * email: 'ignore@example.com',
2653
- * name: 'John Doe',
2654
- * active: true,
2655
- * })
2656
- * // ignore only on email conflict and active is true.
2657
- * .onConflict(db.table.sql`(email) where active`)
2658
- * .ignore();
2338
+ * db.table.where({
2339
+ * NOT: { key: 'value' },
2340
+ * OR: [{ name: 'a' }, { name: 'b' }],
2341
+ * IN: {
2342
+ * columns: ['id', 'name'],
2343
+ * values: [
2344
+ * [1, 'a'],
2345
+ * [2, 'b'],
2346
+ * ],
2347
+ * },
2348
+ * });
2659
2349
  * ```
2660
2350
  *
2661
- * :::
2351
+ * Using methods `whereNot`, `or`, `whereIn` instead of this is a shorter and cleaner way, but in some cases, such object keys way may be more convenient.
2662
2352
  *
2663
- * See the documentation on the .ignore() and .merge() methods for more details.
2353
+ * ```ts
2354
+ * db.table.where({
2355
+ * // see .whereNot
2356
+ * NOT: { id: 1 },
2357
+ * // can be an array:
2358
+ * NOT: [{ id: 1 }, { id: 2 }],
2664
2359
  *
2665
- * @param arg - optionally provide an array of columns
2666
- */
2667
- onConflict<T extends Query, Arg extends OnConflictArg<T>>(this: T, arg?: Arg): OnConflictQueryBuilder<T, Arg>;
2668
- _onConflict<T extends Query, Arg extends OnConflictArg<T> | undefined = undefined>(this: T, arg?: Arg): OnConflictQueryBuilder<T, Arg>;
2669
- }
2670
- declare class OnConflictQueryBuilder<T extends Query, Arg extends OnConflictArg<T> | undefined> {
2671
- private query;
2672
- private onConflict;
2673
- constructor(query: T, onConflict: Arg);
2674
- /**
2675
- * Available only after `onConflict`.
2360
+ * // see .or
2361
+ * OR: [{ name: 'a' }, { name: 'b' }],
2362
+ * // can be an array:
2363
+ * // this will give id = 1 AND id = 2 OR id = 3 AND id = 4
2364
+ * OR: [
2365
+ * [{ id: 1 }, { id: 2 }],
2366
+ * [{ id: 3 }, { id: 4 }],
2367
+ * ],
2676
2368
  *
2677
- * Modifies a create query, and causes it to be silently dropped without an error if a conflict occurs.
2369
+ * // see .in, the key syntax requires an object with columns and values
2370
+ * IN: {
2371
+ * columns: ['id', 'name'],
2372
+ * values: [
2373
+ * [1, 'a'],
2374
+ * [2, 'b'],
2375
+ * ],
2376
+ * },
2377
+ * // can be an array:
2378
+ * IN: [
2379
+ * {
2380
+ * columns: ['id', 'name'],
2381
+ * values: [
2382
+ * [1, 'a'],
2383
+ * [2, 'b'],
2384
+ * ],
2385
+ * },
2386
+ * { columns: ['someColumn'], values: [['foo', 'bar']] },
2387
+ * ],
2388
+ * });
2389
+ * ```
2678
2390
  *
2679
- * Adds the `ON CONFLICT (columns) DO NOTHING` clause to the insert statement.
2391
+ * ## column operators
2680
2392
  *
2681
- * It produces `ON CONFLICT DO NOTHING` when no `onConflict` argument provided.
2393
+ * `where` argument can take an object where the key is the name of the operator and the value is its argument.
2394
+ *
2395
+ * Different types of columns support different sets of operators.
2396
+ *
2397
+ * All column operators can take a value of the same type as the column, a sub-query, or a raw SQL expression:
2682
2398
  *
2683
2399
  * ```ts
2684
- * db.table
2685
- * .create({
2686
- * email: 'ignore@example.com',
2687
- * name: 'John Doe',
2688
- * })
2689
- * .onConflict('email')
2690
- * .ignore();
2691
- * ```
2692
- */
2693
- ignore(): T;
2694
- /**
2695
- * Available only after `onConflict`.
2400
+ * import { sql } from 'orchid-orm';
2696
2401
  *
2697
- * Modifies a create query, to turn it into an 'upsert' operation.
2402
+ * db.table.where({
2403
+ * numericColumn: {
2404
+ * // lower than 5
2405
+ * lt: 5,
2698
2406
  *
2699
- * Adds an `ON CONFLICT (columns) DO UPDATE` clause to the insert statement.
2407
+ * // lower than the value returned by sub-query
2408
+ * lt: OtherTable.select('someNumber').take(),
2700
2409
  *
2701
- * When no `onConflict` argument provided,
2702
- * it will automatically collect all table columns that have unique index and use them as a conflict target.
2410
+ * // raw SQL expression produces WHERE "numericColumn" < "otherColumn" + 10
2411
+ * lt: sql`"otherColumn" + 10`,
2412
+ * },
2413
+ * });
2414
+ * ```
2415
+ *
2416
+ * ### Any type of column operators
2417
+ *
2418
+ * `equals` is a simple `=` operator, it may be useful for comparing column value with JSON object:
2703
2419
  *
2704
2420
  * ```ts
2705
- * db.table
2706
- * .create({
2707
- * email: 'ignore@example.com',
2708
- * name: 'John Doe',
2709
- * })
2710
- * .onConflict('email')
2711
- * .merge();
2421
+ * db.table.where({
2422
+ * // when searching for an exact same JSON value, this won't work:
2423
+ * jsonColumn: someObject,
2424
+ *
2425
+ * // use `{ equals: ... }` instead:
2426
+ * jsonColumn: { equals: someObject },
2427
+ * });
2712
2428
  * ```
2713
2429
  *
2714
- * This also works with batch creates:
2430
+ * `not` is `!=` (aka `<>`) not equal operator:
2715
2431
  *
2716
2432
  * ```ts
2717
- * db.table
2718
- * .createMany([
2719
- * { email: 'john@example.com', name: 'John Doe' },
2720
- * { email: 'jane@example.com', name: 'Jane Doe' },
2721
- * { email: 'alex@example.com', name: 'Alex Doe' },
2722
- * ])
2723
- * .onConflict('email')
2724
- * .merge();
2433
+ * db.table.where({
2434
+ * anyColumn: { not: value },
2435
+ * });
2725
2436
  * ```
2726
2437
  *
2727
- * It is also possible to specify a subset of the columns to merge when a conflict occurs.
2728
- * For example, you may want to set a `createdAt` column when creating but would prefer not to update it if the row already exists:
2438
+ * `in` is for the `IN` operator to check if the column value is included in a list of values.
2439
+ *
2440
+ * 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.
2729
2441
  *
2730
2442
  * ```ts
2731
- * const timestamp = Date.now();
2443
+ * db.table.where({
2444
+ * column: {
2445
+ * in: ['a', 'b', 'c'],
2732
2446
  *
2733
- * db.table
2734
- * .create({
2735
- * email: 'ignore@example.com',
2736
- * name: 'John Doe',
2737
- * createdAt: timestamp,
2738
- * updatedAt: timestamp,
2739
- * })
2740
- * .onConflict('email')
2741
- * // string argument for a single column:
2742
- * .merge('email')
2743
- * // array of strings for multiple columns:
2744
- * .merge(['email', 'name', 'updatedAt']);
2447
+ * // WHERE "column" IN (SELECT "column" FROM "otherTable")
2448
+ * in: OtherTable.select('column'),
2449
+ *
2450
+ * in: db.table.sql`('a', 'b')`,
2451
+ * },
2452
+ * });
2745
2453
  * ```
2746
2454
  *
2747
- * It is also possible to specify data to update separately from the data to create.
2748
- * This is useful if you want to make an update with different data than in creating.
2749
- * For example, you may want to change a value if the row already exists:
2455
+ * `notIn` is for the `NOT IN` operator, and takes the same arguments as `in`
2750
2456
  *
2751
- * ```ts
2752
- * const timestamp = Date.now();
2457
+ * ### Numeric, Date, and Time column operators
2753
2458
  *
2754
- * db.table
2755
- * .create({
2756
- * email: 'ignore@example.com',
2757
- * name: 'John Doe',
2758
- * createdAt: timestamp,
2759
- * updatedAt: timestamp,
2760
- * })
2761
- * .onConflict('email')
2762
- * .merge({
2763
- * name: 'John Doe The Second',
2764
- * });
2765
- * ```
2459
+ * To compare numbers, dates, and times.
2766
2460
  *
2767
- * It is also possible to add a WHERE clause to conditionally update only the matching rows:
2461
+ * `lt` is for `<` (lower than)
2462
+ *
2463
+ * `lte` is for `<=` (lower than or equal)
2464
+ *
2465
+ * `gt` is for `>` (greater than)
2466
+ *
2467
+ * `gte` is for `>=` (greater than or equal)
2768
2468
  *
2769
2469
  * ```ts
2770
- * const timestamp = Date.now();
2470
+ * db.table.where({
2471
+ * numericColumn: {
2472
+ * gt: 5,
2473
+ * lt: 10,
2474
+ * },
2771
2475
  *
2772
- * db.table
2773
- * .create({
2774
- * email: 'ignore@example.com',
2775
- * name: 'John Doe',
2776
- * createdAt: timestamp,
2777
- * updatedAt: timestamp,
2778
- * })
2779
- * .onConflict('email')
2780
- * .merge({
2781
- * name: 'John Doe',
2782
- * updatedAt: timestamp,
2783
- * })
2784
- * .where({ updatedAt: { lt: timestamp } });
2476
+ * date: {
2477
+ * lte: new Date(),
2478
+ * },
2479
+ *
2480
+ * time: {
2481
+ * gte: new Date(),
2482
+ * },
2483
+ * });
2785
2484
  * ```
2786
2485
  *
2787
- * `merge` also accepts raw expression:
2486
+ * `between` also works with numeric, dates, and time columns, it takes an array of two elements.
2788
2487
  *
2789
- * ```ts
2790
- * db.table
2791
- * .create(data)
2792
- * .onConflict()
2793
- * .merge(db.table.sql`raw SQL expression`);
2794
- * ```
2488
+ * Both elements can be of the same type as a column, a sub-query, or a raw SQL expression.
2795
2489
  *
2796
- * @param update - column, or array of columns, or object for new column values, or raw SQL
2797
- */
2798
- merge(update?: keyof T['shape'] | (keyof T['shape'])[] | Partial<T['inputType']> | Expression): T;
2799
- }
2800
-
2801
- type DeleteMethodsNames = 'del' | '_del' | 'delete' | '_delete';
2802
- type DeleteArgs<T extends Query> = T['meta']['hasWhere'] extends true ? [] : [never];
2803
- type DeleteResult<T extends Query> = T['meta']['hasSelect'] extends true ? SetQueryKind<T, 'delete'> : SetQueryReturnsRowCount<SetQueryKind<T, 'delete'>>;
2804
- declare class Delete {
2805
- /**
2806
- * Alias for `delete` method
2807
- */
2808
- del<T extends Query>(this: T, ..._args: DeleteArgs<T>): DeleteResult<T>;
2809
- _del<T extends Query>(this: T, ..._args: DeleteArgs<T>): DeleteResult<T>;
2810
- /**
2811
- * It is aliased to `del` because `delete` is a reserved word in JavaScript.
2490
+ * ```ts
2491
+ * db.table.where({
2492
+ * column: {
2493
+ * // simple values
2494
+ * between: [1, 10],
2812
2495
  *
2813
- * This method deletes one or more rows, based on other conditions specified in the query.
2496
+ * // sub-query and raw SQL expression
2497
+ * between: [OtherTable.select('column').take(), db.table.sql`2 + 2`],
2498
+ * },
2499
+ * });
2500
+ * ```
2814
2501
  *
2815
- * By default, `delete` will return a count of deleted records.
2502
+ * ### Text column operators
2816
2503
  *
2817
- * Place `select`, `selectAll`, or `get` before `delete` to specify returning columns.
2504
+ * For `text`, `char`, `varchar`, and `json` columns.
2818
2505
  *
2819
- * Need to provide `where`, `findBy`, or `find` conditions before calling `delete`.
2820
- * To prevent accidental deletion of all records, deleting without where will result in TypeScript and a runtime error.
2506
+ * `json` is stored as text, so it has text operators. Use the `jsonb` type for JSON operators.
2821
2507
  *
2822
- * Use `all()` to delete ALL records without conditions:
2508
+ * Takes a string, or sub-query returning string, or raw SQL expression as well as other operators.
2823
2509
  *
2824
2510
  * ```ts
2825
- * await db.table.all().delete();
2511
+ * db.table.where({
2512
+ * textColumn: {
2513
+ * // WHERE "textColumn" LIKE '%string%'
2514
+ * contains: 'string',
2515
+ * // WHERE "textColumn" ILIKE '%string%'
2516
+ * containsInsensitive: 'string',
2517
+ * // WHERE "textColumn" LIKE 'string%'
2518
+ * startsWith: 'string',
2519
+ * // WHERE "textColumn" ILIKE 'string%'
2520
+ * startsWithInsensitive: 'string',
2521
+ * // WHERE "textColumn" LIKE '%string'
2522
+ * endsWith: 'string',
2523
+ * // WHERE "textColumn" ILIKE '%string'
2524
+ * endsWithInsensitive: 'string',
2525
+ * },
2526
+ * });
2826
2527
  * ```
2827
2528
  *
2828
- * ```ts
2829
- * // deletedCount is the number of deleted records
2830
- * const deletedCount = await db.table.where(...conditions).delete();
2831
- *
2832
- * // returns a single value, throws if not found
2833
- * const id: number | undefined = await db.table
2834
- * .findBy(...conditions)
2835
- * .get('id')
2836
- * .delete();
2529
+ * ### JSONB column operators
2837
2530
  *
2838
- * // returns an array of records with specified columns
2839
- * const deletedRecord = await db.table
2840
- * .select('id', 'name', 'age')
2841
- * .where(...conditions)
2842
- * .delete();
2531
+ * For the `jsonb` column, note that the `json` type has text operators instead.
2843
2532
  *
2844
- * // returns an array of fully deleted records
2845
- * const deletedUsersFull = await db.table
2846
- * .selectAll()
2847
- * .where(...conditions)
2848
- * .delete();
2849
- * ```
2533
+ * `jsonPath` operator: compare a column value under a given JSON path with the provided value.
2850
2534
  *
2851
- * `delete` supports joining, under the hood the join is transformed to `USING` and `WHERE` statements:
2535
+ * Value can be of any type to compare with JSON value, or it can be a sub-query or a raw SQL expression.
2852
2536
  *
2853
2537
  * ```ts
2854
- * // delete all users who have corresponding profile records:
2855
- * db.table.join(Profile, 'profile.userId', 'user.id').all().delete();
2538
+ * db.table.where({
2539
+ * jsonbColumn: {
2540
+ * jsonPath: [
2541
+ * '$.name', // first element is JSON path
2542
+ * '=', // second argument is comparison operator
2543
+ * 'value', // third argument is a value to compare with
2544
+ * ],
2545
+ * },
2546
+ * });
2856
2547
  * ```
2857
- */
2858
- delete<T extends Query>(this: T, ..._args: DeleteArgs<T>): DeleteResult<T>;
2859
- _delete<T extends Query>(this: T, ..._args: DeleteArgs<T>): DeleteResult<T>;
2860
- }
2861
-
2862
- type ForQueryBuilder<Q extends Query> = Q & {
2863
- noWait<T extends ForQueryBuilder<Q>>(this: T): T;
2864
- _noWait<T extends ForQueryBuilder<Q>>(this: T): T;
2865
- skipLocked<T extends ForQueryBuilder<Q>>(this: T): T;
2866
- _skipLocked<T extends ForQueryBuilder<Q>>(this: T): T;
2867
- };
2868
- declare class For {
2869
- forUpdate<T extends Query>(this: T, tableNames?: string[] | Expression): ForQueryBuilder<T>;
2870
- _forUpdate<T extends Query>(this: T, tableNames?: string[] | Expression): ForQueryBuilder<T>;
2871
- forNoKeyUpdate<T extends Query>(this: T, tableNames?: string[] | Expression): ForQueryBuilder<T>;
2872
- _forNoKeyUpdate<T extends Query>(this: T, tableNames?: string[] | Expression): ForQueryBuilder<T>;
2873
- forShare<T extends Query>(this: T, tableNames?: string[] | Expression): ForQueryBuilder<T>;
2874
- _forShare<T extends Query>(this: T, tableNames?: string[] | Expression): ForQueryBuilder<T>;
2875
- forKeyShare<T extends Query>(this: T, tableNames?: string[] | Expression): ForQueryBuilder<T>;
2876
- _forKeyShare<T extends Query>(this: T, tableNames?: string[] | Expression): ForQueryBuilder<T>;
2877
- }
2878
-
2879
- type FromArgs<T extends Query> = [
2880
- first: Query | Expression | Exclude<keyof T['withData'], symbol | number>,
2881
- second?: {
2882
- only?: boolean;
2883
- }
2884
- ] | TemplateLiteralArgs;
2885
- type FromResult<T extends Query, Args extends FromArgs<T>> = Args extends TemplateStringsArray ? T : Args[0] extends string ? T['withData'] extends Record<string, WithDataItem> ? Args[0] extends keyof T['withData'] ? Omit<T, 'meta' | 'selectable'> & {
2886
- meta: Omit<T['meta'], 'as'> & {
2887
- as?: string;
2888
- };
2889
- selectable: SelectableFromShape<T['withData'][Args[0]]['shape'], Args[0]>;
2890
- } : SetQueryTableAlias<T, Args[0]> : SetQueryTableAlias<T, Args[0]> : Args[0] extends Query ? FromQueryResult<T, Args[0]> : T;
2891
- type FromQueryResult<T extends Query, Q extends Query, Selectable extends SelectableBase = {
2892
- [K in keyof Q['result']]: K extends string ? {
2893
- as: K;
2894
- column: Q['result'][K];
2895
- } : never;
2896
- }, Data = GetQueryResult<T['returnType'], Q['result']>> = {
2897
- [K in keyof T]: K extends 'meta' ? Omit<T['meta'], 'hasSelect' | 'as'> & {
2898
- as: AliasOrTable<Q>;
2899
- } : K extends 'selectable' ? Selectable : K extends 'result' | 'shape' ? Q['result'] : K extends 'then' ? QueryThen<Data> : K extends 'catch' ? QueryCatch<Data> : T[K];
2900
- };
2901
- declare class From {
2902
- /**
2903
- * Set the `FROM` value, by default the table name is used.
2904
2548
  *
2905
- * ```ts
2906
- * // accepts sub-query:
2907
- * db.table.from(Otherdb.table.select('foo', 'bar'));
2549
+ * `jsonSupersetOf`: check if the column value is a superset of provided value.
2908
2550
  *
2909
- * // accepts raw sql by template literal:
2910
- * const value = 123;
2911
- * db.table.from`value = ${value}`;
2551
+ * For instance, it is true if the column has JSON `{ "a": 1, "b": 2 }` and provided value is `{ "a": 1 }`.
2912
2552
  *
2913
- * // accepts raw sql:
2914
- * db.table.from(db.table.sql`value = ${value}`);
2553
+ * Takes the value of any type, or sub query which returns a single value, or a raw SQL expression.
2915
2554
  *
2916
- * // accepts alias of `WITH` expression:
2917
- * q.with('foo', Otherdb.table.select('id', 'name')).from('foo');
2555
+ * ```ts
2556
+ * db.table.where({
2557
+ * jsonbColumn: {
2558
+ * jsonSupersetOf: { a: 1 },
2559
+ * },
2560
+ * });
2918
2561
  * ```
2919
2562
  *
2920
- * Optionally takes a second argument of type `{ only?: boolean }`, (see `FROM ONLY` in Postgres docs, this is related to table inheritance).
2563
+ * `jsonSubsetOf`: check if the column value is a subset of provided value.
2564
+ *
2565
+ * For instance, it is true if the column has JSON `{ "a": 1 }` and provided value is `{ "a": 1, "b": 2 }`.
2566
+ *
2567
+ * Takes the value of any type, or sub query which returns a single value, or a raw SQL expression.
2921
2568
  *
2922
2569
  * ```ts
2923
- * db.table.from(Otherdb.table.select('foo', 'bar'), {
2924
- * only: true,
2570
+ * db.table.where({
2571
+ * jsonbColumn: {
2572
+ * jsonSupersetOf: { a: 1 },
2573
+ * },
2925
2574
  * });
2926
2575
  * ```
2927
2576
  *
2928
- * @param args - query, raw SQL, name of CTE table, or a template string
2577
+ * @param args - {@link WhereArgs}
2929
2578
  */
2930
- from<T extends Query, Args extends FromArgs<T>>(this: T, ...args: Args): FromResult<T, Args>;
2931
- _from<T extends Query, Args extends FromArgs<T>>(this: T, ...args: Args): FromResult<T, Args>;
2932
- }
2933
-
2934
- type GetArg<T extends QueryBase> = GetStringArg<T> | Expression;
2935
- type GetStringArg<T extends QueryBase> = StringKey<keyof T['selectable']>;
2936
- type GetResult<T extends Query, Arg extends GetArg<T>> = Arg extends GetStringArg<T> ? SetQueryReturnsValue<T, Arg> : Arg extends Expression ? SetQueryReturnsColumn<T, Arg['_type']> : never;
2937
- type GetResultOptional<T extends Query, Arg extends GetArg<T>> = Arg extends GetStringArg<T> ? SetQueryReturnsValueOptional<T, Arg> : Arg extends Expression ? SetQueryReturnsColumnOptional<T, Arg['_type']> : never;
2938
- declare class QueryGet {
2579
+ where<T extends WhereQueryBase>(this: T, ...args: WhereArgs<T>): WhereResult<T>;
2580
+ _where<T extends WhereQueryBase>(this: T, ...args: WhereArgs<T>): WhereResult<T>;
2939
2581
  /**
2940
- * `.get` returns a single value, it will add `LIMIT 1` to the query, and accepts a column name or a raw expression.
2941
- * It will throw `NotFoundError` when not found.
2582
+ * `whereNot` takes the same arguments as `where` and prepends them with `NOT` in SQL
2942
2583
  *
2943
2584
  * ```ts
2944
- * import { NumberColumn } from 'pqb';
2945
- *
2946
- * const firstName: string = await db.table.get('name');
2947
- *
2948
- * const rawResult: number = await db.table.get(
2949
- * db.table.sql((t) => t.integer())`1 + 1`,
2950
- * );
2585
+ * // find records of different colors than red
2586
+ * db.table.whereNot({ color: 'red' });
2951
2587
  * ```
2952
2588
  *
2953
- * @param arg - string for a column to get, or a raw SQL
2589
+ * @param args - {@link WhereArgs}
2954
2590
  */
2955
- get<T extends Query, Arg extends GetArg<T>>(this: T, arg: Arg): GetResult<T, Arg>;
2956
- _get<T extends Query, Arg extends GetArg<T>>(this: T, arg: Arg): GetResult<T, Arg>;
2591
+ whereNot<T extends WhereQueryBase>(this: T, ...args: WhereArgs<T>): WhereResult<T>;
2592
+ _whereNot<T extends WhereQueryBase>(this: T, ...args: WhereArgs<T>): WhereResult<T>;
2957
2593
  /**
2958
- * `.getOptional` returns a single value or undefined when not found:
2594
+ * `and` is an alias for {@link where} to make it look closer to SQL:
2959
2595
  *
2960
2596
  * ```ts
2961
- * const firstName: string | undefined = await db.table.getOptional('name');
2597
+ * db.table.where({ id: 1 }).and({ name: 'John' });
2962
2598
  * ```
2963
2599
  *
2964
- * @param arg - string for a column to get, or a raw SQL
2600
+ * @param args - {@link WhereArgs}
2965
2601
  */
2966
- getOptional<T extends Query, Arg extends GetArg<T>>(this: T, arg: Arg): GetResultOptional<T, Arg>;
2967
- _getOptional<T extends Query, Arg extends GetArg<T>>(this: T, arg: Arg): GetResultOptional<T, Arg>;
2968
- }
2969
-
2970
- type HavingArgs<T extends Query> = TemplateLiteralArgs | HavingArgFn<T>[];
2971
- type HavingArgFn<T extends Query> = (q: SelectAggMethods<T>) => Expression<ColumnTypeBase<boolean | null>>;
2972
- declare class Having {
2602
+ and<T extends WhereQueryBase>(this: T, ...args: WhereArgs<T>): WhereResult<T>;
2603
+ _and<T extends WhereQueryBase>(this: T, ...args: WhereArgs<T>): WhereResult<T>;
2973
2604
  /**
2974
- * Build a `HAVING` clause to the query to filter records by results of [aggregate functions](#aggregate-functions).
2605
+ * `andNot` is an alias for `whereNot`.
2975
2606
  *
2976
- * The argument of `having` is a function where you call the aggregate function and compare it with some value by using [column operators](/guide/where.html#column-operators).
2607
+ * @param args - {@link WhereArgs}
2608
+ */
2609
+ andNot<T extends WhereQueryBase>(this: T, ...args: WhereArgs<T>): WhereResult<T>;
2610
+ _andNot<T extends WhereQueryBase>(this: T, ...args: WhereArgs<T>): WhereResult<T>;
2611
+ /**
2612
+ * `or` is accepting the same arguments as {@link where}, joining arguments with `OR`.
2613
+ *
2614
+ * Columns in single arguments are still joined with `AND`.
2615
+ *
2616
+ * The database is processing `AND` before `OR`, so this should be intuitively clear.
2977
2617
  *
2978
2618
  * ```ts
2979
- * db.table.having((q) => q.count().gte(10));
2980
- * // HAVING count(*) >= 10
2619
+ * db.table.or({ id: 1, color: 'red' }, { id: 2, color: 'blue' });
2981
2620
  * ```
2982
2621
  *
2983
- * Alternatively, it accepts a raw SQL template:
2622
+ * This query will produce such SQL (simplified):
2623
+ *
2624
+ * ```sql
2625
+ * SELECT * FROM "table"
2626
+ * WHERE id = 1 AND color = 'red'
2627
+ * OR id = 2 AND color = 'blue'
2628
+ * ```
2629
+ *
2630
+ * @param args - {@link WhereArgs} will be joined with `OR`
2631
+ */
2632
+ or<T extends WhereQueryBase>(this: T, ...args: WhereArg<T>[]): WhereResult<T>;
2633
+ _or<T extends WhereQueryBase>(this: T, ...args: WhereArg<T>[]): WhereResult<T>;
2634
+ /**
2635
+ * `orNot` takes the same arguments as {@link or}, and prepends each condition with `NOT` just as {@link whereNot} does.
2636
+ *
2637
+ * @param args - {@link WhereArgs} will be prefixed with `NOT` and joined with `OR`
2638
+ */
2639
+ orNot<T extends WhereQueryBase>(this: T, ...args: WhereArg<T>[]): WhereResult<T>;
2640
+ _orNot<T extends WhereQueryBase>(this: T, ...args: WhereArg<T>[]): WhereResult<T>;
2641
+ /**
2642
+ * `whereIn` and related methods are for the `IN` operator to check for inclusion in a list of values.
2643
+ *
2644
+ * When used with a single column it works equivalent to the `in` column operator:
2984
2645
  *
2985
2646
  * ```ts
2986
- * db.table.having`count(*) >= ${10}`;
2647
+ * db.table.whereIn('column', [1, 2, 3]);
2648
+ * // the same as:
2649
+ * db.table.where({ column: [1, 2, 3] });
2987
2650
  * ```
2988
2651
  *
2989
- * Multiple having conditions will be combined with `AND`:
2652
+ * `whereIn` can support a tuple of columns, that's what the `in` operator cannot support:
2990
2653
  *
2991
2654
  * ```ts
2992
- * db.table.having(
2993
- * (q) => q.sum('column').gt(5),
2994
- * (q) => q.avg('column').lt(10),
2655
+ * db.table.whereIn(
2656
+ * ['id', 'name'],
2657
+ * [
2658
+ * [1, 'Alice'],
2659
+ * [2, 'Bob'],
2660
+ * ],
2995
2661
  * );
2996
- * // HAVING sum(column) > 5 AND avg(column) < 10
2997
2662
  * ```
2998
2663
  *
2999
- * After applying a comparison, `or` and `and` methods become available:
2664
+ * It supports sub query which should return records with columns of the same type:
3000
2665
  *
3001
2666
  * ```ts
3002
- * db.table.having((q) =>
3003
- * q.sum('column').equals(5).or(q.min('column').gt(1), q.max('column').lt(10)),
3004
- * );
3005
- * // HAVING (sum(column) = 5) OR (min(column) > 1 AND max(column) < 10)
2667
+ * db.table.whereIn(['id', 'name'], OtherTable.select('id', 'name'));
3006
2668
  * ```
3007
2669
  *
3008
- * Aggregate functions are exactly the same functions described in [aggregate functions](#aggregate-functions), they can accept aggregation options:
2670
+ * It supports raw SQL expression:
3009
2671
  *
3010
2672
  * ```ts
3011
- * db.table.having((q) =>
3012
- * q
3013
- * .count('id', {
3014
- * distinct: true,
3015
- * order: { createdAt: 'DESC', filter: { someColumn: { not: null } } },
3016
- * })
3017
- * .gte(10),
3018
- * );
2673
+ * db.table.whereIn(['id', 'name'], db.table.sql`((1, 'one'), (2, 'two'))`);
3019
2674
  * ```
3020
2675
  *
3021
- * Arguments of the aggregate function and of the comparison can be raw SQL:
2676
+ * @param column - one column name, or array of column names
2677
+ * @param values - array of values, or a query to load values, or a raw SQL. Tuple of such values in case of multiple columns.
2678
+ */
2679
+ whereIn<T extends WhereQueryBase, Column extends WhereInColumn<T>>(this: T, column: Column, values: WhereInValues<T, Column>): WhereResult<T>;
2680
+ /**
2681
+ * See {@link whereIn}.
2682
+ *
2683
+ * @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.
2684
+ */
2685
+ whereIn<T extends WhereQueryBase>(this: T, arg: WhereInArg<T>): WhereResult<T>;
2686
+ _whereIn<T extends WhereQueryBase, Column extends WhereInColumn<T>>(this: T, column: Column, values: WhereInValues<T, Column>): WhereResult<T>;
2687
+ _whereIn<T extends WhereQueryBase>(this: T, arg: WhereInArg<T>): WhereResult<T>;
2688
+ /**
2689
+ * Takes the same arguments as {@link whereIn}.
2690
+ * Add a `WHERE IN` condition prefixed with `OR` to the query:
3022
2691
  *
3023
2692
  * ```ts
3024
- * db.table.having((q) => q.count(q.sql('coalesce(one, two)')).gte(q.sql`2 + 2`));
2693
+ * db.table.whereIn('a', [1, 2, 3]).orWhereIn('b', ['one', 'two']);
3025
2694
  * ```
3026
2695
  *
3027
- * @param args - raw SQL template string or one or multiple callbacks returning a boolean expression
2696
+ * @param column - one column name, or array of column names
2697
+ * @param values - array of values, or a query to load values, or a raw SQL. Tuple of such values in case of multiple columns.
3028
2698
  */
3029
- having<T extends Query>(this: T, ...args: HavingArgs<T>): T;
3030
- _having<T extends Query>(this: T, ...args: HavingArgs<T>): T;
3031
- }
3032
-
3033
- type AfterHook<Select extends PropertyKey[], Shape extends ColumnsShapeBase, Selected extends ColumnsShapeBase = Pick<Shape, StringKey<Select[number]>>, Item = {
3034
- [K in keyof Selected]: Selected[K]['outputType'];
3035
- }> = QueryAfterHook<Item[]>;
3036
- type HookSelect<T extends QueryBase> = (keyof T['shape'])[];
3037
- type HookAction = 'Create' | 'Update' | 'Delete';
3038
- declare abstract class QueryHooks extends QueryBase {
2699
+ orWhereIn<T extends WhereQueryBase, Column extends WhereInColumn<T>>(this: T, column: Column, values: WhereInValues<T, Column>): WhereResult<T>;
3039
2700
  /**
3040
- * Run the function before any kind of query.
2701
+ * See {@link orWhereIn}.
3041
2702
  *
3042
- * @param cb - function to call, first argument is a query object
2703
+ * @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.
3043
2704
  */
3044
- beforeQuery<T extends QueryHooks>(this: T, cb: QueryBeforeHook): T;
3045
- _beforeQuery<T extends QueryBase>(this: T, cb: QueryBeforeHook): T;
2705
+ orWhereIn<T extends WhereQueryBase>(this: T, arg: WhereInArg<T>): WhereResult<T>;
2706
+ _orWhereIn<T extends WhereQueryBase, Column extends WhereInColumn<T>>(this: T, column: Column, values: WhereInValues<T, Column>): WhereResult<T>;
2707
+ _orWhereIn<T extends WhereQueryBase>(this: T, arg: WhereInArg<T>): WhereResult<T>;
3046
2708
  /**
3047
- * Run the function after any kind of query.
3048
- * Enforces wrapping the query into a transaction.
3049
- * The function will run after the query is succeeded, but before the transaction commit.
2709
+ * Acts as `whereIn`, but negates the condition with `NOT`:
3050
2710
  *
3051
- * @param cb - function to call, first argument is the query result of type `unknown`, second argument is a query object
2711
+ * ```ts
2712
+ * db.table.whereNotIn('color', ['red', 'green', 'blue']);
2713
+ * ```
2714
+ *
2715
+ * @param column - one column name, or array of column names
2716
+ * @param values - array of values, or a query to load values, or a raw SQL. Tuple of such values in case of multiple columns.
3052
2717
  */
3053
- afterQuery<T extends QueryHooks>(this: T, cb: QueryAfterHook): T;
3054
- _afterQuery<T extends QueryBase>(this: T, cb: QueryAfterHook): T;
2718
+ whereNotIn<T extends WhereQueryBase, Column extends WhereInColumn<T>>(this: T, column: Column, values: WhereInValues<T, Column>): WhereResult<T>;
3055
2719
  /**
3056
- * Run the function before a `create` kind of query.
2720
+ * See {@link whereNotIn}.
3057
2721
  *
3058
- * @param cb - function to call, first argument is a query object
2722
+ * @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.
3059
2723
  */
3060
- beforeCreate<T extends QueryHooks>(this: T, cb: QueryBeforeHook): T;
3061
- _beforeCreate<T extends QueryBase>(this: T, cb: QueryBeforeHook): T;
2724
+ whereNotIn<T extends WhereQueryBase>(this: T, arg: WhereInArg<T>): WhereResult<T>;
2725
+ _whereNotIn<T extends WhereQueryBase, Column extends WhereInColumn<T>>(this: T, column: Column, values: WhereInValues<T, Column>): WhereResult<T>;
2726
+ _whereNotIn<T extends WhereQueryBase>(this: T, arg: WhereInArg<T>): WhereResult<T>;
3062
2727
  /**
3063
- * Run the function after a `create` kind of query.
3064
- * Enforces wrapping the query into a transaction.
3065
- * The function will run after the query is succeeded, but before the transaction commit.
3066
- * Queries inside the function will run in the same transaction as the target query.
2728
+ * Acts as `whereIn`, but prepends `OR` to the condition and negates it with `NOT`:
3067
2729
  *
3068
- * @param select - list of columns to select for the hook
3069
- * @param cb - function to call, first argument is the query result with selected columns, second argument is a query object
2730
+ * ```ts
2731
+ * db.table.whereNotIn('a', [1, 2, 3]).orWhereNoIn('b', ['one', 'two']);
2732
+ * ```
2733
+ *
2734
+ * @param column - one column name, or array of column names
2735
+ * @param values - array of values, or a query to load values, or a raw SQL. Tuple of such values in case of multiple columns.
3070
2736
  */
3071
- afterCreate<T extends QueryHooks, S extends HookSelect<T>>(this: T, select: S, cb: AfterHook<S, T['shape']>): T;
3072
- _afterCreate<T extends QueryBase, S extends HookSelect<T>>(this: T, select: S, cb: AfterHook<S, T['shape']>): T;
2737
+ orWhereNotIn<T extends WhereQueryBase, Column extends WhereInColumn<T>>(this: T, column: Column, values: WhereInValues<T, Column>): WhereResult<T>;
3073
2738
  /**
3074
- * Run the function after transaction for a `create` kind of query will be committed.
3075
- * If the query wasn't wrapped in a transaction, will run after the query.
2739
+ * See {@link orWhereNotIn}.
3076
2740
  *
3077
- * @param select - list of columns to select for the hook
3078
- * @param cb - function to call, first argument is the query result with selected columns, second argument is a query object
2741
+ * @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.
3079
2742
  */
3080
- afterCreateCommit<T extends QueryHooks, S extends HookSelect<T>>(this: T, select: S, cb: AfterHook<S, T['shape']>): T;
3081
- _afterCreateCommit<T extends QueryHooks, S extends HookSelect<T>>(this: T, select: S, cb: AfterHook<S, T['shape']>): T;
2743
+ orWhereNotIn<T extends WhereQueryBase>(this: T, arg: WhereInArg<T>): WhereResult<T>;
2744
+ _orWhereNotIn<T extends WhereQueryBase, Column extends WhereInColumn<T>>(this: T, column: Column, values: WhereInValues<T, Column>): WhereResult<T>;
2745
+ _orWhereNotIn<T extends WhereQueryBase>(this: T, arg: WhereInArg<T>): WhereResult<T>;
3082
2746
  /**
3083
- * Run the function before an `update` kind of query.
2747
+ * `whereExists` is for support of the `WHERE EXISTS (query)` clause.
3084
2748
  *
3085
- * @param cb - function to call, first argument is a query object
2749
+ * This method is accepting the same arguments as `join`, see the {@link Join.join} section for more details.
2750
+ *
2751
+ * ```ts
2752
+ * // find users who have accounts
2753
+ * // find by a relation name if it's defined
2754
+ * db.user.whereExists('account');
2755
+ *
2756
+ * // find using a table and a join conditions
2757
+ * db.user.whereExists(db.account, 'account.id', 'user.id');
2758
+ *
2759
+ * // find using a query builder in a callback:
2760
+ * db.user.whereExists(db.account, (q) => q.on('account.id', '=', 'user.id'));
2761
+ * ```
2762
+ *
2763
+ * @param arg - relation name, or a query object, or a `with` table alias, or a callback returning a query object.
2764
+ * @param args - no arguments needed when the first argument is a relation name, or conditions to join the table with.
3086
2765
  */
3087
- beforeUpdate<T extends QueryHooks>(this: T, cb: QueryBeforeHook): T;
3088
- _beforeUpdate<T extends QueryHooks>(this: T, cb: QueryBeforeHook): T;
2766
+ whereExists<T extends WhereQueryBase, Arg extends JoinFirstArg<T>>(this: T, arg: Arg, ...args: JoinArgs<T, Arg>): WhereResult<T>;
3089
2767
  /**
3090
- * Run the function after an `update` kind of query.
3091
- * Enforces wrapping the query into a transaction.
3092
- * The function will run after the query is succeeded, but before the transaction commit.
3093
- * Queries inside the function will run in the same transaction as the target query.
3094
- * If no records were updated, the hook *won't* run.
2768
+ * See {@link whereExists}.
3095
2769
  *
3096
- * @param select - list of columns to select for the hook
3097
- * @param cb - function to call, first argument is the query result with selected columns, second argument is a query object
2770
+ * @param arg - relation name, or a query object, or a `with` table alias, or a callback returning a query object.
2771
+ * @param cb - callback with a query builder to join the table.
3098
2772
  */
3099
- afterUpdate<T extends QueryHooks, S extends HookSelect<T>>(this: T, select: S, cb: AfterHook<S, T['shape']>): T;
3100
- _afterUpdate<T extends QueryHooks, S extends HookSelect<T>>(this: T, select: S, cb: AfterHook<S, T['shape']>): T;
2773
+ whereExists<T extends WhereQueryBase, Arg extends JoinFirstArg<T>>(this: T, arg: Arg, cb: JoinCallback<T, Arg>): WhereResult<T>;
2774
+ _whereExists<T extends WhereQueryBase, Arg extends JoinFirstArg<T>>(this: T, arg: Arg, ...args: JoinArgs<T, Arg>): WhereResult<T>;
2775
+ _whereExists<T extends WhereQueryBase, Arg extends JoinFirstArg<T>>(this: T, arg: Arg, cb: JoinCallback<T, Arg>): WhereResult<T>;
3101
2776
  /**
3102
- * Run the function after transaction for an `update` kind of query will be committed.
3103
- * If the query wasn't wrapped in a transaction, will run after the query.
3104
- * If no records were updated, the hook *won't* run.
2777
+ * Acts as `whereExists`, but prepends the condition with `OR`:
3105
2778
  *
3106
- * @param select - list of columns to select for the hook
3107
- * @param cb - function to call, first argument is the query result with selected columns, second argument is a query object
2779
+ * ```ts
2780
+ * // find users who have an account or a profile,
2781
+ * // imagine that the user has both `account` and `profile` relations defined.
2782
+ * db.user.whereExist('account').orWhereExists('profile');
2783
+ * ```
2784
+ *
2785
+ * @param arg - relation name, or a query object, or a `with` table alias, or a callback returning a query object.
2786
+ * @param args - no arguments needed when the first argument is a relation name, or conditions to join the table with.
3108
2787
  */
3109
- afterUpdateCommit<T extends QueryHooks, S extends HookSelect<T>>(this: T, select: S, cb: AfterHook<S, T['shape']>): T;
3110
- _afterUpdateCommit<T extends QueryHooks, S extends HookSelect<T>>(this: T, select: S, cb: AfterHook<S, T['shape']>): T;
2788
+ orWhereExists<T extends WhereQueryBase, Arg extends JoinFirstArg<T>, Args extends JoinArgs<T, Arg>>(this: T, arg: Arg, ...args: Args): WhereResult<T>;
3111
2789
  /**
3112
- * Run the function before a `create` or an `update` kind of query.
2790
+ * See {@link orWhereExists}.
3113
2791
  *
3114
- * @param cb - function to call, first argument is a query object
2792
+ * @param arg - relation name, or a query object, or a `with` table alias, or a callback returning a query object.
2793
+ * @param cb - callback with a query builder to join the table.
3115
2794
  */
3116
- beforeSave<T extends QueryHooks>(this: T, cb: QueryBeforeHook): T;
3117
- _beforeSave<T extends QueryHooks>(this: T, cb: QueryBeforeHook): T;
2795
+ orWhereExists<T extends WhereQueryBase, Arg extends JoinFirstArg<T>>(this: T, arg: Arg, cb: JoinCallback<T, Arg>): WhereResult<T>;
2796
+ _orWhereExists<T extends WhereQueryBase, Arg extends JoinFirstArg<T>, Args extends JoinArgs<T, Arg>>(this: T, arg: Arg, ...args: Args): WhereResult<T>;
2797
+ _orWhereExists<T extends WhereQueryBase, Arg extends JoinFirstArg<T>>(this: T, arg: Arg, cb: JoinCallback<T, Arg>): WhereResult<T>;
3118
2798
  /**
3119
- * Run the function after a `create` or an `update` kind of query.
3120
- * Enforces wrapping the query into a transaction.
3121
- * The function will run after the query is succeeded, but before the transaction commit.
3122
- * Queries inside the function will run in the same transaction as the target query.
3123
- * For the `update` query, if no records were updated, the hook *won't* run.
2799
+ * Acts as `whereExists`, but negates the condition with `NOT`:
3124
2800
  *
3125
- * @param select - list of columns to select for the hook
3126
- * @param cb - function to call, first argument is the query result with selected columns, second argument is a query object
2801
+ * ```ts
2802
+ * // find users who don't have an account,
2803
+ * // image that the user `belongsTo` or `hasOne` account.
2804
+ * db.user.whereNotExist('account');
2805
+ * ```
2806
+ *
2807
+ * @param arg - relation name, or a query object, or a `with` table alias, or a callback returning a query object.
2808
+ * @param args - no arguments needed when the first argument is a relation name, or conditions to join the table with.
3127
2809
  */
3128
- afterSave<T extends QueryHooks, S extends HookSelect<T>>(this: T, select: S, cb: AfterHook<S, T['shape']>): T;
3129
- _afterSave<T extends QueryHooks, S extends HookSelect<T>>(this: T, select: S, cb: AfterHook<S, T['shape']>): T;
2810
+ whereNotExists<T extends WhereQueryBase, Arg extends JoinFirstArg<T>, Args extends JoinArgs<T, Arg>>(this: T, arg: Arg, ...args: Args): WhereResult<T>;
3130
2811
  /**
3131
- * Run the function after transaction for a `create` or an `update` kind of query will be committed.
3132
- * If the query wasn't wrapped in a transaction, will run after the query.
3133
- * For the `update` query, if no records were updated, the hook *won't* run.
2812
+ * See {@link whereNotExists}.
3134
2813
  *
3135
- * @param select - list of columns to select for the hook
3136
- * @param cb - function to call, first argument is the query result with selected columns, second argument is a query object
2814
+ * @param arg - relation name, or a query object, or a `with` table alias, or a callback returning a query object.
2815
+ * @param cb - callback with a query builder to join the table.
3137
2816
  */
3138
- afterSaveCommit<T extends QueryHooks, S extends HookSelect<T>>(this: T, select: S, cb: AfterHook<S, T['shape']>): T;
3139
- _afterSaveCommit<T extends QueryHooks, S extends HookSelect<T>>(this: T, select: S, cb: AfterHook<S, T['shape']>): T;
2817
+ whereNotExists<T extends WhereQueryBase, Arg extends JoinFirstArg<T>>(this: T, arg: Arg, cb: JoinCallback<T, Arg>): WhereResult<T>;
2818
+ _whereNotExists<T extends WhereQueryBase, Arg extends JoinFirstArg<T>, Args extends JoinArgs<T, Arg>>(this: T, arg: Arg, ...args: Args): WhereResult<T>;
2819
+ _whereNotExists<T extends WhereQueryBase, Arg extends JoinFirstArg<T>>(this: T, arg: Arg, cb: JoinCallback<T, Arg>): WhereResult<T>;
3140
2820
  /**
3141
- * Run the function before a `delete` kind of query.
2821
+ * Acts as `whereExists`, but prepends the condition with `OR` and negates it with `NOT`:
3142
2822
  *
3143
- * @param cb - function to call, first argument is a query object
2823
+ * ```ts
2824
+ * // find users who don't have an account OR who don't have a profile
2825
+ * // imagine that the user has both `account` and `profile` relations defined.
2826
+ * db.user.whereNotExists('account').orWhereNotExists('profile');
2827
+ * ```
2828
+ *
2829
+ * @param arg - relation name, or a query object, or a `with` table alias, or a callback returning a query object.
2830
+ * @param args - no arguments needed when the first argument is a relation name, or conditions to join the table with.
3144
2831
  */
3145
- beforeDelete<T extends QueryHooks>(this: T, cb: QueryBeforeHook): T;
3146
- _beforeDelete<T extends QueryHooks>(this: T, cb: QueryBeforeHook): T;
2832
+ orWhereNotExists<T extends WhereQueryBase, Arg extends JoinFirstArg<T>, Args extends JoinArgs<T, Arg>>(this: T, arg: Arg, ...args: Args): WhereResult<T>;
3147
2833
  /**
3148
- * Run the function after a `delete` kind of query.
3149
- * Enforces wrapping the query into a transaction.
3150
- * The function will run after the query is succeeded, but before the transaction commit.
3151
- * Queries inside the function will run in the same transaction as the target query.
3152
- * If no records were deleted, the hook *won't* run.
2834
+ * See {@link orWhereNotExists}.
3153
2835
  *
3154
- * @param select - list of columns to select for the hook
3155
- * @param cb - function to call, first argument is the query result with selected columns, second argument is a query object
3156
- */
3157
- afterDelete<T extends QueryHooks, S extends HookSelect<T>>(this: T, select: S, cb: AfterHook<S, T['shape']>): T;
3158
- _afterDelete<T extends QueryHooks, S extends HookSelect<T>>(this: T, select: S, cb: AfterHook<S, T['shape']>): T;
2836
+ * @param arg - relation name, or a query object, or a `with` table alias, or a callback returning a query object.
2837
+ * @param cb - callback with a query builder to join the table.
2838
+ */
2839
+ orWhereNotExists<T extends WhereQueryBase, Arg extends JoinFirstArg<T>>(this: T, arg: Arg, cb: JoinCallback<T, Arg>): WhereResult<T>;
2840
+ _orWhereNotExists<T extends WhereQueryBase, Arg extends JoinFirstArg<T>, Args extends JoinArgs<T, Arg>>(this: T, arg: Arg, ...args: Args): WhereResult<T>;
2841
+ _orWhereNotExists<T extends WhereQueryBase, Arg extends JoinFirstArg<T>>(this: T, arg: Arg, cb: JoinCallback<T, Arg>): WhereResult<T>;
2842
+ }
2843
+ interface WhereQueryBase extends Where, QueryBase {
2844
+ }
2845
+ declare abstract class WhereQueryBase extends QueryBase {
2846
+ }
2847
+
2848
+ type WithSelectable<T extends QueryBase, W extends keyof T['withData']> = T['withData'][W] extends WithDataItem ? StringKey<keyof T['withData'][W]['shape']> | `${T['withData'][W]['table']}.${StringKey<keyof T['withData'][W]['shape']>}` : never;
2849
+ /**
2850
+ * The first argument of all `join` and `joinLateral` methods.
2851
+ * See argument of {@link Join.join}.
2852
+ */
2853
+ type JoinFirstArg<T extends QueryBase> = Query | keyof T['relations'] | keyof T['withData'] | ((q: T['relations']) => Query);
2854
+ /**
2855
+ * Arguments of `join` methods (not `joinLateral`).
2856
+ * See {@link Join.join}
2857
+ */
2858
+ type JoinArgs<T extends QueryBase, Arg extends JoinFirstArg<T>> = Arg extends Query ? JoinQueryArgs<T, Arg> : Arg extends keyof T['relations'] ? EmptyTuple : Arg extends keyof T['withData'] ? JoinWithArgs<T, Arg> : never;
2859
+ /**
2860
+ * Column names of the joined table that can be used to join.
2861
+ * Derived from 'result', not from 'shape',
2862
+ * because if the joined table has a specific selection, it will be wrapped like:
2863
+ * ```sql
2864
+ * JOIN (SELECT something FROM joined) joined ON joined.something = ...
2865
+ * ```
2866
+ * And the selection becomes available to use in the `ON` and to select from the joined table.
2867
+ */
2868
+ type JoinSelectable<Q extends Query> = keyof Q['result'] | `${AliasOrTable<Q>}.${StringKey<keyof Q['result']>}`;
2869
+ type JoinQueryArgs<T extends QueryBase, Q extends Query> = [
2870
+ conditions: Record<JoinSelectable<Q>, Selectable<T> | Expression> | Expression | true
2871
+ ] | [
2872
+ leftColumn: JoinSelectable<Q> | Expression,
2873
+ rightColumn: Selectable<T> | Expression
2874
+ ] | [
2875
+ leftColumn: JoinSelectable<Q> | Expression,
2876
+ op: string,
2877
+ rightColumn: Selectable<T> | Expression
2878
+ ];
2879
+ type JoinWithArgs<T extends QueryBase, W extends keyof T['withData']> = [
2880
+ conditions: Record<WithSelectable<T, W>, Selectable<T> | Expression> | Expression
2881
+ ] | [
2882
+ leftColumn: WithSelectable<T, W> | Expression,
2883
+ rightColumn: Selectable<T> | Expression
2884
+ ] | [
2885
+ leftColumn: WithSelectable<T, W> | Expression,
2886
+ op: string,
2887
+ rightColumn: Selectable<T> | Expression
2888
+ ];
2889
+ /**
2890
+ * Result of all `join` methods, not `joinLateral`.
2891
+ * Adds joined table columns from its 'result' to the 'selectable' of the query.
2892
+ *
2893
+ * @param T - query type to join to
2894
+ * @param Arg - first arg of join, see {@link JoinFirstArg}
2895
+ * @param RequireJoined - when false, joined table shape will be mapped to make all columns optional
2896
+ * @param RequireMain - when false, main table shape will be mapped to make all columns optional (for right and full join)
2897
+ */
2898
+ type JoinResult<T extends Query, Arg extends JoinFirstArg<T>, RequireJoined extends boolean, RequireMain extends boolean, Cb extends (q: never) => {
2899
+ meta: QueryMetaBase;
2900
+ } = () => {
2901
+ meta: QueryMetaBase;
2902
+ }, J extends Pick<Query, 'result' | 'table' | 'meta'> = Arg extends Query ? Arg : Arg extends keyof T['relations'] ? T['relations'][Arg]['relationConfig']['table'] : Arg extends (q: never) => Query ? ReturnType<Arg> : Arg extends keyof T['withData'] ? T['withData'][Arg] extends WithDataItem ? {
2903
+ table: T['withData'][Arg]['table'];
2904
+ result: T['withData'][Arg]['shape'];
2905
+ meta: QueryBase['meta'];
2906
+ } : never : never, Selectable extends SelectableBase = JoinResultSelectable<J, RequireJoined, ReturnType<Cb>>> = RequireMain extends true ? JoinAddSelectable<T, Selectable> : JoinOptionalMain<T, Selectable>;
2907
+ /**
2908
+ * Result of all `joinLateral` methods.
2909
+ * Adds joined table columns from its 'result' to the 'selectable' of the query.
2910
+ *
2911
+ * @param T - query type to join to
2912
+ * @param Arg - first arg of join, see {@link JoinFirstArg}
2913
+ * @param RequireJoined - when false, joined table shape will be mapped to make all columns optional
2914
+ */
2915
+ type JoinLateralResult<T extends Query, R extends QueryBase, RequireJoined extends boolean, Selectable extends SelectableBase = JoinResultSelectable<R, RequireJoined, {
2916
+ meta: QueryMetaBase;
2917
+ }>> = JoinAddSelectable<T, Selectable>;
2918
+ /**
2919
+ * Build `selectable` type for joined table.
2920
+ *
2921
+ * When `RequireJoined` parameter is false,
2922
+ * the result type of the joined table will be mapped to make all columns optional.
2923
+ *
2924
+ * Callback may override the joined table alias.
2925
+ *
2926
+ * The resulting selectable receives all joined table columns prefixed with the table name or alias,
2927
+ * and a star prefixed with the table name or alias to select all joined columns.
2928
+ */
2929
+ type JoinResultSelectable<J extends Pick<Query, 'result' | 'table' | 'meta'>, RequireJoined extends boolean, CbResult extends {
2930
+ meta: QueryMetaBase;
2931
+ }, Result extends ColumnsShapeBase = RequireJoined extends true ? J['result'] : {
2932
+ [K in keyof J['result']]: NullableColumn<J['result'][K]>;
2933
+ }, As extends string = CbResult extends {
2934
+ meta: QueryMetaBase & {
2935
+ as: string;
2936
+ };
2937
+ } ? CbResult['meta']['as'] : AliasOrTable<J>> = {
2938
+ [K in keyof Result as `${As}.${StringKey<K>}`]: {
2939
+ as: K;
2940
+ column: Result[K];
2941
+ };
2942
+ } & {
2943
+ [K in As as `${As}.*`]: {
2944
+ as: K;
2945
+ column: RequireJoined extends true ? ColumnsObject<J['result']> : NullableColumn<ColumnsObject<J['result']>>;
2946
+ };
2947
+ };
2948
+ type JoinAddSelectable<T extends Query, Selectable extends SelectableBase> = {
2949
+ [K in keyof T]: K extends 'selectable' ? T['selectable'] & Selectable : T[K];
2950
+ };
2951
+ type JoinOptionalMain<T extends Query, Selectable extends SelectableBase, Result extends ColumnsShapeBase = {
2952
+ [K in keyof T['result']]: NullableColumn<T['result'][K]>;
2953
+ }, Data = GetQueryResult<T['returnType'], Result>> = {
2954
+ [K in keyof T]: K extends 'selectable' ? {
2955
+ [K in keyof T['selectable']]: {
2956
+ as: T['selectable'][K]['as'];
2957
+ column: NullableColumn<T['selectable'][K]['column']>;
2958
+ };
2959
+ } & Selectable : K extends 'result' ? Result : K extends 'then' ? QueryThen<Data> : K extends 'catch' ? QueryCatch<Data> : T[K];
2960
+ };
2961
+ /**
2962
+ * Map the `with` table first argument of `join` or `joinLateral` to a query type.
2963
+ * Constructs `selectable` based on `with` table shape, and adds generic types to conform the `QueryBase` type.
2964
+ */
2965
+ type JoinWithArgToQuery<With extends WithDataItem, Selectable extends SelectableBase = {
2966
+ [K in keyof With['shape']]: {
2967
+ as: StringKey<K>;
2968
+ column: With['shape'][K];
2969
+ };
2970
+ }> = {
2971
+ q: QueryData;
2972
+ table: With['table'];
2973
+ clone<T extends QueryBase>(this: T): T;
2974
+ selectable: Selectable & {
2975
+ [K in keyof Selectable as `${With['table']}.${StringKey<K>}`]: Selectable[K];
2976
+ };
2977
+ shape: With['shape'];
2978
+ result: With['shape'];
2979
+ baseQuery: Query;
2980
+ relations: RelationsBase;
2981
+ withData: WithDataBase;
2982
+ meta: QueryBase['meta'];
2983
+ internal: QueryInternal;
2984
+ returnType: QueryReturnType;
2985
+ };
2986
+ /**
2987
+ * Map the first argument of `join` or `joinLateral` to a query type.
2988
+ *
2989
+ * `with` table arg is mapped into `QueryBase`,
2990
+ * query arg is returned as is,
2991
+ * relation name is replaced with a relation table.
2992
+ */
2993
+ type JoinArgToQuery<T extends QueryBase, Arg extends JoinFirstArg<T>> = Arg extends keyof T['withData'] ? T['withData'][Arg] extends WithDataItem ? JoinWithArgToQuery<T['withData'][Arg]> : never : Arg extends Query ? Arg : Arg extends keyof T['relations'] ? T['relations'][Arg]['relationConfig']['table'] : never;
2994
+ /**
2995
+ * Type of the `join` callback (not `joinLateral`).
2996
+ *
2997
+ * Receives a query builder that can access columns of both the main and the joined table.
2998
+ *
2999
+ * The query builder is limited to `or` and `where` methods only.
3000
+ *
3001
+ * Callback must return a query builder.
3002
+ */
3003
+ type JoinCallback<T extends QueryBase, Arg extends JoinFirstArg<T>> = (q: OnQueryBuilder<T, JoinArgToQuery<T, Arg>>) => OnQueryBuilder;
3004
+ /**
3005
+ * Type of the `joinLateral`.
3006
+ *
3007
+ * Receives a query builder that can access columns of both the main and the joined table.
3008
+ *
3009
+ * Query builder inside callback is the query derived from the `joinLateral` first argument,
3010
+ * all query methods are allowed, `on` methods are available.
3011
+ *
3012
+ * The callback must return a query object. Its resulting type will become a type of the joined table.
3013
+ */
3014
+ type JoinLateralCallback<T extends QueryBase, Arg extends JoinFirstArg<T>, R extends QueryBase, Q extends QueryBase = JoinArgToQuery<T, Arg>> = (q: Q & OnQueryBuilder<T, Q>) => R;
3015
+ declare class Join {
3159
3016
  /**
3160
- * Run the function after transaction for a `delete` kind of query will be committed.
3161
- * If the query wasn't wrapped in a transaction, will run after the query.
3162
- * If no records were deleted, the hook *won't* run.
3017
+ * TODO: write docs
3163
3018
  *
3164
- * @param select - list of columns to select for the hook
3165
- * @param cb - function to call, first argument is the query result with selected columns, second argument is a query object
3019
+ * @param arg - can be a query object, a name of a relation, a name of `with` table, or a callback to join a relation
3020
+ * @param args - arguments depend on the first argument, it can be object with columns, list of columns, `true` literal.
3166
3021
  */
3167
- afterDeleteCommit<T extends QueryHooks, S extends HookSelect<T>>(this: T, select: S, cb: AfterHook<S, T['shape']>): T;
3168
- _afterDeleteCommit<T extends QueryHooks, S extends HookSelect<T>>(this: T, select: S, cb: AfterHook<S, T['shape']>): T;
3022
+ join<T extends Query, Arg extends JoinFirstArg<T>, Args extends JoinArgs<T, Arg>>(this: T, arg: Arg, ...args: Args): JoinResult<T, Arg, true, true>;
3023
+ join<T extends Query, Arg extends JoinFirstArg<T>, Cb extends JoinCallback<T, Arg>>(this: T, arg: Arg, cb: Cb): JoinResult<T, Arg, true, true, Cb>;
3024
+ _join<T extends Query, Arg extends JoinFirstArg<T>, Args extends JoinArgs<T, Arg>>(this: T, arg: Arg, ...args: Args): JoinResult<T, Arg, true, true>;
3025
+ _join<T extends Query, Arg extends JoinFirstArg<T>, Cb extends JoinCallback<T, Arg>>(this: T, arg: Arg, cb: Cb): JoinResult<T, Arg, true, true, Cb>;
3026
+ leftJoin<T extends Query, Arg extends JoinFirstArg<T>, Args extends JoinArgs<T, Arg>>(this: T, arg: Arg, ...args: Args): JoinResult<T, Arg, false, true>;
3027
+ leftJoin<T extends Query, Arg extends JoinFirstArg<T>, Cb extends JoinCallback<T, Arg>>(this: T, arg: Arg, cb: Cb): JoinResult<T, Arg, false, true, Cb>;
3028
+ _leftJoin<T extends Query, Arg extends JoinFirstArg<T>, Args extends JoinArgs<T, Arg>>(this: T, arg: Arg, ...args: Args): JoinResult<T, Arg, false, true>;
3029
+ _leftJoin<T extends Query, Arg extends JoinFirstArg<T>, Cb extends JoinCallback<T, Arg>>(this: T, arg: Arg, cb: Cb): JoinResult<T, Arg, false, true, Cb>;
3030
+ rightJoin<T extends Query, Arg extends JoinFirstArg<T>, Args extends JoinArgs<T, Arg>>(this: T, arg: Arg, ...args: Args): JoinResult<T, Arg, true, false>;
3031
+ rightJoin<T extends Query, Arg extends JoinFirstArg<T>, Cb extends JoinCallback<T, Arg>>(this: T, arg: Arg, cb: Cb): JoinResult<T, Arg, true, false, Cb>;
3032
+ _rightJoin<T extends Query, Arg extends JoinFirstArg<T>, Args extends JoinArgs<T, Arg>>(this: T, arg: Arg, ...args: Args): JoinResult<T, Arg, true, false>;
3033
+ _rightJoin<T extends Query, Arg extends JoinFirstArg<T>, Cb extends JoinCallback<T, Arg>>(this: T, arg: Arg, cb: Cb): JoinResult<T, Arg, true, false, Cb>;
3034
+ fullJoin<T extends Query, Arg extends JoinFirstArg<T>, Args extends JoinArgs<T, Arg>>(this: T, arg: Arg, ...args: Args): JoinResult<T, Arg, false, false>;
3035
+ fullJoin<T extends Query, Arg extends JoinFirstArg<T>, Cb extends JoinCallback<T, Arg>>(this: T, arg: Arg, cb: Cb): JoinResult<T, Arg, false, false, Cb>;
3036
+ _fullJoin<T extends Query, Arg extends JoinFirstArg<T>, Args extends JoinArgs<T, Arg>>(this: T, arg: Arg, ...args: Args): JoinResult<T, Arg, false, false>;
3037
+ _fullJoin<T extends Query, Arg extends JoinFirstArg<T>, Cb extends JoinCallback<T, Arg>>(this: T, arg: Arg, cb: Cb): JoinResult<T, Arg, false, false, Cb>;
3038
+ joinLateral<T extends Query, Arg extends JoinFirstArg<T>, R extends QueryBase>(this: T, arg: Arg, cb: JoinLateralCallback<T, Arg, R>): JoinLateralResult<T, R, true>;
3039
+ _joinLateral<T extends Query, Arg extends JoinFirstArg<T>, R extends QueryBase>(this: T, arg: Arg, cb: JoinLateralCallback<T, Arg, R>): JoinLateralResult<T, R, true>;
3040
+ leftJoinLateral<T extends Query, Arg extends JoinFirstArg<T>, R extends QueryBase>(this: T, arg: Arg, cb: JoinLateralCallback<T, Arg, R>): JoinLateralResult<T, R, false>;
3041
+ _leftJoinLateral<T extends Query, Arg extends JoinFirstArg<T>, R extends QueryBase>(this: T, arg: Arg, cb: JoinLateralCallback<T, Arg, R>): JoinLateralResult<T, R, false>;
3042
+ }
3043
+ type OnArgs<Q extends {
3044
+ selectable: SelectableBase;
3045
+ }> = [leftColumn: keyof Q['selectable'], rightColumn: keyof Q['selectable']] | [
3046
+ leftColumn: keyof Q['selectable'],
3047
+ op: string,
3048
+ rightColumn: keyof Q['selectable']
3049
+ ];
3050
+ declare const pushQueryOn: <T extends QueryBase>(q: T, joinFrom: QueryBase, joinTo: QueryBase, ...on: OnArgs<QueryBase>) => T;
3051
+ declare const pushQueryOrOn: typeof pushQueryOn;
3052
+ declare const addQueryOn: <T extends QueryBase>(q: T, joinFrom: QueryBase, joinTo: QueryBase, ...args: OnArgs<QueryBase>) => T;
3053
+ declare const addQueryOrOn: typeof pushQueryOrOn;
3054
+ type OnJsonPathEqualsArgs<T extends QueryBase> = [
3055
+ leftColumn: keyof T['selectable'],
3056
+ leftPath: string,
3057
+ rightColumn: keyof T['selectable'],
3058
+ rightPath: string
3059
+ ];
3060
+ declare class OnQueryBuilder<S extends QueryBase = QueryBase, J extends QueryBase = QueryBase> extends WhereQueryBase {
3061
+ selectable: J['selectable'] & Omit<S['selectable'], keyof S['shape']>;
3062
+ relations: J['relations'];
3063
+ result: J['result'];
3064
+ shape: J['shape'];
3065
+ baseQuery: Query;
3066
+ withData: {};
3067
+ internal: QueryInternal;
3068
+ constructor(q: QueryBase, { shape, joinedShapes }: Pick<QueryData, 'shape' | 'joinedShapes'>, joinTo: QueryBase);
3069
+ on<T extends OnQueryBuilder>(this: T, ...args: OnArgs<T>): T;
3070
+ _on<T extends OnQueryBuilder>(this: T, ...args: OnArgs<T>): T;
3071
+ orOn<T extends OnQueryBuilder>(this: T, ...args: OnArgs<T>): T;
3072
+ _orOn<T extends OnQueryBuilder>(this: T, ...args: OnArgs<T>): T;
3073
+ onJsonPathEquals<T extends OnQueryBuilder>(this: T, ...args: OnJsonPathEqualsArgs<T>): T;
3074
+ _onJsonPathEquals<T extends OnQueryBuilder>(this: T, ...args: OnJsonPathEqualsArgs<T>): T;
3169
3075
  }
3170
3076
 
3171
3077
  type JsonColumnName<T extends QueryBase> = StringKey<{
@@ -3436,9 +3342,11 @@ type SelectAsResult<T extends Query, Arg, Result extends SelectObjectResultTuple
3436
3342
  Result[1] & AddSelectable
3437
3343
  ] : Result;
3438
3344
  type SelectAsValueResult<T extends Query, Arg extends SelectAsValue<T>> = Arg extends keyof T['selectable'] ? T['selectable'][Arg]['column'] : Arg extends Expression ? Arg['_type'] : Arg extends (q: SelectQueryBuilder<T>) => infer R ? R extends QueryBase ? SelectSubQueryResult<R> : R extends Expression ? R['_type'] : R extends QueryBase | Expression ? SelectSubQueryResult<Exclude<R, Expression>> | Exclude<R, QueryBase>['_type'] : never : never;
3439
- type SelectSubQueryResult<Arg extends QueryBase & {
3440
- [isRequiredRelationKey]?: boolean;
3441
- }> = QueryReturnsAll<Arg['returnType']> extends true ? ArrayOfColumnsObjects<Arg['result']> : Arg['returnType'] extends 'valueOrThrow' ? Arg['result']['value'] : Arg['returnType'] extends 'pluck' ? PluckResultColumnType<Arg['result']['pluck']> : Arg[isRequiredRelationKey] extends true ? ColumnsObject<Arg['result']> : NullableColumn<ColumnsObject<Arg['result']>>;
3345
+ type SelectSubQueryResult<Arg extends QueryBase> = QueryReturnsAll<Arg['returnType']> extends true ? ArrayOfColumnsObjects<Arg['result']> : Arg['returnType'] extends 'valueOrThrow' ? Arg['result']['value'] : Arg['returnType'] extends 'pluck' ? PluckResultColumnType<Arg['result']['pluck']> : Arg extends {
3346
+ relationConfig: {
3347
+ required: true;
3348
+ };
3349
+ } ? ColumnsObject<Arg['result']> : NullableColumn<ColumnsObject<Arg['result']>>;
3442
3350
  declare const addParserForRawExpression: (q: Query, key: string | getValueKey, raw: Expression) => void;
3443
3351
  declare const addParserForSelectItem: <T extends Query>(q: T, as: string | getValueKey | undefined, key: string, arg: Query | SelectableOrExpression<T>) => string | Expression | Query;
3444
3352
  declare const processSelectArg: <T extends Query>(q: T, as: string | undefined, arg: SelectArg<T>, columnAs?: string | getValueKey) => SelectItem;
@@ -3672,75 +3580,19 @@ declare class Union {
3672
3580
 
3673
3581
  type UpdateData<T extends Query> = {
3674
3582
  [K in keyof T['inputType']]?: UpdateColumn<T, K>;
3675
- } & (T['relations'] extends Record<string, Relation> ? {
3676
- [K in keyof T['relations']]?: T['relations'][K] extends BelongsToRelation ? UpdateBelongsToData<T, T['relations'][K]> : T['relations'][K] extends HasOneRelation ? UpdateHasOneData<T, T['relations'][K]> : T['relations'][K] extends HasManyRelation ? UpdateHasManyData<T, T['relations'][K]> : T['relations'][K] extends HasAndBelongsToManyRelation ? UpdateHasAndBelongsToManyData<T['relations'][K]> : never;
3677
- } : EmptyObject) & {
3678
- __raw?: never;
3583
+ } & {
3584
+ [K in keyof T['relations']]?: UpdateRelationData<T, T['relations'][K]['relationConfig']>;
3679
3585
  };
3680
3586
  type UpdateColumn<T extends Query, Key extends keyof T['inputType']> = T['inputType'][Key] | Expression | {
3681
3587
  [K in keyof Query]: K extends 'then' ? QueryThen<T['inputType'][Key]> : Query[K];
3682
3588
  } | ((q: {
3683
3589
  [K in keyof JsonModifiers]: K extends 'selectable' ? T['selectable'] : T[K];
3684
- } & {
3685
- [K in keyof T['relations']]: T[K];
3686
- }) => JsonItem | (RelationQueryBase & {
3590
+ } & T['relations']) => JsonItem | (RelationQueryBase & {
3687
3591
  meta: {
3688
3592
  kind: 'select';
3689
3593
  };
3690
3594
  }));
3691
- type UpdateBelongsToData<T extends Query, Rel extends BelongsToRelation> = {
3692
- disconnect: boolean;
3693
- } | {
3694
- set: WhereArg<Rel['table']>;
3695
- } | {
3696
- delete: boolean;
3697
- } | {
3698
- update: UpdateData<Rel['table']>;
3699
- } | {
3700
- create: CreateData<Rel['nestedCreateQuery']>;
3701
- } | (QueryReturnsAll<T['returnType']> extends true ? never : {
3702
- upsert: {
3703
- update: UpdateData<Rel['table']>;
3704
- create: CreateData<Rel['nestedCreateQuery']> | (() => CreateData<Rel['nestedCreateQuery']>);
3705
- };
3706
- });
3707
- type UpdateHasOneData<T extends Query, Rel extends HasOneRelation> = {
3708
- disconnect: boolean;
3709
- } | {
3710
- delete: boolean;
3711
- } | {
3712
- update: UpdateData<Rel['table']>;
3713
- } | (QueryReturnsAll<T['returnType']> extends true ? never : {
3714
- set: WhereArg<Rel['table']>;
3715
- } | {
3716
- upsert: {
3717
- update: UpdateData<Rel['table']>;
3718
- create: CreateData<Rel['nestedCreateQuery']> | (() => CreateData<Rel['nestedCreateQuery']>);
3719
- };
3720
- } | {
3721
- create: CreateData<Rel['nestedCreateQuery']>;
3722
- });
3723
- type UpdateHasManyData<T extends Query, Rel extends HasManyRelation> = {
3724
- disconnect?: MaybeArray<WhereArg<Rel['table']>>;
3725
- delete?: MaybeArray<WhereArg<Rel['table']>>;
3726
- update?: {
3727
- where: MaybeArray<WhereArg<Rel['table']>>;
3728
- data: UpdateData<Rel['table']>;
3729
- };
3730
- } & (QueryReturnsAll<T['returnType']> extends true ? EmptyObject : {
3731
- set?: MaybeArray<WhereArg<Rel['table']>>;
3732
- create?: CreateData<Rel['nestedCreateQuery']>[];
3733
- });
3734
- type UpdateHasAndBelongsToManyData<Rel extends HasAndBelongsToManyRelation> = {
3735
- disconnect?: MaybeArray<WhereArg<Rel['table']>>;
3736
- set?: MaybeArray<WhereArg<Rel['table']>>;
3737
- delete?: MaybeArray<WhereArg<Rel['table']>>;
3738
- update?: {
3739
- where: MaybeArray<WhereArg<Rel['table']>>;
3740
- data: UpdateData<Rel['table']>;
3741
- };
3742
- create?: CreateData<Rel['nestedCreateQuery']>[];
3743
- };
3595
+ type UpdateRelationData<T extends Query, Rel extends RelationConfigBase> = Rel['one'] extends true ? Rel['dataForUpdate'] | (QueryReturnsAll<T['returnType']> extends true ? never : Rel['dataForUpdateOne']) : Rel['dataForUpdate'] & (QueryReturnsAll<T['returnType']> extends true ? EmptyObject : Rel['dataForUpdateOne']);
3744
3596
  type UpdateArg<T extends Query> = T['meta']['hasWhere'] extends true ? UpdateData<T> : never;
3745
3597
  type UpdateRawArgs<T extends Query> = T['meta']['hasWhere'] extends true ? [sql: Expression] | TemplateLiteralArgs : never;
3746
3598
  type UpdateResult<T extends Query> = T['meta']['hasSelect'] extends true ? SetQueryKind<T, 'update'> : SetQueryReturnsRowCount<SetQueryKind<T, 'update'>>;
@@ -5206,7 +5058,6 @@ type Query = QueryBase & QueryMethods<ColumnTypesBase> & {
5206
5058
  windows: EmptyObject;
5207
5059
  defaultSelectColumns: string[];
5208
5060
  relations: RelationsBase;
5209
- relationsQueries: Record<string, Query>;
5210
5061
  withData: WithDataBase;
5211
5062
  error: new (message: string, length: number, name: QueryErrorName) => QueryError;
5212
5063
  isSubQuery: boolean;
@@ -5260,7 +5111,7 @@ type SetQueryReturnsPluck<T extends Query, S extends keyof T['selectable'] | Exp
5260
5111
  catch: QueryCatch<C['outputType'][]>;
5261
5112
  };
5262
5113
  type SetQueryReturnsValueOptional<T extends Query, Arg extends GetStringArg<T>> = SetQueryReturnsValue<T, Arg, 'value'>;
5263
- type SetQueryReturnsValue<T extends Query, Arg extends GetStringArg<T>, ReturnType extends 'value' | 'valueOrThrow' = 'valueOrThrow'> = SetQueryReturnsColumn<T, Arg extends keyof T['selectable'] ? T['selectable'][Arg]['column'] : Arg extends RelationQueryBase ? Arg['result']['value'] : never, ReturnType>;
5114
+ type SetQueryReturnsValue<T extends Query, Arg extends GetStringArg<T>, ReturnType extends 'value' | 'valueOrThrow' = 'valueOrThrow'> = SetQueryReturnsColumn<T, Arg extends keyof T['selectable'] ? T['selectable'][Arg]['column'] : Arg extends Query ? Arg['result']['value'] : never, ReturnType>;
5264
5115
  type SetQueryReturnsColumnOptional<T extends QueryBase, Column extends ColumnTypeBase> = SetQueryReturnsColumn<T, Column, 'value'>;
5265
5116
  type SetQueryReturnsColumn<T extends QueryBase, Column extends ColumnTypeBase, ReturnType extends 'value' | 'valueOrThrow' = 'valueOrThrow', Data = ReturnType extends 'value' ? Column['outputType'] | undefined : Column['outputType']> = {
5266
5117
  [K in keyof T]: K extends 'meta' ? T['meta'] & {
@@ -6657,4 +6508,4 @@ declare const testTransaction: {
6657
6508
  close(arg: Arg): Promise<void>;
6658
6509
  };
6659
6510
 
6660
- export { Adapter, AdapterConfig, AdapterOptions, AddQuerySelect, AddQueryWith, AfterHook, AggregateMethods, AggregateOptions, AliasOrTable, ArrayColumn, ArrayData, ArrayOfColumnsObjects, AsMethods, BaseOperators, BaseRelation, BelongsToRelation, BigIntColumn, BigSerialColumn, BitColumn, BitVaryingColumn, BooleanColumn, BooleanNullable, BoxColumn, ByteaColumn, CharColumn, CidrColumn, CircleColumn, CitextColumn, Clear, ClearStatement, ColumnData, ColumnExpression, ColumnFromDbParams, ColumnInfo, ColumnInfoMethods, ColumnInfoQueryData, ColumnOperators, ColumnType, ColumnTypes, ColumnsObject, ColumnsShape, CommonQueryData, CopyMethods, CopyOptions, CopyQueryData, Create, CreateCtx, CreateData, CreateKind, CreateMethodsNames, CustomTypeColumn, DateBaseColumn, DateColumn, DateTimeBaseClass, DateTimeTzBaseClass, Db, DbOptions, DbResult, DbTableOptions, DecimalBaseColumn, DecimalColumn, DefaultColumnTypes, Delete, DeleteMethodsNames, DeleteQueryData, DomainColumn, DoublePrecisionColumn, DropMode, EnumColumn, ExpressionOutput, FnExpression, FnExpressionArg, For, ForeignKey, ForeignKeyAction, ForeignKeyMatch, ForeignKeyOptions, From, FromArgs, FromResult, GetArg, GetQueryResult, GetStringArg, HasAndBelongsToManyRelation, HasManyRelation, HasOneRelation, Having, HavingItem, HookAction, HookSelect, IdentityColumn, IndexColumnOptions, IndexOptions, InetColumn, InsertQueryData, IntegerBaseColumn, IntegerColumn, IntervalColumn, IsolationLevel, JSONColumn, JSONTextColumn, Join, JoinArgs, JoinCallback, JoinFirstArg, JoinItem, JoinLateralCallback, JoinLateralItem, JoinLateralResult, JoinOverrides, JoinResult, JoinedParsers, JoinedShapes, JsonItem, JsonMethods, JsonModifiers, LimitedTextBaseColumn, LineColumn, LsegColumn, MacAddr8Column, MacAddrColumn, MergeQuery, MergeQueryMethods, MoneyColumn, MoreThanOneRowError, NoPrimaryKeyOption, NotFoundError, NumberAsStringBaseColumn, NumberBaseColumn, NumberColumn, NumberColumnData, OnConflictItem, OnConflictMergeUpdate, OnConflictQueryBuilder, OnQueryBuilder, Operator, Operators, OrchidOrmError, OrchidOrmInternalError, OrderArg, OrderArgs, OrderItem, OrderTsQueryConfig, Over, PathColumn, PluckResultColumnType, PointColumn, PolygonColumn, Query, QueryAfterHook, QueryArraysResult, QueryBase, QueryBeforeHook, QueryData, QueryError, QueryErrorName, QueryGet, QueryHookSelect, QueryHooks, QueryLog, QueryLogObject, QueryLogOptions, QueryLogger, QueryMethods, QueryResult, QueryReturnType, QueryReturnsAll, QuerySourceItem, QueryTransform, QueryTransformFn, QueryUpsertOrCreate, QueryWithTable, RawSQL, RawSqlMethods, RealColumn, Relation, RelationQuery, RelationQueryBase, RelationQueryData, RelationSubQueries, RelationsBase, SearchArg, SearchMethods, SearchWeight, Select, SelectAggMethods, SelectArg, SelectItem, SelectQueryBuilder, SelectQueryData, Selectable, SelectableBase, SelectableFromShape, SelectableOfType, SelectableOrExpression, SelectableOrExpressionOfType, SerialColumn, SerialColumnData, SetQueryKind, SetQueryReturns, SetQueryReturnsAll, SetQueryReturnsColumn, SetQueryReturnsColumnInfo, SetQueryReturnsColumnOptional, SetQueryReturnsOne, SetQueryReturnsOneOptional, SetQueryReturnsPluck, SetQueryReturnsRowCount, SetQueryReturnsRows, SetQueryReturnsValue, SetQueryReturnsValueOptional, SetQueryReturnsVoid, SetQueryTableAlias, SetQueryWith, SimpleJoinItem, SingleColumnIndexOptions, SmallIntColumn, SmallSerialColumn, SortDir, StringColumn, SubQueryBuilder, TableData, TextBaseColumn, TextColumn, TextColumnData, Then, TimeColumn, TimeInterval, TimestampColumn, TimestampTZColumn, ToSQLCtx, ToSQLOptions, Transaction, TransactionAdapter, TransactionOptions, TransformMethods, TruncateQueryData, TsQueryColumn, TsVectorColumn, TypeParsers, UUIDColumn, UnhandledTypeError, Union, UnionArg, UnionItem, UnionKind, UnknownColumn, Update, UpdateCtx, UpdateData, UpdateQueryData, UpdateQueryDataItem, UpdateQueryDataObject, UpdatedAtDataInjector, UpsertCreateArg, UpsertData, UpsertResult, UpsertThis, VarCharColumn, VirtualColumn, Where, WhereArg, WhereArgs, WhereInArg, WhereInColumn, WhereInItem, WhereInValues, WhereItem, WhereJsonPathEqualsItem, WhereOnItem, WhereOnJoinItem, WhereQueryBase, WhereQueryBuilder, WhereResult, WhereSearchItem, WhereSearchResult, WindowArg, WindowArgDeclaration, WindowDeclaration, WindowItem, With, WithDataBase, WithDataItem, WithItem, WithOptions, XMLColumn, addOr, addOrNot, addParserForRawExpression, addParserForSelectItem, addQueryOn, addQueryOrOn, addWhere, addWhereIn, addWhereNot, anyShape, checkIfASimpleQuery, cloneQueryArrays, columnCheckToCode, columnCode, columnForeignKeysToCode, columnIndexesToCode, columnTypes, columnsByType, columnsShapeToCode, constraintPropsToCode, constraintToCode, createDb, createOperator, foreignKeyArgumentToCode, getClonedQueryData, getColumnTypes, getConstraintKind, getQueryAs, getShapeFromSelect, getSubQueryBuilder, getTableData, handleResult, identityToCode, indexToCode, instantiateColumn, isQueryReturnsAll, isRequiredRelationKey, isSelectingCount, joinSubQuery, logColors, logParamToLogObject, makeColumnFn, makeColumnFnClass, makeRegexToFindInSql, makeSQL, newTableData, parseRecord, parseResult, primaryKeyToCode, processSelectArg, pushQueryArray, pushQueryOn, pushQueryOrOn, pushQueryValue, queryMethodByReturnType, queryTypeWithLimitOne, quote, quoteString, raw, referencesArgsToCode, relationQueryKey, resetTableData, resolveSubQueryCallback, saveSearchAlias, setQueryObjectValue, simplifyColumnDefault, templateLiteralToSQL, testTransaction, throwIfNoWhere, toSQL, toSQLCacheKey };
6511
+ export { Adapter, AdapterConfig, AdapterOptions, AddQuerySelect, AddQueryWith, AfterHook, AggregateMethods, AggregateOptions, AliasOrTable, ArrayColumn, ArrayData, ArrayOfColumnsObjects, AsMethods, BaseOperators, BigIntColumn, BigSerialColumn, BitColumn, BitVaryingColumn, BooleanColumn, BooleanNullable, BoxColumn, ByteaColumn, CharColumn, CidrColumn, CircleColumn, CitextColumn, Clear, ClearStatement, ColumnData, ColumnExpression, ColumnFromDbParams, ColumnInfo, ColumnInfoMethods, ColumnInfoQueryData, ColumnOperators, ColumnType, ColumnTypes, ColumnsObject, ColumnsShape, CommonQueryData, CopyMethods, CopyOptions, CopyQueryData, Create, CreateCtx, CreateData, CreateKind, CreateMethodsNames, CustomTypeColumn, DateBaseColumn, DateColumn, DateTimeBaseClass, DateTimeTzBaseClass, Db, DbOptions, DbResult, DbTableOptions, DecimalBaseColumn, DecimalColumn, DefaultColumnTypes, Delete, DeleteMethodsNames, DeleteQueryData, DomainColumn, DoublePrecisionColumn, DropMode, EnumColumn, ExpressionOutput, FnExpression, FnExpressionArg, For, ForeignKey, ForeignKeyAction, ForeignKeyMatch, ForeignKeyOptions, From, FromArgs, FromResult, GetArg, GetQueryResult, GetStringArg, Having, HavingItem, HookAction, HookSelect, IdentityColumn, IndexColumnOptions, IndexOptions, InetColumn, InsertQueryData, IntegerBaseColumn, IntegerColumn, IntervalColumn, IsolationLevel, JSONColumn, JSONTextColumn, Join, JoinArgs, JoinCallback, JoinFirstArg, JoinItem, JoinLateralCallback, JoinLateralItem, JoinLateralResult, JoinOverrides, JoinResult, JoinedParsers, JoinedShapes, JsonItem, JsonMethods, JsonModifiers, LimitedTextBaseColumn, LineColumn, LsegColumn, MacAddr8Column, MacAddrColumn, MergeQuery, MergeQueryMethods, MoneyColumn, MoreThanOneRowError, NoPrimaryKeyOption, NotFoundError, NumberAsStringBaseColumn, NumberBaseColumn, NumberColumn, NumberColumnData, OnConflictItem, OnConflictMergeUpdate, OnConflictQueryBuilder, OnQueryBuilder, Operator, Operators, OrchidOrmError, OrchidOrmInternalError, OrderArg, OrderArgs, OrderItem, OrderTsQueryConfig, Over, PathColumn, PluckResultColumnType, PointColumn, PolygonColumn, Query, QueryAfterHook, QueryArraysResult, QueryBase, QueryBeforeHook, QueryData, QueryError, QueryErrorName, QueryGet, QueryHookSelect, QueryHooks, QueryLog, QueryLogObject, QueryLogOptions, QueryLogger, QueryMethods, QueryResult, QueryReturnType, QueryReturnsAll, QuerySourceItem, QueryTransform, QueryTransformFn, QueryUpsertOrCreate, QueryWithTable, RawSQL, RawSqlMethods, RealColumn, RelationConfigBase, RelationQuery, RelationQueryBase, RelationSubQueries, RelationsBase, SearchArg, SearchMethods, SearchWeight, Select, SelectAggMethods, SelectArg, SelectItem, SelectQueryBuilder, SelectQueryData, Selectable, SelectableBase, SelectableFromShape, SelectableOfType, SelectableOrExpression, SelectableOrExpressionOfType, SerialColumn, SerialColumnData, SetQueryKind, SetQueryReturns, SetQueryReturnsAll, SetQueryReturnsColumn, SetQueryReturnsColumnInfo, SetQueryReturnsColumnOptional, SetQueryReturnsOne, SetQueryReturnsOneOptional, SetQueryReturnsPluck, SetQueryReturnsRowCount, SetQueryReturnsRows, SetQueryReturnsValue, SetQueryReturnsValueOptional, SetQueryReturnsVoid, SetQueryTableAlias, SetQueryWith, SimpleJoinItem, SingleColumnIndexOptions, SmallIntColumn, SmallSerialColumn, SortDir, StringColumn, SubQueryBuilder, TableData, TextBaseColumn, TextColumn, TextColumnData, Then, TimeColumn, TimeInterval, TimestampColumn, TimestampTZColumn, ToSQLCtx, ToSQLOptions, Transaction, TransactionAdapter, TransactionOptions, TransformMethods, TruncateQueryData, TsQueryColumn, TsVectorColumn, TypeParsers, UUIDColumn, UnhandledTypeError, Union, UnionArg, UnionItem, UnionKind, UnknownColumn, Update, UpdateCtx, UpdateData, UpdateQueryData, UpdateQueryDataItem, UpdateQueryDataObject, UpdatedAtDataInjector, UpsertCreateArg, UpsertData, UpsertResult, UpsertThis, VarCharColumn, VirtualColumn, Where, WhereArg, WhereArgs, WhereInArg, WhereInColumn, WhereInItem, WhereInValues, WhereItem, WhereJsonPathEqualsItem, WhereOnItem, WhereOnJoinItem, WhereQueryBase, WhereQueryBuilder, WhereResult, WhereSearchItem, WhereSearchResult, WindowArg, WindowArgDeclaration, WindowDeclaration, WindowItem, With, WithDataBase, WithDataItem, WithItem, WithOptions, XMLColumn, addOr, addOrNot, addParserForRawExpression, addParserForSelectItem, addQueryOn, addQueryOrOn, addWhere, addWhereIn, addWhereNot, anyShape, checkIfASimpleQuery, cloneQueryArrays, columnCheckToCode, columnCode, columnForeignKeysToCode, columnIndexesToCode, columnTypes, columnsByType, columnsShapeToCode, constraintPropsToCode, constraintToCode, createDb, createOperator, foreignKeyArgumentToCode, getClonedQueryData, getColumnTypes, getConstraintKind, getQueryAs, getShapeFromSelect, getSubQueryBuilder, getTableData, handleResult, identityToCode, indexToCode, instantiateColumn, isQueryReturnsAll, isSelectingCount, joinSubQuery, logColors, logParamToLogObject, makeColumnFn, makeColumnFnClass, makeRegexToFindInSql, makeSQL, newTableData, parseRecord, parseResult, primaryKeyToCode, processSelectArg, pushQueryArray, pushQueryOn, pushQueryOrOn, pushQueryValue, queryMethodByReturnType, queryTypeWithLimitOne, quote, quoteString, raw, referencesArgsToCode, resetTableData, resolveSubQueryCallback, saveSearchAlias, setQueryObjectValue, simplifyColumnDefault, templateLiteralToSQL, testTransaction, throwIfNoWhere, toSQL, toSQLCacheKey };