orchid-orm 1.72.4 → 1.72.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 +10 -0
- package/dist/index.js +107 -47
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +108 -48
- package/dist/index.mjs.map +1 -1
- package/dist/migrations/index.js +74 -13
- package/dist/migrations/index.js.map +1 -1
- package/dist/migrations/index.mjs +74 -13
- package/dist/migrations/index.mjs.map +1 -1
- package/package.json +5 -5
package/dist/index.d.ts
CHANGED
|
@@ -96,6 +96,11 @@ interface HasManyInfo<T extends RelationConfigSelf, Name extends string, Rel ext
|
|
|
96
96
|
set?: MaybeArray<WhereArg<Q>>;
|
|
97
97
|
add?: MaybeArray<WhereArg<Q>>;
|
|
98
98
|
create?: CreateData<Q>[];
|
|
99
|
+
upsert?: {
|
|
100
|
+
findBy: Q['internal']['uniqueColumns'];
|
|
101
|
+
update: UpdateData<Q>;
|
|
102
|
+
create?: CreateData<Q> | (() => CreateData<Q>);
|
|
103
|
+
};
|
|
99
104
|
} : never;
|
|
100
105
|
}
|
|
101
106
|
interface RelJoin extends JoinQueryMethod {
|
|
@@ -428,6 +433,11 @@ interface HasAndBelongsToManyInfo<T extends RelationConfigSelf, Name extends str
|
|
|
428
433
|
data: UpdateData<Q>;
|
|
429
434
|
};
|
|
430
435
|
create?: CreateData<Q>[];
|
|
436
|
+
upsert?: {
|
|
437
|
+
findBy: Q['internal']['uniqueColumns'];
|
|
438
|
+
update: UpdateData<Q>;
|
|
439
|
+
create?: CreateData<Q> | (() => CreateData<Q>);
|
|
440
|
+
};
|
|
431
441
|
} : {
|
|
432
442
|
disconnect?: MaybeArray<WhereArg<Q>>;
|
|
433
443
|
set?: MaybeArray<WhereArg<Q>>;
|
package/dist/index.js
CHANGED
|
@@ -137,6 +137,25 @@ function createBaseTable({ schemaConfig = pqb_internal.defaultSchemaConfig, colu
|
|
|
137
137
|
base.prototype.autoForeignKeys = autoForeignKeys === true ? {} : autoForeignKeys || void 0;
|
|
138
138
|
return base;
|
|
139
139
|
}
|
|
140
|
+
const throwIfQueryReturnsAllForNestedUpdate = (q, params) => {
|
|
141
|
+
if (!(params.set || params.create || params.upsert) || !(0, pqb_internal.isQueryReturnsAll)(q)) return;
|
|
142
|
+
let key;
|
|
143
|
+
if (params.set) key = "set";
|
|
144
|
+
else if (params.create) key = "create";
|
|
145
|
+
else key = "upsert";
|
|
146
|
+
throw new Error(`\`${key}\` option is not allowed in a batch update`);
|
|
147
|
+
};
|
|
148
|
+
const getNestedUpdateUpsertCreate = (upsert) => {
|
|
149
|
+
if (typeof upsert.create === "function") return upsert.create();
|
|
150
|
+
return upsert.create || pqb_internal.emptyObject;
|
|
151
|
+
};
|
|
152
|
+
const makeNestedUpdateUpsertData = (upsert, setIds) => ({
|
|
153
|
+
update: upsert.update,
|
|
154
|
+
create: {
|
|
155
|
+
...getNestedUpdateUpsertCreate(upsert),
|
|
156
|
+
...setIds
|
|
157
|
+
}
|
|
158
|
+
});
|
|
140
159
|
const getThroughRelation = (table, through) => {
|
|
141
160
|
return table.relations[through];
|
|
142
161
|
};
|
|
@@ -224,8 +243,27 @@ const getColumnKeyFromDbName = (query, name) => {
|
|
|
224
243
|
for (const k in query.shape) if (query.shape[k].data.name === name) return k;
|
|
225
244
|
return name;
|
|
226
245
|
};
|
|
227
|
-
const selectCteColumnsSql = (cteAs, columns) => `(SELECT ${columns.map((c) => `"${cteAs}"."${c}"`).join(", ")} FROM "${cteAs}")`;
|
|
228
|
-
const selectCteColumnSql = (cteAs, column) => `(SELECT "${cteAs}"."${column}" FROM "${cteAs}")`;
|
|
246
|
+
const selectCteColumnsSql$1 = (cteAs, columns) => `(SELECT ${columns.map((c) => `"${cteAs}"."${c}"`).join(", ")} FROM "${cteAs}")`;
|
|
247
|
+
const selectCteColumnSql$1 = (cteAs, column) => `(SELECT "${cteAs}"."${column}" FROM "${cteAs}")`;
|
|
248
|
+
const makeNestedUpdateRelationIds = (q, relQuery, primaryKeys, foreignKeys) => {
|
|
249
|
+
const selectIdsSql = new pqb_internal.RawSql("");
|
|
250
|
+
const setIds = {};
|
|
251
|
+
for (const foreignKey of foreignKeys) setIds[foreignKey] = new pqb_internal.RawSql("");
|
|
252
|
+
let appendedAs;
|
|
253
|
+
(0, pqb_internal._hookSelectColumns)(q, primaryKeys, (aliasedPrimaryKeys) => {
|
|
254
|
+
selectIdsSql._sql = selectCteColumnsSql$1(appendedAs, aliasedPrimaryKeys);
|
|
255
|
+
foreignKeys.forEach((foreignKey, i) => {
|
|
256
|
+
setIds[foreignKey]._sql = selectCteColumnSql$1(appendedAs, aliasedPrimaryKeys[i]);
|
|
257
|
+
});
|
|
258
|
+
});
|
|
259
|
+
return {
|
|
260
|
+
existingRelQuery: (0, pqb_internal._queryWhereIn)((0, pqb_internal._clone)(relQuery), true, foreignKeys, selectIdsSql),
|
|
261
|
+
setIds,
|
|
262
|
+
setAppendedAs(as) {
|
|
263
|
+
appendedAs = as;
|
|
264
|
+
}
|
|
265
|
+
};
|
|
266
|
+
};
|
|
229
267
|
const selectCteColumnFromManySql = (cteAs, column, rowIndex, count) => {
|
|
230
268
|
let sql = `(SELECT "${cteAs}"."${column}" FROM "${cteAs}"`;
|
|
231
269
|
if (count > 1) {
|
|
@@ -406,7 +444,7 @@ const nestedUpdate$2 = ({ query, primaryKeys, foreignKeys, len }) => {
|
|
|
406
444
|
} else if (params.update) {
|
|
407
445
|
let appendedAs;
|
|
408
446
|
(0, pqb_internal._hookSelectColumns)(self, foreignKeys, (aliasedForeignKeys) => {
|
|
409
|
-
selectIdsSql._sql = selectCteColumnsSql(appendedAs, aliasedForeignKeys);
|
|
447
|
+
selectIdsSql._sql = selectCteColumnsSql$1(appendedAs, aliasedForeignKeys);
|
|
410
448
|
});
|
|
411
449
|
const selectIdsSql = new pqb_internal.RawSql("");
|
|
412
450
|
const updateQuery = (0, pqb_internal._queryUpdate)((0, pqb_internal._queryWhereIn)(query.clone(), true, primaryKeys, selectIdsSql), params.update);
|
|
@@ -449,7 +487,7 @@ const relWithSelectIds = (self, rel, primaryKeys, foreignKeys) => {
|
|
|
449
487
|
const selectIdsQuery = makeSelectIdsQuery(self, foreignKeys);
|
|
450
488
|
const selectIdsSql = new pqb_internal.RawSql("");
|
|
451
489
|
(0, pqb_internal._prependWith)(self, (as) => {
|
|
452
|
-
selectIdsSql._sql = selectCteColumnsSql(as, foreignKeys);
|
|
490
|
+
selectIdsSql._sql = selectCteColumnsSql$1(as, foreignKeys);
|
|
453
491
|
}, selectIdsQuery);
|
|
454
492
|
return {
|
|
455
493
|
selectIdsSql,
|
|
@@ -470,12 +508,12 @@ const setForeignKeysFromCte = (record, primaryKeys, foreignKeys, mustExist) => {
|
|
|
470
508
|
foreignKeys.forEach(mustExist ? (foreignKey, i) => {
|
|
471
509
|
record[foreignKey]._sql = selectCteColumnMustExistSql(i, as, primaryKeys[i]);
|
|
472
510
|
} : (foreignKey, i) => {
|
|
473
|
-
record[foreignKey]._sql = selectCteColumnSql(as, primaryKeys[i]);
|
|
511
|
+
record[foreignKey]._sql = selectCteColumnSql$1(as, primaryKeys[i]);
|
|
474
512
|
});
|
|
475
513
|
};
|
|
476
514
|
};
|
|
477
515
|
const selectCteColumnMustExistSql = (i, cteAs, column) => {
|
|
478
|
-
const selectColumn = selectCteColumnSql(cteAs, column);
|
|
516
|
+
const selectColumn = selectCteColumnSql$1(cteAs, column);
|
|
479
517
|
return i === 0 ? `CASE WHEN (SELECT count(*) FROM "${cteAs}") = 0 AND (SELECT 'not-found')::int = 0 THEN NULL ELSE ${selectColumn} END` : selectColumn;
|
|
480
518
|
};
|
|
481
519
|
var HasOneVirtualColumn = class extends pqb_internal.VirtualColumn {
|
|
@@ -541,43 +579,19 @@ var HasOneVirtualColumn = class extends pqb_internal.VirtualColumn {
|
|
|
541
579
|
update(self, set) {
|
|
542
580
|
const querySelf = self;
|
|
543
581
|
const params = set[this.key];
|
|
544
|
-
|
|
545
|
-
const key = params.set ? "set" : params.create ? "create" : "upsert";
|
|
546
|
-
throw new Error(`\`${key}\` option is not allowed in a batch update`);
|
|
547
|
-
}
|
|
582
|
+
throwIfQueryReturnsAllForNestedUpdate(querySelf, params);
|
|
548
583
|
const { primaryKeys, foreignKeys, query: relQuery } = this.state;
|
|
549
584
|
if (params.create || params.update || params.upsert || params.disconnect || params.set || params.delete) {
|
|
550
|
-
|
|
551
|
-
(0, pqb_internal.
|
|
552
|
-
selectIdsSql._sql = selectCteColumnsSql(appendedAs, aliasedPrimaryKeys);
|
|
553
|
-
if (params.create || params.set || params.upsert) foreignKeys.forEach((foreignKey, i) => {
|
|
554
|
-
setIds[foreignKey]._sql = selectCteColumnSql(appendedAs, aliasedPrimaryKeys[i]);
|
|
555
|
-
});
|
|
556
|
-
});
|
|
557
|
-
const selectIdsSql = new pqb_internal.RawSql("");
|
|
558
|
-
const existingRelQuery = (0, pqb_internal._queryWhereIn)((0, pqb_internal._clone)(relQuery), true, foreignKeys, selectIdsSql);
|
|
559
|
-
let setIds = void 0;
|
|
560
|
-
if (params.create || params.set || params.upsert) {
|
|
561
|
-
setIds = {};
|
|
562
|
-
foreignKeys.forEach((foreignKey) => {
|
|
563
|
-
setIds[foreignKey] = new pqb_internal.RawSql("");
|
|
564
|
-
});
|
|
565
|
-
}
|
|
566
|
-
const nullifyOrDeleteQuery = params.update ? (0, pqb_internal._queryUpdate)(existingRelQuery, params.update) : params.upsert ? (0, pqb_internal._queryUpsert)(existingRelQuery, {
|
|
567
|
-
update: params.upsert.update,
|
|
568
|
-
create: {
|
|
569
|
-
...typeof params.upsert.create === "function" ? params.upsert.create() : params.upsert.create,
|
|
570
|
-
...setIds
|
|
571
|
-
}
|
|
572
|
-
}) : params.delete ? (0, pqb_internal._queryDelete)(existingRelQuery) : (0, pqb_internal._queryUpdate)(existingRelQuery, this.setNulls);
|
|
585
|
+
const ids = makeNestedUpdateRelationIds(querySelf, relQuery, primaryKeys, foreignKeys);
|
|
586
|
+
const nullifyOrDeleteQuery = params.update ? (0, pqb_internal._queryUpdate)(ids.existingRelQuery, params.update) : params.upsert ? (0, pqb_internal._queryUpsert)(ids.existingRelQuery, makeNestedUpdateUpsertData(params.upsert, ids.setIds)) : params.delete ? (0, pqb_internal._queryDelete)(ids.existingRelQuery) : (0, pqb_internal._queryUpdate)(ids.existingRelQuery, this.setNulls);
|
|
573
587
|
nullifyOrDeleteQuery.q.returnType = "void";
|
|
574
|
-
(0, pqb_internal._appendQuery)(querySelf, nullifyOrDeleteQuery,
|
|
588
|
+
(0, pqb_internal._appendQuery)(querySelf, nullifyOrDeleteQuery, ids.setAppendedAs);
|
|
575
589
|
if (params.create) (0, pqb_internal._appendQuery)(querySelf, (0, pqb_internal._queryInsert)((0, pqb_internal._clone)(relQuery), {
|
|
576
590
|
...params.create,
|
|
577
|
-
...setIds
|
|
591
|
+
...ids.setIds
|
|
578
592
|
}), pqb_internal.noop);
|
|
579
593
|
else if (params.set) {
|
|
580
|
-
const setQuery = (0, pqb_internal._queryUpdate)((0, pqb_internal._queryWhere)((0, pqb_internal._clone)(relQuery), [params.set]), setIds);
|
|
594
|
+
const setQuery = (0, pqb_internal._queryUpdate)((0, pqb_internal._queryWhere)((0, pqb_internal._clone)(relQuery), [params.set]), ids.setIds);
|
|
581
595
|
setQuery.q.returnType = "void";
|
|
582
596
|
(0, pqb_internal._appendQuery)(querySelf, setQuery, pqb_internal.noop);
|
|
583
597
|
}
|
|
@@ -691,6 +705,8 @@ var HasManyVirtualColumn = class extends pqb_internal.VirtualColumn {
|
|
|
691
705
|
this.state = state;
|
|
692
706
|
this.nestedInsert = nestedInsert$1(state);
|
|
693
707
|
this.nestedUpdate = nestedUpdate$1(state);
|
|
708
|
+
this.setNulls = {};
|
|
709
|
+
for (const foreignKey of state.foreignKeys) this.setNulls[foreignKey] = null;
|
|
694
710
|
}
|
|
695
711
|
create(self, ctx, items, rowIndexes, count) {
|
|
696
712
|
const querySelf = self;
|
|
@@ -761,14 +777,18 @@ var HasManyVirtualColumn = class extends pqb_internal.VirtualColumn {
|
|
|
761
777
|
});
|
|
762
778
|
} else hasRelationHandleCreate(querySelf, ctx, items, rowIndexes, this.key, this.state.primaryKeys, this.nestedInsert);
|
|
763
779
|
}
|
|
764
|
-
update(
|
|
765
|
-
const
|
|
780
|
+
update(self, set) {
|
|
781
|
+
const querySelf = self;
|
|
766
782
|
const params = set[this.key];
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
783
|
+
throwIfQueryReturnsAllForNestedUpdate(querySelf, params);
|
|
784
|
+
hasRelationHandleUpdate(querySelf, set, this.key, this.state.primaryKeys, this.nestedUpdate);
|
|
785
|
+
if (params.upsert) {
|
|
786
|
+
const { primaryKeys, foreignKeys, query: relQuery } = this.state;
|
|
787
|
+
const ids = makeNestedUpdateRelationIds(querySelf, relQuery, primaryKeys, foreignKeys);
|
|
788
|
+
const appendedQuery = (0, pqb_internal._queryUpsert)(ids.existingRelQuery, makeNestedUpdateUpsertData(params.upsert, ids.setIds));
|
|
789
|
+
appendedQuery.q.returnType = "void";
|
|
790
|
+
(0, pqb_internal._appendQuery)(querySelf, appendedQuery, ids.setAppendedAs);
|
|
770
791
|
}
|
|
771
|
-
hasRelationHandleUpdate(query, set, this.key, this.state.primaryKeys, this.nestedUpdate);
|
|
772
792
|
}
|
|
773
793
|
};
|
|
774
794
|
const makeHasManyMethod = (tableConfig, table, relation, relationName, query) => {
|
|
@@ -908,10 +928,10 @@ const nestedInsert$1 = ({ query, primaryKeys, foreignKeys }) => {
|
|
|
908
928
|
}
|
|
909
929
|
});
|
|
910
930
|
};
|
|
911
|
-
const nestedUpdate$1 = ({ query, primaryKeys, foreignKeys }) => {
|
|
931
|
+
const nestedUpdate$1 = ({ query: relQuery, primaryKeys, foreignKeys }) => {
|
|
912
932
|
const len = primaryKeys.length;
|
|
913
933
|
return (async (_, data, params) => {
|
|
914
|
-
const t =
|
|
934
|
+
const t = relQuery.clone();
|
|
915
935
|
if (params.create) {
|
|
916
936
|
const obj = {};
|
|
917
937
|
for (let i = 0; i < len; i++) obj[foreignKeys[i]] = data[0][primaryKeys[i]];
|
|
@@ -921,12 +941,12 @@ const nestedUpdate$1 = ({ query, primaryKeys, foreignKeys }) => {
|
|
|
921
941
|
})));
|
|
922
942
|
}
|
|
923
943
|
if (params.add) {
|
|
924
|
-
if (data.length > 1) throw new pqb.OrchidOrmInternalError(
|
|
944
|
+
if (data.length > 1) throw new pqb.OrchidOrmInternalError(relQuery, "`connect` is not available when updating multiple records, it is only applicable for a single record update");
|
|
925
945
|
const obj = {};
|
|
926
946
|
for (let i = 0; i < len; i++) obj[foreignKeys[i]] = data[0][primaryKeys[i]];
|
|
927
947
|
const relatedWheres = (0, pqb_internal.toArray)(params.add);
|
|
928
948
|
const count = await (0, pqb_internal._queryUpdate)(t.where({ OR: relatedWheres }), obj);
|
|
929
|
-
if (count < relatedWheres.length) throw new pqb.OrchidOrmInternalError(
|
|
949
|
+
if (count < relatedWheres.length) throw new pqb.OrchidOrmInternalError(relQuery, `Expected to find at least ${relatedWheres.length} record(s) based on \`add\` conditions, but found ${count}`);
|
|
930
950
|
}
|
|
931
951
|
if (params.disconnect || params.set) {
|
|
932
952
|
const obj = {};
|
|
@@ -961,9 +981,48 @@ var HasAndBelongsToManyVirtualColumn = class extends pqb_internal.VirtualColumn
|
|
|
961
981
|
hasRelationHandleCreate(q, ctx, items, rowIndexes, this.key, this.state.primaryKeys, this.nestedInsert);
|
|
962
982
|
}
|
|
963
983
|
update(q, set) {
|
|
964
|
-
|
|
984
|
+
const querySelf = q;
|
|
985
|
+
const params = set[this.key];
|
|
986
|
+
hasRelationHandleUpdate(querySelf, set, this.key, this.state.primaryKeys, this.nestedUpdate);
|
|
987
|
+
if (params.upsert) {
|
|
988
|
+
throwIfQueryReturnsAllForNestedUpdate(querySelf, { upsert: params.upsert });
|
|
989
|
+
nestedUpdateUpsert(querySelf, this.state, params.upsert);
|
|
990
|
+
}
|
|
965
991
|
}
|
|
966
992
|
};
|
|
993
|
+
const selectCteColumnsSql = (cteAs, columns) => `(SELECT ${columns.map((c) => `"${cteAs}"."${c}"`).join(", ")} FROM "${cteAs}")`;
|
|
994
|
+
const selectCteColumnSql = (cteAs, column) => `(SELECT "${cteAs}"."${column}" FROM "${cteAs}")`;
|
|
995
|
+
const nestedUpdateUpsert = (querySelf, state, upsert) => {
|
|
996
|
+
const parentIdsSql = new pqb_internal.RawSql("");
|
|
997
|
+
const parentValues = state.foreignKeys.map(() => new pqb_internal.RawSql(""));
|
|
998
|
+
const relatedIdsSql = new pqb_internal.RawSql("");
|
|
999
|
+
const relatedValues = state.throughPrimaryKeys.map(() => new pqb_internal.RawSql(""));
|
|
1000
|
+
let parentAs;
|
|
1001
|
+
(0, pqb_internal._hookSelectColumns)(querySelf, state.primaryKeys, (aliasedPrimaryKeys) => {
|
|
1002
|
+
parentIdsSql._sql = selectCteColumnsSql(parentAs, aliasedPrimaryKeys);
|
|
1003
|
+
for (let i = 0; i < state.foreignKeys.length; i++) parentValues[i]._sql = selectCteColumnSql(parentAs, aliasedPrimaryKeys[i]);
|
|
1004
|
+
});
|
|
1005
|
+
const upsertQuery = (0, pqb_internal._querySelect)((0, pqb_internal._queryUpsert)((0, pqb_internal._queryWhereExists)((0, pqb_internal._queryWhere)((0, pqb_internal._clone)(state.relatedTableQuery), [upsert.findBy]), state.joinTableQuery, [(q) => {
|
|
1006
|
+
for (let i = 0; i < state.throughPrimaryKeys.length; i++) (0, pqb_internal._queryJoinOn)(q, [state.throughForeignKeysFull[i], state.throughPrimaryKeysFull[i]]);
|
|
1007
|
+
return (0, pqb_internal._queryWhereIn)(q, true, state.foreignKeysFull, parentIdsSql);
|
|
1008
|
+
}]), {
|
|
1009
|
+
update: upsert.update,
|
|
1010
|
+
create: upsert.create || {}
|
|
1011
|
+
}), state.throughPrimaryKeys);
|
|
1012
|
+
const selectAs = {};
|
|
1013
|
+
for (let i = 0; i < state.foreignKeys.length; i++) selectAs[state.foreignKeys[i]] = parentValues[i];
|
|
1014
|
+
for (let i = 0; i < state.throughForeignKeys.length; i++) selectAs[state.throughForeignKeys[i]] = relatedValues[i];
|
|
1015
|
+
const joinRows = (0, pqb_internal._querySelect)((0, pqb_internal._clone)(state.queryBuilder), [selectAs]);
|
|
1016
|
+
(0, pqb_internal._queryWhere)(joinRows, [relatedIdsSql]);
|
|
1017
|
+
const joinQuery = state.joinTableQuery.insertForEachFrom(joinRows);
|
|
1018
|
+
joinQuery.q.returnType = "void";
|
|
1019
|
+
(0, pqb_internal._appendQuery)(querySelf, (0, pqb_internal._appendQueryOnUpsertCreate)(upsertQuery, joinQuery, (as) => {
|
|
1020
|
+
relatedIdsSql._sql = `EXISTS (SELECT 1 FROM "${as}")`;
|
|
1021
|
+
for (let i = 0; i < relatedValues.length; i++) relatedValues[i]._sql = selectCteColumnSql(as, state.throughPrimaryKeys[i]);
|
|
1022
|
+
}), (as) => {
|
|
1023
|
+
parentAs = as;
|
|
1024
|
+
});
|
|
1025
|
+
};
|
|
967
1026
|
const removeColumnName = (column) => {
|
|
968
1027
|
if (!column.data.name) return column;
|
|
969
1028
|
const cloned = Object.create(column);
|
|
@@ -1021,6 +1080,7 @@ const makeHasAndBelongsToManyMethod = (tableConfig, table, qb, relation, relatio
|
|
|
1021
1080
|
addAutoForeignKey(tableConfig, subQuery, table, primaryKeys, foreignKeys, relation.options, originalForeignKeys);
|
|
1022
1081
|
addAutoForeignKey(tableConfig, subQuery, query, throughPrimaryKeys, throughForeignKeys, relation.options.through, originalThroughForeignKeys);
|
|
1023
1082
|
const state = {
|
|
1083
|
+
queryBuilder: qb,
|
|
1024
1084
|
relatedTableQuery: query,
|
|
1025
1085
|
joinTableQuery: subQuery,
|
|
1026
1086
|
primaryKeys,
|