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