experimental support for Pg loader run inside txn
[dbsrgits/DBIx-Class-Schema-Loader.git] / t / lib / dbixcsl_common_tests.pm
index 7911ac2..5b04a41 100644 (file)
@@ -114,12 +114,12 @@ sub run_tests {
     my $extra_count = $self->{extra}{count} || 0;
 
     my $col_accessor_map_tests = 5;
-    my $num_rescans = 5;
+    my $num_rescans = 6;
     $num_rescans++ if $self->{vendor} eq 'mssql';
     $num_rescans++ if $self->{vendor} eq 'Firebird';
 
     plan tests => @connect_info *
-        (210 + $num_rescans * $col_accessor_map_tests + $extra_count + ($self->{data_type_tests}{test_count} || 0));
+        (221 + $num_rescans * $col_accessor_map_tests + $extra_count + ($self->{data_type_tests}{test_count} || 0));
 
     foreach my $info_idx (0..$#connect_info) {
         my $info = $connect_info[$info_idx];
@@ -210,6 +210,11 @@ my (@statements, @statements_reltests, @statements_advanced,
     @statements_advanced_sqlite, @statements_inline_rels,
     @statements_implicit_rels);
 
+sub CONSTRAINT {
+    my $self = shift;
+return qr/^(?:\S+\.)?(?:(?:$self->{vendor}|extra)[_-]?)?loader[_-]?test[0-9]+(?!.*_)/i;
+}
+
 sub setup_schema {
     my ($self, $connect_info, $expected_count) = @_;
 
@@ -225,15 +230,15 @@ sub setup_schema {
     }
 
     my %loader_opts = (
-        constraint              =>
-          qr/^(?:\S+\.)?(?:(?:$self->{vendor}|extra)[_-]?)?loader[_-]?test[0-9]+(?!.*_)/i,
+        constraint              => $self->CONSTRAINT,
         result_namespace        => RESULT_NAMESPACE,
         resultset_namespace     => RESULTSET_NAMESPACE,
+        schema_base_class       => 'TestSchemaBaseClass',
         schema_components       => [ 'TestSchemaComponent', '+TestSchemaComponentFQN' ],
         additional_classes      => 'TestAdditional',
         additional_base_classes => 'TestAdditionalBase',
         left_base_classes       => [ qw/TestLeftBase/ ],
-        components              => [ qw/TestComponent +TestComponentFQN/ ],
+        components              => [ qw/TestComponent +TestComponentFQN IntrospectableM2M/ ],
         inflect_plural          => { loader_test4_fkid => 'loader_test4zes' },
         inflect_singular        => { fkid => 'fkid_singular' },
         moniker_map             => \&_monikerize,
@@ -392,9 +397,22 @@ sub test_schema {
         'resultset_namespace set correctly on Schema';
 
     like $schema_code,
+qr/\nuse base 'TestSchemaBaseClass';\n\n|\nextends 'TestSchemaBaseClass';\n\n/,
+        'schema_base_class works';
+
+    is $conn->testschemabaseclass, 'TestSchemaBaseClass works',
+        'schema base class works';
+
+    like $schema_code,
 qr/\n__PACKAGE__->load_components\("TestSchemaComponent", "\+TestSchemaComponentFQN"\);\n\n__PACKAGE__->load_namespaces/,
         'schema_components works';
 
+    is $conn->dbix_class_testschemacomponent, 'dbix_class_testschemacomponent works',
+        'schema component works';
+
+    is $conn->testschemacomponent_fqn, 'TestSchemaComponentFQN works',
+        'fully qualified schema component works';
+
     my @columns_lt2 = $class2->columns;
     is_deeply( \@columns_lt2, [ qw/id dat dat2 set_primary_key can dbix_class_testcomponent dbix_class_testcomponentmap testcomponent_fqn meta test_role_method test_role_for_map_method crumb_crisp_coating/ ], "Column Ordering" );
 
@@ -606,7 +624,7 @@ qr/\n__PACKAGE__->load_components\("TestSchemaComponent", "\+TestSchemaComponent
         'is_nullable=1 detection';
 
     SKIP: {
-        skip $self->{skip_rels}, 131 if $self->{skip_rels};
+        skip $self->{skip_rels}, 137 if $self->{skip_rels};
 
         my $moniker3 = $monikers->{loader_test3};
         my $class3   = $classes->{loader_test3};
@@ -890,6 +908,19 @@ qr/\n__PACKAGE__->(?:belongs_to|has_many|might_have|has_one|many_to_many)\(
         ok($class22->column_info('parent')->{is_foreign_key}, 'Foreign key detected');
         ok($class22->column_info('child')->{is_foreign_key}, 'Foreign key detected');
 
+        # test many_to_many detection 18 -> 20 -> 19 and 19 -> 20 -> 18
+        my $m2m;
+
+        ok($m2m = (try { $class18->_m2m_metadata->{children} }), 'many_to_many created');
+
+        is $m2m->{relation}, 'loader_test20s', 'm2m near rel';
+        is $m2m->{foreign_relation}, 'child', 'm2m far rel';
+
+        ok($m2m = (try { $class19->_m2m_metadata->{parents} }), 'many_to_many created');
+
+        is $m2m->{relation}, 'loader_test20s', 'm2m near rel';
+        is $m2m->{foreign_relation}, 'parent', 'm2m far rel';
+
         # test double multi-col fk 26 -> 25
         my $obj26 = try { $rsobj26->find(33) } || $rsobj26->search({ id => 33 })->first;
 
@@ -1189,6 +1220,41 @@ EOF
     # run extra tests
     $self->{extra}{run}->($conn, $monikers, $classes, $self) if $self->{extra}{run};
 
+    ## Create a dump from an existing $dbh in a transaction
+
+TODO: {
+    local $TODO = 'dumping in a txn is experimental and Pg-only right now'
+        unless $self->{vendor} eq 'Pg';
+
+    ok eval {
+        my %opts = (
+          naming         => 'current',
+          constraint     => $self->CONSTRAINT,
+          dump_directory => DUMP_DIR,
+          debug          => ($ENV{SCHEMA_LOADER_TESTS_DEBUG}||0)
+        );
+
+        my $guard = $conn->txn_scope_guard;
+
+        my $warn_handler = $SIG{__WARN__} || sub { warn @_ };
+        local $SIG{__WARN__} = sub {
+            $warn_handler->(@_)
+                unless $_[0] =~ RESCAN_WARNINGS
+                    || $_[0] =~ /commit ineffective with AutoCommit enabled/; # FIXME
+        };
+
+        my $schema_from = DBIx::Class::Schema::Loader::make_schema_at(
+            "TestSchemaFromAnother", \%opts, [ sub { $conn->storage->dbh } ]
+        );
+
+        $guard->commit;
+
+        1;
+    }, 'Making a schema from another schema inside a transaction worked';
+
+    diag $@ if $@ && (not $TODO);
+}
+
     $self->drop_tables unless $ENV{SCHEMA_LOADER_TESTS_NOCLEANUP};
 
     $conn->storage->disconnect;
@@ -1254,9 +1320,10 @@ qq| INSERT INTO ${oqt}${table41_name}${cqt} VALUES (1, 1) |,
     );
     $conn->storage->disconnect;
 
-    local $conn->loader->{preserve_case} = 1;
-    $conn->loader->_setup;
+    my $orig_preserve_case = $conn->loader->preserve_case;
 
+    $conn->loader->preserve_case(1);
+    $conn->loader->_setup;
     $self->rescan_without_warnings($conn);
 
     if (not $self->{skip_rels}) {
@@ -1273,6 +1340,13 @@ qq| INSERT INTO ${oqt}${table41_name}${cqt} VALUES (1, 1) |,
         is try { $conn->resultset('LoaderTest40')->find(1)->foo3_bar }, 'foo',
             'accessor for mixed-case column name in mixed case table';
     }
+
+    # Further tests may expect preserve_case to be unset, so reset it to the
+    # original value and rescan again.
+
+    $conn->loader->preserve_case($orig_preserve_case);
+    $conn->loader->_setup;
+    $self->rescan_without_warnings($conn);
 }
 
 sub monikers_and_classes {
@@ -1287,7 +1361,7 @@ sub monikers_and_classes {
         $monikers->{$table_name} = $source_name;
         $classes->{$table_name} = $result_class;
 
-        # some DBs (Firebird) uppercase everything
+        # some DBs (Firebird, Oracle) uppercase everything
         $monikers->{lc $table_name} = $source_name;
         $classes->{lc $table_name} = $result_class;
     }
@@ -1362,7 +1436,7 @@ sub create {
 
     $self->drop_tables;
 
-    my $make_auto_inc = $self->{auto_inc_cb} || sub {};
+    my $make_auto_inc = $self->{auto_inc_cb} || sub { return () };
     @statements = (
         qq{
             CREATE TABLE loader_test1s (