[Jifty-commit] r3923 - in Jifty-DBI/trunk: lib/Jifty/DBI

jifty-commit at lists.jifty.org jifty-commit at lists.jifty.org
Mon Aug 20 16:57:43 EDT 2007


Author: efunneko
Date: Mon Aug 20 16:57:43 2007
New Revision: 3923

Modified:
   Jifty-DBI/trunk/lib/Jifty/DBI/Collection.pm
   Jifty-DBI/trunk/lib/Jifty/DBI/Handle.pm
   Jifty-DBI/trunk/t/01searches.t

Log:
Added support for the IN operator within limits.  This should be accompanied by an array ref of values to be compared against.  It also allows an array ref to be passed with the '=' operator to accomplish the same thing

Modified: Jifty-DBI/trunk/lib/Jifty/DBI/Collection.pm
==============================================================================
--- Jifty-DBI/trunk/lib/Jifty/DBI/Collection.pm	(original)
+++ Jifty-DBI/trunk/lib/Jifty/DBI/Collection.pm	Mon Aug 20 16:57:43 2007
@@ -917,6 +917,11 @@
 
 ENDSWITH is like LIKE, except it prepends a % to the beginning of the string
 
+=item "IN"
+
+IN matches a column within a set of values.  The value specified in the limit
+should be an array reference of values.
+
 =back
 
 =item entry_aggregator 
@@ -956,8 +961,16 @@
         unless defined $args{value};
 
     # make passing in an object DTRT
-    if ( ref( $args{value} ) && $args{value}->isa('Jifty::DBI::Record') ) {
-        $args{value} = $args{value}->id;
+    my $value_ref = ref( $args{value} );
+    if ( $value_ref ) {
+        if ( ( $value_ref ne 'ARRAY' ) && 
+             $args{value}->isa('Jifty::DBI::Record') ) {
+            $args{value} = $args{value}->id;
+        }
+        elsif ( $value_ref eq 'ARRAY' ) {
+            map {$_ = ( ( ref $_ && $_->isa('Jifty::DBI::Record') ) ?
+                        ( $_->id ) : $_ ) } @{$args{value}};
+        }
     }
 
     #since we're changing the search criteria, we need to redo the search
@@ -979,22 +992,15 @@
         # we're doing an IS or IS NOT (null), don't quote the operator.
 
         if ( $args{'quote_value'} && $args{'operator'} !~ /IS/i ) {
-            my $tmp = $self->_handle->dbh->quote( $args{'value'} );
-
-            # Accomodate DBI drivers that don't understand UTF8
-            if ( $] >= 5.007 ) {
-                require Encode;
-                if ( Encode::is_utf8( $args{'value'} ) ) {
-                    Encode::_utf8_on($tmp);
-                }
+            if ( $value_ref eq 'ARRAY' ) {
+                map {$_ = $self->_quote_value( $_ )} @{$args{'value'}};
+            }
+            else {
+                $args{'value'} = $self->_quote_value( $args{'value'} );
             }
-            $args{'value'} = $tmp;
         }
     }
 
-    #TODO: $args{'value'} should take an array of values and generate
-    # the proper where clause.
-
     #If we're performing a left join, we really want the alias to be the
     #left join criterion.
 
@@ -1059,6 +1065,13 @@
         }
     }
 
+    if ( $value_ref eq 'ARRAY' ) {
+        croak 'Limits with an array ref are only allowed with operator \'IN\' or \'=\''
+            unless $args{'operator'} =~ /^(IN|=)$/i;
+        $args{'value'} = '( '. join(',', @{$args{'value'}}) .' )';
+        $args{'operator'} = 'IN';
+    }
+
     my $clause = {
         column   => $qualified_column,
         operator => $args{'operator'},
@@ -1188,6 +1201,24 @@
     $self->{$type} = $value;
 }
 
+# quote the search value
+sub _quote_value {
+    my $self = shift;
+    my ( $value ) = @_;
+
+    my $tmp = $self->_handle->dbh->quote( $value );
+
+    # Accomodate DBI drivers that don't understand UTF8
+    if ( $] >= 5.007 ) {
+      require Encode;
+      if ( Encode::is_utf8( $tmp ) ) {
+        Encode::_utf8_on($tmp);
+      }
+    }
+    return $tmp;
+
+}
+
 =head2 order_by_cols DEPRECATED
 
 *DEPRECATED*. Use C<order_by> method.

