Skip to content

Commit

Permalink
Use transactions throughout the write/delete model methods.
Browse files Browse the repository at this point in the history
  • Loading branch information
iamteem committed Jun 8, 2010
1 parent 968857f commit 3382504
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 37 deletions.
5 changes: 4 additions & 1 deletion redisco/containers.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ class Container(object):
``redisco.connection`` module.
"""

def __init__(self, key, db=None):
def __init__(self, key, db=None, pipeline=None):
self._db = db
self.key = key
self.pipeline = pipeline

def clear(self):
"""Remove container from Redis database."""
Expand All @@ -35,6 +36,8 @@ def __getattribute__(self, att):

@property
def db(self):
if self.pipeline:
return self.pipeline
if self._db:
return self._db
if hasattr(self, 'db_cache') and self.db_cache:
Expand Down
70 changes: 35 additions & 35 deletions redisco/models/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,9 +211,11 @@ def key(self, att=None):

def delete(self):
"""Deletes the object from the datastore."""
self._delete_from_indices()
self._delete_membership()
del self.db[self.key()]
pipeline = self.db.pipeline()
self._delete_from_indices(pipeline)
self._delete_membership(pipeline)
pipeline.delete(self.key())
pipeline.execute()

def is_new(self):
"""Returns True if the instance is new.
Expand Down Expand Up @@ -336,8 +338,9 @@ def _write(self, _new=False):
This method also creates the indices and saves the lists
associated to the object.
"""
self._create_membership()
self._update_indices()
pipeline = self.db.pipeline()
self._create_membership(pipeline)
self._update_indices(pipeline)
h = {}
# attributes
for k, v in self.attributes.iteritems():
Expand Down Expand Up @@ -365,55 +368,54 @@ def _write(self, _new=False):
h[index] = unicode(v)
except UnicodeError:
h[index] = unicode(v.decode('utf-8'))
del self.db[self.key()]
pipeline.delete(self.key())
if h:
self.db.hmset(self.key(), h)
pipeline.hmset(self.key(), h)

# lists
for k, v in self.lists.iteritems():
l = List(self.key()[k])
l = List(self.key()[k], pipeline=pipeline)
l.clear()
values = getattr(self, k)
if values:
if v._redisco_model:
l.extend([item.id for item in values])
else:
l.extend(values)
pipeline.execute()

##############
# Membership #
##############

def _create_membership(self):
def _create_membership(self, pipeline=None):
"""Adds the id of the object to the set of all objects of the same
class.
"""
Set(self._key['all']).add(self.id)
Set(self._key['all'], pipeline=pipeline).add(self.id)

def _delete_membership(self):
def _delete_membership(self, pipeline=None):
"""Removes the id of the object to the set of all objects of the
same class.
"""
Set(self._key['all']).remove(self.id)
Set(self._key['all'], pipeline=pipeline).remove(self.id)


############
# INDICES! #
############

def _update_indices(self):
def _update_indices(self, pipeline=None):
"""Updates the indices of the object."""
self._delete_from_indices()
self._add_to_indices()
self._delete_from_indices(pipeline)
self._add_to_indices(pipeline)

def _add_to_indices(self):
def _add_to_indices(self, pipeline):
"""Adds the base64 encoded values of the indices."""
pipe = self.db.pipeline()
for att in self.indices:
self._add_to_index(att, pipe=pipe)
pipe.execute()
self._add_to_index(att, pipeline=pipeline)

def _add_to_index(self, att, val=None, pipe=None):
def _add_to_index(self, att, val=None, pipeline=None):
"""
Adds the id to the index.
Expand All @@ -424,36 +426,34 @@ def _add_to_index(self, att, val=None, pipe=None):
return
t, index = index
if t == 'attribute':
pipe.sadd(index, self.id)
pipe.sadd(self.key()['_indices'], index)
pipeline.sadd(index, self.id)
pipeline.sadd(self.key()['_indices'], index)
elif t == 'list':
for i in index:
pipe.sadd(i, self.id)
pipe.sadd(self.key()['_indices'], i)
pipeline.sadd(i, self.id)
pipeline.sadd(self.key()['_indices'], i)
elif t == 'sortedset':
zindex, index = index
pipe.sadd(index, self.id)
pipe.sadd(self.key()['_indices'], index)
pipeline.sadd(index, self.id)
pipeline.sadd(self.key()['_indices'], index)
descriptor = self.attributes[att]
score = descriptor.typecast_for_storage(getattr(self, att))
pipe.zadd(zindex, self.id, score)
pipe.sadd(self.key()['_zindices'], zindex)
pipeline.zadd(zindex, self.id, score)
pipeline.sadd(self.key()['_zindices'], zindex)


def _delete_from_indices(self):
def _delete_from_indices(self, pipeline):
"""Deletes the object's id from the sets(indices) it has been added
to and removes its list of indices (used for housekeeping).
"""
s = Set(self.key()['_indices'])
z = Set(self.key()['_zindices'])
pipe = s.db.pipeline()
for index in s.members:
pipe.srem(index, self.id)
pipeline.srem(index, self.id)
for index in z.members:
pipe.zrem(index, self.id)
pipe.delete(s.key)
pipe.delete(z.key)
pipe.execute()
pipeline.zrem(index, self.id)
pipeline.delete(s.key)
pipeline.delete(z.key)

def _index_key_for(self, att, value=None):
"""Returns a key based on the attribute and its value.
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env python
import os

version = '0.1.dev20'
version = '0.1.dev21'

try:
from setuptools import setup
Expand Down

0 comments on commit 3382504

Please sign in to comment.