]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/sql/Pg/upgrade/0796.schema.vandelay_bucket_match.sql
LP#1772955: Only include xacts with balance in summary
[Evergreen.git] / Open-ILS / src / sql / Pg / upgrade / 0796.schema.vandelay_bucket_match.sql
1 BEGIN;
2
3 INSERT INTO config.upgrade_log (version, applied_to) VALUES ('0796', :eg_version); -- berick/dbwells
4
5 ALTER TABLE vandelay.bib_queue ADD COLUMN match_bucket
6    INTEGER REFERENCES container.biblio_record_entry_bucket(id)
7    ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED;  
8
9 CREATE OR REPLACE FUNCTION vandelay.match_bib_record() RETURNS TRIGGER AS $func$
10 DECLARE
11     incoming_existing_id    TEXT;
12     test_result             vandelay.match_set_test_result%ROWTYPE;
13     tmp_rec                 BIGINT;
14     match_set               INT;
15     match_bucket            INT;
16 BEGIN
17     IF TG_OP IN ('INSERT','UPDATE') AND NEW.imported_as IS NOT NULL THEN
18         RETURN NEW;
19     END IF;
20
21     DELETE FROM vandelay.bib_match WHERE queued_record = NEW.id;
22
23     SELECT q.match_set INTO match_set FROM vandelay.bib_queue q WHERE q.id = NEW.queue;
24
25     IF match_set IS NOT NULL THEN
26         NEW.quality := vandelay.measure_record_quality( NEW.marc, match_set );
27     END IF;
28
29     -- Perfect matches on 901$c exit early with a match with high quality.
30     incoming_existing_id :=
31         oils_xpath_string('//*[@tag="901"]/*[@code="c"][1]', NEW.marc);
32
33     IF incoming_existing_id IS NOT NULL AND incoming_existing_id != '' THEN
34         SELECT id INTO tmp_rec FROM biblio.record_entry WHERE id = incoming_existing_id::bigint;
35         IF tmp_rec IS NOT NULL THEN
36             INSERT INTO vandelay.bib_match (queued_record, eg_record, match_score, quality) 
37                 SELECT
38                     NEW.id, 
39                     b.id,
40                     9999,
41                     -- note: no match_set means quality==0
42                     vandelay.measure_record_quality( b.marc, match_set )
43                 FROM biblio.record_entry b
44                 WHERE id = incoming_existing_id::bigint;
45         END IF;
46     END IF;
47
48     IF match_set IS NULL THEN
49         RETURN NEW;
50     END IF;
51
52     SELECT q.match_bucket INTO match_bucket FROM vandelay.bib_queue q WHERE q.id = NEW.queue;
53
54     FOR test_result IN SELECT * FROM
55         vandelay.match_set_test_marcxml(match_set, NEW.marc, match_bucket) LOOP
56
57         INSERT INTO vandelay.bib_match ( queued_record, eg_record, match_score, quality )
58             SELECT  
59                 NEW.id,
60                 test_result.record,
61                 test_result.quality,
62                 vandelay.measure_record_quality( b.marc, match_set )
63                 FROM  biblio.record_entry b
64                 WHERE id = test_result.record;
65
66     END LOOP;
67
68     RETURN NEW;
69 END;
70 $func$ LANGUAGE PLPGSQL;
71
72
73 DROP FUNCTION IF EXISTS vandelay.match_set_test_marcxml(INTEGER, TEXT);
74
75 CREATE OR REPLACE FUNCTION vandelay.match_set_test_marcxml(
76     match_set_id INTEGER, record_xml TEXT, bucket_id INTEGER 
77 ) RETURNS SETOF vandelay.match_set_test_result AS $$
78 DECLARE
79     tags_rstore HSTORE;
80     svf_rstore  HSTORE;
81     coal        TEXT;
82     joins       TEXT;
83     query_      TEXT;
84     wq          TEXT;
85     qvalue      INTEGER;
86     rec         RECORD;
87 BEGIN
88     tags_rstore := vandelay.flatten_marc_hstore(record_xml);
89     svf_rstore := vandelay.extract_rec_attrs(record_xml);
90
91     CREATE TEMPORARY TABLE _vandelay_tmp_qrows (q INTEGER);
92     CREATE TEMPORARY TABLE _vandelay_tmp_jrows (j TEXT);
93
94     -- generate the where clause and return that directly (into wq), and as
95     -- a side-effect, populate the _vandelay_tmp_[qj]rows tables.
96     wq := vandelay.get_expr_from_match_set(match_set_id, tags_rstore);
97
98     query_ := 'SELECT DISTINCT(record), ';
99
100     -- qrows table is for the quality bits we add to the SELECT clause
101     SELECT ARRAY_TO_STRING(
102         ARRAY_ACCUM('COALESCE(n' || q::TEXT || '.quality, 0)'), ' + '
103     ) INTO coal FROM _vandelay_tmp_qrows;
104
105     -- our query string so far is the SELECT clause and the inital FROM.
106     -- no JOINs yet nor the WHERE clause
107     query_ := query_ || coal || ' AS quality ' || E'\n';
108
109     -- jrows table is for the joins we must make (and the real text conditions)
110     SELECT ARRAY_TO_STRING(ARRAY_ACCUM(j), E'\n') INTO joins
111         FROM _vandelay_tmp_jrows;
112
113     -- add those joins and the where clause to our query.
114     query_ := query_ || joins || E'\n';
115
116     -- join the record bucket
117     IF bucket_id IS NOT NULL THEN
118         query_ := query_ || 'JOIN container.biblio_record_entry_bucket_item ' ||
119             'brebi ON (brebi.target_biblio_record_entry = record ' ||
120             'AND brebi.bucket = ' || bucket_id || E')\n';
121     END IF;
122
123     query_ := query_ || 'JOIN biblio.record_entry bre ON (bre.id = record) ' || 'WHERE ' || wq || ' AND not bre.deleted';
124
125     -- this will return rows of record,quality
126     FOR rec IN EXECUTE query_ USING tags_rstore, svf_rstore LOOP
127         RETURN NEXT rec;
128     END LOOP;
129
130     DROP TABLE _vandelay_tmp_qrows;
131     DROP TABLE _vandelay_tmp_jrows;
132     RETURN;
133 END;
134 $$ LANGUAGE PLPGSQL;
135
136 COMMIT;