add is_deferrable => 1 to belongs_to by default
Rafael Kitover [Wed, 17 Mar 2010 10:21:07 +0000 (06:21 -0400)]
Changes
lib/DBIx/Class/Schema/Loader/RelBuilder.pm
t/12pg_common.t
t/backcompat/0.04006/lib/dbixcsl_common_tests.pm
t/lib/dbixcsl_common_tests.pm

diff --git a/Changes b/Changes
index 4ed0395..0512855 100644 (file)
--- a/Changes
+++ b/Changes
@@ -2,8 +2,10 @@ Revision history for Perl extension DBIx::Class::Schema::Loader
 
         - better inflection using Lingua::EN::Inflect::Phrase
         - cascade_delete and cascade_copy are turned off for has_many/might_have
-          by default, and belongs_to has on_delete => 'CASCADE' and on_update =>
-          'CASCADE' by default, overridable via relationship_attrs
+          by default, and belongs_to has on_delete => 'CASCADE', on_update =>
+          'CASCADE' and is_deferrable => 1 by default, overridable via
+          relationship_attrs
+        - added config_file option for loading loader options from a file
         - set inflate_datetime => 1 for 'AS getdate()' computed columns in
           Sybase
         - preliminary Firebird support
index cdeea7f..904e5d1 100644 (file)
@@ -119,7 +119,7 @@ sub _inflect_plural {
 
 # Singularize a relationship name
 sub _inflect_singular {
-    my ($self, $relname) = @_;
+    my ($self, $relname, $method) = @_;
 
     return '' if !defined $relname || $relname eq '';
 
@@ -132,7 +132,9 @@ sub _inflect_singular {
         return $inflected if $inflected;
     }
 
-    return $self->_to_S($relname);
+    $method ||= '_to_S';
+
+    return $self->$method($relname);
 }
 
 sub _to_PL {
@@ -161,6 +163,12 @@ sub _to_S {
     return $singular;
 }
 
+sub _old_to_S {
+    my ($self, $name) = @_;
+
+    return Lingua::EN::Inflect::Number::to_S($name);
+}
+
 sub _default_relationship_attrs { +{
     has_many => {
         cascade_delete => 0,
@@ -173,6 +181,7 @@ sub _default_relationship_attrs { +{
     belongs_to => {
         on_delete => 'CASCADE',
         on_update => 'CASCADE',
+        is_deferrable => 1,
     },
 } }
 
@@ -349,7 +358,7 @@ sub _relnames_and_method {
             grep { _array_eq($_->[1], $local_cols) } @$uniqs) {
         $remote_method = 'might_have';
         $local_relname = $self->_inflect_singular($local_relname_uninflected);
-        $old_local_relname = $self->_inflect_singular($old_local_relname_uninflected);
+        $old_local_relname = $self->_inflect_singular($old_local_relname_uninflected, '_old_to_S');
     }
 
     warn __PACKAGE__." $VERSION: renaming ${remote_class} relation '$old_local_relname' to '$local_relname'.  This behavior is new as of 0.05003.\n" if $old_local_relname && $local_relname ne $old_local_relname;
index 57faa7a..b10dfa6 100644 (file)
@@ -15,6 +15,62 @@ my $tester = dbixcsl_common_tests->new(
     dsn         => $dsn,
     user        => $user,
     password    => $password,
+    data_types  => {
+       'bigint'    => { size => undef, data_type => 'bigint' },
+       'int8'      => { size => undef, data_type => 'int8' },
+       'bigserial' => { size => undef, data_type => 'bigserial' },
+       'serial8'   => { size => undef, data_type => 'serial8' },
+       'bit'       => { size => undef, data_type => 'bit' },
+       'boolean'   => { size => undef, data_type => 'boolean' },
+       'bool'      => { size => undef, data_type => 'bool' },
+       'box'       => { size => undef, data_type => 'box' },
+       'bytea'     => { size => undef, data_type => 'bytea' },
+       'cidr'      => { size => undef, data_type => 'cidr' },
+       'circle'    => { size => undef, data_type => 'circle' },
+       'date'      => { size => undef, data_type => 'date' },
+       'double precision' => { size => undef, data_type => 'double precision' },
+       'float8'      => { size => undef, data_type => 'float8' },
+       'inet'        => { size => undef, data_type => 'inet' },
+       'integer'     => { size => undef, data_type => 'integer' },
+       'int'         => { size => undef, data_type => 'int' },
+       'int4'        => { size => undef, data_type => 'int4' },
+       'interval'    => { size => undef, data_type => 'interval' },
+       'interval(2)' => { size => 2, data_type => 'interval' },
+       'line'        => { size => undef, data_type => 'line' },
+       'lseg'        => { size => undef, data_type => 'lseg' },
+       'macaddr'     => { size => undef, data_type => 'macaddr' },
+       'money'       => { size => undef, data_type => 'money' },
+       'path'        => { size => undef, data_type => 'path' },
+       'point'       => { size => undef, data_type => 'point' },
+       'polygon'     => { size => undef, data_type => 'polygon' },
+       'real'        => { size => undef, data_type => 'real' },
+       'float4'      => { size => undef, data_type => 'float4' },
+       'smallint'    => { size => undef, data_type => 'smallint' },
+       'int2'        => { size => undef, data_type => 'int2' },
+       'serial'      => { size => undef, data_type => 'serial' },
+       'serial4'     => { size => undef, data_type => 'serial4' },
+       'text'        => { size => undef, data_type => 'text' },
+       'time'        => { size => undef, data_type => 'time' },
+       'time(2)'     => { size => 2, data_type => 'time' },
+       'time without time zone'         => { size => undef, data_type => 'time without time zone' },
+       'time(2) without time zone'      => { size => 2, data_type => 'time without time zone' },
+       'time with time zone'            => { size => undef, data_type => 'time with time zone' },
+       'time(2) with time zone'         => { size => 2, data_type => 'time with time zone' },
+       'timestamp'                      => { size => undef, data_type => 'timestamp' },
+       'timestamp(2)'                   => { size => 2, data_type => 'timestamp' },
+       'timestamp without time zone'    => { size => undef, data_type => 'timestamp without time zone' },
+       'timestamp(2) without time zone' => { size => 2, data_type => 'timestamp without time zone' },
+       'timestamp with time zone'       => { size => undef, data_type => 'timestamp with time zone' },
+       'timestamp(2) with time zone'    => { size => 2, data_type => 'timestamp with time zone' },
+       'bit varying(2)'                 => { size => 2, data_type => 'bit varying' },
+       'varbit(2)'                      => { size => 2, data_type => 'varbit' },
+       'character varying(2)'           => { size => 2, data_type => 'character varying' },
+       'varchar(2)'                     => { size => 2, data_type => 'varchar' },
+       'character(2)'                   => { size => 2, data_type => 'character' },
+       'char(2)'                        => { size => 2, data_type => 'char' },
+       'numeric(6, 3)'                  => { size => [6,3], data_type => 'numeric' },
+       'decimal(6, 3)'                  => { size => [6,3], data_type => 'decimal' },
+    },
     extra       => {
         create => [
             q{
index 4d51475..5dd3ba2 100644 (file)
@@ -43,7 +43,7 @@ sub _monikerize {
 sub run_tests {
     my $self = shift;
 
-    plan tests => 99;
+    plan tests => 101;
 
     $self->create();
 
@@ -255,7 +255,7 @@ sub run_tests {
     is( $obj2->id, 2 );
 
     SKIP: {
-        skip $self->{skip_rels}, 61 if $self->{skip_rels};
+        skip $self->{skip_rels}, 63 if $self->{skip_rels};
 
         my $moniker3 = $monikers->{loader_test3};
         my $class3   = $classes->{loader_test3};
@@ -367,12 +367,18 @@ sub run_tests {
         ok ((not exists $rsobj3->result_source->relationship_info('loader_test4zes')->{attrs}{on_update}),
             'has_many does not have on_update');
 
+        ok ((not exists $rsobj3->result_source->relationship_info('loader_test4zes')->{attrs}{is_deferrable}),
+            'has_many does not have is_deferrable');
+
         isnt $rsobj4->result_source->relationship_info('fkid_singular')->{attrs}{on_delete}, 'CASCADE',
             "on_delete => 'CASCADE' not on belongs_to by default";
 
         isnt $rsobj4->result_source->relationship_info('fkid_singular')->{attrs}{on_update}, 'CASCADE',
             "on_update => 'CASCADE' not on belongs_to by default";
 
+        isnt $rsobj4->result_source->relationship_info('fkid_singular')->{attrs}{is_deferrable}, 1,
+            "is_deferrable => 1 not on belongs_to by default";
+
         ok ((not exists $rsobj4->result_source->relationship_info('fkid_singular')->{attrs}{cascade_delete}),
             'belongs_to does not have cascade_delete');
 
index d8dc3f5..81a0d1d 100644 (file)
@@ -74,7 +74,7 @@ sub run_tests {
         }
     }
 
-    plan tests => @connect_info * (171 + ($self->{extra}->{count} || 0));
+    plan tests => @connect_info * (174 + ($self->{extra}->{count} || 0));
 
     foreach my $info_idx (0..$#connect_info) {
         my $info = $connect_info[$info_idx];
@@ -369,7 +369,7 @@ sub test_schema {
     );
 
     SKIP: {
-        skip $self->{skip_rels}, 113 if $self->{skip_rels};
+        skip $self->{skip_rels}, 116 if $self->{skip_rels};
 
         my $moniker3 = $monikers->{loader_test3};
         my $class3   = $classes->{loader_test3};
@@ -522,12 +522,18 @@ sub test_schema {
         ok ((not exists $rsobj3->result_source->relationship_info('loader_test4zes')->{attrs}{on_update}),
             'has_many does not have on_update');
 
+        ok ((not exists $rsobj3->result_source->relationship_info('loader_test4zes')->{attrs}{is_deferrable}),
+            'has_many does not have is_deferrable');
+
         is $rsobj4->result_source->relationship_info('fkid_singular')->{attrs}{on_delete}, 'CASCADE',
             "on_delete => 'CASCADE' on belongs_to by default";
 
         is $rsobj4->result_source->relationship_info('fkid_singular')->{attrs}{on_update}, 'CASCADE',
             "on_update => 'CASCADE' on belongs_to by default";
 
+        is $rsobj4->result_source->relationship_info('fkid_singular')->{attrs}{is_deferrable}, 1,
+            "is_deferrable => 1 on belongs_to by default";
+
         ok ((not exists $rsobj4->result_source->relationship_info('fkid_singular')->{attrs}{cascade_delete}),
             'belongs_to does not have cascade_delete');
 
@@ -546,6 +552,9 @@ sub test_schema {
         ok ((not exists $rsobj27->result_source->relationship_info('loader_test28')->{attrs}{on_update}),
             'might_have does not have on_update');
 
+        ok ((not exists $rsobj27->result_source->relationship_info('loader_test28')->{attrs}{is_deferrable}),
+            'might_have does not have is_deferrable');
+
         # find on multi-col pk
         my $obj5 = 
            eval { $rsobj5->find({id1 => 1, iD2 => 1}) } ||