fix for a new record that belongs to an old one; accepting row objects in the updates...
authorzby <zby@bd8105ee-0ff8-0310-8827-fb3f25b6796d>
Sun, 25 Jan 2009 00:58:55 +0000 (00:58 +0000)
committerzby <zby@bd8105ee-0ff8-0310-8827-fb3f25b6796d>
Sun, 25 Jan 2009 00:58:55 +0000 (00:58 +0000)
lib/DBIx/Class/ResultSet/RecursiveUpdate.pm
t/lib/DBSchema/Result/Dvd.pm
t/lib/DBSchema/Result/Twokeys.pm [new file with mode: 0644]
t/lib/RunTests.pm
t/pg.t
t/sqlite.t
t/var/dvdzbr.db

index ebdfbf8abe91a3a8ab3cb4714b8d8fdb36a91f07..a152dc02c21530f4d7d9fc306341ea6e4eb85bbf 100644 (file)
@@ -5,13 +5,30 @@ use version; $VERSION = qv('0.001');
 use warnings;
 use strict;
 use Carp;
+use Scalar::Util qw( blessed );
 
 use base qw(DBIx::Class::ResultSet);
 
 sub recursive_update { 
-    my( $self, $updates ) = @_;
+    my( $self, $updates, $fixed_fields ) = @_;
+    if( blessed( $updates ) && $updates->isa( 'DBIx::Class::Row' ) ){
+        return $updates;
+    }
     my $object;
-    $object = $self->find( $updates, { key => 'primary' } ) || $self->new( {} );
+#    warn 'cond: ' . Dumper( $self->{cond} ); use Data::Dumper;
+#    warn 'where: ' . Dumper( $self->{attrs}{where} ); use Data::Dumper;
+    my @missing = grep { !exists $updates->{$_} && !exists $fixed_fields->{$_} } $self->result_source->primary_columns;
+    if( defined $self->{cond} && $DBIx::Class::ResultSource::UNRESOLVABLE_CONDITION == $self->{cond} ){
+        $self->{cond} = undef;
+        $self->{attrs}{where} = undef;
+        if( ! scalar @missing ){
+            $object = $self->find( $updates, { key => 'primary' } );
+        }
+    }
+    else{
+        $object = $self->find( $updates, { key => 'primary' } );
+    }
+    $object ||= $self->new( {} );
 
     for my $name ( keys %$updates ){ 
         if($object->can($name)){
@@ -46,6 +63,7 @@ sub recursive_update {
     $self->_delete_empty_auto_increment($object);
     # don't allow insert to recurse to related objects - we do the recursion ourselves
     $object->{_rel_in_storage} = 1;
+#    warn Dumper( $object->{_column_data} );
     $object->update_or_insert;
 
     # updating relations that can be done only after the row is inserted into the database
@@ -70,7 +88,7 @@ sub recursive_update {
         }
         elsif( $object->result_source->has_relationship($name) ){
             my $info = $object->result_source->relationship_info( $name );
-            # has many case
+            # has many case (and similar)
             if( ref $updates->{$name} eq 'ARRAY' ){
                 for my $sub_updates ( @{$updates->{$name}} ) {
                     my $sub_object = $object->search_related( $name )->recursive_update( $sub_updates );
@@ -171,8 +189,6 @@ sub _master_relation_cond {
     return;
 }
 
-# Module implementation here
-
 
 1; # Magic true value required at end of module
 __END__
index 4908080ee9893275207e91b7d690fae134eb6875..f761f764300ab2195275cbecaa23f43d530fa20d 100644 (file)
@@ -42,14 +42,16 @@ __PACKAGE__->add_columns(
   },
 );
 __PACKAGE__->set_primary_key('id');
-__PACKAGE__->belongs_to('owner', 'User', { id => 'owner' });
-__PACKAGE__->belongs_to('current_borrower', 'User', { id => 'current_borrower' });
+__PACKAGE__->belongs_to('owner', 'DBSchema::Result::User', { id => 'owner' });
+__PACKAGE__->belongs_to('current_borrower', 'DBSchema::Result::User', { id => 'current_borrower' });
 __PACKAGE__->has_many('dvdtags', 'Dvdtag', { 'foreign.dvd' => 'self.id' });
+__PACKAGE__->has_many('viewings', 'Viewing', { 'foreign.dvd_id' => 'self.id' });
 __PACKAGE__->many_to_many('tags', 'dvdtags' => 'tag');
 __PACKAGE__->might_have(
     liner_notes => 'DBSchema::Result::LinerNotes', undef,
     { proxy => [ qw/notes/ ] },
 );
+__PACKAGE__->add_relationship('like_has_many', 'DBSchema::Result::Twokeys', { 'foreign.dvd_name' => 'self.name' }, { accessor_name => 'like_has_many' } );
 
 
 1;
diff --git a/t/lib/DBSchema/Result/Twokeys.pm b/t/lib/DBSchema/Result/Twokeys.pm
new file mode 100644 (file)
index 0000000..7d71d01
--- /dev/null
@@ -0,0 +1,22 @@
+package DBSchema::Result::Twokeys;
+
+# Created by DBIx::Class::Schema::Loader v0.03000 @ 2006-10-02 08:24:09
+
+use strict;
+use warnings;
+
+use base 'DBIx::Class';
+
+__PACKAGE__->load_components("PK::Auto", "Core");
+__PACKAGE__->table("twokeys");
+__PACKAGE__->add_columns(
+    "dvd_name" => { data_type => 'varchar', size => 100 },
+    "key2" => { data_type => 'integer' },
+);
+__PACKAGE__->set_primary_key("dvd_name", "key2");
+
+__PACKAGE__->add_relationship('like_belongs_to', 'DBSchema::Result::Dvd', { 'foreign.name' => 'self.dvd_name' }, );
+
+
+1;
+
index f3bfbb121bffec700076f19b0121b56246baf17b..2971bde2690f212f52f8c46231166fcb79aeee0e 100644 (file)
@@ -5,14 +5,34 @@ use Exporter 'import'; # gives you Exporter's import() method directly
 use strict;
 use Test::More; 
 
-
 sub run_tests{
     my $schema = shift;
     
     my $dvd_rs = $schema->resultset( 'Dvd' );
-    my $owner = $schema->resultset( 'User' )->first;
-    my $initial_user_count = $schema->resultset( 'User' )->count;
+    my $user_rs = $schema->resultset( 'User' );
+
+    my $owner = $user_rs->next;
+    my $another_owner = $user_rs->next;
+    my $initial_user_count = $user_rs->count;
+   
+    # creating new record linked to some old record
+    
+    my $updates;
+    $updates = {
+            id => undef,
+            name => 'Test name 2',
+            viewings => [ { user_id => $owner->id } ],
+            owner => { id => $owner->id },
+    };
+    
+    my $new_dvd = $dvd_rs->recursive_update( $updates );
+#    my $new_dvd = $dvd_rs->create( $updates );
    
+    is ( $schema->resultset( 'User' )->count, $initial_user_count, "No new user created" );
+    is ( $new_dvd->name, 'Test name 2', 'Dvd name set' );
+    is ( $new_dvd->owner->id, $owner->id, 'Owner set' );
+#    is ( $new_dvd->viewing->user_id, $owner->id, 'Viewing created' );
+;    
     # creating new records
     
     my $updates = {
@@ -20,44 +40,40 @@ sub run_tests{
             aaaa => undef,
             tags => [ '2', { id => '3' } ], 
             name => 'Test name',
-    #        'creation_date.year' => 2002,
-    #        'creation_date.month' => 1,
-    #        'creation_date.day' => 3,
-    #        'creation_date.hour' => 4,
-    #        'creation_date.minute' => 33,
-    #        'creation_date.pm' => 1,
-            owner => $owner->id,
+            owner => $owner,
             current_borrower => {
                 name => 'temp name',
                 username => 'temp name',
                 password => 'temp name',
             },
             liner_notes => {
-                
                 notes => 'test note',
-            }
+            },
+            like_has_many => [
+            { key2 => 1 }
+            ],
     };
     
     my $dvd = $dvd_rs->recursive_update( $updates );
-   
+;   
     is ( $schema->resultset( 'User' )->count, $initial_user_count + 1, "One new user created" );
     is ( $dvd->name, 'Test name', 'Dvd name set' );
     is_deeply ( [ map {$_->id} $dvd->tags ], [ '2', '3' ], 'Tags set' );
-    #my $value = $dvd->creation_date;
-    #is( "$value", '2002-01-03T16:33:00', 'Date set');
     is ( $dvd->owner->id, $owner->id, 'Owner set' );
     
     is ( $dvd->current_borrower->name, 'temp name', 'Related record created' );
     is ( $dvd->liner_notes->notes, 'test note', 'might_have record created' );
-    
+    ok ( $schema->resultset( 'Twokeys' )->find( { dvd_name => 'Test name', key2 => 1 } ), 'Twokeys created' );
+
     # changing existing records
     
+    my $num_of_users = $user_rs->count;
     $updates = {
             id => $dvd->id,
             aaaa => undef,
             name => 'Test name',
             tags => [ ], 
-            'owner' => $owner->id,
+            'owner' => $another_owner->id,
             current_borrower => {
                 username => 'new name a',
                 name => 'new name a',
@@ -68,7 +84,7 @@ sub run_tests{
     
     is ( $schema->resultset( 'User' )->count, $initial_user_count + 1, "No new user created" );
     is ( $dvd->name, 'Test name', 'Dvd name set' );
-    is ( $dvd->owner->id, $owner->id, 'Owner set' );
+    is ( $dvd->owner->id, $another_owner->id, 'Owner updated' );
     is ( $dvd->current_borrower->name, 'new name a', 'Related record modified' );
     is ( $dvd->tags->count, 0, 'Tags deleted' );
 
@@ -93,7 +109,6 @@ sub run_tests{
         ]
     };
     
-    my $user_rs = $schema->resultset( 'User' );
     my $user = $user_rs->recursive_update( $updates );
     my %owned_dvds = map { $_->name => $_ } $user->owned_dvds;
     is( scalar keys %owned_dvds, 2, 'Has many relations created' );
@@ -101,4 +116,5 @@ sub run_tests{
     my @tags = $owned_dvds{'temp name 1'}->tags;
     is( scalar @tags, 2, 'Tags in has_many related record saved' );
     ok( $owned_dvds{'temp name 2'}, 'Second name in a has_many related record saved' );
+
 }    
diff --git a/t/pg.t b/t/pg.t
index 8765d41f63effa53d9910e6d5ff0828fd2a210ce..58ce12494c7b694827751545f4cd04d41980d7ff 100644 (file)
--- a/t/pg.t
+++ b/t/pg.t
@@ -10,7 +10,7 @@ my ($dsn, $user, $pass) = @ENV{map { "DBICTEST_PG_${_}" } qw/DSN USER PASS/};
 plan skip_all => 'Set $ENV{DBICTEST_PG_DSN}, _USER and _PASS to run this test'
  . ' (note: creates and tables!)' unless ($dsn && $user);
 
-plan tests => 15;
+plan tests => 19;
 
 my $schema = DBSchema::get_test_schema( $dsn, $user, $pass );
 
index 835ecd1858cd8f289a524a87f2dc8ccae003ca5d..45eca317591648d992a0ade3243f75d6e1fe3f77 100644 (file)
@@ -4,7 +4,7 @@ use lib 't/lib';
 use DBSchema;
 use RunTests;
 use Test::More;
-plan tests => 15;
+plan tests => 19;
 
 my $schema = DBSchema::get_test_schema();
 run_tests( $schema );
index 3ff59f1999dc5104f523c8d5457ec841914a5072..430d2c06dec9fe097971ac95d0aaca565a800eb2 100644 (file)
Binary files a/t/var/dvdzbr.db and b/t/var/dvdzbr.db differ
This page took 0.027741 seconds and 4 git commands to generate.