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