fix multiple DEFAULT NULLs
[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),
c4a69b87 193 four_id INTEGER UNIQUE REFERENCES "dbicsl-test".pg_loader_test4 (id)
12b86f07 194 )
195 },
196 q{
197 CREATE SCHEMA "dbicsl.test"
198 },
199 q{
c4a69b87 200 CREATE TABLE "dbicsl.test".pg_loader_test6 (
12b86f07 201 id SERIAL PRIMARY KEY,
c4a69b87 202 value VARCHAR(100),
203 pg_loader_test4_id INTEGER REFERENCES "dbicsl-test".pg_loader_test4 (id)
12b86f07 204 )
205 },
206 q{
c4a69b87 207 CREATE TABLE "dbicsl.test".pg_loader_test7 (
208 id SERIAL PRIMARY KEY,
209 value VARCHAR(100),
210 six_id INTEGER UNIQUE REFERENCES "dbicsl.test".pg_loader_test6 (id)
211 )
212 },
213 q{
214 CREATE TABLE "dbicsl-test".pg_loader_test8 (
12b86f07 215 id SERIAL PRIMARY KEY,
216 value VARCHAR(100),
c4a69b87 217 pg_loader_test7_id INTEGER REFERENCES "dbicsl.test".pg_loader_test7 (id)
12b86f07 218 )
219 },
fdd8ff16 220 ],
7b868481 221 pre_drop_ddl => [
222 'DROP SCHEMA dbicsl_test CASCADE',
12b86f07 223 'DROP SCHEMA "dbicsl-test" CASCADE',
224 'DROP SCHEMA "dbicsl.test" CASCADE',
12333562 225 'DROP TYPE pg_loader_test_enum',
7b868481 226 ],
9065de34 227 drop => [ qw/ pg_loader_test1 pg_loader_test2 / ],
c4a69b87 228 count => 4 + 28 * 2,
fdd8ff16 229 run => sub {
230 my ($schema, $monikers, $classes) = @_;
231
7b868481 232 is $schema->source($monikers->{pg_loader_test1})->column_info('id')->{sequence},
233 'dbicsl_test.myseq',
234 'qualified sequence detected';
235
fdd8ff16 236 my $class = $classes->{pg_loader_test1};
c4a69b87 237 my $filename = $schema->loader->get_dump_filename($class);
fdd8ff16 238
fcf328c7 239 my $code = slurp_file $filename;
fdd8ff16 240
af15ea33 241 like $code, qr/^=head1 NAME\n\n^$class - The\nTable ∑\n\n^=cut\n/m,
fdd8ff16 242 'table comment';
243
fd97abca 244 like $code, qr/^=head2 value\n\n(.+:.+\n)+\nThe\nColumn\n\n/m,
79a00530 245 'column comment and attrs';
baff904e 246
4b9fb838 247 $class = $classes->{pg_loader_test2};
c4a69b87 248 $filename = $schema->loader->get_dump_filename($class);
4b9fb838 249
fcf328c7 250 $code = slurp_file $filename;
4b9fb838 251
252 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,
253 'long table comment is in DESCRIPTION';
12b86f07 254
c4a69b87 255 foreach my $db_schema (['dbicsl-test', 'dbicsl.test'], '%') {
256 lives_and {
257 rmtree EXTRA_DUMP_DIR;
258
259 my @warns;
260 local $SIG{__WARN__} = sub {
261 push @warns, $_[0] unless $_[0] =~ /\bcollides\b/;
262 };
263
12b86f07 264 make_schema_at(
c4a69b87 265 'PGMultiSchema',
12b86f07 266 {
267 naming => 'current',
c4a69b87 268 db_schema => $db_schema,
12b86f07 269 preserve_case => 1,
c4a69b87 270 dump_directory => EXTRA_DUMP_DIR,
271 quiet => 1,
12b86f07 272 },
273 [ $dsn, $user, $password, {
274 on_connect_do => [ 'SET client_min_messages=WARNING' ],
275 } ],
276 );
12b86f07 277
c4a69b87 278 diag join "\n", @warns if @warns;
12b86f07 279
c4a69b87 280 is @warns, 0;
281 } 'dumped schema for "dbicsl-test" and "dbicsl.test" schemas with no warnings';
12b86f07 282
c4a69b87 283 my ($test_schema, $rsrc, $rs, $row, %uniqs, $rel_info);
12b86f07 284
c4a69b87 285 lives_and {
286 ok $test_schema = PGMultiSchema->connect($dsn, $user, $password, {
287 on_connect_do => [ 'SET client_min_messages=WARNING' ],
288 });
289 } 'connected test schema';
12b86f07 290
c4a69b87 291 lives_and {
292 ok $rsrc = $test_schema->source('PgLoaderTest4');
293 } 'got source for table in schema name with dash';
12b86f07 294
c4a69b87 295 is try { $rsrc->column_info('id')->{is_auto_increment} }, 1,
296 'column in schema name with dash';
12b86f07 297
c4a69b87 298 is try { $rsrc->column_info('value')->{data_type} }, 'varchar',
299 'column in schema name with dash';
12b86f07 300
c4a69b87 301 is try { $rsrc->column_info('value')->{size} }, 100,
302 'column in schema name with dash';
12b86f07 303
c4a69b87 304 lives_and {
305 ok $rs = $test_schema->resultset('PgLoaderTest4');
306 } 'got resultset for table in schema name with dash';
12b86f07 307
c4a69b87 308 lives_and {
309 ok $row = $rs->create({ value => 'foo' });
310 } 'executed SQL on table in schema name with dash';
12b86f07 311
c4a69b87 312 $rel_info = try { $rsrc->relationship_info('pg_loader_test5') };
12b86f07 313
c4a69b87 314 is_deeply $rel_info->{cond}, {
315 'foreign.four_id' => 'self.id'
316 }, 'relationship in schema name with dash';
12b86f07 317
c4a69b87 318 is $rel_info->{attrs}{accessor}, 'single',
319 'relationship in schema name with dash';
320
321 is $rel_info->{attrs}{join_type}, 'LEFT',
322 'relationship in schema name with dash';
323
324 lives_and {
325 ok $rsrc = $test_schema->source('PgLoaderTest5');
326 } 'got source for table in schema name with dash';
327
328 %uniqs = try { $rsrc->unique_constraints };
12b86f07 329
c4a69b87 330 is keys %uniqs, 2,
331 'got unique and primary constraint in schema name with dash';
12b86f07 332
c4a69b87 333 lives_and {
334 ok $rsrc = $test_schema->source('PgLoaderTest6');
335 } 'got source for table in schema name with dot';
12b86f07 336
c4a69b87 337 is try { $rsrc->column_info('id')->{is_auto_increment} }, 1,
338 'column in schema name with dot introspected correctly';
12b86f07 339
c4a69b87 340 is try { $rsrc->column_info('value')->{data_type} }, 'varchar',
341 'column in schema name with dot introspected correctly';
12b86f07 342
c4a69b87 343 is try { $rsrc->column_info('value')->{size} }, 100,
344 'column in schema name with dot introspected correctly';
12b86f07 345
c4a69b87 346 lives_and {
347 ok $rs = $test_schema->resultset('PgLoaderTest6');
348 } 'got resultset for table in schema name with dot';
12b86f07 349
c4a69b87 350 lives_and {
351 ok $row = $rs->create({ value => 'foo' });
352 } 'executed SQL on table in schema name with dot';
12b86f07 353
c4a69b87 354 $rel_info = try { $rsrc->relationship_info('pg_loader_test7') };
12b86f07 355
c4a69b87 356 is_deeply $rel_info->{cond}, {
357 'foreign.six_id' => 'self.id'
358 }, 'relationship in schema name with dot';
12b86f07 359
c4a69b87 360 is $rel_info->{attrs}{accessor}, 'single',
361 'relationship in schema name with dot';
12b86f07 362
c4a69b87 363 is $rel_info->{attrs}{join_type}, 'LEFT',
364 'relationship in schema name with dot';
12b86f07 365
c4a69b87 366 lives_and {
367 ok $rsrc = $test_schema->source('PgLoaderTest7');
368 } 'got source for table in schema name with dot';
369
370 %uniqs = try { $rsrc->unique_constraints };
371
372 is keys %uniqs, 2,
373 'got unique and primary constraint in schema name with dot';
374
375 lives_and {
376 ok $test_schema->source('PgLoaderTest6')
377 ->has_relationship('pg_loader_test4');
378 } 'cross-schema relationship in multi-db_schema';
379
380 lives_and {
381 ok $test_schema->source('PgLoaderTest4')
382 ->has_relationship('pg_loader_test6s');
383 } 'cross-schema relationship in multi-db_schema';
384
385 lives_and {
386 ok $test_schema->source('PgLoaderTest8')
387 ->has_relationship('pg_loader_test7');
388 } 'cross-schema relationship in multi-db_schema';
389
390 lives_and {
391 ok $test_schema->source('PgLoaderTest7')
392 ->has_relationship('pg_loader_test8s');
393 } 'cross-schema relationship in multi-db_schema';
394 }
fdd8ff16 395 },
396 },
a78e3fed 397);
398
9e978a19 399if( !$dsn || !$user ) {
400 $tester->skip_tests('You need to set the DBICTEST_PG_DSN, _USER, and _PASS environment variables');
a78e3fed 401}
402else {
403 $tester->run_tests();
404}
c4a69b87 405
406END {
407 rmtree EXTRA_DUMP_DIR unless $ENV{SCHEMA_LOADER_TESTS_NOCLEANUP};
408}
8e64075f 409# vim:et sw=4 sts=4 tw=0: