]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/sql/Pg/pgmemcache-ou_tree_traversal_cache.sql
a bit more protection for non-cached values; beware the null depth in the two-param...
[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 permission.mc_init() THEN
61         -- RAISE NOTICE 'Getting perm from cache';
62         EXECUTE $$SELECT memcache_get('oils_orgcache_$$ || org || $$') AS x;$$ INTO cached_value;
63
64         IF cached_value.x IS NOT NULL AND cached_value.x <> '' THEN
65             FOR curr_org IN
66                 SELECT  *
67                   FROM  actor.org_unit
68                   WHERE id IN ( SELECT * FROM explode_array( STRING_TO_ARRAY( cached_value.x, ',' ) ) )
69             LOOP
70                 RETURN NEXT curr_org;
71             END LOOP;
72     
73             RETURN;
74         END IF;
75
76     END IF;
77
78     SELECT * INTO curr_org FROM actor.org_unit WHERE id = org;
79     RETURN NEXT curr_org;
80
81     idlist := ARRAY_APPEND( idlist, curr_org.id );
82
83     FOR kid IN SELECT * FROM actor.org_unit WHERE parent_ou = org LOOP
84         FOR curr_org IN SELECT * FROM actor.noncached_org_unit_descendants(kid.id) LOOP
85             RETURN NEXT curr_org;
86             idlist := ARRAY_APPEND( idlist, curr_org.id );
87         END LOOP;
88     END LOOP;
89
90     IF permission.mc_init() THEN
91         EXECUTE $$
92             SELECT memcache_set(
93                 'oils_orgcache_$$ || org || $$',
94                 $$ || QUOTE_LITERAL(ARRAY_TO_STRING(idlist,',')) || $$,
95                 '10 minutes'::INTERVAL
96             );
97         $$;
98     END IF;
99
100     RETURN;
101 END;
102 $func$ LANGUAGE PLPGSQL;
103
104 COMMIT;
105