Add tests for disabled constraints and triggers for Oracle
Dagfinn Ilmari Mannsåker [Wed, 13 May 2015 13:15:29 +0000 (14:15 +0100)]
Also use the existing deferrability check to skip disabled foreign
keys even if DBD::Oracle returns them.

lib/DBIx/Class/Schema/Loader/DBI/Oracle.pm
t/10_05ora_common.t

index 47bec5a..853548a 100644 (file)
@@ -88,19 +88,22 @@ select deferrable from all_constraints
 where owner = ? and table_name = ? and constraint_name = ? and status = 'ENABLED'
 EOF
 
+    my @enabled_rels;
     foreach my $rel (@$rels) {
         # Oracle does not have update rules
         $rel->{attrs}{on_update} = 'NO ACTION';;
 
         # DBD::Oracle's foreign_key_info does not return DEFERRABILITY, so we get it ourselves
-        my ($deferrable) = $self->dbh->selectrow_array(
+        # Also use this to filter out disabled foreign keys, which are returned by DBD::Oracle < 1.76
+        my $deferrable = $self->dbh->selectrow_array(
             $deferrable_sth, undef, $table->schema, $table->name, $rel->{_constraint_name}
-        );
+        ) or next;
 
-        $rel->{attrs}{is_deferrable} = $deferrable && $deferrable =~ /^DEFERRABLE/i ? 1 : 0;
+        $rel->{attrs}{is_deferrable} = $deferrable =~ /^DEFERRABLE/i ? 1 : 0;
+        push @enabled_rels, $rel;
     }
 
-    return $rels;
+    return \@enabled_rels;
 }
 
 sub _table_uniq_info {
index 2cb7480..160d885 100644 (file)
@@ -27,7 +27,7 @@ my $auto_inc_cb = sub {
     return (
         qq{ CREATE SEQUENCE ${table}_${col}_seq START WITH 1 INCREMENT BY 1},
         qq{
-            CREATE OR REPLACE TRIGGER ${table}_${col}_trigger
+            CREATE OR REPLACE TRIGGER ${table}_${col}_trg
             BEFORE INSERT ON ${table}
             FOR EACH ROW
             BEGIN
@@ -181,9 +181,18 @@ my $tester = dbixcsl_common_tests->new(
                         on delete set null deferrable
                 )
             },
+            q{
+                create table oracle_loader_test11 (
+                    id int primary key disable,
+                    ten_id int unique disable,
+                    foreign key (ten_id) references oracle_loader_test10(id) disable
+                )
+            },
+            $auto_inc_cb->('oracle_loader_test11', 'id'),
+            'alter trigger oracle_loader_test11_id_trg disable',
         ],
-        drop  => [qw/oracle_loader_test1 oracle_loader_test9 oracle_loader_test10/],
-        count => 7 + 31 * 2,
+        drop  => [qw/oracle_loader_test1 oracle_loader_test9 oracle_loader_test10 oracle_loader_test11/],
+        count => 10 + 31 * 2,  # basic + cross-schema * 2
         run   => sub {
             my ($monikers, $classes);
             ($schema, $monikers, $classes) = @_;
@@ -223,6 +232,19 @@ my $tester = dbixcsl_common_tests->new(
             is $rel_info->{attrs}{is_deferrable}, 1,
                 'DEFERRABLE clause introspected correctly';
 
+            my $source11 = $schema->source('OracleLoaderTest11');
+
+            # DBD::Oracle < 1.76 doesn't filter out disabled primary keys
+            my $uniqs = eval { DBD::Oracle->VERSION('1.76') } ? [] : ['primary'];
+            is_deeply [keys %{{$source11->unique_constraints}}], $uniqs,
+                'Disabled unique constraints not loaded';
+
+            ok !$source11->relationship_info('ten'),
+                'Disabled FK not loaded';
+
+            ok !$source11->column_info('id')->{is_auto_increment},
+                'Disabled autoinc trigger not loaded';
+
             SKIP: {
                 skip 'Set the DBICTEST_ORA_EXTRAUSER_DSN, _USER and _PASS environment variables to run the cross-schema relationship tests', 31 * 2
                     unless $ENV{DBICTEST_ORA_EXTRAUSER_DSN};
@@ -485,34 +507,36 @@ else {
 
 END {
     if (not $ENV{SCHEMA_LOADER_TESTS_NOCLEANUP}) {
-        if (my $dbh2 = try { $extra_schema->storage->dbh }) {
-            my $dbh1 = $schema->storage->dbh;
-
-            try {
-                $dbh1->do($_) for $auto_inc_drop_cb->('oracle_loader_test8', 'id');
-                $dbh2->do($_) for $auto_inc_drop_cb->('oracle_loader_test7', 'id');
-                $dbh2->do($_) for $auto_inc_drop_cb->('oracle_loader_test6', 'id');
-                $dbh2->do($_) for $auto_inc_drop_cb->('oracle_loader_test5', 'pk');
-                $dbh1->do($_) for $auto_inc_drop_cb->('oracle_loader_test5', 'id');
-                $dbh1->do($_) for $auto_inc_drop_cb->('oracle_loader_test4', 'id');
-            }
-            catch {
-                die "Error dropping sequences for cross-schema test tables: $_";
-            };
-
-            try {
-                $dbh1->do('DROP TABLE oracle_loader_test8');
-                $dbh2->do('DROP TABLE oracle_loader_test7');
-                $dbh2->do('DROP TABLE oracle_loader_test6');
-                $dbh2->do('DROP TABLE oracle_loader_test5');
-                $dbh1->do('DROP TABLE oracle_loader_test5');
-                $dbh1->do('DROP TABLE oracle_loader_test4');
+        if (my $dbh1 = try { $schema->storage->dbh }) {
+            $dbh1->do($_) for $auto_inc_drop_cb->('oracle_loader_test11','id');
+
+            if (my $dbh2 = try { $extra_schema->storage->dbh }) {
+
+                try {
+                    $dbh1->do($_) for $auto_inc_drop_cb->('oracle_loader_test8', 'id');
+                    $dbh2->do($_) for $auto_inc_drop_cb->('oracle_loader_test7', 'id');
+                    $dbh2->do($_) for $auto_inc_drop_cb->('oracle_loader_test6', 'id');
+                    $dbh2->do($_) for $auto_inc_drop_cb->('oracle_loader_test5', 'pk');
+                    $dbh1->do($_) for $auto_inc_drop_cb->('oracle_loader_test5', 'id');
+                    $dbh1->do($_) for $auto_inc_drop_cb->('oracle_loader_test4', 'id');
+                }
+                catch {
+                    die "Error dropping sequences for cross-schema test tables: $_";
+                };
+
+                try {
+                    $dbh1->do('DROP TABLE oracle_loader_test8');
+                    $dbh2->do('DROP TABLE oracle_loader_test7');
+                    $dbh2->do('DROP TABLE oracle_loader_test6');
+                    $dbh2->do('DROP TABLE oracle_loader_test5');
+                    $dbh1->do('DROP TABLE oracle_loader_test5');
+                    $dbh1->do('DROP TABLE oracle_loader_test4');
+                }
+                catch {
+                    die "Error dropping cross-schema test tables: $_";
+                };
             }
-            catch {
-                die "Error dropping cross-schema test tables: $_";
-            };
         }
-
         rmtree EXTRA_DUMP_DIR;
     }
 }