1 { # Every driver needs to provide a 'compile()' method to OpenILS::Application::Storage::FTS.
2 # If that driver wants to support FTI, that is...
3 #-------------------------------------------------------------------------------
4 package OpenILS::Application::Storage::FTS;
5 use OpenSRF::Utils::Logger qw/:level/;
6 use Unicode::Normalize;
7 my $log = 'OpenSRF::Utils::Logger';
12 my $term = NFD(shift());
14 $log->debug("Raw term: $term",DEBUG);
15 $log->debug("Search class: $class",DEBUG);
20 $self = ref($self) || $self;
21 $self = bless {} => $self;
22 $self->{class} = $class;
24 $term =~ s/(\pM+)//gos;
25 $term =~ s/(\b\.\b)//gos;
27 # hack to normalize ratio-like strings
28 while ($term =~ /\b\d{1}:[, ]?\d+(?:[ ,]\d+[^:])+/o) {
29 $term = $` . join ('', split(/[, ]/, $&)) . $';
32 $self->decompose($term);
35 $newterm = join('&', $self->words) if ($self->words);
38 $newterm = '('.$newterm.')&' if ($newterm);
39 $newterm .= '!('. join('|', $self->nots) . ')';
42 $log->debug("Compiled term is [$newterm]", DEBUG);
43 $newterm = OpenILS::Application::Storage::Driver::Pg->quote($newterm);
44 $log->debug("Quoted term is [$newterm]", DEBUG);
46 $self->{fts_query} = ["to_tsquery('$$self{class}',$newterm)"];
47 $self->{fts_query_nots} = [];
48 $self->{fts_op} = '@@';
49 $self->{text_col} = shift;
50 $self->{fts_col} = shift;
55 sub sql_where_clause {
57 my $column = $self->fts_col;
61 for my $fts ( $self->fts_query ) {
62 push @output, join(' ', $self->fts_col, $self->{fts_op}, $fts);
63 push @ranks, "rank($column, $fts)";
65 $self->{fts_rank} = \@ranks;
67 my $phrase_match = $self->sql_exact_phrase_match();
68 return join(' AND ', @output) . $phrase_match;
71 sub sql_exact_phrase_match {
73 my $column = $self->text_col;
75 for my $phrase ( $self->phrases ) {
76 $phrase =~ s/\*/\\*/go;
77 $phrase =~ s/\./\\./go;
78 $phrase =~ s/'/\\'/go;
79 $phrase =~ s/\s+/\\s+/go;
80 $log->debug("Adding phrase [$phrase] to the match list", DEBUG);
81 $output .= " AND $column ~* \$\$(^|\\W+)$phrase(\\W+|\$)\$\$";
83 $log->debug("Phrase list is [$output]", DEBUG);