better tests for "smalldatetime" support in MSSQL
[dbsrgits/DBIx-Class.git] / t / 746mssql.t
CommitLineData
c1cac633 1use strict;
b9a2c3a5 2use warnings;
c1cac633 3
4use Test::More;
893403c8 5use Test::Exception;
c1cac633 6use lib qw(t/lib);
7use DBICTest;
b2d16f1f 8use DBIC::SqlMakerTest;
c1cac633 9
10my ($dsn, $user, $pass) = @ENV{map { "DBICTEST_MSSQL_ODBC_${_}" } qw/DSN USER PASS/};
11
12plan skip_all => 'Set $ENV{DBICTEST_MSSQL_ODBC_DSN}, _USER and _PASS to run this test'
13 unless ($dsn && $user);
14
7b1b2582 15plan tests => 34;
c1cac633 16
42e5b103 17my $schema = DBICTest::Schema->connect($dsn, $user, $pass);
c1cac633 18
8c0104fe 19{
20 no warnings 'redefine';
21 my $connect_count = 0;
22 my $orig_connect = \&DBI::connect;
23 local *DBI::connect = sub { $connect_count++; goto &$orig_connect };
24
25 $schema->storage->ensure_connected;
26
27 is( $connect_count, 1, 'only one connection made');
28}
9b3e916d 29
c1cac633 30isa_ok( $schema->storage, 'DBIx::Class::Storage::DBI::ODBC::Microsoft_SQL_Server' );
31
c5f77f6c 32$schema->storage->dbh_do (sub {
33 my ($storage, $dbh) = @_;
34 eval { $dbh->do("DROP TABLE artist") };
35 $dbh->do(<<'SQL');
c1cac633 36
c1cac633 37CREATE TABLE artist (
38 artistid INT IDENTITY NOT NULL,
a0dd8679 39 name VARCHAR(100),
39da2a2b 40 rank INT NOT NULL DEFAULT '13',
2eebd801 41 charfield CHAR(10) NULL,
c1cac633 42 primary key(artistid)
43)
44
c5f77f6c 45SQL
46
47});
48
c1cac633 49my %seen_id;
50
7b1b2582 51my @opts = (
52 { on_connect_call => 'use_dynamic_cursors' },
53 {},
54);
55my $new;
2eebd801 56
7b1b2582 57# test Auto-PK with different options
58for my $opts (@opts) {
59 $schema = DBICTest::Schema->clone;
60 $schema->connection($dsn, $user, $pass, $opts);
61
62 $schema->resultset('Artist')->search({ name => 'foo' })->delete;
63
64 $new = $schema->resultset('Artist')->create({ name => 'foo' });
65 ok($new->artistid > 0, "Auto-PK worked");
66}
c1cac633 67
68$seen_id{$new->artistid}++;
69
70# test LIMIT support
71for (1..6) {
72 $new = $schema->resultset('Artist')->create({ name => 'Artist ' . $_ });
73 is ( $seen_id{$new->artistid}, undef, "id for Artist $_ is unique" );
74 $seen_id{$new->artistid}++;
75}
76
77my $it = $schema->resultset('Artist')->search( {}, {
78 rows => 3,
79 order_by => 'artistid',
80});
81
82is( $it->count, 3, "LIMIT count ok" );
83is( $it->next->name, "foo", "iterator->next ok" );
84$it->next;
85is( $it->next->name, "Artist 2", "iterator->next ok" );
86is( $it->next, undef, "next past end of resultset ok" );
87
818ec409 88# test MONEY type
89$schema->storage->dbh_do (sub {
90 my ($storage, $dbh) = @_;
91 eval { $dbh->do("DROP TABLE money_test") };
92 $dbh->do(<<'SQL');
93
94CREATE TABLE money_test (
95 id INT IDENTITY PRIMARY KEY,
5064f5c3 96 amount MONEY NULL
818ec409 97)
98
99SQL
100
101});
102
103my $rs = $schema->resultset('Money');
104
105my $row;
106lives_ok {
d68f21ee 107 $row = $rs->create({ amount => 100 });
818ec409 108} 'inserted a money value';
109
110is $rs->find($row->id)->amount, '100.00', 'money value round-trip';
111
d68f21ee 112lives_ok {
113 $row->update({ amount => 200 });
114} 'updated a money value';
115
116is $rs->find($row->id)->amount, '200.00', 'updated money value round-trip';
117
f6b185e1 118lives_ok {
119 $row->update({ amount => undef });
120} 'updated a money value to NULL';
121
122is $rs->find($row->id)->amount, undef,'updated money value to NULL round-trip';
123
b9a2c3a5 124$schema->storage->dbh_do (sub {
125 my ($storage, $dbh) = @_;
126 eval { $dbh->do("DROP TABLE Owners") };
127 eval { $dbh->do("DROP TABLE Books") };
128 $dbh->do(<<'SQL');
129
130
131CREATE TABLE Books (
132 id INT IDENTITY (1, 1) NOT NULL,
133 source VARCHAR(100),
134 owner INT,
135 title VARCHAR(10),
136 price INT NULL
137)
138
139CREATE TABLE Owners (
140 id INT IDENTITY (1, 1) NOT NULL,
42e5b103 141 name VARCHAR(100),
b9a2c3a5 142)
143
b9a2c3a5 144SQL
145
146});
893403c8 147
148lives_ok ( sub {
149 $schema->populate ('Owners', [
150 [qw/id name /],
151 [qw/1 wiggle/],
152 [qw/2 woggle/],
153 [qw/3 boggle/],
154 [qw/4 fREW/],
155 [qw/5 fRIOUX/],
156 [qw/6 fROOH/],
157 [qw/7 fRUE/],
158 [qw/8 fISMBoC/],
159 [qw/9 station/],
160 [qw/10 mirror/],
161 [qw/11 dimly/],
162 [qw/12 face_to_face/],
163 [qw/13 icarus/],
164 [qw/14 dream/],
165 [qw/15 dyrstyggyr/],
166 ]);
167}, 'populate with PKs supplied ok' );
168
169lives_ok ( sub {
170 $schema->populate ('BooksInLibrary', [
171 [qw/source owner title /],
172 [qw/Library 1 secrets0/],
173 [qw/Library 1 secrets1/],
174 [qw/Eatery 1 secrets2/],
175 [qw/Library 2 secrets3/],
176 [qw/Library 3 secrets4/],
177 [qw/Eatery 3 secrets5/],
178 [qw/Library 4 secrets6/],
179 [qw/Library 5 secrets7/],
180 [qw/Eatery 5 secrets8/],
181 [qw/Library 6 secrets9/],
182 [qw/Library 7 secrets10/],
183 [qw/Eatery 7 secrets11/],
184 [qw/Library 8 secrets12/],
185 ]);
186}, 'populate without PKs supplied ok' );
b9a2c3a5 187
188#
02d133f0 189# try a prefetch on tables with identically named columns
b9a2c3a5 190#
191
02d133f0 192# set quote char - make sure things work while quoted
193$schema->storage->_sql_maker->{quote_char} = [qw/[ ]/];
194$schema->storage->_sql_maker->{name_sep} = '.';
195
b9a2c3a5 196{
893403c8 197 # try a ->has_many direction
fc85215b 198 my $owners = $schema->resultset ('Owners')->search ({
199 'books.id' => { '!=', undef }
200 }, {
201 prefetch => 'books',
ff1ef65b 202 order_by => 'name',
56d2561e 203 rows => 3, # 8 results total
fc85215b 204 });
205
56d2561e 206 is ($owners->page(1)->all, 3, 'has_many prefetch returns correct number of rows');
207 is ($owners->page(1)->count, 3, 'has-many prefetch returns correct count');
208
618a0fe3 209 TODO: {
210 local $TODO = 'limit past end of resultset problem';
56d2561e 211 is ($owners->page(3)->all, 2, 'has_many prefetch returns correct number of rows');
212 is ($owners->page(3)->count, 2, 'has-many prefetch returns correct count');
64c7c000 213 is ($owners->page(3)->count_rs->next, 2, 'has-many prefetch returns correct count_rs');
214
215 # make sure count does not become overly complex FIXME
216 is_same_sql_bind (
217 $owners->page(3)->count_rs->as_query,
218 '(
219 SELECT COUNT( * )
220 FROM (
02d133f0 221 SELECT TOP 3 [me].[id]
222 FROM [owners] [me]
223 LEFT JOIN [books] [books] ON [books].[owner] = [me].[id]
224 WHERE ( [books].[id] IS NOT NULL )
225 GROUP BY [me].[id]
226 ORDER BY [me].[id] DESC
227 ) [count_subq]
64c7c000 228 )',
229 [],
230 );
618a0fe3 231 }
b9a2c3a5 232
42e5b103 233 # try a ->belongs_to direction (no select collapse, group_by should work)
fc85215b 234 my $books = $schema->resultset ('BooksInLibrary')->search ({
56d2561e 235 'owner.name' => [qw/wiggle woggle/],
fc85215b 236 }, {
fc85215b 237 distinct => 1,
42e5b103 238 prefetch => 'owner',
56d2561e 239 rows => 2, # 3 results total
ac93965c 240 order_by => { -desc => 'owner' },
241 # there is no sane way to order by the right side of a grouped prefetch currently :(
242 #order_by => { -desc => 'owner.name' },
fc85215b 243 });
244
b1e1d073 245
56d2561e 246 is ($books->page(1)->all, 2, 'Prefetched grouped search returns correct number of rows');
247 is ($books->page(1)->count, 2, 'Prefetched grouped search returns correct count');
b1e1d073 248
618a0fe3 249 TODO: {
250 local $TODO = 'limit past end of resultset problem';
56d2561e 251 is ($books->page(2)->all, 1, 'Prefetched grouped search returns correct number of rows');
252 is ($books->page(2)->count, 1, 'Prefetched grouped search returns correct count');
64c7c000 253 is ($books->page(2)->count_rs->next, 1, 'Prefetched grouped search returns correct count_rs');
254
255 # make sure count does not become overly complex FIXME
256 is_same_sql_bind (
257 $books->page(2)->count_rs->as_query,
258 '(
259 SELECT COUNT( * )
260 FROM (
02d133f0 261 SELECT TOP 2 [me].[id]
262 FROM [books] [me]
263 JOIN [owners] [owner] ON [owner].[id] = [me].[owner]
264 WHERE ( ( ( [owner].[name] = ? OR [owner].[name] = ? ) AND [source] = ? ) )
265 GROUP BY [me].[id], [me].[source], [me].[owner], [me].[title], [me].[price], [owner].[id], [owner].[name]
266 ORDER BY [me].[id] DESC
267 ) [count_subq]
64c7c000 268 )',
269 [
270 [ 'owner.name' => 'wiggle' ],
271 [ 'owner.name' => 'woggle' ],
272 [ 'source' => 'Library' ],
273 ],
274 );
618a0fe3 275 }
b2d16f1f 276
b9a2c3a5 277}
c1cac633 278
279# clean up our mess
280END {
818ec409 281 if (my $dbh = eval { $schema->storage->_dbh }) {
282 $dbh->do('DROP TABLE artist');
283 $dbh->do('DROP TABLE money_test');
284 $dbh->do('DROP TABLE Books');
285 $dbh->do('DROP TABLE Owners');
286 }
c1cac633 287}
fc85215b 288# vim:sw=2 sts=2