[Jifty-commit] r1871 - in jifty/trunk: lib/Jifty/Action/Record

jifty-commit at lists.jifty.org jifty-commit at lists.jifty.org
Sun Aug 27 23:18:09 EDT 2006


Author: nelhage
Date: Sun Aug 27 23:18:08 2006
New Revision: 1871

Modified:
   jifty/trunk/lib/Jifty/Action/Record/Search.pm
   jifty/trunk/t/TestApp/t/12-search.t

Log:
Adding substring search and date comparison to J::A::R::Search

Modified: jifty/trunk/lib/Jifty/Action/Record/Search.pm
==============================================================================
--- jifty/trunk/lib/Jifty/Action/Record/Search.pm	(original)
+++ jifty/trunk/lib/Jifty/Action/Record/Search.pm	Sun Aug 27 23:18:08 2006
@@ -25,6 +25,17 @@
 restrictions. Remove any arguments that render as password fields, or
 refer to collections.
 
+Generate additional search arguments for each field based on the
+following criteria:
+
+=over 4
+
+=item C<text> or C<textarea> fields
+
+Create C<field>_contains and C<field>_lacks arguments.
+
+=back
+
 =cut
 
 sub arguments {
@@ -51,16 +62,27 @@
         
         if(lc $info->{'render_as'} eq 'password') {
             delete $args->{$field};
+            next;
         } 
-        if($column && defined(my $refers_to = $column->refers_to)) {
+
+        warn "No column for: $field" unless($column);
+        
+        if(defined(my $refers_to = $column->refers_to)) {
             delete $args->{$field}
              if UNIVERSAL::isa($refers_to, 'Jifty::Collection');
         }
         # XXX TODO: What about booleans? Checkbox doesn't quite work,
         # since there are three choices: yes, no, either.
 
-        # XXX TODO: Create arguments for comparisons and substring
-        # matching
+        if($column->type =~ /^text/i) {
+            my $label = $info->{label} || $field;
+            $args->{"${field}_contains"} = {%$info, label => "$label contains"};
+            $args->{"${field}_lacks"} = {%$info, label => "$label lacks"};
+        } elsif($column->type =~ /(?:date|time)/) {
+            my $label = $info->{label} || $field;
+            $args->{"${field}_after"} = {%$info, label => "$label after"};
+            $args->{"${field}_before"} = {%$info, label => "$label before"};
+        }
     }
 
     return $self->_cached_arguments($args);
@@ -88,11 +110,44 @@
 
     for my $field (grep {$self->has_argument($_)} $self->argument_names) {
         my $value = $self->argument_value($field);
+        
+        my $column = $self->record->column($field);
+        my $op = undef;
+        
+        if(!$column) {
+            # If we don't have a column, this is a comparison or
+            # substring search. Skip undef values for those, since
+            # NULL makes no sense.
+            next unless defined($value);
+            next if $value =~ /^\s*$/;
+
+            if($field =~ m{^(.*)_([[:alpha:]]+)$}) {
+                $field = $1;
+                $op = $2;
+                if($op eq 'contains') {
+                    $op = 'LIKE';
+                    $value = "%$value%";
+                } elsif($op eq 'lacks') {
+                    $op = 'NOT LIKE';
+                    $value = "%$value%";
+                } elsif($op eq 'after') {
+                    $op = '>';
+                } elsif($op eq 'before') {
+                    $op = '<';
+                }
+            } else {
+                next;
+            }
+        }
+        
         if(defined($value)) {
             next if $value =~ /^\s*$/;
             $collection->limit(
-                column => $field,
-                value  => $value
+                column   => $field,
+                value    => $value,
+                operator => $op || "=",
+                entry_aggregator => 'AND',
+                $op ? (case_sensitive => 0) : (),
                );
         } else {
             $collection->limit(

Modified: jifty/trunk/t/TestApp/t/12-search.t
==============================================================================
--- jifty/trunk/t/TestApp/t/12-search.t	(original)
+++ jifty/trunk/t/TestApp/t/12-search.t	Sun Aug 27 23:18:08 2006
@@ -42,7 +42,7 @@
 $user = TestApp::Model::User->new(current_user => TestApp::CurrentUser->superuser);
 
 ok($user->create(
-        name       => 'third_test',
+        name       => 'third_user',
         email      => 'test3 at not.a.domain',
         password    => 'hahaha',
         created_on => '1999-12-31 23:59'
@@ -113,7 +113,7 @@
 
 isa_ok($result, 'Jifty::Collection');
 is($result->count, 1);
-is($result->first->name, 'third_test');
+is($result->first->name, 'third_user');
 
 # An empty search should return everything
 $search->argument_values({});
@@ -125,12 +125,70 @@
 is($result->count, 3);
 
 # We ignore empty but defined fields
+$search->argument_values({email => "", name => 'third_user'});
+$search->run;
+
+$result = $search->result->content('search');
+
+isa_ok($result, 'Jifty::Collection');
+is($result->count, 1);
+is($result->first->name, 'third_user');
+
+# Substring searching
+$search->argument_values({name_contains => 'test'});
+$search->run;
+
+$result = $search->result->content('search');
+
+isa_ok($result, 'Jifty::Collection');
+is($result->count, 2);
+is($result->items_array_ref->[0]->name, 'test1');
+is($result->items_array_ref->[1]->name, 'test2');
+
+# Negative substring
+$search->argument_values({name_lacks => 'test'});
+$search->run;
+
+$result = $search->result->content('search');
+
+isa_ok($result, 'Jifty::Collection');
+is($result->count, 1);
+is($result->first->name, 'third_user');
+
+# This is case insensitive substring
+$search->argument_values({name_contains => 'TEST'});
+$search->run;
+
+$result = $search->result->content('search');
+
+isa_ok($result, 'Jifty::Collection');
+is($result->count, 2);
+
+# It makes no sense to contain NULL, so ignore that:
+$search->argument_values({name_contains => undef});
+$search->run;
+
+$result = $search->result->content('search');
+
+isa_ok($result, 'Jifty::Collection');
+is($result->count, 3);
+
+# Datetime searching
+$search->argument_values({created_on_after => '2006-01-01'});
+$search->run;
+
+$result = $search->result->content('search');
+
+isa_ok($result, 'Jifty::Collection');
+is($result->count, 1);
+is($result->first->name, 'test1');
 
-$search->argument_values({email => "", name => 'third_test'});
+# More datetime
+$search->argument_values({created_on_before => '2000-05-32 4:37PM'});
 $search->run;
 
 $result = $search->result->content('search');
 
 isa_ok($result, 'Jifty::Collection');
 is($result->count, 1);
-is($result->first->name, 'third_test');
+is($result->first->name, 'third_user');


More information about the Jifty-commit mailing list