From: Jason Stephenson Date: Thu, 31 Mar 2016 18:36:54 +0000 (-0400) Subject: LP 1564402: Database Function to Return ISBN13 X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=34d54cfb77afdb068c8eaf10739155c76fdb25ba;p=working%2FEvergreen.git LP 1564402: Database Function to Return ISBN13 This commit adds a database function to return the ISBN13 from a text input. The function is evergreen.isbn13(text). See the release notes for more information. Signed-off-by: Jason Stephenson --- diff --git a/Open-ILS/src/sql/Pg/000.functions.general.sql b/Open-ILS/src/sql/Pg/000.functions.general.sql index ad6182e0f5..9603fd2539 100644 --- a/Open-ILS/src/sql/Pg/000.functions.general.sql +++ b/Open-ILS/src/sql/Pg/000.functions.general.sql @@ -86,4 +86,43 @@ END $protect_reserved$ LANGUAGE plpgsql; +CREATE OR REPLACE FUNCTION evergreen.isbn13(text) + RETURNS text AS +$BODY$ + use Business::ISBN; + use strict; + use warnings; + + my $input = shift; + my $output = ''; + + # Find the first "ISBN" in the input. + if ($input =~ /^\s*([0-9xX-]+)/) { + $input = $1; + } + + my $isbn = Business::ISBN->new($input); + + # Fix the checksum if necessary. + if ($isbn && $isbn->is_valid_checksum() == Business::ISBN::BAD_CHECKSUM) { + $isbn->fix_checksum(); + } + + # If we now have a valid ISBN, convert it to ISBN13 + if ($isbn && $isbn->is_valid()) { + $output = ($isbn->type eq 'ISBN13') ? $isbn->isbn : $isbn->as_isbn13->isbn; + } + return $output if $output; + + # If there was no valid ISBN, return undef; + return undef; +$BODY$ + LANGUAGE plperlu VOLATILE + COST 100; +COMMENT ON FUNCTION evergreen.isbn13(text) IS ' +Takes the first ISBN-like data from a text input and returns the +ISBN13 version or NUll if the input is invalid or cannot be translated +to ISBN13. +'; + COMMIT; diff --git a/Open-ILS/src/sql/Pg/t/isbn13.pg b/Open-ILS/src/sql/Pg/t/isbn13.pg new file mode 100644 index 0000000000..47403dbda0 --- /dev/null +++ b/Open-ILS/src/sql/Pg/t/isbn13.pg @@ -0,0 +1,27 @@ +-- Start transaction and plan the tests. +BEGIN; + +-- Number of tests that will be run +SELECT plan(8); + +-- Run the tests + +SELECT is(evergreen.isbn13('0060530871'), '9780060530877', 'Known good ISBN10 to ISBN13'); + +SELECT is(evergreen.isbn13('9780394577913'), '9780394577913', 'ISBN13'); + +SELECT is(evergreen.isbn13('9780061787768 (pbk.)'), '9780061787768', 'ISBN13 with extra on the end'); + +SELECT is(evergreen.isbn13('0061787760 (pbk.)'), '9780061787768', 'ISBN10 to ISBN13 with extra on the end'); + +SELECT is(evergreen.isbn13(' 9780061787768 (pbk.)'), '9780061787768', 'ISBN13 with leading spaces'); + +SELECT is(evergreen.isbn13(' 0061787760 (pbk.)'), '9780061787768', 'ISBN10 to ISBN13 with leading space'); + +SELECT is(evergreen.isbn13('$6.00'), NULL, 'Price is not an ISBN.'); + +SELECT is(evergreen.isbn13('Eengeepo5i'), NULL, 'Random gibberish is not an ISBN.'); + +-- Finish the test and clean up. +SELECT * FROM finish(); +ROLLBACK; diff --git a/Open-ILS/src/sql/Pg/upgrade/XXXX.function.evergreen.isbn13.sql b/Open-ILS/src/sql/Pg/upgrade/XXXX.function.evergreen.isbn13.sql new file mode 100644 index 0000000000..932e07bb9f --- /dev/null +++ b/Open-ILS/src/sql/Pg/upgrade/XXXX.function.evergreen.isbn13.sql @@ -0,0 +1,44 @@ +BEGIN; + +-- SELECT evergreen.upgrade_deps_block_check('XXXX', :eg_version); + +CREATE OR REPLACE FUNCTION evergreen.isbn13(text) + RETURNS text AS +$BODY$ + use Business::ISBN; + use strict; + use warnings; + + my $input = shift; + my $output = ''; + + # Find the first "ISBN" in the input. + if ($input =~ /^\s*([0-9xX-]+)/) { + $input = $1; + } + + my $isbn = Business::ISBN->new($input); + + # Fix the checksum if necessary. + if ($isbn && $isbn->is_valid_checksum() == Business::ISBN::BAD_CHECKSUM) { + $isbn->fix_checksum(); + } + + # If we now have a valid ISBN, convert it to ISBN13 + if ($isbn && $isbn->is_valid()) { + $output = ($isbn->type eq 'ISBN13') ? $isbn->isbn : $isbn->as_isbn13->isbn; + } + return $output if $output; + + # If there was no valid ISBN, return undef; + return undef; +$BODY$ + LANGUAGE plperlu VOLATILE + COST 100; +COMMENT ON FUNCTION evergreen.isbn13(text) IS ' +Takes the first ISBN-like data from a text input and returns the +ISBN13 version or NUll if the input is invalid or cannot be translated +to ISBN13. +'; + +COMMIT; diff --git a/docs/RELEASE_NOTES_NEXT/Cataloging/database_function_to_return_isbn13.adoc b/docs/RELEASE_NOTES_NEXT/Cataloging/database_function_to_return_isbn13.adoc new file mode 100644 index 0000000000..6f27b3f925 --- /dev/null +++ b/docs/RELEASE_NOTES_NEXT/Cataloging/database_function_to_return_isbn13.adoc @@ -0,0 +1,29 @@ +Database Function to Return ISBN13 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +A database function, evergreen.isbn13(text), was added to return the +ISBN13 value of the first ISBN in the input text. The function +expects the first non-whitespace sequence in the input to look like an +ISBN. If it does, it parses that as an ISBN and returns the ISBN13 +value for that ISBN. If this sequence is not an ISBN, or if no such +sequence is found, then NULL is returned. + +This function is useful if you're extracting information for a vendor +and they require the ISBN13 and only the ISBN13. For instance, you +may be asked to provide a list of ISBN13, barcode, call number, and +bibliographic record id, for some added content service. A query like +the one below could make use of this function to return that +information: + +-------------------------- +select distinct on (isbn, itemid) +evergreen.isbn13(mrfr.value) as isbn, +acp.barcode as itemid, +btrim(regexp_replace(acn.label, '[\s]+',' ','g')) as callno, +acn.record as bibrecordid +from asset.copy acp, asset.call_number acn, metabib.real_full_rec mrfr +where acp.deleted = 'f' +and acp.call_number != -1 and acp.call_number = acn.id +and acn.record = mrfr.record and mrfr.tag = '020' and mrfr.subfield in ('a','z') +and evergreen.isbn13(mrfr.value) is not null +--------------------------