]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/sql/Pg/upgrade/0568.schema.cache_visibility_speed_boost.sql
LP1779158 Vandelay workstation setting repairs/additions
[Evergreen.git] / Open-ILS / src / sql / Pg / upgrade / 0568.schema.cache_visibility_speed_boost.sql
1 -- Evergreen DB patch 0568.schema.cache_visibility_speed_boost.sql
2 --
3 BEGIN;
4
5
6 -- check whether patch can be applied
7 SELECT evergreen.upgrade_deps_block_check('0568', :eg_version);
8
9 CREATE OR REPLACE FUNCTION asset.cache_copy_visibility () RETURNS TRIGGER as $func$
10 DECLARE
11     add_front       TEXT;
12     add_back        TEXT;
13     add_base_query  TEXT;
14     add_peer_query  TEXT;
15     remove_query    TEXT;
16     do_add          BOOLEAN := false;
17     do_remove       BOOLEAN := false;
18 BEGIN
19     add_base_query := $$
20         SELECT  cp.id, cp.circ_lib, cn.record, cn.id AS call_number, cp.location, cp.status
21           FROM  asset.copy cp
22                 JOIN asset.call_number cn ON (cn.id = cp.call_number)
23                 JOIN actor.org_unit a ON (cp.circ_lib = a.id)
24                 JOIN asset.copy_location cl ON (cp.location = cl.id)
25                 JOIN config.copy_status cs ON (cp.status = cs.id)
26                 JOIN biblio.record_entry b ON (cn.record = b.id)
27           WHERE NOT cp.deleted
28                 AND NOT cn.deleted
29                 AND NOT b.deleted
30                 AND cs.opac_visible
31                 AND cl.opac_visible
32                 AND cp.opac_visible
33                 AND a.opac_visible
34     $$;
35     add_peer_query := $$
36         SELECT  cp.id, cp.circ_lib, pbcm.peer_record AS record, NULL AS call_number, cp.location, cp.status
37           FROM  asset.copy cp
38                 JOIN biblio.peer_bib_copy_map pbcm ON (pbcm.target_copy = cp.id)
39                 JOIN actor.org_unit a ON (cp.circ_lib = a.id)
40                 JOIN asset.copy_location cl ON (cp.location = cl.id)
41                 JOIN config.copy_status cs ON (cp.status = cs.id)
42           WHERE NOT cp.deleted
43                 AND cs.opac_visible
44                 AND cl.opac_visible
45                 AND cp.opac_visible
46                 AND a.opac_visible
47     $$;
48     add_front := $$
49         INSERT INTO asset.opac_visible_copies (copy_id, circ_lib, record)
50           SELECT id, circ_lib, record FROM (
51     $$;
52     add_back := $$
53         ) AS x
54     $$;
55  
56     remove_query := $$ DELETE FROM asset.opac_visible_copies WHERE copy_id IN ( SELECT id FROM asset.copy WHERE $$;
57
58     IF TG_TABLE_NAME = 'peer_bib_copy_map' THEN
59         IF TG_OP = 'INSERT' THEN
60             add_peer_query := add_peer_query || ' AND cp.id = ' || NEW.target_copy || ' AND pbcm.record = ' || NEW.peer_record;
61             EXECUTE add_front || add_peer_query || add_back;
62             RETURN NEW;
63         ELSE
64             remove_query := 'DELETE FROM asset.opac_visible_copies WHERE copy_id = ' || OLD.target_copy || ' AND record = ' || OLD.peer_record || ';';
65             EXECUTE remove_query;
66             RETURN OLD;
67         END IF;
68     END IF;
69
70     IF TG_OP = 'INSERT' THEN
71
72         IF TG_TABLE_NAME IN ('copy', 'unit') THEN
73             add_base_query := add_base_query || ' AND cp.id = ' || NEW.id;
74             EXECUTE add_front || add_base_query || add_back;
75         END IF;
76
77         RETURN NEW;
78
79     END IF;
80
81     -- handle items first, since with circulation activity
82     -- their statuses change frequently
83     IF TG_TABLE_NAME IN ('copy', 'unit') THEN
84
85         IF OLD.location    <> NEW.location OR
86            OLD.call_number <> NEW.call_number OR
87            OLD.status      <> NEW.status OR
88            OLD.circ_lib    <> NEW.circ_lib THEN
89             -- any of these could change visibility, but
90             -- we'll save some queries and not try to calculate
91             -- the change directly
92             do_remove := true;
93             do_add := true;
94         ELSE
95
96             IF OLD.deleted <> NEW.deleted THEN
97                 IF NEW.deleted THEN
98                     do_remove := true;
99                 ELSE
100                     do_add := true;
101                 END IF;
102             END IF;
103
104             IF OLD.opac_visible <> NEW.opac_visible THEN
105                 IF OLD.opac_visible THEN
106                     do_remove := true;
107                 ELSIF NOT do_remove THEN -- handle edge case where deleted item
108                                         -- is also marked opac_visible
109                     do_add := true;
110                 END IF;
111             END IF;
112
113         END IF;
114
115         IF do_remove THEN
116             DELETE FROM asset.opac_visible_copies WHERE copy_id = NEW.id;
117         END IF;
118         IF do_add THEN
119             add_base_query := add_base_query || ' AND cp.id = ' || NEW.id;
120             add_peer_query := add_peer_query || ' AND cp.id = ' || NEW.id;
121             EXECUTE add_front || add_base_query || ' UNION ' || add_peer_query || add_back;
122         END IF;
123
124         RETURN NEW;
125
126     END IF;
127
128     IF TG_TABLE_NAME IN ('call_number', 'record_entry') THEN -- these have a 'deleted' column
129  
130         IF OLD.deleted AND NEW.deleted THEN -- do nothing
131
132             RETURN NEW;
133  
134         ELSIF NEW.deleted THEN -- remove rows
135  
136             IF TG_TABLE_NAME = 'call_number' THEN
137                 DELETE FROM asset.opac_visible_copies WHERE copy_id IN (SELECT id FROM asset.copy WHERE call_number = NEW.id);
138             ELSIF TG_TABLE_NAME = 'record_entry' THEN
139                 DELETE FROM asset.opac_visible_copies WHERE record = NEW.id;
140             END IF;
141  
142             RETURN NEW;
143  
144         ELSIF OLD.deleted THEN -- add rows
145  
146             IF TG_TABLE_NAME = 'call_number' THEN
147                 add_base_query := add_base_query || ' AND cn.id = ' || NEW.id;
148                 EXECUTE add_front || add_base_query || add_back;
149             ELSIF TG_TABLE_NAME = 'record_entry' THEN
150                 add_base_query := add_base_query || ' AND cn.record = ' || NEW.id;
151                 add_peer_query := add_peer_query || ' AND pbcm.record = ' || NEW.id;
152                 EXECUTE add_front || add_base_query || ' UNION ' || add_peer_query || add_back;
153             END IF;
154  
155             RETURN NEW;
156  
157         END IF;
158  
159     END IF;
160
161     IF TG_TABLE_NAME = 'call_number' THEN
162
163         IF OLD.record <> NEW.record THEN
164             -- call number is linked to different bib
165             remove_query := remove_query || 'call_number = ' || NEW.id || ');';
166             EXECUTE remove_query;
167             add_base_query := add_base_query || ' AND cn.id = ' || NEW.id;
168             EXECUTE add_front || add_base_query || add_back;
169         END IF;
170
171         RETURN NEW;
172
173     END IF;
174
175     IF TG_TABLE_NAME IN ('record_entry') THEN
176         RETURN NEW; -- don't have 'opac_visible'
177     END IF;
178
179     -- actor.org_unit, asset.copy_location, asset.copy_status
180     IF NEW.opac_visible = OLD.opac_visible THEN -- do nothing
181
182         RETURN NEW;
183
184     ELSIF NEW.opac_visible THEN -- add rows
185
186         IF TG_TABLE_NAME = 'org_unit' THEN
187             add_base_query := add_base_query || ' AND cp.circ_lib = ' || NEW.id || ';';
188             add_peer_query := add_peer_query || ' AND cp.circ_lib = ' || NEW.id || ';';
189         ELSIF TG_TABLE_NAME = 'copy_location' THEN
190             add_base_query := add_base_query || ' AND cp.location = ' || NEW.id || ';';
191             add_peer_query := add_peer_query || ' AND cp.location = ' || NEW.id || ';';
192         ELSIF TG_TABLE_NAME = 'copy_status' THEN
193             add_base_query := add_base_query || ' AND cp.status = ' || NEW.id || ';';
194             add_peer_query := add_peer_query || ' AND cp.status = ' || NEW.id || ';';
195         END IF;
196  
197         EXECUTE add_front || add_base_query || ' UNION ' || add_peer_query || add_back;
198  
199     ELSE -- delete rows
200
201         IF TG_TABLE_NAME = 'org_unit' THEN
202             remove_query := 'DELETE FROM asset.opac_visible_copies WHERE circ_lib = ' || NEW.id || ';';
203         ELSIF TG_TABLE_NAME = 'copy_location' THEN
204             remove_query := remove_query || 'location = ' || NEW.id || ');';
205         ELSIF TG_TABLE_NAME = 'copy_status' THEN
206             remove_query := remove_query || 'status = ' || NEW.id || ');';
207         END IF;
208  
209         EXECUTE remove_query;
210  
211     END IF;
212  
213     RETURN NEW;
214 END;
215 $func$ LANGUAGE PLPGSQL;
216
217 COMMIT;
218