]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/sql/Pg/version-upgrade/2.0.8-2.0.9-upgrade-db.sql
LP#1772028 Add some FK violation functions just in case they are missing
[Evergreen.git] / Open-ILS / src / sql / Pg / version-upgrade / 2.0.8-2.0.9-upgrade-db.sql
1 BEGIN;
2
3 INSERT INTO config.upgrade_log (version) VALUES ('2.0.9');
4
5
6 -- Fix LP#825303 by allowing for ancestor OUs to be checked
7 -- when retrieving the default classification scheme.
8 --
9 INSERT INTO config.upgrade_log (version) VALUES ('0600');
10
11 CREATE OR REPLACE FUNCTION asset.label_normalizer() RETURNS TRIGGER AS $func$
12 DECLARE
13     sortkey        TEXT := '';
14 BEGIN
15     sortkey := NEW.label_sortkey;
16
17     IF NEW.label_class IS NULL THEN
18             NEW.label_class := COALESCE(
19             (
20                 SELECT substring(value from E'\\d+')::integer
21                 FROM actor.org_unit_ancestor_setting('cat.default_classification_scheme', NEW.owning_lib)
22             ), 1
23         );
24     END IF;
25
26     EXECUTE 'SELECT ' || acnc.normalizer || '(' || 
27        quote_literal( NEW.label ) || ')'
28        FROM asset.call_number_class acnc
29        WHERE acnc.id = NEW.label_class
30        INTO sortkey;
31     NEW.label_sortkey = sortkey;
32     RETURN NEW;
33 END;
34 $func$ LANGUAGE PLPGSQL;
35
36
37 -- Correct actor.org_unit_ancestor_setting so that it returns
38 -- at most one setting value, rather than the entire set
39 -- of values defined for the OU and its ancestors.
40 --
41 INSERT INTO config.upgrade_log (version) VALUES ('0601');
42
43 CREATE OR REPLACE FUNCTION actor.org_unit_ancestor_setting( setting_name TEXT, org_id INT ) RETURNS SETOF actor.org_unit_setting AS $$
44 DECLARE
45     setting RECORD;
46     cur_org INT;
47 BEGIN
48     cur_org := org_id;
49     LOOP
50         SELECT INTO setting * FROM actor.org_unit_setting WHERE org_unit = cur_org AND name = setting_name;
51         IF FOUND THEN
52             RETURN NEXT setting;
53             EXIT;
54         END IF;
55         SELECT INTO cur_org parent_ou FROM actor.org_unit WHERE id = cur_org;
56         EXIT WHEN cur_org IS NULL;
57     END LOOP;
58     RETURN;
59 END;
60 $$ LANGUAGE plpgsql STABLE ROWS 1;
61
62
63 INSERT INTO config.upgrade_log (version) VALUES ('0602'); -- dbs via miker
64
65 CREATE OR REPLACE FUNCTION asset.opac_lasso_metarecord_copy_count (i_lasso INT, rid BIGINT) RETURNS TABLE (depth INT, org_unit INT, visible BIGINT, available BIGINT, unshadow BIGINT, transcendant INT) AS $f$
66 DECLARE
67     ans RECORD;
68     trans INT;
69 BEGIN
70     SELECT 1 INTO trans FROM biblio.record_entry b JOIN config.bib_source src ON (b.source = src.id) WHERE src.transcendant AND b.id = rid;
71
72     FOR ans IN SELECT u.org_unit AS id FROM actor.org_lasso_map AS u WHERE lasso = i_lasso LOOP
73         RETURN QUERY
74         SELECT  -1,
75                 ans.id,
76                 COUNT( av.id ),
77                 SUM( CASE WHEN cp.status IN (0,7,12) THEN 1 ELSE 0 END ),
78                 COUNT( av.id ),
79                 trans
80           FROM
81                 actor.org_unit_descendants(ans.id) d
82                 JOIN asset.opac_visible_copies av ON (av.record = rid AND av.circ_lib = d.id)
83                 JOIN asset.copy cp ON (cp.id = av.id)
84                 JOIN metabib.metarecord_source_map m ON (m.source = av.record)
85           GROUP BY 1,2,6;
86
87         IF NOT FOUND THEN
88             RETURN QUERY SELECT -1, ans.id, 0::BIGINT, 0::BIGINT, 0::BIGINT, trans;
89         END IF;
90
91     END LOOP;   
92                 
93     RETURN;     
94 END;            
95 $f$ LANGUAGE PLPGSQL;
96
97
98 CREATE OR REPLACE FUNCTION asset.staff_lasso_metarecord_copy_count (i_lasso INT, rid BIGINT) RETURNS TABLE (depth INT, org_unit INT, visible BIGINT, available BIGINT, unshadow BIGINT, transcendant INT) AS $f$
99 DECLARE
100     ans RECORD;
101     trans INT;
102 BEGIN
103     SELECT 1 INTO trans FROM biblio.record_entry b JOIN config.bib_source src ON (b.source = src.id) WHERE src.transcendant AND b.id = rid;
104
105     FOR ans IN SELECT u.org_unit AS id FROM actor.org_lasso_map AS u WHERE lasso = i_lasso LOOP
106         RETURN QUERY
107         SELECT  -1,
108                 ans.id,
109                 COUNT( cp.id ),
110                 SUM( CASE WHEN cp.status IN (0,7,12) THEN 1 ELSE 0 END ),
111                 COUNT( cp.id ),
112                 trans
113           FROM
114                 actor.org_unit_descendants(ans.id) d
115                 JOIN asset.copy cp ON (cp.circ_lib = d.id AND NOT cp.deleted)
116                 JOIN asset.call_number cn ON (cn.record = rid AND cn.id = cp.call_number AND NOT cn.deleted)
117                 JOIN metabib.metarecord_source_map m ON (m.source = cn.record)
118           GROUP BY 1,2,6;
119
120         IF NOT FOUND THEN
121             RETURN QUERY SELECT -1, ans.id, 0::BIGINT, 0::BIGINT, 0::BIGINT, trans;
122         END IF;
123
124     END LOOP;
125
126     RETURN;
127 END;
128 $f$ LANGUAGE PLPGSQL;
129
130 CREATE OR REPLACE FUNCTION asset.opac_lasso_record_copy_count (i_lasso INT, rid BIGINT) RETURNS TABLE (depth INT, org_unit INT, visible BIGINT, available BIGINT, unshadow BIGINT, transcendant INT) AS $f$
131 DECLARE
132     ans RECORD;
133     trans INT;
134 BEGIN
135     SELECT 1 INTO trans FROM biblio.record_entry b JOIN config.bib_source src ON (b.source = src.id) WHERE src.transcendant AND b.id = rid;
136
137     FOR ans IN SELECT u.org_unit AS id FROM actor.org_lasso_map AS u WHERE lasso = i_lasso LOOP
138         RETURN QUERY
139         SELECT  -1,
140                 ans.id,
141                 COUNT( av.id ),
142                 SUM( CASE WHEN cp.status IN (0,7,12) THEN 1 ELSE 0 END ),
143                 COUNT( av.id ),
144                 trans
145           FROM
146                 actor.org_unit_descendants(ans.id) d
147                 JOIN asset.opac_visible_copies av ON (av.record = rid AND av.circ_lib = d.id)
148                 JOIN asset.copy cp ON (cp.id = av.id)
149           GROUP BY 1,2,6;
150
151         IF NOT FOUND THEN
152             RETURN QUERY SELECT -1, ans.id, 0::BIGINT, 0::BIGINT, 0::BIGINT, trans;
153         END IF;
154
155     END LOOP;   
156                 
157     RETURN;     
158 END;            
159 $f$ LANGUAGE PLPGSQL;
160
161 CREATE OR REPLACE FUNCTION asset.staff_lasso_record_copy_count (i_lasso INT, rid BIGINT) RETURNS TABLE (depth INT, org_unit INT, visible BIGINT, available BIGINT, unshadow BIGINT, transcendant INT) AS $f$
162 DECLARE
163     ans RECORD;
164     trans INT;
165 BEGIN
166     SELECT 1 INTO trans FROM biblio.record_entry b JOIN config.bib_source src ON (b.source = src.id) WHERE src.transcendant AND b.id = rid;
167
168     FOR ans IN SELECT u.org_unit AS id FROM actor.org_lasso_map AS u WHERE lasso = i_lasso LOOP
169         RETURN QUERY
170         SELECT  -1,
171                 ans.id,
172                 COUNT( cp.id ),
173                 SUM( CASE WHEN cp.status IN (0,7,12) THEN 1 ELSE 0 END ),
174                 COUNT( cp.id ),
175                 trans
176           FROM
177                 actor.org_unit_descendants(ans.id) d
178                 JOIN asset.copy cp ON (cp.circ_lib = d.id AND NOT cp.deleted)
179                 JOIN asset.call_number cn ON (cn.record = rid AND cn.id = cp.call_number AND NOT cn.deleted)
180           GROUP BY 1,2,6;
181
182         IF NOT FOUND THEN
183             RETURN QUERY SELECT -1, ans.id, 0::BIGINT, 0::BIGINT, 0::BIGINT, trans;
184         END IF;
185
186     END LOOP;
187
188     RETURN;
189 END;
190 $f$ LANGUAGE PLPGSQL;
191
192 -- Correct the fact that actor.org_unit_parent_protect() may not work
193 -- due to 'IF' conditions in PL/pgSQL not necessarily processing in the
194 -- order written
195 --
196 INSERT INTO config.upgrade_log (version) VALUES ('0605'); --dbwells via dbs
197
198 CREATE OR REPLACE FUNCTION actor.org_unit_parent_protect () RETURNS TRIGGER AS $$
199         DECLARE
200                 current_aou actor.org_unit%ROWTYPE;
201                 seen_ous    INT[];
202                 depth_count INT;
203         BEGIN
204                 current_aou := NEW;
205                 depth_count := 0;
206                 seen_ous := ARRAY[NEW.id];
207
208                 IF (TG_OP = 'UPDATE') THEN
209                         IF (NEW.parent_ou IS NOT DISTINCT FROM OLD.parent_ou) THEN
210                                 RETURN NEW; -- Doing an UPDATE with no change, just return it
211                         END IF;
212                 END IF;
213
214                 LOOP
215                         IF current_aou.parent_ou IS NULL THEN -- Top of the org tree?
216                                 RETURN NEW; -- No loop. Carry on.
217                         END IF;
218                         IF current_aou.parent_ou = ANY(seen_ous) THEN -- Parent is one we have seen?
219                                 RAISE 'OU LOOP: Saw % twice', current_aou.parent_ou; -- LOOP! ABORT!
220                         END IF;
221                         -- Get the next one!
222                         SELECT INTO current_aou * FROM actor.org_unit WHERE id = current_aou.parent_ou;
223                         seen_ous := seen_ous || current_aou.id;
224                         depth_count := depth_count + 1;
225                         IF depth_count = 100 THEN
226                                 RAISE 'OU CHECK TOO DEEP';
227                         END IF;
228                 END LOOP;
229
230                 RETURN NEW;
231         END;
232 $$ LANGUAGE PLPGSQL;
233
234
235 INSERT INTO config.upgrade_log (version) VALUES ('0607');
236
237 CREATE OR REPLACE FUNCTION actor.org_unit_ancestors( INT ) RETURNS SETOF actor.org_unit AS $$
238     WITH RECURSIVE org_unit_ancestors_distance(id, distance) AS (
239             SELECT $1, 0
240         UNION
241             SELECT ou.parent_ou, ouad.distance+1
242             FROM actor.org_unit ou JOIN org_unit_ancestors_distance ouad ON (ou.id = ouad.id)
243             WHERE ou.parent_ou IS NOT NULL
244     )
245     SELECT ou.* FROM actor.org_unit ou JOIN org_unit_ancestors_distance ouad USING (id) ORDER BY ouad.distance DESC;
246 $$ LANGUAGE SQL ROWS 1;
247
248 COMMIT;
249