4 use DBIx::Class::Schema::Loader 'make_schema_at';
5 use DBIx::Class::Schema::Loader::Utils qw/no_warnings slurp_file/;
9 use File::Path 'rmtree';
13 use dbixcsl_common_tests ();
14 use dbixcsl_test_dir '$tdir';
16 use constant EXTRA_DUMP_DIR => "$tdir/pg_extra_dump";
18 my $dsn = $ENV{DBICTEST_PG_DSN} || '';
19 my $user = $ENV{DBICTEST_PG_USER} || '';
20 my $password = $ENV{DBICTEST_PG_PASS} || '';
22 my $tester = dbixcsl_common_tests->new(
24 auto_inc_pk => 'SERIAL NOT NULL PRIMARY KEY',
27 password => $password,
28 loader_options => { preserve_case => 1 },
29 connect_info_opts => {
31 on_connect_do => [ 'SET client_min_messages=WARNING' ],
35 # http://www.postgresql.org/docs/7.4/interactive/datatype.html
38 boolean => { data_type => 'boolean' },
39 bool => { data_type => 'boolean' },
41 => { data_type => 'boolean', default_value => \'false' },
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' },
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 },
53 integer => { data_type => 'integer' },
54 int => { data_type => 'integer' },
55 int4 => { data_type => 'integer' },
56 serial => { data_type => 'integer', is_auto_increment => 1 },
57 serial4 => { data_type => 'integer', is_auto_increment => 1 },
58 smallint => { data_type => 'smallint' },
59 int2 => { data_type => 'smallint' },
61 money => { data_type => 'money' },
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' },
72 numeric => { data_type => 'numeric' },
73 decimal => { data_type => 'numeric' },
74 'numeric(6,3)' => { data_type => 'numeric', size => [6,3] },
75 'decimal(6,3)' => { data_type => 'numeric', size => [6,3] },
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 },
85 inet => { data_type => 'inet' },
86 cidr => { data_type => 'cidr' },
87 macaddr => { data_type => 'macaddr' },
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' },
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 },
103 'character' => { data_type => 'char', size => 1 },
104 'char' => { data_type => 'char', size => 1 },
105 text => { data_type => 'text' },
106 # varchar with no size has unlimited size, we rewrite to 'text'
107 varchar => { data_type => 'text',
108 original => { data_type => 'varchar' } },
109 # check that default NULL is correctly rewritten
110 'varchar(3) default NULL' => { data_type => 'varchar', size => 3,
111 default_value => \'null' },
114 date => { data_type => 'date' },
115 interval => { data_type => 'interval' },
116 'interval(2)' => { data_type => 'interval', size => 2 },
117 time => { data_type => 'time' },
118 'time(2)' => { data_type => 'time', size => 2 },
119 'time without time zone' => { data_type => 'time' },
120 'time(2) without time zone' => { data_type => 'time', size => 2 },
121 'time with time zone' => { data_type => 'time with time zone' },
122 'time(2) with time zone' => { data_type => 'time with time zone', size => 2 },
123 timestamp => { data_type => 'timestamp' },
124 'timestamp default now()'
125 => { data_type => 'timestamp', default_value => \'current_timestamp',
126 original => { default_value => \'now()' } },
127 'timestamp(2)' => { data_type => 'timestamp', size => 2 },
128 'timestamp without time zone' => { data_type => 'timestamp' },
129 'timestamp(2) without time zone' => { data_type => 'timestamp', size => 2 },
131 'timestamp with time zone' => { data_type => 'timestamp with time zone' },
132 'timestamp(2) with time zone' => { data_type => 'timestamp with time zone', size => 2 },
135 bytea => { data_type => 'bytea' },
138 pg_loader_test_enum => { data_type => 'enum', extra => { custom_type_name => 'pg_loader_test_enum',
139 list => [ qw/foo bar baz/] } },
143 CREATE TYPE pg_loader_test_enum AS ENUM (
151 CREATE SCHEMA dbicsl_test
154 CREATE SEQUENCE dbicsl_test.myseq
157 CREATE TABLE pg_loader_test1 (
158 id INTEGER NOT NULL DEFAULT nextval('dbicsl_test.myseq') PRIMARY KEY,
163 COMMENT ON TABLE pg_loader_test1 IS 'The\15\12Table ∑'
166 COMMENT ON COLUMN pg_loader_test1.value IS 'The\15\12Column'
169 CREATE TABLE pg_loader_test2 (
170 id SERIAL PRIMARY KEY,
175 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'
178 CREATE SCHEMA "dbicsl-test"
181 CREATE TABLE "dbicsl-test".pg_loader_test4 (
182 id SERIAL PRIMARY KEY,
187 CREATE TABLE "dbicsl-test".pg_loader_test5 (
188 id SERIAL PRIMARY KEY,
190 four_id INTEGER UNIQUE REFERENCES "dbicsl-test".pg_loader_test4 (id)
194 CREATE SCHEMA "dbicsl.test"
197 CREATE TABLE "dbicsl.test".pg_loader_test6 (
198 id SERIAL PRIMARY KEY,
200 pg_loader_test4_id INTEGER REFERENCES "dbicsl-test".pg_loader_test4 (id)
204 CREATE TABLE "dbicsl.test".pg_loader_test7 (
205 id SERIAL PRIMARY KEY,
207 six_id INTEGER UNIQUE REFERENCES "dbicsl.test".pg_loader_test6 (id)
211 CREATE TABLE "dbicsl-test".pg_loader_test8 (
212 id SERIAL PRIMARY KEY,
214 pg_loader_test7_id INTEGER REFERENCES "dbicsl.test".pg_loader_test7 (id)
219 'DROP SCHEMA dbicsl_test CASCADE',
220 'DROP SCHEMA "dbicsl-test" CASCADE',
221 'DROP SCHEMA "dbicsl.test" CASCADE',
222 'DROP TYPE pg_loader_test_enum',
224 drop => [ qw/ pg_loader_test1 pg_loader_test2 / ],
227 my ($schema, $monikers, $classes) = @_;
229 is $schema->source($monikers->{pg_loader_test1})->column_info('id')->{sequence},
231 'qualified sequence detected';
233 my $class = $classes->{pg_loader_test1};
234 my $filename = $schema->loader->get_dump_filename($class);
236 my $code = slurp_file $filename;
238 like $code, qr/^=head1 NAME\n\n^$class - The\nTable ∑\n\n^=cut\n/m,
241 like $code, qr/^=head2 value\n\n(.+:.+\n)+\nThe\nColumn\n\n/m,
242 'column comment and attrs';
244 $class = $classes->{pg_loader_test2};
245 $filename = $schema->loader->get_dump_filename($class);
247 $code = slurp_file $filename;
249 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,
250 'long table comment is in DESCRIPTION';
252 foreach my $db_schema (['dbicsl-test', 'dbicsl.test'], '%') {
254 rmtree EXTRA_DUMP_DIR;
257 local $SIG{__WARN__} = sub {
258 push @warns, $_[0] unless $_[0] =~ /\bcollides\b/;
265 db_schema => $db_schema,
267 dump_directory => EXTRA_DUMP_DIR,
270 [ $dsn, $user, $password, {
271 on_connect_do => [ 'SET client_min_messages=WARNING' ],
275 diag join "\n", @warns if @warns;
278 } 'dumped schema for "dbicsl-test" and "dbicsl.test" schemas with no warnings';
280 my ($test_schema, $rsrc, $rs, $row, %uniqs, $rel_info);
283 ok $test_schema = PGMultiSchema->connect($dsn, $user, $password, {
284 on_connect_do => [ 'SET client_min_messages=WARNING' ],
286 } 'connected test schema';
289 ok $rsrc = $test_schema->source('PgLoaderTest4');
290 } 'got source for table in schema name with dash';
292 is try { $rsrc->column_info('id')->{is_auto_increment} }, 1,
293 'column in schema name with dash';
295 is try { $rsrc->column_info('value')->{data_type} }, 'varchar',
296 'column in schema name with dash';
298 is try { $rsrc->column_info('value')->{size} }, 100,
299 'column in schema name with dash';
302 ok $rs = $test_schema->resultset('PgLoaderTest4');
303 } 'got resultset for table in schema name with dash';
306 ok $row = $rs->create({ value => 'foo' });
307 } 'executed SQL on table in schema name with dash';
309 $rel_info = try { $rsrc->relationship_info('pg_loader_test5') };
311 is_deeply $rel_info->{cond}, {
312 'foreign.four_id' => 'self.id'
313 }, 'relationship in schema name with dash';
315 is $rel_info->{attrs}{accessor}, 'single',
316 'relationship in schema name with dash';
318 is $rel_info->{attrs}{join_type}, 'LEFT',
319 'relationship in schema name with dash';
322 ok $rsrc = $test_schema->source('PgLoaderTest5');
323 } 'got source for table in schema name with dash';
325 %uniqs = try { $rsrc->unique_constraints };
328 'got unique and primary constraint in schema name with dash';
331 ok $rsrc = $test_schema->source('PgLoaderTest6');
332 } 'got source for table in schema name with dot';
334 is try { $rsrc->column_info('id')->{is_auto_increment} }, 1,
335 'column in schema name with dot introspected correctly';
337 is try { $rsrc->column_info('value')->{data_type} }, 'varchar',
338 'column in schema name with dot introspected correctly';
340 is try { $rsrc->column_info('value')->{size} }, 100,
341 'column in schema name with dot introspected correctly';
344 ok $rs = $test_schema->resultset('PgLoaderTest6');
345 } 'got resultset for table in schema name with dot';
348 ok $row = $rs->create({ value => 'foo' });
349 } 'executed SQL on table in schema name with dot';
351 $rel_info = try { $rsrc->relationship_info('pg_loader_test7') };
353 is_deeply $rel_info->{cond}, {
354 'foreign.six_id' => 'self.id'
355 }, 'relationship in schema name with dot';
357 is $rel_info->{attrs}{accessor}, 'single',
358 'relationship in schema name with dot';
360 is $rel_info->{attrs}{join_type}, 'LEFT',
361 'relationship in schema name with dot';
364 ok $rsrc = $test_schema->source('PgLoaderTest7');
365 } 'got source for table in schema name with dot';
367 %uniqs = try { $rsrc->unique_constraints };
370 'got unique and primary constraint in schema name with dot';
373 ok $test_schema->source('PgLoaderTest6')
374 ->has_relationship('pg_loader_test4');
375 } 'cross-schema relationship in multi-db_schema';
378 ok $test_schema->source('PgLoaderTest4')
379 ->has_relationship('pg_loader_test6s');
380 } 'cross-schema relationship in multi-db_schema';
383 ok $test_schema->source('PgLoaderTest8')
384 ->has_relationship('pg_loader_test7');
385 } 'cross-schema relationship in multi-db_schema';
388 ok $test_schema->source('PgLoaderTest7')
389 ->has_relationship('pg_loader_test8s');
390 } 'cross-schema relationship in multi-db_schema';
396 if( !$dsn || !$user ) {
397 $tester->skip_tests('You need to set the DBICTEST_PG_DSN, _USER, and _PASS environment variables');
400 $tester->run_tests();
404 rmtree EXTRA_DUMP_DIR unless $ENV{SCHEMA_LOADER_TESTS_NOCLEANUP};
406 # vim:et sw=4 sts=4 tw=0: