summaryrefslogtreecommitdiff
path: root/memcache.py
diff options
context:
space:
mode:
authorSean Reifschneider <jafo@guin.tummy.com>2009-11-27 21:40:49 -0700
committerSean Reifschneider <jafo@guin.tummy.com>2009-11-27 21:40:49 -0700
commite5ed3a4ffff0eaa456d776e74df6c63995141ed2 (patch)
treebb8e1ac3d2cfd8dce3eede9ee51aa5e6c8d3628e /memcache.py
parentc1f57dc0d6776179be4c67d4a50f56eee80e6408 (diff)
downloadpython-memcached-e5ed3a4ffff0eaa456d776e74df6c63995141ed2.tar.gz
* Adding support for multiple deserialization formats including PHP and
JSON. Patch by Gavin M. Roy. PHP requires http://pypi.python.org/pypi/phpserialize
Diffstat (limited to 'memcache.py')
-rw-r--r--memcache.py63
1 files changed, 59 insertions, 4 deletions
diff --git a/memcache.py b/memcache.py
index 76aae88..5332d91 100644
--- a/memcache.py
+++ b/memcache.py
@@ -76,6 +76,24 @@ try:
except ImportError:
from StringIO import StringIO
+# import JSON library
+try:
+ import json
+ _supports_json = True
+except ImportError:
+ try:
+ import simplejson as json
+ _supports_json = True
+ except ImportError:
+ _supports_json = False
+
+# See if we can deserialize PHP
+try:
+ import phpserialize
+ _supports_phpserialize = True
+except ImportError:
+ _supports_phpserialize = False
+
__author__ = "Evan Martin <martine@danga.com>"
__version__ = "1.31"
@@ -121,11 +139,16 @@ class Client(local):
@sort: __init__, set_servers, forget_dead_hosts, disconnect_all, debuglog,\
set, set_multi, add, replace, get, get_multi, incr, decr, delete, delete_multi
"""
- _FLAG_PICKLE = 1<<0
+ _FLAG_SERIALIZED = 1<<0
_FLAG_INTEGER = 1<<1
_FLAG_LONG = 1<<2
_FLAG_COMPRESSED = 1<<3
+ # Serialization flags
+ _FLAG_PICKLE = 1
+ _FLAG_JSON = 2
+ _FLAG_PHP = 3
+
_SERVER_RETRIES = 10 # how many times to try finding a free server.
# exceptions for Client
@@ -171,6 +194,7 @@ class Client(local):
self.unpickler = unpickler
self.persistent_load = pload
self.persistent_id = pid
+ self.serialization = self._FLAG_PICKLE
# figure out the pickler style
file = StringIO()
@@ -180,6 +204,22 @@ class Client(local):
except TypeError:
self.picklerIsKeyword = False
+ def set_serialization(self, serialization):
+ """
+ Set the serialization format for data sets, one of _FLAG_PICKLE,
+ _FLAG_JSON or _FLAG_PHP
+
+ @param serialization_format: _FLAG_PICKLE,_FLAG_JOSN,FLAG_PHP
+ """
+
+ # If our serialization is set to one of our values, use it
+ if serialization == Client._FLAG_JSON and _supports_json == True:
+ self.serialization = Client._FLAG_JSON
+ elif serialization == Client._FLAG_PHP and _supports_phpserialize == True:
+ self.serialization = Client._FLAG_PHP
+ else:
+ self.serialization = Client._FLAG_PICKLE
+
def set_servers(self, servers):
"""
Set the pool of servers used by this client.
@@ -682,7 +722,7 @@ class Client(local):
# force no attempt to compress this silly string.
min_compress_len = 0
else:
- flags |= Client._FLAG_PICKLE
+ flags |= Client._FLAG_SERIALIZED
file = StringIO()
if self.picklerIsKeyword:
pickler = self.pickler(file, protocol = self.pickleProtocol)
@@ -886,7 +926,6 @@ class Client(local):
if flags & Client._FLAG_COMPRESSED:
buf = decompress(buf)
-
if flags == 0 or flags == Client._FLAG_COMPRESSED:
# Either a bare string or a compressed string now decompressed...
val = buf
@@ -894,8 +933,9 @@ class Client(local):
val = int(buf)
elif flags & Client._FLAG_LONG:
val = long(buf)
- elif flags & Client._FLAG_PICKLE:
+ elif flags & Client._FLAG_SERIALIZED:
try:
+ # try and unpickle
file = StringIO(buf)
unpickler = self.unpickler(file)
if self.persistent_load:
@@ -904,6 +944,21 @@ class Client(local):
except Exception, e:
self.debuglog('Pickle error: %s\n' % e)
val = None
+
+ if val is None and _supports_json:
+ # Try and deserialize via JSON
+ try:
+ val = json.loads(buf)
+ except Exception, e:
+ self.debuglog('Json error: %s\n' % e)
+
+ if val is None and _supports_phpserialize:
+ # Try and deserialize via PHP
+ try:
+ val = phpserialize.loads(buf)
+ except Exception, e:
+ self.debuglog('PHP Deserialization error: %s\n' % e)
+
else:
self.debuglog("unknown flags on get: %x\n" % flags)