]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/src/sql/Pg/upgrade/1195.function.located_uri_auto_suggest_visibility.sql
LP2045292 Color contrast for AngularJS patron bills
[working/Evergreen.git] / Open-ILS / src / sql / Pg / upgrade / 1195.function.located_uri_auto_suggest_visibility.sql
1 BEGIN;
2
3 SELECT evergreen.upgrade_deps_block_check('1195', :eg_version);
4
5 CREATE OR REPLACE FUNCTION metabib.suggest_browse_entries(raw_query_text text, search_class text, headline_opts text, visibility_org integer, query_limit integer, normalization integer)
6  RETURNS TABLE(value text, field integer, buoyant_and_class_match boolean, field_match boolean, field_weight integer, rank real, buoyant boolean, match text)
7 AS $f$
8 DECLARE
9     prepared_query_texts    TEXT[];
10     query                   TSQUERY;
11     plain_query             TSQUERY;
12     opac_visibility_join    TEXT;
13     search_class_join       TEXT;
14     r_fields                RECORD;
15     b_tests                 TEXT := '';
16 BEGIN
17     prepared_query_texts := metabib.autosuggest_prepare_tsquery(raw_query_text);
18
19     query := TO_TSQUERY('keyword', prepared_query_texts[1]);
20     plain_query := TO_TSQUERY('keyword', prepared_query_texts[2]);
21
22     visibility_org := NULLIF(visibility_org,-1);
23     IF visibility_org IS NOT NULL THEN
24         PERFORM FROM actor.org_unit WHERE id = visibility_org AND parent_ou IS NULL;
25         IF FOUND THEN
26             opac_visibility_join := '';
27         ELSE
28             PERFORM 1 FROM config.internal_flag WHERE enabled AND name = 'opac.located_uri.act_as_copy';
29             IF FOUND THEN
30                 b_tests := search.calculate_visibility_attribute_test(
31                     'luri_org',
32                     (SELECT ARRAY_AGG(id) FROM actor.org_unit_full_path(visibility_org))
33                 );
34             ELSE
35                 b_tests := search.calculate_visibility_attribute_test(
36                     'luri_org',
37                     (SELECT ARRAY_AGG(id) FROM actor.org_unit_ancestors(visibility_org))
38                 );
39             END IF;
40             opac_visibility_join := '
41     LEFT JOIN asset.copy_vis_attr_cache acvac ON (acvac.record = x.source)
42     LEFT JOIN biblio.record_entry b ON (b.id = x.source)
43     JOIN vm ON (acvac.vis_attr_vector @@
44             (vm.c_attrs || $$&$$ ||
45                 search.calculate_visibility_attribute_test(
46                     $$circ_lib$$,
47                     (SELECT ARRAY_AGG(id) FROM actor.org_unit_descendants($4))
48                 )
49             )::query_int
50          ) OR (b.vis_attr_vector @@ $$' || b_tests || '$$::query_int)
51 ';
52         END IF;
53     ELSE
54         opac_visibility_join := '';
55     END IF;
56
57     -- The following determines whether we only provide suggestsons matching
58     -- the user's selected search_class, or whether we show other suggestions
59     -- too. The reason for MIN() is that for search_classes like
60     -- 'title|proper|uniform' you would otherwise get multiple rows.  The
61     -- implication is that if title as a class doesn't have restrict,
62     -- nor does the proper field, but the uniform field does, you're going
63     -- to get 'false' for your overall evaluation of 'should we restrict?'
64     -- To invert that, change from MIN() to MAX().
65
66     SELECT
67         INTO r_fields
68             MIN(cmc.restrict::INT) AS restrict_class,
69             MIN(cmf.restrict::INT) AS restrict_field
70         FROM metabib.search_class_to_registered_components(search_class)
71             AS _registered (field_class TEXT, field INT)
72         JOIN
73             config.metabib_class cmc ON (cmc.name = _registered.field_class)
74         LEFT JOIN
75             config.metabib_field cmf ON (cmf.id = _registered.field);
76
77     -- evaluate 'should we restrict?'
78     IF r_fields.restrict_field::BOOL OR r_fields.restrict_class::BOOL THEN
79         search_class_join := '
80     JOIN
81         metabib.search_class_to_registered_components($2)
82         AS _registered (field_class TEXT, field INT) ON (
83             (_registered.field IS NULL AND
84                 _registered.field_class = cmf.field_class) OR
85             (_registered.field = cmf.id)
86         )
87     ';
88     ELSE
89         search_class_join := '
90     LEFT JOIN
91         metabib.search_class_to_registered_components($2)
92         AS _registered (field_class TEXT, field INT) ON (
93             _registered.field_class = cmc.name
94         )
95     ';
96     END IF;
97
98     RETURN QUERY EXECUTE '
99 WITH vm AS ( SELECT * FROM asset.patron_default_visibility_mask() ),
100      mbe AS (SELECT * FROM metabib.browse_entry WHERE index_vector @@ $1 LIMIT 10000)
101 SELECT  DISTINCT
102         x.value,
103         x.id,
104         x.push,
105         x.restrict,
106         x.weight,
107         x.ts_rank_cd,
108         x.buoyant,
109         TS_HEADLINE(value, $7, $3)
110   FROM  (SELECT DISTINCT
111                 mbe.value,
112                 cmf.id,
113                 cmc.buoyant AND _registered.field_class IS NOT NULL AS push,
114                 _registered.field = cmf.id AS restrict,
115                 cmf.weight,
116                 TS_RANK_CD(mbe.index_vector, $1, $6),
117                 cmc.buoyant,
118                 mbedm.source
119           FROM  metabib.browse_entry_def_map mbedm
120                 JOIN mbe ON (mbe.id = mbedm.entry)
121                 JOIN config.metabib_field cmf ON (cmf.id = mbedm.def)
122                 JOIN config.metabib_class cmc ON (cmf.field_class = cmc.name)
123                 '  || search_class_join || '
124           ORDER BY 3 DESC, 4 DESC NULLS LAST, 5 DESC, 6 DESC, 7 DESC, 1 ASC
125           LIMIT 1000) AS x
126         ' || opac_visibility_join || '
127   ORDER BY 3 DESC, 4 DESC NULLS LAST, 5 DESC, 6 DESC, 7 DESC, 1 ASC
128   LIMIT $5
129 '   -- sic, repeat the order by clause in the outer select too
130     USING
131         query, search_class, headline_opts,
132         visibility_org, query_limit, normalization, plain_query
133         ;
134
135     -- sort order:
136     --  buoyant AND chosen class = match class
137     --  chosen field = match field
138     --  field weight
139     --  rank
140     --  buoyancy
141     --  value itself
142
143 END;
144 $f$ LANGUAGE plpgsql ROWS 10;
145
146 COMMIT;