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