orchid-orm 1.77.1 → 1.77.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +6 -6
- package/dist/index.js +753 -727
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +753 -727
- package/dist/index.mjs.map +1 -1
- package/package.json +7 -7
package/dist/index.js
CHANGED
|
@@ -712,6 +712,20 @@ const selectCteColumnFromManySql = (cteAs, column, rowIndex, count) => {
|
|
|
712
712
|
}
|
|
713
713
|
return sql + ")";
|
|
714
714
|
};
|
|
715
|
+
const selectCteColumnMustExistSql = (i, cteAs, column) => {
|
|
716
|
+
const selectColumn = selectCteColumnSql$1(cteAs, column);
|
|
717
|
+
return i === 0 ? `CASE WHEN (SELECT count(*) FROM "${cteAs}") = 0 AND (SELECT 'not-found')::int = 0 THEN NULL ELSE ${selectColumn} END` : selectColumn;
|
|
718
|
+
};
|
|
719
|
+
const setForeignKeysFromCte = (record, primaryKeys, foreignKeys, mustExist) => {
|
|
720
|
+
for (const key of foreignKeys) record[key] = new pqb_internal.RawSql("");
|
|
721
|
+
return (as) => {
|
|
722
|
+
foreignKeys.forEach(mustExist ? (foreignKey, i) => {
|
|
723
|
+
record[foreignKey]._sql = selectCteColumnMustExistSql(i, as, primaryKeys[i]);
|
|
724
|
+
} : (foreignKey, i) => {
|
|
725
|
+
record[foreignKey]._sql = selectCteColumnSql$1(as, primaryKeys[i]);
|
|
726
|
+
});
|
|
727
|
+
};
|
|
728
|
+
};
|
|
715
729
|
const joinQueryChainHOF = (relPKeys, reverseJoin, joinQuery) => (joiningQuery, baseQuery) => {
|
|
716
730
|
const jq = joiningQuery;
|
|
717
731
|
const chain = jq.q.relChain;
|
|
@@ -783,122 +797,61 @@ const wrapQuery = (joiningQuery, result, item) => {
|
|
|
783
797
|
result.q.returnsOne = true;
|
|
784
798
|
return result.wrap(outer);
|
|
785
799
|
};
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
items.forEach((item) => {
|
|
798
|
-
const value = item[key];
|
|
799
|
-
const kind = value.create ? "create" : value.connect ? "connect" : "connectOrCreate";
|
|
800
|
-
if (kind) {
|
|
801
|
-
const nestedCreateItem = (nestedCreateItems ??= {})[kind] ??= {
|
|
802
|
-
items: [],
|
|
803
|
-
values: []
|
|
804
|
-
};
|
|
805
|
-
nestedCreateItem.items.push(item);
|
|
806
|
-
nestedCreateItem.values.push(value[kind]);
|
|
807
|
-
if (kind !== "connect") for (const key of foreignKeys) item[key] = new pqb_internal.RawSql("");
|
|
808
|
-
}
|
|
809
|
-
});
|
|
810
|
-
if (!nestedCreateItems) return;
|
|
811
|
-
for (const key of foreignKeys) if (!ctx.columns.has(key)) ctx.columns.set(key, ctx.columns.size);
|
|
812
|
-
const { create, connect, connectOrCreate } = nestedCreateItems;
|
|
813
|
-
if (create) {
|
|
814
|
-
const selectPKeys = query.select(...primaryKeys);
|
|
815
|
-
let createQuery;
|
|
816
|
-
if (queryForCreate.q.type === "upsert") {
|
|
817
|
-
const createWhereNotExists = new pqb_internal.RawSql("");
|
|
818
|
-
(0, pqb_internal._onUpsertUpdate)(queryForCreate, (as) => {
|
|
819
|
-
createWhereNotExists._sql = `NOT EXISTS (SELECT 1 FROM "${as}")`;
|
|
820
|
-
});
|
|
821
|
-
const sourceQuery = (0, pqb_internal._queryWhere)((0, pqb_internal._queryTake)((0, pqb_internal._querySelect)((0, pqb_internal._clone)(query.qb), [{}])), [createWhereNotExists]);
|
|
822
|
-
createQuery = (0, pqb_internal._queryInsertManyFrom)(selectPKeys, sourceQuery, create.values);
|
|
823
|
-
} else createQuery = (0, pqb_internal._queryInsertMany)(selectPKeys, create.values);
|
|
824
|
-
const setForeignKeys = (as) => {
|
|
825
|
-
const count = create.items.length;
|
|
826
|
-
foreignKeys.forEach((foreignKey, i) => {
|
|
827
|
-
const primaryKey = primaryKeys[i];
|
|
828
|
-
create.items.forEach((item, i) => {
|
|
829
|
-
item[foreignKey]._sql = selectCteColumnFromManySql(as, primaryKey, i, count);
|
|
830
|
-
});
|
|
831
|
-
});
|
|
800
|
+
const belongsToCreate = (key, state, q, ctx, items) => {
|
|
801
|
+
const queryForCreate = q;
|
|
802
|
+
const { query, primaryKeys, foreignKeys } = state;
|
|
803
|
+
let nestedCreateItems;
|
|
804
|
+
items.forEach((item) => {
|
|
805
|
+
const value = item[key];
|
|
806
|
+
const kind = value.create ? "create" : value.connect ? "connect" : "connectOrCreate";
|
|
807
|
+
if (kind) {
|
|
808
|
+
const nestedCreateItem = (nestedCreateItems ??= {})[kind] ??= {
|
|
809
|
+
items: [],
|
|
810
|
+
values: []
|
|
832
811
|
};
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
812
|
+
nestedCreateItem.items.push(item);
|
|
813
|
+
nestedCreateItem.values.push(value[kind]);
|
|
814
|
+
if (kind !== "connect") for (const key of foreignKeys) item[key] = new pqb_internal.RawSql("");
|
|
815
|
+
}
|
|
816
|
+
});
|
|
817
|
+
if (!nestedCreateItems) return;
|
|
818
|
+
for (const key of foreignKeys) if (!ctx.columns.has(key)) ctx.columns.set(key, ctx.columns.size);
|
|
819
|
+
const { create, connect, connectOrCreate } = nestedCreateItems;
|
|
820
|
+
if (create) {
|
|
821
|
+
const selectPKeys = query.select(...primaryKeys);
|
|
822
|
+
let createQuery;
|
|
823
|
+
if (queryForCreate.q.type === "upsert") {
|
|
824
|
+
const createWhereNotExists = new pqb_internal.RawSql("");
|
|
825
|
+
(0, pqb_internal._onUpsertUpdate)(queryForCreate, (as) => {
|
|
826
|
+
createWhereNotExists._sql = `NOT EXISTS (SELECT 1 FROM "${as}")`;
|
|
841
827
|
});
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
828
|
+
const sourceQuery = (0, pqb_internal._queryWhere)((0, pqb_internal._queryTake)((0, pqb_internal._querySelect)((0, pqb_internal._clone)(query.qb), [{}])), [createWhereNotExists]);
|
|
829
|
+
createQuery = (0, pqb_internal._queryInsertManyFrom)(selectPKeys, sourceQuery, create.values);
|
|
830
|
+
} else createQuery = (0, pqb_internal._queryInsertMany)(selectPKeys, create.values);
|
|
831
|
+
const setForeignKeys = (as) => {
|
|
832
|
+
const count = create.items.length;
|
|
833
|
+
foreignKeys.forEach((foreignKey, i) => {
|
|
834
|
+
const primaryKey = primaryKeys[i];
|
|
835
|
+
create.items.forEach((item, i) => {
|
|
836
|
+
item[foreignKey]._sql = selectCteColumnFromManySql(as, primaryKey, i, count);
|
|
837
|
+
});
|
|
838
|
+
});
|
|
839
|
+
};
|
|
840
|
+
if (queryForCreate.q.type === "upsert") (0, pqb_internal._prependWithOnUpsertCreate)(queryForCreate, setForeignKeys, createQuery);
|
|
841
|
+
else (0, pqb_internal._prependWith)(queryForCreate, setForeignKeys, createQuery);
|
|
854
842
|
}
|
|
855
|
-
|
|
856
|
-
const
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
843
|
+
if (connect) connect.values.forEach((value, itemI) => {
|
|
844
|
+
const as = (0, pqb_internal.getFreeAlias)(queryForCreate.q.withShapes, "q");
|
|
845
|
+
(queryForCreate.q.type === "upsert" ? pqb_internal._prependWithOnUpsertCreate : pqb_internal._prependWith)(queryForCreate, as, query.select(...primaryKeys).findBy(value));
|
|
846
|
+
foreignKeys.map((foreignKey, i) => {
|
|
847
|
+
connect.items[itemI][foreignKey] = new pqb_internal.RawSql(selectCteColumnMustExistSql(i, as, primaryKeys[i]));
|
|
848
|
+
});
|
|
849
|
+
});
|
|
850
|
+
if (connectOrCreate) connectOrCreate.values.forEach((value, itemI) => {
|
|
851
|
+
const asFn = setForeignKeysFromCte(connectOrCreate.items[itemI], primaryKeys, foreignKeys);
|
|
852
|
+
const selectPKeys = query.select(...primaryKeys);
|
|
853
|
+
(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));
|
|
862
854
|
});
|
|
863
|
-
};
|
|
864
|
-
const makeBelongsToMethod = (tableConfig, table, relation, relationName, query) => {
|
|
865
|
-
const primaryKeys = relation.options.references;
|
|
866
|
-
const foreignKeys = relation.options.columns;
|
|
867
|
-
const { on } = relation.options;
|
|
868
|
-
if (on) {
|
|
869
|
-
(0, pqb_internal._queryWhere)(query, [on]);
|
|
870
|
-
(0, pqb_internal._queryDefaults)(query, on);
|
|
871
|
-
}
|
|
872
|
-
const len = primaryKeys.length;
|
|
873
|
-
const state = {
|
|
874
|
-
query,
|
|
875
|
-
primaryKeys,
|
|
876
|
-
foreignKeys,
|
|
877
|
-
len,
|
|
878
|
-
on
|
|
879
|
-
};
|
|
880
|
-
addAutoForeignKey(tableConfig, table, query, primaryKeys, foreignKeys, relation.options);
|
|
881
|
-
const join = (baseQuery, joiningQuery, primaryKeys, foreignKeys) => {
|
|
882
|
-
const baseAs = (0, pqb_internal.getQueryAs)(baseQuery);
|
|
883
|
-
const q = joiningQuery.clone();
|
|
884
|
-
(0, pqb_internal.setQueryObjectValueImmutable)(q, "joinedShapes", baseAs, baseQuery.q.selectShape);
|
|
885
|
-
for (let i = 0; i < len; i++) (0, pqb_internal.pushQueryOnForOuter)(q, baseQuery, joiningQuery, primaryKeys[i], `${baseAs}.${foreignKeys[i]}`);
|
|
886
|
-
return q;
|
|
887
|
-
};
|
|
888
|
-
const reverseJoin = (baseQuery, joiningQuery) => {
|
|
889
|
-
return join(joiningQuery, baseQuery, foreignKeys, primaryKeys);
|
|
890
|
-
};
|
|
891
|
-
return {
|
|
892
|
-
returns: "one",
|
|
893
|
-
queryRelated(params) {
|
|
894
|
-
const obj = {};
|
|
895
|
-
for (let i = 0; i < len; i++) obj[primaryKeys[i]] = params[foreignKeys[i]];
|
|
896
|
-
return query.where(obj);
|
|
897
|
-
},
|
|
898
|
-
virtualColumn: new BelongsToVirtualColumn(pqb_internal.internalSchemaConfig, relationName, state),
|
|
899
|
-
joinQuery: joinQueryChainHOF((0, pqb_internal.getPrimaryKeys)(query), reverseJoin, (joiningQuery, baseQuery) => join(baseQuery, joiningQuery, primaryKeys, foreignKeys)),
|
|
900
|
-
reverseJoin
|
|
901
|
-
};
|
|
902
855
|
};
|
|
903
856
|
const nestedUpdate$2 = ({ query, primaryKeys, foreignKeys, len }) => {
|
|
904
857
|
return ((self, update, params) => {
|
|
@@ -971,240 +924,69 @@ const makeSelectIdsQuery = (self, foreignKeys) => {
|
|
|
971
924
|
selectIdsQuery.q.or = self.q.or;
|
|
972
925
|
return selectIdsQuery;
|
|
973
926
|
};
|
|
974
|
-
|
|
975
|
-
for (const key of foreignKeys) record[key] = new pqb_internal.RawSql("");
|
|
976
|
-
return (as) => {
|
|
977
|
-
foreignKeys.forEach(mustExist ? (foreignKey, i) => {
|
|
978
|
-
record[foreignKey]._sql = selectCteColumnMustExistSql(i, as, primaryKeys[i]);
|
|
979
|
-
} : (foreignKey, i) => {
|
|
980
|
-
record[foreignKey]._sql = selectCteColumnSql$1(as, primaryKeys[i]);
|
|
981
|
-
});
|
|
982
|
-
};
|
|
983
|
-
};
|
|
984
|
-
const selectCteColumnMustExistSql = (i, cteAs, column) => {
|
|
985
|
-
const selectColumn = selectCteColumnSql$1(cteAs, column);
|
|
986
|
-
return i === 0 ? `CASE WHEN (SELECT count(*) FROM "${cteAs}") = 0 AND (SELECT 'not-found')::int = 0 THEN NULL ELSE ${selectColumn} END` : selectColumn;
|
|
987
|
-
};
|
|
988
|
-
var HasOneVirtualColumn = class extends pqb_internal.VirtualColumn {
|
|
927
|
+
var BelongsToVirtualColumn = class extends pqb_internal.VirtualColumn {
|
|
989
928
|
constructor(schema, key, state) {
|
|
990
929
|
super(schema);
|
|
991
930
|
this.key = key;
|
|
992
931
|
this.state = state;
|
|
993
|
-
this.
|
|
994
|
-
this.setNulls = {};
|
|
995
|
-
for (const foreignKey of state.foreignKeys) this.setNulls[foreignKey] = null;
|
|
932
|
+
this.nestedUpdate = nestedUpdate$2(this.state);
|
|
996
933
|
}
|
|
997
|
-
create(
|
|
998
|
-
|
|
999
|
-
if (count <= querySelf.qb.internal.nestedCreateBatchMax) {
|
|
1000
|
-
const { query: rel, primaryKeys, foreignKeys } = this.state;
|
|
1001
|
-
let nestedCreateItems;
|
|
1002
|
-
items.forEach((item, i) => {
|
|
1003
|
-
const value = item[this.key];
|
|
1004
|
-
const kind = value.create ? "create" : value.connect ? "connect" : "connectOrCreate";
|
|
1005
|
-
if (kind) {
|
|
1006
|
-
const nestedCreateItem = (nestedCreateItems ??= {})[kind] ??= {
|
|
1007
|
-
indexes: [],
|
|
1008
|
-
items: [],
|
|
1009
|
-
values: []
|
|
1010
|
-
};
|
|
1011
|
-
nestedCreateItem.indexes.push(rowIndexes[i]);
|
|
1012
|
-
nestedCreateItem.values.push(value[kind]);
|
|
1013
|
-
const data = value.create ? { ...value.create } : {};
|
|
1014
|
-
for (const key of foreignKeys) data[key] = new pqb_internal.RawSql("");
|
|
1015
|
-
nestedCreateItem.items.push(data);
|
|
1016
|
-
}
|
|
1017
|
-
});
|
|
1018
|
-
if (!nestedCreateItems) return;
|
|
1019
|
-
let createAs;
|
|
1020
|
-
let createWhereExists;
|
|
1021
|
-
let createSelectAs;
|
|
1022
|
-
let createAliasedPrimaryKeys;
|
|
1023
|
-
let upsertCreateAs;
|
|
1024
|
-
let connectAs;
|
|
1025
|
-
let connectOrCreateAs;
|
|
1026
|
-
const setUpsertCreatePlaceholders = () => {
|
|
1027
|
-
if (!upsertCreateAs || !createAliasedPrimaryKeys) return;
|
|
1028
|
-
const aliasedPrimaryKeys = createAliasedPrimaryKeys;
|
|
1029
|
-
if (createWhereExists) createWhereExists._sql = `EXISTS (SELECT 1 FROM "${upsertCreateAs}")`;
|
|
1030
|
-
if (createSelectAs) foreignKeys.forEach((key, keyI) => {
|
|
1031
|
-
createSelectAs[key]._sql = selectCteColumnFromManySql(upsertCreateAs, aliasedPrimaryKeys[keyI], 0, 1);
|
|
1032
|
-
});
|
|
1033
|
-
if (connect) foreignKeys.forEach((key, keyI) => {
|
|
1034
|
-
const primaryKey = aliasedPrimaryKeys[keyI];
|
|
1035
|
-
for (let i = 0; i < connect.items.length; i++) connect.items[i][key]._sql = selectCteColumnFromManySql(upsertCreateAs, primaryKey, connect.indexes[i], count);
|
|
1036
|
-
});
|
|
1037
|
-
if (connectOrCreate) foreignKeys.forEach((key, keyI) => {
|
|
1038
|
-
const primaryKey = aliasedPrimaryKeys[keyI];
|
|
1039
|
-
for (let i = 0; i < connectOrCreate.items.length; i++) connectOrCreate.items[i][key]._sql = selectCteColumnFromManySql(upsertCreateAs, primaryKey, connectOrCreate.indexes[i], count);
|
|
1040
|
-
});
|
|
1041
|
-
};
|
|
1042
|
-
(0, pqb_internal._hookSelectColumns)(querySelf, primaryKeys, (aliasedPrimaryKeys) => {
|
|
1043
|
-
createAliasedPrimaryKeys = aliasedPrimaryKeys;
|
|
1044
|
-
foreignKeys.forEach((key, keyI) => {
|
|
1045
|
-
const primaryKey = aliasedPrimaryKeys[keyI];
|
|
1046
|
-
if (create && createAs) for (let i = 0; i < create.items.length; i++) create.items[i][key]._sql = selectCteColumnFromManySql(createAs, primaryKey, create.indexes[i], count);
|
|
1047
|
-
if (connect && connectAs) for (let i = 0; i < connect.items.length; i++) connect.items[i][key]._sql = selectCteColumnFromManySql(connectAs, primaryKey, connect.indexes[i], count);
|
|
1048
|
-
if (connectOrCreate && connectOrCreateAs) for (let i = 0; i < connectOrCreate.items.length; i++) connectOrCreate.items[i][key]._sql = selectCteColumnFromManySql(connectOrCreateAs, primaryKey, connectOrCreate.indexes[i], count);
|
|
1049
|
-
});
|
|
1050
|
-
setUpsertCreatePlaceholders();
|
|
1051
|
-
});
|
|
1052
|
-
const { create, connect, connectOrCreate } = nestedCreateItems;
|
|
1053
|
-
if (create) {
|
|
1054
|
-
let query;
|
|
1055
|
-
if (querySelf.q.type === "upsert") {
|
|
1056
|
-
createWhereExists = new pqb_internal.RawSql("");
|
|
1057
|
-
createSelectAs = {};
|
|
1058
|
-
for (const key of foreignKeys) createSelectAs[key] = new pqb_internal.RawSql("");
|
|
1059
|
-
const sourceQuery = (0, pqb_internal._queryWhere)((0, pqb_internal._queryTake)((0, pqb_internal._querySelect)((0, pqb_internal._clone)(rel.qb), [createSelectAs])), [createWhereExists]);
|
|
1060
|
-
query = (0, pqb_internal._queryInsertManyFrom)((0, pqb_internal._clone)(rel), sourceQuery, create.items);
|
|
1061
|
-
} else query = (0, pqb_internal._queryInsertMany)((0, pqb_internal._clone)(rel), create.items);
|
|
1062
|
-
if (querySelf.q.type === "upsert") (0, pqb_internal._appendQueryOnUpsertCreate)(querySelf, query, (as) => {
|
|
1063
|
-
upsertCreateAs = as;
|
|
1064
|
-
setUpsertCreatePlaceholders();
|
|
1065
|
-
});
|
|
1066
|
-
else (0, pqb_internal._appendQuery)(querySelf, query, (as) => createAs = as);
|
|
1067
|
-
}
|
|
1068
|
-
if (connect) connect.values.forEach((value, i) => {
|
|
1069
|
-
const connectWhereExists = querySelf.q.type === "upsert" ? new pqb_internal.RawSql("") : void 0;
|
|
1070
|
-
const query = (0, pqb_internal._queryUpdateOrThrow)(rel.where(value), connect.items[i]);
|
|
1071
|
-
if (connectWhereExists) (0, pqb_internal._queryWhere)(query, [connectWhereExists]);
|
|
1072
|
-
query.q.ensureCount = 1;
|
|
1073
|
-
(querySelf.q.type === "upsert" ? pqb_internal._appendQueryOnUpsertCreate : pqb_internal._appendQuery)(querySelf, query, (as) => {
|
|
1074
|
-
upsertCreateAs = as;
|
|
1075
|
-
setUpsertCreatePlaceholders();
|
|
1076
|
-
connectAs = as;
|
|
1077
|
-
if (connectWhereExists) connectWhereExists._sql = `EXISTS (SELECT 1 FROM "${as}")`;
|
|
1078
|
-
});
|
|
1079
|
-
});
|
|
1080
|
-
if (connectOrCreate) connectOrCreate.values.forEach((value, i) => {
|
|
1081
|
-
const foreignKeyValues = connectOrCreate.items[i];
|
|
1082
|
-
const connectOrCreateWhereExists = querySelf.q.type === "upsert" ? new pqb_internal.RawSql("") : void 0;
|
|
1083
|
-
const connectOrCreateSelectAs = {};
|
|
1084
|
-
if (connectOrCreateWhereExists) for (const key of foreignKeys) {
|
|
1085
|
-
const value = foreignKeyValues[key];
|
|
1086
|
-
value.result = { value: rel.qb.shape[key] };
|
|
1087
|
-
connectOrCreateSelectAs[key] = value;
|
|
1088
|
-
}
|
|
1089
|
-
const query = (0, pqb_internal._queryUpsert)(rel.where(value.where), {
|
|
1090
|
-
update: foreignKeyValues,
|
|
1091
|
-
create: {
|
|
1092
|
-
...value.create,
|
|
1093
|
-
...foreignKeyValues
|
|
1094
|
-
}
|
|
1095
|
-
});
|
|
1096
|
-
if (connectOrCreateWhereExists) {
|
|
1097
|
-
(0, pqb_internal._queryWhere)(query, [connectOrCreateWhereExists]);
|
|
1098
|
-
const guardQuery = (0, pqb_internal._queryWhere)((0, pqb_internal._queryTake)((0, pqb_internal._querySelect)((0, pqb_internal._clone)(rel.qb), [{ one: new pqb_internal.RawSql("1") }])), [connectOrCreateWhereExists]);
|
|
1099
|
-
const sourceQuery = (0, pqb_internal._querySelect)((0, pqb_internal._clone)(rel.qb).from(guardQuery), [connectOrCreateSelectAs]);
|
|
1100
|
-
const q = query.q;
|
|
1101
|
-
const columns = q.columns || [];
|
|
1102
|
-
const foreignKeysSet = new Set(foreignKeys);
|
|
1103
|
-
q.columns = [...foreignKeys, ...columns.filter((column) => !foreignKeysSet.has(column))];
|
|
1104
|
-
q.values = q.values.map((row) => row.filter((_, i) => !foreignKeysSet.has(columns[i])));
|
|
1105
|
-
q.queryColumnsCount = foreignKeys.length;
|
|
1106
|
-
q.insertFrom = (0, pqb_internal.prepareSubQueryForSql)(query, sourceQuery);
|
|
1107
|
-
}
|
|
1108
|
-
(querySelf.q.type === "upsert" ? pqb_internal._appendQueryOnUpsertCreate : pqb_internal._appendQuery)(querySelf, query, (as) => {
|
|
1109
|
-
upsertCreateAs = as;
|
|
1110
|
-
setUpsertCreatePlaceholders();
|
|
1111
|
-
connectOrCreateAs = as;
|
|
1112
|
-
if (connectOrCreateWhereExists) connectOrCreateWhereExists._sql = `EXISTS (SELECT 1 FROM "${as}")`;
|
|
1113
|
-
});
|
|
1114
|
-
});
|
|
1115
|
-
} else hasRelationHandleCreate(querySelf, ctx, items, rowIndexes, this.key, this.state.primaryKeys, this.nestedInsert);
|
|
934
|
+
create(q, ctx, items) {
|
|
935
|
+
belongsToCreate(this.key, this.state, q, ctx, items);
|
|
1116
936
|
}
|
|
1117
|
-
update(
|
|
1118
|
-
const
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
if (params.create || params.update || params.upsert || params.disconnect || params.set || params.delete) {
|
|
1123
|
-
const ids = makeNestedUpdateRelationIds(querySelf, relQuery, primaryKeys, foreignKeys);
|
|
1124
|
-
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);
|
|
1125
|
-
nullifyOrDeleteQuery.q.returnType = "void";
|
|
1126
|
-
(0, pqb_internal._appendQuery)(querySelf, nullifyOrDeleteQuery, ids.setAppendedAs);
|
|
1127
|
-
if (params.create) {
|
|
1128
|
-
const createQuery = (0, pqb_internal._queryInsert)((0, pqb_internal._clone)(relQuery), {
|
|
1129
|
-
...params.create,
|
|
1130
|
-
...ids.setIds
|
|
1131
|
-
});
|
|
1132
|
-
(0, pqb_internal._appendQuery)(querySelf, createQuery, pqb_internal.noop);
|
|
1133
|
-
} else if (params.set) {
|
|
1134
|
-
const setQuery = (0, pqb_internal._queryUpdate)((0, pqb_internal._queryWhere)((0, pqb_internal._clone)(relQuery), [params.set]), ids.setIds);
|
|
1135
|
-
setQuery.q.returnType = "void";
|
|
1136
|
-
(0, pqb_internal._appendQuery)(querySelf, setQuery, pqb_internal.noop);
|
|
1137
|
-
}
|
|
1138
|
-
}
|
|
937
|
+
update(q, set) {
|
|
938
|
+
const queryForUpdate = q;
|
|
939
|
+
queryForUpdate.q.wrapInTransaction = true;
|
|
940
|
+
const data = set[this.key];
|
|
941
|
+
this.nestedUpdate(queryForUpdate, set, data);
|
|
1139
942
|
}
|
|
1140
943
|
};
|
|
1141
|
-
const
|
|
1142
|
-
const
|
|
1143
|
-
if ("
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
return joinHasThrough(baseQuery, baseQuery, joiningQuery, throughRelation, sourceRelation);
|
|
1153
|
-
};
|
|
1154
|
-
return {
|
|
1155
|
-
returns: "one",
|
|
1156
|
-
queryRelated: (params) => {
|
|
1157
|
-
const throughQuery = table.queryRelated(through, params);
|
|
1158
|
-
return query.whereExists(throughQuery, whereExistsCallback);
|
|
1159
|
-
},
|
|
1160
|
-
joinQuery: joinQueryChainHOF(relPKeys, reverseJoin, (joiningQuery, baseQuery) => joinHasThrough(joiningQuery, baseQuery, joiningQuery, throughRelation, sourceRelation)),
|
|
1161
|
-
reverseJoin
|
|
1162
|
-
};
|
|
1163
|
-
}
|
|
1164
|
-
const primaryKeys = relation.options.columns;
|
|
1165
|
-
const foreignKeys = relation.options.references;
|
|
944
|
+
const getBelongsToRequired = (tableConfig, relatedTableConfig, relation) => {
|
|
945
|
+
const { required } = relation.options;
|
|
946
|
+
if (typeof required === "boolean") return required;
|
|
947
|
+
if (relatedTableConfig.softDelete) return false;
|
|
948
|
+
return relation.options.columns.every((key) => {
|
|
949
|
+
return !tableConfig.columns.shape[key].data.isNullable;
|
|
950
|
+
});
|
|
951
|
+
};
|
|
952
|
+
const makeBelongsToMethod = (tableConfig, table, relation, relationName, query) => {
|
|
953
|
+
const primaryKeys = relation.options.references;
|
|
954
|
+
const foreignKeys = relation.options.columns;
|
|
1166
955
|
const { on } = relation.options;
|
|
1167
956
|
if (on) {
|
|
1168
957
|
(0, pqb_internal._queryWhere)(query, [on]);
|
|
1169
958
|
(0, pqb_internal._queryDefaults)(query, on);
|
|
1170
959
|
}
|
|
1171
|
-
|
|
960
|
+
const len = primaryKeys.length;
|
|
1172
961
|
const state = {
|
|
1173
962
|
query,
|
|
1174
963
|
primaryKeys,
|
|
1175
964
|
foreignKeys,
|
|
965
|
+
len,
|
|
1176
966
|
on
|
|
1177
967
|
};
|
|
1178
|
-
|
|
1179
|
-
const
|
|
1180
|
-
|
|
1181
|
-
|
|
968
|
+
addAutoForeignKey(tableConfig, table, query, primaryKeys, foreignKeys, relation.options);
|
|
969
|
+
const join = (baseQuery, joiningQuery, primaryKeys, foreignKeys) => {
|
|
970
|
+
const baseAs = (0, pqb_internal.getQueryAs)(baseQuery);
|
|
971
|
+
const q = joiningQuery.clone();
|
|
972
|
+
(0, pqb_internal.setQueryObjectValueImmutable)(q, "joinedShapes", baseAs, baseQuery.q.selectShape);
|
|
973
|
+
for (let i = 0; i < len; i++) (0, pqb_internal.pushQueryOnForOuter)(q, baseQuery, joiningQuery, primaryKeys[i], `${baseAs}.${foreignKeys[i]}`);
|
|
974
|
+
return q;
|
|
975
|
+
};
|
|
1182
976
|
const reverseJoin = (baseQuery, joiningQuery) => {
|
|
1183
|
-
return
|
|
977
|
+
return join(joiningQuery, baseQuery, foreignKeys, primaryKeys);
|
|
1184
978
|
};
|
|
1185
979
|
return {
|
|
1186
980
|
returns: "one",
|
|
1187
|
-
queryRelated
|
|
1188
|
-
const
|
|
1189
|
-
for (let i = 0; i < len; i++)
|
|
1190
|
-
return
|
|
1191
|
-
...on,
|
|
1192
|
-
...values
|
|
1193
|
-
});
|
|
981
|
+
queryRelated(params) {
|
|
982
|
+
const obj = {};
|
|
983
|
+
for (let i = 0; i < len; i++) obj[primaryKeys[i]] = params[foreignKeys[i]];
|
|
984
|
+
return query.where(obj);
|
|
1194
985
|
},
|
|
1195
|
-
virtualColumn: new
|
|
1196
|
-
joinQuery: joinQueryChainHOF(
|
|
1197
|
-
reverseJoin
|
|
1198
|
-
|
|
1199
|
-
return (query) => {
|
|
1200
|
-
const baseQuery = query.clone();
|
|
1201
|
-
baseQuery.q.select = fromQuerySelect;
|
|
1202
|
-
const q = relationQuery.q;
|
|
1203
|
-
q.insertFrom = (0, pqb_internal.prepareSubQueryForSql)(q, baseQuery);
|
|
1204
|
-
q.values = [];
|
|
1205
|
-
};
|
|
1206
|
-
}
|
|
1207
|
-
};
|
|
986
|
+
virtualColumn: new BelongsToVirtualColumn(pqb_internal.internalSchemaConfig, relationName, state),
|
|
987
|
+
joinQuery: joinQueryChainHOF((0, pqb_internal.getPrimaryKeys)(query), reverseJoin, (joiningQuery, baseQuery) => join(baseQuery, joiningQuery, primaryKeys, foreignKeys)),
|
|
988
|
+
reverseJoin
|
|
989
|
+
};
|
|
1208
990
|
};
|
|
1209
991
|
const nestedInsert$2 = ({ query, primaryKeys, foreignKeys }) => {
|
|
1210
992
|
return (async (_, data) => {
|
|
@@ -1239,192 +1021,189 @@ const nestedInsert$2 = ({ query, primaryKeys, foreignKeys }) => {
|
|
|
1239
1021
|
}
|
|
1240
1022
|
});
|
|
1241
1023
|
};
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
const
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
values: []
|
|
1278
|
-
};
|
|
1279
|
-
nestedCreateItem.indexes.push(rowIndexes[i]);
|
|
1280
|
-
nestedCreateItem.values.push(value[kind]);
|
|
1281
|
-
const data = {};
|
|
1282
|
-
for (const key of foreignKeys) data[key] = new pqb_internal.RawSql("");
|
|
1283
|
-
nestedCreateItem.items.push(data);
|
|
1284
|
-
}
|
|
1285
|
-
}
|
|
1024
|
+
const hasOneCreate = (key, state, nestedInsertFn, self, ctx, items, rowIndexes, count) => {
|
|
1025
|
+
const querySelf = self;
|
|
1026
|
+
if (count <= querySelf.qb.internal.nestedCreateBatchMax) {
|
|
1027
|
+
const { query: rel, primaryKeys, foreignKeys } = state;
|
|
1028
|
+
let nestedCreateItems;
|
|
1029
|
+
items.forEach((item, i) => {
|
|
1030
|
+
const value = item[key];
|
|
1031
|
+
const kind = value.create ? "create" : value.connect ? "connect" : "connectOrCreate";
|
|
1032
|
+
if (kind) {
|
|
1033
|
+
const nestedCreateItem = (nestedCreateItems ??= {})[kind] ??= {
|
|
1034
|
+
indexes: [],
|
|
1035
|
+
items: [],
|
|
1036
|
+
values: []
|
|
1037
|
+
};
|
|
1038
|
+
nestedCreateItem.indexes.push(rowIndexes[i]);
|
|
1039
|
+
nestedCreateItem.values.push(value[kind]);
|
|
1040
|
+
const data = value.create ? { ...value.create } : {};
|
|
1041
|
+
for (const key of foreignKeys) data[key] = new pqb_internal.RawSql("");
|
|
1042
|
+
nestedCreateItem.items.push(data);
|
|
1043
|
+
}
|
|
1044
|
+
});
|
|
1045
|
+
if (!nestedCreateItems) return;
|
|
1046
|
+
let createAs;
|
|
1047
|
+
let createWhereExists;
|
|
1048
|
+
let createSelectAs;
|
|
1049
|
+
let createAliasedPrimaryKeys;
|
|
1050
|
+
let upsertCreateAs;
|
|
1051
|
+
let connectAs;
|
|
1052
|
+
let connectOrCreateAs;
|
|
1053
|
+
const setUpsertCreatePlaceholders = () => {
|
|
1054
|
+
if (!upsertCreateAs || !createAliasedPrimaryKeys) return;
|
|
1055
|
+
const aliasedPrimaryKeys = createAliasedPrimaryKeys;
|
|
1056
|
+
if (createWhereExists) createWhereExists._sql = `EXISTS (SELECT 1 FROM "${upsertCreateAs}")`;
|
|
1057
|
+
if (createSelectAs) foreignKeys.forEach((key, keyI) => {
|
|
1058
|
+
createSelectAs[key]._sql = selectCteColumnFromManySql(upsertCreateAs, aliasedPrimaryKeys[keyI], 0, 1);
|
|
1286
1059
|
});
|
|
1287
|
-
if (
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
if (
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
}
|
|
1319
|
-
if (connect && connectAs) for (let i = 0; i < connect.items.length; i++) connect.items[i][key]._sql = selectCteColumnFromManySql(connectAs, primaryKey, connect.indexes[i], count);
|
|
1320
|
-
if (connectOrCreate && connectOrCreateAs) for (let i = 0; i < connectOrCreate.items.length; i++) connectOrCreate.items[i][key]._sql = selectCteColumnFromManySql(connectOrCreateAs, primaryKey, connectOrCreate.indexes[i], count);
|
|
1321
|
-
});
|
|
1060
|
+
if (connect) foreignKeys.forEach((key, keyI) => {
|
|
1061
|
+
const primaryKey = aliasedPrimaryKeys[keyI];
|
|
1062
|
+
for (let i = 0; i < connect.items.length; i++) connect.items[i][key]._sql = selectCteColumnFromManySql(upsertCreateAs, primaryKey, connect.indexes[i], count);
|
|
1063
|
+
});
|
|
1064
|
+
if (connectOrCreate) foreignKeys.forEach((key, keyI) => {
|
|
1065
|
+
const primaryKey = aliasedPrimaryKeys[keyI];
|
|
1066
|
+
for (let i = 0; i < connectOrCreate.items.length; i++) connectOrCreate.items[i][key]._sql = selectCteColumnFromManySql(upsertCreateAs, primaryKey, connectOrCreate.indexes[i], count);
|
|
1067
|
+
});
|
|
1068
|
+
};
|
|
1069
|
+
(0, pqb_internal._hookSelectColumns)(querySelf, primaryKeys, (aliasedPrimaryKeys) => {
|
|
1070
|
+
createAliasedPrimaryKeys = aliasedPrimaryKeys;
|
|
1071
|
+
foreignKeys.forEach((key, keyI) => {
|
|
1072
|
+
const primaryKey = aliasedPrimaryKeys[keyI];
|
|
1073
|
+
if (create && createAs) for (let i = 0; i < create.items.length; i++) create.items[i][key]._sql = selectCteColumnFromManySql(createAs, primaryKey, create.indexes[i], count);
|
|
1074
|
+
if (connect && connectAs) for (let i = 0; i < connect.items.length; i++) connect.items[i][key]._sql = selectCteColumnFromManySql(connectAs, primaryKey, connect.indexes[i], count);
|
|
1075
|
+
if (connectOrCreate && connectOrCreateAs) for (let i = 0; i < connectOrCreate.items.length; i++) connectOrCreate.items[i][key]._sql = selectCteColumnFromManySql(connectOrCreateAs, primaryKey, connectOrCreate.indexes[i], count);
|
|
1076
|
+
});
|
|
1077
|
+
setUpsertCreatePlaceholders();
|
|
1078
|
+
});
|
|
1079
|
+
const { create, connect, connectOrCreate } = nestedCreateItems;
|
|
1080
|
+
if (create) {
|
|
1081
|
+
let query;
|
|
1082
|
+
if (querySelf.q.type === "upsert") {
|
|
1083
|
+
createWhereExists = new pqb_internal.RawSql("");
|
|
1084
|
+
createSelectAs = {};
|
|
1085
|
+
for (const key of foreignKeys) createSelectAs[key] = new pqb_internal.RawSql("");
|
|
1086
|
+
const sourceQuery = (0, pqb_internal._queryWhere)((0, pqb_internal._queryTake)((0, pqb_internal._querySelect)((0, pqb_internal._clone)(rel.qb), [createSelectAs])), [createWhereExists]);
|
|
1087
|
+
query = (0, pqb_internal._queryInsertManyFrom)((0, pqb_internal._clone)(rel), sourceQuery, create.items);
|
|
1088
|
+
} else query = (0, pqb_internal._queryInsertMany)((0, pqb_internal._clone)(rel), create.items);
|
|
1089
|
+
if (querySelf.q.type === "upsert") (0, pqb_internal._appendQueryOnUpsertCreate)(querySelf, query, (as) => {
|
|
1090
|
+
upsertCreateAs = as;
|
|
1322
1091
|
setUpsertCreatePlaceholders();
|
|
1323
1092
|
});
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
setUpsertCreatePlaceholders();
|
|
1337
|
-
});
|
|
1338
|
-
else (0, pqb_internal._appendQuery)(querySelf, query, (as) => createAs = as);
|
|
1339
|
-
}
|
|
1340
|
-
if (connect) connect.values.forEach((value, i) => {
|
|
1341
|
-
const connectWhereExists = querySelf.q.type === "upsert" ? new pqb_internal.RawSql("") : void 0;
|
|
1342
|
-
const query = (0, pqb_internal._queryUpdateOrThrow)(rel.whereOneOf(...value), connect.items[i]);
|
|
1343
|
-
if (connectWhereExists) (0, pqb_internal._queryWhere)(query, [connectWhereExists]);
|
|
1344
|
-
query.q.ensureCount = value.length;
|
|
1345
|
-
(querySelf.q.type === "upsert" ? pqb_internal._appendQueryOnUpsertCreate : pqb_internal._appendQuery)(querySelf, query, (as) => {
|
|
1346
|
-
upsertCreateAs = as;
|
|
1347
|
-
setUpsertCreatePlaceholders();
|
|
1348
|
-
connectAs = as;
|
|
1349
|
-
if (connectWhereExists) connectWhereExists._sql = `EXISTS (SELECT 1 FROM "${as}")`;
|
|
1350
|
-
});
|
|
1093
|
+
else (0, pqb_internal._appendQuery)(querySelf, query, (as) => createAs = as);
|
|
1094
|
+
}
|
|
1095
|
+
if (connect) connect.values.forEach((value, i) => {
|
|
1096
|
+
const connectWhereExists = querySelf.q.type === "upsert" ? new pqb_internal.RawSql("") : void 0;
|
|
1097
|
+
const query = (0, pqb_internal._queryUpdateOrThrow)(rel.where(value), connect.items[i]);
|
|
1098
|
+
if (connectWhereExists) (0, pqb_internal._queryWhere)(query, [connectWhereExists]);
|
|
1099
|
+
query.q.ensureCount = 1;
|
|
1100
|
+
(querySelf.q.type === "upsert" ? pqb_internal._appendQueryOnUpsertCreate : pqb_internal._appendQuery)(querySelf, query, (as) => {
|
|
1101
|
+
upsertCreateAs = as;
|
|
1102
|
+
setUpsertCreatePlaceholders();
|
|
1103
|
+
connectAs = as;
|
|
1104
|
+
if (connectWhereExists) connectWhereExists._sql = `EXISTS (SELECT 1 FROM "${as}")`;
|
|
1351
1105
|
});
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
}
|
|
1368
|
-
});
|
|
1369
|
-
if (connectOrCreateWhereExists) {
|
|
1370
|
-
(0, pqb_internal._queryWhere)(query, [connectOrCreateWhereExists]);
|
|
1371
|
-
const guardQuery = (0, pqb_internal._queryWhere)((0, pqb_internal._queryTake)((0, pqb_internal._querySelect)((0, pqb_internal._clone)(rel.qb), [{ one: new pqb_internal.RawSql("1") }])), [connectOrCreateWhereExists]);
|
|
1372
|
-
const sourceQuery = (0, pqb_internal._querySelect)((0, pqb_internal._clone)(rel.qb).from(guardQuery), [connectOrCreateSelectAs]);
|
|
1373
|
-
const q = query.q;
|
|
1374
|
-
const columns = q.columns || [];
|
|
1375
|
-
const foreignKeysSet = new Set(foreignKeys);
|
|
1376
|
-
q.columns = [...foreignKeys, ...columns.filter((column) => !foreignKeysSet.has(column))];
|
|
1377
|
-
q.values = q.values.map((row) => row.filter((_, i) => !foreignKeysSet.has(columns[i])));
|
|
1378
|
-
q.queryColumnsCount = foreignKeys.length;
|
|
1379
|
-
q.insertFrom = (0, pqb_internal.prepareSubQueryForSql)(query, sourceQuery);
|
|
1380
|
-
}
|
|
1381
|
-
(querySelf.q.type === "upsert" ? pqb_internal._appendQueryOnUpsertCreate : pqb_internal._appendQuery)(querySelf, query, (as) => {
|
|
1382
|
-
upsertCreateAs = as;
|
|
1383
|
-
setUpsertCreatePlaceholders();
|
|
1384
|
-
connectOrCreateAs = as;
|
|
1385
|
-
if (connectOrCreateWhereExists) connectOrCreateWhereExists._sql = `EXISTS (SELECT 1 FROM "${as}")`;
|
|
1386
|
-
});
|
|
1106
|
+
});
|
|
1107
|
+
if (connectOrCreate) connectOrCreate.values.forEach((value, i) => {
|
|
1108
|
+
const foreignKeyValues = connectOrCreate.items[i];
|
|
1109
|
+
const connectOrCreateWhereExists = querySelf.q.type === "upsert" ? new pqb_internal.RawSql("") : void 0;
|
|
1110
|
+
const connectOrCreateSelectAs = {};
|
|
1111
|
+
if (connectOrCreateWhereExists) for (const key of foreignKeys) {
|
|
1112
|
+
const value = foreignKeyValues[key];
|
|
1113
|
+
value.result = { value: rel.qb.shape[key] };
|
|
1114
|
+
connectOrCreateSelectAs[key] = value;
|
|
1115
|
+
}
|
|
1116
|
+
const query = (0, pqb_internal._queryUpsert)(rel.where(value.where), {
|
|
1117
|
+
update: foreignKeyValues,
|
|
1118
|
+
create: {
|
|
1119
|
+
...value.create,
|
|
1120
|
+
...foreignKeyValues
|
|
1387
1121
|
}
|
|
1388
1122
|
});
|
|
1389
|
-
|
|
1123
|
+
if (connectOrCreateWhereExists) {
|
|
1124
|
+
(0, pqb_internal._queryWhere)(query, [connectOrCreateWhereExists]);
|
|
1125
|
+
const guardQuery = (0, pqb_internal._queryWhere)((0, pqb_internal._queryTake)((0, pqb_internal._querySelect)((0, pqb_internal._clone)(rel.qb), [{ one: new pqb_internal.RawSql("1") }])), [connectOrCreateWhereExists]);
|
|
1126
|
+
const sourceQuery = (0, pqb_internal._querySelect)((0, pqb_internal._clone)(rel.qb).from(guardQuery), [connectOrCreateSelectAs]);
|
|
1127
|
+
const q = query.q;
|
|
1128
|
+
const columns = q.columns || [];
|
|
1129
|
+
const foreignKeysSet = new Set(foreignKeys);
|
|
1130
|
+
q.columns = [...foreignKeys, ...columns.filter((column) => !foreignKeysSet.has(column))];
|
|
1131
|
+
q.values = q.values.map((row) => row.filter((_, i) => !foreignKeysSet.has(columns[i])));
|
|
1132
|
+
q.queryColumnsCount = foreignKeys.length;
|
|
1133
|
+
q.insertFrom = (0, pqb_internal.prepareSubQueryForSql)(query, sourceQuery);
|
|
1134
|
+
}
|
|
1135
|
+
(querySelf.q.type === "upsert" ? pqb_internal._appendQueryOnUpsertCreate : pqb_internal._appendQuery)(querySelf, query, (as) => {
|
|
1136
|
+
upsertCreateAs = as;
|
|
1137
|
+
setUpsertCreatePlaceholders();
|
|
1138
|
+
connectOrCreateAs = as;
|
|
1139
|
+
if (connectOrCreateWhereExists) connectOrCreateWhereExists._sql = `EXISTS (SELECT 1 FROM "${as}")`;
|
|
1140
|
+
});
|
|
1141
|
+
});
|
|
1142
|
+
} else hasRelationHandleCreate(querySelf, ctx, items, rowIndexes, key, state.primaryKeys, nestedInsertFn);
|
|
1143
|
+
};
|
|
1144
|
+
const hasOneThrough = (table, options, relationName, query, relPKeys) => {
|
|
1145
|
+
const { through, source, on } = options;
|
|
1146
|
+
if (on) (0, pqb_internal._queryWhere)(query, [on]);
|
|
1147
|
+
const throughRelation = getThroughRelation(table, through);
|
|
1148
|
+
const sourceRelation = getSourceRelation(throughRelation, source);
|
|
1149
|
+
const sourceRelationQuery = sourceRelation.query.as(relationName);
|
|
1150
|
+
const sourceQuery = sourceRelation.joinQuery(sourceRelationQuery, throughRelation.query);
|
|
1151
|
+
const whereExistsCallback = () => sourceQuery;
|
|
1152
|
+
const reverseJoin = (baseQuery, joiningQuery) => {
|
|
1153
|
+
return joinHasThrough(baseQuery, baseQuery, joiningQuery, throughRelation, sourceRelation);
|
|
1154
|
+
};
|
|
1155
|
+
return {
|
|
1156
|
+
returns: "one",
|
|
1157
|
+
queryRelated: (params) => {
|
|
1158
|
+
const throughQuery = table.queryRelated(through, params);
|
|
1159
|
+
return query.whereExists(throughQuery, whereExistsCallback);
|
|
1160
|
+
},
|
|
1161
|
+
joinQuery: joinQueryChainHOF(relPKeys, reverseJoin, (joiningQuery, baseQuery) => joinHasThrough(joiningQuery, baseQuery, joiningQuery, throughRelation, sourceRelation)),
|
|
1162
|
+
reverseJoin
|
|
1163
|
+
};
|
|
1164
|
+
};
|
|
1165
|
+
const hasOneUpdate = (key, state, self, set) => {
|
|
1166
|
+
const querySelf = self;
|
|
1167
|
+
const params = set[key];
|
|
1168
|
+
throwIfQueryReturnsAllForNestedUpdate(querySelf, params);
|
|
1169
|
+
const { primaryKeys, foreignKeys, query: relQuery } = state;
|
|
1170
|
+
if (params.create || params.update || params.upsert || params.disconnect || params.set || params.delete) {
|
|
1171
|
+
const ids = makeNestedUpdateRelationIds(querySelf, relQuery, primaryKeys, foreignKeys);
|
|
1172
|
+
const setNulls = {};
|
|
1173
|
+
for (const foreignKey of foreignKeys) setNulls[foreignKey] = null;
|
|
1174
|
+
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, setNulls);
|
|
1175
|
+
nullifyOrDeleteQuery.q.returnType = "void";
|
|
1176
|
+
(0, pqb_internal._appendQuery)(querySelf, nullifyOrDeleteQuery, ids.setAppendedAs);
|
|
1177
|
+
if (params.create) {
|
|
1178
|
+
const createQuery = (0, pqb_internal._queryInsert)((0, pqb_internal._clone)(relQuery), {
|
|
1179
|
+
...params.create,
|
|
1180
|
+
...ids.setIds
|
|
1181
|
+
});
|
|
1182
|
+
(0, pqb_internal._appendQuery)(querySelf, createQuery, pqb_internal.noop);
|
|
1183
|
+
} else if (params.set) {
|
|
1184
|
+
const setQuery = (0, pqb_internal._queryUpdate)((0, pqb_internal._queryWhere)((0, pqb_internal._clone)(relQuery), [params.set]), ids.setIds);
|
|
1185
|
+
setQuery.q.returnType = "void";
|
|
1186
|
+
(0, pqb_internal._appendQuery)(querySelf, setQuery, pqb_internal.noop);
|
|
1187
|
+
}
|
|
1188
|
+
}
|
|
1189
|
+
};
|
|
1190
|
+
var HasOneVirtualColumn = class extends pqb_internal.VirtualColumn {
|
|
1191
|
+
constructor(schema, key, state) {
|
|
1192
|
+
super(schema);
|
|
1193
|
+
this.key = key;
|
|
1194
|
+
this.state = state;
|
|
1195
|
+
this.nestedInsert = nestedInsert$2(state);
|
|
1196
|
+
}
|
|
1197
|
+
create(self, ctx, items, rowIndexes, count) {
|
|
1198
|
+
hasOneCreate(this.key, this.state, this.nestedInsert, self, ctx, items, rowIndexes, count);
|
|
1390
1199
|
}
|
|
1391
1200
|
update(self, set) {
|
|
1392
|
-
|
|
1393
|
-
const params = set[this.key];
|
|
1394
|
-
throwIfQueryReturnsAllForNestedUpdate(querySelf, params);
|
|
1395
|
-
hasRelationHandleUpdate(querySelf, set, this.key, this.state.primaryKeys, this.nestedUpdate);
|
|
1396
|
-
if (params.upsert) {
|
|
1397
|
-
const { primaryKeys, foreignKeys, query: relQuery } = this.state;
|
|
1398
|
-
const ids = makeNestedUpdateRelationIds(querySelf, relQuery, primaryKeys, foreignKeys);
|
|
1399
|
-
const appendedQuery = (0, pqb_internal._queryUpsert)(ids.existingRelQuery, makeNestedUpdateUpsertData(params.upsert, ids.setIds));
|
|
1400
|
-
appendedQuery.q.returnType = "void";
|
|
1401
|
-
(0, pqb_internal._appendQuery)(querySelf, appendedQuery, ids.setAppendedAs);
|
|
1402
|
-
}
|
|
1201
|
+
hasOneUpdate(this.key, this.state, self, set);
|
|
1403
1202
|
}
|
|
1404
1203
|
};
|
|
1405
|
-
const
|
|
1204
|
+
const makeHasOneMethod = (tableConfig, table, relation, relationName, query) => {
|
|
1406
1205
|
const relPKeys = (0, pqb_internal.getPrimaryKeys)(query);
|
|
1407
|
-
if ("through" in relation.options)
|
|
1408
|
-
const { through, source, on } = relation.options;
|
|
1409
|
-
if (on) (0, pqb_internal._queryWhere)(query, [on]);
|
|
1410
|
-
const throughRelation = getThroughRelation(table, through);
|
|
1411
|
-
const sourceRelation = getSourceRelation(throughRelation, source);
|
|
1412
|
-
const sourceRelationQuery = sourceRelation.query.as(relationName);
|
|
1413
|
-
const sourceQuery = sourceRelation.joinQuery(sourceRelationQuery, throughRelation.query);
|
|
1414
|
-
const whereExistsCallback = () => sourceQuery;
|
|
1415
|
-
const reverseJoin = (baseQuery, joiningQuery) => {
|
|
1416
|
-
return joinHasThrough(baseQuery, baseQuery, joiningQuery, throughRelation, sourceRelation);
|
|
1417
|
-
};
|
|
1418
|
-
return {
|
|
1419
|
-
returns: "many",
|
|
1420
|
-
queryRelated: (params) => {
|
|
1421
|
-
const throughQuery = table.queryRelated(through, params);
|
|
1422
|
-
return query.whereExists(throughQuery, whereExistsCallback);
|
|
1423
|
-
},
|
|
1424
|
-
joinQuery: joinQueryChainHOF(relPKeys, reverseJoin, (joiningQuery, baseQuery) => joinHasThrough(joiningQuery, baseQuery, joiningQuery, throughRelation, sourceRelation)),
|
|
1425
|
-
reverseJoin
|
|
1426
|
-
};
|
|
1427
|
-
}
|
|
1206
|
+
if ("through" in relation.options) return hasOneThrough(table, relation.options, relationName, query, relPKeys);
|
|
1428
1207
|
const primaryKeys = relation.options.columns;
|
|
1429
1208
|
const foreignKeys = relation.options.references;
|
|
1430
1209
|
const { on } = relation.options;
|
|
@@ -1447,7 +1226,7 @@ const makeHasManyMethod = (tableConfig, table, relation, relationName, query) =>
|
|
|
1447
1226
|
return joinHasRelation(joiningQuery, baseQuery, foreignKeys, primaryKeys, len);
|
|
1448
1227
|
};
|
|
1449
1228
|
return {
|
|
1450
|
-
returns: "
|
|
1229
|
+
returns: "one",
|
|
1451
1230
|
queryRelated: (params) => {
|
|
1452
1231
|
const values = {};
|
|
1453
1232
|
for (let i = 0; i < len; i++) values[foreignKeys[i]] = params[primaryKeys[i]];
|
|
@@ -1456,7 +1235,7 @@ const makeHasManyMethod = (tableConfig, table, relation, relationName, query) =>
|
|
|
1456
1235
|
...values
|
|
1457
1236
|
});
|
|
1458
1237
|
},
|
|
1459
|
-
virtualColumn: new
|
|
1238
|
+
virtualColumn: new HasOneVirtualColumn(pqb_internal.internalSchemaConfig, relationName, state),
|
|
1460
1239
|
joinQuery: joinQueryChainHOF(relPKeys, reverseJoin, (joiningQuery, baseQuery) => joinHasRelation(baseQuery, joiningQuery, primaryKeys, foreignKeys, len)),
|
|
1461
1240
|
reverseJoin,
|
|
1462
1241
|
modifyRelatedQuery(relationQuery) {
|
|
@@ -1479,6 +1258,81 @@ const getWhereForNestedUpdate = (t, data, params, primaryKeys, foreignKeys) => {
|
|
|
1479
1258
|
OR: params ? (0, pqb_internal.toArray)(params) : void 0
|
|
1480
1259
|
});
|
|
1481
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) => {
|
|
1302
|
+
const querySelf = self;
|
|
1303
|
+
const params = set[key];
|
|
1304
|
+
throwIfQueryReturnsAllForNestedUpdate(querySelf, params);
|
|
1305
|
+
hasRelationHandleUpdate(querySelf, set, key, state.primaryKeys, nestedUpdateFn);
|
|
1306
|
+
if (params.upsert) {
|
|
1307
|
+
const { primaryKeys, foreignKeys, query: relQuery } = state;
|
|
1308
|
+
const ids = makeNestedUpdateRelationIds(querySelf, relQuery, primaryKeys, foreignKeys);
|
|
1309
|
+
const appendedQuery = (0, pqb_internal._queryUpsert)(ids.existingRelQuery, makeNestedUpdateUpsertData(params.upsert, ids.setIds));
|
|
1310
|
+
appendedQuery.q.returnType = "void";
|
|
1311
|
+
(0, pqb_internal._appendQuery)(querySelf, appendedQuery, ids.setAppendedAs);
|
|
1312
|
+
}
|
|
1313
|
+
};
|
|
1314
|
+
const makeHasManyThroughMethod = ({ table, query, relation, relationName, relPKeys }) => {
|
|
1315
|
+
if (!("through" in relation.options)) return;
|
|
1316
|
+
const { through, source, on } = relation.options;
|
|
1317
|
+
if (on) (0, pqb_internal._queryWhere)(query, [on]);
|
|
1318
|
+
const throughRelation = getThroughRelation(table, through);
|
|
1319
|
+
const sourceRelation = getSourceRelation(throughRelation, source);
|
|
1320
|
+
const sourceRelationQuery = sourceRelation.query.as(relationName);
|
|
1321
|
+
const sourceQuery = sourceRelation.joinQuery(sourceRelationQuery, throughRelation.query);
|
|
1322
|
+
const whereExistsCallback = () => sourceQuery;
|
|
1323
|
+
const reverseJoin = (baseQuery, joiningQuery) => {
|
|
1324
|
+
return joinHasThrough(baseQuery, baseQuery, joiningQuery, throughRelation, sourceRelation);
|
|
1325
|
+
};
|
|
1326
|
+
return {
|
|
1327
|
+
returns: "many",
|
|
1328
|
+
queryRelated: (params) => {
|
|
1329
|
+
const throughQuery = table.queryRelated(through, params);
|
|
1330
|
+
return query.whereExists(throughQuery, whereExistsCallback);
|
|
1331
|
+
},
|
|
1332
|
+
joinQuery: joinQueryChainHOF(relPKeys, reverseJoin, (joiningQuery, baseQuery) => joinHasThrough(joiningQuery, baseQuery, joiningQuery, throughRelation, sourceRelation)),
|
|
1333
|
+
reverseJoin
|
|
1334
|
+
};
|
|
1335
|
+
};
|
|
1482
1336
|
const nestedInsert$1 = ({ query, primaryKeys, foreignKeys }) => {
|
|
1483
1337
|
const len = primaryKeys.length;
|
|
1484
1338
|
return (async (_, data) => {
|
|
@@ -1540,258 +1394,218 @@ const nestedInsert$1 = ({ query, primaryKeys, foreignKeys }) => {
|
|
|
1540
1394
|
}
|
|
1541
1395
|
});
|
|
1542
1396
|
};
|
|
1543
|
-
const
|
|
1544
|
-
const
|
|
1545
|
-
|
|
1546
|
-
const
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1397
|
+
const hasManyCreate = (key, state, nestedInsertFn, self, ctx, items, rowIndexes, count) => {
|
|
1398
|
+
const querySelf = self;
|
|
1399
|
+
if (count <= querySelf.qb.internal.nestedCreateBatchMax) {
|
|
1400
|
+
const { query: rel, primaryKeys, foreignKeys } = state;
|
|
1401
|
+
let nestedCreateItems;
|
|
1402
|
+
items.forEach((item, i) => {
|
|
1403
|
+
const value = item[key];
|
|
1404
|
+
if (value.create?.length) {
|
|
1405
|
+
const nestedCreateItem = (nestedCreateItems ??= {}).create ??= {
|
|
1406
|
+
indexes: [],
|
|
1407
|
+
items: []
|
|
1408
|
+
};
|
|
1409
|
+
nestedCreateItem.indexes.push(rowIndexes[i]);
|
|
1410
|
+
const data = value.create.map((obj) => {
|
|
1411
|
+
const data = { ...obj };
|
|
1412
|
+
for (const key of foreignKeys) data[key] = new pqb_internal.RawSql("");
|
|
1413
|
+
return data;
|
|
1414
|
+
});
|
|
1415
|
+
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
|
+
}
|
|
1574
1430
|
}
|
|
1575
|
-
}
|
|
1576
|
-
if (
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
const
|
|
1606
|
-
const
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1431
|
+
});
|
|
1432
|
+
if (!nestedCreateItems) return;
|
|
1433
|
+
let createAs;
|
|
1434
|
+
let createWhereExists;
|
|
1435
|
+
let createSelectAs;
|
|
1436
|
+
let createAliasedPrimaryKeys;
|
|
1437
|
+
let upsertCreateAs;
|
|
1438
|
+
let connectAs;
|
|
1439
|
+
let connectOrCreateAs;
|
|
1440
|
+
const setUpsertCreatePlaceholders = () => {
|
|
1441
|
+
if (!upsertCreateAs || !createAliasedPrimaryKeys) return;
|
|
1442
|
+
const aliasedPrimaryKeys = createAliasedPrimaryKeys;
|
|
1443
|
+
if (createWhereExists) createWhereExists._sql = `EXISTS (SELECT 1 FROM "${upsertCreateAs}")`;
|
|
1444
|
+
if (createSelectAs) foreignKeys.forEach((key, keyI) => {
|
|
1445
|
+
createSelectAs[key]._sql = selectCteColumnFromManySql(upsertCreateAs, aliasedPrimaryKeys[keyI], 0, 1);
|
|
1446
|
+
});
|
|
1447
|
+
if (connect) foreignKeys.forEach((key, keyI) => {
|
|
1448
|
+
const primaryKey = aliasedPrimaryKeys[keyI];
|
|
1449
|
+
for (let i = 0; i < connect.items.length; i++) connect.items[i][key]._sql = selectCteColumnFromManySql(upsertCreateAs, primaryKey, connect.indexes[i], count);
|
|
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
|
+
});
|
|
1455
|
+
};
|
|
1456
|
+
(0, pqb_internal._hookSelectColumns)(querySelf, primaryKeys, (aliasedPrimaryKeys) => {
|
|
1457
|
+
createAliasedPrimaryKeys = aliasedPrimaryKeys;
|
|
1458
|
+
foreignKeys.forEach((key, keyI) => {
|
|
1459
|
+
const primaryKey = aliasedPrimaryKeys[keyI];
|
|
1460
|
+
if (create && createAs) for (let i = 0; i < create.items.length; i++) {
|
|
1461
|
+
const sql = selectCteColumnFromManySql(createAs, primaryKey, create.indexes[i], count);
|
|
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
|
+
});
|
|
1467
|
+
setUpsertCreatePlaceholders();
|
|
1468
|
+
});
|
|
1469
|
+
const { create, connect, connectOrCreate } = nestedCreateItems;
|
|
1470
|
+
if (create) {
|
|
1471
|
+
let query;
|
|
1472
|
+
if (querySelf.q.type === "upsert") {
|
|
1473
|
+
createWhereExists = new pqb_internal.RawSql("");
|
|
1474
|
+
createSelectAs = {};
|
|
1475
|
+
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)(rel.qb), [createSelectAs])), [createWhereExists]);
|
|
1477
|
+
query = (0, pqb_internal._queryInsertManyFrom)((0, pqb_internal._clone)(rel), sourceQuery, create.items.flat());
|
|
1478
|
+
} else query = (0, pqb_internal._queryInsertMany)((0, pqb_internal._clone)(rel), create.items.flat());
|
|
1479
|
+
if (querySelf.q.type === "upsert") (0, pqb_internal._appendQueryOnUpsertCreate)(querySelf, query, (as) => {
|
|
1480
|
+
upsertCreateAs = as;
|
|
1481
|
+
setUpsertCreatePlaceholders();
|
|
1482
|
+
});
|
|
1483
|
+
else (0, pqb_internal._appendQuery)(querySelf, query, (as) => createAs = as);
|
|
1484
|
+
}
|
|
1485
|
+
if (connect) connect.values.forEach((value, i) => {
|
|
1486
|
+
const connectWhereExists = querySelf.q.type === "upsert" ? new pqb_internal.RawSql("") : void 0;
|
|
1487
|
+
const query = (0, pqb_internal._queryUpdateOrThrow)(rel.whereOneOf(...value), connect.items[i]);
|
|
1488
|
+
if (connectWhereExists) (0, pqb_internal._queryWhere)(query, [connectWhereExists]);
|
|
1489
|
+
query.q.ensureCount = value.length;
|
|
1490
|
+
(querySelf.q.type === "upsert" ? pqb_internal._appendQueryOnUpsertCreate : pqb_internal._appendQuery)(querySelf, query, (as) => {
|
|
1491
|
+
upsertCreateAs = as;
|
|
1492
|
+
setUpsertCreatePlaceholders();
|
|
1493
|
+
connectAs = as;
|
|
1494
|
+
if (connectWhereExists) connectWhereExists._sql = `EXISTS (SELECT 1 FROM "${as}")`;
|
|
1495
|
+
});
|
|
1496
|
+
});
|
|
1497
|
+
if (connectOrCreate) connectOrCreate.values.forEach((array, i) => {
|
|
1498
|
+
const foreignKeyValues = connectOrCreate.items[i];
|
|
1499
|
+
for (const value of array) {
|
|
1500
|
+
const connectOrCreateWhereExists = querySelf.q.type === "upsert" ? new pqb_internal.RawSql("") : void 0;
|
|
1501
|
+
const connectOrCreateSelectAs = {};
|
|
1502
|
+
if (connectOrCreateWhereExists) for (const key of foreignKeys) {
|
|
1503
|
+
const value = foreignKeyValues[key];
|
|
1504
|
+
value.result = { value: rel.qb.shape[key] };
|
|
1505
|
+
connectOrCreateSelectAs[key] = value;
|
|
1506
|
+
}
|
|
1507
|
+
const query = (0, pqb_internal._queryUpsert)(rel.where(value.where), {
|
|
1508
|
+
update: foreignKeyValues,
|
|
1509
|
+
create: {
|
|
1510
|
+
...value.create,
|
|
1511
|
+
...foreignKeyValues
|
|
1512
|
+
}
|
|
1513
|
+
});
|
|
1514
|
+
if (connectOrCreateWhereExists) {
|
|
1515
|
+
(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)(rel.qb), [{ one: new pqb_internal.RawSql("1") }])), [connectOrCreateWhereExists]);
|
|
1517
|
+
const sourceQuery = (0, pqb_internal._querySelect)((0, pqb_internal._clone)(rel.qb).from(guardQuery), [connectOrCreateSelectAs]);
|
|
1518
|
+
const q = query.q;
|
|
1519
|
+
const columns = q.columns || [];
|
|
1520
|
+
const foreignKeysSet = new Set(foreignKeys);
|
|
1521
|
+
q.columns = [...foreignKeys, ...columns.filter((column) => !foreignKeysSet.has(column))];
|
|
1522
|
+
q.values = q.values.map((row) => row.filter((_, i) => !foreignKeysSet.has(columns[i])));
|
|
1523
|
+
q.queryColumnsCount = foreignKeys.length;
|
|
1524
|
+
q.insertFrom = (0, pqb_internal.prepareSubQueryForSql)(query, sourceQuery);
|
|
1525
|
+
}
|
|
1526
|
+
(querySelf.q.type === "upsert" ? pqb_internal._appendQueryOnUpsertCreate : pqb_internal._appendQuery)(querySelf, query, (as) => {
|
|
1527
|
+
upsertCreateAs = as;
|
|
1528
|
+
setUpsertCreatePlaceholders();
|
|
1529
|
+
connectOrCreateAs = as;
|
|
1530
|
+
if (connectOrCreateWhereExists) connectOrCreateWhereExists._sql = `EXISTS (SELECT 1 FROM "${as}")`;
|
|
1531
|
+
});
|
|
1532
|
+
}
|
|
1533
|
+
});
|
|
1534
|
+
} else hasRelationHandleCreate(querySelf, ctx, items, rowIndexes, key, state.primaryKeys, nestedInsertFn);
|
|
1638
1535
|
};
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1536
|
+
var HasManyVirtualColumn = class extends pqb_internal.VirtualColumn {
|
|
1537
|
+
constructor(schema, key, state) {
|
|
1538
|
+
super(schema);
|
|
1539
|
+
this.key = key;
|
|
1540
|
+
this.state = state;
|
|
1541
|
+
this.nestedInsert = nestedInsert$1(state);
|
|
1542
|
+
this.nestedUpdate = nestedUpdate$1(state);
|
|
1543
|
+
this.setNulls = {};
|
|
1544
|
+
for (const foreignKey of state.foreignKeys) this.setNulls[foreignKey] = null;
|
|
1545
|
+
}
|
|
1546
|
+
create(self, ctx, items, rowIndexes, count) {
|
|
1547
|
+
hasManyCreate(this.key, this.state, this.nestedInsert, self, ctx, items, rowIndexes, count);
|
|
1548
|
+
}
|
|
1549
|
+
update(self, set) {
|
|
1550
|
+
hasManyUpdate(this.key, this.state, this.nestedUpdate, self, set);
|
|
1551
|
+
}
|
|
1647
1552
|
};
|
|
1648
|
-
const
|
|
1649
|
-
const
|
|
1650
|
-
const
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
const
|
|
1553
|
+
const makeHasManyMethod = (tableConfig, table, relation, relationName, query) => {
|
|
1554
|
+
const relPKeys = (0, pqb_internal.getPrimaryKeys)(query);
|
|
1555
|
+
const throughResult = makeHasManyThroughMethod({
|
|
1556
|
+
table,
|
|
1557
|
+
query,
|
|
1558
|
+
relation,
|
|
1559
|
+
relationName,
|
|
1560
|
+
relPKeys
|
|
1561
|
+
});
|
|
1562
|
+
if (throughResult) return throughResult;
|
|
1563
|
+
const opts = relation.options;
|
|
1564
|
+
const primaryKeys = opts.columns;
|
|
1565
|
+
const foreignKeys = opts.references;
|
|
1566
|
+
const { on } = opts;
|
|
1659
1567
|
if (on) {
|
|
1660
1568
|
(0, pqb_internal._queryWhere)(query, [on]);
|
|
1661
1569
|
(0, pqb_internal._queryDefaults)(query, on);
|
|
1662
1570
|
}
|
|
1663
|
-
|
|
1664
|
-
if (snakeCase) key = foreignKeys[i] = (0, pqb_internal.toSnakeCase)(key);
|
|
1665
|
-
return `${joinTable}.${key}`;
|
|
1666
|
-
});
|
|
1667
|
-
const throughForeignKeysFull = throughForeignKeys.map((key, i) => {
|
|
1668
|
-
if (snakeCase) key = throughForeignKeys[i] = (0, pqb_internal.toSnakeCase)(key);
|
|
1669
|
-
return `${joinTable}.${key}`;
|
|
1670
|
-
});
|
|
1671
|
-
const foreignTable = (0, pqb_internal.getQueryAs)(query);
|
|
1672
|
-
const throughPrimaryKeysFull = throughPrimaryKeys.map((key) => `${foreignTable}.${key}`);
|
|
1673
|
-
const len = primaryKeys.length;
|
|
1674
|
-
const throughLen = throughPrimaryKeys.length;
|
|
1675
|
-
const baseQuery = Object.create(qb.baseQuery);
|
|
1676
|
-
baseQuery.baseQuery = baseQuery;
|
|
1677
|
-
baseQuery.table = joinTable;
|
|
1678
|
-
const shape = {};
|
|
1679
|
-
const primaryKeysShape = {};
|
|
1680
|
-
for (let i = 0; i < len; i++) {
|
|
1681
|
-
const pk = primaryKeys[i];
|
|
1682
|
-
shape[foreignKeys[i]] = removeColumnName(table.shape[pk]);
|
|
1683
|
-
primaryKeysShape[pk] = table.shape[pk];
|
|
1684
|
-
}
|
|
1685
|
-
for (let i = 0; i < throughLen; i++) shape[throughForeignKeys[i]] = removeColumnName(query.shape[throughPrimaryKeys[i]]);
|
|
1686
|
-
baseQuery.shape = shape;
|
|
1687
|
-
baseQuery.q = {
|
|
1688
|
-
...baseQuery.q,
|
|
1689
|
-
schema: options.through.schema || schema,
|
|
1690
|
-
shape: baseQuery.shape
|
|
1691
|
-
};
|
|
1692
|
-
const subQuery = Object.create(baseQuery);
|
|
1693
|
-
addAutoForeignKey(tableConfig, subQuery, table, primaryKeys, foreignKeys, relation.options, originalForeignKeys);
|
|
1694
|
-
addAutoForeignKey(tableConfig, subQuery, query, throughPrimaryKeys, throughForeignKeys, relation.options.through, originalThroughForeignKeys);
|
|
1571
|
+
addAutoForeignKey(tableConfig, query, table, primaryKeys, foreignKeys, opts);
|
|
1695
1572
|
const state = {
|
|
1696
|
-
|
|
1697
|
-
relatedTableQuery: query,
|
|
1698
|
-
joinTableQuery: subQuery,
|
|
1573
|
+
query,
|
|
1699
1574
|
primaryKeys,
|
|
1700
1575
|
foreignKeys,
|
|
1701
|
-
throughForeignKeys,
|
|
1702
|
-
throughPrimaryKeys,
|
|
1703
|
-
foreignKeysFull,
|
|
1704
|
-
throughForeignKeysFull,
|
|
1705
|
-
throughPrimaryKeysFull,
|
|
1706
|
-
primaryKeysShape,
|
|
1707
1576
|
on
|
|
1708
1577
|
};
|
|
1709
|
-
const
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
for (let i = 0; i < throughLen; i++) (0, pqb_internal._queryJoinOn)(q, [throughForeignKeysFull[i], `${foreignAs}.${throughPrimaryKeys[i]}`]);
|
|
1714
|
-
for (let i = 0; i < len; i++) (0, pqb_internal._queryJoinOn)(q, [foreignKeysFull[i], `${tableAs}.${primaryKeys[i]}`]);
|
|
1715
|
-
return q;
|
|
1716
|
-
}]);
|
|
1717
|
-
};
|
|
1718
|
-
const obj = {};
|
|
1719
|
-
for (let i = 0; i < len; i++) obj[foreignKeys[i]] = primaryKeys[i];
|
|
1720
|
-
const selectPrimaryKeysAsForeignKeys = [{ selectAs: obj }];
|
|
1578
|
+
const len = primaryKeys.length;
|
|
1579
|
+
const reversedOn = {};
|
|
1580
|
+
for (let i = 0; i < len; i++) reversedOn[foreignKeys[i]] = primaryKeys[i];
|
|
1581
|
+
const fromQuerySelect = [{ selectAs: reversedOn }];
|
|
1721
1582
|
const reverseJoin = (baseQuery, joiningQuery) => {
|
|
1722
|
-
|
|
1723
|
-
return joinQuery(baseQuery, (0, pqb_internal.getQueryAs)(baseQuery), foreignAs, {
|
|
1724
|
-
...baseQuery.q.joinedShapes,
|
|
1725
|
-
[foreignAs]: joiningQuery.q.selectShape
|
|
1726
|
-
});
|
|
1583
|
+
return joinHasRelation(joiningQuery, baseQuery, foreignKeys, primaryKeys, len);
|
|
1727
1584
|
};
|
|
1728
1585
|
return {
|
|
1729
1586
|
returns: "many",
|
|
1730
|
-
queryRelated(params) {
|
|
1731
|
-
const
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
return (0, pqb_internal._queryWhere)(q, [where]);
|
|
1587
|
+
queryRelated: (params) => {
|
|
1588
|
+
const values = {};
|
|
1589
|
+
for (let i = 0; i < len; i++) values[foreignKeys[i]] = params[primaryKeys[i]];
|
|
1590
|
+
return (0, pqb_internal._queryDefaults)(query.where(values), {
|
|
1591
|
+
...on,
|
|
1592
|
+
...values
|
|
1737
1593
|
});
|
|
1738
|
-
return on ? (0, pqb_internal._queryDefaults)(q, on) : q;
|
|
1739
1594
|
},
|
|
1740
|
-
virtualColumn: new
|
|
1741
|
-
joinQuery: joinQueryChainHOF(
|
|
1742
|
-
...joiningQuery.q.joinedShapes,
|
|
1743
|
-
[baseQuery.q.as || baseQuery.table]: baseQuery.q.selectShape
|
|
1744
|
-
})),
|
|
1595
|
+
virtualColumn: new HasManyVirtualColumn(pqb_internal.internalSchemaConfig, relationName, state),
|
|
1596
|
+
joinQuery: joinQueryChainHOF(relPKeys, reverseJoin, (joiningQuery, baseQuery) => joinHasRelation(baseQuery, joiningQuery, primaryKeys, foreignKeys, len)),
|
|
1745
1597
|
reverseJoin,
|
|
1746
1598
|
modifyRelatedQuery(relationQuery) {
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
for (let i = 0; i < throughLen; i++) dataRow[throughForeignKeys[i]] = resultRow[throughPrimaryKeys[i]];
|
|
1754
|
-
return dataRow;
|
|
1755
|
-
});
|
|
1756
|
-
if (await (0, pqb_internal._queryCreateManyFrom)(subQuery.count(), baseQuery, data) === 0) throw new pqb.NotFoundError(baseQuery);
|
|
1757
|
-
});
|
|
1758
|
-
return (q) => {
|
|
1759
|
-
ref.q = q;
|
|
1599
|
+
return (query) => {
|
|
1600
|
+
const baseQuery = query.clone();
|
|
1601
|
+
baseQuery.q.select = fromQuerySelect;
|
|
1602
|
+
const q = relationQuery.q;
|
|
1603
|
+
q.insertFrom = (0, pqb_internal.prepareSubQueryForSql)(q, baseQuery);
|
|
1604
|
+
q.values = [];
|
|
1760
1605
|
};
|
|
1761
1606
|
}
|
|
1762
1607
|
};
|
|
1763
1608
|
};
|
|
1764
|
-
const queryJoinTable = (state, data, conditions) => {
|
|
1765
|
-
const t = state.joinTableQuery.where({ IN: {
|
|
1766
|
-
columns: state.foreignKeys,
|
|
1767
|
-
values: data.map((item) => state.primaryKeys.map((key) => item[key]))
|
|
1768
|
-
} });
|
|
1769
|
-
if (conditions) (0, pqb_internal._queryWhere)(t, [{ IN: {
|
|
1770
|
-
columns: state.throughForeignKeys,
|
|
1771
|
-
values: (0, pqb_internal._querySelect)(state.relatedTableQuery.where(conditionsToWhereArg(conditions)), state.throughPrimaryKeys)
|
|
1772
|
-
} }]);
|
|
1773
|
-
if (state.on) (0, pqb_internal._queryWhereExists)(t, state.relatedTableQuery, [(q) => {
|
|
1774
|
-
for (let i = 0; i < state.throughPrimaryKeys.length; i++) (0, pqb_internal._queryJoinOn)(q, [state.throughPrimaryKeysFull[i], state.throughForeignKeysFull[i]]);
|
|
1775
|
-
return q;
|
|
1776
|
-
}]);
|
|
1777
|
-
return t;
|
|
1778
|
-
};
|
|
1779
|
-
const conditionsToWhereArg = (conditions) => Array.isArray(conditions) ? { OR: conditions } : conditions;
|
|
1780
|
-
const insertToJoinTable = (state, joinTableTransaction, data, idsRows) => {
|
|
1781
|
-
const len = state.primaryKeys.length;
|
|
1782
|
-
const throughLen = state.throughPrimaryKeys.length;
|
|
1783
|
-
const records = [];
|
|
1784
|
-
for (const item of data) {
|
|
1785
|
-
const obj = {};
|
|
1786
|
-
for (let i = 0; i < len; i++) obj[state.foreignKeys[i]] = item[state.primaryKeys[i]];
|
|
1787
|
-
for (const ids of idsRows) {
|
|
1788
|
-
const record = { ...obj };
|
|
1789
|
-
for (let i = 0; i < throughLen; i++) record[state.throughForeignKeys[i]] = ids[i];
|
|
1790
|
-
records.push(record);
|
|
1791
|
-
}
|
|
1792
|
-
}
|
|
1793
|
-
return joinTableTransaction.insertMany(records);
|
|
1794
|
-
};
|
|
1795
1609
|
const nestedInsert = ({ relatedTableQuery, joinTableQuery, primaryKeys, foreignKeys, throughPrimaryKeys, throughForeignKeys }) => {
|
|
1796
1610
|
const len = primaryKeys.length;
|
|
1797
1611
|
const throughLen = primaryKeys.length;
|
|
@@ -1877,6 +1691,71 @@ const nestedInsert = ({ relatedTableQuery, joinTableQuery, primaryKeys, foreignK
|
|
|
1877
1691
|
await joinTableQuery.insertMany(records);
|
|
1878
1692
|
});
|
|
1879
1693
|
};
|
|
1694
|
+
const selectCteColumnsSql = (cteAs, columns) => `(SELECT ${columns.map((c) => `"${cteAs}"."${c}"`).join(", ")} FROM "${cteAs}")`;
|
|
1695
|
+
const selectCteColumnSql = (cteAs, column) => `(SELECT "${cteAs}"."${column}" FROM "${cteAs}")`;
|
|
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);
|
|
1726
|
+
};
|
|
1727
|
+
const nestedUpdateUpsert = (querySelf, state, upsert) => {
|
|
1728
|
+
const parentIdsSql = new pqb_internal.RawSql("");
|
|
1729
|
+
const parentValues = state.foreignKeys.map(() => new pqb_internal.RawSql(""));
|
|
1730
|
+
const relatedIdsSql = new pqb_internal.RawSql("");
|
|
1731
|
+
const relatedValues = state.throughPrimaryKeys.map(() => new pqb_internal.RawSql(""));
|
|
1732
|
+
let parentAs;
|
|
1733
|
+
(0, pqb_internal._hookSelectColumns)(querySelf, state.primaryKeys, (aliasedPrimaryKeys) => {
|
|
1734
|
+
parentIdsSql._sql = selectCteColumnsSql(parentAs, aliasedPrimaryKeys);
|
|
1735
|
+
for (let i = 0; i < state.foreignKeys.length; i++) parentValues[i]._sql = selectCteColumnSql(parentAs, aliasedPrimaryKeys[i]);
|
|
1736
|
+
});
|
|
1737
|
+
const existingRelQuery = (0, pqb_internal._queryWhereExists)((0, pqb_internal._queryWhere)((0, pqb_internal._clone)(state.relatedTableQuery), [upsert.findBy]), state.joinTableQuery, [(q) => {
|
|
1738
|
+
for (let i = 0; i < state.throughPrimaryKeys.length; i++) (0, pqb_internal._queryJoinOn)(q, [state.throughForeignKeysFull[i], state.throughPrimaryKeysFull[i]]);
|
|
1739
|
+
return (0, pqb_internal._queryWhereIn)(q, true, state.foreignKeysFull, parentIdsSql);
|
|
1740
|
+
}]);
|
|
1741
|
+
const upsertQuery = (0, pqb_internal._querySelect)((0, pqb_internal._queryUpsert)(existingRelQuery, {
|
|
1742
|
+
update: upsert.update,
|
|
1743
|
+
create: upsert.create || {}
|
|
1744
|
+
}), state.throughPrimaryKeys);
|
|
1745
|
+
const selectAs = {};
|
|
1746
|
+
for (let i = 0; i < state.foreignKeys.length; i++) selectAs[state.foreignKeys[i]] = parentValues[i];
|
|
1747
|
+
for (let i = 0; i < state.throughForeignKeys.length; i++) selectAs[state.throughForeignKeys[i]] = relatedValues[i];
|
|
1748
|
+
const joinRows = (0, pqb_internal._querySelect)((0, pqb_internal._clone)(state.queryBuilder), [selectAs]);
|
|
1749
|
+
(0, pqb_internal._queryWhere)(joinRows, [relatedIdsSql]);
|
|
1750
|
+
const joinQuery = state.joinTableQuery.insertForEachFrom(joinRows);
|
|
1751
|
+
joinQuery.q.returnType = "void";
|
|
1752
|
+
(0, pqb_internal._appendQuery)(querySelf, (0, pqb_internal._appendQueryOnUpsertCreate)(upsertQuery, joinQuery, (as) => {
|
|
1753
|
+
relatedIdsSql._sql = `EXISTS (SELECT 1 FROM "${as}")`;
|
|
1754
|
+
for (let i = 0; i < relatedValues.length; i++) relatedValues[i]._sql = selectCteColumnSql(as, state.throughPrimaryKeys[i]);
|
|
1755
|
+
}), (as) => {
|
|
1756
|
+
parentAs = as;
|
|
1757
|
+
});
|
|
1758
|
+
};
|
|
1880
1759
|
const nestedUpdate = (state) => {
|
|
1881
1760
|
const len = state.primaryKeys.length;
|
|
1882
1761
|
const throughLen = state.throughPrimaryKeys.length;
|
|
@@ -1938,6 +1817,153 @@ const nestedUpdate = (state) => {
|
|
|
1938
1817
|
}
|
|
1939
1818
|
});
|
|
1940
1819
|
};
|
|
1820
|
+
var HasAndBelongsToManyVirtualColumn = class extends pqb_internal.VirtualColumn {
|
|
1821
|
+
constructor(joinTable, schema, key, state) {
|
|
1822
|
+
super(schema);
|
|
1823
|
+
this.joinTable = joinTable;
|
|
1824
|
+
this.key = key;
|
|
1825
|
+
this.state = state;
|
|
1826
|
+
this.nestedInsert = nestedInsert(state);
|
|
1827
|
+
this.nestedUpdate = nestedUpdate(state);
|
|
1828
|
+
}
|
|
1829
|
+
create(q, ctx, items, rowIndexes) {
|
|
1830
|
+
hasRelationHandleCreate(q, ctx, items, rowIndexes, this.key, this.state.primaryKeys, this.nestedInsert);
|
|
1831
|
+
}
|
|
1832
|
+
update(q, set) {
|
|
1833
|
+
const querySelf = q;
|
|
1834
|
+
const params = set[this.key];
|
|
1835
|
+
hasRelationHandleUpdate(querySelf, set, this.key, this.state.primaryKeys, this.nestedUpdate);
|
|
1836
|
+
if (params.upsert) {
|
|
1837
|
+
throwIfQueryReturnsAllForNestedUpdate(querySelf, { upsert: params.upsert });
|
|
1838
|
+
nestedUpdateUpsert(querySelf, this.state, params.upsert);
|
|
1839
|
+
}
|
|
1840
|
+
}
|
|
1841
|
+
};
|
|
1842
|
+
const removeColumnName = (column) => {
|
|
1843
|
+
if (!column.data.name) return column;
|
|
1844
|
+
const cloned = Object.create(column);
|
|
1845
|
+
cloned.data = {
|
|
1846
|
+
...column.data,
|
|
1847
|
+
name: void 0
|
|
1848
|
+
};
|
|
1849
|
+
return cloned;
|
|
1850
|
+
};
|
|
1851
|
+
const makeHasAndBelongsToManyMethod = (tableConfig, table, qb, relation, relationName, query, schema) => {
|
|
1852
|
+
const { options } = relation;
|
|
1853
|
+
const { snakeCase } = table.internal;
|
|
1854
|
+
const primaryKeys = options.columns;
|
|
1855
|
+
const originalForeignKeys = options.references;
|
|
1856
|
+
const foreignKeys = snakeCase ? [...originalForeignKeys] : originalForeignKeys;
|
|
1857
|
+
const joinTable = snakeCase && options.through.snakeCase !== false ? (0, pqb_internal.toSnakeCase)(options.through.table) : options.through.table;
|
|
1858
|
+
const originalThroughForeignKeys = options.through.columns;
|
|
1859
|
+
const throughForeignKeys = snakeCase ? [...originalThroughForeignKeys] : originalThroughForeignKeys;
|
|
1860
|
+
const throughPrimaryKeys = options.through.references;
|
|
1861
|
+
const { on } = options;
|
|
1862
|
+
if (on) {
|
|
1863
|
+
(0, pqb_internal._queryWhere)(query, [on]);
|
|
1864
|
+
(0, pqb_internal._queryDefaults)(query, on);
|
|
1865
|
+
}
|
|
1866
|
+
const foreignKeysFull = foreignKeys.map((key, i) => {
|
|
1867
|
+
if (snakeCase) key = foreignKeys[i] = (0, pqb_internal.toSnakeCase)(key);
|
|
1868
|
+
return `${joinTable}.${key}`;
|
|
1869
|
+
});
|
|
1870
|
+
const throughForeignKeysFull = throughForeignKeys.map((key, i) => {
|
|
1871
|
+
if (snakeCase) key = throughForeignKeys[i] = (0, pqb_internal.toSnakeCase)(key);
|
|
1872
|
+
return `${joinTable}.${key}`;
|
|
1873
|
+
});
|
|
1874
|
+
const foreignTable = (0, pqb_internal.getQueryAs)(query);
|
|
1875
|
+
const throughPrimaryKeysFull = throughPrimaryKeys.map((key) => `${foreignTable}.${key}`);
|
|
1876
|
+
const len = primaryKeys.length;
|
|
1877
|
+
const throughLen = throughPrimaryKeys.length;
|
|
1878
|
+
const baseQuery = Object.create(qb.baseQuery);
|
|
1879
|
+
baseQuery.baseQuery = baseQuery;
|
|
1880
|
+
baseQuery.table = joinTable;
|
|
1881
|
+
const shape = {};
|
|
1882
|
+
const primaryKeysShape = {};
|
|
1883
|
+
for (let i = 0; i < len; i++) {
|
|
1884
|
+
const pk = primaryKeys[i];
|
|
1885
|
+
shape[foreignKeys[i]] = removeColumnName(table.shape[pk]);
|
|
1886
|
+
primaryKeysShape[pk] = table.shape[pk];
|
|
1887
|
+
}
|
|
1888
|
+
for (let i = 0; i < throughLen; i++) shape[throughForeignKeys[i]] = removeColumnName(query.shape[throughPrimaryKeys[i]]);
|
|
1889
|
+
baseQuery.shape = shape;
|
|
1890
|
+
baseQuery.q = {
|
|
1891
|
+
...baseQuery.q,
|
|
1892
|
+
schema: options.through.schema || schema,
|
|
1893
|
+
shape: baseQuery.shape
|
|
1894
|
+
};
|
|
1895
|
+
const subQuery = Object.create(baseQuery);
|
|
1896
|
+
addAutoForeignKey(tableConfig, subQuery, table, primaryKeys, foreignKeys, relation.options, originalForeignKeys);
|
|
1897
|
+
addAutoForeignKey(tableConfig, subQuery, query, throughPrimaryKeys, throughForeignKeys, relation.options.through, originalThroughForeignKeys);
|
|
1898
|
+
const state = {
|
|
1899
|
+
queryBuilder: qb,
|
|
1900
|
+
relatedTableQuery: query,
|
|
1901
|
+
joinTableQuery: subQuery,
|
|
1902
|
+
primaryKeys,
|
|
1903
|
+
foreignKeys,
|
|
1904
|
+
throughForeignKeys,
|
|
1905
|
+
throughPrimaryKeys,
|
|
1906
|
+
foreignKeysFull,
|
|
1907
|
+
throughForeignKeysFull,
|
|
1908
|
+
throughPrimaryKeysFull,
|
|
1909
|
+
primaryKeysShape,
|
|
1910
|
+
on
|
|
1911
|
+
};
|
|
1912
|
+
const joinQuery = (joiningQuery, tableAs, foreignAs, joinedShapes) => {
|
|
1913
|
+
const cloned = joiningQuery.clone();
|
|
1914
|
+
cloned.q.joinedShapes = joinedShapes;
|
|
1915
|
+
return (0, pqb_internal._queryWhereExists)(cloned, subQuery, [(q) => {
|
|
1916
|
+
for (let i = 0; i < throughLen; i++) (0, pqb_internal._queryJoinOn)(q, [throughForeignKeysFull[i], `${foreignAs}.${throughPrimaryKeys[i]}`]);
|
|
1917
|
+
for (let i = 0; i < len; i++) (0, pqb_internal._queryJoinOn)(q, [foreignKeysFull[i], `${tableAs}.${primaryKeys[i]}`]);
|
|
1918
|
+
return q;
|
|
1919
|
+
}]);
|
|
1920
|
+
};
|
|
1921
|
+
const obj = {};
|
|
1922
|
+
for (let i = 0; i < len; i++) obj[foreignKeys[i]] = primaryKeys[i];
|
|
1923
|
+
const selectPrimaryKeysAsForeignKeys = [{ selectAs: obj }];
|
|
1924
|
+
const reverseJoin = (baseQuery, joiningQuery) => {
|
|
1925
|
+
const foreignAs = (0, pqb_internal.getQueryAs)(joiningQuery);
|
|
1926
|
+
return joinQuery(baseQuery, (0, pqb_internal.getQueryAs)(baseQuery), foreignAs, {
|
|
1927
|
+
...baseQuery.q.joinedShapes,
|
|
1928
|
+
[foreignAs]: joiningQuery.q.selectShape
|
|
1929
|
+
});
|
|
1930
|
+
};
|
|
1931
|
+
return {
|
|
1932
|
+
returns: "many",
|
|
1933
|
+
queryRelated(params) {
|
|
1934
|
+
const q = query.whereExists(subQuery, (q) => {
|
|
1935
|
+
q = q.clone();
|
|
1936
|
+
const where = {};
|
|
1937
|
+
for (let i = 0; i < len; i++) where[foreignKeysFull[i]] = params[primaryKeys[i]];
|
|
1938
|
+
for (let i = 0; i < throughLen; i++) (0, pqb_internal._queryJoinOn)(q, [throughForeignKeysFull[i], throughPrimaryKeysFull[i]]);
|
|
1939
|
+
return (0, pqb_internal._queryWhere)(q, [where]);
|
|
1940
|
+
});
|
|
1941
|
+
return on ? (0, pqb_internal._queryDefaults)(q, on) : q;
|
|
1942
|
+
},
|
|
1943
|
+
virtualColumn: new HasAndBelongsToManyVirtualColumn(subQuery, pqb_internal.internalSchemaConfig, relationName, state),
|
|
1944
|
+
joinQuery: joinQueryChainHOF((0, pqb_internal.getPrimaryKeys)(query), reverseJoin, (joiningQuery, baseQuery) => joinQuery(joiningQuery, (0, pqb_internal.getQueryAs)(baseQuery), (0, pqb_internal.getQueryAs)(joiningQuery), {
|
|
1945
|
+
...joiningQuery.q.joinedShapes,
|
|
1946
|
+
[baseQuery.q.as || baseQuery.table]: baseQuery.q.selectShape
|
|
1947
|
+
})),
|
|
1948
|
+
reverseJoin,
|
|
1949
|
+
modifyRelatedQuery(relationQuery) {
|
|
1950
|
+
const ref = {};
|
|
1951
|
+
(0, pqb_internal._queryHookAfterCreate)(relationQuery, [], async (result) => {
|
|
1952
|
+
const baseQuery = ref.q.clone();
|
|
1953
|
+
baseQuery.q.select = selectPrimaryKeysAsForeignKeys;
|
|
1954
|
+
const data = result.map((resultRow) => {
|
|
1955
|
+
const dataRow = {};
|
|
1956
|
+
for (let i = 0; i < throughLen; i++) dataRow[throughForeignKeys[i]] = resultRow[throughPrimaryKeys[i]];
|
|
1957
|
+
return dataRow;
|
|
1958
|
+
});
|
|
1959
|
+
if (await (0, pqb_internal._queryCreateManyFrom)(subQuery.count(), baseQuery, data) === 0) throw new pqb.NotFoundError(baseQuery);
|
|
1960
|
+
});
|
|
1961
|
+
return (q) => {
|
|
1962
|
+
ref.q = q;
|
|
1963
|
+
};
|
|
1964
|
+
}
|
|
1965
|
+
};
|
|
1966
|
+
};
|
|
1941
1967
|
const applyRelations = (qb, tables, result, schema) => {
|
|
1942
1968
|
const tableEntries = Object.entries(tables);
|
|
1943
1969
|
const delayedRelations = /* @__PURE__ */ new Map();
|