From bd73ffccae78e2d981620875fc5541e8301239d1 Mon Sep 17 00:00:00 2001 From: erickson Date: Mon, 11 Apr 2005 18:08:37 +0000 Subject: [PATCH] added much, moving fast ;) added orgtree caching added mr searching to biblio git-svn-id: svn://svn.open-ils.org/ILS/trunk@472 dcc99617-32d9-48b4-a31d-7c20da2025e4 --- .../perlmods/OpenILS/Application/AppUtils.pm | 54 +++- .../src/perlmods/OpenILS/Application/Cat.pm | 2 + .../perlmods/OpenILS/Application/Search.pm | 6 +- .../OpenILS/Application/Search/Biblio.pm | 298 +++++++++++++++++- 4 files changed, 337 insertions(+), 23 deletions(-) diff --git a/Open-ILS/src/perlmods/OpenILS/Application/AppUtils.pm b/Open-ILS/src/perlmods/OpenILS/Application/AppUtils.pm index ba4d034c75..91ba42d8b0 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/AppUtils.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/AppUtils.pm @@ -1,8 +1,11 @@ package OpenILS::Application::AppUtils; use strict; use warnings; use base qw/OpenSRF::Application/; +use OpenSRF::Utils::Cache; +my $cache_client = OpenSRF::Utils::Cache->new( "global", 0 ); + # --------------------------------------------------------------------------- # Pile of utilty methods used accross applications. # --------------------------------------------------------------------------- @@ -104,23 +107,33 @@ sub simple_scalar_request { my $session = OpenSRF::AppSession->create( $service ); my $request = $session->request( $method, @params ); - my $response = $request->recv(); + my $response = $request->recv(30); + + $request->wait_complete; + + if(!$request->complete) { + throw $response ("Call to $service for method $method with params @params" . + "\n did not complete successfully"); + } if(!$response) { - throw OpenSRF::EX::ERROR - ("No response from $service for method $method with params @params" ); + warn "No response from $service for method $method with params @params"; } - if($response->isa("Error")) { + if($response and $response->isa("Error")) { throw $response ("Call to $service for method $method with params @params" . "\n failed with exception: " . $response->stringify ); } - my $value = $response->content; $request->finish(); + $session->finish(); $session->disconnect(); - $session->kill_me(); + + my $value; + + if($response) { $value = $response->content; } + else { $value = undef; } return $value; } @@ -129,26 +142,38 @@ sub simple_scalar_request { -my $orglist = undef; -my $org_typelist = undef; -my $org_typelist_hash = {}; +my $tree = undef; +my $orglist = undef; +my $org_typelist = undef; +my $org_typelist_hash = {}; sub get_org_tree { my $self = shift; + if($tree) { return $tree; } + + # see if it's in the cache + $tree = $cache_client->get_cache('orgtree'); + if($tree) { return $tree; } if(!$orglist) { + warn "Retrieving Org Tree\n"; $orglist = $self->simple_scalar_request( - "open-ils.storage", "open-ils.storage.direct.actor.org_unit.retrieve.all" ); + "open-ils.storage", + "open-ils.storage.direct.actor.org_unit.retrieve.all" ); } if( ! $org_typelist ) { + warn "Retrieving org types\n"; $org_typelist = $self->simple_scalar_request( - "open-ils.storage", "open-ils.storage.direct.actor.org_unit_type.retrieve.all" ); + "open-ils.storage", + "open-ils.storage.direct.actor.org_unit_type.retrieve.all" ); $self->build_org_type( $org_typelist ); } - return $self->build_org_tree($orglist, $org_typelist); + $tree = $self->build_org_tree($orglist, $org_typelist); + $cache_client->put_cache($tree); + return $tree; } @@ -175,12 +200,15 @@ sub build_org_tree { $a->name cmp $b->name } @$orglist; for my $org (@list) { - next unless ($org and defined($org->parent_ou)); + + next unless ($org); if(!ref($org->ou_type())) { $org->ou_type( $org_typelist_hash->{$org->ou_type()}); } + next unless (defined($org->parent_ou)); + my ($parent) = grep { $_->id == $org->parent_ou } @list; next unless $parent; $parent->children([]) unless defined($parent->children); diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Cat.pm b/Open-ILS/src/perlmods/OpenILS/Application/Cat.pm index f387f8df63..9eb9de2725 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Cat.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Cat.pm @@ -66,6 +66,8 @@ sub biblio_record_tree_retrieve { $tree->owner_doc( $marcxml->id() ); warn "returning tree\n"; + #use Data::Dumper; + #warn Dumper $tree; return $tree; } diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Search.pm b/Open-ILS/src/perlmods/OpenILS/Application/Search.pm index 35823760f4..aecfb07fb9 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Search.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Search.pm @@ -85,7 +85,11 @@ sub get_org_tree { return $home_ou; } - return OpenILS::Application::AppUtils->get_org_tree(); + warn "Getting ORG Tree\n"; + my $org_tree = OpenILS::Application::AppUtils->get_org_tree(); + warn "Returning Org Tree\n"; + + return $org_tree; } diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Search/Biblio.pm b/Open-ILS/src/perlmods/OpenILS/Application/Search/Biblio.pm index a1da07c8bd..bb0059ad11 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Search/Biblio.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Search/Biblio.pm @@ -225,17 +225,21 @@ my $cat_search_hash = { { tag => "035", subfield => "_" }, ], + isbn => [ + { tag => "020", subfield => "a" }, + ], + }; __PACKAGE__->register_method( - method => "cat_biblio_search_tcn", - api_name => "open-ils.search.cat.biblio.tcn", + method => "biblio_search_tcn", + api_name => "open-ils.search.biblio.tcn", argc => 3, - note => "Searches biblio information by search class", + note => "Retrieve a record by TCN", ); -sub cat_biblio_search_tcn { +sub biblio_search_tcn { my( $self, $client, $tcn ) = @_; @@ -264,17 +268,74 @@ sub cat_biblio_search_tcn { warn "received ID's for tcn search @ids\n"; + my $size = @ids; + return { count => $size, ids => \@ids }; + +} + - my $record_list = _records_to_mods( @ids ); +# -------------------------------------------------------------------------------- +# ISBN - for my $rec (@$record_list) { - $client->respond($rec); +__PACKAGE__->register_method( + method => "biblio_search_isbn", + api_name => "open-ils.search.biblio.isbn", +); + +sub biblio_search_isbn { + my( $self, $client, $isbn ) = @_; + throw OpenSRF::EX::InvalidArg + + ("biblio_search_isbn needs an ISBN to search") + unless defined $isbn; + + warn "biblio search for ISBN $isbn\n"; + my $method = $self->method_lookup("open-ils.search.biblio.marc"); + my ($records) = $method->run( $cat_search_hash->{isbn}, $isbn ); + my @ids; + for my $i (@$records) { + if( ref($i) and defined($i->[0])) { + push @ids, $i->[0]; + } } - return undef; + my $size = @ids; + return { count => $size, ids => \@ids }; +} +# XXX make me work +__PACKAGE__->register_method( + method => "biblio_search_barcode", + api_name => "open-ils.search.biblio.barcode", +); + +sub biblio_search_barcode { + my( $self, $client, $barcode ) = @_; + throw OpenSRF::EX::InvalidArg + + ("biblio_search_barcode needs an ISBN to search") + unless defined $barcode; + + warn "biblio search for ISBN $barcode\n"; + my $records = OpenILS::Application::AppUtils->simple_scalar_request( + "open-ils.storage", "open-ils.storage.direct.asset.copy.search.barcode", + $barcode ); + + my @ids; + for my $i (@$records) { + if( ref($i) and defined($i->[0])) { + push @ids, $i->[0]; + } + } + + my $size = @ids; + return { count => $size, ids => \@ids }; } + + +# -------------------------------------------------------------------------------- + __PACKAGE__->register_method( method => "cat_biblio_search_class", api_name => "open-ils.search.cat.biblio.class", @@ -398,7 +459,12 @@ sub cat_biblio_search_class_id { my @cache_ids; - for my $i (@$records) { push @cache_ids, $i->[0]; } + for my $i (@$records) { + if(defined($i->[0])) { + push @cache_ids, $i->[0]; + } + } + my @ids = @cache_ids[ $offset..($offset+$limit) ]; my $size = @$records; @@ -411,5 +477,219 @@ sub cat_biblio_search_class_id { } +__PACKAGE__->register_method( + method => "biblio_search_class", + api_name => "open-ils.search.biblio.class", + argc => 3, + note => "Searches biblio information by search class and returns the IDs", +); + +sub biblio_search_class { + + my( $self, $client, $class, $string, $org_id, $org_type, $limit, $offset ) = @_; + + $offset ||= 0; + $limit = 100 unless defined($limit and $limit > 0 ); + $org_id = "1" unless defined($org_id); # xxx + $org_type = 0 unless defined($org_type); + + + warn "Searching biblio.class.id string: $string offset: $offset limit: $limit\n"; + + $string = OpenILS::Application::Search->filter_search($string); + if(!$string) { return undef; } + + if( !defined($org_id) or !$class or !$string ) { + warn "not enbough args to metarecord searcn\n"; + throw OpenSRF::EX::InvalidArg + ("Not enough args to open-ils.search.cat.biblio.class") + } + + $class =~ s/\s+//g; + + if( ($class ne "title") and ($class ne "author") and + ($class ne "subject") and ($class ne "keyword") ) { + warn "Invalid search class: $class\n"; + throw OpenSRF::EX::InvalidArg ("Not a valid search class: $class") + } + + # grab the mr id's from storage + + my $method = "open-ils.storage.metabib.$class.search_fts.metarecord_count"; + warn "Performing count method $method\n"; + my $session = OpenSRF::AppSession->create('open-ils.storage'); + my $request = $session->request( $method, $string, $org_id, $org_type ); + my $response = $request->recv(); + + if(UNIVERSAL::isa($response, "OpenSRF::EX")) { + throw $response ($response->stringify); + } + + my $count = $response->content; + warn "Received count $count\n"; + + # XXX check count size and respond accordingly + + $request->finish(); + warn "performing mr search\n"; + $request = $session->request( + "open-ils.storage.metabib.$class.search_fts.metarecord", + $string, $org_id, $org_type, $limit ); + + warn "a\n"; + $response = $request->recv(); + + if(UNIVERSAL::isa($response, "OpenSRF::EX")) { + warn "Recieved Exception from storage: " . $response->stringify . "\n"; + $response->{'msg'} = $response->stringify(); + throw $response ($response->stringify); + } + + warn "b\n"; + + my $records = $response->content; + + my @all_ids; + + for my $i (@$records) { + if(defined($i->[0])) { + push @all_ids, $i->[0]; + } + } + + my @ids = @all_ids[ $offset..($offset+$limit) ]; + @ids = grep { defined($_) } @ids; + #my $size = @$records; + + $request->finish(); + $session->finish(); + $session->disconnect(); + + warn "Returning biblio.class $string\n"; + return { count =>$count, ids => \@ids }; + +} + + + + +__PACKAGE__->register_method( + method => "biblio_mrid_to_modsbatch", + api_name => "open-ils.search.biblio.metarecord.mods_slim.retrieve", +); + +sub biblio_mrid_to_modsbatch { + my( $self, $client, $mrid ) = @_; + + throw OpenSRF::EX::InvalidArg + ("search.biblio.metarecord_to_mods requires mr id") + unless defined( $mrid ); + + warn "Creating mods batch for metarecord $mrid\n"; + my $id_hash = biblio_mrid_to_record_ids( undef, undef, $mrid ); + my @ids = @{$id_hash->{ids}}; + + if(@ids < 1) { return undef; } + + # grab the master record... + + my $master_id = OpenILS::Application::AppUtils->simple_scalar_request( "open-ils.storage", + "open-ils.storage.direct.metabib.metarecord.search.master_record", $mrid ); + + $master_id = $master_id->[0]; # there should only be one + + use Data::Dumper; + warn "Master Record: " . Dumper($master_id); + + if (!ref($master_id) or !defined($master_id->id())) { + warn "No Master Record Found, using first found id\n"; + $master_id = shift @ids; + } else { + $master_id = $master_id->id(); + } + + warn "Master ID is $master_id\n"; + + # grab the master record to start the mods batch + + my $record = OpenILS::Application::AppUtils->simple_scalar_request( "open-ils.storage", + "open-ils.storage.direct.biblio.record_marc.retrieve", $master_id ); + + if(!$record) { + throw OpenSRF::EX::ERROR + ("No record returned with id $master_id"); + } + + my $u = OpenILS::Utils::ModsParser->new(); + $u->start_mods_batch( $record->marc ); + my $main_doc_id = $record->id(); + + @ids = grep { $_ ne $master_id } @ids; + + warn "NON-Master IDs are @ids\n"; + + # now we have to collect all of the marc objects and push them into a mods batch + my $session = OpenSRF::AppSession->create("open-ils.storage"); + my $request = $session->request( + "open-ils.storage.direct.biblio.record_marc.batch.retrieve", @ids ); + + while( my $response = $request->recv() ) { + + next unless $response; + if(UNIVERSAL::isa( $response,"OpenSRF::EX")) { + throw $response ($response->stringify); + } + + my $content = $response->content; + + if( $content ) { + $u->push_mods_batch( $content->marc ); + } + } + + my $mods = $u->finish_mods_batch(); + $mods->{doc_id} = $main_doc_id; + + $request->finish(); + $session->finish(); + $session->disconnect(); + + return $mods; + +} + + + +# converts a mr id into a list of record ids + +__PACKAGE__->register_method( + method => "biblio_mrid_to_record_ids", + api_name => "open-ils.search.biblio.metarecord_to_records", +); + +sub biblio_mrid_to_record_ids { + my( $self, $client, $mrid ) = @_; + + throw OpenSRF::EX::InvalidArg + ("search.biblio.metarecord_to_record_ids requires mr id") + unless defined( $mrid ); + + warn "Searching for record for MR $mrid\n"; + + my $mrmaps = OpenILS::Application::AppUtils->simple_scalar_request( "open-ils.storage", + "open-ils.storage.direct.metabib.metarecord_source_map.search.metarecord", $mrid ); + + my @ids; + for my $map (@$mrmaps) { push @ids, $map->source(); } + + warn "Recovered id's [@ids] for mr $mrid\n"; + + my $size = @ids; + + return { count => $size, ids => \@ids }; + +} + + 1; -- 2.43.2