pqb 0.54.1 → 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 +87 -100
- package/dist/index.js +168 -282
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +136 -248
- 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,
|
|
@@ -8823,38 +8814,50 @@ const processCreateItem = (q, item, rowIndex, ctx, encoders) => {
|
|
|
8823
8814
|
var _a;
|
|
8824
8815
|
const { shape } = q.q;
|
|
8825
8816
|
for (const key in item) {
|
|
8826
|
-
|
|
8827
|
-
|
|
8828
|
-
|
|
8829
|
-
|
|
8830
|
-
q,
|
|
8831
|
-
value
|
|
8832
|
-
);
|
|
8833
|
-
if (value && typeof value === "object" && value instanceof Db) {
|
|
8834
|
-
moveQueryValueToWith(
|
|
8835
|
-
q,
|
|
8836
|
-
(_a = q.q).insertWith ?? (_a.insertWith = {}),
|
|
8837
|
-
value,
|
|
8838
|
-
item,
|
|
8839
|
-
key,
|
|
8840
|
-
rowIndex
|
|
8841
|
-
);
|
|
8842
|
-
}
|
|
8843
|
-
}
|
|
8844
|
-
if (!ctx.columns.has(key) && (shape[key] && !shape[key].data.readonly || shape === anyShape) && value !== void 0) {
|
|
8845
|
-
ctx.columns.set(key, ctx.columns.size);
|
|
8846
|
-
encoders[key] = shape[key]?.data.encode;
|
|
8847
|
-
}
|
|
8848
|
-
} else if (shape[key] instanceof VirtualColumn) {
|
|
8849
|
-
shape[key].create?.(
|
|
8817
|
+
const column = shape[key];
|
|
8818
|
+
if (!column) continue;
|
|
8819
|
+
if (column.data.virtual) {
|
|
8820
|
+
column.create?.(
|
|
8850
8821
|
q,
|
|
8851
8822
|
ctx,
|
|
8852
8823
|
item,
|
|
8853
8824
|
rowIndex
|
|
8854
8825
|
);
|
|
8826
|
+
continue;
|
|
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;
|
|
8855
8849
|
}
|
|
8856
8850
|
}
|
|
8857
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
|
+
);
|
|
8859
|
+
}
|
|
8860
|
+
};
|
|
8858
8861
|
const createCtx = () => ({
|
|
8859
8862
|
columns: /* @__PURE__ */ new Map(),
|
|
8860
8863
|
resultAll: void 0
|
|
@@ -8928,7 +8931,7 @@ const insert = (self, {
|
|
|
8928
8931
|
}
|
|
8929
8932
|
return self;
|
|
8930
8933
|
};
|
|
8931
|
-
const getFromSelectColumns = (from, obj, many) => {
|
|
8934
|
+
const getFromSelectColumns = (q, from, obj, many) => {
|
|
8932
8935
|
if (!many && !queryTypeWithLimitOne[from.q.returnType]) {
|
|
8933
8936
|
throw new Error(
|
|
8934
8937
|
"Cannot create based on a query which returns multiple records"
|
|
@@ -8946,12 +8949,16 @@ const getFromSelectColumns = (from, obj, many) => {
|
|
|
8946
8949
|
if (obj?.columns) {
|
|
8947
8950
|
queryColumns.push(...obj.columns);
|
|
8948
8951
|
}
|
|
8952
|
+
for (const key of queryColumns) {
|
|
8953
|
+
const column = q.shape[key];
|
|
8954
|
+
if (column) throwOnReadOnly$1(from, column, key);
|
|
8955
|
+
}
|
|
8949
8956
|
return queryColumns;
|
|
8950
8957
|
};
|
|
8951
8958
|
const insertFromQuery = (q, from, many, data) => {
|
|
8952
8959
|
const ctx = createCtx();
|
|
8953
8960
|
const obj = data && handleOneData(q, data, ctx);
|
|
8954
|
-
const columns = getFromSelectColumns(from, obj, many);
|
|
8961
|
+
const columns = getFromSelectColumns(q, from, obj, many);
|
|
8955
8962
|
return insert(
|
|
8956
8963
|
q,
|
|
8957
8964
|
{
|
|
@@ -8970,7 +8977,7 @@ const _queryInsert = (q, data) => {
|
|
|
8970
8977
|
const obj = handleOneData(q, data, ctx);
|
|
8971
8978
|
const values = q.q.values;
|
|
8972
8979
|
if (values && "from" in values) {
|
|
8973
|
-
obj.columns = getFromSelectColumns(values.from, obj);
|
|
8980
|
+
obj.columns = getFromSelectColumns(q, values.from, obj);
|
|
8974
8981
|
values.values = obj.values[0];
|
|
8975
8982
|
obj.values = values;
|
|
8976
8983
|
}
|
|
@@ -9004,7 +9011,7 @@ const _queryDefaults = (q, data) => {
|
|
|
9004
9011
|
q.q.defaults = data;
|
|
9005
9012
|
return q;
|
|
9006
9013
|
};
|
|
9007
|
-
class
|
|
9014
|
+
class QueryCreate {
|
|
9008
9015
|
/**
|
|
9009
9016
|
* `create` and `insert` create a single record.
|
|
9010
9017
|
*
|
|
@@ -9408,6 +9415,8 @@ class OnConflictQueryBuilder {
|
|
|
9408
9415
|
set(set) {
|
|
9409
9416
|
let resolved;
|
|
9410
9417
|
for (const key in set) {
|
|
9418
|
+
const column = this.query.shape[key];
|
|
9419
|
+
if (column) throwOnReadOnly$1(this.query, column, key);
|
|
9411
9420
|
if (typeof set[key] === "function") {
|
|
9412
9421
|
if (!resolved) resolved = { ...set };
|
|
9413
9422
|
resolved[key] = set[key]();
|
|
@@ -9700,7 +9709,11 @@ class Having {
|
|
|
9700
9709
|
const before = (q, key, cb) => pushQueryValueImmutable(q, `before${key}`, cb);
|
|
9701
9710
|
const after = (query, key, select, cb, commit) => {
|
|
9702
9711
|
const q = query;
|
|
9703
|
-
pushQueryValueImmutable(
|
|
9712
|
+
pushQueryValueImmutable(
|
|
9713
|
+
q,
|
|
9714
|
+
`after${key}${commit ? "Commit" : ""}`,
|
|
9715
|
+
cb
|
|
9716
|
+
);
|
|
9704
9717
|
const prop = `after${key}Select`;
|
|
9705
9718
|
const set = q.q[prop] = new Set(q.q[prop]);
|
|
9706
9719
|
for (const column of select) {
|
|
@@ -9715,7 +9728,13 @@ const _queryHookAfterQuery = (q, cb) => {
|
|
|
9715
9728
|
return pushQueryValueImmutable(q, "after", cb);
|
|
9716
9729
|
};
|
|
9717
9730
|
const _queryHookBeforeCreate = (q, cb) => {
|
|
9718
|
-
return before(
|
|
9731
|
+
return before(
|
|
9732
|
+
q,
|
|
9733
|
+
"Create",
|
|
9734
|
+
(q2) => cb(
|
|
9735
|
+
new QueryHookUtils(q2, q2.q.columns, "hookCreateSet")
|
|
9736
|
+
)
|
|
9737
|
+
);
|
|
9719
9738
|
};
|
|
9720
9739
|
const _queryHookAfterCreate = (q, select, cb) => {
|
|
9721
9740
|
return after(q, "Create", select, cb);
|
|
@@ -9724,7 +9743,15 @@ const _queryHookAfterCreateCommit = (q, select, cb) => {
|
|
|
9724
9743
|
return after(q, "Create", select, cb, true);
|
|
9725
9744
|
};
|
|
9726
9745
|
const _queryHookBeforeUpdate = (q, cb) => {
|
|
9727
|
-
return before(q, "Update", (q2) =>
|
|
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
|
+
});
|
|
9728
9755
|
};
|
|
9729
9756
|
const _queryHookAfterUpdate = (q, select, cb) => {
|
|
9730
9757
|
return after(q, "Update", select, cb);
|
|
@@ -9733,11 +9760,7 @@ const _queryHookAfterUpdateCommit = (q, select, cb) => {
|
|
|
9733
9760
|
return after(q, "Update", select, cb, true);
|
|
9734
9761
|
};
|
|
9735
9762
|
const _queryHookBeforeSave = (q, cb) => {
|
|
9736
|
-
return
|
|
9737
|
-
before(q, "Create", (q2) => cb(new QueryHookUtils(q2, "hookCreateSet"))),
|
|
9738
|
-
"Update",
|
|
9739
|
-
(q2) => cb(new QueryHookUtils(q2, "hookUpdateSet"))
|
|
9740
|
-
);
|
|
9763
|
+
return _queryHookBeforeUpdate(_queryHookBeforeCreate(q, cb), cb);
|
|
9741
9764
|
};
|
|
9742
9765
|
const _queryHookAfterSave = (q, select, cb) => {
|
|
9743
9766
|
return after(after(q, "Create", select, cb), "Update", select, cb);
|
|
@@ -9760,21 +9783,6 @@ const _queryHookAfterDelete = (q, select, cb) => {
|
|
|
9760
9783
|
const _queryHookAfterDeleteCommit = (q, select, cb) => {
|
|
9761
9784
|
return after(q, "Delete", select, cb, true);
|
|
9762
9785
|
};
|
|
9763
|
-
class QueryHookUtils {
|
|
9764
|
-
constructor(query, key) {
|
|
9765
|
-
this.query = query;
|
|
9766
|
-
this.key = key;
|
|
9767
|
-
this.set = (data) => {
|
|
9768
|
-
const set = {};
|
|
9769
|
-
for (const key in data) {
|
|
9770
|
-
if (data[key] !== void 0) {
|
|
9771
|
-
set[key] = data[key];
|
|
9772
|
-
}
|
|
9773
|
-
}
|
|
9774
|
-
pushQueryValueImmutable(this.query, this.key, set);
|
|
9775
|
-
};
|
|
9776
|
-
}
|
|
9777
|
-
}
|
|
9778
9786
|
class QueryHooks {
|
|
9779
9787
|
/**
|
|
9780
9788
|
* Run the function before any kind of query.
|
|
@@ -10805,6 +10813,15 @@ class MergeQueryMethods {
|
|
|
10805
10813
|
}
|
|
10806
10814
|
}
|
|
10807
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
|
+
};
|
|
10808
10825
|
const _queryChangeCounter = (self, op, data) => {
|
|
10809
10826
|
const q = self.q;
|
|
10810
10827
|
q.type = "update";
|
|
@@ -10821,9 +10838,17 @@ const _queryChangeCounter = (self, op, data) => {
|
|
|
10821
10838
|
map = {};
|
|
10822
10839
|
for (const key in data) {
|
|
10823
10840
|
map[key] = { op, arg: data[key] };
|
|
10841
|
+
const column = self.shape[key];
|
|
10842
|
+
if (column) {
|
|
10843
|
+
throwOnReadOnly(self, column, key);
|
|
10844
|
+
}
|
|
10824
10845
|
}
|
|
10825
10846
|
} else {
|
|
10826
10847
|
map = { [data]: { op, arg: 1 } };
|
|
10848
|
+
const column = self.shape[data];
|
|
10849
|
+
if (column) {
|
|
10850
|
+
throwOnReadOnly(self, column, data);
|
|
10851
|
+
}
|
|
10827
10852
|
}
|
|
10828
10853
|
pushQueryValueImmutable(self, "updateData", map);
|
|
10829
10854
|
return self;
|
|
@@ -10847,12 +10872,13 @@ const _queryUpdate = (query, arg) => {
|
|
|
10847
10872
|
const ctx = {};
|
|
10848
10873
|
for (const key in arg) {
|
|
10849
10874
|
const item = shape[key];
|
|
10850
|
-
if (item
|
|
10851
|
-
item.update(query, ctx, set);
|
|
10875
|
+
if (!item && shape !== anyShape) {
|
|
10852
10876
|
delete set[key];
|
|
10853
|
-
} else if (
|
|
10877
|
+
} else if (item.data.virtual) {
|
|
10878
|
+
item.update?.(query, ctx, set);
|
|
10854
10879
|
delete set[key];
|
|
10855
10880
|
} else {
|
|
10881
|
+
if (item) throwOnReadOnly(query, item, key);
|
|
10856
10882
|
let value = set[key];
|
|
10857
10883
|
if (typeof value === "function") {
|
|
10858
10884
|
value = resolveSubQueryCallbackV2(
|
|
@@ -10878,7 +10904,7 @@ const _queryUpdate = (query, arg) => {
|
|
|
10878
10904
|
"with"
|
|
10879
10905
|
);
|
|
10880
10906
|
} else {
|
|
10881
|
-
const encode =
|
|
10907
|
+
const encode = item?.data.encode;
|
|
10882
10908
|
if (encode) set[key] = encode(value);
|
|
10883
10909
|
}
|
|
10884
10910
|
}
|
|
@@ -11548,109 +11574,13 @@ function orCreate(query, data, updateData, mergeData) {
|
|
|
11548
11574
|
};
|
|
11549
11575
|
return query;
|
|
11550
11576
|
}
|
|
11551
|
-
|
|
11552
|
-
|
|
11553
|
-
|
|
11554
|
-
|
|
11555
|
-
|
|
11556
|
-
|
|
11557
|
-
|
|
11558
|
-
*
|
|
11559
|
-
* It can take `update` and `create` objects, then they are used separately for update and create queries.
|
|
11560
|
-
* Or, it can take `data` and `create` objects, `data` will be used for update and be mixed to `create` object.
|
|
11561
|
-
*
|
|
11562
|
-
* `data` and `update` objects are of the same type that's expected by `update` method, `create` object is of type of `create` method argument.
|
|
11563
|
-
*
|
|
11564
|
-
* No values are returned by default, place `select` or `selectAll` before `upsert` to specify returning columns.
|
|
11565
|
-
*
|
|
11566
|
-
* ```ts
|
|
11567
|
-
* await User.selectAll()
|
|
11568
|
-
* .findBy({ email: 'some@email.com' })
|
|
11569
|
-
* .upsert({
|
|
11570
|
-
* data: {
|
|
11571
|
-
* // update record's name
|
|
11572
|
-
* name: 'new name',
|
|
11573
|
-
* // supports sql and nested queries
|
|
11574
|
-
* fromSQL: () => sql`*SQL expression*`,
|
|
11575
|
-
* fromQuery: () => db.someTable.create(data).get('column'),
|
|
11576
|
-
* },
|
|
11577
|
-
* create: {
|
|
11578
|
-
* // create a new record with this email and a name 'new name'
|
|
11579
|
-
* email: 'some@email.com',
|
|
11580
|
-
* // supports sql and nested queries as well
|
|
11581
|
-
* },
|
|
11582
|
-
* create: {
|
|
11583
|
-
* // create a new record with this email and a name 'new name'
|
|
11584
|
-
* email: 'some@email.com',
|
|
11585
|
-
* },
|
|
11586
|
-
* });
|
|
11587
|
-
*
|
|
11588
|
-
* // the same as above but using `update` and `create`
|
|
11589
|
-
* await User.selectAll()
|
|
11590
|
-
* .findBy({ email: 'some@email.com' })
|
|
11591
|
-
* .upsert({
|
|
11592
|
-
* update: {
|
|
11593
|
-
* name: 'updated user',
|
|
11594
|
-
* },
|
|
11595
|
-
* create: {
|
|
11596
|
-
* email: 'some@email.com',
|
|
11597
|
-
* // here we use a different name when creating a record
|
|
11598
|
-
* name: 'created user',
|
|
11599
|
-
* },
|
|
11600
|
-
* });
|
|
11601
|
-
* ```
|
|
11602
|
-
*
|
|
11603
|
-
* The data for `create` may be returned from a function, it won't be called if a record was updated:
|
|
11604
|
-
*
|
|
11605
|
-
* ```ts
|
|
11606
|
-
* await User.selectAll()
|
|
11607
|
-
* .findBy({ email: 'some@email.com' })
|
|
11608
|
-
* .upsert({
|
|
11609
|
-
* update: {
|
|
11610
|
-
* name: 'updated user',
|
|
11611
|
-
* },
|
|
11612
|
-
* create: () => ({
|
|
11613
|
-
* email: 'some@email.com',
|
|
11614
|
-
* name: 'created user',
|
|
11615
|
-
* }),
|
|
11616
|
-
* });
|
|
11617
|
-
*
|
|
11618
|
-
* // the same as above using `data`
|
|
11619
|
-
* await User.selectAll()
|
|
11620
|
-
* .findBy({ email: 'some@email.com' })
|
|
11621
|
-
* .upsert({
|
|
11622
|
-
* data: {
|
|
11623
|
-
* name: 'updated user',
|
|
11624
|
-
* },
|
|
11625
|
-
* create: () => ({
|
|
11626
|
-
* email: 'some@email.com',
|
|
11627
|
-
* // name in `create` is overriding the name from `data`
|
|
11628
|
-
* name: 'created user',
|
|
11629
|
-
* }),
|
|
11630
|
-
* });
|
|
11631
|
-
* ```
|
|
11632
|
-
*
|
|
11633
|
-
* Data from `data` or `update` is passed to the `create` function and can be used:
|
|
11634
|
-
*
|
|
11635
|
-
* ```ts
|
|
11636
|
-
* const user = await User.selectAll()
|
|
11637
|
-
* .findBy({ email: 'some@email.com' })
|
|
11638
|
-
* .upsert({
|
|
11639
|
-
* data: {
|
|
11640
|
-
* name: 'updated user',
|
|
11641
|
-
* },
|
|
11642
|
-
* // `updateData` has the exact type of what is passed to `data`
|
|
11643
|
-
* create: (updateData) => ({
|
|
11644
|
-
* email: `${updateData.name}@email.com`,
|
|
11645
|
-
* }),
|
|
11646
|
-
* });
|
|
11647
|
-
* ```
|
|
11648
|
-
*
|
|
11649
|
-
* `upsert` works in the exact same way as [orCreate](#orCreate), but with `UPDATE` statement instead of `SELECT`.
|
|
11650
|
-
* it also performs a single query if the record exists, and two queries if there is no record yet.
|
|
11651
|
-
*
|
|
11652
|
-
* @param data - `update` property for the data to update, `create` property for the data to create
|
|
11653
|
-
*/
|
|
11577
|
+
const QueryOrCreate = {
|
|
11578
|
+
orCreate(data) {
|
|
11579
|
+
return orCreate(_clone(this), data);
|
|
11580
|
+
}
|
|
11581
|
+
};
|
|
11582
|
+
|
|
11583
|
+
const QueryUpsert = {
|
|
11654
11584
|
upsert(data) {
|
|
11655
11585
|
const q = _clone(this);
|
|
11656
11586
|
let updateData;
|
|
@@ -11665,75 +11595,7 @@ class QueryUpsertOrCreate {
|
|
|
11665
11595
|
}
|
|
11666
11596
|
return orCreate(q, data.create, updateData, mergeData);
|
|
11667
11597
|
}
|
|
11668
|
-
|
|
11669
|
-
* `orCreate` creates a record only if it was not found by conditions.
|
|
11670
|
-
*
|
|
11671
|
-
* `find` or `findBy` must precede `orCreate`.
|
|
11672
|
-
*
|
|
11673
|
-
* It is accepting the same argument as `create` commands.
|
|
11674
|
-
*
|
|
11675
|
-
* No result is returned by default, place `get`, `select`, or `selectAll` before `orCreate` to specify returning columns.
|
|
11676
|
-
*
|
|
11677
|
-
* ```ts
|
|
11678
|
-
* const user = await db.user
|
|
11679
|
-
* .selectAll()
|
|
11680
|
-
* .findBy({ email: 'some@email.com' })
|
|
11681
|
-
* .orCreate({
|
|
11682
|
-
* email: 'some@email.com',
|
|
11683
|
-
* name: 'created user',
|
|
11684
|
-
* // supports sql and nested queries
|
|
11685
|
-
* fromSQL: () => sql`*SQL expression*`,
|
|
11686
|
-
* fromQuery: () => db.someTable.create(data).get('column'),
|
|
11687
|
-
* fromRelated: (q) => q.relatedTable.update(data).get('column'),
|
|
11688
|
-
* });
|
|
11689
|
-
* ```
|
|
11690
|
-
*
|
|
11691
|
-
* The data can be returned from a function, it won't be called if the record was found:
|
|
11692
|
-
*
|
|
11693
|
-
* ```ts
|
|
11694
|
-
* const user = await User.selectAll()
|
|
11695
|
-
* .findBy({ email: 'some@email.com' })
|
|
11696
|
-
* .orCreate(() => ({
|
|
11697
|
-
* email: 'some@email.com',
|
|
11698
|
-
* name: 'created user',
|
|
11699
|
-
* }));
|
|
11700
|
-
* ```
|
|
11701
|
-
*
|
|
11702
|
-
* `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.
|
|
11703
|
-
*
|
|
11704
|
-
* At first, it performs a "find" query, the query cost is exact same as if you didn't use `orCreate`.
|
|
11705
|
-
*
|
|
11706
|
-
* 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,
|
|
11707
|
-
* 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.
|
|
11708
|
-
*
|
|
11709
|
-
* ```sql
|
|
11710
|
-
* -- first query
|
|
11711
|
-
* SELECT * FROM "table" WHERE "key" = 'value'
|
|
11712
|
-
*
|
|
11713
|
-
* -- the record could have been created in between these two queries
|
|
11714
|
-
*
|
|
11715
|
-
* -- second query
|
|
11716
|
-
* WITH find_row AS (
|
|
11717
|
-
* SELECT * FROM "table" WHERE "key" = 'value'
|
|
11718
|
-
* )
|
|
11719
|
-
* WITH insert_row AS (
|
|
11720
|
-
* INSERT INTO "table" ("key")
|
|
11721
|
-
* SELECT 'value'
|
|
11722
|
-
* -- skip the insert if the row already exists
|
|
11723
|
-
* WHERE NOT EXISTS (SELECT 1 FROM find_row)
|
|
11724
|
-
* RETURNING *
|
|
11725
|
-
* )
|
|
11726
|
-
* SELECT * FROM find_row
|
|
11727
|
-
* UNION ALL
|
|
11728
|
-
* SELECT * FROM insert_row
|
|
11729
|
-
* ```
|
|
11730
|
-
*
|
|
11731
|
-
* @param data - the same data as for `create`, it may be returned from a callback
|
|
11732
|
-
*/
|
|
11733
|
-
orCreate(data) {
|
|
11734
|
-
return orCreate(_clone(this), data);
|
|
11735
|
-
}
|
|
11736
|
-
}
|
|
11598
|
+
};
|
|
11737
11599
|
|
|
11738
11600
|
class SqlMethod {
|
|
11739
11601
|
sql(...args) {
|
|
@@ -12817,6 +12679,8 @@ class QueryMethods {
|
|
|
12817
12679
|
return _chain(this, _clone(rel.query), rel);
|
|
12818
12680
|
}
|
|
12819
12681
|
}
|
|
12682
|
+
Object.assign(QueryMethods.prototype, QueryUpsert);
|
|
12683
|
+
Object.assign(QueryMethods.prototype, QueryOrCreate);
|
|
12820
12684
|
applyMixins(QueryMethods, [
|
|
12821
12685
|
AsMethods,
|
|
12822
12686
|
AggregateMethods,
|
|
@@ -12827,7 +12691,7 @@ applyMixins(QueryMethods, [
|
|
|
12827
12691
|
WithMethods,
|
|
12828
12692
|
Union,
|
|
12829
12693
|
JsonMethods,
|
|
12830
|
-
|
|
12694
|
+
QueryCreate,
|
|
12831
12695
|
Update,
|
|
12832
12696
|
Delete,
|
|
12833
12697
|
Transaction,
|
|
@@ -12839,7 +12703,6 @@ applyMixins(QueryMethods, [
|
|
|
12839
12703
|
Then,
|
|
12840
12704
|
QueryLog,
|
|
12841
12705
|
QueryHooks,
|
|
12842
|
-
QueryUpsertOrCreate,
|
|
12843
12706
|
QueryGet,
|
|
12844
12707
|
MergeQueryMethods,
|
|
12845
12708
|
SqlMethod,
|
|
@@ -13015,6 +12878,7 @@ class Db extends QueryMethods {
|
|
|
13015
12878
|
let hasParsers = false;
|
|
13016
12879
|
let modifyQuery = void 0;
|
|
13017
12880
|
let prepareSelectAll = false;
|
|
12881
|
+
let hasHookSetters;
|
|
13018
12882
|
const { snakeCase } = options;
|
|
13019
12883
|
for (const key in shape) {
|
|
13020
12884
|
const column = shape[key];
|
|
@@ -13050,6 +12914,9 @@ class Db extends QueryMethods {
|
|
|
13050
12914
|
column.data.runtimeDefault = encode ? () => encode(def()) : def;
|
|
13051
12915
|
}
|
|
13052
12916
|
}
|
|
12917
|
+
if (column.data.setOnCreate || column.data.setOnUpdate || column.data.setOnSave) {
|
|
12918
|
+
hasHookSetters = true;
|
|
12919
|
+
}
|
|
13053
12920
|
}
|
|
13054
12921
|
this.q = {
|
|
13055
12922
|
adapter,
|
|
@@ -13124,6 +12991,27 @@ class Db extends QueryMethods {
|
|
|
13124
12991
|
if (softDelete) {
|
|
13125
12992
|
enableSoftDelete(this, table, shape, softDelete, scopes);
|
|
13126
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
|
+
}
|
|
13127
13015
|
}
|
|
13128
13016
|
[inspect.custom]() {
|
|
13129
13017
|
return `Query<${this.table}>`;
|
|
@@ -13457,5 +13345,5 @@ function copyTableData(query, arg) {
|
|
|
13457
13345
|
return q;
|
|
13458
13346
|
}
|
|
13459
13347
|
|
|
13460
|
-
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 };
|
|
13461
13349
|
//# sourceMappingURL=index.mjs.map
|