]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/src/sql/Pg/upgrade/XXXX.schema.workstation-settings.sql
LP#1750894 Cascade settings batch retrieve func
[working/Evergreen.git] / Open-ILS / src / sql / Pg / upgrade / XXXX.schema.workstation-settings.sql
1 BEGIN;
2
3 -- SELECT evergreen.upgrade_deps_block_check('XXXX', :eg_version);
4
5 CREATE TABLE config.workstation_setting_type (
6     name            TEXT    PRIMARY KEY,
7     label           TEXT    UNIQUE NOT NULL,
8     grp             TEXT    REFERENCES config.settings_group (name),
9     description     TEXT,
10     datatype        TEXT    NOT NULL DEFAULT 'string',
11     fm_class        TEXT,
12     --
13     -- define valid datatypes
14     --
15     CONSTRAINT cwst_valid_datatype CHECK ( datatype IN
16     ( 'bool', 'integer', 'float', 'currency', 'interval',
17       'date', 'string', 'object', 'array', 'link' ) ),
18     --
19     -- fm_class is meaningful only for 'link' datatype
20     --
21     CONSTRAINT cwst_no_empty_link CHECK
22     ( ( datatype =  'link' AND fm_class IS NOT NULL ) OR
23       ( datatype <> 'link' AND fm_class IS NULL ) )
24 );
25
26 CREATE TABLE actor.workstation_setting (
27     id          SERIAL PRIMARY KEY,
28     workstation INT    NOT NULL REFERENCES actor.workstation (id) 
29                        ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
30     name        TEXT   NOT NULL REFERENCES config.workstation_setting_type (name) 
31                        ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
32     value       JSON   NOT NULL
33 );
34
35 CREATE OR REPLACE FUNCTION config.setting_is_user_or_ws()
36 RETURNS TRIGGER AS $FUNC$
37 BEGIN
38
39     IF TG_TABLE_NAME = 'usr_setting_type' THEN
40         PERFORM TRUE FROM config.workstation_setting_type cwst
41             WHERE cwst.name = NEW.name;
42         IF NOT FOUND THEN
43             RETURN NULL;
44         END IF;
45     END IF;
46
47     IF TG_TABLE_NAME = 'workstation_setting_type' THEN
48         PERFORM TRUE FROM config.usr_setting_type cust
49             WHERE cust.name = NEW.name;
50         IF NOT FOUND THEN
51             RETURN NULL;
52         END IF;
53     END IF;
54
55     RAISE EXCEPTION 
56         '% Cannot be used as both a user setting and a workstation setting.', 
57         NEW.name;
58 END;
59 $FUNC$ LANGUAGE PLPGSQL STABLE;
60
61 CREATE CONSTRAINT TRIGGER check_setting_is_usr_or_ws
62   AFTER INSERT OR UPDATE ON config.usr_setting_type
63   FOR EACH ROW EXECUTE PROCEDURE config.setting_is_user_or_ws();
64
65 CREATE CONSTRAINT TRIGGER check_setting_is_usr_or_ws
66   AFTER INSERT OR UPDATE ON config.workstation_setting_type
67   FOR EACH ROW EXECUTE PROCEDURE config.setting_is_user_or_ws();
68
69 CREATE OR REPLACE FUNCTION actor.get_setting(setting_name TEXT, 
70     org_id INT, user_id INT, workstation_id INT) RETURNS JSON AS
71 $FUNC$
72 DECLARE
73     setting_value JSON;
74     org_setting_type config.org_unit_setting_type%ROWTYPE;
75 BEGIN
76
77     -- User and workstation settings have the same priority.
78     -- Start with user settings since that's the simplest code path.
79     IF user_id IS NOT NULL THEN
80         SELECT INTO setting_value value 
81             FROM actor.usr_setting
82             WHERE usr = user_id AND name = setting_name;
83         IF FOUND THEN
84             RETURN setting_value;
85         END IF;
86     END IF;
87
88     -- No user setting value found.  Next try workstation.
89     IF workstation_id IS NOT NULL THEN
90
91         SELECT INTO setting_value value 
92             FROM actor.workstation_setting         
93             WHERE workstation = workstation_id AND name = setting_name;
94
95         IF FOUND THEN
96             RETURN setting_value;
97         END IF;
98
99         -- Workstation setting not found.  However, since we have a
100         -- workstation let's use its owning_lib as our context org unit
101         -- instead of the value provided by 'org_id' which could be NULL.
102         SELECT INTO org_id owning_lib 
103             FROM actor.workstation WHERE id = workstation_id;
104     END IF;
105
106     -- Some org unit settings are protected by a view permission.
107     -- First see if we have any data that needs protecting, then 
108     -- check the permission if needed.
109
110     SELECT INTO setting_value value 
111         FROM actor.org_unit_ancestor_setting(setting_name, org_id);
112
113     IF NOT FOUND THEN
114         -- No value found -- perm check is irrelevant.
115         RETURN NULL;
116     END IF;
117
118     -- Check view permissions if necessary.
119     SELECT INTO org_setting_type * 
120         FROM config.org_unit_setting_type WHERE name = setting_name;
121
122     IF org_setting_type.view_perm IS NOT NULL THEN
123
124         IF user_id IS NULL THEN
125             RAISE NOTICE 'Perm check required but no user_id provided';
126             RETURN NULL;
127         END IF;
128
129         IF NOT permission.usr_has_perm(
130             user_id, (SELECT code FROM permission.perm_list 
131                 WHERE id = org_setting_type.view_perm), org_id) 
132         THEN
133             RAISE NOTICE 'Perm check failed for user % on %',
134                 user_id, org_setting_type.view_perm;
135             RETURN NULL;
136         END IF;
137     END IF;
138
139     -- Perm check succeeded or was not necessary.
140     RETURN setting_value;
141 END;
142 $FUNC$ LANGUAGE PLPGSQL;
143
144
145 CREATE OR REPLACE FUNCTION actor.get_setting_batch(setting_names TEXT[], 
146     org_id INT, user_id INT, workstation_id INT) RETURNS SETOF JSON AS
147 $FUNC$
148 -- Returns a row per setting matching the setting name order.  If no 
149 -- value is applied, NULL is returned to retain name-response ordering.
150 DECLARE
151     setting_name TEXT;
152 BEGIN
153     FOREACH setting_name IN ARRAY setting_names LOOP
154         RETURN NEXT * FROM actor.get_setting(
155             setting_Name, org_id, user_id, workstation_id);
156     END LOOP;
157 END;
158 $FUNC$ LANGUAGE PLPGSQL;
159
160 COMMIT;
161
162
163