InflateColumn::DateTime overloads inflate/deflate, but doesn't affect search 
conditions.

So, while ref($row->dte) == 'DateTime', if you were to do a search for a 
particular value of dte:

  $rs->search({ dte => DateTime->now() })

... the DateTime object would be passed to SQL::Abstract where it would be 
stringified.  This is not intuitive.

While I'm told by <ilmari> that this is being worked on in a SQL::Abstract 
refactoring, I didn't want to wait.  Below is a patch on DBIx::Class::ResultSet 
that will deflate any references found in the WHERE args before submitting to 
the driver.  I've put this here rather than at the Storage level because it 
seems that the result_source data (which seems to contain the column_info data 
that InflateColumn modifies) is not available further down the chain.  While 
it'd be nice to include this in DBIx::Class::InflateColumn, I don't see a way 
to do that.  Please let me know if I'm off base here.

With the attached code, one would be able to do a search using a ref and have 
it behave the same as getting/setting the value on a row.  This end behavior is 
more intuitive.  This is not throughly tested.

Eric Waters

-- patch follows --

*** ResultSet.pm        Fri May 25 16:51:58 2007
--- /home/users/e/ewaters/lib/perl5/DBIx/Class/ResultSet.pm     Fri May 25 
16:50:04 2007
*************** sub search_rs {
*** 230,235 ****
--- 230,237 ----
          : $cond);
    }
  
+   $self->_deflate_references($new_attrs->{where}) if defined 
$new_attrs->{where};
+ 
    if (defined $having) {
      $new_attrs->{having} = (
        defined $new_attrs->{having}
*************** sub search_rs {
*** 249,254 ****
--- 251,286 ----
    return $rs;
  }
  
+ ## Given a reference to a WHERE structure, replace value references with 
deflated scalar
+ #  Called from any point the user defines WHERE parameters (new(), single())
+ sub _deflate_references {
+   my ($self, $where) = @_;
+   
+   while (my ($key, $value) = each %$where) {
+     # Handle -or, -and
+         if (ref($value) && ref($value) eq 'ARRAY') {
+           $self->_deflate_references($_) foreach @$value;
+           next;
+         }
+         unless (ref($value) && ref($value) eq 'HASH') {
+           next;
+         }
+         my $col = $key;
+ 
+         # Do we need to deflate this column?
+         my $info = $self->result_source->column_info($col)->{_inflate_info};
+         next if ! $info;
+         my $deflator = $info->{deflate};
+         $self->throw_exception("No deflator for $col") unless defined 
$deflator;
+ 
+         foreach my $col_val (values %$value) {
+           # Is the column value comparator a non-simple reference
+           next if ! ref($col_val) || ref($col_val) =~ 
m/^(SCALAR|ARRAY|HASH)$/;
+           $col_val = $deflator->($col_val, $self);
+         }
+   }
+ }
+ 
  =head2 search_literal
  
  =over 4
*************** sub single {
*** 520,525 ****
--- 552,558 ----
    my ($self, $where) = @_;
    my $attrs = { %{$self->_resolved_attrs} };
    if ($where) {
+     $self->_deflate_references($where);
      if (defined $attrs->{where}) {
        $attrs->{where} = {
          '-and' =>

_______________________________________________
List: http://lists.rawmode.org/cgi-bin/mailman/listinfo/dbix-class
Wiki: http://dbix-class.shadowcatsystems.co.uk/
IRC: irc.perl.org#dbix-class
SVN: http://dev.catalyst.perl.org/repos/bast/trunk/DBIx-Class/
Searchable Archive: http://www.mail-archive.com/[email protected]/

Reply via email to