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