# split the query string in 3 parts : X AND Y means : $left="X", $operand="AND" and $right="Y"
# then, call again NZanalyse with $left and $right
# (recursive until we find a leaf (=> something without and/or/not)
- $string =~ /(.*)( and | or | not | AND | OR | NOT )(.*)/;
- my $left = $1;
+ #process parenthesis before.
+ if ($string =~ /^\s*\((.*)\)(( and | or | not | AND | OR | NOT )(.*))?/){
+ my $left = $1;
+ warn "left :".$left;
+ my $right = $4;
+ my $operator = lc($3); # FIXME: and/or/not are operators, not operands
+ my $leftresult = NZanalyse($left,$server);
+ if ($operator) {
+ my $rightresult = NZanalyse($right,$server);
+ # OK, we have the results for right and left part of the query
+ # depending of operand, intersect, union or exclude both lists
+ # to get a result list
+ if ($operator eq ' and ') {
+ my @leftresult = split /;/, $leftresult;
+# my @rightresult = split /;/,$leftresult;
+ my $finalresult;
+ # parse the left results, and if the biblionumber exist in the right result, save it in finalresult
+ # the result is stored twice, to have the same weight for AND than OR.
+ # example : TWO : 61,61,64,121 (two is twice in the biblio #61) / TOWER : 61,64,130
+ # result : 61,61,61,61,64,64 for two AND tower : 61 has more weight than 64
+ foreach (@leftresult) {
+ if ($rightresult =~ "$_;") {
+ $finalresult .= "$_;$_;";
+ }
+ }
+ return $finalresult;
+ } elsif ($operator eq ' or ') {
+ # just merge the 2 strings
+ return $leftresult.$rightresult;
+ } elsif ($operator eq ' not ') {
+ my @leftresult = split /;/, $leftresult;
+# my @rightresult = split /;/,$leftresult;
+ my $finalresult;
+ foreach (@leftresult) {
+ unless ($rightresult =~ "$_;") {
+ $finalresult .= "$_;";
+ }
+ }
+ return $finalresult;
+ } else {
+ # this error is impossible, because of the regexp that isolate the operand, but just in case...
+ return $leftresult;
+ exit;
+ }
+ }
+ }
+ warn "string :".$string;
+ $string =~ /(.*?)( and | or | not | AND | OR | NOT )(.*)/;
+ my $left = $1;
my $right = $3;
my $operand = lc($2); # FIXME: and/or/not are operators, not operands
# it's not a leaf, we have a and/or/not
} else {
$string =~ s/__X__/"$commacontent"/ if $commacontent;
$string =~ s/-|\.|\?|,|;|!|'|\(|\)|\[|\]|{|}|"|&|\+|\*|\// /g;
- warn "leaf : $string\n" if $DEBUG;
+ warn "leaf : $string\n" if $DEBUG;
# parse the string in in operator/operand/value again
$string =~ /(.*)(>=|<=)(.*)/;
my $left = $1;
my $sth = $dbh->prepare("SELECT biblionumbers,value FROM nozebra WHERE server=? AND indexname=? AND value $operator ?");
warn "$left / $operator / $right\n";
# split each word, query the DB and build the biblionumbers result
+ #sanitizing leftpart
+ $left=~s/^\s+|\s+$//;
+ my ($biblionumbers,$value);
foreach (split / /,$right) {
- my ($biblionumbers,$value);
next unless $_;
warn "EXECUTE : $server, $left, $_";
$sth->execute($server, $left, $_) or warn "execute failed: $!";
# if we are dealing with a numeric value, use only numeric results (in case of >=, <=, > or <)
# otherwise, fill the result
$biblionumbers .= $line unless ($right =~ /\d/ && $value =~ /\D/);
- warn "result : $value ". ($right =~ /\d/) . "==".(!$value =~ /\d/) ;#= $line";
+# warn "result : $value ". ($right =~ /\d/) . "==".(!$value =~ /\d/) ;#= $line";
}
# do a AND with existing list if there is one, otherwise, use the biblionumbers list as 1st result list
if ($results) {
}
}
}
- warn "return : $results for LEAF : $string" if $DEBUG;
+# warn "return : $results for LEAF : $string" if $DEBUG;
return $results;
}
}