Date:   Sunday February 2, 2003 @ 22:42
Author: matt

Update of /home/cvs/AxKit-XSP-Wiki/lib/AxKit/XSP
In directory ted.sergeant.org:/tmp/cvs-serv31250/lib/AxKit/XSP

Modified Files:
        Wiki.pm 
Log Message:
Search code
Log:
Submitted by:   
Reviewed by:    
PR:


Index: Wiki.pm
===================================================================
RCS file: /home/cvs/AxKit-XSP-Wiki/lib/AxKit/XSP/Wiki.pm,v
retrieving revision 1.13
retrieving revision 1.14
diff -b -u -r1.13 -r1.14
--- Wiki.pm     2003/02/02 22:22:09     1.13
+++ Wiki.pm     2003/02/02 22:42:34     1.14
@@ -213,6 +213,123 @@
 sub search {
     my ($dbpath, $dbname, $query) = @_;
     my $db = _mkdb($dbpath, $dbname);
+    my %search = parse_search($query);
+    my $results = search_message_index( db => $db,
+                                        required => $search{required},
+                                        normal => $search{normal},
+                                        phrase => $search{phrase},
+                                      );
+    my $output = '<search-results>';
+    while (my $row = $results->fetch) {
+        $output .= "<result><page>" . xml_escape($row->[0]) . "</page>";
+        $output .= "<rank>" . xml_escape($row->[1]) . "</rank></result>";
+    }
+    $output .= "</search-results>";
+    return $output;
+}
+
+sub search_message_index {
+    my %p = @_;
+    
+    my $db = $p{db};
+    
+    my $sql = "
+SELECT Page.name, SUM(ContentIndex.value) AS value
+FROM ContentIndex, Page
+WHERE Page.id = ContentIndex.page_id";
+    
+    my @fromlist;
+    
+    my $clause = '';
+
+    my $word_from_id = 1;
+
+    if ( $p{required} ) {
+        foreach my $word ( @{ $p{required} } ) {
+            push @fromlist, "Word AS word$word_from_id";
+            $clause .= "AND ContentIndex.word_id = word$word_from_id\.id\n";
+            $clause .= "AND word$word_from_id\.word = " . $db->quote($word) . "\n";
+            $word_from_id++;
+        }
+    }
+    
+    if ($p{normal}) {
+        foreach my $word ( @{ $p{required} } ) {
+            push @fromlist, "Word AS word$word_from_id";
+            $clause .= "AND ContentIndex.word_id LEFT OUTER JOIN 
+word$word_from_id\.id\n";
+            $clause .= "AND word$word_from_id\.word = " . $db->quote($word) . "\n";
+            $word_from_id++;
+        }
+    }
+    
+    if ($p{phrase}) {
+        # Can this work with Postgres?  I don't think so.
+        foreach my $phrase ( @{ $p{phrase} } ) {
+            $clause .= "AND Page.content LIKE " . $db->quote("\%" . $phrase . "\%");
+            $clause .= "\n";
+        }
+    }
+    
+    if (@fromlist) {
+        $sql .= ", " . join(', ', @fromlist);
+    }
+    
+    $sql .= "
+$clause
+GROUP BY ContentIndex.page_id";
+    
+    warn("About to execute:\n$sql\n");
+    
+    my $sth = $db->prepare($sql);
+    $sth->execute();
+    return $sth;
+}
+
+
+
+sub parse_search {
+    my $query = shift;
+    my %search;
+    while (defined $query && $query =~ /\G(\S*)(\s*)/gc) {
+        my $term = $1;
+        my $space = $2;
+        next unless length($term);
+
+        if ($term =~ s/^\+//) {
+            $search{required}{$term}++;
+            warn "Search required: $term\n";
+        }
+        elsif ($term =~ /^(["'])/) {
+            my $quote = $1;
+            $term =~ s/^$quote//;
+            $term .= $space;
+
+            if ($query =~ /\G(.*?)\.?$quote\s*/gc) {
+                $term .= $1;
+                $search{phrase}{$term}++;
+                warn "Search phrase: $term\n";
+            }
+        }
+        else {
+            $search{normal}{$term}++;
+            warn "Search optional: $term\n";
+        }
+    }
+
+    # turn into arrayrefs
+    foreach ( qw( normal required phrase ) )
+    {
+       if ( $search{$_} )
+       {
+           $search{$_} = [ keys %{ $search{$_} } ]
+       }
+       else
+       {
+           $search{$_} = [];
+       }
+    }
+
+    return %search;
 }
 
 sub save_page {

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to