Modified: Jifty-DBI/trunk/lib/Jifty/DBI/Handle.pm
==============================================================================
--- Jifty-DBI/trunk/lib/Jifty/DBI/Handle.pm	(original)
+++ Jifty-DBI/trunk/lib/Jifty/DBI/Handle.pm	Mon Aug 20 16:57:43 2007
@@ -661,8 +661,13 @@
     my $value    = shift;
 
     if ($self->_case_insensitivity_valid($column, $operator, $value)) {
-      $column = "lower($column)";
-      $value  = "lower($value)";
+        $column = "lower($column)";
+        if (ref $value eq 'ARRAY') {
+            map {$_ = "lower($_)"} @{$value};
+        }
+        else {
+            $value  = "lower($value)";
+        }
     }
     return ( $column, $operator, $value );
 }

Modified: Jifty-DBI/trunk/t/01searches.t
==============================================================================
--- Jifty-DBI/trunk/t/01searches.t	(original)
+++ Jifty-DBI/trunk/t/01searches.t	Mon Aug 20 16:57:43 2007
@@ -8,7 +8,7 @@
 BEGIN { require "t/utils.pl" }
 our (@available_drivers);
 
-use constant TESTS_PER_DRIVER => 82;
+use constant TESTS_PER_DRIVER => 97;
 
 my $total = scalar(@available_drivers) * TESTS_PER_DRIVER;
 plan tests => $total;
@@ -136,6 +136,19 @@
         isa_ok( $first_rec, 'Jifty::DBI::Record', 'First returns record object' );
         is( $first_rec->login, 'audreyt', 'login is correct' );
 
+        # IN
+        $users_obj->clean_slate;
+        is_deeply( $users_obj, $clean_obj, 'after clean_slate looks like new object');
+        $users_obj->limit( column => 'login', operator => 'IN', 
+                           value => ['cubic', 'obra', 'glasser', 'audreyt'] );
+        is( $users_obj->count, 4, "found 4 user ids" );
+        my %logins = (cubic => 1, obra => 1, glasser => 1, audreyt => 1);
+        while ( my $user = $users_obj->next ) {
+          is ( defined $logins{$user->login}, 1, 'Found login' );
+          delete $logins{$user->login};
+        }
+        is ( scalar( keys( %logins ) ), 0, 'All logins found' );
+
         # IS NULL
         # XXX TODO FIXME: column => undef should be handled as NULL
         $users_obj->clean_slate;
@@ -166,6 +179,14 @@
         is_deeply( $users_obj, $clean_obj, 'after clean_slate looks like new object');
         $users_obj->limit( column => 'name', value => 'jesse vincent' );
         is( $users_obj->count, 1, "case insensitive, non-matched case, should find one row");
+        $users_obj->clean_slate;
+        is_deeply( $users_obj, $clean_obj, 'after clean_slate looks like new object');
+        $users_obj->limit( column => 'name', value => ['Jesse Vincent', 'Audrey Tang'], operator => 'IN');
+        is( $users_obj->count, 2, "case insensitive, matching case, should find two rows");
+        $users_obj->clean_slate;
+        is_deeply( $users_obj, $clean_obj, 'after clean_slate looks like new object');
+        $users_obj->limit( column => 'name', value => ['jesse vincent', 'audrey tang'], operator => 'IN');
+        is( $users_obj->count, 2, "case insensitive, non-matched case, should find two rows");
 
         # CASE SENSITIVITY, testing with case_sensitive => 1
         $users_obj->clean_slate;
@@ -179,6 +200,22 @@
             local $TODO = "MySQL still needs case sensitive fixes" if ( $d eq 'mysql' || $d eq 'mysqlPP' );
             is( $users_obj->count, 0, "case sensitive search, should find zero rows");
         }
+        $users_obj->clean_slate;
+        is_deeply( $users_obj, $clean_obj, 'after clean_slate looks like new object');
+        $users_obj->limit( column => 'name', value => ['Jesse Vincent', 'Audrey Tang'], operator => 'IN',
+                           case_sensitive => 1 );
+        TODO: {
+            local $TODO = "MySQL still needs case sensitive fixes" if ( $d eq 'mysql' || $d eq 'mysqlPP' );
+            is( $users_obj->count, 2, "case sensitive search, should find two rows");
+        }
+        $users_obj->clean_slate;
+        is_deeply( $users_obj, $clean_obj, 'after clean_slate looks like new object');
+        $users_obj->limit( column => 'name', value => ['jesse vincent', 'audrey tang'], operator => 'IN', 
+                           case_sensitive => 1 );
+        TODO: {
+            local $TODO = "MySQL still needs case sensitive fixes" if ( $d eq 'mysql' || $d eq 'mysqlPP' );
+            is( $users_obj->count, 0, "case sensitive search, should find zero rows");
+        }
 
         # ORDER BY / GROUP BY
         $users_obj->clean_slate;


More information about the Jifty-commit mailing list