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]/