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 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 },
47 integer => { data_type => 'integer' },
48 int => { data_type => 'integer' },
49 int4 => { data_type => 'integer' },
50 serial => { data_type => 'integer', is_auto_increment => 1 },
51 serial4 => { data_type => 'integer', is_auto_increment => 1 },
52 smallint => { data_type => 'smallint' },
53 int2 => { data_type => 'smallint' },
55 money => { data_type => 'money' },
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' },
66 numeric => { data_type => 'numeric' },
67 decimal => { data_type => 'numeric' },
68 'numeric(6,3)' => { data_type => 'numeric', size => [6,3] },
69 'decimal(6,3)' => { data_type => 'numeric', size => [6,3] },
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 },
79 inet => { data_type => 'inet' },
80 cidr => { data_type => 'cidr' },
81 macaddr => { data_type => 'macaddr' },
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' },
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 },
99 text => { data_type => 'text' },
100 # varchar with no size has unlimited size, we rewrite to 'text'
101 varchar => { data_type => 'text',
102 original => { data_type => 'varchar' } },
105 date => { data_type => 'date' },
106 interval => { data_type => 'interval' },
107 'interval(2)' => { data_type => 'interval', size => 2 },
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 },
112 'time with time zone' => { data_type => 'time with time zone' },
113 'time(2) with time zone' => { data_type => 'time with time zone', size => 2 },
114 timestamp => { data_type => 'timestamp' },
115 'timestamp default now()'
116 => { data_type => 'timestamp', default_value => \'current_timestamp',
117 original => { default_value => \'now()' } },
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 },
122 'timestamp with time zone' => { data_type => 'timestamp with time zone' },
123 'timestamp(2) with time zone' => { data_type => 'timestamp with time zone', size => 2 },
126 bytea => { data_type => 'bytea' },
129 pg_loader_test_enum => { data_type => 'enum', extra => { custom_type_name => 'pg_loader_test_enum',
130 list => [ qw/foo bar baz/] } },
134 CREATE TYPE pg_loader_test_enum AS ENUM (
142 CREATE SCHEMA dbicsl_test
145 CREATE SEQUENCE dbicsl_test.myseq
148 CREATE TABLE pg_loader_test1 (
149 id INTEGER NOT NULL DEFAULT nextval('dbicsl_test.myseq') PRIMARY KEY,
154 COMMENT ON TABLE pg_loader_test1 IS 'The\15\12Table ∑'
157 COMMENT ON COLUMN pg_loader_test1.value IS 'The\15\12Column'
160 CREATE TABLE pg_loader_test2 (
161 id SERIAL PRIMARY KEY,
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'
169 CREATE SCHEMA "dbicsl-test"
172 CREATE TABLE "dbicsl-test".pg_loader_test4 (
173 id SERIAL PRIMARY KEY,
178 CREATE TABLE "dbicsl-test".pg_loader_test5 (
179 id SERIAL PRIMARY KEY,
181 four_id INTEGER UNIQUE REFERENCES "dbicsl-test".pg_loader_test4 (id)
185 CREATE SCHEMA "dbicsl.test"
188 CREATE TABLE "dbicsl.test".pg_loader_test6 (
189 id SERIAL PRIMARY KEY,
191 pg_loader_test4_id INTEGER REFERENCES "dbicsl-test".pg_loader_test4 (id)
195 CREATE TABLE "dbicsl.test".pg_loader_test7 (
196 id SERIAL PRIMARY KEY,
198 six_id INTEGER UNIQUE REFERENCES "dbicsl.test".pg_loader_test6 (id)
202 CREATE TABLE "dbicsl-test".pg_loader_test8 (
203 id SERIAL PRIMARY KEY,
205 pg_loader_test7_id INTEGER REFERENCES "dbicsl.test".pg_loader_test7 (id)
210 'DROP SCHEMA dbicsl_test CASCADE',
211 'DROP SCHEMA "dbicsl-test" CASCADE',
212 'DROP SCHEMA "dbicsl.test" CASCADE',
213 'DROP TYPE pg_loader_test_enum',
215 drop => [ qw/ pg_loader_test1 pg_loader_test2 / ],
218 my ($schema, $monikers, $classes) = @_;
220 is $schema->source($monikers->{pg_loader_test1})->column_info('id')->{sequence},
222 'qualified sequence detected';
224 my $class = $classes->{pg_loader_test1};
225 my $filename = $schema->loader->get_dump_filename($class);
227 my $code = slurp_file $filename;
229 like $code, qr/^=head1 NAME\n\n^$class - The\nTable ∑\n\n^=cut\n/m,
232 like $code, qr/^=head2 value\n\n(.+:.+\n)+\nThe\nColumn\n\n/m,
233 'column comment and attrs';
235 $class = $classes->{pg_loader_test2};
236 $filename = $schema->loader->get_dump_filename($class);
238 $code = slurp_file $filename;
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';
243 foreach my $db_schema (['dbicsl-test', 'dbicsl.test'], '%') {
245 rmtree EXTRA_DUMP_DIR;
248 local $SIG{__WARN__} = sub {
249 push @warns, $_[0] unless $_[0] =~ /\bcollides\b/;
256 db_schema => $db_schema,
258 dump_directory => EXTRA_DUMP_DIR,
261 [ $dsn, $user, $password, {
262 on_connect_do => [ 'SET client_min_messages=WARNING' ],
266 diag join "\n", @warns if @warns;
269 } 'dumped schema for "dbicsl-test" and "dbicsl.test" schemas with no warnings';
271 my ($test_schema, $rsrc, $rs, $row, %uniqs, $rel_info);
274 ok $test_schema = PGMultiSchema->connect($dsn, $user, $password, {
275 on_connect_do => [ 'SET client_min_messages=WARNING' ],
277 } 'connected test schema';
280 ok $rsrc = $test_schema->source('PgLoaderTest4');
281 } 'got source for table in schema name with dash';
283 is try { $rsrc->column_info('id')->{is_auto_increment} }, 1,
284 'column in schema name with dash';
286 is try { $rsrc->column_info('value')->{data_type} }, 'varchar',
287 'column in schema name with dash';
289 is try { $rsrc->column_info('value')->{size} }, 100,
290 'column in schema name with dash';
293 ok $rs = $test_schema->resultset('PgLoaderTest4');
294 } 'got resultset for table in schema name with dash';
297 ok $row = $rs->create({ value => 'foo' });
298 } 'executed SQL on table in schema name with dash';
300 $rel_info = try { $rsrc->relationship_info('pg_loader_test5') };
302 is_deeply $rel_info->{cond}, {
303 'foreign.four_id' => 'self.id'
304 }, 'relationship in schema name with dash';
306 is $rel_info->{attrs}{accessor}, 'single',
307 'relationship in schema name with dash';
309 is $rel_info->{attrs}{join_type}, 'LEFT',
310 'relationship in schema name with dash';
313 ok $rsrc = $test_schema->source('PgLoaderTest5');
314 } 'got source for table in schema name with dash';
316 %uniqs = try { $rsrc->unique_constraints };
319 'got unique and primary constraint in schema name with dash';
322 ok $rsrc = $test_schema->source('PgLoaderTest6');
323 } 'got source for table in schema name with dot';
325 is try { $rsrc->column_info('id')->{is_auto_increment} }, 1,
326 'column in schema name with dot introspected correctly';
328 is try { $rsrc->column_info('value')->{data_type} }, 'varchar',
329 'column in schema name with dot introspected correctly';
331 is try { $rsrc->column_info('value')->{size} }, 100,
332 'column in schema name with dot introspected correctly';
335 ok $rs = $test_schema->resultset('PgLoaderTest6');
336 } 'got resultset for table in schema name with dot';
339 ok $row = $rs->create({ value => 'foo' });
340 } 'executed SQL on table in schema name with dot';
342 $rel_info = try { $rsrc->relationship_info('pg_loader_test7') };
344 is_deeply $rel_info->{cond}, {
345 'foreign.six_id' => 'self.id'
346 }, 'relationship in schema name with dot';
348 is $rel_info->{attrs}{accessor}, 'single',
349 'relationship in schema name with dot';
351 is $rel_info->{attrs}{join_type}, 'LEFT',
352 'relationship in schema name with dot';
355 ok $rsrc = $test_schema->source('PgLoaderTest7');
356 } 'got source for table in schema name with dot';
358 %uniqs = try { $rsrc->unique_constraints };
361 'got unique and primary constraint in schema name with dot';
364 ok $test_schema->source('PgLoaderTest6')
365 ->has_relationship('pg_loader_test4');
366 } 'cross-schema relationship in multi-db_schema';
369 ok $test_schema->source('PgLoaderTest4')
370 ->has_relationship('pg_loader_test6s');
371 } 'cross-schema relationship in multi-db_schema';
374 ok $test_schema->source('PgLoaderTest8')
375 ->has_relationship('pg_loader_test7');
376 } 'cross-schema relationship in multi-db_schema';
379 ok $test_schema->source('PgLoaderTest7')
380 ->has_relationship('pg_loader_test8s');
381 } 'cross-schema relationship in multi-db_schema';
387 if( !$dsn || !$user ) {
388 $tester->skip_tests('You need to set the DBICTEST_PG_DSN, _USER, and _PASS environment variables');
391 $tester->run_tests();
395 rmtree EXTRA_DUMP_DIR unless $ENV{SCHEMA_LOADER_TESTS_NOCLEANUP};
397 # vim:et sw=4 sts=4 tw=0: