]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/src/sql/Pg/upgrade/XXXX.schema.serial-holding-groups.sql
TPAC: Improvement to serials display (under the "issues held" label)
[working/Evergreen.git] / Open-ILS / src / sql / Pg / upgrade / XXXX.schema.serial-holding-groups.sql
1 BEGIN;
2
3 SELECT evergreen.upgrade_deps_block_check('XXXX', :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 ROWS 1;
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     holding_type TEXT NOT NULL,
74     ind1 TEXT,
75     ind2 TEXT,
76     subfield CHAR,
77     value TEXT
78 );
79
80 CREATE OR REPLACE FUNCTION serial.materialize_holding_code() RETURNS TRIGGER
81 AS $func$ 
82 use strict;
83
84 use MARC::Field;
85 use JSON::XS;
86
87 # Do nothing if holding_code has not changed...
88
89 if ($_TD->{new}{holding_code} eq $_TD->{old}{holding_code}) {
90     # ... unless the following internal flag is set.
91
92     my $flag_rv = spi_exec_query(q{
93         SELECT * FROM config.internal_flag
94         WHERE name = 'serial.rematerialize_on_same_holding_code' AND enabled
95     }, 1);
96     return unless $flag_rv->{processed};
97 }
98
99
100 my $holding_code = (new JSON::XS)->decode($_TD->{new}{holding_code});
101
102 my $field = new MARC::Field('999', @$holding_code); # tag doesnt matter
103
104 my $dstmt = spi_prepare(
105     'DELETE FROM serial.materialized_holding_code WHERE issuance = $1',
106     'INT'
107 );
108 spi_exec_prepared($dstmt, $_TD->{new}{id});
109
110 my $istmt = spi_prepare(
111     q{
112         INSERT INTO serial.materialized_holding_code (
113             issuance, holding_type, ind1, ind2, subfield, value
114         ) VALUES ($1, $2, $3, $4, $5, $6)
115     }, qw{INT TEXT TEXT TEXT CHAR TEXT}
116 );
117
118 foreach ($field->subfields) {
119     spi_exec_prepared(
120         $istmt,
121         $_TD->{new}{id},
122         $_TD->{new}{holding_type},
123         $field->indicator(1),
124         $field->indicator(2),
125         $_->[0],
126         $_->[1]
127     );
128 }
129
130 return;
131
132 $func$ LANGUAGE 'plperlu';
133
134 CREATE INDEX assist_holdings_display
135     ON serial.materialized_holding_code (issuance, subfield);
136
137 CREATE TRIGGER materialize_holding_code
138     AFTER INSERT OR UPDATE ON serial.issuance
139     FOR EACH ROW EXECUTE PROCEDURE serial.materialize_holding_code() ;
140
141 -- starting here, we materialize all existing holding codes.
142
143 UPDATE config.internal_flag
144     SET enabled = TRUE
145     WHERE name = 'serial.rematerialize_on_same_holding_code';
146
147 UPDATE serial.issuance SET holding_code = holding_code;
148
149 UPDATE config.internal_flag
150     SET enabled = FALSE
151     WHERE name = 'serial.rematerialize_on_same_holding_code';
152
153 -- finish holding code materialization process
154
155 COMMIT;