pqb 0.2.2 → 0.2.4
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 +832 -793
- package/dist/index.esm.js +197 -150
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +197 -150
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/columnSchema/columnsSchema.ts +15 -4
- package/src/columnSchema/number.ts +3 -0
- package/src/queryMethods/aggregate.test.ts +2 -2
- package/src/queryMethods/insert.test.ts +217 -205
- package/src/queryMethods/insert.ts +383 -273
- package/src/queryMethods/update.test.ts +3 -3
- package/src/queryMethods/upsert.test.ts +1 -1
- package/src/queryMethods/window.test.ts +2 -2
- package/src/relations.ts +5 -2
- package/src/utils.test.ts +37 -0
- package/src/utils.ts +9 -0
|
@@ -1,98 +1,141 @@
|
|
|
1
1
|
import {
|
|
2
2
|
defaultsKey,
|
|
3
3
|
Query,
|
|
4
|
+
QueryReturnType,
|
|
4
5
|
SetQueryReturnsAll,
|
|
5
6
|
SetQueryReturnsOne,
|
|
6
7
|
SetQueryReturnsRowCount,
|
|
7
8
|
} from '../query';
|
|
8
9
|
import { pushQueryArray } from '../queryDataUtils';
|
|
9
|
-
import {
|
|
10
|
+
import { RawExpression } from '../common';
|
|
10
11
|
import {
|
|
11
12
|
BelongsToNestedInsert,
|
|
12
13
|
BelongsToRelation,
|
|
14
|
+
HasAndBelongsToManyRelation,
|
|
15
|
+
HasManyRelation,
|
|
13
16
|
HasOneNestedInsert,
|
|
14
17
|
HasOneRelation,
|
|
15
18
|
NestedInsertItem,
|
|
16
19
|
NestedInsertOneItem,
|
|
17
20
|
Relation,
|
|
21
|
+
RelationsBase,
|
|
18
22
|
} from '../relations';
|
|
19
23
|
import { SetOptional } from '../utils';
|
|
20
24
|
import { InsertQueryData, OnConflictItem, OnConflictMergeUpdate } from '../sql';
|
|
21
25
|
import { WhereArg } from './where';
|
|
22
26
|
import { parseResult, queryMethodByReturnType } from './then';
|
|
23
27
|
|
|
24
|
-
export type OptionalKeys<T extends Query> = {
|
|
25
|
-
[K in keyof T['shape']]: T['shape'][K]['isPrimaryKey'] extends true
|
|
26
|
-
? K
|
|
27
|
-
: T['shape'][K]['isNullable'] extends true
|
|
28
|
-
? K
|
|
29
|
-
: never;
|
|
30
|
-
}[keyof T['shape']];
|
|
31
|
-
|
|
32
28
|
export type InsertData<
|
|
33
29
|
T extends Query,
|
|
34
30
|
DefaultKeys extends PropertyKey = keyof T[defaultsKey],
|
|
35
|
-
Data = SetOptional<
|
|
31
|
+
Data = SetOptional<T['inputType'], DefaultKeys>,
|
|
36
32
|
> = [keyof T['relations']] extends [never]
|
|
37
33
|
? Data
|
|
38
|
-
:
|
|
39
|
-
|
|
34
|
+
: OmitBelongsToForeignKeys<T['relations'], Data> & InsertRelationData<T>;
|
|
35
|
+
|
|
36
|
+
type OmitBelongsToForeignKeys<R extends RelationsBase, Data> = Omit<
|
|
37
|
+
Data,
|
|
38
|
+
{
|
|
39
|
+
[K in keyof R]: R[K] extends BelongsToRelation
|
|
40
|
+
? R[K]['options']['foreignKey']
|
|
41
|
+
: never;
|
|
42
|
+
}[keyof R]
|
|
43
|
+
>;
|
|
44
|
+
|
|
45
|
+
type InsertRelationData<T extends Query> = {
|
|
46
|
+
[Key in keyof T['relations']]: T['relations'][Key] extends BelongsToRelation
|
|
47
|
+
? InsertBelongsToData<T, Key, T['relations'][Key]>
|
|
48
|
+
: T['relations'][Key] extends HasOneRelation
|
|
49
|
+
? InsertHasOneData<T, Key, T['relations'][Key]>
|
|
50
|
+
: T['relations'][Key] extends HasManyRelation | HasAndBelongsToManyRelation
|
|
51
|
+
? InsertHasManyData<T, Key, T['relations'][Key]>
|
|
52
|
+
: // eslint-disable-next-line @typescript-eslint/ban-types
|
|
53
|
+
{};
|
|
54
|
+
}[keyof T['relations']];
|
|
55
|
+
|
|
56
|
+
type InsertBelongsToData<
|
|
57
|
+
T extends Query,
|
|
58
|
+
Key extends keyof T['relations'],
|
|
59
|
+
Rel extends BelongsToRelation,
|
|
60
|
+
> =
|
|
61
|
+
| SetOptional<
|
|
40
62
|
{
|
|
41
|
-
[K in
|
|
42
|
-
? T['
|
|
63
|
+
[K in Rel['options']['foreignKey']]: Rel['options']['foreignKey'] extends keyof T['inputType']
|
|
64
|
+
? T['inputType'][Rel['options']['foreignKey']]
|
|
43
65
|
: never;
|
|
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
|
-
|
|
66
|
+
},
|
|
67
|
+
keyof T[defaultsKey]
|
|
68
|
+
>
|
|
69
|
+
| {
|
|
70
|
+
[K in Key]:
|
|
71
|
+
| {
|
|
72
|
+
create: InsertData<Rel['nestedCreateQuery']>;
|
|
73
|
+
connect?: never;
|
|
74
|
+
connectOrCreate?: never;
|
|
75
|
+
}
|
|
76
|
+
| {
|
|
77
|
+
create?: never;
|
|
78
|
+
connect: WhereArg<Rel['model']>;
|
|
79
|
+
connectOrCreate?: never;
|
|
80
|
+
}
|
|
81
|
+
| {
|
|
82
|
+
create?: never;
|
|
83
|
+
connect?: never;
|
|
84
|
+
connectOrCreate: {
|
|
85
|
+
where: WhereArg<Rel['model']>;
|
|
86
|
+
create: InsertData<Rel['nestedCreateQuery']>;
|
|
87
|
+
};
|
|
88
|
+
};
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
type InsertHasOneData<
|
|
92
|
+
T extends Query,
|
|
93
|
+
Key extends keyof T['relations'],
|
|
94
|
+
Rel extends HasOneRelation,
|
|
95
|
+
> = 'through' extends Rel['options']
|
|
96
|
+
? // eslint-disable-next-line @typescript-eslint/ban-types
|
|
97
|
+
{}
|
|
98
|
+
: {
|
|
99
|
+
[K in Key]?:
|
|
100
|
+
| {
|
|
101
|
+
create: InsertData<Rel['nestedCreateQuery']>;
|
|
102
|
+
connect?: never;
|
|
103
|
+
connectOrCreate?: never;
|
|
104
|
+
}
|
|
105
|
+
| {
|
|
106
|
+
create?: never;
|
|
107
|
+
connect: WhereArg<Rel['model']>;
|
|
108
|
+
connectOrCreate?: never;
|
|
109
|
+
}
|
|
110
|
+
| {
|
|
111
|
+
create?: never;
|
|
112
|
+
connect?: never;
|
|
113
|
+
connectOrCreate: {
|
|
114
|
+
where?: WhereArg<Rel['model']>;
|
|
115
|
+
create?: InsertData<Rel['nestedCreateQuery']>;
|
|
116
|
+
};
|
|
117
|
+
};
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
type InsertHasManyData<
|
|
121
|
+
T extends Query,
|
|
122
|
+
Key extends keyof T['relations'],
|
|
123
|
+
Rel extends HasManyRelation | HasAndBelongsToManyRelation,
|
|
124
|
+
> = 'through' extends Rel['options']
|
|
125
|
+
? // eslint-disable-next-line @typescript-eslint/ban-types
|
|
126
|
+
{}
|
|
127
|
+
: {
|
|
128
|
+
[K in Key]?: {
|
|
129
|
+
create?: InsertData<Rel['nestedCreateQuery']>[];
|
|
130
|
+
connect?: WhereArg<Rel['model']>[];
|
|
131
|
+
connectOrCreate?: {
|
|
132
|
+
where: WhereArg<Rel['model']>;
|
|
133
|
+
create: InsertData<Rel['nestedCreateQuery']>;
|
|
134
|
+
}[];
|
|
135
|
+
};
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
type InsertRawData = { columns: string[]; values: RawExpression };
|
|
96
139
|
|
|
97
140
|
type InsertOneResult<T extends Query> = T['hasSelect'] extends false
|
|
98
141
|
? SetQueryReturnsRowCount<T>
|
|
@@ -123,20 +166,24 @@ type AppendRelations = Record<
|
|
|
123
166
|
[rowIndex: number, data: NestedInsertItem][]
|
|
124
167
|
>;
|
|
125
168
|
|
|
169
|
+
type InsertCtx = {
|
|
170
|
+
prependRelations: PrependRelations;
|
|
171
|
+
appendRelations: AppendRelations;
|
|
172
|
+
requiredReturning: Record<string, boolean>;
|
|
173
|
+
relations: Record<string, Relation>;
|
|
174
|
+
};
|
|
175
|
+
|
|
126
176
|
const processInsertItem = (
|
|
127
177
|
item: Record<string, unknown>,
|
|
128
178
|
rowIndex: number,
|
|
129
|
-
|
|
130
|
-
prependRelations: PrependRelations,
|
|
131
|
-
appendRelations: AppendRelations,
|
|
132
|
-
requiredReturning: Record<string, boolean>,
|
|
179
|
+
ctx: InsertCtx,
|
|
133
180
|
columns: string[],
|
|
134
181
|
columnsMap: Record<string, number>,
|
|
135
182
|
) => {
|
|
136
183
|
Object.keys(item).forEach((key) => {
|
|
137
|
-
if (relations[key]) {
|
|
138
|
-
if (relations[key].type === 'belongsTo') {
|
|
139
|
-
const foreignKey = (relations[key] as BelongsToRelation).options
|
|
184
|
+
if (ctx.relations[key]) {
|
|
185
|
+
if (ctx.relations[key].type === 'belongsTo') {
|
|
186
|
+
const foreignKey = (ctx.relations[key] as BelongsToRelation).options
|
|
140
187
|
.foreignKey;
|
|
141
188
|
|
|
142
189
|
let columnIndex = columnsMap[foreignKey];
|
|
@@ -145,19 +192,22 @@ const processInsertItem = (
|
|
|
145
192
|
columns.push(foreignKey);
|
|
146
193
|
}
|
|
147
194
|
|
|
148
|
-
if (!prependRelations[key]) prependRelations[key] = [];
|
|
195
|
+
if (!ctx.prependRelations[key]) ctx.prependRelations[key] = [];
|
|
149
196
|
|
|
150
|
-
prependRelations[key].push([
|
|
197
|
+
ctx.prependRelations[key].push([
|
|
151
198
|
rowIndex,
|
|
152
199
|
columnIndex,
|
|
153
200
|
item[key] as Record<string, unknown>,
|
|
154
201
|
]);
|
|
155
202
|
} else {
|
|
156
|
-
requiredReturning[relations[key].primaryKey] = true;
|
|
203
|
+
ctx.requiredReturning[ctx.relations[key].primaryKey] = true;
|
|
157
204
|
|
|
158
|
-
if (!appendRelations[key]) appendRelations[key] = [];
|
|
205
|
+
if (!ctx.appendRelations[key]) ctx.appendRelations[key] = [];
|
|
159
206
|
|
|
160
|
-
appendRelations[key].push([
|
|
207
|
+
ctx.appendRelations[key].push([
|
|
208
|
+
rowIndex,
|
|
209
|
+
item[key] as NestedInsertItem,
|
|
210
|
+
]);
|
|
161
211
|
}
|
|
162
212
|
} else if (columnsMap[key] === undefined) {
|
|
163
213
|
columnsMap[key] = columns.length;
|
|
@@ -166,230 +216,290 @@ const processInsertItem = (
|
|
|
166
216
|
});
|
|
167
217
|
};
|
|
168
218
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
219
|
+
const createInsertCtx = (q: Query): InsertCtx => ({
|
|
220
|
+
prependRelations: {},
|
|
221
|
+
appendRelations: {},
|
|
222
|
+
requiredReturning: {},
|
|
223
|
+
relations: (q as unknown as Query).relations,
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
const getInsertSingleReturnType = (q: Query) => {
|
|
227
|
+
const { select, returnType } = q.query;
|
|
228
|
+
if (select) {
|
|
229
|
+
return returnType === 'all' ? 'one' : returnType;
|
|
230
|
+
} else {
|
|
231
|
+
return 'rowCount';
|
|
178
232
|
}
|
|
233
|
+
};
|
|
179
234
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
) {
|
|
191
|
-
const q = this as unknown as Query & { query: InsertQueryData };
|
|
192
|
-
const returning = q.query.select;
|
|
193
|
-
|
|
194
|
-
delete q.query.and;
|
|
195
|
-
delete q.query.or;
|
|
196
|
-
|
|
197
|
-
let columns: string[];
|
|
198
|
-
const prependRelations: PrependRelations = {};
|
|
199
|
-
const appendRelations: AppendRelations = {};
|
|
200
|
-
const requiredReturning: Record<string, boolean> = {};
|
|
201
|
-
const relations = (this as unknown as Query).relations as unknown as Record<
|
|
202
|
-
string,
|
|
203
|
-
Relation
|
|
204
|
-
>;
|
|
205
|
-
let values: unknown[][] | RawExpression;
|
|
206
|
-
|
|
207
|
-
let returnType = q.query.returnType;
|
|
208
|
-
if (returning) {
|
|
209
|
-
if (Array.isArray(data)) {
|
|
210
|
-
if (returnType === 'one' || returnType === 'oneOrThrow') {
|
|
211
|
-
returnType = 'all';
|
|
212
|
-
}
|
|
213
|
-
} else {
|
|
214
|
-
if (returnType === 'all') {
|
|
215
|
-
returnType = 'one';
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
} else {
|
|
219
|
-
returnType = 'rowCount';
|
|
220
|
-
}
|
|
235
|
+
const getInsertManyReturnType = (q: Query) => {
|
|
236
|
+
const { select, returnType } = q.query;
|
|
237
|
+
if (select) {
|
|
238
|
+
return returnType === 'one' || returnType === 'oneOrThrow'
|
|
239
|
+
? 'all'
|
|
240
|
+
: returnType;
|
|
241
|
+
} else {
|
|
242
|
+
return 'rowCount';
|
|
243
|
+
}
|
|
244
|
+
};
|
|
221
245
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
246
|
+
const handleInsertOneData = (
|
|
247
|
+
q: Query,
|
|
248
|
+
data: InsertData<Query>,
|
|
249
|
+
ctx: InsertCtx,
|
|
250
|
+
) => {
|
|
251
|
+
const columns: string[] = [];
|
|
252
|
+
const columnsMap: Record<string, number> = {};
|
|
253
|
+
const defaults = q.query.defaults;
|
|
254
|
+
|
|
255
|
+
if (defaults) {
|
|
256
|
+
data = { ...defaults, ...data };
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
processInsertItem(data, 0, ctx, columns, columnsMap);
|
|
260
|
+
|
|
261
|
+
const values = [columns.map((key) => (data as Record<string, unknown>)[key])];
|
|
262
|
+
|
|
263
|
+
return { columns, values };
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
const handleInsertManyData = (
|
|
267
|
+
q: Query,
|
|
268
|
+
data: InsertData<Query>[],
|
|
269
|
+
ctx: InsertCtx,
|
|
270
|
+
) => {
|
|
271
|
+
const columns: string[] = [];
|
|
272
|
+
const columnsMap: Record<string, number> = {};
|
|
273
|
+
const defaults = q.query.defaults;
|
|
274
|
+
|
|
275
|
+
if (defaults) {
|
|
276
|
+
data = data.map((item) => ({ ...defaults, ...item }));
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
data.forEach((item, i) => {
|
|
280
|
+
processInsertItem(item, i, ctx, columns, columnsMap);
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
const values = Array(data.length);
|
|
284
|
+
|
|
285
|
+
data.forEach((item, i) => {
|
|
286
|
+
(values as unknown[][])[i] = columns.map((key) => item[key]);
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
return { columns, values };
|
|
290
|
+
};
|
|
239
291
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
292
|
+
const insert = (
|
|
293
|
+
self: Query,
|
|
294
|
+
{
|
|
295
|
+
columns,
|
|
296
|
+
values,
|
|
297
|
+
}: {
|
|
298
|
+
columns: string[];
|
|
299
|
+
values: unknown[][] | RawExpression;
|
|
300
|
+
},
|
|
301
|
+
returnType: QueryReturnType,
|
|
302
|
+
ctx?: InsertCtx,
|
|
303
|
+
) => {
|
|
304
|
+
const q = self as Query & { query: InsertQueryData };
|
|
305
|
+
const returning = q.query.select;
|
|
306
|
+
|
|
307
|
+
delete q.query.and;
|
|
308
|
+
delete q.query.or;
|
|
309
|
+
|
|
310
|
+
q.query.type = 'insert';
|
|
311
|
+
q.query.columns = columns;
|
|
312
|
+
q.query.values = values;
|
|
313
|
+
|
|
314
|
+
if (!ctx) {
|
|
315
|
+
q.query.returnType = returnType;
|
|
316
|
+
return q;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
const prependRelationsKeys = Object.keys(ctx.prependRelations);
|
|
320
|
+
if (prependRelationsKeys.length) {
|
|
321
|
+
pushQueryArray(
|
|
322
|
+
q,
|
|
323
|
+
'beforeQuery',
|
|
324
|
+
prependRelationsKeys.map((relationName) => {
|
|
325
|
+
return async (q: Query) => {
|
|
326
|
+
const relationData = ctx.prependRelations[relationName];
|
|
327
|
+
const relation = ctx.relations[relationName];
|
|
328
|
+
|
|
329
|
+
const inserted = await (
|
|
330
|
+
relation.nestedInsert as BelongsToNestedInsert
|
|
331
|
+
)(
|
|
332
|
+
q,
|
|
333
|
+
relationData.map(([, , data]) => data as NestedInsertOneItem),
|
|
250
334
|
);
|
|
251
|
-
});
|
|
252
335
|
|
|
253
|
-
|
|
336
|
+
const primaryKey = (relation as BelongsToRelation).options.primaryKey;
|
|
337
|
+
relationData.forEach(([rowIndex, columnIndex], index) => {
|
|
338
|
+
(values as unknown[][])[rowIndex][columnIndex] =
|
|
339
|
+
inserted[index][primaryKey];
|
|
340
|
+
});
|
|
341
|
+
};
|
|
342
|
+
}),
|
|
343
|
+
);
|
|
344
|
+
}
|
|
254
345
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
if (defaults) {
|
|
260
|
-
data = { ...defaults, ...data };
|
|
261
|
-
}
|
|
346
|
+
const appendRelationsKeys = Object.keys(ctx.appendRelations);
|
|
347
|
+
if (appendRelationsKeys.length) {
|
|
348
|
+
if (!returning?.includes('*')) {
|
|
349
|
+
const requiredColumns = Object.keys(ctx.requiredReturning);
|
|
262
350
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
requiredReturning,
|
|
270
|
-
columns,
|
|
271
|
-
columnsMap,
|
|
272
|
-
);
|
|
273
|
-
|
|
274
|
-
values = [columns.map((key) => (data as Record<string, unknown>)[key])];
|
|
351
|
+
if (!returning) {
|
|
352
|
+
q.query.select = requiredColumns;
|
|
353
|
+
} else {
|
|
354
|
+
q.query.select = [
|
|
355
|
+
...new Set([...(returning as string[]), ...requiredColumns]),
|
|
356
|
+
];
|
|
275
357
|
}
|
|
276
358
|
}
|
|
277
359
|
|
|
278
|
-
|
|
279
|
-
if (
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
);
|
|
294
|
-
|
|
295
|
-
const primaryKey = (relation as BelongsToRelation).options
|
|
296
|
-
.primaryKey;
|
|
297
|
-
relationData.forEach(([rowIndex, columnIndex], index) => {
|
|
298
|
-
(values as unknown[][])[rowIndex][columnIndex] =
|
|
299
|
-
inserted[index][primaryKey];
|
|
300
|
-
});
|
|
301
|
-
};
|
|
302
|
-
}),
|
|
303
|
-
);
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
const appendRelationsKeys = Object.keys(appendRelations);
|
|
307
|
-
if (appendRelationsKeys.length) {
|
|
308
|
-
if (!returning?.includes('*')) {
|
|
309
|
-
const requiredColumns = Object.keys(requiredReturning);
|
|
310
|
-
|
|
311
|
-
if (!returning) {
|
|
312
|
-
q.query.select = requiredColumns;
|
|
313
|
-
} else {
|
|
314
|
-
q.query.select = [
|
|
315
|
-
...new Set([...(returning as string[]), ...requiredColumns]),
|
|
316
|
-
];
|
|
360
|
+
let resultOfTypeAll: Record<string, unknown>[] | undefined;
|
|
361
|
+
if (returnType !== 'all') {
|
|
362
|
+
const { handleResult } = q.query;
|
|
363
|
+
q.query.handleResult = async (q, queryResult) => {
|
|
364
|
+
resultOfTypeAll = (await handleResult(q, queryResult)) as Record<
|
|
365
|
+
string,
|
|
366
|
+
unknown
|
|
367
|
+
>[];
|
|
368
|
+
|
|
369
|
+
if (queryMethodByReturnType[returnType] === 'arrays') {
|
|
370
|
+
queryResult.rows.forEach(
|
|
371
|
+
(row, i) =>
|
|
372
|
+
((queryResult.rows as unknown as unknown[][])[i] =
|
|
373
|
+
Object.values(row)),
|
|
374
|
+
);
|
|
317
375
|
}
|
|
318
|
-
}
|
|
319
376
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
q.query.handleResult = async (q, queryResult) => {
|
|
324
|
-
resultOfTypeAll = (await handleResult(q, queryResult)) as Record<
|
|
325
|
-
string,
|
|
326
|
-
unknown
|
|
327
|
-
>[];
|
|
328
|
-
|
|
329
|
-
if (queryMethodByReturnType[returnType] === 'arrays') {
|
|
330
|
-
queryResult.rows.forEach(
|
|
331
|
-
(row, i) =>
|
|
332
|
-
((queryResult.rows as unknown as unknown[][])[i] =
|
|
333
|
-
Object.values(row)),
|
|
334
|
-
);
|
|
335
|
-
}
|
|
377
|
+
return parseResult(q, returnType, queryResult);
|
|
378
|
+
};
|
|
379
|
+
}
|
|
336
380
|
|
|
337
|
-
|
|
381
|
+
pushQueryArray(
|
|
382
|
+
q,
|
|
383
|
+
'afterQuery',
|
|
384
|
+
appendRelationsKeys.map((relationName) => {
|
|
385
|
+
return (q: Query, result: Record<string, unknown>[]) => {
|
|
386
|
+
const all = resultOfTypeAll || result;
|
|
387
|
+
return (
|
|
388
|
+
ctx.relations[relationName].nestedInsert as HasOneNestedInsert
|
|
389
|
+
)?.(
|
|
390
|
+
q,
|
|
391
|
+
ctx.appendRelations[relationName].map(([rowIndex, data]) => [
|
|
392
|
+
all[rowIndex],
|
|
393
|
+
data as NestedInsertOneItem,
|
|
394
|
+
]),
|
|
395
|
+
);
|
|
338
396
|
};
|
|
339
|
-
}
|
|
397
|
+
}),
|
|
398
|
+
);
|
|
399
|
+
}
|
|
340
400
|
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
appendRelationsKeys.map((relationName) => {
|
|
345
|
-
return (q: Query, result: Record<string, unknown>[]) => {
|
|
346
|
-
const all = resultOfTypeAll || result;
|
|
347
|
-
return (
|
|
348
|
-
relations[relationName].nestedInsert as HasOneNestedInsert
|
|
349
|
-
)?.(
|
|
350
|
-
q,
|
|
351
|
-
appendRelations[relationName].map(([rowIndex, data]) => [
|
|
352
|
-
all[rowIndex],
|
|
353
|
-
data as NestedInsertOneItem,
|
|
354
|
-
]),
|
|
355
|
-
);
|
|
356
|
-
};
|
|
357
|
-
}),
|
|
358
|
-
);
|
|
359
|
-
}
|
|
401
|
+
if (prependRelationsKeys.length || appendRelationsKeys.length) {
|
|
402
|
+
q.query.wrapInTransaction = true;
|
|
403
|
+
}
|
|
360
404
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
q.query.wrapInTransaction = true;
|
|
366
|
-
}
|
|
405
|
+
q.query.returnType = appendRelationsKeys.length ? 'all' : returnType;
|
|
406
|
+
|
|
407
|
+
return q;
|
|
408
|
+
};
|
|
367
409
|
|
|
368
|
-
|
|
410
|
+
export class Insert {
|
|
411
|
+
insert<T extends Query>(this: T, data: InsertData<T>): InsertOneResult<T> {
|
|
412
|
+
return this.clone()._insert(data);
|
|
413
|
+
}
|
|
414
|
+
_insert<T extends Query>(this: T, data: InsertData<T>): InsertOneResult<T> {
|
|
415
|
+
const ctx = createInsertCtx(this);
|
|
416
|
+
return insert(
|
|
417
|
+
this,
|
|
418
|
+
handleInsertOneData(this, data, ctx),
|
|
419
|
+
getInsertSingleReturnType(this),
|
|
420
|
+
ctx,
|
|
421
|
+
) as InsertOneResult<T>;
|
|
422
|
+
}
|
|
369
423
|
|
|
370
|
-
|
|
424
|
+
insertMany<T extends Query>(
|
|
425
|
+
this: T,
|
|
426
|
+
data: InsertData<T>[],
|
|
427
|
+
): InsertManyResult<T> {
|
|
428
|
+
return this.clone()._insertMany(data);
|
|
429
|
+
}
|
|
430
|
+
_insertMany<T extends Query>(
|
|
431
|
+
this: T,
|
|
432
|
+
data: InsertData<T>[],
|
|
433
|
+
): InsertManyResult<T> {
|
|
434
|
+
const ctx = createInsertCtx(this);
|
|
435
|
+
return insert(
|
|
436
|
+
this,
|
|
437
|
+
handleInsertManyData(this, data, ctx),
|
|
438
|
+
getInsertManyReturnType(this),
|
|
439
|
+
ctx,
|
|
440
|
+
) as InsertManyResult<T>;
|
|
371
441
|
}
|
|
372
442
|
|
|
373
|
-
|
|
374
|
-
create<T extends Query>(
|
|
443
|
+
insertRaw<T extends Query>(
|
|
375
444
|
this: T,
|
|
376
|
-
data:
|
|
377
|
-
):
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
445
|
+
data: InsertRawData,
|
|
446
|
+
): InsertManyResult<T> {
|
|
447
|
+
return this.clone()._insertRaw(data);
|
|
448
|
+
}
|
|
449
|
+
_insertRaw<T extends Query>(
|
|
450
|
+
this: T,
|
|
451
|
+
data: InsertRawData,
|
|
452
|
+
): InsertManyResult<T> {
|
|
453
|
+
return insert(
|
|
454
|
+
this,
|
|
455
|
+
data,
|
|
456
|
+
getInsertManyReturnType(this),
|
|
457
|
+
) as InsertManyResult<T>;
|
|
381
458
|
}
|
|
382
459
|
|
|
383
|
-
|
|
460
|
+
create<T extends Query>(this: T, data: InsertData<T>): SetQueryReturnsOne<T> {
|
|
461
|
+
return this.clone()._create(data);
|
|
462
|
+
}
|
|
384
463
|
_create<T extends Query>(
|
|
385
464
|
this: T,
|
|
386
|
-
data: InsertData<T
|
|
387
|
-
):
|
|
388
|
-
|
|
465
|
+
data: InsertData<T>,
|
|
466
|
+
): SetQueryReturnsOne<T> {
|
|
467
|
+
if (!this.query.select) {
|
|
468
|
+
this.query.select = ['*'];
|
|
469
|
+
}
|
|
470
|
+
return this.clone()._insert(data) as SetQueryReturnsOne<T>;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
createMany<T extends Query>(
|
|
474
|
+
this: T,
|
|
475
|
+
data: InsertData<T>[],
|
|
476
|
+
): SetQueryReturnsAll<T> {
|
|
477
|
+
return this.clone()._createMany(data);
|
|
478
|
+
}
|
|
479
|
+
_createMany<T extends Query>(
|
|
480
|
+
this: T,
|
|
481
|
+
data: InsertData<T>[],
|
|
482
|
+
): SetQueryReturnsAll<T> {
|
|
483
|
+
if (!this.query.select) {
|
|
484
|
+
this.query.select = ['*'];
|
|
485
|
+
}
|
|
486
|
+
return this.clone()._insertMany(data) as SetQueryReturnsAll<T>;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
createRaw<T extends Query>(
|
|
490
|
+
this: T,
|
|
491
|
+
data: InsertRawData,
|
|
492
|
+
): SetQueryReturnsAll<T> {
|
|
493
|
+
return this.clone()._createRaw(data);
|
|
494
|
+
}
|
|
495
|
+
_createRaw<T extends Query>(
|
|
496
|
+
this: T,
|
|
497
|
+
data: InsertRawData,
|
|
498
|
+
): SetQueryReturnsAll<T> {
|
|
389
499
|
if (!this.query.select) {
|
|
390
500
|
this.query.select = ['*'];
|
|
391
501
|
}
|
|
392
|
-
return this.
|
|
502
|
+
return this.clone()._insertRaw(data) as SetQueryReturnsAll<T>;
|
|
393
503
|
}
|
|
394
504
|
|
|
395
505
|
defaults<T extends Query, Data extends Partial<InsertData<T>>>(
|