Last active
December 31, 2015 01:49
-
-
Save proteneer/7916922 to your computer and use it in GitHub Desktop.
python redis hash+set wrapper
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import redis | |
rc = redis.Redis(port=6782) | |
rc.flushdb() | |
class HashSet(object): | |
_rc = None | |
_rmaps = [] | |
@classmethod | |
def set_redis(cls,rc): | |
cls._rc = rc | |
@classmethod | |
def exists(cls,id): | |
return cls._rc.sismember(cls._prefix+'s',id) | |
@classmethod | |
def create(cls,id): | |
if cls.exists(id): | |
raise KeyError(id,'already exists') | |
cls._rc.sadd(cls._prefix+'s',id) | |
@classmethod | |
def delete(cls,id): | |
if not cls.exists(id): | |
raise KeyError('key not found') | |
cls._rc.srem(cls._prefix+'s',id) | |
# cleanup rmap first | |
for field in cls._rmaps: | |
rmap_index = cls._rc.hget(cls._prefix+':'+id, field) | |
cls._rc.delete(field+':'+rmap_index+':'+cls._prefix) | |
cls._rc.delete(cls._prefix+':'+id) | |
@classmethod | |
def instance(cls,id): | |
return cls(id) | |
@classmethod | |
def rmap(cls,field,id): | |
if not field in cls._fields: | |
raise KeyError('invalid field') | |
return cls._rc.get(field+':'+id+':'+cls._prefix) | |
def hincrby(self, attr, count=1): | |
if not attr in self.__class__._fields: | |
raise KeyError('invalid field') | |
if not self.__class__._fields[attr] is int: | |
raise TypeError('can only increment ints') | |
return self.__class__._rc.hincrby(self.__class__._prefix+':'+self._id,attr,count) | |
def __init__(self,id): | |
if not self.__class__.exists(id): | |
raise KeyError(id,'has not been created yet') | |
self.__dict__['_id'] = id | |
def __getattr__(self, attr): | |
if not attr in self._fields: | |
raise KeyError('invalid field') | |
# get value then type cast | |
return self.__class__._fields[attr](self.__class__._rc.hget(self.__class__._prefix+':'+self._id, attr)) | |
def __setattr__(self, attr, value): | |
if not attr in self._fields: | |
raise KeyError('invalid field') | |
if not isinstance(value,self._fields[attr]): | |
raise TypeError('expected',self.__class__._fields[attr],'got',type(value)) | |
if attr in self.__class__._rmaps: | |
self.__class__._rc.set(attr+':'+value+':'+self.__class__._prefix,self._id) | |
self.__class__._rc.hset(self.__class__._prefix+':'+self._id, attr, value) | |
class StreamHS(HashSet): | |
_prefix = 'stream' | |
_fields = {'frames' : int, | |
'status' : str, | |
'error_count' : int, | |
'system_hash' : str, | |
'integrator_hash' : str, | |
'download_token' : str, | |
'cc_id' : str, | |
'steps_per_frame' : int | |
} | |
_rmaps = ['download_token'] | |
# Usage example | |
StreamHS.set_redis(rc) | |
stream_id = '5lk2j345' | |
StreamHS.create(stream_id) | |
s = StreamHS.instance(stream_id) | |
s.frames = 5 | |
s.status = 'OK' | |
s.download_token = 'bnzl2l3n1' | |
StreamHS.rmap('download_token','bnzl2l3n1') # returns 5lk2j345 | |
StreamHS.delete(stream_id) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment