bae2e7c53d3cdb1b80686f323ae0b1da90a81e9b
[dbsrgits/DBIx-Class.git] / t / 746mssql.t
1 use strict;
2 use warnings;
3
4 use Test::More;
5 use lib qw(t/lib);
6 use DBICTest;
7 use DBIC::SqlMakerTest;
8
9 my ($dsn, $user, $pass) = @ENV{map { "DBICTEST_MSSQL_ODBC_${_}" } qw/DSN USER PASS/};
10
11 plan skip_all => 'Set $ENV{DBICTEST_MSSQL_ODBC_DSN}, _USER and _PASS to run this test'
12   unless ($dsn && $user);
13
14 plan tests => 25;
15
16 my $schema = DBICTest::Schema->connect($dsn, $user, $pass);
17
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 }
28
29 isa_ok( $schema->storage, 'DBIx::Class::Storage::DBI::ODBC::Microsoft_SQL_Server' );
30
31 $schema->storage->dbh_do (sub {
32     my ($storage, $dbh) = @_;
33     eval { $dbh->do("DROP TABLE artist") };
34     $dbh->do(<<'SQL');
35
36 CREATE TABLE artist (
37    artistid INT IDENTITY NOT NULL,
38    name VARCHAR(100),
39    rank INT NOT NULL DEFAULT '13',
40    charfield CHAR(10) NULL,
41    primary key(artistid)
42 )
43
44 SQL
45
46 });
47
48 my %seen_id;
49
50 # fresh $schema so we start unconnected
51 $schema = DBICTest::Schema->connect($dsn, $user, $pass);
52
53 # test primary key handling
54 my $new = $schema->resultset('Artist')->create({ name => 'foo' });
55 ok($new->artistid > 0, "Auto-PK worked");
56
57 $seen_id{$new->artistid}++;
58
59 # test LIMIT support
60 for (1..6) {
61     $new = $schema->resultset('Artist')->create({ name => 'Artist ' . $_ });
62     is ( $seen_id{$new->artistid}, undef, "id for Artist $_ is unique" );
63     $seen_id{$new->artistid}++;
64 }
65
66 my $it = $schema->resultset('Artist')->search( {}, {
67     rows => 3,
68     order_by => 'artistid',
69 });
70
71 is( $it->count, 3, "LIMIT count ok" );
72 is( $it->next->name, "foo", "iterator->next ok" );
73 $it->next;
74 is( $it->next->name, "Artist 2", "iterator->next ok" );
75 is( $it->next, undef, "next past end of resultset ok" );
76
77 $schema->storage->dbh_do (sub {
78     my ($storage, $dbh) = @_;
79     eval { $dbh->do("DROP TABLE Owners") };
80     eval { $dbh->do("DROP TABLE Books") };
81     $dbh->do(<<'SQL');
82
83
84 CREATE TABLE Books (
85    id INT IDENTITY (1, 1) NOT NULL,
86    source VARCHAR(100),
87    owner INT,
88    title VARCHAR(10),
89    price INT NULL
90 )
91
92 CREATE TABLE Owners (
93    id INT IDENTITY (1, 1) NOT NULL,
94    name VARCHAR(100),
95 )
96
97 SQL
98
99 });
100 $schema->populate ('Owners', [
101   [qw/id  name  /],
102   [qw/1   wiggle/],
103   [qw/2   woggle/],
104   [qw/3   boggle/],
105   [qw/4   fREW/],
106   [qw/5   fRIOUX/],
107   [qw/6   fROOH/],
108   [qw/7   fRUE/],
109   [qw/8   fISMBoC/],
110   [qw/9   station/],
111   [qw/10   mirror/],
112   [qw/11   dimly/],
113   [qw/12   face_to_face/],
114   [qw/13   icarus/],
115   [qw/14   dream/],
116   [qw/15   dyrstyggyr/],
117 ]);
118
119 $schema->populate ('BooksInLibrary', [
120   [qw/source  owner title   /],
121   [qw/Library 1     secrets0/],
122   [qw/Library 1     secrets1/],
123   [qw/Eatery  1     secrets2/],
124   [qw/Library 2     secrets3/],
125   [qw/Library 3     secrets4/],
126   [qw/Eatery  3     secrets5/],
127   [qw/Library 4     secrets6/],
128   [qw/Library 5     secrets7/],
129   [qw/Eatery  5     secrets8/],
130   [qw/Library 6     secrets9/],
131   [qw/Library 7     secrets10/],
132   [qw/Eatery  7     secrets11/],
133   [qw/Library 8     secrets12/],
134 ]);
135
136 #
137 # try a prefetch on tables with identically named columns
138 #
139
140 # set quote char - make sure things work while quoted
141 $schema->storage->_sql_maker->{quote_char} = [qw/[ ]/];
142 $schema->storage->_sql_maker->{name_sep} = '.';
143
144 {
145   # try a ->has_many direction (group_by is not possible on has_many with limit)
146   my $owners = $schema->resultset ('Owners')->search ({
147       'books.id' => { '!=', undef }
148     }, {
149       prefetch => 'books',
150       order_by => 'name',
151       rows     => 3,  # 8 results total
152     });
153
154   is ($owners->page(1)->all, 3, 'has_many prefetch returns correct number of rows');
155   is ($owners->page(1)->count, 3, 'has-many prefetch returns correct count');
156
157   TODO: {
158     local $TODO = 'limit past end of resultset problem';
159     is ($owners->page(3)->all, 2, 'has_many prefetch returns correct number of rows');
160     is ($owners->page(3)->count, 2, 'has-many prefetch returns correct count');
161     is ($owners->page(3)->count_rs->next, 2, 'has-many prefetch returns correct count_rs');
162
163     # make sure count does not become overly complex FIXME
164     is_same_sql_bind (
165       $owners->page(3)->count_rs->as_query,
166       '(
167         SELECT COUNT( * )
168           FROM (
169             SELECT TOP 3 [me].[id]
170               FROM [owners] [me]
171               LEFT JOIN [books] [books] ON [books].[owner] = [me].[id]
172             WHERE ( [books].[id] IS NOT NULL )
173             GROUP BY [me].[id]
174             ORDER BY [me].[id] DESC
175           ) [count_subq]
176       )',
177       [],
178     );
179   }
180
181   # try a ->belongs_to direction (no select collapse, group_by should work)
182   my $books = $schema->resultset ('BooksInLibrary')->search ({
183       'owner.name' => [qw/wiggle woggle/],
184     }, {
185       distinct => 1,
186       prefetch => 'owner',
187       order_by => 'name',
188       rows     => 2,  # 3 results total
189     });
190
191
192   is ($books->page(1)->all, 2, 'Prefetched grouped search returns correct number of rows');
193   is ($books->page(1)->count, 2, 'Prefetched grouped search returns correct count');
194
195   TODO: {
196     local $TODO = 'limit past end of resultset problem';
197     is ($books->page(2)->all, 1, 'Prefetched grouped search returns correct number of rows');
198     is ($books->page(2)->count, 1, 'Prefetched grouped search returns correct count');
199     is ($books->page(2)->count_rs->next, 1, 'Prefetched grouped search returns correct count_rs');
200
201     # make sure count does not become overly complex FIXME
202     is_same_sql_bind (
203       $books->page(2)->count_rs->as_query,
204       '(
205         SELECT COUNT( * )
206           FROM (
207             SELECT TOP 2 [me].[id]
208               FROM [books] [me]
209               JOIN [owners] [owner] ON [owner].[id] = [me].[owner]
210             WHERE ( ( ( [owner].[name] = ? OR [owner].[name] = ? ) AND [source] = ? ) )
211             GROUP BY [me].[id], [me].[source], [me].[owner], [me].[title], [me].[price], [owner].[id], [owner].[name]
212             ORDER BY [me].[id] DESC
213           ) [count_subq]
214       )',
215       [
216         [ 'owner.name' => 'wiggle' ],
217         [ 'owner.name' => 'woggle' ],
218         [ 'source' => 'Library' ],
219       ],
220     );
221   }
222
223 }
224
225 # clean up our mess
226 END {
227     my $dbh = eval { $schema->storage->_dbh };
228     $dbh->do('DROP TABLE artist') if $dbh;
229 }
230 # vim:sw=2 sts=2