]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/sql/Pg/pgmemcache-ou_tree_traversal_cache.sql
LP#1917826: add release notes entry
[Evergreen.git] / Open-ILS / src / sql / Pg / pgmemcache-ou_tree_traversal_cache.sql
1 BEGIN;
2
3 /*
4  * Use pgmemcache and memcached to increase the speed of org tree traversal
5  * ------------------------------------------------------------------------
6  *
7  * This set of functions allows the use of memcached as a caching mechanism for
8  * org tree traversal checks.  It is transparent and optional.  If memcache is
9  * not set up, either by not running or the lack of the pgmemcache postgres
10  * addon, then the default, existing behaviour is preserved and live database
11  * queries are used to test all org tree traversals.
12  *
13  * This Evergreen addon extention requires the pgmemcache-perm_cache.sql to be
14  * installed as well.  See that extention script for details on pgmemcache
15  * setup and installation.
16  *
17  * TODO: Make the cache timeout configurable via a global setting for EG 2.0
18  *
19  */
20
21
22 CREATE OR REPLACE FUNCTION actor.org_unit_descendants ( INT, INT ) RETURNS SETOF actor.org_unit AS $$
23     SELECT  *
24       FROM  actor.org_unit_descendants(
25                 CASE WHEN $2 IS NOT NULL THEN
26                     (actor.org_unit_ancestor_at_depth($1,$2)).id
27                 ELSE 
28                     $1
29                 END
30     );
31 $$ LANGUAGE SQL STABLE;
32
33 CREATE OR REPLACE FUNCTION actor.noncached_org_unit_descendants ( org INT ) RETURNS SETOF actor.org_unit AS $$
34 DECLARE
35     kid             actor.org_unit%ROWTYPE;
36     curr_org        actor.org_unit%ROWTYPE;
37 BEGIN
38
39     SELECT * INTO curr_org FROM actor.org_unit WHERE id = org;
40     RETURN NEXT curr_org;
41
42     FOR kid IN SELECT * FROM actor.org_unit WHERE parent_ou = org LOOP
43         FOR curr_org IN SELECT * FROM actor.noncached_org_unit_descendants(kid.id) LOOP
44             RETURN NEXT curr_org;
45         END LOOP;
46     END LOOP;
47
48     RETURN;
49 END;
50 $$ LANGUAGE PLPGSQL;
51
52 CREATE OR REPLACE FUNCTION actor.org_unit_descendants ( org INT ) RETURNS SETOF actor.org_unit AS $func$
53 DECLARE
54     kid             actor.org_unit%ROWTYPE;
55     curr_org        actor.org_unit%ROWTYPE;
56     idlist          INT[] := '{}'::INT[];
57     cached_value    RECORD;
58 BEGIN
59
60     IF org IS NULL THEN
61         RETURN;
62     END IF;
63
64     IF permission.mc_init() THEN
65         -- RAISE NOTICE 'Getting perm from cache';
66         EXECUTE $$SELECT memcache_get('oils_orgcache_$$ || org || $$') AS x;$$ INTO cached_value;
67
68         IF cached_value.x IS NOT NULL AND cached_value.x <> '' THEN
69             FOR curr_org IN
70                 SELECT  *
71                   FROM  actor.org_unit
72                   WHERE id IN ( SELECT * FROM unnest( STRING_TO_ARRAY( cached_value.x, ',' ) ) )
73             LOOP
74                 RETURN NEXT curr_org;
75             END LOOP;
76     
77             RETURN;
78         END IF;
79
80     END IF;
81
82     SELECT * INTO curr_org FROM actor.org_unit WHERE id = org;
83     RETURN NEXT curr_org;
84
85     idlist := ARRAY_APPEND( idlist, curr_org.id );
86
87     FOR kid IN SELECT * FROM actor.org_unit WHERE parent_ou = org LOOP
88         FOR curr_org IN SELECT * FROM actor.noncached_org_unit_descendants(kid.id) LOOP
89             RETURN NEXT curr_org;
90             idlist := ARRAY_APPEND( idlist, curr_org.id );
91         END LOOP;
92     END LOOP;
93
94     IF permission.mc_init() THEN
95         EXECUTE $$
96             SELECT memcache_set(
97                 'oils_orgcache_$$ || org || $$',
98                 $$ || QUOTE_LITERAL(ARRAY_TO_STRING(idlist,',')) || $$,
99                 '10 minutes'::INTERVAL
100             );
101         $$;
102     END IF;
103
104     RETURN;
105 END;
106 $func$ LANGUAGE PLPGSQL;
107
108 COMMIT;
109