]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/sql/Pg/pgmemcache-ou_tree_traversal_cache.sql
caching extention for org tree traversal
[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  * FROM  actor.org_unit_descendants( (actor.org_unit_ancestor_at_depth($1,$2)).id );
24 $$ LANGUAGE SQL STABLE;
25
26 CREATE OR REPLACE FUNCTION actor.noncached_org_unit_descendants ( org INT ) RETURNS SETOF actor.org_unit AS $$
27 DECLARE
28     kid             actor.org_unit%ROWTYPE;
29     curr_org        actor.org_unit%ROWTYPE;
30 BEGIN
31
32     SELECT * INTO curr_org FROM actor.org_unit WHERE id = org;
33     RETURN NEXT curr_org;
34
35     FOR kid IN SELECT * FROM actor.org_unit WHERE parent_ou = org LOOP
36         FOR curr_org IN SELECT * FROM actor.noncached_org_unit_descendants(kid.id) LOOP
37             RETURN NEXT curr_org;
38         END LOOP;
39     END LOOP;
40
41     RETURN;
42 END;
43 $$ LANGUAGE PLPGSQL;
44
45 CREATE OR REPLACE FUNCTION actor.org_unit_descendants ( org INT ) RETURNS SETOF actor.org_unit AS $func$
46 DECLARE
47     kid             actor.org_unit%ROWTYPE;
48     curr_org        actor.org_unit%ROWTYPE;
49     idlist          INT[] := '{}'::INT[];
50     cached_value    RECORD;
51 BEGIN
52
53     IF permission.mc_init() THEN
54         -- RAISE NOTICE 'Getting perm from cache';
55         EXECUTE $$SELECT memcache_get('oils_orgcache_$$ || org || $$') AS x;$$ INTO cached_value;
56
57         IF cached_value.x IS NOT NULL THEN
58             FOR curr_org IN
59                 SELECT  *
60                   FROM  actor.org_unit
61                   WHERE id IN ( SELECT * FROM explode_array( STRING_TO_ARRAY( cached_value.x, ',' ) ) )
62             LOOP
63                 RETURN NEXT curr_org;
64             END LOOP;
65     
66             RETURN;
67         END IF;
68
69     END IF;
70
71     SELECT * INTO curr_org FROM actor.org_unit WHERE id = org;
72     RETURN NEXT curr_org;
73
74     idlist := ARRAY_APPEND( idlist, curr_org.id );
75
76     FOR kid IN SELECT * FROM actor.org_unit WHERE parent_ou = org LOOP
77         FOR curr_org IN SELECT * FROM actor.noncached_org_unit_descendants(kid.id) LOOP
78             RETURN NEXT curr_org;
79             idlist := ARRAY_APPEND( idlist, curr_org.id );
80         END LOOP;
81     END LOOP;
82
83     IF permission.mc_init() THEN
84         EXECUTE $$
85             SELECT memcache_set(
86                 'oils_orgcache_$$ || org || $$',
87                 $$ || QUOTE_LITERAL(ARRAY_TO_STRING(idlist,',')) || $$,
88                 '10 minutes'::INTERVAL
89             );
90         $$;
91     END IF;
92
93     RETURN;
94 END;
95 $func$ LANGUAGE PLPGSQL;
96
97 COMMIT;
98