2nd Pass
[dbsrgits/DBIx-Class.git] / t / 86ss_anydata.t
1 use strict;
2 use warnings;
3
4 use Test::More;
5 use Test::Exception;
6
7 use lib qw(t/lib);
8 use DBICTest;
9 use DBIC::SqlMakerTest;
10 use DBIx::Class::Optional::Dependencies ();
11
12 use Path::Class;
13
14 plan skip_all => 'Set $ENV{DBICTEST_DBD_ANYDATA} = 1 to run this test'
15    unless ($ENV{DBICTEST_DBD_ANYDATA});
16
17 plan skip_all =>
18    'Test needs ' . DBIx::Class::Optional::Dependencies->req_missing_for ('test_rdbms_ss_anydata')
19    unless DBIx::Class::Optional::Dependencies->req_ok_for ('test_rdbms_ss_anydata');
20
21 # just in case they try to use these conflicting versions
22 use DBD::AnyData;
23 plan skip_all =>
24    'Incompatible versions of DBD::AnyData and DBI'
25    if ($DBD::AnyData::VERSION <= 0.110 && $DBI::VERSION >= 1.623);
26
27 my ($dsn, $opts) = ('dbi:AnyData:', {});
28
29 my $schema = DBICTest::Schema->connect($dsn, '', '', $opts);
30 is ($schema->storage->sqlt_type, 'AnyData', 'sqlt_type correct pre-connection');
31 isa_ok($schema->storage->sql_maker, 'DBIx::Class::SQLMaker::SQLStatement');
32
33 # Custom deployment
34 my $dbh = $schema->storage->dbh;
35 my @cmds = split /\s*\;\s*/, scalar file(qw/t lib dbdfile.sql/)->slurp;
36 $dbh->do($_) for @cmds;
37
38 ### S:S doesn't have any sort of AUTOINCREMENT support, so IDs will have to be generated by hand ###
39
40 # test primary key handling
41 my $new = $schema->resultset('Artist')->create({
42    artistid => 1,
43    name => 'foo'
44 });
45 ok($new->artistid, "Create worked");
46
47 # test LIMIT support
48 for (1..6) {
49    $schema->resultset('Artist')->create({
50       artistid => $_+1,
51       name     => 'Artist '.$_,
52    });
53 }
54 my $it = $schema->resultset('Artist')->search( {}, {
55    rows   => 3,
56    offset => 2,
57    order_by => 'artistid'
58 });
59 is( $it->count, 3, "LIMIT count ok" );  # ask for 3 rows out of 7 artists
60 is( $it->next->name, "Artist 2", "iterator->next ok" );
61 $it->next;
62 $it->next;
63 is( $it->next, undef, "next past end of resultset ok" );
64
65 # Limit with select-lock (which is silently thrown away)
66 lives_ok {
67    isa_ok (
68       $schema->resultset('Artist')->find({artistid => 1}, {for => 'update', rows => 1}),
69       'DBICTest::Schema::Artist',
70    );
71 } 'Limited FOR UPDATE select works';
72
73 # shared-lock (which is silently thrown away)
74 lives_ok {
75    isa_ok (
76       $schema->resultset('Artist')->find({artistid => 1}, {for => 'shared'}),
77       'DBICTest::Schema::Artist',
78    );
79 } 'LOCK IN SHARE MODE select works';
80
81 # (No sizes with DBD::AnyData and all is_nullable)
82 my $test_type_info = {
83    'artistid' => {
84       'data_type' => 'VARCHAR',
85       'is_nullable' => 1,
86       'size' => 0,
87    },
88    'name' => {
89       'data_type' => 'VARCHAR',
90       'is_nullable' => 1,
91       'size' => 0,
92    },
93    'rank' => {
94       'data_type' => 'VARCHAR',
95       'is_nullable' => 1,
96       'size' => 0,
97    },
98    'charfield' => {
99       'data_type' => 'VARCHAR',
100       'is_nullable' => 1,
101       'size' => 0,
102    },
103 };
104
105 $ENV{DBIC_DBDFILE_TXN_NOWARN} = 1;
106
107 $schema->populate ('Owners', [
108    [qw/id  name  /],
109    [qw/1   wiggle/],
110    [qw/2   woggle/],
111    [qw/3   boggle/],
112 ]);
113
114 $schema->populate ('BooksInLibrary', [
115    [qw/id source  owner title   /],
116    [qw/1  Library 1     secrets1/],
117    [qw/2  Eatery  1     secrets2/],
118    [qw/3  Library 2     secrets3/],
119 ]);
120
121 {
122    # try a ->has_many direction (due to a 'multi' accessor the select/group_by group is collapsed)
123    my $owners = $schema->resultset('Owners')->search(
124       { 'books.id' => { '!=', undef }},
125       { prefetch => 'books', cache => 1 }
126    );
127    is($owners->all, 2, 'Prefetched grouped search returns correct number of rows');
128
129    # only works here because of the full cache
130    # S:S would croak on a subselect otherwise
131    is($owners->count, 2, 'Prefetched grouped search returns correct count');
132
133    # try a ->belongs_to direction (no select collapse)
134    my $books = $schema->resultset('BooksInLibrary')->search (
135       { 'owner.name' => 'wiggle' },
136       { prefetch => 'owner', distinct => 1 }
137    );
138
139    {
140       local $TODO = 'populate does not subtract the non-Library INSERTs here...';
141       is($owners->all, 1, 'Prefetched grouped search returns correct number of rows');
142       is($owners->count, 1, 'Prefetched grouped search returns correct count');
143    }
144 }
145
146 my $type_info = $schema->storage->columns_info_for('artist');
147 is_deeply($type_info, $test_type_info, 'columns_info_for - column data types');
148
149 my $cd = $schema->resultset('CD')->create({ cdid => 1 });
150 my $producer = $schema->resultset('Producer')->create({ producerid => 1 });
151 lives_ok { $cd->set_producers ([ $producer ]) } 'set_relationship doesnt die';
152
153 {
154    my $artist = $schema->resultset('Artist')->next;
155    my $cd = $schema->resultset('CD')->next;
156    $cd->set_from_related('artist', $artist);
157    $cd->update;
158
159    my $rs = $schema->resultset('CD')->search ({}, { prefetch => 'artist' });
160
161    lives_ok sub {
162       my $cd = $rs->next;
163       is ($cd->artist->name, $artist->name, 'Prefetched artist');
164    }, 'join does not throw';
165
166    local $schema->storage->sql_maker->{_default_jointype} = 'inner';
167    is_same_sql_bind (
168       $rs->as_query,
169       '(
170          SELECT
171             me.cdid, me.artist, me.title, me.year, me.genreid, me.single_track,
172             artist.artistid, artist.name, artist.rank, artist.charfield
173          FROM cd me
174          INNER JOIN artist artist ON artist.artistid = me.artist
175       )',
176       [],
177       'overriden default join type works',
178    );
179 }
180
181 {
182    # Test support for straight joins
183    my $cdsrc = $schema->source('CD');
184    my $artrel_info = $cdsrc->relationship_info ('artist');
185    $cdsrc->add_relationship(
186       'straight_artist',
187       $artrel_info->{class},
188       $artrel_info->{cond},
189       { %{$artrel_info->{attrs}}, join_type => 'straight' },
190    );
191    is_same_sql_bind (
192       $cdsrc->resultset->search({}, { prefetch => 'straight_artist' })->as_query,
193       '(
194          SELECT
195             me.cdid, me.artist, me.title, me.year, me.genreid, me.single_track,
196             straight_artist.artistid, straight_artist.name, straight_artist.rank, straight_artist.charfield
197          FROM cd me
198          STRAIGHT JOIN artist straight_artist ON straight_artist.artistid = me.artist
199       )',
200       [],
201       'straight joins correctly supported'
202    );
203 }
204
205 # Can we properly deal with the null search problem?
206 {
207    $schema->resultset('Artist')->create({ artistid => 2222, name => 'last created artist' });
208
209    ok my $artist1_rs = $schema->resultset('Artist')->search({artistid=>6666})
210      => 'Created an artist resultset of 6666';
211
212    is $artist1_rs->count, 0
213      => 'Got no returned rows';
214
215    ok my $artist2_rs = $schema->resultset('Artist')->search({artistid=>undef})
216      => 'Created an artist resultset of undef';
217
218    is $artist2_rs->count, 0
219      => 'got no rows';
220
221    my $artist = $artist2_rs->single;
222
223    is $artist => undef
224      => 'Nothing Found!';
225 }
226
227 {
228    my $cds_per_year = {
229       2001 => 2,
230       2002 => 1,
231       2005 => 3,
232    };
233
234    # kill the scalar ref here
235    $schema->source('CD')->name('cd');
236
237    my $rs = $schema->resultset('CD');
238    $rs->delete;
239    my $cdid = 1;
240    foreach my $y (keys %$cds_per_year) {
241       foreach my $c (1 .. $cds_per_year->{$y} ) {
242          $rs->create({ cdid => $cdid++, title => "CD $y-$c", artist => 1, year => "$y-01-01" });
243       }
244    }
245
246    is ($rs->count, 6, 'CDs created successfully');
247 }
248
249 done_testing;