pqb 0.54.0 → 0.54.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +105 -109
- package/dist/index.js +380 -323
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +349 -291
- 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, templateLiteralSQLToCode, quoteObjectKey, toArray, emptyArray, singleQuote, addCode, singleQuoteArray, objectHasValues, toSnakeCase, columnDefaultArgumentToCode, columnErrorMessagesToCode, setObjectValueImmutable, getValueKey, addValue, isExpression, dateDataToCode, joinTruthy, arrayDataToCode, numberDataToCode, noop, stringDataToCode, getDefaultLanguage, setDefaultNowFn, setDefaultLanguage, setCurrentColumnName, timestampHelpers, returnArg as returnArg$1,
|
|
1
|
+
import { ExpressionTypeMethod, Expression, RawSQLBase, emptyObject, isTemplateLiteralArgs, ColumnTypeBase, setColumnData, pushColumnData, templateLiteralSQLToCode, quoteObjectKey, toArray, emptyArray, singleQuote, addCode, singleQuoteArray, objectHasValues, toSnakeCase, columnDefaultArgumentToCode, columnErrorMessagesToCode, setObjectValueImmutable, getValueKey, addValue, isExpression, dateDataToCode, joinTruthy, arrayDataToCode, numberDataToCode, noop, stringDataToCode, getDefaultLanguage, setDefaultNowFn, setDefaultLanguage, setCurrentColumnName, timestampHelpers, returnArg as returnArg$1, pushQueryValueImmutable, logColors, applyTransforms, callWithThis, setParserToQuery, pushOrNewArray, isRawSQL, setAdapterConnectRetry, pushOrNewArrayToObjectImmutable, QueryHookUtils, isObjectEmpty, ValExpression, applyMixins, snakeCaseKey } from 'orchid-core';
|
|
2
2
|
import pg from 'pg';
|
|
3
3
|
import { inspect } from 'node:util';
|
|
4
4
|
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
@@ -430,7 +430,7 @@ class ColumnType extends ColumnTypeBase {
|
|
|
430
430
|
return sql2;
|
|
431
431
|
}
|
|
432
432
|
});
|
|
433
|
-
column.data.
|
|
433
|
+
column.data.readOnly = true;
|
|
434
434
|
return column;
|
|
435
435
|
}
|
|
436
436
|
}
|
|
@@ -2156,7 +2156,7 @@ class TsVectorColumn extends ColumnType {
|
|
|
2156
2156
|
toSQL,
|
|
2157
2157
|
toCode
|
|
2158
2158
|
});
|
|
2159
|
-
column.data.
|
|
2159
|
+
column.data.readOnly = true;
|
|
2160
2160
|
return column;
|
|
2161
2161
|
}
|
|
2162
2162
|
}
|
|
@@ -2456,8 +2456,7 @@ class VirtualColumn extends ColumnType {
|
|
|
2456
2456
|
super(schema, inputSchema);
|
|
2457
2457
|
this.dataType = "";
|
|
2458
2458
|
this.operators = Operators.any;
|
|
2459
|
-
this.data.explicitSelect = true;
|
|
2460
|
-
this.data.insertable = this.data.updatable = false;
|
|
2459
|
+
this.data.explicitSelect = this.data.appReadOnly = this.data.virtual = true;
|
|
2461
2460
|
}
|
|
2462
2461
|
toCode() {
|
|
2463
2462
|
throw new Error(`toCode is not implemented for virtual column`);
|
|
@@ -2468,8 +2467,7 @@ const _UnknownColumn = class _UnknownColumn extends VirtualColumn {
|
|
|
2468
2467
|
constructor(schema) {
|
|
2469
2468
|
super(schema, schema.unknown());
|
|
2470
2469
|
this.selectable = true;
|
|
2471
|
-
this.data.explicitSelect = void 0;
|
|
2472
|
-
this.data.insertable = this.data.updatable = true;
|
|
2470
|
+
this.data.explicitSelect = this.data.appReadOnly = this.data.virtual = void 0;
|
|
2473
2471
|
}
|
|
2474
2472
|
};
|
|
2475
2473
|
_UnknownColumn.instance = new _UnknownColumn(defaultSchemaConfig);
|
|
@@ -2728,8 +2726,9 @@ class NotFoundError extends OrchidOrmError {
|
|
|
2728
2726
|
}
|
|
2729
2727
|
_query = new WeakMap();
|
|
2730
2728
|
class OrchidOrmInternalError extends Error {
|
|
2731
|
-
constructor(query, message) {
|
|
2729
|
+
constructor(query, message, data) {
|
|
2732
2730
|
super(message);
|
|
2731
|
+
this.data = data;
|
|
2733
2732
|
// `#query` is private to prevent it from serializing to not cause problems to test runner reports
|
|
2734
2733
|
__privateAdd(this, _query2);
|
|
2735
2734
|
__privateSet(this, _query2, query);
|
|
@@ -3403,11 +3402,7 @@ const resolveCallbacksInArgs = (q, args) => {
|
|
|
3403
3402
|
};
|
|
3404
3403
|
const _queryWhere = (q, args) => {
|
|
3405
3404
|
resolveCallbacksInArgs(q, args);
|
|
3406
|
-
return pushQueryArrayImmutable(
|
|
3407
|
-
q,
|
|
3408
|
-
"and",
|
|
3409
|
-
args
|
|
3410
|
-
);
|
|
3405
|
+
return pushQueryArrayImmutable(q, "and", args);
|
|
3411
3406
|
};
|
|
3412
3407
|
const _queryFindBy = (q, args) => {
|
|
3413
3408
|
return _queryTake(_queryWhere(q, args));
|
|
@@ -4297,10 +4292,6 @@ const pushQueryArrayImmutable = (q, key, value) => {
|
|
|
4297
4292
|
q.q[key] = arr ? [...arr, ...value] : value;
|
|
4298
4293
|
return q;
|
|
4299
4294
|
};
|
|
4300
|
-
const pushQueryValueImmutable = (q, key, value) => {
|
|
4301
|
-
pushOrNewArrayToObjectImmutable(q.q, key, value);
|
|
4302
|
-
return q;
|
|
4303
|
-
};
|
|
4304
4295
|
const setQueryObjectValueImmutable = (q, object, key, value) => {
|
|
4305
4296
|
q.q[object] = {
|
|
4306
4297
|
...q.q[object],
|
|
@@ -4984,7 +4975,7 @@ const applyComputedColumns = (q, fn) => {
|
|
|
4984
4975
|
const { data } = col;
|
|
4985
4976
|
data.computed = item;
|
|
4986
4977
|
data.explicitSelect = true;
|
|
4987
|
-
data.
|
|
4978
|
+
data.readOnly = true;
|
|
4988
4979
|
addColumnParserToQuery(
|
|
4989
4980
|
q.q,
|
|
4990
4981
|
key,
|
|
@@ -6238,6 +6229,8 @@ function _querySelect(q, args) {
|
|
|
6238
6229
|
q.q.returnType = q.q.returningMany ? "all" : "oneOrThrow";
|
|
6239
6230
|
} else if (returnType === "value") {
|
|
6240
6231
|
q.q.returnType = q.q.returningMany ? "all" : "one";
|
|
6232
|
+
} else if (returnType === "void") {
|
|
6233
|
+
q.q.returnType = q.q.returningMany ? "all" : "oneOrThrow";
|
|
6241
6234
|
}
|
|
6242
6235
|
const len = args.length;
|
|
6243
6236
|
if (!len) {
|
|
@@ -6427,7 +6420,22 @@ const pushWithSql = (ctx, items) => {
|
|
|
6427
6420
|
};
|
|
6428
6421
|
|
|
6429
6422
|
const makeInsertSql = (ctx, q, query, quotedAs) => {
|
|
6430
|
-
|
|
6423
|
+
let { columns } = query;
|
|
6424
|
+
const { shape, inCTE, hookCreateSet } = query;
|
|
6425
|
+
const QueryClass = ctx.qb.constructor;
|
|
6426
|
+
let values = query.values;
|
|
6427
|
+
let hookSetSql;
|
|
6428
|
+
if (hookCreateSet) {
|
|
6429
|
+
({ hookSetSql, columns, values } = processHookSet(
|
|
6430
|
+
ctx,
|
|
6431
|
+
q,
|
|
6432
|
+
values,
|
|
6433
|
+
hookCreateSet,
|
|
6434
|
+
columns,
|
|
6435
|
+
QueryClass,
|
|
6436
|
+
quotedAs
|
|
6437
|
+
));
|
|
6438
|
+
}
|
|
6431
6439
|
const quotedColumns = columns.map(
|
|
6432
6440
|
(column) => `"${shape[column]?.data.name || column}"`
|
|
6433
6441
|
);
|
|
@@ -6442,7 +6450,6 @@ const makeInsertSql = (ctx, q, query, quotedAs) => {
|
|
|
6442
6450
|
}
|
|
6443
6451
|
}
|
|
6444
6452
|
}
|
|
6445
|
-
let values = query.values;
|
|
6446
6453
|
if (quotedColumns.length === 0) {
|
|
6447
6454
|
const key = Object.keys(q.shape)[0];
|
|
6448
6455
|
if (key) {
|
|
@@ -6454,12 +6461,11 @@ const makeInsertSql = (ctx, q, query, quotedAs) => {
|
|
|
6454
6461
|
}
|
|
6455
6462
|
}
|
|
6456
6463
|
const insertSql = `INSERT INTO ${quotedAs}${quotedColumns.length ? "(" + quotedColumns.join(", ") + ")" : ""}`;
|
|
6457
|
-
if (
|
|
6464
|
+
if ("from" in values && query.insertWith) {
|
|
6458
6465
|
pushWithSql(ctx, Object.values(query.insertWith).flat());
|
|
6459
6466
|
}
|
|
6460
6467
|
const valuesPos = ctx.sql.length + 1;
|
|
6461
6468
|
ctx.sql.push(insertSql, null);
|
|
6462
|
-
const QueryClass = ctx.qb.constructor;
|
|
6463
6469
|
if (query.onConflict) {
|
|
6464
6470
|
ctx.sql.push("ON CONFLICT");
|
|
6465
6471
|
const { target } = query.onConflict;
|
|
@@ -6523,7 +6529,28 @@ const makeInsertSql = (ctx, q, query, quotedAs) => {
|
|
|
6523
6529
|
returning = makeReturningSql(ctx, q, query, quotedAs, 2);
|
|
6524
6530
|
}
|
|
6525
6531
|
if (returning.select) ctx.sql.push("RETURNING", returning.select);
|
|
6526
|
-
if (
|
|
6532
|
+
if ("from" in values) {
|
|
6533
|
+
const { from, values: v } = values;
|
|
6534
|
+
const q2 = from.clone();
|
|
6535
|
+
if (v) {
|
|
6536
|
+
pushQueryValueImmutable(
|
|
6537
|
+
q2,
|
|
6538
|
+
"select",
|
|
6539
|
+
new RawSQL(
|
|
6540
|
+
encodeRow(
|
|
6541
|
+
ctx,
|
|
6542
|
+
ctx.values,
|
|
6543
|
+
q2,
|
|
6544
|
+
QueryClass,
|
|
6545
|
+
v,
|
|
6546
|
+
runtimeDefaults,
|
|
6547
|
+
quotedAs
|
|
6548
|
+
)
|
|
6549
|
+
)
|
|
6550
|
+
);
|
|
6551
|
+
}
|
|
6552
|
+
ctx.sql[valuesPos] = getSqlText(toSQL(q2, { values: ctx.values }));
|
|
6553
|
+
} else {
|
|
6527
6554
|
const valuesSql = [];
|
|
6528
6555
|
let ctxValues = ctx.values;
|
|
6529
6556
|
const restValuesLen = ctxValues.length;
|
|
@@ -6544,7 +6571,8 @@ const makeInsertSql = (ctx, q, query, quotedAs) => {
|
|
|
6544
6571
|
QueryClass,
|
|
6545
6572
|
values[i],
|
|
6546
6573
|
runtimeDefaults,
|
|
6547
|
-
quotedAs
|
|
6574
|
+
quotedAs,
|
|
6575
|
+
hookSetSql
|
|
6548
6576
|
);
|
|
6549
6577
|
if (!inCTE) encodedRow = "(" + encodedRow + ")";
|
|
6550
6578
|
if (ctxValues.length > MAX_BINDING_PARAMS) {
|
|
@@ -6593,32 +6621,127 @@ const makeInsertSql = (ctx, q, query, quotedAs) => {
|
|
|
6593
6621
|
if (inCTE) {
|
|
6594
6622
|
ctx.sql[valuesPos] += ' WHERE NOT EXISTS (SELECT 1 FROM "f")';
|
|
6595
6623
|
}
|
|
6596
|
-
}
|
|
6597
|
-
|
|
6598
|
-
|
|
6599
|
-
|
|
6600
|
-
|
|
6601
|
-
|
|
6602
|
-
|
|
6603
|
-
|
|
6604
|
-
|
|
6624
|
+
}
|
|
6625
|
+
return {
|
|
6626
|
+
hookSelect: returning.hookSelect,
|
|
6627
|
+
text: ctx.sql.join(" "),
|
|
6628
|
+
values: ctx.values
|
|
6629
|
+
};
|
|
6630
|
+
};
|
|
6631
|
+
const processHookSet = (ctx, q, values, hookCreateSet, columns, QueryClass, quotedAs) => {
|
|
6632
|
+
const hookSet = {};
|
|
6633
|
+
for (const item of hookCreateSet) {
|
|
6634
|
+
Object.assign(hookSet, item);
|
|
6635
|
+
}
|
|
6636
|
+
const addHookSetColumns = Object.keys(hookSet).filter(
|
|
6637
|
+
(key) => !columns.includes(key)
|
|
6638
|
+
);
|
|
6639
|
+
if ("from" in values) {
|
|
6640
|
+
const v = { ...values };
|
|
6641
|
+
const newColumns = [];
|
|
6642
|
+
const originalSelect = v.from.q.select;
|
|
6643
|
+
if (originalSelect) {
|
|
6644
|
+
v.from = _clone(v.from);
|
|
6645
|
+
const select = [];
|
|
6646
|
+
for (const s of originalSelect) {
|
|
6647
|
+
if (typeof s === "string" && !hookSet[s]) {
|
|
6648
|
+
select.push(s);
|
|
6649
|
+
newColumns.push(s);
|
|
6650
|
+
} else if (typeof s === "object" && "selectAs" in s) {
|
|
6651
|
+
const filtered = {};
|
|
6652
|
+
for (const key in s.selectAs) {
|
|
6653
|
+
if (!hookSet[key]) {
|
|
6654
|
+
filtered[key] = s.selectAs[key];
|
|
6655
|
+
newColumns.push(key);
|
|
6656
|
+
}
|
|
6657
|
+
}
|
|
6658
|
+
select.push({ selectAs: filtered });
|
|
6659
|
+
}
|
|
6660
|
+
}
|
|
6661
|
+
v.from.q.select = select;
|
|
6662
|
+
}
|
|
6663
|
+
let row;
|
|
6664
|
+
if (v.values) {
|
|
6665
|
+
const originalRow = v.values;
|
|
6666
|
+
const valuesColumns = columns.slice(-originalRow.length);
|
|
6667
|
+
row = [];
|
|
6668
|
+
valuesColumns.forEach((c, i) => {
|
|
6669
|
+
if (!hookSet[c]) {
|
|
6670
|
+
newColumns.push(c);
|
|
6671
|
+
row.push(originalRow[i]);
|
|
6672
|
+
}
|
|
6673
|
+
});
|
|
6674
|
+
} else {
|
|
6675
|
+
row = [];
|
|
6676
|
+
}
|
|
6677
|
+
v.values = row;
|
|
6678
|
+
columns.forEach((column) => {
|
|
6679
|
+
if (column in hookSet) {
|
|
6680
|
+
newColumns.push(column);
|
|
6681
|
+
const fromHook = {
|
|
6682
|
+
fromHook: encodeValue(
|
|
6605
6683
|
ctx,
|
|
6606
6684
|
ctx.values,
|
|
6607
|
-
|
|
6685
|
+
q,
|
|
6608
6686
|
QueryClass,
|
|
6609
|
-
|
|
6610
|
-
runtimeDefaults,
|
|
6687
|
+
hookSet[column],
|
|
6611
6688
|
quotedAs
|
|
6612
6689
|
)
|
|
6613
|
-
|
|
6614
|
-
|
|
6690
|
+
};
|
|
6691
|
+
row.push(fromHook);
|
|
6692
|
+
}
|
|
6693
|
+
});
|
|
6694
|
+
if (addHookSetColumns) {
|
|
6695
|
+
for (const key of addHookSetColumns) {
|
|
6696
|
+
row.push({
|
|
6697
|
+
fromHook: encodeValue(
|
|
6698
|
+
ctx,
|
|
6699
|
+
ctx.values,
|
|
6700
|
+
q,
|
|
6701
|
+
QueryClass,
|
|
6702
|
+
hookSet[key],
|
|
6703
|
+
quotedAs
|
|
6704
|
+
)
|
|
6705
|
+
});
|
|
6706
|
+
}
|
|
6707
|
+
return {
|
|
6708
|
+
columns: [...newColumns, ...addHookSetColumns],
|
|
6709
|
+
values: v
|
|
6710
|
+
};
|
|
6615
6711
|
}
|
|
6616
|
-
|
|
6712
|
+
return { columns: newColumns, values: v };
|
|
6617
6713
|
}
|
|
6714
|
+
columns.forEach((column, i) => {
|
|
6715
|
+
if (column in hookSet) {
|
|
6716
|
+
const fromHook = {
|
|
6717
|
+
fromHook: encodeValue(
|
|
6718
|
+
ctx,
|
|
6719
|
+
ctx.values,
|
|
6720
|
+
q,
|
|
6721
|
+
QueryClass,
|
|
6722
|
+
hookSet[column],
|
|
6723
|
+
quotedAs
|
|
6724
|
+
)
|
|
6725
|
+
};
|
|
6726
|
+
for (const row of values) {
|
|
6727
|
+
row[i] = fromHook;
|
|
6728
|
+
}
|
|
6729
|
+
}
|
|
6730
|
+
});
|
|
6731
|
+
const hookSetSql = addHookSetColumns.map(
|
|
6732
|
+
(key) => encodeValue(
|
|
6733
|
+
ctx,
|
|
6734
|
+
ctx.values,
|
|
6735
|
+
q,
|
|
6736
|
+
QueryClass,
|
|
6737
|
+
hookSet[key],
|
|
6738
|
+
quotedAs
|
|
6739
|
+
)
|
|
6740
|
+
).join(", ");
|
|
6618
6741
|
return {
|
|
6619
|
-
|
|
6620
|
-
|
|
6621
|
-
values
|
|
6742
|
+
hookSetSql,
|
|
6743
|
+
columns: addHookSetColumns ? [...columns, ...addHookSetColumns] : columns,
|
|
6744
|
+
values
|
|
6622
6745
|
};
|
|
6623
6746
|
};
|
|
6624
6747
|
const mergeColumnsSql = (columns, quotedColumns, target, except) => {
|
|
@@ -6642,24 +6765,30 @@ const mergeColumnsSql = (columns, quotedColumns, target, except) => {
|
|
|
6642
6765
|
`DO UPDATE SET ${quotedColumns[0]} = excluded.${quotedColumns[0]}`
|
|
6643
6766
|
);
|
|
6644
6767
|
};
|
|
6645
|
-
const encodeRow = (ctx, values, q, QueryClass, row, runtimeDefaults, quotedAs) => {
|
|
6646
|
-
const arr = row.map(
|
|
6647
|
-
|
|
6648
|
-
|
|
6649
|
-
return value.toSQL(ctx, quotedAs);
|
|
6650
|
-
} else if (value instanceof QueryClass) {
|
|
6651
|
-
return `(${getSqlText(joinSubQuery(q, value).toSQL(ctx))})`;
|
|
6652
|
-
}
|
|
6653
|
-
}
|
|
6654
|
-
return value === void 0 ? "DEFAULT" : addValue(values, value);
|
|
6655
|
-
});
|
|
6768
|
+
const encodeRow = (ctx, values, q, QueryClass, row, runtimeDefaults, quotedAs, hookSetSql) => {
|
|
6769
|
+
const arr = row.map(
|
|
6770
|
+
(value) => encodeValue(ctx, values, q, QueryClass, value, quotedAs)
|
|
6771
|
+
);
|
|
6656
6772
|
if (runtimeDefaults) {
|
|
6657
6773
|
for (const fn of runtimeDefaults) {
|
|
6658
6774
|
arr.push(addValue(values, fn()));
|
|
6659
6775
|
}
|
|
6660
6776
|
}
|
|
6777
|
+
if (hookSetSql) arr.push(hookSetSql);
|
|
6661
6778
|
return arr.join(", ");
|
|
6662
6779
|
};
|
|
6780
|
+
const encodeValue = (ctx, values, q, QueryClass, value, quotedAs) => {
|
|
6781
|
+
if (value && typeof value === "object") {
|
|
6782
|
+
if (value instanceof Expression) {
|
|
6783
|
+
return value.toSQL(ctx, quotedAs);
|
|
6784
|
+
} else if (value instanceof QueryClass) {
|
|
6785
|
+
return `(${getSqlText(joinSubQuery(q, value).toSQL(ctx))})`;
|
|
6786
|
+
} else if ("fromHook" in value) {
|
|
6787
|
+
return value.fromHook;
|
|
6788
|
+
}
|
|
6789
|
+
}
|
|
6790
|
+
return value === void 0 ? "DEFAULT" : addValue(values, value);
|
|
6791
|
+
};
|
|
6663
6792
|
const hookSelectKeys = [
|
|
6664
6793
|
null,
|
|
6665
6794
|
"afterUpdateSelect",
|
|
@@ -7238,8 +7367,20 @@ const pushUpdateSql = (ctx, table, query, quotedAs) => {
|
|
|
7238
7367
|
query.schema,
|
|
7239
7368
|
table.table || query.from
|
|
7240
7369
|
);
|
|
7370
|
+
let hookSet;
|
|
7371
|
+
if (query.hookUpdateSet) {
|
|
7372
|
+
hookSet = {};
|
|
7373
|
+
for (const item of query.hookUpdateSet) {
|
|
7374
|
+
Object.assign(hookSet, item);
|
|
7375
|
+
}
|
|
7376
|
+
} else {
|
|
7377
|
+
hookSet = emptyObject;
|
|
7378
|
+
}
|
|
7241
7379
|
const set = [];
|
|
7242
|
-
processData(ctx, table, set, query.updateData, quotedAs);
|
|
7380
|
+
processData(ctx, table, set, query.updateData, hookSet, quotedAs);
|
|
7381
|
+
if (query.hookUpdateSet) {
|
|
7382
|
+
applySet(ctx, table, set, hookSet, emptyObject, quotedAs);
|
|
7383
|
+
}
|
|
7243
7384
|
if (!set.length) {
|
|
7244
7385
|
if (!query.select) {
|
|
7245
7386
|
query.select = countSelect;
|
|
@@ -7279,32 +7420,35 @@ const pushUpdateReturning = (ctx, table, query, quotedAs, keyword) => {
|
|
|
7279
7420
|
if (s) ctx.sql.push(keyword, s);
|
|
7280
7421
|
return hookSelect;
|
|
7281
7422
|
};
|
|
7282
|
-
const processData = (ctx, table, set, data, quotedAs) => {
|
|
7423
|
+
const processData = (ctx, table, set, data, hookSet, quotedAs) => {
|
|
7283
7424
|
let append;
|
|
7284
|
-
const QueryClass = ctx.qb.constructor;
|
|
7285
7425
|
for (const item of data) {
|
|
7286
7426
|
if (typeof item === "function") {
|
|
7287
7427
|
const result = item(data);
|
|
7288
7428
|
if (result) append = pushOrNewArray(append, result);
|
|
7289
7429
|
} else {
|
|
7290
|
-
|
|
7291
|
-
for (const key in item) {
|
|
7292
|
-
const value = item[key];
|
|
7293
|
-
if (value === void 0) continue;
|
|
7294
|
-
set.push(
|
|
7295
|
-
`"${shape[key].data.name || key}" = ${processValue(
|
|
7296
|
-
ctx,
|
|
7297
|
-
table,
|
|
7298
|
-
QueryClass,
|
|
7299
|
-
key,
|
|
7300
|
-
value,
|
|
7301
|
-
quotedAs
|
|
7302
|
-
)}`
|
|
7303
|
-
);
|
|
7304
|
-
}
|
|
7430
|
+
applySet(ctx, table, set, item, hookSet, quotedAs);
|
|
7305
7431
|
}
|
|
7306
7432
|
}
|
|
7307
|
-
if (append) processData(ctx, table, set, append, quotedAs);
|
|
7433
|
+
if (append) processData(ctx, table, set, append, hookSet, quotedAs);
|
|
7434
|
+
};
|
|
7435
|
+
const applySet = (ctx, table, set, item, hookSet, quotedAs) => {
|
|
7436
|
+
const QueryClass = ctx.qb.constructor;
|
|
7437
|
+
const shape = table.q.shape;
|
|
7438
|
+
for (const key in item) {
|
|
7439
|
+
const value = item[key];
|
|
7440
|
+
if (value === void 0 || key in hookSet) continue;
|
|
7441
|
+
set.push(
|
|
7442
|
+
`"${shape[key].data.name || key}" = ${processValue(
|
|
7443
|
+
ctx,
|
|
7444
|
+
table,
|
|
7445
|
+
QueryClass,
|
|
7446
|
+
key,
|
|
7447
|
+
value,
|
|
7448
|
+
quotedAs
|
|
7449
|
+
)}`
|
|
7450
|
+
);
|
|
7451
|
+
}
|
|
7308
7452
|
};
|
|
7309
7453
|
const processValue = (ctx, table, QueryClass, key, value, quotedAs) => {
|
|
7310
7454
|
if (value && typeof value === "object") {
|
|
@@ -8670,36 +8814,48 @@ const processCreateItem = (q, item, rowIndex, ctx, encoders) => {
|
|
|
8670
8814
|
var _a;
|
|
8671
8815
|
const { shape } = q.q;
|
|
8672
8816
|
for (const key in item) {
|
|
8673
|
-
|
|
8674
|
-
|
|
8675
|
-
|
|
8676
|
-
|
|
8677
|
-
q,
|
|
8678
|
-
value
|
|
8679
|
-
);
|
|
8680
|
-
if (value && typeof value === "object" && value instanceof Db) {
|
|
8681
|
-
moveQueryValueToWith(
|
|
8682
|
-
q,
|
|
8683
|
-
(_a = q.q).insertWith ?? (_a.insertWith = {}),
|
|
8684
|
-
value,
|
|
8685
|
-
item,
|
|
8686
|
-
key,
|
|
8687
|
-
rowIndex
|
|
8688
|
-
);
|
|
8689
|
-
}
|
|
8690
|
-
}
|
|
8691
|
-
if (!ctx.columns.has(key) && (shape[key] && !shape[key].data.readonly || shape === anyShape) && value !== void 0) {
|
|
8692
|
-
ctx.columns.set(key, ctx.columns.size);
|
|
8693
|
-
encoders[key] = shape[key]?.data.encode;
|
|
8694
|
-
}
|
|
8695
|
-
} else if (shape[key] instanceof VirtualColumn) {
|
|
8696
|
-
shape[key].create?.(
|
|
8817
|
+
const column = shape[key];
|
|
8818
|
+
if (!column) continue;
|
|
8819
|
+
if (column.data.virtual) {
|
|
8820
|
+
column.create?.(
|
|
8697
8821
|
q,
|
|
8698
8822
|
ctx,
|
|
8699
8823
|
item,
|
|
8700
8824
|
rowIndex
|
|
8701
8825
|
);
|
|
8826
|
+
continue;
|
|
8702
8827
|
}
|
|
8828
|
+
throwOnReadOnly$1(q, column, key);
|
|
8829
|
+
let value = item[key];
|
|
8830
|
+
if (typeof value === "function") {
|
|
8831
|
+
value = item[key] = resolveSubQueryCallbackV2(
|
|
8832
|
+
q,
|
|
8833
|
+
value
|
|
8834
|
+
);
|
|
8835
|
+
if (value && typeof value === "object" && value instanceof Db) {
|
|
8836
|
+
moveQueryValueToWith(
|
|
8837
|
+
q,
|
|
8838
|
+
(_a = q.q).insertWith ?? (_a.insertWith = {}),
|
|
8839
|
+
value,
|
|
8840
|
+
item,
|
|
8841
|
+
key,
|
|
8842
|
+
rowIndex
|
|
8843
|
+
);
|
|
8844
|
+
}
|
|
8845
|
+
}
|
|
8846
|
+
if (!ctx.columns.has(key) && (column && !column.data.readOnly || shape === anyShape) && value !== void 0) {
|
|
8847
|
+
ctx.columns.set(key, ctx.columns.size);
|
|
8848
|
+
encoders[key] = column?.data.encode;
|
|
8849
|
+
}
|
|
8850
|
+
}
|
|
8851
|
+
};
|
|
8852
|
+
const throwOnReadOnly$1 = (q, column, key) => {
|
|
8853
|
+
if (column.data.appReadOnly || column.data.readOnly) {
|
|
8854
|
+
throw new OrchidOrmInternalError(
|
|
8855
|
+
q,
|
|
8856
|
+
"Trying to insert a readonly column",
|
|
8857
|
+
{ column: key }
|
|
8858
|
+
);
|
|
8703
8859
|
}
|
|
8704
8860
|
};
|
|
8705
8861
|
const createCtx = () => ({
|
|
@@ -8745,7 +8901,7 @@ const handleManyData = (q, data, ctx) => {
|
|
|
8745
8901
|
const insert = (self, {
|
|
8746
8902
|
columns,
|
|
8747
8903
|
values
|
|
8748
|
-
},
|
|
8904
|
+
}, many) => {
|
|
8749
8905
|
const { q } = self;
|
|
8750
8906
|
if (!q.select?.length) {
|
|
8751
8907
|
q.returning = true;
|
|
@@ -8756,7 +8912,6 @@ const insert = (self, {
|
|
|
8756
8912
|
q.type = "insert";
|
|
8757
8913
|
q.columns = columns;
|
|
8758
8914
|
q.values = values;
|
|
8759
|
-
if (!q.kind) q.kind = kind;
|
|
8760
8915
|
const { select, returnType } = q;
|
|
8761
8916
|
if (!select) {
|
|
8762
8917
|
if (returnType !== "void") {
|
|
@@ -8776,7 +8931,7 @@ const insert = (self, {
|
|
|
8776
8931
|
}
|
|
8777
8932
|
return self;
|
|
8778
8933
|
};
|
|
8779
|
-
const getFromSelectColumns = (from, obj, many) => {
|
|
8934
|
+
const getFromSelectColumns = (q, from, obj, many) => {
|
|
8780
8935
|
if (!many && !queryTypeWithLimitOne[from.q.returnType]) {
|
|
8781
8936
|
throw new Error(
|
|
8782
8937
|
"Cannot create based on a query which returns multiple records"
|
|
@@ -8794,19 +8949,22 @@ const getFromSelectColumns = (from, obj, many) => {
|
|
|
8794
8949
|
if (obj?.columns) {
|
|
8795
8950
|
queryColumns.push(...obj.columns);
|
|
8796
8951
|
}
|
|
8952
|
+
for (const key of queryColumns) {
|
|
8953
|
+
const column = q.shape[key];
|
|
8954
|
+
if (column) throwOnReadOnly$1(from, column, key);
|
|
8955
|
+
}
|
|
8797
8956
|
return queryColumns;
|
|
8798
8957
|
};
|
|
8799
8958
|
const insertFromQuery = (q, from, many, data) => {
|
|
8800
8959
|
const ctx = createCtx();
|
|
8801
8960
|
const obj = data && handleOneData(q, data, ctx);
|
|
8802
|
-
const columns = getFromSelectColumns(from, obj, many);
|
|
8961
|
+
const columns = getFromSelectColumns(q, from, obj, many);
|
|
8803
8962
|
return insert(
|
|
8804
8963
|
q,
|
|
8805
8964
|
{
|
|
8806
8965
|
columns,
|
|
8807
|
-
values: { from, values: obj?.values }
|
|
8966
|
+
values: { from, values: obj?.values[0] }
|
|
8808
8967
|
},
|
|
8809
|
-
"from",
|
|
8810
8968
|
many
|
|
8811
8969
|
);
|
|
8812
8970
|
};
|
|
@@ -8819,11 +8977,11 @@ const _queryInsert = (q, data) => {
|
|
|
8819
8977
|
const obj = handleOneData(q, data, ctx);
|
|
8820
8978
|
const values = q.q.values;
|
|
8821
8979
|
if (values && "from" in values) {
|
|
8822
|
-
obj.columns = getFromSelectColumns(values.from, obj);
|
|
8823
|
-
values.values = obj.values;
|
|
8980
|
+
obj.columns = getFromSelectColumns(q, values.from, obj);
|
|
8981
|
+
values.values = obj.values[0];
|
|
8824
8982
|
obj.values = values;
|
|
8825
8983
|
}
|
|
8826
|
-
return insert(q, obj
|
|
8984
|
+
return insert(q, obj);
|
|
8827
8985
|
};
|
|
8828
8986
|
const _queryCreateMany = (q, data) => {
|
|
8829
8987
|
createSelect(q);
|
|
@@ -8831,7 +8989,7 @@ const _queryCreateMany = (q, data) => {
|
|
|
8831
8989
|
};
|
|
8832
8990
|
const _queryInsertMany = (q, data) => {
|
|
8833
8991
|
const ctx = createCtx();
|
|
8834
|
-
let result = insert(q, handleManyData(q, data, ctx),
|
|
8992
|
+
let result = insert(q, handleManyData(q, data, ctx), true);
|
|
8835
8993
|
if (!data.length) result = result.none();
|
|
8836
8994
|
return result;
|
|
8837
8995
|
};
|
|
@@ -8853,7 +9011,7 @@ const _queryDefaults = (q, data) => {
|
|
|
8853
9011
|
q.q.defaults = data;
|
|
8854
9012
|
return q;
|
|
8855
9013
|
};
|
|
8856
|
-
class
|
|
9014
|
+
class QueryCreate {
|
|
8857
9015
|
/**
|
|
8858
9016
|
* `create` and `insert` create a single record.
|
|
8859
9017
|
*
|
|
@@ -9257,6 +9415,8 @@ class OnConflictQueryBuilder {
|
|
|
9257
9415
|
set(set) {
|
|
9258
9416
|
let resolved;
|
|
9259
9417
|
for (const key in set) {
|
|
9418
|
+
const column = this.query.shape[key];
|
|
9419
|
+
if (column) throwOnReadOnly$1(this.query, column, key);
|
|
9260
9420
|
if (typeof set[key] === "function") {
|
|
9261
9421
|
if (!resolved) resolved = { ...set };
|
|
9262
9422
|
resolved[key] = set[key]();
|
|
@@ -9549,7 +9709,11 @@ class Having {
|
|
|
9549
9709
|
const before = (q, key, cb) => pushQueryValueImmutable(q, `before${key}`, cb);
|
|
9550
9710
|
const after = (query, key, select, cb, commit) => {
|
|
9551
9711
|
const q = query;
|
|
9552
|
-
pushQueryValueImmutable(
|
|
9712
|
+
pushQueryValueImmutable(
|
|
9713
|
+
q,
|
|
9714
|
+
`after${key}${commit ? "Commit" : ""}`,
|
|
9715
|
+
cb
|
|
9716
|
+
);
|
|
9553
9717
|
const prop = `after${key}Select`;
|
|
9554
9718
|
const set = q.q[prop] = new Set(q.q[prop]);
|
|
9555
9719
|
for (const column of select) {
|
|
@@ -9564,7 +9728,13 @@ const _queryHookAfterQuery = (q, cb) => {
|
|
|
9564
9728
|
return pushQueryValueImmutable(q, "after", cb);
|
|
9565
9729
|
};
|
|
9566
9730
|
const _queryHookBeforeCreate = (q, cb) => {
|
|
9567
|
-
return before(
|
|
9731
|
+
return before(
|
|
9732
|
+
q,
|
|
9733
|
+
"Create",
|
|
9734
|
+
(q2) => cb(
|
|
9735
|
+
new QueryHookUtils(q2, q2.q.columns, "hookCreateSet")
|
|
9736
|
+
)
|
|
9737
|
+
);
|
|
9568
9738
|
};
|
|
9569
9739
|
const _queryHookAfterCreate = (q, select, cb) => {
|
|
9570
9740
|
return after(q, "Create", select, cb);
|
|
@@ -9573,7 +9743,15 @@ const _queryHookAfterCreateCommit = (q, select, cb) => {
|
|
|
9573
9743
|
return after(q, "Create", select, cb, true);
|
|
9574
9744
|
};
|
|
9575
9745
|
const _queryHookBeforeUpdate = (q, cb) => {
|
|
9576
|
-
return before(q, "Update",
|
|
9746
|
+
return before(q, "Update", (q2) => {
|
|
9747
|
+
const columns = [];
|
|
9748
|
+
for (const item of q2.q.updateData) {
|
|
9749
|
+
if (typeof item === "object") {
|
|
9750
|
+
columns.push(...Object.keys(item));
|
|
9751
|
+
}
|
|
9752
|
+
}
|
|
9753
|
+
return cb(new QueryHookUtils(q2, columns, "hookUpdateSet"));
|
|
9754
|
+
});
|
|
9577
9755
|
};
|
|
9578
9756
|
const _queryHookAfterUpdate = (q, select, cb) => {
|
|
9579
9757
|
return after(q, "Update", select, cb);
|
|
@@ -9582,7 +9760,7 @@ const _queryHookAfterUpdateCommit = (q, select, cb) => {
|
|
|
9582
9760
|
return after(q, "Update", select, cb, true);
|
|
9583
9761
|
};
|
|
9584
9762
|
const _queryHookBeforeSave = (q, cb) => {
|
|
9585
|
-
return
|
|
9763
|
+
return _queryHookBeforeUpdate(_queryHookBeforeCreate(q, cb), cb);
|
|
9586
9764
|
};
|
|
9587
9765
|
const _queryHookAfterSave = (q, select, cb) => {
|
|
9588
9766
|
return after(after(q, "Create", select, cb), "Update", select, cb);
|
|
@@ -10635,6 +10813,15 @@ class MergeQueryMethods {
|
|
|
10635
10813
|
}
|
|
10636
10814
|
}
|
|
10637
10815
|
|
|
10816
|
+
const throwOnReadOnly = (q, column, key) => {
|
|
10817
|
+
if (column.data.appReadOnly || column.data.readOnly) {
|
|
10818
|
+
throw new OrchidOrmInternalError(
|
|
10819
|
+
q,
|
|
10820
|
+
"Trying to update a readonly column",
|
|
10821
|
+
{ column: key }
|
|
10822
|
+
);
|
|
10823
|
+
}
|
|
10824
|
+
};
|
|
10638
10825
|
const _queryChangeCounter = (self, op, data) => {
|
|
10639
10826
|
const q = self.q;
|
|
10640
10827
|
q.type = "update";
|
|
@@ -10651,9 +10838,17 @@ const _queryChangeCounter = (self, op, data) => {
|
|
|
10651
10838
|
map = {};
|
|
10652
10839
|
for (const key in data) {
|
|
10653
10840
|
map[key] = { op, arg: data[key] };
|
|
10841
|
+
const column = self.shape[key];
|
|
10842
|
+
if (column) {
|
|
10843
|
+
throwOnReadOnly(self, column, key);
|
|
10844
|
+
}
|
|
10654
10845
|
}
|
|
10655
10846
|
} else {
|
|
10656
10847
|
map = { [data]: { op, arg: 1 } };
|
|
10848
|
+
const column = self.shape[data];
|
|
10849
|
+
if (column) {
|
|
10850
|
+
throwOnReadOnly(self, column, data);
|
|
10851
|
+
}
|
|
10657
10852
|
}
|
|
10658
10853
|
pushQueryValueImmutable(self, "updateData", map);
|
|
10659
10854
|
return self;
|
|
@@ -10677,12 +10872,13 @@ const _queryUpdate = (query, arg) => {
|
|
|
10677
10872
|
const ctx = {};
|
|
10678
10873
|
for (const key in arg) {
|
|
10679
10874
|
const item = shape[key];
|
|
10680
|
-
if (item
|
|
10681
|
-
item.update(query, ctx, set);
|
|
10875
|
+
if (!item && shape !== anyShape) {
|
|
10682
10876
|
delete set[key];
|
|
10683
|
-
} else if (
|
|
10877
|
+
} else if (item.data.virtual) {
|
|
10878
|
+
item.update?.(query, ctx, set);
|
|
10684
10879
|
delete set[key];
|
|
10685
10880
|
} else {
|
|
10881
|
+
if (item) throwOnReadOnly(query, item, key);
|
|
10686
10882
|
let value = set[key];
|
|
10687
10883
|
if (typeof value === "function") {
|
|
10688
10884
|
value = resolveSubQueryCallbackV2(
|
|
@@ -10708,7 +10904,7 @@ const _queryUpdate = (query, arg) => {
|
|
|
10708
10904
|
"with"
|
|
10709
10905
|
);
|
|
10710
10906
|
} else {
|
|
10711
|
-
const encode =
|
|
10907
|
+
const encode = item?.data.encode;
|
|
10712
10908
|
if (encode) set[key] = encode(value);
|
|
10713
10909
|
}
|
|
10714
10910
|
}
|
|
@@ -11356,7 +11552,7 @@ function orCreate(query, data, updateData, mergeData) {
|
|
|
11356
11552
|
q22.q.log = q2.q.log;
|
|
11357
11553
|
q22.q.logger = q2.q.logger;
|
|
11358
11554
|
q22.q.type = "upsert";
|
|
11359
|
-
q22.q.beforeCreate = q2.q.beforeCreate;
|
|
11555
|
+
q22.q.beforeCreate = q2.q.beforeCreate?.map((cb) => () => cb(c));
|
|
11360
11556
|
if (hasAfterCallback) {
|
|
11361
11557
|
((_a = q22.q).afterCreate ?? (_a.afterCreate = [])).push(
|
|
11362
11558
|
(data2, query2) => afterHooks && Promise.all([...afterHooks].map((fn) => fn(data2, query2)))
|
|
@@ -11378,109 +11574,13 @@ function orCreate(query, data, updateData, mergeData) {
|
|
|
11378
11574
|
};
|
|
11379
11575
|
return query;
|
|
11380
11576
|
}
|
|
11381
|
-
|
|
11382
|
-
|
|
11383
|
-
|
|
11384
|
-
|
|
11385
|
-
|
|
11386
|
-
|
|
11387
|
-
|
|
11388
|
-
*
|
|
11389
|
-
* It can take `update` and `create` objects, then they are used separately for update and create queries.
|
|
11390
|
-
* Or, it can take `data` and `create` objects, `data` will be used for update and be mixed to `create` object.
|
|
11391
|
-
*
|
|
11392
|
-
* `data` and `update` objects are of the same type that's expected by `update` method, `create` object is of type of `create` method argument.
|
|
11393
|
-
*
|
|
11394
|
-
* No values are returned by default, place `select` or `selectAll` before `upsert` to specify returning columns.
|
|
11395
|
-
*
|
|
11396
|
-
* ```ts
|
|
11397
|
-
* await User.selectAll()
|
|
11398
|
-
* .findBy({ email: 'some@email.com' })
|
|
11399
|
-
* .upsert({
|
|
11400
|
-
* data: {
|
|
11401
|
-
* // update record's name
|
|
11402
|
-
* name: 'new name',
|
|
11403
|
-
* // supports sql and nested queries
|
|
11404
|
-
* fromSQL: () => sql`*SQL expression*`,
|
|
11405
|
-
* fromQuery: () => db.someTable.create(data).get('column'),
|
|
11406
|
-
* },
|
|
11407
|
-
* create: {
|
|
11408
|
-
* // create a new record with this email and a name 'new name'
|
|
11409
|
-
* email: 'some@email.com',
|
|
11410
|
-
* // supports sql and nested queries as well
|
|
11411
|
-
* },
|
|
11412
|
-
* create: {
|
|
11413
|
-
* // create a new record with this email and a name 'new name'
|
|
11414
|
-
* email: 'some@email.com',
|
|
11415
|
-
* },
|
|
11416
|
-
* });
|
|
11417
|
-
*
|
|
11418
|
-
* // the same as above but using `update` and `create`
|
|
11419
|
-
* await User.selectAll()
|
|
11420
|
-
* .findBy({ email: 'some@email.com' })
|
|
11421
|
-
* .upsert({
|
|
11422
|
-
* update: {
|
|
11423
|
-
* name: 'updated user',
|
|
11424
|
-
* },
|
|
11425
|
-
* create: {
|
|
11426
|
-
* email: 'some@email.com',
|
|
11427
|
-
* // here we use a different name when creating a record
|
|
11428
|
-
* name: 'created user',
|
|
11429
|
-
* },
|
|
11430
|
-
* });
|
|
11431
|
-
* ```
|
|
11432
|
-
*
|
|
11433
|
-
* The data for `create` may be returned from a function, it won't be called if a record was updated:
|
|
11434
|
-
*
|
|
11435
|
-
* ```ts
|
|
11436
|
-
* await User.selectAll()
|
|
11437
|
-
* .findBy({ email: 'some@email.com' })
|
|
11438
|
-
* .upsert({
|
|
11439
|
-
* update: {
|
|
11440
|
-
* name: 'updated user',
|
|
11441
|
-
* },
|
|
11442
|
-
* create: () => ({
|
|
11443
|
-
* email: 'some@email.com',
|
|
11444
|
-
* name: 'created user',
|
|
11445
|
-
* }),
|
|
11446
|
-
* });
|
|
11447
|
-
*
|
|
11448
|
-
* // the same as above using `data`
|
|
11449
|
-
* await User.selectAll()
|
|
11450
|
-
* .findBy({ email: 'some@email.com' })
|
|
11451
|
-
* .upsert({
|
|
11452
|
-
* data: {
|
|
11453
|
-
* name: 'updated user',
|
|
11454
|
-
* },
|
|
11455
|
-
* create: () => ({
|
|
11456
|
-
* email: 'some@email.com',
|
|
11457
|
-
* // name in `create` is overriding the name from `data`
|
|
11458
|
-
* name: 'created user',
|
|
11459
|
-
* }),
|
|
11460
|
-
* });
|
|
11461
|
-
* ```
|
|
11462
|
-
*
|
|
11463
|
-
* Data from `data` or `update` is passed to the `create` function and can be used:
|
|
11464
|
-
*
|
|
11465
|
-
* ```ts
|
|
11466
|
-
* const user = await User.selectAll()
|
|
11467
|
-
* .findBy({ email: 'some@email.com' })
|
|
11468
|
-
* .upsert({
|
|
11469
|
-
* data: {
|
|
11470
|
-
* name: 'updated user',
|
|
11471
|
-
* },
|
|
11472
|
-
* // `updateData` has the exact type of what is passed to `data`
|
|
11473
|
-
* create: (updateData) => ({
|
|
11474
|
-
* email: `${updateData.name}@email.com`,
|
|
11475
|
-
* }),
|
|
11476
|
-
* });
|
|
11477
|
-
* ```
|
|
11478
|
-
*
|
|
11479
|
-
* `upsert` works in the exact same way as [orCreate](#orCreate), but with `UPDATE` statement instead of `SELECT`.
|
|
11480
|
-
* it also performs a single query if the record exists, and two queries if there is no record yet.
|
|
11481
|
-
*
|
|
11482
|
-
* @param data - `update` property for the data to update, `create` property for the data to create
|
|
11483
|
-
*/
|
|
11577
|
+
const QueryOrCreate = {
|
|
11578
|
+
orCreate(data) {
|
|
11579
|
+
return orCreate(_clone(this), data);
|
|
11580
|
+
}
|
|
11581
|
+
};
|
|
11582
|
+
|
|
11583
|
+
const QueryUpsert = {
|
|
11484
11584
|
upsert(data) {
|
|
11485
11585
|
const q = _clone(this);
|
|
11486
11586
|
let updateData;
|
|
@@ -11495,75 +11595,7 @@ class QueryUpsertOrCreate {
|
|
|
11495
11595
|
}
|
|
11496
11596
|
return orCreate(q, data.create, updateData, mergeData);
|
|
11497
11597
|
}
|
|
11498
|
-
|
|
11499
|
-
* `orCreate` creates a record only if it was not found by conditions.
|
|
11500
|
-
*
|
|
11501
|
-
* `find` or `findBy` must precede `orCreate`.
|
|
11502
|
-
*
|
|
11503
|
-
* It is accepting the same argument as `create` commands.
|
|
11504
|
-
*
|
|
11505
|
-
* No result is returned by default, place `get`, `select`, or `selectAll` before `orCreate` to specify returning columns.
|
|
11506
|
-
*
|
|
11507
|
-
* ```ts
|
|
11508
|
-
* const user = await db.user
|
|
11509
|
-
* .selectAll()
|
|
11510
|
-
* .findBy({ email: 'some@email.com' })
|
|
11511
|
-
* .orCreate({
|
|
11512
|
-
* email: 'some@email.com',
|
|
11513
|
-
* name: 'created user',
|
|
11514
|
-
* // supports sql and nested queries
|
|
11515
|
-
* fromSQL: () => sql`*SQL expression*`,
|
|
11516
|
-
* fromQuery: () => db.someTable.create(data).get('column'),
|
|
11517
|
-
* fromRelated: (q) => q.relatedTable.update(data).get('column'),
|
|
11518
|
-
* });
|
|
11519
|
-
* ```
|
|
11520
|
-
*
|
|
11521
|
-
* The data can be returned from a function, it won't be called if the record was found:
|
|
11522
|
-
*
|
|
11523
|
-
* ```ts
|
|
11524
|
-
* const user = await User.selectAll()
|
|
11525
|
-
* .findBy({ email: 'some@email.com' })
|
|
11526
|
-
* .orCreate(() => ({
|
|
11527
|
-
* email: 'some@email.com',
|
|
11528
|
-
* name: 'created user',
|
|
11529
|
-
* }));
|
|
11530
|
-
* ```
|
|
11531
|
-
*
|
|
11532
|
-
* `orCreate` works by performing just a single query in the case if the record exists, and one additional query when the record does not exist.
|
|
11533
|
-
*
|
|
11534
|
-
* At first, it performs a "find" query, the query cost is exact same as if you didn't use `orCreate`.
|
|
11535
|
-
*
|
|
11536
|
-
* Then, if the record wasn't found, it performs a single query with CTE expressions to try finding it again, for the case it was already created just a moment before,
|
|
11537
|
-
* and then it creates the record if it's still not found. Using such CTE allows to skip using transactions, while still conforming to atomicity.
|
|
11538
|
-
*
|
|
11539
|
-
* ```sql
|
|
11540
|
-
* -- first query
|
|
11541
|
-
* SELECT * FROM "table" WHERE "key" = 'value'
|
|
11542
|
-
*
|
|
11543
|
-
* -- the record could have been created in between these two queries
|
|
11544
|
-
*
|
|
11545
|
-
* -- second query
|
|
11546
|
-
* WITH find_row AS (
|
|
11547
|
-
* SELECT * FROM "table" WHERE "key" = 'value'
|
|
11548
|
-
* )
|
|
11549
|
-
* WITH insert_row AS (
|
|
11550
|
-
* INSERT INTO "table" ("key")
|
|
11551
|
-
* SELECT 'value'
|
|
11552
|
-
* -- skip the insert if the row already exists
|
|
11553
|
-
* WHERE NOT EXISTS (SELECT 1 FROM find_row)
|
|
11554
|
-
* RETURNING *
|
|
11555
|
-
* )
|
|
11556
|
-
* SELECT * FROM find_row
|
|
11557
|
-
* UNION ALL
|
|
11558
|
-
* SELECT * FROM insert_row
|
|
11559
|
-
* ```
|
|
11560
|
-
*
|
|
11561
|
-
* @param data - the same data as for `create`, it may be returned from a callback
|
|
11562
|
-
*/
|
|
11563
|
-
orCreate(data) {
|
|
11564
|
-
return orCreate(_clone(this), data);
|
|
11565
|
-
}
|
|
11566
|
-
}
|
|
11598
|
+
};
|
|
11567
11599
|
|
|
11568
11600
|
class SqlMethod {
|
|
11569
11601
|
sql(...args) {
|
|
@@ -12647,6 +12679,8 @@ class QueryMethods {
|
|
|
12647
12679
|
return _chain(this, _clone(rel.query), rel);
|
|
12648
12680
|
}
|
|
12649
12681
|
}
|
|
12682
|
+
Object.assign(QueryMethods.prototype, QueryUpsert);
|
|
12683
|
+
Object.assign(QueryMethods.prototype, QueryOrCreate);
|
|
12650
12684
|
applyMixins(QueryMethods, [
|
|
12651
12685
|
AsMethods,
|
|
12652
12686
|
AggregateMethods,
|
|
@@ -12657,7 +12691,7 @@ applyMixins(QueryMethods, [
|
|
|
12657
12691
|
WithMethods,
|
|
12658
12692
|
Union,
|
|
12659
12693
|
JsonMethods,
|
|
12660
|
-
|
|
12694
|
+
QueryCreate,
|
|
12661
12695
|
Update,
|
|
12662
12696
|
Delete,
|
|
12663
12697
|
Transaction,
|
|
@@ -12669,7 +12703,6 @@ applyMixins(QueryMethods, [
|
|
|
12669
12703
|
Then,
|
|
12670
12704
|
QueryLog,
|
|
12671
12705
|
QueryHooks,
|
|
12672
|
-
QueryUpsertOrCreate,
|
|
12673
12706
|
QueryGet,
|
|
12674
12707
|
MergeQueryMethods,
|
|
12675
12708
|
SqlMethod,
|
|
@@ -12845,6 +12878,7 @@ class Db extends QueryMethods {
|
|
|
12845
12878
|
let hasParsers = false;
|
|
12846
12879
|
let modifyQuery = void 0;
|
|
12847
12880
|
let prepareSelectAll = false;
|
|
12881
|
+
let hasHookSetters;
|
|
12848
12882
|
const { snakeCase } = options;
|
|
12849
12883
|
for (const key in shape) {
|
|
12850
12884
|
const column = shape[key];
|
|
@@ -12880,6 +12914,9 @@ class Db extends QueryMethods {
|
|
|
12880
12914
|
column.data.runtimeDefault = encode ? () => encode(def()) : def;
|
|
12881
12915
|
}
|
|
12882
12916
|
}
|
|
12917
|
+
if (column.data.setOnCreate || column.data.setOnUpdate || column.data.setOnSave) {
|
|
12918
|
+
hasHookSetters = true;
|
|
12919
|
+
}
|
|
12883
12920
|
}
|
|
12884
12921
|
this.q = {
|
|
12885
12922
|
adapter,
|
|
@@ -12954,6 +12991,27 @@ class Db extends QueryMethods {
|
|
|
12954
12991
|
if (softDelete) {
|
|
12955
12992
|
enableSoftDelete(this, table, shape, softDelete, scopes);
|
|
12956
12993
|
}
|
|
12994
|
+
if (hasHookSetters) {
|
|
12995
|
+
const hooks = {
|
|
12996
|
+
setOnCreate: _queryHookBeforeCreate,
|
|
12997
|
+
setOnUpdate: _queryHookBeforeUpdate,
|
|
12998
|
+
setOnSave: _queryHookBeforeSave
|
|
12999
|
+
};
|
|
13000
|
+
for (const key in shape) {
|
|
13001
|
+
const { data } = shape[key];
|
|
13002
|
+
for (const hookKey in hooks) {
|
|
13003
|
+
const fn = data[hookKey];
|
|
13004
|
+
if (fn) {
|
|
13005
|
+
hooks[hookKey](this, (arg) => {
|
|
13006
|
+
const value = fn(arg);
|
|
13007
|
+
if (value !== void 0) {
|
|
13008
|
+
arg.set({ [key]: value });
|
|
13009
|
+
}
|
|
13010
|
+
});
|
|
13011
|
+
}
|
|
13012
|
+
}
|
|
13013
|
+
}
|
|
13014
|
+
}
|
|
12957
13015
|
}
|
|
12958
13016
|
[inspect.custom]() {
|
|
12959
13017
|
return `Query<${this.table}>`;
|
|
@@ -13287,5 +13345,5 @@ function copyTableData(query, arg) {
|
|
|
13287
13345
|
return q;
|
|
13288
13346
|
}
|
|
13289
13347
|
|
|
13290
|
-
export { Adapter, AfterCommitError, AggregateMethods, ArrayColumn, AsMethods, BigIntColumn, BigSerialColumn, BitColumn, BitVaryingColumn, BooleanColumn, BoxColumn, ByteaColumn, CidrColumn, CircleColumn, CitextColumn, Clear, ColumnRefExpression, ColumnType, ComputedColumn,
|
|
13348
|
+
export { Adapter, AfterCommitError, AggregateMethods, ArrayColumn, AsMethods, BigIntColumn, BigSerialColumn, BitColumn, BitVaryingColumn, BooleanColumn, BoxColumn, ByteaColumn, CidrColumn, CircleColumn, CitextColumn, Clear, ColumnRefExpression, ColumnType, ComputedColumn, CustomTypeColumn, DateBaseColumn, DateColumn, DateTimeBaseClass, DateTimeTzBaseClass, Db, DecimalColumn, Delete, DomainColumn, DoublePrecisionColumn, DynamicRawSQL, EnumColumn, ExpressionMethods, FnExpression, For, FromMethods, Having, InetColumn, IntegerBaseColumn, IntegerColumn, IntervalColumn, JSONColumn, JSONTextColumn, Join, JsonMethods, LimitedTextBaseColumn, LineColumn, LsegColumn, MacAddr8Column, MacAddrColumn, MergeQueryMethods, MoneyColumn, MoreThanOneRowError, NotFoundError, NumberAsStringBaseColumn, NumberBaseColumn, OnConflictQueryBuilder, OnMethods, Operators, OrExpression, OrchidOrmError, OrchidOrmInternalError, PathColumn, PointColumn, PolygonColumn, PostgisGeographyPointColumn, QueryCreate, QueryError, QueryGet, QueryHooks, QueryLog, QueryMethods, QueryUpsert, RawSQL, RealColumn, RefExpression, SearchMethods, Select, SerialColumn, SmallIntColumn, SmallSerialColumn, SqlMethod, StringColumn, TextBaseColumn, TextColumn, Then, TimeColumn, TimestampColumn, TimestampTZColumn, Transaction, TransactionAdapter, TransformMethods, TsQueryColumn, TsVectorColumn, UUIDColumn, UnhandledTypeError, Union, UnknownColumn, Update, VarCharColumn, VirtualColumn, Where, WithMethods, XMLColumn, _clone, _getSelectableColumn, _initQueryBuilder, _queryAfterSaveCommit, _queryAll, _queryAs, _queryChangeCounter, _queryCreate, _queryCreateFrom, _queryCreateMany, _queryCreateManyFrom, _queryDefaults, _queryDelete, _queryExec, _queryFindBy, _queryFindByOptional, _queryGet, _queryGetOptional, _queryHookAfterCreate, _queryHookAfterCreateCommit, _queryHookAfterDelete, _queryHookAfterDeleteCommit, _queryHookAfterQuery, _queryHookAfterSave, _queryHookAfterUpdate, _queryHookAfterUpdateCommit, _queryHookBeforeCreate, _queryHookBeforeDelete, _queryHookBeforeQuery, _queryHookBeforeSave, _queryHookBeforeUpdate, _queryInsert, _queryInsertFrom, _queryInsertMany, _queryInsertManyFrom, _queryJoinOn, _queryJoinOnJsonPathEquals, _queryJoinOrOn, _queryOr, _queryOrNot, _queryResolveAlias, _queryRows, _querySelect, _queryTake, _queryTakeOptional, _queryUnion, _queryUpdate, _queryUpdateOrThrow, _queryWhere, _queryWhereExists, _queryWhereIn, _queryWhereNot, _queryWhereNotOneOf, _queryWhereNotSql, _queryWhereOneOf, _queryWhereSql, _runAfterCommitHooks, addColumnParserToQuery, addParserForRawExpression, addParserForSelectItem, addQueryOn, anyShape, applyComputedColumns, assignDbDataToColumn, checkIfASimpleQuery, cloneQueryBaseUnscoped, columnCheckToCode, columnCode, columnExcludesToCode, columnForeignKeysToCode, columnIndexesToCode, columnsShapeToCode, commitSql$1 as commitSql, constraintInnerToCode, constraintToCode, copyTableData, countSelect, createDb, defaultSchemaConfig, escapeForLog, escapeForMigration, escapeString, excludeInnerToCode, excludeToCode, extendQuery, filterResult, foreignKeyArgumentToCode, getClonedQueryData, getColumnBaseType, getColumnInfo, getColumnTypes, getFullColumnTable, getPrimaryKeys, getQueryAs, getShapeFromSelect, getSqlText, handleResult, identityToCode, indexInnerToCode, indexToCode, isDefaultTimeStamp, isInUserTransaction, isQueryReturnsAll, isSelectingCount, joinSubQuery, logParamToLogObject, makeColumnTypes, makeColumnsByType, makeFnExpression, moveQueryValueToWith, parseRecord, parseTableData, parseTableDataInput, postgisTypmodToSql, primaryKeyInnerToCode, processComputedBatches, processComputedResult, processSelectArg, pushLimitSQL, pushQueryArrayImmutable, pushQueryOn, pushQueryOnForOuter, pushQueryOrOn, pushTableDataCode, queryFrom, queryFromSql, queryJson, queryMethodByReturnType, queryTypeWithLimitOne, queryWrap, raw, referencesArgsToCode, resolveSubQueryCallbackV2, rollbackSql$1 as rollbackSql, saveAliasedShape, setColumnDefaultParse, setColumnEncode, setColumnParse, setColumnParseNull, setParserForSelectedString, setQueryObjectValueImmutable, setQueryOperators, simplifyColumnDefault, sqlFn, sqlQueryArgsToExpression, tableDataMethods, templateLiteralToSQL, testTransaction, throwIfJoinLateral, throwIfNoWhere, toSQL };
|
|
13291
13349
|
//# sourceMappingURL=index.mjs.map
|