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]