pqb 0.3.0 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +57 -37
- package/dist/index.esm.js +3746 -3663
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +3750 -3662
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/columnSchema/columnType.ts +25 -21
- package/src/columnSchema/columnTypes.ts +2 -12
- package/src/columnSchema/timestamps.test.ts +79 -0
- package/src/columnSchema/timestamps.ts +49 -0
- package/src/columnsOperators.ts +1 -1
- package/src/common.ts +5 -1
- package/src/db.ts +20 -9
- package/src/queryDataUtils.ts +7 -4
- package/src/queryMethods/aggregate.test.ts +3 -3
- package/src/queryMethods/callbacks.test.ts +20 -0
- package/src/queryMethods/callbacks.ts +16 -2
- package/src/queryMethods/clear.test.ts +1 -1
- package/src/queryMethods/clear.ts +2 -2
- package/src/queryMethods/having.test.ts +1 -1
- package/src/queryMethods/queryMethods.test.ts +1 -1
- package/src/queryMethods/queryMethods.ts +3 -2
- package/src/queryMethods/then.ts +24 -16
- package/src/queryMethods/union.test.ts +1 -1
- package/src/queryMethods/update.test.ts +33 -18
- package/src/queryMethods/update.ts +152 -132
- package/src/queryMethods/window.test.ts +1 -1
- package/src/sql/fromAndAs.ts +2 -2
- package/src/sql/select.ts +1 -1
- package/src/sql/toSql.ts +17 -2
- package/src/sql/types.ts +25 -10
- package/src/sql/update.ts +27 -8
- package/src/sql/where.ts +1 -1
- package/src/sql/with.ts +1 -1
- package/src/utils.test.ts +76 -2
- package/src/utils.ts +32 -2
|
@@ -37,12 +37,12 @@ describe('update', () => {
|
|
|
37
37
|
const count = 2;
|
|
38
38
|
const users = await User.select('id').insertMany([userData, userData]);
|
|
39
39
|
|
|
40
|
-
const query = User.or(...users).
|
|
40
|
+
const query = User.or(...users).updateRaw(raw(`name = 'name'`));
|
|
41
41
|
expectSql(
|
|
42
42
|
query.toSql(),
|
|
43
43
|
`
|
|
44
44
|
UPDATE "user"
|
|
45
|
-
SET name = 'name'
|
|
45
|
+
SET name = 'name', "updatedAt" = now()
|
|
46
46
|
WHERE "user"."id" = $1 OR "user"."id" = $2
|
|
47
47
|
`,
|
|
48
48
|
[users[0].id, users[1].id],
|
|
@@ -69,7 +69,8 @@ describe('update', () => {
|
|
|
69
69
|
`
|
|
70
70
|
UPDATE "user"
|
|
71
71
|
SET "name" = $1,
|
|
72
|
-
"password" = $2
|
|
72
|
+
"password" = $2,
|
|
73
|
+
"updatedAt" = now()
|
|
73
74
|
WHERE "user"."id" = $3
|
|
74
75
|
`,
|
|
75
76
|
[update.name, update.password, id],
|
|
@@ -99,7 +100,8 @@ describe('update', () => {
|
|
|
99
100
|
`
|
|
100
101
|
UPDATE "user"
|
|
101
102
|
SET "name" = $1,
|
|
102
|
-
"password" = $2
|
|
103
|
+
"password" = $2,
|
|
104
|
+
"updatedAt" = now()
|
|
103
105
|
WHERE "user"."id" = $3
|
|
104
106
|
RETURNING "user"."id"
|
|
105
107
|
`,
|
|
@@ -126,7 +128,8 @@ describe('update', () => {
|
|
|
126
128
|
`
|
|
127
129
|
UPDATE "user"
|
|
128
130
|
SET "name" = $1,
|
|
129
|
-
"password" = $2
|
|
131
|
+
"password" = $2,
|
|
132
|
+
"updatedAt" = now()
|
|
130
133
|
WHERE "user"."id" = $3
|
|
131
134
|
RETURNING "user"."id", "user"."name"
|
|
132
135
|
`,
|
|
@@ -151,7 +154,8 @@ describe('update', () => {
|
|
|
151
154
|
`
|
|
152
155
|
UPDATE "user"
|
|
153
156
|
SET "name" = $1,
|
|
154
|
-
"password" = $2
|
|
157
|
+
"password" = $2,
|
|
158
|
+
"updatedAt" = now()
|
|
155
159
|
WHERE "user"."id" = $3
|
|
156
160
|
RETURNING *
|
|
157
161
|
`,
|
|
@@ -183,7 +187,8 @@ describe('update', () => {
|
|
|
183
187
|
`
|
|
184
188
|
UPDATE "user"
|
|
185
189
|
SET "name" = $1,
|
|
186
|
-
"password" = $2
|
|
190
|
+
"password" = $2,
|
|
191
|
+
"updatedAt" = now()
|
|
187
192
|
WHERE "user"."id" IN ($3, $4)
|
|
188
193
|
RETURNING "user"."id", "user"."name"
|
|
189
194
|
`,
|
|
@@ -215,7 +220,8 @@ describe('update', () => {
|
|
|
215
220
|
`
|
|
216
221
|
UPDATE "user"
|
|
217
222
|
SET "name" = $1,
|
|
218
|
-
"password" = $2
|
|
223
|
+
"password" = $2,
|
|
224
|
+
"updatedAt" = now()
|
|
219
225
|
WHERE "user"."id" IN ($3, $4)
|
|
220
226
|
RETURNING *
|
|
221
227
|
`,
|
|
@@ -243,7 +249,8 @@ describe('update', () => {
|
|
|
243
249
|
`
|
|
244
250
|
UPDATE "user"
|
|
245
251
|
SET "name" = $1,
|
|
246
|
-
"data" = $2
|
|
252
|
+
"data" = $2,
|
|
253
|
+
"updatedAt" = now()
|
|
247
254
|
WHERE "user"."id" = $3
|
|
248
255
|
`,
|
|
249
256
|
['new name', null, 1],
|
|
@@ -261,7 +268,7 @@ describe('update', () => {
|
|
|
261
268
|
query.toSql(),
|
|
262
269
|
`
|
|
263
270
|
UPDATE "user"
|
|
264
|
-
SET "name" = 'raw sql'
|
|
271
|
+
SET "name" = 'raw sql', "updatedAt" = now()
|
|
265
272
|
WHERE "user"."id" = $1
|
|
266
273
|
`,
|
|
267
274
|
[1],
|
|
@@ -285,7 +292,8 @@ describe('update', () => {
|
|
|
285
292
|
`
|
|
286
293
|
UPDATE "user"
|
|
287
294
|
SET "name" = $1,
|
|
288
|
-
"password" = $2
|
|
295
|
+
"password" = $2,
|
|
296
|
+
"updatedAt" = now()
|
|
289
297
|
WHERE "user"."id" = $3
|
|
290
298
|
RETURNING *
|
|
291
299
|
`,
|
|
@@ -337,7 +345,8 @@ describe('update', () => {
|
|
|
337
345
|
query.toSql(),
|
|
338
346
|
`
|
|
339
347
|
UPDATE "user"
|
|
340
|
-
SET "age" = "age" + $1
|
|
348
|
+
SET "age" = "age" + $1,
|
|
349
|
+
"updatedAt" = now()
|
|
341
350
|
`,
|
|
342
351
|
[1],
|
|
343
352
|
);
|
|
@@ -349,7 +358,8 @@ describe('update', () => {
|
|
|
349
358
|
query.toSql(),
|
|
350
359
|
`
|
|
351
360
|
UPDATE "user"
|
|
352
|
-
SET "age" = "age" + $1
|
|
361
|
+
SET "age" = "age" + $1,
|
|
362
|
+
"updatedAt" = now()
|
|
353
363
|
`,
|
|
354
364
|
[3],
|
|
355
365
|
);
|
|
@@ -361,7 +371,8 @@ describe('update', () => {
|
|
|
361
371
|
query.toSql(),
|
|
362
372
|
`
|
|
363
373
|
UPDATE "user"
|
|
364
|
-
SET "age" = "age" + $1
|
|
374
|
+
SET "age" = "age" + $1,
|
|
375
|
+
"updatedAt" = now()
|
|
365
376
|
RETURNING "user"."id"
|
|
366
377
|
`,
|
|
367
378
|
[3],
|
|
@@ -379,7 +390,8 @@ describe('update', () => {
|
|
|
379
390
|
query.toSql(),
|
|
380
391
|
`
|
|
381
392
|
UPDATE "user"
|
|
382
|
-
SET "age" = "age" - $1
|
|
393
|
+
SET "age" = "age" - $1,
|
|
394
|
+
"updatedAt" = now()
|
|
383
395
|
`,
|
|
384
396
|
[1],
|
|
385
397
|
);
|
|
@@ -391,7 +403,8 @@ describe('update', () => {
|
|
|
391
403
|
query.toSql(),
|
|
392
404
|
`
|
|
393
405
|
UPDATE "user"
|
|
394
|
-
SET "age" = "age" - $1
|
|
406
|
+
SET "age" = "age" - $1,
|
|
407
|
+
"updatedAt" = now()
|
|
395
408
|
`,
|
|
396
409
|
[3],
|
|
397
410
|
);
|
|
@@ -403,7 +416,8 @@ describe('update', () => {
|
|
|
403
416
|
query.toSql(),
|
|
404
417
|
`
|
|
405
418
|
UPDATE "user"
|
|
406
|
-
SET "age" = "age" - $1
|
|
419
|
+
SET "age" = "age" - $1,
|
|
420
|
+
"updatedAt" = now()
|
|
407
421
|
RETURNING "user"."id"
|
|
408
422
|
`,
|
|
409
423
|
[3],
|
|
@@ -430,7 +444,8 @@ describe('update', () => {
|
|
|
430
444
|
SET "name" = $1,
|
|
431
445
|
"id" = "id" + $2,
|
|
432
446
|
"password" = $3,
|
|
433
|
-
"age" = "age" - $4
|
|
447
|
+
"age" = "age" - $4,
|
|
448
|
+
"updatedAt" = now()
|
|
434
449
|
WHERE "user"."id" = $5
|
|
435
450
|
RETURNING "user"."id"
|
|
436
451
|
`,
|
|
@@ -31,7 +31,9 @@ export type UpdateData<T extends Query> = {
|
|
|
31
31
|
? UpdateHasAndBelongsToManyData<T['relations'][K]>
|
|
32
32
|
: never;
|
|
33
33
|
}
|
|
34
|
-
: EmptyObject)
|
|
34
|
+
: EmptyObject) & {
|
|
35
|
+
__raw?: never; // forbid RawExpression argument
|
|
36
|
+
};
|
|
35
37
|
|
|
36
38
|
type UpdateBelongsToData<T extends Query, Rel extends BelongsToRelation> =
|
|
37
39
|
| { disconnect: boolean }
|
|
@@ -96,8 +98,14 @@ type UpdateHasAndBelongsToManyData<Rel extends HasAndBelongsToManyRelation> = {
|
|
|
96
98
|
type UpdateArgs<T extends Query, ForceAll extends boolean> = (
|
|
97
99
|
T['hasWhere'] extends true ? true : ForceAll
|
|
98
100
|
) extends true
|
|
99
|
-
? [update:
|
|
100
|
-
: [update:
|
|
101
|
+
? [update: UpdateData<T>]
|
|
102
|
+
: [update: UpdateData<T>, forceAll: true];
|
|
103
|
+
|
|
104
|
+
type UpdateRawArgs<T extends Query, ForceAll extends boolean> = (
|
|
105
|
+
T['hasWhere'] extends true ? true : ForceAll
|
|
106
|
+
) extends true
|
|
107
|
+
? [update: RawExpression]
|
|
108
|
+
: [update: RawExpression, forceAll: true];
|
|
101
109
|
|
|
102
110
|
type UpdateResult<T extends Query> = T['hasSelect'] extends false
|
|
103
111
|
? SetQueryReturnsRowCount<T>
|
|
@@ -124,12 +132,27 @@ const applyCountChange = <T extends Query>(
|
|
|
124
132
|
map = { [data as string]: { op, arg: 1 } };
|
|
125
133
|
}
|
|
126
134
|
|
|
127
|
-
pushQueryValue(self, '
|
|
135
|
+
pushQueryValue(self, 'updateData', map);
|
|
128
136
|
return self as unknown as UpdateResult<T>;
|
|
129
137
|
};
|
|
130
138
|
|
|
131
139
|
const checkIfUpdateIsEmpty = (q: UpdateQueryData) => {
|
|
132
|
-
return !q.
|
|
140
|
+
return !q.updateData?.some((item) => isRaw(item) || Object.keys(item).length);
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
const update = <T extends Query>(q: T, forceAll: boolean): UpdateResult<T> => {
|
|
144
|
+
const { query } = q;
|
|
145
|
+
query.type = 'update';
|
|
146
|
+
|
|
147
|
+
if (!query.and?.length && !query.or?.length && !forceAll) {
|
|
148
|
+
throw new Error('No where conditions or forceAll flag provided to update');
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (!query.select) {
|
|
152
|
+
query.returnType = 'rowCount';
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
return q as unknown as UpdateResult<T>;
|
|
133
156
|
};
|
|
134
157
|
|
|
135
158
|
export class Update {
|
|
@@ -141,161 +164,158 @@ export class Update {
|
|
|
141
164
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
142
165
|
return q._update(...(args as any));
|
|
143
166
|
}
|
|
144
|
-
|
|
145
167
|
_update<T extends Query, ForceAll extends boolean = false>(
|
|
146
168
|
this: T,
|
|
147
169
|
...args: UpdateArgs<T, ForceAll>
|
|
148
170
|
): UpdateResult<T> {
|
|
149
|
-
const [data, forceAll] = args as unknown as [
|
|
150
|
-
Record<string, unknown>,
|
|
151
|
-
boolean | undefined,
|
|
152
|
-
];
|
|
153
171
|
const { query } = this;
|
|
154
|
-
|
|
172
|
+
const data = args[0];
|
|
155
173
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
174
|
+
const set: Record<string, unknown> = { ...data };
|
|
175
|
+
pushQueryValue(this, 'updateData', set);
|
|
176
|
+
|
|
177
|
+
const relations = this.relations as Record<string, Relation>;
|
|
178
|
+
|
|
179
|
+
const prependRelations: Record<string, Record<string, unknown>> = {};
|
|
180
|
+
const appendRelations: Record<string, Record<string, unknown>> = {};
|
|
181
|
+
|
|
182
|
+
const originalReturnType = query.returnType;
|
|
161
183
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
const originalReturnType = this.query.returnType;
|
|
174
|
-
|
|
175
|
-
for (const key in data) {
|
|
176
|
-
if (relations[key]) {
|
|
177
|
-
delete update[key];
|
|
178
|
-
if (relations[key].type === 'belongsTo') {
|
|
179
|
-
prependRelations[key] = data[key] as Record<string, unknown>;
|
|
180
|
-
} else {
|
|
181
|
-
if (!query.select?.includes('*')) {
|
|
182
|
-
const primaryKey = relations[key].primaryKey;
|
|
183
|
-
if (!query.select?.includes(primaryKey)) {
|
|
184
|
-
this._select(primaryKey as StringKey<keyof T['selectable']>);
|
|
185
|
-
}
|
|
184
|
+
for (const key in data) {
|
|
185
|
+
if (relations[key]) {
|
|
186
|
+
delete set[key];
|
|
187
|
+
if (relations[key].type === 'belongsTo') {
|
|
188
|
+
prependRelations[key] = data[key] as Record<string, unknown>;
|
|
189
|
+
} else {
|
|
190
|
+
if (!query.select?.includes('*')) {
|
|
191
|
+
const primaryKey = relations[key].primaryKey;
|
|
192
|
+
if (!query.select?.includes(primaryKey)) {
|
|
193
|
+
this._select(primaryKey as StringKey<keyof T['selectable']>);
|
|
186
194
|
}
|
|
187
|
-
appendRelations[key] = data[key] as Record<string, unknown>;
|
|
188
195
|
}
|
|
196
|
+
appendRelations[key] = data[key] as Record<string, unknown>;
|
|
189
197
|
}
|
|
190
198
|
}
|
|
199
|
+
}
|
|
191
200
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
201
|
+
const state: {
|
|
202
|
+
updateLater?: Record<string, unknown>;
|
|
203
|
+
updateLaterPromises?: Promise<void>[];
|
|
204
|
+
} = {};
|
|
196
205
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
206
|
+
const prependRelationKeys = Object.keys(prependRelations);
|
|
207
|
+
let willSetKeys = false;
|
|
208
|
+
if (prependRelationKeys.length) {
|
|
209
|
+
willSetKeys = prependRelationKeys.some((relationName) => {
|
|
210
|
+
const data = prependRelations[relationName] as NestedUpdateOneItem;
|
|
202
211
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
if (!willSetKeys && checkIfUpdateIsEmpty(this.query as UpdateQueryData)) {
|
|
212
|
-
delete this.query.type;
|
|
213
|
-
}
|
|
212
|
+
return (
|
|
213
|
+
relations[relationName] as {
|
|
214
|
+
nestedUpdate: BelongsToNestedUpdate;
|
|
215
|
+
}
|
|
216
|
+
).nestedUpdate(this, set, data, state);
|
|
217
|
+
});
|
|
218
|
+
}
|
|
214
219
|
|
|
215
|
-
|
|
220
|
+
if (!willSetKeys && checkIfUpdateIsEmpty(query as UpdateQueryData)) {
|
|
221
|
+
delete query.type;
|
|
222
|
+
}
|
|
216
223
|
|
|
217
|
-
|
|
224
|
+
const appendRelationKeys = Object.keys(appendRelations);
|
|
218
225
|
|
|
219
|
-
|
|
220
|
-
state?.updateLater ||
|
|
221
|
-
(appendRelationKeys.length && originalReturnType !== 'all')
|
|
222
|
-
) {
|
|
223
|
-
this.query.returnType = 'all';
|
|
226
|
+
let resultOfTypeAll: Record<string, unknown>[] | undefined;
|
|
224
227
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
});
|
|
231
|
-
}
|
|
228
|
+
if (
|
|
229
|
+
state?.updateLater ||
|
|
230
|
+
(appendRelationKeys.length && originalReturnType !== 'all')
|
|
231
|
+
) {
|
|
232
|
+
query.returnType = 'all';
|
|
232
233
|
|
|
233
|
-
|
|
234
|
-
this.
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
unknown
|
|
238
|
-
>[];
|
|
239
|
-
|
|
240
|
-
if (state?.updateLater) {
|
|
241
|
-
await Promise.all(state.updateLaterPromises as Promise<void>[]);
|
|
242
|
-
|
|
243
|
-
const t = this.__model.clone().transacting(q);
|
|
244
|
-
const keys = this.schema.primaryKeys as string[];
|
|
245
|
-
(
|
|
246
|
-
t._whereIn as unknown as (
|
|
247
|
-
keys: string[],
|
|
248
|
-
values: unknown[][],
|
|
249
|
-
) => Query
|
|
250
|
-
)(
|
|
251
|
-
keys,
|
|
252
|
-
resultOfTypeAll.map((item) => keys.map((key) => item[key])),
|
|
253
|
-
);
|
|
254
|
-
|
|
255
|
-
await (t as WhereResult<Query>)._update(state.updateLater);
|
|
256
|
-
|
|
257
|
-
resultOfTypeAll.forEach((item) =>
|
|
258
|
-
Object.assign(item, state.updateLater),
|
|
259
|
-
);
|
|
234
|
+
if (state?.updateLater) {
|
|
235
|
+
this.schema.primaryKeys.forEach((key: string) => {
|
|
236
|
+
if (!query.select?.includes('*') && !query.select?.includes(key)) {
|
|
237
|
+
this._select(key as StringKey<keyof T['selectable']>);
|
|
260
238
|
}
|
|
239
|
+
});
|
|
240
|
+
}
|
|
261
241
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
}
|
|
242
|
+
const { handleResult } = query;
|
|
243
|
+
query.handleResult = async (q, queryResult) => {
|
|
244
|
+
resultOfTypeAll = (await handleResult(q, queryResult)) as Record<
|
|
245
|
+
string,
|
|
246
|
+
unknown
|
|
247
|
+
>[];
|
|
269
248
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
249
|
+
if (state?.updateLater) {
|
|
250
|
+
await Promise.all(state.updateLaterPromises as Promise<void>[]);
|
|
251
|
+
|
|
252
|
+
const t = this.__model.clone().transacting(q);
|
|
253
|
+
const keys = this.schema.primaryKeys as string[];
|
|
254
|
+
(
|
|
255
|
+
t._whereIn as unknown as (
|
|
256
|
+
keys: string[],
|
|
257
|
+
values: unknown[][],
|
|
258
|
+
) => Query
|
|
259
|
+
)(
|
|
260
|
+
keys,
|
|
261
|
+
resultOfTypeAll.map((item) => keys.map((key) => item[key])),
|
|
262
|
+
);
|
|
263
|
+
|
|
264
|
+
await (t as WhereResult<Query>)._update(state.updateLater);
|
|
265
|
+
|
|
266
|
+
resultOfTypeAll.forEach((item) =>
|
|
267
|
+
Object.assign(item, state.updateLater),
|
|
268
|
+
);
|
|
269
|
+
}
|
|
273
270
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
return (
|
|
282
|
-
relations[relationName].nestedUpdate as HasOneNestedUpdate
|
|
283
|
-
)?.(q, all, appendRelations[relationName] as NestedUpdateOneItem);
|
|
284
|
-
};
|
|
285
|
-
}),
|
|
286
|
-
);
|
|
287
|
-
}
|
|
271
|
+
if (queryMethodByReturnType[originalReturnType] === 'arrays') {
|
|
272
|
+
queryResult.rows.forEach(
|
|
273
|
+
(row, i) =>
|
|
274
|
+
((queryResult.rows as unknown as unknown[][])[i] =
|
|
275
|
+
Object.values(row)),
|
|
276
|
+
);
|
|
277
|
+
}
|
|
288
278
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
}
|
|
279
|
+
return parseResult(q, originalReturnType, queryResult);
|
|
280
|
+
};
|
|
292
281
|
}
|
|
293
282
|
|
|
294
|
-
if (
|
|
295
|
-
|
|
283
|
+
if (appendRelationKeys.length) {
|
|
284
|
+
pushQueryArray(
|
|
285
|
+
this,
|
|
286
|
+
'afterQuery',
|
|
287
|
+
appendRelationKeys.map((relationName) => {
|
|
288
|
+
return (q: Query, result: Record<string, unknown>[]) => {
|
|
289
|
+
const all = resultOfTypeAll || result;
|
|
290
|
+
return (
|
|
291
|
+
relations[relationName].nestedUpdate as HasOneNestedUpdate
|
|
292
|
+
)?.(q, all, appendRelations[relationName] as NestedUpdateOneItem);
|
|
293
|
+
};
|
|
294
|
+
}),
|
|
295
|
+
);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
if (prependRelationKeys.length || appendRelationKeys.length) {
|
|
299
|
+
query.wrapInTransaction = true;
|
|
296
300
|
}
|
|
297
301
|
|
|
298
|
-
return this as unknown
|
|
302
|
+
return update(this, (args as [unknown, boolean])[1]);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
updateRaw<T extends Query, ForceAll extends boolean = false>(
|
|
306
|
+
this: T,
|
|
307
|
+
...args: UpdateRawArgs<T, ForceAll>
|
|
308
|
+
): UpdateResult<T> {
|
|
309
|
+
const q = this.clone() as T;
|
|
310
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
311
|
+
return q._updateRaw(...(args as any));
|
|
312
|
+
}
|
|
313
|
+
_updateRaw<T extends Query, ForceAll extends boolean = false>(
|
|
314
|
+
this: T,
|
|
315
|
+
...args: UpdateRawArgs<T, ForceAll>
|
|
316
|
+
): UpdateResult<T> {
|
|
317
|
+
pushQueryValue(this, 'updateData', args[0]);
|
|
318
|
+
return update(this, (args as [unknown, boolean])[1]);
|
|
299
319
|
}
|
|
300
320
|
|
|
301
321
|
updateOrThrow<T extends Query, ForceAll extends boolean = false>(
|
package/src/sql/fromAndAs.ts
CHANGED
|
@@ -33,7 +33,7 @@ const getFrom = (
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
if (!query.from.table) {
|
|
36
|
-
const sql = query.from.toSql(values);
|
|
36
|
+
const sql = query.from.toSql({ values });
|
|
37
37
|
return `(${sql.text})`;
|
|
38
38
|
}
|
|
39
39
|
|
|
@@ -41,7 +41,7 @@ const getFrom = (
|
|
|
41
41
|
const keys = Object.keys(q) as (keyof SelectQueryData)[];
|
|
42
42
|
// if query contains more than just schema return (SELECT ...)
|
|
43
43
|
if (keys.some((key) => queryKeysOfNotSimpleQuery.includes(key))) {
|
|
44
|
-
const sql = query.from.toSql(values);
|
|
44
|
+
const sql = query.from.toSql({ values });
|
|
45
45
|
return `(${sql.text})`;
|
|
46
46
|
}
|
|
47
47
|
|
package/src/sql/select.ts
CHANGED
|
@@ -173,7 +173,7 @@ const pushSubQuerySql = (
|
|
|
173
173
|
throw new UnhandledTypeError(returnType);
|
|
174
174
|
}
|
|
175
175
|
|
|
176
|
-
let subQuerySql = `(${query.toSql(values).text})`;
|
|
176
|
+
let subQuerySql = `(${query.toSql({ values }).text})`;
|
|
177
177
|
const { coalesceValue } = query.query;
|
|
178
178
|
if (coalesceValue !== undefined) {
|
|
179
179
|
const value =
|
package/src/sql/toSql.ts
CHANGED
|
@@ -25,7 +25,22 @@ export type ToSqlCtx = {
|
|
|
25
25
|
values: unknown[];
|
|
26
26
|
};
|
|
27
27
|
|
|
28
|
-
export
|
|
28
|
+
export type toSqlCacheKey = typeof toSqlCacheKey;
|
|
29
|
+
export const toSqlCacheKey = Symbol('toSqlCache');
|
|
30
|
+
|
|
31
|
+
export type ToSqlOptions = {
|
|
32
|
+
clearCache?: boolean;
|
|
33
|
+
values?: unknown[];
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export const toSql = (model: Query, options?: ToSqlOptions): Sql => {
|
|
37
|
+
return (
|
|
38
|
+
(!options?.clearCache && model.query[toSqlCacheKey]) ||
|
|
39
|
+
(model.query[toSqlCacheKey] = makeSql(model, options))
|
|
40
|
+
);
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const makeSql = (model: Query, { values = [] }: ToSqlOptions = {}): Sql => {
|
|
29
44
|
const query = model.query;
|
|
30
45
|
const sql: string[] = [];
|
|
31
46
|
const ctx: ToSqlCtx = {
|
|
@@ -130,7 +145,7 @@ export const toSql = (model: Query, values: unknown[] = []): Sql => {
|
|
|
130
145
|
if (isRaw(item.arg)) {
|
|
131
146
|
itemSql = getRaw(item.arg, values);
|
|
132
147
|
} else {
|
|
133
|
-
const argSql = item.arg.toSql(values);
|
|
148
|
+
const argSql = item.arg.toSql({ values });
|
|
134
149
|
itemSql = argSql.text;
|
|
135
150
|
}
|
|
136
151
|
sql.push(`${item.kind} ${item.wrap ? `(${itemSql})` : itemSql}`);
|
package/src/sql/types.ts
CHANGED
|
@@ -13,6 +13,7 @@ import { Adapter, QueryResult } from '../adapter';
|
|
|
13
13
|
import { MaybeArray } from '../utils';
|
|
14
14
|
import { QueryLogger, QueryLogObject } from '../queryMethods/log';
|
|
15
15
|
import { AfterCallback, BeforeCallback } from '../queryMethods/callbacks';
|
|
16
|
+
import { toSqlCacheKey } from './toSql';
|
|
16
17
|
|
|
17
18
|
export type Sql = {
|
|
18
19
|
text: string;
|
|
@@ -63,10 +64,11 @@ export type CommonQueryData = {
|
|
|
63
64
|
parsers?: ColumnsParsers;
|
|
64
65
|
notFoundDefault?: unknown;
|
|
65
66
|
defaults?: Record<string, unknown>;
|
|
66
|
-
beforeQuery?: BeforeCallback
|
|
67
|
-
afterQuery?: AfterCallback
|
|
67
|
+
beforeQuery?: BeforeCallback[];
|
|
68
|
+
afterQuery?: AfterCallback[];
|
|
68
69
|
log?: QueryLogObject;
|
|
69
70
|
logger: QueryLogger;
|
|
71
|
+
[toSqlCacheKey]?: Sql;
|
|
70
72
|
};
|
|
71
73
|
|
|
72
74
|
export type SelectQueryData = CommonQueryData & {
|
|
@@ -107,24 +109,37 @@ export type InsertQueryData = CommonQueryData & {
|
|
|
107
109
|
expr?: OnConflictItem;
|
|
108
110
|
update?: OnConflictMergeUpdate;
|
|
109
111
|
};
|
|
110
|
-
beforeInsert?: BeforeCallback
|
|
111
|
-
afterInsert?: AfterCallback
|
|
112
|
+
beforeInsert?: BeforeCallback[];
|
|
113
|
+
afterInsert?: AfterCallback[];
|
|
112
114
|
};
|
|
113
115
|
|
|
116
|
+
export type UpdateQueryDataObject = Record<
|
|
117
|
+
string,
|
|
118
|
+
RawExpression | { op: string; arg: unknown } | unknown
|
|
119
|
+
>;
|
|
120
|
+
|
|
121
|
+
export type UpdatedAtDataInjector = (
|
|
122
|
+
data: UpdateQueryDataItem[],
|
|
123
|
+
) => UpdateQueryDataItem | void;
|
|
124
|
+
|
|
125
|
+
export type UpdateQueryDataItem =
|
|
126
|
+
| UpdateQueryDataObject
|
|
127
|
+
| RawExpression
|
|
128
|
+
| UpdatedAtDataInjector;
|
|
129
|
+
|
|
114
130
|
export type UpdateQueryData = CommonQueryData & {
|
|
115
131
|
type: 'update';
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
)[];
|
|
120
|
-
beforeUpdate?: BeforeCallback<Query>[];
|
|
121
|
-
afterUpdate?: AfterCallback<Query>[];
|
|
132
|
+
updateData: UpdateQueryDataItem[];
|
|
133
|
+
beforeUpdate?: BeforeCallback[];
|
|
134
|
+
afterUpdate?: AfterCallback[];
|
|
122
135
|
};
|
|
123
136
|
|
|
124
137
|
export type DeleteQueryData = CommonQueryData & {
|
|
125
138
|
type: 'delete';
|
|
126
139
|
join?: JoinItem[];
|
|
127
140
|
joinedParsers?: Record<string, ColumnsParsers>;
|
|
141
|
+
beforeDelete?: BeforeCallback[];
|
|
142
|
+
afterDelete?: AfterCallback[];
|
|
128
143
|
};
|
|
129
144
|
|
|
130
145
|
export type TruncateQueryData = CommonQueryData & {
|