Using TokyoTyrant as a Model-like TokyoTyrantStorage
Python
2011-06-09 08:37 (14 years ago)

# -*- coding: utf-8 -*- """ Using TokyoTyrant as a Model class Soldier(TokyoTyrantStorage): hp = TokyoTyrantStorage.Field(default=0) mp = TokyoTyrantStorage.Field(default=0) cain = Soldier('Cain') cain.hp = 100 cain.mp = 50 cain.save() abel = Soldier('Abel') abel.hp = 50 abel.mp = 100 abel.save() cain = Soldier('Cain') cain.hp -= 80 cain.save() abel = Soldier('Abel') abel.mp -= 20 abel.save() cain = Soldier('Cain') cain.hp = min(cain.hp + 50, 100) cain.save() cain = Soldier('Cain') cain.hp Out: 70 """ import logging from tokyotyrant import get_client import msgpack class TokyoTyrantStorage(object): """ Base class for using TokyoTyrant as a dictionary Please use it by inheritance """ packer = msgpack.Packer() tt_client = get_client() def __new__(cls, *args, **kwargs): for k, v in vars(cls).items(): if isinstance(v, TokyoTyrantStorage.Field): v.set_field_name(k) return object.__new__(cls) def __init__(self, key_object): """ @param key_object: Django model instance, etc. player or osuser Override and if you don't want to call super's __init__, just call self.after_init(key_part) """ self.key_object = key_object key_part = getattr(key_object, 'pk', str(key_object)) self.after_init(key_part) def after_init(self, key_part): """ Second half of initialization process @param (str)key_part: Unique string used as the base for key generation """ self.kvs_key = '%s::%s' % (self.__class__.__name__, key_part) bulk_storage = self.tt_client.get(self.kvs_key, None) if bulk_storage: self.storage = msgpack.unpackb(bulk_storage) else: self.storage = {} def get(self, k, default=None): return self.storage.get(k,default) def set(self, k, value): self.storage[k] = value def save(self): """ Save storage """ self.tt_client.set(self.kvs_key, self.packer.pack(self.storage)) def delete(self): """ Delete storage """ self.tt_client.out(self.kvs_key) self.storage = {} def dump(self): logging.debug("[TokyoTyrantStorage] dump: kvs_key=%s, storage=%r" % (self.kvs_key, self.storage)) class Field(object): """ Field that can be used in TokyoTyrantStorage Use it like score = TokyoTyrantStorage.Field(default=0). """ def __init__(self, key_name=None, default=None): self._key_name = key_name self.default = default def __get__(self, inst, type=None): assert isinstance(inst, TokyoTyrantStorage), '%s use only TokyoTyrantStorage class.' % self.__class__.__name__ return inst.get(self.key_name, self.default) def __set__(self, inst, value): assert isinstance(inst, TokyoTyrantStorage), '%s use only TokyoTyrantStorage class.' % self.__class__.__name__ inst.set(self.key_name, value) def set_field_name(self, field_name): # Called from TokyoTyrantStorage.__new__ self.field_name = field_name @property def key_name(self): return self._key_name or self.field_name
Please rate this article
Currently unrated
The author runs the application development company Cyberneura.
We look forward to discussing your development needs.
We look forward to discussing your development needs.