Backout sybase changes
[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
ca791b95 15DBICTest::Schema->load_classes('ArtistGUID');
42e5b103 16my $schema = DBICTest::Schema->connect($dsn, $user, $pass);
c1cac633 17
8c0104fe 18{
19 no warnings 'redefine';
20 my $connect_count = 0;
21 my $orig_connect = \&DBI::connect;
22 local *DBI::connect = sub { $connect_count++; goto &$orig_connect };
23
24 $schema->storage->ensure_connected;
25
26 is( $connect_count, 1, 'only one connection made');
27}
9b3e916d 28
c1cac633 29isa_ok( $schema->storage, 'DBIx::Class::Storage::DBI::ODBC::Microsoft_SQL_Server' );
30
c5f77f6c 31$schema->storage->dbh_do (sub {
32 my ($storage, $dbh) = @_;
33 eval { $dbh->do("DROP TABLE artist") };
34 $dbh->do(<<'SQL');
c1cac633 35CREATE TABLE artist (
36 artistid INT IDENTITY NOT NULL,
a0dd8679 37 name VARCHAR(100),
39da2a2b 38 rank INT NOT NULL DEFAULT '13',
2eebd801 39 charfield CHAR(10) NULL,
c1cac633 40 primary key(artistid)
41)
c5f77f6c 42SQL
c5f77f6c 43});
44
c1cac633 45my %seen_id;
46
7b1b2582 47my @opts = (
48 { on_connect_call => 'use_dynamic_cursors' },
49 {},
50);
51my $new;
2eebd801 52
7b1b2582 53# test Auto-PK with different options
54for my $opts (@opts) {
41dd5d30 55 SKIP: {
56 $schema = DBICTest::Schema->connect($dsn, $user, $pass, $opts);
7b1b2582 57
41dd5d30 58 eval {
59 $schema->storage->ensure_connected
60 };
61 if ($@ =~ /dynamic cursors/) {
62 skip
63'Dynamic Cursors not functional, tds_version 8.0 or greater required if using'.
64' FreeTDS', 1;
65 }
2eebd801 66
41dd5d30 67 $schema->resultset('Artist')->search({ name => 'foo' })->delete;
68
69 $new = $schema->resultset('Artist')->create({ name => 'foo' });
70
71 ok($new->artistid > 0, "Auto-PK worked");
72 }
7b1b2582 73}
c1cac633 74
75$seen_id{$new->artistid}++;
76
77# test LIMIT support
78for (1..6) {
79 $new = $schema->resultset('Artist')->create({ name => 'Artist ' . $_ });
80 is ( $seen_id{$new->artistid}, undef, "id for Artist $_ is unique" );
81 $seen_id{$new->artistid}++;
82}
83
84my $it = $schema->resultset('Artist')->search( {}, {
85 rows => 3,
86 order_by => 'artistid',
87});
88
89is( $it->count, 3, "LIMIT count ok" );
90is( $it->next->name, "foo", "iterator->next ok" );
91$it->next;
92is( $it->next->name, "Artist 2", "iterator->next ok" );
93is( $it->next, undef, "next past end of resultset ok" );
94
ca791b95 95# test GUID columns
96
97$schema->storage->dbh_do (sub {
98 my ($storage, $dbh) = @_;
99 eval { $dbh->do("DROP TABLE artist") };
100 $dbh->do(<<'SQL');
101CREATE TABLE artist (
102 artistid UNIQUEIDENTIFIER NOT NULL,
103 name VARCHAR(100),
104 rank INT NOT NULL DEFAULT '13',
105 charfield CHAR(10) NULL,
106 a_guid UNIQUEIDENTIFIER,
107 primary key(artistid)
108)
109SQL
110});
111
e34bae3a 112# start disconnected to make sure insert works on an un-reblessed storage
113$schema = DBICTest::Schema->connect($dsn, $user, $pass);
114
ca791b95 115my $row;
116lives_ok {
117 $row = $schema->resultset('ArtistGUID')->create({ name => 'mtfnpy' })
118} 'created a row with a GUID';
119
120ok(
121 eval { $row->artistid },
122 'row has GUID PK col populated',
123);
124diag $@ if $@;
125
126ok(
127 eval { $row->a_guid },
128 'row has a GUID col with auto_nextval populated',
129);
130diag $@ if $@;
131
132my $row_from_db = $schema->resultset('ArtistGUID')
133 ->search({ name => 'mtfnpy' })->first;
134
135is $row_from_db->artistid, $row->artistid,
136 'PK GUID round trip';
137
138is $row_from_db->a_guid, $row->a_guid,
139 'NON-PK GUID round trip';
140
818ec409 141# test MONEY type
142$schema->storage->dbh_do (sub {
143 my ($storage, $dbh) = @_;
144 eval { $dbh->do("DROP TABLE money_test") };
145 $dbh->do(<<'SQL');
26283ee3 146
818ec409 147CREATE TABLE money_test (
148 id INT IDENTITY PRIMARY KEY,
5064f5c3 149 amount MONEY NULL
818ec409 150)
26283ee3 151
818ec409 152SQL
26283ee3 153
818ec409 154});
155
156my $rs = $schema->resultset('Money');
157
818ec409 158lives_ok {
d68f21ee 159 $row = $rs->create({ amount => 100 });
818ec409 160} 'inserted a money value';
161
a33d2444 162cmp_ok $rs->find($row->id)->amount, '==', 100, 'money value round-trip';
818ec409 163
d68f21ee 164lives_ok {
165 $row->update({ amount => 200 });
166} 'updated a money value';
167
a33d2444 168cmp_ok $rs->find($row->id)->amount, '==', 200,
169 'updated money value round-trip';
d68f21ee 170
f6b185e1 171lives_ok {
172 $row->update({ amount => undef });
173} 'updated a money value to NULL';
174
175is $rs->find($row->id)->amount, undef,'updated money value to NULL round-trip';
176
b9a2c3a5 177$schema->storage->dbh_do (sub {
178 my ($storage, $dbh) = @_;
179 eval { $dbh->do("DROP TABLE Owners") };
180 eval { $dbh->do("DROP TABLE Books") };
181 $dbh->do(<<'SQL');
b9a2c3a5 182CREATE TABLE Books (
183 id INT IDENTITY (1, 1) NOT NULL,
184 source VARCHAR(100),
185 owner INT,
186 title VARCHAR(10),
187 price INT NULL
188)
189
190CREATE TABLE Owners (
191 id INT IDENTITY (1, 1) NOT NULL,
42e5b103 192 name VARCHAR(100),
b9a2c3a5 193)
b9a2c3a5 194SQL
195
196});
893403c8 197
198lives_ok ( sub {
e29dc2bb 199 # start a new connection, make sure rebless works
48617009 200 my $schema = DBICTest::Schema->connect($dsn, $user, $pass);
893403c8 201 $schema->populate ('Owners', [
202 [qw/id name /],
203 [qw/1 wiggle/],
204 [qw/2 woggle/],
205 [qw/3 boggle/],
206 [qw/4 fREW/],
207 [qw/5 fRIOUX/],
208 [qw/6 fROOH/],
209 [qw/7 fRUE/],
210 [qw/8 fISMBoC/],
211 [qw/9 station/],
212 [qw/10 mirror/],
213 [qw/11 dimly/],
214 [qw/12 face_to_face/],
215 [qw/13 icarus/],
216 [qw/14 dream/],
217 [qw/15 dyrstyggyr/],
218 ]);
219}, 'populate with PKs supplied ok' );
220
afcfff01 221lives_ok (sub {
222 # start a new connection, make sure rebless works
223 # test an insert with a supplied identity, followed by one without
224 my $schema = DBICTest::Schema->connect($dsn, $user, $pass);
225 for (1..2) {
226 my $id = $_ * 20 ;
227 $schema->resultset ('Owners')->create ({ id => $id, name => "troglodoogle $id" });
228 $schema->resultset ('Owners')->create ({ name => "troglodoogle " . ($id + 1) });
229 }
230}, 'create with/without PKs ok' );
231
232is ($schema->resultset ('Owners')->count, 19, 'owner rows really in db' );
233
893403c8 234lives_ok ( sub {
e29dc2bb 235 # start a new connection, make sure rebless works
48617009 236 my $schema = DBICTest::Schema->connect($dsn, $user, $pass);
893403c8 237 $schema->populate ('BooksInLibrary', [
238 [qw/source owner title /],
239 [qw/Library 1 secrets0/],
240 [qw/Library 1 secrets1/],
241 [qw/Eatery 1 secrets2/],
242 [qw/Library 2 secrets3/],
243 [qw/Library 3 secrets4/],
244 [qw/Eatery 3 secrets5/],
245 [qw/Library 4 secrets6/],
246 [qw/Library 5 secrets7/],
247 [qw/Eatery 5 secrets8/],
248 [qw/Library 6 secrets9/],
249 [qw/Library 7 secrets10/],
250 [qw/Eatery 7 secrets11/],
251 [qw/Library 8 secrets12/],
252 ]);
253}, 'populate without PKs supplied ok' );
b9a2c3a5 254
255#
02d133f0 256# try a prefetch on tables with identically named columns
b9a2c3a5 257#
258
02d133f0 259# set quote char - make sure things work while quoted
260$schema->storage->_sql_maker->{quote_char} = [qw/[ ]/];
261$schema->storage->_sql_maker->{name_sep} = '.';
262
b9a2c3a5 263{
893403c8 264 # try a ->has_many direction
fc85215b 265 my $owners = $schema->resultset ('Owners')->search ({
266 'books.id' => { '!=', undef }
267 }, {
268 prefetch => 'books',
ff1ef65b 269 order_by => 'name',
56d2561e 270 rows => 3, # 8 results total
fc85215b 271 });
272
56d2561e 273 is ($owners->page(1)->all, 3, 'has_many prefetch returns correct number of rows');
274 is ($owners->page(1)->count, 3, 'has-many prefetch returns correct count');
275
618a0fe3 276 TODO: {
277 local $TODO = 'limit past end of resultset problem';
56d2561e 278 is ($owners->page(3)->all, 2, 'has_many prefetch returns correct number of rows');
279 is ($owners->page(3)->count, 2, 'has-many prefetch returns correct count');
64c7c000 280 is ($owners->page(3)->count_rs->next, 2, 'has-many prefetch returns correct count_rs');
281
e2751d0b 282 # make sure count does not become overly complex
64c7c000 283 is_same_sql_bind (
284 $owners->page(3)->count_rs->as_query,
285 '(
286 SELECT COUNT( * )
287 FROM (
02d133f0 288 SELECT TOP 3 [me].[id]
289 FROM [owners] [me]
290 LEFT JOIN [books] [books] ON [books].[owner] = [me].[id]
291 WHERE ( [books].[id] IS NOT NULL )
292 GROUP BY [me].[id]
293 ORDER BY [me].[id] DESC
294 ) [count_subq]
64c7c000 295 )',
296 [],
297 );
618a0fe3 298 }
b9a2c3a5 299
42e5b103 300 # try a ->belongs_to direction (no select collapse, group_by should work)
fc85215b 301 my $books = $schema->resultset ('BooksInLibrary')->search ({
56d2561e 302 'owner.name' => [qw/wiggle woggle/],
fc85215b 303 }, {
fc85215b 304 distinct => 1,
42e5b103 305 prefetch => 'owner',
56d2561e 306 rows => 2, # 3 results total
ac93965c 307 order_by => { -desc => 'owner' },
308 # there is no sane way to order by the right side of a grouped prefetch currently :(
309 #order_by => { -desc => 'owner.name' },
fc85215b 310 });
311
b1e1d073 312
56d2561e 313 is ($books->page(1)->all, 2, 'Prefetched grouped search returns correct number of rows');
314 is ($books->page(1)->count, 2, 'Prefetched grouped search returns correct count');
b1e1d073 315
618a0fe3 316 TODO: {
317 local $TODO = 'limit past end of resultset problem';
56d2561e 318 is ($books->page(2)->all, 1, 'Prefetched grouped search returns correct number of rows');
319 is ($books->page(2)->count, 1, 'Prefetched grouped search returns correct count');
64c7c000 320 is ($books->page(2)->count_rs->next, 1, 'Prefetched grouped search returns correct count_rs');
321
e2751d0b 322 # make sure count does not become overly complex (FIXME - the distinct-induced group_by is incorrect)
64c7c000 323 is_same_sql_bind (
324 $books->page(2)->count_rs->as_query,
325 '(
326 SELECT COUNT( * )
327 FROM (
02d133f0 328 SELECT TOP 2 [me].[id]
329 FROM [books] [me]
330 JOIN [owners] [owner] ON [owner].[id] = [me].[owner]
331 WHERE ( ( ( [owner].[name] = ? OR [owner].[name] = ? ) AND [source] = ? ) )
e2751d0b 332 GROUP BY [me].[id], [me].[source], [me].[owner], [me].[title], [me].[price]
02d133f0 333 ORDER BY [me].[id] DESC
334 ) [count_subq]
64c7c000 335 )',
336 [
337 [ 'owner.name' => 'wiggle' ],
338 [ 'owner.name' => 'woggle' ],
339 [ 'source' => 'Library' ],
340 ],
341 );
618a0fe3 342 }
b9a2c3a5 343}
c1cac633 344
afcfff01 345done_testing;
346
c1cac633 347# clean up our mess
348END {
e06ad5d5 349 if (my $dbh = eval { $schema->storage->_dbh }) {
350 eval { $dbh->do("DROP TABLE $_") }
351 for qw/artist money_test Books Owners/;
352 }
c1cac633 353}
fc85215b 354# vim:sw=2 sts=2