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