expression expansion pass, zeroth cut
[scpubgit/Q-Branch.git] / lib / SQL / Abstract.pm
index d30a7e3..3327db7 100644 (file)
@@ -27,7 +27,7 @@ BEGIN {
 # GLOBALS
 #======================================================================
 
-our $VERSION  = '1.85';
+our $VERSION  = '1.86';
 
 # This would confuse some packagers
 $VERSION = eval $VERSION if $VERSION =~ /_/; # numify for warning-free dev releases
@@ -464,17 +464,24 @@ sub select {
   my $where  = shift;
   my $order  = shift;
 
-  my($where_sql, @bind) = $self->where($where, $order);
+  my ($fields_sql, @bind) = $self->_select_fields($fields);
 
-  my $f = (ref $fields eq 'ARRAY') ? join ', ', map { $self->_quote($_) } @$fields
-                                   : $fields;
-  my $sql = join(' ', $self->_sqlcase('select'), $f,
+  my ($where_sql, @where_bind) = $self->where($where, $order);
+  push @bind, @where_bind;
+
+  my $sql = join(' ', $self->_sqlcase('select'), $fields_sql,
                       $self->_sqlcase('from'),   $table)
           . $where_sql;
 
   return wantarray ? ($sql, @bind) : $sql;
 }
 
+sub _select_fields {
+  my ($self, $fields) = @_;
+  return ref $fields eq 'ARRAY' ? join ', ', map { $self->_quote($_) } @$fields
+                                : $fields;
+}
+
 #======================================================================
 # DELETE
 #======================================================================
@@ -516,7 +523,7 @@ sub where {
 
   # where ?
   my ($sql, @bind) = $self->_recurse_where($where);
-  $sql = $sql ? $self->_sqlcase(' where ') . "( $sql )" : '';
+  $sql = (defined $sql and length $sql) ? $self->_sqlcase(' where ') . "( $sql )" : '';
 
   # order by?
   if ($order) {
@@ -528,14 +535,26 @@ sub where {
   return wantarray ? ($sql, @bind) : $sql;
 }
 
+sub _expand_expr {
+  my ($self, $expr, $logic) = @_;
+  if (ref($expr) eq 'HASH' and keys %$expr > 1) {
+    $logic ||= 'and';
+    return +{ "-${logic}" => [
+      map +{ $_ => $expr->{$_} }, sort keys %$expr
+    ] };
+  }
+  return $expr;
+}
 
 sub _recurse_where {
   my ($self, $where, $logic) = @_;
 
+  my $where_exp = $self->_expand_expr($where, $logic);
+
   # dispatch on appropriate method according to refkind of $where
-  my $method = $self->_METHOD_FOR_refkind("_where", $where);
+  my $method = $self->_METHOD_FOR_refkind("_where", $where_exp);
 
-  my ($sql, @bind) =  $self->$method($where, $logic);
+  my ($sql, @bind) =  $self->$method($where_exp, $logic);
 
   # DBIx::Class used to call _recurse_where in scalar context
   # something else might too...
@@ -837,7 +856,7 @@ sub _where_op_VALUE {
   # special-case NULL
   if (! defined $rhs) {
     return defined $lhs
-      ? $self->_convert($self->_quote($lhs)) . ' IS NULL'
+      ? $self->_where_hashpair_HASHREF($lhs, { -is => undef })
       : undef
     ;
   }
@@ -1082,19 +1101,14 @@ sub _where_hashpair_ARRAYREFREF {
 sub _where_hashpair_SCALAR {
   my ($self, $k, $v) = @_;
   $self->_debug("NOREF($k) means simple key=val: $k $self->{cmp} $v");
-  my $sql = join ' ', $self->_convert($self->_quote($k)),
-                      $self->_sqlcase($self->{cmp}),
-                      $self->_convert('?');
-  my @bind =  $self->_bindtype($k, $v);
-  return ($sql, @bind);
+  return ($self->_where_hashpair_HASHREF($k, { $self->{cmp} => $v }));
 }
 
 
 sub _where_hashpair_UNDEF {
   my ($self, $k, $v) = @_;
   $self->_debug("UNDEF($k) means IS NULL");
-  my $sql = $self->_quote($k) . $self->_sqlcase(' is null');
-  return ($sql);
+  return $self->_where_hashpair_HASHREF($k, { -is => undef });
 }
 
 #======================================================================