1. python_mirrors
  2. tracker/django-gae2django

Commits

Andi Albrecht  committed 348b196 Draft

Add memcache API.

  • Participants
  • Parent commits 1d8acfe
  • Branches default

Comments (0)

Files changed (3)

File README

View file
-
 gae2django is a Django helper application that provides an implementation of
 Google's App Engine API based on pure Django. The helper makes it easier to
 re-use applications originally designed for the App Engine environment in a
-pure Django environment. 
+pure Django environment.

File gae2django/gaeapi/appengine/api/memcache.py

View file
+#
+# Copyright 2008 Andi Albrecht <albrecht.andi@gmail.com>
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Implements the URL fetch API.
+
+http://code.google.com/appengine/docs/memcache/
+"""
+
+from django.core.cache import cache
+
+
+class Client(object):
+
+    def set(self, key, value, time=0, min_compress_len=0):
+        cache.set(key, value)
+        return True
+
+    def set_multi(self, mapping, time=0, key_prefix='', min_compress_len=0):
+        [self.set('%s%s' % (key_prefix, key), mapping[key],
+                  time, min_compress_len) for key in mapping]
+        return []
+
+    def get(self, key):
+        return cache.get(key)
+
+    def get_multi(self, keys, key_prefix=''):
+        mapping = {}
+        [mapping.setdefault(key, self.get('%s%s' % (key_prefix, key)))
+         for key in keys
+         if cache.has_key(key)]
+        return mapping
+
+    def delete(self, key, seconds=0):
+        # TODO: Implement locking (seconds keyword).
+        if not cache.has_key(key):
+            return 1
+        cache.delete(key)
+        return 2
+
+    def delete_multi(self, keys, seconds=0, key_prefix=''):
+        succeeded = True
+        for key in keys:
+            if self.delete('%s%s' % (key_prefix, key), seconds) != 2:
+                succeeded = False
+        return succeeded
+
+    def add(self, key, value, time=0, min_compress_len=0):
+        return cache.add(key, value, time or None)
+
+    def replace(self, key, value, time=0, min_compress_len=0):
+        if cache.has_key(key):
+            self.set(key, value, time, min_compress_len)
+            return True
+        return False
+
+    def incr(self, key, delta=1):
+        if cache.has_key(key):
+            try:
+                old = long(cache.get(key))
+                new = old+delta
+                cache.set(key, new)
+                return new
+            except ValueError:
+                return None
+        return None
+
+    def decr(self, key, delta=1):
+        return self.incr(key, delta*-1)
+
+    def flush_all(self):
+        # Django doesn't know all keys in cache. So let's raise an RPC error...
+        return False
+
+    def get_stats(self):
+        # Again, Django doesn't have this information.
+        return {'hits': 0,
+                'misses': 0,
+                'byte_hits': 0,
+                'items': 0,
+                'bytes': 0,
+                'oldest_item_age': 0}
+
+    def set_servers(self, servers):
+        pass
+
+    def disconnect_all(self):
+        pass
+
+    def forget_dead_hosts(self):
+        pass
+
+    def debuglog(self):
+        pass
+
+
+_CLIENT = None
+
+def setup_cache(client_obj):
+    global _CLIENT
+    var_dict = globals()
+  
+    _CLIENT = client_obj
+    var_dict['set_servers'] = _CLIENT.set_servers
+    var_dict['disconnect_all'] = _CLIENT.disconnect_all
+    var_dict['forget_dead_hosts'] = _CLIENT.forget_dead_hosts
+    var_dict['debuglog'] = _CLIENT.debuglog
+    var_dict['get'] = _CLIENT.get
+    var_dict['get_multi'] = _CLIENT.get_multi
+    var_dict['set'] = _CLIENT.set
+    var_dict['set_multi'] = _CLIENT.set_multi
+    var_dict['add'] = _CLIENT.add
+    var_dict['replace'] = _CLIENT.replace
+    var_dict['delete'] = _CLIENT.delete
+    var_dict['delete_multi'] = _CLIENT.delete_multi
+    var_dict['incr'] = _CLIENT.incr
+    var_dict['decr'] = _CLIENT.decr
+    var_dict['flush_all'] = _CLIENT.flush_all
+    var_dict['get_stats'] = _CLIENT.get_stats
+
+setup_cache(Client())

File gae2django/tests/test_memcache.py

View file
+#
+# Copyright 2008 Andi Albrecht <albrecht.andi@gmail.com>
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import unittest
+import types
+
+from gae2django.gaeapi.appengine.api import memcache
+
+
+class MemcacheTest(unittest.TestCase):
+    """Tests memcache API."""
+
+    def test_set_get(self):
+        memcache.set('foo', 'bar')
+        assert memcache.get('foo') == 'bar'
+        assert memcache.get('DOES_NOT_EXIST') == None
+
+    def test_set_multi(self):
+        memcache.set_multi({'multi1': 1, 'multi2': 2})
+        assert memcache.get('multi1') == 1
+        assert memcache.get('multi2') == 2
+        memcache.set_multi({'multi1': 3, 'multi2': 4}, key_prefix='x_')
+        assert memcache.get('multi1') == 1
+        assert memcache.get('multi2') == 2
+        assert memcache.get('x_multi1') == 3
+        assert memcache.get('x_multi2') == 4
+
+    def test_get_multi(self):
+        memcache.delete('DOES_NOT_EXIST')
+        memcache.set('foo', 'bar')
+        memcache.set('bar', 'foo')
+        result = memcache.get_multi(['foo', 'bar', 'DOES_NOT_EXIST'])
+        assert result['foo'] == 'bar'
+        assert result['bar'] == 'foo'
+        assert ('DOES_NOT_EXIST' in result) == False
+        memcache.set('x_foo', 'bar')
+        memcache.set('x_bar', 'foo')
+        result = memcache.get_multi(['foo', 'bar'], key_prefix='x_')
+        assert result['foo'] == 'bar'
+        assert result['bar'] == 'foo'
+
+    def test_delete(self):
+        memcache.set('foo', 'bar')
+        assert memcache.delete('foo') == 2
+        assert memcache.delete('DOES_NOT_EXIST') == 1
+
+    def test_delete_multi(self):
+        memcache.set('foo', 'bar')
+        assert memcache.delete_multi(['foo']) == True
+        memcache.set('foo', 'bar')
+        assert memcache.delete_multi(['foo', 'DOES_NOT_EXIST']) == False
+        assert memcache.get('foo') == None
+
+    def test_add(self):
+        memcache.delete('foo') # make sure it doesn't exist
+        assert memcache.add('foo', 'bar') == True
+        assert memcache.get('foo') == 'bar'
+        assert memcache.add('foo', 'bar2') == False
+        assert memcache.get('foo') == 'bar'
+
+    def test_replace(self):
+        memcache.add('foo', 'bar')
+        assert memcache.replace('foo', 123) == True
+        assert memcache.get('foo') == 123
+        assert memcache.replace('DOES_NOT_EXIST', 123) == False
+
+    def test_incr(self):
+        memcache.set('incr', 1L)
+        assert memcache.incr('incr', 1) == 2L
+        assert memcache.incr('incr', 2) == 4L
+        assert memcache.incr('DOES_NOT_EXIST', 1) == None
+        memcache.set('foo', 'bar')
+        assert memcache.incr('foo', 1) == None
+
+    def test_decr(self):
+        memcache.set('decr', 2)
+        assert memcache.decr('decr', 1) == 1
+        assert memcache.decr('DOES_NOT_EXIST', 1) == None
+
+    def test_flush_all(self):
+        assert memcache.flush_all() == False
+
+    def test_get_stats(self):
+        stats = memcache.get_stats()
+        assert type(stats) == types.DictType
+        assert 'hits' in stats
+        assert 'misses' in stats
+        assert 'byte_hits' in stats
+        assert 'items' in stats
+        assert 'bytes' in stats
+        assert 'oldest_item_age' in stats
+        assert len(stats) == 6
+
+    def test_client(self):
+        client = memcache.Client()
+        assert isinstance(client, memcache.Client)