pqb 0.30.5 → 0.30.6
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 +94 -5
- package/dist/index.js +207 -39
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +208 -40
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as orchid_core from 'orchid-core';
|
|
2
|
-
import { QueryResultRow, AdapterConfigBase, AdapterBase, QueryInput, Sql, RecordUnknown, RecordKeyTrue, EmptyObject, QueryBaseCommon, QueryColumns, QueryMetaBase, QueryReturnType, QueryThen, Expression, QueryColumn, MaybeArray, SelectableBase, TemplateLiteralArgs, PickOutputTypeAndOperators, PickQueryResult, OperatorToSQL, ColumnsShapeBase, ColumnsParsers, RecordString, PickQueryTable, FnUnknownToUnknown, ExpressionChain, getValueKey, PickQueryShape, PickQueryTableMetaResult, EmptyTuple, PickQueryMeta, PickQueryMetaResultReturnType, QueryColumnToNullable, PickQueryMetaShape, PickQueryTableMetaResultShape, PickQueryMetaResultWindows, QueryColumnBooleanOrNull, ExpressionData, ValExpression, PickOutputType, SQLQueryArgs, ColumnSchemaConfig, DateColumnData, Code, TimeInterval, ColumnTypeSchemaArg, ColumnDataBase, ArrayMethodsData, RawSQLBase, RawSQLValues, ExpressionTypeMethod, DynamicSQLArg, StaticSQLArgs, ForeignKeyTable, ColumnNameOfTable, BaseNumberData, PickColumnBaseData, ColumnWithDefault, StringTypeData, PrimaryKeyColumn, ParseColumn, EncodeColumn, PickQueryMetaResult, QueryColumnsInit, DefaultSelectColumns, CoreQueryScopes, DbBase, QueryCatch, TransactionState, ColumnTypeBase, CoreBaseOperators, PickQueryUniqueProperties, IsQuery, PickQueryMetaShapeResultReturnType, MergeObjects, PickQueryResultUniqueColumns, QueryInternalBase, PickQueryReturnType, PickType, ColumnShapeOutput, PickQueryMetaReturnType, UniqueColumn, TimestampHelpers, Codes, ColumnDataCheckBase, PickQueryTableMetaShape } from 'orchid-core';
|
|
2
|
+
import { QueryResultRow, AdapterConfigBase, AdapterBase, QueryInput, Sql, RecordUnknown, RecordKeyTrue, EmptyObject, QueryBaseCommon, QueryColumns, QueryMetaBase, QueryReturnType, QueryThen, Expression, QueryColumn, MaybeArray, SelectableBase, TemplateLiteralArgs, PickOutputTypeAndOperators, PickQueryResult, OperatorToSQL, ColumnsShapeBase, ColumnsParsers, RecordString, PickQueryTable, FnUnknownToUnknown, ExpressionChain, getValueKey, PickQueryShape, PickQueryTableMetaResult, EmptyTuple, PickQueryMeta, PickQueryMetaResultReturnType, QueryColumnToNullable, PickQueryMetaShape, PickQueryTableMetaResultShape, PickQueryMetaResultWindows, QueryColumnBooleanOrNull, ExpressionData, ValExpression, PickOutputType, SQLQueryArgs, ColumnSchemaConfig, DateColumnData, Code, TimeInterval, ColumnTypeSchemaArg, ColumnDataBase, ArrayMethodsData, RawSQLBase, RawSQLValues, ExpressionTypeMethod, DynamicSQLArg, StaticSQLArgs, ForeignKeyTable, ColumnNameOfTable, BaseNumberData, PickColumnBaseData, ColumnWithDefault, StringTypeData, PrimaryKeyColumn, ParseColumn, EncodeColumn, PickQueryMetaResult, QueryColumnsInit, DefaultSelectColumns, CoreQueryScopes, DbBase, QueryCatch, TransactionState, ColumnTypeBase, CoreBaseOperators, PickQueryUniqueProperties, IsQuery, PickQueryMetaShapeResultReturnType, MergeObjects, PickQueryResultUniqueColumns, QueryInternalBase, PickQueryReturnType, PickType, ColumnShapeOutput, OperatorsNullable, PickQueryMetaReturnType, UniqueColumn, TimestampHelpers, Codes, ColumnDataCheckBase, PickQueryTableMetaShape } from 'orchid-core';
|
|
3
3
|
import { PoolConfig, Pool, PoolClient } from 'pg';
|
|
4
4
|
import { inspect } from 'node:util';
|
|
5
5
|
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
@@ -2155,6 +2155,15 @@ declare class Where {
|
|
|
2155
2155
|
* ```ts
|
|
2156
2156
|
* db.table.whereIn(['id', 'name'], sql`((1, 'one'), (2, 'two'))`);
|
|
2157
2157
|
* ```
|
|
2158
|
+
*
|
|
2159
|
+
* When empty set of values is given, `whereIn` will resolve into a {@link QueryMethods.none} query that has a special behavior.
|
|
2160
|
+
*
|
|
2161
|
+
* ```ts
|
|
2162
|
+
* // following queries resolves into `none`:
|
|
2163
|
+
* db.table.where('id', [])
|
|
2164
|
+
* db.table.where(['id', 'name'], [])
|
|
2165
|
+
* db.table.where({ id: [] })
|
|
2166
|
+
* ```
|
|
2158
2167
|
*/
|
|
2159
2168
|
whereIn<T extends PickQueryMetaRelations, Column extends WhereInColumn<T>>(this: T, ...args: [column: Column, values: WhereInValues<T, Column>] | [arg: WhereInArg<T>]): WhereResult<T>;
|
|
2160
2169
|
/**
|
|
@@ -4124,6 +4133,7 @@ declare class Create {
|
|
|
4124
4133
|
* db.table.create(data).onConflictDoNothing();
|
|
4125
4134
|
*
|
|
4126
4135
|
* // single column:
|
|
4136
|
+
* // (this requires a composite primary key or unique index, see below)
|
|
4127
4137
|
* db.table.create(data).onConfict('email').merge();
|
|
4128
4138
|
*
|
|
4129
4139
|
* // array of columns:
|
|
@@ -4139,6 +4149,34 @@ declare class Create {
|
|
|
4139
4149
|
* .merge();
|
|
4140
4150
|
* ```
|
|
4141
4151
|
*
|
|
4152
|
+
* :::info
|
|
4153
|
+
* A primary key or a unique index for a **single** column can be fined on a column:
|
|
4154
|
+
*
|
|
4155
|
+
* ```ts
|
|
4156
|
+
* export class MyTable extends BaseTable {
|
|
4157
|
+
* columns = this.setColumns((t) => ({
|
|
4158
|
+
* pkey: t.uuid().primaryKey(),
|
|
4159
|
+
* unique: t.string().unique(),
|
|
4160
|
+
* }));
|
|
4161
|
+
* }
|
|
4162
|
+
* ```
|
|
4163
|
+
*
|
|
4164
|
+
* But for composite primary keys or indexes (having multiple columns), define it in a separate function:
|
|
4165
|
+
*
|
|
4166
|
+
* ```ts
|
|
4167
|
+
* export class MyTable extends BaseTable {
|
|
4168
|
+
* columns = this.setColumns(
|
|
4169
|
+
* (t) => ({
|
|
4170
|
+
* one: t.integer(),
|
|
4171
|
+
* two: t.string(),
|
|
4172
|
+
* three: t.boolean(),
|
|
4173
|
+
* }),
|
|
4174
|
+
* (t) => [t.primaryKey(['one', 'two']), t.unique(['two', 'three'])],
|
|
4175
|
+
* );
|
|
4176
|
+
* }
|
|
4177
|
+
* ```
|
|
4178
|
+
* :::
|
|
4179
|
+
*
|
|
4142
4180
|
* You can use the `sql` function exported from your `BaseTable` file in onConflict.
|
|
4143
4181
|
* It can be useful to specify a condition when you have a partial index:
|
|
4144
4182
|
*
|
|
@@ -4963,10 +5001,10 @@ type SelectAsSelectable<Arg> = {
|
|
|
4963
5001
|
} : never;
|
|
4964
5002
|
}[keyof Arg];
|
|
4965
5003
|
type SelectAsValueResult<T extends SelectSelf, Arg> = Arg extends keyof T['meta']['selectable'] ? T['meta']['selectable'][Arg]['column'] : Arg extends Expression ? Arg['result']['value'] : Arg extends (q: never) => QueryBase ? SelectSubQueryResult<ReturnType<Arg>> : Arg extends (q: never) => Expression ? ReturnType<Arg>['result']['value'] : Arg extends (q: never) => QueryBase | Expression ? SelectSubQueryResult<Exclude<ReturnType<Arg>, Expression>> | Exclude<ReturnType<Arg>, QueryBase>['result']['value'] : never;
|
|
4966
|
-
type SelectSubQueryResult<Arg extends SelectSelf> = QueryReturnsAll<Arg['returnType']> extends true ? ColumnsShapeToObjectArray<Arg['result']> : Arg['returnType'] extends 'valueOrThrow' ? Arg['result']['value'] : Arg['returnType'] extends 'pluck' ? ColumnsShapeToPluck<Arg['result']> : Arg['returnType'] extends 'one' ? ColumnsShapeToNullableObject<Arg['result']> : ColumnsShapeToObject<Arg['result']>;
|
|
5004
|
+
type SelectSubQueryResult<Arg extends SelectSelf> = QueryReturnsAll<Arg['returnType']> extends true ? ColumnsShapeToObjectArray<Arg['result']> : Arg['returnType'] extends 'value' | 'valueOrThrow' ? Arg['result']['value'] : Arg['returnType'] extends 'pluck' ? ColumnsShapeToPluck<Arg['result']> : Arg['returnType'] extends 'one' ? ColumnsShapeToNullableObject<Arg['result']> : ColumnsShapeToObject<Arg['result']>;
|
|
4967
5005
|
declare const addParserForRawExpression: (q: PickQueryQ, key: string | getValueKey, raw: Expression) => void;
|
|
4968
5006
|
declare const addParserForSelectItem: <T extends PickQueryMeta>(q: T, as: string | getValueKey | undefined, key: string, arg: SelectableOrExpression<T> | Query) => string | Expression | Query;
|
|
4969
|
-
declare const processSelectArg: <T extends SelectSelf>(q: T, as: string | undefined, arg: SelectArg<T>, columnAs?: string | getValueKey) => SelectItem;
|
|
5007
|
+
declare const processSelectArg: <T extends SelectSelf>(q: T, as: string | undefined, arg: SelectArg<T>, columnAs?: string | getValueKey) => SelectItem | undefined;
|
|
4970
5008
|
declare const setParserForSelectedString: (q: PickQueryQ, arg: string, as: string | getValueKey | undefined, columnAs?: string | getValueKey) => string;
|
|
4971
5009
|
declare const getShapeFromSelect: (q: QueryBase, isSubQuery?: boolean) => QueryColumns;
|
|
4972
5010
|
declare function _querySelect<T extends SelectSelf, Columns extends SelectArg<T>[]>(q: T, columns: Columns): SelectResult<T, Columns>;
|
|
@@ -6620,6 +6658,55 @@ declare class QueryMethods<ColumnTypes> {
|
|
|
6620
6658
|
* await db.table.all().update(data); // -> 0
|
|
6621
6659
|
* await db.table.all().delete(); // -> 0
|
|
6622
6660
|
* ```
|
|
6661
|
+
*
|
|
6662
|
+
* When it's being used in sub-selects, it will return empty arrays, `undefined`'s, or `0` for count,
|
|
6663
|
+
* or it will throw if the sub-query require a result:
|
|
6664
|
+
*
|
|
6665
|
+
* ```ts
|
|
6666
|
+
* await db.user.select({
|
|
6667
|
+
* // returns empty array
|
|
6668
|
+
* pets: (q) => q.pets.none(),
|
|
6669
|
+
* // returns `undefined`
|
|
6670
|
+
* firstPet: (q) => q.pets.none().takeOptional(),
|
|
6671
|
+
* // throws NotFound error
|
|
6672
|
+
* requriedFirstPet: (q) => q.pets.none().take(),
|
|
6673
|
+
* // returns `undefined`
|
|
6674
|
+
* firstPetName: (q) => q.pets.none().getOptional('name'),
|
|
6675
|
+
* // throws NotFound error
|
|
6676
|
+
* requiredFirstPetName: (q) => q.pets.none().get('name'),
|
|
6677
|
+
* // returns empty array
|
|
6678
|
+
* petsNames: (q) => q.pets.none().pluck('name'),
|
|
6679
|
+
* // returns 0
|
|
6680
|
+
* petsCount: (q) => q.pets.none().count(),
|
|
6681
|
+
* });
|
|
6682
|
+
* ```
|
|
6683
|
+
*
|
|
6684
|
+
* When the `none` query is being used for joins that require match, the host query will return an empty result:
|
|
6685
|
+
*
|
|
6686
|
+
* ```ts
|
|
6687
|
+
* // all the following queries will resolve into empty arrays
|
|
6688
|
+
*
|
|
6689
|
+
* await db.user.select({
|
|
6690
|
+
* pets: (q) => q.pets.join().none(),
|
|
6691
|
+
* });
|
|
6692
|
+
*
|
|
6693
|
+
* await db.user.join(
|
|
6694
|
+
* (q) => q.pets.none(),
|
|
6695
|
+
* (q) => q,
|
|
6696
|
+
* );
|
|
6697
|
+
*
|
|
6698
|
+
* await db.user.join('pets', (q) => q.none());
|
|
6699
|
+
* ```
|
|
6700
|
+
*
|
|
6701
|
+
* When it's being used in `leftJoin` or `fullJoin`, it implicitly adds `ON false` into the join's SQL.
|
|
6702
|
+
*
|
|
6703
|
+
* ```ts
|
|
6704
|
+
* // this query can return user records
|
|
6705
|
+
* await db.user.leftJoin('pets', (q) => q.none());
|
|
6706
|
+
*
|
|
6707
|
+
* // this query won't return user records, because of the added where condition
|
|
6708
|
+
* await db.user.leftJoin('pets', (q) => q.none()).where({ 'pets.name': 'Kitty' });
|
|
6709
|
+
* ```
|
|
6623
6710
|
*/
|
|
6624
6711
|
none<T>(this: T): T;
|
|
6625
6712
|
/**
|
|
@@ -6967,7 +7054,9 @@ type SetQueryReturnsPluckColumnKindResult<T extends PickQueryMetaResult, Kind ex
|
|
|
6967
7054
|
} : K extends 'returnType' ? 'pluck' : K extends 'result' ? Result : K extends 'then' ? QueryThen<T['result']['value']['outputType'][]> : T[K];
|
|
6968
7055
|
} & QueryMetaHasSelect;
|
|
6969
7056
|
type SetQueryReturnsValueOrThrow<T extends PickQueryMeta, Arg extends GetStringArg<T>> = SetQueryReturnsColumnOrThrow<T, T['meta']['selectable'][Arg]['column']> & T['meta']['selectable'][Arg]['column']['operators'];
|
|
6970
|
-
type SetQueryReturnsValueOptional<T extends PickQueryMeta, Arg extends GetStringArg<T>> = SetQueryReturnsColumnOptional<T,
|
|
7057
|
+
type SetQueryReturnsValueOptional<T extends PickQueryMeta, Arg extends GetStringArg<T>> = SetQueryReturnsColumnOptional<T, {
|
|
7058
|
+
[K in keyof T['meta']['selectable'][Arg]['column']]: K extends 'outputType' ? T['meta']['selectable'][Arg]['column'][K] | undefined : T['meta']['selectable'][Arg]['column'][K];
|
|
7059
|
+
}> & Omit<T['meta']['selectable'][Arg]['column']['operators'], 'equals' | 'not'> & OperatorsNullable<T['meta']['selectable'][Arg]['column']>;
|
|
6971
7060
|
type SetQueryReturnsColumnOrThrow<T, Column extends PickOutputType> = {
|
|
6972
7061
|
[K in keyof T]: K extends 'result' ? {
|
|
6973
7062
|
value: Column;
|
|
@@ -7444,7 +7533,7 @@ interface ColumnsShapeToObject<Shape extends QueryColumns> {
|
|
|
7444
7533
|
interface ColumnsShapeToNullableObject<Shape extends QueryColumns> {
|
|
7445
7534
|
dataType: 'object';
|
|
7446
7535
|
type: ObjectType<Shape>;
|
|
7447
|
-
outputType: ObjectOutput<Shape> |
|
|
7536
|
+
outputType: ObjectOutput<Shape> | undefined;
|
|
7448
7537
|
queryType: ObjectQuery<Shape> | null;
|
|
7449
7538
|
operators: OperatorsAny;
|
|
7450
7539
|
}
|
package/dist/index.js
CHANGED
|
@@ -2593,6 +2593,32 @@ const makeJoinQueryBuilder = (joinedQuery, joinedShapes, joinTo) => {
|
|
|
2593
2593
|
return q;
|
|
2594
2594
|
};
|
|
2595
2595
|
|
|
2596
|
+
const noneMethods = {
|
|
2597
|
+
// `then` resolves or rejects based on return type of the query.
|
|
2598
|
+
// It is `async` so it returns a chainable Promise.
|
|
2599
|
+
async then(resolve, reject) {
|
|
2600
|
+
const type = this.q.returnType;
|
|
2601
|
+
if (!type || type === "all" || type === "rows" || type === "pluck")
|
|
2602
|
+
resolve == null ? void 0 : resolve([]);
|
|
2603
|
+
else if (type === "one" || type === "value" || type === "void")
|
|
2604
|
+
resolve == null ? void 0 : resolve();
|
|
2605
|
+
else if (type === "rowCount")
|
|
2606
|
+
resolve == null ? void 0 : resolve(0);
|
|
2607
|
+
else
|
|
2608
|
+
reject == null ? void 0 : reject(new NotFoundError(this));
|
|
2609
|
+
},
|
|
2610
|
+
// `catch` returns a Promise, so it is chainable with then/catch.
|
|
2611
|
+
catch: () => new Promise(orchidCore.noop)
|
|
2612
|
+
};
|
|
2613
|
+
const _queryNone = (q) => {
|
|
2614
|
+
if (isQueryNone(q))
|
|
2615
|
+
return q;
|
|
2616
|
+
q = extendQuery(q, noneMethods);
|
|
2617
|
+
pushQueryValue(q, "and", new RawSQL("false"));
|
|
2618
|
+
return q;
|
|
2619
|
+
};
|
|
2620
|
+
const isQueryNone = (q) => q.then === noneMethods.then;
|
|
2621
|
+
|
|
2596
2622
|
var __defProp$b = Object.defineProperty;
|
|
2597
2623
|
var __defProps$3 = Object.defineProperties;
|
|
2598
2624
|
var __getOwnPropDescs$3 = Object.getOwnPropertyDescriptors;
|
|
@@ -2612,36 +2638,39 @@ var __spreadValues$b = (a, b) => {
|
|
|
2612
2638
|
return a;
|
|
2613
2639
|
};
|
|
2614
2640
|
var __spreadProps$3 = (a, b) => __defProps$3(a, __getOwnPropDescs$3(b));
|
|
2615
|
-
const _join = (
|
|
2641
|
+
const _join = (query, require2, type, first, args) => {
|
|
2616
2642
|
var _a, _b;
|
|
2617
2643
|
let joinKey;
|
|
2618
2644
|
let shape;
|
|
2619
2645
|
let parsers;
|
|
2620
2646
|
let joinSubQuery = false;
|
|
2621
2647
|
if (typeof first === "function") {
|
|
2622
|
-
first = first(
|
|
2648
|
+
first = first(query.relations);
|
|
2623
2649
|
first.joinQueryAfterCallback = first.joinQuery;
|
|
2624
2650
|
}
|
|
2625
2651
|
if (typeof first === "object") {
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2652
|
+
if (require2 && isQueryNone(first)) {
|
|
2653
|
+
return _queryNone(query);
|
|
2654
|
+
}
|
|
2655
|
+
const q = first;
|
|
2656
|
+
joinSubQuery = getIsJoinSubQuery(q);
|
|
2657
|
+
joinKey = q.q.as || q.table;
|
|
2629
2658
|
if (joinKey) {
|
|
2630
|
-
shape = getShapeFromSelect(
|
|
2631
|
-
parsers =
|
|
2659
|
+
shape = getShapeFromSelect(q, joinSubQuery);
|
|
2660
|
+
parsers = q.q.parsers;
|
|
2632
2661
|
if (joinSubQuery) {
|
|
2633
|
-
first =
|
|
2662
|
+
first = q.clone();
|
|
2634
2663
|
first.shape = shape;
|
|
2635
2664
|
}
|
|
2636
2665
|
}
|
|
2637
2666
|
} else {
|
|
2638
2667
|
joinKey = first;
|
|
2639
|
-
const relation =
|
|
2668
|
+
const relation = query.relations[joinKey];
|
|
2640
2669
|
if (relation) {
|
|
2641
2670
|
shape = getShapeFromSelect(relation.relationConfig.query);
|
|
2642
2671
|
parsers = relation.relationConfig.query.q.parsers;
|
|
2643
2672
|
} else {
|
|
2644
|
-
shape = (_a =
|
|
2673
|
+
shape = (_a = query.q.withShapes) == null ? void 0 : _a[joinKey];
|
|
2645
2674
|
if (shape) {
|
|
2646
2675
|
if (!require2)
|
|
2647
2676
|
shape = __spreadValues$b({}, shape);
|
|
@@ -2657,20 +2686,20 @@ const _join = (q, require2, type, first, args) => {
|
|
|
2657
2686
|
}
|
|
2658
2687
|
if (joinKey) {
|
|
2659
2688
|
setQueryObjectValue(
|
|
2660
|
-
|
|
2689
|
+
query,
|
|
2661
2690
|
"joinedShapes",
|
|
2662
2691
|
joinKey,
|
|
2663
2692
|
shape
|
|
2664
2693
|
);
|
|
2665
2694
|
setQueryObjectValue(
|
|
2666
|
-
|
|
2695
|
+
query,
|
|
2667
2696
|
"joinedParsers",
|
|
2668
2697
|
joinKey,
|
|
2669
2698
|
parsers
|
|
2670
2699
|
);
|
|
2671
2700
|
}
|
|
2672
2701
|
const joinArgs = processJoinArgs(
|
|
2673
|
-
|
|
2702
|
+
query,
|
|
2674
2703
|
first,
|
|
2675
2704
|
args,
|
|
2676
2705
|
joinSubQuery
|
|
@@ -2680,20 +2709,22 @@ const _join = (q, require2, type, first, args) => {
|
|
|
2680
2709
|
if (j.q.select || !j.internal.columnsForSelectAll) {
|
|
2681
2710
|
const shape2 = getShapeFromSelect(j, true);
|
|
2682
2711
|
setQueryObjectValue(
|
|
2683
|
-
|
|
2712
|
+
query,
|
|
2684
2713
|
"joinedShapes",
|
|
2685
2714
|
joinKey,
|
|
2686
2715
|
shape2
|
|
2687
2716
|
);
|
|
2688
2717
|
setQueryObjectValue(
|
|
2689
|
-
|
|
2718
|
+
query,
|
|
2690
2719
|
"joinedParsers",
|
|
2691
2720
|
joinKey,
|
|
2692
2721
|
j.q.parsers
|
|
2693
2722
|
);
|
|
2694
2723
|
}
|
|
2724
|
+
} else if (require2 && "r" in joinArgs && isQueryNone(joinArgs.r)) {
|
|
2725
|
+
return _queryNone(query);
|
|
2695
2726
|
}
|
|
2696
|
-
return pushQueryValue(
|
|
2727
|
+
return pushQueryValue(query, "join", {
|
|
2697
2728
|
type,
|
|
2698
2729
|
args: joinArgs
|
|
2699
2730
|
});
|
|
@@ -3328,6 +3359,26 @@ const addParserForSelectItem = (q, as, key, arg) => {
|
|
|
3328
3359
|
);
|
|
3329
3360
|
});
|
|
3330
3361
|
}
|
|
3362
|
+
if (query.returnType === "valueOrThrow" || query.returnType === "oneOrThrow") {
|
|
3363
|
+
pushQueryValue(
|
|
3364
|
+
q,
|
|
3365
|
+
"transform",
|
|
3366
|
+
(data) => {
|
|
3367
|
+
if (Array.isArray(data)) {
|
|
3368
|
+
for (const item of data) {
|
|
3369
|
+
if (item[key] === void 0) {
|
|
3370
|
+
throw new NotFoundError(q);
|
|
3371
|
+
}
|
|
3372
|
+
}
|
|
3373
|
+
} else {
|
|
3374
|
+
if (data[key] === void 0) {
|
|
3375
|
+
throw new NotFoundError(q);
|
|
3376
|
+
}
|
|
3377
|
+
}
|
|
3378
|
+
return data;
|
|
3379
|
+
}
|
|
3380
|
+
);
|
|
3381
|
+
}
|
|
3331
3382
|
}
|
|
3332
3383
|
return arg;
|
|
3333
3384
|
}
|
|
@@ -3344,7 +3395,11 @@ const processSelectArg = (q, as, arg, columnAs) => {
|
|
|
3344
3395
|
let value = arg[key];
|
|
3345
3396
|
if (typeof value === "function") {
|
|
3346
3397
|
value = resolveSubQueryCallback(q, value);
|
|
3347
|
-
if (
|
|
3398
|
+
if (isQueryNone(value)) {
|
|
3399
|
+
if (value.q.innerJoinLateral) {
|
|
3400
|
+
return;
|
|
3401
|
+
}
|
|
3402
|
+
} else if (!orchidCore.isExpression(value) && value.joinQuery) {
|
|
3348
3403
|
value = value.joinQuery(value, q);
|
|
3349
3404
|
let query;
|
|
3350
3405
|
const returnType = value.q.returnType;
|
|
@@ -3501,11 +3556,18 @@ const maybeUnNameColumn = (column, isSubQuery) => {
|
|
|
3501
3556
|
return isSubQuery && (column == null ? void 0 : column.data.name) ? orchidCore.setColumnData(column, "name", void 0) : column;
|
|
3502
3557
|
};
|
|
3503
3558
|
function _querySelect(q, args) {
|
|
3504
|
-
|
|
3559
|
+
const len = args.length;
|
|
3560
|
+
if (!len) {
|
|
3505
3561
|
return q;
|
|
3506
3562
|
}
|
|
3507
3563
|
const as = q.q.as || q.table;
|
|
3508
|
-
const selectArgs =
|
|
3564
|
+
const selectArgs = new Array(len);
|
|
3565
|
+
for (let i = 0; i < len; i++) {
|
|
3566
|
+
selectArgs[i] = processSelectArg(q, as, args[i]);
|
|
3567
|
+
if (!selectArgs[i]) {
|
|
3568
|
+
return _queryNone(q);
|
|
3569
|
+
}
|
|
3570
|
+
}
|
|
3509
3571
|
return pushQueryArray(q, "select", selectArgs);
|
|
3510
3572
|
}
|
|
3511
3573
|
class Select {
|
|
@@ -3855,7 +3917,37 @@ const selectAllSql = (table, query, quotedAs) => {
|
|
|
3855
3917
|
return ((_a = query.join) == null ? void 0 : _a.length) ? ((_b = table.internal.columnsForSelectAll) == null ? void 0 : _b.map((item) => `${quotedAs}.${item}`).join(", ")) || `${quotedAs}.*` : ((_c = table.internal.columnsForSelectAll) == null ? void 0 : _c.join(", ")) || "*";
|
|
3856
3918
|
};
|
|
3857
3919
|
const pushSubQuerySql = (ctx, query, as, list, quotedAs) => {
|
|
3920
|
+
var _a;
|
|
3858
3921
|
const { returnType = "all" } = query.q;
|
|
3922
|
+
if (isQueryNone(query)) {
|
|
3923
|
+
let sql;
|
|
3924
|
+
switch (returnType) {
|
|
3925
|
+
case "one":
|
|
3926
|
+
case "oneOrThrow":
|
|
3927
|
+
case "void":
|
|
3928
|
+
return;
|
|
3929
|
+
case "value":
|
|
3930
|
+
case "valueOrThrow":
|
|
3931
|
+
if (((_a = query.q.expr) == null ? void 0 : _a.result.value) instanceof IntegerBaseColumn) {
|
|
3932
|
+
sql = "0";
|
|
3933
|
+
} else {
|
|
3934
|
+
return;
|
|
3935
|
+
}
|
|
3936
|
+
break;
|
|
3937
|
+
case "all":
|
|
3938
|
+
case "pluck":
|
|
3939
|
+
case "rows":
|
|
3940
|
+
sql = `'[]'::json`;
|
|
3941
|
+
break;
|
|
3942
|
+
case "rowCount":
|
|
3943
|
+
sql = "0";
|
|
3944
|
+
break;
|
|
3945
|
+
default:
|
|
3946
|
+
throw new UnhandledTypeError(query, returnType);
|
|
3947
|
+
}
|
|
3948
|
+
list.push(`${sql} "${as}"`);
|
|
3949
|
+
return;
|
|
3950
|
+
}
|
|
3859
3951
|
if (query.q.joinedForSelect) {
|
|
3860
3952
|
let sql;
|
|
3861
3953
|
switch (returnType) {
|
|
@@ -6509,6 +6601,7 @@ class Create {
|
|
|
6509
6601
|
* db.table.create(data).onConflictDoNothing();
|
|
6510
6602
|
*
|
|
6511
6603
|
* // single column:
|
|
6604
|
+
* // (this requires a composite primary key or unique index, see below)
|
|
6512
6605
|
* db.table.create(data).onConfict('email').merge();
|
|
6513
6606
|
*
|
|
6514
6607
|
* // array of columns:
|
|
@@ -6524,6 +6617,34 @@ class Create {
|
|
|
6524
6617
|
* .merge();
|
|
6525
6618
|
* ```
|
|
6526
6619
|
*
|
|
6620
|
+
* :::info
|
|
6621
|
+
* A primary key or a unique index for a **single** column can be fined on a column:
|
|
6622
|
+
*
|
|
6623
|
+
* ```ts
|
|
6624
|
+
* export class MyTable extends BaseTable {
|
|
6625
|
+
* columns = this.setColumns((t) => ({
|
|
6626
|
+
* pkey: t.uuid().primaryKey(),
|
|
6627
|
+
* unique: t.string().unique(),
|
|
6628
|
+
* }));
|
|
6629
|
+
* }
|
|
6630
|
+
* ```
|
|
6631
|
+
*
|
|
6632
|
+
* But for composite primary keys or indexes (having multiple columns), define it in a separate function:
|
|
6633
|
+
*
|
|
6634
|
+
* ```ts
|
|
6635
|
+
* export class MyTable extends BaseTable {
|
|
6636
|
+
* columns = this.setColumns(
|
|
6637
|
+
* (t) => ({
|
|
6638
|
+
* one: t.integer(),
|
|
6639
|
+
* two: t.string(),
|
|
6640
|
+
* three: t.boolean(),
|
|
6641
|
+
* }),
|
|
6642
|
+
* (t) => [t.primaryKey(['one', 'two']), t.unique(['two', 'three'])],
|
|
6643
|
+
* );
|
|
6644
|
+
* }
|
|
6645
|
+
* ```
|
|
6646
|
+
* :::
|
|
6647
|
+
*
|
|
6527
6648
|
* You can use the `sql` function exported from your `BaseTable` file in onConflict.
|
|
6528
6649
|
* It can be useful to specify a condition when you have a partial index:
|
|
6529
6650
|
*
|
|
@@ -8431,6 +8552,9 @@ const _queryOrNot = (q, args) => {
|
|
|
8431
8552
|
const _queryWhereIn = (q, and, arg, values, not) => {
|
|
8432
8553
|
let item;
|
|
8433
8554
|
if (values) {
|
|
8555
|
+
if ("length" in values && !values.length) {
|
|
8556
|
+
return _queryNone(q);
|
|
8557
|
+
}
|
|
8434
8558
|
if (Array.isArray(arg)) {
|
|
8435
8559
|
item = {
|
|
8436
8560
|
IN: {
|
|
@@ -8444,7 +8568,11 @@ const _queryWhereIn = (q, and, arg, values, not) => {
|
|
|
8444
8568
|
} else {
|
|
8445
8569
|
item = {};
|
|
8446
8570
|
for (const key in arg) {
|
|
8447
|
-
|
|
8571
|
+
const values2 = arg[key];
|
|
8572
|
+
if ("length" in values2 && !values2.length) {
|
|
8573
|
+
return _queryNone(q);
|
|
8574
|
+
}
|
|
8575
|
+
item[key] = { in: values2 };
|
|
8448
8576
|
}
|
|
8449
8577
|
}
|
|
8450
8578
|
if (not)
|
|
@@ -8993,6 +9121,15 @@ class Where {
|
|
|
8993
9121
|
* ```ts
|
|
8994
9122
|
* db.table.whereIn(['id', 'name'], sql`((1, 'one'), (2, 'two'))`);
|
|
8995
9123
|
* ```
|
|
9124
|
+
*
|
|
9125
|
+
* When empty set of values is given, `whereIn` will resolve into a {@link QueryMethods.none} query that has a special behavior.
|
|
9126
|
+
*
|
|
9127
|
+
* ```ts
|
|
9128
|
+
* // following queries resolves into `none`:
|
|
9129
|
+
* db.table.where('id', [])
|
|
9130
|
+
* db.table.where(['id', 'name'], [])
|
|
9131
|
+
* db.table.where({ id: [] })
|
|
9132
|
+
* ```
|
|
8996
9133
|
*/
|
|
8997
9134
|
whereIn(...args) {
|
|
8998
9135
|
return _queryWhereIn(
|
|
@@ -10197,24 +10334,6 @@ class TransformMethods {
|
|
|
10197
10334
|
}
|
|
10198
10335
|
}
|
|
10199
10336
|
|
|
10200
|
-
const noneMethods = {
|
|
10201
|
-
// `then` resolves or rejects based on return type of the query.
|
|
10202
|
-
// It is `async` so it returns a chainable Promise.
|
|
10203
|
-
async then(resolve, reject) {
|
|
10204
|
-
const type = this.q.returnType;
|
|
10205
|
-
if (!type || type === "all" || type === "rows" || type === "pluck")
|
|
10206
|
-
resolve == null ? void 0 : resolve([]);
|
|
10207
|
-
else if (type === "one" || type === "value" || type === "void")
|
|
10208
|
-
resolve == null ? void 0 : resolve();
|
|
10209
|
-
else if (type === "rowCount")
|
|
10210
|
-
resolve == null ? void 0 : resolve(0);
|
|
10211
|
-
else
|
|
10212
|
-
reject == null ? void 0 : reject(new NotFoundError(this));
|
|
10213
|
-
},
|
|
10214
|
-
// `catch` returns a Promise, so it is chainable with then/catch.
|
|
10215
|
-
catch: () => new Promise(orchidCore.noop)
|
|
10216
|
-
};
|
|
10217
|
-
|
|
10218
10337
|
class ScopeMethods {
|
|
10219
10338
|
/**
|
|
10220
10339
|
* See {@link ScopeMethods}
|
|
@@ -10998,9 +11117,58 @@ class QueryMethods {
|
|
|
10998
11117
|
* await db.table.all().update(data); // -> 0
|
|
10999
11118
|
* await db.table.all().delete(); // -> 0
|
|
11000
11119
|
* ```
|
|
11120
|
+
*
|
|
11121
|
+
* When it's being used in sub-selects, it will return empty arrays, `undefined`'s, or `0` for count,
|
|
11122
|
+
* or it will throw if the sub-query require a result:
|
|
11123
|
+
*
|
|
11124
|
+
* ```ts
|
|
11125
|
+
* await db.user.select({
|
|
11126
|
+
* // returns empty array
|
|
11127
|
+
* pets: (q) => q.pets.none(),
|
|
11128
|
+
* // returns `undefined`
|
|
11129
|
+
* firstPet: (q) => q.pets.none().takeOptional(),
|
|
11130
|
+
* // throws NotFound error
|
|
11131
|
+
* requriedFirstPet: (q) => q.pets.none().take(),
|
|
11132
|
+
* // returns `undefined`
|
|
11133
|
+
* firstPetName: (q) => q.pets.none().getOptional('name'),
|
|
11134
|
+
* // throws NotFound error
|
|
11135
|
+
* requiredFirstPetName: (q) => q.pets.none().get('name'),
|
|
11136
|
+
* // returns empty array
|
|
11137
|
+
* petsNames: (q) => q.pets.none().pluck('name'),
|
|
11138
|
+
* // returns 0
|
|
11139
|
+
* petsCount: (q) => q.pets.none().count(),
|
|
11140
|
+
* });
|
|
11141
|
+
* ```
|
|
11142
|
+
*
|
|
11143
|
+
* When the `none` query is being used for joins that require match, the host query will return an empty result:
|
|
11144
|
+
*
|
|
11145
|
+
* ```ts
|
|
11146
|
+
* // all the following queries will resolve into empty arrays
|
|
11147
|
+
*
|
|
11148
|
+
* await db.user.select({
|
|
11149
|
+
* pets: (q) => q.pets.join().none(),
|
|
11150
|
+
* });
|
|
11151
|
+
*
|
|
11152
|
+
* await db.user.join(
|
|
11153
|
+
* (q) => q.pets.none(),
|
|
11154
|
+
* (q) => q,
|
|
11155
|
+
* );
|
|
11156
|
+
*
|
|
11157
|
+
* await db.user.join('pets', (q) => q.none());
|
|
11158
|
+
* ```
|
|
11159
|
+
*
|
|
11160
|
+
* When it's being used in `leftJoin` or `fullJoin`, it implicitly adds `ON false` into the join's SQL.
|
|
11161
|
+
*
|
|
11162
|
+
* ```ts
|
|
11163
|
+
* // this query can return user records
|
|
11164
|
+
* await db.user.leftJoin('pets', (q) => q.none());
|
|
11165
|
+
*
|
|
11166
|
+
* // this query won't return user records, because of the added where condition
|
|
11167
|
+
* await db.user.leftJoin('pets', (q) => q.none()).where({ 'pets.name': 'Kitty' });
|
|
11168
|
+
* ```
|
|
11001
11169
|
*/
|
|
11002
11170
|
none() {
|
|
11003
|
-
return
|
|
11171
|
+
return _queryNone(this);
|
|
11004
11172
|
}
|
|
11005
11173
|
/**
|
|
11006
11174
|
* `modify` allows modifying the query with your function:
|