[open-ils-commits] r15942 - in trunk/Open-ILS/src/perlmods/OpenILS/Application/Storage: . Driver/Pg Publisher (miker)
svn at svn.open-ils.org
svn at svn.open-ils.org
Tue Mar 23 15:55:15 EDT 2010
Author: miker
Date: 2010-03-23 15:55:10 -0400 (Tue, 23 Mar 2010)
New Revision: 15942
Modified:
trunk/Open-ILS/src/perlmods/OpenILS/Application/Storage/Driver/Pg/QueryParser.pm
trunk/Open-ILS/src/perlmods/OpenILS/Application/Storage/Publisher/metabib.pm
trunk/Open-ILS/src/perlmods/OpenILS/Application/Storage/QueryParser.pm
Log:
switching to the query parser ... truncation support!
Modified: trunk/Open-ILS/src/perlmods/OpenILS/Application/Storage/Driver/Pg/QueryParser.pm
===================================================================
--- trunk/Open-ILS/src/perlmods/OpenILS/Application/Storage/Driver/Pg/QueryParser.pm 2010-03-23 17:49:13 UTC (rev 15941)
+++ trunk/Open-ILS/src/perlmods/OpenILS/Application/Storage/Driver/Pg/QueryParser.pm 2010-03-23 19:55:10 UTC (rev 15942)
@@ -129,7 +129,7 @@
my $cmf_list = shift;
for my $cmf (@$cmf_list) {
- $self->add_field_id_map( $cmf->field_class, $cmf->field, $cmf->id, $cmf->weight );
+ __PACKAGE__->add_field_id_map( $cmf->field_class, $cmf->name, $cmf->id, $cmf->weight );
}
return $self->field_id_map;
@@ -141,7 +141,7 @@
for my $sra (@$sra_list) {
my $c = $self->field_class_by_id( $sra->field );
- $self->add_relevance_bump( $c->{classname}, $c->{field}, $sra->bump_type, $sra->multiplier );
+ __PACKAGE__->add_relevance_bump( $c->{classname}, $c->{field}, $sra->bump_type, $sra->multiplier );
}
return $self->relevance_bumps;
@@ -153,7 +153,7 @@
for my $cmfinm ( @$tree ) {
my $field_info = $self->field_class_by_id( $cmfinm->field );
- $self->add_query_normalizer( $field_info->{classname}, $field_info->{field}, $cmfinm->norm->func, OpenSRF::Utils::JSON->JSON2perl($cmfinm->params) );
+ __PACKAGE__->add_query_normalizer( $field_info->{classname}, $field_info->{field}, $cmfinm->norm->func, OpenSRF::Utils::JSON->JSON2perl($cmfinm->params) );
}
}
@@ -254,7 +254,7 @@
__PACKAGE__->add_search_filter( 'item_type' );
__PACKAGE__->add_search_filter( 'item_form' );
__PACKAGE__->add_search_filter( 'lit_form' );
-__PACKAGE__->add_search_filter( 'location' );
+__PACKAGE__->add_search_filter( 'locations' );
__PACKAGE__->add_search_filter( 'site' );
__PACKAGE__->add_search_filter( 'lasso' );
__PACKAGE__->add_search_filter( 'my_lasso' );
Modified: trunk/Open-ILS/src/perlmods/OpenILS/Application/Storage/Publisher/metabib.pm
===================================================================
--- trunk/Open-ILS/src/perlmods/OpenILS/Application/Storage/Publisher/metabib.pm 2010-03-23 17:49:13 UTC (rev 15941)
+++ trunk/Open-ILS/src/perlmods/OpenILS/Application/Storage/Publisher/metabib.pm 2010-03-23 19:55:10 UTC (rev 15942)
@@ -2598,28 +2598,28 @@
__PACKAGE__->register_method(
api_name => "open-ils.storage.biblio.multiclass.staged.search_fts",
method => 'staged_fts',
- api_level => 1,
+ api_level => 0,
stream => 1,
cachable => 1,
);
__PACKAGE__->register_method(
api_name => "open-ils.storage.biblio.multiclass.staged.search_fts.staff",
method => 'staged_fts',
- api_level => 1,
+ api_level => 0,
stream => 1,
cachable => 1,
);
__PACKAGE__->register_method(
api_name => "open-ils.storage.metabib.multiclass.staged.search_fts",
method => 'staged_fts',
- api_level => 1,
+ api_level => 0,
stream => 1,
cachable => 1,
);
__PACKAGE__->register_method(
api_name => "open-ils.storage.metabib.multiclass.staged.search_fts.staff",
method => 'staged_fts',
- api_level => 1,
+ api_level => 0,
stream => 1,
cachable => 1,
);
@@ -2758,11 +2758,13 @@
sub query_parser_fts {
my $self = shift;
my $client = shift;
- my %args = shift;
+ my %args = @_;
# grab the query parser and initialize it
my $parser = $OpenILS::Application::Storage::QParser;
+ $parser->use;
+
if (!$parser->initialization_complete) {
my $cstore = OpenSRF::AppSession->create( 'open-ils.cstore' );
$parser->initialize(
@@ -2825,11 +2827,12 @@
# I hope we have a query!
- if (! scalar( keys %{$args{query}} )) {
- die "No search arguments were passed to ".$self->api_name;
+ if (! $args{query} ) {
+ die "No query was passed to ".$self->api_name;
}
+ my $simple_plan = $args{_simple_plan};
# remove bad chunks of the %args hash
for my $bad ( grep { /^_/ } keys(%args)) {
delete($args{$bad});
@@ -2838,12 +2841,11 @@
# parse the query and supply any query-level %arg-based defaults
# we expect, and make use of, query, superpage, superpage_size, debug and core_limit args
- my $query = $parser->new( %args );
+ my $query = $parser->new( %args )->parse;
-
# gather the site, if one is specified, defaulting to the in-query version
my $ou = $args{org_unit};
- if (my $filter = $query->parse_tree->find_filter('site')) {
+ if (my ($filter) = $query->parse_tree->find_filter('site')) {
$ou = $filter->args->[0] if (@{$filter->args});
}
$ou = actor::org_unit->search( { shortname => $ou } )->next->id if ($ou and $ou !~ /^\d+$/);
@@ -2851,7 +2853,7 @@
# gather lasso, as with $ou
my $lasso = $args{lasso};
- if (my $filter = $query->parse_tree->find_filter('lasso')) {
+ if (my ($filter) = $query->parse_tree->find_filter('lasso')) {
$lasso = $filter->args->[0] if (@{$filter->args});
}
$lasso = actor::org_lasso->search( { name => $lasso } )->next->id if ($lasso and $lasso !~ /^\d+$/);
@@ -2861,7 +2863,7 @@
# # XXX once we have org_unit containers, we can make user-defined lassos .. WHEEE
# # gather user lasso, as with $ou and lasso
# my $mylasso = $args{my_lasso};
-# if (my $filter = $query->parse_tree->find_filter('my_lasso')) {
+# if (my ($filter) = $query->parse_tree->find_filter('my_lasso')) {
# $mylasso = $filter->args->[0] if (@{$filter->args});
# }
# $mylasso = actor::org_unit->search( { name => $mylasso } )->next->id if ($mylasso and $mylasso !~ /^\d+$/);
@@ -2878,7 +2880,7 @@
# XXX when user lassos are here, check to make sure we don't have one -- it'll be passed in the depth, with an ou of 0
# gather the depth, if one is specified, defaulting to the in-query version
my $depth = $args{depth};
- if (my $filter = $query->parse_tree->find_filter('depth')) {
+ if (my ($filter) = $query->parse_tree->find_filter('depth')) {
$depth = $filter->args->[0] if (@{$filter->args});
}
$depth = actor::org_unit->search_where( [{ name => $depth },{ opac_label => $depth }], {limit => 1} )->next->id if ($depth and $depth !~ /^\d+$/);
@@ -2886,28 +2888,28 @@
# gather the limit or default to 10
my $limit = $args{limit} || 10;
- if (my $filter = $query->parse_tree->find_filter('limit')) {
+ if (my ($filter) = $query->parse_tree->find_filter('limit')) {
$limit = $filter->args->[0] if (@{$filter->args});
}
# gather the offset or default to 0
my $offset = $args{offset} || 0;
- if (my $filter = $query->parse_tree->find_filter('offset')) {
+ if (my ($filter) = $query->parse_tree->find_filter('offset')) {
$offset = $filter->args->[0] if (@{$filter->args});
}
# gather the estimation strategy or default to inclusion
my $estimation_strategy = $args{estimation_strategy} || 'inclusion';
- if (my $filter = $query->parse_tree->find_filter('estimation_strategy')) {
+ if (my ($filter) = $query->parse_tree->find_filter('estimation_strategy')) {
$estimation_strategy = $filter->args->[0] if (@{$filter->args});
}
# gather statuses, and then forget those if we have an #available modifier
my @statuses;
- if (my $filter = $query->parse_tree->find_filter('statuses')) {
+ if (my ($filter) = $query->parse_tree->find_filter('statuses')) {
@statuses = @{$filter->args} if (@{$filter->args});
}
@statuses = (0,7,12) if ($query->parse_tree->find_modifier('available'));
@@ -2915,22 +2917,22 @@
# gather locations
my @location;
- if (my $filter = $query->parse_tree->find_filter('location')) {
+ if (my ($filter) = $query->parse_tree->find_filter('locations')) {
@location = @{$filter->args} if (@{$filter->args});
}
- my $param_limit = $self->QueryParser->superpage_size || 'NULL';
+ my $param_limit = $query->superpage_size || 'NULL';
my $param_offset = 'NULL';
- my $sp = $self->QueryParser->superpage || 1;
+ my $sp = $query->superpage || 1;
if ($sp > 1) {
$param_offset = ($sp - 1) * $sp_size;
}
my $param_search_ou = $ou;
my $param_depth = $depth; $param_depth = 'NULL' unless (defined($depth) and length($depth) > 0 );
- my $param_core_query = $query->parse_tree->toSQL;
+ my $param_core_query = "\$core_query_$$\$" . $query->parse_tree->toSQL . "\$core_query_$$\$";
my $param_statuses = '$${' . join(',', map { s/\$//go; "\"$_\""} @statuses) . '}$$';
my $param_locations = '$${' . join(',', map { s/\$//go; "\"$_\""} @location) . '}$$';
my $staff = ($self->api_name =~ /staff/ or $query->parse_tree->find_modifier('staff')) ? "'t'" : "'f'";
@@ -2974,8 +2976,8 @@
delete $$summary_row{rel};
delete $$summary_row{record};
- if (defined($args{_simple_plan})) {
- $$summary_row{complex_query} = $args{_simple_plan};
+ if (defined($simple_plan)) {
+ $$summary_row{complex_query} = $simple_plan ? 0 : 1;
} else {
$$summary_row{complex_query} = $query->simple_plan ? 0 : 1;
}
@@ -2997,5 +2999,127 @@
return undef;
}
+sub query_parser_fts_wrapper {
+ my $self = shift;
+ my $client = shift;
+ my %args = @_;
+
+ # grab the query parser and initialize it
+ my $parser = $OpenILS::Application::Storage::QParser;
+ $parser->use;
+
+ if (!$parser->initialization_complete) {
+ my $cstore = OpenSRF::AppSession->create( 'open-ils.cstore' );
+ $parser->initialize(
+ config_metabib_field_index_norm_map =>
+ $cstore->request(
+ 'open-ils.cstore.direct.config.metabib_field_index_norm_map.search.atomic',
+ { id => { "!=" => undef } },
+ { flesh => 1, flesh_fields => { cmfinm => [qw/norm/] }, order_by => [{ class => "cmfinm", field => "pos" }] }
+ )->gather(1),
+ search_relevance_adjustment =>
+ $cstore->request(
+ 'open-ils.cstore.direct.search.relevance_adjustment.search.atomic',
+ { id => { "!=" => undef } }
+ )->gather(1),
+ config_metabib_field =>
+ $cstore->request(
+ 'open-ils.cstore.direct.config.metabib_field.search.atomic',
+ { id => { "!=" => undef } }
+ )->gather(1),
+ );
+
+ $cstore->disconnect;
+ die("Cannot initialize $parser!") unless ($parser->initialization_complete);
+ }
+
+ if (! scalar( keys %{$args{searches}} )) {
+ die "No search arguments were passed to ".$self->api_name;
+ }
+
+ my $base_query = '';
+ for my $sclass ( keys %{$args{searches}} ) {
+ $base_query .= " $sclass: $args{searches}{$sclass}{term}";
+ }
+
+ my $query = $base_query;
+
+
+ if (!$locale_map{COMPLETE}) {
+
+ my @locales = config::i18n_locale->search_where({ code => { '<>' => '' } });
+ for my $locale ( @locales ) {
+ $locale_map{$locale->code} = $locale->marc_code;
+ }
+ $locale_map{COMPLETE} = 1;
+
+ }
+
+
+ $query = "preferred_language($args{preferred_language}) $query" if ($args{preferred_language});
+ $query = "preferred_language_weight($args{preferred_language_weight}) $query" if ($args{preferred_language_weight});
+ $query = "estimation_strategy($args{estimation_strategy}) $query" if ($args{estimation_strategy});
+ $query = "site($args{org_unit}) $query" if ($args{org_unit});
+ $query = "limit($args{limit}) $query" if ($args{limit});
+ $query = "offset($args{offset}) $query" if ($args{offset});
+ $query = "#available $query" if ($args{available});
+ $query = "#staff $query" if ($self->api_name =~ /staff/);
+
+
+ my (@between, at statuses, at locations, at types, at forms, at lang, at aud, at lit_form, at vformats, at bib_level);
+
+ # XXX legacy format and item type support
+ if ($args{format}) {
+ my ($t, $f) = split '-', $args{format};
+ $args{item_type} = [ split '', $t ];
+ $args{item_form} = [ split '', $f ];
+ }
+
+ for my $filter ( qw/locations statuses between audience language lit_form item_form item_type bib_level vr_format/ ) {
+ if (my $s = $args{$filter}) {
+ $s = [$s] if (!ref($s));
+
+ my @filter_list = @$s;
+
+ next if ($filter eq 'between' and scalar(@filter_list) != 2);
+ next if (@filter_list == 0);
+
+ my $filter_string = join ',', @filter_list;
+ $query = "$filter($filter_string) $query";
+ }
+ }
+
+ return query_parser_fts($self, $client, query => $query, _simple_plan => $parser->new( query => $base_query )->parse->simple_plan );
+}
+__PACKAGE__->register_method(
+ api_name => "open-ils.storage.biblio.multiclass.staged.search_fts",
+ method => 'query_parser_fts_wrapper',
+ api_level => 1,
+ stream => 1,
+ cachable => 1,
+);
+__PACKAGE__->register_method(
+ api_name => "open-ils.storage.biblio.multiclass.staged.search_fts.staff",
+ method => 'query_parser_fts_wrapper',
+ api_level => 1,
+ stream => 1,
+ cachable => 1,
+);
+__PACKAGE__->register_method(
+ api_name => "open-ils.storage.metabib.multiclass.staged.search_fts",
+ method => 'query_parser_fts_wrapper',
+ api_level => 1,
+ stream => 1,
+ cachable => 1,
+);
+__PACKAGE__->register_method(
+ api_name => "open-ils.storage.metabib.multiclass.staged.search_fts.staff",
+ method => 'query_parser_fts_wrapper',
+ api_level => 1,
+ stream => 1,
+ cachable => 1,
+);
+
+
1;
Modified: trunk/Open-ILS/src/perlmods/OpenILS/Application/Storage/QueryParser.pm
===================================================================
--- trunk/Open-ILS/src/perlmods/OpenILS/Application/Storage/QueryParser.pm 2010-03-23 17:49:13 UTC (rev 15941)
+++ trunk/Open-ILS/src/perlmods/OpenILS/Application/Storage/QueryParser.pm 2010-03-23 19:55:10 UTC (rev 15942)
@@ -332,6 +332,8 @@
sub parse {
my $self = shift;
+ my $pkg = ref($self) || $self;
+ warn " ** parse package is $pkg\n" if $self->debug;
$self->parse_tree(
$self->decompose(
$self->query( shift() )
@@ -343,8 +345,10 @@
sub decompose {
my $self = shift;
- my $pkg = ref($self) || $self;;
+ my $pkg = ref($self) || $self;
+ warn " ** decompose package is $pkg\n" if $self->debug;
+
$_ = shift;
my $current_class = shift || $self->default_search_class;
@@ -354,20 +358,21 @@
my $search_class_re = '^\s*(';
my $first_class = 1;
- for my $class ( keys %{$pkg->search_field_aliases} ) {
+ my %seen_classes;
+ for my $class ( keys %{$pkg->search_fields} ) {
- for my $field ( keys %{$pkg->search_field_aliases->{$class}} ) {
+ for my $field ( @{$pkg->search_fields->{$class}} ) {
for my $alias ( @{$pkg->search_field_aliases->{$class}{$field}} ) {
$alias = qr/$alias/;
s/\b$alias[:=]/$class\|$field:/g;
}
+ }
- $search_class_re .= '|' unless ($first_class);
- $first_class = 0;
-
- $search_class_re .= $class;
- }
+ $search_class_re .= '|' unless ($first_class);
+ $first_class = 0;
+ $search_class_re .= $class . '(?:\|\w+)*';
+ $seeen_class{$class} = 1;
}
for my $class ( keys %{$pkg->search_class_aliases} ) {
@@ -381,10 +386,13 @@
$search_class_re .= '|' unless ($first_class);
$first_class = 0;
- $search_class_re .= $class . '(?:\|\w+)*';
+ $search_class_re .= $class . '(?:\|\w+)*' if (!$seeen_class{$class});
+ $seeen_class{$class} = 1;
}
$search_class_re .= '):';
+ warn " ** Search class RE: $search_class_re\n" if $self->debug;
+
my $required_re = $pkg->operator('required');
$required_re = qr/^\s*\Q$required_re\E/;
my $and_re = $pkg->operator('and');
More information about the open-ils-commits
mailing list