]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/sql/Pg/upgrade/0223.schema.staged_search.stored_proc.sql
Merge branch 'master' of git.evergreen-ils.org:Evergreen-DocBook into doc_consolidati...
[Evergreen.git] / Open-ILS / src / sql / Pg / upgrade / 0223.schema.staged_search.stored_proc.sql
1
2 BEGIN;
3
4 INSERT INTO config.upgrade_log (version) VALUES ('0223'); -- miker
5
6 DROP FUNCTION search.query_parser_fts ( INT,INT,TEXT,INT[],INT[],INT,INT,BOOL,BOOL );
7
8 CREATE OR REPLACE FUNCTION search.query_parser_fts (
9
10     param_search_ou INT,
11     param_depth     INT,
12     param_query     TEXT,
13     param_statuses  INT[],
14     param_locations INT[],
15     param_offset    INT,
16     param_check     INT,
17     param_limit     INT,
18     metarecord      BOOL,
19     staff           BOOL
20
21 ) RETURNS SETOF search.search_result AS $func$
22 DECLARE
23
24     current_res         search.search_result%ROWTYPE;
25     search_org_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 BEGIN
43
44     check_limit := COALESCE( param_check, 1000 );
45     core_limit  := COALESCE( param_limit, 25000 );
46     core_offset := COALESCE( param_offset, 0 );
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_accum(distinct id) INTO search_org_list FROM actor.org_unit_descendants( param_search_ou, param_depth );
53         ELSE
54             SELECT array_accum(distinct id) INTO search_org_list FROM actor.org_unit_descendants( param_search_ou );
55         END IF;
56     ELSIF param_search_ou < 0 THEN
57         SELECT array_accum(distinct org_unit) INTO search_org_list FROM actor.org_lasso_map WHERE lasso = -param_search_ou;
58     ELSIF param_search_ou = 0 THEN
59         -- reserved for user lassos (ou_buckets/type='lasso') with ID passed in depth ... hack? sure.
60     END IF;
61
62     OPEN core_cursor FOR EXECUTE param_query;
63
64     LOOP
65
66         FETCH core_cursor INTO core_result;
67         EXIT WHEN NOT FOUND;
68         EXIT WHEN total_count >= core_limit;
69
70         total_count := total_count + 1;
71
72         CONTINUE WHEN total_count NOT BETWEEN  core_offset + 1 AND check_limit + core_offset;
73
74         check_count := check_count + 1;
75
76         PERFORM 1 FROM biblio.record_entry b WHERE NOT b.deleted AND b.id IN ( SELECT * FROM search.explode_array( core_result.records ) );
77         IF NOT FOUND THEN
78             -- RAISE NOTICE ' % were all deleted ... ', core_result.records;
79             deleted_count := deleted_count + 1;
80             CONTINUE;
81         END IF;
82
83         PERFORM 1
84           FROM  biblio.record_entry b
85                 JOIN config.bib_source s ON (b.source = s.id)
86           WHERE s.transcendant
87                 AND b.id IN ( SELECT * FROM search.explode_array( core_result.records ) );
88
89         IF FOUND THEN
90             -- RAISE NOTICE ' % were all transcendant ... ', core_result.records;
91             visible_count := visible_count + 1;
92
93             current_res.id = core_result.id;
94             current_res.rel = core_result.rel;
95
96             tmp_int := 1;
97             IF metarecord THEN
98                 SELECT COUNT(DISTINCT s.source) INTO tmp_int FROM metabib.metarecord_source_map s WHERE s.metarecord = core_result.id;
99             END IF;
100
101             IF tmp_int = 1 THEN
102                 current_res.record = core_result.records[1];
103             ELSE
104                 current_res.record = NULL;
105             END IF;
106
107             RETURN NEXT current_res;
108
109             CONTINUE;
110         END IF;
111
112         PERFORM 1
113           FROM  asset.call_number cn
114                 JOIN asset.uri_call_number_map map ON (map.call_number = cn.id)
115                 JOIN asset.uri uri ON (map.uri = uri.id)
116           WHERE NOT cn.deleted
117                 AND cn.label = '##URI##'
118                 AND uri.active
119                 AND ( param_locations IS NULL OR array_upper(param_locations, 1) IS NULL )
120                 AND cn.record IN ( SELECT * FROM search.explode_array( core_result.records ) )
121                 AND cn.owning_lib IN ( SELECT * FROM search.explode_array( search_org_list ) )
122           LIMIT 1;
123
124         IF FOUND THEN
125             -- RAISE NOTICE ' % have at least one URI ... ', core_result.records;
126             visible_count := visible_count + 1;
127
128             current_res.id = core_result.id;
129             current_res.rel = core_result.rel;
130
131             tmp_int := 1;
132             IF metarecord THEN
133                 SELECT COUNT(DISTINCT s.source) INTO tmp_int FROM metabib.metarecord_source_map s WHERE s.metarecord = core_result.id;
134             END IF;
135
136             IF tmp_int = 1 THEN
137                 current_res.record = core_result.records[1];
138             ELSE
139                 current_res.record = NULL;
140             END IF;
141
142             RETURN NEXT current_res;
143
144             CONTINUE;
145         END IF;
146
147         IF param_statuses IS NOT NULL AND array_upper(param_statuses, 1) > 0 THEN
148
149             PERFORM 1
150               FROM  asset.call_number cn
151                     JOIN asset.copy cp ON (cp.call_number = cn.id)
152               WHERE NOT cn.deleted
153                     AND NOT cp.deleted
154                     AND cp.status IN ( SELECT * FROM search.explode_array( param_statuses ) )
155                     AND cn.record IN ( SELECT * FROM search.explode_array( core_result.records ) )
156                     AND cp.circ_lib IN ( SELECT * FROM search.explode_array( search_org_list ) )
157               LIMIT 1;
158
159             IF NOT FOUND THEN
160                 -- RAISE NOTICE ' % were all status-excluded ... ', core_result.records;
161                 excluded_count := excluded_count + 1;
162                 CONTINUE;
163             END IF;
164
165         END IF;
166
167         IF param_locations IS NOT NULL AND array_upper(param_locations, 1) > 0 THEN
168
169             PERFORM 1
170               FROM  asset.call_number cn
171                     JOIN asset.copy cp ON (cp.call_number = cn.id)
172               WHERE NOT cn.deleted
173                     AND NOT cp.deleted
174                     AND cp.location IN ( SELECT * FROM search.explode_array( param_locations ) )
175                     AND cn.record IN ( SELECT * FROM search.explode_array( core_result.records ) )
176                     AND cp.circ_lib IN ( SELECT * FROM search.explode_array( search_org_list ) )
177               LIMIT 1;
178
179             IF NOT FOUND THEN
180                 -- RAISE NOTICE ' % were all copy_location-excluded ... ', core_result.records;
181                 excluded_count := excluded_count + 1;
182                 CONTINUE;
183             END IF;
184
185         END IF;
186
187         IF staff IS NULL OR NOT staff THEN
188
189             PERFORM 1
190               FROM  asset.call_number cn
191                     JOIN asset.copy cp ON (cp.call_number = cn.id)
192                     JOIN actor.org_unit a ON (cp.circ_lib = a.id)
193                     JOIN asset.copy_location cl ON (cp.location = cl.id)
194                     JOIN config.copy_status cs ON (cp.status = cs.id)
195               WHERE NOT cn.deleted
196                     AND NOT cp.deleted
197                     AND cs.opac_visible
198                     AND cl.opac_visible
199                     AND cp.opac_visible
200                     AND a.opac_visible
201                     AND cp.circ_lib IN ( SELECT * FROM search.explode_array( search_org_list ) )
202                     AND cn.record IN ( SELECT * FROM search.explode_array( core_result.records ) )
203               LIMIT 1;
204
205             IF NOT FOUND THEN
206                 -- RAISE NOTICE ' % were all visibility-excluded ... ', core_result.records;
207                 excluded_count := excluded_count + 1;
208                 CONTINUE;
209             END IF;
210
211         ELSE
212
213             PERFORM 1
214               FROM  asset.call_number cn
215                     JOIN asset.copy cp ON (cp.call_number = cn.id)
216                     JOIN actor.org_unit a ON (cp.circ_lib = a.id)
217                     JOIN asset.copy_location cl ON (cp.location = cl.id)
218               WHERE NOT cn.deleted
219                     AND NOT cp.deleted
220                     AND cp.circ_lib IN ( SELECT * FROM search.explode_array( search_org_list ) )
221                     AND cn.record IN ( SELECT * FROM search.explode_array( core_result.records ) )
222               LIMIT 1;
223
224             IF NOT FOUND THEN
225
226                 PERFORM 1
227                   FROM  asset.call_number cn
228                   WHERE cn.record IN ( SELECT * FROM search.explode_array( core_result.records ) )
229                   LIMIT 1;
230
231                 IF FOUND THEN
232                     -- RAISE NOTICE ' % were all visibility-excluded ... ', core_result.records;
233                     excluded_count := excluded_count + 1;
234                     CONTINUE;
235                 END IF;
236
237             END IF;
238
239         END IF;
240
241         visible_count := visible_count + 1;
242
243         current_res.id = core_result.id;
244         current_res.rel = core_result.rel;
245
246         tmp_int := 1;
247         IF metarecord THEN
248             SELECT COUNT(DISTINCT s.source) INTO tmp_int FROM metabib.metarecord_source_map s WHERE s.metarecord = core_result.id;
249         END IF;
250
251         IF tmp_int = 1 THEN
252             current_res.record = core_result.records[1];
253         ELSE
254             current_res.record = NULL;
255         END IF;
256
257         RETURN NEXT current_res;
258
259         IF visible_count % 1000 = 0 THEN
260             -- RAISE NOTICE ' % visible so far ... ', visible_count;
261         END IF;
262
263     END LOOP;
264
265     current_res.id = NULL;
266     current_res.rel = NULL;
267     current_res.record = NULL;
268     current_res.total = total_count;
269     current_res.checked = check_count;
270     current_res.deleted = deleted_count;
271     current_res.visible = visible_count;
272     current_res.excluded = excluded_count;
273
274     CLOSE core_cursor;
275
276     RETURN NEXT current_res;
277
278 END;
279 $func$ LANGUAGE PLPGSQL;
280
281 COMMIT;
282