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