Merge 'trunk' into 'on_connect_call'
Rafael Kitover [Sun, 14 Jun 2009 16:57:41 +0000 (16:57 +0000)]
r5510@hlagh (orig r6661):  ribasushi | 2009-06-13 08:56:54 -0700
Test resultset serialization as well
r5511@hlagh (orig r6662):  ribasushi | 2009-06-13 09:08:14 -0700
local()ize sqla for in the right place
r5512@hlagh (orig r6663):  ribasushi | 2009-06-13 09:10:22 -0700
Do not use raw sources in {from} - proxy via source handles
r5514@hlagh (orig r6665):  ribasushi | 2009-06-13 10:31:55 -0700
really local()ize for as the author intended
r5515@hlagh (orig r6666):  michaelr | 2009-06-13 15:23:15 -0700
Added documentation for from => $rs->as_query

r5516@hlagh (orig r6667):  caelum | 2009-06-13 16:20:02 -0700
fix master debug output for ::Replicated
r5517@hlagh (orig r6668):  ribasushi | 2009-06-14 01:22:28 -0700
Release 0.08107
r5519@hlagh (orig r6670):  ribasushi | 2009-06-14 02:00:35 -0700
Lapse in copy() docs
r5521@hlagh (orig r6672):  ribasushi | 2009-06-14 02:33:22 -0700
Forgotten piece of as_query refactor

Changes
lib/DBIx/Class.pm
lib/DBIx/Class/ResultSet.pm
lib/DBIx/Class/ResultSource.pm
lib/DBIx/Class/Row.pm
lib/DBIx/Class/Storage/DBI.pm
lib/DBIx/Class/Storage/DBI/Replicated.pm
t/84serialize.t

diff --git a/Changes b/Changes
index ade471a..e31367a 100644 (file)
--- a/Changes
+++ b/Changes
@@ -1,5 +1,11 @@
 Revision history for DBIx::Class
 
+0.08107 2009-06-14 08:21:00 (UTC)
+        - Fix serialization regression introduced in 0.08103 (affects
+          Cursor::Cached)
+        - POD fixes
+        - Fixed incomplete ::Replicated debug output
+
 0.08106 2009-06-11 21:42:00 (UTC)
         - Switched SQLite storage driver to DateTime::Format::SQLite
           (proper timezone handling)
index 6b28058..bed13d2 100644 (file)
@@ -24,7 +24,7 @@ sub component_base_class { 'DBIx::Class' }
 # i.e. first release of 0.XX *must* be 0.XX000. This avoids fBSD ports
 # brain damage and presumably various other packaging systems too
 
-$VERSION = '0.08106';
+$VERSION = '0.08107';
 
 $VERSION = eval $VERSION; # numify for warning-free dev releases
 
