First stab at adding resultsources to each join in select - works won-der-ful-ly
Peter Rabbitson [Mon, 8 Jun 2009 11:00:54 +0000 (11:00 +0000)]
lib/DBIx/Class/ResultSet.pm
lib/DBIx/Class/ResultSource.pm
lib/DBIx/Class/Storage/DBI.pm
t/bind/bindtype_columns.t

index 4ab4afa..7ef13b5 100644 (file)
@@ -2435,7 +2435,11 @@ sub _resolve_from {
   my $attrs = $self->{attrs};
 
   my $from = $attrs->{from}
-    || [ { $attrs->{alias} => $source->from } ];
+    || [ {
+      -result_source => $source,
+      -alias => $attrs->{alias},
+      $attrs->{alias} => $source->from,
+    } ];
 
   my $seen = { %{$attrs->{seen_join}||{}} };
 
@@ -2540,7 +2544,11 @@ sub _resolved_attrs {
     push( @{ $attrs->{as} }, @$adds );
   }
 
-  $attrs->{from} ||= [ { $self->{attrs}{alias} => $source->from } ];
+  $attrs->{from} ||= [ {
+    -result_source => $source,
+    -alias => $self->{attrs}{alias},
+    $self->{attrs}{alias} => $source->from,
+  } ];
 
   if ( exists $attrs->{join} || exists $attrs->{prefetch} ) {
     my $join = delete $attrs->{join} || {};
@@ -2613,7 +2621,7 @@ sub _joinpath_aliases {
 
     my $p = $paths;
     $p = $p->{$_} ||= {} for @{$j->[0]{-join_path}};
-    push @{$p->{-join_aliases} }, $j->[0]{-join_alias};
+    push @{$p->{-join_aliases} }, $j->[0]{-alias};
   }
 
   return $paths;
index cd819a8..c8f7e8d 100644 (file)
@@ -1120,10 +1120,13 @@ sub _resolve_join {
       $type = $rel_info->{attrs}{join_type} || '';
       $force_left->{force} = 1 if lc($type) eq 'left';
     }
-    return [ { $as => $self->related_source($join)->from,
+
+    my $rel_src = $self->related_source($join);
+    return [ { $as => $rel_src->from,
+               -result_source => $rel_src,
                -join_type => $type,
                -join_path => [@$jpath, $join],
-               -join_alias => $as,
+               -alias => $as,
                -relation_chain_depth => $seen->{-relation_chain_depth} || 0,
              },
              $self->_resolve_condition($rel_info->{cond}, $as, $alias) ];
index c20a931..666d318 100644 (file)
@@ -10,7 +10,7 @@ use DBI;
 use DBIx::Class::SQLAHacks;
 use DBIx::Class::Storage::DBI::Cursor;
 use DBIx::Class::Storage::Statistics;
-use Scalar::Util qw/blessed weaken/;
+use Scalar::Util();
 use List::Util();
 
 __PACKAGE__->mk_group_accessors('simple' =>
@@ -717,7 +717,7 @@ sub _connect {
 
     if($dbh && !$self->unsafe) {
       my $weak_self = $self;
-      weaken($weak_self);
+      Scalar::Util::weaken($weak_self);
       $dbh->{HandleError} = sub {
           if ($weak_self) {
             $weak_self->throw_exception("DBI Exception: $_[0]");
@@ -898,7 +898,7 @@ sub txn_rollback {
 sub _prep_for_execute {
   my ($self, $op, $extra_bind, $ident, $args) = @_;
 
-  if( blessed($ident) && $ident->isa("DBIx::Class::ResultSource") ) {
+  if( Scalar::Util::blessed($ident) && $ident->isa("DBIx::Class::ResultSource") ) {
     $ident = $ident->from();
   }
 
@@ -990,7 +990,7 @@ sub _execute {
 
 sub insert {
   my ($self, $source, $to_insert) = @_;
-  
+
   my $ident = $source->from; 
   my $bind_attributes = $self->source_bind_attributes($source);
 
@@ -1092,7 +1092,7 @@ sub delete {
   my $self = shift @_;
   my $source = shift @_;
   
-  my $bind_attrs = {}; ## If ever it's needed...
+  my $bind_attrs = $self->source_bind_attributes($source);
   
   return $self->_execute('delete' => [], $source, $bind_attrs, @_);
 }
@@ -1213,7 +1213,42 @@ sub _select_args {
       ( map { $_ => $attrs->{$_} } (@in_order_attrs) )
     };
   }
-  my $bind_attrs = {}; ## Future support
+
+  # the reason this is so contrived is because we have several tables in
+  # from, each with its own set of bindattrs
+  my $alias2source;
+  if ( Scalar::Util::blessed($ident) && $ident->isa("DBIx::Class::ResultSource") ) {
+    $alias2source->{$ident->alias} = $ident;
+  }
+  elsif (ref $ident eq 'ARRAY') {
+
+    for (@$ident) {
+      my $tabinfo;
+      if (ref $_ eq 'HASH') {
+        $tabinfo = $_;
+      }
+      if (ref $_ eq 'ARRAY' and ref $_->[0] eq 'HASH') {
+        $tabinfo = $_->[0];
+      }
+
+      $alias2source->{$tabinfo->{-alias}} = $tabinfo->{-result_source}
+        if ($tabinfo->{-result_source});
+    }
+  }
+
+  my $bind_attrs = {};
+  for my $alias (keys %$alias2source) {
+    my $bindtypes = $self->source_bind_attributes ($alias2source->{$alias}) || {};
+    for my $col (keys %$bindtypes) {
+
+      my $fqcn = join ('.', $alias, $col);
+      $bind_attrs->{$fqcn} = $bindtypes->{$col} if $bindtypes->{$col};
+
+      # so that unqualified searches can be bound too
+      $bind_attrs->{$col} = $bind_attrs->{$fqcn} if $alias eq 'me';
+    }
+  }
+
   my @args = ('select', $attrs->{bind}, $ident, $bind_attrs, $select, $condition, $order);
   if ($attrs->{software_limit} ||
       $sql_maker->_default_limit_syntax eq "GenericSubQ") {
index 1462d9b..629185d 100644 (file)
@@ -49,10 +49,7 @@ my $new;
   is($row->get_column('bytea'), $big_long_string, "Created the blob correctly.");
 }
 
-TODO: {
-  local $TODO =
-    'Passing bind attributes to $sth->bind_param() should be implemented (it only works in $storage->insert ATM)';
-
+{
   my $rs = $schema->resultset('BindType')->search({ bytea => $big_long_string });
 
   # search on the bytea column (select)