orchid-orm 1.5.28 → 1.5.30

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 (57) hide show
  1. package/dist/index.js +10 -10
  2. package/dist/index.js.map +1 -1
  3. package/dist/index.mjs +10 -10
  4. package/dist/index.mjs.map +1 -1
  5. package/package.json +13 -22
  6. package/.env.example +0 -1
  7. package/.turbo/turbo-test.log +0 -26
  8. package/.turbo/turbo-test:ci.log +0 -26
  9. package/CHANGELOG.md +0 -375
  10. package/coverage/coverage-summary.json +0 -28
  11. package/jest-setup.ts +0 -11
  12. package/rollup.config.js +0 -18
  13. package/src/bin/bin.ts +0 -3
  14. package/src/bin/init.test.ts +0 -810
  15. package/src/bin/init.ts +0 -529
  16. package/src/codegen/appCodeUpdater.test.ts +0 -75
  17. package/src/codegen/appCodeUpdater.ts +0 -53
  18. package/src/codegen/createBaseTableFile.test.ts +0 -53
  19. package/src/codegen/createBaseTableFile.ts +0 -31
  20. package/src/codegen/fileChanges.ts +0 -41
  21. package/src/codegen/testUtils.ts +0 -56
  22. package/src/codegen/tsUtils.ts +0 -180
  23. package/src/codegen/updateMainFile.test.ts +0 -253
  24. package/src/codegen/updateMainFile.ts +0 -210
  25. package/src/codegen/updateTableFile/changeTable.test.ts +0 -804
  26. package/src/codegen/updateTableFile/changeTable.ts +0 -536
  27. package/src/codegen/updateTableFile/createTable.test.ts +0 -139
  28. package/src/codegen/updateTableFile/createTable.ts +0 -51
  29. package/src/codegen/updateTableFile/renameTable.test.ts +0 -124
  30. package/src/codegen/updateTableFile/renameTable.ts +0 -67
  31. package/src/codegen/updateTableFile/updateTableFile.ts +0 -22
  32. package/src/codegen/utils.ts +0 -13
  33. package/src/index.ts +0 -5
  34. package/src/orm.test.ts +0 -92
  35. package/src/orm.ts +0 -98
  36. package/src/relations/belongsTo.test.ts +0 -1122
  37. package/src/relations/belongsTo.ts +0 -352
  38. package/src/relations/hasAndBelongsToMany.test.ts +0 -1335
  39. package/src/relations/hasAndBelongsToMany.ts +0 -472
  40. package/src/relations/hasMany.test.ts +0 -2616
  41. package/src/relations/hasMany.ts +0 -401
  42. package/src/relations/hasOne.test.ts +0 -1701
  43. package/src/relations/hasOne.ts +0 -351
  44. package/src/relations/relations.test.ts +0 -37
  45. package/src/relations/relations.ts +0 -363
  46. package/src/relations/utils.ts +0 -162
  47. package/src/repo.test.ts +0 -200
  48. package/src/repo.ts +0 -119
  49. package/src/table.test.ts +0 -121
  50. package/src/table.ts +0 -184
  51. package/src/test-utils/test-db.ts +0 -32
  52. package/src/test-utils/test-tables.ts +0 -194
  53. package/src/test-utils/test-utils.ts +0 -119
  54. package/src/transaction.test.ts +0 -47
  55. package/src/transaction.ts +0 -27
  56. package/src/utils.ts +0 -9
  57. 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
- });