orchid-orm 1.5.29 → 1.5.31

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.
Files changed (59) hide show
  1. package/dist/index.d.ts +6 -14
  2. package/dist/index.js +26 -21
  3. package/dist/index.js.map +1 -1
  4. package/dist/index.mjs +26 -21
  5. package/dist/index.mjs.map +1 -1
  6. package/package.json +12 -22
  7. package/.env.example +0 -1
  8. package/.turbo/turbo-check.log +0 -26
  9. package/.turbo/turbo-test.log +0 -26
  10. package/.turbo/turbo-test:ci.log +0 -26
  11. package/CHANGELOG.md +0 -382
  12. package/coverage/coverage-summary.json +0 -28
  13. package/jest-setup.ts +0 -11
  14. package/rollup.config.js +0 -18
  15. package/src/bin/bin.ts +0 -3
  16. package/src/bin/init.test.ts +0 -810
  17. package/src/bin/init.ts +0 -529
  18. package/src/codegen/appCodeUpdater.test.ts +0 -75
  19. package/src/codegen/appCodeUpdater.ts +0 -53
  20. package/src/codegen/createBaseTableFile.test.ts +0 -53
  21. package/src/codegen/createBaseTableFile.ts +0 -31
  22. package/src/codegen/fileChanges.ts +0 -41
  23. package/src/codegen/testUtils.ts +0 -56
  24. package/src/codegen/tsUtils.ts +0 -180
  25. package/src/codegen/updateMainFile.test.ts +0 -253
  26. package/src/codegen/updateMainFile.ts +0 -210
  27. package/src/codegen/updateTableFile/changeTable.test.ts +0 -804
  28. package/src/codegen/updateTableFile/changeTable.ts +0 -536
  29. package/src/codegen/updateTableFile/createTable.test.ts +0 -139
  30. package/src/codegen/updateTableFile/createTable.ts +0 -51
  31. package/src/codegen/updateTableFile/renameTable.test.ts +0 -124
  32. package/src/codegen/updateTableFile/renameTable.ts +0 -67
  33. package/src/codegen/updateTableFile/updateTableFile.ts +0 -22
  34. package/src/codegen/utils.ts +0 -13
  35. package/src/index.ts +0 -5
  36. package/src/orm.test.ts +0 -92
  37. package/src/orm.ts +0 -98
  38. package/src/relations/belongsTo.test.ts +0 -1122
  39. package/src/relations/belongsTo.ts +0 -352
  40. package/src/relations/hasAndBelongsToMany.test.ts +0 -1335
  41. package/src/relations/hasAndBelongsToMany.ts +0 -472
  42. package/src/relations/hasMany.test.ts +0 -2616
  43. package/src/relations/hasMany.ts +0 -401
  44. package/src/relations/hasOne.test.ts +0 -1701
  45. package/src/relations/hasOne.ts +0 -351
  46. package/src/relations/relations.test.ts +0 -37
  47. package/src/relations/relations.ts +0 -363
  48. package/src/relations/utils.ts +0 -162
  49. package/src/repo.test.ts +0 -200
  50. package/src/repo.ts +0 -119
  51. package/src/table.test.ts +0 -121
  52. package/src/table.ts +0 -184
  53. package/src/test-utils/test-db.ts +0 -32
  54. package/src/test-utils/test-tables.ts +0 -194
  55. package/src/test-utils/test-utils.ts +0 -119
  56. package/src/transaction.test.ts +0 -47
  57. package/src/transaction.ts +0 -27
  58. package/src/utils.ts +0 -9
  59. package/tsconfig.json +0 -14
