Merge branch 'master' into subfolders-8.3
[pyTivo/wmcbrine.git] / Cheetah / CacheStore.py
blobf1a184024c541ab23f787a1a1b90cf537aa5b362
1 """Provides several CacheStore backends for Cheetah's caching framework. The
2 methods provided by these classes have the same semantics as those in the
3 python-memcached API, except for their return values:
5 set(key, val, time=0)
6 set the value unconditionally
7 add(key, val, time=0)
8 set only if the server doesn't already have this key
9 replace(key, val, time=0)
10 set only if the server already have this key
11 get(key, val)
12 returns val or raises a KeyError
13 delete(key)
14 deletes or raises a KeyError
16 """
17 from time import time as currentTime
19 from Cheetah.Utils.memcache import Client as MemcachedClient
21 class Error(Exception):
22 pass
24 class AbstractCacheStore(object):
26 def set(self, key, val, time=None):
27 raise NotImplementedError
29 def add(self, key, val, time=None):
30 raise NotImplementedError
32 def replace(self, key, val, time=None):
33 raise NotImplementedError
35 def delete(self, key):
36 raise NotImplementedError
38 def get(self, key):
39 raise NotImplementedError
41 class MemoryCacheStore(AbstractCacheStore):
42 def __init__(self):
43 self._data = {}
45 def set(self, key, val, time=0):
46 self._data[key] = (val, time)
48 def add(self, key, val, time=0):
49 if self._data.has_key(key):
50 raise Error('a value for key %r is already in the cache'%key)
51 self._data[key] = (val, time)
53 def replace(self, key, val, time=0):
54 if self._data.has_key(key):
55 raise Error('a value for key %r is already in the cache'%key)
56 self._data[key] = (val, time)
58 def delete(self, key):
59 del self._data[key]
61 def get(self, key):
62 (val, exptime) = self._data[key]
63 if exptime and currentTime() > exptime:
64 del self._data[key]
65 raise KeyError(key)
66 else:
67 return val
69 def clear(self):
70 self._data.clear()
72 class MemcachedCacheStore(AbstractCacheStore):
73 servers = ('127.0.0.1:11211')
74 def __init__(self, servers=None, debug=False):
75 if servers is None:
76 servers = self.servers
78 self._client = MemcachedClient(servers, debug)
80 def set(self, key, val, time=0):
81 self._client.set(key, val, time)
83 def add(self, key, val, time=0):
84 res = self._client.add(key, val, time)
85 if not res:
86 raise Error('a value for key %r is already in the cache'%key)
87 self._data[key] = (val, time)
89 def replace(self, key, val, time=0):
90 res = self._client.replace(key, val, time)
91 if not res:
92 raise Error('a value for key %r is already in the cache'%key)
93 self._data[key] = (val, time)
95 def delete(self, key):
96 res = self._client.delete(key, time=0)
97 if not res:
98 raise KeyError(key)
100 def get(self, key):
101 val = self._client.get(key)
102 if val is None:
103 raise KeyError(key)
104 else:
105 return val
107 def clear(self):
108 self._client.flush_all()