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