add self to credits
[dbsrgits/DBIx-Class-Schema-Loader.git] / t / 10_03pg_common.t
index e3a8b03..2fe5fc9 100644 (file)
@@ -1,3 +1,6 @@
+use DBIx::Class::Schema::Loader::Optional::Dependencies
+    -skip_all_without => 'test_rdbms_pg';
+
 use strict;
 use warnings;
 use utf8;
@@ -19,7 +22,7 @@ my $dsn      = $ENV{DBICTEST_PG_DSN} || '';
 my $user     = $ENV{DBICTEST_PG_USER} || '';
 my $password = $ENV{DBICTEST_PG_PASS} || '';
 
-my $tester = dbixcsl_common_tests->new(
+dbixcsl_common_tests->new(
     vendor      => 'Pg',
     auto_inc_pk => 'SERIAL NOT NULL PRIMARY KEY',
     dsn         => $dsn,
@@ -37,8 +40,8 @@ my $tester = dbixcsl_common_tests->new(
         # http://www.postgresql.org/docs/7.4/interactive/datatype.html
         #
         # Numeric Types
-       boolean     => { data_type => 'boolean' },
-       bool        => { data_type => 'boolean' },
+        boolean     => { data_type => 'boolean' },
+        bool        => { data_type => 'boolean' },
         'bool default false'
                     => { data_type => 'boolean', default_value => \'false' },
         'bool default true'
@@ -48,100 +51,108 @@ my $tester = dbixcsl_common_tests->new(
         'bool default 1::bool'
                     => { data_type => 'boolean', default_value => \'true' },
 
-       bigint      => { data_type => 'bigint' },
-       int8        => { data_type => 'bigint' },
-       bigserial   => { data_type => 'bigint', is_auto_increment => 1 },
-       serial8     => { data_type => 'bigint', is_auto_increment => 1 },
-       integer     => { data_type => 'integer' },
-       int         => { data_type => 'integer' },
-       int4        => { data_type => 'integer' },
-       serial      => { data_type => 'integer', is_auto_increment => 1 },
-       serial4     => { data_type => 'integer', is_auto_increment => 1 },
-       smallint    => { data_type => 'smallint' },
-       int2        => { data_type => 'smallint' },
-
-       money       => { data_type => 'money' },
-
-       'double precision' => { data_type => 'double precision' },
-       float8             => { data_type => 'double precision' },
-       real               => { data_type => 'real' },
-       float4             => { data_type => 'real' },
+        bigint      => { data_type => 'bigint' },
+        int8        => { data_type => 'bigint' },
+        bigserial   => { data_type => 'bigint', is_auto_increment => 1 },
+        serial8     => { data_type => 'bigint', is_auto_increment => 1 },
+        integer     => { data_type => 'integer' },
+        int         => { data_type => 'integer' },
+        int4        => { data_type => 'integer' },
+        serial      => { data_type => 'integer', is_auto_increment => 1 },
+        serial4     => { data_type => 'integer', is_auto_increment => 1 },
+        smallint    => { data_type => 'smallint' },
+        int2        => { data_type => 'smallint' },
+
+        money       => { data_type => 'money' },
+
+        'double precision' => { data_type => 'double precision' },
+        float8             => { data_type => 'double precision' },
+        real               => { data_type => 'real' },
+        float4             => { data_type => 'real' },
         'float(24)'        => { data_type => 'real' },
         'float(25)'        => { data_type => 'double precision' },
         'float(53)'        => { data_type => 'double precision' },
         float              => { data_type => 'double precision' },
 
-        numeric        => { data_type => 'numeric' },
-        decimal        => { data_type => 'numeric' },
-       'numeric(6,3)' => { data_type => 'numeric', size => [6,3] },
-       'decimal(6,3)' => { data_type => 'numeric', size => [6,3] },
+        numeric            => { data_type => 'numeric' },
+        decimal            => { data_type => 'numeric' },
+        'numeric(6,3)'     => { data_type => 'numeric', size => [6,3] },
+        'decimal(6,3)'     => { data_type => 'numeric', size => [6,3] },
 
         # Bit String Types
-       'bit varying(2)' => { data_type => 'varbit', size => 2 },
-       'varbit(2)'      => { data_type => 'varbit', size => 2 },
-       'varbit'         => { data_type => 'varbit' },
-       bit              => { data_type => 'bit', size => 1 },
-       'bit(3)'         => { data_type => 'bit', size => 3 },
+        'bit varying(2)' => { data_type => 'varbit', size => 2 },
+        'varbit(2)'      => { data_type => 'varbit', size => 2 },
+        'bit varying'    => { data_type => 'varbit' },
+        'varbit'         => { data_type => 'varbit' },
+        bit              => { data_type => 'bit', size => 1 },
+        'bit(3)'         => { data_type => 'bit', size => 3 },
 
         # Network Types
-       inet    => { data_type => 'inet' },
-       cidr    => { data_type => 'cidr' },
-       macaddr => { data_type => 'macaddr' },
+        inet    => { data_type => 'inet' },
+        cidr    => { data_type => 'cidr' },
+        macaddr => { data_type => 'macaddr' },
 
         # Geometric Types
-       point   => { data_type => 'point' },
-       line    => { data_type => 'line' },
-       lseg    => { data_type => 'lseg' },
-       box     => { data_type => 'box' },
-       path    => { data_type => 'path' },
-       polygon => { data_type => 'polygon' },
-       circle  => { data_type => 'circle' },
+        point   => { data_type => 'point' },
+        line    => { data_type => 'line' },
+        lseg    => { data_type => 'lseg' },
+        box     => { data_type => 'box' },
+        path    => { data_type => 'path' },
+        polygon => { data_type => 'polygon' },
+        circle  => { data_type => 'circle' },
 
         # Character Types
-       'character varying(2)'           => { data_type => 'varchar', size => 2 },
-       'varchar(2)'                     => { data_type => 'varchar', size => 2 },
-       'character(2)'                   => { data_type => 'char', size => 2 },
-       'char(2)'                        => { data_type => 'char', size => 2 },
+        'character varying(2)'           => { data_type => 'varchar', size => 2 },
+        'varchar(2)'                     => { data_type => 'varchar', size => 2 },
+        'character(2)'                   => { data_type => 'char', size => 2 },
+        'char(2)'                        => { data_type => 'char', size => 2 },
         # check that default null is correctly rewritten
         'char(3) default null'           => { data_type => 'char', size => 3,
                                               default_value => \'null' },
-       'character'                      => { data_type => 'char', size => 1 },
-       'char'                           => { data_type => 'char', size => 1 },
-       text                             => { data_type => 'text' },
+        'character'                      => { data_type => 'char', size => 1 },
+        'char'                           => { data_type => 'char', size => 1 },
+        text                             => { data_type => 'text' },
         # varchar with no size has unlimited size, we rewrite to 'text'
-       varchar                          => { data_type => 'text',
+        varchar                          => { data_type => 'text',
                                               original => { data_type => 'varchar' } },
         # check default null again (to make sure ref is safe)
         'varchar(3) default null'        => { data_type => 'varchar', size => 3,
                                               default_value => \'null' },
 
         # Datetime Types
-       date                             => { data_type => 'date' },
-       interval                         => { data_type => 'interval' },
-       'interval(2)'                    => { data_type => 'interval', size => 2 },
-       time                             => { data_type => 'time' },
-       'time(2)'                        => { data_type => 'time', size => 2 },
-       'time without time zone'         => { data_type => 'time' },
-       'time(2) without time zone'      => { data_type => 'time', size => 2 },
-       'time with time zone'            => { data_type => 'time with time zone' },
-       'time(2) with time zone'         => { data_type => 'time with time zone', size => 2 },
-       timestamp                        => { data_type => 'timestamp' },
-        'timestamp default now()'
-                                         => { data_type => 'timestamp', default_value => \'current_timestamp',
+        date                             => { data_type => 'date' },
+        interval                         => { data_type => 'interval' },
+        'interval(0)'                    => { data_type => 'interval', size => 0 },
+        'interval(2)'                    => { data_type => 'interval', size => 2 },
+        time                             => { data_type => 'time' },
+        'time(0)'                        => { data_type => 'time', size => 0 },
+        'time(2)'                        => { data_type => 'time', size => 2 },
+        'time without time zone'         => { data_type => 'time' },
+        'time(0) without time zone'      => { data_type => 'time', size => 0 },
+        'time with time zone'            => { data_type => 'time with time zone' },
+        'time(0) with time zone'         => { data_type => 'time with time zone', size => 0 },
+        'time(2) with time zone'         => { data_type => 'time with time zone', size => 2 },
+        timestamp                        => { data_type => 'timestamp' },
+        'timestamp default now()'        => { data_type => 'timestamp',
+                                              default_value => \'current_timestamp',
                                               original => { default_value => \'now()' } },
-       'timestamp(2)'                   => { data_type => 'timestamp', size => 2 },
-       'timestamp without time zone'    => { data_type => 'timestamp' },
-       'timestamp(2) without time zone' => { data_type => 'timestamp', size => 2 },
+        'timestamp(0)'                   => { data_type => 'timestamp', size => 0 },
+        'timestamp(2)'                   => { data_type => 'timestamp', size => 2 },
+        'timestamp without time zone'    => { data_type => 'timestamp' },
+        'timestamp(0) without time zone' => { data_type => 'timestamp', size => 0 },
+        'timestamp(2) without time zone' => { data_type => 'timestamp', size => 2 },
 
-       'timestamp with time zone'       => { data_type => 'timestamp with time zone' },
-       'timestamp(2) with time zone'    => { data_type => 'timestamp with time zone', size => 2 },
+        'timestamp with time zone'       => { data_type => 'timestamp with time zone' },
+        'timestamp(0) with time zone'    => { data_type => 'timestamp with time zone', size => 0 },
+        'timestamp(2) with time zone'    => { data_type => 'timestamp with time zone', size => 2 },
 
         # Blob Types
-       bytea => { data_type => 'bytea' },
+        bytea => { data_type => 'bytea' },
 
         # Enum Types
-        pg_loader_test_enum => { data_type => 'enum', extra => { custom_type_name => 'pg_loader_test_enum',
-                                                                 list => [ qw/foo bar baz/] } },
+        pg_loader_test_enum => { data_type => 'enum',
+                                 extra => { custom_type_name => 'pg_loader_test_enum',
+                                            list => [ qw/foo bar baz/] } },
     },
     pre_create => [
         q{
@@ -215,9 +226,12 @@ my $tester = dbixcsl_common_tests->new(
                 )
             },
             q{
+                CREATE TYPE "dbicsl.test".pg_loader_test_enum2 AS ENUM ('wibble','wobble')
+            },
+            q{
                 CREATE TABLE "dbicsl.test".pg_loader_test7 (
                     id SERIAL PRIMARY KEY,
-                    value VARCHAR(100),
+                    value "dbicsl.test".pg_loader_test_enum2,
                     six_id INTEGER UNIQUE REFERENCES "dbicsl.test".pg_loader_test6 (id)
                 )
             },
@@ -242,15 +256,48 @@ my $tester = dbixcsl_common_tests->new(
                         on delete restrict on update set null deferrable
                 )
             },
+            q{
+                create view pg_loader_test11 as
+                    select * from pg_loader_test1
+            },
+            q{
+                create table pg_loader_test12 (
+                    id integer not null,
+                    value integer,
+                    active boolean,
+                    name text
+                )
+            },
+            q{
+                create unique index uniq_id_lc_name on pg_loader_test12 (
+                    id, lower(name)
+                )
+            },
+            q{
+                create unique index uniq_uc_name_id on pg_loader_test12 (
+                    upper(name), id
+                )
+            },
+            q{
+                create unique index pg_loader_test12_value on pg_loader_test12 (
+                    value
+                )
+            },
+            q{
+                create unique index pg_loader_test12_name_active on pg_loader_test12 (
+                    name
+                ) where active
+            },
         ],
         pre_drop_ddl => [
             'DROP SCHEMA dbicsl_test CASCADE',
             'DROP SCHEMA "dbicsl-test" CASCADE',
             'DROP SCHEMA "dbicsl.test" CASCADE',
             'DROP TYPE pg_loader_test_enum',
+            'DROP VIEW pg_loader_test11',
         ],
-        drop  => [ qw/pg_loader_test1 pg_loader_test2 pg_loader_test9 pg_loader_test10/ ],
-        count => 8 + 30 * 2,
+        drop  => [ qw/pg_loader_test1 pg_loader_test2 pg_loader_test9 pg_loader_test10 pg_loader_test12/ ],
+        count => 11 + 33 * 2,   # regular + multi-schema * 2
         run   => sub {
             my ($schema, $monikers, $classes) = @_;
 
@@ -370,8 +417,10 @@ my $tester = dbixcsl_common_tests->new(
 
                 delete $uniqs{primary};
 
-                is_deeply ((values %uniqs)[0], ['four_id'],
-                    'unique constraint is correct in schema name with dash');
+                is_deeply(
+                    (values %uniqs)[0], ['four_id'],
+                    'unique constraint is correct in schema name with dash'
+                );
 
                 lives_and {
                     ok $rsrc = $test_schema->source('PgLoaderTest6');
@@ -408,6 +457,13 @@ my $tester = dbixcsl_common_tests->new(
 
                 lives_and {
                     ok $rsrc = $test_schema->source('PgLoaderTest7');
+                    my $col_info = $rsrc->column_info('value');
+                    is $col_info->{data_type}, 'enum',
+                        'enum column in schema name with dot';
+                    is $col_info->{extra}{custom_type_name}, '"dbicsl.test".pg_loader_test_enum2',
+                        'original data type for enum in schema name with dot';
+                    is_deeply $col_info->{extra}{list}, [qw(wibble wobble)],
+                        'value list for for enum in schema name with dot';
                 } 'got source for table in schema name with dot';
 
                 %uniqs = try { $rsrc->unique_constraints };
@@ -417,8 +473,10 @@ my $tester = dbixcsl_common_tests->new(
 
                 delete $uniqs{primary};
 
-                is_deeply ((values %uniqs)[0], ['six_id'],
-                    'unique constraint is correct in schema name with dot');
+                is_deeply(
+                    (values %uniqs)[0], ['six_id'],
+                    'unique constraint is correct in schema name with dot'
+                );
 
                 lives_and {
                     ok $test_schema->source('PgLoaderTest6')
@@ -440,16 +498,23 @@ my $tester = dbixcsl_common_tests->new(
                         ->has_relationship('pg_loader_test8s');
                 } 'cross-schema relationship in multi-db_schema';
             }
+
+            # test that views are marked as such
+            my $view_source = $schema->resultset($monikers->{pg_loader_test11})->result_source;
+            isa_ok $view_source, 'DBIx::Class::ResultSource::View',
+                'view result source';
+
+            like $view_source->view_definition,
+                qr/\A \s* select\b .* \bfrom \s+ pg_loader_test1 \s* \z/imsx,
+                'view definition';
+
+            is_deeply
+                { $schema->source($monikers->{pg_loader_test12})->unique_constraints },
+                { pg_loader_test12_value => ['value'] },
+                'unique indexes are dumped correctly';
         },
     },
-);
-
-if( !$dsn || !$user ) {
-    $tester->skip_tests('You need to set the DBICTEST_PG_DSN, _USER, and _PASS environment variables');
-}
-else {
-    $tester->run_tests();
-}
+)->run_tests();
 
 END {
     rmtree EXTRA_DUMP_DIR unless $ENV{SCHEMA_LOADER_TESTS_NOCLEANUP};