Commit | Line | Data |
70350518 |
1 | use strict; |
246fa39d |
2 | use warnings; |
70350518 |
3 | |
4 | use Test::More; |
034d0be4 |
5 | use Test::Exception; |
e29e2b27 |
6 | use Test::Warn; |
70350518 |
7 | use lib qw(t/lib); |
8 | use DBICTest; |
9 | |
a47e1233 |
10 | my $schema = DBICTest->init_schema(); |
87f0da6a |
11 | |
365d06b7 |
12 | # Check the defined unique constraints |
13 | is_deeply( |
14 | [ sort $schema->source('CD')->unique_constraint_names ], |
15 | [ qw/cd_artist_title primary/ ], |
16 | 'CD source has an automatically named unique constraint' |
17 | ); |
18 | is_deeply( |
19 | [ sort $schema->source('Producer')->unique_constraint_names ], |
20 | [ qw/primary prod_name/ ], |
21 | 'Producer source has a named unique constraint' |
22 | ); |
23 | is_deeply( |
24 | [ sort $schema->source('Track')->unique_constraint_names ], |
25 | [ qw/primary track_cd_position track_cd_title/ ], |
26 | 'Track source has three unique constraints' |
27 | ); |
034d0be4 |
28 | is_deeply( |
29 | [ sort $schema->source('Tag')->unique_constraint_names ], |
30 | [ qw/primary tagid_cd tagid_cd_tag tags_tagid_tag tags_tagid_tag_cd/ ], |
31 | 'Tag source has five unique constraints (from add_unique_constraings)' |
32 | ); |
87f0da6a |
33 | |
34 | my $artistid = 1; |
35 | my $title = 'UNIQUE Constraint'; |
36 | |
37 | my $cd1 = $schema->resultset('CD')->find_or_create({ |
38 | artist => $artistid, |
39 | title => $title, |
40 | year => 2005, |
41 | }); |
42 | |
43 | my $cd2 = $schema->resultset('CD')->find( |
44 | { |
45 | artist => $artistid, |
46 | title => $title, |
47 | }, |
368a5228 |
48 | { key => 'cd_artist_title' } |
87f0da6a |
49 | ); |
50 | |
51 | is($cd2->get_column('artist'), $cd1->get_column('artist'), 'find by specific key: artist is correct'); |
52 | is($cd2->title, $cd1->title, 'title is correct'); |
53 | is($cd2->year, $cd1->year, 'year is correct'); |
54 | |
368a5228 |
55 | my $cd3 = $schema->resultset('CD')->find($artistid, $title, { key => 'cd_artist_title' }); |
c9bb4b2f |
56 | |
57 | is($cd3->get_column('artist'), $cd1->get_column('artist'), 'find by specific key, ordered columns: artist is correct'); |
58 | is($cd3->title, $cd1->title, 'title is correct'); |
59 | is($cd3->year, $cd1->year, 'year is correct'); |
60 | |
61 | my $cd4 = $schema->resultset('CD')->update_or_create( |
87f0da6a |
62 | { |
63 | artist => $artistid, |
64 | title => $title, |
65 | year => 2007, |
66 | }, |
67 | ); |
68 | |
c9bb4b2f |
69 | ok(! $cd4->is_changed, 'update_or_create without key: row is clean'); |
70 | is($cd4->cdid, $cd2->cdid, 'cdid is correct'); |
71 | is($cd4->get_column('artist'), $cd2->get_column('artist'), 'artist is correct'); |
72 | is($cd4->title, $cd2->title, 'title is correct'); |
73 | is($cd4->year, 2007, 'updated year is correct'); |
87f0da6a |
74 | |
c9bb4b2f |
75 | my $cd5 = $schema->resultset('CD')->update_or_create( |
87f0da6a |
76 | { |
77 | artist => $artistid, |
78 | title => $title, |
79 | year => 2007, |
80 | }, |
368a5228 |
81 | { key => 'cd_artist_title' } |
87f0da6a |
82 | ); |
83 | |
c9bb4b2f |
84 | ok(! $cd5->is_changed, 'update_or_create by specific key: row is clean'); |
85 | is($cd5->cdid, $cd2->cdid, 'cdid is correct'); |
86 | is($cd5->get_column('artist'), $cd2->get_column('artist'), 'artist is correct'); |
87 | is($cd5->title, $cd2->title, 'title is correct'); |
88 | is($cd5->year, 2007, 'updated year is correct'); |
87f0da6a |
89 | |
c9bb4b2f |
90 | my $cd6 = $schema->resultset('CD')->update_or_create( |
87f0da6a |
91 | { |
92 | cdid => $cd2->cdid, |
93 | artist => 1, |
94 | title => $cd2->title, |
95 | year => 2005, |
96 | }, |
97 | { key => 'primary' } |
98 | ); |
99 | |
c9bb4b2f |
100 | ok(! $cd6->is_changed, 'update_or_create by PK: row is clean'); |
101 | is($cd6->cdid, $cd2->cdid, 'cdid is correct'); |
102 | is($cd6->get_column('artist'), $cd2->get_column('artist'), 'artist is correct'); |
103 | is($cd6->title, $cd2->title, 'title is correct'); |
104 | is($cd6->year, 2005, 'updated year is correct'); |
87f0da6a |
105 | |
c9bb4b2f |
106 | my $cd7 = $schema->resultset('CD')->find_or_create( |
8dc40f3e |
107 | { |
108 | artist => $artistid, |
109 | title => $title, |
110 | year => 2010, |
111 | }, |
368a5228 |
112 | { key => 'cd_artist_title' } |
8dc40f3e |
113 | ); |
114 | |
c9bb4b2f |
115 | is($cd7->cdid, $cd1->cdid, 'find_or_create by specific key: cdid is correct'); |
116 | is($cd7->get_column('artist'), $cd1->get_column('artist'), 'artist is correct'); |
117 | is($cd7->title, $cd1->title, 'title is correct'); |
118 | is($cd7->year, $cd1->year, 'year is correct'); |
8dc40f3e |
119 | |
120 | my $artist = $schema->resultset('Artist')->find($artistid); |
c9bb4b2f |
121 | my $cd8 = $artist->find_or_create_related('cds', |
8dc40f3e |
122 | { |
8dc40f3e |
123 | title => $title, |
124 | year => 2020, |
125 | }, |
368a5228 |
126 | { key => 'cd_artist_title' } |
8dc40f3e |
127 | ); |
128 | |
c9bb4b2f |
129 | is($cd8->cdid, $cd1->cdid, 'find_or_create related by specific key: cdid is correct'); |
130 | is($cd8->get_column('artist'), $cd1->get_column('artist'), 'artist is correct'); |
131 | is($cd8->title, $cd1->title, 'title is correct'); |
132 | is($cd8->year, $cd1->year, 'year is correct'); |
8dc40f3e |
133 | |
b7743dab |
134 | # Add an extra row to potentially confuse the query |
135 | $schema->resultset('CD')->create ({ |
136 | artist => 2, |
137 | title => $title, |
138 | year => 2022, |
139 | }); |
d180c0f3 |
140 | my $cd9 = $artist->cds->update_or_create( |
045120e6 |
141 | { |
d180c0f3 |
142 | cdid => $cd1->cdid, |
045120e6 |
143 | title => $title, |
144 | year => 2021, |
145 | }, |
368a5228 |
146 | { key => 'cd_artist_title' } |
045120e6 |
147 | ); |
148 | |
c9bb4b2f |
149 | ok(! $cd9->is_changed, 'update_or_create by specific key: row is clean'); |
150 | is($cd9->cdid, $cd1->cdid, 'cdid is correct'); |
151 | is($cd9->get_column('artist'), $cd1->get_column('artist'), 'artist is correct'); |
152 | is($cd9->title, $cd1->title, 'title is correct'); |
153 | is($cd9->year, 2021, 'year is correct'); |
045120e6 |
154 | |
dcfb635f |
155 | # Table with two unique constraints, and we're satisying one of them |
365d06b7 |
156 | my $track = $schema->resultset('Track')->find( |
157 | { |
158 | cd => 1, |
159 | position => 3, |
160 | }, |
161 | { order_by => 'position' } |
162 | ); |
163 | |
164 | is($track->get_column('cd'), 1, 'track cd is correct'); |
165 | is($track->get_column('position'), 3, 'track position is correct'); |
89034887 |
166 | |
167 | # Test a table with a unique constraint but no primary key |
168 | my $row = $schema->resultset('NoPrimaryKey')->update_or_create( |
169 | { |
170 | foo => 1, |
171 | bar => 2, |
172 | baz => 3, |
173 | }, |
174 | { key => 'foo_bar' } |
175 | ); |
d180c0f3 |
176 | |
8070a151 |
177 | ok(! $row->is_changed, 'update_or_create on table without primary key: row is clean'); |
89034887 |
178 | is($row->foo, 1, 'foo is correct'); |
179 | is($row->bar, 2, 'bar is correct'); |
180 | is($row->baz, 3, 'baz is correct'); |
d180c0f3 |
181 | |
182 | # Test a unique condition with extra information in the where attr |
183 | { |
184 | my $artist = $schema->resultset('Artist')->find({ artistid => 1 }); |
185 | my $cd = $artist->cds->find_or_new( |
186 | { |
187 | cdid => 1, |
188 | title => 'Not The Real Title', |
189 | year => 3000, |
190 | }, |
191 | { key => 'primary' } |
192 | ); |
193 | |
194 | ok($cd->in_storage, 'find correctly grepped the key across a relationship'); |
195 | is($cd->cdid, 1, 'cdid is correct'); |
196 | } |
9ffa8fd7 |
197 | |
198 | # Test update_or_new |
199 | { |
200 | my $cd1 = $schema->resultset('CD')->update_or_new( |
201 | { |
202 | artist => $artistid, |
203 | title => "SuperHits $$", |
204 | year => 2007, |
205 | }, |
206 | { key => 'cd_artist_title' } |
207 | ); |
208 | |
63bb9738 |
209 | is($cd1->in_storage, 0, 'CD is not in storage yet after update_or_new'); |
9ffa8fd7 |
210 | $cd1->insert; |
211 | ok($cd1->in_storage, 'CD got added to strage after update_or_new && insert'); |
212 | |
213 | my $cd2 = $schema->resultset('CD')->update_or_new( |
214 | { |
215 | artist => $artistid, |
216 | title => "SuperHits $$", |
217 | year => 2008, |
218 | }, |
219 | { key => 'cd_artist_title' } |
220 | ); |
221 | ok($cd2->in_storage, 'Updating year using update_or_new was successful'); |
222 | is($cd2->id, $cd1->id, 'Got the same CD using update_or_new'); |
246fa39d |
223 | } |
224 | |
225 | # make sure the ident condition is assembled sanely |
226 | { |
fb88ca2c |
227 | my $artist = $schema->resultset('Artist')->find(1); |
246fa39d |
228 | |
2cfc22dd |
229 | $schema->is_executed_sql_bind( sub { $artist->discard_changes }, [ |
230 | [ |
231 | 'SELECT me.artistid, me.name, me.rank, me.charfield FROM artist me WHERE me.artistid = ?', |
232 | [ { dbic_colname => "me.artistid", sqlt_datatype => "integer" } => 1 ], |
233 | ] |
234 | ], 'Expected query on discard_changes'); |
246fa39d |
235 | } |
236 | |
034d0be4 |
237 | { |
238 | throws_ok { |
239 | eval <<'MOD' or die $@; |
240 | package # hide from PAUSE |
241 | DBICTest::Schema::UniqueConstraintWarningTest; |
242 | |
243 | use base qw/DBIx::Class::Core/; |
244 | |
245 | __PACKAGE__->table('dummy'); |
246 | |
247 | __PACKAGE__->add_column(qw/ foo bar /); |
248 | |
249 | __PACKAGE__->add_unique_constraint( |
250 | constraint1 => [qw/ foo /], |
251 | constraint2 => [qw/ bar /], |
252 | ); |
253 | |
254 | 1; |
255 | MOD |
256 | } qr/\Qadd_unique_constraint() does not accept multiple constraints, use add_unique_constraints() instead\E/, |
257 | 'add_unique_constraint throws when more than one constraint specified'; |
258 | } |
e29e2b27 |
259 | # make sure NULL is not considered condition-deterministic |
260 | my $art_rs = $schema->resultset('Artist')->search({}, { order_by => 'artistid' }); |
261 | $art_rs->create ({ artistid => $_ + 640, name => "Outranked $_" }) for (1..2); |
262 | warnings_are { |
263 | is( |
264 | $art_rs->find ({ artistid => 642, rank => 13, charfield => undef })->name, |
265 | 'Outranked 2', |
266 | 'Correct artist retrieved with find' |
267 | ); |
034d0be4 |
268 | |
e29e2b27 |
269 | is ( |
270 | $art_rs->search({ charfield => undef })->find ({ artistid => 642, rank => 13 })->name, |
271 | 'Outranked 2', |
272 | 'Correct artist retrieved with find' |
273 | ); |
274 | } [], 'no warnings'; |
034d0be4 |
275 | |
246fa39d |
276 | done_testing; |
034d0be4 |
277 | |