orchid-orm 1.77.0 → 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.mjs 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 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,127 +797,68 @@ const wrapQuery = (joiningQuery, result, item) => {
783
797
  result.q.returnsOne = true;
784
798
  return result.wrap(outer);
785
799
  };
786
- var BelongsToVirtualColumn = class extends VirtualColumn {
787
- constructor(schema, key, state) {
788
- super(schema);
789
- this.key = key;
790
- this.state = state;
791
- this.nestedUpdate = nestedUpdate$2(this.state);
792
- }
793
- create(q, ctx, items) {
794
- const queryForCreate = q;
795
- const { key, state: { query, primaryKeys, foreignKeys } } = this;
796
- let nestedCreateItems;
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 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 RawSql("");
818
- _onUpsertUpdate(queryForCreate, (as) => {
819
- createWhereNotExists._sql = `NOT EXISTS (SELECT 1 FROM "${as}")`;
820
- });
821
- createQuery = _queryInsertManyFrom(selectPKeys, _queryWhere(_queryTake(_querySelect(_clone(query.qb), [{}])), [createWhereNotExists]), create.values);
822
- } else createQuery = _queryInsertMany(selectPKeys, create.values);
823
- const setForeignKeys = (as) => {
824
- const count = create.items.length;
825
- foreignKeys.forEach((foreignKey, i) => {
826
- const primaryKey = primaryKeys[i];
827
- create.items.forEach((item, i) => {
828
- item[foreignKey]._sql = selectCteColumnFromManySql(as, primaryKey, i, count);
829
- });
830
- });
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: []
831
811
  };
832
- if (queryForCreate.q.type === "upsert") _prependWithOnUpsertCreate(queryForCreate, setForeignKeys, createQuery);
833
- else _prependWith(queryForCreate, setForeignKeys, createQuery);
834
- }
835
- if (connect) connect.values.forEach((value, itemI) => {
836
- const as = getFreeAlias(queryForCreate.q.withShapes, "q");
837
- (queryForCreate.q.type === "upsert" ? _prependWithOnUpsertCreate : _prependWith)(queryForCreate, as, query.select(...primaryKeys).findBy(value));
838
- foreignKeys.map((foreignKey, i) => {
839
- connect.items[itemI][foreignKey] = new RawSql(selectCteColumnMustExistSql(i, as, primaryKeys[i]));
812
+ nestedCreateItem.items.push(item);
813
+ nestedCreateItem.values.push(value[kind]);
814
+ if (kind !== "connect") for (const key of foreignKeys) item[key] = new 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 RawSql("");
825
+ _onUpsertUpdate(queryForCreate, (as) => {
826
+ createWhereNotExists._sql = `NOT EXISTS (SELECT 1 FROM "${as}")`;
840
827
  });
841
- });
842
- if (connectOrCreate) connectOrCreate.values.forEach((value, itemI) => {
843
- const asFn = setForeignKeysFromCte(connectOrCreate.items[itemI], primaryKeys, foreignKeys);
844
- const selectPKeys = query.select(...primaryKeys);
845
- (queryForCreate.q.type === "upsert" ? _prependWithOnUpsertCreate : _prependWith)(queryForCreate, asFn, _orCreate(_queryWhere(selectPKeys, [value.where]), value.create));
846
- });
847
- }
848
- update(q, set) {
849
- const queryForUpdate = q;
850
- queryForUpdate.q.wrapInTransaction = true;
851
- const data = set[this.key];
852
- this.nestedUpdate(queryForUpdate, set, data);
828
+ const sourceQuery = _queryWhere(_queryTake(_querySelect(_clone(query.qb), [{}])), [createWhereNotExists]);
829
+ createQuery = _queryInsertManyFrom(selectPKeys, sourceQuery, create.values);
830
+ } else createQuery = _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") _prependWithOnUpsertCreate(queryForCreate, setForeignKeys, createQuery);
841
+ else _prependWith(queryForCreate, setForeignKeys, createQuery);
853
842
  }
854
- };
855
- const getBelongsToRequired = (tableConfig, relatedTableConfig, relation) => {
856
- const { required } = relation.options;
857
- if (typeof required === "boolean") return required;
858
- if (relatedTableConfig.softDelete) return false;
859
- return relation.options.columns.every((key) => {
860
- return !tableConfig.columns.shape[key].data.isNullable;
843
+ if (connect) connect.values.forEach((value, itemI) => {
844
+ const as = getFreeAlias(queryForCreate.q.withShapes, "q");
845
+ (queryForCreate.q.type === "upsert" ? _prependWithOnUpsertCreate : _prependWith)(queryForCreate, as, query.select(...primaryKeys).findBy(value));
846
+ foreignKeys.map((foreignKey, i) => {
847
+ connect.items[itemI][foreignKey] = new 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" ? _prependWithOnUpsertCreate : _prependWith)(queryForCreate, asFn, _orCreate(_queryWhere(selectPKeys, [value.where]), value.create));
861
854
  });
862
- };
863
- const makeBelongsToMethod = (tableConfig, table, relation, relationName, query) => {
864
- const primaryKeys = relation.options.references;
865
- const foreignKeys = relation.options.columns;
866
- const { on } = relation.options;
867
- if (on) {
868
- _queryWhere(query, [on]);
869
- _queryDefaults(query, on);
870
- }
871
- const len = primaryKeys.length;
872
- const state = {
873
- query,
874
- primaryKeys,
875
- foreignKeys,
876
- len,
877
- on
878
- };
879
- addAutoForeignKey(tableConfig, table, query, primaryKeys, foreignKeys, relation.options);
880
- const join = (baseQuery, joiningQuery, primaryKeys, foreignKeys) => {
881
- const baseAs = getQueryAs(baseQuery);
882
- const q = joiningQuery.clone();
883
- setQueryObjectValueImmutable(q, "joinedShapes", baseAs, baseQuery.q.selectShape);
884
- for (let i = 0; i < len; i++) pushQueryOnForOuter(q, baseQuery, joiningQuery, primaryKeys[i], `${baseAs}.${foreignKeys[i]}`);
885
- return q;
886
- };
887
- const reverseJoin = (baseQuery, joiningQuery) => {
888
- return join(joiningQuery, baseQuery, foreignKeys, primaryKeys);
889
- };
890
- return {
891
- returns: "one",
892
- queryRelated(params) {
893
- const obj = {};
894
- for (let i = 0; i < len; i++) obj[primaryKeys[i]] = params[foreignKeys[i]];
895
- return query.where(obj);
896
- },
897
- virtualColumn: new BelongsToVirtualColumn(internalSchemaConfig, relationName, state),
898
- joinQuery: joinQueryChainHOF(getPrimaryKeys(query), reverseJoin, (joiningQuery, baseQuery) => join(baseQuery, joiningQuery, primaryKeys, foreignKeys)),
899
- reverseJoin
900
- };
901
855
  };
902
856
  const nestedUpdate$2 = ({ query, primaryKeys, foreignKeys, len }) => {
903
857
  return ((self, update, params) => {
904
858
  if (params.create) {
905
859
  const createQuery = _querySelect(_queryCreate(query.clone(), params.create), primaryKeys);
906
- _prependWith(self, setForeignKeysFromCte(update, primaryKeys, foreignKeys), createQuery);
860
+ const asFn = setForeignKeysFromCte(update, primaryKeys, foreignKeys);
861
+ _prependWith(self, asFn, createQuery);
907
862
  } else if (params.update) {
908
863
  let appendedAs;
909
864
  _hookSelectColumns(self, foreignKeys, (aliasedForeignKeys) => {
@@ -917,7 +872,8 @@ const nestedUpdate$2 = ({ query, primaryKeys, foreignKeys, len }) => {
917
872
  if (isQueryReturnsAll(self)) throw new Error("`upsert` option is not allowed in a batch update");
918
873
  const { relQuery } = relWithSelectIds(self, query, primaryKeys, foreignKeys);
919
874
  const upsertQuery = _querySelect(_queryUpsert(relQuery, params.upsert), primaryKeys);
920
- _prependWith(self, setForeignKeysFromCte(update, primaryKeys, foreignKeys), upsertQuery);
875
+ const asFn = setForeignKeysFromCte(update, primaryKeys, foreignKeys);
876
+ _prependWith(self, asFn, upsertQuery);
921
877
  } else if (params.delete) {
922
878
  _hookSelectColumns(self, foreignKeys, noop);
923
879
  disconnect(update, foreignKeys);
@@ -939,7 +895,10 @@ const nestedUpdate$2 = ({ query, primaryKeys, foreignKeys, len }) => {
939
895
  (loadForeignKeys ??= []).push(foreignKeys[i]);
940
896
  }
941
897
  }
942
- if (loadPrimaryKeys) _prependWith(self, setForeignKeysFromCte(update, loadPrimaryKeys, loadForeignKeys, true), _queryFindBy(query.select(...loadPrimaryKeys), params.set));
898
+ if (loadPrimaryKeys) {
899
+ const asFn = setForeignKeysFromCte(update, loadPrimaryKeys, loadForeignKeys, true);
900
+ _prependWith(self, asFn, _queryFindBy(query.select(...loadPrimaryKeys), params.set));
901
+ }
943
902
  }
944
903
  });
945
904
  };
@@ -965,237 +924,68 @@ const makeSelectIdsQuery = (self, foreignKeys) => {
965
924
  selectIdsQuery.q.or = self.q.or;
966
925
  return selectIdsQuery;
967
926
  };
968
- const setForeignKeysFromCte = (record, primaryKeys, foreignKeys, mustExist) => {
969
- for (const key of foreignKeys) record[key] = new RawSql("");
970
- return (as) => {
971
- foreignKeys.forEach(mustExist ? (foreignKey, i) => {
972
- record[foreignKey]._sql = selectCteColumnMustExistSql(i, as, primaryKeys[i]);
973
- } : (foreignKey, i) => {
974
- record[foreignKey]._sql = selectCteColumnSql$1(as, primaryKeys[i]);
975
- });
976
- };
977
- };
978
- const selectCteColumnMustExistSql = (i, cteAs, column) => {
979
- const selectColumn = selectCteColumnSql$1(cteAs, column);
980
- return i === 0 ? `CASE WHEN (SELECT count(*) FROM "${cteAs}") = 0 AND (SELECT 'not-found')::int = 0 THEN NULL ELSE ${selectColumn} END` : selectColumn;
981
- };
982
- var HasOneVirtualColumn = class extends VirtualColumn {
927
+ var BelongsToVirtualColumn = class extends VirtualColumn {
983
928
  constructor(schema, key, state) {
984
929
  super(schema);
985
930
  this.key = key;
986
931
  this.state = state;
987
- this.nestedInsert = nestedInsert$2(state);
988
- this.setNulls = {};
989
- for (const foreignKey of state.foreignKeys) this.setNulls[foreignKey] = null;
932
+ this.nestedUpdate = nestedUpdate$2(this.state);
990
933
  }
991
- create(self, ctx, items, rowIndexes, count) {
992
- const querySelf = self;
993
- if (count <= querySelf.qb.internal.nestedCreateBatchMax) {
994
- const { query: rel, primaryKeys, foreignKeys } = this.state;
995
- let nestedCreateItems;
996
- items.forEach((item, i) => {
997
- const value = item[this.key];
998
- const kind = value.create ? "create" : value.connect ? "connect" : "connectOrCreate";
999
- if (kind) {
1000
- const nestedCreateItem = (nestedCreateItems ??= {})[kind] ??= {
1001
- indexes: [],
1002
- items: [],
1003
- values: []
1004
- };
1005
- nestedCreateItem.indexes.push(rowIndexes[i]);
1006
- nestedCreateItem.values.push(value[kind]);
1007
- const data = value.create ? { ...value.create } : {};
1008
- for (const key of foreignKeys) data[key] = new RawSql("");
1009
- nestedCreateItem.items.push(data);
1010
- }
1011
- });
1012
- if (!nestedCreateItems) return;
1013
- let createAs;
1014
- let createWhereExists;
1015
- let createSelectAs;
1016
- let createAliasedPrimaryKeys;
1017
- let upsertCreateAs;
1018
- let connectAs;
1019
- let connectOrCreateAs;
1020
- const setUpsertCreatePlaceholders = () => {
1021
- if (!upsertCreateAs || !createAliasedPrimaryKeys) return;
1022
- const aliasedPrimaryKeys = createAliasedPrimaryKeys;
1023
- if (createWhereExists) createWhereExists._sql = `EXISTS (SELECT 1 FROM "${upsertCreateAs}")`;
1024
- if (createSelectAs) foreignKeys.forEach((key, keyI) => {
1025
- createSelectAs[key]._sql = selectCteColumnFromManySql(upsertCreateAs, aliasedPrimaryKeys[keyI], 0, 1);
1026
- });
1027
- if (connect) foreignKeys.forEach((key, keyI) => {
1028
- const primaryKey = aliasedPrimaryKeys[keyI];
1029
- for (let i = 0; i < connect.items.length; i++) connect.items[i][key]._sql = selectCteColumnFromManySql(upsertCreateAs, primaryKey, connect.indexes[i], count);
1030
- });
1031
- if (connectOrCreate) foreignKeys.forEach((key, keyI) => {
1032
- const primaryKey = aliasedPrimaryKeys[keyI];
1033
- for (let i = 0; i < connectOrCreate.items.length; i++) connectOrCreate.items[i][key]._sql = selectCteColumnFromManySql(upsertCreateAs, primaryKey, connectOrCreate.indexes[i], count);
1034
- });
1035
- };
1036
- _hookSelectColumns(querySelf, primaryKeys, (aliasedPrimaryKeys) => {
1037
- createAliasedPrimaryKeys = aliasedPrimaryKeys;
1038
- foreignKeys.forEach((key, keyI) => {
1039
- const primaryKey = aliasedPrimaryKeys[keyI];
1040
- if (create && createAs) for (let i = 0; i < create.items.length; i++) create.items[i][key]._sql = selectCteColumnFromManySql(createAs, primaryKey, create.indexes[i], count);
1041
- if (connect && connectAs) for (let i = 0; i < connect.items.length; i++) connect.items[i][key]._sql = selectCteColumnFromManySql(connectAs, primaryKey, connect.indexes[i], count);
1042
- if (connectOrCreate && connectOrCreateAs) for (let i = 0; i < connectOrCreate.items.length; i++) connectOrCreate.items[i][key]._sql = selectCteColumnFromManySql(connectOrCreateAs, primaryKey, connectOrCreate.indexes[i], count);
1043
- });
1044
- setUpsertCreatePlaceholders();
1045
- });
1046
- const { create, connect, connectOrCreate } = nestedCreateItems;
1047
- if (create) {
1048
- let query;
1049
- if (querySelf.q.type === "upsert") {
1050
- createWhereExists = new RawSql("");
1051
- createSelectAs = {};
1052
- for (const key of foreignKeys) createSelectAs[key] = new RawSql("");
1053
- const sourceQuery = _queryWhere(_queryTake(_querySelect(_clone(rel.qb), [createSelectAs])), [createWhereExists]);
1054
- query = _queryInsertManyFrom(_clone(rel), sourceQuery, create.items);
1055
- } else query = _queryInsertMany(_clone(rel), create.items);
1056
- if (querySelf.q.type === "upsert") _appendQueryOnUpsertCreate(querySelf, query, (as) => {
1057
- upsertCreateAs = as;
1058
- setUpsertCreatePlaceholders();
1059
- });
1060
- else _appendQuery(querySelf, query, (as) => createAs = as);
1061
- }
1062
- if (connect) connect.values.forEach((value, i) => {
1063
- const connectWhereExists = querySelf.q.type === "upsert" ? new RawSql("") : void 0;
1064
- const query = _queryUpdateOrThrow(rel.where(value), connect.items[i]);
1065
- if (connectWhereExists) _queryWhere(query, [connectWhereExists]);
1066
- query.q.ensureCount = 1;
1067
- (querySelf.q.type === "upsert" ? _appendQueryOnUpsertCreate : _appendQuery)(querySelf, query, (as) => {
1068
- upsertCreateAs = as;
1069
- setUpsertCreatePlaceholders();
1070
- connectAs = as;
1071
- if (connectWhereExists) connectWhereExists._sql = `EXISTS (SELECT 1 FROM "${as}")`;
1072
- });
1073
- });
1074
- if (connectOrCreate) connectOrCreate.values.forEach((value, i) => {
1075
- const foreignKeyValues = connectOrCreate.items[i];
1076
- const connectOrCreateWhereExists = querySelf.q.type === "upsert" ? new RawSql("") : void 0;
1077
- const connectOrCreateSelectAs = {};
1078
- if (connectOrCreateWhereExists) for (const key of foreignKeys) {
1079
- const value = foreignKeyValues[key];
1080
- value.result = { value: rel.qb.shape[key] };
1081
- connectOrCreateSelectAs[key] = value;
1082
- }
1083
- const query = _queryUpsert(rel.where(value.where), {
1084
- update: foreignKeyValues,
1085
- create: {
1086
- ...value.create,
1087
- ...foreignKeyValues
1088
- }
1089
- });
1090
- if (connectOrCreateWhereExists) {
1091
- _queryWhere(query, [connectOrCreateWhereExists]);
1092
- const guardQuery = _queryWhere(_queryTake(_querySelect(_clone(rel.qb), [{ one: new RawSql("1") }])), [connectOrCreateWhereExists]);
1093
- const sourceQuery = _querySelect(_clone(rel.qb).from(guardQuery), [connectOrCreateSelectAs]);
1094
- const q = query.q;
1095
- const columns = q.columns || [];
1096
- const foreignKeysSet = new Set(foreignKeys);
1097
- q.columns = [...foreignKeys, ...columns.filter((column) => !foreignKeysSet.has(column))];
1098
- q.values = q.values.map((row) => row.filter((_, i) => !foreignKeysSet.has(columns[i])));
1099
- q.queryColumnsCount = foreignKeys.length;
1100
- q.insertFrom = prepareSubQueryForSql(query, sourceQuery);
1101
- }
1102
- (querySelf.q.type === "upsert" ? _appendQueryOnUpsertCreate : _appendQuery)(querySelf, query, (as) => {
1103
- upsertCreateAs = as;
1104
- setUpsertCreatePlaceholders();
1105
- connectOrCreateAs = as;
1106
- if (connectOrCreateWhereExists) connectOrCreateWhereExists._sql = `EXISTS (SELECT 1 FROM "${as}")`;
1107
- });
1108
- });
1109
- } 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);
1110
936
  }
1111
- update(self, set) {
1112
- const querySelf = self;
1113
- const params = set[this.key];
1114
- throwIfQueryReturnsAllForNestedUpdate(querySelf, params);
1115
- const { primaryKeys, foreignKeys, query: relQuery } = this.state;
1116
- if (params.create || params.update || params.upsert || params.disconnect || params.set || params.delete) {
1117
- const ids = makeNestedUpdateRelationIds(querySelf, relQuery, primaryKeys, foreignKeys);
1118
- const nullifyOrDeleteQuery = params.update ? _queryUpdate(ids.existingRelQuery, params.update) : params.upsert ? _queryUpsert(ids.existingRelQuery, makeNestedUpdateUpsertData(params.upsert, ids.setIds)) : params.delete ? _queryDelete(ids.existingRelQuery) : _queryUpdate(ids.existingRelQuery, this.setNulls);
1119
- nullifyOrDeleteQuery.q.returnType = "void";
1120
- _appendQuery(querySelf, nullifyOrDeleteQuery, ids.setAppendedAs);
1121
- if (params.create) _appendQuery(querySelf, _queryInsert(_clone(relQuery), {
1122
- ...params.create,
1123
- ...ids.setIds
1124
- }), noop);
1125
- else if (params.set) {
1126
- const setQuery = _queryUpdate(_queryWhere(_clone(relQuery), [params.set]), ids.setIds);
1127
- setQuery.q.returnType = "void";
1128
- _appendQuery(querySelf, setQuery, noop);
1129
- }
1130
- }
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);
1131
942
  }
1132
943
  };
1133
- const makeHasOneMethod = (tableConfig, table, relation, relationName, query) => {
1134
- const relPKeys = getPrimaryKeys(query);
1135
- if ("through" in relation.options) {
1136
- const { through, source, on } = relation.options;
1137
- if (on) _queryWhere(query, [on]);
1138
- const throughRelation = getThroughRelation(table, through);
1139
- const sourceRelation = getSourceRelation(throughRelation, source);
1140
- const sourceRelationQuery = sourceRelation.query.as(relationName);
1141
- const sourceQuery = sourceRelation.joinQuery(sourceRelationQuery, throughRelation.query);
1142
- const whereExistsCallback = () => sourceQuery;
1143
- const reverseJoin = (baseQuery, joiningQuery) => {
1144
- return joinHasThrough(baseQuery, baseQuery, joiningQuery, throughRelation, sourceRelation);
1145
- };
1146
- return {
1147
- returns: "one",
1148
- queryRelated: (params) => {
1149
- const throughQuery = table.queryRelated(through, params);
1150
- return query.whereExists(throughQuery, whereExistsCallback);
1151
- },
1152
- joinQuery: joinQueryChainHOF(relPKeys, reverseJoin, (joiningQuery, baseQuery) => joinHasThrough(joiningQuery, baseQuery, joiningQuery, throughRelation, sourceRelation)),
1153
- reverseJoin
1154
- };
1155
- }
1156
- const primaryKeys = relation.options.columns;
1157
- 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;
1158
955
  const { on } = relation.options;
1159
956
  if (on) {
1160
957
  _queryWhere(query, [on]);
1161
958
  _queryDefaults(query, on);
1162
959
  }
1163
- addAutoForeignKey(tableConfig, query, table, primaryKeys, foreignKeys, relation.options);
960
+ const len = primaryKeys.length;
1164
961
  const state = {
1165
962
  query,
1166
963
  primaryKeys,
1167
964
  foreignKeys,
965
+ len,
1168
966
  on
1169
967
  };
1170
- const len = primaryKeys.length;
1171
- const reversedOn = {};
1172
- for (let i = 0; i < len; i++) reversedOn[foreignKeys[i]] = primaryKeys[i];
1173
- const fromQuerySelect = [{ selectAs: reversedOn }];
968
+ addAutoForeignKey(tableConfig, table, query, primaryKeys, foreignKeys, relation.options);
969
+ const join = (baseQuery, joiningQuery, primaryKeys, foreignKeys) => {
970
+ const baseAs = getQueryAs(baseQuery);
971
+ const q = joiningQuery.clone();
972
+ setQueryObjectValueImmutable(q, "joinedShapes", baseAs, baseQuery.q.selectShape);
973
+ for (let i = 0; i < len; i++) pushQueryOnForOuter(q, baseQuery, joiningQuery, primaryKeys[i], `${baseAs}.${foreignKeys[i]}`);
974
+ return q;
975
+ };
1174
976
  const reverseJoin = (baseQuery, joiningQuery) => {
1175
- return joinHasRelation(joiningQuery, baseQuery, foreignKeys, primaryKeys, len);
977
+ return join(joiningQuery, baseQuery, foreignKeys, primaryKeys);
1176
978
  };
1177
979
  return {
1178
980
  returns: "one",
1179
- queryRelated: (params) => {
1180
- const values = {};
1181
- for (let i = 0; i < len; i++) values[foreignKeys[i]] = params[primaryKeys[i]];
1182
- return _queryDefaults(query.where(values), {
1183
- ...on,
1184
- ...values
1185
- });
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);
1186
985
  },
1187
- virtualColumn: new HasOneVirtualColumn(internalSchemaConfig, relationName, state),
1188
- joinQuery: joinQueryChainHOF(relPKeys, reverseJoin, (joiningQuery, baseQuery) => joinHasRelation(baseQuery, joiningQuery, primaryKeys, foreignKeys, len)),
1189
- reverseJoin,
1190
- modifyRelatedQuery(relationQuery) {
1191
- return (query) => {
1192
- const baseQuery = query.clone();
1193
- baseQuery.q.select = fromQuerySelect;
1194
- const q = relationQuery.q;
1195
- q.insertFrom = prepareSubQueryForSql(q, baseQuery);
1196
- q.values = [];
1197
- };
1198
- }
986
+ virtualColumn: new BelongsToVirtualColumn(internalSchemaConfig, relationName, state),
987
+ joinQuery: joinQueryChainHOF(getPrimaryKeys(query), reverseJoin, (joiningQuery, baseQuery) => join(baseQuery, joiningQuery, primaryKeys, foreignKeys)),
988
+ reverseJoin
1199
989
  };
1200
990
  };
1201
991
  const nestedInsert$2 = ({ query, primaryKeys, foreignKeys }) => {
@@ -1231,192 +1021,189 @@ const nestedInsert$2 = ({ query, primaryKeys, foreignKeys }) => {
1231
1021
  }
1232
1022
  });
1233
1023
  };
1234
- var HasManyVirtualColumn = class extends VirtualColumn {
1235
- constructor(schema, key, state) {
1236
- super(schema);
1237
- this.key = key;
1238
- this.state = state;
1239
- this.nestedInsert = nestedInsert$1(state);
1240
- this.nestedUpdate = nestedUpdate$1(state);
1241
- this.setNulls = {};
1242
- for (const foreignKey of state.foreignKeys) this.setNulls[foreignKey] = null;
1243
- }
1244
- create(self, ctx, items, rowIndexes, count) {
1245
- const querySelf = self;
1246
- if (count <= querySelf.qb.internal.nestedCreateBatchMax) {
1247
- const { query: rel, primaryKeys, foreignKeys } = this.state;
1248
- let nestedCreateItems;
1249
- items.forEach((item, i) => {
1250
- const value = item[this.key];
1251
- if (value.create?.length) {
1252
- const nestedCreateItem = (nestedCreateItems ??= {}).create ??= {
1253
- indexes: [],
1254
- items: []
1255
- };
1256
- nestedCreateItem.indexes.push(rowIndexes[i]);
1257
- const data = value.create.map((obj) => {
1258
- const data = { ...obj };
1259
- for (const key of foreignKeys) data[key] = new RawSql("");
1260
- return data;
1261
- });
1262
- nestedCreateItem.items.push(data);
1263
- } else {
1264
- const kind = value.connect?.length ? "connect" : value.connectOrCreate?.length ? "connectOrCreate" : void 0;
1265
- if (kind) {
1266
- const nestedCreateItem = (nestedCreateItems ??= {})[kind] ??= {
1267
- indexes: [],
1268
- items: [],
1269
- values: []
1270
- };
1271
- nestedCreateItem.indexes.push(rowIndexes[i]);
1272
- nestedCreateItem.values.push(value[kind]);
1273
- const data = {};
1274
- for (const key of foreignKeys) data[key] = new RawSql("");
1275
- nestedCreateItem.items.push(data);
1276
- }
1277
- }
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 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);
1278
1059
  });
1279
- if (!nestedCreateItems) return;
1280
- let createAs;
1281
- let createWhereExists;
1282
- let createSelectAs;
1283
- let createAliasedPrimaryKeys;
1284
- let upsertCreateAs;
1285
- let connectAs;
1286
- let connectOrCreateAs;
1287
- const setUpsertCreatePlaceholders = () => {
1288
- if (!upsertCreateAs || !createAliasedPrimaryKeys) return;
1289
- const aliasedPrimaryKeys = createAliasedPrimaryKeys;
1290
- if (createWhereExists) createWhereExists._sql = `EXISTS (SELECT 1 FROM "${upsertCreateAs}")`;
1291
- if (createSelectAs) foreignKeys.forEach((key, keyI) => {
1292
- createSelectAs[key]._sql = selectCteColumnFromManySql(upsertCreateAs, aliasedPrimaryKeys[keyI], 0, 1);
1293
- });
1294
- if (connect) foreignKeys.forEach((key, keyI) => {
1295
- const primaryKey = aliasedPrimaryKeys[keyI];
1296
- for (let i = 0; i < connect.items.length; i++) connect.items[i][key]._sql = selectCteColumnFromManySql(upsertCreateAs, primaryKey, connect.indexes[i], count);
1297
- });
1298
- if (connectOrCreate) foreignKeys.forEach((key, keyI) => {
1299
- const primaryKey = aliasedPrimaryKeys[keyI];
1300
- for (let i = 0; i < connectOrCreate.items.length; i++) connectOrCreate.items[i][key]._sql = selectCteColumnFromManySql(upsertCreateAs, primaryKey, connectOrCreate.indexes[i], count);
1301
- });
1302
- };
1303
- _hookSelectColumns(querySelf, primaryKeys, (aliasedPrimaryKeys) => {
1304
- createAliasedPrimaryKeys = aliasedPrimaryKeys;
1305
- foreignKeys.forEach((key, keyI) => {
1306
- const primaryKey = aliasedPrimaryKeys[keyI];
1307
- if (create && createAs) for (let i = 0; i < create.items.length; i++) {
1308
- const sql = selectCteColumnFromManySql(createAs, primaryKey, create.indexes[i], count);
1309
- for (const item of create.items[i]) item[key]._sql = sql;
1310
- }
1311
- if (connect && connectAs) for (let i = 0; i < connect.items.length; i++) connect.items[i][key]._sql = selectCteColumnFromManySql(connectAs, primaryKey, connect.indexes[i], count);
1312
- if (connectOrCreate && connectOrCreateAs) for (let i = 0; i < connectOrCreate.items.length; i++) connectOrCreate.items[i][key]._sql = selectCteColumnFromManySql(connectOrCreateAs, primaryKey, connectOrCreate.indexes[i], count);
1313
- });
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
+ _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 RawSql("");
1084
+ createSelectAs = {};
1085
+ for (const key of foreignKeys) createSelectAs[key] = new RawSql("");
1086
+ const sourceQuery = _queryWhere(_queryTake(_querySelect(_clone(rel.qb), [createSelectAs])), [createWhereExists]);
1087
+ query = _queryInsertManyFrom(_clone(rel), sourceQuery, create.items);
1088
+ } else query = _queryInsertMany(_clone(rel), create.items);
1089
+ if (querySelf.q.type === "upsert") _appendQueryOnUpsertCreate(querySelf, query, (as) => {
1090
+ upsertCreateAs = as;
1314
1091
  setUpsertCreatePlaceholders();
1315
1092
  });
1316
- const { create, connect, connectOrCreate } = nestedCreateItems;
1317
- if (create) {
1318
- let query;
1319
- if (querySelf.q.type === "upsert") {
1320
- createWhereExists = new RawSql("");
1321
- createSelectAs = {};
1322
- for (const key of foreignKeys) createSelectAs[key] = new RawSql("");
1323
- const sourceQuery = _queryWhere(_queryTake(_querySelect(_clone(rel.qb), [createSelectAs])), [createWhereExists]);
1324
- query = _queryInsertManyFrom(_clone(rel), sourceQuery, create.items.flat());
1325
- } else query = _queryInsertMany(_clone(rel), create.items.flat());
1326
- if (querySelf.q.type === "upsert") _appendQueryOnUpsertCreate(querySelf, query, (as) => {
1327
- upsertCreateAs = as;
1328
- setUpsertCreatePlaceholders();
1329
- });
1330
- else _appendQuery(querySelf, query, (as) => createAs = as);
1331
- }
1332
- if (connect) connect.values.forEach((value, i) => {
1333
- const connectWhereExists = querySelf.q.type === "upsert" ? new RawSql("") : void 0;
1334
- const query = _queryUpdateOrThrow(rel.whereOneOf(...value), connect.items[i]);
1335
- if (connectWhereExists) _queryWhere(query, [connectWhereExists]);
1336
- query.q.ensureCount = value.length;
1337
- (querySelf.q.type === "upsert" ? _appendQueryOnUpsertCreate : _appendQuery)(querySelf, query, (as) => {
1338
- upsertCreateAs = as;
1339
- setUpsertCreatePlaceholders();
1340
- connectAs = as;
1341
- if (connectWhereExists) connectWhereExists._sql = `EXISTS (SELECT 1 FROM "${as}")`;
1342
- });
1093
+ else _appendQuery(querySelf, query, (as) => createAs = as);
1094
+ }
1095
+ if (connect) connect.values.forEach((value, i) => {
1096
+ const connectWhereExists = querySelf.q.type === "upsert" ? new RawSql("") : void 0;
1097
+ const query = _queryUpdateOrThrow(rel.where(value), connect.items[i]);
1098
+ if (connectWhereExists) _queryWhere(query, [connectWhereExists]);
1099
+ query.q.ensureCount = 1;
1100
+ (querySelf.q.type === "upsert" ? _appendQueryOnUpsertCreate : _appendQuery)(querySelf, query, (as) => {
1101
+ upsertCreateAs = as;
1102
+ setUpsertCreatePlaceholders();
1103
+ connectAs = as;
1104
+ if (connectWhereExists) connectWhereExists._sql = `EXISTS (SELECT 1 FROM "${as}")`;
1343
1105
  });
1344
- if (connectOrCreate) connectOrCreate.values.forEach((array, i) => {
1345
- const foreignKeyValues = connectOrCreate.items[i];
1346
- for (const value of array) {
1347
- const connectOrCreateWhereExists = querySelf.q.type === "upsert" ? new RawSql("") : void 0;
1348
- const connectOrCreateSelectAs = {};
1349
- if (connectOrCreateWhereExists) for (const key of foreignKeys) {
1350
- const value = foreignKeyValues[key];
1351
- value.result = { value: rel.qb.shape[key] };
1352
- connectOrCreateSelectAs[key] = value;
1353
- }
1354
- const query = _queryUpsert(rel.where(value.where), {
1355
- update: foreignKeyValues,
1356
- create: {
1357
- ...value.create,
1358
- ...foreignKeyValues
1359
- }
1360
- });
1361
- if (connectOrCreateWhereExists) {
1362
- _queryWhere(query, [connectOrCreateWhereExists]);
1363
- const guardQuery = _queryWhere(_queryTake(_querySelect(_clone(rel.qb), [{ one: new RawSql("1") }])), [connectOrCreateWhereExists]);
1364
- const sourceQuery = _querySelect(_clone(rel.qb).from(guardQuery), [connectOrCreateSelectAs]);
1365
- const q = query.q;
1366
- const columns = q.columns || [];
1367
- const foreignKeysSet = new Set(foreignKeys);
1368
- q.columns = [...foreignKeys, ...columns.filter((column) => !foreignKeysSet.has(column))];
1369
- q.values = q.values.map((row) => row.filter((_, i) => !foreignKeysSet.has(columns[i])));
1370
- q.queryColumnsCount = foreignKeys.length;
1371
- q.insertFrom = prepareSubQueryForSql(query, sourceQuery);
1372
- }
1373
- (querySelf.q.type === "upsert" ? _appendQueryOnUpsertCreate : _appendQuery)(querySelf, query, (as) => {
1374
- upsertCreateAs = as;
1375
- setUpsertCreatePlaceholders();
1376
- connectOrCreateAs = as;
1377
- if (connectOrCreateWhereExists) connectOrCreateWhereExists._sql = `EXISTS (SELECT 1 FROM "${as}")`;
1378
- });
1106
+ });
1107
+ if (connectOrCreate) connectOrCreate.values.forEach((value, i) => {
1108
+ const foreignKeyValues = connectOrCreate.items[i];
1109
+ const connectOrCreateWhereExists = querySelf.q.type === "upsert" ? new 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 = _queryUpsert(rel.where(value.where), {
1117
+ update: foreignKeyValues,
1118
+ create: {
1119
+ ...value.create,
1120
+ ...foreignKeyValues
1379
1121
  }
1380
1122
  });
1381
- } else hasRelationHandleCreate(querySelf, ctx, items, rowIndexes, this.key, this.state.primaryKeys, this.nestedInsert);
1123
+ if (connectOrCreateWhereExists) {
1124
+ _queryWhere(query, [connectOrCreateWhereExists]);
1125
+ const guardQuery = _queryWhere(_queryTake(_querySelect(_clone(rel.qb), [{ one: new RawSql("1") }])), [connectOrCreateWhereExists]);
1126
+ const sourceQuery = _querySelect(_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 = prepareSubQueryForSql(query, sourceQuery);
1134
+ }
1135
+ (querySelf.q.type === "upsert" ? _appendQueryOnUpsertCreate : _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) _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 ? _queryUpdate(ids.existingRelQuery, params.update) : params.upsert ? _queryUpsert(ids.existingRelQuery, makeNestedUpdateUpsertData(params.upsert, ids.setIds)) : params.delete ? _queryDelete(ids.existingRelQuery) : _queryUpdate(ids.existingRelQuery, setNulls);
1175
+ nullifyOrDeleteQuery.q.returnType = "void";
1176
+ _appendQuery(querySelf, nullifyOrDeleteQuery, ids.setAppendedAs);
1177
+ if (params.create) {
1178
+ const createQuery = _queryInsert(_clone(relQuery), {
1179
+ ...params.create,
1180
+ ...ids.setIds
1181
+ });
1182
+ _appendQuery(querySelf, createQuery, noop);
1183
+ } else if (params.set) {
1184
+ const setQuery = _queryUpdate(_queryWhere(_clone(relQuery), [params.set]), ids.setIds);
1185
+ setQuery.q.returnType = "void";
1186
+ _appendQuery(querySelf, setQuery, noop);
1187
+ }
1188
+ }
1189
+ };
1190
+ var HasOneVirtualColumn = class extends 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);
1382
1199
  }
1383
1200
  update(self, set) {
1384
- const querySelf = self;
1385
- const params = set[this.key];
1386
- throwIfQueryReturnsAllForNestedUpdate(querySelf, params);
1387
- hasRelationHandleUpdate(querySelf, set, this.key, this.state.primaryKeys, this.nestedUpdate);
1388
- if (params.upsert) {
1389
- const { primaryKeys, foreignKeys, query: relQuery } = this.state;
1390
- const ids = makeNestedUpdateRelationIds(querySelf, relQuery, primaryKeys, foreignKeys);
1391
- const appendedQuery = _queryUpsert(ids.existingRelQuery, makeNestedUpdateUpsertData(params.upsert, ids.setIds));
1392
- appendedQuery.q.returnType = "void";
1393
- _appendQuery(querySelf, appendedQuery, ids.setAppendedAs);
1394
- }
1201
+ hasOneUpdate(this.key, this.state, self, set);
1395
1202
  }
1396
1203
  };
1397
- const makeHasManyMethod = (tableConfig, table, relation, relationName, query) => {
1204
+ const makeHasOneMethod = (tableConfig, table, relation, relationName, query) => {
1398
1205
  const relPKeys = getPrimaryKeys(query);
1399
- if ("through" in relation.options) {
1400
- const { through, source, on } = relation.options;
1401
- if (on) _queryWhere(query, [on]);
1402
- const throughRelation = getThroughRelation(table, through);
1403
- const sourceRelation = getSourceRelation(throughRelation, source);
1404
- const sourceRelationQuery = sourceRelation.query.as(relationName);
1405
- const sourceQuery = sourceRelation.joinQuery(sourceRelationQuery, throughRelation.query);
1406
- const whereExistsCallback = () => sourceQuery;
1407
- const reverseJoin = (baseQuery, joiningQuery) => {
1408
- return joinHasThrough(baseQuery, baseQuery, joiningQuery, throughRelation, sourceRelation);
1409
- };
1410
- return {
1411
- returns: "many",
1412
- queryRelated: (params) => {
1413
- const throughQuery = table.queryRelated(through, params);
1414
- return query.whereExists(throughQuery, whereExistsCallback);
1415
- },
1416
- joinQuery: joinQueryChainHOF(relPKeys, reverseJoin, (joiningQuery, baseQuery) => joinHasThrough(joiningQuery, baseQuery, joiningQuery, throughRelation, sourceRelation)),
1417
- reverseJoin
1418
- };
1419
- }
1206
+ if ("through" in relation.options) return hasOneThrough(table, relation.options, relationName, query, relPKeys);
1420
1207
  const primaryKeys = relation.options.columns;
1421
1208
  const foreignKeys = relation.options.references;
1422
1209
  const { on } = relation.options;
@@ -1439,7 +1226,7 @@ const makeHasManyMethod = (tableConfig, table, relation, relationName, query) =>
1439
1226
  return joinHasRelation(joiningQuery, baseQuery, foreignKeys, primaryKeys, len);
1440
1227
  };
1441
1228
  return {
1442
- returns: "many",
1229
+ returns: "one",
1443
1230
  queryRelated: (params) => {
1444
1231
  const values = {};
1445
1232
  for (let i = 0; i < len; i++) values[foreignKeys[i]] = params[primaryKeys[i]];
@@ -1448,7 +1235,7 @@ const makeHasManyMethod = (tableConfig, table, relation, relationName, query) =>
1448
1235
  ...values
1449
1236
  });
1450
1237
  },
1451
- virtualColumn: new HasManyVirtualColumn(internalSchemaConfig, relationName, state),
1238
+ virtualColumn: new HasOneVirtualColumn(internalSchemaConfig, relationName, state),
1452
1239
  joinQuery: joinQueryChainHOF(relPKeys, reverseJoin, (joiningQuery, baseQuery) => joinHasRelation(baseQuery, joiningQuery, primaryKeys, foreignKeys, len)),
1453
1240
  reverseJoin,
1454
1241
  modifyRelatedQuery(relationQuery) {
@@ -1471,6 +1258,81 @@ const getWhereForNestedUpdate = (t, data, params, primaryKeys, foreignKeys) => {
1471
1258
  OR: params ? toArray(params) : void 0
1472
1259
  });
1473
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 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 = toArray(params.add);
1278
+ const count = await _queryUpdate(t.where({ OR: relatedWheres }), obj);
1279
+ if (count < relatedWheres.length) throw new 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 : 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 _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 _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 _queryDelete(q);
1297
+ else if (params.update) await _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 = _queryUpsert(ids.existingRelQuery, makeNestedUpdateUpsertData(params.upsert, ids.setIds));
1310
+ appendedQuery.q.returnType = "void";
1311
+ _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) _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
+ };
1474
1336
  const nestedInsert$1 = ({ query, primaryKeys, foreignKeys }) => {
1475
1337
  const len = primaryKeys.length;
1476
1338
  return (async (_, data) => {
@@ -1532,257 +1394,218 @@ const nestedInsert$1 = ({ query, primaryKeys, foreignKeys }) => {
1532
1394
  }
1533
1395
  });
1534
1396
  };
1535
- const nestedUpdate$1 = ({ query: relQuery, primaryKeys, foreignKeys }) => {
1536
- const len = primaryKeys.length;
1537
- return (async (_, data, params) => {
1538
- const t = relQuery.clone();
1539
- if (params.create) {
1540
- const obj = {};
1541
- for (let i = 0; i < len; i++) obj[foreignKeys[i]] = data[0][primaryKeys[i]];
1542
- await t.insertMany(params.create.map((create) => ({
1543
- ...create,
1544
- ...obj
1545
- })));
1546
- }
1547
- if (params.add) {
1548
- if (data.length > 1) throw new OrchidOrmInternalError(relQuery, "`connect` is not available when updating multiple records, it is only applicable for a single record update");
1549
- const obj = {};
1550
- for (let i = 0; i < len; i++) obj[foreignKeys[i]] = data[0][primaryKeys[i]];
1551
- const relatedWheres = toArray(params.add);
1552
- const count = await _queryUpdate(t.where({ OR: relatedWheres }), obj);
1553
- if (count < relatedWheres.length) throw new OrchidOrmInternalError(relQuery, `Expected to find at least ${relatedWheres.length} record(s) based on \`add\` conditions, but found ${count}`);
1554
- }
1555
- if (params.disconnect || params.set) {
1556
- const obj = {};
1557
- for (const foreignKey of foreignKeys) obj[foreignKey] = null;
1558
- const setConditions = params.set && (Array.isArray(params.set) ? params.set.length : objectHasValues(params.set)) && (Array.isArray(params.set) ? { OR: params.set } : params.set);
1559
- let queryToDisconnect = getWhereForNestedUpdate(t, data, params.disconnect, primaryKeys, foreignKeys);
1560
- if (setConditions) queryToDisconnect = queryToDisconnect.whereNot(setConditions);
1561
- await _queryUpdate(queryToDisconnect, obj);
1562
- if (setConditions) {
1563
- const obj = {};
1564
- for (let i = 0; i < len; i++) obj[foreignKeys[i]] = data[0][primaryKeys[i]];
1565
- await _queryUpdate(t.where(setConditions), obj);
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 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 RawSql("");
1428
+ nestedCreateItem.items.push(data);
1429
+ }
1566
1430
  }
1567
- }
1568
- if (params.delete || params.update) {
1569
- const q = getWhereForNestedUpdate(t, data, params.delete || params.update?.where, primaryKeys, foreignKeys);
1570
- if (params.delete) await _queryDelete(q);
1571
- else if (params.update) await _queryUpdate(q, params.update.data);
1572
- }
1573
- });
1574
- };
1575
- var HasAndBelongsToManyVirtualColumn = class extends VirtualColumn {
1576
- constructor(joinTable, schema, key, state) {
1577
- super(schema);
1578
- this.joinTable = joinTable;
1579
- this.key = key;
1580
- this.state = state;
1581
- this.nestedInsert = nestedInsert(state);
1582
- this.nestedUpdate = nestedUpdate(state);
1583
- }
1584
- create(q, ctx, items, rowIndexes) {
1585
- hasRelationHandleCreate(q, ctx, items, rowIndexes, this.key, this.state.primaryKeys, this.nestedInsert);
1586
- }
1587
- update(q, set) {
1588
- const querySelf = q;
1589
- const params = set[this.key];
1590
- hasRelationHandleUpdate(querySelf, set, this.key, this.state.primaryKeys, this.nestedUpdate);
1591
- if (params.upsert) {
1592
- throwIfQueryReturnsAllForNestedUpdate(querySelf, { upsert: params.upsert });
1593
- nestedUpdateUpsert(querySelf, this.state, params.upsert);
1594
- }
1595
- }
1596
- };
1597
- const selectCteColumnsSql = (cteAs, columns) => `(SELECT ${columns.map((c) => `"${cteAs}"."${c}"`).join(", ")} FROM "${cteAs}")`;
1598
- const selectCteColumnSql = (cteAs, column) => `(SELECT "${cteAs}"."${column}" FROM "${cteAs}")`;
1599
- const nestedUpdateUpsert = (querySelf, state, upsert) => {
1600
- const parentIdsSql = new RawSql("");
1601
- const parentValues = state.foreignKeys.map(() => new RawSql(""));
1602
- const relatedIdsSql = new RawSql("");
1603
- const relatedValues = state.throughPrimaryKeys.map(() => new RawSql(""));
1604
- let parentAs;
1605
- _hookSelectColumns(querySelf, state.primaryKeys, (aliasedPrimaryKeys) => {
1606
- parentIdsSql._sql = selectCteColumnsSql(parentAs, aliasedPrimaryKeys);
1607
- for (let i = 0; i < state.foreignKeys.length; i++) parentValues[i]._sql = selectCteColumnSql(parentAs, aliasedPrimaryKeys[i]);
1608
- });
1609
- const upsertQuery = _querySelect(_queryUpsert(_queryWhereExists(_queryWhere(_clone(state.relatedTableQuery), [upsert.findBy]), state.joinTableQuery, [(q) => {
1610
- for (let i = 0; i < state.throughPrimaryKeys.length; i++) _queryJoinOn(q, [state.throughForeignKeysFull[i], state.throughPrimaryKeysFull[i]]);
1611
- return _queryWhereIn(q, true, state.foreignKeysFull, parentIdsSql);
1612
- }]), {
1613
- update: upsert.update,
1614
- create: upsert.create || {}
1615
- }), state.throughPrimaryKeys);
1616
- const selectAs = {};
1617
- for (let i = 0; i < state.foreignKeys.length; i++) selectAs[state.foreignKeys[i]] = parentValues[i];
1618
- for (let i = 0; i < state.throughForeignKeys.length; i++) selectAs[state.throughForeignKeys[i]] = relatedValues[i];
1619
- const joinRows = _querySelect(_clone(state.queryBuilder), [selectAs]);
1620
- _queryWhere(joinRows, [relatedIdsSql]);
1621
- const joinQuery = state.joinTableQuery.insertForEachFrom(joinRows);
1622
- joinQuery.q.returnType = "void";
1623
- _appendQuery(querySelf, _appendQueryOnUpsertCreate(upsertQuery, joinQuery, (as) => {
1624
- relatedIdsSql._sql = `EXISTS (SELECT 1 FROM "${as}")`;
1625
- for (let i = 0; i < relatedValues.length; i++) relatedValues[i]._sql = selectCteColumnSql(as, state.throughPrimaryKeys[i]);
1626
- }), (as) => {
1627
- parentAs = as;
1628
- });
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
+ _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 RawSql("");
1474
+ createSelectAs = {};
1475
+ for (const key of foreignKeys) createSelectAs[key] = new RawSql("");
1476
+ const sourceQuery = _queryWhere(_queryTake(_querySelect(_clone(rel.qb), [createSelectAs])), [createWhereExists]);
1477
+ query = _queryInsertManyFrom(_clone(rel), sourceQuery, create.items.flat());
1478
+ } else query = _queryInsertMany(_clone(rel), create.items.flat());
1479
+ if (querySelf.q.type === "upsert") _appendQueryOnUpsertCreate(querySelf, query, (as) => {
1480
+ upsertCreateAs = as;
1481
+ setUpsertCreatePlaceholders();
1482
+ });
1483
+ else _appendQuery(querySelf, query, (as) => createAs = as);
1484
+ }
1485
+ if (connect) connect.values.forEach((value, i) => {
1486
+ const connectWhereExists = querySelf.q.type === "upsert" ? new RawSql("") : void 0;
1487
+ const query = _queryUpdateOrThrow(rel.whereOneOf(...value), connect.items[i]);
1488
+ if (connectWhereExists) _queryWhere(query, [connectWhereExists]);
1489
+ query.q.ensureCount = value.length;
1490
+ (querySelf.q.type === "upsert" ? _appendQueryOnUpsertCreate : _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 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 = _queryUpsert(rel.where(value.where), {
1508
+ update: foreignKeyValues,
1509
+ create: {
1510
+ ...value.create,
1511
+ ...foreignKeyValues
1512
+ }
1513
+ });
1514
+ if (connectOrCreateWhereExists) {
1515
+ _queryWhere(query, [connectOrCreateWhereExists]);
1516
+ const guardQuery = _queryWhere(_queryTake(_querySelect(_clone(rel.qb), [{ one: new RawSql("1") }])), [connectOrCreateWhereExists]);
1517
+ const sourceQuery = _querySelect(_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 = prepareSubQueryForSql(query, sourceQuery);
1525
+ }
1526
+ (querySelf.q.type === "upsert" ? _appendQueryOnUpsertCreate : _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);
1629
1535
  };
1630
- const removeColumnName = (column) => {
1631
- if (!column.data.name) return column;
1632
- const cloned = Object.create(column);
1633
- cloned.data = {
1634
- ...column.data,
1635
- name: void 0
1636
- };
1637
- return cloned;
1536
+ var HasManyVirtualColumn = class extends 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
+ }
1638
1552
  };
1639
- const makeHasAndBelongsToManyMethod = (tableConfig, table, qb, relation, relationName, query, schema) => {
1640
- const { options } = relation;
1641
- const { snakeCase } = table.internal;
1642
- const primaryKeys = options.columns;
1643
- const originalForeignKeys = options.references;
1644
- const foreignKeys = snakeCase ? [...originalForeignKeys] : originalForeignKeys;
1645
- const joinTable = snakeCase && options.through.snakeCase !== false ? toSnakeCase(options.through.table) : options.through.table;
1646
- const originalThroughForeignKeys = options.through.columns;
1647
- const throughForeignKeys = snakeCase ? [...originalThroughForeignKeys] : originalThroughForeignKeys;
1648
- const throughPrimaryKeys = options.through.references;
1649
- const { on } = options;
1553
+ const makeHasManyMethod = (tableConfig, table, relation, relationName, query) => {
1554
+ const relPKeys = 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;
1650
1567
  if (on) {
1651
1568
  _queryWhere(query, [on]);
1652
1569
  _queryDefaults(query, on);
1653
1570
  }
1654
- const foreignKeysFull = foreignKeys.map((key, i) => {
1655
- if (snakeCase) key = foreignKeys[i] = toSnakeCase(key);
1656
- return `${joinTable}.${key}`;
1657
- });
1658
- const throughForeignKeysFull = throughForeignKeys.map((key, i) => {
1659
- if (snakeCase) key = throughForeignKeys[i] = toSnakeCase(key);
1660
- return `${joinTable}.${key}`;
1661
- });
1662
- const foreignTable = getQueryAs(query);
1663
- const throughPrimaryKeysFull = throughPrimaryKeys.map((key) => `${foreignTable}.${key}`);
1664
- const len = primaryKeys.length;
1665
- const throughLen = throughPrimaryKeys.length;
1666
- const baseQuery = Object.create(qb.baseQuery);
1667
- baseQuery.baseQuery = baseQuery;
1668
- baseQuery.table = joinTable;
1669
- const shape = {};
1670
- const primaryKeysShape = {};
1671
- for (let i = 0; i < len; i++) {
1672
- const pk = primaryKeys[i];
1673
- shape[foreignKeys[i]] = removeColumnName(table.shape[pk]);
1674
- primaryKeysShape[pk] = table.shape[pk];
1675
- }
1676
- for (let i = 0; i < throughLen; i++) shape[throughForeignKeys[i]] = removeColumnName(query.shape[throughPrimaryKeys[i]]);
1677
- baseQuery.shape = shape;
1678
- baseQuery.q = {
1679
- ...baseQuery.q,
1680
- schema: options.through.schema || schema,
1681
- shape: baseQuery.shape
1682
- };
1683
- const subQuery = Object.create(baseQuery);
1684
- addAutoForeignKey(tableConfig, subQuery, table, primaryKeys, foreignKeys, relation.options, originalForeignKeys);
1685
- addAutoForeignKey(tableConfig, subQuery, query, throughPrimaryKeys, throughForeignKeys, relation.options.through, originalThroughForeignKeys);
1571
+ addAutoForeignKey(tableConfig, query, table, primaryKeys, foreignKeys, opts);
1686
1572
  const state = {
1687
- queryBuilder: qb,
1688
- relatedTableQuery: query,
1689
- joinTableQuery: subQuery,
1573
+ query,
1690
1574
  primaryKeys,
1691
1575
  foreignKeys,
1692
- throughForeignKeys,
1693
- throughPrimaryKeys,
1694
- foreignKeysFull,
1695
- throughForeignKeysFull,
1696
- throughPrimaryKeysFull,
1697
- primaryKeysShape,
1698
1576
  on
1699
1577
  };
1700
- const joinQuery = (joiningQuery, tableAs, foreignAs, joinedShapes) => {
1701
- const cloned = joiningQuery.clone();
1702
- cloned.q.joinedShapes = joinedShapes;
1703
- return _queryWhereExists(cloned, subQuery, [(q) => {
1704
- for (let i = 0; i < throughLen; i++) _queryJoinOn(q, [throughForeignKeysFull[i], `${foreignAs}.${throughPrimaryKeys[i]}`]);
1705
- for (let i = 0; i < len; i++) _queryJoinOn(q, [foreignKeysFull[i], `${tableAs}.${primaryKeys[i]}`]);
1706
- return q;
1707
- }]);
1708
- };
1709
- const obj = {};
1710
- for (let i = 0; i < len; i++) obj[foreignKeys[i]] = primaryKeys[i];
1711
- 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 }];
1712
1582
  const reverseJoin = (baseQuery, joiningQuery) => {
1713
- const foreignAs = getQueryAs(joiningQuery);
1714
- return joinQuery(baseQuery, getQueryAs(baseQuery), foreignAs, {
1715
- ...baseQuery.q.joinedShapes,
1716
- [foreignAs]: joiningQuery.q.selectShape
1717
- });
1583
+ return joinHasRelation(joiningQuery, baseQuery, foreignKeys, primaryKeys, len);
1718
1584
  };
1719
1585
  return {
1720
1586
  returns: "many",
1721
- queryRelated(params) {
1722
- const q = query.whereExists(subQuery, (q) => {
1723
- q = q.clone();
1724
- const where = {};
1725
- for (let i = 0; i < len; i++) where[foreignKeysFull[i]] = params[primaryKeys[i]];
1726
- for (let i = 0; i < throughLen; i++) _queryJoinOn(q, [throughForeignKeysFull[i], throughPrimaryKeysFull[i]]);
1727
- return _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 _queryDefaults(query.where(values), {
1591
+ ...on,
1592
+ ...values
1728
1593
  });
1729
- return on ? _queryDefaults(q, on) : q;
1730
1594
  },
1731
- virtualColumn: new HasAndBelongsToManyVirtualColumn(subQuery, internalSchemaConfig, relationName, state),
1732
- joinQuery: joinQueryChainHOF(getPrimaryKeys(query), reverseJoin, (joiningQuery, baseQuery) => joinQuery(joiningQuery, getQueryAs(baseQuery), getQueryAs(joiningQuery), {
1733
- ...joiningQuery.q.joinedShapes,
1734
- [baseQuery.q.as || baseQuery.table]: baseQuery.q.selectShape
1735
- })),
1595
+ virtualColumn: new HasManyVirtualColumn(internalSchemaConfig, relationName, state),
1596
+ joinQuery: joinQueryChainHOF(relPKeys, reverseJoin, (joiningQuery, baseQuery) => joinHasRelation(baseQuery, joiningQuery, primaryKeys, foreignKeys, len)),
1736
1597
  reverseJoin,
1737
1598
  modifyRelatedQuery(relationQuery) {
1738
- const ref = {};
1739
- _queryHookAfterCreate(relationQuery, [], async (result) => {
1740
- const baseQuery = ref.q.clone();
1741
- baseQuery.q.select = selectPrimaryKeysAsForeignKeys;
1742
- const data = result.map((resultRow) => {
1743
- const dataRow = {};
1744
- for (let i = 0; i < throughLen; i++) dataRow[throughForeignKeys[i]] = resultRow[throughPrimaryKeys[i]];
1745
- return dataRow;
1746
- });
1747
- if (await _queryCreateManyFrom(subQuery.count(), baseQuery, data) === 0) throw new NotFoundError(baseQuery);
1748
- });
1749
- return (q) => {
1750
- ref.q = q;
1599
+ return (query) => {
1600
+ const baseQuery = query.clone();
1601
+ baseQuery.q.select = fromQuerySelect;
1602
+ const q = relationQuery.q;
1603
+ q.insertFrom = prepareSubQueryForSql(q, baseQuery);
1604
+ q.values = [];
1751
1605
  };
1752
1606
  }
1753
1607
  };
1754
1608
  };
1755
- const queryJoinTable = (state, data, conditions) => {
1756
- const t = state.joinTableQuery.where({ IN: {
1757
- columns: state.foreignKeys,
1758
- values: data.map((item) => state.primaryKeys.map((key) => item[key]))
1759
- } });
1760
- if (conditions) _queryWhere(t, [{ IN: {
1761
- columns: state.throughForeignKeys,
1762
- values: _querySelect(state.relatedTableQuery.where(conditionsToWhereArg(conditions)), state.throughPrimaryKeys)
1763
- } }]);
1764
- if (state.on) _queryWhereExists(t, state.relatedTableQuery, [(q) => {
1765
- for (let i = 0; i < state.throughPrimaryKeys.length; i++) _queryJoinOn(q, [state.throughPrimaryKeysFull[i], state.throughForeignKeysFull[i]]);
1766
- return q;
1767
- }]);
1768
- return t;
1769
- };
1770
- const conditionsToWhereArg = (conditions) => Array.isArray(conditions) ? { OR: conditions } : conditions;
1771
- const insertToJoinTable = (state, joinTableTransaction, data, idsRows) => {
1772
- const len = state.primaryKeys.length;
1773
- const throughLen = state.throughPrimaryKeys.length;
1774
- const records = [];
1775
- for (const item of data) {
1776
- const obj = {};
1777
- for (let i = 0; i < len; i++) obj[state.foreignKeys[i]] = item[state.primaryKeys[i]];
1778
- for (const ids of idsRows) {
1779
- const record = { ...obj };
1780
- for (let i = 0; i < throughLen; i++) record[state.throughForeignKeys[i]] = ids[i];
1781
- records.push(record);
1782
- }
1783
- }
1784
- return joinTableTransaction.insertMany(records);
1785
- };
1786
1609
  const nestedInsert = ({ relatedTableQuery, joinTableQuery, primaryKeys, foreignKeys, throughPrimaryKeys, throughForeignKeys }) => {
1787
1610
  const len = primaryKeys.length;
1788
1611
  const throughLen = primaryKeys.length;
@@ -1868,6 +1691,71 @@ const nestedInsert = ({ relatedTableQuery, joinTableQuery, primaryKeys, foreignK
1868
1691
  await joinTableQuery.insertMany(records);
1869
1692
  });
1870
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) _queryWhere(t, [{ IN: {
1703
+ columns: state.throughForeignKeys,
1704
+ values: _querySelect(state.relatedTableQuery.where(conditionsToWhereArg(conditions)), state.throughPrimaryKeys)
1705
+ } }]);
1706
+ if (state.on) _queryWhereExists(t, state.relatedTableQuery, [(q) => {
1707
+ for (let i = 0; i < state.throughPrimaryKeys.length; i++) _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 RawSql("");
1729
+ const parentValues = state.foreignKeys.map(() => new RawSql(""));
1730
+ const relatedIdsSql = new RawSql("");
1731
+ const relatedValues = state.throughPrimaryKeys.map(() => new RawSql(""));
1732
+ let parentAs;
1733
+ _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 = _queryWhereExists(_queryWhere(_clone(state.relatedTableQuery), [upsert.findBy]), state.joinTableQuery, [(q) => {
1738
+ for (let i = 0; i < state.throughPrimaryKeys.length; i++) _queryJoinOn(q, [state.throughForeignKeysFull[i], state.throughPrimaryKeysFull[i]]);
1739
+ return _queryWhereIn(q, true, state.foreignKeysFull, parentIdsSql);
1740
+ }]);
1741
+ const upsertQuery = _querySelect(_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 = _querySelect(_clone(state.queryBuilder), [selectAs]);
1749
+ _queryWhere(joinRows, [relatedIdsSql]);
1750
+ const joinQuery = state.joinTableQuery.insertForEachFrom(joinRows);
1751
+ joinQuery.q.returnType = "void";
1752
+ _appendQuery(querySelf, _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
+ };
1871
1759
  const nestedUpdate = (state) => {
1872
1760
  const len = state.primaryKeys.length;
1873
1761
  const throughLen = state.throughPrimaryKeys.length;
@@ -1912,7 +1800,8 @@ const nestedUpdate = (state) => {
1912
1800
  }
1913
1801
  if (params.disconnect) await _queryDelete(queryJoinTable(state, data, params.disconnect));
1914
1802
  if (params.delete) {
1915
- const idsRows = await _queryDelete(_queryRows(_querySelect(queryJoinTable(state, data, params.delete), state.throughForeignKeys)));
1803
+ const j = queryJoinTable(state, data, params.delete);
1804
+ const idsRows = await _queryDelete(_queryRows(_querySelect(j, state.throughForeignKeys)));
1916
1805
  await _queryDelete(state.relatedTableQuery.where({ IN: {
1917
1806
  columns: state.throughPrimaryKeys,
1918
1807
  values: idsRows
@@ -1921,10 +1810,160 @@ const nestedUpdate = (state) => {
1921
1810
  if (params.set) {
1922
1811
  const j = queryJoinTable(state, data);
1923
1812
  await _queryDelete(j);
1924
- if (Array.isArray(params.set) ? params.set.length : objectHasValues(params.set)) await insertToJoinTable(state, j, data, await _queryRows(_querySelect(state.relatedTableQuery.where(conditionsToWhereArg(params.set)), state.throughPrimaryKeys)));
1813
+ if (Array.isArray(params.set) ? params.set.length : objectHasValues(params.set)) {
1814
+ const idsRows = await _queryRows(_querySelect(state.relatedTableQuery.where(conditionsToWhereArg(params.set)), state.throughPrimaryKeys));
1815
+ await insertToJoinTable(state, j, data, idsRows);
1816
+ }
1925
1817
  }
1926
1818
  });
1927
1819
  };
1820
+ var HasAndBelongsToManyVirtualColumn = class extends 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 ? 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
+ _queryWhere(query, [on]);
1864
+ _queryDefaults(query, on);
1865
+ }
1866
+ const foreignKeysFull = foreignKeys.map((key, i) => {
1867
+ if (snakeCase) key = foreignKeys[i] = toSnakeCase(key);
1868
+ return `${joinTable}.${key}`;
1869
+ });
1870
+ const throughForeignKeysFull = throughForeignKeys.map((key, i) => {
1871
+ if (snakeCase) key = throughForeignKeys[i] = toSnakeCase(key);
1872
+ return `${joinTable}.${key}`;
1873
+ });
1874
+ const foreignTable = 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 _queryWhereExists(cloned, subQuery, [(q) => {
1916
+ for (let i = 0; i < throughLen; i++) _queryJoinOn(q, [throughForeignKeysFull[i], `${foreignAs}.${throughPrimaryKeys[i]}`]);
1917
+ for (let i = 0; i < len; i++) _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 = getQueryAs(joiningQuery);
1926
+ return joinQuery(baseQuery, 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++) _queryJoinOn(q, [throughForeignKeysFull[i], throughPrimaryKeysFull[i]]);
1939
+ return _queryWhere(q, [where]);
1940
+ });
1941
+ return on ? _queryDefaults(q, on) : q;
1942
+ },
1943
+ virtualColumn: new HasAndBelongsToManyVirtualColumn(subQuery, internalSchemaConfig, relationName, state),
1944
+ joinQuery: joinQueryChainHOF(getPrimaryKeys(query), reverseJoin, (joiningQuery, baseQuery) => joinQuery(joiningQuery, getQueryAs(baseQuery), 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
+ _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 _queryCreateManyFrom(subQuery.count(), baseQuery, data) === 0) throw new NotFoundError(baseQuery);
1960
+ });
1961
+ return (q) => {
1962
+ ref.q = q;
1963
+ };
1964
+ }
1965
+ };
1966
+ };
1928
1967
  const applyRelations = (qb, tables, result, schema) => {
1929
1968
  const tableEntries = Object.entries(tables);
1930
1969
  const delayedRelations = /* @__PURE__ */ new Map();