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.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ExpressionTypeMethod, Expression, RawSQLBase, emptyObject, isTemplateLiteralArgs, ColumnTypeBase, setColumnData, pushColumnData, quoteObjectKey, toArray, singleQuote, addCode, singleQuoteArray, objectHasValues, columnDefaultArgumentToCode, columnErrorMessagesToCode, getValueKey, addValue, isExpression, joinTruthy, numberDataToCode, stringDataToCode, getDefaultLanguage, dateDataToCode, pushOrNewArrayToObject,
|
|
1
|
+
import { ExpressionTypeMethod, Expression, RawSQLBase, emptyObject, isTemplateLiteralArgs, ColumnTypeBase, setColumnData, pushColumnData, quoteObjectKey, toArray, singleQuote, addCode, singleQuoteArray, objectHasValues, columnDefaultArgumentToCode, columnErrorMessagesToCode, getValueKey, addValue, isExpression, joinTruthy, numberDataToCode, stringDataToCode, getDefaultLanguage, dateDataToCode, pushOrNewArrayToObject, noop, arrayDataToCode, emptyArray, callWithThis, setParserToQuery, applyTransforms, isRawSQL, pushOrNewArray, setDefaultNowFn, setDefaultLanguage, makeTimestampsHelpers, setCurrentColumnName, setAdapterConnectRetry, isObjectEmpty, ValExpression, applyMixins, toSnakeCase, snakeCaseKey } from 'orchid-core';
|
|
2
2
|
import pg from 'pg';
|
|
3
3
|
import { inspect } from 'node:util';
|
|
4
4
|
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
@@ -2591,6 +2591,32 @@ const makeJoinQueryBuilder = (joinedQuery, joinedShapes, joinTo) => {
|
|
|
2591
2591
|
return q;
|
|
2592
2592
|
};
|
|
2593
2593
|
|
|
2594
|
+
const noneMethods = {
|
|
2595
|
+
// `then` resolves or rejects based on return type of the query.
|
|
2596
|
+
// It is `async` so it returns a chainable Promise.
|
|
2597
|
+
async then(resolve, reject) {
|
|
2598
|
+
const type = this.q.returnType;
|
|
2599
|
+
if (!type || type === "all" || type === "rows" || type === "pluck")
|
|
2600
|
+
resolve == null ? void 0 : resolve([]);
|
|
2601
|
+
else if (type === "one" || type === "value" || type === "void")
|
|
2602
|
+
resolve == null ? void 0 : resolve();
|
|
2603
|
+
else if (type === "rowCount")
|
|
2604
|
+
resolve == null ? void 0 : resolve(0);
|
|
2605
|
+
else
|
|
2606
|
+
reject == null ? void 0 : reject(new NotFoundError(this));
|
|
2607
|
+
},
|
|
2608
|
+
// `catch` returns a Promise, so it is chainable with then/catch.
|
|
2609
|
+
catch: () => new Promise(noop)
|
|
2610
|
+
};
|
|
2611
|
+
const _queryNone = (q) => {
|
|
2612
|
+
if (isQueryNone(q))
|
|
2613
|
+
return q;
|
|
2614
|
+
q = extendQuery(q, noneMethods);
|
|
2615
|
+
pushQueryValue(q, "and", new RawSQL("false"));
|
|
2616
|
+
return q;
|
|
2617
|
+
};
|
|
2618
|
+
const isQueryNone = (q) => q.then === noneMethods.then;
|
|
2619
|
+
|
|
2594
2620
|
var __defProp$b = Object.defineProperty;
|
|
2595
2621
|
var __defProps$3 = Object.defineProperties;
|
|
2596
2622
|
var __getOwnPropDescs$3 = Object.getOwnPropertyDescriptors;
|
|
@@ -2610,36 +2636,39 @@ var __spreadValues$b = (a, b) => {
|
|
|
2610
2636
|
return a;
|
|
2611
2637
|
};
|
|
2612
2638
|
var __spreadProps$3 = (a, b) => __defProps$3(a, __getOwnPropDescs$3(b));
|
|
2613
|
-
const _join = (
|
|
2639
|
+
const _join = (query, require2, type, first, args) => {
|
|
2614
2640
|
var _a, _b;
|
|
2615
2641
|
let joinKey;
|
|
2616
2642
|
let shape;
|
|
2617
2643
|
let parsers;
|
|
2618
2644
|
let joinSubQuery = false;
|
|
2619
2645
|
if (typeof first === "function") {
|
|
2620
|
-
first = first(
|
|
2646
|
+
first = first(query.relations);
|
|
2621
2647
|
first.joinQueryAfterCallback = first.joinQuery;
|
|
2622
2648
|
}
|
|
2623
2649
|
if (typeof first === "object") {
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2650
|
+
if (require2 && isQueryNone(first)) {
|
|
2651
|
+
return _queryNone(query);
|
|
2652
|
+
}
|
|
2653
|
+
const q = first;
|
|
2654
|
+
joinSubQuery = getIsJoinSubQuery(q);
|
|
2655
|
+
joinKey = q.q.as || q.table;
|
|
2627
2656
|
if (joinKey) {
|
|
2628
|
-
shape = getShapeFromSelect(
|
|
2629
|
-
parsers =
|
|
2657
|
+
shape = getShapeFromSelect(q, joinSubQuery);
|
|
2658
|
+
parsers = q.q.parsers;
|
|
2630
2659
|
if (joinSubQuery) {
|
|
2631
|
-
first =
|
|
2660
|
+
first = q.clone();
|
|
2632
2661
|
first.shape = shape;
|
|
2633
2662
|
}
|
|
2634
2663
|
}
|
|
2635
2664
|
} else {
|
|
2636
2665
|
joinKey = first;
|
|
2637
|
-
const relation =
|
|
2666
|
+
const relation = query.relations[joinKey];
|
|
2638
2667
|
if (relation) {
|
|
2639
2668
|
shape = getShapeFromSelect(relation.relationConfig.query);
|
|
2640
2669
|
parsers = relation.relationConfig.query.q.parsers;
|
|
2641
2670
|
} else {
|
|
2642
|
-
shape = (_a =
|
|
2671
|
+
shape = (_a = query.q.withShapes) == null ? void 0 : _a[joinKey];
|
|
2643
2672
|
if (shape) {
|
|
2644
2673
|
if (!require2)
|
|
2645
2674
|
shape = __spreadValues$b({}, shape);
|
|
@@ -2655,20 +2684,20 @@ const _join = (q, require2, type, first, args) => {
|
|
|
2655
2684
|
}
|
|
2656
2685
|
if (joinKey) {
|
|
2657
2686
|
setQueryObjectValue(
|
|
2658
|
-
|
|
2687
|
+
query,
|
|
2659
2688
|
"joinedShapes",
|
|
2660
2689
|
joinKey,
|
|
2661
2690
|
shape
|
|
2662
2691
|
);
|
|
2663
2692
|
setQueryObjectValue(
|
|
2664
|
-
|
|
2693
|
+
query,
|
|
2665
2694
|
"joinedParsers",
|
|
2666
2695
|
joinKey,
|
|
2667
2696
|
parsers
|
|
2668
2697
|
);
|
|
2669
2698
|
}
|
|
2670
2699
|
const joinArgs = processJoinArgs(
|
|
2671
|
-
|
|
2700
|
+
query,
|
|
2672
2701
|
first,
|
|
2673
2702
|
args,
|
|
2674
2703
|
joinSubQuery
|
|
@@ -2678,20 +2707,22 @@ const _join = (q, require2, type, first, args) => {
|
|
|
2678
2707
|
if (j.q.select || !j.internal.columnsForSelectAll) {
|
|
2679
2708
|
const shape2 = getShapeFromSelect(j, true);
|
|
2680
2709
|
setQueryObjectValue(
|
|
2681
|
-
|
|
2710
|
+
query,
|
|
2682
2711
|
"joinedShapes",
|
|
2683
2712
|
joinKey,
|
|
2684
2713
|
shape2
|
|
2685
2714
|
);
|
|
2686
2715
|
setQueryObjectValue(
|
|
2687
|
-
|
|
2716
|
+
query,
|
|
2688
2717
|
"joinedParsers",
|
|
2689
2718
|
joinKey,
|
|
2690
2719
|
j.q.parsers
|
|
2691
2720
|
);
|
|
2692
2721
|
}
|
|
2722
|
+
} else if (require2 && "r" in joinArgs && isQueryNone(joinArgs.r)) {
|
|
2723
|
+
return _queryNone(query);
|
|
2693
2724
|
}
|
|
2694
|
-
return pushQueryValue(
|
|
2725
|
+
return pushQueryValue(query, "join", {
|
|
2695
2726
|
type,
|
|
2696
2727
|
args: joinArgs
|
|
2697
2728
|
});
|
|
@@ -3326,6 +3357,26 @@ const addParserForSelectItem = (q, as, key, arg) => {
|
|
|
3326
3357
|
);
|
|
3327
3358
|
});
|
|
3328
3359
|
}
|
|
3360
|
+
if (query.returnType === "valueOrThrow" || query.returnType === "oneOrThrow") {
|
|
3361
|
+
pushQueryValue(
|
|
3362
|
+
q,
|
|
3363
|
+
"transform",
|
|
3364
|
+
(data) => {
|
|
3365
|
+
if (Array.isArray(data)) {
|
|
3366
|
+
for (const item of data) {
|
|
3367
|
+
if (item[key] === void 0) {
|
|
3368
|
+
throw new NotFoundError(q);
|
|
3369
|
+
}
|
|
3370
|
+
}
|
|
3371
|
+
} else {
|
|
3372
|
+
if (data[key] === void 0) {
|
|
3373
|
+
throw new NotFoundError(q);
|
|
3374
|
+
}
|
|
3375
|
+
}
|
|
3376
|
+
return data;
|
|
3377
|
+
}
|
|
3378
|
+
);
|
|
3379
|
+
}
|
|
3329
3380
|
}
|
|
3330
3381
|
return arg;
|
|
3331
3382
|
}
|
|
@@ -3342,7 +3393,11 @@ const processSelectArg = (q, as, arg, columnAs) => {
|
|
|
3342
3393
|
let value = arg[key];
|
|
3343
3394
|
if (typeof value === "function") {
|
|
3344
3395
|
value = resolveSubQueryCallback(q, value);
|
|
3345
|
-
if (
|
|
3396
|
+
if (isQueryNone(value)) {
|
|
3397
|
+
if (value.q.innerJoinLateral) {
|
|
3398
|
+
return;
|
|
3399
|
+
}
|
|
3400
|
+
} else if (!isExpression(value) && value.joinQuery) {
|
|
3346
3401
|
value = value.joinQuery(value, q);
|
|
3347
3402
|
let query;
|
|
3348
3403
|
const returnType = value.q.returnType;
|
|
@@ -3499,11 +3554,18 @@ const maybeUnNameColumn = (column, isSubQuery) => {
|
|
|
3499
3554
|
return isSubQuery && (column == null ? void 0 : column.data.name) ? setColumnData(column, "name", void 0) : column;
|
|
3500
3555
|
};
|
|
3501
3556
|
function _querySelect(q, args) {
|
|
3502
|
-
|
|
3557
|
+
const len = args.length;
|
|
3558
|
+
if (!len) {
|
|
3503
3559
|
return q;
|
|
3504
3560
|
}
|
|
3505
3561
|
const as = q.q.as || q.table;
|
|
3506
|
-
const selectArgs =
|
|
3562
|
+
const selectArgs = new Array(len);
|
|
3563
|
+
for (let i = 0; i < len; i++) {
|
|
3564
|
+
selectArgs[i] = processSelectArg(q, as, args[i]);
|
|
3565
|
+
if (!selectArgs[i]) {
|
|
3566
|
+
return _queryNone(q);
|
|
3567
|
+
}
|
|
3568
|
+
}
|
|
3507
3569
|
return pushQueryArray(q, "select", selectArgs);
|
|
3508
3570
|
}
|
|
3509
3571
|
class Select {
|
|
@@ -3853,7 +3915,37 @@ const selectAllSql = (table, query, quotedAs) => {
|
|
|
3853
3915
|
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(", ")) || "*";
|
|
3854
3916
|
};
|
|
3855
3917
|
const pushSubQuerySql = (ctx, query, as, list, quotedAs) => {
|
|
3918
|
+
var _a;
|
|
3856
3919
|
const { returnType = "all" } = query.q;
|
|
3920
|
+
if (isQueryNone(query)) {
|
|
3921
|
+
let sql;
|
|
3922
|
+
switch (returnType) {
|
|
3923
|
+
case "one":
|
|
3924
|
+
case "oneOrThrow":
|
|
3925
|
+
case "void":
|
|
3926
|
+
return;
|
|
3927
|
+
case "value":
|
|
3928
|
+
case "valueOrThrow":
|
|
3929
|
+
if (((_a = query.q.expr) == null ? void 0 : _a.result.value) instanceof IntegerBaseColumn) {
|
|
3930
|
+
sql = "0";
|
|
3931
|
+
} else {
|
|
3932
|
+
return;
|
|
3933
|
+
}
|
|
3934
|
+
break;
|
|
3935
|
+
case "all":
|
|
3936
|
+
case "pluck":
|
|
3937
|
+
case "rows":
|
|
3938
|
+
sql = `'[]'::json`;
|
|
3939
|
+
break;
|
|
3940
|
+
case "rowCount":
|
|
3941
|
+
sql = "0";
|
|
3942
|
+
break;
|
|
3943
|
+
default:
|
|
3944
|
+
throw new UnhandledTypeError(query, returnType);
|
|
3945
|
+
}
|
|
3946
|
+
list.push(`${sql} "${as}"`);
|
|
3947
|
+
return;
|
|
3948
|
+
}
|
|
3857
3949
|
if (query.q.joinedForSelect) {
|
|
3858
3950
|
let sql;
|
|
3859
3951
|
switch (returnType) {
|
|
@@ -6507,6 +6599,7 @@ class Create {
|
|
|
6507
6599
|
* db.table.create(data).onConflictDoNothing();
|
|
6508
6600
|
*
|
|
6509
6601
|
* // single column:
|
|
6602
|
+
* // (this requires a composite primary key or unique index, see below)
|
|
6510
6603
|
* db.table.create(data).onConfict('email').merge();
|
|
6511
6604
|
*
|
|
6512
6605
|
* // array of columns:
|
|
@@ -6522,6 +6615,34 @@ class Create {
|
|
|
6522
6615
|
* .merge();
|
|
6523
6616
|
* ```
|
|
6524
6617
|
*
|
|
6618
|
+
* :::info
|
|
6619
|
+
* A primary key or a unique index for a **single** column can be fined on a column:
|
|
6620
|
+
*
|
|
6621
|
+
* ```ts
|
|
6622
|
+
* export class MyTable extends BaseTable {
|
|
6623
|
+
* columns = this.setColumns((t) => ({
|
|
6624
|
+
* pkey: t.uuid().primaryKey(),
|
|
6625
|
+
* unique: t.string().unique(),
|
|
6626
|
+
* }));
|
|
6627
|
+
* }
|
|
6628
|
+
* ```
|
|
6629
|
+
*
|
|
6630
|
+
* But for composite primary keys or indexes (having multiple columns), define it in a separate function:
|
|
6631
|
+
*
|
|
6632
|
+
* ```ts
|
|
6633
|
+
* export class MyTable extends BaseTable {
|
|
6634
|
+
* columns = this.setColumns(
|
|
6635
|
+
* (t) => ({
|
|
6636
|
+
* one: t.integer(),
|
|
6637
|
+
* two: t.string(),
|
|
6638
|
+
* three: t.boolean(),
|
|
6639
|
+
* }),
|
|
6640
|
+
* (t) => [t.primaryKey(['one', 'two']), t.unique(['two', 'three'])],
|
|
6641
|
+
* );
|
|
6642
|
+
* }
|
|
6643
|
+
* ```
|
|
6644
|
+
* :::
|
|
6645
|
+
*
|
|
6525
6646
|
* You can use the `sql` function exported from your `BaseTable` file in onConflict.
|
|
6526
6647
|
* It can be useful to specify a condition when you have a partial index:
|
|
6527
6648
|
*
|
|
@@ -8429,6 +8550,9 @@ const _queryOrNot = (q, args) => {
|
|
|
8429
8550
|
const _queryWhereIn = (q, and, arg, values, not) => {
|
|
8430
8551
|
let item;
|
|
8431
8552
|
if (values) {
|
|
8553
|
+
if ("length" in values && !values.length) {
|
|
8554
|
+
return _queryNone(q);
|
|
8555
|
+
}
|
|
8432
8556
|
if (Array.isArray(arg)) {
|
|
8433
8557
|
item = {
|
|
8434
8558
|
IN: {
|
|
@@ -8442,7 +8566,11 @@ const _queryWhereIn = (q, and, arg, values, not) => {
|
|
|
8442
8566
|
} else {
|
|
8443
8567
|
item = {};
|
|
8444
8568
|
for (const key in arg) {
|
|
8445
|
-
|
|
8569
|
+
const values2 = arg[key];
|
|
8570
|
+
if ("length" in values2 && !values2.length) {
|
|
8571
|
+
return _queryNone(q);
|
|
8572
|
+
}
|
|
8573
|
+
item[key] = { in: values2 };
|
|
8446
8574
|
}
|
|
8447
8575
|
}
|
|
8448
8576
|
if (not)
|
|
@@ -8991,6 +9119,15 @@ class Where {
|
|
|
8991
9119
|
* ```ts
|
|
8992
9120
|
* db.table.whereIn(['id', 'name'], sql`((1, 'one'), (2, 'two'))`);
|
|
8993
9121
|
* ```
|
|
9122
|
+
*
|
|
9123
|
+
* When empty set of values is given, `whereIn` will resolve into a {@link QueryMethods.none} query that has a special behavior.
|
|
9124
|
+
*
|
|
9125
|
+
* ```ts
|
|
9126
|
+
* // following queries resolves into `none`:
|
|
9127
|
+
* db.table.where('id', [])
|
|
9128
|
+
* db.table.where(['id', 'name'], [])
|
|
9129
|
+
* db.table.where({ id: [] })
|
|
9130
|
+
* ```
|
|
8994
9131
|
*/
|
|
8995
9132
|
whereIn(...args) {
|
|
8996
9133
|
return _queryWhereIn(
|
|
@@ -10195,24 +10332,6 @@ class TransformMethods {
|
|
|
10195
10332
|
}
|
|
10196
10333
|
}
|
|
10197
10334
|
|
|
10198
|
-
const noneMethods = {
|
|
10199
|
-
// `then` resolves or rejects based on return type of the query.
|
|
10200
|
-
// It is `async` so it returns a chainable Promise.
|
|
10201
|
-
async then(resolve, reject) {
|
|
10202
|
-
const type = this.q.returnType;
|
|
10203
|
-
if (!type || type === "all" || type === "rows" || type === "pluck")
|
|
10204
|
-
resolve == null ? void 0 : resolve([]);
|
|
10205
|
-
else if (type === "one" || type === "value" || type === "void")
|
|
10206
|
-
resolve == null ? void 0 : resolve();
|
|
10207
|
-
else if (type === "rowCount")
|
|
10208
|
-
resolve == null ? void 0 : resolve(0);
|
|
10209
|
-
else
|
|
10210
|
-
reject == null ? void 0 : reject(new NotFoundError(this));
|
|
10211
|
-
},
|
|
10212
|
-
// `catch` returns a Promise, so it is chainable with then/catch.
|
|
10213
|
-
catch: () => new Promise(noop)
|
|
10214
|
-
};
|
|
10215
|
-
|
|
10216
10335
|
class ScopeMethods {
|
|
10217
10336
|
/**
|
|
10218
10337
|
* See {@link ScopeMethods}
|
|
@@ -10996,9 +11115,58 @@ class QueryMethods {
|
|
|
10996
11115
|
* await db.table.all().update(data); // -> 0
|
|
10997
11116
|
* await db.table.all().delete(); // -> 0
|
|
10998
11117
|
* ```
|
|
11118
|
+
*
|
|
11119
|
+
* When it's being used in sub-selects, it will return empty arrays, `undefined`'s, or `0` for count,
|
|
11120
|
+
* or it will throw if the sub-query require a result:
|
|
11121
|
+
*
|
|
11122
|
+
* ```ts
|
|
11123
|
+
* await db.user.select({
|
|
11124
|
+
* // returns empty array
|
|
11125
|
+
* pets: (q) => q.pets.none(),
|
|
11126
|
+
* // returns `undefined`
|
|
11127
|
+
* firstPet: (q) => q.pets.none().takeOptional(),
|
|
11128
|
+
* // throws NotFound error
|
|
11129
|
+
* requriedFirstPet: (q) => q.pets.none().take(),
|
|
11130
|
+
* // returns `undefined`
|
|
11131
|
+
* firstPetName: (q) => q.pets.none().getOptional('name'),
|
|
11132
|
+
* // throws NotFound error
|
|
11133
|
+
* requiredFirstPetName: (q) => q.pets.none().get('name'),
|
|
11134
|
+
* // returns empty array
|
|
11135
|
+
* petsNames: (q) => q.pets.none().pluck('name'),
|
|
11136
|
+
* // returns 0
|
|
11137
|
+
* petsCount: (q) => q.pets.none().count(),
|
|
11138
|
+
* });
|
|
11139
|
+
* ```
|
|
11140
|
+
*
|
|
11141
|
+
* When the `none` query is being used for joins that require match, the host query will return an empty result:
|
|
11142
|
+
*
|
|
11143
|
+
* ```ts
|
|
11144
|
+
* // all the following queries will resolve into empty arrays
|
|
11145
|
+
*
|
|
11146
|
+
* await db.user.select({
|
|
11147
|
+
* pets: (q) => q.pets.join().none(),
|
|
11148
|
+
* });
|
|
11149
|
+
*
|
|
11150
|
+
* await db.user.join(
|
|
11151
|
+
* (q) => q.pets.none(),
|
|
11152
|
+
* (q) => q,
|
|
11153
|
+
* );
|
|
11154
|
+
*
|
|
11155
|
+
* await db.user.join('pets', (q) => q.none());
|
|
11156
|
+
* ```
|
|
11157
|
+
*
|
|
11158
|
+
* When it's being used in `leftJoin` or `fullJoin`, it implicitly adds `ON false` into the join's SQL.
|
|
11159
|
+
*
|
|
11160
|
+
* ```ts
|
|
11161
|
+
* // this query can return user records
|
|
11162
|
+
* await db.user.leftJoin('pets', (q) => q.none());
|
|
11163
|
+
*
|
|
11164
|
+
* // this query won't return user records, because of the added where condition
|
|
11165
|
+
* await db.user.leftJoin('pets', (q) => q.none()).where({ 'pets.name': 'Kitty' });
|
|
11166
|
+
* ```
|
|
10999
11167
|
*/
|
|
11000
11168
|
none() {
|
|
11001
|
-
return
|
|
11169
|
+
return _queryNone(this);
|
|
11002
11170
|
}
|
|
11003
11171
|
/**
|
|
11004
11172
|
* `modify` allows modifying the query with your function:
|