merge on_connect_call updates
[dbsrgits/DBIx-Class.git] / t / 746sybase.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 use DateTime::Format::Sybase;
9
10 my ($dsn, $user, $pass) = @ENV{map { "DBICTEST_SYBASE_${_}" } qw/DSN USER PASS/};
11
12 plan skip_all => 'Set $ENV{DBICTEST_SYBASE_DSN}, _USER and _PASS to run this test'
13   unless ($dsn && $user);
14
15 plan tests => (26 + 4*2)*2;
16
17 my @storage_types = (
18   'DBI::Sybase',
19   'DBI::Sybase::NoBindVars',
20 );
21 my $schema;
22
23 for my $storage_type (@storage_types) {
24   $schema = DBICTest::Schema->clone;
25
26   unless ($storage_type eq 'DBI::Sybase') { # autodetect
27     $schema->storage_type("::$storage_type");
28   }
29   $schema->connection($dsn, $user, $pass, {
30     AutoCommit => 1,
31     on_connect_call => [
32       [ 'datetime_setup' ],
33       [ blob_setup => log_on_update => 1 ], # this is a safer option
34     ],
35   });
36
37   $schema->storage->ensure_connected;
38
39   isa_ok( $schema->storage, "DBIx::Class::Storage::$storage_type" );
40
41   $schema->storage->dbh_do (sub {
42       my ($storage, $dbh) = @_;
43       eval { $dbh->do("DROP TABLE artist") };
44       $dbh->do(<<'SQL');
45 CREATE TABLE artist (
46    artistid INT IDENTITY PRIMARY KEY,
47    name VARCHAR(100),
48    rank INT DEFAULT 13 NOT NULL,
49    charfield CHAR(10) NULL
50 )
51 SQL
52   });
53
54   my %seen_id;
55
56 # so we start unconnected
57   $schema->storage->disconnect;
58
59 # test primary key handling
60   my $new = $schema->resultset('Artist')->create({ name => 'foo' });
61   ok($new->artistid > 0, "Auto-PK worked");
62
63   $seen_id{$new->artistid}++;
64
65   for (1..6) {
66     $new = $schema->resultset('Artist')->create({ name => 'Artist ' . $_ });
67     is ( $seen_id{$new->artistid}, undef, "id for Artist $_ is unique" );
68     $seen_id{$new->artistid}++;
69   }
70
71 # test simple count
72   is ($schema->resultset('Artist')->count, 7, 'count(*) of whole table ok');
73
74 # test LIMIT support
75   my $it = $schema->resultset('Artist')->search({
76     artistid => { '>' => 0 }
77   }, {
78     rows => 3,
79     order_by => 'artistid',
80   });
81
82   is( $it->count, 3, "LIMIT count ok" );
83
84   is( $it->next->name, "foo", "iterator->next ok" );
85   $it->next;
86   is( $it->next->name, "Artist 2", "iterator->next ok" );
87   is( $it->next, undef, "next past end of resultset ok" );
88
89 # now try with offset
90   $it = $schema->resultset('Artist')->search({}, {
91     rows => 3,
92     offset => 3,
93     order_by => 'artistid',
94   });
95
96   is( $it->count, 3, "LIMIT with offset count ok" );
97
98   is( $it->next->name, "Artist 3", "iterator->next ok" );
99   $it->next;
100   is( $it->next->name, "Artist 5", "iterator->next ok" );
101   is( $it->next, undef, "next past end of resultset ok" );
102
103 # now try a grouped count
104   $schema->resultset('Artist')->create({ name => 'Artist 6' })
105     for (1..6);
106
107   $it = $schema->resultset('Artist')->search({}, {
108     group_by => 'name'
109   });
110
111   is( $it->count, 7, 'COUNT of GROUP_BY ok' );
112
113 # Test DateTime inflation with DATETIME
114   my @dt_types = (
115     ['DATETIME', '2004-08-21T14:36:48.080Z'],
116     ['SMALLDATETIME', '2004-08-21T14:36:00.000Z'], # minute precision
117   );
118   
119   for my $dt_type (@dt_types) {
120     my ($type, $sample_dt) = @$dt_type;
121
122     eval { $schema->storage->dbh->do("DROP TABLE track") };
123     $schema->storage->dbh->do(<<"SQL");
124 CREATE TABLE track (
125    trackid INT IDENTITY PRIMARY KEY,
126    cd INT,
127    position INT,
128    last_updated_on $type,
129 )
130 SQL
131     ok(my $dt = DateTime::Format::Sybase->parse_datetime($sample_dt));
132
133     my $row;
134     ok( $row = $schema->resultset('Track')->create({
135       last_updated_on => $dt,
136       cd => 1,
137     }));
138     ok( $row = $schema->resultset('Track')
139       ->search({ trackid => $row->trackid }, { select => ['last_updated_on'] })
140       ->first
141     );
142     is( $row->updated_date, $dt, 'DateTime inflation works' );
143   }
144
145 # mostly stole the blob stuff Nniuq wrote for t/73oracle.t
146   my $dbh = $schema->storage->dbh;
147   {
148     local $SIG{__WARN__} = sub {};
149     eval { $dbh->do('DROP TABLE bindtype_test') };
150
151     $dbh->do(qq[
152       CREATE TABLE bindtype_test 
153       (
154         id    INT   PRIMARY KEY,
155         bytea INT   NULL,
156         blob  IMAGE NULL,
157         clob  TEXT  NULL
158       )
159     ],{ RaiseError => 1, PrintError => 1 });
160   }
161
162   my %binstr = ( 'small' => join('', map { chr($_) } ( 1 .. 127 )) );
163   $binstr{'large'} = $binstr{'small'} x 1024;
164
165   my $maxloblen = length $binstr{'large'};
166   note "Localizing LongReadLen to $maxloblen to avoid truncation of test data";
167   local $dbh->{'LongReadLen'} = $maxloblen;
168
169   my $rs = $schema->resultset('BindType');
170   my $id = 0;
171
172   foreach my $type (qw(blob clob)) {
173     foreach my $size (qw(small large)) {
174       no warnings 'uninitialized';
175       $id++;
176
177       eval { $rs->create( { 'id' => $id, $type => $binstr{$size} } ) };
178       ok(!$@, "inserted $size $type without dying");
179       diag $@ if $@;
180
181       ok(eval {
182         $rs->search({ id=> $id }, { select => [$type] })->single->$type
183       } eq $binstr{$size}, "verified inserted $size $type" );
184     }
185   }
186 }
187
188 # clean up our mess
189 END {
190   if (my $dbh = eval { $schema->storage->_dbh }) {
191     $dbh->do('DROP TABLE artist');
192     $dbh->do('DROP TABLE track');
193     $dbh->do('DROP TABLE bindtype_test');
194   }
195 }