Check truth of preserve_case not definedness
[dbsrgits/DBIx-Class-Schema-Loader.git] / t / 10_06sybase_common.t
CommitLineData
fe67d343 1use strict;
c4a69b87 2use warnings;
804c115d 3use Test::More;
2d1dc6de 4use Test::Exception;
c4a69b87 5use Try::Tiny;
6use File::Path 'rmtree';
7use DBIx::Class::Schema::Loader 'make_schema_at';
5975bbe6 8use namespace::clean;
c4a69b87 9use DBI ();
10
11use lib qw(t/lib);
12
13use dbixcsl_common_tests ();
14use dbixcsl_test_dir '$tdir';
15
16use constant EXTRA_DUMP_DIR => "$tdir/sybase_extra_dump";
f9f65ded 17
fe67d343 18my $dsn = $ENV{DBICTEST_SYBASE_DSN} || '';
19my $user = $ENV{DBICTEST_SYBASE_USER} || '';
20my $password = $ENV{DBICTEST_SYBASE_PASS} || '';
21
4c2e2ce9 22BEGIN { $ENV{DBIC_SYBASE_FREETDS_NOWARN} = 1 }
23
c4a69b87 24my ($schema, $databases_created); # for cleanup in END for extra tests
25
fe67d343 26my $tester = dbixcsl_common_tests->new(
7cb9244f 27 vendor => 'sybase',
fe67d343 28 auto_inc_pk => 'INTEGER IDENTITY NOT NULL PRIMARY KEY',
41968729 29 default_function => 'getdate()',
30 default_function_def => 'AS getdate()',
fe67d343 31 dsn => $dsn,
32 user => $user,
33 password => $password,
5163dc4a 34 data_types => {
760fd65c 35 # http://ispirer.com/wiki/sqlways/sybase/data-types
6bbfc7ed 36 #
37 # Numeric Types
5163dc4a 38 'integer identity' => { data_type => 'integer', is_auto_increment => 1 },
5163dc4a 39 int => { data_type => 'integer' },
40 integer => { data_type => 'integer' },
6bbfc7ed 41 bigint => { data_type => 'bigint' },
5163dc4a 42 smallint => { data_type => 'smallint' },
43 tinyint => { data_type => 'tinyint' },
6bbfc7ed 44 'double precision' => { data_type => 'double precision' },
45 real => { data_type => 'real' },
46 float => { data_type => 'double precision' },
47 'float(14)' => { data_type => 'real' },
48 'float(15)' => { data_type => 'real' },
49 'float(16)' => { data_type => 'double precision' },
50 'float(48)' => { data_type => 'double precision' },
51 'numeric(6,3)' => { data_type => 'numeric', size => [6,3] },
52 'decimal(6,3)' => { data_type => 'numeric', size => [6,3] },
53 numeric => { data_type => 'numeric' },
54 decimal => { data_type => 'numeric' },
55 bit => { data_type => 'bit' },
56
57 # Money Types
58 money => { data_type => 'money' },
59 smallmoney => { data_type => 'smallmoney' },
60
61 # Computed Column
62 'AS getdate()' => { data_type => undef, inflate_datetime => 1, default_value => \'getdate()' },
63
64 # Blob Types
65 text => { data_type => 'text' },
66 unitext => { data_type => 'unitext' },
67 image => { data_type => 'image' },
68
69 # DateTime Types
5163dc4a 70 date => { data_type => 'date' },
71 time => { data_type => 'time' },
72 datetime => { data_type => 'datetime' },
73 smalldatetime => { data_type => 'smalldatetime' },
6bbfc7ed 74
75 # Timestamp column
5163dc4a 76 timestamp => { data_type => 'timestamp', inflate_datetime => 0 },
6bbfc7ed 77
78 # String Types
79 'char' => { data_type => 'char', size => 1 },
5163dc4a 80 'char(2)' => { data_type => 'char', size => 2 },
6bbfc7ed 81 'nchar' => { data_type => 'nchar', size => 1 },
5163dc4a 82 'nchar(2)' => { data_type => 'nchar', size => 2 },
83 'unichar(2)' => { data_type => 'unichar', size => 2 },
84 'varchar(2)' => { data_type => 'varchar', size => 2 },
85 'nvarchar(2)' => { data_type => 'nvarchar', size => 2 },
86 'univarchar(2)' => { data_type => 'univarchar', size => 2 },
6bbfc7ed 87
88 # Binary Types
89 'binary' => { data_type => 'binary', size => 1 },
5163dc4a 90 'binary(2)' => { data_type => 'binary', size => 2 },
91 'varbinary(2)' => { data_type => 'varbinary', size => 2 },
804c115d 92 },
8f65b7e5 93 # test that named constraints aren't picked up as tables (I can't reproduce this on my machine)
94 failtrigger_warnings => [ qr/^Bad table or view 'sybase_loader_test2_ref_slt1'/ ],
5c1b0a23 95 extra => {
96 create => [
97 q{
98 CREATE TABLE sybase_loader_test1 (
99 id int identity primary key
100 )
101 },
102 q{
103 CREATE TABLE sybase_loader_test2 (
104 id int identity primary key,
105 sybase_loader_test1_id int,
106 CONSTRAINT sybase_loader_test2_ref_slt1 FOREIGN KEY (sybase_loader_test1_id) REFERENCES sybase_loader_test1 (id)
107 )
108 },
109 ],
110 drop => [ qw/sybase_loader_test1 sybase_loader_test2/ ],
5975bbe6 111 count => 30 * 4,
c4a69b87 112 run => sub {
113 $schema = shift;
114
115 SKIP: {
116 my $dbh = $schema->storage->dbh;
117
118 try {
119 $dbh->do('USE master');
120 }
121 catch {
5975bbe6 122 skip "these tests require the sysadmin role", 30 * 4;
c4a69b87 123 };
124
125 try {
126 $dbh->do('CREATE DATABASE [dbicsl_test1]');
127 $dbh->do('CREATE DATABASE [dbicsl_test2]');
128 }
129 catch {
5975bbe6 130 skip "cannot create databases: $_", 30 * 4;
c4a69b87 131 };
132
133 try {
134 my $warn_handler = $SIG{__WARN__} || sub { warn @_ };
135 local $SIG{__WARN__} = sub {
136 $warn_handler->(@_)
137 unless $_[0] =~ /^Password correctly set\.$|^Account unlocked\.$|^New login created\.$|^New user added\.$/;
138 };
139
140 $dbh->do("sp_addlogin dbicsl_user1, dbicsl, [dbicsl_test1]");
141 $dbh->do("sp_addlogin dbicsl_user2, dbicsl, [dbicsl_test2]");
142
143 $dbh->do("USE [dbicsl_test1]");
144 $dbh->do("sp_adduser dbicsl_user1");
145 $dbh->do("sp_adduser dbicsl_user2");
146 $dbh->do("GRANT ALL TO dbicsl_user1");
147 $dbh->do("GRANT ALL TO dbicsl_user2");
148
149 $dbh->do("USE [dbicsl_test2]");
150 $dbh->do("sp_adduser dbicsl_user2");
151 $dbh->do("sp_adduser dbicsl_user1");
152 $dbh->do("GRANT ALL TO dbicsl_user2");
153 $dbh->do("GRANT ALL TO dbicsl_user1");
154 }
155 catch {
5975bbe6 156 skip "cannot add logins: $_", 30 * 4;
c4a69b87 157 };
158
159 my ($dbh1, $dbh2);
160 {
161 my $warn_handler = $SIG{__WARN__} || sub { warn @_ };
162 local $SIG{__WARN__} = sub {
163 $warn_handler->(@_) unless $_[0] =~ /can't change context/;
164 };
165
166 $dbh1 = DBI->connect($dsn, 'dbicsl_user1', 'dbicsl', {
167 RaiseError => 1,
168 PrintError => 0,
169 });
170 $dbh1->do('USE [dbicsl_test1]');
171
172 $dbh2 = DBI->connect($dsn, 'dbicsl_user2', 'dbicsl', {
173 RaiseError => 1,
174 PrintError => 0,
175 });
176 $dbh2->do('USE [dbicsl_test2]');
177 }
178
179 $dbh1->do(<<"EOF");
180 CREATE TABLE sybase_loader_test4 (
181 id INT IDENTITY PRIMARY KEY,
182 value VARCHAR(100) NULL
183 )
184EOF
185 $dbh1->do('GRANT ALL ON sybase_loader_test4 TO dbicsl_user2');
186 $dbh1->do(<<"EOF");
187 CREATE TABLE sybase_loader_test5 (
188 id INT IDENTITY PRIMARY KEY,
189 value VARCHAR(100) NULL,
5975bbe6 190 four_id INTEGER,
191 CONSTRAINT loader_test5_uniq UNIQUE (four_id),
c4a69b87 192 FOREIGN KEY (four_id) REFERENCES sybase_loader_test4 (id)
193 )
194EOF
195 $dbh2->do(<<"EOF");
5975bbe6 196 CREATE TABLE sybase_loader_test5 (
197 pk INT IDENTITY PRIMARY KEY,
198 value VARCHAR(100) NULL,
199 four_id INTEGER,
200 CONSTRAINT loader_test5_uniq UNIQUE (four_id),
201 FOREIGN KEY (four_id) REFERENCES [dbicsl_test1].dbicsl_user1.sybase_loader_test4 (id)
202 )
203EOF
204 $dbh2->do(<<"EOF");
c4a69b87 205 CREATE TABLE sybase_loader_test6 (
206 id INT IDENTITY PRIMARY KEY,
207 value VARCHAR(100) NULL,
208 sybase_loader_test4_id INTEGER NULL,
209 FOREIGN KEY (sybase_loader_test4_id) REFERENCES [dbicsl_test1].dbicsl_user1.sybase_loader_test4 (id)
210 )
211EOF
212 $dbh2->do(<<"EOF");
213 CREATE TABLE sybase_loader_test7 (
214 id INT IDENTITY PRIMARY KEY,
215 value VARCHAR(100) NULL,
216 six_id INTEGER UNIQUE,
217 FOREIGN KEY (six_id) REFERENCES sybase_loader_test6 (id)
218 )
219EOF
220 $dbh2->do('GRANT ALL ON sybase_loader_test7 TO dbicsl_user1');
221 $dbh1->do(<<"EOF");
222 CREATE TABLE sybase_loader_test8 (
223 id INT IDENTITY PRIMARY KEY,
224 value VARCHAR(100) NULL,
225 sybase_loader_test7_id INTEGER,
226 FOREIGN KEY (sybase_loader_test7_id) REFERENCES [dbicsl_test2].dbicsl_user2.sybase_loader_test7 (id)
227 )
228EOF
229
230 $databases_created = 1;
231
232 foreach my $databases (['dbicsl_test1', 'dbicsl_test2'], '%') {
233 foreach my $owners ([qw/dbicsl_user1 dbicsl_user2/], '%') {
234 lives_and {
235 rmtree EXTRA_DUMP_DIR;
236
237 my @warns;
238 local $SIG{__WARN__} = sub {
239 push @warns, $_[0] unless $_[0] =~ /\bcollides\b/
240 || $_[0] =~ /can't change context/;
241 };
242
243 my $database = $databases;
244
245 $database = [ $database ] unless ref $database;
246
247 my $db_schema = {};
248
249 foreach my $db (@$database) {
250 $db_schema->{$db} = $owners;
251 }
252
253 make_schema_at(
254 'SybaseMultiSchema',
255 {
256 naming => 'current',
257 db_schema => $db_schema,
258 dump_directory => EXTRA_DUMP_DIR,
259 quiet => 1,
260 },
261 [ $dsn, $user, $password ],
262 );
263
e17ad40a 264 SybaseMultiSchema->storage->disconnect;
265
c4a69b87 266 diag join "\n", @warns if @warns;
267
268 is @warns, 0;
269 } 'dumped schema for "dbicsl_test1" and "dbicsl_test2" databases with no warnings';
270
271 my ($test_schema, $rsrc, $rs, $row, %uniqs, $rel_info);
272
273 lives_and {
274 ok $test_schema = SybaseMultiSchema->connect($dsn, $user, $password);
275 } 'connected test schema';
276
277 lives_and {
4c2e2ce9 278 ok $rsrc = $test_schema->source('SybaseLoaderTest4');
c4a69b87 279 } 'got source for table in database one';
280
281 is try { $rsrc->column_info('id')->{is_auto_increment} }, 1,
282 'column in database one';
283
284 is try { $rsrc->column_info('value')->{data_type} }, 'varchar',
285 'column in database one';
286
287 is try { $rsrc->column_info('value')->{size} }, 100,
288 'column in database one';
289
290 lives_and {
4c2e2ce9 291 ok $rs = $test_schema->resultset('SybaseLoaderTest4');
c4a69b87 292 } 'got resultset for table in database one';
293
294 lives_and {
295 ok $row = $rs->create({ value => 'foo' });
296 } 'executed SQL on table in database one';
297
5975bbe6 298 $rel_info = try { $rsrc->relationship_info('dbicsl_test1_sybase_loader_test5') };
c4a69b87 299
300 is_deeply $rel_info->{cond}, {
301 'foreign.four_id' => 'self.id'
302 }, 'relationship in database one';
303
304 is $rel_info->{attrs}{accessor}, 'single',
305 'relationship in database one';
306
307 is $rel_info->{attrs}{join_type}, 'LEFT',
308 'relationship in database one';
309
310 lives_and {
5975bbe6 311 ok $rsrc = $test_schema->source('DbicslTest1SybaseLoaderTest5');
c4a69b87 312 } 'got source for table in database one';
313
314 %uniqs = try { $rsrc->unique_constraints };
315
316 is keys %uniqs, 2,
317 'got unique and primary constraint in database one';
318
5975bbe6 319 delete $uniqs{primary};
320
321 is_deeply ((values %uniqs)[0], ['four_id'],
322 'correct unique constraint in database one');
323
c4a69b87 324 lives_and {
4c2e2ce9 325 ok $rsrc = $test_schema->source('SybaseLoaderTest6');
c4a69b87 326 } 'got source for table in database two';
327
328 is try { $rsrc->column_info('id')->{is_auto_increment} }, 1,
329 'column in database two introspected correctly';
330
331 is try { $rsrc->column_info('value')->{data_type} }, 'varchar',
332 'column in database two introspected correctly';
333
334 is try { $rsrc->column_info('value')->{size} }, 100,
335 'column in database two introspected correctly';
336
337 lives_and {
4c2e2ce9 338 ok $rs = $test_schema->resultset('SybaseLoaderTest6');
c4a69b87 339 } 'got resultset for table in database two';
340
341 lives_and {
342 ok $row = $rs->create({ value => 'foo' });
343 } 'executed SQL on table in database two';
344
345 $rel_info = try { $rsrc->relationship_info('sybase_loader_test7') };
346
347 is_deeply $rel_info->{cond}, {
348 'foreign.six_id' => 'self.id'
349 }, 'relationship in database two';
350
351 is $rel_info->{attrs}{accessor}, 'single',
352 'relationship in database two';
353
354 is $rel_info->{attrs}{join_type}, 'LEFT',
355 'relationship in database two';
356
357 lives_and {
4c2e2ce9 358 ok $rsrc = $test_schema->source('SybaseLoaderTest7');
c4a69b87 359 } 'got source for table in database two';
360
361 %uniqs = try { $rsrc->unique_constraints };
362
363 is keys %uniqs, 2,
364 'got unique and primary constraint in database two';
365
5975bbe6 366 delete $uniqs{primary};
367
368 is_deeply ((values %uniqs)[0], ['six_id'],
369 'correct unique constraint in database two');
370
c4a69b87 371 lives_and {
4c2e2ce9 372 ok $test_schema->source('SybaseLoaderTest6')
c4a69b87 373 ->has_relationship('sybase_loader_test4');
374 } 'cross-database relationship in multi database schema';
375
376 lives_and {
4c2e2ce9 377 ok $test_schema->source('SybaseLoaderTest4')
c4a69b87 378 ->has_relationship('sybase_loader_test6s');
379 } 'cross-database relationship in multi database schema';
380
381 lives_and {
4c2e2ce9 382 ok $test_schema->source('SybaseLoaderTest8')
c4a69b87 383 ->has_relationship('sybase_loader_test7');
384 } 'cross-database relationship in multi database schema';
385
386 lives_and {
4c2e2ce9 387 ok $test_schema->source('SybaseLoaderTest7')
c4a69b87 388 ->has_relationship('sybase_loader_test8s');
389 } 'cross-database relationship in multi database schema';
390 }
391 }
392 }
393 },
5c1b0a23 394 },
fe67d343 395);
396
397if( !$dsn || !$user ) {
398 $tester->skip_tests('You need to set the DBICTEST_SYBASE_DSN, _USER, and _PASS environment variables');
399}
400else {
401 $tester->run_tests();
402}
5c1b0a23 403
c4a69b87 404END {
405 if (not $ENV{SCHEMA_LOADER_TESTS_NOCLEANUP}) {
406 rmtree EXTRA_DUMP_DIR;
407
408 if ($databases_created) {
409 my $dbh = $schema->storage->dbh;
410
411 $dbh->do('USE master');
412
413 local $dbh->{FetchHashKeyName} = 'NAME_lc';
414
415 my $sth = $dbh->prepare('sp_who');
416 $sth->execute;
417
418 while (my $row = $sth->fetchrow_hashref) {
419 if ($row->{dbname} =~ /^dbicsl_test[12]\z/) {
420 $dbh->do("kill $row->{spid}");
421 }
422 }
423
424 foreach my $table ('[dbicsl_test1].dbicsl_user1.sybase_loader_test8',
425 '[dbicsl_test2].dbicsl_user2.sybase_loader_test7',
426 '[dbicsl_test2].dbicsl_user2.sybase_loader_test6',
5975bbe6 427 '[dbicsl_test2].dbicsl_user2.sybase_loader_test5',
c4a69b87 428 '[dbicsl_test1].dbicsl_user1.sybase_loader_test5',
429 '[dbicsl_test1].dbicsl_user1.sybase_loader_test4') {
430 try {
431 $dbh->do("DROP TABLE $table");
432 }
433 catch {
434 diag "Error dropping table $table: $_";
435 };
436 }
437
438 foreach my $db (qw/dbicsl_test1 dbicsl_test2/) {
439 try {
440 $dbh->do("DROP DATABASE [$db]");
441 }
442 catch {
443 diag "Error dropping test database $db: $_";
444 };
445 }
446
447 foreach my $login (qw/dbicsl_user1 dbicsl_user2/) {
448 try {
449 my $warn_handler = $SIG{__WARN__} || sub { warn @_ };
450 local $SIG{__WARN__} = sub {
451 $warn_handler->(@_)
452 unless $_[0] =~ /^Account locked\.$|^Login dropped\.$/;
453 };
454
455 $dbh->do("sp_droplogin $login");
456 }
457 catch {
458 diag "Error dropping login $login: $_"
459 unless /Incorrect syntax/;
460 };
461 }
462 }
463 }
464}
5c1b0a23 465# vim:et sts=4 sw=4 tw=0: