9e7bc8805105c218e668d50f02abf59862e7df5d
[dbsrgits/DBIx-Class.git] / t / 100populate.t
1 use strict;
2 use warnings;
3
4 use Test::More;
5 use Test::Exception;
6 use lib qw(t/lib);
7 use DBICTest;
8
9 my $schema = DBICTest->init_schema();
10
11 # The map below generates stuff like:
12 #   [ qw/artistid name/ ],
13 #   [ 4, "b" ],
14 #   [ 5, "c" ],
15 #   ...
16 #   [ 9999, "ntm" ],
17 #   [ 10000, "ntn" ],
18
19 my $start_id = 'populateXaaaaaa';
20 my $rows = 10;
21 my $offset = 3;
22
23 $schema->populate('Artist', [ [ qw/artistid name/ ], map { [ ($_ + $offset) => $start_id++ ] } ( 1 .. $rows ) ] );
24 is (
25     $schema->resultset ('Artist')->search ({ name => { -like => 'populateX%' } })->count,
26     $rows,
27     'populate created correct number of rows with massive AoA bulk insert',
28 );
29
30 my $artist = $schema->resultset ('Artist')
31               ->search ({ 'cds.title' => { '!=', undef } }, { join => 'cds' })
32                 ->first;
33 my $ex_title = $artist->cds->first->title;
34
35 throws_ok ( sub {
36   my $i = 600;
37   $schema->populate('CD', [
38     map {
39       {
40         artist => $artist->id,
41         title => $_,
42         year => 2009,
43       }
44     } ('Huey', 'Dewey', $ex_title, 'Louie')
45   ])
46 }, qr/columns .+ are not unique for populate slice.+$ex_title/ms, 'Readable exception thrown for failed populate');
47
48 ## make sure populate honors fields/orders in list context
49 ## schema order
50 my @links = $schema->populate('Link', [
51 [ qw/id url title/ ],
52 [ qw/2 burl btitle/ ]
53 ]);
54 is(scalar @links, 1);
55
56 my $link2 = shift @links;
57 is($link2->id, 2, 'Link 2 id');
58 is($link2->url, 'burl', 'Link 2 url');
59 is($link2->title, 'btitle', 'Link 2 title');
60
61 ## non-schema order
62 @links = $schema->populate('Link', [
63 [ qw/id title url/ ],
64 [ qw/3 ctitle curl/ ]
65 ]);
66 is(scalar @links, 1);
67
68 my $link3 = shift @links;
69 is($link3->id, 3, 'Link 3 id');
70 is($link3->url, 'curl', 'Link 3 url');
71 is($link3->title, 'ctitle', 'Link 3 title');
72
73 ## not all physical columns
74 @links = $schema->populate('Link', [
75 [ qw/id title/ ],
76 [ qw/4 dtitle/ ]
77 ]);
78 is(scalar @links, 1);
79
80 my $link4 = shift @links;
81 is($link4->id, 4, 'Link 4 id');
82 is($link4->url, undef, 'Link 4 url');
83 is($link4->title, 'dtitle', 'Link 4 title');
84
85
86 ## make sure populate -> insert_bulk honors fields/orders in void context
87 ## schema order
88 $schema->populate('Link', [
89 [ qw/id url title/ ],
90 [ qw/5 eurl etitle/ ]
91 ]);
92 my $link5 = $schema->resultset('Link')->find(5);
93 is($link5->id, 5, 'Link 5 id');
94 is($link5->url, 'eurl', 'Link 5 url');
95 is($link5->title, 'etitle', 'Link 5 title');
96
97 ## non-schema order
98 $schema->populate('Link', [
99 [ qw/id title url/ ],
100 [ qw/6 ftitle furl/ ]
101 ]);
102 my $link6 = $schema->resultset('Link')->find(6);
103 is($link6->id, 6, 'Link 6 id');
104 is($link6->url, 'furl', 'Link 6 url');
105 is($link6->title, 'ftitle', 'Link 6 title');
106
107 ## not all physical columns
108 $schema->populate('Link', [
109 [ qw/id title/ ],
110 [ qw/7 gtitle/ ]
111 ]);
112 my $link7 = $schema->resultset('Link')->find(7);
113 is($link7->id, 7, 'Link 7 id');
114 is($link7->url, undef, 'Link 7 url');
115 is($link7->title, 'gtitle', 'Link 7 title');
116
117 my $rs = $schema->resultset('Artist');
118 $rs->delete;
119
120 # test _execute_array_empty (insert_bulk with all literal sql)
121
122 $rs->populate([
123     (+{
124         name => \"'DT'",
125         rank => \500,
126         charfield => \"'mtfnpy'",
127     }) x 5
128 ]);
129
130 is((grep {
131   $_->name eq 'DT' &&
132   $_->rank == 500  &&
133   $_->charfield eq 'mtfnpy'
134 } $rs->all), 5, 'populate with all literal SQL');
135
136 $rs->delete;
137
138 # test mixed binds with literal sql
139
140 $rs->populate([
141     (+{
142         name => \"'DT'",
143         rank => 500,
144         charfield => \"'mtfnpy'",
145     }) x 5
146 ]);
147
148 is((grep {
149   $_->name eq 'DT' &&
150   $_->rank == 500  &&
151   $_->charfield eq 'mtfnpy'
152 } $rs->all), 5, 'populate with all literal SQL');
153
154 $rs->delete;
155
156 ###
157
158 throws_ok {
159     $rs->populate([
160         {
161             artistid => 1,
162             name => 'foo1',
163         },
164         {
165             artistid => 'foo', # this dies
166             name => 'foo2',
167         },
168         {
169             artistid => 3,
170             name => 'foo3',
171         },
172     ]);
173 } qr/slice/, 'bad slice';
174
175 is($rs->count, 0, 'populate is atomic');
176
177 # Trying to use a column marked as a bind in the first slice with literal sql in
178 # a later slice should throw.
179
180 throws_ok {
181   $rs->populate([
182     {
183       artistid => 1,
184       name => \"'foo'",
185     },
186     {
187       artistid => \2,
188       name => \"'foo'",
189     }
190   ]);
191 } qr/bind expected/, 'literal sql where bind expected throws';
192
193 # ... and vice-versa.
194
195 throws_ok {
196   $rs->populate([
197     {
198       artistid => \1,
199       name => \"'foo'",
200     },
201     {
202       artistid => 2,
203       name => \"'foo'",
204     }
205   ]);
206 } qr/literal SQL expected/i, 'bind where literal sql expected throws';
207
208 throws_ok {
209   $rs->populate([
210     {
211       artistid => 1,
212       name => \"'foo'",
213     },
214     {
215       artistid => 2,
216       name => \"'bar'",
217     }
218   ]);
219 } qr/inconsistent/, 'literal sql must be the same in all slices';
220
221 done_testing;