fix some issues with multi-db_schema support
[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,
5975bbe6 278 moniker_parts => [qw/schema name/],
12b86f07 279 preserve_case => 1,
c4a69b87 280 dump_directory => EXTRA_DUMP_DIR,
281 quiet => 1,
12b86f07 282 },
283 [ $dsn, $user, $password, {
284 on_connect_do => [ 'SET client_min_messages=WARNING' ],
285 } ],
286 );
12b86f07 287
c4a69b87 288 diag join "\n", @warns if @warns;
12b86f07 289
c4a69b87 290 is @warns, 0;
291 } 'dumped schema for "dbicsl-test" and "dbicsl.test" schemas with no warnings';
12b86f07 292
c4a69b87 293 my ($test_schema, $rsrc, $rs, $row, %uniqs, $rel_info);
12b86f07 294
c4a69b87 295 lives_and {
296 ok $test_schema = PGMultiSchema->connect($dsn, $user, $password, {
297 on_connect_do => [ 'SET client_min_messages=WARNING' ],
298 });
299 } 'connected test schema';
12b86f07 300
c4a69b87 301 lives_and {
5975bbe6 302 ok $rsrc = $test_schema->source('DbicslDashTestPgLoaderTest4');
c4a69b87 303 } 'got source for table in schema name with dash';
12b86f07 304
c4a69b87 305 is try { $rsrc->column_info('id')->{is_auto_increment} }, 1,
306 'column in schema name with dash';
12b86f07 307
c4a69b87 308 is try { $rsrc->column_info('value')->{data_type} }, 'varchar',
309 'column in schema name with dash';
12b86f07 310
c4a69b87 311 is try { $rsrc->column_info('value')->{size} }, 100,
312 'column in schema name with dash';
12b86f07 313
c4a69b87 314 lives_and {
5975bbe6 315 ok $rs = $test_schema->resultset('DbicslDashTestPgLoaderTest4');
c4a69b87 316 } 'got resultset for table in schema name with dash';
12b86f07 317
c4a69b87 318 lives_and {
319 ok $row = $rs->create({ value => 'foo' });
320 } 'executed SQL on table in schema name with dash';
12b86f07 321
5975bbe6 322 $rel_info = try { $rsrc->relationship_info('dbicsl_dash_test_pg_loader_test5') };
12b86f07 323
c4a69b87 324 is_deeply $rel_info->{cond}, {
325 'foreign.four_id' => 'self.id'
326 }, 'relationship in schema name with dash';
12b86f07 327
c4a69b87 328 is $rel_info->{attrs}{accessor}, 'single',
329 'relationship in schema name with dash';
330
331 is $rel_info->{attrs}{join_type}, 'LEFT',
332 'relationship in schema name with dash';
333
334 lives_and {
5975bbe6 335 ok $rsrc = $test_schema->source('DbicslDashTestPgLoaderTest5');
c4a69b87 336 } 'got source for table in schema name with dash';
337
338 %uniqs = try { $rsrc->unique_constraints };
12b86f07 339
c4a69b87 340 is keys %uniqs, 2,
341 'got unique and primary constraint in schema name with dash';
12b86f07 342
5975bbe6 343 delete $uniqs{primary};
344
345 is_deeply ((values %uniqs)[0], ['four_id'],
346 'unique constraint is correct in schema name with dash');
347
c4a69b87 348 lives_and {
5975bbe6 349 ok $rsrc = $test_schema->source('DbicslDotTestPgLoaderTest6');
c4a69b87 350 } 'got source for table in schema name with dot';
12b86f07 351
c4a69b87 352 is try { $rsrc->column_info('id')->{is_auto_increment} }, 1,
353 'column in schema name with dot introspected correctly';
12b86f07 354
c4a69b87 355 is try { $rsrc->column_info('value')->{data_type} }, 'varchar',
356 'column in schema name with dot introspected correctly';
12b86f07 357
c4a69b87 358 is try { $rsrc->column_info('value')->{size} }, 100,
359 'column in schema name with dot introspected correctly';
12b86f07 360
c4a69b87 361 lives_and {
5975bbe6 362 ok $rs = $test_schema->resultset('DbicslDotTestPgLoaderTest6');
c4a69b87 363 } 'got resultset for table in schema name with dot';
12b86f07 364
c4a69b87 365 lives_and {
366 ok $row = $rs->create({ value => 'foo' });
367 } 'executed SQL on table in schema name with dot';
12b86f07 368
c4a69b87 369 $rel_info = try { $rsrc->relationship_info('pg_loader_test7') };
12b86f07 370
c4a69b87 371 is_deeply $rel_info->{cond}, {
372 'foreign.six_id' => 'self.id'
373 }, 'relationship in schema name with dot';
12b86f07 374
c4a69b87 375 is $rel_info->{attrs}{accessor}, 'single',
376 'relationship in schema name with dot';
12b86f07 377
c4a69b87 378 is $rel_info->{attrs}{join_type}, 'LEFT',
379 'relationship in schema name with dot';
12b86f07 380
c4a69b87 381 lives_and {
5975bbe6 382 ok $rsrc = $test_schema->source('DbicslDotTestPgLoaderTest7');
c4a69b87 383 } 'got source for table in schema name with dot';
384
385 %uniqs = try { $rsrc->unique_constraints };
386
387 is keys %uniqs, 2,
388 'got unique and primary constraint in schema name with dot';
389
5975bbe6 390 delete $uniqs{primary};
391
392 is_deeply ((values %uniqs)[0], ['six_id'],
393 'unique constraint is correct in schema name with dot');
394
c4a69b87 395 lives_and {
5975bbe6 396 ok $test_schema->source('DbicslDotTestPgLoaderTest6')
c4a69b87 397 ->has_relationship('pg_loader_test4');
398 } 'cross-schema relationship in multi-db_schema';
399
400 lives_and {
5975bbe6 401 ok $test_schema->source('DbicslDashTestPgLoaderTest4')
c4a69b87 402 ->has_relationship('pg_loader_test6s');
403 } 'cross-schema relationship in multi-db_schema';
404
405 lives_and {
5975bbe6 406 ok $test_schema->source('DbicslDashTestPgLoaderTest8')
c4a69b87 407 ->has_relationship('pg_loader_test7');
408 } 'cross-schema relationship in multi-db_schema';
409
410 lives_and {
5975bbe6 411 ok $test_schema->source('DbicslDotTestPgLoaderTest7')
c4a69b87 412 ->has_relationship('pg_loader_test8s');
413 } 'cross-schema relationship in multi-db_schema';
414 }
fdd8ff16 415 },
416 },
a78e3fed 417);
418
9e978a19 419if( !$dsn || !$user ) {
420 $tester->skip_tests('You need to set the DBICTEST_PG_DSN, _USER, and _PASS environment variables');
a78e3fed 421}
422else {
423 $tester->run_tests();
424}
c4a69b87 425
426END {
427 rmtree EXTRA_DUMP_DIR unless $ENV{SCHEMA_LOADER_TESTS_NOCLEANUP};
428}
8e64075f 429# vim:et sw=4 sts=4 tw=0: