Django

Code

Changeset 6572

Show
Ignore:
Timestamp:
10/20/07 10:16:34 (11 months ago)
Author:
mtredinnick
Message:

Fixed #4831 -- Added an "add" cache key method, for parity with memcached's
API. This works for all cache backends. Patch from Matt McClanahan?.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/trunk/django/core/cache/backends/base.py

    r5171 r6572  
    1414            timeout = 300 
    1515        self.default_timeout = timeout 
     16 
     17    def add(self, key, value, timeout=None): 
     18        """ 
     19        Set a value in the cache if the key does not already exist.  If 
     20        timeout is given, that timeout will be used for the key; otherwise 
     21        the default cache timeout will be used. 
     22        """ 
     23        raise NotImplementedError 
    1624 
    1725    def get(self, key, default=None): 
  • django/trunk/django/core/cache/backends/db.py

    r4265 r6572  
    2525            self._cull_frequency = 3 
    2626 
     27    def add(self, key, value, timeout=None): 
     28        return self._base_set('add', key, value, timeout) 
     29 
    2730    def get(self, key, default=None): 
    2831        cursor = connection.cursor() 
     
    3942 
    4043    def set(self, key, value, timeout=None): 
     44        return self._base_set('set', key, value, timeout) 
     45 
     46    def _base_set(self, mode, key, value, timeout=None): 
    4147        if timeout is None: 
    4248            timeout = self.default_timeout 
     
    5157        cursor.execute("SELECT cache_key FROM %s WHERE cache_key = %%s" % self._table, [key]) 
    5258        try: 
    53             if cursor.fetchone(): 
     59            if mode == 'set' and cursor.fetchone(): 
    5460                cursor.execute("UPDATE %s SET value = %%s, expires = %%s WHERE cache_key = %%s" % self._table, [encoded, str(exp), key]) 
    5561            else: 
    56                 cursor.execute("INSERT INTO %s (cache_key, value, expires) VALUES (%%s, %%s, %%s)" % self._table, [key, encoded, str(exp)]) 
     62                if mode == 'add': 
     63                    cursor.execute("INSERT INTO %s (cache_key, value, expires) VALUES (%%s, %%s, %%s)" % self._table, [key, encoded, str(exp)]) 
    5764        except DatabaseError: 
    5865            # To be threadsafe, updates/inserts are allowed to fail silently 
  • django/trunk/django/core/cache/backends/dummy.py

    r4308 r6572  
    55class CacheClass(BaseCache): 
    66    def __init__(self, *args, **kwargs): 
     7        pass 
     8 
     9    def add(self, *args, **kwargs): 
    710        pass 
    811 
  • django/trunk/django/core/cache/backends/filebased.py

    r5718 r6572  
    1717        del self._cache 
    1818        del self._expire_info 
     19 
     20    def add(self, key, value, timeout=None): 
     21        fname = self._key_to_file(key) 
     22        if timeout is None: 
     23            timeout = self.default_timeout 
     24        try: 
     25            filelist = os.listdir(self._dir) 
     26        except (IOError, OSError): 
     27            self._createdir() 
     28            filelist = [] 
     29        if len(filelist) > self._max_entries: 
     30            self._cull(filelist) 
     31        if os.path.basename(fname) not in filelist: 
     32            try: 
     33                f = open(fname, 'wb') 
     34                now = time.time() 
     35                pickle.dump(now + timeout, f, 2) 
     36                pickle.dump(value, f, 2) 
     37            except (IOError, OSError): 
     38                pass 
    1939 
    2040    def get(self, key, default=None): 
  • django/trunk/django/core/cache/backends/locmem.py

    r5704 r6572  
    1414        SimpleCacheClass.__init__(self, host, params) 
    1515        self._lock = RWLock() 
     16 
     17    def add(self, key, value, timeout=None): 
     18        self._lock.writer_enters() 
     19        try: 
     20            SimpleCacheClass.add(self, key, value, timeout) 
     21        finally: 
     22            self._lock.writer_leaves() 
    1623 
    1724    def get(self, key, default=None): 
  • django/trunk/django/core/cache/backends/memcached.py

    r5718 r6572  
    1616        BaseCache.__init__(self, params) 
    1717        self._cache = memcache.Client(server.split(';')) 
     18 
     19    def add(self, key, value, timeout=0): 
     20        self._cache.add(key.encode('ascii', 'ignore'), value, timeout or self.default_timeout) 
    1821 
    1922    def get(self, key, default=None): 
  • django/trunk/django/core/cache/backends/simple.py

    r5091 r6572  
    2121        except (ValueError, TypeError): 
    2222            self._cull_frequency = 3 
     23 
     24    def add(self, key, value, timeout=None): 
     25        if len(self._cache) >= self._max_entries: 
     26            self._cull() 
     27        if timeout is None: 
     28            timeout = self.default_timeout 
     29        if key not in self._cache.keys(): 
     30            self._cache[key] = value 
     31            self._expire_info[key] = time.time() + timeout 
    2332 
    2433    def get(self, key, default=None): 
  • django/trunk/docs/cache.txt

    r6308 r6572  
    327327    'has expired' 
    328328 
     329To add a key only if it doesn't already exist, there is an add() method.  It 
     330takes the same parameters as set(), but will not attempt to update the cache 
     331if the key specified is already present:: 
     332 
     333    >>> cache.set('add_key', 'Initial value') 
     334    >>> cache.add('add_key', 'New value') 
     335    >>> cache.get('add_key') 
     336    'Initial value' 
     337 
    329338There's also a get_many() interface that only hits the cache once. get_many() 
    330339returns a dictionary with all the keys you asked for that actually exist in the 
  • django/trunk/tests/regressiontests/cache/tests.py

    r5876 r6572  
    1919        cache.set("key", "value") 
    2020        self.assertEqual(cache.get("key"), "value") 
     21 
     22    def test_add(self): 
     23        # test add (only add if key isn't already in cache) 
     24        cache.add("addkey1", "value") 
     25        cache.add("addkey1", "newvalue") 
     26        self.assertEqual(cache.get("addkey1"), "value") 
    2127 
    2228    def test_non_existent(self):