orchid-orm 1.77.2 → 1.78.0
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 +60 -49
- package/dist/index.js +758 -230
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +759 -231
- package/dist/index.mjs.map +1 -1
- package/dist/migrations/index.js.map +1 -1
- package/dist/migrations/index.mjs.map +1 -1
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -587,6 +587,21 @@ const makeNestedUpdateUpsertData = (upsert, setIds) => ({
|
|
|
587
587
|
...setIds
|
|
588
588
|
}
|
|
589
589
|
});
|
|
590
|
+
const makeRawSqlPlaceholders = (length) => {
|
|
591
|
+
return Array.from({ length }, () => new pqb_internal.RawSql(""));
|
|
592
|
+
};
|
|
593
|
+
const makeRawSqlPlaceholderRecord = (keys) => {
|
|
594
|
+
const placeholders = makeRawSqlPlaceholders(keys.length);
|
|
595
|
+
const record = {};
|
|
596
|
+
for (let i = 0; i < keys.length; i++) record[keys[i]] = placeholders[i];
|
|
597
|
+
return record;
|
|
598
|
+
};
|
|
599
|
+
const setRawSqlPlaceholdersFromCte = (placeholders, cte, primaryKeys, rowIndex, count) => {
|
|
600
|
+
for (let i = 0; i < placeholders.length; i++) placeholders[i]._sql = selectCteColumnFromManySql(cte, primaryKeys[i], rowIndex, count);
|
|
601
|
+
};
|
|
602
|
+
const setRawSqlPlaceholderRecordFromCte = (record, keys, cte, primaryKeys, rowIndex, count) => {
|
|
603
|
+
setRawSqlPlaceholdersFromCte(keys.map((key) => record[key]), cte, primaryKeys, rowIndex, count);
|
|
604
|
+
};
|
|
590
605
|
const getThroughRelation = (table, through) => {
|
|
591
606
|
return table.relations[through];
|
|
592
607
|
};
|
|
@@ -597,7 +612,7 @@ const hasRelationHandleCreate = (q, ctx, items, rowIndexes, key, primaryKeys, ne
|
|
|
597
612
|
q.q.wrapInTransaction = true;
|
|
598
613
|
items.forEach((item, i) => {
|
|
599
614
|
const value = item[key];
|
|
600
|
-
if ((!value.create || Array.isArray(value.create) && value.create.length === 0) && (!value.connect || Array.isArray(value.connect) && value.connect.length === 0) && (!value.connectOrCreate || Array.isArray(value.connectOrCreate) && value.connectOrCreate.length === 0)) return;
|
|
615
|
+
if ((!value.create || Array.isArray(value.create) && value.create.length === 0) && (!value.connect || Array.isArray(value.connect) && value.connect.length === 0) && (!value.connectOrCreate || Array.isArray(value.connectOrCreate) && value.connectOrCreate.length === 0) && (!("upsert" in value) || !value.upsert || Array.isArray(value.upsert) && value.upsert.length === 0)) return;
|
|
601
616
|
const store = ctx;
|
|
602
617
|
if (!store.hasRelation) store.hasRelation = {};
|
|
603
618
|
const values = [rowIndexes[i], value];
|
|
@@ -610,14 +625,6 @@ const hasRelationHandleCreate = (q, ctx, items, rowIndexes, key, primaryKeys, ne
|
|
|
610
625
|
(0, pqb_internal._queryHookAfterCreate)(q, primaryKeys, (rows, q) => nestedInsert(q, relationData.map(([rowIndex, data]) => [rows[rowIndex], data])));
|
|
611
626
|
});
|
|
612
627
|
};
|
|
613
|
-
const hasRelationHandleUpdate = (q, set, key, primaryKeys, nestedUpdate) => {
|
|
614
|
-
const value = set[key];
|
|
615
|
-
if (!value.set && !("upsert" in value) && (!value.add || Array.isArray(value.add) && value.add.length === 0) && (!value.disconnect || Array.isArray(value.disconnect) && value.disconnect.length === 0) && (!value.delete || Array.isArray(value.delete) && value.delete.length === 0) && (!value.update || Array.isArray(value.update.where) && value.update.where.length === 0) && (!value.create || Array.isArray(value.create) && value.create.length === 0)) return;
|
|
616
|
-
q.q.wrapInTransaction = true;
|
|
617
|
-
(0, pqb_internal._queryHookAfterUpdate)(q, primaryKeys, (rows, q) => {
|
|
618
|
-
return nestedUpdate(q, rows, value);
|
|
619
|
-
});
|
|
620
|
-
};
|
|
621
628
|
function joinHasThrough(q, baseQuery, joiningQuery, throughRelation, sourceRelation) {
|
|
622
629
|
return q.whereExists(throughRelation.joinQuery(throughRelation.query, baseQuery), (() => {
|
|
623
630
|
const as = (0, pqb_internal.getQueryAs)(joiningQuery);
|
|
@@ -683,17 +690,17 @@ const getColumnKeyFromDbName = (query, name) => {
|
|
|
683
690
|
for (const k in query.shape) if (query.shape[k].data.name === name) return k;
|
|
684
691
|
return name;
|
|
685
692
|
};
|
|
686
|
-
const selectCteColumnsSql
|
|
687
|
-
const selectCteColumnSql
|
|
693
|
+
const selectCteColumnsSql = (cteAs, columns) => `(SELECT ${columns.map((c) => `"${cteAs}"."${c}"`).join(", ")} FROM "${cteAs}")`;
|
|
694
|
+
const selectCteColumnSql = (cteAs, column) => `(SELECT "${cteAs}"."${column}" FROM "${cteAs}")`;
|
|
688
695
|
const makeNestedUpdateRelationIds = (q, relQuery, primaryKeys, foreignKeys) => {
|
|
689
696
|
const selectIdsSql = new pqb_internal.RawSql("");
|
|
690
697
|
const setIds = {};
|
|
691
698
|
for (const foreignKey of foreignKeys) setIds[foreignKey] = new pqb_internal.RawSql("");
|
|
692
699
|
let appendedAs;
|
|
693
700
|
(0, pqb_internal._hookSelectColumns)(q, primaryKeys, (aliasedPrimaryKeys) => {
|
|
694
|
-
selectIdsSql._sql = selectCteColumnsSql
|
|
701
|
+
selectIdsSql._sql = selectCteColumnsSql(appendedAs, aliasedPrimaryKeys);
|
|
695
702
|
foreignKeys.forEach((foreignKey, i) => {
|
|
696
|
-
setIds[foreignKey]._sql = selectCteColumnSql
|
|
703
|
+
setIds[foreignKey]._sql = selectCteColumnSql(appendedAs, aliasedPrimaryKeys[i]);
|
|
697
704
|
});
|
|
698
705
|
});
|
|
699
706
|
return {
|
|
@@ -713,8 +720,8 @@ const selectCteColumnFromManySql = (cteAs, column, rowIndex, count) => {
|
|
|
713
720
|
return sql + ")";
|
|
714
721
|
};
|
|
715
722
|
const selectCteColumnMustExistSql = (i, cteAs, column) => {
|
|
716
|
-
const selectColumn = selectCteColumnSql
|
|
717
|
-
return i === 0 ? `CASE WHEN (SELECT count(*) FROM "${cteAs}") = 0 AND (SELECT 'not-found')::int = 0 THEN NULL ELSE ${selectColumn} END` : selectColumn;
|
|
723
|
+
const selectColumn = selectCteColumnSql(cteAs, column);
|
|
724
|
+
return i === 0 ? `CASE WHEN (SELECT count(*) FROM "${cteAs}") = 0 AND (SELECT ':not-found:1:0')::int = 0 THEN NULL ELSE ${selectColumn} END` : selectColumn;
|
|
718
725
|
};
|
|
719
726
|
const setForeignKeysFromCte = (record, primaryKeys, foreignKeys, mustExist) => {
|
|
720
727
|
for (const key of foreignKeys) record[key] = new pqb_internal.RawSql("");
|
|
@@ -722,7 +729,7 @@ const setForeignKeysFromCte = (record, primaryKeys, foreignKeys, mustExist) => {
|
|
|
722
729
|
foreignKeys.forEach(mustExist ? (foreignKey, i) => {
|
|
723
730
|
record[foreignKey]._sql = selectCteColumnMustExistSql(i, as, primaryKeys[i]);
|
|
724
731
|
} : (foreignKey, i) => {
|
|
725
|
-
record[foreignKey]._sql = selectCteColumnSql
|
|
732
|
+
record[foreignKey]._sql = selectCteColumnSql(as, primaryKeys[i]);
|
|
726
733
|
});
|
|
727
734
|
};
|
|
728
735
|
};
|
|
@@ -803,7 +810,7 @@ const belongsToCreate = (key, state, q, ctx, items) => {
|
|
|
803
810
|
let nestedCreateItems;
|
|
804
811
|
items.forEach((item) => {
|
|
805
812
|
const value = item[key];
|
|
806
|
-
const kind = value.create ? "create" : value.connect ? "connect" : "connectOrCreate";
|
|
813
|
+
const kind = value.create ? "create" : value.connect ? "connect" : value.connectOrCreate ? "connectOrCreate" : void 0;
|
|
807
814
|
if (kind) {
|
|
808
815
|
const nestedCreateItem = (nestedCreateItems ??= {})[kind] ??= {
|
|
809
816
|
items: [],
|
|
@@ -811,7 +818,7 @@ const belongsToCreate = (key, state, q, ctx, items) => {
|
|
|
811
818
|
};
|
|
812
819
|
nestedCreateItem.items.push(item);
|
|
813
820
|
nestedCreateItem.values.push(value[kind]);
|
|
814
|
-
if (kind
|
|
821
|
+
if (kind === "create" || kind === "connectOrCreate") for (const key of foreignKeys) item[key] = new pqb_internal.RawSql("");
|
|
815
822
|
}
|
|
816
823
|
});
|
|
817
824
|
if (!nestedCreateItems) return;
|
|
@@ -853,7 +860,7 @@ const belongsToCreate = (key, state, q, ctx, items) => {
|
|
|
853
860
|
(queryForCreate.q.type === "upsert" ? pqb_internal._prependWithOnUpsertCreate : pqb_internal._prependWith)(queryForCreate, asFn, (0, pqb_internal._orCreate)((0, pqb_internal._queryWhere)(selectPKeys, [value.where]), value.create));
|
|
854
861
|
});
|
|
855
862
|
};
|
|
856
|
-
const nestedUpdate
|
|
863
|
+
const nestedUpdate = ({ query, primaryKeys, foreignKeys, len }) => {
|
|
857
864
|
return ((self, update, params) => {
|
|
858
865
|
if (params.create) {
|
|
859
866
|
const createQuery = (0, pqb_internal._querySelect)((0, pqb_internal._queryCreate)(query.clone(), params.create), primaryKeys);
|
|
@@ -862,7 +869,7 @@ const nestedUpdate$2 = ({ query, primaryKeys, foreignKeys, len }) => {
|
|
|
862
869
|
} else if (params.update) {
|
|
863
870
|
let appendedAs;
|
|
864
871
|
(0, pqb_internal._hookSelectColumns)(self, foreignKeys, (aliasedForeignKeys) => {
|
|
865
|
-
selectIdsSql._sql = selectCteColumnsSql
|
|
872
|
+
selectIdsSql._sql = selectCteColumnsSql(appendedAs, aliasedForeignKeys);
|
|
866
873
|
});
|
|
867
874
|
const selectIdsSql = new pqb_internal.RawSql("");
|
|
868
875
|
const updateQuery = (0, pqb_internal._queryUpdate)((0, pqb_internal._queryWhereIn)(query.clone(), true, primaryKeys, selectIdsSql), params.update);
|
|
@@ -872,6 +879,7 @@ const nestedUpdate$2 = ({ query, primaryKeys, foreignKeys, len }) => {
|
|
|
872
879
|
if ((0, pqb_internal.isQueryReturnsAll)(self)) throw new Error("`upsert` option is not allowed in a batch update");
|
|
873
880
|
const { relQuery } = relWithSelectIds(self, query, primaryKeys, foreignKeys);
|
|
874
881
|
const upsertQuery = (0, pqb_internal._querySelect)((0, pqb_internal._queryUpsert)(relQuery, params.upsert), primaryKeys);
|
|
882
|
+
upsertQuery.q.returnType = "one";
|
|
875
883
|
const asFn = setForeignKeysFromCte(update, primaryKeys, foreignKeys);
|
|
876
884
|
(0, pqb_internal._prependWith)(self, asFn, upsertQuery);
|
|
877
885
|
} else if (params.delete) {
|
|
@@ -897,7 +905,9 @@ const nestedUpdate$2 = ({ query, primaryKeys, foreignKeys, len }) => {
|
|
|
897
905
|
}
|
|
898
906
|
if (loadPrimaryKeys) {
|
|
899
907
|
const asFn = setForeignKeysFromCte(update, loadPrimaryKeys, loadForeignKeys, true);
|
|
900
|
-
|
|
908
|
+
const findByQuery = (0, pqb_internal._queryFindBy)(query.select(...loadPrimaryKeys), params.set);
|
|
909
|
+
findByQuery.q.returnType = "value";
|
|
910
|
+
(0, pqb_internal._prependWith)(self, asFn, findByQuery);
|
|
901
911
|
}
|
|
902
912
|
}
|
|
903
913
|
});
|
|
@@ -909,7 +919,7 @@ const relWithSelectIds = (self, rel, primaryKeys, foreignKeys) => {
|
|
|
909
919
|
const selectIdsQuery = makeSelectIdsQuery(self, foreignKeys);
|
|
910
920
|
const selectIdsSql = new pqb_internal.RawSql("");
|
|
911
921
|
(0, pqb_internal._prependWith)(self, (as) => {
|
|
912
|
-
selectIdsSql._sql = selectCteColumnsSql
|
|
922
|
+
selectIdsSql._sql = selectCteColumnsSql(as, foreignKeys);
|
|
913
923
|
}, selectIdsQuery);
|
|
914
924
|
return {
|
|
915
925
|
selectIdsSql,
|
|
@@ -929,7 +939,7 @@ var BelongsToVirtualColumn = class extends pqb_internal.VirtualColumn {
|
|
|
929
939
|
super(schema);
|
|
930
940
|
this.key = key;
|
|
931
941
|
this.state = state;
|
|
932
|
-
this.nestedUpdate = nestedUpdate
|
|
942
|
+
this.nestedUpdate = nestedUpdate(this.state);
|
|
933
943
|
}
|
|
934
944
|
create(q, ctx, items) {
|
|
935
945
|
belongsToCreate(this.key, this.state, q, ctx, items);
|
|
@@ -1096,7 +1106,7 @@ const hasOneCreate = (key, state, nestedInsertFn, self, ctx, items, rowIndexes,
|
|
|
1096
1106
|
const connectWhereExists = querySelf.q.type === "upsert" ? new pqb_internal.RawSql("") : void 0;
|
|
1097
1107
|
const query = (0, pqb_internal._queryUpdateOrThrow)(rel.where(value), connect.items[i]);
|
|
1098
1108
|
if (connectWhereExists) (0, pqb_internal._queryWhere)(query, [connectWhereExists]);
|
|
1099
|
-
query.q.ensureCount = 1;
|
|
1109
|
+
query.q.ensureCount = { expected: 1 };
|
|
1100
1110
|
(querySelf.q.type === "upsert" ? pqb_internal._appendQueryOnUpsertCreate : pqb_internal._appendQuery)(querySelf, query, (as) => {
|
|
1101
1111
|
upsertCreateAs = as;
|
|
1102
1112
|
setUpsertCreatePlaceholders();
|
|
@@ -1249,66 +1259,163 @@ const makeHasOneMethod = (tableConfig, table, relation, relationName, query) =>
|
|
|
1249
1259
|
}
|
|
1250
1260
|
};
|
|
1251
1261
|
};
|
|
1252
|
-
const
|
|
1253
|
-
return t.where({
|
|
1254
|
-
IN: {
|
|
1255
|
-
columns: foreignKeys,
|
|
1256
|
-
values: data.map((item) => primaryKeys.map((key) => item[key]))
|
|
1257
|
-
},
|
|
1258
|
-
OR: params ? (0, pqb_internal.toArray)(params) : void 0
|
|
1259
|
-
});
|
|
1260
|
-
};
|
|
1261
|
-
const nestedUpdate$1 = ({ query: relQuery, primaryKeys, foreignKeys }) => {
|
|
1262
|
-
const len = primaryKeys.length;
|
|
1263
|
-
return (async (_, data, params) => {
|
|
1264
|
-
const t = relQuery.clone();
|
|
1265
|
-
if (params.create) {
|
|
1266
|
-
const obj = {};
|
|
1267
|
-
for (let i = 0; i < len; i++) obj[foreignKeys[i]] = data[0][primaryKeys[i]];
|
|
1268
|
-
await t.insertMany(params.create.map((create) => ({
|
|
1269
|
-
...create,
|
|
1270
|
-
...obj
|
|
1271
|
-
})));
|
|
1272
|
-
}
|
|
1273
|
-
if (params.add) {
|
|
1274
|
-
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");
|
|
1275
|
-
const obj = {};
|
|
1276
|
-
for (let i = 0; i < len; i++) obj[foreignKeys[i]] = data[0][primaryKeys[i]];
|
|
1277
|
-
const relatedWheres = (0, pqb_internal.toArray)(params.add);
|
|
1278
|
-
const count = await (0, pqb_internal._queryUpdate)(t.where({ OR: relatedWheres }), obj);
|
|
1279
|
-
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}`);
|
|
1280
|
-
}
|
|
1281
|
-
if (params.disconnect || params.set) {
|
|
1282
|
-
const obj = {};
|
|
1283
|
-
for (const foreignKey of foreignKeys) obj[foreignKey] = null;
|
|
1284
|
-
const setConditions = params.set && (Array.isArray(params.set) ? params.set.length : (0, pqb_internal.objectHasValues)(params.set)) && (Array.isArray(params.set) ? { OR: params.set } : params.set);
|
|
1285
|
-
let queryToDisconnect = getWhereForNestedUpdate(t, data, params.disconnect, primaryKeys, foreignKeys);
|
|
1286
|
-
if (setConditions) queryToDisconnect = queryToDisconnect.whereNot(setConditions);
|
|
1287
|
-
await (0, pqb_internal._queryUpdate)(queryToDisconnect, obj);
|
|
1288
|
-
if (setConditions) {
|
|
1289
|
-
const obj = {};
|
|
1290
|
-
for (let i = 0; i < len; i++) obj[foreignKeys[i]] = data[0][primaryKeys[i]];
|
|
1291
|
-
await (0, pqb_internal._queryUpdate)(t.where(setConditions), obj);
|
|
1292
|
-
}
|
|
1293
|
-
}
|
|
1294
|
-
if (params.delete || params.update) {
|
|
1295
|
-
const q = getWhereForNestedUpdate(t, data, params.delete || params.update?.where, primaryKeys, foreignKeys);
|
|
1296
|
-
if (params.delete) await (0, pqb_internal._queryDelete)(q);
|
|
1297
|
-
else if (params.update) await (0, pqb_internal._queryUpdate)(q, params.update.data);
|
|
1298
|
-
}
|
|
1299
|
-
});
|
|
1300
|
-
};
|
|
1301
|
-
const hasManyUpdate = (key, state, nestedUpdateFn, self, set) => {
|
|
1262
|
+
const hasManyUpdate = (key, state, self, set) => {
|
|
1302
1263
|
const querySelf = self;
|
|
1303
1264
|
const params = set[key];
|
|
1304
1265
|
throwIfQueryReturnsAllForNestedUpdate(querySelf, params);
|
|
1305
|
-
|
|
1306
|
-
|
|
1266
|
+
const makeRelationIds = () => makeNestedUpdateRelationIds(querySelf, state.query, state.primaryKeys, state.foreignKeys);
|
|
1267
|
+
const hasDisconnect = !!params.disconnect && (!Array.isArray(params.disconnect) || params.disconnect.length > 0);
|
|
1268
|
+
const hasSetConditions = params.set && (Array.isArray(params.set) ? params.set.length : (0, pqb_internal.objectHasValues)(params.set));
|
|
1269
|
+
if (hasDisconnect || params.set !== void 0) {
|
|
1307
1270
|
const { primaryKeys, foreignKeys, query: relQuery } = state;
|
|
1308
|
-
const
|
|
1309
|
-
const
|
|
1310
|
-
|
|
1311
|
-
|
|
1271
|
+
const relatedAs = relQuery.q.as || relQuery.table;
|
|
1272
|
+
const joinSql = new pqb_internal.RawSql("");
|
|
1273
|
+
let mainAs;
|
|
1274
|
+
let aliasedPrimaryKeys;
|
|
1275
|
+
const setNulls = Object.fromEntries(foreignKeys.map((foreignKey) => [foreignKey, null]));
|
|
1276
|
+
let queryToDisconnect = relQuery.clone().updateFrom("");
|
|
1277
|
+
if (hasDisconnect && params.set === void 0) queryToDisconnect = queryToDisconnect.where({ OR: (0, pqb_internal.toArray)(params.disconnect) });
|
|
1278
|
+
if (params.set && hasSetConditions) queryToDisconnect = queryToDisconnect.whereNot(Array.isArray(params.set) ? { OR: params.set } : params.set);
|
|
1279
|
+
const disconnectQuery = (0, pqb_internal._queryUpdate)(queryToDisconnect.whereSql(joinSql), setNulls);
|
|
1280
|
+
disconnectQuery.q.returnType = "void";
|
|
1281
|
+
const setJoinSql = () => {
|
|
1282
|
+
if (mainAs && aliasedPrimaryKeys) joinSql._sql = foreignKeys.map((foreignKey, i) => `"${relatedAs}"."${relQuery.shape[foreignKey].data.name || foreignKey}" = "${mainAs}"."${aliasedPrimaryKeys[i]}"`).join(" AND ");
|
|
1283
|
+
};
|
|
1284
|
+
(0, pqb_internal._hookSelectColumns)(querySelf, primaryKeys, (aliased) => {
|
|
1285
|
+
aliasedPrimaryKeys = aliased;
|
|
1286
|
+
setJoinSql();
|
|
1287
|
+
});
|
|
1288
|
+
(0, pqb_internal._appendQuery)(querySelf, disconnectQuery, (as) => {
|
|
1289
|
+
mainAs = as;
|
|
1290
|
+
disconnectQuery.q.updateFrom.w = as;
|
|
1291
|
+
disconnectQuery.q.joinedShapes = {
|
|
1292
|
+
...disconnectQuery.q.joinedShapes,
|
|
1293
|
+
[as]: {}
|
|
1294
|
+
};
|
|
1295
|
+
setJoinSql();
|
|
1296
|
+
});
|
|
1297
|
+
}
|
|
1298
|
+
const hasAdd = params.add && (!Array.isArray(params.add) || params.add.length > 0);
|
|
1299
|
+
const updates = params.update ? (0, pqb_internal.toArray)(params.update) : [];
|
|
1300
|
+
const hasUpdate = updates.some((update) => !Array.isArray(update.where) || update.where.length);
|
|
1301
|
+
const relatedIdsAs = hasUpdate && (hasAdd || hasSetConditions) ? [] : void 0;
|
|
1302
|
+
const sourceCondition = relatedIdsAs ? new pqb_internal.RawSql("") : void 0;
|
|
1303
|
+
const updateFrom = relatedIdsAs ? new pqb_internal.RawSql("") : void 0;
|
|
1304
|
+
const upsertRelatedIdsAs = params.upsert ? [] : void 0;
|
|
1305
|
+
const upsertSourceCondition = upsertRelatedIdsAs ? new pqb_internal.RawSql("") : void 0;
|
|
1306
|
+
const upsertUpdateFrom = upsertRelatedIdsAs ? new pqb_internal.RawSql("") : void 0;
|
|
1307
|
+
let appendRelatedQuery;
|
|
1308
|
+
const setSourceCondition = (relatedIdsAs, sourceCondition, updateFrom, relatedPrimaryKeys) => {
|
|
1309
|
+
if (!relatedIdsAs) return;
|
|
1310
|
+
const relatedAs = state.query.q.as || state.query.table;
|
|
1311
|
+
const sourceAs = "\"relatedIds\"";
|
|
1312
|
+
sourceCondition._sql = relatedPrimaryKeys.map((primaryKey) => `"${relatedAs}"."${state.query.shape[primaryKey].data.name || primaryKey}" = ${sourceAs}."${primaryKey}"`).join(" AND ");
|
|
1313
|
+
const columns = relatedPrimaryKeys.map((key) => `"${key}"`).join(", ");
|
|
1314
|
+
updateFrom._sql = `(${relatedIdsAs.map((as) => `SELECT ${columns} FROM ${as._sql}`).join(" UNION ALL ")}) AS ${sourceAs}`;
|
|
1315
|
+
};
|
|
1316
|
+
if (hasAdd || hasSetConditions) {
|
|
1317
|
+
const { query: relQuery } = state;
|
|
1318
|
+
const relatedWheres = [...hasAdd ? (0, pqb_internal.toArray)(params.add) : [], ...hasSetConditions ? (0, pqb_internal.toArray)(params.set) : []];
|
|
1319
|
+
if (relatedIdsAs || upsertRelatedIdsAs) {
|
|
1320
|
+
const relatedPrimaryKeys = (0, pqb_internal.getPrimaryKeys)(relQuery);
|
|
1321
|
+
const relatedQuery = (0, pqb_internal._querySelect)(relQuery.clone().where({ OR: relatedWheres }), relatedPrimaryKeys);
|
|
1322
|
+
relatedQuery.q.returnType = "void";
|
|
1323
|
+
(0, pqb_internal._appendQuery)(querySelf, relatedQuery, () => {}, (as) => {
|
|
1324
|
+
if (relatedIdsAs) {
|
|
1325
|
+
relatedIdsAs.push(new pqb_internal.RawSql(`"${as}"`));
|
|
1326
|
+
setSourceCondition(relatedIdsAs, sourceCondition, updateFrom, relatedPrimaryKeys);
|
|
1327
|
+
}
|
|
1328
|
+
if (upsertRelatedIdsAs) {
|
|
1329
|
+
upsertRelatedIdsAs.push(new pqb_internal.RawSql(`"${as}"`));
|
|
1330
|
+
setSourceCondition(upsertRelatedIdsAs, upsertSourceCondition, upsertUpdateFrom, relatedPrimaryKeys);
|
|
1331
|
+
}
|
|
1332
|
+
});
|
|
1333
|
+
if (!querySelf.q.upsertUpdate) relatedQuery.q.ensureCount = {
|
|
1334
|
+
expected: relatedWheres.length,
|
|
1335
|
+
message: `based on \`${hasAdd ? "add" : "set"}\` conditions`
|
|
1336
|
+
};
|
|
1337
|
+
}
|
|
1338
|
+
appendRelatedQuery = () => {
|
|
1339
|
+
const ids = makeRelationIds();
|
|
1340
|
+
const addQuery = (0, pqb_internal._queryUpdate)(sourceCondition ? relQuery.clone().where({
|
|
1341
|
+
OR: relatedWheres,
|
|
1342
|
+
NOT: { OR: updates.flatMap((update) => (0, pqb_internal.toArray)(update.where)) }
|
|
1343
|
+
}) : relQuery.clone().where({ OR: relatedWheres }), ids.setIds);
|
|
1344
|
+
addQuery.q.returnType = "void";
|
|
1345
|
+
if (!sourceCondition && !querySelf.q.upsertUpdate) addQuery.q.ensureCount = {
|
|
1346
|
+
expected: relatedWheres.length,
|
|
1347
|
+
message: `based on \`${hasAdd ? "add" : "set"}\` conditions`
|
|
1348
|
+
};
|
|
1349
|
+
(0, pqb_internal._appendQuery)(querySelf, addQuery, ids.setAppendedAs);
|
|
1350
|
+
};
|
|
1351
|
+
}
|
|
1352
|
+
if (upsertRelatedIdsAs) {
|
|
1353
|
+
const { query: relQuery } = state;
|
|
1354
|
+
const ids = makeRelationIds();
|
|
1355
|
+
let existingRelQuery = hasDisconnect ? ids.existingRelQuery.whereNot({ OR: (0, pqb_internal.toArray)(params.disconnect) }) : ids.existingRelQuery;
|
|
1356
|
+
if (params.set !== void 0) existingRelQuery = hasSetConditions ? existingRelQuery.where(Array.isArray(params.set) ? { OR: params.set } : params.set) : existingRelQuery.none();
|
|
1357
|
+
const relatedPrimaryKeys = (0, pqb_internal.getPrimaryKeys)(relQuery);
|
|
1358
|
+
const relatedQuery = (0, pqb_internal._querySelect)(existingRelQuery, relatedPrimaryKeys);
|
|
1359
|
+
relatedQuery.q.returnType = "void";
|
|
1360
|
+
(0, pqb_internal._appendQuery)(querySelf, relatedQuery, ids.setAppendedAs, (as) => {
|
|
1361
|
+
upsertRelatedIdsAs.push(new pqb_internal.RawSql(`"${as}"`));
|
|
1362
|
+
setSourceCondition(upsertRelatedIdsAs, upsertSourceCondition, upsertUpdateFrom, relatedPrimaryKeys);
|
|
1363
|
+
});
|
|
1364
|
+
}
|
|
1365
|
+
if (params.delete && (!Array.isArray(params.delete) || params.delete.length > 0)) {
|
|
1366
|
+
const ids = makeRelationIds();
|
|
1367
|
+
const deleteQuery = (0, pqb_internal._queryDelete)(ids.existingRelQuery.where({ OR: (0, pqb_internal.toArray)(params.delete) }));
|
|
1368
|
+
deleteQuery.q.returnType = "void";
|
|
1369
|
+
(0, pqb_internal._appendQuery)(querySelf, deleteQuery, ids.setAppendedAs);
|
|
1370
|
+
}
|
|
1371
|
+
appendRelatedQuery?.();
|
|
1372
|
+
if (params.upsert) {
|
|
1373
|
+
const { query: relQuery } = state;
|
|
1374
|
+
for (const upsert of (0, pqb_internal.toArray)(params.upsert)) {
|
|
1375
|
+
const ids = makeRelationIds();
|
|
1376
|
+
const appendedQuery = (0, pqb_internal._queryUpsert)(upsertSourceCondition ? relQuery.clone().where(upsert.findBy).whereSql(upsertSourceCondition) : ids.existingRelQuery.where(upsert.findBy), makeNestedUpdateUpsertData(upsertSourceCondition ? {
|
|
1377
|
+
...upsert,
|
|
1378
|
+
update: {
|
|
1379
|
+
...upsert.update,
|
|
1380
|
+
...ids.setIds
|
|
1381
|
+
}
|
|
1382
|
+
} : upsert, ids.setIds));
|
|
1383
|
+
if (upsertUpdateFrom) appendedQuery.q.updateFrom = {
|
|
1384
|
+
u: true,
|
|
1385
|
+
x: upsertUpdateFrom
|
|
1386
|
+
};
|
|
1387
|
+
appendedQuery.q.returnType = "void";
|
|
1388
|
+
(0, pqb_internal._appendQuery)(querySelf, appendedQuery, ids.setAppendedAs);
|
|
1389
|
+
}
|
|
1390
|
+
}
|
|
1391
|
+
if (hasUpdate) for (const update of updates) {
|
|
1392
|
+
if (Array.isArray(update.where) && update.where.length === 0) continue;
|
|
1393
|
+
const { query: relQuery } = state;
|
|
1394
|
+
const ids = makeRelationIds();
|
|
1395
|
+
let relatedUpdateQuery = relQuery.clone().where({ OR: (0, pqb_internal.toArray)(update.where) });
|
|
1396
|
+
if (sourceCondition) {
|
|
1397
|
+
relatedUpdateQuery.q.updateFrom = {
|
|
1398
|
+
u: true,
|
|
1399
|
+
x: updateFrom
|
|
1400
|
+
};
|
|
1401
|
+
relatedUpdateQuery = relatedUpdateQuery.whereSql(sourceCondition);
|
|
1402
|
+
} else relatedUpdateQuery = ids.existingRelQuery.where({ OR: (0, pqb_internal.toArray)(update.where) });
|
|
1403
|
+
const updateQuery = (0, pqb_internal._queryUpdate)(relatedUpdateQuery, sourceCondition ? {
|
|
1404
|
+
...update.data,
|
|
1405
|
+
...ids.setIds
|
|
1406
|
+
} : update.data);
|
|
1407
|
+
updateQuery.q.returnType = "void";
|
|
1408
|
+
(0, pqb_internal._appendQuery)(querySelf, updateQuery, ids.setAppendedAs);
|
|
1409
|
+
}
|
|
1410
|
+
if (params.create?.length) {
|
|
1411
|
+
const { query: relQuery } = state;
|
|
1412
|
+
const ids = makeRelationIds();
|
|
1413
|
+
const createQuery = (0, pqb_internal._queryInsertMany)(relQuery.clone(), params.create.map((data) => ({
|
|
1414
|
+
...data,
|
|
1415
|
+
...ids.setIds
|
|
1416
|
+
})));
|
|
1417
|
+
createQuery.q.returnType = "void";
|
|
1418
|
+
(0, pqb_internal._appendQuery)(querySelf, createQuery, ids.setAppendedAs);
|
|
1312
1419
|
}
|
|
1313
1420
|
};
|
|
1314
1421
|
const makeHasManyThroughMethod = ({ table, query, relation, relationName, relPKeys }) => {
|
|
@@ -1392,12 +1499,29 @@ const nestedInsert$1 = ({ query, primaryKeys, foreignKeys }) => {
|
|
|
1392
1499
|
}
|
|
1393
1500
|
await (0, pqb_internal._queryCreateMany)(t, records);
|
|
1394
1501
|
}
|
|
1502
|
+
items.length = 0;
|
|
1503
|
+
for (const item of data) if (item[1].upsert) items.push(item);
|
|
1504
|
+
if (items.length) {
|
|
1505
|
+
const queries = [];
|
|
1506
|
+
for (const [selfData, { upsert }] of items) {
|
|
1507
|
+
const foreignKeyValues = {};
|
|
1508
|
+
for (let i = 0; i < len; i++) foreignKeyValues[foreignKeys[i]] = selfData[primaryKeys[i]];
|
|
1509
|
+
for (const item of (0, pqb_internal.toArray)(upsert)) queries.push((0, pqb_internal._queryUpsert)(t.clone().where(item.findBy), {
|
|
1510
|
+
update: {
|
|
1511
|
+
...item.update,
|
|
1512
|
+
...foreignKeyValues
|
|
1513
|
+
},
|
|
1514
|
+
create: makeNestedUpdateUpsertData(item, foreignKeyValues).create
|
|
1515
|
+
}));
|
|
1516
|
+
}
|
|
1517
|
+
await Promise.all(queries);
|
|
1518
|
+
}
|
|
1395
1519
|
});
|
|
1396
1520
|
};
|
|
1397
1521
|
const hasManyCreate = (key, state, nestedInsertFn, self, ctx, items, rowIndexes, count) => {
|
|
1398
1522
|
const querySelf = self;
|
|
1399
1523
|
if (count <= querySelf.qb.internal.nestedCreateBatchMax) {
|
|
1400
|
-
const { query:
|
|
1524
|
+
const { query: relQuery, primaryKeys, foreignKeys } = state;
|
|
1401
1525
|
let nestedCreateItems;
|
|
1402
1526
|
items.forEach((item, i) => {
|
|
1403
1527
|
const value = item[key];
|
|
@@ -1407,26 +1531,28 @@ const hasManyCreate = (key, state, nestedInsertFn, self, ctx, items, rowIndexes,
|
|
|
1407
1531
|
items: []
|
|
1408
1532
|
};
|
|
1409
1533
|
nestedCreateItem.indexes.push(rowIndexes[i]);
|
|
1410
|
-
const data = value.create.map((obj) => {
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1534
|
+
const data = value.create.map((obj) => ({
|
|
1535
|
+
...obj,
|
|
1536
|
+
...makeRawSqlPlaceholderRecord(foreignKeys)
|
|
1537
|
+
}));
|
|
1538
|
+
nestedCreateItem.items.push(data);
|
|
1539
|
+
}
|
|
1540
|
+
for (const kind of [
|
|
1541
|
+
"connect",
|
|
1542
|
+
"connectOrCreate",
|
|
1543
|
+
"upsert"
|
|
1544
|
+
]) {
|
|
1545
|
+
const values = kind === "upsert" ? value.upsert ? (0, pqb_internal.toArray)(value.upsert) : void 0 : value[kind];
|
|
1546
|
+
if (!values?.length) continue;
|
|
1547
|
+
const nestedCreateItem = (nestedCreateItems ??= {})[kind] ??= {
|
|
1548
|
+
indexes: [],
|
|
1549
|
+
items: [],
|
|
1550
|
+
values: []
|
|
1551
|
+
};
|
|
1552
|
+
nestedCreateItem.indexes.push(rowIndexes[i]);
|
|
1553
|
+
nestedCreateItem.values.push(values);
|
|
1554
|
+
const data = makeRawSqlPlaceholderRecord(foreignKeys);
|
|
1415
1555
|
nestedCreateItem.items.push(data);
|
|
1416
|
-
} else {
|
|
1417
|
-
const kind = value.connect?.length ? "connect" : value.connectOrCreate?.length ? "connectOrCreate" : void 0;
|
|
1418
|
-
if (kind) {
|
|
1419
|
-
const nestedCreateItem = (nestedCreateItems ??= {})[kind] ??= {
|
|
1420
|
-
indexes: [],
|
|
1421
|
-
items: [],
|
|
1422
|
-
values: []
|
|
1423
|
-
};
|
|
1424
|
-
nestedCreateItem.indexes.push(rowIndexes[i]);
|
|
1425
|
-
nestedCreateItem.values.push(value[kind]);
|
|
1426
|
-
const data = {};
|
|
1427
|
-
for (const key of foreignKeys) data[key] = new pqb_internal.RawSql("");
|
|
1428
|
-
nestedCreateItem.items.push(data);
|
|
1429
|
-
}
|
|
1430
1556
|
}
|
|
1431
1557
|
});
|
|
1432
1558
|
if (!nestedCreateItems) return;
|
|
@@ -1437,6 +1563,7 @@ const hasManyCreate = (key, state, nestedInsertFn, self, ctx, items, rowIndexes,
|
|
|
1437
1563
|
let upsertCreateAs;
|
|
1438
1564
|
let connectAs;
|
|
1439
1565
|
let connectOrCreateAs;
|
|
1566
|
+
let upsertAs;
|
|
1440
1567
|
const setUpsertCreatePlaceholders = () => {
|
|
1441
1568
|
if (!upsertCreateAs || !createAliasedPrimaryKeys) return;
|
|
1442
1569
|
const aliasedPrimaryKeys = createAliasedPrimaryKeys;
|
|
@@ -1444,38 +1571,28 @@ const hasManyCreate = (key, state, nestedInsertFn, self, ctx, items, rowIndexes,
|
|
|
1444
1571
|
if (createSelectAs) foreignKeys.forEach((key, keyI) => {
|
|
1445
1572
|
createSelectAs[key]._sql = selectCteColumnFromManySql(upsertCreateAs, aliasedPrimaryKeys[keyI], 0, 1);
|
|
1446
1573
|
});
|
|
1447
|
-
if (connect)
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
});
|
|
1451
|
-
if (connectOrCreate) foreignKeys.forEach((key, keyI) => {
|
|
1452
|
-
const primaryKey = aliasedPrimaryKeys[keyI];
|
|
1453
|
-
for (let i = 0; i < connectOrCreate.items.length; i++) connectOrCreate.items[i][key]._sql = selectCteColumnFromManySql(upsertCreateAs, primaryKey, connectOrCreate.indexes[i], count);
|
|
1454
|
-
});
|
|
1574
|
+
if (connect) for (let i = 0; i < connect.items.length; i++) setRawSqlPlaceholderRecordFromCte(connect.items[i], foreignKeys, upsertCreateAs, aliasedPrimaryKeys, connect.indexes[i], count);
|
|
1575
|
+
if (connectOrCreate) for (let i = 0; i < connectOrCreate.items.length; i++) setRawSqlPlaceholderRecordFromCte(connectOrCreate.items[i], foreignKeys, upsertCreateAs, aliasedPrimaryKeys, connectOrCreate.indexes[i], count);
|
|
1576
|
+
if (upsert) for (let i = 0; i < upsert.items.length; i++) setRawSqlPlaceholderRecordFromCte(upsert.items[i], foreignKeys, upsertCreateAs, aliasedPrimaryKeys, upsert.indexes[i], count);
|
|
1455
1577
|
};
|
|
1456
1578
|
(0, pqb_internal._hookSelectColumns)(querySelf, primaryKeys, (aliasedPrimaryKeys) => {
|
|
1457
1579
|
createAliasedPrimaryKeys = aliasedPrimaryKeys;
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
for (const item of create.items[i]) item[key]._sql = sql;
|
|
1463
|
-
}
|
|
1464
|
-
if (connect && connectAs) for (let i = 0; i < connect.items.length; i++) connect.items[i][key]._sql = selectCteColumnFromManySql(connectAs, primaryKey, connect.indexes[i], count);
|
|
1465
|
-
if (connectOrCreate && connectOrCreateAs) for (let i = 0; i < connectOrCreate.items.length; i++) connectOrCreate.items[i][key]._sql = selectCteColumnFromManySql(connectOrCreateAs, primaryKey, connectOrCreate.indexes[i], count);
|
|
1466
|
-
});
|
|
1580
|
+
if (create && createAs) for (let i = 0; i < create.items.length; i++) for (const item of create.items[i]) setRawSqlPlaceholderRecordFromCte(item, foreignKeys, createAs, aliasedPrimaryKeys, create.indexes[i], count);
|
|
1581
|
+
if (connect && connectAs) for (let i = 0; i < connect.items.length; i++) setRawSqlPlaceholderRecordFromCte(connect.items[i], foreignKeys, connectAs, aliasedPrimaryKeys, connect.indexes[i], count);
|
|
1582
|
+
if (connectOrCreate && connectOrCreateAs) for (let i = 0; i < connectOrCreate.items.length; i++) setRawSqlPlaceholderRecordFromCte(connectOrCreate.items[i], foreignKeys, connectOrCreateAs, aliasedPrimaryKeys, connectOrCreate.indexes[i], count);
|
|
1583
|
+
if (upsert && upsertAs) for (let i = 0; i < upsert.items.length; i++) setRawSqlPlaceholderRecordFromCte(upsert.items[i], foreignKeys, upsertAs, aliasedPrimaryKeys, upsert.indexes[i], count);
|
|
1467
1584
|
setUpsertCreatePlaceholders();
|
|
1468
1585
|
});
|
|
1469
|
-
const { create, connect, connectOrCreate } = nestedCreateItems;
|
|
1586
|
+
const { create, connect, connectOrCreate, upsert } = nestedCreateItems;
|
|
1470
1587
|
if (create) {
|
|
1471
1588
|
let query;
|
|
1472
1589
|
if (querySelf.q.type === "upsert") {
|
|
1473
1590
|
createWhereExists = new pqb_internal.RawSql("");
|
|
1474
1591
|
createSelectAs = {};
|
|
1475
1592
|
for (const key of foreignKeys) createSelectAs[key] = new pqb_internal.RawSql("");
|
|
1476
|
-
const sourceQuery = (0, pqb_internal._queryWhere)((0, pqb_internal._queryTake)((0, pqb_internal._querySelect)((0, pqb_internal._clone)(
|
|
1477
|
-
query = (0, pqb_internal._queryInsertManyFrom)((0, pqb_internal._clone)(
|
|
1478
|
-
} else query = (0, pqb_internal._queryInsertMany)((0, pqb_internal._clone)(
|
|
1593
|
+
const sourceQuery = (0, pqb_internal._queryWhere)((0, pqb_internal._queryTake)((0, pqb_internal._querySelect)((0, pqb_internal._clone)(relQuery.qb), [createSelectAs])), [createWhereExists]);
|
|
1594
|
+
query = (0, pqb_internal._queryInsertManyFrom)((0, pqb_internal._clone)(relQuery), sourceQuery, create.items.flat());
|
|
1595
|
+
} else query = (0, pqb_internal._queryInsertMany)((0, pqb_internal._clone)(relQuery), create.items.flat());
|
|
1479
1596
|
if (querySelf.q.type === "upsert") (0, pqb_internal._appendQueryOnUpsertCreate)(querySelf, query, (as) => {
|
|
1480
1597
|
upsertCreateAs = as;
|
|
1481
1598
|
setUpsertCreatePlaceholders();
|
|
@@ -1484,9 +1601,9 @@ const hasManyCreate = (key, state, nestedInsertFn, self, ctx, items, rowIndexes,
|
|
|
1484
1601
|
}
|
|
1485
1602
|
if (connect) connect.values.forEach((value, i) => {
|
|
1486
1603
|
const connectWhereExists = querySelf.q.type === "upsert" ? new pqb_internal.RawSql("") : void 0;
|
|
1487
|
-
const query = (0, pqb_internal._queryUpdateOrThrow)(
|
|
1604
|
+
const query = (0, pqb_internal._queryUpdateOrThrow)(relQuery.whereOneOf(...value), connect.items[i]);
|
|
1488
1605
|
if (connectWhereExists) (0, pqb_internal._queryWhere)(query, [connectWhereExists]);
|
|
1489
|
-
query.q.ensureCount = value.length;
|
|
1606
|
+
query.q.ensureCount = { expected: value.length };
|
|
1490
1607
|
(querySelf.q.type === "upsert" ? pqb_internal._appendQueryOnUpsertCreate : pqb_internal._appendQuery)(querySelf, query, (as) => {
|
|
1491
1608
|
upsertCreateAs = as;
|
|
1492
1609
|
setUpsertCreatePlaceholders();
|
|
@@ -1501,10 +1618,10 @@ const hasManyCreate = (key, state, nestedInsertFn, self, ctx, items, rowIndexes,
|
|
|
1501
1618
|
const connectOrCreateSelectAs = {};
|
|
1502
1619
|
if (connectOrCreateWhereExists) for (const key of foreignKeys) {
|
|
1503
1620
|
const value = foreignKeyValues[key];
|
|
1504
|
-
value.result = { value:
|
|
1621
|
+
value.result = { value: relQuery.qb.shape[key] };
|
|
1505
1622
|
connectOrCreateSelectAs[key] = value;
|
|
1506
1623
|
}
|
|
1507
|
-
const query = (0, pqb_internal._queryUpsert)(
|
|
1624
|
+
const query = (0, pqb_internal._queryUpsert)(relQuery.where(value.where), {
|
|
1508
1625
|
update: foreignKeyValues,
|
|
1509
1626
|
create: {
|
|
1510
1627
|
...value.create,
|
|
@@ -1513,8 +1630,8 @@ const hasManyCreate = (key, state, nestedInsertFn, self, ctx, items, rowIndexes,
|
|
|
1513
1630
|
});
|
|
1514
1631
|
if (connectOrCreateWhereExists) {
|
|
1515
1632
|
(0, pqb_internal._queryWhere)(query, [connectOrCreateWhereExists]);
|
|
1516
|
-
const guardQuery = (0, pqb_internal._queryWhere)((0, pqb_internal._queryTake)((0, pqb_internal._querySelect)((0, pqb_internal._clone)(
|
|
1517
|
-
const sourceQuery = (0, pqb_internal._querySelect)((0, pqb_internal._clone)(
|
|
1633
|
+
const guardQuery = (0, pqb_internal._queryWhere)((0, pqb_internal._queryTake)((0, pqb_internal._querySelect)((0, pqb_internal._clone)(relQuery.qb), [{ one: new pqb_internal.RawSql("1") }])), [connectOrCreateWhereExists]);
|
|
1634
|
+
const sourceQuery = (0, pqb_internal._querySelect)((0, pqb_internal._clone)(relQuery.qb).from(guardQuery), [connectOrCreateSelectAs]);
|
|
1518
1635
|
const q = query.q;
|
|
1519
1636
|
const columns = q.columns || [];
|
|
1520
1637
|
const foreignKeysSet = new Set(foreignKeys);
|
|
@@ -1531,6 +1648,43 @@ const hasManyCreate = (key, state, nestedInsertFn, self, ctx, items, rowIndexes,
|
|
|
1531
1648
|
});
|
|
1532
1649
|
}
|
|
1533
1650
|
});
|
|
1651
|
+
if (upsert) upsert.values.forEach((array, i) => {
|
|
1652
|
+
const foreignKeyValues = upsert.items[i];
|
|
1653
|
+
for (const value of array) {
|
|
1654
|
+
const upsertWhereExists = querySelf.q.type === "upsert" ? new pqb_internal.RawSql("") : void 0;
|
|
1655
|
+
const upsertSelectAs = {};
|
|
1656
|
+
if (upsertWhereExists) for (const key of foreignKeys) {
|
|
1657
|
+
const foreignKeyValue = foreignKeyValues[key];
|
|
1658
|
+
foreignKeyValue.result = { value: relQuery.qb.shape[key] };
|
|
1659
|
+
upsertSelectAs[key] = foreignKeyValue;
|
|
1660
|
+
}
|
|
1661
|
+
const query = (0, pqb_internal._queryUpsert)(relQuery.where(value.findBy), {
|
|
1662
|
+
update: {
|
|
1663
|
+
...value.update,
|
|
1664
|
+
...foreignKeyValues
|
|
1665
|
+
},
|
|
1666
|
+
create: makeNestedUpdateUpsertData(value, foreignKeyValues).create
|
|
1667
|
+
});
|
|
1668
|
+
if (upsertWhereExists) {
|
|
1669
|
+
(0, pqb_internal._queryWhere)(query, [upsertWhereExists]);
|
|
1670
|
+
const guardQuery = (0, pqb_internal._queryWhere)((0, pqb_internal._queryTake)((0, pqb_internal._querySelect)((0, pqb_internal._clone)(relQuery.qb), [{ one: new pqb_internal.RawSql("1") }])), [upsertWhereExists]);
|
|
1671
|
+
const sourceQuery = (0, pqb_internal._querySelect)((0, pqb_internal._clone)(relQuery.qb).from(guardQuery), [upsertSelectAs]);
|
|
1672
|
+
const q = query.q;
|
|
1673
|
+
const columns = q.columns || [];
|
|
1674
|
+
const foreignKeysSet = new Set(foreignKeys);
|
|
1675
|
+
q.columns = [...foreignKeys, ...columns.filter((column) => !foreignKeysSet.has(column))];
|
|
1676
|
+
q.values = q.values.map((row) => row.filter((_, i) => !foreignKeysSet.has(columns[i])));
|
|
1677
|
+
q.queryColumnsCount = foreignKeys.length;
|
|
1678
|
+
q.insertFrom = (0, pqb_internal.prepareSubQueryForSql)(query, sourceQuery);
|
|
1679
|
+
}
|
|
1680
|
+
(querySelf.q.type === "upsert" ? pqb_internal._appendQueryOnUpsertCreate : pqb_internal._appendQuery)(querySelf, query, (as) => {
|
|
1681
|
+
upsertCreateAs = as;
|
|
1682
|
+
setUpsertCreatePlaceholders();
|
|
1683
|
+
upsertAs = as;
|
|
1684
|
+
if (upsertWhereExists) upsertWhereExists._sql = `EXISTS (SELECT 1 FROM "${as}")`;
|
|
1685
|
+
});
|
|
1686
|
+
}
|
|
1687
|
+
});
|
|
1534
1688
|
} else hasRelationHandleCreate(querySelf, ctx, items, rowIndexes, key, state.primaryKeys, nestedInsertFn);
|
|
1535
1689
|
};
|
|
1536
1690
|
var HasManyVirtualColumn = class extends pqb_internal.VirtualColumn {
|
|
@@ -1539,7 +1693,6 @@ var HasManyVirtualColumn = class extends pqb_internal.VirtualColumn {
|
|
|
1539
1693
|
this.key = key;
|
|
1540
1694
|
this.state = state;
|
|
1541
1695
|
this.nestedInsert = nestedInsert$1(state);
|
|
1542
|
-
this.nestedUpdate = nestedUpdate$1(state);
|
|
1543
1696
|
this.setNulls = {};
|
|
1544
1697
|
for (const foreignKey of state.foreignKeys) this.setNulls[foreignKey] = null;
|
|
1545
1698
|
}
|
|
@@ -1547,7 +1700,7 @@ var HasManyVirtualColumn = class extends pqb_internal.VirtualColumn {
|
|
|
1547
1700
|
hasManyCreate(this.key, this.state, this.nestedInsert, self, ctx, items, rowIndexes, count);
|
|
1548
1701
|
}
|
|
1549
1702
|
update(self, set) {
|
|
1550
|
-
hasManyUpdate(this.key, this.state,
|
|
1703
|
+
hasManyUpdate(this.key, this.state, self, set);
|
|
1551
1704
|
}
|
|
1552
1705
|
};
|
|
1553
1706
|
const makeHasManyMethod = (tableConfig, table, relation, relationName, query) => {
|
|
@@ -1606,6 +1759,197 @@ const makeHasManyMethod = (tableConfig, table, relation, relationName, query) =>
|
|
|
1606
1759
|
}
|
|
1607
1760
|
};
|
|
1608
1761
|
};
|
|
1762
|
+
const hasAndBelongsToManyCreate = (key, state, nestedInsertFn, self, ctx, items, rowIndexes, count) => {
|
|
1763
|
+
const querySelf = self;
|
|
1764
|
+
if (count <= querySelf.qb.internal.nestedCreateBatchMax) {
|
|
1765
|
+
const { relatedTableQuery: relQuery, joinTableQuery, primaryKeys, foreignKeys, throughForeignKeys, throughPrimaryKeys } = state;
|
|
1766
|
+
const nestedRecords = [];
|
|
1767
|
+
const nestedConnects = [];
|
|
1768
|
+
const nestedConnectOrCreates = [];
|
|
1769
|
+
const nestedUpserts = [];
|
|
1770
|
+
for (let i = 0; i < items.length; i++) {
|
|
1771
|
+
const value = items[i][key];
|
|
1772
|
+
if (value.create?.length) nestedRecords.push({
|
|
1773
|
+
rowIndex: rowIndexes[i],
|
|
1774
|
+
records: value.create,
|
|
1775
|
+
foreignKeyValues: makeRawSqlPlaceholders(foreignKeys.length)
|
|
1776
|
+
});
|
|
1777
|
+
if (value.connect?.length) nestedConnects.push({
|
|
1778
|
+
rowIndex: rowIndexes[i],
|
|
1779
|
+
connect: value.connect,
|
|
1780
|
+
foreignKeyValues: makeRawSqlPlaceholders(foreignKeys.length)
|
|
1781
|
+
});
|
|
1782
|
+
if (value.connectOrCreate?.length) nestedConnectOrCreates.push({
|
|
1783
|
+
rowIndex: rowIndexes[i],
|
|
1784
|
+
connectOrCreate: value.connectOrCreate,
|
|
1785
|
+
foreignKeyValues: makeRawSqlPlaceholders(foreignKeys.length)
|
|
1786
|
+
});
|
|
1787
|
+
if (value.upsert) nestedUpserts.push({
|
|
1788
|
+
rowIndex: rowIndexes[i],
|
|
1789
|
+
upsert: value.upsert,
|
|
1790
|
+
foreignKeyValues: makeRawSqlPlaceholders(foreignKeys.length)
|
|
1791
|
+
});
|
|
1792
|
+
}
|
|
1793
|
+
if (nestedRecords.length || nestedConnects.length || nestedConnectOrCreates.length || nestedUpserts.length) {
|
|
1794
|
+
let mainAs;
|
|
1795
|
+
let aliasedPrimaryKeysForMain;
|
|
1796
|
+
const setMainForeignKeyValues = () => {
|
|
1797
|
+
if (!mainAs || !aliasedPrimaryKeysForMain) return;
|
|
1798
|
+
for (const { rowIndex, foreignKeyValues } of [
|
|
1799
|
+
...nestedRecords,
|
|
1800
|
+
...nestedConnects,
|
|
1801
|
+
...nestedConnectOrCreates,
|
|
1802
|
+
...nestedUpserts
|
|
1803
|
+
]) setRawSqlPlaceholdersFromCte(foreignKeyValues, mainAs, aliasedPrimaryKeysForMain, rowIndex, count);
|
|
1804
|
+
};
|
|
1805
|
+
const setMainAs = (as) => {
|
|
1806
|
+
mainAs = as;
|
|
1807
|
+
setMainForeignKeyValues();
|
|
1808
|
+
};
|
|
1809
|
+
(0, pqb_internal._hookSelectColumns)(querySelf, primaryKeys, (aliasedPrimaryKeys) => {
|
|
1810
|
+
aliasedPrimaryKeysForMain = aliasedPrimaryKeys;
|
|
1811
|
+
setMainForeignKeyValues();
|
|
1812
|
+
});
|
|
1813
|
+
const joinQueries = [];
|
|
1814
|
+
for (const nested of nestedRecords) {
|
|
1815
|
+
const { foreignKeyValues } = nested;
|
|
1816
|
+
const throughForeignKeyValues = makeRawSqlPlaceholders(throughForeignKeys.length);
|
|
1817
|
+
const selectAs = {};
|
|
1818
|
+
for (let i = 0; i < foreignKeys.length; i++) selectAs[foreignKeys[i]] = foreignKeyValues[i];
|
|
1819
|
+
for (let i = 0; i < throughForeignKeys.length; i++) selectAs[throughForeignKeys[i]] = throughForeignKeyValues[i];
|
|
1820
|
+
const joinRows = (0, pqb_internal._querySelect)((0, pqb_internal._clone)(relQuery.baseQuery), [selectAs]);
|
|
1821
|
+
const joinQuery = (0, pqb_internal._queryInsertForEachFrom)((0, pqb_internal._clone)(joinTableQuery), joinRows);
|
|
1822
|
+
joinQuery.q.returnType = "void";
|
|
1823
|
+
joinQuery.q.ensureCount = { expected: 1 };
|
|
1824
|
+
if (querySelf.q.type === "upsert") {
|
|
1825
|
+
const createWhereExists = new pqb_internal.RawSql("");
|
|
1826
|
+
const sourceQuery = (0, pqb_internal._queryWhere)((0, pqb_internal._queryTake)((0, pqb_internal._querySelect)((0, pqb_internal._clone)(relQuery.qb), [{}])), [createWhereExists]);
|
|
1827
|
+
const query = (0, pqb_internal._queryInsertManyFrom)((0, pqb_internal._querySelect)((0, pqb_internal._clone)(relQuery), throughPrimaryKeys), sourceQuery, nested.records);
|
|
1828
|
+
const queryWithJoin = (0, pqb_internal._appendQuery)(query, joinQuery, (as) => {
|
|
1829
|
+
joinRows.q.from = as;
|
|
1830
|
+
joinRows.q.schema = void 0;
|
|
1831
|
+
for (let i = 0; i < throughForeignKeyValues.length; i++) throughForeignKeyValues[i]._sql = `"${as}"."${throughPrimaryKeys[i]}"`;
|
|
1832
|
+
});
|
|
1833
|
+
(0, pqb_internal._appendQueryOnUpsertCreate)(querySelf, queryWithJoin, (as) => {
|
|
1834
|
+
setMainAs(as);
|
|
1835
|
+
createWhereExists._sql = `EXISTS (SELECT 1 FROM "${as}")`;
|
|
1836
|
+
});
|
|
1837
|
+
} else {
|
|
1838
|
+
joinQueries.push(joinQuery);
|
|
1839
|
+
const query = (0, pqb_internal._queryInsertMany)((0, pqb_internal._querySelect)((0, pqb_internal._clone)(relQuery), throughPrimaryKeys), nested.records);
|
|
1840
|
+
(0, pqb_internal._appendQuery)(querySelf, query, setMainAs, (as) => {
|
|
1841
|
+
joinRows.q.from = as;
|
|
1842
|
+
joinRows.q.schema = void 0;
|
|
1843
|
+
for (let i = 0; i < throughForeignKeyValues.length; i++) throughForeignKeyValues[i]._sql = `"${as}"."${throughPrimaryKeys[i]}"`;
|
|
1844
|
+
});
|
|
1845
|
+
}
|
|
1846
|
+
}
|
|
1847
|
+
for (const { connect, foreignKeyValues } of nestedConnects) for (const item of connect) {
|
|
1848
|
+
const selectAs = {};
|
|
1849
|
+
for (let i = 0; i < foreignKeys.length; i++) selectAs[foreignKeys[i]] = foreignKeyValues[i];
|
|
1850
|
+
for (let i = 0; i < throughForeignKeys.length; i++) selectAs[throughForeignKeys[i]] = throughPrimaryKeys[i];
|
|
1851
|
+
const joinRows = (0, pqb_internal._queryFindBy)((0, pqb_internal._querySelect)((0, pqb_internal._clone)(relQuery), [selectAs]), item);
|
|
1852
|
+
const joinQuery = (0, pqb_internal._queryInsertForEachFrom)((0, pqb_internal._clone)(joinTableQuery), joinRows);
|
|
1853
|
+
joinQuery.q.returnType = "void";
|
|
1854
|
+
joinQuery.q.ensureCount = { expected: 1 };
|
|
1855
|
+
if (querySelf.q.type === "upsert") {
|
|
1856
|
+
const connectWhereExists = new pqb_internal.RawSql("");
|
|
1857
|
+
(0, pqb_internal._queryWhere)(joinRows, [connectWhereExists]);
|
|
1858
|
+
(0, pqb_internal._appendQueryOnUpsertCreate)(querySelf, joinQuery, (as) => {
|
|
1859
|
+
setMainAs(as);
|
|
1860
|
+
connectWhereExists._sql = `EXISTS (SELECT 1 FROM "${as}")`;
|
|
1861
|
+
});
|
|
1862
|
+
} else joinQueries.push(joinQuery);
|
|
1863
|
+
}
|
|
1864
|
+
for (const joinQuery of joinQueries) (0, pqb_internal._appendQuery)(querySelf, joinQuery, setMainAs);
|
|
1865
|
+
for (const { connectOrCreate, foreignKeyValues } of nestedConnectOrCreates) for (const value of connectOrCreate) {
|
|
1866
|
+
const selectAs = {};
|
|
1867
|
+
for (let i = 0; i < foreignKeys.length; i++) selectAs[foreignKeys[i]] = foreignKeyValues[i];
|
|
1868
|
+
for (let i = 0; i < throughForeignKeys.length; i++) selectAs[throughForeignKeys[i]] = throughPrimaryKeys[i];
|
|
1869
|
+
const connectRows = (0, pqb_internal._queryFindBy)((0, pqb_internal._querySelect)((0, pqb_internal._clone)(relQuery), [selectAs]), value.where);
|
|
1870
|
+
const connectQuery = (0, pqb_internal._queryInsertForEachFrom)((0, pqb_internal._clone)(joinTableQuery), connectRows);
|
|
1871
|
+
connectQuery.q.returnType = "void";
|
|
1872
|
+
const createWhereNotExists = new pqb_internal.RawSql("");
|
|
1873
|
+
const createWhereExists = querySelf.q.type === "upsert" ? new pqb_internal.RawSql("") : void 0;
|
|
1874
|
+
const createSource = (0, pqb_internal._queryWhere)((0, pqb_internal._queryTake)((0, pqb_internal._querySelect)((0, pqb_internal._clone)(relQuery.qb), [{}])), [createWhereNotExists, createWhereExists].filter(Boolean));
|
|
1875
|
+
const createQuery = (0, pqb_internal._queryInsertManyFrom)((0, pqb_internal._querySelect)((0, pqb_internal._clone)(relQuery), throughPrimaryKeys), createSource, [value.create]);
|
|
1876
|
+
const throughForeignKeyValues = makeRawSqlPlaceholders(throughForeignKeys.length);
|
|
1877
|
+
const createSelectAs = {};
|
|
1878
|
+
for (let i = 0; i < foreignKeys.length; i++) createSelectAs[foreignKeys[i]] = foreignKeyValues[i];
|
|
1879
|
+
for (let i = 0; i < throughForeignKeys.length; i++) createSelectAs[throughForeignKeys[i]] = throughForeignKeyValues[i];
|
|
1880
|
+
const createJoinRows = (0, pqb_internal._querySelect)((0, pqb_internal._clone)(relQuery.baseQuery), [createSelectAs]);
|
|
1881
|
+
const createJoinQuery = (0, pqb_internal._queryInsertForEachFrom)((0, pqb_internal._clone)(joinTableQuery), createJoinRows);
|
|
1882
|
+
createJoinQuery.q.returnType = "void";
|
|
1883
|
+
if (querySelf.q.type === "upsert") {
|
|
1884
|
+
const connectWhereExists = new pqb_internal.RawSql("");
|
|
1885
|
+
(0, pqb_internal._queryWhere)(connectRows, [connectWhereExists]);
|
|
1886
|
+
const createQueryWithJoin = (0, pqb_internal._appendQuery)(createQuery, createJoinQuery, (as) => {
|
|
1887
|
+
createJoinRows.q.from = as;
|
|
1888
|
+
createJoinRows.q.schema = void 0;
|
|
1889
|
+
for (let i = 0; i < throughForeignKeyValues.length; i++) throughForeignKeyValues[i]._sql = `"${as}"."${throughPrimaryKeys[i]}"`;
|
|
1890
|
+
});
|
|
1891
|
+
const query = (0, pqb_internal._appendQuery)(connectQuery, createQueryWithJoin, (as) => {
|
|
1892
|
+
createWhereNotExists._sql = `NOT EXISTS (SELECT 1 FROM "${as}")`;
|
|
1893
|
+
});
|
|
1894
|
+
(0, pqb_internal._appendQueryOnUpsertCreate)(querySelf, query, (as) => {
|
|
1895
|
+
setMainAs(as);
|
|
1896
|
+
connectWhereExists._sql = `EXISTS (SELECT 1 FROM "${as}")`;
|
|
1897
|
+
createWhereExists._sql = `EXISTS (SELECT 1 FROM "${as}")`;
|
|
1898
|
+
});
|
|
1899
|
+
} else {
|
|
1900
|
+
(0, pqb_internal._appendQuery)(querySelf, connectQuery, setMainAs, (as) => {
|
|
1901
|
+
createWhereNotExists._sql = `NOT EXISTS (SELECT 1 FROM "${as}")`;
|
|
1902
|
+
});
|
|
1903
|
+
(0, pqb_internal._appendQuery)(querySelf, createQuery, setMainAs, (as) => {
|
|
1904
|
+
createJoinRows.q.from = as;
|
|
1905
|
+
createJoinRows.q.schema = void 0;
|
|
1906
|
+
for (let i = 0; i < throughForeignKeyValues.length; i++) throughForeignKeyValues[i]._sql = `"${as}"."${throughPrimaryKeys[i]}"`;
|
|
1907
|
+
});
|
|
1908
|
+
(0, pqb_internal._appendQuery)(querySelf, createJoinQuery, setMainAs);
|
|
1909
|
+
}
|
|
1910
|
+
}
|
|
1911
|
+
for (const { upsert, foreignKeyValues } of nestedUpserts) for (const value of (0, pqb_internal.toArray)(upsert)) {
|
|
1912
|
+
const upsertWhereExists = querySelf.q.type === "upsert" ? new pqb_internal.RawSql("") : void 0;
|
|
1913
|
+
const makeJoinQuery = () => {
|
|
1914
|
+
const selectAs = {};
|
|
1915
|
+
for (let i = 0; i < foreignKeys.length; i++) selectAs[foreignKeys[i]] = foreignKeyValues[i];
|
|
1916
|
+
for (let i = 0; i < throughForeignKeys.length; i++) selectAs[throughForeignKeys[i]] = new pqb_internal.RawSql("");
|
|
1917
|
+
const joinRows = (0, pqb_internal._querySelect)((0, pqb_internal._clone)(relQuery.baseQuery), [selectAs]);
|
|
1918
|
+
const joinQuery = (0, pqb_internal._queryInsertForEachFrom)((0, pqb_internal._clone)(joinTableQuery), joinRows);
|
|
1919
|
+
joinQuery.q.returnType = "void";
|
|
1920
|
+
return {
|
|
1921
|
+
joinQuery,
|
|
1922
|
+
setJoinRowsFrom: (as) => {
|
|
1923
|
+
joinRows.q.from = as;
|
|
1924
|
+
joinRows.q.schema = void 0;
|
|
1925
|
+
for (let i = 0; i < throughForeignKeys.length; i++) selectAs[throughForeignKeys[i]]._sql = `"${as}"."${throughPrimaryKeys[i]}"`;
|
|
1926
|
+
}
|
|
1927
|
+
};
|
|
1928
|
+
};
|
|
1929
|
+
const updateQuery = (0, pqb_internal._querySelect)((0, pqb_internal._queryUpdate)((0, pqb_internal._clone)(relQuery).where(value.findBy), value.update), throughPrimaryKeys);
|
|
1930
|
+
if (upsertWhereExists) (0, pqb_internal._queryWhere)(updateQuery, [upsertWhereExists]);
|
|
1931
|
+
const updateJoin = makeJoinQuery();
|
|
1932
|
+
const updateQueryWithJoin = (0, pqb_internal._appendQuery)(updateQuery, updateJoin.joinQuery, updateJoin.setJoinRowsFrom);
|
|
1933
|
+
let query = updateQueryWithJoin;
|
|
1934
|
+
if (value.create) {
|
|
1935
|
+
const createWhereNotExists = new pqb_internal.RawSql("");
|
|
1936
|
+
const createSource = (0, pqb_internal._queryWhere)((0, pqb_internal._queryTake)((0, pqb_internal._querySelect)((0, pqb_internal._clone)(relQuery.qb), [{}])), [createWhereNotExists, upsertWhereExists].filter(Boolean));
|
|
1937
|
+
const create = typeof value.create === "function" ? value.create() : value.create;
|
|
1938
|
+
const createQuery = (0, pqb_internal._queryInsertManyFrom)((0, pqb_internal._querySelect)((0, pqb_internal._clone)(relQuery), throughPrimaryKeys), createSource, [create]);
|
|
1939
|
+
const createJoin = makeJoinQuery();
|
|
1940
|
+
const createQueryWithJoin = (0, pqb_internal._appendQuery)(createQuery, createJoin.joinQuery, createJoin.setJoinRowsFrom);
|
|
1941
|
+
query = (0, pqb_internal._appendQuery)(updateQueryWithJoin, createQueryWithJoin, (as) => {
|
|
1942
|
+
createWhereNotExists._sql = `NOT EXISTS (SELECT 1 FROM "${as}")`;
|
|
1943
|
+
});
|
|
1944
|
+
}
|
|
1945
|
+
(querySelf.q.type === "upsert" ? pqb_internal._appendQueryOnUpsertCreate : pqb_internal._appendQuery)(querySelf, query, (as) => {
|
|
1946
|
+
setMainAs(as);
|
|
1947
|
+
if (upsertWhereExists) upsertWhereExists._sql = `EXISTS (SELECT 1 FROM "${as}")`;
|
|
1948
|
+
});
|
|
1949
|
+
}
|
|
1950
|
+
}
|
|
1951
|
+
} else hasRelationHandleCreate(querySelf, ctx, items, rowIndexes, key, state.primaryKeys, nestedInsertFn);
|
|
1952
|
+
};
|
|
1609
1953
|
const nestedInsert = ({ relatedTableQuery, joinTableQuery, primaryKeys, foreignKeys, throughPrimaryKeys, throughForeignKeys }) => {
|
|
1610
1954
|
const len = primaryKeys.length;
|
|
1611
1955
|
const throughLen = primaryKeys.length;
|
|
@@ -1650,6 +1994,15 @@ const nestedInsert = ({ relatedTableQuery, joinTableQuery, primaryKeys, foreignK
|
|
|
1650
1994
|
created = await (0, pqb_internal._queryCreateMany)(t.select(...throughPrimaryKeys), records);
|
|
1651
1995
|
} else created = [];
|
|
1652
1996
|
const allKeys = data;
|
|
1997
|
+
for (let index = 0; index < data.length; index++) {
|
|
1998
|
+
const item = data[index][1];
|
|
1999
|
+
if (!item.upsert) continue;
|
|
2000
|
+
const upserted = await Promise.all((0, pqb_internal.toArray)(item.upsert).map((upsert) => (0, pqb_internal._querySelect)((0, pqb_internal._queryUpsert)(t.clone().where(upsert.findBy), {
|
|
2001
|
+
update: upsert.update,
|
|
2002
|
+
create: upsert.create || {}
|
|
2003
|
+
}), throughPrimaryKeys)));
|
|
2004
|
+
allKeys[index][1] = upserted.map((record) => Array.isArray(record) ? record[0] : record);
|
|
2005
|
+
}
|
|
1653
2006
|
let createI = 0;
|
|
1654
2007
|
let connectI = 0;
|
|
1655
2008
|
connectOrCreateI = 0;
|
|
@@ -1691,57 +2044,42 @@ const nestedInsert = ({ relatedTableQuery, joinTableQuery, primaryKeys, foreignK
|
|
|
1691
2044
|
await joinTableQuery.insertMany(records);
|
|
1692
2045
|
});
|
|
1693
2046
|
};
|
|
1694
|
-
const
|
|
1695
|
-
const
|
|
1696
|
-
const conditionsToWhereArg = (conditions) => Array.isArray(conditions) ? { OR: conditions } : conditions;
|
|
1697
|
-
const queryJoinTable = (state, data, conditions) => {
|
|
1698
|
-
const t = state.joinTableQuery.where({ IN: {
|
|
1699
|
-
columns: state.foreignKeys,
|
|
1700
|
-
values: data.map((item) => state.primaryKeys.map((key) => item[key]))
|
|
1701
|
-
} });
|
|
1702
|
-
if (conditions) (0, pqb_internal._queryWhere)(t, [{ IN: {
|
|
1703
|
-
columns: state.throughForeignKeys,
|
|
1704
|
-
values: (0, pqb_internal._querySelect)(state.relatedTableQuery.where(conditionsToWhereArg(conditions)), state.throughPrimaryKeys)
|
|
1705
|
-
} }]);
|
|
1706
|
-
if (state.on) (0, pqb_internal._queryWhereExists)(t, state.relatedTableQuery, [(q) => {
|
|
1707
|
-
for (let i = 0; i < state.throughPrimaryKeys.length; i++) (0, pqb_internal._queryJoinOn)(q, [state.throughPrimaryKeysFull[i], state.throughForeignKeysFull[i]]);
|
|
1708
|
-
return q;
|
|
1709
|
-
}]);
|
|
1710
|
-
return t;
|
|
1711
|
-
};
|
|
1712
|
-
const insertToJoinTable = (state, joinTableTransaction, data, idsRows) => {
|
|
1713
|
-
const len = state.primaryKeys.length;
|
|
1714
|
-
const throughLen = state.throughPrimaryKeys.length;
|
|
1715
|
-
const records = [];
|
|
1716
|
-
for (const item of data) {
|
|
1717
|
-
const obj = {};
|
|
1718
|
-
for (let i = 0; i < len; i++) obj[state.foreignKeys[i]] = item[state.primaryKeys[i]];
|
|
1719
|
-
for (const ids of idsRows) {
|
|
1720
|
-
const record = { ...obj };
|
|
1721
|
-
for (let i = 0; i < throughLen; i++) record[state.throughForeignKeys[i]] = ids[i];
|
|
1722
|
-
records.push(record);
|
|
1723
|
-
}
|
|
1724
|
-
}
|
|
1725
|
-
return joinTableTransaction.insertMany(records);
|
|
2047
|
+
const nestedUpdateUpsert = (querySelf, state, upsert, onAppended, updateFrom, sourceCondition, disconnect, set) => {
|
|
2048
|
+
for (const [index, item] of (0, pqb_internal.toArray)(upsert).entries()) nestedUpdateUpsertOne(querySelf, state, item, (as) => onAppended?.(as, index), updateFrom, sourceCondition, disconnect, set);
|
|
1726
2049
|
};
|
|
1727
|
-
const
|
|
2050
|
+
const nestedUpdateUpsertOne = (querySelf, state, upsert, onAppended, updateFrom, sourceCondition, disconnect, set) => {
|
|
1728
2051
|
const parentIdsSql = new pqb_internal.RawSql("");
|
|
1729
|
-
const parentValues = state.foreignKeys.
|
|
2052
|
+
const parentValues = makeRawSqlPlaceholders(state.foreignKeys.length);
|
|
1730
2053
|
const relatedIdsSql = new pqb_internal.RawSql("");
|
|
1731
|
-
const relatedValues = state.throughPrimaryKeys.
|
|
2054
|
+
const relatedValues = makeRawSqlPlaceholders(state.throughPrimaryKeys.length);
|
|
1732
2055
|
let parentAs;
|
|
1733
2056
|
(0, pqb_internal._hookSelectColumns)(querySelf, state.primaryKeys, (aliasedPrimaryKeys) => {
|
|
1734
2057
|
parentIdsSql._sql = selectCteColumnsSql(parentAs, aliasedPrimaryKeys);
|
|
1735
2058
|
for (let i = 0; i < state.foreignKeys.length; i++) parentValues[i]._sql = selectCteColumnSql(parentAs, aliasedPrimaryKeys[i]);
|
|
1736
2059
|
});
|
|
1737
|
-
|
|
2060
|
+
let existingRelQuery = (0, pqb_internal._queryWhere)((0, pqb_internal._clone)(state.relatedTableQuery), [upsert.findBy]);
|
|
2061
|
+
if (disconnect) existingRelQuery = existingRelQuery.whereNot({ OR: (0, pqb_internal.toArray)(disconnect) });
|
|
2062
|
+
existingRelQuery = (0, pqb_internal._queryWhereExists)(existingRelQuery, state.joinTableQuery, [(q) => {
|
|
1738
2063
|
for (let i = 0; i < state.throughPrimaryKeys.length; i++) (0, pqb_internal._queryJoinOn)(q, [state.throughForeignKeysFull[i], state.throughPrimaryKeysFull[i]]);
|
|
1739
2064
|
return (0, pqb_internal._queryWhereIn)(q, true, state.foreignKeysFull, parentIdsSql);
|
|
1740
2065
|
}]);
|
|
2066
|
+
if (sourceCondition) {
|
|
2067
|
+
existingRelQuery.q.updateFrom = {
|
|
2068
|
+
u: true,
|
|
2069
|
+
x: updateFrom
|
|
2070
|
+
};
|
|
2071
|
+
const conditions = existingRelQuery.q.and;
|
|
2072
|
+
const existingRelationCondition = conditions.pop();
|
|
2073
|
+
const relationCondition = set ? sourceCondition : { OR: [existingRelationCondition, sourceCondition] };
|
|
2074
|
+
conditions.push(relationCondition);
|
|
2075
|
+
}
|
|
1741
2076
|
const upsertQuery = (0, pqb_internal._querySelect)((0, pqb_internal._queryUpsert)(existingRelQuery, {
|
|
1742
2077
|
update: upsert.update,
|
|
1743
2078
|
create: upsert.create || {}
|
|
1744
2079
|
}), state.throughPrimaryKeys);
|
|
2080
|
+
upsertQuery.q.returnType = "void";
|
|
2081
|
+
(0, pqb_internal._onUpsertUpdate)(upsertQuery, (as) => onAppended?.(as));
|
|
2082
|
+
if (onAppended) upsertQuery.q.upsertCreateAsFns = [...upsertQuery.q.upsertCreateAsFns || [], onAppended];
|
|
1745
2083
|
const selectAs = {};
|
|
1746
2084
|
for (let i = 0; i < state.foreignKeys.length; i++) selectAs[state.foreignKeys[i]] = parentValues[i];
|
|
1747
2085
|
for (let i = 0; i < state.throughForeignKeys.length; i++) selectAs[state.throughForeignKeys[i]] = relatedValues[i];
|
|
@@ -1750,72 +2088,197 @@ const nestedUpdateUpsert = (querySelf, state, upsert) => {
|
|
|
1750
2088
|
const joinQuery = state.joinTableQuery.insertForEachFrom(joinRows);
|
|
1751
2089
|
joinQuery.q.returnType = "void";
|
|
1752
2090
|
(0, pqb_internal._appendQuery)(querySelf, (0, pqb_internal._appendQueryOnUpsertCreate)(upsertQuery, joinQuery, (as) => {
|
|
2091
|
+
onAppended?.(as);
|
|
1753
2092
|
relatedIdsSql._sql = `EXISTS (SELECT 1 FROM "${as}")`;
|
|
1754
2093
|
for (let i = 0; i < relatedValues.length; i++) relatedValues[i]._sql = selectCteColumnSql(as, state.throughPrimaryKeys[i]);
|
|
1755
2094
|
}), (as) => {
|
|
1756
2095
|
parentAs = as;
|
|
1757
2096
|
});
|
|
1758
2097
|
};
|
|
1759
|
-
const
|
|
1760
|
-
const
|
|
1761
|
-
const
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
} }
|
|
1783
|
-
})
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
2098
|
+
const nestedUpdateAdd = (querySelf, state, add, onAppended) => {
|
|
2099
|
+
const relatedWheres = (0, pqb_internal.toArray)(add);
|
|
2100
|
+
const joinTableColumns = [...state.foreignKeys, ...state.throughForeignKeys];
|
|
2101
|
+
const parentValues = makeRawSqlPlaceholders(state.foreignKeys.length);
|
|
2102
|
+
const mainQuery = (0, pqb_internal._clone)(state.queryBuilder);
|
|
2103
|
+
const isRootUpsert = querySelf.q.upsertUpdate;
|
|
2104
|
+
let parentCount = 0;
|
|
2105
|
+
if (!isRootUpsert) (0, pqb_internal._queryHookAfterUpdate)(querySelf, state.primaryKeys, (rows) => {
|
|
2106
|
+
parentCount = rows.length;
|
|
2107
|
+
});
|
|
2108
|
+
(0, pqb_internal._hookSelectColumns)(querySelf, state.primaryKeys, (aliased) => {
|
|
2109
|
+
for (let i = 0; i < parentValues.length; i++) parentValues[i]._sql = `"${mainQuery.q.from}"."${aliased[i]}"`;
|
|
2110
|
+
});
|
|
2111
|
+
const joinRows = (0, pqb_internal._querySelect)(state.relatedTableQuery.whereOneOf(...relatedWheres), [Object.fromEntries([...state.foreignKeys.map((key, i) => [key, parentValues[i]]), ...state.throughForeignKeys.map((key, i) => [key, state.throughPrimaryKeys[i]])])]).join(mainQuery, true);
|
|
2112
|
+
const joinQuery = state.joinTableQuery.insertForEachFrom(joinRows).onConflict(joinTableColumns).merge([state.foreignKeys[0]]);
|
|
2113
|
+
if (onAppended) (0, pqb_internal._querySelect)(joinQuery, state.throughForeignKeys);
|
|
2114
|
+
else joinQuery.q.returnType = "void";
|
|
2115
|
+
if (!isRootUpsert) {
|
|
2116
|
+
joinQuery.q.ensureCount = {
|
|
2117
|
+
expected: relatedWheres.length,
|
|
2118
|
+
message: "based on `add` conditions"
|
|
2119
|
+
};
|
|
2120
|
+
(0, pqb_internal._queryHookAfterCreate)(joinQuery, state.foreignKeys, (rows) => {
|
|
2121
|
+
if (rows.length < parentCount * relatedWheres.length) throw new pqb.OrchidOrmInternalError(querySelf, `Expected to find at least ${relatedWheres.length} record(s) based on \`add\` conditions, but found ${rows.length / parentCount}`);
|
|
2122
|
+
});
|
|
2123
|
+
}
|
|
2124
|
+
(0, pqb_internal._appendQuery)(querySelf, joinQuery, (as) => {
|
|
2125
|
+
mainQuery.q.from = as;
|
|
2126
|
+
mainQuery.q.schema = void 0;
|
|
2127
|
+
mainQuery.q.as = void 0;
|
|
2128
|
+
}, onAppended);
|
|
2129
|
+
};
|
|
2130
|
+
const nestedUpdateDisconnect = (querySelf, state, disconnect) => {
|
|
2131
|
+
const relatedWheres = (0, pqb_internal.toArray)(disconnect);
|
|
2132
|
+
const joinTableColumns = [...state.foreignKeys, ...state.throughForeignKeys];
|
|
2133
|
+
const parentValues = makeRawSqlPlaceholders(state.foreignKeys.length);
|
|
2134
|
+
const mainQuery = (0, pqb_internal._clone)(state.queryBuilder);
|
|
2135
|
+
(0, pqb_internal._hookSelectColumns)(querySelf, state.primaryKeys, (aliased) => {
|
|
2136
|
+
for (let i = 0; i < parentValues.length; i++) parentValues[i]._sql = `"${mainQuery.q.from}"."${aliased[i]}"`;
|
|
2137
|
+
});
|
|
2138
|
+
const joinRows = (0, pqb_internal._querySelect)(state.relatedTableQuery.whereOneOf(...relatedWheres), [Object.fromEntries([...state.foreignKeys.map((key, i) => [key, parentValues[i]]), ...state.throughForeignKeys.map((key, i) => [key, state.throughPrimaryKeys[i]])])]).join(mainQuery, true);
|
|
2139
|
+
const joinQuery = (0, pqb_internal._queryDelete)(state.joinTableQuery.where({ IN: {
|
|
2140
|
+
columns: joinTableColumns,
|
|
2141
|
+
values: joinRows
|
|
2142
|
+
} }));
|
|
2143
|
+
joinQuery.q.returnType = "void";
|
|
2144
|
+
(0, pqb_internal._appendQuery)(querySelf, joinQuery, (as) => {
|
|
2145
|
+
mainQuery.q.from = as;
|
|
2146
|
+
mainQuery.q.schema = void 0;
|
|
2147
|
+
mainQuery.q.as = void 0;
|
|
2148
|
+
});
|
|
2149
|
+
};
|
|
2150
|
+
const nestedUpdateDelete = (querySelf, state, del) => {
|
|
2151
|
+
const relatedWheres = (0, pqb_internal.toArray)(del);
|
|
2152
|
+
const parentValues = makeRawSqlPlaceholders(state.foreignKeys.length);
|
|
2153
|
+
const relatedValues = makeRawSqlPlaceholders(state.throughForeignKeys.length);
|
|
2154
|
+
const parentIdsSql = new pqb_internal.RawSql("");
|
|
2155
|
+
const mainQuery = (0, pqb_internal._clone)(state.queryBuilder);
|
|
2156
|
+
const relatedRows = (0, pqb_internal._querySelect)((0, pqb_internal._clone)(state.queryBuilder), [Object.fromEntries([...state.foreignKeys.map((key, i) => [key, parentValues[i]]), ...state.throughForeignKeys.map((key, i) => [key, relatedValues[i]])])]).join(mainQuery, true);
|
|
2157
|
+
(0, pqb_internal._hookSelectColumns)(querySelf, state.primaryKeys, (aliased) => {
|
|
2158
|
+
parentIdsSql._sql = selectCteColumnsSql(mainQuery.q.from, aliased);
|
|
2159
|
+
for (let i = 0; i < parentValues.length; i++) parentValues[i]._sql = `"${mainQuery.q.from}"."${aliased[i]}"`;
|
|
2160
|
+
});
|
|
2161
|
+
const relatedQuery = (0, pqb_internal._queryWhereExists)(state.relatedTableQuery.whereOneOf(...relatedWheres), state.joinTableQuery, [(q) => {
|
|
2162
|
+
for (let i = 0; i < state.throughPrimaryKeys.length; i++) (0, pqb_internal._queryJoinOn)(q, [state.throughForeignKeysFull[i], state.throughPrimaryKeysFull[i]]);
|
|
2163
|
+
return (0, pqb_internal._queryWhereIn)(q, true, state.foreignKeysFull, parentIdsSql);
|
|
2164
|
+
}]);
|
|
2165
|
+
const relatedDeleteQuery = (0, pqb_internal._queryDelete)((0, pqb_internal._querySelect)(relatedQuery, state.throughPrimaryKeys));
|
|
2166
|
+
relatedDeleteQuery.q.returnType = "void";
|
|
2167
|
+
const joinQuery = (0, pqb_internal._queryDelete)(state.joinTableQuery.where({ IN: {
|
|
2168
|
+
columns: [...state.foreignKeys, ...state.throughForeignKeys],
|
|
2169
|
+
values: relatedRows
|
|
2170
|
+
} }));
|
|
2171
|
+
joinQuery.q.returnType = "void";
|
|
2172
|
+
(0, pqb_internal._appendQuery)(querySelf, relatedDeleteQuery, () => {}, (as) => {
|
|
2173
|
+
relatedRows.q.from = as;
|
|
2174
|
+
relatedRows.q.schema = void 0;
|
|
2175
|
+
relatedRows.q.as = void 0;
|
|
2176
|
+
for (let i = 0; i < relatedValues.length; i++) relatedValues[i]._sql = `"${as}"."${state.throughPrimaryKeys[i]}"`;
|
|
2177
|
+
});
|
|
2178
|
+
(0, pqb_internal._appendQuery)(querySelf, joinQuery, (as) => {
|
|
2179
|
+
mainQuery.q.from = as;
|
|
2180
|
+
mainQuery.q.schema = void 0;
|
|
2181
|
+
mainQuery.q.as = void 0;
|
|
2182
|
+
});
|
|
2183
|
+
};
|
|
2184
|
+
const nestedUpdateUpdate = (querySelf, state, update, updateFrom, sourceCondition, disconnect, set) => {
|
|
2185
|
+
const parentIdsSql = new pqb_internal.RawSql("");
|
|
2186
|
+
const mainQuery = (0, pqb_internal._clone)(state.queryBuilder);
|
|
2187
|
+
const isRootUpsert = querySelf.q.upsertUpdate;
|
|
2188
|
+
(0, pqb_internal._hookSelectColumns)(querySelf, state.primaryKeys, (aliased) => {
|
|
2189
|
+
parentIdsSql._sql = selectCteColumnsSql(mainQuery.q.from, aliased);
|
|
2190
|
+
});
|
|
2191
|
+
for (const item of (0, pqb_internal.toArray)(update)) for (const relatedWhere of (0, pqb_internal.toArray)(item.where)) {
|
|
2192
|
+
let relatedQuery = (0, pqb_internal._queryWhere)((0, pqb_internal._clone)(state.relatedTableQuery), [relatedWhere]);
|
|
2193
|
+
if (disconnect) relatedQuery = relatedQuery.whereNot({ OR: (0, pqb_internal.toArray)(disconnect) });
|
|
2194
|
+
if (sourceCondition) {
|
|
2195
|
+
relatedQuery.q.updateFrom = {
|
|
2196
|
+
u: true,
|
|
2197
|
+
x: updateFrom
|
|
2198
|
+
};
|
|
2199
|
+
relatedQuery = relatedQuery.whereSql(sourceCondition);
|
|
2200
|
+
} else relatedQuery = (0, pqb_internal._queryWhereExists)(relatedQuery, state.joinTableQuery, [(q) => {
|
|
2201
|
+
for (let i = 0; i < state.throughPrimaryKeys.length; i++) (0, pqb_internal._queryJoinOn)(q, [state.throughForeignKeysFull[i], state.throughPrimaryKeysFull[i]]);
|
|
2202
|
+
return (0, pqb_internal._queryWhereIn)(q, true, state.foreignKeysFull, parentIdsSql);
|
|
2203
|
+
}]);
|
|
2204
|
+
const relatedUpdateQuery = (0, pqb_internal._queryUpdate)(relatedQuery, item.data);
|
|
2205
|
+
relatedUpdateQuery.q.returnType = "void";
|
|
2206
|
+
if (!isRootUpsert && !disconnect && !set) relatedUpdateQuery.q.ensureCount = { expected: 1 };
|
|
2207
|
+
(0, pqb_internal._appendQuery)(querySelf, relatedUpdateQuery, (as) => {
|
|
2208
|
+
mainQuery.q.from = as;
|
|
2209
|
+
mainQuery.q.schema = void 0;
|
|
2210
|
+
mainQuery.q.as = void 0;
|
|
2211
|
+
});
|
|
2212
|
+
}
|
|
2213
|
+
};
|
|
2214
|
+
const nestedUpdateCreate = (querySelf, state, create) => {
|
|
2215
|
+
const mainQuery = (0, pqb_internal._clone)(state.queryBuilder);
|
|
2216
|
+
const parentValues = makeRawSqlPlaceholders(state.foreignKeys.length);
|
|
2217
|
+
const relatedValues = makeRawSqlPlaceholders(state.throughForeignKeys.length);
|
|
2218
|
+
(0, pqb_internal._hookSelectColumns)(querySelf, state.primaryKeys, (aliased) => {
|
|
2219
|
+
for (let i = 0; i < parentValues.length; i++) parentValues[i]._sql = `"${mainQuery.q.from}"."${aliased[i]}"`;
|
|
2220
|
+
});
|
|
2221
|
+
const joinRows = (0, pqb_internal._querySelect)((0, pqb_internal._clone)(state.relatedTableQuery.baseQuery), [Object.fromEntries([...state.foreignKeys.map((key, i) => [key, parentValues[i]]), ...state.throughForeignKeys.map((key, i) => [key, relatedValues[i]])])]).join(mainQuery, true);
|
|
2222
|
+
const joinQuery = (0, pqb_internal._queryInsertForEachFrom)((0, pqb_internal._clone)(state.joinTableQuery), joinRows);
|
|
2223
|
+
joinQuery.q.returnType = "void";
|
|
2224
|
+
const relatedCreateQuery = (0, pqb_internal._queryInsertMany)((0, pqb_internal._querySelect)((0, pqb_internal._clone)(state.relatedTableQuery), state.throughPrimaryKeys), create);
|
|
2225
|
+
relatedCreateQuery.q.returnType = "void";
|
|
2226
|
+
(0, pqb_internal._appendQuery)(querySelf, relatedCreateQuery, (as) => {
|
|
2227
|
+
mainQuery.q.from = as;
|
|
2228
|
+
mainQuery.q.schema = void 0;
|
|
2229
|
+
mainQuery.q.as = void 0;
|
|
2230
|
+
}, (as) => {
|
|
2231
|
+
joinRows.q.from = as;
|
|
2232
|
+
joinRows.q.schema = void 0;
|
|
2233
|
+
joinRows.q.as = void 0;
|
|
2234
|
+
for (let i = 0; i < relatedValues.length; i++) relatedValues[i]._sql = `"${as}"."${state.throughPrimaryKeys[i]}"`;
|
|
2235
|
+
});
|
|
2236
|
+
(0, pqb_internal._appendQuery)(querySelf, joinQuery, () => {});
|
|
2237
|
+
};
|
|
2238
|
+
const nestedUpdateSet = (querySelf, state, set, onAppended) => {
|
|
2239
|
+
const mainQuery = (0, pqb_internal._clone)(state.queryBuilder);
|
|
2240
|
+
const parentIdsSql = new pqb_internal.RawSql("");
|
|
2241
|
+
const parentValues = makeRawSqlPlaceholders(state.foreignKeys.length);
|
|
2242
|
+
(0, pqb_internal._hookSelectColumns)(querySelf, state.primaryKeys, (aliased) => {
|
|
2243
|
+
parentIdsSql._sql = selectCteColumnsSql(mainQuery.q.from, aliased);
|
|
2244
|
+
for (let i = 0; i < parentValues.length; i++) parentValues[i]._sql = `"${mainQuery.q.from}"."${aliased[i]}"`;
|
|
2245
|
+
});
|
|
2246
|
+
const deleteQuery = (0, pqb_internal._queryDelete)(state.joinTableQuery.where({ IN: {
|
|
2247
|
+
columns: state.foreignKeys,
|
|
2248
|
+
values: parentIdsSql
|
|
2249
|
+
} }));
|
|
2250
|
+
deleteQuery.q.returnType = "void";
|
|
2251
|
+
if (state.on) (0, pqb_internal._queryWhereExists)(deleteQuery, state.relatedTableQuery, [(q) => {
|
|
2252
|
+
for (let i = 0; i < state.throughPrimaryKeys.length; i++) (0, pqb_internal._queryJoinOn)(q, [state.throughPrimaryKeysFull[i], state.throughForeignKeysFull[i]]);
|
|
2253
|
+
return q;
|
|
2254
|
+
}]);
|
|
2255
|
+
(0, pqb_internal._appendQuery)(querySelf, deleteQuery, (as) => {
|
|
2256
|
+
mainQuery.q.from = as;
|
|
2257
|
+
mainQuery.q.schema = void 0;
|
|
2258
|
+
mainQuery.q.as = void 0;
|
|
1818
2259
|
});
|
|
2260
|
+
if (Array.isArray(set) ? set.length === 0 : !(0, pqb_internal.objectHasValues)(set)) return;
|
|
2261
|
+
const relatedWheres = (0, pqb_internal.toArray)(set);
|
|
2262
|
+
const joinTableColumns = [...state.foreignKeys, ...state.throughForeignKeys];
|
|
2263
|
+
const isRootUpsert = querySelf.q.upsertUpdate;
|
|
2264
|
+
let parentCount = 0;
|
|
2265
|
+
if (!isRootUpsert) (0, pqb_internal._queryHookAfterUpdate)(querySelf, state.primaryKeys, (rows) => {
|
|
2266
|
+
parentCount = rows.length;
|
|
2267
|
+
});
|
|
2268
|
+
const joinRows = (0, pqb_internal._querySelect)(state.relatedTableQuery.whereOneOf(...relatedWheres), [Object.fromEntries([...state.foreignKeys.map((key, i) => [key, parentValues[i]]), ...state.throughForeignKeys.map((key, i) => [key, state.throughPrimaryKeys[i]])])]).join(mainQuery, true);
|
|
2269
|
+
const joinQuery = state.joinTableQuery.insertForEachFrom(joinRows).onConflict(joinTableColumns).merge([state.foreignKeys[0]]);
|
|
2270
|
+
if (onAppended) (0, pqb_internal._querySelect)(joinQuery, state.throughForeignKeys);
|
|
2271
|
+
else joinQuery.q.returnType = "void";
|
|
2272
|
+
if (!isRootUpsert) {
|
|
2273
|
+
joinQuery.q.ensureCount = {
|
|
2274
|
+
expected: relatedWheres.length,
|
|
2275
|
+
message: "based on `set` conditions"
|
|
2276
|
+
};
|
|
2277
|
+
(0, pqb_internal._queryHookAfterCreate)(joinQuery, state.foreignKeys, (rows) => {
|
|
2278
|
+
if (rows.length < parentCount * relatedWheres.length) throw new pqb.OrchidOrmInternalError(querySelf, `Expected to find at least ${relatedWheres.length} record(s) based on \`set\` conditions, but found ${rows.length / parentCount}`);
|
|
2279
|
+
});
|
|
2280
|
+
}
|
|
2281
|
+
(0, pqb_internal._appendQuery)(querySelf, joinQuery, () => {}, onAppended);
|
|
1819
2282
|
};
|
|
1820
2283
|
var HasAndBelongsToManyVirtualColumn = class extends pqb_internal.VirtualColumn {
|
|
1821
2284
|
constructor(joinTable, schema, key, state) {
|
|
@@ -1824,18 +2287,83 @@ var HasAndBelongsToManyVirtualColumn = class extends pqb_internal.VirtualColumn
|
|
|
1824
2287
|
this.key = key;
|
|
1825
2288
|
this.state = state;
|
|
1826
2289
|
this.nestedInsert = nestedInsert(state);
|
|
1827
|
-
this.nestedUpdate = nestedUpdate(state);
|
|
1828
2290
|
}
|
|
1829
|
-
create(
|
|
1830
|
-
|
|
2291
|
+
create(self, ctx, items, rowIndexes, count) {
|
|
2292
|
+
hasAndBelongsToManyCreate(this.key, this.state, this.nestedInsert, self, ctx, items, rowIndexes, count);
|
|
1831
2293
|
}
|
|
1832
2294
|
update(q, set) {
|
|
1833
2295
|
const querySelf = q;
|
|
1834
2296
|
const params = set[this.key];
|
|
1835
|
-
|
|
1836
|
-
|
|
2297
|
+
const hasUpdate = !!params.update && (0, pqb_internal.toArray)(params.update).some((update) => !Array.isArray(update.where) || update.where.length);
|
|
2298
|
+
const hasAdd = params.add && (!Array.isArray(params.add) || params.add.length > 0);
|
|
2299
|
+
const addedAs = hasUpdate && hasAdd ? new pqb_internal.RawSql("") : void 0;
|
|
2300
|
+
const setAs = hasUpdate && params.set ? new pqb_internal.RawSql("") : void 0;
|
|
2301
|
+
const sourceCondition = addedAs || setAs ? new pqb_internal.RawSql("") : void 0;
|
|
2302
|
+
const updateFrom = sourceCondition ? new pqb_internal.RawSql("") : void 0;
|
|
2303
|
+
const setSourceCondition = () => {
|
|
2304
|
+
if (!sourceCondition) return;
|
|
2305
|
+
const relatedAs = this.state.relatedTableQuery.q.as || this.state.relatedTableQuery.table;
|
|
2306
|
+
const joinCondition = (as) => this.state.throughPrimaryKeys.map((key, i) => `"${relatedAs}"."${this.state.relatedTableQuery.shape[key].data.name || key}" = ${as}."${this.state.throughForeignKeys[i]}"`).join(" AND ");
|
|
2307
|
+
const sourceAs = "\"relatedIds\"";
|
|
2308
|
+
sourceCondition._sql = joinCondition(sourceAs);
|
|
2309
|
+
const sourceColumns = this.state.throughForeignKeys.map((key) => `"${key}"`).join(", ");
|
|
2310
|
+
updateFrom._sql = `(${[addedAs, setAs].filter((as) => !!as && !!as._sql).map((as) => `SELECT ${sourceColumns} FROM ${as._sql}`).concat().join(" UNION ALL ")}) AS ${sourceAs}`;
|
|
2311
|
+
};
|
|
2312
|
+
if (params.add) {
|
|
2313
|
+
nestedUpdateAdd(querySelf, this.state, params.add, (as) => {
|
|
2314
|
+
if (addedAs) {
|
|
2315
|
+
addedAs._sql = `"${as}"`;
|
|
2316
|
+
setSourceCondition();
|
|
2317
|
+
}
|
|
2318
|
+
});
|
|
2319
|
+
set[this.key] = {
|
|
2320
|
+
...params,
|
|
2321
|
+
add: void 0
|
|
2322
|
+
};
|
|
2323
|
+
}
|
|
2324
|
+
if (params.create?.length) {
|
|
2325
|
+
nestedUpdateCreate(querySelf, this.state, params.create);
|
|
2326
|
+
set[this.key] = {
|
|
2327
|
+
...params,
|
|
2328
|
+
create: void 0
|
|
2329
|
+
};
|
|
2330
|
+
}
|
|
2331
|
+
if (params.disconnect && (!Array.isArray(params.disconnect) || params.disconnect.length > 0)) {
|
|
2332
|
+
nestedUpdateDisconnect(querySelf, this.state, params.disconnect);
|
|
2333
|
+
set[this.key] = {
|
|
2334
|
+
...params,
|
|
2335
|
+
disconnect: void 0
|
|
2336
|
+
};
|
|
2337
|
+
}
|
|
2338
|
+
if (params.delete && (!Array.isArray(params.delete) || params.delete.length)) {
|
|
2339
|
+
nestedUpdateDelete(querySelf, this.state, params.delete);
|
|
2340
|
+
set[this.key] = {
|
|
2341
|
+
...params,
|
|
2342
|
+
delete: void 0
|
|
2343
|
+
};
|
|
2344
|
+
}
|
|
2345
|
+
if (params.set) {
|
|
2346
|
+
nestedUpdateSet(querySelf, this.state, params.set, (as) => {
|
|
2347
|
+
if (setAs) {
|
|
2348
|
+
setAs._sql = `"${as}"`;
|
|
2349
|
+
setSourceCondition();
|
|
2350
|
+
}
|
|
2351
|
+
});
|
|
2352
|
+
set[this.key] = {
|
|
2353
|
+
...params,
|
|
2354
|
+
set: void 0
|
|
2355
|
+
};
|
|
2356
|
+
}
|
|
2357
|
+
if (!!params.upsert && (!Array.isArray(params.upsert) || params.upsert.length > 0)) {
|
|
1837
2358
|
throwIfQueryReturnsAllForNestedUpdate(querySelf, { upsert: params.upsert });
|
|
1838
|
-
nestedUpdateUpsert(querySelf, this.state, params.upsert);
|
|
2359
|
+
nestedUpdateUpsert(querySelf, this.state, params.upsert, void 0, hasAdd || params.set ? updateFrom : void 0, hasAdd || params.set ? sourceCondition : void 0, params.disconnect, params.set);
|
|
2360
|
+
}
|
|
2361
|
+
if (hasUpdate) {
|
|
2362
|
+
nestedUpdateUpdate(querySelf, this.state, params.update, updateFrom, sourceCondition, params.disconnect, params.set);
|
|
2363
|
+
set[this.key] = {
|
|
2364
|
+
...params,
|
|
2365
|
+
update: void 0
|
|
2366
|
+
};
|
|
1839
2367
|
}
|
|
1840
2368
|
}
|
|
1841
2369
|
};
|