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