Merge 'and_or' into 'trunk'
Peter Rabbitson [Thu, 23 Apr 2009 22:16:52 +0000 (22:16 +0000)]
r5860@Thesaurus (orig r5859):  arcanez | 2009-04-07 18:37:24 +0200
 * branch to work on -and => [], -or => {}
r5862@Thesaurus (orig r5861):  arcanez | 2009-04-08 04:47:47 +0200
fix for hashref $logic
r5969@Thesaurus (orig r5968):  arcanez | 2009-04-24 00:03:03 +0200
readd the failing test back in
r5970@Thesaurus (orig r5969):  ribasushi | 2009-04-24 00:16:41 +0200
Strip some parenthesis for easier reading

1  2 
lib/SQL/Abstract.pm

diff --combined lib/SQL/Abstract.pm
@@@ -63,7 -63,7 +63,7 @@@ sub new 
    delete $opt{case} if $opt{case} && $opt{case} ne 'lower';
  
    # default logic for interpreting arrayrefs
 -  $opt{logic} = uc $opt{logic} || 'OR';
 +  $opt{logic} = $opt{logic} ? uc $opt{logic} : 'OR';
  
    # how to return bind vars
    # LDNOTE: changed nwiger code : why this 'delete' ??
@@@ -528,9 -528,10 +528,10 @@@ sub _where_hashpair_ARRAYREF 
  }
  
  sub _where_hashpair_HASHREF {
-   my ($self, $k, $v) = @_;
+   my ($self, $k, $v, $logic) = @_;
+   $logic ||= 'and';
  
-   my (@all_sql, @all_bind);
+   my ($all_sql, @all_bind);
  
    for my $op (sort keys %$v) {
      my $val = $v->{$op};
            @bind = @sub_bind;
          },
  
+         HASHREF => sub {
+           ($sql, @bind) = $self->_where_hashpair_HASHREF($k, $val, $op);
+         },
          UNDEF => sub {          # CASE: col => {op => undef} : sql "IS (NOT)? NULL"
            my $is = ($op =~ $self->{equality_op})   ? 'is'     :
                     ($op =~ $self->{inequality_op}) ? 'is not' :
        });
      }
  
-     push @all_sql, $sql;
+     ($all_sql) = (defined $all_sql and $all_sql) ? $self->_join_sql_clauses($logic, [$all_sql, $sql], []) : $sql;
      push @all_bind, @bind;
    }
-   return $self->_join_sql_clauses('and', \@all_sql, \@all_bind);
+   return ($all_sql, @all_bind);
  }
  
  
@@@ -699,39 -703,16 +703,39 @@@ sub _where_UNDEF 
  sub _where_field_BETWEEN {
    my ($self, $k, $op, $vals) = @_;
  
 -  ref $vals eq 'ARRAY' && @$vals == 2 
 -    or puke "special op 'between' requires an arrayref of two values";
 +  (ref $vals eq 'ARRAY' && @$vals == 2) or 
 +  (ref $vals eq 'REF' && (@$$vals == 1 || @$$vals == 2 || @$$vals == 3))
 +    or puke "special op 'between' requires an arrayref of two values (or a scalarref or arrayrefref for literal SQL)";
  
 -  my ($label)       = $self->_convert($self->_quote($k));
 -  my ($placeholder) = $self->_convert('?');
 -  my $and           = $self->_sqlcase('and');
 +  my ($clause, @bind, $label, $and, $placeholder);
 +  $label       = $self->_convert($self->_quote($k));
 +  $and         = ' ' . $self->_sqlcase('and') . ' ';
 +  $placeholder = $self->_convert('?');
    $op               = $self->_sqlcase($op);
  
 -  my $sql  = "( $label $op $placeholder $and $placeholder )";
 -  my @bind = $self->_bindtype($k, @$vals);
 +  if (ref $vals eq 'REF') {
 +    ($clause, @bind) = @$$vals;
 +  }
 +  else {
 +    my (@all_sql, @all_bind);
 +
 +    foreach my $val (@$vals) {
 +      my ($sql, @bind) = $self->_SWITCH_refkind($val, {
 +         SCALAR => sub {
 +           return ($placeholder, ($val));
 +         },
 +         SCALARREF => sub {
 +           return ($self->_convert($$val), ());
 +         },
 +      });
 +      push @all_sql, $sql;
 +      push @all_bind, @bind;
 +    }
 +
 +    $clause = (join $and, @all_sql);
 +    @bind = $self->_bindtype($k, @all_bind);
 +  }
 +  my $sql = "( $label $op $clause )";
    return ($sql, @bind)
  }