use Data::Dumper;
use Digest::MD5 qw/md5_hex/;
-#use OpenILS::Application::Storage::Driver::Pg::QueryParser;
+use OpenILS::Application::Storage::QueryParser;
my $log = 'OpenSRF::Utils::Logger';
api_level => 1,
);
-
-sub _abstract_query2str_filter {
- my $f = shift;
-
- return sprintf(
- "%s%s(%s)",
- $f->{negate} ? $qpconfig->{operators}{disallowed} : "",
- $f->{name},
- join(",", @{$f->{args}})
- );
-}
-
-sub _abstract_query2str_modifier {
- my $f = shift;
-
- return $qpconfig->{operators}{modifier} . $f;
-}
-
-# This should produce an equivalent query to the original, given an
-# abstract_query with a qp config.
-sub abstract_query2str_impl {
- my ($abstract_query, $depth, $qpconfig) = @_;
-
- my $gs = $qpconfig->{operators}{group_start};
- my $ge = $qpconfig->{operators}{group_end};
- my $and = $qpconfig->{operators}{and};
- my $or = $qpconfig->{operators}{or};
-
- my $q = "";
- $q .= $gs if $abstract_query->{type} and $abstract_query->{type} eq "query_plan" and $depth;
-
- if (exists $abstract_query->{type}) {
- if ($abstract_query->{type} eq 'query_plan') {
- $q .= join(" ", map { _abstract_query2str_filter($_) } @{$abstract_query->{filters}}) if
- exists $abstract_query->{filters};
- $q .= " ";
-
- $q .= join(" ", map { _abstract_query2str_modifier($_) } @{$abstract_query->{modifiers}}) if
- exists $abstract_query->{modifiers};
- } elsif ($abstract_query->{type} eq 'node') {
- if ($abstract_query->{alias}) {
- $q .= " " . $abstract_query->{alias};
- $q .= "|$_" foreach @{$abstract_query->{alias_fields}};
- } else {
- $q .= " " . $abstract_query->{class};
- $q .= "|$_" foreach @{$abstract_query->{fields}};
- }
- $q .= ":";
- } elsif ($abstract_query->{type} eq 'atom') {
- my $prefix = $abstract_query->{prefix} || '';
- $prefix = $qpconfig->{operators}{disallowed} if $prefix eq '!';
- $q .= $prefix .
- ($abstract_query->{content} || '') .
- ($abstract_query->{suffix} || '');
- } elsif ($abstract_query->{type} eq 'facet') {
- # facet syntax [ # ] is hardcoded I guess?
- my $prefix = $abstract_query->{negate} ? $qpconfig->{operators}{disallowed} : '';
- $q .= $prefix . $abstract_query->{name} . "[" .
- join(" # ", @{$abstract_query->{values}}) . "]";
- }
- }
-
- if (exists $abstract_query->{children}) {
- my $op = (keys(%{$abstract_query->{children}}))[0];
- $q .= join(
- " " . ($op eq '&' ? $and : $or) . " ",
- map {
- abstract_query2str_impl($_, $depth + 1, $qpconfig)
- } @{$abstract_query->{children}{$op}}
- );
- } elsif ($abstract_query->{'&'} or $abstract_query->{'|'}) {
- my $op = (keys(%{$abstract_query}))[0];
- $q .= join(
- " " . ($op eq '&' ? $and : $or) . " ",
- map {
- abstract_query2str_impl($_, $depth + 1, $qpconfig)
- } @{$abstract_query->{$op}}
- );
- }
- $q .= " ";
-
- $q .= $ge if $abstract_query->{type} and $abstract_query->{type} eq "query_plan" and $depth;
-
- return $q;
-}
-
# Takes an abstract query object and recursively turns it back into a string
# for QueryParser.
sub abstract_query2str {
my ($self, $conn, $query) = @_;
- return abstract_query2str_impl($query, 0, $query->{config});
+ return QueryParser::Canonicalize::abstract_query2str_impl($query, 0);
}
__PACKAGE__->register_method(
}
#-------------------------------
+package QueryParser::Canonicalize; # not OO
+
+sub _abstract_query2str_filter {
+ my $f = shift;
+ my $qpconfig = $parser_config{QueryParser};
+
+ return sprintf(
+ "%s%s(%s)",
+ $f->{negate} ? $qpconfig->{operators}{disallowed} : "",
+ $f->{name},
+ join(",", @{$f->{args}})
+ );
+}
+
+sub _abstract_query2str_modifier {
+ my $f = shift;
+ my $qpconfig = $parser_config{QueryParser};
+
+ return $qpconfig->{operators}{modifier} . $f;
+}
+
+# This should produce an equivalent query to the original, given an
+# abstract_query.
+sub abstract_query2str_impl {
+ my ($abstract_query, $depth) = @_;
+
+ my $qpconfig = $parser_config{QueryParser};
+
+ my $gs = $qpconfig->{operators}{group_start};
+ my $ge = $qpconfig->{operators}{group_end};
+ my $and = $qpconfig->{operators}{and};
+ my $or = $qpconfig->{operators}{or};
+
+ my $q = "";
+ $q .= $gs if $abstract_query->{type} and $abstract_query->{type} eq "query_plan" and $depth;
+
+ if (exists $abstract_query->{type}) {
+ if ($abstract_query->{type} eq 'query_plan') {
+ $q .= join(" ", map { _abstract_query2str_filter($_) } @{$abstract_query->{filters}}) if
+ exists $abstract_query->{filters};
+ $q .= " ";
+
+ $q .= join(" ", map { _abstract_query2str_modifier($_) } @{$abstract_query->{modifiers}}) if
+ exists $abstract_query->{modifiers};
+ } elsif ($abstract_query->{type} eq 'node') {
+ if ($abstract_query->{alias}) {
+ $q .= " " . $abstract_query->{alias};
+ $q .= "|$_" foreach @{$abstract_query->{alias_fields}};
+ } else {
+ $q .= " " . $abstract_query->{class};
+ $q .= "|$_" foreach @{$abstract_query->{fields}};
+ }
+ $q .= ":";
+ } elsif ($abstract_query->{type} eq 'atom') {
+ my $prefix = $abstract_query->{prefix} || '';
+ $prefix = $qpconfig->{operators}{disallowed} if $prefix eq '!';
+ $q .= $prefix .
+ ($abstract_query->{content} || '') .
+ ($abstract_query->{suffix} || '');
+ } elsif ($abstract_query->{type} eq 'facet') {
+ # facet syntax [ # ] is hardcoded I guess?
+ my $prefix = $abstract_query->{negate} ? $qpconfig->{operators}{disallowed} : '';
+ $q .= $prefix . $abstract_query->{name} . "[" .
+ join(" # ", @{$abstract_query->{values}}) . "]";
+ }
+ }
+
+ if (exists $abstract_query->{children}) {
+ my $op = (keys(%{$abstract_query->{children}}))[0];
+ $q .= join(
+ " " . ($op eq '&' ? $and : $or) . " ",
+ map {
+ abstract_query2str_impl($_, $depth + 1)
+ } @{$abstract_query->{children}{$op}}
+ );
+ } elsif ($abstract_query->{'&'} or $abstract_query->{'|'}) {
+ my $op = (keys(%{$abstract_query}))[0];
+ $q .= join(
+ " " . ($op eq '&' ? $and : $or) . " ",
+ map {
+ abstract_query2str_impl($_, $depth + 1)
+ } @{$abstract_query->{$op}}
+ );
+ }
+ $q .= " ";
+
+ $q .= $ge if $abstract_query->{type} and $abstract_query->{type} eq "query_plan" and $depth;
+
+ return $q;
+}
+
+#-------------------------------
package QueryParser::query_plan;
sub QueryParser {