@@ -1,1122 +0,0 @@
1
- import { db } from '../test-utils/test-db';
2
- import {
3
- assertType,
4
- chatData,
5
- expectSql,
6
- messageData,
7
- profileData,
8
- userData,
9
- useRelationCallback,
10
- useTestDatabase,
11
- } from '../test-utils/test-utils';
12
- import { RelationQuery } from 'pqb';
13
- import { User } from '../test-utils/test-tables';
14
-
15
- describe('belongsTo', () => {
16
- useTestDatabase();
17
-
18
- describe('querying', () => {
19
- it('should have method to query related data', async () => {
20
- const userQuery = db.user.take();
21
- type UserQuery = typeof userQuery;
22
-
23
- assertType<
24
- typeof db.profile.user,
25
- RelationQuery<'user', { userId: number | null }, never, UserQuery, true>
26
- >();
27
-
28
- const userId = await db.user.get('id').create(userData);
29
- const profileId = await db.profile
30
- .get('id')
31
- .create({ ...profileData, userId });
32
-
33
- const profile = await db.profile.find(profileId);
34
- const query = db.profile.user(profile);
35
-
36
- expectSql(
37
- query.toSql(),
38
- `
39
- SELECT * FROM "user"
40
- WHERE "user"."id" = $1
41
- LIMIT $2
42
- `,
43
- [userId, 1],
44
- );
45
-
46
- const user = await query;
47
-
48
- expect(user).toMatchObject(userData);
49
- });
50
-
51
- it('should handle chained query', () => {
52
- const query = db.profile
53
- .where({ bio: 'bio' })
54
- .user.where({ name: 'name' });
55
-
56
- expectSql(
57
- query.toSql(),
58
- `
59
- SELECT * FROM "user"
60
- WHERE EXISTS (
61
- SELECT 1 FROM "profile"
62
- WHERE "profile"."bio" = $1
63
- AND "profile"."userId" = "user"."id"
64
- LIMIT 1
65
- )
66
- AND "user"."name" = $2
67
- LIMIT $3
68
- `,
69
- ['bio', 'name', 1],
70
- );
71
- });
72
-
73
- it('should have disabled create and delete method', () => {
74
- // @ts-expect-error belongsTo should not have chained create
75
- db.profile.user.create(userData);
76
-
77
- // @ts-expect-error belongsTo should not have chained create
78
- db.profile.user.find(1).delete();
79
- });
80
-
81
- it('should have proper joinQuery', () => {
82
- expectSql(
83
- db.profile.relations.user
84
- .joinQuery(db.profile.as('p'), db.user.as('u'))
85
- .toSql(),
86
- `
87
- SELECT * FROM "user" AS "u"
88
- WHERE "u"."id" = "p"."userId"
89
- `,
90
- );
91
- });
92
-
93
- it('should be supported in whereExists', () => {
94
- expectSql(
95
- db.profile.whereExists('user').toSql(),
96
- `
97
- SELECT * FROM "profile"
98
- WHERE EXISTS (
99
- SELECT 1 FROM "user"
100
- WHERE "user"."id" = "profile"."userId"
101
- LIMIT 1
102
- )
103
- `,
104
- );
105
-
106
- expectSql(
107
- db.profile
108
- .as('p')
109
- .whereExists('user', (q) => q.where({ name: 'name' }))
110
- .toSql(),
111
- `
112
- SELECT * FROM "profile" AS "p"
113
- WHERE EXISTS (
114
- SELECT 1 FROM "user"
115
- WHERE "user"."id" = "p"."userId"
116
- AND "user"."name" = $1
117
- LIMIT 1
118
- )
119
- `,
120
- ['name'],
121
- );
122
- });
123
-
124
- it('should support nested whereExists', () => {
125
- expectSql(
126
- db.message
127
- .as('m')
128
- .whereExists('user', (q) =>
129
- q.whereExists('profile', (q) => q.where({ bio: 'bio' })),
130
- )
131
- .toSql(),
132
- `
133
- SELECT * FROM "message" AS "m"
134
- WHERE EXISTS (
135
- SELECT 1 FROM "user"
136
- WHERE "user"."id" = "m"."authorId"
137
- AND EXISTS (
138
- SELECT 1 FROM "profile"
139
- WHERE "profile"."userId" = "user"."id"
140
- AND "profile"."bio" = $1
141
- LIMIT 1
142
- )
143
- LIMIT 1
144
- )
145
- `,
146
- ['bio'],
147
- );
148
- });
149
-
150
- it('should be supported in join', () => {
151
- const query = db.profile
152
- .as('p')
153
- .join('user', (q) => q.where({ name: 'name' }))
154
- .select('bio', 'user.name');
155
-
156
- assertType<
157
- Awaited<typeof query>,
158
- { bio: string | null; name: string }[]
159
- >();
160
-
161
- expectSql(
162
- query.toSql(),
163
- `
164
- SELECT "p"."bio", "user"."name"
165
- FROM "profile" AS "p"
166
- JOIN "user" ON "user"."id" = "p"."userId" AND "user"."name" = $1
167
- `,
168
- ['name'],
169
- );
170
- });
171
-
172
- describe('select', () => {
173
- it('should be selectable', async () => {
174
- const query = db.profile.as('p').select('id', {
175
- user: (q) => q.user.select('id', 'name').where({ name: 'name' }),
176
- });
177
-
178
- assertType<
179
- Awaited<typeof query>,
180
- { id: number; user: { id: number; name: string } }[]
181
- >();
182
-
183
- expectSql(
184
- query.toSql(),
185
- `
186
- SELECT
187
- "p"."id",
188
- (
189
- SELECT row_to_json("t".*)
190
- FROM (
191
- SELECT "user"."id", "user"."name" FROM "user"
192
- WHERE "user"."name" = $1
193
- AND "user"."id" = "p"."userId"
194
- LIMIT $2
195
- ) AS "t"
196
- ) AS "user"
197
- FROM "profile" AS "p"
198
- `,
199
- ['name', 1],
200
- );
201
- });
202
-
203
- it('should be selectable by relation name', async () => {
204
- const query = db.profile.select('id', 'user');
205
-
206
- assertType<Awaited<typeof query>, { id: number; user: User }[]>();
207
-
208
- expectSql(
209
- query.toSql(),
210
- `
211
- SELECT
212
- "profile"."id",
213
- (
214
- SELECT row_to_json("t".*)
215
- FROM (
216
- SELECT * FROM "user"
217
- WHERE "user"."id" = "profile"."userId"
218
- LIMIT $1
219
- ) AS "t"
220
- ) AS "user"
221
- FROM "profile"
222
- `,
223
- [1],
224
- );
225
- });
226
-
227
- it('should handle exists sub query', async () => {
228
- const query = db.profile.as('p').select('id', {
229
- hasUser: (q) => q.user.exists(),
230
- });
231
-
232
- assertType<Awaited<typeof query>, { id: number; hasUser: boolean }[]>();
233
-
234
- expectSql(
235
- query.toSql(),
236
- `
237
- SELECT
238
- "p"."id",
239
- COALESCE((
240
- SELECT true
241
- FROM "user"
242
- WHERE "user"."id" = "p"."userId"
243
- ), false) AS "hasUser"
244
- FROM "profile" AS "p"
245
- `,
246
- );
247
- });
248
- });
249
- });
250
-
251
- describe('create', () => {
252
- const checkCreatedResults = async ({
253
- messageId,
254
- chatId,
255
- authorId,
256
- text,
257
- title,
258
- name,
259
- }: {
260
- messageId: number;
261
- chatId: number;
262
- authorId: number | null;
263
- text: string;
264
- title: string;
265
- name: string;
266
- }) => {
267
- const message = await db.message.find(messageId);
268
- expect(message).toEqual({
269
- ...message,
270
- ...messageData,
271
- chatId,
272
- authorId,
273
- text,
274
- });
275
-
276
- const chat = await db.chat.find(chatId);
277
- expect(chat).toEqual({
278
- ...chat,
279
- ...chatData,
280
- title,
281
- });
282
-
283
- if (!authorId) return;
284
- const user = await db.user.find(authorId);
285
- expect(user).toEqual({
286
- ...user,
287
- ...userData,
288
- active: null,
289
- age: null,
290
- data: null,
291
- picture: null,
292
- name,
293
- });
294
- };
295
-
296
- describe('nested create', () => {
297
- it('should support create', async () => {
298
- const {
299
- id: messageId,
300
- chatId,
301
- authorId,
302
- } = await db.message.select('id', 'chatId', 'authorId').create({
303
- ...messageData,
304
- text: 'message',
305
- chat: {
306
- create: {
307
- ...chatData,
308
- title: 'chat',
309
- },
310
- },
311
- user: {
312
- create: {
313
- ...userData,
314
- name: 'user',
315
- },
316
- },
317
- });
318
-
319
- await checkCreatedResults({
320
- messageId,
321
- chatId,
322
- authorId,
323
- text: 'message',
324
- title: 'chat',
325
- name: 'user',
326
- });
327
- });
328
-
329
- it('should support create in batch create', async () => {
330
- const query = db.message.select('id', 'chatId', 'authorId').createMany([
331
- {
332
- ...messageData,
333
- text: 'message 1',
334
- chat: {
335
- create: {
336
- ...chatData,
337
- title: 'chat 1',
338
- },
339
- },
340
- user: {
341
- create: {
342
- ...userData,
343
- name: 'user 1',
344
- },
345
- },
346
- },
347
- {
348
- ...messageData,
349
- text: 'message 2',
350
- chat: {
351
- create: {
352
- ...chatData,
353
- title: 'chat 2',
354
- },
355
- },
356
- user: {
357
- create: {
358
- ...userData,
359
- name: 'user 2',
360
- },
361
- },
362
- },
363
- ]);
364
-
365
- const [first, second] = await query;
366
-
367
- await checkCreatedResults({
368
- messageId: first.id,
369
- chatId: first.chatId,
370
- authorId: first.authorId,
371
- text: 'message 1',
372
- title: 'chat 1',
373
- name: 'user 1',
374
- });
375
-
376
- await checkCreatedResults({
377
- messageId: second.id,
378
- chatId: second.chatId,
379
- authorId: second.authorId,
380
- text: 'message 2',
381
- title: 'chat 2',
382
- name: 'user 2',
383
- });
384
- });
385
-
386
- describe('relation callbacks', () => {
387
- const { beforeCreate, afterCreate, resetMocks } = useRelationCallback(
388
- db.message.relations.chat,
389
- );
390
-
391
- const data = {
392
- ...messageData,
393
- chat: {
394
- create: chatData,
395
- },
396
- };
397
-
398
- it('should invoke callbacks', async () => {
399
- await db.message.create(data);
400
-
401
- expect(beforeCreate).toHaveBeenCalledTimes(1);
402
- expect(afterCreate).toHaveBeenCalledTimes(1);
403
- });
404
-
405
- it('should invoke callbacks in a batch create', async () => {
406
- resetMocks();
407
-
408
- await db.message.createMany([data, data]);
409
-
410
- expect(beforeCreate).toHaveBeenCalledTimes(1);
411
- expect(afterCreate).toHaveBeenCalledTimes(1);
412
- });
413
- });
414
- });
415
-
416
- describe('connect', () => {
417
- it('should support connect', async () => {
418
- await db.chat.create({ ...chatData, title: 'chat' });
419
- await db.user.create({ ...userData, name: 'user' });
420
-
421
- const query = db.message.select('id', 'chatId', 'authorId').create({
422
- ...messageData,
423
- text: 'message',
424
- chat: {
425
- connect: { title: 'chat' },
426
- },
427
- user: {
428
- connect: { name: 'user' },
429
- },
430
- });
431
-
432
- const { id: messageId, chatId, authorId } = await query;
433
-
434
- await checkCreatedResults({
435
- messageId,
436
- chatId,
437
- authorId,
438
- text: 'message',
439
- title: 'chat',
440
- name: 'user',
441
- });
442
- });
443
-
444
- it('should support connect in batch create', async () => {
445
- await db.chat.createMany([
446
- { ...chatData, title: 'chat 1' },
447
- { ...chatData, title: 'chat 2' },
448
- ]);
449
- await db.user.createMany([
450
- { ...userData, name: 'user 1' },
451
- { ...userData, name: 'user 2' },
452
- ]);
453
-
454
- const query = db.message.select('id', 'chatId', 'authorId').createMany([
455
- {
456
- ...messageData,
457
- text: 'message 1',
458
- chat: {
459
- connect: { title: 'chat 1' },
460
- },
461
- user: {
462
- connect: { name: 'user 1' },
463
- },
464
- },
465
- {
466
- ...messageData,
467
- text: 'message 2',
468
- chat: {
469
- connect: { title: 'chat 2' },
470
- },
471
- user: {
472
- connect: { name: 'user 2' },
473
- },
474
- },
475
- ]);
476
-
477
- const [first, second] = await query;
478
-
479
- await checkCreatedResults({
480
- messageId: first.id,
481
- chatId: first.chatId,
482
- authorId: first.authorId,
483
- text: 'message 1',
484
- title: 'chat 1',
485
- name: 'user 1',
486
- });
487
-
488
- await checkCreatedResults({
489
- messageId: second.id,
490
- chatId: second.chatId,
491
- authorId: second.authorId,
492
- text: 'message 2',
493
- title: 'chat 2',
494
- name: 'user 2',
495
- });
496
- });
497
- });
498
-
499
- describe('connectOrCreate', () => {
500
- it('should support connect or create', async () => {
501
- const chat = await db.chat.select('id').create({
502
- ...chatData,
503
- title: 'chat',
504
- });
505
-
506
- const query = await db.message
507
- .select('id', 'chatId', 'authorId')
508
- .create({
509
- ...messageData,
510
- text: 'message',
511
- chat: {
512
- connectOrCreate: {
513
- where: { title: 'chat' },
514
- create: { ...chatData, title: 'chat' },
515
- },
516
- },
517
- user: {
518
- connectOrCreate: {
519
- where: { name: 'user' },
520
- create: { ...userData, name: 'user' },
521
- },
522
- },
523
- });
524
-
525
- const { id: messageId, chatId, authorId } = await query;
526
-
527
- expect(chatId).toBe(chat.id);
528
-
529
- await checkCreatedResults({
530
- messageId,
531
- chatId,
532
- authorId,
533
- text: 'message',
534
- title: 'chat',
535
- name: 'user',
536
- });
537
- });
538
-
539
- it('should support connect or create in batch create', async () => {
540
- const chat = await db.chat.select('id').create({
541
- ...chatData,
542
- title: 'chat 1',
543
- });
544
- const user = await db.user.select('id').create({
545
- ...userData,
546
- name: 'user 2',
547
- });
548
-
549
- const query = await db.message
550
- .select('id', 'chatId', 'authorId')
551
- .createMany([
552
- {
553
- ...messageData,
554
- text: 'message 1',
555
- chat: {
556
- connectOrCreate: {
557
- where: { title: 'chat 1' },
558
- create: { ...chatData, title: 'chat 1' },
559
- },
560
- },
561
- user: {
562
- connectOrCreate: {
563
- where: { name: 'user 1' },
564
- create: { ...userData, name: 'user 1' },
565
- },
566
- },
567
- },
568
- {
569
- ...messageData,
570
- text: 'message 2',
571
- chat: {
572
- connectOrCreate: {
573
- where: { title: 'chat 2' },
574
- create: { ...chatData, title: 'chat 2' },
575
- },
576
- },
577
- user: {
578
- connectOrCreate: {
579
- where: { name: 'user 2' },
580
- create: { ...userData, name: 'user 2' },
581
- },
582
- },
583
- },
584
- ]);
585
-
586
- const [first, second] = await query;
587
-
588
- expect(first.chatId).toBe(chat.id);
589
- expect(second.authorId).toBe(user.id);
590
-
591
- await checkCreatedResults({
592
- messageId: first.id,
593
- chatId: first.chatId,
594
- authorId: first.authorId,
595
- text: 'message 1',
596
- title: 'chat 1',
597
- name: 'user 1',
598
- });
599
-
600
- await checkCreatedResults({
601
- messageId: second.id,
602
- chatId: second.chatId,
603
- authorId: second.authorId,
604
- text: 'message 2',
605
- title: 'chat 2',
606
- name: 'user 2',
607
- });
608
- });
609
-
610
- describe('relation callbacks', () => {
611
- const { beforeCreate, afterCreate, resetMocks } = useRelationCallback(
612
- db.message.relations.chat,
613
- );
614
-
615
- const data = {
616
- ...messageData,
617
- chat: {
618
- connectOrCreate: {
619
- where: { title: 'title' },
620
- create: chatData,
621
- },
622
- },
623
- };
624
-
625
- it('should invoke callbacks', async () => {
626
- await db.message.create(data);
627
-
628
- expect(beforeCreate).toHaveBeenCalledTimes(1);
629
- expect(afterCreate).toHaveBeenCalledTimes(1);
630
- });
631
-
632
- it('should invoke callbacks in a batch create', async () => {
633
- resetMocks();
634
-
635
- await db.message.createMany([data, data]);
636
-
637
- expect(beforeCreate).toHaveBeenCalledTimes(1);
638
- expect(afterCreate).toHaveBeenCalledTimes(1);
639
- });
640
- });
641
- });
642
- });
643
-
644
- describe('update', () => {
645
- describe('disconnect', () => {
646
- it('should nullify foreignKey', async () => {
647
- const id = await db.profile
648
- .get('id')
649
- .create({ ...profileData, user: { create: userData } });
650
-
651
- const profile = await db.profile
652
- .select('userId')
653
- .find(id)
654
- .update({
655
- bio: 'string',
656
- user: { disconnect: true },
657
- });
658
-
659
- expect(profile.userId).toBe(null);
660
- });
661
-
662
- it('should nullify foreignKey in batch update', async () => {
663
- const ids = await db.profile.pluck('id').createMany([
664
- { ...profileData, user: { create: userData } },
665
- { ...profileData, user: { create: userData } },
666
- ]);
667
-
668
- const userIds = await db.profile
669
- .pluck('userId')
670
- .where({ id: { in: ids } })
671
- .update({
672
- bio: 'string',
673
- user: { disconnect: true },
674
- });
675
-
676
- expect(userIds).toEqual([null, null]);
677
- });
678
- });
679
-
680
- describe('set', () => {
681
- it('should set foreignKey of current record with provided primaryKey', async () => {
682
- const id = await db.profile.get('id').create(profileData);
683
- const user = await db.user.select('id').create(userData);
684
-
685
- const profile = await db.profile
686
- .selectAll()
687
- .find(id)
688
- .update({
689
- user: {
690
- set: user,
691
- },
692
- });
693
-
694
- expect(profile.userId).toBe(user.id);
695
- });
696
-
697
- it('should set foreignKey of current record from found related record', async () => {
698
- const id = await db.profile.get('id').create(profileData);
699
- const user = await db.user.select('id').create({
700
- ...userData,
701
- name: 'user',
702
- });
703
-
704
- const profile = await db.profile
705
- .selectAll()
706
- .find(id)
707
- .update({
708
- user: {
709
- set: { name: 'user' },
710
- },
711
- });
712
-
713
- expect(profile.userId).toBe(user.id);
714
- });
715
-
716
- it('should set foreignKey of current record with provided primaryKey in batch update', async () => {
717
- const profileIds = await db.profile
718
- .pluck('id')
719
- .createMany([profileData, profileData]);
720
- const user = await db.user.select('id').create(userData);
721
-
722
- const updatedUserIds = await db.profile
723
- .pluck('userId')
724
- .where({ id: { in: profileIds } })
725
- .update({
726
- user: {
727
- set: user,
728
- },
729
- });
730
-
731
- expect(updatedUserIds).toEqual([user.id, user.id]);
732
- });
733
-
734
- it('should set foreignKey of current record from found related record in batch update', async () => {
735
- const profileIds = await db.profile
736
- .pluck('id')
737
- .createMany([profileData, profileData]);
738
- const user = await db.user.select('id').create({
739
- ...userData,
740
- name: 'user',
741
- });
742
-
743
- const updatedUserIds = await db.profile
744
- .pluck('userId')
745
- .where({ id: { in: profileIds } })
746
- .update({
747
- user: {
748
- set: { name: 'user' },
749
- },
750
- });
751
-
752
- expect(updatedUserIds).toEqual([user.id, user.id]);
753
- });
754
- });
755
-
756
- describe('delete', () => {
757
- it('should nullify foreignKey and delete related record', async () => {
758
- const { id, userId } = await db.profile
759
- .select('id', 'userId')
760
- .create({ ...profileData, user: { create: userData } });
761
-
762
- const profile = await db.profile
763
- .select('userId')
764
- .find(id)
765
- .update({
766
- user: {
767
- delete: true,
768
- },
769
- });
770
-
771
- expect(profile.userId).toBe(null);
772
-
773
- const user = await db.user.findByOptional({ id: userId });
774
- expect(user).toBe(undefined);
775
- });
776
-
777
- it('should nullify foreignKey and delete related record in batch update', async () => {
778
- const user = await db.user.selectAll().create(userData);
779
- const profileIds = await db.profile.pluck('id').createMany([
780
- { ...profileData, userId: user.id },
781
- { ...profileData, userId: user.id },
782
- ]);
783
-
784
- const updatedUserIds = await db.profile
785
- .pluck('userId')
786
- .where({ id: { in: profileIds } })
787
- .update({
788
- user: {
789
- delete: true,
790
- },
791
- });
792
-
793
- expect(updatedUserIds).toEqual([null, null]);
794
-
795
- const deletedUser = await db.user.findOptional(user.id);
796
- expect(deletedUser).toBe(undefined);
797
- });
798
-
799
- describe('relation callbacks', () => {
800
- const { beforeDelete, afterDelete, resetMocks } = useRelationCallback(
801
- db.profile.relations.user,
802
- );
803
-
804
- const profileWithUserData = {
805
- ...profileData,
806
- user: {
807
- create: userData,
808
- },
809
- };
810
-
811
- const data = {
812
- user: {
813
- delete: true,
814
- },
815
- };
816
-
817
- it('should invoke callbacks', async () => {
818
- const id = await db.profile.get('id').create(profileWithUserData);
819
-
820
- await db.profile.find(id).update(data);
821
-
822
- expect(beforeDelete).toHaveBeenCalledTimes(1);
823
- expect(afterDelete).toHaveBeenCalledTimes(1);
824
- });
825
-
826
- it('should invoke callbacks in a batch delete', async () => {
827
- resetMocks();
828
-
829
- const ids = await db.profile
830
- .pluck('id')
831
- .createMany([profileWithUserData, profileWithUserData]);
832
-
833
- await db.profile.where({ id: { in: ids } }).update(data);
834
-
835
- expect(beforeDelete).toHaveBeenCalledTimes(1);
836
- expect(afterDelete).toHaveBeenCalledTimes(1);
837
- });
838
- });
839
- });
840
-
841
- describe('nested update', () => {
842
- it('should update related record', async () => {
843
- const { id, userId } = await db.profile
844
- .select('id', 'userId')
845
- .create({ ...profileData, user: { create: userData } });
846
-
847
- await db.profile
848
- .select('userId')
849
- .find(id)
850
- .update({
851
- user: {
852
- update: {
853
- name: 'new name',
854
- },
855
- },
856
- });
857
-
858
- const user = await db.user.findBy({ id: userId });
859
- expect(user.name).toBe('new name');
860
- });
861
-
862
- it('should update related records in batch update', async () => {
863
- const profiles = await db.profile.select('id', 'userId').createMany([
864
- { ...profileData, user: { create: userData } },
865
- { ...profileData, user: { create: userData } },
866
- ]);
867
-
868
- await db.profile
869
- .where({ id: { in: profiles.map((profile) => profile.id) } })
870
- .update({
871
- user: {
872
- update: {
873
- name: 'new name',
874
- },
875
- },
876
- });
877
-
878
- const updatedNames = await db.user.pluck('name').where({
879
- id: { in: profiles.map((profile) => profile.userId as number) },
880
- });
881
- expect(updatedNames).toEqual(['new name', 'new name']);
882
- });
883
-
884
- describe('relation callbacks', () => {
885
- const { beforeUpdate, afterUpdate, resetMocks } = useRelationCallback(
886
- db.profile.relations.user,
887
- );
888
-
889
- const profileWithUserData = {
890
- ...profileData,
891
- user: {
892
- create: userData,
893
- },
894
- };
895
-
896
- const data = {
897
- user: {
898
- update: {
899
- name: 'new name',
900
- },
901
- },
902
- };
903
-
904
- it('should invoke callbacks', async () => {
905
- const id = await db.profile.get('id').create(profileWithUserData);
906
-
907
- await db.profile.find(id).update(data);
908
-
909
- expect(beforeUpdate).toHaveBeenCalledTimes(1);
910
- expect(afterUpdate).toHaveBeenCalledTimes(1);
911
- });
912
-
913
- it('should invoke callbacks in a batch create', async () => {
914
- resetMocks();
915
-
916
- const ids = await db.profile
917
- .pluck('id')
918
- .createMany([profileWithUserData, profileWithUserData]);
919
-
920
- await db.profile.where({ id: { in: ids } }).update(data);
921
-
922
- expect(beforeUpdate).toHaveBeenCalledTimes(1);
923
- expect(afterUpdate).toHaveBeenCalledTimes(1);
924
- });
925
- });
926
- });
927
-
928
- describe('nested upsert', () => {
929
- it('should update related record if it exists', async () => {
930
- const profile = await db.profile.create({
931
- ...profileData,
932
- user: {
933
- create: userData,
934
- },
935
- });
936
-
937
- await db.profile.find(profile.id).update({
938
- user: {
939
- upsert: {
940
- update: {
941
- name: 'updated',
942
- },
943
- create: userData,
944
- },
945
- },
946
- });
947
-
948
- const user = await db.profile.user(profile);
949
- expect(user.name).toBe('updated');
950
- });
951
-
952
- it('should create related record if it does not exist', async () => {
953
- const profile = await db.profile.create(profileData);
954
-
955
- const updated = await db.profile
956
- .selectAll()
957
- .find(profile.id)
958
- .update({
959
- user: {
960
- upsert: {
961
- update: {
962
- name: 'updated',
963
- },
964
- create: {
965
- ...userData,
966
- name: 'created',
967
- },
968
- },
969
- },
970
- });
971
-
972
- const user = await db.profile.user(updated);
973
- expect(user.name).toBe('created');
974
- });
975
-
976
- it('should throw in batch update', () => {
977
- expect(() =>
978
- db.profile.where({ id: 1 }).update({
979
- user: {
980
- // @ts-expect-error not allows in batch update
981
- upsert: {
982
- update: {
983
- name: 'updated',
984
- },
985
- create: {
986
- ...userData,
987
- name: 'created',
988
- },
989
- },
990
- },
991
- }),
992
- ).toThrow();
993
- });
994
-
995
- describe('relation callbacks', () => {
996
- const {
997
- beforeUpdate,
998
- afterUpdate,
999
- beforeCreate,
1000
- afterCreate,
1001
- resetMocks,
1002
- } = useRelationCallback(db.profile.relations.user);
1003
-
1004
- const data = {
1005
- user: {
1006
- upsert: {
1007
- update: {
1008
- name: 'new name',
1009
- },
1010
- create: userData,
1011
- },
1012
- },
1013
- };
1014
-
1015
- it('should invoke update callbacks when updating', async () => {
1016
- const id = await db.profile.get('id').create({
1017
- ...profileData,
1018
- user: {
1019
- create: userData,
1020
- },
1021
- });
1022
-
1023
- resetMocks();
1024
-
1025
- await db.profile.find(id).update(data);
1026
-
1027
- expect(beforeUpdate).toHaveBeenCalledTimes(1);
1028
- expect(afterUpdate).toHaveBeenCalledTimes(1);
1029
- expect(beforeCreate).not.toBeCalled();
1030
- expect(afterCreate).not.toBeCalled();
1031
- });
1032
-
1033
- it('should invoke create callbacks when creating', async () => {
1034
- resetMocks();
1035
-
1036
- const id = await db.profile.get('id').create(profileData);
1037
-
1038
- await db.profile.find(id).update(data);
1039
-
1040
- expect(beforeUpdate).not.toBeCalled();
1041
- expect(afterUpdate).not.toBeCalled();
1042
- expect(beforeCreate).toHaveBeenCalledTimes(1);
1043
- expect(afterCreate).toHaveBeenCalledTimes(1);
1044
- });
1045
- });
1046
- });
1047
-
1048
- describe('nested create', () => {
1049
- it('should create new related record and update foreignKey', async () => {
1050
- const profileId = await db.profile
1051
- .get('id')
1052
- .create({ ...profileData, user: { create: userData } });
1053
-
1054
- const updated = await db.profile
1055
- .selectAll()
1056
- .find(profileId)
1057
- .update({
1058
- user: {
1059
- create: { ...userData, name: 'created' },
1060
- },
1061
- });
1062
-
1063
- const user = await db.profile.user(updated);
1064
- expect(user.name).toBe('created');
1065
- });
1066
-
1067
- it('should create new related record and update foreignKey in batch update', async () => {
1068
- const profileIds = await db.profile
1069
- .pluck('id')
1070
- .createMany([profileData, profileData]);
1071
-
1072
- const updatedUserIds = await db.profile
1073
- .pluck('userId')
1074
- .where({ id: { in: profileIds } })
1075
- .update({
1076
- user: {
1077
- create: { ...userData, name: 'created' },
1078
- },
1079
- });
1080
-
1081
- expect(updatedUserIds[0]).toBe(updatedUserIds[1]);
1082
-
1083
- const user = await db.user.find(updatedUserIds[0] as number);
1084
- expect(user.name).toBe('created');
1085
- });
1086
-
1087
- describe('relation callbacks', () => {
1088
- const { beforeCreate, afterCreate, resetMocks } = useRelationCallback(
1089
- db.profile.relations.user,
1090
- );
1091
-
1092
- const data = {
1093
- user: {
1094
- create: userData,
1095
- },
1096
- };
1097
-
1098
- it('should invoke callbacks', async () => {
1099
- const id = await db.profile.get('id').create(profileData);
1100
-
1101
- await db.profile.find(id).update(data);
1102
-
1103
- expect(beforeCreate).toHaveBeenCalledTimes(1);
1104
- expect(afterCreate).toHaveBeenCalledTimes(1);
1105
- });
1106
-
1107
- it('should invoke callbacks in a batch update', async () => {
1108
- const ids = await db.profile
1109
- .pluck('id')
1110
- .createMany([profileData, profileData]);
1111
-
1112
- resetMocks();
1113
-
1114
- await db.profile.where({ id: { in: ids } }).update(data);
1115
-
1116
- expect(beforeCreate).toHaveBeenCalledTimes(1);
1117
- expect(afterCreate).toHaveBeenCalledTimes(1);
1118
- });
1119
- });
1120
- });
1121
- });
1122
- });