From: Lebbeous Fogle-Weekley Date: Thu, 1 Mar 2012 19:27:55 +0000 (-0500) Subject: towards the right way of gettin tree of grouped holdings X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=beb0abb8613a1aa108824606bd91150c76f0e3ac;p=evergreen%2Fequinox.git towards the right way of gettin tree of grouped holdings Signed-off-by: Lebbeous Fogle-Weekley --- diff --git a/Open-ILS/examples/fm_IDL.xml b/Open-ILS/examples/fm_IDL.xml index 4071e9f61f..63b6efc9d4 100644 --- a/Open-ILS/examples/fm_IDL.xml +++ b/Open-ILS/examples/fm_IDL.xml @@ -4059,7 +4059,7 @@ SELECT usr, - + @@ -4364,6 +4364,20 @@ SELECT usr, + + + + + + + + + + + + + + diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Serial.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Serial.pm index 95536db55b..0eefc07f4e 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Serial.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Serial.pm @@ -61,8 +61,10 @@ my %MFHD_NAMES_BY_TAG = ( '853' => $MFHD_NAMES[0], my %MFHD_TAGS_BY_NAME = ( $MFHD_NAMES[0] => '853', $MFHD_NAMES[1] => '854', $MFHD_NAMES[2] => '855'); -my @MFHD_ENUM_SUBFIELDS = qw/abcdef/; # $g and $h intentionally omitted -my @MFHD_CHRON_SUBFIELDS = qw/ijklm/; +my %MFHD_SUMMARIZED_SUBFIELDS = ( + enum => [ split //, "abcdef" ], # $g and $h intentionally omitted for now + chron => [ split //, "ijklm" ] +); my $_strp_date = new DateTime::Format::Strptime(pattern => '%F'); @@ -857,19 +859,118 @@ __PACKAGE__->register_method( sub grouped_holdings_for_summary { my ( - $self, $client, - $summary_type, $summary_id, $expand_path, $limits, $offsets + $self, $client, $summary_type, $summary_id, + $expand_path, $limits, $offsets ) = @_; - # fetch summary and flesh sdist. From that, get display_grouping (chron or enum) + # Validate input or set defaults. + ($summary_type .= "") =~ s/[^\w]//g; + $summary_id = int($summary_id); + $expand_path ||= []; + $limits ||= [10]; + $offsets ||= [0]; + + foreach ($expand_path, $limits, $offsets) { + if (ref $_ ne 'ARRAY') { + return new OpenILS::Event( + "BAD_PARAMS", note => + "expand_path, limits and offsets arguments must be arrays" + ); + } + } + + if (not (scalar(@$limits) == scalar(@$expand_path) + 1) and + (scalar(@$offsets) == scalar(@$expand_path) + 1)) { + return new OpenILS::Event( + "BAD_PARAMS", note => + "limits and offsets must be one element longer than expand_path" + ); + } + + # Get the class hint for whichever type of summary we're expanding. + my $fmclass = "Fieldmapper::serial::${summary_type}_summary"; + my $summary_hint = $Fieldmapper::fieldmap->{$fmclass}{hint} or + return new OpenILS::Event("BAD_PARAMS", note => "summary_type"); - # get scap (lots of joins to get there) + my $e = new_editor; + + # First, get display grouping for requested summary (either chron or enum). + my $row = $e->json_query({ + select => {sdist => ["display_grouping"]}, + from => {$summary_hint => {sdist => {}}}, + where => {"+$summary_hint" => {id => $summary_id}} + }) or return $e->die_event; + + return new OpenILS::Event("BAD_PARAMS", note => "summary_id not found") + unless @$row; + + # And now we know which subfields we care about from + # serial.materialized_holding_code. + my @subfields = @{ + $MFHD_SUMMARIZED_SUBFIELDS{$row->[0]->{display_grouping}} + }; + + # We look for holdings grouped at the top level once no matter what, + # then we'll look deeper with additional queries for every element of + # $expand_path later. + # Below we define parts of the SELECT and JOIN clauses that we'll + # potentially reuse if $expand_path has elements. + + my $subfield = shift @subfields; +# my %holding_leaf_select = ( +# siss => [qw/id label date_published/], + + my %deep_joins = ( + ); - # get unique values from each field of received items' issuances' holding - # codes and build a tree to group them + # Now get the top level of holdings. + my $holdings = $e->json_query({ + select => { + "smhc_$subfield" => ["value"], + scap => ["pattern_code"] + }, + from => { + $summary_hint => { + sdist => { + join => { + sstr => { + join => { + sitem => { + join => { + siss => { + join => { + scap => {}, + "smhc_$subfield" => { + class => "smhc" + } + } + } + } + } + } + } + } + } + } + }, + where => { + "+$summary_hint" => {id => $summary_id}, + "+sitem" => {date_received => {"!=" => undef}}, + "+smhc_$subfield" => {subfield => $subfield} + }, + distinct => 1, # sic, this goes here in json_query + limit => int(shift(@$limits)), + offset => int(shift(@$offsets)), + order_by => [ + {class => "smhc_$subfield", field => "value", + direction => "descending"} + ] + }) or return $e->die_event; - # only go as far as expand_path dictates in grouping issuances. - # scalar(@$expand_path) + 1, up to (num_grouping_fields - 1) + # Ok, that got us the top level, with nothing expanded. Now we loop through + # the deeper levels of @$expand_path, issuing similar queries to get us + # lower groupings and even actual specific holdings. + return $holdings; } __PACKAGE__->register_method( @@ -885,9 +986,9 @@ __PACKAGE__->register_method( { name => "summary_id", type => "number" }, { name => "expand_path", type => "array" }, { name => "limits", type => "array", desc => - "This should be one element longer than expand_path" }, + "This must be exactly one element longer than expand_path" }, { name => "offsets", type => "array", desc => - "This should be one element longer than expand_path" } + "This must be exactly one element longer than expand_path" } ] } ); diff --git a/Open-ILS/src/sql/Pg/upgrade/XXXX.schema.serial-holding-groups.sql b/Open-ILS/src/sql/Pg/upgrade/XXXX.schema.serial-holding-groups.sql index b1eccd79c2..76d6ea61fc 100644 --- a/Open-ILS/src/sql/Pg/upgrade/XXXX.schema.serial-holding-groups.sql +++ b/Open-ILS/src/sql/Pg/upgrade/XXXX.schema.serial-holding-groups.sql @@ -110,6 +110,11 @@ return; $func$ LANGUAGE 'plperlu'; +CREATE INDEX assist_holdings_display + ON serial.materialized_holding_code (issuance, subfield); + +-- XXX add more indices to assist with other joins new to Serial.pm + CREATE TRIGGER materialize_holding_code AFTER INSERT OR UPDATE ON serial.issuance FOR EACH ROW EXECUTE PROCEDURE serial.materialize_holding_code() ; @@ -117,4 +122,4 @@ CREATE TRIGGER materialize_holding_code -- XXX need to materialize_holding_code() for all existing rows in serial.issuance -- at time of upgrde script execution as well. -COMMIT'; +COMMIT;