]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/src/sql/Pg/upgrade/0700.schema.serial-holding-groups.sql
LP#1758426: Disable triggers before recalculating bib visibility in 1085
[working/Evergreen.git] / Open-ILS / src / sql / Pg / upgrade / 0700.schema.serial-holding-groups.sql
1 BEGIN;
2
3 SELECT evergreen.upgrade_deps_block_check('0700', :eg_version);
4
5 INSERT INTO config.internal_flag (name, value, enabled) VALUES (
6     'serial.rematerialize_on_same_holding_code', NULL, FALSE
7 );
8
9 INSERT INTO config.org_unit_setting_type (
10     name, label, grp, description, datatype
11 ) VALUES (
12     'serial.default_display_grouping',
13     'Default display grouping for serials distributions presented in the OPAC.',
14     'serial',
15     'Default display grouping for serials distributions presented in the OPAC. This can be "enum" or "chron".',
16     'string'
17 );
18
19 ALTER TABLE serial.distribution
20     ADD COLUMN display_grouping TEXT NOT NULL DEFAULT 'chron'
21         CHECK (display_grouping IN ('enum', 'chron'));
22
23 -- why didn't we just make one summary table in the first place?
24 CREATE VIEW serial.any_summary AS
25     SELECT
26         'basic' AS summary_type, id, distribution,
27         generated_coverage, textual_holdings, show_generated
28     FROM serial.basic_summary
29     UNION
30     SELECT
31         'index' AS summary_type, id, distribution,
32         generated_coverage, textual_holdings, show_generated
33     FROM serial.index_summary
34     UNION
35     SELECT
36         'supplement' AS summary_type, id, distribution,
37         generated_coverage, textual_holdings, show_generated
38     FROM serial.supplement_summary ;
39
40
41 -- Given the IDs of two rows in actor.org_unit, *the second being an ancestor
42 -- of the first*, return in array form the path from the ancestor to the
43 -- descendant, with each point in the path being an org_unit ID.  This is
44 -- useful for sorting org_units by their position in a depth-first (display
45 -- order) representation of the tree.
46 --
47 -- This breaks with the precedent set by actor.org_unit_full_path() and others,
48 -- and gets the parameters "backwards," but otherwise this function would
49 -- not be very usable within json_query.
50 CREATE OR REPLACE FUNCTION actor.org_unit_simple_path(INT, INT)
51 RETURNS INT[] AS $$
52     WITH RECURSIVE descendant_depth(id, path) AS (
53         SELECT  aou.id,
54                 ARRAY[aou.id]
55           FROM  actor.org_unit aou
56                 JOIN actor.org_unit_type aout ON (aout.id = aou.ou_type)
57           WHERE aou.id = $2
58             UNION ALL
59         SELECT  aou.id,
60                 dd.path || ARRAY[aou.id]
61           FROM  actor.org_unit aou
62                 JOIN actor.org_unit_type aout ON (aout.id = aou.ou_type)
63                 JOIN descendant_depth dd ON (dd.id = aou.parent_ou)
64     ) SELECT dd.path
65         FROM actor.org_unit aou
66         JOIN descendant_depth dd USING (id)
67         WHERE aou.id = $1 ORDER BY dd.path;
68 $$ LANGUAGE SQL STABLE;
69
70 CREATE TABLE serial.materialized_holding_code (
71     id BIGSERIAL PRIMARY KEY,
72     issuance INTEGER NOT NULL REFERENCES serial.issuance (id) ON DELETE CASCADE,
73     subfield CHAR,
74     value TEXT
75 );
76
77 CREATE OR REPLACE FUNCTION serial.materialize_holding_code() RETURNS TRIGGER
78 AS $func$ 
79 use strict;
80
81 use MARC::Field;
82 use JSON::XS;
83
84 # Do nothing if holding_code has not changed...
85
86 if ($_TD->{new}{holding_code} eq $_TD->{old}{holding_code}) {
87     # ... unless the following internal flag is set.
88
89     my $flag_rv = spi_exec_query(q{
90         SELECT * FROM config.internal_flag
91         WHERE name = 'serial.rematerialize_on_same_holding_code' AND enabled
92     }, 1);
93     return unless $flag_rv->{processed};
94 }
95
96
97 my $holding_code = (new JSON::XS)->decode($_TD->{new}{holding_code});
98
99 my $field = new MARC::Field('999', @$holding_code); # tag doesnt matter
100
101 my $dstmt = spi_prepare(
102     'DELETE FROM serial.materialized_holding_code WHERE issuance = $1',
103     'INT'
104 );
105 spi_exec_prepared($dstmt, $_TD->{new}{id});
106
107 my $istmt = spi_prepare(
108     q{
109         INSERT INTO serial.materialized_holding_code (
110             issuance, subfield, value
111         ) VALUES ($1, $2, $3)
112     }, qw{INT CHAR TEXT}
113 );
114
115 foreach ($field->subfields) {
116     spi_exec_prepared(
117         $istmt,
118         $_TD->{new}{id},
119         $_->[0],
120         $_->[1]
121     );
122 }
123
124 return;
125
126 $func$ LANGUAGE 'plperlu';
127
128 CREATE INDEX assist_holdings_display
129     ON serial.materialized_holding_code (issuance, subfield);
130
131 CREATE TRIGGER materialize_holding_code
132     AFTER INSERT OR UPDATE ON serial.issuance
133     FOR EACH ROW EXECUTE PROCEDURE serial.materialize_holding_code() ;
134
135 -- starting here, we materialize all existing holding codes.
136
137 UPDATE config.internal_flag
138     SET enabled = TRUE
139     WHERE name = 'serial.rematerialize_on_same_holding_code';
140
141 UPDATE serial.issuance SET holding_code = holding_code;
142
143 UPDATE config.internal_flag
144     SET enabled = FALSE
145     WHERE name = 'serial.rematerialize_on_same_holding_code';
146
147 -- finish holding code materialization process
148
149 -- fix up missing holding_code fields from serial.issuance
150 UPDATE serial.issuance siss
151     SET holding_type = scap.type
152     FROM serial.caption_and_pattern scap
153     WHERE scap.id = siss.caption_and_pattern AND siss.holding_type IS NULL;
154
155 COMMIT;