Check truth of preserve_case not definedness
[dbsrgits/DBIx-Class-Schema-Loader.git] / t / 10_03pg_common.t
CommitLineData
a78e3fed 1use strict;
fcf328c7 2use warnings;
3use utf8;
12b86f07 4use DBIx::Class::Schema::Loader 'make_schema_at';
fcf328c7 5use DBIx::Class::Schema::Loader::Utils qw/no_warnings slurp_file/;
fdd8ff16 6use Test::More;
12b86f07 7use Test::Exception;
12b86f07 8use Try::Tiny;
c4a69b87 9use File::Path 'rmtree';
fcf328c7 10use namespace::clean;
c4a69b87 11
fcf328c7 12use lib qw(t/lib);
13use dbixcsl_common_tests ();
c4a69b87 14use dbixcsl_test_dir '$tdir';
15
16use constant EXTRA_DUMP_DIR => "$tdir/pg_extra_dump";
a78e3fed 17
9e978a19 18my $dsn = $ENV{DBICTEST_PG_DSN} || '';
19my $user = $ENV{DBICTEST_PG_USER} || '';
20my $password = $ENV{DBICTEST_PG_PASS} || '';
a78e3fed 21
fbd83464 22my $tester = dbixcsl_common_tests->new(
a78e3fed 23 vendor => 'Pg',
24 auto_inc_pk => 'SERIAL NOT NULL PRIMARY KEY',
9e978a19 25 dsn => $dsn,
a78e3fed 26 user => $user,
27 password => $password,
c930f78b 28 loader_options => { preserve_case => 1 },
c38ec663 29 connect_info_opts => {
af15ea33 30 pg_enable_utf8 => 1,
31 on_connect_do => [ 'SET client_min_messages=WARNING' ],
c38ec663 32 },
c930f78b 33 quote_char => '"',
ee07e280 34 data_types => {
760fd65c 35 # http://www.postgresql.org/docs/7.4/interactive/datatype.html
36 #
37 # Numeric Types
38 boolean => { data_type => 'boolean' },
39 bool => { data_type => 'boolean' },
45321eda 40 'bool default false'
41 => { data_type => 'boolean', default_value => \'false' },
96336646 42 'bool default true'
43 => { data_type => 'boolean', default_value => \'true' },
44 'bool default 0::bool'
45 => { data_type => 'boolean', default_value => \'false' },
46 'bool default 1::bool'
47 => { data_type => 'boolean', default_value => \'true' },
760fd65c 48
49 bigint => { data_type => 'bigint' },
50 int8 => { data_type => 'bigint' },
51 bigserial => { data_type => 'bigint', is_auto_increment => 1 },
52 serial8 => { data_type => 'bigint', is_auto_increment => 1 },
5163dc4a 53 integer => { data_type => 'integer' },
54 int => { data_type => 'integer' },
55 int4 => { data_type => 'integer' },
5163dc4a 56 serial => { data_type => 'integer', is_auto_increment => 1 },
57 serial4 => { data_type => 'integer', is_auto_increment => 1 },
760fd65c 58 smallint => { data_type => 'smallint' },
59 int2 => { data_type => 'smallint' },
60
61 money => { data_type => 'money' },
62
63 'double precision' => { data_type => 'double precision' },
64 float8 => { data_type => 'double precision' },
65 real => { data_type => 'real' },
66 float4 => { data_type => 'real' },
67 'float(24)' => { data_type => 'real' },
68 'float(25)' => { data_type => 'double precision' },
69 'float(53)' => { data_type => 'double precision' },
70 float => { data_type => 'double precision' },
71
72 numeric => { data_type => 'numeric' },
73 decimal => { data_type => 'numeric' },
f80b0ea7 74 'numeric(6,3)' => { data_type => 'numeric', size => [6,3] },
75 'decimal(6,3)' => { data_type => 'numeric', size => [6,3] },
760fd65c 76
77 # Bit String Types
f80b0ea7 78 'bit varying(2)' => { data_type => 'varbit', size => 2 },
79 'varbit(2)' => { data_type => 'varbit', size => 2 },
80 'varbit' => { data_type => 'varbit' },
81 bit => { data_type => 'bit', size => 1 },
82 'bit(3)' => { data_type => 'bit', size => 3 },
760fd65c 83
84 # Network Types
85 inet => { data_type => 'inet' },
86 cidr => { data_type => 'cidr' },
87 macaddr => { data_type => 'macaddr' },
88
89 # Geometric Types
90 point => { data_type => 'point' },
91 line => { data_type => 'line' },
92 lseg => { data_type => 'lseg' },
93 box => { data_type => 'box' },
94 path => { data_type => 'path' },
95 polygon => { data_type => 'polygon' },
96 circle => { data_type => 'circle' },
97
98 # Character Types
f80b0ea7 99 'character varying(2)' => { data_type => 'varchar', size => 2 },
100 'varchar(2)' => { data_type => 'varchar', size => 2 },
101 'character(2)' => { data_type => 'char', size => 2 },
102 'char(2)' => { data_type => 'char', size => 2 },
87a43db1 103 # check that default null is correctly rewritten
104 'char(3) default null' => { data_type => 'char', size => 3,
105 default_value => \'null' },
f80b0ea7 106 'character' => { data_type => 'char', size => 1 },
107 'char' => { data_type => 'char', size => 1 },
760fd65c 108 text => { data_type => 'text' },
f80b0ea7 109 # varchar with no size has unlimited size, we rewrite to 'text'
8e030521 110 varchar => { data_type => 'text',
111 original => { data_type => 'varchar' } },
87a43db1 112 # check default null again (to make sure ref is safe)
113 'varchar(3) default null' => { data_type => 'varchar', size => 3,
96336646 114 default_value => \'null' },
760fd65c 115
116 # Datetime Types
117 date => { data_type => 'date' },
118 interval => { data_type => 'interval' },
f80b0ea7 119 'interval(2)' => { data_type => 'interval', size => 2 },
8e030521 120 time => { data_type => 'time' },
121 'time(2)' => { data_type => 'time', size => 2 },
122 'time without time zone' => { data_type => 'time' },
123 'time(2) without time zone' => { data_type => 'time', size => 2 },
df956aad 124 'time with time zone' => { data_type => 'time with time zone' },
f80b0ea7 125 'time(2) with time zone' => { data_type => 'time with time zone', size => 2 },
126 timestamp => { data_type => 'timestamp' },
701cd3e3 127 'timestamp default now()'
128 => { data_type => 'timestamp', default_value => \'current_timestamp',
129 original => { default_value => \'now()' } },
f80b0ea7 130 'timestamp(2)' => { data_type => 'timestamp', size => 2 },
131 'timestamp without time zone' => { data_type => 'timestamp' },
132 'timestamp(2) without time zone' => { data_type => 'timestamp', size => 2 },
760fd65c 133
df956aad 134 'timestamp with time zone' => { data_type => 'timestamp with time zone' },
f80b0ea7 135 'timestamp(2) with time zone' => { data_type => 'timestamp with time zone', size => 2 },
760fd65c 136
137 # Blob Types
138 bytea => { data_type => 'bytea' },
12333562 139
140 # Enum Types
b8ae4518 141 pg_loader_test_enum => { data_type => 'enum', extra => { custom_type_name => 'pg_loader_test_enum',
463c86fb 142 list => [ qw/foo bar baz/] } },
ee07e280 143 },
12333562 144 pre_create => [
145 q{
146 CREATE TYPE pg_loader_test_enum AS ENUM (
147 'foo', 'bar', 'baz'
148 )
149 },
150 ],
fdd8ff16 151 extra => {
152 create => [
153 q{
7b868481 154 CREATE SCHEMA dbicsl_test
155 },
156 q{
157 CREATE SEQUENCE dbicsl_test.myseq
158 },
159 q{
fdd8ff16 160 CREATE TABLE pg_loader_test1 (
7b868481 161 id INTEGER NOT NULL DEFAULT nextval('dbicsl_test.myseq') PRIMARY KEY,
fdd8ff16 162 value VARCHAR(100)
163 )
164 },
fd97abca 165 qq{
af15ea33 166 COMMENT ON TABLE pg_loader_test1 IS 'The\15\12Table ∑'
fdd8ff16 167 },
fd97abca 168 qq{
169 COMMENT ON COLUMN pg_loader_test1.value IS 'The\15\12Column'
fdd8ff16 170 },
4b9fb838 171 q{
172 CREATE TABLE pg_loader_test2 (
12b86f07 173 id SERIAL PRIMARY KEY,
4b9fb838 174 value VARCHAR(100)
175 )
176 },
177 q{
178 COMMENT ON TABLE pg_loader_test2 IS 'very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very long comment'
179 },
12b86f07 180 q{
181 CREATE SCHEMA "dbicsl-test"
182 },
183 q{
c4a69b87 184 CREATE TABLE "dbicsl-test".pg_loader_test4 (
12b86f07 185 id SERIAL PRIMARY KEY,
186 value VARCHAR(100)
187 )
188 },
189 q{
c4a69b87 190 CREATE TABLE "dbicsl-test".pg_loader_test5 (
12b86f07 191 id SERIAL PRIMARY KEY,
192 value VARCHAR(100),
5975bbe6 193 four_id INTEGER REFERENCES "dbicsl-test".pg_loader_test4 (id),
194 CONSTRAINT loader_test5_uniq UNIQUE (four_id)
12b86f07 195 )
196 },
197 q{
198 CREATE SCHEMA "dbicsl.test"
199 },
200 q{
5975bbe6 201 CREATE TABLE "dbicsl.test".pg_loader_test5 (
202 pk SERIAL PRIMARY KEY,
203 value VARCHAR(100),
204 four_id INTEGER REFERENCES "dbicsl-test".pg_loader_test4 (id),
205 CONSTRAINT loader_test5_uniq UNIQUE (four_id)
206 )
207 },
208 q{
c4a69b87 209 CREATE TABLE "dbicsl.test".pg_loader_test6 (
12b86f07 210 id SERIAL PRIMARY KEY,
c4a69b87 211 value VARCHAR(100),
212 pg_loader_test4_id INTEGER REFERENCES "dbicsl-test".pg_loader_test4 (id)
12b86f07 213 )
214 },
215 q{
c4a69b87 216 CREATE TABLE "dbicsl.test".pg_loader_test7 (
217 id SERIAL PRIMARY KEY,
218 value VARCHAR(100),
219 six_id INTEGER UNIQUE REFERENCES "dbicsl.test".pg_loader_test6 (id)
220 )
221 },
222 q{
223 CREATE TABLE "dbicsl-test".pg_loader_test8 (
12b86f07 224 id SERIAL PRIMARY KEY,
225 value VARCHAR(100),
c4a69b87 226 pg_loader_test7_id INTEGER REFERENCES "dbicsl.test".pg_loader_test7 (id)
12b86f07 227 )
228 },
fdd8ff16 229 ],
7b868481 230 pre_drop_ddl => [
231 'DROP SCHEMA dbicsl_test CASCADE',
12b86f07 232 'DROP SCHEMA "dbicsl-test" CASCADE',
233 'DROP SCHEMA "dbicsl.test" CASCADE',
12333562 234 'DROP TYPE pg_loader_test_enum',
7b868481 235 ],
9065de34 236 drop => [ qw/ pg_loader_test1 pg_loader_test2 / ],
5975bbe6 237 count => 4 + 30 * 2,
fdd8ff16 238 run => sub {
239 my ($schema, $monikers, $classes) = @_;
240
7b868481 241 is $schema->source($monikers->{pg_loader_test1})->column_info('id')->{sequence},
242 'dbicsl_test.myseq',
243 'qualified sequence detected';
244
fdd8ff16 245 my $class = $classes->{pg_loader_test1};
c4a69b87 246 my $filename = $schema->loader->get_dump_filename($class);
fdd8ff16 247
fcf328c7 248 my $code = slurp_file $filename;
fdd8ff16 249
af15ea33 250 like $code, qr/^=head1 NAME\n\n^$class - The\nTable ∑\n\n^=cut\n/m,
fdd8ff16 251 'table comment';
252
fd97abca 253 like $code, qr/^=head2 value\n\n(.+:.+\n)+\nThe\nColumn\n\n/m,
79a00530 254 'column comment and attrs';
baff904e 255
4b9fb838 256 $class = $classes->{pg_loader_test2};
c4a69b87 257 $filename = $schema->loader->get_dump_filename($class);
4b9fb838 258
fcf328c7 259 $code = slurp_file $filename;
4b9fb838 260
261 like $code, qr/^=head1 NAME\n\n^$class\n\n=head1 DESCRIPTION\n\n^very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very long comment\n\n^=cut\n/m,
262 'long table comment is in DESCRIPTION';
12b86f07 263
c4a69b87 264 foreach my $db_schema (['dbicsl-test', 'dbicsl.test'], '%') {
265 lives_and {
266 rmtree EXTRA_DUMP_DIR;
267
268 my @warns;
269 local $SIG{__WARN__} = sub {
270 push @warns, $_[0] unless $_[0] =~ /\bcollides\b/;
271 };
272
12b86f07 273 make_schema_at(
c4a69b87 274 'PGMultiSchema',
12b86f07 275 {
276 naming => 'current',
c4a69b87 277 db_schema => $db_schema,
12b86f07 278 preserve_case => 1,
c4a69b87 279 dump_directory => EXTRA_DUMP_DIR,
280 quiet => 1,
12b86f07 281 },
282 [ $dsn, $user, $password, {
283 on_connect_do => [ 'SET client_min_messages=WARNING' ],
284 } ],
285 );
12b86f07 286
c4a69b87 287 diag join "\n", @warns if @warns;
12b86f07 288
c4a69b87 289 is @warns, 0;
290 } 'dumped schema for "dbicsl-test" and "dbicsl.test" schemas with no warnings';
12b86f07 291
c4a69b87 292 my ($test_schema, $rsrc, $rs, $row, %uniqs, $rel_info);
12b86f07 293
c4a69b87 294 lives_and {
295 ok $test_schema = PGMultiSchema->connect($dsn, $user, $password, {
296 on_connect_do => [ 'SET client_min_messages=WARNING' ],
297 });
298 } 'connected test schema';
12b86f07 299
c4a69b87 300 lives_and {
4c2e2ce9 301 ok $rsrc = $test_schema->source('PgLoaderTest4');
c4a69b87 302 } 'got source for table in schema name with dash';
12b86f07 303
c4a69b87 304 is try { $rsrc->column_info('id')->{is_auto_increment} }, 1,
305 'column in schema name with dash';
12b86f07 306
c4a69b87 307 is try { $rsrc->column_info('value')->{data_type} }, 'varchar',
308 'column in schema name with dash';
12b86f07 309
c4a69b87 310 is try { $rsrc->column_info('value')->{size} }, 100,
311 'column in schema name with dash';
12b86f07 312
c4a69b87 313 lives_and {
4c2e2ce9 314 ok $rs = $test_schema->resultset('PgLoaderTest4');
c4a69b87 315 } 'got resultset for table in schema name with dash';
12b86f07 316
c4a69b87 317 lives_and {
318 ok $row = $rs->create({ value => 'foo' });
319 } 'executed SQL on table in schema name with dash';
12b86f07 320
5975bbe6 321 $rel_info = try { $rsrc->relationship_info('dbicsl_dash_test_pg_loader_test5') };
12b86f07 322
c4a69b87 323 is_deeply $rel_info->{cond}, {
324 'foreign.four_id' => 'self.id'
325 }, 'relationship in schema name with dash';
12b86f07 326
c4a69b87 327 is $rel_info->{attrs}{accessor}, 'single',
328 'relationship in schema name with dash';
329
330 is $rel_info->{attrs}{join_type}, 'LEFT',
331 'relationship in schema name with dash';
332
333 lives_and {
5975bbe6 334 ok $rsrc = $test_schema->source('DbicslDashTestPgLoaderTest5');
c4a69b87 335 } 'got source for table in schema name with dash';
336
337 %uniqs = try { $rsrc->unique_constraints };
12b86f07 338
c4a69b87 339 is keys %uniqs, 2,
340 'got unique and primary constraint in schema name with dash';
12b86f07 341
5975bbe6 342 delete $uniqs{primary};
343
344 is_deeply ((values %uniqs)[0], ['four_id'],
345 'unique constraint is correct in schema name with dash');
346
c4a69b87 347 lives_and {
4c2e2ce9 348 ok $rsrc = $test_schema->source('PgLoaderTest6');
c4a69b87 349 } 'got source for table in schema name with dot';
12b86f07 350
c4a69b87 351 is try { $rsrc->column_info('id')->{is_auto_increment} }, 1,
352 'column in schema name with dot introspected correctly';
12b86f07 353
c4a69b87 354 is try { $rsrc->column_info('value')->{data_type} }, 'varchar',
355 'column in schema name with dot introspected correctly';
12b86f07 356
c4a69b87 357 is try { $rsrc->column_info('value')->{size} }, 100,
358 'column in schema name with dot introspected correctly';
12b86f07 359
c4a69b87 360 lives_and {
4c2e2ce9 361 ok $rs = $test_schema->resultset('PgLoaderTest6');
c4a69b87 362 } 'got resultset for table in schema name with dot';
12b86f07 363
c4a69b87 364 lives_and {
365 ok $row = $rs->create({ value => 'foo' });
366 } 'executed SQL on table in schema name with dot';
12b86f07 367
c4a69b87 368 $rel_info = try { $rsrc->relationship_info('pg_loader_test7') };
12b86f07 369
c4a69b87 370 is_deeply $rel_info->{cond}, {
371 'foreign.six_id' => 'self.id'
372 }, 'relationship in schema name with dot';
12b86f07 373
c4a69b87 374 is $rel_info->{attrs}{accessor}, 'single',
375 'relationship in schema name with dot';
12b86f07 376
c4a69b87 377 is $rel_info->{attrs}{join_type}, 'LEFT',
378 'relationship in schema name with dot';
12b86f07 379
c4a69b87 380 lives_and {
4c2e2ce9 381 ok $rsrc = $test_schema->source('PgLoaderTest7');
c4a69b87 382 } 'got source for table in schema name with dot';
383
384 %uniqs = try { $rsrc->unique_constraints };
385
386 is keys %uniqs, 2,
387 'got unique and primary constraint in schema name with dot';
388
5975bbe6 389 delete $uniqs{primary};
390
391 is_deeply ((values %uniqs)[0], ['six_id'],
392 'unique constraint is correct in schema name with dot');
393
c4a69b87 394 lives_and {
4c2e2ce9 395 ok $test_schema->source('PgLoaderTest6')
c4a69b87 396 ->has_relationship('pg_loader_test4');
397 } 'cross-schema relationship in multi-db_schema';
398
399 lives_and {
4c2e2ce9 400 ok $test_schema->source('PgLoaderTest4')
c4a69b87 401 ->has_relationship('pg_loader_test6s');
402 } 'cross-schema relationship in multi-db_schema';
403
404 lives_and {
4c2e2ce9 405 ok $test_schema->source('PgLoaderTest8')
c4a69b87 406 ->has_relationship('pg_loader_test7');
407 } 'cross-schema relationship in multi-db_schema';
408
409 lives_and {
4c2e2ce9 410 ok $test_schema->source('PgLoaderTest7')
c4a69b87 411 ->has_relationship('pg_loader_test8s');
412 } 'cross-schema relationship in multi-db_schema';
413 }
fdd8ff16 414 },
415 },
a78e3fed 416);
417
9e978a19 418if( !$dsn || !$user ) {
419 $tester->skip_tests('You need to set the DBICTEST_PG_DSN, _USER, and _PASS environment variables');
a78e3fed 420}
421else {
422 $tester->run_tests();
423}
c4a69b87 424
425END {
426 rmtree EXTRA_DUMP_DIR unless $ENV{SCHEMA_LOADER_TESTS_NOCLEANUP};
427}
8e64075f 428# vim:et sw=4 sts=4 tw=0: