orchid-orm 1.3.15 → 1.4.16
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/CHANGELOG.md +20 -0
- package/dist/index.d.ts +59 -54
- package/dist/index.esm.js +777 -547
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +776 -546
- package/dist/index.js.map +1 -1
- package/jest-setup.ts +4 -0
- package/package.json +8 -4
- package/src/appCodeUpdater/appCodeUpdater.ts +19 -0
- package/src/appCodeUpdater/fileChanges.ts +41 -0
- package/src/appCodeUpdater/testUtils.ts +31 -0
- package/src/appCodeUpdater/tsUtils.ts +137 -0
- package/src/appCodeUpdater/updateMainFile.test.ts +230 -0
- package/src/appCodeUpdater/updateMainFile.ts +163 -0
- package/src/appCodeUpdater/updateTableFile.ts +19 -0
- package/src/index.ts +5 -1
- package/src/orm.test.ts +13 -13
- package/src/orm.ts +21 -21
- package/src/relations/belongsTo.test.ts +1 -1
- package/src/relations/belongsTo.ts +291 -186
- package/src/relations/hasAndBelongsToMany.test.ts +1 -1
- package/src/relations/hasAndBelongsToMany.ts +292 -218
- package/src/relations/hasMany.test.ts +16 -10
- package/src/relations/hasMany.ts +243 -172
- package/src/relations/hasOne.test.ts +10 -10
- package/src/relations/hasOne.ts +211 -138
- package/src/relations/relations.ts +85 -77
- package/src/relations/utils.ts +154 -4
- package/src/repo.test.ts +29 -29
- package/src/repo.ts +6 -6
- package/src/{model.test.ts → table.test.ts} +15 -15
- package/src/{model.ts → table.ts} +17 -17
- package/src/test-utils/test-db.ts +15 -15
- package/src/test-utils/{test-models.ts → test-tables.ts} +42 -42
- package/src/transaction.test.ts +1 -1
- package/src/transaction.ts +4 -4
- package/src/utils.ts +9 -0
- package/tsconfig.json +1 -0
package/dist/index.esm.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { getColumnTypes,
|
|
1
|
+
import { getColumnTypes, addQueryOn, VirtualColumn, pushQueryValue, isQueryReturnsAll, getQueryAs, toSqlCacheKey, NotFoundError, relationQueryKey, Db, Adapter, anyShape, columnTypes, getClonedQueryData } from 'pqb';
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
return class
|
|
3
|
+
const createBaseTable = (options) => {
|
|
4
|
+
return class BaseTable {
|
|
5
5
|
constructor() {
|
|
6
6
|
this.setColumns = (fn) => {
|
|
7
7
|
const shape = getColumnTypes(options.columnTypes, fn);
|
|
@@ -47,150 +47,249 @@ const createModel = (options) => {
|
|
|
47
47
|
};
|
|
48
48
|
};
|
|
49
49
|
|
|
50
|
-
|
|
50
|
+
class BelongsToVirtualColumn extends VirtualColumn {
|
|
51
|
+
constructor(key, state) {
|
|
52
|
+
super();
|
|
53
|
+
this.key = key;
|
|
54
|
+
this.state = state;
|
|
55
|
+
this.nestedInsert = nestedInsert$3(this.state);
|
|
56
|
+
this.nestedUpdate = nestedUpdate$3(this.state);
|
|
57
|
+
}
|
|
58
|
+
create(q, ctx, item, rowIndex) {
|
|
59
|
+
const {
|
|
60
|
+
key,
|
|
61
|
+
state: { foreignKey, primaryKey }
|
|
62
|
+
} = this;
|
|
63
|
+
let columnIndex = ctx.columns.get(foreignKey);
|
|
64
|
+
if (columnIndex === void 0) {
|
|
65
|
+
ctx.columns.set(foreignKey, columnIndex = ctx.columns.size);
|
|
66
|
+
}
|
|
67
|
+
const store = ctx;
|
|
68
|
+
if (!store.belongsTo)
|
|
69
|
+
store.belongsTo = {};
|
|
70
|
+
const values = [rowIndex, columnIndex, item[key]];
|
|
71
|
+
if (store.belongsTo[key]) {
|
|
72
|
+
store.belongsTo[key].push(values);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
const relationData = [values];
|
|
76
|
+
store.belongsTo[key] = relationData;
|
|
77
|
+
q.query.wrapInTransaction = true;
|
|
78
|
+
pushQueryValue(q, "beforeCreate", async (q2) => {
|
|
79
|
+
const inserted = await this.nestedInsert(
|
|
80
|
+
q2,
|
|
81
|
+
relationData.map(([, , data]) => data)
|
|
82
|
+
);
|
|
83
|
+
const { values: values2 } = q2.query;
|
|
84
|
+
relationData.forEach(([rowIndex2, columnIndex2], index) => {
|
|
85
|
+
values2[rowIndex2][columnIndex2] = inserted[index][primaryKey];
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
update(q, ctx, set) {
|
|
90
|
+
q.query.wrapInTransaction = true;
|
|
91
|
+
const data = set[this.key];
|
|
92
|
+
if (this.nestedUpdate(q, set, data, ctx)) {
|
|
93
|
+
ctx.willSetKeys = true;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
const makeBelongsToMethod = (relation, relationName, query) => {
|
|
51
98
|
const { primaryKey, foreignKey } = relation.options;
|
|
99
|
+
const state = { query, primaryKey, foreignKey };
|
|
52
100
|
return {
|
|
53
101
|
returns: "one",
|
|
54
102
|
method: (params) => {
|
|
55
103
|
return query.findBy({ [primaryKey]: params[foreignKey] });
|
|
56
104
|
},
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
105
|
+
virtualColumn: new BelongsToVirtualColumn(relationName, state),
|
|
106
|
+
joinQuery(fromQuery, toQuery) {
|
|
107
|
+
return addQueryOn(toQuery, fromQuery, toQuery, primaryKey, foreignKey);
|
|
108
|
+
},
|
|
109
|
+
reverseJoin(fromQuery, toQuery) {
|
|
110
|
+
return addQueryOn(fromQuery, toQuery, fromQuery, foreignKey, primaryKey);
|
|
111
|
+
},
|
|
112
|
+
primaryKey
|
|
113
|
+
};
|
|
114
|
+
};
|
|
115
|
+
const nestedInsert$3 = ({ query, primaryKey }) => {
|
|
116
|
+
return async (q, data) => {
|
|
117
|
+
const connectOrCreate = data.filter(
|
|
118
|
+
(item) => Boolean(item.connectOrCreate)
|
|
119
|
+
);
|
|
120
|
+
const t = query.transacting(q);
|
|
121
|
+
let connectOrCreated;
|
|
122
|
+
if (connectOrCreate.length) {
|
|
123
|
+
connectOrCreated = await Promise.all(
|
|
124
|
+
connectOrCreate.map(
|
|
125
|
+
(item) => t.findBy(item.connectOrCreate.where)._takeOptional()
|
|
126
|
+
)
|
|
60
127
|
);
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}
|
|
72
|
-
let connectOrCreatedI = 0;
|
|
73
|
-
const create = data.filter(
|
|
74
|
-
(item) => {
|
|
75
|
-
if (item.connectOrCreate) {
|
|
76
|
-
return !connectOrCreated[connectOrCreatedI++];
|
|
77
|
-
} else {
|
|
78
|
-
return Boolean(item.create);
|
|
79
|
-
}
|
|
128
|
+
} else {
|
|
129
|
+
connectOrCreated = [];
|
|
130
|
+
}
|
|
131
|
+
let connectOrCreatedI = 0;
|
|
132
|
+
const create = data.filter(
|
|
133
|
+
(item) => {
|
|
134
|
+
if (item.connectOrCreate) {
|
|
135
|
+
return !connectOrCreated[connectOrCreatedI++];
|
|
136
|
+
} else {
|
|
137
|
+
return Boolean(item.create);
|
|
80
138
|
}
|
|
81
|
-
);
|
|
82
|
-
let created;
|
|
83
|
-
if (create.length) {
|
|
84
|
-
created = await t.select(primaryKey)._createMany(
|
|
85
|
-
create.map(
|
|
86
|
-
(item) => "create" in item ? item.create : item.connectOrCreate.create
|
|
87
|
-
)
|
|
88
|
-
);
|
|
89
|
-
} else {
|
|
90
|
-
created = [];
|
|
91
139
|
}
|
|
92
|
-
|
|
93
|
-
|
|
140
|
+
);
|
|
141
|
+
let created;
|
|
142
|
+
if (create.length) {
|
|
143
|
+
created = await t.select(primaryKey)._createMany(
|
|
144
|
+
create.map(
|
|
145
|
+
(item) => "create" in item ? item.create : item.connectOrCreate.create
|
|
146
|
+
)
|
|
94
147
|
);
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
connectOrCreatedI = 0;
|
|
106
|
-
return data.map(
|
|
107
|
-
(item) => item.connectOrCreate ? connectOrCreated[connectOrCreatedI++] || created[createdI++] : item.connect ? connected[connectedI++] : created[createdI++]
|
|
148
|
+
} else {
|
|
149
|
+
created = [];
|
|
150
|
+
}
|
|
151
|
+
const connect = data.filter(
|
|
152
|
+
(item) => Boolean(item.connect)
|
|
153
|
+
);
|
|
154
|
+
let connected;
|
|
155
|
+
if (connect.length) {
|
|
156
|
+
connected = await Promise.all(
|
|
157
|
+
connect.map((item) => t.findBy(item.connect)._take())
|
|
108
158
|
);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
if (upsert || params.update || params.delete) {
|
|
136
|
-
if (!((_a = q.query.select) == null ? void 0 : _a.includes("*")) && !((_b = q.query.select) == null ? void 0 : _b.includes(foreignKey))) {
|
|
137
|
-
q._select(foreignKey);
|
|
159
|
+
} else {
|
|
160
|
+
connected = [];
|
|
161
|
+
}
|
|
162
|
+
let createdI = 0;
|
|
163
|
+
let connectedI = 0;
|
|
164
|
+
connectOrCreatedI = 0;
|
|
165
|
+
return data.map(
|
|
166
|
+
(item) => item.connectOrCreate ? connectOrCreated[connectOrCreatedI++] || created[createdI++] : item.connect ? connected[connectedI++] : created[createdI++]
|
|
167
|
+
);
|
|
168
|
+
};
|
|
169
|
+
};
|
|
170
|
+
const nestedUpdate$3 = ({ query, primaryKey, foreignKey }) => {
|
|
171
|
+
return (q, update, params, state) => {
|
|
172
|
+
var _a, _b;
|
|
173
|
+
if (params.upsert && isQueryReturnsAll(q)) {
|
|
174
|
+
throw new Error("`upsert` option is not allowed in a batch update");
|
|
175
|
+
}
|
|
176
|
+
let idForDelete;
|
|
177
|
+
q._beforeUpdate(async (q2) => {
|
|
178
|
+
if (params.disconnect) {
|
|
179
|
+
update[foreignKey] = null;
|
|
180
|
+
} else if (params.set) {
|
|
181
|
+
if (primaryKey in params.set) {
|
|
182
|
+
update[foreignKey] = params.set[primaryKey];
|
|
183
|
+
} else {
|
|
184
|
+
update[foreignKey] = await query.transacting(q2)._findBy(params.set)._get(primaryKey);
|
|
138
185
|
}
|
|
186
|
+
} else if (params.create) {
|
|
187
|
+
update[foreignKey] = await query.transacting(q2)._get(primaryKey)._create(params.create);
|
|
188
|
+
} else if (params.delete) {
|
|
189
|
+
const selectQuery = q2.transacting(q2);
|
|
190
|
+
selectQuery.query.type = void 0;
|
|
191
|
+
idForDelete = await selectQuery._getOptional(foreignKey);
|
|
192
|
+
update[foreignKey] = null;
|
|
139
193
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
194
|
+
});
|
|
195
|
+
const { upsert } = params;
|
|
196
|
+
if (upsert || params.update || params.delete) {
|
|
197
|
+
if (!((_a = q.query.select) == null ? void 0 : _a.includes("*")) && !((_b = q.query.select) == null ? void 0 : _b.includes(foreignKey))) {
|
|
198
|
+
q._select(foreignKey);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
if (upsert) {
|
|
202
|
+
if (!state.updateLater) {
|
|
203
|
+
state.updateLater = {};
|
|
204
|
+
state.updateLaterPromises = [];
|
|
205
|
+
}
|
|
206
|
+
const { handleResult } = q.query;
|
|
207
|
+
q.query.handleResult = async (q2, queryResult) => {
|
|
208
|
+
const data = await handleResult(q2, queryResult);
|
|
209
|
+
const id = data[0][foreignKey];
|
|
210
|
+
if (id !== null) {
|
|
211
|
+
await query.transacting(q2)._findBy({ [primaryKey]: id })._update(upsert.update);
|
|
212
|
+
} else {
|
|
213
|
+
state.updateLaterPromises.push(
|
|
214
|
+
query.transacting(q2)._select(primaryKey)._create(upsert.create).then((result) => {
|
|
215
|
+
state.updateLater[foreignKey] = result[primaryKey];
|
|
216
|
+
})
|
|
217
|
+
);
|
|
144
218
|
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
} else if (params.delete || params.update) {
|
|
161
|
-
q._afterQuery(async (q2, data) => {
|
|
162
|
-
const id = params.delete ? idForDelete : Array.isArray(data) ? data.length === 0 ? null : {
|
|
163
|
-
in: data.map((item) => item[foreignKey]).filter((id2) => id2 !== null)
|
|
164
|
-
} : data[foreignKey];
|
|
165
|
-
if (id !== void 0 && id !== null) {
|
|
166
|
-
const t = query.transacting(q2)._findBy({
|
|
167
|
-
[primaryKey]: id
|
|
168
|
-
});
|
|
169
|
-
if (params.delete) {
|
|
170
|
-
await t._delete();
|
|
171
|
-
} else if (params.update) {
|
|
172
|
-
await t._update(params.update);
|
|
173
|
-
}
|
|
219
|
+
return data;
|
|
220
|
+
};
|
|
221
|
+
} else if (params.delete || params.update) {
|
|
222
|
+
q._afterQuery(async (q2, data) => {
|
|
223
|
+
const id = params.delete ? idForDelete : Array.isArray(data) ? data.length === 0 ? null : {
|
|
224
|
+
in: data.map((item) => item[foreignKey]).filter((id2) => id2 !== null)
|
|
225
|
+
} : data[foreignKey];
|
|
226
|
+
if (id !== void 0 && id !== null) {
|
|
227
|
+
const t = query.transacting(q2)._findBy({
|
|
228
|
+
[primaryKey]: id
|
|
229
|
+
});
|
|
230
|
+
if (params.delete) {
|
|
231
|
+
await t._delete();
|
|
232
|
+
} else if (params.update) {
|
|
233
|
+
await t._update(params.update);
|
|
174
234
|
}
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
joinQuery(fromQuery, toQuery) {
|
|
180
|
-
return addQueryOn(toQuery, fromQuery, toQuery, primaryKey, foreignKey);
|
|
181
|
-
},
|
|
182
|
-
reverseJoin(fromQuery, toQuery) {
|
|
183
|
-
return addQueryOn(fromQuery, toQuery, fromQuery, foreignKey, primaryKey);
|
|
184
|
-
},
|
|
185
|
-
primaryKey
|
|
235
|
+
}
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
return !params.update && !params.upsert;
|
|
186
239
|
};
|
|
187
240
|
};
|
|
188
241
|
|
|
189
|
-
const getThroughRelation = (
|
|
190
|
-
return
|
|
242
|
+
const getThroughRelation = (table, through) => {
|
|
243
|
+
return table.relations[through];
|
|
191
244
|
};
|
|
192
245
|
const getSourceRelation = (throughRelation, source) => {
|
|
193
|
-
return throughRelation.
|
|
246
|
+
return throughRelation.table.relations[source];
|
|
247
|
+
};
|
|
248
|
+
const hasRelationHandleCreate = (q, ctx, item, rowIndex, key, primaryKey, nestedInsert) => {
|
|
249
|
+
const value = item[key];
|
|
250
|
+
if ((!value.create || Array.isArray(value.create) && value.create.length === 0) && (!value.connect || Array.isArray(value.connect) && value.connect.length === 0) && (!value.connectOrCreate || Array.isArray(value.connectOrCreate) && value.connectOrCreate.length === 0))
|
|
251
|
+
return;
|
|
252
|
+
const store = ctx;
|
|
253
|
+
if (!store.hasRelation)
|
|
254
|
+
store.hasRelation = {};
|
|
255
|
+
const values = [rowIndex, value];
|
|
256
|
+
if (store.hasRelation[key]) {
|
|
257
|
+
store.hasRelation[key].push(values);
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
q.query.wrapInTransaction = true;
|
|
261
|
+
ctx.returnTypeAll = true;
|
|
262
|
+
ctx.requiredReturning[primaryKey] = true;
|
|
263
|
+
const relationData = [values];
|
|
264
|
+
store.hasRelation[key] = relationData;
|
|
265
|
+
pushQueryValue(q, "afterCreate", async (q2) => {
|
|
266
|
+
const { resultAll } = ctx;
|
|
267
|
+
return nestedInsert(
|
|
268
|
+
q2,
|
|
269
|
+
relationData.map(([rowIndex2, data]) => [
|
|
270
|
+
resultAll[rowIndex2],
|
|
271
|
+
data
|
|
272
|
+
])
|
|
273
|
+
);
|
|
274
|
+
});
|
|
275
|
+
};
|
|
276
|
+
const hasRelationHandleUpdate = (q, ctx, set, key, primaryKey, nestedUpdate) => {
|
|
277
|
+
var _a, _b;
|
|
278
|
+
const value = set[key];
|
|
279
|
+
if (!value.set && !("upsert" in value) && (!value.disconnect || Array.isArray(value.disconnect) && value.disconnect.length === 0) && (!value.delete || Array.isArray(value.delete) && value.delete.length === 0) && (!value.update || Array.isArray(value.update.where) && value.update.where.length === 0) && (!value.create || Array.isArray(value.create) && value.create.length === 0))
|
|
280
|
+
return;
|
|
281
|
+
if (!((_a = q.query.select) == null ? void 0 : _a.includes("*")) && !((_b = q.query.select) == null ? void 0 : _b.includes(primaryKey))) {
|
|
282
|
+
q._select(primaryKey);
|
|
283
|
+
}
|
|
284
|
+
q.query.wrapInTransaction = true;
|
|
285
|
+
ctx.returnTypeAll = true;
|
|
286
|
+
pushQueryValue(q, "afterUpdate", (q2) => {
|
|
287
|
+
return nestedUpdate(
|
|
288
|
+
q2,
|
|
289
|
+
ctx.resultAll,
|
|
290
|
+
value
|
|
291
|
+
);
|
|
292
|
+
});
|
|
194
293
|
};
|
|
195
294
|
|
|
196
295
|
var __defProp$4 = Object.defineProperty;
|
|
@@ -212,7 +311,37 @@ var __spreadValues$4 = (a, b) => {
|
|
|
212
311
|
return a;
|
|
213
312
|
};
|
|
214
313
|
var __spreadProps$2 = (a, b) => __defProps$2(a, __getOwnPropDescs$2(b));
|
|
215
|
-
|
|
314
|
+
class HasOneVirtualColumn extends VirtualColumn {
|
|
315
|
+
constructor(key, state) {
|
|
316
|
+
super();
|
|
317
|
+
this.key = key;
|
|
318
|
+
this.state = state;
|
|
319
|
+
this.nestedInsert = nestedInsert$2(state);
|
|
320
|
+
this.nestedUpdate = nestedUpdate$2(state);
|
|
321
|
+
}
|
|
322
|
+
create(q, ctx, item, rowIndex) {
|
|
323
|
+
hasRelationHandleCreate(
|
|
324
|
+
q,
|
|
325
|
+
ctx,
|
|
326
|
+
item,
|
|
327
|
+
rowIndex,
|
|
328
|
+
this.key,
|
|
329
|
+
this.state.primaryKey,
|
|
330
|
+
this.nestedInsert
|
|
331
|
+
);
|
|
332
|
+
}
|
|
333
|
+
update(q, ctx, set) {
|
|
334
|
+
hasRelationHandleUpdate(
|
|
335
|
+
q,
|
|
336
|
+
ctx,
|
|
337
|
+
set,
|
|
338
|
+
this.key,
|
|
339
|
+
this.state.primaryKey,
|
|
340
|
+
this.nestedUpdate
|
|
341
|
+
);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
const makeHasOneMethod = (table, relation, relationName, query) => {
|
|
216
345
|
if (relation.options.required) {
|
|
217
346
|
query._take();
|
|
218
347
|
} else {
|
|
@@ -220,21 +349,19 @@ const makeHasOneMethod = (model, relation, relationName, query) => {
|
|
|
220
349
|
}
|
|
221
350
|
if ("through" in relation.options) {
|
|
222
351
|
const { through, source } = relation.options;
|
|
223
|
-
const throughRelation = getThroughRelation(
|
|
352
|
+
const throughRelation = getThroughRelation(table, through);
|
|
224
353
|
const sourceRelation = getSourceRelation(throughRelation, source);
|
|
225
354
|
const sourceQuery = sourceRelation.joinQuery(throughRelation.query, sourceRelation.query).as(relationName);
|
|
226
355
|
const whereExistsCallback = () => sourceQuery;
|
|
227
356
|
return {
|
|
228
357
|
returns: "one",
|
|
229
358
|
method: (params) => {
|
|
230
|
-
const throughQuery =
|
|
359
|
+
const throughQuery = table[through](params);
|
|
231
360
|
return query.whereExists(
|
|
232
361
|
throughQuery,
|
|
233
362
|
whereExistsCallback
|
|
234
363
|
);
|
|
235
364
|
},
|
|
236
|
-
nestedInsert: void 0,
|
|
237
|
-
nestedUpdate: void 0,
|
|
238
365
|
joinQuery(fromQuery, toQuery) {
|
|
239
366
|
return toQuery.whereExists(
|
|
240
367
|
throughRelation.joinQuery(fromQuery, throughRelation.query),
|
|
@@ -263,6 +390,7 @@ const makeHasOneMethod = (model, relation, relationName, query) => {
|
|
|
263
390
|
};
|
|
264
391
|
}
|
|
265
392
|
const { primaryKey, foreignKey } = relation.options;
|
|
393
|
+
const state = { query, primaryKey, foreignKey };
|
|
266
394
|
const fromQuerySelect = [{ selectAs: { [foreignKey]: primaryKey } }];
|
|
267
395
|
return {
|
|
268
396
|
returns: "one",
|
|
@@ -270,75 +398,7 @@ const makeHasOneMethod = (model, relation, relationName, query) => {
|
|
|
270
398
|
const values = { [foreignKey]: params[primaryKey] };
|
|
271
399
|
return query.where(values)._defaults(values);
|
|
272
400
|
},
|
|
273
|
-
|
|
274
|
-
const connect = data.filter(
|
|
275
|
-
(item) => Boolean(item[1].connect || item[1].connectOrCreate)
|
|
276
|
-
);
|
|
277
|
-
const t = query.transacting(q);
|
|
278
|
-
let connected;
|
|
279
|
-
if (connect.length) {
|
|
280
|
-
connected = await Promise.all(
|
|
281
|
-
connect.map(([selfData, item]) => {
|
|
282
|
-
const data2 = { [foreignKey]: selfData[primaryKey] };
|
|
283
|
-
return "connect" in item ? t.where(item.connect)._updateOrThrow(data2) : t.where(item.connectOrCreate.where)._update(data2);
|
|
284
|
-
})
|
|
285
|
-
);
|
|
286
|
-
} else {
|
|
287
|
-
connected = [];
|
|
288
|
-
}
|
|
289
|
-
let connectedI = 0;
|
|
290
|
-
const create = data.filter(
|
|
291
|
-
(item) => {
|
|
292
|
-
if (item[1].connectOrCreate) {
|
|
293
|
-
return !connected[connectedI++];
|
|
294
|
-
}
|
|
295
|
-
return Boolean(item[1].create);
|
|
296
|
-
}
|
|
297
|
-
);
|
|
298
|
-
if (create.length) {
|
|
299
|
-
await t._count()._createMany(
|
|
300
|
-
create.map(([selfData, item]) => __spreadValues$4({
|
|
301
|
-
[foreignKey]: selfData[primaryKey]
|
|
302
|
-
}, "create" in item ? item.create : item.connectOrCreate.create))
|
|
303
|
-
);
|
|
304
|
-
}
|
|
305
|
-
},
|
|
306
|
-
nestedUpdate: async (q, data, params) => {
|
|
307
|
-
if ((params.set || params.create || params.upsert) && isQueryReturnsAll(q)) {
|
|
308
|
-
const key = params.set ? "set" : params.create ? "create" : "upsert";
|
|
309
|
-
throw new Error(`\`${key}\` option is not allowed in a batch update`);
|
|
310
|
-
}
|
|
311
|
-
const t = query.transacting(q);
|
|
312
|
-
const ids = data.map((item) => item[primaryKey]);
|
|
313
|
-
const currentRelationsQuery = t.where({
|
|
314
|
-
[foreignKey]: { in: ids }
|
|
315
|
-
});
|
|
316
|
-
if (params.create || params.disconnect || params.set) {
|
|
317
|
-
await currentRelationsQuery._update({ [foreignKey]: null });
|
|
318
|
-
if (params.create) {
|
|
319
|
-
await t._count()._create(__spreadProps$2(__spreadValues$4({}, params.create), {
|
|
320
|
-
[foreignKey]: data[0][primaryKey]
|
|
321
|
-
}));
|
|
322
|
-
}
|
|
323
|
-
if (params.set) {
|
|
324
|
-
await t._where(params.set)._update({ [foreignKey]: data[0][primaryKey] });
|
|
325
|
-
}
|
|
326
|
-
} else if (params.update) {
|
|
327
|
-
await currentRelationsQuery._update(params.update);
|
|
328
|
-
} else if (params.delete) {
|
|
329
|
-
await currentRelationsQuery._delete();
|
|
330
|
-
} else if (params.upsert) {
|
|
331
|
-
const { update, create } = params.upsert;
|
|
332
|
-
const updatedIds = await currentRelationsQuery._pluck(foreignKey)._update(update);
|
|
333
|
-
if (updatedIds.length < ids.length) {
|
|
334
|
-
await t.createMany(
|
|
335
|
-
ids.filter((id) => !updatedIds.includes(id)).map((id) => __spreadProps$2(__spreadValues$4({}, create), {
|
|
336
|
-
[foreignKey]: id
|
|
337
|
-
}))
|
|
338
|
-
);
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
},
|
|
401
|
+
virtualColumn: new HasOneVirtualColumn(relationName, state),
|
|
342
402
|
joinQuery(fromQuery, toQuery) {
|
|
343
403
|
return addQueryOn(toQuery, fromQuery, toQuery, foreignKey, primaryKey);
|
|
344
404
|
},
|
|
@@ -355,6 +415,79 @@ const makeHasOneMethod = (model, relation, relationName, query) => {
|
|
|
355
415
|
}
|
|
356
416
|
};
|
|
357
417
|
};
|
|
418
|
+
const nestedInsert$2 = ({ query, primaryKey, foreignKey }) => {
|
|
419
|
+
return async (q, data) => {
|
|
420
|
+
const connect = data.filter(
|
|
421
|
+
(item) => Boolean(item[1].connect || item[1].connectOrCreate)
|
|
422
|
+
);
|
|
423
|
+
const t = query.transacting(q);
|
|
424
|
+
let connected;
|
|
425
|
+
if (connect.length) {
|
|
426
|
+
connected = await Promise.all(
|
|
427
|
+
connect.map(([selfData, item]) => {
|
|
428
|
+
const data2 = { [foreignKey]: selfData[primaryKey] };
|
|
429
|
+
return "connect" in item ? t.where(item.connect)._updateOrThrow(data2) : t.where(item.connectOrCreate.where)._update(data2);
|
|
430
|
+
})
|
|
431
|
+
);
|
|
432
|
+
} else {
|
|
433
|
+
connected = [];
|
|
434
|
+
}
|
|
435
|
+
let connectedI = 0;
|
|
436
|
+
const create = data.filter(
|
|
437
|
+
(item) => {
|
|
438
|
+
if (item[1].connectOrCreate) {
|
|
439
|
+
return !connected[connectedI++];
|
|
440
|
+
}
|
|
441
|
+
return Boolean(item[1].create);
|
|
442
|
+
}
|
|
443
|
+
);
|
|
444
|
+
if (create.length) {
|
|
445
|
+
await t._count()._createMany(
|
|
446
|
+
create.map(([selfData, item]) => __spreadValues$4({
|
|
447
|
+
[foreignKey]: selfData[primaryKey]
|
|
448
|
+
}, "create" in item ? item.create : item.connectOrCreate.create))
|
|
449
|
+
);
|
|
450
|
+
}
|
|
451
|
+
};
|
|
452
|
+
};
|
|
453
|
+
const nestedUpdate$2 = ({ query, primaryKey, foreignKey }) => {
|
|
454
|
+
return async (q, data, params) => {
|
|
455
|
+
if ((params.set || params.create || params.upsert) && isQueryReturnsAll(q)) {
|
|
456
|
+
const key = params.set ? "set" : params.create ? "create" : "upsert";
|
|
457
|
+
throw new Error(`\`${key}\` option is not allowed in a batch update`);
|
|
458
|
+
}
|
|
459
|
+
const t = query.transacting(q);
|
|
460
|
+
const ids = data.map((item) => item[primaryKey]);
|
|
461
|
+
const currentRelationsQuery = t.where({
|
|
462
|
+
[foreignKey]: { in: ids }
|
|
463
|
+
});
|
|
464
|
+
if (params.create || params.disconnect || params.set) {
|
|
465
|
+
await currentRelationsQuery._update({ [foreignKey]: null });
|
|
466
|
+
if (params.create) {
|
|
467
|
+
await t._count()._create(__spreadProps$2(__spreadValues$4({}, params.create), {
|
|
468
|
+
[foreignKey]: data[0][primaryKey]
|
|
469
|
+
}));
|
|
470
|
+
}
|
|
471
|
+
if (params.set) {
|
|
472
|
+
await t._where(params.set)._update({ [foreignKey]: data[0][primaryKey] });
|
|
473
|
+
}
|
|
474
|
+
} else if (params.update) {
|
|
475
|
+
await currentRelationsQuery._update(params.update);
|
|
476
|
+
} else if (params.delete) {
|
|
477
|
+
await currentRelationsQuery._delete();
|
|
478
|
+
} else if (params.upsert) {
|
|
479
|
+
const { update, create } = params.upsert;
|
|
480
|
+
const updatedIds = await currentRelationsQuery._pluck(foreignKey)._update(update);
|
|
481
|
+
if (updatedIds.length < ids.length) {
|
|
482
|
+
await t.createMany(
|
|
483
|
+
ids.filter((id) => !updatedIds.includes(id)).map((id) => __spreadProps$2(__spreadValues$4({}, create), {
|
|
484
|
+
[foreignKey]: id
|
|
485
|
+
}))
|
|
486
|
+
);
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
};
|
|
490
|
+
};
|
|
358
491
|
|
|
359
492
|
var __defProp$3 = Object.defineProperty;
|
|
360
493
|
var __defProps$1 = Object.defineProperties;
|
|
@@ -375,10 +508,40 @@ var __spreadValues$3 = (a, b) => {
|
|
|
375
508
|
return a;
|
|
376
509
|
};
|
|
377
510
|
var __spreadProps$1 = (a, b) => __defProps$1(a, __getOwnPropDescs$1(b));
|
|
378
|
-
|
|
511
|
+
class HasManyVirtualColumn extends VirtualColumn {
|
|
512
|
+
constructor(key, state) {
|
|
513
|
+
super();
|
|
514
|
+
this.key = key;
|
|
515
|
+
this.state = state;
|
|
516
|
+
this.nestedInsert = nestedInsert$1(state);
|
|
517
|
+
this.nestedUpdate = nestedUpdate$1(state);
|
|
518
|
+
}
|
|
519
|
+
create(q, ctx, item, rowIndex) {
|
|
520
|
+
hasRelationHandleCreate(
|
|
521
|
+
q,
|
|
522
|
+
ctx,
|
|
523
|
+
item,
|
|
524
|
+
rowIndex,
|
|
525
|
+
this.key,
|
|
526
|
+
this.state.primaryKey,
|
|
527
|
+
this.nestedInsert
|
|
528
|
+
);
|
|
529
|
+
}
|
|
530
|
+
update(q, ctx, set) {
|
|
531
|
+
hasRelationHandleUpdate(
|
|
532
|
+
q,
|
|
533
|
+
ctx,
|
|
534
|
+
set,
|
|
535
|
+
this.key,
|
|
536
|
+
this.state.primaryKey,
|
|
537
|
+
this.nestedUpdate
|
|
538
|
+
);
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
const makeHasManyMethod = (table, relation, relationName, query) => {
|
|
379
542
|
if ("through" in relation.options) {
|
|
380
543
|
const { through, source } = relation.options;
|
|
381
|
-
const throughRelation = getThroughRelation(
|
|
544
|
+
const throughRelation = getThroughRelation(table, through);
|
|
382
545
|
const sourceRelation = getSourceRelation(throughRelation, source);
|
|
383
546
|
const sourceRelationQuery = sourceRelation.query.as(relationName);
|
|
384
547
|
const sourceQuery = sourceRelation.joinQuery(
|
|
@@ -389,14 +552,12 @@ const makeHasManyMethod = (model, relation, relationName, query) => {
|
|
|
389
552
|
return {
|
|
390
553
|
returns: "many",
|
|
391
554
|
method: (params) => {
|
|
392
|
-
const throughQuery =
|
|
555
|
+
const throughQuery = table[through](params);
|
|
393
556
|
return query.whereExists(
|
|
394
557
|
throughQuery,
|
|
395
558
|
whereExistsCallback
|
|
396
559
|
);
|
|
397
560
|
},
|
|
398
|
-
nestedInsert: void 0,
|
|
399
|
-
nestedUpdate: void 0,
|
|
400
561
|
joinQuery(fromQuery, toQuery) {
|
|
401
562
|
return toQuery.whereExists(
|
|
402
563
|
throughRelation.joinQuery(fromQuery, throughRelation.query),
|
|
@@ -425,6 +586,7 @@ const makeHasManyMethod = (model, relation, relationName, query) => {
|
|
|
425
586
|
};
|
|
426
587
|
}
|
|
427
588
|
const { primaryKey, foreignKey } = relation.options;
|
|
589
|
+
const state = { query, primaryKey, foreignKey };
|
|
428
590
|
const fromQuerySelect = [{ selectAs: { [foreignKey]: primaryKey } }];
|
|
429
591
|
return {
|
|
430
592
|
returns: "many",
|
|
@@ -432,117 +594,7 @@ const makeHasManyMethod = (model, relation, relationName, query) => {
|
|
|
432
594
|
const values = { [foreignKey]: params[primaryKey] };
|
|
433
595
|
return query.where(values)._defaults(values);
|
|
434
596
|
},
|
|
435
|
-
|
|
436
|
-
const connect = data.filter(
|
|
437
|
-
(item) => Boolean(item[1].connect)
|
|
438
|
-
);
|
|
439
|
-
const t = query.transacting(q);
|
|
440
|
-
if (connect.length) {
|
|
441
|
-
await Promise.all(
|
|
442
|
-
connect.flatMap(
|
|
443
|
-
([selfData, { connect: connect2 }]) => t.or(...connect2)._updateOrThrow({ [foreignKey]: selfData[primaryKey] })
|
|
444
|
-
)
|
|
445
|
-
);
|
|
446
|
-
}
|
|
447
|
-
const connectOrCreate = data.filter(
|
|
448
|
-
(item) => Boolean(item[1].connectOrCreate)
|
|
449
|
-
);
|
|
450
|
-
let connected;
|
|
451
|
-
if (connectOrCreate.length) {
|
|
452
|
-
connected = await Promise.all(
|
|
453
|
-
connectOrCreate.flatMap(
|
|
454
|
-
([selfData, { connectOrCreate: connectOrCreate2 }]) => connectOrCreate2.map(
|
|
455
|
-
(item) => t.where(item.where)._update({
|
|
456
|
-
[foreignKey]: selfData[primaryKey]
|
|
457
|
-
})
|
|
458
|
-
)
|
|
459
|
-
)
|
|
460
|
-
);
|
|
461
|
-
} else {
|
|
462
|
-
connected = [];
|
|
463
|
-
}
|
|
464
|
-
let connectedI = 0;
|
|
465
|
-
const create = data.filter(
|
|
466
|
-
(item) => {
|
|
467
|
-
if (item[1].connectOrCreate) {
|
|
468
|
-
const length = item[1].connectOrCreate.length;
|
|
469
|
-
connectedI += length;
|
|
470
|
-
for (let i = length; i > 0; i--) {
|
|
471
|
-
if (connected[connectedI - i] === 0)
|
|
472
|
-
return true;
|
|
473
|
-
}
|
|
474
|
-
}
|
|
475
|
-
return Boolean(item[1].create);
|
|
476
|
-
}
|
|
477
|
-
);
|
|
478
|
-
connectedI = 0;
|
|
479
|
-
if (create.length) {
|
|
480
|
-
await t._createMany(
|
|
481
|
-
create.flatMap(
|
|
482
|
-
([selfData, { create: create2 = [], connectOrCreate: connectOrCreate2 = [] }]) => {
|
|
483
|
-
return [
|
|
484
|
-
...create2.map((item) => __spreadValues$3({
|
|
485
|
-
[foreignKey]: selfData[primaryKey]
|
|
486
|
-
}, item)),
|
|
487
|
-
...connectOrCreate2.filter(() => connected[connectedI++] === 0).map((item) => __spreadValues$3({
|
|
488
|
-
[foreignKey]: selfData[primaryKey]
|
|
489
|
-
}, item.create))
|
|
490
|
-
];
|
|
491
|
-
}
|
|
492
|
-
)
|
|
493
|
-
);
|
|
494
|
-
}
|
|
495
|
-
},
|
|
496
|
-
nestedUpdate: async (q, data, params) => {
|
|
497
|
-
var _a;
|
|
498
|
-
if ((params.set || params.create) && isQueryReturnsAll(q)) {
|
|
499
|
-
const key = params.set ? "set" : "create";
|
|
500
|
-
throw new Error(`\`${key}\` option is not allowed in a batch update`);
|
|
501
|
-
}
|
|
502
|
-
const t = query.transacting(q);
|
|
503
|
-
if (params.create) {
|
|
504
|
-
await t._count()._createMany(
|
|
505
|
-
params.create.map((create) => __spreadProps$1(__spreadValues$3({}, create), {
|
|
506
|
-
[foreignKey]: data[0][primaryKey]
|
|
507
|
-
}))
|
|
508
|
-
);
|
|
509
|
-
delete t.query[toSqlCacheKey];
|
|
510
|
-
}
|
|
511
|
-
if (params.disconnect || params.set) {
|
|
512
|
-
await t.where(
|
|
513
|
-
getWhereForNestedUpdate(
|
|
514
|
-
data,
|
|
515
|
-
params.disconnect,
|
|
516
|
-
primaryKey,
|
|
517
|
-
foreignKey
|
|
518
|
-
)
|
|
519
|
-
)._update({ [foreignKey]: null });
|
|
520
|
-
if (params.set) {
|
|
521
|
-
delete t.query[toSqlCacheKey];
|
|
522
|
-
await t.where(
|
|
523
|
-
Array.isArray(params.set) ? {
|
|
524
|
-
OR: params.set
|
|
525
|
-
} : params.set
|
|
526
|
-
)._update({ [foreignKey]: data[0][primaryKey] });
|
|
527
|
-
}
|
|
528
|
-
}
|
|
529
|
-
if (params.delete || params.update) {
|
|
530
|
-
delete t.query[toSqlCacheKey];
|
|
531
|
-
const q2 = t._where(
|
|
532
|
-
getWhereForNestedUpdate(
|
|
533
|
-
data,
|
|
534
|
-
params.delete || ((_a = params.update) == null ? void 0 : _a.where),
|
|
535
|
-
primaryKey,
|
|
536
|
-
foreignKey
|
|
537
|
-
)
|
|
538
|
-
);
|
|
539
|
-
if (params.delete) {
|
|
540
|
-
await q2._delete();
|
|
541
|
-
} else if (params.update) {
|
|
542
|
-
await q2._update(params.update.data);
|
|
543
|
-
}
|
|
544
|
-
}
|
|
545
|
-
},
|
|
597
|
+
virtualColumn: new HasManyVirtualColumn(relationName, state),
|
|
546
598
|
joinQuery(fromQuery, toQuery) {
|
|
547
599
|
return addQueryOn(toQuery, fromQuery, toQuery, foreignKey, primaryKey);
|
|
548
600
|
},
|
|
@@ -572,6 +624,119 @@ const getWhereForNestedUpdate = (data, params, primaryKey, foreignKey) => {
|
|
|
572
624
|
}
|
|
573
625
|
return where;
|
|
574
626
|
};
|
|
627
|
+
const nestedInsert$1 = ({ query, primaryKey, foreignKey }) => {
|
|
628
|
+
return async (q, data) => {
|
|
629
|
+
const connect = data.filter(
|
|
630
|
+
(item) => Boolean(item[1].connect)
|
|
631
|
+
);
|
|
632
|
+
const t = query.transacting(q);
|
|
633
|
+
if (connect.length) {
|
|
634
|
+
await Promise.all(
|
|
635
|
+
connect.flatMap(
|
|
636
|
+
([selfData, { connect: connect2 }]) => t.or(...connect2)._updateOrThrow({ [foreignKey]: selfData[primaryKey] })
|
|
637
|
+
)
|
|
638
|
+
);
|
|
639
|
+
}
|
|
640
|
+
const connectOrCreate = data.filter(
|
|
641
|
+
(item) => Boolean(item[1].connectOrCreate)
|
|
642
|
+
);
|
|
643
|
+
let connected;
|
|
644
|
+
if (connectOrCreate.length) {
|
|
645
|
+
connected = await Promise.all(
|
|
646
|
+
connectOrCreate.flatMap(
|
|
647
|
+
([selfData, { connectOrCreate: connectOrCreate2 }]) => connectOrCreate2.map(
|
|
648
|
+
(item) => t.where(item.where)._update({
|
|
649
|
+
[foreignKey]: selfData[primaryKey]
|
|
650
|
+
})
|
|
651
|
+
)
|
|
652
|
+
)
|
|
653
|
+
);
|
|
654
|
+
} else {
|
|
655
|
+
connected = [];
|
|
656
|
+
}
|
|
657
|
+
let connectedI = 0;
|
|
658
|
+
const create = data.filter(
|
|
659
|
+
(item) => {
|
|
660
|
+
if (item[1].connectOrCreate) {
|
|
661
|
+
const length = item[1].connectOrCreate.length;
|
|
662
|
+
connectedI += length;
|
|
663
|
+
for (let i = length; i > 0; i--) {
|
|
664
|
+
if (connected[connectedI - i] === 0)
|
|
665
|
+
return true;
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
return Boolean(item[1].create);
|
|
669
|
+
}
|
|
670
|
+
);
|
|
671
|
+
connectedI = 0;
|
|
672
|
+
if (create.length) {
|
|
673
|
+
await t._createMany(
|
|
674
|
+
create.flatMap(([selfData, { create: create2 = [], connectOrCreate: connectOrCreate2 = [] }]) => {
|
|
675
|
+
return [
|
|
676
|
+
...create2.map((item) => __spreadValues$3({
|
|
677
|
+
[foreignKey]: selfData[primaryKey]
|
|
678
|
+
}, item)),
|
|
679
|
+
...connectOrCreate2.filter(() => connected[connectedI++] === 0).map((item) => __spreadValues$3({
|
|
680
|
+
[foreignKey]: selfData[primaryKey]
|
|
681
|
+
}, item.create))
|
|
682
|
+
];
|
|
683
|
+
})
|
|
684
|
+
);
|
|
685
|
+
}
|
|
686
|
+
};
|
|
687
|
+
};
|
|
688
|
+
const nestedUpdate$1 = ({ query, primaryKey, foreignKey }) => {
|
|
689
|
+
return async (q, data, params) => {
|
|
690
|
+
var _a;
|
|
691
|
+
if ((params.set || params.create) && isQueryReturnsAll(q)) {
|
|
692
|
+
const key = params.set ? "set" : "create";
|
|
693
|
+
throw new Error(`\`${key}\` option is not allowed in a batch update`);
|
|
694
|
+
}
|
|
695
|
+
const t = query.transacting(q);
|
|
696
|
+
if (params.create) {
|
|
697
|
+
await t._count()._createMany(
|
|
698
|
+
params.create.map((create) => __spreadProps$1(__spreadValues$3({}, create), {
|
|
699
|
+
[foreignKey]: data[0][primaryKey]
|
|
700
|
+
}))
|
|
701
|
+
);
|
|
702
|
+
delete t.query[toSqlCacheKey];
|
|
703
|
+
}
|
|
704
|
+
if (params.disconnect || params.set) {
|
|
705
|
+
await t.where(
|
|
706
|
+
getWhereForNestedUpdate(
|
|
707
|
+
data,
|
|
708
|
+
params.disconnect,
|
|
709
|
+
primaryKey,
|
|
710
|
+
foreignKey
|
|
711
|
+
)
|
|
712
|
+
)._update({ [foreignKey]: null });
|
|
713
|
+
if (params.set) {
|
|
714
|
+
delete t.query[toSqlCacheKey];
|
|
715
|
+
await t.where(
|
|
716
|
+
Array.isArray(params.set) ? {
|
|
717
|
+
OR: params.set
|
|
718
|
+
} : params.set
|
|
719
|
+
)._update({ [foreignKey]: data[0][primaryKey] });
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
if (params.delete || params.update) {
|
|
723
|
+
delete t.query[toSqlCacheKey];
|
|
724
|
+
const q2 = t._where(
|
|
725
|
+
getWhereForNestedUpdate(
|
|
726
|
+
data,
|
|
727
|
+
params.delete || ((_a = params.update) == null ? void 0 : _a.where),
|
|
728
|
+
primaryKey,
|
|
729
|
+
foreignKey
|
|
730
|
+
)
|
|
731
|
+
);
|
|
732
|
+
if (params.delete) {
|
|
733
|
+
await q2._delete();
|
|
734
|
+
} else if (params.update) {
|
|
735
|
+
await q2._update(params.update.data);
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
};
|
|
739
|
+
};
|
|
575
740
|
|
|
576
741
|
var __defProp$2 = Object.defineProperty;
|
|
577
742
|
var __getOwnPropSymbols$2 = Object.getOwnPropertySymbols;
|
|
@@ -589,7 +754,37 @@ var __spreadValues$2 = (a, b) => {
|
|
|
589
754
|
}
|
|
590
755
|
return a;
|
|
591
756
|
};
|
|
592
|
-
|
|
757
|
+
class HasAndBelongsToManyVirtualColumn extends VirtualColumn {
|
|
758
|
+
constructor(key, state) {
|
|
759
|
+
super();
|
|
760
|
+
this.key = key;
|
|
761
|
+
this.state = state;
|
|
762
|
+
this.nestedInsert = nestedInsert(state);
|
|
763
|
+
this.nestedUpdate = nestedUpdate(state);
|
|
764
|
+
}
|
|
765
|
+
create(q, ctx, item, rowIndex) {
|
|
766
|
+
hasRelationHandleCreate(
|
|
767
|
+
q,
|
|
768
|
+
ctx,
|
|
769
|
+
item,
|
|
770
|
+
rowIndex,
|
|
771
|
+
this.key,
|
|
772
|
+
this.state.primaryKey,
|
|
773
|
+
this.nestedInsert
|
|
774
|
+
);
|
|
775
|
+
}
|
|
776
|
+
update(q, ctx, set) {
|
|
777
|
+
hasRelationHandleUpdate(
|
|
778
|
+
q,
|
|
779
|
+
ctx,
|
|
780
|
+
set,
|
|
781
|
+
this.key,
|
|
782
|
+
this.state.primaryKey,
|
|
783
|
+
this.nestedUpdate
|
|
784
|
+
);
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
const makeHasAndBelongsToManyMethod = (table, qb, relation, relationName, query) => {
|
|
593
788
|
const {
|
|
594
789
|
primaryKey: pk,
|
|
595
790
|
foreignKey: fk,
|
|
@@ -600,14 +795,14 @@ const makeHasAndBelongsToManyMethod = (model, qb, relation, query) => {
|
|
|
600
795
|
const foreignKeyFull = `${joinTable}.${fk}`;
|
|
601
796
|
const associationForeignKeyFull = `${joinTable}.${afk}`;
|
|
602
797
|
const associationPrimaryKeyFull = `${getQueryAs(query)}.${apk}`;
|
|
603
|
-
const
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
[fk]:
|
|
798
|
+
const __table = Object.create(qb.__table);
|
|
799
|
+
__table.__table = __table;
|
|
800
|
+
__table.table = joinTable;
|
|
801
|
+
__table.shape = {
|
|
802
|
+
[fk]: table.shape[pk],
|
|
608
803
|
[afk]: query.shape[apk]
|
|
609
804
|
};
|
|
610
|
-
const subQuery = Object.create(
|
|
805
|
+
const subQuery = Object.create(__table);
|
|
611
806
|
subQuery.query = __spreadValues$2({}, subQuery.query);
|
|
612
807
|
const state = {
|
|
613
808
|
relatedTableQuery: query,
|
|
@@ -615,7 +810,10 @@ const makeHasAndBelongsToManyMethod = (model, qb, relation, query) => {
|
|
|
615
810
|
primaryKey: pk,
|
|
616
811
|
foreignKey: fk,
|
|
617
812
|
associationPrimaryKey: apk,
|
|
618
|
-
associationForeignKey: afk
|
|
813
|
+
associationForeignKey: afk,
|
|
814
|
+
foreignKeyFull,
|
|
815
|
+
associationForeignKeyFull,
|
|
816
|
+
associationPrimaryKeyFull
|
|
619
817
|
};
|
|
620
818
|
return {
|
|
621
819
|
returns: "many",
|
|
@@ -627,144 +825,7 @@ const makeHasAndBelongsToManyMethod = (model, qb, relation, query) => {
|
|
|
627
825
|
})
|
|
628
826
|
);
|
|
629
827
|
},
|
|
630
|
-
|
|
631
|
-
const connect = data.filter(
|
|
632
|
-
(item) => Boolean(item[1].connect)
|
|
633
|
-
);
|
|
634
|
-
const t = query.transacting(q);
|
|
635
|
-
let connected;
|
|
636
|
-
if (connect.length) {
|
|
637
|
-
connected = await Promise.all(
|
|
638
|
-
connect.flatMap(
|
|
639
|
-
([, { connect: connect2 }]) => connect2.map((item) => t.select(apk)._findBy(item)._take())
|
|
640
|
-
)
|
|
641
|
-
);
|
|
642
|
-
} else {
|
|
643
|
-
connected = [];
|
|
644
|
-
}
|
|
645
|
-
const connectOrCreate = data.filter(
|
|
646
|
-
(item) => Boolean(item[1].connectOrCreate)
|
|
647
|
-
);
|
|
648
|
-
let connectOrCreated;
|
|
649
|
-
if (connectOrCreate.length) {
|
|
650
|
-
connectOrCreated = await Promise.all(
|
|
651
|
-
connectOrCreate.flatMap(
|
|
652
|
-
([, { connectOrCreate: connectOrCreate2 }]) => connectOrCreate2.map(
|
|
653
|
-
(item) => t.select(apk)._findBy(item.where)._takeOptional()
|
|
654
|
-
)
|
|
655
|
-
)
|
|
656
|
-
);
|
|
657
|
-
} else {
|
|
658
|
-
connectOrCreated = [];
|
|
659
|
-
}
|
|
660
|
-
let connectOrCreateI = 0;
|
|
661
|
-
const create = data.filter(
|
|
662
|
-
(item) => {
|
|
663
|
-
if (item[1].connectOrCreate) {
|
|
664
|
-
const length = item[1].connectOrCreate.length;
|
|
665
|
-
connectOrCreateI += length;
|
|
666
|
-
for (let i = length; i > 0; i--) {
|
|
667
|
-
if (!connectOrCreated[connectOrCreateI - i])
|
|
668
|
-
return true;
|
|
669
|
-
}
|
|
670
|
-
}
|
|
671
|
-
return Boolean(item[1].create);
|
|
672
|
-
}
|
|
673
|
-
);
|
|
674
|
-
connectOrCreateI = 0;
|
|
675
|
-
let created;
|
|
676
|
-
if (create.length) {
|
|
677
|
-
created = await t.select(apk)._createMany(
|
|
678
|
-
create.flatMap(([, { create: create2 = [], connectOrCreate: connectOrCreate2 = [] }]) => [
|
|
679
|
-
...create2,
|
|
680
|
-
...connectOrCreate2.filter(() => !connectOrCreated[connectOrCreateI++]).map((item) => item.create)
|
|
681
|
-
])
|
|
682
|
-
);
|
|
683
|
-
} else {
|
|
684
|
-
created = [];
|
|
685
|
-
}
|
|
686
|
-
const allKeys = data;
|
|
687
|
-
let createI = 0;
|
|
688
|
-
let connectI = 0;
|
|
689
|
-
connectOrCreateI = 0;
|
|
690
|
-
data.forEach(([, data2], index) => {
|
|
691
|
-
if (data2.create || data2.connectOrCreate) {
|
|
692
|
-
if (data2.create) {
|
|
693
|
-
const len = data2.create.length;
|
|
694
|
-
allKeys[index][1] = created.slice(createI, createI + len);
|
|
695
|
-
createI += len;
|
|
696
|
-
}
|
|
697
|
-
if (data2.connectOrCreate) {
|
|
698
|
-
const arr = [];
|
|
699
|
-
allKeys[index][1] = arr;
|
|
700
|
-
const len = data2.connectOrCreate.length;
|
|
701
|
-
for (let i = 0; i < len; i++) {
|
|
702
|
-
const item = connectOrCreated[connectOrCreateI++];
|
|
703
|
-
if (item) {
|
|
704
|
-
arr.push(item);
|
|
705
|
-
} else {
|
|
706
|
-
arr.push(created[createI++]);
|
|
707
|
-
}
|
|
708
|
-
}
|
|
709
|
-
}
|
|
710
|
-
}
|
|
711
|
-
if (data2.connect) {
|
|
712
|
-
const len = data2.connect.length;
|
|
713
|
-
allKeys[index][1] = connected.slice(connectI, connectI + len);
|
|
714
|
-
connectI += len;
|
|
715
|
-
}
|
|
716
|
-
});
|
|
717
|
-
await subQuery.transacting(q)._count()._createMany(
|
|
718
|
-
allKeys.flatMap(([selfData, relationKeys]) => {
|
|
719
|
-
const selfKey = selfData[pk];
|
|
720
|
-
return relationKeys.map((relationData) => ({
|
|
721
|
-
[fk]: selfKey,
|
|
722
|
-
[afk]: relationData[apk]
|
|
723
|
-
}));
|
|
724
|
-
})
|
|
725
|
-
);
|
|
726
|
-
},
|
|
727
|
-
nestedUpdate: async (q, data, params) => {
|
|
728
|
-
if (params.create) {
|
|
729
|
-
const ids = await query.transacting(q)._pluck(apk)._createMany(params.create);
|
|
730
|
-
await subQuery.transacting(q)._createMany(
|
|
731
|
-
data.flatMap(
|
|
732
|
-
(item) => ids.map((id) => ({
|
|
733
|
-
[fk]: item[pk],
|
|
734
|
-
[afk]: id
|
|
735
|
-
}))
|
|
736
|
-
)
|
|
737
|
-
);
|
|
738
|
-
}
|
|
739
|
-
if (params.update) {
|
|
740
|
-
await query.transacting(q)._whereExists(
|
|
741
|
-
subQuery,
|
|
742
|
-
(q2) => q2._on(associationForeignKeyFull, associationPrimaryKeyFull)._where({
|
|
743
|
-
IN: {
|
|
744
|
-
columns: [foreignKeyFull],
|
|
745
|
-
values: [data.map((item) => item[pk])]
|
|
746
|
-
}
|
|
747
|
-
})
|
|
748
|
-
)._where(
|
|
749
|
-
Array.isArray(params.update.where) ? { OR: params.update.where } : params.update.where
|
|
750
|
-
)._update(params.update.data);
|
|
751
|
-
}
|
|
752
|
-
if (params.disconnect) {
|
|
753
|
-
await queryJoinTable(state, q, data, params.disconnect)._delete();
|
|
754
|
-
}
|
|
755
|
-
if (params.delete) {
|
|
756
|
-
const j = queryJoinTable(state, q, data, params.delete);
|
|
757
|
-
const ids = await j._pluck(afk)._delete();
|
|
758
|
-
await queryRelatedTable(query, q, { [apk]: { in: ids } })._delete();
|
|
759
|
-
}
|
|
760
|
-
if (params.set) {
|
|
761
|
-
const j = queryJoinTable(state, q, data);
|
|
762
|
-
await j._delete();
|
|
763
|
-
delete j.query[toSqlCacheKey];
|
|
764
|
-
const ids = await queryRelatedTable(query, q, params.set)._pluck(apk);
|
|
765
|
-
await insertToJoinTable(state, j, data, ids);
|
|
766
|
-
}
|
|
767
|
-
},
|
|
828
|
+
virtualColumn: new HasAndBelongsToManyVirtualColumn(relationName, state),
|
|
768
829
|
joinQuery(fromQuery, toQuery) {
|
|
769
830
|
return toQuery.whereExists(
|
|
770
831
|
subQuery,
|
|
@@ -830,39 +891,201 @@ const insertToJoinTable = (state, joinTableTransaction, data, ids) => {
|
|
|
830
891
|
)
|
|
831
892
|
);
|
|
832
893
|
};
|
|
894
|
+
const nestedInsert = ({
|
|
895
|
+
relatedTableQuery,
|
|
896
|
+
joinTableQuery,
|
|
897
|
+
primaryKey,
|
|
898
|
+
foreignKey,
|
|
899
|
+
associationPrimaryKey,
|
|
900
|
+
associationForeignKey
|
|
901
|
+
}) => {
|
|
902
|
+
return async (q, data) => {
|
|
903
|
+
const connect = data.filter(
|
|
904
|
+
(item) => Boolean(item[1].connect)
|
|
905
|
+
);
|
|
906
|
+
const t = relatedTableQuery.transacting(q);
|
|
907
|
+
let connected;
|
|
908
|
+
if (connect.length) {
|
|
909
|
+
connected = await Promise.all(
|
|
910
|
+
connect.flatMap(
|
|
911
|
+
([, { connect: connect2 }]) => connect2.map(
|
|
912
|
+
(item) => t.select(associationPrimaryKey)._findBy(item)._take()
|
|
913
|
+
)
|
|
914
|
+
)
|
|
915
|
+
);
|
|
916
|
+
} else {
|
|
917
|
+
connected = [];
|
|
918
|
+
}
|
|
919
|
+
const connectOrCreate = data.filter(
|
|
920
|
+
(item) => Boolean(item[1].connectOrCreate)
|
|
921
|
+
);
|
|
922
|
+
let connectOrCreated;
|
|
923
|
+
if (connectOrCreate.length) {
|
|
924
|
+
connectOrCreated = await Promise.all(
|
|
925
|
+
connectOrCreate.flatMap(
|
|
926
|
+
([, { connectOrCreate: connectOrCreate2 }]) => connectOrCreate2.map(
|
|
927
|
+
(item) => t.select(associationPrimaryKey)._findBy(item.where)._takeOptional()
|
|
928
|
+
)
|
|
929
|
+
)
|
|
930
|
+
);
|
|
931
|
+
} else {
|
|
932
|
+
connectOrCreated = [];
|
|
933
|
+
}
|
|
934
|
+
let connectOrCreateI = 0;
|
|
935
|
+
const create = data.filter(
|
|
936
|
+
(item) => {
|
|
937
|
+
if (item[1].connectOrCreate) {
|
|
938
|
+
const length = item[1].connectOrCreate.length;
|
|
939
|
+
connectOrCreateI += length;
|
|
940
|
+
for (let i = length; i > 0; i--) {
|
|
941
|
+
if (!connectOrCreated[connectOrCreateI - i])
|
|
942
|
+
return true;
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
return Boolean(item[1].create);
|
|
946
|
+
}
|
|
947
|
+
);
|
|
948
|
+
connectOrCreateI = 0;
|
|
949
|
+
let created;
|
|
950
|
+
if (create.length) {
|
|
951
|
+
created = await t.select(associationPrimaryKey)._createMany(
|
|
952
|
+
create.flatMap(([, { create: create2 = [], connectOrCreate: connectOrCreate2 = [] }]) => [
|
|
953
|
+
...create2,
|
|
954
|
+
...connectOrCreate2.filter(() => !connectOrCreated[connectOrCreateI++]).map((item) => item.create)
|
|
955
|
+
])
|
|
956
|
+
);
|
|
957
|
+
} else {
|
|
958
|
+
created = [];
|
|
959
|
+
}
|
|
960
|
+
const allKeys = data;
|
|
961
|
+
let createI = 0;
|
|
962
|
+
let connectI = 0;
|
|
963
|
+
connectOrCreateI = 0;
|
|
964
|
+
data.forEach(([, data2], index) => {
|
|
965
|
+
if (data2.create || data2.connectOrCreate) {
|
|
966
|
+
if (data2.create) {
|
|
967
|
+
const len = data2.create.length;
|
|
968
|
+
allKeys[index][1] = created.slice(createI, createI + len);
|
|
969
|
+
createI += len;
|
|
970
|
+
}
|
|
971
|
+
if (data2.connectOrCreate) {
|
|
972
|
+
const arr = [];
|
|
973
|
+
allKeys[index][1] = arr;
|
|
974
|
+
const len = data2.connectOrCreate.length;
|
|
975
|
+
for (let i = 0; i < len; i++) {
|
|
976
|
+
const item = connectOrCreated[connectOrCreateI++];
|
|
977
|
+
if (item) {
|
|
978
|
+
arr.push(item);
|
|
979
|
+
} else {
|
|
980
|
+
arr.push(created[createI++]);
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
}
|
|
985
|
+
if (data2.connect) {
|
|
986
|
+
const len = data2.connect.length;
|
|
987
|
+
allKeys[index][1] = connected.slice(connectI, connectI + len);
|
|
988
|
+
connectI += len;
|
|
989
|
+
}
|
|
990
|
+
});
|
|
991
|
+
await joinTableQuery.transacting(q)._count()._createMany(
|
|
992
|
+
allKeys.flatMap(([selfData, relationKeys]) => {
|
|
993
|
+
const selfKey = selfData[primaryKey];
|
|
994
|
+
return relationKeys.map((relationData) => ({
|
|
995
|
+
[foreignKey]: selfKey,
|
|
996
|
+
[associationForeignKey]: relationData[associationPrimaryKey]
|
|
997
|
+
}));
|
|
998
|
+
})
|
|
999
|
+
);
|
|
1000
|
+
};
|
|
1001
|
+
};
|
|
1002
|
+
const nestedUpdate = (state) => {
|
|
1003
|
+
return async (q, data, params) => {
|
|
1004
|
+
if (params.create) {
|
|
1005
|
+
const ids = await state.relatedTableQuery.transacting(q)._pluck(state.associationPrimaryKey)._createMany(params.create);
|
|
1006
|
+
await state.joinTableQuery.transacting(q)._createMany(
|
|
1007
|
+
data.flatMap(
|
|
1008
|
+
(item) => ids.map((id) => ({
|
|
1009
|
+
[state.foreignKey]: item[state.primaryKey],
|
|
1010
|
+
[state.associationForeignKey]: id
|
|
1011
|
+
}))
|
|
1012
|
+
)
|
|
1013
|
+
);
|
|
1014
|
+
}
|
|
1015
|
+
if (params.update) {
|
|
1016
|
+
await state.relatedTableQuery.transacting(q)._whereExists(
|
|
1017
|
+
state.joinTableQuery,
|
|
1018
|
+
(q2) => q2._on(
|
|
1019
|
+
state.associationForeignKeyFull,
|
|
1020
|
+
state.associationPrimaryKeyFull
|
|
1021
|
+
)._where({
|
|
1022
|
+
IN: {
|
|
1023
|
+
columns: [state.foreignKeyFull],
|
|
1024
|
+
values: [data.map((item) => item[state.primaryKey])]
|
|
1025
|
+
}
|
|
1026
|
+
})
|
|
1027
|
+
)._where(
|
|
1028
|
+
Array.isArray(params.update.where) ? { OR: params.update.where } : params.update.where
|
|
1029
|
+
)._update(params.update.data);
|
|
1030
|
+
}
|
|
1031
|
+
if (params.disconnect) {
|
|
1032
|
+
await queryJoinTable(state, q, data, params.disconnect)._delete();
|
|
1033
|
+
}
|
|
1034
|
+
if (params.delete) {
|
|
1035
|
+
const j = queryJoinTable(state, q, data, params.delete);
|
|
1036
|
+
const ids = await j._pluck(state.associationForeignKey)._delete();
|
|
1037
|
+
await queryRelatedTable(state.relatedTableQuery, q, {
|
|
1038
|
+
[state.associationPrimaryKey]: { in: ids }
|
|
1039
|
+
})._delete();
|
|
1040
|
+
}
|
|
1041
|
+
if (params.set) {
|
|
1042
|
+
const j = queryJoinTable(state, q, data);
|
|
1043
|
+
await j._delete();
|
|
1044
|
+
delete j.query[toSqlCacheKey];
|
|
1045
|
+
const ids = await queryRelatedTable(
|
|
1046
|
+
state.relatedTableQuery,
|
|
1047
|
+
q,
|
|
1048
|
+
params.set
|
|
1049
|
+
)._pluck(state.associationPrimaryKey);
|
|
1050
|
+
await insertToJoinTable(state, j, data, ids);
|
|
1051
|
+
}
|
|
1052
|
+
};
|
|
1053
|
+
};
|
|
833
1054
|
|
|
834
|
-
const applyRelations = (qb,
|
|
835
|
-
const
|
|
1055
|
+
const applyRelations = (qb, tables, result) => {
|
|
1056
|
+
const tableEntries = Object.entries(tables);
|
|
836
1057
|
const delayedRelations = /* @__PURE__ */ new Map();
|
|
837
|
-
for (const
|
|
838
|
-
const
|
|
839
|
-
if (!("relations" in
|
|
1058
|
+
for (const name in tables) {
|
|
1059
|
+
const table = tables[name];
|
|
1060
|
+
if (!("relations" in table) || typeof table.relations !== "object")
|
|
840
1061
|
continue;
|
|
841
|
-
const
|
|
842
|
-
for (const relationName in
|
|
843
|
-
const relation =
|
|
844
|
-
const
|
|
845
|
-
const
|
|
846
|
-
(pair) => pair[1] instanceof
|
|
1062
|
+
const dbTable = result[name];
|
|
1063
|
+
for (const relationName in table.relations) {
|
|
1064
|
+
const relation = table.relations[relationName];
|
|
1065
|
+
const otherTableClass = relation.fn();
|
|
1066
|
+
const otherTable = tableEntries.find(
|
|
1067
|
+
(pair) => pair[1] instanceof otherTableClass
|
|
847
1068
|
);
|
|
848
|
-
if (!
|
|
849
|
-
throw new Error(
|
|
1069
|
+
if (!otherTable) {
|
|
1070
|
+
throw new Error(
|
|
1071
|
+
`Cannot find table class for class ${otherTableClass.name}`
|
|
1072
|
+
);
|
|
850
1073
|
}
|
|
851
|
-
const
|
|
852
|
-
const
|
|
853
|
-
if (!
|
|
854
|
-
throw new Error(`Cannot find
|
|
1074
|
+
const otherTableName = otherTable[0];
|
|
1075
|
+
const otherDbTable = result[otherTableName];
|
|
1076
|
+
if (!otherDbTable)
|
|
1077
|
+
throw new Error(`Cannot find table class by name ${otherTableName}`);
|
|
855
1078
|
const data = {
|
|
856
1079
|
relationName,
|
|
857
1080
|
relation,
|
|
858
|
-
|
|
859
|
-
|
|
1081
|
+
dbTable,
|
|
1082
|
+
otherDbTable
|
|
860
1083
|
};
|
|
861
1084
|
const options = relation.options;
|
|
862
1085
|
if (typeof options.through === "string" && typeof options.source === "string") {
|
|
863
|
-
const throughRelation = getThroughRelation(
|
|
1086
|
+
const throughRelation = getThroughRelation(dbTable, options.through);
|
|
864
1087
|
if (!throughRelation) {
|
|
865
|
-
delayRelation(delayedRelations,
|
|
1088
|
+
delayRelation(delayedRelations, dbTable, options.through, data);
|
|
866
1089
|
continue;
|
|
867
1090
|
}
|
|
868
1091
|
const sourceRelation = getSourceRelation(
|
|
@@ -872,7 +1095,7 @@ const applyRelations = (qb, models, result) => {
|
|
|
872
1095
|
if (!sourceRelation) {
|
|
873
1096
|
delayRelation(
|
|
874
1097
|
delayedRelations,
|
|
875
|
-
throughRelation.
|
|
1098
|
+
throughRelation.table,
|
|
876
1099
|
options.source,
|
|
877
1100
|
data
|
|
878
1101
|
);
|
|
@@ -887,92 +1110,99 @@ const applyRelations = (qb, models, result) => {
|
|
|
887
1110
|
for (const key in value) {
|
|
888
1111
|
for (const item of value[key]) {
|
|
889
1112
|
const { relation } = item;
|
|
890
|
-
if (item.
|
|
1113
|
+
if (item.dbTable.relations[item.relationName])
|
|
891
1114
|
continue;
|
|
892
|
-
const as = item.
|
|
1115
|
+
const as = item.dbTable.definedAs;
|
|
893
1116
|
let message = `Cannot define a \`${item.relationName}\` relation on \`${as}\``;
|
|
894
|
-
const
|
|
1117
|
+
const table = result[as];
|
|
895
1118
|
const { through, source } = relation.options;
|
|
896
|
-
const throughRel =
|
|
1119
|
+
const throughRel = table.relations[through];
|
|
897
1120
|
if (through && !throughRel) {
|
|
898
1121
|
message += `: cannot find \`${through}\` relation required by the \`through\` option`;
|
|
899
|
-
} else if (source && throughRel && !throughRel.
|
|
900
|
-
message += `: cannot find \`${source}\` relation in \`${throughRel.
|
|
1122
|
+
} else if (source && throughRel && !throughRel.table.relations[source]) {
|
|
1123
|
+
message += `: cannot find \`${source}\` relation in \`${throughRel.table.definedAs}\` required by the \`source\` option`;
|
|
901
1124
|
}
|
|
902
1125
|
throw new Error(message);
|
|
903
1126
|
}
|
|
904
1127
|
}
|
|
905
1128
|
}
|
|
906
1129
|
};
|
|
907
|
-
const delayRelation = (delayedRelations,
|
|
908
|
-
let
|
|
909
|
-
if (!
|
|
910
|
-
|
|
911
|
-
delayedRelations.set(
|
|
1130
|
+
const delayRelation = (delayedRelations, table, relationName, data) => {
|
|
1131
|
+
let tableRelations = delayedRelations.get(table);
|
|
1132
|
+
if (!tableRelations) {
|
|
1133
|
+
tableRelations = {};
|
|
1134
|
+
delayedRelations.set(table, tableRelations);
|
|
912
1135
|
}
|
|
913
|
-
if (
|
|
914
|
-
|
|
1136
|
+
if (tableRelations[relationName]) {
|
|
1137
|
+
tableRelations[relationName].push(data);
|
|
915
1138
|
} else {
|
|
916
|
-
|
|
1139
|
+
tableRelations[relationName] = [data];
|
|
917
1140
|
}
|
|
918
1141
|
};
|
|
919
|
-
const applyRelation = (qb, { relationName, relation,
|
|
1142
|
+
const applyRelation = (qb, { relationName, relation, dbTable, otherDbTable }, delayedRelations) => {
|
|
920
1143
|
var _a;
|
|
921
|
-
const query = (relation.options.scope ? relation.options.scope(
|
|
1144
|
+
const query = (relation.options.scope ? relation.options.scope(otherDbTable) : otherDbTable).as(relationName);
|
|
922
1145
|
const definedAs = query.definedAs;
|
|
923
1146
|
if (!definedAs) {
|
|
924
1147
|
throw new Error(
|
|
925
|
-
`
|
|
1148
|
+
`Table class for table ${query.table} is not attached to db instance`
|
|
926
1149
|
);
|
|
927
1150
|
}
|
|
928
1151
|
const { type } = relation;
|
|
929
1152
|
let data;
|
|
930
1153
|
if (type === "belongsTo") {
|
|
931
|
-
data = makeBelongsToMethod(relation, query);
|
|
1154
|
+
data = makeBelongsToMethod(relation, relationName, query);
|
|
932
1155
|
} else if (type === "hasOne") {
|
|
933
|
-
data = makeHasOneMethod(
|
|
1156
|
+
data = makeHasOneMethod(dbTable, relation, relationName, query);
|
|
934
1157
|
} else if (type === "hasMany") {
|
|
935
|
-
data = makeHasManyMethod(
|
|
1158
|
+
data = makeHasManyMethod(dbTable, relation, relationName, query);
|
|
936
1159
|
} else if (type === "hasAndBelongsToMany") {
|
|
937
|
-
data = makeHasAndBelongsToManyMethod(
|
|
1160
|
+
data = makeHasAndBelongsToManyMethod(
|
|
1161
|
+
dbTable,
|
|
1162
|
+
qb,
|
|
1163
|
+
relation,
|
|
1164
|
+
relationName,
|
|
1165
|
+
query
|
|
1166
|
+
);
|
|
938
1167
|
} else {
|
|
939
1168
|
throw new Error(`Unknown relation type ${type}`);
|
|
940
1169
|
}
|
|
941
1170
|
if (data.returns === "one") {
|
|
942
1171
|
query._take();
|
|
943
1172
|
}
|
|
944
|
-
|
|
945
|
-
|
|
1173
|
+
if (data.virtualColumn) {
|
|
1174
|
+
dbTable.shape[relationName] = data.virtualColumn;
|
|
1175
|
+
}
|
|
1176
|
+
makeRelationQuery(dbTable, definedAs, relationName, data);
|
|
1177
|
+
dbTable.relations[relationName] = {
|
|
946
1178
|
type,
|
|
947
1179
|
key: relationName,
|
|
948
|
-
|
|
1180
|
+
table: otherDbTable,
|
|
949
1181
|
query,
|
|
950
|
-
nestedInsert: data.nestedInsert,
|
|
951
|
-
nestedUpdate: data.nestedUpdate,
|
|
952
1182
|
joinQuery: data.joinQuery,
|
|
953
1183
|
primaryKey: data.primaryKey,
|
|
954
1184
|
options: relation.options
|
|
955
1185
|
};
|
|
956
|
-
const
|
|
957
|
-
if (!
|
|
1186
|
+
const tableRelations = delayedRelations.get(dbTable);
|
|
1187
|
+
if (!tableRelations)
|
|
958
1188
|
return;
|
|
959
|
-
(_a =
|
|
1189
|
+
(_a = tableRelations[relationName]) == null ? void 0 : _a.forEach((data2) => {
|
|
960
1190
|
applyRelation(qb, data2, delayedRelations);
|
|
961
1191
|
});
|
|
962
1192
|
};
|
|
963
|
-
const makeRelationQuery = (
|
|
964
|
-
Object.defineProperty(
|
|
1193
|
+
const makeRelationQuery = (table, definedAs, relationName, data) => {
|
|
1194
|
+
Object.defineProperty(table, relationName, {
|
|
965
1195
|
get() {
|
|
966
1196
|
var _a;
|
|
967
|
-
const
|
|
1197
|
+
const toTable = this.db[definedAs].as(relationName);
|
|
968
1198
|
if (data.returns === "one") {
|
|
969
|
-
|
|
1199
|
+
toTable._take();
|
|
970
1200
|
}
|
|
971
|
-
const query = this.isSubQuery ?
|
|
1201
|
+
const query = this.isSubQuery ? toTable : toTable._whereExists(data.reverseJoin(this, toTable), (q) => q);
|
|
972
1202
|
query.query[relationQueryKey] = {
|
|
973
1203
|
relationName,
|
|
974
1204
|
sourceQuery: this,
|
|
975
|
-
relationQuery:
|
|
1205
|
+
relationQuery: toTable,
|
|
976
1206
|
joinQuery: data.joinQuery
|
|
977
1207
|
};
|
|
978
1208
|
const setQuery = (_a = data.modifyRelatedQuery) == null ? void 0 : _a.call(data, query);
|
|
@@ -995,10 +1225,10 @@ function transaction(fn) {
|
|
|
995
1225
|
for (const key in this) {
|
|
996
1226
|
const value = this[key];
|
|
997
1227
|
if (value instanceof Db) {
|
|
998
|
-
const
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
orm[key] =
|
|
1228
|
+
const table = value.transacting(q);
|
|
1229
|
+
table.__table = table;
|
|
1230
|
+
table.db = orm;
|
|
1231
|
+
orm[key] = table;
|
|
1002
1232
|
} else {
|
|
1003
1233
|
orm[key] = value;
|
|
1004
1234
|
}
|
|
@@ -1038,7 +1268,7 @@ var __objRest = (source, exclude) => {
|
|
|
1038
1268
|
}
|
|
1039
1269
|
return target;
|
|
1040
1270
|
};
|
|
1041
|
-
const orchidORM = (_a,
|
|
1271
|
+
const orchidORM = (_a, tables) => {
|
|
1042
1272
|
var _b = _a, {
|
|
1043
1273
|
log,
|
|
1044
1274
|
logger,
|
|
@@ -1072,31 +1302,31 @@ const orchidORM = (_a, models) => {
|
|
|
1072
1302
|
$queryBuilder: qb,
|
|
1073
1303
|
$close: () => adapter.close()
|
|
1074
1304
|
};
|
|
1075
|
-
const
|
|
1076
|
-
for (const key in
|
|
1305
|
+
const tableInstances = {};
|
|
1306
|
+
for (const key in tables) {
|
|
1077
1307
|
if (key[0] === "$") {
|
|
1078
|
-
throw new Error(`
|
|
1308
|
+
throw new Error(`Table class name must not start with $`);
|
|
1079
1309
|
}
|
|
1080
|
-
const
|
|
1081
|
-
|
|
1310
|
+
const table = new tables[key]();
|
|
1311
|
+
tableInstances[key] = table;
|
|
1082
1312
|
const options2 = __spreadProps(__spreadValues$1({}, commonOptions), {
|
|
1083
|
-
schema:
|
|
1313
|
+
schema: table.schema
|
|
1084
1314
|
});
|
|
1085
|
-
if (
|
|
1315
|
+
if (table.noPrimaryKey)
|
|
1086
1316
|
options2.noPrimaryKey = "ignore";
|
|
1087
|
-
const
|
|
1317
|
+
const dbTable = new Db(
|
|
1088
1318
|
adapter,
|
|
1089
1319
|
qb,
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1320
|
+
table.table,
|
|
1321
|
+
table.columns.shape,
|
|
1322
|
+
table.columnTypes,
|
|
1093
1323
|
options2
|
|
1094
1324
|
);
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
result[key] =
|
|
1325
|
+
dbTable.definedAs = key;
|
|
1326
|
+
dbTable.db = result;
|
|
1327
|
+
result[key] = dbTable;
|
|
1098
1328
|
}
|
|
1099
|
-
applyRelations(qb,
|
|
1329
|
+
applyRelations(qb, tableInstances, result);
|
|
1100
1330
|
return result;
|
|
1101
1331
|
};
|
|
1102
1332
|
|
|
@@ -1116,26 +1346,26 @@ var __spreadValues = (a, b) => {
|
|
|
1116
1346
|
}
|
|
1117
1347
|
return a;
|
|
1118
1348
|
};
|
|
1119
|
-
const createRepo = (
|
|
1349
|
+
const createRepo = (table, methods) => {
|
|
1120
1350
|
const queryMethods = __spreadValues(__spreadValues(__spreadValues(__spreadValues({}, methods.queryMethods), methods.queryOneMethods), methods.queryWithWhereMethods), methods.queryOneWithWhereMethods);
|
|
1121
1351
|
const plainMethods = methods.methods;
|
|
1122
1352
|
const repo = (q2) => {
|
|
1123
|
-
const proto = Object.create(q2.
|
|
1124
|
-
proto.
|
|
1353
|
+
const proto = Object.create(q2.__table);
|
|
1354
|
+
proto.__table = proto;
|
|
1125
1355
|
const result = Object.create(proto);
|
|
1126
1356
|
result.query = getClonedQueryData(q2.query);
|
|
1127
1357
|
if (plainMethods) {
|
|
1128
|
-
Object.assign(proto.
|
|
1358
|
+
Object.assign(proto.__table, plainMethods);
|
|
1129
1359
|
}
|
|
1130
1360
|
for (const key in queryMethods) {
|
|
1131
1361
|
const method = queryMethods[key];
|
|
1132
|
-
proto.
|
|
1362
|
+
proto.__table[key] = function(...args) {
|
|
1133
1363
|
return method(this, ...args);
|
|
1134
1364
|
};
|
|
1135
1365
|
}
|
|
1136
1366
|
return result;
|
|
1137
1367
|
};
|
|
1138
|
-
const q = repo(
|
|
1368
|
+
const q = repo(table);
|
|
1139
1369
|
return new Proxy(repo, {
|
|
1140
1370
|
get(_, key) {
|
|
1141
1371
|
return q[key];
|
|
@@ -1143,5 +1373,5 @@ const createRepo = (model, methods) => {
|
|
|
1143
1373
|
});
|
|
1144
1374
|
};
|
|
1145
1375
|
|
|
1146
|
-
export {
|
|
1376
|
+
export { createBaseTable, createRepo, orchidORM };
|
|
1147
1377
|
//# sourceMappingURL=index.esm.js.map
|