kmain-310. Additional language search Searches MARC 041 for additional language codes.
authorBill Erickson <berickxx@gmail.com>
Wed, 29 Oct 2014 21:06:14 +0000 (17:06 -0400)
committerBill Erickson <berickxx@gmail.com>
Thu, 21 Mar 2019 19:46:23 +0000 (15:46 -0400)
SQL scripts add new metabib.language_filter table and associated
trigger/scripts
new file:   sql/kmain-310/kclsupgrad34.rollback.sql
new file:   sql/kmain-310/kclsupgrad34.sql
modified:   usr/lib/perl5/site_perl/5.8.8/OpenILS/Application/Storage/Driver/Pg/QueryParser.pm
(cherry picked from commit baf328d0c8a9ffb10eeb243db2fe4278ff1adcec)

    Cross-port: 7952a80

Conflicts:
Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Driver/Pg/QueryParser.pm

Conflicts:
Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Driver/Pg/QueryParser.pm

KCLS/sql/kmain-310/kclsupgrad34.rollback.sql [new file with mode: 0644]
KCLS/sql/kmain-310/kclsupgrad34.sql [new file with mode: 0644]
Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Driver/Pg/QueryParser.pm

diff --git a/KCLS/sql/kmain-310/kclsupgrad34.rollback.sql b/KCLS/sql/kmain-310/kclsupgrad34.rollback.sql
new file mode 100644 (file)
index 0000000..18cfaa3
--- /dev/null
@@ -0,0 +1,22 @@
+-- Trigger: language_filter_trigger on biblio.record_entry
+
+DROP TRIGGER IF EXISTS language_filter_trigger ON biblio.record_entry;
+  
+-- Table: metabib.language_filter
+
+DROP TABLE IF EXISTS metabib.language_filter;
+
+-- Function: biblio.extract_languages(bigint)
+
+DROP FUNCTION IF EXISTS biblio.extract_languages(bigint);
+  
+-- Function: biblio.update_language_filter()
+
+DROP FUNCTION IF EXISTS biblio.update_language_filter();
+
+-- RECORD in config.org_unit_setting_type
+
+DELETE FROM config.org_unit_setting_type_log WHERE field_name = 'opac.additional_language.subfields';
+DELETE FROM actor.org_unit_setting WHERE name = 'opac.additional_language.subfields';
+DELETE FROM config.org_unit_setting_type_log WHERE field_name = 'opac.additional_language.subfields';
+DELETE FROM config.org_unit_setting_type WHERE name = 'opac.additional_language.subfields';
diff --git a/KCLS/sql/kmain-310/kclsupgrad34.sql b/KCLS/sql/kmain-310/kclsupgrad34.sql
new file mode 100644 (file)
index 0000000..0feadc2
--- /dev/null
@@ -0,0 +1,112 @@
+-- Table: metabib.language_filter
+
+-- DROP TABLE metabib.language_filter;
+
+CREATE TABLE metabib.language_filter
+(
+  id bigserial NOT NULL,
+  source bigint NOT NULL,
+  value tsvector,
+  CONSTRAINT id PRIMARY KEY (id ),
+  CONSTRAINT source FOREIGN KEY (source)
+      REFERENCES biblio.record_entry (id) MATCH SIMPLE
+      ON UPDATE NO ACTION ON DELETE NO ACTION
+)
+WITH (
+  OIDS=FALSE
+);
+ALTER TABLE metabib.language_filter
+  OWNER TO evergreen;
+
+-- Function: biblio.extract_languages(bigint)
+
+-- DROP FUNCTION biblio.extract_languages(bigint);
+
+CREATE OR REPLACE FUNCTION biblio.extract_languages(bigint)
+  RETURNS tsvector AS
+$BODY$
+
+DECLARE
+    alt_lang    text;
+    lang        text;
+    subfields   text;
+BEGIN
+    lang := biblio.marc21_extract_fixed_field($1, 'Lang');  
+
+--  read MARC 041 subfields from actor.org_unit_setting.opac_additional_language_subfields
+--  trim any '"' chars, split into array of subfields   
+
+    SELECT value INTO subfields FROM actor.org_unit_setting where name like 'opac.additional_language_subfields';
+--
+--  query MARC 041 specified subfields for additional search languages
+--
+    FOR alt_lang IN (SELECT value FROM biblio.flatten_marc($1) where tag='041' and POSITION(subfield IN subfields) > 0)
+    LOOP
+        lang := lang || ' ' || alt_lang;
+    END LOOP;
+    
+    return lang::tsvector;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION biblio.extract_languages(bigint)
+  OWNER TO evergreen;
+  
+-- Function: update_language_filter()
+
+-- DROP FUNCTION update_language_filter();
+
+CREATE OR REPLACE FUNCTION biblio.update_language_filter()
+  RETURNS trigger AS
+$BODY$
+DECLARE
+    lang    tsvector;
+    lang_filter bigint;
+BEGIN    
+    lang := biblio.extract_languages(NEW.id);   
+        
+    SELECT metabib.language_filter.source INTO lang_filter FROM metabib.language_filter WHERE NEW.id = metabib.language_filter.source;
+
+    IF FOUND THEN
+    UPDATE metabib.language_filter SET value = lang WHERE metabib.language_filter.source = NEW.id;  
+    ELSE
+    INSERT INTO metabib.language_filter(source, value) VALUES (NEW.id, lang);   
+    END IF;
+
+    RETURN NEW;
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION biblio.update_language_filter()
+  OWNER TO evergreen;
+
+-- Trigger: language_filter_trigger on biblio.record_entry
+
+-- DROP TRIGGER language_filter_trigger ON biblio.record_entry;
+  
+CREATE TRIGGER language_filter_trigger
+  AFTER INSERT OR UPDATE
+  ON biblio.record_entry
+  FOR EACH ROW
+  EXECUTE PROCEDURE biblio.update_language_filter();
+
+--
+-- added record in config.org_unit_setting_type is used in proposal/additional_language_search
+--
+INSERT INTO config.org_unit_setting_type 
+    (name, label, grp, description, datatype)
+    VALUES (
+        'opac.additional_language.subfields',
+        'Specify MARC 041 subfields for additional search languages',
+        'opac',
+        'Specify which MARC 041 subfields should be used when searching for additional languages.',
+        'string'
+    );
+
+INSERT INTO actor.org_unit_setting
+    (org_unit, name, value) VALUES
+    (1, 'opac.additional_language.subfields', '"abdefj"'
+    );
index 9410851..d7fe36e 100644 (file)
@@ -835,6 +835,7 @@ sub toSQL {
 
     my $flat_plan = $self->flatten;
 
+
     # generate the relevance ranking
     my $rel = '1'; # Default to something simple in case rank_list is empty.
     if (@{$$flat_plan{rank_list}}) {
@@ -887,6 +888,11 @@ sub toSQL {
         $bre_join = 'INNER JOIN biblio.record_entry bre ON m.source = bre.id AND NOT bre.deleted';
     }
 
+    my $mlf_join = '';
+    if ($$flat_plan{uses_mlf}) {
+        $mlf_join = 'JOIN metabib.language_filter AS mlf ON m.source = mlf.source';
+    }
+    
     my $desc = 'ASC';
     $desc = 'DESC' if ($self->find_modifier('descending'));
 
@@ -1156,6 +1162,7 @@ SELECT  id,
                 $lang_join
                 $c_attr_join
                 $b_attr_join
+                $mlf_join
           WHERE 1=1
                 $flat_where
           GROUP BY 1
@@ -1198,6 +1205,7 @@ sub flatten {
     my $uses_bre = 0;
     my $uses_mrd = 0;
     my $uses_mrv = 0;
+    my $uses_mlf = 0;
 
     my @rank_list;
     for my $node ( @{$self->query_nodes} ) {
@@ -1412,6 +1420,7 @@ sub flatten {
                 $uses_bre = $$subnode{uses_bre};
                 $uses_mrd = $$subnode{uses_mrd};
                 $uses_mrv = $$subnode{uses_mrv};
+                $uses_mlf = $$subnode{uses_mlf};
             }
         } else {
 
@@ -1468,6 +1477,7 @@ sub flatten {
     my @dlist = ();
     my $common = 0;
     # for each dynamic filter, build more of the WHERE clause
+
     for my $filter (@{$self->filters}) {
         my $NOT = $filter->negate ? 'NOT ' : '';
         if (grep { $_ eq $filter->name } @{ $self->QueryParser->dynamic_filters }) {
@@ -1476,6 +1486,17 @@ sub flatten {
             $fname = 'item_lang' if $fname eq 'language'; #XXX filter aliases 
 
             warn "flatten(): processing dynamic filter ". $filter->name ."\n"
+            if ($fname eq 'item_lang')
+            {
+                $where .= "$NOT( " . 'mlf.value @@ ' . "\'" . join('|', @fargs) . '\'::tsquery)';
+                $uses_mlf = 1;
+            } else {
+                $where .= sprintf(
+                    "${NOT}COALESCE((mrd.attrs->'%s') IN (%s), false)", $fname, 
+                    join(',', map { $self->QueryParser->quote_value($_) } @fargs));
+            }
+
+            warn "flatten(): filter where => $where\n"
                 if $self->QueryParser->debug;
 
             my $vlist_query;
@@ -1735,7 +1756,8 @@ sub flatten {
         vis_filter => \%vis_filter,
         uses_bre => $uses_bre,
         uses_mrv => $uses_mrv,
-        uses_mrd => $uses_mrd
+        uses_mrd => $uses_mrd,
+        uses_mlf => $uses_mlf
     };
 }