[open-ils-commits] [GIT] Evergreen ILS branch master updated. 3cd206a5e61f6665420602dd2e9da15270a5b26c
Evergreen Git
git at git.evergreen-ils.org
Wed Aug 19 12:17:46 EDT 2015
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Evergreen ILS".
The branch, master has been updated
via 3cd206a5e61f6665420602dd2e9da15270a5b26c (commit)
via 303608ce23452f1d59e924da7656e7e4c65b603c (commit)
via 97806b5b66b3b5685e9bd231a2b3c59f4b729daf (commit)
via 8df8d6be077fbaf5360c379e3ee1f0934dcc9dd0 (commit)
via f9747810978804a79786349e7f604e0f838ddefc (commit)
via b1c8c14e48abaa729ae164fd969ffe5c304a857d (commit)
via 55f4479eb3adeb2f67ab88b566d8fc7453bc3ed3 (commit)
from 9e946f5af3be4ecfe7d694a902c5a2ce8f9a4d23 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 3cd206a5e61f6665420602dd2e9da15270a5b26c
Author: Ben Shum <bshum at biblio.org>
Date: Wed Aug 19 12:17:17 2015 -0400
LP#1379815: Stamping upgrade scripts for vandelay stat cat import
Signed-off-by: Ben Shum <bshum at biblio.org>
diff --git a/Open-ILS/src/sql/Pg/002.schema.config.sql b/Open-ILS/src/sql/Pg/002.schema.config.sql
index 3b00fb8..209df2d 100644
--- a/Open-ILS/src/sql/Pg/002.schema.config.sql
+++ b/Open-ILS/src/sql/Pg/002.schema.config.sql
@@ -91,7 +91,7 @@ CREATE TRIGGER no_overlapping_deps
BEFORE INSERT OR UPDATE ON config.db_patch_dependencies
FOR EACH ROW EXECUTE PROCEDURE evergreen.array_overlap_check ('deprecates');
-INSERT INTO config.upgrade_log (version, applied_to) VALUES ('0927', :eg_version); -- dbwells/csharp/bshum
+INSERT INTO config.upgrade_log (version, applied_to) VALUES ('0929', :eg_version); -- dbwells/remington/bshum
CREATE TABLE config.bib_source (
id SERIAL PRIMARY KEY,
diff --git a/Open-ILS/src/sql/Pg/upgrade/XXXX.function.vandelay-oils_xpath_tag_to_table.sql b/Open-ILS/src/sql/Pg/upgrade/0928.function.vandelay-oils_xpath_tag_to_table.sql
similarity index 95%
rename from Open-ILS/src/sql/Pg/upgrade/XXXX.function.vandelay-oils_xpath_tag_to_table.sql
rename to Open-ILS/src/sql/Pg/upgrade/0928.function.vandelay-oils_xpath_tag_to_table.sql
index 48e44f8..9796f8d 100644
--- a/Open-ILS/src/sql/Pg/upgrade/XXXX.function.vandelay-oils_xpath_tag_to_table.sql
+++ b/Open-ILS/src/sql/Pg/upgrade/0928.function.vandelay-oils_xpath_tag_to_table.sql
@@ -1,6 +1,6 @@
BEGIN;
---SELECT evergreen.upgrade_deps_block_check('XXXX', :eg_version);
+SELECT evergreen.upgrade_deps_block_check('0928', :eg_version);
CREATE OR REPLACE FUNCTION oils_xpath_tag_to_table(marc text, tag text, xpaths text[]) RETURNS SETOF record AS $function$
diff --git a/Open-ILS/src/sql/Pg/upgrade/YYYY.schema.vandelay-stat-cat-import.sql b/Open-ILS/src/sql/Pg/upgrade/0929.schema.vandelay-stat-cat-import.sql
similarity index 99%
rename from Open-ILS/src/sql/Pg/upgrade/YYYY.schema.vandelay-stat-cat-import.sql
rename to Open-ILS/src/sql/Pg/upgrade/0929.schema.vandelay-stat-cat-import.sql
index 57b0a45..e475366 100644
--- a/Open-ILS/src/sql/Pg/upgrade/YYYY.schema.vandelay-stat-cat-import.sql
+++ b/Open-ILS/src/sql/Pg/upgrade/0929.schema.vandelay-stat-cat-import.sql
@@ -1,6 +1,6 @@
BEGIN;
---SELECT evergreen.upgrade_deps_block_check('XXXX', :eg_version);
+SELECT evergreen.upgrade_deps_block_check('0929', :eg_version);
INSERT INTO vandelay.import_error ( code, description ) VALUES (
'import.item.invalid.stat_cat_format', oils_i18n_gettext('import.item.invalid.stat_cat_format', 'Bad format for stat cat data, should be like: CAT 1|VALUE 1', 'vie', 'description') );
commit 303608ce23452f1d59e924da7656e7e4c65b603c
Author: Remington Steed <rjs7 at calvin.edu>
Date: Tue Jul 7 16:08:23 2015 -0400
LP#1379815 Better error handling
This commit adds more thorough error checking and handling for the stat
cat import feature, including adding two custom import error codes.
Signed-off-by: Remington Steed <rjs7 at calvin.edu>
Signed-off-by: Ben Shum <bshum at biblio.org>
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
index b5ae6f6..a93a51e 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
@@ -1931,16 +1931,28 @@ sub import_record_asset_list_impl {
push (@$stat_cat_entries, $stat_cat_entry) if $stat_cat_entry;
}
} else {
- $logger->warn("Bad format for stat cat data ($stat_cat_pair), should be like: CAT 1|VALUE 1");
+ $$report_args{import_error} = "import.item.invalid.stat_cat_format";
+ last;
}
if (!$stat_cat or !$stat_cat_entry) {
- $logger->warn("Invalid stat cat data ($stat_cat_pair): " . $e->die_event);
+ $$report_args{import_error} = "import.item.invalid.stat_cat_data";
+ last;
}
}
+ if ($$report_args{import_error}) {
+ $logger->error("vl: invalid stat cat data: " . $item->stat_cat_data);
+ respond_with_status($report_args);
+ next;
+ }
$copy->stat_cat_entries( $stat_cat_entries );
$copy->ischanged(1);
$evt = OpenILS::Application::Cat::AssetCommon->update_copy_stat_entries($e, $copy, 0, 1); #delete_stats=0, add_or_update_only=1
+ if($evt) {
+ $$report_args{evt} = $evt;
+ respond_with_status($report_args);
+ next;
+ }
}
# set the import data on the import item
diff --git a/Open-ILS/src/sql/Pg/950.data.seed-values.sql b/Open-ILS/src/sql/Pg/950.data.seed-values.sql
index 0ce75a4..3e30e7c 100644
--- a/Open-ILS/src/sql/Pg/950.data.seed-values.sql
+++ b/Open-ILS/src/sql/Pg/950.data.seed-values.sql
@@ -10399,6 +10399,10 @@ INSERT INTO vandelay.import_error ( code, description ) VALUES (
'import.item.invalid.circ_as_type', oils_i18n_gettext('import.item.invalid.circ_as_type', 'Invalid value for "circ_as_type"', 'vie', 'description') );
INSERT INTO vandelay.import_error ( code, description ) VALUES (
'import.record.perm_failure', oils_i18n_gettext('import.record.perm_failure', 'Perm failure creating a record', 'vie', 'description') );
+INSERT INTO vandelay.import_error ( code, description ) VALUES (
+ 'import.item.invalid.stat_cat_format', oils_i18n_gettext('import.item.invalid.stat_cat_format', 'Bad format for stat cat data, should be like: CAT 1|VALUE 1', 'vie', 'description') );
+INSERT INTO vandelay.import_error ( code, description ) VALUES (
+ 'import.item.invalid.stat_cat_data', oils_i18n_gettext('import.item.invalid.stat_cat_data', 'Invalid stat cat data', 'vie', 'description') );
-- Event def for email notice for hold cancelled due to lack of target -----
diff --git a/Open-ILS/src/sql/Pg/upgrade/YYYY.schema.vandelay-stat-cat-import.sql b/Open-ILS/src/sql/Pg/upgrade/YYYY.schema.vandelay-stat-cat-import.sql
index 0256b1b..57b0a45 100644
--- a/Open-ILS/src/sql/Pg/upgrade/YYYY.schema.vandelay-stat-cat-import.sql
+++ b/Open-ILS/src/sql/Pg/upgrade/YYYY.schema.vandelay-stat-cat-import.sql
@@ -2,6 +2,11 @@ BEGIN;
--SELECT evergreen.upgrade_deps_block_check('XXXX', :eg_version);
+INSERT INTO vandelay.import_error ( code, description ) VALUES (
+ 'import.item.invalid.stat_cat_format', oils_i18n_gettext('import.item.invalid.stat_cat_format', 'Bad format for stat cat data, should be like: CAT 1|VALUE 1', 'vie', 'description') );
+INSERT INTO vandelay.import_error ( code, description ) VALUES (
+ 'import.item.invalid.stat_cat_data', oils_i18n_gettext('import.item.invalid.stat_cat_data', 'Invalid stat cat data', 'vie', 'description') );
+
ALTER TABLE vandelay.import_item_attr_definition
ADD COLUMN stat_cat_data TEXT;
commit 97806b5b66b3b5685e9bd231a2b3c59f4b729daf
Author: Remington Steed <rjs7 at calvin.edu>
Date: Fri Feb 20 10:54:26 2015 -0500
LP#1379815 Add release notes
Signed-off-by: Remington Steed <rjs7 at calvin.edu>
Signed-off-by: Ben Shum <bshum at biblio.org>
diff --git a/docs/RELEASE_NOTES_NEXT/Cataloging/importing_stat_cats.txt b/docs/RELEASE_NOTES_NEXT/Cataloging/importing_stat_cats.txt
new file mode 100644
index 0000000..7d2e828
--- /dev/null
+++ b/docs/RELEASE_NOTES_NEXT/Cataloging/importing_stat_cats.txt
@@ -0,0 +1,19 @@
+Importing Statistical Categories
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+You can now retrieve statistical categories (stat cats) from the MARC
+record and apply them to the items in Evergreen. When importing or
+overlaying items through the Vandelay MARC batch import process, edit
+your Holdings Import Profile to tell Evergreen which subfield contains
+your stat cat data. That subfield in your MARC records should be
+formatted like the following:
+
+----
+CATEGORY 1|VALUE 1||CATEGORY 2|VALUE 2
+----
+
+Notice that the pipe character '|' is used to separate each category
+from its value, and two pipes separate each pair of category values.
+
+If you are overlaying existing copies which already have stat cats
+attached to them, the overlay process will keep those values unless the
+incoming copies contain updated values for matching categories.
commit 8df8d6be077fbaf5360c379e3ee1f0934dcc9dd0
Author: Remington Steed <rjs7 at calvin.edu>
Date: Fri Feb 20 09:57:18 2015 -0500
LP#1379815 Add pgTAP test
This commit adds a pgTAP test which ensures that imported items are
being successfully added to the 'import_item' table. The test confirms
that the correct number of items have stat cat data in the table. The
test also ensures that the new xpath function works properly, simply by
using it.
Signed-off-by: Remington Steed <rjs7 at calvin.edu>
Signed-off-by: Ben Shum <bshum at biblio.org>
diff --git a/Open-ILS/src/sql/Pg/t/regress/lp1379815_vl_import_item_stat_cats.pg b/Open-ILS/src/sql/Pg/t/regress/lp1379815_vl_import_item_stat_cats.pg
new file mode 100644
index 0000000..1756266
--- /dev/null
+++ b/Open-ILS/src/sql/Pg/t/regress/lp1379815_vl_import_item_stat_cats.pg
@@ -0,0 +1,52 @@
+BEGIN;
+
+SELECT plan(1);
+
+-------------------------
+-- Setup test environment
+-- Circ modifier
+-- Vandelay settings (queue, import_item_attr_definition)
+-- Bib record added to Vandelay queue
+-- including items with stat cat data
+-------------------------
+
+INSERT INTO config.circ_modifier (code, name, description, sip2_media_type)
+ VALUES ('TEST', 'TEST', 'TEST', 'TEST');
+
+INSERT INTO vandelay.import_item_attr_definition (
+ owner, name, tag, owning_lib, circ_lib,
+ call_number, internal_id, status, location,
+ barcode, circ_modifier, stat_cat_data)
+VALUES (
+ 1, 'TEST', '999', 'b', 'b',
+ 'j', 'e', 'z', 'c',
+ 'p', 'a', 'd');
+
+INSERT INTO vandelay.bib_queue (owner, name, item_attr_def)
+ VALUES (1, 'TEST', CURRVAL('vandelay.import_item_attr_definition_id_seq'));
+
+----------------------
+-- Add record to queue
+-- This triggers ingest_bib_items()
+-- which calls ingest_items()
+----------------------
+INSERT INTO vandelay.queued_bib_record (queue, bib_source, marc)
+ VALUES ( CURRVAL('vandelay.queue_id_seq'), 2,
+ '<record xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.loc.gov/MARC21/slim" xsi:schemaLocation="http://www.loc.gov/MARC21/slim http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd"><leader>01532nam a22003138a 4500</leader><controlfield tag="001">996</controlfield><controlfield tag="003">CONS</controlfield><controlfield tag="005">20140910210953.0</controlfield><controlfield tag="008">070119s2009 nyua j 000 1 eng </controlfield><datafield tag="010" ind1=" " ind2=" "><subfield code="a"> 2006100441</subfield></datafield><datafield tag="019" ind1=" " ind2=" "><subfield code="a">232977713</subfield></datafield><datafield tag="020" ind1=" " ind2=" "><subfield code="a">97800608089 (trade bdg.)</subfield></datafield><datafield tag="035" ind1=" " ind2=" "><subfield code="a">test</subfield></datafield><datafield tag="100" ind1="1" ind2=" "><subfield code="a">Gaiman, Neil.</subfield></datafield><datafield tag="245" ind1="1" ind2="0
"><subfield code="a">Blueberry girl 2 /</subfield><subfield code="c">written by Neil Gaiman.</subfield></datafield><datafield tag="250" ind1=" " ind2=" "><subfield code="a">1st ed.</subfield></datafield><datafield tag="260" ind1=" " ind2=" "><subfield code="a">New York :</subfield><subfield code="b">HarperCollinsPublishers,</subfield><subfield code="c">2009.</subfield></datafield><datafield tag="999" ind1="4" ind2=" "><subfield code="a">TEST</subfield><subfield code="b">BR1</subfield><subfield code="c">Stacks</subfield><subfield code="d">Item Category 1|EBOOK</subfield><subfield code="e">4674</subfield><subfield code="j">HV 1431 .S76 1990</subfield><subfield code="p">SC1001</subfield><subfield code="x">nonreference</subfield><subfield code="x">holdable</subfield><subfield code="x">circulating</subfield><subfield code="x">visible</subfield><subfield code="z">Available</subfield></datafield><datafield tag="999" ind1="4" ind2=" "><subfield code="a">TEST</subfield><subfield code
="b">BR1</subfield><subfield code="c">Stacks</subfield><subfield code="e">4675</subfield><subfield code="j">HV 1431 .S76 1990</subfield><subfield code="g">TEST</subfield><subfield code="p">SC1002</subfield><subfield code="x">nonreference</subfield><subfield code="x">holdable</subfield><subfield code="x">circulating</subfield><subfield code="x">visible</subfield><subfield code="z">Available</subfield></datafield><datafield tag="999" ind1="4" ind2=" "><subfield code="a">TEST</subfield><subfield code="b">BR1</subfield><subfield code="c">Stacks</subfield><subfield code="d">Item Category 1|EBOOK||Item Category 2|E-PROJECT MUSE</subfield><subfield code="j">HV 1431 .S76 1990</subfield><subfield code="p">SC3003</subfield><subfield code="x">nonreference</subfield><subfield code="x">holdable</subfield><subfield code="x">circulating</subfield><subfield code="x">visible</subfield><subfield code="z">Available</subfield></datafield><datafield tag="999" ind1="4" ind2=" "><subfield code="a"
>TEST</subfield><subfield code="b">BR1</subfield><subfield code="c">Stacks</subfield><subfield code="j">HV 1431 .S76 1990</subfield><subfield code="p">SC3004</subfield><subfield code="x">nonreference</subfield><subfield code="x">holdable</subfield><subfield code="x">circulating</subfield><subfield code="x">visible</subfield><subfield code="z">Available</subfield></datafield></record>'
+ );
+
+-------------------
+-- Test the results
+-------------------
+SELECT is(
+ (
+ SELECT count(*)
+ FROM vandelay.import_item
+ WHERE record = CURRVAL('vandelay.queued_record_id_seq')
+ AND stat_cat_data IS NOT NULL
+ ),
+ 2::bigint,
+ 'Stat cat data?'
+);
+
+ROLLBACK;
commit f9747810978804a79786349e7f604e0f838ddefc
Author: Remington Steed <rjs7 at calvin.edu>
Date: Mon Sep 8 16:11:37 2014 -0400
LP#1379815 Add code to assign stat cats on Vandelay imported items
This commit adds columns to the Holdings Import Profile table
(vandelay.import_item_attr_definition) and to vandelay.import_item, adds
the corresponding fields to the IDL, modifies the database functions
which import the data (ingest_bib_items() and ingest_items()) and adds
code that parses the imported stat cat data (of the form
CAT 1|VALUE 1||CAT 2|VALUE 2) and applies it to the appropriate
overlayed copy.
Signed-off-by: Remington Steed <rjs7 at calvin.edu>
Signed-off-by: Dan Wells <dbw2 at calvin.edu>
Signed-off-by: Ben Shum <bshum at biblio.org>
diff --git a/Open-ILS/examples/fm_IDL.xml b/Open-ILS/examples/fm_IDL.xml
index 9776286..4686e7f 100644
--- a/Open-ILS/examples/fm_IDL.xml
+++ b/Open-ILS/examples/fm_IDL.xml
@@ -294,6 +294,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
<field reporter:label="Private Note" name="priv_note" reporter:datatype="text"/>
<field reporter:label="OPAC Visible" name="opac_visible" reporter:datatype="bool"/>
<field reporter:label="Overlay Match ID" name="internal_id" reporter:datatype="int"/>
+ <field reporter:label="Stat Cat Data" name="stat_cat_data" reporter:datatype="text"/>
</fields>
<links>
<link field="import_error" reltype="has_a" key="code" map="" class="vie"/>
@@ -346,6 +347,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
<field reporter:label="OPAC Visible" name="opac_visible" reporter:datatype="text"/>
<field reporter:label="Copy Number" name="copy_number" reporter:datatype="text"/>
<field reporter:label="Overlay Match ID" name="internal_id" reporter:datatype="text"/>
+ <field reporter:label="Stat Cat Data" name="stat_cat_data" reporter:datatype="text"/>
</fields>
<links>
<link field="owner" reltype="has_a" key="id" map="" class="aou"/>
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
index 588642d..b5ae6f6 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
@@ -1916,6 +1916,33 @@ sub import_record_asset_list_impl {
}
}
+ if ($item->stat_cat_data) {
+ $logger->info("vl: parsing stat cat data: " . $item->stat_cat_data);
+ my @stat_cat_pairs = split('\|\|', $item->stat_cat_data);
+ my $stat_cat_entries = [];
+ # lookup stat cats
+ foreach my $stat_cat_pair (@stat_cat_pairs) {
+ my ($stat_cat, $stat_cat_entry);
+ my @pair_pieces = split('\|', $stat_cat_pair);
+ if (@pair_pieces == 2) {
+ $stat_cat = $e->search_asset_stat_cat({name=>$pair_pieces[0]})->[0];
+ if ($stat_cat) {
+ $stat_cat_entry = $e->search_asset_stat_cat_entry({'value' => $pair_pieces[1], 'stat_cat' => $stat_cat->id})->[0];
+ push (@$stat_cat_entries, $stat_cat_entry) if $stat_cat_entry;
+ }
+ } else {
+ $logger->warn("Bad format for stat cat data ($stat_cat_pair), should be like: CAT 1|VALUE 1");
+ }
+
+ if (!$stat_cat or !$stat_cat_entry) {
+ $logger->warn("Invalid stat cat data ($stat_cat_pair): " . $e->die_event);
+ }
+ }
+ $copy->stat_cat_entries( $stat_cat_entries );
+ $copy->ischanged(1);
+ $evt = OpenILS::Application::Cat::AssetCommon->update_copy_stat_entries($e, $copy, 0, 1); #delete_stats=0, add_or_update_only=1
+ }
+
# set the import data on the import item
$item->imported_as($copy->id); # $copy->id is set by create_copy() ^--
$item->import_time('now');
diff --git a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
index 27eb528..f750adb 100644
--- a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
+++ b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
@@ -107,6 +107,7 @@ CREATE TABLE vandelay.import_item_attr_definition (
priv_note_title TEXT,
priv_note TEXT,
internal_id TEXT,
+ stat_cat_data TEXT,
CONSTRAINT vand_import_item_attr_def_idx UNIQUE (owner,name)
);
@@ -178,6 +179,7 @@ CREATE TABLE vandelay.import_item (
alert_message TEXT,
pub_note TEXT,
priv_note TEXT,
+ stat_cat_data TEXT,
opac_visible BOOL,
internal_id BIGINT -- queue_type == 'acq' ? acq.lineitem_detail.id : asset.copy.id
);
diff --git a/Open-ILS/src/sql/Pg/999.functions.global.sql b/Open-ILS/src/sql/Pg/999.functions.global.sql
index bb87a6b..589eab8 100644
--- a/Open-ILS/src/sql/Pg/999.functions.global.sql
+++ b/Open-ILS/src/sql/Pg/999.functions.global.sql
@@ -1724,12 +1724,13 @@ DECLARE
pub_note TEXT;
priv_note TEXT;
internal_id TEXT;
+ stat_cat_data TEXT;
attr_def RECORD;
tmp_attr_set RECORD;
attr_set vandelay.import_item%ROWTYPE;
- xpath TEXT;
+ xpaths TEXT[];
tmp_str TEXT;
BEGIN
@@ -1745,172 +1746,162 @@ BEGIN
owning_lib :=
CASE
WHEN attr_def.owning_lib IS NULL THEN 'null()'
- WHEN LENGTH( attr_def.owning_lib ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.owning_lib || '"]'
- ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.owning_lib
+ WHEN LENGTH( attr_def.owning_lib ) = 1 THEN '*[@code="' || attr_def.owning_lib || '"]'
+ ELSE '*' || attr_def.owning_lib
END;
circ_lib :=
CASE
WHEN attr_def.circ_lib IS NULL THEN 'null()'
- WHEN LENGTH( attr_def.circ_lib ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.circ_lib || '"]'
- ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.circ_lib
+ WHEN LENGTH( attr_def.circ_lib ) = 1 THEN '*[@code="' || attr_def.circ_lib || '"]'
+ ELSE '*' || attr_def.circ_lib
END;
call_number :=
CASE
WHEN attr_def.call_number IS NULL THEN 'null()'
- WHEN LENGTH( attr_def.call_number ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.call_number || '"]'
- ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.call_number
+ WHEN LENGTH( attr_def.call_number ) = 1 THEN '*[@code="' || attr_def.call_number || '"]'
+ ELSE '*' || attr_def.call_number
END;
copy_number :=
CASE
WHEN attr_def.copy_number IS NULL THEN 'null()'
- WHEN LENGTH( attr_def.copy_number ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.copy_number || '"]'
- ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.copy_number
+ WHEN LENGTH( attr_def.copy_number ) = 1 THEN '*[@code="' || attr_def.copy_number || '"]'
+ ELSE '*' || attr_def.copy_number
END;
status :=
CASE
WHEN attr_def.status IS NULL THEN 'null()'
- WHEN LENGTH( attr_def.status ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.status || '"]'
- ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.status
+ WHEN LENGTH( attr_def.status ) = 1 THEN '*[@code="' || attr_def.status || '"]'
+ ELSE '*' || attr_def.status
END;
location :=
CASE
WHEN attr_def.location IS NULL THEN 'null()'
- WHEN LENGTH( attr_def.location ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.location || '"]'
- ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.location
+ WHEN LENGTH( attr_def.location ) = 1 THEN '*[@code="' || attr_def.location || '"]'
+ ELSE '*' || attr_def.location
END;
circulate :=
CASE
WHEN attr_def.circulate IS NULL THEN 'null()'
- WHEN LENGTH( attr_def.circulate ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.circulate || '"]'
- ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.circulate
+ WHEN LENGTH( attr_def.circulate ) = 1 THEN '*[@code="' || attr_def.circulate || '"]'
+ ELSE '*' || attr_def.circulate
END;
deposit :=
CASE
WHEN attr_def.deposit IS NULL THEN 'null()'
- WHEN LENGTH( attr_def.deposit ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.deposit || '"]'
- ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.deposit
+ WHEN LENGTH( attr_def.deposit ) = 1 THEN '*[@code="' || attr_def.deposit || '"]'
+ ELSE '*' || attr_def.deposit
END;
deposit_amount :=
CASE
WHEN attr_def.deposit_amount IS NULL THEN 'null()'
- WHEN LENGTH( attr_def.deposit_amount ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.deposit_amount || '"]'
- ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.deposit_amount
+ WHEN LENGTH( attr_def.deposit_amount ) = 1 THEN '*[@code="' || attr_def.deposit_amount || '"]'
+ ELSE '*' || attr_def.deposit_amount
END;
ref :=
CASE
WHEN attr_def.ref IS NULL THEN 'null()'
- WHEN LENGTH( attr_def.ref ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.ref || '"]'
- ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.ref
+ WHEN LENGTH( attr_def.ref ) = 1 THEN '*[@code="' || attr_def.ref || '"]'
+ ELSE '*' || attr_def.ref
END;
holdable :=
CASE
WHEN attr_def.holdable IS NULL THEN 'null()'
- WHEN LENGTH( attr_def.holdable ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.holdable || '"]'
- ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.holdable
+ WHEN LENGTH( attr_def.holdable ) = 1 THEN '*[@code="' || attr_def.holdable || '"]'
+ ELSE '*' || attr_def.holdable
END;
price :=
CASE
WHEN attr_def.price IS NULL THEN 'null()'
- WHEN LENGTH( attr_def.price ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.price || '"]'
- ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.price
+ WHEN LENGTH( attr_def.price ) = 1 THEN '*[@code="' || attr_def.price || '"]'
+ ELSE '*' || attr_def.price
END;
barcode :=
CASE
WHEN attr_def.barcode IS NULL THEN 'null()'
- WHEN LENGTH( attr_def.barcode ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.barcode || '"]'
- ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.barcode
+ WHEN LENGTH( attr_def.barcode ) = 1 THEN '*[@code="' || attr_def.barcode || '"]'
+ ELSE '*' || attr_def.barcode
END;
circ_modifier :=
CASE
WHEN attr_def.circ_modifier IS NULL THEN 'null()'
- WHEN LENGTH( attr_def.circ_modifier ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.circ_modifier || '"]'
- ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.circ_modifier
+ WHEN LENGTH( attr_def.circ_modifier ) = 1 THEN '*[@code="' || attr_def.circ_modifier || '"]'
+ ELSE '*' || attr_def.circ_modifier
END;
circ_as_type :=
CASE
WHEN attr_def.circ_as_type IS NULL THEN 'null()'
- WHEN LENGTH( attr_def.circ_as_type ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.circ_as_type || '"]'
- ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.circ_as_type
+ WHEN LENGTH( attr_def.circ_as_type ) = 1 THEN '*[@code="' || attr_def.circ_as_type || '"]'
+ ELSE '*' || attr_def.circ_as_type
END;
alert_message :=
CASE
WHEN attr_def.alert_message IS NULL THEN 'null()'
- WHEN LENGTH( attr_def.alert_message ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.alert_message || '"]'
- ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.alert_message
+ WHEN LENGTH( attr_def.alert_message ) = 1 THEN '*[@code="' || attr_def.alert_message || '"]'
+ ELSE '*' || attr_def.alert_message
END;
opac_visible :=
CASE
WHEN attr_def.opac_visible IS NULL THEN 'null()'
- WHEN LENGTH( attr_def.opac_visible ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.opac_visible || '"]'
- ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.opac_visible
+ WHEN LENGTH( attr_def.opac_visible ) = 1 THEN '*[@code="' || attr_def.opac_visible || '"]'
+ ELSE '*' || attr_def.opac_visible
END;
pub_note :=
CASE
WHEN attr_def.pub_note IS NULL THEN 'null()'
- WHEN LENGTH( attr_def.pub_note ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.pub_note || '"]'
- ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.pub_note
+ WHEN LENGTH( attr_def.pub_note ) = 1 THEN '*[@code="' || attr_def.pub_note || '"]'
+ ELSE '*' || attr_def.pub_note
END;
priv_note :=
CASE
WHEN attr_def.priv_note IS NULL THEN 'null()'
- WHEN LENGTH( attr_def.priv_note ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.priv_note || '"]'
- ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.priv_note
+ WHEN LENGTH( attr_def.priv_note ) = 1 THEN '*[@code="' || attr_def.priv_note || '"]'
+ ELSE '*' || attr_def.priv_note
END;
internal_id :=
CASE
WHEN attr_def.internal_id IS NULL THEN 'null()'
- WHEN LENGTH( attr_def.internal_id ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.internal_id || '"]'
- ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.internal_id
+ WHEN LENGTH( attr_def.internal_id ) = 1 THEN '*[@code="' || attr_def.internal_id || '"]'
+ ELSE '*' || attr_def.internal_id
+ END;
+
+ stat_cat_data :=
+ CASE
+ WHEN attr_def.stat_cat_data IS NULL THEN 'null()'
+ WHEN LENGTH( attr_def.stat_cat_data ) = 1 THEN '*[@code="' || attr_def.stat_cat_data || '"]'
+ ELSE '*' || attr_def.stat_cat_data
END;
- xpath :=
- owning_lib || '|' ||
- circ_lib || '|' ||
- call_number || '|' ||
- copy_number || '|' ||
- status || '|' ||
- location || '|' ||
- circulate || '|' ||
- deposit || '|' ||
- deposit_amount || '|' ||
- ref || '|' ||
- holdable || '|' ||
- price || '|' ||
- barcode || '|' ||
- circ_modifier || '|' ||
- circ_as_type || '|' ||
- alert_message || '|' ||
- pub_note || '|' ||
- priv_note || '|' ||
- internal_id || '|' ||
- opac_visible;
+ xpaths := ARRAY[owning_lib, circ_lib, call_number, copy_number, status, location, circulate,
+ deposit, deposit_amount, ref, holdable, price, barcode, circ_modifier, circ_as_type,
+ alert_message, pub_note, priv_note, internal_id, stat_cat_data, opac_visible];
FOR tmp_attr_set IN
SELECT *
- FROM oils_xpath_table( 'id', 'marc', 'vandelay.queued_bib_record', xpath, 'id = ' || import_id )
- AS t( id INT, ol TEXT, clib TEXT, cn TEXT, cnum TEXT, cs TEXT, cl TEXT, circ TEXT,
+ FROM oils_xpath_tag_to_table( (SELECT marc FROM vandelay.queued_bib_record WHERE id = import_id), attr_def.tag, xpaths)
+ AS t( ol TEXT, clib TEXT, cn TEXT, cnum TEXT, cs TEXT, cl TEXT, circ TEXT,
dep TEXT, dep_amount TEXT, r TEXT, hold TEXT, pr TEXT, bc TEXT, circ_mod TEXT,
- circ_as TEXT, amessage TEXT, note TEXT, pnote TEXT, internal_id TEXT, opac_vis TEXT )
+ circ_as TEXT, amessage TEXT, note TEXT, pnote TEXT, internal_id TEXT,
+ stat_cat_data TEXT, opac_vis TEXT )
LOOP
attr_set.import_error := NULL;
@@ -2092,6 +2083,7 @@ BEGIN
attr_set.priv_note := tmp_attr_set.pnote; -- TEXT,
attr_set.alert_message := tmp_attr_set.amessage; -- TEXT,
attr_set.internal_id := tmp_attr_set.internal_id::BIGINT;
+ attr_set.stat_cat_data := tmp_attr_set.stat_cat_data; -- TEXT,
RETURN NEXT attr_set;
@@ -2143,6 +2135,7 @@ BEGIN
priv_note,
internal_id,
opac_visible,
+ stat_cat_data,
import_error,
error_detail
) VALUES (
@@ -2168,6 +2161,7 @@ BEGIN
item_data.priv_note,
item_data.internal_id,
item_data.opac_visible,
+ item_data.stat_cat_data,
item_data.import_error,
item_data.error_detail
);
diff --git a/Open-ILS/src/sql/Pg/upgrade/YYYY.schema.vandelay-stat-cat-import.sql b/Open-ILS/src/sql/Pg/upgrade/YYYY.schema.vandelay-stat-cat-import.sql
new file mode 100644
index 0000000..0256b1b
--- /dev/null
+++ b/Open-ILS/src/sql/Pg/upgrade/YYYY.schema.vandelay-stat-cat-import.sql
@@ -0,0 +1,476 @@
+BEGIN;
+
+--SELECT evergreen.upgrade_deps_block_check('XXXX', :eg_version);
+
+ALTER TABLE vandelay.import_item_attr_definition
+ ADD COLUMN stat_cat_data TEXT;
+
+ALTER TABLE vandelay.import_item
+ ADD COLUMN stat_cat_data TEXT;
+
+CREATE OR REPLACE FUNCTION vandelay.ingest_items ( import_id BIGINT, attr_def_id BIGINT ) RETURNS SETOF vandelay.import_item AS $$
+DECLARE
+
+ owning_lib TEXT;
+ circ_lib TEXT;
+ call_number TEXT;
+ copy_number TEXT;
+ status TEXT;
+ location TEXT;
+ circulate TEXT;
+ deposit TEXT;
+ deposit_amount TEXT;
+ ref TEXT;
+ holdable TEXT;
+ price TEXT;
+ barcode TEXT;
+ circ_modifier TEXT;
+ circ_as_type TEXT;
+ alert_message TEXT;
+ opac_visible TEXT;
+ pub_note TEXT;
+ priv_note TEXT;
+ internal_id TEXT;
+ stat_cat_data TEXT;
+
+ attr_def RECORD;
+ tmp_attr_set RECORD;
+ attr_set vandelay.import_item%ROWTYPE;
+
+ xpaths TEXT[];
+ tmp_str TEXT;
+
+BEGIN
+
+ SELECT * INTO attr_def FROM vandelay.import_item_attr_definition WHERE id = attr_def_id;
+
+ IF FOUND THEN
+
+ attr_set.definition := attr_def.id;
+
+ -- Build the combined XPath
+
+ owning_lib :=
+ CASE
+ WHEN attr_def.owning_lib IS NULL THEN 'null()'
+ WHEN LENGTH( attr_def.owning_lib ) = 1 THEN '*[@code="' || attr_def.owning_lib || '"]'
+ ELSE '*' || attr_def.owning_lib
+ END;
+
+ circ_lib :=
+ CASE
+ WHEN attr_def.circ_lib IS NULL THEN 'null()'
+ WHEN LENGTH( attr_def.circ_lib ) = 1 THEN '*[@code="' || attr_def.circ_lib || '"]'
+ ELSE '*' || attr_def.circ_lib
+ END;
+
+ call_number :=
+ CASE
+ WHEN attr_def.call_number IS NULL THEN 'null()'
+ WHEN LENGTH( attr_def.call_number ) = 1 THEN '*[@code="' || attr_def.call_number || '"]'
+ ELSE '*' || attr_def.call_number
+ END;
+
+ copy_number :=
+ CASE
+ WHEN attr_def.copy_number IS NULL THEN 'null()'
+ WHEN LENGTH( attr_def.copy_number ) = 1 THEN '*[@code="' || attr_def.copy_number || '"]'
+ ELSE '*' || attr_def.copy_number
+ END;
+
+ status :=
+ CASE
+ WHEN attr_def.status IS NULL THEN 'null()'
+ WHEN LENGTH( attr_def.status ) = 1 THEN '*[@code="' || attr_def.status || '"]'
+ ELSE '*' || attr_def.status
+ END;
+
+ location :=
+ CASE
+ WHEN attr_def.location IS NULL THEN 'null()'
+ WHEN LENGTH( attr_def.location ) = 1 THEN '*[@code="' || attr_def.location || '"]'
+ ELSE '*' || attr_def.location
+ END;
+
+ circulate :=
+ CASE
+ WHEN attr_def.circulate IS NULL THEN 'null()'
+ WHEN LENGTH( attr_def.circulate ) = 1 THEN '*[@code="' || attr_def.circulate || '"]'
+ ELSE '*' || attr_def.circulate
+ END;
+
+ deposit :=
+ CASE
+ WHEN attr_def.deposit IS NULL THEN 'null()'
+ WHEN LENGTH( attr_def.deposit ) = 1 THEN '*[@code="' || attr_def.deposit || '"]'
+ ELSE '*' || attr_def.deposit
+ END;
+
+ deposit_amount :=
+ CASE
+ WHEN attr_def.deposit_amount IS NULL THEN 'null()'
+ WHEN LENGTH( attr_def.deposit_amount ) = 1 THEN '*[@code="' || attr_def.deposit_amount || '"]'
+ ELSE '*' || attr_def.deposit_amount
+ END;
+
+ ref :=
+ CASE
+ WHEN attr_def.ref IS NULL THEN 'null()'
+ WHEN LENGTH( attr_def.ref ) = 1 THEN '*[@code="' || attr_def.ref || '"]'
+ ELSE '*' || attr_def.ref
+ END;
+
+ holdable :=
+ CASE
+ WHEN attr_def.holdable IS NULL THEN 'null()'
+ WHEN LENGTH( attr_def.holdable ) = 1 THEN '*[@code="' || attr_def.holdable || '"]'
+ ELSE '*' || attr_def.holdable
+ END;
+
+ price :=
+ CASE
+ WHEN attr_def.price IS NULL THEN 'null()'
+ WHEN LENGTH( attr_def.price ) = 1 THEN '*[@code="' || attr_def.price || '"]'
+ ELSE '*' || attr_def.price
+ END;
+
+ barcode :=
+ CASE
+ WHEN attr_def.barcode IS NULL THEN 'null()'
+ WHEN LENGTH( attr_def.barcode ) = 1 THEN '*[@code="' || attr_def.barcode || '"]'
+ ELSE '*' || attr_def.barcode
+ END;
+
+ circ_modifier :=
+ CASE
+ WHEN attr_def.circ_modifier IS NULL THEN 'null()'
+ WHEN LENGTH( attr_def.circ_modifier ) = 1 THEN '*[@code="' || attr_def.circ_modifier || '"]'
+ ELSE '*' || attr_def.circ_modifier
+ END;
+
+ circ_as_type :=
+ CASE
+ WHEN attr_def.circ_as_type IS NULL THEN 'null()'
+ WHEN LENGTH( attr_def.circ_as_type ) = 1 THEN '*[@code="' || attr_def.circ_as_type || '"]'
+ ELSE '*' || attr_def.circ_as_type
+ END;
+
+ alert_message :=
+ CASE
+ WHEN attr_def.alert_message IS NULL THEN 'null()'
+ WHEN LENGTH( attr_def.alert_message ) = 1 THEN '*[@code="' || attr_def.alert_message || '"]'
+ ELSE '*' || attr_def.alert_message
+ END;
+
+ opac_visible :=
+ CASE
+ WHEN attr_def.opac_visible IS NULL THEN 'null()'
+ WHEN LENGTH( attr_def.opac_visible ) = 1 THEN '*[@code="' || attr_def.opac_visible || '"]'
+ ELSE '*' || attr_def.opac_visible
+ END;
+
+ pub_note :=
+ CASE
+ WHEN attr_def.pub_note IS NULL THEN 'null()'
+ WHEN LENGTH( attr_def.pub_note ) = 1 THEN '*[@code="' || attr_def.pub_note || '"]'
+ ELSE '*' || attr_def.pub_note
+ END;
+ priv_note :=
+ CASE
+ WHEN attr_def.priv_note IS NULL THEN 'null()'
+ WHEN LENGTH( attr_def.priv_note ) = 1 THEN '*[@code="' || attr_def.priv_note || '"]'
+ ELSE '*' || attr_def.priv_note
+ END;
+
+ internal_id :=
+ CASE
+ WHEN attr_def.internal_id IS NULL THEN 'null()'
+ WHEN LENGTH( attr_def.internal_id ) = 1 THEN '*[@code="' || attr_def.internal_id || '"]'
+ ELSE '*' || attr_def.internal_id
+ END;
+
+ stat_cat_data :=
+ CASE
+ WHEN attr_def.stat_cat_data IS NULL THEN 'null()'
+ WHEN LENGTH( attr_def.stat_cat_data ) = 1 THEN '*[@code="' || attr_def.stat_cat_data || '"]'
+ ELSE '*' || attr_def.stat_cat_data
+ END;
+
+
+
+ xpaths := ARRAY[owning_lib, circ_lib, call_number, copy_number, status, location, circulate,
+ deposit, deposit_amount, ref, holdable, price, barcode, circ_modifier, circ_as_type,
+ alert_message, pub_note, priv_note, internal_id, stat_cat_data, opac_visible];
+
+ FOR tmp_attr_set IN
+ SELECT *
+ FROM oils_xpath_tag_to_table( (SELECT marc FROM vandelay.queued_bib_record WHERE id = import_id), attr_def.tag, xpaths)
+ AS t( ol TEXT, clib TEXT, cn TEXT, cnum TEXT, cs TEXT, cl TEXT, circ TEXT,
+ dep TEXT, dep_amount TEXT, r TEXT, hold TEXT, pr TEXT, bc TEXT, circ_mod TEXT,
+ circ_as TEXT, amessage TEXT, note TEXT, pnote TEXT, internal_id TEXT,
+ stat_cat_data TEXT, opac_vis TEXT )
+ LOOP
+
+ attr_set.import_error := NULL;
+ attr_set.error_detail := NULL;
+ attr_set.deposit_amount := NULL;
+ attr_set.copy_number := NULL;
+ attr_set.price := NULL;
+ attr_set.circ_modifier := NULL;
+ attr_set.location := NULL;
+ attr_set.barcode := NULL;
+ attr_set.call_number := NULL;
+
+ IF tmp_attr_set.pr != '' THEN
+ tmp_str = REGEXP_REPLACE(tmp_attr_set.pr, E'[^0-9\\.]', '', 'g');
+ IF tmp_str = '' THEN
+ attr_set.import_error := 'import.item.invalid.price';
+ attr_set.error_detail := tmp_attr_set.pr; -- original value
+ RETURN NEXT attr_set; CONTINUE;
+ END IF;
+ attr_set.price := tmp_str::NUMERIC(8,2);
+ END IF;
+
+ IF tmp_attr_set.dep_amount != '' THEN
+ tmp_str = REGEXP_REPLACE(tmp_attr_set.dep_amount, E'[^0-9\\.]', '', 'g');
+ IF tmp_str = '' THEN
+ attr_set.import_error := 'import.item.invalid.deposit_amount';
+ attr_set.error_detail := tmp_attr_set.dep_amount;
+ RETURN NEXT attr_set; CONTINUE;
+ END IF;
+ attr_set.deposit_amount := tmp_str::NUMERIC(8,2);
+ END IF;
+
+ IF tmp_attr_set.cnum != '' THEN
+ tmp_str = REGEXP_REPLACE(tmp_attr_set.cnum, E'[^0-9]', '', 'g');
+ IF tmp_str = '' THEN
+ attr_set.import_error := 'import.item.invalid.copy_number';
+ attr_set.error_detail := tmp_attr_set.cnum;
+ RETURN NEXT attr_set; CONTINUE;
+ END IF;
+ attr_set.copy_number := tmp_str::INT;
+ END IF;
+
+ IF tmp_attr_set.ol != '' THEN
+ SELECT id INTO attr_set.owning_lib FROM actor.org_unit WHERE shortname = UPPER(tmp_attr_set.ol); -- INT
+ IF NOT FOUND THEN
+ attr_set.import_error := 'import.item.invalid.owning_lib';
+ attr_set.error_detail := tmp_attr_set.ol;
+ RETURN NEXT attr_set; CONTINUE;
+ END IF;
+ END IF;
+
+ IF tmp_attr_set.clib != '' THEN
+ SELECT id INTO attr_set.circ_lib FROM actor.org_unit WHERE shortname = UPPER(tmp_attr_set.clib); -- INT
+ IF NOT FOUND THEN
+ attr_set.import_error := 'import.item.invalid.circ_lib';
+ attr_set.error_detail := tmp_attr_set.clib;
+ RETURN NEXT attr_set; CONTINUE;
+ END IF;
+ END IF;
+
+ IF tmp_attr_set.cs != '' THEN
+ SELECT id INTO attr_set.status FROM config.copy_status WHERE LOWER(name) = LOWER(tmp_attr_set.cs); -- INT
+ IF NOT FOUND THEN
+ attr_set.import_error := 'import.item.invalid.status';
+ attr_set.error_detail := tmp_attr_set.cs;
+ RETURN NEXT attr_set; CONTINUE;
+ END IF;
+ END IF;
+
+ IF COALESCE(tmp_attr_set.circ_mod, '') = '' THEN
+
+ -- no circ mod defined, see if we should apply a default
+ SELECT INTO attr_set.circ_modifier TRIM(BOTH '"' FROM value)
+ FROM actor.org_unit_ancestor_setting(
+ 'vandelay.item.circ_modifier.default',
+ attr_set.owning_lib
+ );
+
+ -- make sure the value from the org setting is still valid
+ PERFORM 1 FROM config.circ_modifier WHERE code = attr_set.circ_modifier;
+ IF NOT FOUND THEN
+ attr_set.import_error := 'import.item.invalid.circ_modifier';
+ attr_set.error_detail := tmp_attr_set.circ_mod;
+ RETURN NEXT attr_set; CONTINUE;
+ END IF;
+
+ ELSE
+
+ SELECT code INTO attr_set.circ_modifier FROM config.circ_modifier WHERE code = tmp_attr_set.circ_mod;
+ IF NOT FOUND THEN
+ attr_set.import_error := 'import.item.invalid.circ_modifier';
+ attr_set.error_detail := tmp_attr_set.circ_mod;
+ RETURN NEXT attr_set; CONTINUE;
+ END IF;
+ END IF;
+
+ IF tmp_attr_set.circ_as != '' THEN
+ SELECT code INTO attr_set.circ_as_type FROM config.coded_value_map WHERE ctype = 'item_type' AND code = tmp_attr_set.circ_as;
+ IF NOT FOUND THEN
+ attr_set.import_error := 'import.item.invalid.circ_as_type';
+ attr_set.error_detail := tmp_attr_set.circ_as;
+ RETURN NEXT attr_set; CONTINUE;
+ END IF;
+ END IF;
+
+ IF COALESCE(tmp_attr_set.cl, '') = '' THEN
+ -- no location specified, see if we should apply a default
+
+ SELECT INTO attr_set.location TRIM(BOTH '"' FROM value)
+ FROM actor.org_unit_ancestor_setting(
+ 'vandelay.item.copy_location.default',
+ attr_set.owning_lib
+ );
+
+ -- make sure the value from the org setting is still valid
+ PERFORM 1 FROM asset.copy_location WHERE id = attr_set.location;
+ IF NOT FOUND THEN
+ attr_set.import_error := 'import.item.invalid.location';
+ attr_set.error_detail := tmp_attr_set.cs;
+ RETURN NEXT attr_set; CONTINUE;
+ END IF;
+ ELSE
+
+ -- search up the org unit tree for a matching copy location
+ WITH RECURSIVE anscestor_depth AS (
+ SELECT ou.id,
+ out.depth AS depth,
+ ou.parent_ou
+ FROM actor.org_unit ou
+ JOIN actor.org_unit_type out ON (out.id = ou.ou_type)
+ WHERE ou.id = COALESCE(attr_set.owning_lib, attr_set.circ_lib)
+ UNION ALL
+ SELECT ou.id,
+ out.depth,
+ ou.parent_ou
+ FROM actor.org_unit ou
+ JOIN actor.org_unit_type out ON (out.id = ou.ou_type)
+ JOIN anscestor_depth ot ON (ot.parent_ou = ou.id)
+ ) SELECT cpl.id INTO attr_set.location
+ FROM anscestor_depth a
+ JOIN asset.copy_location cpl ON (cpl.owning_lib = a.id)
+ WHERE LOWER(cpl.name) = LOWER(tmp_attr_set.cl)
+ ORDER BY a.depth DESC
+ LIMIT 1;
+
+ IF NOT FOUND THEN
+ attr_set.import_error := 'import.item.invalid.location';
+ attr_set.error_detail := tmp_attr_set.cs;
+ RETURN NEXT attr_set; CONTINUE;
+ END IF;
+ END IF;
+
+ attr_set.circulate :=
+ LOWER( SUBSTRING( tmp_attr_set.circ, 1, 1)) IN ('t','y','1')
+ OR LOWER(tmp_attr_set.circ) = 'circulating'; -- BOOL
+
+ attr_set.deposit :=
+ LOWER( SUBSTRING( tmp_attr_set.dep, 1, 1 ) ) IN ('t','y','1')
+ OR LOWER(tmp_attr_set.dep) = 'deposit'; -- BOOL
+
+ attr_set.holdable :=
+ LOWER( SUBSTRING( tmp_attr_set.hold, 1, 1 ) ) IN ('t','y','1')
+ OR LOWER(tmp_attr_set.hold) = 'holdable'; -- BOOL
+
+ attr_set.opac_visible :=
+ LOWER( SUBSTRING( tmp_attr_set.opac_vis, 1, 1 ) ) IN ('t','y','1')
+ OR LOWER(tmp_attr_set.opac_vis) = 'visible'; -- BOOL
+
+ attr_set.ref :=
+ LOWER( SUBSTRING( tmp_attr_set.r, 1, 1 ) ) IN ('t','y','1')
+ OR LOWER(tmp_attr_set.r) = 'reference'; -- BOOL
+
+ attr_set.call_number := tmp_attr_set.cn; -- TEXT
+ attr_set.barcode := tmp_attr_set.bc; -- TEXT,
+ attr_set.alert_message := tmp_attr_set.amessage; -- TEXT,
+ attr_set.pub_note := tmp_attr_set.note; -- TEXT,
+ attr_set.priv_note := tmp_attr_set.pnote; -- TEXT,
+ attr_set.alert_message := tmp_attr_set.amessage; -- TEXT,
+ attr_set.internal_id := tmp_attr_set.internal_id::BIGINT;
+ attr_set.stat_cat_data := tmp_attr_set.stat_cat_data; -- TEXT,
+
+ RETURN NEXT attr_set;
+
+ END LOOP;
+
+ END IF;
+
+ RETURN;
+
+END;
+$$ LANGUAGE PLPGSQL;
+
+CREATE OR REPLACE FUNCTION vandelay.ingest_bib_items ( ) RETURNS TRIGGER AS $func$
+DECLARE
+ attr_def BIGINT;
+ item_data vandelay.import_item%ROWTYPE;
+BEGIN
+
+ IF TG_OP IN ('INSERT','UPDATE') AND NEW.imported_as IS NOT NULL THEN
+ RETURN NEW;
+ END IF;
+
+ SELECT item_attr_def INTO attr_def FROM vandelay.bib_queue WHERE id = NEW.queue;
+
+ FOR item_data IN SELECT * FROM vandelay.ingest_items( NEW.id::BIGINT, attr_def ) LOOP
+ INSERT INTO vandelay.import_item (
+ record,
+ definition,
+ owning_lib,
+ circ_lib,
+ call_number,
+ copy_number,
+ status,
+ location,
+ circulate,
+ deposit,
+ deposit_amount,
+ ref,
+ holdable,
+ price,
+ barcode,
+ circ_modifier,
+ circ_as_type,
+ alert_message,
+ pub_note,
+ priv_note,
+ internal_id,
+ opac_visible,
+ stat_cat_data,
+ import_error,
+ error_detail
+ ) VALUES (
+ NEW.id,
+ item_data.definition,
+ item_data.owning_lib,
+ item_data.circ_lib,
+ item_data.call_number,
+ item_data.copy_number,
+ item_data.status,
+ item_data.location,
+ item_data.circulate,
+ item_data.deposit,
+ item_data.deposit_amount,
+ item_data.ref,
+ item_data.holdable,
+ item_data.price,
+ item_data.barcode,
+ item_data.circ_modifier,
+ item_data.circ_as_type,
+ item_data.alert_message,
+ item_data.pub_note,
+ item_data.priv_note,
+ item_data.internal_id,
+ item_data.opac_visible,
+ item_data.stat_cat_data,
+ item_data.import_error,
+ item_data.error_detail
+ );
+ END LOOP;
+
+ RETURN NULL;
+END;
+$func$ LANGUAGE PLPGSQL;
+
+COMMIT;
commit b1c8c14e48abaa729ae164fd969ffe5c304a857d
Author: Dan Wells <dbw2 at calvin.edu>
Date: Wed Oct 8 13:35:43 2014 -0400
LP#1379815 Add missing behavior to update_copy_stat_entries
The current function doesn't provide the level of control we need, even
with the 'delete_stats' flag set to zero. This commit adds a new
'add_or_update_only' option which preserves existing stat cat entry maps
for any stat cat not represented on the incoming copy object, and
updates values when appropriate.
This commit also updates the function comment for better clarity.
Signed-off-by: Dan Wells <dbw2 at calvin.edu>
Signed-off-by: Ben Shum <bshum at biblio.org>
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Cat/AssetCommon.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Cat/AssetCommon.pm
index 2dcc62d..4d78cb5 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Cat/AssetCommon.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Cat/AssetCommon.pm
@@ -80,11 +80,17 @@ sub create_copy {
}
-# if 'delete_stats' is true, the copy->stat_cat_entries data is
-# treated as the authoritative list for the copy. existing entries
-# that are not in said list will be deleted from the DB
+# 'delete_stats' is somewhat of a misnomer. With no flags set, this method
+# still deletes any existing maps not represented in $copy->stat_cat_entries,
+# but aborts when $copy->stat_cat_entries is empty or undefined. If
+# 'delete_stats' is true, this method will delete all the maps when
+# $copy->stat_cat_entries is empty or undefined.
+#
+# The 'add_or_update_only' flag is more straightforward. It adds missing
+# maps, updates present maps with any new values, and leaves the rest
+# alone.
sub update_copy_stat_entries {
- my($class, $editor, $copy, $delete_stats) = @_;
+ my($class, $editor, $copy, $delete_stats, $add_or_update_only) = @_;
return undef if $copy->isdeleted;
return undef unless $copy->ischanged or $copy->isnew;
@@ -104,13 +110,24 @@ sub update_copy_stat_entries {
# if there is no stat cat entry on the copy who's id matches the
# current map's id, remove the map from the database
for my $map (@$maps) {
- if(! grep { $_->id == $map->stat_cat_entry } @$entries ) {
+ if (!$add_or_update_only) {
+ if(! grep { $_->id == $map->stat_cat_entry } @$entries ) {
- $logger->info("copy update found stale ".
- "stat cat entry map ".$map->id. " on copy ".$copy->id);
+ $logger->info("copy update found stale ".
+ "stat cat entry map ".$map->id. " on copy ".$copy->id);
- $editor->delete_asset_stat_cat_entry_copy_map($map)
- or return $editor->event;
+ $editor->delete_asset_stat_cat_entry_copy_map($map)
+ or return $editor->event;
+ }
+ } else {
+ if( grep { $_->stat_cat == $map->stat_cat and $_->id != $map->stat_cat_entry } @$entries ) {
+
+ $logger->info("copy update found ".
+ "stat cat entry map ".$map->id. " needing update on copy ".$copy->id);
+
+ $editor->delete_asset_stat_cat_entry_copy_map($map)
+ or return $editor->event;
+ }
}
}
}
commit 55f4479eb3adeb2f67ab88b566d8fc7453bc3ed3
Author: Dan Wells <dbw2 at calvin.edu>
Date: Mon Oct 6 11:52:27 2014 -0400
LP#1379815 Fetch tag data as a table using tag/xpath combo
New function: oils_xpath_tag_to_table()
This function is adapted from oils_xpath_table() with the goal of being
more targeted and simpler to use.
The main issue with oils_xpath_table() is that it relies on peer
UNNEST() functions, and that leads to unexpected behavior whenever the
xpath arguments result in uneven or "gapped" selections. In the first
type of case, the resulting table includes rows representing the least
common multiple of the underlying xpath selections. In the second
type, though the xpaths may sometimes return the same number of values,
those values are not correlated except by order in the marc, which does
not account for the real possibility of null values in the set.
Crude Example:
999 $d ABC $e 123
999 $d DEF
999 $d GHI
999 $e 456
We need a table representing subfields 'd' and 'e' of the '999' fields,
so we might try an xpath like:
//*[@tag="999"]/*[@code="d"]|//*[@tag="999"]/*[@code="e"]
We want:
d | e
---------
ABC | 123
DEF |
GHI |
| 456
but we get:
d | e
---------
ABC | 123
DEF | 456
GHI | 123
ABC | 456
DEF | 123
GHI | 456
This example illustrates both negative behaviors (non-correlated fields
and least-common-multiple row multiplication).
The new method, while internally quite similar, has a different
signature, with the most significant change being a 'tag' argument
which serves as a common base element for the xpaths (now an array
rather than a pipe-delimited string).
Signed-off-by: Dan Wells <dbw2 at calvin.edu>
Signed-off-by: Ben Shum <bshum at biblio.org>
diff --git a/Open-ILS/src/sql/Pg/002.functions.config.sql b/Open-ILS/src/sql/Pg/002.functions.config.sql
index 077e9e8..527e89b 100644
--- a/Open-ILS/src/sql/Pg/002.functions.config.sql
+++ b/Open-ILS/src/sql/Pg/002.functions.config.sql
@@ -185,6 +185,48 @@ SELECT * FROM (
END;
$func$ LANGUAGE PLPGSQL IMMUTABLE;
+CREATE OR REPLACE FUNCTION oils_xpath_tag_to_table(marc text, tag text, xpaths text[]) RETURNS SETOF record AS $function$
+
+-- This function currently populates columns with the FIRST matching value
+-- of each XPATH. It would be reasonable to add a 'return_arrays' option
+-- where each column is an array of all matching values for each path, but
+-- that remains as a TODO
+
+DECLARE
+ field RECORD;
+ output RECORD;
+ select_list TEXT[];
+ from_list TEXT[];
+ q TEXT;
+BEGIN
+ -- setup query select
+ FOR i IN 1 .. ARRAY_UPPER(xpaths,1) LOOP
+ IF xpaths[i] = 'null()' THEN
+ select_list := ARRAY_APPEND(select_list, 'NULL::TEXT AS c_' || i );
+ ELSE
+ select_list := ARRAY_APPEND(select_list, '(oils_xpath(' ||
+ quote_literal(
+ CASE
+ WHEN xpaths[i] ~ $re$/[^/[]*@[^/]+$$re$ -- attribute
+ OR xpaths[i] ~ $re$text\(\)$$re$
+ THEN xpaths[i]
+ ELSE xpaths[i] || '//text()'
+ END
+ ) || ', field_marc))[1] AS cl_' || i);
+ -- hardcoded to first value for each path
+ END IF;
+ END LOOP;
+
+ -- run query over tag set
+ q := 'SELECT ' || ARRAY_TO_STRING(select_list, ',')
+ || ' FROM UNNEST(oils_xpath(' || quote_literal('//*[@tag="' || tag
+ || '"]') || ', ' || quote_literal(marc) || ')) AS field_marc;';
+ --RAISE NOTICE '%', q;
+
+ RETURN QUERY EXECUTE q;
+END;
+
+$function$ LANGUAGE PLPGSQL;
CREATE OR REPLACE FUNCTION extract_marc_field ( TEXT, BIGINT, TEXT, TEXT ) RETURNS TEXT AS $$
DECLARE
diff --git a/Open-ILS/src/sql/Pg/upgrade/XXXX.function.vandelay-oils_xpath_tag_to_table.sql b/Open-ILS/src/sql/Pg/upgrade/XXXX.function.vandelay-oils_xpath_tag_to_table.sql
new file mode 100644
index 0000000..48e44f8
--- /dev/null
+++ b/Open-ILS/src/sql/Pg/upgrade/XXXX.function.vandelay-oils_xpath_tag_to_table.sql
@@ -0,0 +1,48 @@
+BEGIN;
+
+--SELECT evergreen.upgrade_deps_block_check('XXXX', :eg_version);
+
+CREATE OR REPLACE FUNCTION oils_xpath_tag_to_table(marc text, tag text, xpaths text[]) RETURNS SETOF record AS $function$
+
+-- This function currently populates columns with the FIRST matching value
+-- of each XPATH. It would be reasonable to add a 'return_arrays' option
+-- where each column is an array of all matching values for each path, but
+-- that remains as a TODO
+
+DECLARE
+ field RECORD;
+ output RECORD;
+ select_list TEXT[];
+ from_list TEXT[];
+ q TEXT;
+BEGIN
+ -- setup query select
+ FOR i IN 1 .. ARRAY_UPPER(xpaths,1) LOOP
+ IF xpaths[i] = 'null()' THEN
+ select_list := ARRAY_APPEND(select_list, 'NULL::TEXT AS c_' || i );
+ ELSE
+ select_list := ARRAY_APPEND(select_list, '(oils_xpath(' ||
+ quote_literal(
+ CASE
+ WHEN xpaths[i] ~ $re$/[^/[]*@[^/]+$$re$ -- attribute
+ OR xpaths[i] ~ $re$text\(\)$$re$
+ THEN xpaths[i]
+ ELSE xpaths[i] || '//text()'
+ END
+ ) || ', field_marc))[1] AS cl_' || i);
+ -- hardcoded to first value for each path
+ END IF;
+ END LOOP;
+
+ -- run query over tag set
+ q := 'SELECT ' || ARRAY_TO_STRING(select_list, ',')
+ || ' FROM UNNEST(oils_xpath(' || quote_literal('//*[@tag="' || tag
+ || '"]') || ', ' || quote_literal(marc) || ')) AS field_marc;';
+ --RAISE NOTICE '%', q;
+
+ RETURN QUERY EXECUTE q;
+END;
+
+$function$ LANGUAGE PLPGSQL;
+
+COMMIT;
-----------------------------------------------------------------------
Summary of changes:
Open-ILS/examples/fm_IDL.xml | 2 +
.../lib/OpenILS/Application/Cat/AssetCommon.pm | 35 ++-
.../perlmods/lib/OpenILS/Application/Vandelay.pm | 39 +++
Open-ILS/src/sql/Pg/002.functions.config.sql | 42 +++
Open-ILS/src/sql/Pg/002.schema.config.sql | 2 +-
Open-ILS/src/sql/Pg/012.schema.vandelay.sql | 2 +
Open-ILS/src/sql/Pg/950.data.seed-values.sql | 4 +
Open-ILS/src/sql/Pg/999.functions.global.sql | 124 ++++----
.../regress/lp1379815_vl_import_item_stat_cats.pg | 52 +++
...8.function.vandelay-oils_xpath_tag_to_table.sql | 48 +++
...ql => 0929.schema.vandelay-stat-cat-import.sql} | 359 +++++++++++---------
.../Cataloging/importing_stat_cats.txt | 19 +
12 files changed, 488 insertions(+), 240 deletions(-)
create mode 100644 Open-ILS/src/sql/Pg/t/regress/lp1379815_vl_import_item_stat_cats.pg
create mode 100644 Open-ILS/src/sql/Pg/upgrade/0928.function.vandelay-oils_xpath_tag_to_table.sql
copy Open-ILS/src/sql/Pg/upgrade/{0731.schema.vandelay_item_overlay.sql => 0929.schema.vandelay-stat-cat-import.sql} (61%)
create mode 100644 docs/RELEASE_NOTES_NEXT/Cataloging/importing_stat_cats.txt
hooks/post-receive
--
Evergreen ILS
More information about the open-ils-commits
mailing list