Skip to content

Instantly share code, notes, and snippets.

@zvoase
Created November 30, 2008 01:22
Show Gist options
  • Save zvoase/30356 to your computer and use it in GitHub Desktop.
Save zvoase/30356 to your computer and use it in GitHub Desktop.
try:
import cPickle as pickle
except ImportError:
import pickle
from couchdb import client
from django.conf import settings
from django.contrib.sessions.backends.base import SessionBase
class SessionStore(SessionBase):
"""A CouchDB-based session store."""
def __init__(self, session_key=None):
# This implies two new settings; COUCHDB_URI and COUCHDB_SESSION_DB.
# The first is mandatory, the second optional.
self.server = client.Server(getattr(settings, 'COUCHDB_URI'))
self.database = self.server[getattr(settings, 'COUCHDB_SESSION_DB',
'django_sessions')]
self._doc_cache = {}
super(SessionStore, self).__init__(session_key)
def load(self):
# If we already have a cached version, then check that it's the right
# revision (to avoid conflicts).
if self._doc_cache:
cache_rev = self._doc_cache.rev
doc_rev = self._get_server_rev()
# In the case that it's the correct version, unpickle the data and
# return it.
if cache_rev >= doc_rev:
session_data = {}
for key, value in self._doc_cache.items():
if key in ['_rev', '_id']:
continue
session_data[key] = pickle.loads(value)
return session_data
# Otherwise, if we have an older version, update the current version
# and run this method again.
elif self.session_key:
self._doc_cache = self.database[self.session_key]
return self.load()
# If all else fails, make a new session.
else:
self.create()
self._doc_cache = {}
return self.load()
def create(self):
# The unique session key is automatically generated by the database.
self.session_key = self.database.create({})
self.save()
def save(self):
session_data = self._get_session(no_load=False)
doc_data = {}
for key, value in session_data.items():
if key in ['_rev', '_id']:
continue
doc_data[key] = pickle.dumps(value)
self.database[self.session_key] = doc_data
def exists(self, session_key):
return session_key in self.database
def delete(self, session_key=None):
if not session_key and not self.session_key:
return
session_key = session_key or self.session_key
self.database.delete(self.database[session_key])
def _get_server_rev(self):
map_fun = '''
function (doc) {
emit(doc._rev, null);
}'''
return list(db.query(map_fun, key=self.session_key))[0].value
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment