[Catalyst-commits] r7296 - trunk/examples/CatalystAdvent/root/2007/pen

zby at dev.catalyst.perl.org zby at dev.catalyst.perl.org
Fri Dec 14 13:01:21 GMT 2007


Author: zby
Date: 2007-12-14 13:01:20 +0000 (Fri, 14 Dec 2007)
New Revision: 7296

Modified:
   trunk/examples/CatalystAdvent/root/2007/pen/15.pod
Log:
names changed

Modified: trunk/examples/CatalystAdvent/root/2007/pen/15.pod
===================================================================
--- trunk/examples/CatalystAdvent/root/2007/pen/15.pod	2007-12-14 01:16:41 UTC (rev 7295)
+++ trunk/examples/CatalystAdvent/root/2007/pen/15.pod	2007-12-14 13:01:20 UTC (rev 7296)
@@ -39,7 +39,7 @@
 
 The solution I propose is this simple module:
 
-    package Ymogen2::DB::RSSearchBase;
+    package AdvancedSearch;
     
     use strict;
     use warnings;
@@ -54,42 +54,42 @@
                 $self = $self->$search( $params );
                 next;
             }
-            my ( $full_name, $relation ) = $self->simple_predicate( $column );
+            my ( $full_name, $relation ) = $self->parse_column( $column );
             $self = $self->search({}, { join => $relation });
             $columns->{$full_name} = $params->{$column};
         }
         return $self->search( $columns, $attrs );
     }
 
-You use it like that:
+You can use it like that:
 
     my @records = $schema->ResultSet( 'MyTable' )->advanced_search( 
-        \%search_params, 
+        $reqest->params, 
         { page => 1, rows => 5 } 
     );
 
 But first you need to make your ResultSet class inherit from it.  This can be
 done in several ways, what we do is adding:
 
-    __PACKAGE__->resultset_class(__PACKAGE__ . '::ResultSet');
+    MyTable->resultset_class(MyTable . '::ResultSet');
     
-    package Ymogen2::DB::Schema::Users::ResultSet;
+    package MyApp::DBSchema::MyTable::ResultSet;
 
-    use base qw( Ymogen2::DB::RSSearchBase );
+    use base qw( AdvancedSearch );
 
 
 to MyTable.pm.
 
 For the simple case it works just like the familiar 'search' method of the
 L<DBIx::Class::ResultSet class>. But it also works for searching in related
-records.  For that we have the simple_predicate function. It looks like that: 
+records.  For that we have the parse_column function. It looks like that: 
 
-    sub simple_predicate {
+    sub parse_column {
         my ( $self, $field)  = @_;
         if( $field =~ /(.*?)\.(.*)/ ){
             my $first = $1;
             my $rest  = $2;
-            my( $column, $join ) = simple_predicate( $rest );
+            my( $column, $join ) = parse_column( $rest );
             if ( $join ) {
                 return $column, { $first => $join };
             }else{
@@ -127,6 +127,9 @@
 =head2 The Extensions
 
 But the real advantage of this approach is how easily it can be extended.  
+It works as a kind of a fuzy L<http://en.wikipedia.org/wiki/Template_method_pattern> - where
+you don't specify the exact names of the methods to be called - but rather setup a condition
+on those names.  Like here we say - now call a method that starts with 'search_for_' if it exists.
 
 =head3 Tags
 
@@ -171,37 +174,38 @@
 
 This query will use indices and should be fast (a more detailed cover of this
 technique you can find at my blog at:
-http://perlalchemy.blogspot.com/2006/10/tags-and-search-and-dbixclass.html).
+L<http://perlalchemy.blogspot.com/2006/10/tags-and-search-and-dbixclass.html>).
 
 *Attention:* You need the 0.08008 version of DBIx::Class for this to work properly.
 
 =head3 Full Text Search
 
-For full text search I use the PostgreSQL tsearch2 engine here.  
+For full text search I use the PostgreSQL tsearch2 engine here 
+(see L<http://www.sai.msu.su/~megera/postgres/gist/tsearch/V2/>).  
 First I split the query into a list of words, then I build a tsearch2 query out
 of those words using the '|' alternative operator and quote the result.  
 When programming a site for a geek audience the alternative approach can be to let 
 the user to build the query using the tsearch2 syntax.
 
-  sub search_for_query {
-      my ( $self, $rs, $params ) = @_;
-      my $value = $params->{query};
-          my @query_cols = $self->query_cols; 
-          my $dbh = $self->result_source->schema->storage->dbh;
-          my @words =  split /\s+/, $value;
-          my $q = $dbh->quote( join '|',  @words );
-          return $rs->search( {
-                  '-nest' => [
-                  $query_cols[0] => \"@@ to_tsquery( $q )",
-                  $query_cols[1] => \"@@ to_tsquery( $q )",
-                  ]
-              }
-          );
-  }
-  
-  sub query_cols {
-      return qw/ name_vec synopsis_vec /;
-  }
+    sub search_for_query {
+        my ( $self, $rs, $params ) = @_;
+        my $value = $params->{query};
+            my @query_cols = $self->query_cols; 
+            my $dbh = $self->result_source->schema->storage->dbh;
+            my @words =  split /\s+/, $value;
+            my $q = $dbh->quote( join '|',  @words );
+            return $rs->search( {
+                    '-nest' => [
+                    $query_cols[0] => \"@@ to_tsquery( $q )",
+                    $query_cols[1] => \"@@ to_tsquery( $q )",
+                    ]
+                }
+            );
+    }
+    
+    sub query_cols {
+        return qw/ name_vec synopsis_vec /;
+    }
 
 We override the query_cols method in some subclasses so that we can search
 by different columns.
@@ -209,7 +213,7 @@
 =head3 Search by Proximity
 
 For searching by proximity I use the PostgreSQL geometric functions 
-(http://www.postgresql.org/docs/8.2/interactive/functions-geometry.html).
+L<http://www.postgresql.org/docs/8.2/interactive/functions-geometry.html>.
 There are  
 problems with it - the distance operator assumes planar coordinates, 
 while for the interesting thing is to search geographic data with the standard
@@ -226,17 +230,17 @@
 
 Here is the function we use to filter the results by proximity to a place:
 
-sub search_for_distance {
-    my ( $self, $rs, $params ) = @_;
-    my $lat_long = $params->{lat_long};
-    my $distance = $params->{distance} / 50;  
-    # around London the actual proportions are around 43 for latitude 
-    # and 69 for longitude 
-    return $rs->search( 
-        { "(lat_long <-> '$lat_long'::POINT) < " => \$distance },
-        { join => 'location' }
-    );
-}
+    sub search_for_distance {
+        my ( $self, $rs, $params ) = @_;
+        my $lat_long = $params->{lat_long};
+        my $distance = $params->{distance} / 50;  
+        # around London the actual proportions are around 43 for latitude 
+        # and 69 for longitude 
+        return $rs->search( 
+            { "(lat_long <-> '$lat_long'::POINT) < " => \$distance },
+            { join => 'location' }
+        );
+    }
 
 This function assumes there are two parameters on the $params hash: distance
 and lat_long (lattitude/logintude coordinates).  The location data in our
@@ -244,19 +248,19 @@
 
 We also use another search extension:
 
-sub search_for_lat_long {
-    my ( $self, $rs, $params ) = @_;
-    my $lat_long = $params->{lat_long};
-    $rs = $rs->search( undef,        
-        { 
-            join => 'location',
-            '+select' => [ \"(lat_long <-> '$lat_long'::POINT) AS distance" ],
-            '+as' => 'distance',
-            order_by => 'distance ASC',
-        }
-    );
-    return $rs;
-}
+    sub search_for_lat_long {
+        my ( $self, $rs, $params ) = @_;
+        my $lat_long = $params->{lat_long};
+        $rs = $rs->search( undef,        
+            { 
+                join => 'location',
+                '+select' => [ \"(lat_long <-> '$lat_long'::POINT) AS distance" ],
+                '+as' => 'distance',
+                order_by => 'distance ASC',
+            }
+        );
+        return $rs;
+    }
 
 This function sorts the results by proximity to the point determined by the
 lat_long coordinates.  This way the user does not need to specify the
@@ -268,7 +272,7 @@
 The '<<' (letf to), '>>' (right to) and '<<|', '|>>' for up and down 
 comparison operators can use indices.  So one can use them 
 to build a query based on
-L<<a href="http://en.wikipedia.org/wiki/Taxicab_geometry">Manhattan distance</a>>
+L<http://en.wikipedia.org/wiki/Taxicab_geometry>
 instead of the normal geometry.
 
 =head2 The To Do
@@ -291,8 +295,7 @@
 
 L<http://perlalchemy.blogspot.com/>
 
-The code in this article is copyrighted by Ymogen (http://ymogen.com) and is licenced 
-under the same conditions as Perl itself.
+The code in this article is licenced under the same conditions as Perl itself.
 
 =cut
 




More information about the Catalyst-commits mailing list