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