Commit | Line | Data |
33dd4e80 |
1 | use strict; |
af2d42c0 |
2 | use warnings; |
33dd4e80 |
3 | |
04ec3909 |
4 | use Test::More; |
fe8cee09 |
5 | use Test::Exception; |
33dd4e80 |
6 | use lib qw(t/lib); |
7 | use DBICTest; |
8 | |
ab4b097b |
9 | plan tests => 72; |
04ec3909 |
10 | |
33dd4e80 |
11 | my $schema = DBICTest->init_schema(); |
12 | |
c45f4e10 |
13 | # simple create + parent (the stuff $rs belongs_to) |
04ec3909 |
14 | eval { |
c45f4e10 |
15 | my $cd = $schema->resultset('CD')->create({ |
04ec3909 |
16 | artist => { |
17 | name => 'Fred Bloggs' |
18 | }, |
19 | title => 'Some CD', |
20 | year => 1996 |
21 | }); |
22 | |
c45f4e10 |
23 | isa_ok($cd, 'DBICTest::CD', 'Created CD object'); |
24 | isa_ok($cd->artist, 'DBICTest::Artist', 'Created related Artist'); |
25 | is($cd->artist->name, 'Fred Bloggs', 'Artist created correctly'); |
26 | }; |
27 | diag $@ if $@; |
28 | |
ab4b097b |
29 | # same as above but the child and parent have no values, |
c45f4e10 |
30 | # except for an explicit parent pk |
31 | eval { |
32 | my $bm_rs = $schema->resultset('Bookmark'); |
33 | my $bookmark = $bm_rs->create({ |
34 | link => { |
35 | id => 66, |
36 | }, |
37 | }); |
38 | |
39 | isa_ok($bookmark, 'DBICTest::Bookmark', 'Created Bookrmark object'); |
40 | isa_ok($bookmark->link, 'DBICTest::Link', 'Created related Link'); |
41 | is ( |
42 | $bm_rs->search ( |
43 | { 'link.title' => $bookmark->link->title }, |
44 | { join => 'link' }, |
45 | )->count, |
46 | 1, |
47 | 'Bookmark and link made it to the DB', |
48 | ); |
04ec3909 |
49 | }; |
50 | diag $@ if $@; |
51 | |
52 | # create over > 1 levels of has_many create (A => { has_many => { B => has_many => C } } ) |
53 | eval { |
ab4b097b |
54 | my $artist = $schema->resultset('Artist')->first; |
55 | my $cd = $artist->create_related (cds => { |
56 | title => 'Music to code by', |
57 | year => 2007, |
58 | tags => [ |
59 | { 'tag' => 'rock' }, |
60 | ], |
61 | }); |
04ec3909 |
62 | |
ab4b097b |
63 | isa_ok($cd, 'DBICTest::CD', 'Created CD'); |
64 | is($cd->title, 'Music to code by', 'CD created correctly'); |
65 | is($cd->tags->count, 1, 'One tag created for CD'); |
66 | is($cd->tags->first->tag, 'rock', 'Tag created correctly'); |
04ec3909 |
67 | |
04ec3909 |
68 | }; |
69 | diag $@ if $@; |
70 | |
fe8cee09 |
71 | throws_ok ( |
72 | sub { |
73 | # Create via update - add a new CD <--- THIS SHOULD HAVE NEVER WORKED! |
74 | $schema->resultset('Artist')->first->update({ |
75 | cds => [ |
76 | { title => 'Yet another CD', |
77 | year => 2006, |
78 | }, |
79 | ], |
80 | }); |
81 | }, |
82 | qr/Recursive update is not supported over relationships of type multi/, |
83 | 'create via update of multi relationships throws an exception' |
84 | ); |
85 | |
ab4b097b |
86 | # Create m2m while originating in the linker table |
87 | eval { |
88 | my $artist = $schema->resultset('Artist')->first; |
89 | my $c2p = $schema->resultset('CD_to_Producer')->create ({ |
90 | cd => { |
91 | artist => $artist, |
92 | title => 'Bad investment', |
93 | year => 2008, |
94 | tracks => [ |
95 | { position => 1, title => 'Just buy' }, |
96 | { position => 2, title => 'Why did we do it' }, |
97 | { position => 3, title => 'Burn baby burn' }, |
98 | ], |
99 | }, |
100 | producer => { |
101 | name => 'Lehman Bros.', |
102 | }, |
103 | }); |
104 | |
105 | isa_ok ($c2p, 'DBICTest::CD_to_Producer', 'Linker object created'); |
106 | my $prod = $schema->resultset ('Producer')->find ({ name => 'Lehman Bros.' }); |
107 | isa_ok ($prod, 'DBICTest::Producer', 'Producer row found'); |
108 | is ($prod->cds->count, 1, 'Producer has one production'); |
109 | my $cd = $prod->cds->first; |
110 | is ($cd->title, 'Bad investment', 'CD created correctly'); |
111 | is ($cd->tracks->count, 3, 'CD has 3 tracks'); |
112 | |
113 | }; |
114 | diag $@ if $@; |
115 | |
51f30f72 |
116 | # create over > 1 levels of might_have (A => { might_have => { B => has_many => C } } ) |
117 | eval { |
118 | my $artist = $schema->resultset('Artist')->first; |
119 | my $cd = $schema->resultset('CD')->create ({ |
120 | artist => $artist, |
121 | title => 'Music to code by at night', |
122 | year => 2008, |
123 | tracks => [ |
124 | { |
125 | position => 1, |
126 | title => 'Off by one again', |
127 | }, |
128 | { |
129 | position => 2, |
130 | title => 'The dereferencer', |
131 | cd_single => { |
132 | artist => $artist, |
133 | year => 2008, |
134 | title => 'Was that a null (Single)', |
135 | tracks => [ |
136 | { title => 'The dereferencer', position => 1 }, |
137 | { title => 'The dereferencer II', position => 2 }, |
138 | ], |
139 | cd_to_producer => [ |
140 | { |
141 | producer => { |
142 | name => 'K&R', |
143 | } |
144 | } |
145 | ] |
146 | }, |
147 | }, |
148 | ], |
149 | }); |
150 | |
151 | isa_ok ($cd, 'DBICTest::CD', 'Main CD object created'); |
152 | is ($cd->title, 'Music to code by at night', 'Correct CD title'); |
153 | is ($cd->tracks->count, 2, 'Two tracks on main CD'); |
154 | |
155 | my ($t1, $t2) = $cd->tracks->all; |
156 | is ($t1->title, 'Off by one again', 'Correct 1st track name'); |
157 | is ($t1->cd_single, undef, 'No single for 1st track'); |
158 | is ($t2->title, 'The dereferencer', 'Correct 2nd track name'); |
159 | isa_ok ($t2->cd_single, 'DBICTest::CD', 'Created a single for 2nd track'); |
160 | |
161 | my $single = $t2->cd_single; |
162 | is ($single->tracks->count, 2, 'Two tracks on single CD'); |
163 | is ($single->tracks->find ({ position => 1})->title, 'The dereferencer', 'Correct 1st track title'); |
164 | is ($single->tracks->find ({ position => 2})->title, 'The dereferencer II', 'Correct 2nd track title'); |
165 | |
166 | is ($single->cd_to_producer->count, 1, 'One producer created with the single cd'); |
167 | is ($single->cd_to_producer->first->producer->name, 'K&R', 'Producer name correct'); |
168 | }; |
169 | diag $@ if $@; |
170 | |
04ec3909 |
171 | # nested find_or_create |
172 | eval { |
173 | my $newartist2 = $schema->resultset('Artist')->find_or_create({ |
174 | name => 'Fred 3', |
175 | cds => [ |
176 | { |
177 | title => 'Noah Act', |
178 | year => 2007, |
179 | }, |
180 | ], |
181 | }); |
182 | is($newartist2->name, 'Fred 3', 'Created new artist with cds via find_or_create'); |
183 | }; |
184 | diag $@ if $@; |
185 | |
186 | # multiple same level has_many create |
187 | eval { |
188 | my $artist2 = $schema->resultset('Artist')->create({ |
51f30f72 |
189 | name => 'Fred 4', |
04ec3909 |
190 | cds => [ |
191 | { |
192 | title => 'Music to code by', |
193 | year => 2007, |
194 | }, |
195 | ], |
196 | cds_unordered => [ |
197 | { |
198 | title => 'Music to code by', |
199 | year => 2007, |
200 | }, |
201 | ] |
202 | }); |
203 | |
204 | is($artist2->in_storage, 1, 'artist with duplicate rels inserted okay'); |
205 | }; |
206 | diag $@ if $@; |
3d8ee6ab |
207 | |
04ec3909 |
208 | # first create_related pass |
209 | eval { |
3d8ee6ab |
210 | my $artist = $schema->resultset('Artist')->first; |
211 | |
212 | my $cd_result = $artist->create_related('cds', { |
213 | |
214 | title => 'TestOneCD1', |
215 | year => 2007, |
216 | tracks => [ |
217 | |
218 | { position=>111, |
219 | title => 'TrackOne', |
220 | }, |
221 | { position=>112, |
222 | title => 'TrackTwo', |
223 | } |
224 | ], |
225 | |
226 | }); |
227 | |
228 | ok( $cd_result && ref $cd_result eq 'DBICTest::CD', "Got Good CD Class"); |
229 | ok( $cd_result->title eq "TestOneCD1", "Got Expected Title"); |
230 | |
231 | my $tracks = $cd_result->tracks; |
232 | |
233 | ok( ref $tracks eq "DBIx::Class::ResultSet", "Got Expected Tracks ResultSet"); |
234 | |
235 | foreach my $track ($tracks->all) |
236 | { |
237 | ok( $track && ref $track eq 'DBICTest::Track', 'Got Expected Track Class'); |
238 | } |
04ec3909 |
239 | }; |
240 | diag $@ if $@; |
3d8ee6ab |
241 | |
04ec3909 |
242 | # second create_related with same arguments |
243 | eval { |
2ec8e594 |
244 | my $artist = $schema->resultset('Artist')->first; |
3d8ee6ab |
245 | |
2ec8e594 |
246 | my $cd_result = $artist->create_related('cds', { |
3d8ee6ab |
247 | |
2ec8e594 |
248 | title => 'TestOneCD2', |
3d8ee6ab |
249 | year => 2007, |
250 | tracks => [ |
251 | |
252 | { position=>111, |
253 | title => 'TrackOne', |
254 | }, |
255 | { position=>112, |
256 | title => 'TrackTwo', |
257 | } |
258 | ], |
259 | |
9c6d6d93 |
260 | liner_notes => { notes => 'I can haz liner notes?' }, |
261 | |
3d8ee6ab |
262 | }); |
263 | |
264 | ok( $cd_result && ref $cd_result eq 'DBICTest::CD', "Got Good CD Class"); |
2ec8e594 |
265 | ok( $cd_result->title eq "TestOneCD2", "Got Expected Title"); |
9c6d6d93 |
266 | ok( $cd_result->notes eq 'I can haz liner notes?', 'Liner notes'); |
3d8ee6ab |
267 | |
268 | my $tracks = $cd_result->tracks; |
269 | |
270 | ok( ref $tracks eq "DBIx::Class::ResultSet", "Got Expected Tracks ResultSet"); |
271 | |
272 | foreach my $track ($tracks->all) |
273 | { |
274 | ok( $track && ref $track eq 'DBICTest::Track', 'Got Expected Track Class'); |
275 | } |
04ec3909 |
276 | }; |
277 | diag $@ if $@; |
e5dddc05 |
278 | |
04ec3909 |
279 | # create of parents of a record linker table |
280 | eval { |
281 | my $cdp = $schema->resultset('CD_to_Producer')->create({ |
282 | cd => { artist => 1, title => 'foo', year => 2000 }, |
283 | producer => { name => 'jorge' } |
284 | }); |
285 | ok($cdp, 'join table record created ok'); |
286 | }; |
287 | diag $@ if $@; |
2bc3c81e |
288 | |
04ec3909 |
289 | #SPECIAL_CASE |
290 | eval { |
2bc3c81e |
291 | my $kurt_cobain = { name => 'Kurt Cobain' }; |
292 | |
293 | my $in_utero = $schema->resultset('CD')->new({ |
294 | title => 'In Utero', |
295 | year => 1993 |
296 | }); |
297 | |
298 | $kurt_cobain->{cds} = [ $in_utero ]; |
299 | |
300 | |
301 | $schema->resultset('Artist')->populate([ $kurt_cobain ]); # %) |
302 | $a = $schema->resultset('Artist')->find({name => 'Kurt Cobain'}); |
303 | |
304 | is($a->name, 'Kurt Cobain', 'Artist insertion ok'); |
305 | is($a->cds && $a->cds->first && $a->cds->first->title, |
306 | 'In Utero', 'CD insertion ok'); |
04ec3909 |
307 | }; |
308 | diag $@ if $@; |
2bc3c81e |
309 | |
04ec3909 |
310 | #SPECIAL_CASE2 |
311 | eval { |
2bc3c81e |
312 | my $pink_floyd = { name => 'Pink Floyd' }; |
313 | |
314 | my $the_wall = { title => 'The Wall', year => 1979 }; |
315 | |
316 | $pink_floyd->{cds} = [ $the_wall ]; |
317 | |
318 | |
319 | $schema->resultset('Artist')->populate([ $pink_floyd ]); # %) |
320 | $a = $schema->resultset('Artist')->find({name => 'Pink Floyd'}); |
321 | |
322 | is($a->name, 'Pink Floyd', 'Artist insertion ok'); |
323 | is($a->cds && $a->cds->first->title, 'The Wall', 'CD insertion ok'); |
04ec3909 |
324 | }; |
325 | diag $@ if $@; |
e02b9964 |
326 | |
327 | ## Create foreign key col obj including PK |
328 | ## See test 20 in 66relationships.t |
04ec3909 |
329 | eval { |
330 | my $new_cd_hashref = { |
331 | cdid => 27, |
332 | title => 'Boogie Woogie', |
333 | year => '2007', |
334 | artist => { artistid => 17, name => 'king luke' } |
335 | }; |
e02b9964 |
336 | |
04ec3909 |
337 | my $cd = $schema->resultset("CD")->find(1); |
f10ac17d |
338 | |
04ec3909 |
339 | is($cd->artist->id, 1, 'rel okay'); |
f10ac17d |
340 | |
04ec3909 |
341 | my $new_cd = $schema->resultset("CD")->create($new_cd_hashref); |
342 | is($new_cd->artist->id, 17, 'new id retained okay'); |
343 | }; |
344 | diag $@ if $@; |
6ede9177 |
345 | |
346 | eval { |
347 | $schema->resultset("CD")->create({ |
38c03c20 |
348 | cdid => 28, |
370f2ba2 |
349 | title => 'Boogie Wiggle', |
38c03c20 |
350 | year => '2007', |
351 | artist => { artistid => 18, name => 'larry' } |
6ede9177 |
352 | }); |
38c03c20 |
353 | }; |
6ede9177 |
354 | is($@, '', 'new cd created without clash on related artist'); |
38c03c20 |
355 | |
f10ac17d |
356 | # Make sure exceptions from errors in created rels propogate |
357 | eval { |
370f2ba2 |
358 | my $t = $schema->resultset("Track")->new({ cd => { artist => undef } }); |
359 | #$t->cd($t->new_related('cd', { artist => undef } ) ); |
360 | #$t->{_rel_in_storage} = 0; |
f10ac17d |
361 | $t->insert; |
362 | }; |
363 | like($@, qr/cd.artist may not be NULL/, "Exception propogated properly"); |
bbbf67eb |
364 | |
365 | # Test multi create over many_to_many |
04ec3909 |
366 | eval { |
367 | $schema->resultset('CD')->create ({ |
368 | artist => { |
369 | name => 'larry', # should already exist |
370 | }, |
76b8cf98 |
371 | title => 'Warble Marble', |
372 | year => '2009', |
373 | cd_to_producer => [ |
04ec3909 |
374 | { producer => { name => 'Cowboy Neal' } }, |
76b8cf98 |
375 | ], |
04ec3909 |
376 | }); |
76b8cf98 |
377 | |
04ec3909 |
378 | my $m2m_cd = $schema->resultset('CD')->search ({ title => 'Warble Marble'}); |
379 | is ($m2m_cd->count, 1, 'One CD row created via M2M create'); |
380 | is ($m2m_cd->first->producers->count, 1, 'CD row created with one producer'); |
381 | is ($m2m_cd->first->producers->first->name, 'Cowboy Neal', 'Correct producer row created'); |
382 | }; |
76b8cf98 |
383 | |
384 | # and some insane multicreate |
385 | # (should work, despite the fact that no one will probably use it this way) |
386 | |
04ec3909 |
387 | # first count how many rows do we initially have |
76b8cf98 |
388 | my $counts; |
04ec3909 |
389 | $counts->{$_} = $schema->resultset($_)->count for qw/Artist CD Genre Producer Tag/; |
76b8cf98 |
390 | |
391 | # do the crazy create |
04ec3909 |
392 | eval { |
393 | $schema->resultset('CD')->create ({ |
394 | artist => { |
533292a0 |
395 | name => 'james', |
04ec3909 |
396 | }, |
76b8cf98 |
397 | title => 'Greatest hits 1', |
398 | year => '2012', |
399 | genre => { |
400 | name => '"Greatest" collections', |
401 | }, |
04ec3909 |
402 | tags => [ |
403 | { tag => 'A' }, |
404 | { tag => 'B' }, |
405 | ], |
76b8cf98 |
406 | cd_to_producer => [ |
407 | { |
408 | producer => { |
533292a0 |
409 | name => 'bob', |
76b8cf98 |
410 | producer_to_cd => [ |
411 | { |
412 | cd => { |
413 | artist => { |
533292a0 |
414 | name => 'lars', |
04ec3909 |
415 | cds => [ |
416 | { |
533292a0 |
417 | title => 'Greatest hits 2', |
04ec3909 |
418 | year => 2012, |
419 | genre => { |
420 | name => '"Greatest" collections', |
421 | }, |
422 | tags => [ |
423 | { tag => 'A' }, |
424 | { tag => 'B' }, |
425 | ], |
533292a0 |
426 | # This cd is created via artist so it doesn't know about producers |
427 | cd_to_producer => [ |
428 | # if we specify 'bob' here things bomb |
429 | # as the producer attached to Greatest Hits 1 is |
430 | # already created, but not yet inserted. |
431 | # Maybe this can be fixed, but things are hairy |
432 | # enough already. |
433 | # |
434 | #{ producer => { name => 'bob' } }, |
435 | { producer => { name => 'paul' } }, |
436 | { producer => { |
437 | name => 'flemming', |
438 | producer_to_cd => [ |
439 | { cd => { |
440 | artist => { |
441 | name => 'kirk', |
442 | cds => [ |
443 | { |
444 | title => 'Greatest hits 3', |
445 | year => 2012, |
446 | genre => { |
447 | name => '"Greatest" collections', |
448 | }, |
449 | tags => [ |
450 | { tag => 'A' }, |
451 | { tag => 'B' }, |
452 | ], |
453 | }, |
454 | { |
455 | title => 'Greatest hits 4', |
456 | year => 2012, |
457 | genre => { |
458 | name => '"Greatest" collections2', |
459 | }, |
460 | tags => [ |
461 | { tag => 'A' }, |
462 | { tag => 'B' }, |
463 | ], |
464 | }, |
465 | ], |
466 | }, |
467 | title => 'Greatest hits 5', |
468 | year => 2013, |
469 | genre => { |
470 | name => '"Greatest" collections2', |
471 | }, |
472 | }}, |
473 | ], |
474 | }}, |
475 | ], |
04ec3909 |
476 | }, |
477 | ], |
76b8cf98 |
478 | }, |
533292a0 |
479 | title => 'Greatest hits 6', |
76b8cf98 |
480 | year => 2012, |
481 | genre => { |
482 | name => '"Greatest" collections', |
483 | }, |
04ec3909 |
484 | tags => [ |
485 | { tag => 'A' }, |
486 | { tag => 'B' }, |
487 | ], |
76b8cf98 |
488 | }, |
489 | }, |
490 | { |
491 | cd => { |
492 | artist => { |
533292a0 |
493 | name => 'lars', # should already exist |
494 | # even though the artist 'name' is not uniquely constrained |
495 | # find_or_create will arguably DWIM |
76b8cf98 |
496 | }, |
533292a0 |
497 | title => 'Greatest hits 7', |
498 | year => 2013, |
76b8cf98 |
499 | }, |
500 | }, |
501 | ], |
502 | }, |
503 | }, |
504 | ], |
04ec3909 |
505 | }); |
76b8cf98 |
506 | |
533292a0 |
507 | is ($schema->resultset ('Artist')->count, $counts->{Artist} + 3, '3 new artists created'); |
508 | is ($schema->resultset ('Genre')->count, $counts->{Genre} + 2, '2 additional genres created'); |
509 | is ($schema->resultset ('Producer')->count, $counts->{Producer} + 3, '3 new producer'); |
510 | is ($schema->resultset ('CD')->count, $counts->{CD} + 7, '7 new CDs'); |
511 | is ($schema->resultset ('Tag')->count, $counts->{Tag} + 10, '10 new Tags'); |
512 | |
513 | my $cd_rs = $schema->resultset ('CD') |
514 | ->search ({ title => { -like => 'Greatest hits %' }}, { order_by => 'title'} ); |
515 | is ($cd_rs->count, 7, '7 greatest hits created'); |
516 | |
517 | my $cds_2012 = $cd_rs->search ({ year => 2012}); |
518 | is ($cds_2012->count, 5, '5 CDs created in 2012'); |
519 | |
520 | is ( |
521 | $cds_2012->search( |
522 | { 'tags.tag' => { -in => [qw/A B/] } }, |
523 | { join => 'tags', group_by => 'me.cdid' } |
524 | ), |
525 | 5, |
c45f4e10 |
526 | 'All 10 tags were pairwise distributed between 5 year-2012 CDs' |
533292a0 |
527 | ); |
528 | |
529 | my $paul_prod = $cd_rs->search ( |
530 | { 'producer.name' => 'paul'}, |
531 | { join => { cd_to_producer => 'producer' } } |
532 | ); |
533 | is ($paul_prod->count, 1, 'Paul had 1 production'); |
534 | my $pauls_cd = $paul_prod->single; |
535 | is ($pauls_cd->cd_to_producer->count, 2, 'Paul had one co-producer'); |
536 | is ( |
537 | $pauls_cd->search_related ('cd_to_producer', |
538 | { 'producer.name' => 'flemming'}, |
539 | { join => 'producer' } |
540 | )->count, |
541 | 1, |
542 | 'The second producer is flemming', |
543 | ); |
544 | |
545 | my $kirk_cds = $cd_rs->search ({ 'artist.name' => 'kirk' }, { join => 'artist' }); |
546 | is ($kirk_cds, 3, 'Kirk had 3 CDs'); |
547 | is ( |
548 | $kirk_cds->search ( |
549 | { 'cd_to_producer.cd' => { '!=', undef } }, |
550 | { join => 'cd_to_producer' }, |
551 | ), |
552 | 1, |
553 | 'Kirk had a producer only on one cd', |
554 | ); |
555 | |
556 | my $lars_cds = $cd_rs->search ({ 'artist.name' => 'lars' }, { join => 'artist' }); |
557 | is ($lars_cds->count, 3, 'Lars had 3 CDs'); |
558 | is ( |
559 | $lars_cds->search ( |
560 | { 'cd_to_producer.cd' => undef }, |
561 | { join => 'cd_to_producer' }, |
562 | ), |
563 | 0, |
564 | 'Lars always had a producer', |
565 | ); |
566 | is ( |
567 | $lars_cds->search_related ('cd_to_producer', |
568 | { 'producer.name' => 'flemming'}, |
569 | { join => 'producer' } |
570 | )->count, |
571 | 1, |
572 | 'Lars produced 1 CD with flemming', |
573 | ); |
574 | is ( |
575 | $lars_cds->search_related ('cd_to_producer', |
576 | { 'producer.name' => 'bob'}, |
577 | { join => 'producer' } |
578 | )->count, |
579 | 2, |
580 | 'Lars produced 2 CDs with bob', |
581 | ); |
582 | |
583 | my $bob_prod = $cd_rs->search ( |
584 | { 'producer.name' => 'bob'}, |
585 | { join => { cd_to_producer => 'producer' } } |
586 | ); |
587 | is ($bob_prod->count, 3, 'Bob produced a total of 3 CDs'); |
588 | |
589 | is ( |
590 | $bob_prod->search ({ 'artist.name' => 'james' }, { join => 'artist' })->count, |
591 | 1, |
c45f4e10 |
592 | "Bob produced james' only CD", |
533292a0 |
593 | ); |
04ec3909 |
594 | }; |
595 | diag $@ if $@; |
ab4b097b |
596 | |
597 | 1; |