]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/perlmods/OpenILS/Application/Storage/Driver/Pg/fts.pm
stripping .s in the middle of stuff ... like "u.s.a."
[Evergreen.git] / Open-ILS / src / perlmods / OpenILS / Application / Storage / Driver / Pg / fts.pm
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';
8
9         sub compile {
10                 my $self = shift;
11                 my $term = NFD(shift());
12
13                 $log->debug("Raw term: $term",DEBUG);
14
15                 $term =~ s/\&//go;
16                 $term =~ s/\|//go;
17
18                 $self = ref($self) || $self;
19                 $self = bless {} => $self;
20
21                 $term =~ s/(\pM+)//gos;
22                 $term =~ s/(\b\.\b)//gos;
23                 $self->decompose($term);
24
25                 my $newterm = '';
26                 $newterm = join('&', $self->words) if ($self->words);
27
28                 if (@{$self->nots}) {
29                         $newterm = '('.$newterm.')&' if ($newterm);
30                         $newterm .= '!('. join('|', $self->nots) . ')';
31                 }
32
33                 $log->debug("Compiled term is [$newterm]", DEBUG);
34                 $newterm = OpenILS::Application::Storage::Driver::Pg->quote($newterm);
35                 $log->debug("Quoted term is [$newterm]", DEBUG);
36
37                 $self->{fts_query} = ["to_tsquery('default',$newterm)"];
38                 $self->{fts_query_nots} = [];
39                 $self->{fts_op} = '@@';
40                 $self->{text_col} = shift;
41                 $self->{fts_col} = shift;
42
43                 return $self;
44         }
45
46         sub sql_where_clause {
47                 my $self = shift;
48                 my $column = $self->fts_col;
49                 my @output;
50         
51                 my @ranks;
52                 for my $fts ( $self->fts_query ) {
53                         push @output, join(' ', $self->fts_col, $self->{fts_op}, $fts);
54                         push @ranks, "rank($column, $fts)";
55                 }
56                 $self->{fts_rank} = \@ranks;
57         
58                 my $phrase_match = $self->sql_exact_phrase_match();
59                 return join(' AND ', @output) . $phrase_match;
60         }
61
62         sub sql_exact_phrase_match {
63                 my $self = shift;
64                 my $column = $self->text_col;
65                 my $output = '';
66                 for my $phrase ( $self->phrases ) {
67                         $phrase =~ s/\*/\\*/go;
68                         $phrase =~ s/\./\\./go;
69                         $phrase =~ s/'/\\'/go;
70                         $phrase =~ s/\s+/\\s+/go;
71                         $log->debug("Adding phrase [$phrase] to the match list", DEBUG);
72                         $output .= " AND $column ~* \$\$(^|\\W+)$phrase(\\W+|\$)\$\$";
73                 }
74                 $log->debug("Phrase list is [$output]", DEBUG);
75                 return $output;
76         }
77
78 }
79
80 1;