orchid-orm 1.67.1 → 1.68.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +642 -682
- package/dist/index.js +1398 -2304
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1391 -2298
- package/dist/index.mjs.map +1 -1
- package/dist/migrations/index.d.ts +14 -13
- package/dist/migrations/index.js +2379 -3597
- package/dist/migrations/index.js.map +1 -1
- package/dist/migrations/index.mjs +2345 -3586
- package/dist/migrations/index.mjs.map +1 -1
- package/dist/migrations/node-postgres.d.ts +13 -14
- package/dist/migrations/node-postgres.js +12 -3795
- package/dist/migrations/node-postgres.js.map +1 -1
- package/dist/migrations/node-postgres.mjs +4 -3785
- package/dist/migrations/node-postgres.mjs.map +1 -1
- package/dist/migrations/postgres-js.d.ts +13 -14
- package/dist/migrations/postgres-js.js +12 -3795
- package/dist/migrations/postgres-js.js.map +1 -1
- package/dist/migrations/postgres-js.mjs +4 -3785
- package/dist/migrations/postgres-js.mjs.map +1 -1
- package/dist/node-postgres.d.ts +10 -10
- package/dist/node-postgres.js +17 -21
- package/dist/node-postgres.js.map +1 -1
- package/dist/node-postgres.mjs +14 -17
- package/dist/node-postgres.mjs.map +1 -1
- package/dist/postgres-js.d.ts +11 -14
- package/dist/postgres-js.js +16 -17
- package/dist/postgres-js.js.map +1 -1
- package/dist/postgres-js.mjs +13 -13
- package/dist/postgres-js.mjs.map +1 -1
- package/package.json +62 -27
package/dist/index.js
CHANGED
|
@@ -1,2395 +1,1489 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
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
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
fn,
|
|
140
|
-
options
|
|
141
|
-
};
|
|
142
|
-
}
|
|
143
|
-
}, _a.nowSQL = nowSQL, _a.exportAs = exportAs, _a.columnTypes = columnTypes, _a.sql = internal._createDbSqlMethod(columnTypes), _a);
|
|
144
|
-
internal.applyMixins(base, [internal.QueryHooks]);
|
|
145
|
-
base.prototype.types = columnTypes;
|
|
146
|
-
base.prototype.snakeCase = snakeCase;
|
|
147
|
-
base.prototype.language = language;
|
|
148
|
-
base.prototype.autoForeignKeys = autoForeignKeys === true ? {} : autoForeignKeys || void 0;
|
|
149
|
-
return base;
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
let pqb_internal = require("pqb/internal");
|
|
3
|
+
let pqb = require("pqb");
|
|
4
|
+
let node_async_hooks = require("node:async_hooks");
|
|
5
|
+
function createBaseTable({ schemaConfig = pqb_internal.defaultSchemaConfig, columnTypes: columnTypesArg, snakeCase, filePath: filePathArg, nowSQL, exportAs = "BaseTable", language, autoForeignKeys } = {}) {
|
|
6
|
+
const columnTypes = typeof columnTypesArg === "function" ? columnTypesArg((0, pqb_internal.makeColumnTypes)(schemaConfig)) : columnTypesArg || (0, pqb_internal.makeColumnTypes)(schemaConfig);
|
|
7
|
+
const filePathOrStack = filePathArg || (0, pqb_internal.getStackTrace)();
|
|
8
|
+
let filePath;
|
|
9
|
+
const defaultColumns = {
|
|
10
|
+
shape: pqb_internal.emptyObject,
|
|
11
|
+
data: pqb_internal.emptyArray
|
|
12
|
+
};
|
|
13
|
+
const instances = /* @__PURE__ */ new WeakMap();
|
|
14
|
+
const base = class BaseTable {
|
|
15
|
+
constructor() {
|
|
16
|
+
this.columns = defaultColumns;
|
|
17
|
+
this.snakeCase = snakeCase;
|
|
18
|
+
this.types = columnTypes;
|
|
19
|
+
this.q = {};
|
|
20
|
+
this.language = language;
|
|
21
|
+
}
|
|
22
|
+
static {
|
|
23
|
+
this.nowSQL = nowSQL;
|
|
24
|
+
}
|
|
25
|
+
static {
|
|
26
|
+
this.exportAs = exportAs;
|
|
27
|
+
}
|
|
28
|
+
static {
|
|
29
|
+
this.columnTypes = columnTypes;
|
|
30
|
+
}
|
|
31
|
+
static {
|
|
32
|
+
this.sql = (0, pqb_internal._createDbSqlMethod)(columnTypes);
|
|
33
|
+
}
|
|
34
|
+
static inputSchema() {
|
|
35
|
+
this.instance();
|
|
36
|
+
return this._inputSchema === void 0 ? this._inputSchema = schemaConfig.inputSchema.call(this) : this._inputSchema;
|
|
37
|
+
}
|
|
38
|
+
static outputSchema() {
|
|
39
|
+
this.instance();
|
|
40
|
+
return this._outputSchema === void 0 ? this._outputSchema = schemaConfig.outputSchema.call(this) : this._outputSchema;
|
|
41
|
+
}
|
|
42
|
+
static querySchema() {
|
|
43
|
+
this.instance();
|
|
44
|
+
return this._querySchema === void 0 ? this._querySchema = schemaConfig.querySchema.call(this) : this._querySchema;
|
|
45
|
+
}
|
|
46
|
+
static createSchema() {
|
|
47
|
+
this.instance();
|
|
48
|
+
return this._createSchema === void 0 ? this._createSchema = schemaConfig.createSchema.call(this) : this._createSchema;
|
|
49
|
+
}
|
|
50
|
+
static updateSchema() {
|
|
51
|
+
this.instance();
|
|
52
|
+
return this._updateSchema === void 0 ? this._updateSchema = schemaConfig.updateSchema.call(this) : this._updateSchema;
|
|
53
|
+
}
|
|
54
|
+
static pkeySchema() {
|
|
55
|
+
this.instance();
|
|
56
|
+
return this._pkeySchema === void 0 ? this._pkeySchema = schemaConfig.pkeySchema.call(this) : this._pkeySchema;
|
|
57
|
+
}
|
|
58
|
+
static getFilePath() {
|
|
59
|
+
if (filePath) return filePath;
|
|
60
|
+
if (typeof filePathOrStack === "string") return filePath = filePathOrStack;
|
|
61
|
+
filePath = (0, pqb_internal.getCallerFilePath)(filePathOrStack);
|
|
62
|
+
if (filePath) return filePath;
|
|
63
|
+
throw new Error(`Failed to determine file path of a base table. Please set the \`filePath\` option of \`createBaseTable\` manually.`);
|
|
64
|
+
}
|
|
65
|
+
static instance() {
|
|
66
|
+
let instance = instances.get(this);
|
|
67
|
+
if (!instance) {
|
|
68
|
+
instance = new this();
|
|
69
|
+
instances.set(this, instance);
|
|
70
|
+
}
|
|
71
|
+
return instance;
|
|
72
|
+
}
|
|
73
|
+
clone() {
|
|
74
|
+
return this;
|
|
75
|
+
}
|
|
76
|
+
getFilePath() {
|
|
77
|
+
if (this.filePath) return this.filePath;
|
|
78
|
+
if (typeof filePathOrStack === "string") return this.filePath = filePathOrStack;
|
|
79
|
+
const filePath = (0, pqb_internal.getCallerFilePath)(filePathOrStack);
|
|
80
|
+
if (filePath) return this.filePath = filePath;
|
|
81
|
+
throw new Error(`Failed to determine file path for table ${this.constructor.name}. Please set \`filePath\` property manually`);
|
|
82
|
+
}
|
|
83
|
+
setColumns(fn, dataFn) {
|
|
84
|
+
columnTypes[pqb_internal.snakeCaseKey] = this.snakeCase;
|
|
85
|
+
const shape = (0, pqb_internal.getColumnTypes)(columnTypes, fn, nowSQL, this.language);
|
|
86
|
+
const tableData = (0, pqb_internal.parseTableData)(dataFn);
|
|
87
|
+
if (this.snakeCase) for (const key in shape) {
|
|
88
|
+
const column = shape[key];
|
|
89
|
+
if (column.data.name) continue;
|
|
90
|
+
const snakeName = (0, pqb_internal.toSnakeCase)(key);
|
|
91
|
+
if (snakeName !== key) column.data.name = snakeName;
|
|
92
|
+
}
|
|
93
|
+
return this.constructor.prototype.columns = {
|
|
94
|
+
shape,
|
|
95
|
+
data: tableData
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
setComputed(computed) {
|
|
99
|
+
return computed;
|
|
100
|
+
}
|
|
101
|
+
setScopes(scopes) {
|
|
102
|
+
return scopes;
|
|
103
|
+
}
|
|
104
|
+
belongsTo(fn, options) {
|
|
105
|
+
return {
|
|
106
|
+
type: "belongsTo",
|
|
107
|
+
fn,
|
|
108
|
+
options
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
hasOne(fn, options) {
|
|
112
|
+
return {
|
|
113
|
+
type: "hasOne",
|
|
114
|
+
fn,
|
|
115
|
+
options
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
hasMany(fn, options) {
|
|
119
|
+
return {
|
|
120
|
+
type: "hasMany",
|
|
121
|
+
fn,
|
|
122
|
+
options
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
hasAndBelongsToMany(fn, options) {
|
|
126
|
+
return {
|
|
127
|
+
type: "hasAndBelongsToMany",
|
|
128
|
+
fn,
|
|
129
|
+
options
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
(0, pqb_internal.applyMixins)(base, [pqb_internal.QueryHooks]);
|
|
134
|
+
base.prototype.types = columnTypes;
|
|
135
|
+
base.prototype.snakeCase = snakeCase;
|
|
136
|
+
base.prototype.language = language;
|
|
137
|
+
base.prototype.autoForeignKeys = autoForeignKeys === true ? {} : autoForeignKeys || void 0;
|
|
138
|
+
return base;
|
|
150
139
|
}
|
|
151
|
-
|
|
152
140
|
const getThroughRelation = (table, through) => {
|
|
153
|
-
|
|
141
|
+
return table.relations[through];
|
|
154
142
|
};
|
|
155
143
|
const getSourceRelation = (throughRelation, source) => {
|
|
156
|
-
|
|
144
|
+
return throughRelation.query.relations[source];
|
|
157
145
|
};
|
|
158
146
|
const hasRelationHandleCreate = (q, ctx, items, rowIndexes, key, primaryKeys, nestedInsert) => {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
q,
|
|
175
|
-
primaryKeys,
|
|
176
|
-
(rows, q2) => nestedInsert(
|
|
177
|
-
q2,
|
|
178
|
-
relationData.map(([rowIndex, data]) => [
|
|
179
|
-
rows[rowIndex],
|
|
180
|
-
data
|
|
181
|
-
])
|
|
182
|
-
)
|
|
183
|
-
);
|
|
184
|
-
});
|
|
147
|
+
q.q.wrapInTransaction = true;
|
|
148
|
+
items.forEach((item, i) => {
|
|
149
|
+
const value = item[key];
|
|
150
|
+
if ((!value.create || Array.isArray(value.create) && value.create.length === 0) && (!value.connect || Array.isArray(value.connect) && value.connect.length === 0) && (!value.connectOrCreate || Array.isArray(value.connectOrCreate) && value.connectOrCreate.length === 0)) return;
|
|
151
|
+
const store = ctx;
|
|
152
|
+
if (!store.hasRelation) store.hasRelation = {};
|
|
153
|
+
const values = [rowIndexes[i], value];
|
|
154
|
+
if (store.hasRelation[key]) {
|
|
155
|
+
store.hasRelation[key].push(values);
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
const relationData = [values];
|
|
159
|
+
store.hasRelation[key] = relationData;
|
|
160
|
+
(0, pqb_internal._queryHookAfterCreate)(q, primaryKeys, (rows, q) => nestedInsert(q, relationData.map(([rowIndex, data]) => [rows[rowIndex], data])));
|
|
161
|
+
});
|
|
185
162
|
};
|
|
186
163
|
const hasRelationHandleUpdate = (q, set, key, primaryKeys, nestedUpdate) => {
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
q2,
|
|
194
|
-
rows,
|
|
195
|
-
value
|
|
196
|
-
);
|
|
197
|
-
});
|
|
164
|
+
const value = set[key];
|
|
165
|
+
if (!value.set && !("upsert" in value) && (!value.add || Array.isArray(value.add) && value.add.length === 0) && (!value.disconnect || Array.isArray(value.disconnect) && value.disconnect.length === 0) && (!value.delete || Array.isArray(value.delete) && value.delete.length === 0) && (!value.update || Array.isArray(value.update.where) && value.update.where.length === 0) && (!value.create || Array.isArray(value.create) && value.create.length === 0)) return;
|
|
166
|
+
q.q.wrapInTransaction = true;
|
|
167
|
+
(0, pqb_internal._queryHookAfterUpdate)(q, primaryKeys, (rows, q) => {
|
|
168
|
+
return nestedUpdate(q, rows, value);
|
|
169
|
+
});
|
|
198
170
|
};
|
|
199
171
|
function joinHasThrough(q, baseQuery, joiningQuery, throughRelation, sourceRelation) {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
),
|
|
205
|
-
() => {
|
|
206
|
-
const as = internal.getQueryAs(joiningQuery);
|
|
207
|
-
return sourceRelation.joinQuery(
|
|
208
|
-
sourceRelation.query.as(as),
|
|
209
|
-
throughRelation.query
|
|
210
|
-
);
|
|
211
|
-
}
|
|
212
|
-
);
|
|
172
|
+
return q.whereExists(throughRelation.joinQuery(throughRelation.query, baseQuery), (() => {
|
|
173
|
+
const as = (0, pqb_internal.getQueryAs)(joiningQuery);
|
|
174
|
+
return sourceRelation.joinQuery(sourceRelation.query.as(as), throughRelation.query);
|
|
175
|
+
}));
|
|
213
176
|
}
|
|
214
177
|
function joinHasRelation(baseQuery, joiningQuery, primaryKeys, foreignKeys, len) {
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
q,
|
|
221
|
-
baseQuery,
|
|
222
|
-
joiningQuery,
|
|
223
|
-
foreignKeys[i],
|
|
224
|
-
`${baseAs}.${primaryKeys[i]}`
|
|
225
|
-
);
|
|
226
|
-
}
|
|
227
|
-
return q;
|
|
178
|
+
const baseAs = (0, pqb_internal.getQueryAs)(baseQuery);
|
|
179
|
+
const q = joiningQuery.clone();
|
|
180
|
+
(0, pqb_internal.setQueryObjectValueImmutable)(q, "joinedShapes", baseAs, baseQuery.q.shape);
|
|
181
|
+
for (let i = 0; i < len; i++) (0, pqb_internal.pushQueryOnForOuter)(q, baseQuery, joiningQuery, foreignKeys[i], `${baseAs}.${primaryKeys[i]}`);
|
|
182
|
+
return q;
|
|
228
183
|
}
|
|
229
184
|
const addAutoForeignKey = (tableConfig, from, to, primaryKeys, foreignKeys, options, originalForeignKeys) => {
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
references: {
|
|
268
|
-
columns: originalForeignKeys || foreignKeys,
|
|
269
|
-
fnOrTable: toTable,
|
|
270
|
-
foreignColumns: primaryKeys,
|
|
271
|
-
options: fkeyOptions
|
|
272
|
-
},
|
|
273
|
-
dropMode: fkeyOptions.dropMode
|
|
274
|
-
});
|
|
185
|
+
const toTable = to.table;
|
|
186
|
+
let fkeyOptions = options.foreignKey !== void 0 ? options.foreignKey : tableConfig.autoForeignKeys;
|
|
187
|
+
if (!fkeyOptions) return;
|
|
188
|
+
if (fkeyOptions === true) fkeyOptions = tableConfig.autoForeignKeys || pqb_internal.emptyObject;
|
|
189
|
+
if (foreignKeys.length === 1) {
|
|
190
|
+
const column = from.shape[foreignKeys[0]];
|
|
191
|
+
if (column.data.foreignKeys) {
|
|
192
|
+
const pkey = primaryKeys[0];
|
|
193
|
+
for (const fkey of column.data.foreignKeys) {
|
|
194
|
+
let fkeyTable;
|
|
195
|
+
let fkeyColumn = fkey.foreignColumns[0];
|
|
196
|
+
if (typeof fkey.fnOrTable === "string") {
|
|
197
|
+
fkeyTable = fkey.fnOrTable;
|
|
198
|
+
fkeyColumn = getColumnKeyFromDbName(to, fkeyColumn);
|
|
199
|
+
} else fkeyTable = fkey.fnOrTable().instance().table;
|
|
200
|
+
if (toTable === fkeyTable && pkey === fkeyColumn) return;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
const { constraints } = from.internal.tableData;
|
|
205
|
+
if (constraints) {
|
|
206
|
+
const sortedPkeys = [...primaryKeys].sort();
|
|
207
|
+
const sortedFkeys = [...foreignKeys].sort();
|
|
208
|
+
for (const { references: refs } of constraints) {
|
|
209
|
+
if (!refs) continue;
|
|
210
|
+
if (refs.columns.length === sortedFkeys.length && refs.columns.every((column, i) => column === sortedFkeys[i]) && refs.foreignColumns.length === sortedPkeys.length && (typeof refs.fnOrTable === "string" ? refs.fnOrTable === toTable && refs.foreignColumns.every((column, i) => getColumnKeyFromDbName(to, column) === sortedPkeys[i]) : refs.fnOrTable().instance().table === toTable && refs.foreignColumns.every((column, i) => column === sortedPkeys[i]))) return;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
(from.internal.tableData.constraints ??= []).push({
|
|
214
|
+
references: {
|
|
215
|
+
columns: originalForeignKeys || foreignKeys,
|
|
216
|
+
fnOrTable: toTable,
|
|
217
|
+
foreignColumns: primaryKeys,
|
|
218
|
+
options: fkeyOptions
|
|
219
|
+
},
|
|
220
|
+
dropMode: fkeyOptions.dropMode
|
|
221
|
+
});
|
|
275
222
|
};
|
|
276
223
|
const getColumnKeyFromDbName = (query, name) => {
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
return k;
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
return name;
|
|
224
|
+
for (const k in query.shape) if (query.shape[k].data.name === name) return k;
|
|
225
|
+
return name;
|
|
283
226
|
};
|
|
284
227
|
const selectCteColumnsSql = (cteAs, columns) => `(SELECT ${columns.map((c) => `"${cteAs}"."${c}"`).join(", ")} FROM "${cteAs}")`;
|
|
285
228
|
const selectCteColumnSql = (cteAs, column) => `(SELECT "${cteAs}"."${column}" FROM "${cteAs}")`;
|
|
286
229
|
const selectCteColumnFromManySql = (cteAs, column, rowIndex, count) => {
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
230
|
+
let sql = `(SELECT "${cteAs}"."${column}" FROM "${cteAs}"`;
|
|
231
|
+
if (count > 1) {
|
|
232
|
+
sql += ` LIMIT 1`;
|
|
233
|
+
if (rowIndex) sql += ` OFFSET ${rowIndex}`;
|
|
234
|
+
}
|
|
235
|
+
return sql + ")";
|
|
293
236
|
};
|
|
294
|
-
|
|
295
237
|
const joinQueryChainHOF = (relPKeys, reverseJoin, joinQuery) => (joiningQuery, baseQuery) => {
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
return true;
|
|
341
|
-
}
|
|
342
|
-
});
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
if (useWhereExist) {
|
|
346
|
-
return jq.where({
|
|
347
|
-
EXISTS: { q: reverseJoin(query, jq) }
|
|
348
|
-
});
|
|
349
|
-
}
|
|
350
|
-
const result = jq.join(
|
|
351
|
-
{ _internalJoin: reverseJoin(query, jq) },
|
|
352
|
-
void 0
|
|
353
|
-
);
|
|
354
|
-
if (!query.q.chainMultiple) {
|
|
355
|
-
return result;
|
|
356
|
-
}
|
|
357
|
-
const item = selectRowNumber(result, relPKeys);
|
|
358
|
-
combineOrdering(result, query);
|
|
359
|
-
if (!result.q.select) result.q.select = ["*"];
|
|
360
|
-
return wrapQuery(jq, result, item);
|
|
238
|
+
const jq = joiningQuery;
|
|
239
|
+
const chain = jq.q.relChain;
|
|
240
|
+
if (!chain || chain.length === 1) return joinQuery(jq, baseQuery);
|
|
241
|
+
const last = chain[chain.length - 1];
|
|
242
|
+
const query = chain[chain.length - 2].rel.joinQuery(last.query, baseQuery);
|
|
243
|
+
let useWhereExist = true;
|
|
244
|
+
if (jq.q.returnType !== "value" && jq.q.returnType !== "valueOrThrow") {
|
|
245
|
+
let tablePrefix;
|
|
246
|
+
if (jq.q.order) {
|
|
247
|
+
const prefix = tablePrefix = (0, pqb_internal.getQueryAs)(jq) + ".";
|
|
248
|
+
useWhereExist = jq.q.order.every((o) => {
|
|
249
|
+
if (typeof o === "string") return isOwnColumn(prefix, o);
|
|
250
|
+
else if ((0, pqb_internal.isExpression)(o)) return false;
|
|
251
|
+
else {
|
|
252
|
+
for (const key in o) if (!isOwnColumn(prefix, key)) return false;
|
|
253
|
+
return true;
|
|
254
|
+
}
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
if (useWhereExist && jq.q.select) {
|
|
258
|
+
const prefix = tablePrefix || (0, pqb_internal.getQueryAs)(jq) + ".";
|
|
259
|
+
useWhereExist = jq.q.select.every((s) => {
|
|
260
|
+
if (typeof s === "string") return isOwnColumn(prefix, s);
|
|
261
|
+
else if ((0, pqb_internal.isExpression)(s)) return false;
|
|
262
|
+
else if (!s) return false;
|
|
263
|
+
else {
|
|
264
|
+
for (const key in s.selectAs) {
|
|
265
|
+
const value = s.selectAs[key];
|
|
266
|
+
if (typeof value !== "string" || !isOwnColumn(prefix, value)) return false;
|
|
267
|
+
}
|
|
268
|
+
return true;
|
|
269
|
+
}
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
if (useWhereExist) return jq.where({ EXISTS: { q: reverseJoin(query, jq) } });
|
|
274
|
+
const result = jq.join({ _internalJoin: reverseJoin(query, jq) }, void 0);
|
|
275
|
+
if (!query.q.chainMultiple) return result;
|
|
276
|
+
const item = selectRowNumber(result, relPKeys);
|
|
277
|
+
combineOrdering(result, query);
|
|
278
|
+
if (!result.q.select) result.q.select = ["*"];
|
|
279
|
+
return wrapQuery(jq, result, item);
|
|
361
280
|
};
|
|
362
281
|
const isOwnColumn = (prefix, column) => !column.includes(".") || column.startsWith(prefix);
|
|
363
282
|
const selectRowNumber = (result, relPKeys) => {
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
(key) => `${as}."${result.shape[key]?.data.name || key}"`
|
|
370
|
-
);
|
|
371
|
-
const item = {
|
|
372
|
-
select: {
|
|
373
|
-
sql: `row_number() OVER (PARTITION BY ${partitionColumns.join(", ")})`
|
|
374
|
-
}
|
|
375
|
-
};
|
|
376
|
-
hookSelect.set("r", item);
|
|
377
|
-
return item;
|
|
283
|
+
const hookSelect = result.q.hookSelect = new Map(result.q.hookSelect && [...result.q.hookSelect]);
|
|
284
|
+
const as = `"${(0, pqb_internal.getQueryAs)(result)}"`;
|
|
285
|
+
const item = { select: { sql: `row_number() OVER (PARTITION BY ${relPKeys.map((key) => `${as}."${result.shape[key]?.data.name || key}"`).join(", ")})` } };
|
|
286
|
+
hookSelect.set("r", item);
|
|
287
|
+
return item;
|
|
378
288
|
};
|
|
379
289
|
const combineOrdering = (result, joined) => {
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
);
|
|
388
|
-
const arr = result.q.order;
|
|
389
|
-
result.q.order = arr ? [...add, ...arr] : add;
|
|
390
|
-
}
|
|
290
|
+
const { order } = joined.q;
|
|
291
|
+
if (order) {
|
|
292
|
+
const as = (0, pqb_internal.getQueryAs)(joined);
|
|
293
|
+
const add = order.map((o) => typeof o === "string" ? `${as}.${o}` : (0, pqb_internal.isExpression)(o) ? o : Object.fromEntries(Object.entries(o).map(([key, value]) => [`${as}.${key}`, value])));
|
|
294
|
+
const arr = result.q.order;
|
|
295
|
+
result.q.order = arr ? [...add, ...arr] : add;
|
|
296
|
+
}
|
|
391
297
|
};
|
|
392
298
|
const wrapQuery = (joiningQuery, result, item) => {
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
299
|
+
const outer = (0, pqb_internal.cloneQueryBaseUnscoped)(joiningQuery).clone();
|
|
300
|
+
outer.q.and = [new pqb_internal.DynamicRawSQL(() => new pqb_internal.RawSql(`${item.as || "r"} = 1`))];
|
|
301
|
+
outer.q.useFromLimitOffset = true;
|
|
302
|
+
outer.shape = (0, pqb_internal.getShapeFromSelect)(result, true);
|
|
303
|
+
outer.q.select = Object.keys(outer.shape);
|
|
304
|
+
outer.q.returnType = result.q.returnType;
|
|
305
|
+
result.q.returnsOne = true;
|
|
306
|
+
return result.wrap(outer);
|
|
307
|
+
};
|
|
308
|
+
var BelongsToVirtualColumn = class extends pqb_internal.VirtualColumn {
|
|
309
|
+
constructor(schema, key, state) {
|
|
310
|
+
super(schema);
|
|
311
|
+
this.key = key;
|
|
312
|
+
this.state = state;
|
|
313
|
+
this.nestedUpdate = nestedUpdate$2(this.state);
|
|
314
|
+
}
|
|
315
|
+
create(q, ctx, items) {
|
|
316
|
+
const { key, state: { query, primaryKeys, foreignKeys } } = this;
|
|
317
|
+
let nestedCreateItems;
|
|
318
|
+
items.forEach((item) => {
|
|
319
|
+
const value = item[key];
|
|
320
|
+
const kind = value.create ? "create" : value.connect ? "connect" : "connectOrCreate";
|
|
321
|
+
if (kind) {
|
|
322
|
+
const nestedCreateItem = (nestedCreateItems ??= {})[kind] ??= {
|
|
323
|
+
items: [],
|
|
324
|
+
values: []
|
|
325
|
+
};
|
|
326
|
+
nestedCreateItem.items.push(item);
|
|
327
|
+
nestedCreateItem.values.push(value[kind]);
|
|
328
|
+
if (kind !== "connect") for (const key of foreignKeys) item[key] = new pqb_internal.RawSql("");
|
|
329
|
+
}
|
|
330
|
+
});
|
|
331
|
+
if (!nestedCreateItems) return;
|
|
332
|
+
for (const key of foreignKeys) if (!ctx.columns.has(key)) ctx.columns.set(key, ctx.columns.size);
|
|
333
|
+
const { create, connect, connectOrCreate } = nestedCreateItems;
|
|
334
|
+
if (create) (0, pqb_internal._prependWith)(q, (as) => {
|
|
335
|
+
const count = create.items.length;
|
|
336
|
+
foreignKeys.forEach((foreignKey, i) => {
|
|
337
|
+
const primaryKey = primaryKeys[i];
|
|
338
|
+
create.items.forEach((item, i) => {
|
|
339
|
+
item[foreignKey]._sql = selectCteColumnFromManySql(as, primaryKey, i, count);
|
|
340
|
+
});
|
|
341
|
+
});
|
|
342
|
+
}, (0, pqb_internal._queryInsertMany)(query.select(...primaryKeys), create.values));
|
|
343
|
+
if (connect) connect.values.forEach((value, itemI) => {
|
|
344
|
+
const as = (0, pqb_internal.getFreeAlias)(q.q.withShapes, "q");
|
|
345
|
+
(0, pqb_internal._prependWith)(q, as, query.select(...primaryKeys).findBy(value));
|
|
346
|
+
foreignKeys.map((foreignKey, i) => {
|
|
347
|
+
connect.items[itemI][foreignKey] = new pqb_internal.RawSql(selectCteColumnMustExistSql(i, as, primaryKeys[i]));
|
|
348
|
+
});
|
|
349
|
+
});
|
|
350
|
+
if (connectOrCreate) connectOrCreate.values.forEach((value, itemI) => {
|
|
351
|
+
(0, pqb_internal._prependWith)(q, setForeignKeysFromCte(connectOrCreate.items[itemI], primaryKeys, foreignKeys), (0, pqb_internal._orCreate)((0, pqb_internal._queryWhere)(query.select(...primaryKeys), [value.where]), value.create));
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
update(q, set) {
|
|
355
|
+
q.q.wrapInTransaction = true;
|
|
356
|
+
const data = set[this.key];
|
|
357
|
+
this.nestedUpdate(q, set, data);
|
|
358
|
+
}
|
|
402
359
|
};
|
|
403
|
-
|
|
404
|
-
class BelongsToVirtualColumn extends internal.VirtualColumn {
|
|
405
|
-
constructor(schema, key, state) {
|
|
406
|
-
super(schema);
|
|
407
|
-
this.key = key;
|
|
408
|
-
this.state = state;
|
|
409
|
-
this.nestedUpdate = nestedUpdate$2(this.state);
|
|
410
|
-
}
|
|
411
|
-
create(q, ctx, items) {
|
|
412
|
-
const {
|
|
413
|
-
key,
|
|
414
|
-
state: { query, primaryKeys, foreignKeys }
|
|
415
|
-
} = this;
|
|
416
|
-
let nestedCreateItems;
|
|
417
|
-
items.forEach((item) => {
|
|
418
|
-
var _a;
|
|
419
|
-
const value = item[key];
|
|
420
|
-
const kind = value.create ? "create" : value.connect ? "connect" : "connectOrCreate";
|
|
421
|
-
{
|
|
422
|
-
const nestedCreateItem = (_a = nestedCreateItems ?? (nestedCreateItems = {}))[kind] ?? (_a[kind] = {
|
|
423
|
-
items: [],
|
|
424
|
-
values: []
|
|
425
|
-
});
|
|
426
|
-
nestedCreateItem.items.push(item);
|
|
427
|
-
nestedCreateItem.values.push(value[kind]);
|
|
428
|
-
if (kind !== "connect") {
|
|
429
|
-
for (const key2 of foreignKeys) {
|
|
430
|
-
item[key2] = new internal.RawSql("");
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
});
|
|
435
|
-
if (!nestedCreateItems) {
|
|
436
|
-
return;
|
|
437
|
-
}
|
|
438
|
-
for (const key2 of foreignKeys) {
|
|
439
|
-
if (!ctx.columns.has(key2)) {
|
|
440
|
-
ctx.columns.set(key2, ctx.columns.size);
|
|
441
|
-
}
|
|
442
|
-
}
|
|
443
|
-
const { create, connect, connectOrCreate } = nestedCreateItems;
|
|
444
|
-
if (create) {
|
|
445
|
-
const selectPKeys = query.select(...primaryKeys);
|
|
446
|
-
internal._prependWith(
|
|
447
|
-
q,
|
|
448
|
-
(as) => {
|
|
449
|
-
const count = create.items.length;
|
|
450
|
-
foreignKeys.forEach((foreignKey, i) => {
|
|
451
|
-
const primaryKey = primaryKeys[i];
|
|
452
|
-
create.items.forEach((item, i2) => {
|
|
453
|
-
item[foreignKey]._sql = selectCteColumnFromManySql(
|
|
454
|
-
as,
|
|
455
|
-
primaryKey,
|
|
456
|
-
i2,
|
|
457
|
-
count
|
|
458
|
-
);
|
|
459
|
-
});
|
|
460
|
-
});
|
|
461
|
-
},
|
|
462
|
-
internal._queryInsertMany(selectPKeys, create.values)
|
|
463
|
-
);
|
|
464
|
-
}
|
|
465
|
-
if (connect) {
|
|
466
|
-
connect.values.forEach((value, itemI) => {
|
|
467
|
-
const as = internal.getFreeAlias(q.q.withShapes, "q");
|
|
468
|
-
internal._prependWith(q, as, query.select(...primaryKeys).findBy(value));
|
|
469
|
-
foreignKeys.map((foreignKey, i) => {
|
|
470
|
-
connect.items[itemI][foreignKey] = new internal.RawSql(
|
|
471
|
-
selectCteColumnMustExistSql(i, as, primaryKeys[i])
|
|
472
|
-
);
|
|
473
|
-
});
|
|
474
|
-
});
|
|
475
|
-
}
|
|
476
|
-
if (connectOrCreate) {
|
|
477
|
-
connectOrCreate.values.forEach((value, itemI) => {
|
|
478
|
-
const asFn = setForeignKeysFromCte(
|
|
479
|
-
connectOrCreate.items[itemI],
|
|
480
|
-
primaryKeys,
|
|
481
|
-
foreignKeys
|
|
482
|
-
);
|
|
483
|
-
const selectPKeys = query.select(...primaryKeys);
|
|
484
|
-
internal._prependWith(
|
|
485
|
-
q,
|
|
486
|
-
asFn,
|
|
487
|
-
internal._orCreate(
|
|
488
|
-
internal._queryWhere(selectPKeys, [value.where]),
|
|
489
|
-
value.create
|
|
490
|
-
)
|
|
491
|
-
);
|
|
492
|
-
});
|
|
493
|
-
}
|
|
494
|
-
}
|
|
495
|
-
update(q, set) {
|
|
496
|
-
q.q.wrapInTransaction = true;
|
|
497
|
-
const data = set[this.key];
|
|
498
|
-
this.nestedUpdate(q, set, data);
|
|
499
|
-
}
|
|
500
|
-
}
|
|
501
360
|
const makeBelongsToMethod = (tableConfig, table, relation, relationName, query) => {
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
primaryKeys
|
|
540
|
-
);
|
|
541
|
-
};
|
|
542
|
-
return {
|
|
543
|
-
returns: "one",
|
|
544
|
-
queryRelated(params) {
|
|
545
|
-
const obj = {};
|
|
546
|
-
for (let i = 0; i < len; i++) {
|
|
547
|
-
obj[primaryKeys[i]] = params[foreignKeys[i]];
|
|
548
|
-
}
|
|
549
|
-
return query.where(obj);
|
|
550
|
-
},
|
|
551
|
-
virtualColumn: new BelongsToVirtualColumn(
|
|
552
|
-
internal.defaultSchemaConfig,
|
|
553
|
-
relationName,
|
|
554
|
-
state
|
|
555
|
-
),
|
|
556
|
-
joinQuery: joinQueryChainHOF(
|
|
557
|
-
internal.getPrimaryKeys(query),
|
|
558
|
-
reverseJoin,
|
|
559
|
-
(joiningQuery, baseQuery) => join(
|
|
560
|
-
baseQuery,
|
|
561
|
-
joiningQuery,
|
|
562
|
-
primaryKeys,
|
|
563
|
-
foreignKeys
|
|
564
|
-
)
|
|
565
|
-
),
|
|
566
|
-
reverseJoin
|
|
567
|
-
};
|
|
361
|
+
const primaryKeys = relation.options.references;
|
|
362
|
+
const foreignKeys = relation.options.columns;
|
|
363
|
+
const { on } = relation.options;
|
|
364
|
+
if (on) {
|
|
365
|
+
(0, pqb_internal._queryWhere)(query, [on]);
|
|
366
|
+
(0, pqb_internal._queryDefaults)(query, on);
|
|
367
|
+
}
|
|
368
|
+
const len = primaryKeys.length;
|
|
369
|
+
const state = {
|
|
370
|
+
query,
|
|
371
|
+
primaryKeys,
|
|
372
|
+
foreignKeys,
|
|
373
|
+
len,
|
|
374
|
+
on
|
|
375
|
+
};
|
|
376
|
+
addAutoForeignKey(tableConfig, table, query, primaryKeys, foreignKeys, relation.options);
|
|
377
|
+
const join = (baseQuery, joiningQuery, primaryKeys, foreignKeys) => {
|
|
378
|
+
const baseAs = (0, pqb_internal.getQueryAs)(baseQuery);
|
|
379
|
+
const q = joiningQuery.clone();
|
|
380
|
+
(0, pqb_internal.setQueryObjectValueImmutable)(q, "joinedShapes", baseAs, baseQuery.q.shape);
|
|
381
|
+
for (let i = 0; i < len; i++) (0, pqb_internal.pushQueryOnForOuter)(q, baseQuery, joiningQuery, primaryKeys[i], `${baseAs}.${foreignKeys[i]}`);
|
|
382
|
+
return q;
|
|
383
|
+
};
|
|
384
|
+
const reverseJoin = (baseQuery, joiningQuery) => {
|
|
385
|
+
return join(joiningQuery, baseQuery, foreignKeys, primaryKeys);
|
|
386
|
+
};
|
|
387
|
+
return {
|
|
388
|
+
returns: "one",
|
|
389
|
+
queryRelated(params) {
|
|
390
|
+
const obj = {};
|
|
391
|
+
for (let i = 0; i < len; i++) obj[primaryKeys[i]] = params[foreignKeys[i]];
|
|
392
|
+
return query.where(obj);
|
|
393
|
+
},
|
|
394
|
+
virtualColumn: new BelongsToVirtualColumn(pqb_internal.defaultSchemaConfig, relationName, state),
|
|
395
|
+
joinQuery: joinQueryChainHOF((0, pqb_internal.getPrimaryKeys)(query), reverseJoin, (joiningQuery, baseQuery) => join(baseQuery, joiningQuery, primaryKeys, foreignKeys)),
|
|
396
|
+
reverseJoin
|
|
397
|
+
};
|
|
568
398
|
};
|
|
569
399
|
const nestedUpdate$2 = ({ query, primaryKeys, foreignKeys, len }) => {
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
} else if (params.delete) {
|
|
613
|
-
internal._hookSelectColumns(self, foreignKeys, internal.noop);
|
|
614
|
-
disconnect(update, foreignKeys);
|
|
615
|
-
const { selectIdsSql, relQuery } = relWithSelectIds(
|
|
616
|
-
self,
|
|
617
|
-
query,
|
|
618
|
-
primaryKeys,
|
|
619
|
-
foreignKeys
|
|
620
|
-
);
|
|
621
|
-
self.q.and = self.q.or = void 0;
|
|
622
|
-
internal._queryWhereIn(self, true, foreignKeys, selectIdsSql);
|
|
623
|
-
const deleteQuery = internal._queryDelete(relQuery);
|
|
624
|
-
deleteQuery.q.returnType = "value";
|
|
625
|
-
internal._appendQuery(self, deleteQuery, internal.noop);
|
|
626
|
-
} else if (params.disconnect) {
|
|
627
|
-
disconnect(update, foreignKeys);
|
|
628
|
-
} else if (params.set) {
|
|
629
|
-
let loadPrimaryKeys;
|
|
630
|
-
let loadForeignKeys;
|
|
631
|
-
for (let i = 0; i < len; i++) {
|
|
632
|
-
const primaryKey = primaryKeys[i];
|
|
633
|
-
if (primaryKey in params.set) {
|
|
634
|
-
update[foreignKeys[i]] = params.set[primaryKey];
|
|
635
|
-
} else {
|
|
636
|
-
(loadPrimaryKeys ?? (loadPrimaryKeys = [])).push(primaryKey);
|
|
637
|
-
(loadForeignKeys ?? (loadForeignKeys = [])).push(foreignKeys[i]);
|
|
638
|
-
}
|
|
639
|
-
}
|
|
640
|
-
if (loadPrimaryKeys) {
|
|
641
|
-
const asFn = setForeignKeysFromCte(
|
|
642
|
-
update,
|
|
643
|
-
loadPrimaryKeys,
|
|
644
|
-
loadForeignKeys,
|
|
645
|
-
true
|
|
646
|
-
);
|
|
647
|
-
internal._prependWith(
|
|
648
|
-
self,
|
|
649
|
-
asFn,
|
|
650
|
-
internal._queryFindBy(query.select(...loadPrimaryKeys), params.set)
|
|
651
|
-
);
|
|
652
|
-
}
|
|
653
|
-
}
|
|
654
|
-
};
|
|
400
|
+
return ((self, update, params) => {
|
|
401
|
+
if (params.create) {
|
|
402
|
+
const createQuery = (0, pqb_internal._querySelect)((0, pqb_internal._queryCreate)(query.clone(), params.create), primaryKeys);
|
|
403
|
+
(0, pqb_internal._prependWith)(self, setForeignKeysFromCte(update, primaryKeys, foreignKeys), createQuery);
|
|
404
|
+
} else if (params.update) {
|
|
405
|
+
let appendedAs;
|
|
406
|
+
(0, pqb_internal._hookSelectColumns)(self, foreignKeys, (aliasedForeignKeys) => {
|
|
407
|
+
selectIdsSql._sql = selectCteColumnsSql(appendedAs, aliasedForeignKeys);
|
|
408
|
+
});
|
|
409
|
+
const selectIdsSql = new pqb_internal.RawSql("");
|
|
410
|
+
const updateQuery = (0, pqb_internal._queryUpdate)((0, pqb_internal._queryWhereIn)(query.clone(), true, primaryKeys, selectIdsSql), params.update);
|
|
411
|
+
updateQuery.q.returnType = "value";
|
|
412
|
+
(0, pqb_internal._appendQuery)(self, updateQuery, (as) => appendedAs = as);
|
|
413
|
+
} else if (params.upsert) {
|
|
414
|
+
if ((0, pqb_internal.isQueryReturnsAll)(self)) throw new Error("`upsert` option is not allowed in a batch update");
|
|
415
|
+
const { relQuery } = relWithSelectIds(self, query, primaryKeys, foreignKeys);
|
|
416
|
+
const upsertQuery = (0, pqb_internal._querySelect)((0, pqb_internal._queryUpsert)(relQuery, params.upsert), primaryKeys);
|
|
417
|
+
(0, pqb_internal._prependWith)(self, setForeignKeysFromCte(update, primaryKeys, foreignKeys), upsertQuery);
|
|
418
|
+
} else if (params.delete) {
|
|
419
|
+
(0, pqb_internal._hookSelectColumns)(self, foreignKeys, pqb_internal.noop);
|
|
420
|
+
disconnect(update, foreignKeys);
|
|
421
|
+
const { selectIdsSql, relQuery } = relWithSelectIds(self, query, primaryKeys, foreignKeys);
|
|
422
|
+
self.q.and = self.q.or = void 0;
|
|
423
|
+
(0, pqb_internal._queryWhereIn)(self, true, foreignKeys, selectIdsSql);
|
|
424
|
+
const deleteQuery = (0, pqb_internal._queryDelete)(relQuery);
|
|
425
|
+
deleteQuery.q.returnType = "value";
|
|
426
|
+
(0, pqb_internal._appendQuery)(self, deleteQuery, pqb_internal.noop);
|
|
427
|
+
} else if (params.disconnect) disconnect(update, foreignKeys);
|
|
428
|
+
else if (params.set) {
|
|
429
|
+
let loadPrimaryKeys;
|
|
430
|
+
let loadForeignKeys;
|
|
431
|
+
for (let i = 0; i < len; i++) {
|
|
432
|
+
const primaryKey = primaryKeys[i];
|
|
433
|
+
if (primaryKey in params.set) update[foreignKeys[i]] = params.set[primaryKey];
|
|
434
|
+
else {
|
|
435
|
+
(loadPrimaryKeys ??= []).push(primaryKey);
|
|
436
|
+
(loadForeignKeys ??= []).push(foreignKeys[i]);
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
if (loadPrimaryKeys) (0, pqb_internal._prependWith)(self, setForeignKeysFromCte(update, loadPrimaryKeys, loadForeignKeys, true), (0, pqb_internal._queryFindBy)(query.select(...loadPrimaryKeys), params.set));
|
|
440
|
+
}
|
|
441
|
+
});
|
|
655
442
|
};
|
|
656
443
|
const disconnect = (update, foreignKeys) => {
|
|
657
|
-
|
|
658
|
-
update[foreignKey] = null;
|
|
659
|
-
}
|
|
444
|
+
for (const foreignKey of foreignKeys) update[foreignKey] = null;
|
|
660
445
|
};
|
|
661
446
|
const relWithSelectIds = (self, rel, primaryKeys, foreignKeys) => {
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
return {
|
|
672
|
-
selectIdsSql,
|
|
673
|
-
relQuery: internal._queryWhereIn(rel.clone(), true, primaryKeys, selectIdsSql)
|
|
674
|
-
};
|
|
447
|
+
const selectIdsQuery = makeSelectIdsQuery(self, foreignKeys);
|
|
448
|
+
const selectIdsSql = new pqb_internal.RawSql("");
|
|
449
|
+
(0, pqb_internal._prependWith)(self, (as) => {
|
|
450
|
+
selectIdsSql._sql = selectCteColumnsSql(as, foreignKeys);
|
|
451
|
+
}, selectIdsQuery);
|
|
452
|
+
return {
|
|
453
|
+
selectIdsSql,
|
|
454
|
+
relQuery: (0, pqb_internal._queryWhereIn)(rel.clone(), true, primaryKeys, selectIdsSql)
|
|
455
|
+
};
|
|
675
456
|
};
|
|
676
457
|
const makeSelectIdsQuery = (self, foreignKeys) => {
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
458
|
+
const selectIdsQuery = self.baseQuery.clone();
|
|
459
|
+
selectIdsQuery.q.distinct = pqb_internal.emptyArray;
|
|
460
|
+
selectIdsQuery.q.select = foreignKeys;
|
|
461
|
+
selectIdsQuery.q.and = self.q.and;
|
|
462
|
+
selectIdsQuery.q.or = self.q.or;
|
|
463
|
+
return selectIdsQuery;
|
|
683
464
|
};
|
|
684
465
|
const setForeignKeysFromCte = (record, primaryKeys, foreignKeys, mustExist) => {
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
as,
|
|
694
|
-
primaryKeys[i]
|
|
695
|
-
);
|
|
696
|
-
} : (foreignKey, i) => {
|
|
697
|
-
record[foreignKey]._sql = selectCteColumnSql(
|
|
698
|
-
as,
|
|
699
|
-
primaryKeys[i]
|
|
700
|
-
);
|
|
701
|
-
}
|
|
702
|
-
);
|
|
703
|
-
};
|
|
466
|
+
for (const key of foreignKeys) record[key] = new pqb_internal.RawSql("");
|
|
467
|
+
return (as) => {
|
|
468
|
+
foreignKeys.forEach(mustExist ? (foreignKey, i) => {
|
|
469
|
+
record[foreignKey]._sql = selectCteColumnMustExistSql(i, as, primaryKeys[i]);
|
|
470
|
+
} : (foreignKey, i) => {
|
|
471
|
+
record[foreignKey]._sql = selectCteColumnSql(as, primaryKeys[i]);
|
|
472
|
+
});
|
|
473
|
+
};
|
|
704
474
|
};
|
|
705
475
|
const selectCteColumnMustExistSql = (i, cteAs, column) => {
|
|
706
|
-
|
|
707
|
-
|
|
476
|
+
const selectColumn = selectCteColumnSql(cteAs, column);
|
|
477
|
+
return i === 0 ? `CASE WHEN (SELECT count(*) FROM "${cteAs}") = 0 AND (SELECT 'not-found')::int = 0 THEN NULL ELSE ${selectColumn} END` : selectColumn;
|
|
478
|
+
};
|
|
479
|
+
var HasOneVirtualColumn = class extends pqb_internal.VirtualColumn {
|
|
480
|
+
constructor(schema, key, state) {
|
|
481
|
+
super(schema);
|
|
482
|
+
this.key = key;
|
|
483
|
+
this.state = state;
|
|
484
|
+
this.nestedInsert = nestedInsert$2(state);
|
|
485
|
+
this.setNulls = {};
|
|
486
|
+
for (const foreignKey of state.foreignKeys) this.setNulls[foreignKey] = null;
|
|
487
|
+
}
|
|
488
|
+
create(self, ctx, items, rowIndexes, count) {
|
|
489
|
+
if (count <= self.qb.internal.nestedCreateBatchMax) {
|
|
490
|
+
const { query: rel, primaryKeys, foreignKeys } = this.state;
|
|
491
|
+
let nestedCreateItems;
|
|
492
|
+
items.forEach((item, i) => {
|
|
493
|
+
const value = item[this.key];
|
|
494
|
+
const kind = value.create ? "create" : value.connect ? "connect" : "connectOrCreate";
|
|
495
|
+
if (kind) {
|
|
496
|
+
const nestedCreateItem = (nestedCreateItems ??= {})[kind] ??= {
|
|
497
|
+
indexes: [],
|
|
498
|
+
items: [],
|
|
499
|
+
values: []
|
|
500
|
+
};
|
|
501
|
+
nestedCreateItem.indexes.push(rowIndexes[i]);
|
|
502
|
+
nestedCreateItem.values.push(value[kind]);
|
|
503
|
+
const data = value.create ? { ...value.create } : {};
|
|
504
|
+
for (const key of foreignKeys) data[key] = new pqb_internal.RawSql("");
|
|
505
|
+
nestedCreateItem.items.push(data);
|
|
506
|
+
}
|
|
507
|
+
});
|
|
508
|
+
if (!nestedCreateItems) return;
|
|
509
|
+
let createAs;
|
|
510
|
+
let connectAs;
|
|
511
|
+
let connectOrCreateAs;
|
|
512
|
+
(0, pqb_internal._hookSelectColumns)(self, primaryKeys, (aliasedPrimaryKeys) => {
|
|
513
|
+
foreignKeys.forEach((key, keyI) => {
|
|
514
|
+
const primaryKey = aliasedPrimaryKeys[keyI];
|
|
515
|
+
if (create && createAs) for (let i = 0; i < create.items.length; i++) create.items[i][key]._sql = selectCteColumnFromManySql(createAs, primaryKey, create.indexes[i], count);
|
|
516
|
+
if (connect && connectAs) for (let i = 0; i < connect.items.length; i++) connect.items[i][key]._sql = selectCteColumnFromManySql(connectAs, primaryKey, connect.indexes[i], count);
|
|
517
|
+
if (connectOrCreate && connectOrCreateAs) for (let i = 0; i < connectOrCreate.items.length; i++) connectOrCreate.items[i][key]._sql = selectCteColumnFromManySql(connectOrCreateAs, primaryKey, connectOrCreate.indexes[i], count);
|
|
518
|
+
});
|
|
519
|
+
});
|
|
520
|
+
const { create, connect, connectOrCreate } = nestedCreateItems;
|
|
521
|
+
if (create) (0, pqb_internal._appendQuery)(self, (0, pqb_internal._queryInsertMany)((0, pqb_internal._clone)(rel), create.items), (as) => createAs = as);
|
|
522
|
+
if (connect) connect.values.forEach((value, i) => {
|
|
523
|
+
const query = (0, pqb_internal._queryUpdateOrThrow)(rel.where(value), connect.items[i]);
|
|
524
|
+
query.q.ensureCount = 1;
|
|
525
|
+
(0, pqb_internal._appendQuery)(self, query, (as) => connectAs = as);
|
|
526
|
+
});
|
|
527
|
+
if (connectOrCreate) connectOrCreate.values.forEach((value, i) => {
|
|
528
|
+
(0, pqb_internal._appendQuery)(self, (0, pqb_internal._queryUpsert)(rel.where(value.where), {
|
|
529
|
+
update: connectOrCreate.items[i],
|
|
530
|
+
create: {
|
|
531
|
+
...value.create,
|
|
532
|
+
...connectOrCreate.items[i]
|
|
533
|
+
}
|
|
534
|
+
}), (as) => connectOrCreateAs = as);
|
|
535
|
+
});
|
|
536
|
+
} else hasRelationHandleCreate(self, ctx, items, rowIndexes, this.key, this.state.primaryKeys, this.nestedInsert);
|
|
537
|
+
}
|
|
538
|
+
update(self, set) {
|
|
539
|
+
const params = set[this.key];
|
|
540
|
+
if ((params.set || params.create || params.upsert) && (0, pqb_internal.isQueryReturnsAll)(self)) {
|
|
541
|
+
const key = params.set ? "set" : params.create ? "create" : "upsert";
|
|
542
|
+
throw new Error(`\`${key}\` option is not allowed in a batch update`);
|
|
543
|
+
}
|
|
544
|
+
const { primaryKeys, foreignKeys, query: relQuery } = this.state;
|
|
545
|
+
if (params.create || params.update || params.upsert || params.disconnect || params.set || params.delete) {
|
|
546
|
+
let appendedAs;
|
|
547
|
+
(0, pqb_internal._hookSelectColumns)(self, primaryKeys, (aliasedPrimaryKeys) => {
|
|
548
|
+
selectIdsSql._sql = selectCteColumnsSql(appendedAs, aliasedPrimaryKeys);
|
|
549
|
+
if (params.create || params.set || params.upsert) foreignKeys.forEach((foreignKey, i) => {
|
|
550
|
+
setIds[foreignKey]._sql = selectCteColumnSql(appendedAs, aliasedPrimaryKeys[i]);
|
|
551
|
+
});
|
|
552
|
+
});
|
|
553
|
+
const selectIdsSql = new pqb_internal.RawSql("");
|
|
554
|
+
const existingRelQuery = (0, pqb_internal._queryWhereIn)((0, pqb_internal._clone)(relQuery), true, foreignKeys, selectIdsSql);
|
|
555
|
+
let setIds = void 0;
|
|
556
|
+
if (params.create || params.set || params.upsert) {
|
|
557
|
+
setIds = {};
|
|
558
|
+
foreignKeys.forEach((foreignKey) => {
|
|
559
|
+
setIds[foreignKey] = new pqb_internal.RawSql("");
|
|
560
|
+
});
|
|
561
|
+
}
|
|
562
|
+
const nullifyOrDeleteQuery = params.update ? (0, pqb_internal._queryUpdate)(existingRelQuery, params.update) : params.upsert ? (0, pqb_internal._queryUpsert)(existingRelQuery, {
|
|
563
|
+
update: params.upsert.update,
|
|
564
|
+
create: {
|
|
565
|
+
...typeof params.upsert.create === "function" ? params.upsert.create() : params.upsert.create,
|
|
566
|
+
...setIds
|
|
567
|
+
}
|
|
568
|
+
}) : params.delete ? (0, pqb_internal._queryDelete)(existingRelQuery) : (0, pqb_internal._queryUpdate)(existingRelQuery, this.setNulls);
|
|
569
|
+
nullifyOrDeleteQuery.q.returnType = "void";
|
|
570
|
+
(0, pqb_internal._appendQuery)(self, nullifyOrDeleteQuery, (as) => appendedAs = as);
|
|
571
|
+
if (params.create) (0, pqb_internal._appendQuery)(self, (0, pqb_internal._queryInsert)((0, pqb_internal._clone)(relQuery), {
|
|
572
|
+
...params.create,
|
|
573
|
+
...setIds
|
|
574
|
+
}), pqb_internal.noop);
|
|
575
|
+
else if (params.set) {
|
|
576
|
+
const setQuery = (0, pqb_internal._queryUpdate)((0, pqb_internal._queryWhere)((0, pqb_internal._clone)(relQuery), [params.set]), setIds);
|
|
577
|
+
setQuery.q.returnType = "void";
|
|
578
|
+
(0, pqb_internal._appendQuery)(self, setQuery, pqb_internal.noop);
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
}
|
|
708
582
|
};
|
|
709
|
-
|
|
710
|
-
class HasOneVirtualColumn extends internal.VirtualColumn {
|
|
711
|
-
constructor(schema, key, state) {
|
|
712
|
-
super(schema);
|
|
713
|
-
this.key = key;
|
|
714
|
-
this.state = state;
|
|
715
|
-
this.nestedInsert = nestedInsert$2(state);
|
|
716
|
-
this.setNulls = {};
|
|
717
|
-
for (const foreignKey of state.foreignKeys) {
|
|
718
|
-
this.setNulls[foreignKey] = null;
|
|
719
|
-
}
|
|
720
|
-
}
|
|
721
|
-
create(self, ctx, items, rowIndexes, count) {
|
|
722
|
-
if (count <= self.qb.internal.nestedCreateBatchMax) {
|
|
723
|
-
const { query: rel, primaryKeys, foreignKeys } = this.state;
|
|
724
|
-
let nestedCreateItems;
|
|
725
|
-
items.forEach((item, i) => {
|
|
726
|
-
var _a;
|
|
727
|
-
const value = item[this.key];
|
|
728
|
-
const kind = value.create ? "create" : value.connect ? "connect" : "connectOrCreate";
|
|
729
|
-
{
|
|
730
|
-
const nestedCreateItem = (_a = nestedCreateItems ?? (nestedCreateItems = {}))[kind] ?? (_a[kind] = {
|
|
731
|
-
indexes: [],
|
|
732
|
-
items: [],
|
|
733
|
-
values: []
|
|
734
|
-
});
|
|
735
|
-
nestedCreateItem.indexes.push(rowIndexes[i]);
|
|
736
|
-
nestedCreateItem.values.push(value[kind]);
|
|
737
|
-
const data = value.create ? { ...value.create } : {};
|
|
738
|
-
for (const key of foreignKeys) {
|
|
739
|
-
data[key] = new internal.RawSql("");
|
|
740
|
-
}
|
|
741
|
-
nestedCreateItem.items.push(data);
|
|
742
|
-
}
|
|
743
|
-
});
|
|
744
|
-
if (!nestedCreateItems) {
|
|
745
|
-
return;
|
|
746
|
-
}
|
|
747
|
-
let createAs;
|
|
748
|
-
let connectAs;
|
|
749
|
-
let connectOrCreateAs;
|
|
750
|
-
internal._hookSelectColumns(self, primaryKeys, (aliasedPrimaryKeys) => {
|
|
751
|
-
foreignKeys.forEach((key, keyI) => {
|
|
752
|
-
const primaryKey = aliasedPrimaryKeys[keyI];
|
|
753
|
-
if (create && createAs) {
|
|
754
|
-
for (let i = 0; i < create.items.length; i++) {
|
|
755
|
-
create.items[i][key]._sql = selectCteColumnFromManySql(
|
|
756
|
-
createAs,
|
|
757
|
-
primaryKey,
|
|
758
|
-
create.indexes[i],
|
|
759
|
-
count
|
|
760
|
-
);
|
|
761
|
-
}
|
|
762
|
-
}
|
|
763
|
-
if (connect && connectAs) {
|
|
764
|
-
for (let i = 0; i < connect.items.length; i++) {
|
|
765
|
-
connect.items[i][key]._sql = selectCteColumnFromManySql(
|
|
766
|
-
connectAs,
|
|
767
|
-
primaryKey,
|
|
768
|
-
connect.indexes[i],
|
|
769
|
-
count
|
|
770
|
-
);
|
|
771
|
-
}
|
|
772
|
-
}
|
|
773
|
-
if (connectOrCreate && connectOrCreateAs) {
|
|
774
|
-
for (let i = 0; i < connectOrCreate.items.length; i++) {
|
|
775
|
-
connectOrCreate.items[i][key]._sql = selectCteColumnFromManySql(
|
|
776
|
-
connectOrCreateAs,
|
|
777
|
-
primaryKey,
|
|
778
|
-
connectOrCreate.indexes[i],
|
|
779
|
-
count
|
|
780
|
-
);
|
|
781
|
-
}
|
|
782
|
-
}
|
|
783
|
-
});
|
|
784
|
-
});
|
|
785
|
-
const { create, connect, connectOrCreate } = nestedCreateItems;
|
|
786
|
-
if (create) {
|
|
787
|
-
const query = internal._queryInsertMany(internal._clone(rel), create.items);
|
|
788
|
-
internal._appendQuery(self, query, (as) => createAs = as);
|
|
789
|
-
}
|
|
790
|
-
if (connect) {
|
|
791
|
-
connect.values.forEach((value, i) => {
|
|
792
|
-
const query = internal._queryUpdateOrThrow(
|
|
793
|
-
rel.where(value),
|
|
794
|
-
connect.items[i]
|
|
795
|
-
);
|
|
796
|
-
query.q.ensureCount = 1;
|
|
797
|
-
internal._appendQuery(self, query, (as) => connectAs = as);
|
|
798
|
-
});
|
|
799
|
-
}
|
|
800
|
-
if (connectOrCreate) {
|
|
801
|
-
connectOrCreate.values.forEach((value, i) => {
|
|
802
|
-
const query = internal._queryUpsert(rel.where(value.where), {
|
|
803
|
-
update: connectOrCreate.items[i],
|
|
804
|
-
create: {
|
|
805
|
-
...value.create,
|
|
806
|
-
...connectOrCreate.items[i]
|
|
807
|
-
}
|
|
808
|
-
});
|
|
809
|
-
internal._appendQuery(self, query, (as) => connectOrCreateAs = as);
|
|
810
|
-
});
|
|
811
|
-
}
|
|
812
|
-
} else {
|
|
813
|
-
hasRelationHandleCreate(
|
|
814
|
-
self,
|
|
815
|
-
ctx,
|
|
816
|
-
items,
|
|
817
|
-
rowIndexes,
|
|
818
|
-
this.key,
|
|
819
|
-
this.state.primaryKeys,
|
|
820
|
-
this.nestedInsert
|
|
821
|
-
);
|
|
822
|
-
}
|
|
823
|
-
}
|
|
824
|
-
update(self, set) {
|
|
825
|
-
const params = set[this.key];
|
|
826
|
-
if ((params.set || params.create || params.upsert) && internal.isQueryReturnsAll(self)) {
|
|
827
|
-
const key = params.set ? "set" : params.create ? "create" : "upsert";
|
|
828
|
-
throw new Error(`\`${key}\` option is not allowed in a batch update`);
|
|
829
|
-
}
|
|
830
|
-
const { primaryKeys, foreignKeys, query: relQuery } = this.state;
|
|
831
|
-
if (params.create || params.update || params.upsert || params.disconnect || params.set || params.delete) {
|
|
832
|
-
let appendedAs;
|
|
833
|
-
internal._hookSelectColumns(self, primaryKeys, (aliasedPrimaryKeys) => {
|
|
834
|
-
selectIdsSql._sql = selectCteColumnsSql(
|
|
835
|
-
appendedAs,
|
|
836
|
-
aliasedPrimaryKeys
|
|
837
|
-
);
|
|
838
|
-
if (params.create || params.set || params.upsert) {
|
|
839
|
-
foreignKeys.forEach((foreignKey, i) => {
|
|
840
|
-
setIds[foreignKey]._sql = selectCteColumnSql(
|
|
841
|
-
appendedAs,
|
|
842
|
-
aliasedPrimaryKeys[i]
|
|
843
|
-
);
|
|
844
|
-
});
|
|
845
|
-
}
|
|
846
|
-
});
|
|
847
|
-
const selectIdsSql = new internal.RawSql("");
|
|
848
|
-
const existingRelQuery = internal._queryWhereIn(
|
|
849
|
-
internal._clone(relQuery),
|
|
850
|
-
true,
|
|
851
|
-
foreignKeys,
|
|
852
|
-
selectIdsSql
|
|
853
|
-
);
|
|
854
|
-
let setIds = void 0;
|
|
855
|
-
if (params.create || params.set || params.upsert) {
|
|
856
|
-
setIds = {};
|
|
857
|
-
foreignKeys.forEach((foreignKey) => {
|
|
858
|
-
setIds[foreignKey] = new internal.RawSql("");
|
|
859
|
-
});
|
|
860
|
-
}
|
|
861
|
-
const nullifyOrDeleteQuery = params.update ? internal._queryUpdate(existingRelQuery, params.update) : params.upsert ? internal._queryUpsert(existingRelQuery, {
|
|
862
|
-
update: params.upsert.update,
|
|
863
|
-
create: {
|
|
864
|
-
...typeof params.upsert.create === "function" ? params.upsert.create() : params.upsert.create,
|
|
865
|
-
...setIds
|
|
866
|
-
}
|
|
867
|
-
}) : params.delete ? internal._queryDelete(existingRelQuery) : internal._queryUpdate(existingRelQuery, this.setNulls);
|
|
868
|
-
nullifyOrDeleteQuery.q.returnType = "void";
|
|
869
|
-
internal._appendQuery(self, nullifyOrDeleteQuery, (as) => appendedAs = as);
|
|
870
|
-
if (params.create) {
|
|
871
|
-
const createQuery = internal._queryInsert(internal._clone(relQuery), {
|
|
872
|
-
...params.create,
|
|
873
|
-
...setIds
|
|
874
|
-
});
|
|
875
|
-
internal._appendQuery(self, createQuery, internal.noop);
|
|
876
|
-
} else if (params.set) {
|
|
877
|
-
const setQuery = internal._queryUpdate(
|
|
878
|
-
internal._queryWhere(internal._clone(relQuery), [params.set]),
|
|
879
|
-
setIds
|
|
880
|
-
);
|
|
881
|
-
setQuery.q.returnType = "void";
|
|
882
|
-
internal._appendQuery(self, setQuery, internal.noop);
|
|
883
|
-
}
|
|
884
|
-
}
|
|
885
|
-
}
|
|
886
|
-
}
|
|
887
583
|
const makeHasOneMethod = (tableConfig, table, relation, relationName, query) => {
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
return joinHasRelation(
|
|
954
|
-
joiningQuery,
|
|
955
|
-
baseQuery,
|
|
956
|
-
foreignKeys,
|
|
957
|
-
primaryKeys,
|
|
958
|
-
len
|
|
959
|
-
);
|
|
960
|
-
};
|
|
961
|
-
return {
|
|
962
|
-
returns: "one",
|
|
963
|
-
queryRelated: (params) => {
|
|
964
|
-
const values = {};
|
|
965
|
-
for (let i = 0; i < len; i++) {
|
|
966
|
-
values[foreignKeys[i]] = params[primaryKeys[i]];
|
|
967
|
-
}
|
|
968
|
-
return internal._queryDefaults(query.where(values), { ...on, ...values });
|
|
969
|
-
},
|
|
970
|
-
virtualColumn: new HasOneVirtualColumn(
|
|
971
|
-
internal.defaultSchemaConfig,
|
|
972
|
-
relationName,
|
|
973
|
-
state
|
|
974
|
-
),
|
|
975
|
-
joinQuery: joinQueryChainHOF(
|
|
976
|
-
relPKeys,
|
|
977
|
-
reverseJoin,
|
|
978
|
-
(joiningQuery, baseQuery) => joinHasRelation(
|
|
979
|
-
baseQuery,
|
|
980
|
-
joiningQuery,
|
|
981
|
-
primaryKeys,
|
|
982
|
-
foreignKeys,
|
|
983
|
-
len
|
|
984
|
-
)
|
|
985
|
-
),
|
|
986
|
-
reverseJoin,
|
|
987
|
-
modifyRelatedQuery(relationQuery) {
|
|
988
|
-
return (query2) => {
|
|
989
|
-
const baseQuery = query2.clone();
|
|
990
|
-
baseQuery.q.select = fromQuerySelect;
|
|
991
|
-
const q = relationQuery.q;
|
|
992
|
-
q.insertFrom = internal.prepareSubQueryForSql(q, baseQuery);
|
|
993
|
-
q.values = [];
|
|
994
|
-
};
|
|
995
|
-
}
|
|
996
|
-
};
|
|
584
|
+
const relPKeys = (0, pqb_internal.getPrimaryKeys)(query);
|
|
585
|
+
if ("through" in relation.options) {
|
|
586
|
+
const { through, source } = relation.options;
|
|
587
|
+
const throughRelation = getThroughRelation(table, through);
|
|
588
|
+
const sourceRelation = getSourceRelation(throughRelation, source);
|
|
589
|
+
const sourceRelationQuery = sourceRelation.query.as(relationName);
|
|
590
|
+
const sourceQuery = sourceRelation.joinQuery(sourceRelationQuery, throughRelation.query);
|
|
591
|
+
const whereExistsCallback = () => sourceQuery;
|
|
592
|
+
const reverseJoin = (baseQuery, joiningQuery) => {
|
|
593
|
+
return joinHasThrough(baseQuery, baseQuery, joiningQuery, throughRelation, sourceRelation);
|
|
594
|
+
};
|
|
595
|
+
return {
|
|
596
|
+
returns: "one",
|
|
597
|
+
queryRelated: (params) => {
|
|
598
|
+
const throughQuery = table.queryRelated(through, params);
|
|
599
|
+
return query.whereExists(throughQuery, whereExistsCallback);
|
|
600
|
+
},
|
|
601
|
+
joinQuery: joinQueryChainHOF(relPKeys, reverseJoin, (joiningQuery, baseQuery) => joinHasThrough(joiningQuery, baseQuery, joiningQuery, throughRelation, sourceRelation)),
|
|
602
|
+
reverseJoin
|
|
603
|
+
};
|
|
604
|
+
}
|
|
605
|
+
const primaryKeys = relation.options.columns;
|
|
606
|
+
const foreignKeys = relation.options.references;
|
|
607
|
+
const { on } = relation.options;
|
|
608
|
+
if (on) {
|
|
609
|
+
(0, pqb_internal._queryWhere)(query, [on]);
|
|
610
|
+
(0, pqb_internal._queryDefaults)(query, on);
|
|
611
|
+
}
|
|
612
|
+
addAutoForeignKey(tableConfig, query, table, primaryKeys, foreignKeys, relation.options);
|
|
613
|
+
const state = {
|
|
614
|
+
query,
|
|
615
|
+
primaryKeys,
|
|
616
|
+
foreignKeys,
|
|
617
|
+
on
|
|
618
|
+
};
|
|
619
|
+
const len = primaryKeys.length;
|
|
620
|
+
const reversedOn = {};
|
|
621
|
+
for (let i = 0; i < len; i++) reversedOn[foreignKeys[i]] = primaryKeys[i];
|
|
622
|
+
const fromQuerySelect = [{ selectAs: reversedOn }];
|
|
623
|
+
const reverseJoin = (baseQuery, joiningQuery) => {
|
|
624
|
+
return joinHasRelation(joiningQuery, baseQuery, foreignKeys, primaryKeys, len);
|
|
625
|
+
};
|
|
626
|
+
return {
|
|
627
|
+
returns: "one",
|
|
628
|
+
queryRelated: (params) => {
|
|
629
|
+
const values = {};
|
|
630
|
+
for (let i = 0; i < len; i++) values[foreignKeys[i]] = params[primaryKeys[i]];
|
|
631
|
+
return (0, pqb_internal._queryDefaults)(query.where(values), {
|
|
632
|
+
...on,
|
|
633
|
+
...values
|
|
634
|
+
});
|
|
635
|
+
},
|
|
636
|
+
virtualColumn: new HasOneVirtualColumn(pqb_internal.defaultSchemaConfig, relationName, state),
|
|
637
|
+
joinQuery: joinQueryChainHOF(relPKeys, reverseJoin, (joiningQuery, baseQuery) => joinHasRelation(baseQuery, joiningQuery, primaryKeys, foreignKeys, len)),
|
|
638
|
+
reverseJoin,
|
|
639
|
+
modifyRelatedQuery(relationQuery) {
|
|
640
|
+
return (query) => {
|
|
641
|
+
const baseQuery = query.clone();
|
|
642
|
+
baseQuery.q.select = fromQuerySelect;
|
|
643
|
+
const q = relationQuery.q;
|
|
644
|
+
q.insertFrom = (0, pqb_internal.prepareSubQueryForSql)(q, baseQuery);
|
|
645
|
+
q.values = [];
|
|
646
|
+
};
|
|
647
|
+
}
|
|
648
|
+
};
|
|
997
649
|
};
|
|
998
650
|
const nestedInsert$2 = ({ query, primaryKeys, foreignKeys }) => {
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
651
|
+
return (async (_, data) => {
|
|
652
|
+
const t = query.clone();
|
|
653
|
+
const items = [];
|
|
654
|
+
for (const item of data) if (item[1].connect || item[1].connectOrCreate) items.push(item);
|
|
655
|
+
let connected;
|
|
656
|
+
if (items.length) {
|
|
657
|
+
for (let i = 0, len = items.length; i < len; i++) {
|
|
658
|
+
const [selfData, item] = items[i];
|
|
659
|
+
const data = {};
|
|
660
|
+
primaryKeys.forEach((primaryKey, i) => {
|
|
661
|
+
data[foreignKeys[i]] = selfData[primaryKey];
|
|
662
|
+
});
|
|
663
|
+
items[i] = "connect" in item ? (0, pqb_internal._queryUpdateOrThrow)(t.where(item.connect), data) : (0, pqb_internal._queryUpdate)(t.where(item.connectOrCreate.where), data);
|
|
664
|
+
}
|
|
665
|
+
connected = await Promise.all(items);
|
|
666
|
+
} else connected = [];
|
|
667
|
+
let connectedI = 0;
|
|
668
|
+
items.length = 0;
|
|
669
|
+
for (const item of data) if (item[1].connectOrCreate) {
|
|
670
|
+
if (!connected[connectedI++]) items.push(item);
|
|
671
|
+
} else if (item[1].create) items.push(item);
|
|
672
|
+
if (items.length) {
|
|
673
|
+
for (let i = 0, len = items.length; i < len; i++) {
|
|
674
|
+
const [selfData, item] = items[i];
|
|
675
|
+
const data = { ..."create" in item ? item.create : item.connectOrCreate.create };
|
|
676
|
+
for (let i = 0; i < primaryKeys.length; i++) data[foreignKeys[i]] = selfData[primaryKeys[i]];
|
|
677
|
+
items[i] = data;
|
|
678
|
+
}
|
|
679
|
+
await t.insertMany(items);
|
|
680
|
+
}
|
|
681
|
+
});
|
|
682
|
+
};
|
|
683
|
+
var HasManyVirtualColumn = class extends pqb_internal.VirtualColumn {
|
|
684
|
+
constructor(schema, key, state) {
|
|
685
|
+
super(schema);
|
|
686
|
+
this.key = key;
|
|
687
|
+
this.state = state;
|
|
688
|
+
this.nestedInsert = nestedInsert$1(state);
|
|
689
|
+
this.nestedUpdate = nestedUpdate$1(state);
|
|
690
|
+
}
|
|
691
|
+
create(self, ctx, items, rowIndexes, count) {
|
|
692
|
+
if (count <= self.qb.internal.nestedCreateBatchMax) {
|
|
693
|
+
const { query: rel, primaryKeys, foreignKeys } = this.state;
|
|
694
|
+
let nestedCreateItems;
|
|
695
|
+
items.forEach((item, i) => {
|
|
696
|
+
const value = item[this.key];
|
|
697
|
+
if (value.create?.length) {
|
|
698
|
+
const nestedCreateItem = (nestedCreateItems ??= {}).create ??= {
|
|
699
|
+
indexes: [],
|
|
700
|
+
items: []
|
|
701
|
+
};
|
|
702
|
+
nestedCreateItem.indexes.push(rowIndexes[i]);
|
|
703
|
+
const data = value.create.map((obj) => {
|
|
704
|
+
const data = { ...obj };
|
|
705
|
+
for (const key of foreignKeys) data[key] = new pqb_internal.RawSql("");
|
|
706
|
+
return data;
|
|
707
|
+
});
|
|
708
|
+
nestedCreateItem.items.push(data);
|
|
709
|
+
} else {
|
|
710
|
+
const kind = value.connect?.length ? "connect" : value.connectOrCreate?.length ? "connectOrCreate" : void 0;
|
|
711
|
+
if (kind) {
|
|
712
|
+
const nestedCreateItem = (nestedCreateItems ??= {})[kind] ??= {
|
|
713
|
+
indexes: [],
|
|
714
|
+
items: [],
|
|
715
|
+
values: []
|
|
716
|
+
};
|
|
717
|
+
nestedCreateItem.indexes.push(rowIndexes[i]);
|
|
718
|
+
nestedCreateItem.values.push(value[kind]);
|
|
719
|
+
const data = {};
|
|
720
|
+
for (const key of foreignKeys) data[key] = new pqb_internal.RawSql("");
|
|
721
|
+
nestedCreateItem.items.push(data);
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
});
|
|
725
|
+
if (!nestedCreateItems) return;
|
|
726
|
+
let createAs;
|
|
727
|
+
let connectAs;
|
|
728
|
+
let connectOrCreateAs;
|
|
729
|
+
(0, pqb_internal._hookSelectColumns)(self, primaryKeys, (aliasedPrimaryKeys) => {
|
|
730
|
+
foreignKeys.forEach((key, keyI) => {
|
|
731
|
+
const primaryKey = aliasedPrimaryKeys[keyI];
|
|
732
|
+
if (create && createAs) for (let i = 0; i < create.items.length; i++) {
|
|
733
|
+
const sql = selectCteColumnFromManySql(createAs, primaryKey, create.indexes[i], count);
|
|
734
|
+
for (const item of create.items[i]) item[key]._sql = sql;
|
|
735
|
+
}
|
|
736
|
+
if (connect && connectAs) for (let i = 0; i < connect.items.length; i++) connect.items[i][key]._sql = selectCteColumnFromManySql(connectAs, primaryKey, connect.indexes[i], count);
|
|
737
|
+
if (connectOrCreate && connectOrCreateAs) for (let i = 0; i < connectOrCreate.items.length; i++) connectOrCreate.items[i][key]._sql = selectCteColumnFromManySql(connectOrCreateAs, primaryKey, connectOrCreate.indexes[i], count);
|
|
738
|
+
});
|
|
739
|
+
});
|
|
740
|
+
const { create, connect, connectOrCreate } = nestedCreateItems;
|
|
741
|
+
if (create) (0, pqb_internal._appendQuery)(self, (0, pqb_internal._queryInsertMany)((0, pqb_internal._clone)(rel), create.items.flat()), (as) => createAs = as);
|
|
742
|
+
if (connect) connect.values.forEach((value, i) => {
|
|
743
|
+
const query = (0, pqb_internal._queryUpdateOrThrow)(rel.whereOneOf(...value), connect.items[i]);
|
|
744
|
+
query.q.ensureCount = value.length;
|
|
745
|
+
(0, pqb_internal._appendQuery)(self, query, (as) => connectAs = as);
|
|
746
|
+
});
|
|
747
|
+
if (connectOrCreate) connectOrCreate.values.forEach((array, i) => {
|
|
748
|
+
const foreignKeyValues = connectOrCreate.items[i];
|
|
749
|
+
for (const value of array) (0, pqb_internal._appendQuery)(self, (0, pqb_internal._queryUpsert)(rel.where(value.where), {
|
|
750
|
+
update: foreignKeyValues,
|
|
751
|
+
create: {
|
|
752
|
+
...value.create,
|
|
753
|
+
...foreignKeyValues
|
|
754
|
+
}
|
|
755
|
+
}), (as) => connectOrCreateAs = as);
|
|
756
|
+
});
|
|
757
|
+
} else hasRelationHandleCreate(self, ctx, items, rowIndexes, this.key, this.state.primaryKeys, this.nestedInsert);
|
|
758
|
+
}
|
|
759
|
+
update(q, set) {
|
|
760
|
+
const params = set[this.key];
|
|
761
|
+
if ((params.set || params.create) && (0, pqb_internal.isQueryReturnsAll)(q)) {
|
|
762
|
+
const key = params.set ? "set" : "create";
|
|
763
|
+
throw new Error(`\`${key}\` option is not allowed in a batch update`);
|
|
764
|
+
}
|
|
765
|
+
hasRelationHandleUpdate(q, set, this.key, this.state.primaryKeys, this.nestedUpdate);
|
|
766
|
+
}
|
|
1054
767
|
};
|
|
1055
|
-
|
|
1056
|
-
class HasManyVirtualColumn extends internal.VirtualColumn {
|
|
1057
|
-
constructor(schema, key, state) {
|
|
1058
|
-
super(schema);
|
|
1059
|
-
this.key = key;
|
|
1060
|
-
this.state = state;
|
|
1061
|
-
this.nestedInsert = nestedInsert$1(state);
|
|
1062
|
-
this.nestedUpdate = nestedUpdate$1(state);
|
|
1063
|
-
}
|
|
1064
|
-
create(self, ctx, items, rowIndexes, count) {
|
|
1065
|
-
if (count <= self.qb.internal.nestedCreateBatchMax) {
|
|
1066
|
-
const { query: rel, primaryKeys, foreignKeys } = this.state;
|
|
1067
|
-
let nestedCreateItems;
|
|
1068
|
-
items.forEach((item, i) => {
|
|
1069
|
-
var _a, _b;
|
|
1070
|
-
const value = item[this.key];
|
|
1071
|
-
if (value.create?.length) {
|
|
1072
|
-
const nestedCreateItem = (_a = nestedCreateItems ?? (nestedCreateItems = {})).create ?? (_a.create = {
|
|
1073
|
-
indexes: [],
|
|
1074
|
-
items: []
|
|
1075
|
-
});
|
|
1076
|
-
nestedCreateItem.indexes.push(rowIndexes[i]);
|
|
1077
|
-
const data = value.create.map((obj) => {
|
|
1078
|
-
const data2 = { ...obj };
|
|
1079
|
-
for (const key of foreignKeys) {
|
|
1080
|
-
data2[key] = new internal.RawSql("");
|
|
1081
|
-
}
|
|
1082
|
-
return data2;
|
|
1083
|
-
});
|
|
1084
|
-
nestedCreateItem.items.push(data);
|
|
1085
|
-
} else {
|
|
1086
|
-
const kind = value.connect?.length ? "connect" : value.connectOrCreate?.length ? "connectOrCreate" : void 0;
|
|
1087
|
-
if (kind) {
|
|
1088
|
-
const nestedCreateItem = (_b = nestedCreateItems ?? (nestedCreateItems = {}))[kind] ?? (_b[kind] = {
|
|
1089
|
-
indexes: [],
|
|
1090
|
-
items: [],
|
|
1091
|
-
values: []
|
|
1092
|
-
});
|
|
1093
|
-
nestedCreateItem.indexes.push(rowIndexes[i]);
|
|
1094
|
-
nestedCreateItem.values.push(value[kind]);
|
|
1095
|
-
const data = {};
|
|
1096
|
-
for (const key of foreignKeys) {
|
|
1097
|
-
data[key] = new internal.RawSql("");
|
|
1098
|
-
}
|
|
1099
|
-
nestedCreateItem.items.push(data);
|
|
1100
|
-
}
|
|
1101
|
-
}
|
|
1102
|
-
});
|
|
1103
|
-
if (!nestedCreateItems) {
|
|
1104
|
-
return;
|
|
1105
|
-
}
|
|
1106
|
-
let createAs;
|
|
1107
|
-
let connectAs;
|
|
1108
|
-
let connectOrCreateAs;
|
|
1109
|
-
internal._hookSelectColumns(self, primaryKeys, (aliasedPrimaryKeys) => {
|
|
1110
|
-
foreignKeys.forEach((key, keyI) => {
|
|
1111
|
-
const primaryKey = aliasedPrimaryKeys[keyI];
|
|
1112
|
-
if (create && createAs) {
|
|
1113
|
-
for (let i = 0; i < create.items.length; i++) {
|
|
1114
|
-
const sql = selectCteColumnFromManySql(
|
|
1115
|
-
createAs,
|
|
1116
|
-
primaryKey,
|
|
1117
|
-
create.indexes[i],
|
|
1118
|
-
count
|
|
1119
|
-
);
|
|
1120
|
-
for (const item of create.items[i]) {
|
|
1121
|
-
item[key]._sql = sql;
|
|
1122
|
-
}
|
|
1123
|
-
}
|
|
1124
|
-
}
|
|
1125
|
-
if (connect && connectAs) {
|
|
1126
|
-
for (let i = 0; i < connect.items.length; i++) {
|
|
1127
|
-
connect.items[i][key]._sql = selectCteColumnFromManySql(
|
|
1128
|
-
connectAs,
|
|
1129
|
-
primaryKey,
|
|
1130
|
-
connect.indexes[i],
|
|
1131
|
-
count
|
|
1132
|
-
);
|
|
1133
|
-
}
|
|
1134
|
-
}
|
|
1135
|
-
if (connectOrCreate && connectOrCreateAs) {
|
|
1136
|
-
for (let i = 0; i < connectOrCreate.items.length; i++) {
|
|
1137
|
-
connectOrCreate.items[i][key]._sql = selectCteColumnFromManySql(
|
|
1138
|
-
connectOrCreateAs,
|
|
1139
|
-
primaryKey,
|
|
1140
|
-
connectOrCreate.indexes[i],
|
|
1141
|
-
count
|
|
1142
|
-
);
|
|
1143
|
-
}
|
|
1144
|
-
}
|
|
1145
|
-
});
|
|
1146
|
-
});
|
|
1147
|
-
const { create, connect, connectOrCreate } = nestedCreateItems;
|
|
1148
|
-
if (create) {
|
|
1149
|
-
const query = internal._queryInsertMany(
|
|
1150
|
-
internal._clone(rel),
|
|
1151
|
-
create.items.flat()
|
|
1152
|
-
);
|
|
1153
|
-
internal._appendQuery(self, query, (as) => createAs = as);
|
|
1154
|
-
}
|
|
1155
|
-
if (connect) {
|
|
1156
|
-
connect.values.forEach((value, i) => {
|
|
1157
|
-
const query = internal._queryUpdateOrThrow(
|
|
1158
|
-
rel.whereOneOf(...value),
|
|
1159
|
-
connect.items[i]
|
|
1160
|
-
);
|
|
1161
|
-
query.q.ensureCount = value.length;
|
|
1162
|
-
internal._appendQuery(self, query, (as) => connectAs = as);
|
|
1163
|
-
});
|
|
1164
|
-
}
|
|
1165
|
-
if (connectOrCreate) {
|
|
1166
|
-
connectOrCreate.values.forEach((array, i) => {
|
|
1167
|
-
const foreignKeyValues = connectOrCreate.items[i];
|
|
1168
|
-
for (const value of array) {
|
|
1169
|
-
const query = internal._queryUpsert(rel.where(value.where), {
|
|
1170
|
-
update: foreignKeyValues,
|
|
1171
|
-
create: {
|
|
1172
|
-
...value.create,
|
|
1173
|
-
...foreignKeyValues
|
|
1174
|
-
}
|
|
1175
|
-
});
|
|
1176
|
-
internal._appendQuery(self, query, (as) => connectOrCreateAs = as);
|
|
1177
|
-
}
|
|
1178
|
-
});
|
|
1179
|
-
}
|
|
1180
|
-
} else {
|
|
1181
|
-
hasRelationHandleCreate(
|
|
1182
|
-
self,
|
|
1183
|
-
ctx,
|
|
1184
|
-
items,
|
|
1185
|
-
rowIndexes,
|
|
1186
|
-
this.key,
|
|
1187
|
-
this.state.primaryKeys,
|
|
1188
|
-
this.nestedInsert
|
|
1189
|
-
);
|
|
1190
|
-
}
|
|
1191
|
-
}
|
|
1192
|
-
update(q, set) {
|
|
1193
|
-
const params = set[this.key];
|
|
1194
|
-
if ((params.set || params.create) && internal.isQueryReturnsAll(q)) {
|
|
1195
|
-
const key = params.set ? "set" : "create";
|
|
1196
|
-
throw new Error(`\`${key}\` option is not allowed in a batch update`);
|
|
1197
|
-
}
|
|
1198
|
-
hasRelationHandleUpdate(
|
|
1199
|
-
q,
|
|
1200
|
-
set,
|
|
1201
|
-
this.key,
|
|
1202
|
-
this.state.primaryKeys,
|
|
1203
|
-
this.nestedUpdate
|
|
1204
|
-
);
|
|
1205
|
-
}
|
|
1206
|
-
}
|
|
1207
768
|
const makeHasManyMethod = (tableConfig, table, relation, relationName, query) => {
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
}
|
|
1274
|
-
const fromQuerySelect = [{ selectAs: reversedOn }];
|
|
1275
|
-
const reverseJoin = (baseQuery, joiningQuery) => {
|
|
1276
|
-
return joinHasRelation(
|
|
1277
|
-
joiningQuery,
|
|
1278
|
-
baseQuery,
|
|
1279
|
-
foreignKeys,
|
|
1280
|
-
primaryKeys,
|
|
1281
|
-
len
|
|
1282
|
-
);
|
|
1283
|
-
};
|
|
1284
|
-
return {
|
|
1285
|
-
returns: "many",
|
|
1286
|
-
queryRelated: (params) => {
|
|
1287
|
-
const values = {};
|
|
1288
|
-
for (let i = 0; i < len; i++) {
|
|
1289
|
-
values[foreignKeys[i]] = params[primaryKeys[i]];
|
|
1290
|
-
}
|
|
1291
|
-
return internal._queryDefaults(query.where(values), { ...on, ...values });
|
|
1292
|
-
},
|
|
1293
|
-
virtualColumn: new HasManyVirtualColumn(
|
|
1294
|
-
internal.defaultSchemaConfig,
|
|
1295
|
-
relationName,
|
|
1296
|
-
state
|
|
1297
|
-
),
|
|
1298
|
-
joinQuery: joinQueryChainHOF(
|
|
1299
|
-
relPKeys,
|
|
1300
|
-
reverseJoin,
|
|
1301
|
-
(joiningQuery, baseQuery) => joinHasRelation(
|
|
1302
|
-
baseQuery,
|
|
1303
|
-
joiningQuery,
|
|
1304
|
-
primaryKeys,
|
|
1305
|
-
foreignKeys,
|
|
1306
|
-
len
|
|
1307
|
-
)
|
|
1308
|
-
),
|
|
1309
|
-
reverseJoin,
|
|
1310
|
-
modifyRelatedQuery(relationQuery) {
|
|
1311
|
-
return (query2) => {
|
|
1312
|
-
const baseQuery = query2.clone();
|
|
1313
|
-
baseQuery.q.select = fromQuerySelect;
|
|
1314
|
-
const q = relationQuery.q;
|
|
1315
|
-
q.insertFrom = internal.prepareSubQueryForSql(q, baseQuery);
|
|
1316
|
-
q.values = [];
|
|
1317
|
-
};
|
|
1318
|
-
}
|
|
1319
|
-
};
|
|
769
|
+
const relPKeys = (0, pqb_internal.getPrimaryKeys)(query);
|
|
770
|
+
if ("through" in relation.options) {
|
|
771
|
+
const { through, source } = relation.options;
|
|
772
|
+
const throughRelation = getThroughRelation(table, through);
|
|
773
|
+
const sourceRelation = getSourceRelation(throughRelation, source);
|
|
774
|
+
const sourceRelationQuery = sourceRelation.query.as(relationName);
|
|
775
|
+
const sourceQuery = sourceRelation.joinQuery(sourceRelationQuery, throughRelation.query);
|
|
776
|
+
const whereExistsCallback = () => sourceQuery;
|
|
777
|
+
const reverseJoin = (baseQuery, joiningQuery) => {
|
|
778
|
+
return joinHasThrough(baseQuery, baseQuery, joiningQuery, throughRelation, sourceRelation);
|
|
779
|
+
};
|
|
780
|
+
return {
|
|
781
|
+
returns: "many",
|
|
782
|
+
queryRelated: (params) => {
|
|
783
|
+
const throughQuery = table.queryRelated(through, params);
|
|
784
|
+
return query.whereExists(throughQuery, whereExistsCallback);
|
|
785
|
+
},
|
|
786
|
+
joinQuery: joinQueryChainHOF(relPKeys, reverseJoin, (joiningQuery, baseQuery) => joinHasThrough(joiningQuery, baseQuery, joiningQuery, throughRelation, sourceRelation)),
|
|
787
|
+
reverseJoin
|
|
788
|
+
};
|
|
789
|
+
}
|
|
790
|
+
const primaryKeys = relation.options.columns;
|
|
791
|
+
const foreignKeys = relation.options.references;
|
|
792
|
+
const { on } = relation.options;
|
|
793
|
+
if (on) {
|
|
794
|
+
(0, pqb_internal._queryWhere)(query, [on]);
|
|
795
|
+
(0, pqb_internal._queryDefaults)(query, on);
|
|
796
|
+
}
|
|
797
|
+
addAutoForeignKey(tableConfig, query, table, primaryKeys, foreignKeys, relation.options);
|
|
798
|
+
const state = {
|
|
799
|
+
query,
|
|
800
|
+
primaryKeys,
|
|
801
|
+
foreignKeys,
|
|
802
|
+
on
|
|
803
|
+
};
|
|
804
|
+
const len = primaryKeys.length;
|
|
805
|
+
const reversedOn = {};
|
|
806
|
+
for (let i = 0; i < len; i++) reversedOn[foreignKeys[i]] = primaryKeys[i];
|
|
807
|
+
const fromQuerySelect = [{ selectAs: reversedOn }];
|
|
808
|
+
const reverseJoin = (baseQuery, joiningQuery) => {
|
|
809
|
+
return joinHasRelation(joiningQuery, baseQuery, foreignKeys, primaryKeys, len);
|
|
810
|
+
};
|
|
811
|
+
return {
|
|
812
|
+
returns: "many",
|
|
813
|
+
queryRelated: (params) => {
|
|
814
|
+
const values = {};
|
|
815
|
+
for (let i = 0; i < len; i++) values[foreignKeys[i]] = params[primaryKeys[i]];
|
|
816
|
+
return (0, pqb_internal._queryDefaults)(query.where(values), {
|
|
817
|
+
...on,
|
|
818
|
+
...values
|
|
819
|
+
});
|
|
820
|
+
},
|
|
821
|
+
virtualColumn: new HasManyVirtualColumn(pqb_internal.defaultSchemaConfig, relationName, state),
|
|
822
|
+
joinQuery: joinQueryChainHOF(relPKeys, reverseJoin, (joiningQuery, baseQuery) => joinHasRelation(baseQuery, joiningQuery, primaryKeys, foreignKeys, len)),
|
|
823
|
+
reverseJoin,
|
|
824
|
+
modifyRelatedQuery(relationQuery) {
|
|
825
|
+
return (query) => {
|
|
826
|
+
const baseQuery = query.clone();
|
|
827
|
+
baseQuery.q.select = fromQuerySelect;
|
|
828
|
+
const q = relationQuery.q;
|
|
829
|
+
q.insertFrom = (0, pqb_internal.prepareSubQueryForSql)(q, baseQuery);
|
|
830
|
+
q.values = [];
|
|
831
|
+
};
|
|
832
|
+
}
|
|
833
|
+
};
|
|
1320
834
|
};
|
|
1321
835
|
const getWhereForNestedUpdate = (t, data, params, primaryKeys, foreignKeys) => {
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
836
|
+
return t.where({
|
|
837
|
+
IN: {
|
|
838
|
+
columns: foreignKeys,
|
|
839
|
+
values: data.map((item) => primaryKeys.map((key) => item[key]))
|
|
840
|
+
},
|
|
841
|
+
OR: params ? (0, pqb_internal.toArray)(params) : void 0
|
|
842
|
+
});
|
|
1329
843
|
};
|
|
1330
844
|
const nestedInsert$1 = ({ query, primaryKeys, foreignKeys }) => {
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
items.push(item);
|
|
1391
|
-
break;
|
|
1392
|
-
}
|
|
1393
|
-
}
|
|
1394
|
-
} else if (item[1].create) {
|
|
1395
|
-
items.push(item);
|
|
1396
|
-
}
|
|
1397
|
-
}
|
|
1398
|
-
connectedI = 0;
|
|
1399
|
-
if (items.length) {
|
|
1400
|
-
const records = [];
|
|
1401
|
-
for (const [selfData, { create, connectOrCreate }] of items) {
|
|
1402
|
-
const obj = {};
|
|
1403
|
-
for (let i = 0; i < len; i++) {
|
|
1404
|
-
obj[foreignKeys[i]] = selfData[primaryKeys[i]];
|
|
1405
|
-
}
|
|
1406
|
-
if (create) {
|
|
1407
|
-
for (const item of create) {
|
|
1408
|
-
records.push({
|
|
1409
|
-
...item,
|
|
1410
|
-
...obj
|
|
1411
|
-
});
|
|
1412
|
-
}
|
|
1413
|
-
}
|
|
1414
|
-
if (connectOrCreate) {
|
|
1415
|
-
for (const item of connectOrCreate) {
|
|
1416
|
-
if (connected[connectedI++] === 0) {
|
|
1417
|
-
records.push({
|
|
1418
|
-
...item.create,
|
|
1419
|
-
...obj
|
|
1420
|
-
});
|
|
1421
|
-
}
|
|
1422
|
-
}
|
|
1423
|
-
}
|
|
1424
|
-
}
|
|
1425
|
-
await internal._queryCreateMany(t, records);
|
|
1426
|
-
}
|
|
1427
|
-
};
|
|
845
|
+
const len = primaryKeys.length;
|
|
846
|
+
return (async (_, data) => {
|
|
847
|
+
const t = query.clone();
|
|
848
|
+
const items = [];
|
|
849
|
+
for (const item of data) if (item[1].connect) items.push(item);
|
|
850
|
+
if (items.length) {
|
|
851
|
+
for (let i = 0, len = items.length; i < len; i++) {
|
|
852
|
+
const [selfData, { connect }] = items[i];
|
|
853
|
+
const obj = {};
|
|
854
|
+
for (let i = 0; i < len; i++) obj[foreignKeys[i]] = selfData[primaryKeys[i]];
|
|
855
|
+
items[i] = (0, pqb_internal._queryUpdateOrThrow)(t.where({ OR: connect }), obj);
|
|
856
|
+
}
|
|
857
|
+
await Promise.all(items);
|
|
858
|
+
}
|
|
859
|
+
items.length = 0;
|
|
860
|
+
for (const item of data) if (item[1].connectOrCreate) items.push(item);
|
|
861
|
+
let connected;
|
|
862
|
+
if (items.length) {
|
|
863
|
+
const queries = [];
|
|
864
|
+
for (let i = 0, len = items.length; i < len; i++) {
|
|
865
|
+
const [selfData, { connectOrCreate }] = items[i];
|
|
866
|
+
for (const item of connectOrCreate) {
|
|
867
|
+
const obj = {};
|
|
868
|
+
for (let i = 0; i < len; i++) obj[foreignKeys[i]] = selfData[primaryKeys[i]];
|
|
869
|
+
queries.push((0, pqb_internal._queryUpdate)(t.where(item.where), obj));
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
connected = await Promise.all(queries);
|
|
873
|
+
} else connected = [];
|
|
874
|
+
let connectedI = 0;
|
|
875
|
+
items.length = 0;
|
|
876
|
+
for (const item of data) if (item[1].connectOrCreate) {
|
|
877
|
+
const length = item[1].connectOrCreate.length;
|
|
878
|
+
connectedI += length;
|
|
879
|
+
for (let i = length; i > 0; i--) if (connected[connectedI - i] === 0) {
|
|
880
|
+
items.push(item);
|
|
881
|
+
break;
|
|
882
|
+
}
|
|
883
|
+
} else if (item[1].create) items.push(item);
|
|
884
|
+
connectedI = 0;
|
|
885
|
+
if (items.length) {
|
|
886
|
+
const records = [];
|
|
887
|
+
for (const [selfData, { create, connectOrCreate }] of items) {
|
|
888
|
+
const obj = {};
|
|
889
|
+
for (let i = 0; i < len; i++) obj[foreignKeys[i]] = selfData[primaryKeys[i]];
|
|
890
|
+
if (create) for (const item of create) records.push({
|
|
891
|
+
...item,
|
|
892
|
+
...obj
|
|
893
|
+
});
|
|
894
|
+
if (connectOrCreate) {
|
|
895
|
+
for (const item of connectOrCreate) if (connected[connectedI++] === 0) records.push({
|
|
896
|
+
...item.create,
|
|
897
|
+
...obj
|
|
898
|
+
});
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
await (0, pqb_internal._queryCreateMany)(t, records);
|
|
902
|
+
}
|
|
903
|
+
});
|
|
1428
904
|
};
|
|
1429
905
|
const nestedUpdate$1 = ({ query, primaryKeys, foreignKeys }) => {
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
queryToDisconnect = queryToDisconnect.whereNot(setConditions);
|
|
1485
|
-
}
|
|
1486
|
-
await internal._queryUpdate(queryToDisconnect, obj);
|
|
1487
|
-
if (setConditions) {
|
|
1488
|
-
const obj2 = {};
|
|
1489
|
-
for (let i = 0; i < len; i++) {
|
|
1490
|
-
obj2[foreignKeys[i]] = data[0][primaryKeys[i]];
|
|
1491
|
-
}
|
|
1492
|
-
await internal._queryUpdate(
|
|
1493
|
-
t.where(setConditions),
|
|
1494
|
-
obj2
|
|
1495
|
-
);
|
|
1496
|
-
}
|
|
1497
|
-
}
|
|
1498
|
-
if (params.delete || params.update) {
|
|
1499
|
-
const q = getWhereForNestedUpdate(
|
|
1500
|
-
t,
|
|
1501
|
-
data,
|
|
1502
|
-
params.delete || params.update?.where,
|
|
1503
|
-
primaryKeys,
|
|
1504
|
-
foreignKeys
|
|
1505
|
-
);
|
|
1506
|
-
if (params.delete) {
|
|
1507
|
-
await internal._queryDelete(q);
|
|
1508
|
-
} else if (params.update) {
|
|
1509
|
-
await internal._queryUpdate(q, params.update.data);
|
|
1510
|
-
}
|
|
1511
|
-
}
|
|
1512
|
-
};
|
|
906
|
+
const len = primaryKeys.length;
|
|
907
|
+
return (async (_, data, params) => {
|
|
908
|
+
const t = query.clone();
|
|
909
|
+
if (params.create) {
|
|
910
|
+
const obj = {};
|
|
911
|
+
for (let i = 0; i < len; i++) obj[foreignKeys[i]] = data[0][primaryKeys[i]];
|
|
912
|
+
await t.insertMany(params.create.map((create) => ({
|
|
913
|
+
...create,
|
|
914
|
+
...obj
|
|
915
|
+
})));
|
|
916
|
+
}
|
|
917
|
+
if (params.add) {
|
|
918
|
+
if (data.length > 1) throw new pqb.OrchidOrmInternalError(query, "`connect` is not available when updating multiple records, it is only applicable for a single record update");
|
|
919
|
+
const obj = {};
|
|
920
|
+
for (let i = 0; i < len; i++) obj[foreignKeys[i]] = data[0][primaryKeys[i]];
|
|
921
|
+
const relatedWheres = (0, pqb_internal.toArray)(params.add);
|
|
922
|
+
const count = await (0, pqb_internal._queryUpdate)(t.where({ OR: relatedWheres }), obj);
|
|
923
|
+
if (count < relatedWheres.length) throw new pqb.OrchidOrmInternalError(query, `Expected to find at least ${relatedWheres.length} record(s) based on \`add\` conditions, but found ${count}`);
|
|
924
|
+
}
|
|
925
|
+
if (params.disconnect || params.set) {
|
|
926
|
+
const obj = {};
|
|
927
|
+
for (const foreignKey of foreignKeys) obj[foreignKey] = null;
|
|
928
|
+
const setConditions = params.set && (Array.isArray(params.set) ? params.set.length : (0, pqb_internal.objectHasValues)(params.set)) && (Array.isArray(params.set) ? { OR: params.set } : params.set);
|
|
929
|
+
let queryToDisconnect = getWhereForNestedUpdate(t, data, params.disconnect, primaryKeys, foreignKeys);
|
|
930
|
+
if (setConditions) queryToDisconnect = queryToDisconnect.whereNot(setConditions);
|
|
931
|
+
await (0, pqb_internal._queryUpdate)(queryToDisconnect, obj);
|
|
932
|
+
if (setConditions) {
|
|
933
|
+
const obj = {};
|
|
934
|
+
for (let i = 0; i < len; i++) obj[foreignKeys[i]] = data[0][primaryKeys[i]];
|
|
935
|
+
await (0, pqb_internal._queryUpdate)(t.where(setConditions), obj);
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
if (params.delete || params.update) {
|
|
939
|
+
const q = getWhereForNestedUpdate(t, data, params.delete || params.update?.where, primaryKeys, foreignKeys);
|
|
940
|
+
if (params.delete) await (0, pqb_internal._queryDelete)(q);
|
|
941
|
+
else if (params.update) await (0, pqb_internal._queryUpdate)(q, params.update.data);
|
|
942
|
+
}
|
|
943
|
+
});
|
|
944
|
+
};
|
|
945
|
+
var HasAndBelongsToManyVirtualColumn = class extends pqb_internal.VirtualColumn {
|
|
946
|
+
constructor(joinTable, schema, key, state) {
|
|
947
|
+
super(schema);
|
|
948
|
+
this.joinTable = joinTable;
|
|
949
|
+
this.key = key;
|
|
950
|
+
this.state = state;
|
|
951
|
+
this.nestedInsert = nestedInsert(state);
|
|
952
|
+
this.nestedUpdate = nestedUpdate(state);
|
|
953
|
+
}
|
|
954
|
+
create(q, ctx, items, rowIndexes) {
|
|
955
|
+
hasRelationHandleCreate(q, ctx, items, rowIndexes, this.key, this.state.primaryKeys, this.nestedInsert);
|
|
956
|
+
}
|
|
957
|
+
update(q, set) {
|
|
958
|
+
hasRelationHandleUpdate(q, set, this.key, this.state.primaryKeys, this.nestedUpdate);
|
|
959
|
+
}
|
|
1513
960
|
};
|
|
1514
|
-
|
|
1515
|
-
class HasAndBelongsToManyVirtualColumn extends internal.VirtualColumn {
|
|
1516
|
-
constructor(joinTable, schema, key, state) {
|
|
1517
|
-
super(schema);
|
|
1518
|
-
this.joinTable = joinTable;
|
|
1519
|
-
this.key = key;
|
|
1520
|
-
this.state = state;
|
|
1521
|
-
this.nestedInsert = nestedInsert(state);
|
|
1522
|
-
this.nestedUpdate = nestedUpdate(state);
|
|
1523
|
-
}
|
|
1524
|
-
create(q, ctx, items, rowIndexes) {
|
|
1525
|
-
hasRelationHandleCreate(
|
|
1526
|
-
q,
|
|
1527
|
-
ctx,
|
|
1528
|
-
items,
|
|
1529
|
-
rowIndexes,
|
|
1530
|
-
this.key,
|
|
1531
|
-
this.state.primaryKeys,
|
|
1532
|
-
this.nestedInsert
|
|
1533
|
-
);
|
|
1534
|
-
}
|
|
1535
|
-
update(q, set) {
|
|
1536
|
-
hasRelationHandleUpdate(
|
|
1537
|
-
q,
|
|
1538
|
-
set,
|
|
1539
|
-
this.key,
|
|
1540
|
-
this.state.primaryKeys,
|
|
1541
|
-
this.nestedUpdate
|
|
1542
|
-
);
|
|
1543
|
-
}
|
|
1544
|
-
}
|
|
1545
961
|
const removeColumnName = (column) => {
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
962
|
+
if (!column.data.name) return column;
|
|
963
|
+
const cloned = Object.create(column);
|
|
964
|
+
cloned.data = {
|
|
965
|
+
...column.data,
|
|
966
|
+
name: void 0
|
|
967
|
+
};
|
|
968
|
+
return cloned;
|
|
1550
969
|
};
|
|
1551
970
|
const makeHasAndBelongsToManyMethod = (tableConfig, table, qb, relation, relationName, query, schema) => {
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
...baseQuery2.q.joinedShapes,
|
|
1666
|
-
[foreignAs]: joiningQuery.q.shape
|
|
1667
|
-
}
|
|
1668
|
-
);
|
|
1669
|
-
};
|
|
1670
|
-
return {
|
|
1671
|
-
returns: "many",
|
|
1672
|
-
queryRelated(params) {
|
|
1673
|
-
const q = query.whereExists(subQuery, (q2) => {
|
|
1674
|
-
q2 = q2.clone();
|
|
1675
|
-
const where = {};
|
|
1676
|
-
for (let i = 0; i < len; i++) {
|
|
1677
|
-
where[foreignKeysFull[i]] = params[primaryKeys[i]];
|
|
1678
|
-
}
|
|
1679
|
-
for (let i = 0; i < throughLen; i++) {
|
|
1680
|
-
internal._queryJoinOn(q2, [
|
|
1681
|
-
throughForeignKeysFull[i],
|
|
1682
|
-
throughPrimaryKeysFull[i]
|
|
1683
|
-
]);
|
|
1684
|
-
}
|
|
1685
|
-
return internal._queryWhere(q2, [where]);
|
|
1686
|
-
});
|
|
1687
|
-
return on ? internal._queryDefaults(q, on) : q;
|
|
1688
|
-
},
|
|
1689
|
-
virtualColumn: new HasAndBelongsToManyVirtualColumn(
|
|
1690
|
-
subQuery,
|
|
1691
|
-
internal.defaultSchemaConfig,
|
|
1692
|
-
relationName,
|
|
1693
|
-
state
|
|
1694
|
-
),
|
|
1695
|
-
joinQuery: joinQueryChainHOF(
|
|
1696
|
-
internal.getPrimaryKeys(query),
|
|
1697
|
-
reverseJoin,
|
|
1698
|
-
(joiningQuery, baseQuery2) => joinQuery(
|
|
1699
|
-
joiningQuery,
|
|
1700
|
-
internal.getQueryAs(baseQuery2),
|
|
1701
|
-
internal.getQueryAs(joiningQuery),
|
|
1702
|
-
{
|
|
1703
|
-
...joiningQuery.q.joinedShapes,
|
|
1704
|
-
[baseQuery2.q.as || baseQuery2.table]: baseQuery2.q.shape
|
|
1705
|
-
}
|
|
1706
|
-
)
|
|
1707
|
-
),
|
|
1708
|
-
reverseJoin,
|
|
1709
|
-
modifyRelatedQuery(relationQuery) {
|
|
1710
|
-
const ref = {};
|
|
1711
|
-
internal._queryHookAfterCreate(
|
|
1712
|
-
relationQuery,
|
|
1713
|
-
[],
|
|
1714
|
-
async (result) => {
|
|
1715
|
-
const baseQuery2 = ref.q.clone();
|
|
1716
|
-
baseQuery2.q.select = selectPrimaryKeysAsForeignKeys;
|
|
1717
|
-
const data = result.map((resultRow) => {
|
|
1718
|
-
const dataRow = {};
|
|
1719
|
-
for (let i = 0; i < throughLen; i++) {
|
|
1720
|
-
dataRow[throughForeignKeys[i]] = resultRow[throughPrimaryKeys[i]];
|
|
1721
|
-
}
|
|
1722
|
-
return dataRow;
|
|
1723
|
-
});
|
|
1724
|
-
const createdCount = await internal._queryCreateManyFrom(
|
|
1725
|
-
subQuery.count(),
|
|
1726
|
-
baseQuery2,
|
|
1727
|
-
data
|
|
1728
|
-
);
|
|
1729
|
-
if (createdCount === 0) {
|
|
1730
|
-
throw new pqb.NotFoundError(baseQuery2);
|
|
1731
|
-
}
|
|
1732
|
-
}
|
|
1733
|
-
);
|
|
1734
|
-
return (q) => {
|
|
1735
|
-
ref.q = q;
|
|
1736
|
-
};
|
|
1737
|
-
}
|
|
1738
|
-
};
|
|
971
|
+
const { options } = relation;
|
|
972
|
+
const { snakeCase } = table.internal;
|
|
973
|
+
const primaryKeys = options.columns;
|
|
974
|
+
const foreignKeys = options.references;
|
|
975
|
+
const originalForeignKeys = snakeCase ? [...foreignKeys] : foreignKeys;
|
|
976
|
+
const joinTable = options.through.table;
|
|
977
|
+
const throughForeignKeys = options.through.columns;
|
|
978
|
+
const originalThroughForeignKeys = snakeCase ? [...throughForeignKeys] : throughForeignKeys;
|
|
979
|
+
const throughPrimaryKeys = options.through.references;
|
|
980
|
+
const { on } = options;
|
|
981
|
+
if (on) {
|
|
982
|
+
(0, pqb_internal._queryWhere)(query, [on]);
|
|
983
|
+
(0, pqb_internal._queryDefaults)(query, on);
|
|
984
|
+
}
|
|
985
|
+
const foreignKeysFull = foreignKeys.map((key, i) => {
|
|
986
|
+
if (snakeCase) key = foreignKeys[i] = (0, pqb_internal.toSnakeCase)(key);
|
|
987
|
+
return `${joinTable}.${key}`;
|
|
988
|
+
});
|
|
989
|
+
const throughForeignKeysFull = throughForeignKeys.map((key, i) => {
|
|
990
|
+
if (snakeCase) key = throughForeignKeys[i] = (0, pqb_internal.toSnakeCase)(key);
|
|
991
|
+
return `${joinTable}.${key}`;
|
|
992
|
+
});
|
|
993
|
+
const foreignTable = (0, pqb_internal.getQueryAs)(query);
|
|
994
|
+
const throughPrimaryKeysFull = throughPrimaryKeys.map((key) => `${foreignTable}.${key}`);
|
|
995
|
+
const len = primaryKeys.length;
|
|
996
|
+
const throughLen = throughPrimaryKeys.length;
|
|
997
|
+
const baseQuery = Object.create(qb.baseQuery);
|
|
998
|
+
baseQuery.baseQuery = baseQuery;
|
|
999
|
+
baseQuery.table = joinTable;
|
|
1000
|
+
const shape = {};
|
|
1001
|
+
const primaryKeysShape = {};
|
|
1002
|
+
for (let i = 0; i < len; i++) {
|
|
1003
|
+
const pk = primaryKeys[i];
|
|
1004
|
+
shape[foreignKeys[i]] = removeColumnName(table.shape[pk]);
|
|
1005
|
+
primaryKeysShape[pk] = table.shape[pk];
|
|
1006
|
+
}
|
|
1007
|
+
for (let i = 0; i < throughLen; i++) shape[throughForeignKeys[i]] = removeColumnName(query.shape[throughPrimaryKeys[i]]);
|
|
1008
|
+
baseQuery.shape = shape;
|
|
1009
|
+
baseQuery.q = {
|
|
1010
|
+
...baseQuery.q,
|
|
1011
|
+
schema: options.through.schema || schema,
|
|
1012
|
+
shape: baseQuery.shape
|
|
1013
|
+
};
|
|
1014
|
+
const subQuery = Object.create(baseQuery);
|
|
1015
|
+
addAutoForeignKey(tableConfig, subQuery, table, primaryKeys, foreignKeys, relation.options, originalForeignKeys);
|
|
1016
|
+
addAutoForeignKey(tableConfig, subQuery, query, throughPrimaryKeys, throughForeignKeys, relation.options.through, originalThroughForeignKeys);
|
|
1017
|
+
const state = {
|
|
1018
|
+
relatedTableQuery: query,
|
|
1019
|
+
joinTableQuery: subQuery,
|
|
1020
|
+
primaryKeys,
|
|
1021
|
+
foreignKeys,
|
|
1022
|
+
throughForeignKeys,
|
|
1023
|
+
throughPrimaryKeys,
|
|
1024
|
+
foreignKeysFull,
|
|
1025
|
+
throughForeignKeysFull,
|
|
1026
|
+
throughPrimaryKeysFull,
|
|
1027
|
+
primaryKeysShape,
|
|
1028
|
+
on
|
|
1029
|
+
};
|
|
1030
|
+
const joinQuery = (joiningQuery, tableAs, foreignAs, joinedShapes) => {
|
|
1031
|
+
const cloned = joiningQuery.clone();
|
|
1032
|
+
cloned.q.joinedShapes = joinedShapes;
|
|
1033
|
+
return (0, pqb_internal._queryWhereExists)(cloned, subQuery, [(q) => {
|
|
1034
|
+
for (let i = 0; i < throughLen; i++) (0, pqb_internal._queryJoinOn)(q, [throughForeignKeysFull[i], `${foreignAs}.${throughPrimaryKeys[i]}`]);
|
|
1035
|
+
for (let i = 0; i < len; i++) (0, pqb_internal._queryJoinOn)(q, [foreignKeysFull[i], `${tableAs}.${primaryKeys[i]}`]);
|
|
1036
|
+
return q;
|
|
1037
|
+
}]);
|
|
1038
|
+
};
|
|
1039
|
+
const obj = {};
|
|
1040
|
+
for (let i = 0; i < len; i++) obj[foreignKeys[i]] = primaryKeys[i];
|
|
1041
|
+
const selectPrimaryKeysAsForeignKeys = [{ selectAs: obj }];
|
|
1042
|
+
const reverseJoin = (baseQuery, joiningQuery) => {
|
|
1043
|
+
const foreignAs = (0, pqb_internal.getQueryAs)(joiningQuery);
|
|
1044
|
+
return joinQuery(baseQuery, (0, pqb_internal.getQueryAs)(baseQuery), foreignAs, {
|
|
1045
|
+
...baseQuery.q.joinedShapes,
|
|
1046
|
+
[foreignAs]: joiningQuery.q.shape
|
|
1047
|
+
});
|
|
1048
|
+
};
|
|
1049
|
+
return {
|
|
1050
|
+
returns: "many",
|
|
1051
|
+
queryRelated(params) {
|
|
1052
|
+
const q = query.whereExists(subQuery, (q) => {
|
|
1053
|
+
q = q.clone();
|
|
1054
|
+
const where = {};
|
|
1055
|
+
for (let i = 0; i < len; i++) where[foreignKeysFull[i]] = params[primaryKeys[i]];
|
|
1056
|
+
for (let i = 0; i < throughLen; i++) (0, pqb_internal._queryJoinOn)(q, [throughForeignKeysFull[i], throughPrimaryKeysFull[i]]);
|
|
1057
|
+
return (0, pqb_internal._queryWhere)(q, [where]);
|
|
1058
|
+
});
|
|
1059
|
+
return on ? (0, pqb_internal._queryDefaults)(q, on) : q;
|
|
1060
|
+
},
|
|
1061
|
+
virtualColumn: new HasAndBelongsToManyVirtualColumn(subQuery, pqb_internal.defaultSchemaConfig, relationName, state),
|
|
1062
|
+
joinQuery: joinQueryChainHOF((0, pqb_internal.getPrimaryKeys)(query), reverseJoin, (joiningQuery, baseQuery) => joinQuery(joiningQuery, (0, pqb_internal.getQueryAs)(baseQuery), (0, pqb_internal.getQueryAs)(joiningQuery), {
|
|
1063
|
+
...joiningQuery.q.joinedShapes,
|
|
1064
|
+
[baseQuery.q.as || baseQuery.table]: baseQuery.q.shape
|
|
1065
|
+
})),
|
|
1066
|
+
reverseJoin,
|
|
1067
|
+
modifyRelatedQuery(relationQuery) {
|
|
1068
|
+
const ref = {};
|
|
1069
|
+
(0, pqb_internal._queryHookAfterCreate)(relationQuery, [], async (result) => {
|
|
1070
|
+
const baseQuery = ref.q.clone();
|
|
1071
|
+
baseQuery.q.select = selectPrimaryKeysAsForeignKeys;
|
|
1072
|
+
const data = result.map((resultRow) => {
|
|
1073
|
+
const dataRow = {};
|
|
1074
|
+
for (let i = 0; i < throughLen; i++) dataRow[throughForeignKeys[i]] = resultRow[throughPrimaryKeys[i]];
|
|
1075
|
+
return dataRow;
|
|
1076
|
+
});
|
|
1077
|
+
if (await (0, pqb_internal._queryCreateManyFrom)(subQuery.count(), baseQuery, data) === 0) throw new pqb.NotFoundError(baseQuery);
|
|
1078
|
+
});
|
|
1079
|
+
return (q) => {
|
|
1080
|
+
ref.q = q;
|
|
1081
|
+
};
|
|
1082
|
+
}
|
|
1083
|
+
};
|
|
1739
1084
|
};
|
|
1740
1085
|
const queryJoinTable = (state, data, conditions) => {
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
state.throughPrimaryKeys
|
|
1755
|
-
)
|
|
1756
|
-
}
|
|
1757
|
-
}
|
|
1758
|
-
]);
|
|
1759
|
-
}
|
|
1760
|
-
if (state.on) {
|
|
1761
|
-
internal._queryWhereExists(t, state.relatedTableQuery, [
|
|
1762
|
-
(q) => {
|
|
1763
|
-
for (let i = 0; i < state.throughPrimaryKeys.length; i++) {
|
|
1764
|
-
internal._queryJoinOn(q, [
|
|
1765
|
-
state.throughPrimaryKeysFull[i],
|
|
1766
|
-
state.throughForeignKeysFull[i]
|
|
1767
|
-
]);
|
|
1768
|
-
}
|
|
1769
|
-
return q;
|
|
1770
|
-
}
|
|
1771
|
-
]);
|
|
1772
|
-
}
|
|
1773
|
-
return t;
|
|
1086
|
+
const t = state.joinTableQuery.where({ IN: {
|
|
1087
|
+
columns: state.foreignKeys,
|
|
1088
|
+
values: data.map((item) => state.primaryKeys.map((key) => item[key]))
|
|
1089
|
+
} });
|
|
1090
|
+
if (conditions) (0, pqb_internal._queryWhere)(t, [{ IN: {
|
|
1091
|
+
columns: state.throughForeignKeys,
|
|
1092
|
+
values: (0, pqb_internal._querySelect)(state.relatedTableQuery.where(conditionsToWhereArg(conditions)), state.throughPrimaryKeys)
|
|
1093
|
+
} }]);
|
|
1094
|
+
if (state.on) (0, pqb_internal._queryWhereExists)(t, state.relatedTableQuery, [(q) => {
|
|
1095
|
+
for (let i = 0; i < state.throughPrimaryKeys.length; i++) (0, pqb_internal._queryJoinOn)(q, [state.throughPrimaryKeysFull[i], state.throughForeignKeysFull[i]]);
|
|
1096
|
+
return q;
|
|
1097
|
+
}]);
|
|
1098
|
+
return t;
|
|
1774
1099
|
};
|
|
1775
1100
|
const conditionsToWhereArg = (conditions) => Array.isArray(conditions) ? { OR: conditions } : conditions;
|
|
1776
1101
|
const insertToJoinTable = (state, joinTableTransaction, data, idsRows) => {
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
records.push(record);
|
|
1791
|
-
}
|
|
1792
|
-
}
|
|
1793
|
-
return joinTableTransaction.insertMany(records);
|
|
1102
|
+
const len = state.primaryKeys.length;
|
|
1103
|
+
const throughLen = state.throughPrimaryKeys.length;
|
|
1104
|
+
const records = [];
|
|
1105
|
+
for (const item of data) {
|
|
1106
|
+
const obj = {};
|
|
1107
|
+
for (let i = 0; i < len; i++) obj[state.foreignKeys[i]] = item[state.primaryKeys[i]];
|
|
1108
|
+
for (const ids of idsRows) {
|
|
1109
|
+
const record = { ...obj };
|
|
1110
|
+
for (let i = 0; i < throughLen; i++) record[state.throughForeignKeys[i]] = ids[i];
|
|
1111
|
+
records.push(record);
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
return joinTableTransaction.insertMany(records);
|
|
1794
1115
|
};
|
|
1795
|
-
const nestedInsert = ({
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
if (!connectOrCreated[connectOrCreateI++]) {
|
|
1880
|
-
records2.push(item.create);
|
|
1881
|
-
}
|
|
1882
|
-
}
|
|
1883
|
-
}
|
|
1884
|
-
}
|
|
1885
|
-
created = await internal._queryCreateMany(
|
|
1886
|
-
t.select(...throughPrimaryKeys),
|
|
1887
|
-
records2
|
|
1888
|
-
);
|
|
1889
|
-
} else {
|
|
1890
|
-
created = [];
|
|
1891
|
-
}
|
|
1892
|
-
const allKeys = data;
|
|
1893
|
-
let createI = 0;
|
|
1894
|
-
let connectI = 0;
|
|
1895
|
-
connectOrCreateI = 0;
|
|
1896
|
-
for (let index = 0, len2 = data.length; index < len2; index++) {
|
|
1897
|
-
const item = data[index][1];
|
|
1898
|
-
if (item.create || item.connectOrCreate) {
|
|
1899
|
-
if (item.create) {
|
|
1900
|
-
const len3 = item.create.length;
|
|
1901
|
-
allKeys[index][1] = created.slice(createI, createI + len3);
|
|
1902
|
-
createI += len3;
|
|
1903
|
-
}
|
|
1904
|
-
if (item.connectOrCreate) {
|
|
1905
|
-
const arr = [];
|
|
1906
|
-
allKeys[index][1] = arr;
|
|
1907
|
-
const len3 = item.connectOrCreate.length;
|
|
1908
|
-
for (let i = 0; i < len3; i++) {
|
|
1909
|
-
const item2 = connectOrCreated[connectOrCreateI++];
|
|
1910
|
-
if (item2) {
|
|
1911
|
-
arr.push(item2);
|
|
1912
|
-
} else {
|
|
1913
|
-
arr.push(created[createI++]);
|
|
1914
|
-
}
|
|
1915
|
-
}
|
|
1916
|
-
}
|
|
1917
|
-
}
|
|
1918
|
-
if (item.connect) {
|
|
1919
|
-
const len3 = item.connect.length;
|
|
1920
|
-
allKeys[index][1] = connected.slice(connectI, connectI + len3);
|
|
1921
|
-
connectI += len3;
|
|
1922
|
-
}
|
|
1923
|
-
}
|
|
1924
|
-
const records = [];
|
|
1925
|
-
for (const [selfData, relationKeys] of allKeys) {
|
|
1926
|
-
const obj = {};
|
|
1927
|
-
for (let i = 0; i < len; i++) {
|
|
1928
|
-
obj[foreignKeys[i]] = selfData[primaryKeys[i]];
|
|
1929
|
-
}
|
|
1930
|
-
for (const relationData of relationKeys) {
|
|
1931
|
-
const record = { ...obj };
|
|
1932
|
-
for (let i = 0; i < throughLen; i++) {
|
|
1933
|
-
record[throughForeignKeys[i]] = relationData[throughPrimaryKeys[i]];
|
|
1934
|
-
}
|
|
1935
|
-
records.push(record);
|
|
1936
|
-
}
|
|
1937
|
-
}
|
|
1938
|
-
await joinTableQuery.insertMany(records);
|
|
1939
|
-
};
|
|
1116
|
+
const nestedInsert = ({ relatedTableQuery, joinTableQuery, primaryKeys, foreignKeys, throughPrimaryKeys, throughForeignKeys }) => {
|
|
1117
|
+
const len = primaryKeys.length;
|
|
1118
|
+
const throughLen = primaryKeys.length;
|
|
1119
|
+
return (async (_, data) => {
|
|
1120
|
+
const t = relatedTableQuery.clone();
|
|
1121
|
+
const items = [];
|
|
1122
|
+
for (const item of data) if (item[1].connect) items.push(item);
|
|
1123
|
+
let connected;
|
|
1124
|
+
if (items.length) {
|
|
1125
|
+
const queries = [];
|
|
1126
|
+
for (const [, { connect }] of items) for (const item of connect) queries.push((0, pqb_internal._queryFindBy)(t.select(...throughPrimaryKeys), item));
|
|
1127
|
+
connected = await Promise.all(queries);
|
|
1128
|
+
} else connected = [];
|
|
1129
|
+
items.length = 0;
|
|
1130
|
+
for (const item of data) if (item[1].connectOrCreate) items.push(item);
|
|
1131
|
+
let connectOrCreated;
|
|
1132
|
+
if (items.length) {
|
|
1133
|
+
const queries = [];
|
|
1134
|
+
for (const [, { connectOrCreate }] of items) for (const item of connectOrCreate) queries.push((0, pqb_internal._queryFindByOptional)(t.select(...throughPrimaryKeys), item.where));
|
|
1135
|
+
connectOrCreated = await Promise.all(queries);
|
|
1136
|
+
} else connectOrCreated = [];
|
|
1137
|
+
let connectOrCreateI = 0;
|
|
1138
|
+
items.length = 0;
|
|
1139
|
+
for (const item of data) if (item[1].connectOrCreate) {
|
|
1140
|
+
const length = item[1].connectOrCreate.length;
|
|
1141
|
+
connectOrCreateI += length;
|
|
1142
|
+
for (let i = length; i > 0; i--) if (!connectOrCreated[connectOrCreateI - i]) {
|
|
1143
|
+
items.push(item);
|
|
1144
|
+
break;
|
|
1145
|
+
}
|
|
1146
|
+
} else if (item[1].create) items.push(item);
|
|
1147
|
+
connectOrCreateI = 0;
|
|
1148
|
+
let created;
|
|
1149
|
+
if (items.length) {
|
|
1150
|
+
const records = [];
|
|
1151
|
+
for (const [, { create, connectOrCreate }] of items) {
|
|
1152
|
+
if (create) records.push(...create);
|
|
1153
|
+
if (connectOrCreate) {
|
|
1154
|
+
for (const item of connectOrCreate) if (!connectOrCreated[connectOrCreateI++]) records.push(item.create);
|
|
1155
|
+
}
|
|
1156
|
+
}
|
|
1157
|
+
created = await (0, pqb_internal._queryCreateMany)(t.select(...throughPrimaryKeys), records);
|
|
1158
|
+
} else created = [];
|
|
1159
|
+
const allKeys = data;
|
|
1160
|
+
let createI = 0;
|
|
1161
|
+
let connectI = 0;
|
|
1162
|
+
connectOrCreateI = 0;
|
|
1163
|
+
for (let index = 0, len = data.length; index < len; index++) {
|
|
1164
|
+
const item = data[index][1];
|
|
1165
|
+
if (item.create || item.connectOrCreate) {
|
|
1166
|
+
if (item.create) {
|
|
1167
|
+
const len = item.create.length;
|
|
1168
|
+
allKeys[index][1] = created.slice(createI, createI + len);
|
|
1169
|
+
createI += len;
|
|
1170
|
+
}
|
|
1171
|
+
if (item.connectOrCreate) {
|
|
1172
|
+
const arr = [];
|
|
1173
|
+
allKeys[index][1] = arr;
|
|
1174
|
+
const len = item.connectOrCreate.length;
|
|
1175
|
+
for (let i = 0; i < len; i++) {
|
|
1176
|
+
const item = connectOrCreated[connectOrCreateI++];
|
|
1177
|
+
if (item) arr.push(item);
|
|
1178
|
+
else arr.push(created[createI++]);
|
|
1179
|
+
}
|
|
1180
|
+
}
|
|
1181
|
+
}
|
|
1182
|
+
if (item.connect) {
|
|
1183
|
+
const len = item.connect.length;
|
|
1184
|
+
allKeys[index][1] = connected.slice(connectI, connectI + len);
|
|
1185
|
+
connectI += len;
|
|
1186
|
+
}
|
|
1187
|
+
}
|
|
1188
|
+
const records = [];
|
|
1189
|
+
for (const [selfData, relationKeys] of allKeys) {
|
|
1190
|
+
const obj = {};
|
|
1191
|
+
for (let i = 0; i < len; i++) obj[foreignKeys[i]] = selfData[primaryKeys[i]];
|
|
1192
|
+
for (const relationData of relationKeys) {
|
|
1193
|
+
const record = { ...obj };
|
|
1194
|
+
for (let i = 0; i < throughLen; i++) record[throughForeignKeys[i]] = relationData[throughPrimaryKeys[i]];
|
|
1195
|
+
records.push(record);
|
|
1196
|
+
}
|
|
1197
|
+
}
|
|
1198
|
+
await joinTableQuery.insertMany(records);
|
|
1199
|
+
});
|
|
1940
1200
|
};
|
|
1941
1201
|
const nestedUpdate = (state) => {
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
...state.throughForeignKeys
|
|
1998
|
-
];
|
|
1999
|
-
try {
|
|
2000
|
-
const count = await state.joinTableQuery.insertForEachFrom(
|
|
2001
|
-
internal._querySelect(
|
|
2002
|
-
state.relatedTableQuery.whereOneOf(...relatedWheres),
|
|
2003
|
-
[
|
|
2004
|
-
Object.fromEntries([
|
|
2005
|
-
...state.primaryKeys.map((key, i) => [
|
|
2006
|
-
state.foreignKeys[i],
|
|
2007
|
-
as + "." + (state.primaryKeysShape[key].data.name || key)
|
|
2008
|
-
]),
|
|
2009
|
-
...state.throughForeignKeys.map((key, i) => [
|
|
2010
|
-
key,
|
|
2011
|
-
state.throughPrimaryKeys[i]
|
|
2012
|
-
])
|
|
2013
|
-
])
|
|
2014
|
-
]
|
|
2015
|
-
).joinData(
|
|
2016
|
-
as,
|
|
2017
|
-
() => Object.fromEntries(
|
|
2018
|
-
state.primaryKeys.map((key) => [
|
|
2019
|
-
key,
|
|
2020
|
-
state.primaryKeysShape[key]
|
|
2021
|
-
])
|
|
2022
|
-
),
|
|
2023
|
-
data.map((x) => internal.pick(x, state.primaryKeys))
|
|
2024
|
-
)
|
|
2025
|
-
).onConflict(joinTableColumns).merge([state.foreignKeys[0]]);
|
|
2026
|
-
if (count < data.length * relatedWheres.length) {
|
|
2027
|
-
throw new pqb.OrchidOrmInternalError(
|
|
2028
|
-
query,
|
|
2029
|
-
`Expected to find at least ${relatedWheres.length} record(s) based on \`add\` conditions, but found ${count / data.length}`
|
|
2030
|
-
);
|
|
2031
|
-
}
|
|
2032
|
-
} catch (err) {
|
|
2033
|
-
if (err.code === "42P10") {
|
|
2034
|
-
throw new pqb.OrchidOrmInternalError(
|
|
2035
|
-
query,
|
|
2036
|
-
`"${state.joinTableQuery.table}" must have a primary key or a unique index on columns (${joinTableColumns.join(
|
|
2037
|
-
", "
|
|
2038
|
-
)}) for this kind of query.`
|
|
2039
|
-
);
|
|
2040
|
-
}
|
|
2041
|
-
throw err;
|
|
2042
|
-
}
|
|
2043
|
-
}
|
|
2044
|
-
if (params.disconnect) {
|
|
2045
|
-
await internal._queryDelete(
|
|
2046
|
-
queryJoinTable(state, data, params.disconnect)
|
|
2047
|
-
);
|
|
2048
|
-
}
|
|
2049
|
-
if (params.delete) {
|
|
2050
|
-
const j = queryJoinTable(state, data, params.delete);
|
|
2051
|
-
const idsRows = await internal._queryDelete(
|
|
2052
|
-
internal._queryRows(internal._querySelect(j, state.throughForeignKeys))
|
|
2053
|
-
);
|
|
2054
|
-
await internal._queryDelete(
|
|
2055
|
-
state.relatedTableQuery.where({
|
|
2056
|
-
IN: {
|
|
2057
|
-
columns: state.throughPrimaryKeys,
|
|
2058
|
-
values: idsRows
|
|
2059
|
-
}
|
|
2060
|
-
})
|
|
2061
|
-
);
|
|
2062
|
-
}
|
|
2063
|
-
if (params.set) {
|
|
2064
|
-
const j = queryJoinTable(state, data);
|
|
2065
|
-
await internal._queryDelete(j);
|
|
2066
|
-
if (Array.isArray(params.set) ? params.set.length : internal.objectHasValues(params.set)) {
|
|
2067
|
-
const idsRows = await internal._queryRows(
|
|
2068
|
-
internal._querySelect(
|
|
2069
|
-
state.relatedTableQuery.where(
|
|
2070
|
-
conditionsToWhereArg(params.set)
|
|
2071
|
-
),
|
|
2072
|
-
state.throughPrimaryKeys
|
|
2073
|
-
)
|
|
2074
|
-
);
|
|
2075
|
-
await insertToJoinTable(state, j, data, idsRows);
|
|
2076
|
-
}
|
|
2077
|
-
}
|
|
2078
|
-
};
|
|
1202
|
+
const len = state.primaryKeys.length;
|
|
1203
|
+
const throughLen = state.throughPrimaryKeys.length;
|
|
1204
|
+
return (async (query, data, params) => {
|
|
1205
|
+
if (params.create) {
|
|
1206
|
+
const idsRows = await (0, pqb_internal._queryCreateMany)((0, pqb_internal._queryRows)(state.relatedTableQuery.select(...state.throughPrimaryKeys)), params.create);
|
|
1207
|
+
const records = [];
|
|
1208
|
+
for (const item of data) {
|
|
1209
|
+
const obj = {};
|
|
1210
|
+
for (let i = 0; i < len; i++) obj[state.foreignKeys[i]] = item[state.primaryKeys[i]];
|
|
1211
|
+
for (const ids of idsRows) {
|
|
1212
|
+
const record = { ...obj };
|
|
1213
|
+
for (let i = 0; i < throughLen; i++) record[state.throughForeignKeys[i]] = ids[i];
|
|
1214
|
+
records.push(record);
|
|
1215
|
+
}
|
|
1216
|
+
}
|
|
1217
|
+
await state.joinTableQuery.createMany(records);
|
|
1218
|
+
}
|
|
1219
|
+
if (params.update) await (0, pqb_internal._queryUpdate)((0, pqb_internal._queryWhere)(state.relatedTableQuery.whereExists(state.joinTableQuery, (q) => {
|
|
1220
|
+
for (let i = 0; i < throughLen; i++) (0, pqb_internal._queryJoinOn)(q, [state.throughForeignKeysFull[i], state.throughPrimaryKeysFull[i]]);
|
|
1221
|
+
return (0, pqb_internal._queryWhere)(q, [{ IN: {
|
|
1222
|
+
columns: state.foreignKeysFull,
|
|
1223
|
+
values: data.map((item) => state.primaryKeys.map((key) => item[key]))
|
|
1224
|
+
} }]);
|
|
1225
|
+
}), [conditionsToWhereArg(params.update.where)]), params.update.data);
|
|
1226
|
+
/**
|
|
1227
|
+
* Performs `insertForEachFrom` on the joining table,
|
|
1228
|
+
* based on a query to the related table with applied filters of `params.connect`,
|
|
1229
|
+
* joins the main table data using `joinData`.
|
|
1230
|
+
*/
|
|
1231
|
+
if (params.add) {
|
|
1232
|
+
const as = query.table;
|
|
1233
|
+
const relatedWheres = (0, pqb_internal.toArray)(params.add);
|
|
1234
|
+
const joinTableColumns = [...state.foreignKeys, ...state.throughForeignKeys];
|
|
1235
|
+
try {
|
|
1236
|
+
const count = await state.joinTableQuery.insertForEachFrom((0, pqb_internal._querySelect)(state.relatedTableQuery.whereOneOf(...relatedWheres), [Object.fromEntries([...state.primaryKeys.map((key, i) => [state.foreignKeys[i], as + "." + (state.primaryKeysShape[key].data.name || key)]), ...state.throughForeignKeys.map((key, i) => [key, state.throughPrimaryKeys[i]])])]).joinData(as, () => Object.fromEntries(state.primaryKeys.map((key) => [key, state.primaryKeysShape[key]])), data.map((x) => (0, pqb_internal.pick)(x, state.primaryKeys)))).onConflict(joinTableColumns).merge([state.foreignKeys[0]]);
|
|
1237
|
+
if (count < data.length * relatedWheres.length) throw new pqb.OrchidOrmInternalError(query, `Expected to find at least ${relatedWheres.length} record(s) based on \`add\` conditions, but found ${count / data.length}`);
|
|
1238
|
+
} catch (err) {
|
|
1239
|
+
if (err.code === "42P10") throw new pqb.OrchidOrmInternalError(query, `"${state.joinTableQuery.table}" must have a primary key or a unique index on columns (${joinTableColumns.join(", ")}) for this kind of query.`);
|
|
1240
|
+
throw err;
|
|
1241
|
+
}
|
|
1242
|
+
}
|
|
1243
|
+
if (params.disconnect) await (0, pqb_internal._queryDelete)(queryJoinTable(state, data, params.disconnect));
|
|
1244
|
+
if (params.delete) {
|
|
1245
|
+
const idsRows = await (0, pqb_internal._queryDelete)((0, pqb_internal._queryRows)((0, pqb_internal._querySelect)(queryJoinTable(state, data, params.delete), state.throughForeignKeys)));
|
|
1246
|
+
await (0, pqb_internal._queryDelete)(state.relatedTableQuery.where({ IN: {
|
|
1247
|
+
columns: state.throughPrimaryKeys,
|
|
1248
|
+
values: idsRows
|
|
1249
|
+
} }));
|
|
1250
|
+
}
|
|
1251
|
+
if (params.set) {
|
|
1252
|
+
const j = queryJoinTable(state, data);
|
|
1253
|
+
await (0, pqb_internal._queryDelete)(j);
|
|
1254
|
+
if (Array.isArray(params.set) ? params.set.length : (0, pqb_internal.objectHasValues)(params.set)) await insertToJoinTable(state, j, data, await (0, pqb_internal._queryRows)((0, pqb_internal._querySelect)(state.relatedTableQuery.where(conditionsToWhereArg(params.set)), state.throughPrimaryKeys)));
|
|
1255
|
+
}
|
|
1256
|
+
});
|
|
2079
1257
|
};
|
|
2080
|
-
|
|
2081
1258
|
const applyRelations = (qb, tables, result, schema) => {
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
}
|
|
2133
|
-
}
|
|
2134
|
-
if (delayedRelations.size) {
|
|
2135
|
-
const { value } = delayedRelations.values().next();
|
|
2136
|
-
for (const key in value) {
|
|
2137
|
-
for (const item of value[key]) {
|
|
2138
|
-
const { relation } = item;
|
|
2139
|
-
if (item.dbTable.relations[item.relationName]) continue;
|
|
2140
|
-
const as = item.dbTable.definedAs;
|
|
2141
|
-
let message = `Cannot define a \`${item.relationName}\` relation on \`${as}\``;
|
|
2142
|
-
const table = result[as];
|
|
2143
|
-
const { through, source } = relation.options;
|
|
2144
|
-
const throughRel = table.relations[through];
|
|
2145
|
-
if (through && !throughRel) {
|
|
2146
|
-
message += `: cannot find \`${through}\` relation required by the \`through\` option`;
|
|
2147
|
-
} else if (source && throughRel && !throughRel.table.relations[source]) {
|
|
2148
|
-
message += `: cannot find \`${source}\` relation in \`${throughRel.table.definedAs}\` required by the \`source\` option`;
|
|
2149
|
-
}
|
|
2150
|
-
throw new Error(message);
|
|
2151
|
-
}
|
|
2152
|
-
}
|
|
2153
|
-
}
|
|
1259
|
+
const tableEntries = Object.entries(tables);
|
|
1260
|
+
const delayedRelations = /* @__PURE__ */ new Map();
|
|
1261
|
+
for (const name in tables) {
|
|
1262
|
+
const table = tables[name];
|
|
1263
|
+
if (!("relations" in table) || typeof table.relations !== "object") continue;
|
|
1264
|
+
const dbTable = result[name];
|
|
1265
|
+
for (const relationName in table.relations) {
|
|
1266
|
+
const relation = table.relations[relationName];
|
|
1267
|
+
const otherTableClass = relation.fn();
|
|
1268
|
+
const otherTable = tableEntries.find((pair) => pair[1] instanceof otherTableClass);
|
|
1269
|
+
if (!otherTable) throw new Error(`Cannot find table class for class ${otherTableClass.name}`);
|
|
1270
|
+
const otherTableName = otherTable[0];
|
|
1271
|
+
const otherDbTable = result[otherTableName];
|
|
1272
|
+
if (!otherDbTable) throw new Error(`Cannot find table class by name ${otherTableName}`);
|
|
1273
|
+
const data = {
|
|
1274
|
+
relationName,
|
|
1275
|
+
relation,
|
|
1276
|
+
dbTable,
|
|
1277
|
+
otherDbTable
|
|
1278
|
+
};
|
|
1279
|
+
const options = relation.options;
|
|
1280
|
+
if (typeof options.through === "string" && typeof options.source === "string") {
|
|
1281
|
+
const throughRelation = getThroughRelation(dbTable, options.through);
|
|
1282
|
+
if (!throughRelation) {
|
|
1283
|
+
delayRelation(delayedRelations, dbTable, options.through, data);
|
|
1284
|
+
continue;
|
|
1285
|
+
}
|
|
1286
|
+
if (!getSourceRelation(throughRelation, options.source)) {
|
|
1287
|
+
delayRelation(delayedRelations, throughRelation.table, options.source, data);
|
|
1288
|
+
continue;
|
|
1289
|
+
}
|
|
1290
|
+
}
|
|
1291
|
+
applyRelation(table, qb, data, delayedRelations, schema);
|
|
1292
|
+
}
|
|
1293
|
+
}
|
|
1294
|
+
if (delayedRelations.size) {
|
|
1295
|
+
const { value } = delayedRelations.values().next();
|
|
1296
|
+
for (const key in value) for (const item of value[key]) {
|
|
1297
|
+
const { relation } = item;
|
|
1298
|
+
if (item.dbTable.relations[item.relationName]) continue;
|
|
1299
|
+
const as = item.dbTable.definedAs;
|
|
1300
|
+
let message = `Cannot define a \`${item.relationName}\` relation on \`${as}\``;
|
|
1301
|
+
const table = result[as];
|
|
1302
|
+
const { through, source } = relation.options;
|
|
1303
|
+
const throughRel = table.relations[through];
|
|
1304
|
+
if (through && !throughRel) message += `: cannot find \`${through}\` relation required by the \`through\` option`;
|
|
1305
|
+
else if (source && throughRel && !throughRel.table.relations[source]) message += `: cannot find \`${source}\` relation in \`${throughRel.table.definedAs}\` required by the \`source\` option`;
|
|
1306
|
+
throw new Error(message);
|
|
1307
|
+
}
|
|
1308
|
+
}
|
|
2154
1309
|
};
|
|
2155
1310
|
const delayRelation = (delayedRelations, table, relationName, data) => {
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
} else {
|
|
2164
|
-
tableRelations[relationName] = [data];
|
|
2165
|
-
}
|
|
1311
|
+
let tableRelations = delayedRelations.get(table);
|
|
1312
|
+
if (!tableRelations) {
|
|
1313
|
+
tableRelations = {};
|
|
1314
|
+
delayedRelations.set(table, tableRelations);
|
|
1315
|
+
}
|
|
1316
|
+
if (tableRelations[relationName]) tableRelations[relationName].push(data);
|
|
1317
|
+
else tableRelations[relationName] = [data];
|
|
2166
1318
|
};
|
|
2167
1319
|
const applyRelation = (table, qb, { relationName, relation, dbTable, otherDbTable }, delayedRelations, schema) => {
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
baseQuery.joinQuery = data.joinQuery;
|
|
2210
|
-
const { join: originalJoin } = baseQuery;
|
|
2211
|
-
baseQuery.join = function(...args) {
|
|
2212
|
-
if (args.length) {
|
|
2213
|
-
return originalJoin.apply(this, args);
|
|
2214
|
-
} else {
|
|
2215
|
-
const q = this.clone();
|
|
2216
|
-
q.q.innerJoinLateral = true;
|
|
2217
|
-
return q;
|
|
2218
|
-
}
|
|
2219
|
-
};
|
|
2220
|
-
dbTable.relations[relationName] = {
|
|
2221
|
-
table: otherDbTable,
|
|
2222
|
-
query,
|
|
2223
|
-
queryRelated: data.queryRelated,
|
|
2224
|
-
joinQuery: data.joinQuery,
|
|
2225
|
-
reverseJoin: data.reverseJoin,
|
|
2226
|
-
modifyRelatedQuery: data.modifyRelatedQuery
|
|
2227
|
-
};
|
|
2228
|
-
(dbTable.relationQueries ?? (dbTable.relationQueries = {}))[relationName] = query;
|
|
2229
|
-
const tableRelations = delayedRelations.get(dbTable);
|
|
2230
|
-
if (!tableRelations) return;
|
|
2231
|
-
tableRelations[relationName]?.forEach((data2) => {
|
|
2232
|
-
applyRelation(table, qb, data2, delayedRelations, schema);
|
|
2233
|
-
});
|
|
1320
|
+
const baseQuery = Object.create(otherDbTable);
|
|
1321
|
+
baseQuery.baseQuery = baseQuery;
|
|
1322
|
+
const query = baseQuery.as(relationName);
|
|
1323
|
+
if (!query.definedAs) throw new Error(`Table class for table ${query.table} is not attached to db instance`);
|
|
1324
|
+
const { type } = relation;
|
|
1325
|
+
let data;
|
|
1326
|
+
if (type === "belongsTo") data = makeBelongsToMethod(table, dbTable, relation, relationName, query);
|
|
1327
|
+
else if (type === "hasOne") data = makeHasOneMethod(table, dbTable, relation, relationName, query);
|
|
1328
|
+
else if (type === "hasMany") data = makeHasManyMethod(table, dbTable, relation, relationName, query);
|
|
1329
|
+
else if (type === "hasAndBelongsToMany") data = makeHasAndBelongsToManyMethod(table, dbTable, qb, relation, relationName, query, schema);
|
|
1330
|
+
else throw new Error(`Unknown relation type ${type}`);
|
|
1331
|
+
if (data.returns === "one") {
|
|
1332
|
+
if (relation.options.required) (0, pqb_internal._queryTake)(query);
|
|
1333
|
+
else (0, pqb_internal._queryTakeOptional)(query);
|
|
1334
|
+
query.q.returnsOne = true;
|
|
1335
|
+
}
|
|
1336
|
+
if (data.virtualColumn) dbTable.shape[relationName] = dbTable.q.shape[relationName] = data.virtualColumn;
|
|
1337
|
+
baseQuery.joinQuery = data.joinQuery;
|
|
1338
|
+
const { join: originalJoin } = baseQuery;
|
|
1339
|
+
baseQuery.join = function(...args) {
|
|
1340
|
+
if (args.length) return originalJoin.apply(this, args);
|
|
1341
|
+
else {
|
|
1342
|
+
const q = this.clone();
|
|
1343
|
+
q.q.innerJoinLateral = true;
|
|
1344
|
+
return q;
|
|
1345
|
+
}
|
|
1346
|
+
};
|
|
1347
|
+
dbTable.relations[relationName] = {
|
|
1348
|
+
table: otherDbTable,
|
|
1349
|
+
query,
|
|
1350
|
+
queryRelated: data.queryRelated,
|
|
1351
|
+
joinQuery: data.joinQuery,
|
|
1352
|
+
reverseJoin: data.reverseJoin,
|
|
1353
|
+
modifyRelatedQuery: data.modifyRelatedQuery
|
|
1354
|
+
};
|
|
1355
|
+
(dbTable.relationQueries ??= {})[relationName] = query;
|
|
1356
|
+
const tableRelations = delayedRelations.get(dbTable);
|
|
1357
|
+
if (!tableRelations) return;
|
|
1358
|
+
tableRelations[relationName]?.forEach((data) => {
|
|
1359
|
+
applyRelation(table, qb, data, delayedRelations, schema);
|
|
1360
|
+
});
|
|
2234
1361
|
};
|
|
2235
|
-
|
|
2236
1362
|
function transaction(fnOrOptions, fn) {
|
|
2237
|
-
|
|
2238
|
-
fnOrOptions,
|
|
2239
|
-
fn
|
|
2240
|
-
);
|
|
1363
|
+
return this.$qb.transaction(fnOrOptions, fn);
|
|
2241
1364
|
}
|
|
2242
1365
|
function ensureTransaction(cb) {
|
|
2243
|
-
|
|
1366
|
+
return this.$qb.ensureTransaction(cb);
|
|
2244
1367
|
}
|
|
2245
1368
|
function isInTransaction() {
|
|
2246
|
-
|
|
1369
|
+
return this.$qb.isInTransaction();
|
|
2247
1370
|
}
|
|
2248
1371
|
function afterCommit(hook) {
|
|
2249
|
-
|
|
1372
|
+
this.$qb.afterCommit(hook);
|
|
2250
1373
|
}
|
|
2251
|
-
|
|
2252
|
-
const
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
const dbTable = new pqb.Db(
|
|
2324
|
-
adapter,
|
|
2325
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2326
|
-
qb,
|
|
2327
|
-
table.table,
|
|
2328
|
-
table.columns.shape,
|
|
2329
|
-
table.types,
|
|
2330
|
-
asyncStorage,
|
|
2331
|
-
options2,
|
|
2332
|
-
table.constructor.prototype.columns?.data ?? {}
|
|
2333
|
-
);
|
|
2334
|
-
dbTable.definedAs = key;
|
|
2335
|
-
dbTable.db = result;
|
|
2336
|
-
dbTable.filePath = table.filePath;
|
|
2337
|
-
dbTable.name = table.constructor.name;
|
|
2338
|
-
result[key] = dbTable;
|
|
2339
|
-
}
|
|
2340
|
-
applyRelations(qb, tableInstances, result, schema);
|
|
2341
|
-
for (const key in tables) {
|
|
2342
|
-
const table = tableInstances[key];
|
|
2343
|
-
if (table.init) {
|
|
2344
|
-
table.init(result);
|
|
2345
|
-
Object.assign(result[key].baseQuery.q, table.q);
|
|
2346
|
-
}
|
|
2347
|
-
}
|
|
2348
|
-
return result;
|
|
1374
|
+
const orchidORMWithAdapter = ({ log, logger, autoPreparedStatements, noPrimaryKey = "error", schema, ...options }, tables) => {
|
|
1375
|
+
const commonOptions = {
|
|
1376
|
+
log,
|
|
1377
|
+
logger,
|
|
1378
|
+
autoPreparedStatements,
|
|
1379
|
+
noPrimaryKey
|
|
1380
|
+
};
|
|
1381
|
+
let adapter;
|
|
1382
|
+
let asyncStorage;
|
|
1383
|
+
let qb;
|
|
1384
|
+
if ("db" in options) {
|
|
1385
|
+
adapter = options.db.q.adapter;
|
|
1386
|
+
asyncStorage = options.db.internal.asyncStorage;
|
|
1387
|
+
qb = options.db.qb;
|
|
1388
|
+
} else {
|
|
1389
|
+
adapter = options.adapter;
|
|
1390
|
+
asyncStorage = new node_async_hooks.AsyncLocalStorage();
|
|
1391
|
+
qb = (0, pqb_internal._initQueryBuilder)(adapter, (0, pqb_internal.makeColumnTypes)(pqb_internal.defaultSchemaConfig), asyncStorage, commonOptions, options);
|
|
1392
|
+
}
|
|
1393
|
+
const result = {
|
|
1394
|
+
$transaction: transaction,
|
|
1395
|
+
$ensureTransaction: ensureTransaction,
|
|
1396
|
+
$isInTransaction: isInTransaction,
|
|
1397
|
+
$afterCommit: afterCommit,
|
|
1398
|
+
$adapterNotInTransaction: adapter,
|
|
1399
|
+
$getAdapter,
|
|
1400
|
+
$qb: qb,
|
|
1401
|
+
get $query() {
|
|
1402
|
+
return qb.query;
|
|
1403
|
+
},
|
|
1404
|
+
$queryArrays: ((...args) => qb.queryArrays(...args)),
|
|
1405
|
+
$with: qb.with.bind(qb),
|
|
1406
|
+
$withRecursive: qb.withRecursive.bind(qb),
|
|
1407
|
+
$withSql: qb.withSql.bind(qb),
|
|
1408
|
+
$from: qb.from.bind(qb),
|
|
1409
|
+
$close: adapter.close.bind(adapter),
|
|
1410
|
+
$withOptions: qb.withOptions.bind(qb)
|
|
1411
|
+
};
|
|
1412
|
+
const tableInstances = {};
|
|
1413
|
+
for (const key in tables) {
|
|
1414
|
+
if (key[0] === "$") throw new Error(`Table class name must not start with $`);
|
|
1415
|
+
const tableClass = tables[key];
|
|
1416
|
+
const table = tableClass.instance();
|
|
1417
|
+
tableInstances[key] = table;
|
|
1418
|
+
const options = {
|
|
1419
|
+
...commonOptions,
|
|
1420
|
+
schema: table.schema || schema,
|
|
1421
|
+
language: table.language,
|
|
1422
|
+
scopes: table.scopes,
|
|
1423
|
+
softDelete: table.softDelete,
|
|
1424
|
+
snakeCase: table.snakeCase,
|
|
1425
|
+
comment: table.comment,
|
|
1426
|
+
noPrimaryKey: table.noPrimaryKey ? "ignore" : void 0,
|
|
1427
|
+
computed: table.computed,
|
|
1428
|
+
nowSQL: tableClass.nowSQL
|
|
1429
|
+
};
|
|
1430
|
+
const dbTable = new pqb.Db(adapter, qb, table.table, table.columns.shape, table.types, asyncStorage, options, table.constructor.prototype.columns?.data ?? {});
|
|
1431
|
+
dbTable.definedAs = key;
|
|
1432
|
+
dbTable.db = result;
|
|
1433
|
+
dbTable.filePath = table.filePath;
|
|
1434
|
+
dbTable.name = table.constructor.name;
|
|
1435
|
+
result[key] = dbTable;
|
|
1436
|
+
}
|
|
1437
|
+
applyRelations(qb, tableInstances, result, schema);
|
|
1438
|
+
for (const key in tables) {
|
|
1439
|
+
const table = tableInstances[key];
|
|
1440
|
+
if (table.init) {
|
|
1441
|
+
table.init(result);
|
|
1442
|
+
Object.assign(result[key].baseQuery.q, table.q);
|
|
1443
|
+
}
|
|
1444
|
+
}
|
|
1445
|
+
return result;
|
|
2349
1446
|
};
|
|
2350
1447
|
function $getAdapter() {
|
|
2351
|
-
|
|
1448
|
+
return this.$qb.$getAdapter();
|
|
2352
1449
|
}
|
|
2353
|
-
|
|
2354
1450
|
const createRepo = (table, methods) => {
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
get(_, key) {
|
|
2381
|
-
return q[key];
|
|
2382
|
-
}
|
|
2383
|
-
});
|
|
1451
|
+
const queryMethods = {
|
|
1452
|
+
...methods.queryMethods,
|
|
1453
|
+
...methods.queryOneMethods,
|
|
1454
|
+
...methods.queryWithWhereMethods,
|
|
1455
|
+
...methods.queryOneWithWhereMethods
|
|
1456
|
+
};
|
|
1457
|
+
const plainMethods = methods.methods;
|
|
1458
|
+
const repo = (q) => {
|
|
1459
|
+
const proto = Object.create(q.baseQuery);
|
|
1460
|
+
proto.baseQuery = proto;
|
|
1461
|
+
const result = Object.create(proto);
|
|
1462
|
+
result.q = (0, pqb_internal.getClonedQueryData)(q.q);
|
|
1463
|
+
if (plainMethods) Object.assign(proto.baseQuery, plainMethods);
|
|
1464
|
+
for (const key in queryMethods) {
|
|
1465
|
+
const method = queryMethods[key];
|
|
1466
|
+
proto.baseQuery[key] = function(...args) {
|
|
1467
|
+
return method(this, ...args);
|
|
1468
|
+
};
|
|
1469
|
+
}
|
|
1470
|
+
return result;
|
|
1471
|
+
};
|
|
1472
|
+
const q = repo(table);
|
|
1473
|
+
return new Proxy(repo, { get(_, key) {
|
|
1474
|
+
return q[key];
|
|
1475
|
+
} });
|
|
2384
1476
|
};
|
|
2385
|
-
|
|
2386
1477
|
exports.createBaseTable = createBaseTable;
|
|
2387
1478
|
exports.createRepo = createRepo;
|
|
2388
1479
|
exports.orchidORMWithAdapter = orchidORMWithAdapter;
|
|
2389
|
-
Object.keys(pqb).forEach(function
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
1480
|
+
Object.keys(pqb).forEach(function(k) {
|
|
1481
|
+
if (k !== "default" && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
|
1482
|
+
enumerable: true,
|
|
1483
|
+
get: function() {
|
|
1484
|
+
return pqb[k];
|
|
1485
|
+
}
|
|
1486
|
+
});
|
|
2394
1487
|
});
|
|
2395
|
-
|
|
1488
|
+
|
|
1489
|
+
//# sourceMappingURL=index.js.map
|