index c220dd9..fe622b9 100644 (file)
@@ -1930,7 +1930,13 @@ sub as_query {
 
   my $attrs = $self->_resolved_attrs_copy;
 
-  my ($sqlbind, $bind_attrs) = $self->result_source->storage
+  # For future use:
+  #
+  # in list ctx:
+  # my ($sql, \@bind, \%dbi_bind_attrs) = _select_args_to_query (...)
+  # $sql also has no wrapping parenthesis in list ctx
+  #
+  my $sqlbind = $self->result_source->storage
     ->_select_args_to_query ($attrs->{from}, $attrs->{select}, $attrs->{where}, $attrs);
 
   return $sqlbind;
@@ -2440,7 +2446,7 @@ sub _resolve_from {
       $attrs->{from}
         ||
       [{
-        -result_source => $source,
+        -source_handle => $source->handle,
         -alias => $attrs->{alias},
         $attrs->{alias} => $source->from,
       }]
@@ -2550,7 +2556,7 @@ sub _resolved_attrs {
   }
 
   $attrs->{from} ||= [ {
-    -result_source => $source,
+    -source_handle => $source->handle,
     -alias => $self->{attrs}{alias},
     $self->{attrs}{alias} => $source->from,
   } ];
@@ -3287,9 +3293,21 @@ with a father in the person table, we could explicitly use C<INNER JOIN>:
     # SELECT child.* FROM person child
     # INNER JOIN person father ON child.father_id = father.id
 
-If you need to express really complex joins or you need a subselect, you
+You can select from a subquery by passing a resultset to from as follows.
+
+    $schema->resultset('Artist')->search( 
+        undef, 
+        {   alias => 'artist2',
+            from  => [ { artist2 => $artist_rs->as_query } ],
+        } );
+
+    # and you'll get sql like this..
+    # SELECT artist2.artistid, artist2.name, artist2.rank, artist2.charfield FROM 
+    #   ( SELECT me.artistid, me.name, me.rank, me.charfield FROM artists me ) artist2
+
+If you need to express really complex joins, you
 can supply literal SQL to C<from> via a scalar reference. In this case
-the contents of the scalar will replace the table name asscoiated with the
+the contents of the scalar will replace the table name associated with the
 resultsource.
 
 WARNING: This technique might very well not work as expected on chained
index aa636a7..2287bef 100644 (file)
@@ -1135,7 +1135,7 @@ sub _resolve_join {
 
     my $rel_src = $self->related_source($join);
     return [ { $as => $rel_src->from,
-               -result_source => $rel_src,
+               -source_handle => $rel_src->handle,
                -join_type => $type,
                -join_path => [@$jpath, $join],
                -alias => $as,
index 8631832..bde2989 100644 (file)
@@ -911,7 +911,11 @@ sub set_inflated_columns {
 
 Inserts a new row into the database, as a copy of the original
 object. If a hashref of replacement data is supplied, these will take
-precedence over data in the original.
+precedence over data in the original. Also any columns which have
+the L<column info attribute|DBIx::Class::ResultSource/add_columns>
+C<< is_auto_increment => 1 >> are explicitly removed before the copy,
+so that the database can insert its own autoincremented values into
+the new object.
 
 Relationships will be followed by the copy procedure B<only> if the
 relationship specifes a true value for its
index b668f44..2590747 100644 (file)
@@ -1356,34 +1356,45 @@ sub _per_row_update_delete {
 
 sub _select {
   my $self = shift;
+
+  # localization is neccessary as
+  # 1) there is no infrastructure to pass this around (easy to do, but will wait)
+  # 2) _select_args sets it and _prep_for_execute consumes it
   my $sql_maker = $self->sql_maker;
   local $sql_maker->{for};
+
   return $self->_execute($self->_select_args(@_));
 }
 
 sub _select_args_to_query {
   my $self = shift;
 
+  # localization is neccessary as
+  # 1) there is no infrastructure to pass this around (easy to do, but will wait)
+  # 2) _select_args sets it and _prep_for_execute consumes it
   my $sql_maker = $self->sql_maker;
   local $sql_maker->{for};
 
-  # my ($op, $bind, $ident, $bind_attrs, $select, $cond, $order, $rows, $offset) 
+  # my ($op, $bind, $ident, $bind_attrs, $select, $cond, $order, $rows, $offset)
   #  = $self->_select_args($ident, $select, $cond, $attrs);
   my ($op, $bind, $ident, $bind_attrs, @args) =
     $self->_select_args(@_);
 
-  # my ($sql, $bind) = $self->_prep_for_execute($op, $bind, $ident, [ $select, $cond, $order, $rows, $offset ]);
+  # my ($sql, $prepared_bind) = $self->_prep_for_execute($op, $bind, $ident, [ $select, $cond, $order, $rows, $offset ]);
   my ($sql, $prepared_bind) = $self->_prep_for_execute($op, $bind, $ident, \@args);
+  $prepared_bind ||= [];
 
-  return \[ "($sql)", @{ $prepared_bind || [] }];
+  return wantarray
+    ? ($sql, $prepared_bind, $bind_attrs)
+    : \[ "($sql)", @$prepared_bind ]
+  ;
 }
 
 sub _select_args {
   my ($self, $ident, $select, $condition, $attrs) = @_;
 
-  my $for = delete $attrs->{for};
   my $sql_maker = $self->sql_maker;
-  $sql_maker->{for} = $for;
+  $sql_maker->{for} = delete $attrs->{for};
 
   my $order = { map
     { $attrs->{$_} ? ( $_ => $attrs->{$_} ) : ()  }
@@ -1452,8 +1463,8 @@ sub _resolve_ident_sources {
         $tabinfo = $_->[0];
       }
 
-      $alias2source->{$tabinfo->{-alias}} = $tabinfo->{-result_source}
-        if ($tabinfo->{-result_source});
+      $alias2source->{$tabinfo->{-alias}} = $tabinfo->{-source_handle}->resolve
+        if ($tabinfo->{-source_handle});
     }
   }
 
index 259cdc5..731e16a 100644 (file)
@@ -366,10 +366,11 @@ around connect_info => sub {
     $res = $self->$next($info, @extra);
   }
 
-  # May have to reapply role if master will be reblessed to a more specific
-  # driver.
-  $self->master->_determine_driver;
-  DBIx::Class::Storage::DBI::Replicated::WithDSN->meta->apply($self->master);
+  # Make sure master is blessed into the correct class and apply role to it.
+  my $master = $self->master;
+  $master->_determine_driver;
+  Moose::Meta::Class->initialize(ref $master);
+  DBIx::Class::Storage::DBI::Replicated::WithDSN->meta->apply($master);
 
   $wantarray ? @res : $res;
 };
@@ -405,7 +406,6 @@ Lazy builder for the L</master> attribute.
 sub _build_master {
   my $self = shift @_;
   my $master = DBIx::Class::Storage::DBI->new($self->schema);
-  DBIx::Class::Storage::DBI::Replicated::WithDSN->meta->apply($master);
   $master
 }
 
index 76e18c2..99449d4 100644 (file)
@@ -2,6 +2,7 @@ use strict;
 use warnings;  
 
 use Test::More;
+use Test::Exception;
 use lib qw(t/lib);
 use DBICTest;
 use Storable qw(dclone freeze thaw);
@@ -20,10 +21,11 @@ my %stores = (
     },
 );
 
-plan tests => (7 * keys %stores);
+plan tests => (11 * keys %stores);
 
 for my $name (keys %stores) {
     my $store = $stores{$name};
+    my $copy;
 
     my $artist = $schema->resultset('Artist')->find(1);
     
@@ -39,22 +41,35 @@ for my $name (keys %stores) {
         DBICTest::CD->result_source_instance->schema(undef);
     }
 
-    my $copy = eval { $store->($artist) };
+    lives_ok { $copy = $store->($artist) } "serialize row object lives: $name";
     is_deeply($copy, $artist, "serialize row object works: $name");
 
-    # Test that an object with a related_resultset can be serialized.
-    my @cds = $artist->related_resultset("cds");
+    my $cd_rs = $artist->search_related("cds");
+
+    # test that a result source can be serialized as well
+
+    $cd_rs->_resolved_attrs;  # this builds up the {from} attr
 
+    lives_ok {
+      $copy = $store->($cd_rs);
+      is_deeply (
+        [ $copy->all ],
+        [ $cd_rs->all ],
+        "serialize resultset works: $name",
+      );
+    } "serialize resultset lives: $name";
+
+    # Test that an object with a related_resultset can be serialized.
     ok $artist->{related_resultsets}, 'has key: related_resultsets';
 
-    $copy = eval { $store->($artist) };
+    lives_ok { $copy = $store->($artist) } "serialize row object with related_resultset lives: $name";
     for my $key (keys %$artist) {
         next if $key eq 'related_resultsets';
         next if $key eq '_inflated_column';
         is_deeply($copy->{$key}, $artist->{$key},
                   qq[serialize with related_resultset "$key"]);
     }
-  
+
     ok eval { $copy->discard_changes; 1 } or diag $@;
     is($copy->id, $artist->id, "IDs still match ");
 }