]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/sql/Pg/upgrade/0882.function.staff-uri-visibility.sql
LP#1917826: tweaks to data update
[Evergreen.git] / Open-ILS / src / sql / Pg / upgrade / 0882.function.staff-uri-visibility.sql
1 BEGIN;
2
3 SELECT evergreen.upgrade_deps_block_check('0882', :eg_version);
4
5 CREATE OR REPLACE FUNCTION search.query_parser_fts (
6
7     param_search_ou INT,
8     param_depth     INT,
9     param_query     TEXT,
10     param_statuses  INT[],
11     param_locations INT[],
12     param_offset    INT,
13     param_check     INT,
14     param_limit     INT,
15     metarecord      BOOL,
16     staff           BOOL,
17     deleted_search  BOOL,
18     param_pref_ou   INT DEFAULT NULL
19 ) RETURNS SETOF search.search_result AS $func$
20 DECLARE
21
22     current_res         search.search_result%ROWTYPE;
23     search_org_list     INT[];
24     luri_org_list       INT[];
25     tmp_int_list        INT[];
26
27     check_limit         INT;
28     core_limit          INT;
29     core_offset         INT;
30     tmp_int             INT;
31
32     core_result         RECORD;
33     core_cursor         REFCURSOR;
34     core_rel_query      TEXT;
35
36     total_count         INT := 0;
37     check_count         INT := 0;
38     deleted_count       INT := 0;
39     visible_count       INT := 0;
40     excluded_count      INT := 0;
41
42     luri_as_copy        BOOL;
43 BEGIN
44
45     check_limit := COALESCE( param_check, 1000 );
46     core_limit  := COALESCE( param_limit, 25000 );
47     core_offset := COALESCE( param_offset, 0 );
48
49     SELECT COALESCE( enabled, FALSE ) INTO luri_as_copy FROM config.global_flag WHERE name = 'opac.located_uri.act_as_copy';
50
51     -- core_skip_chk := COALESCE( param_skip_chk, 1 );
52
53     IF param_search_ou > 0 THEN
54         IF param_depth IS NOT NULL THEN
55             SELECT ARRAY_AGG(distinct id) INTO search_org_list FROM actor.org_unit_descendants( param_search_ou, param_depth );
56         ELSE
57             SELECT ARRAY_AGG(distinct id) INTO search_org_list FROM actor.org_unit_descendants( param_search_ou );
58         END IF;
59
60         IF luri_as_copy THEN
61             SELECT ARRAY_AGG(distinct id) INTO luri_org_list FROM actor.org_unit_full_path( param_search_ou );
62         ELSE
63             SELECT ARRAY_AGG(distinct id) INTO luri_org_list FROM actor.org_unit_ancestors( param_search_ou );
64         END IF;
65
66     ELSIF param_search_ou < 0 THEN
67         SELECT ARRAY_AGG(distinct org_unit) INTO search_org_list FROM actor.org_lasso_map WHERE lasso = -param_search_ou;
68
69         FOR tmp_int IN SELECT * FROM UNNEST(search_org_list) LOOP
70
71             IF luri_as_copy THEN
72                 SELECT ARRAY_AGG(distinct id) INTO tmp_int_list FROM actor.org_unit_full_path( tmp_int );
73             ELSE
74                 SELECT ARRAY_AGG(distinct id) INTO tmp_int_list FROM actor.org_unit_ancestors( tmp_int );
75             END IF;
76
77             luri_org_list := luri_org_list || tmp_int_list;
78         END LOOP;
79
80         SELECT ARRAY_AGG(DISTINCT x.id) INTO luri_org_list FROM UNNEST(luri_org_list) x(id);
81
82     ELSIF param_search_ou = 0 THEN
83         -- reserved for user lassos (ou_buckets/type='lasso') with ID passed in depth ... hack? sure.
84     END IF;
85
86     IF param_pref_ou IS NOT NULL THEN
87             IF luri_as_copy THEN
88                 SELECT ARRAY_AGG(distinct id) INTO tmp_int_list FROM actor.org_unit_full_path( param_pref_ou );
89             ELSE
90                 SELECT ARRAY_AGG(distinct id) INTO tmp_int_list FROM actor.org_unit_ancestors( param_pref_ou );
91             END IF;
92
93         luri_org_list := luri_org_list || tmp_int_list;
94     END IF;
95
96     OPEN core_cursor FOR EXECUTE param_query;
97
98     LOOP
99
100         FETCH core_cursor INTO core_result;
101         EXIT WHEN NOT FOUND;
102         EXIT WHEN total_count >= core_limit;
103
104         total_count := total_count + 1;
105
106         CONTINUE WHEN total_count NOT BETWEEN  core_offset + 1 AND check_limit + core_offset;
107
108         check_count := check_count + 1;
109
110         IF NOT deleted_search THEN
111
112             PERFORM 1 FROM biblio.record_entry b WHERE NOT b.deleted AND b.id IN ( SELECT * FROM unnest( core_result.records ) );
113             IF NOT FOUND THEN
114                 -- RAISE NOTICE ' % were all deleted ... ', core_result.records;
115                 deleted_count := deleted_count + 1;
116                 CONTINUE;
117             END IF;
118
119             PERFORM 1
120               FROM  biblio.record_entry b
121                     JOIN config.bib_source s ON (b.source = s.id)
122               WHERE s.transcendant
123                     AND b.id IN ( SELECT * FROM unnest( core_result.records ) );
124
125             IF FOUND THEN
126                 -- RAISE NOTICE ' % were all transcendant ... ', core_result.records;
127                 visible_count := visible_count + 1;
128
129                 current_res.id = core_result.id;
130                 current_res.rel = core_result.rel;
131
132                 tmp_int := 1;
133                 IF metarecord THEN
134                     SELECT COUNT(DISTINCT s.source) INTO tmp_int FROM metabib.metarecord_source_map s WHERE s.metarecord = core_result.id;
135                 END IF;
136
137                 IF tmp_int = 1 THEN
138                     current_res.record = core_result.records[1];
139                 ELSE
140                     current_res.record = NULL;
141                 END IF;
142
143                 RETURN NEXT current_res;
144
145                 CONTINUE;
146             END IF;
147
148             PERFORM 1
149               FROM  asset.call_number cn
150                     JOIN asset.uri_call_number_map map ON (map.call_number = cn.id)
151                     JOIN asset.uri uri ON (map.uri = uri.id)
152               WHERE NOT cn.deleted
153                     AND cn.label = '##URI##'
154                     AND uri.active
155                     AND ( param_locations IS NULL OR array_upper(param_locations, 1) IS NULL )
156                     AND cn.record IN ( SELECT * FROM unnest( core_result.records ) )
157                     AND cn.owning_lib IN ( SELECT * FROM unnest( luri_org_list ) )
158               LIMIT 1;
159
160             IF FOUND THEN
161                 -- RAISE NOTICE ' % have at least one URI ... ', core_result.records;
162                 visible_count := visible_count + 1;
163
164                 current_res.id = core_result.id;
165                 current_res.rel = core_result.rel;
166
167                 tmp_int := 1;
168                 IF metarecord THEN
169                     SELECT COUNT(DISTINCT s.source) INTO tmp_int FROM metabib.metarecord_source_map s WHERE s.metarecord = core_result.id;
170                 END IF;
171
172                 IF tmp_int = 1 THEN
173                     current_res.record = core_result.records[1];
174                 ELSE
175                     current_res.record = NULL;
176                 END IF;
177
178                 RETURN NEXT current_res;
179
180                 CONTINUE;
181             END IF;
182
183             IF param_statuses IS NOT NULL AND array_upper(param_statuses, 1) > 0 THEN
184
185                 PERFORM 1
186                   FROM  asset.call_number cn
187                         JOIN asset.copy cp ON (cp.call_number = cn.id)
188                   WHERE NOT cn.deleted
189                         AND NOT cp.deleted
190                         AND cp.status IN ( SELECT * FROM unnest( param_statuses ) )
191                         AND cn.record IN ( SELECT * FROM unnest( core_result.records ) )
192                         AND cp.circ_lib IN ( SELECT * FROM unnest( search_org_list ) )
193                   LIMIT 1;
194
195                 IF NOT FOUND THEN
196                     PERFORM 1
197                       FROM  biblio.peer_bib_copy_map pr
198                             JOIN asset.copy cp ON (cp.id = pr.target_copy)
199                       WHERE NOT cp.deleted
200                             AND cp.status IN ( SELECT * FROM unnest( param_statuses ) )
201                             AND pr.peer_record IN ( SELECT * FROM unnest( core_result.records ) )
202                             AND cp.circ_lib IN ( SELECT * FROM unnest( search_org_list ) )
203                       LIMIT 1;
204
205                     IF NOT FOUND THEN
206                     -- RAISE NOTICE ' % and multi-home linked records were all status-excluded ... ', core_result.records;
207                         excluded_count := excluded_count + 1;
208                         CONTINUE;
209                     END IF;
210                 END IF;
211
212             END IF;
213
214             IF param_locations IS NOT NULL AND array_upper(param_locations, 1) > 0 THEN
215
216                 PERFORM 1
217                   FROM  asset.call_number cn
218                         JOIN asset.copy cp ON (cp.call_number = cn.id)
219                   WHERE NOT cn.deleted
220                         AND NOT cp.deleted
221                         AND cp.location IN ( SELECT * FROM unnest( param_locations ) )
222                         AND cn.record IN ( SELECT * FROM unnest( core_result.records ) )
223                         AND cp.circ_lib IN ( SELECT * FROM unnest( search_org_list ) )
224                   LIMIT 1;
225
226                 IF NOT FOUND THEN
227                     PERFORM 1
228                       FROM  biblio.peer_bib_copy_map pr
229                             JOIN asset.copy cp ON (cp.id = pr.target_copy)
230                       WHERE NOT cp.deleted
231                             AND cp.location IN ( SELECT * FROM unnest( param_locations ) )
232                             AND pr.peer_record IN ( SELECT * FROM unnest( core_result.records ) )
233                             AND cp.circ_lib IN ( SELECT * FROM unnest( search_org_list ) )
234                       LIMIT 1;
235
236                     IF NOT FOUND THEN
237                         -- RAISE NOTICE ' % and multi-home linked records were all copy_location-excluded ... ', core_result.records;
238                         excluded_count := excluded_count + 1;
239                         CONTINUE;
240                     END IF;
241                 END IF;
242
243             END IF;
244
245             IF staff IS NULL OR NOT staff THEN
246
247                 PERFORM 1
248                   FROM  asset.opac_visible_copies
249                   WHERE circ_lib IN ( SELECT * FROM unnest( search_org_list ) )
250                         AND record IN ( SELECT * FROM unnest( core_result.records ) )
251                   LIMIT 1;
252
253                 IF NOT FOUND THEN
254                     PERFORM 1
255                       FROM  biblio.peer_bib_copy_map pr
256                             JOIN asset.opac_visible_copies cp ON (cp.copy_id = pr.target_copy)
257                       WHERE cp.circ_lib IN ( SELECT * FROM unnest( search_org_list ) )
258                             AND pr.peer_record IN ( SELECT * FROM unnest( core_result.records ) )
259                       LIMIT 1;
260
261                     IF NOT FOUND THEN
262
263                         -- RAISE NOTICE ' % and multi-home linked records were all visibility-excluded ... ', core_result.records;
264                         excluded_count := excluded_count + 1;
265                         CONTINUE;
266                     END IF;
267                 END IF;
268
269             ELSE
270
271                 PERFORM 1
272                   FROM  asset.call_number cn
273                         JOIN asset.copy cp ON (cp.call_number = cn.id)
274                   WHERE NOT cn.deleted
275                         AND NOT cp.deleted
276                         AND cp.circ_lib IN ( SELECT * FROM unnest( search_org_list ) )
277                         AND cn.record IN ( SELECT * FROM unnest( core_result.records ) )
278                   LIMIT 1;
279
280                 IF NOT FOUND THEN
281
282                     PERFORM 1
283                       FROM  biblio.peer_bib_copy_map pr
284                             JOIN asset.copy cp ON (cp.id = pr.target_copy)
285                       WHERE NOT cp.deleted
286                             AND cp.circ_lib IN ( SELECT * FROM unnest( search_org_list ) )
287                             AND pr.peer_record IN ( SELECT * FROM unnest( core_result.records ) )
288                       LIMIT 1;
289
290                     IF NOT FOUND THEN
291
292                         PERFORM 1
293                           FROM  asset.call_number cn
294                                 JOIN asset.copy cp ON (cp.call_number = cn.id)
295                           WHERE cn.record IN ( SELECT * FROM unnest( core_result.records ) )
296                                 AND NOT cp.deleted
297                           LIMIT 1;
298
299                         IF NOT FOUND THEN
300                             -- Recheck Located URI visibility in the case of no "foreign" copies
301                             PERFORM 1
302                               FROM  asset.call_number cn
303                                     JOIN asset.uri_call_number_map map ON (map.call_number = cn.id)
304                                     JOIN asset.uri uri ON (map.uri = uri.id)
305                               WHERE NOT cn.deleted
306                                     AND cn.label = '##URI##'
307                                     AND uri.active
308                                     AND cn.record IN ( SELECT * FROM unnest( core_result.records ) )
309                                     AND cn.owning_lib NOT IN ( SELECT * FROM unnest( luri_org_list ) )
310                               LIMIT 1;
311
312                             IF FOUND THEN
313                                 -- RAISE NOTICE ' % were excluded for foreign located URIs... ', core_result.records;
314                                 excluded_count := excluded_count + 1;
315                                 CONTINUE;
316                             END IF;
317                         ELSE
318                             -- RAISE NOTICE ' % and multi-home linked records were all visibility-excluded ... ', core_result.records;
319                             excluded_count := excluded_count + 1;
320                             CONTINUE;
321                         END IF;
322                     END IF;
323
324                 END IF;
325
326             END IF;
327
328         END IF;
329
330         visible_count := visible_count + 1;
331
332         current_res.id = core_result.id;
333         current_res.rel = core_result.rel;
334
335         tmp_int := 1;
336         IF metarecord THEN
337             SELECT COUNT(DISTINCT s.source) INTO tmp_int FROM metabib.metarecord_source_map s WHERE s.metarecord = core_result.id;
338         END IF;
339
340         IF tmp_int = 1 THEN
341             current_res.record = core_result.records[1];
342         ELSE
343             current_res.record = NULL;
344         END IF;
345
346         RETURN NEXT current_res;
347
348         IF visible_count % 1000 = 0 THEN
349             -- RAISE NOTICE ' % visible so far ... ', visible_count;
350         END IF;
351
352     END LOOP;
353
354     current_res.id = NULL;
355     current_res.rel = NULL;
356     current_res.record = NULL;
357     current_res.total = total_count;
358     current_res.checked = check_count;
359     current_res.deleted = deleted_count;
360     current_res.visible = visible_count;
361     current_res.excluded = excluded_count;
362
363     CLOSE core_cursor;
364
365     RETURN NEXT current_res;
366
367 END;
368 $func$ LANGUAGE PLPGSQL;
369
370 COMMIT;