Hi,
I have a slightly modified use of the infoheritance pattern in an
application I am writing. It seems to be working as I expected, though
its implementation does not follow the normal pattern exactly. I was
wondering if there are any potential errors I missed or performance
issues I might encounter later, or with more advanced test cases, that
someone with experience can see now. Or if your opinion is it's not as
elegant as the normal approach.
A little explanation: the base class here is used as a universal
reference. The application needs to be able to receive reference
information and retrieve the corresponding object from the database,
regardless of its type. You can pretty much ignore the external SHA
stuff; it's just important that each object has a unique SHA-1 hash.
Thanks a bunch for any help,
Jeremy
The output of the simple tests are
Barack: 558a41bb44479236cd60c331f2b5b584bdd0fcec
Ann: 413864193855201046def1b763bdfe74468d8d5f
Found Barack Obama: id=558a41bb44479236cd60c331f2b5b584bdd0fcec
Found Ann Dunham Soetoro: id=413864193855201046def1b763bdfe74468d8d5f
Ann's children: ['Barack Obama']
Barack's parents: ['Ann Dunham Soetoro']
rbarack == rbarack.ref.object? -> True
rbarack is rbarack.ref.object? -> True
rbarack == rbarack2? -> True
rbarack is rbarack2? -> False
rbarack == rbarack3? -> True
rbarack is rbarack3? -> True
which is exactly what I expected. Anything unforeseen?
from storm.locals import (create_database, Store, Int, RawStr,
Reference, ReferenceSet)
from twc.memory.shabase import SHAObject, SHAReference, SHAObjSec
class SQLSHAReference(object):
__storm_table__ = 'sharefs'
hash = RawStr(primary=True)
object_type = RawStr(allow_none=False)
object_types = {}
_object = None
def __init__(self, ref, o=None):
self.hash = ref.hash
if o is not None:
# initialized the reference directly, or from sub-class
self.object_type = o.__class__.object_type
self._object = o
@property
def object(self):
if self._object is not None:
return self._object
assert self.hash is not None
obj_class = self.object_types[self.object_type]
o = Store.of(self).get(obj_class, self.hash)
self._object = o
return o
@classmethod
def register_object_type(cls, object_class):
object_type = object_class.__module__ + '.' + object_class.__name__
object_class.object_type = object_type
cls.object_types[object_type] = object_class
return object_type
def __eq__(self, other):
return self.hash == other.hash
class Person(SHAObject):
def __init__(self, name):
SHAObject.__init__(self)
self.name = name
self.lbd = '01' * 200
def __getstate__(self):
return self.name, self.lbd, SHAObject.__getstate__(self)
def __setstate__(self, args):
self.name, self.lbd, tail = args
SHAObject.__setstate__(self, tail)
class ReferencedSQLSHAObject(object):
hash = RawStr(allow_none=False, primary=True)
ref = Reference(hash, SQLSHAReference.hash)
def __init__(self, ref, o=None):
self.ref = SQLSHAReference(ref, o=o)
def __eq__(self, other):
return self.ref == other.ref
class RPerson(ReferencedSQLSHAObject):
__storm_table__ = 'person'
name = RawStr()
def __init__(self, person):
# initialize the sql reference to point to ourself
super(RPerson, self).__init__(person, self)
# copy attributes
self.name = person.name
@property
def kid_names(self):
for c in self.children:
yield c.name
@property
def parent_names(self):
for p in self.parents:
yield p.name
SQLSHAReference.register_object_type(RPerson)
class RPersonChild(object):
__storm_table__ = 'person_child'
__storm_primary__ = 'parent_id', 'child_id'
parent_id = RawStr()
child_id = RawStr()
RPerson.children = ReferenceSet(RPerson.hash,
RPersonChild.parent_id,
RPersonChild.child_id,
RPerson.hash)
RPerson.parents = ReferenceSet(RPerson.hash,
RPersonChild.child_id,
RPersonChild.parent_id,
RPerson.hash)
def test_references():
# backend stuff - not important to storm code
sec = SHAObjSec()
barack = Person('Barack Obama')
ann = Person('Ann Dunham Soetoro')
sec.hash(barack)
sec.hash(ann)
print "Barack:", barack.hash
print "Ann:", ann.hash
# begin simple storm tests
db = create_database('...')
store = Store(db)
store.execute('DROP TABLE IF EXISTS sharefs, person, person_child')
store.execute(
'CREATE TABLE sharefs'
'(hash BINARY(40) PRIMARY KEY NOT NULL,'
' object_type VARCHAR(100) NOT NULL)'
)
store.execute(
'CREATE TABLE person'
'(hash BINARY(40) PRIMARY KEY NOT NULL,'
' name VARCHAR(100))'
)
store.execute(
'CREATE TABLE person_child'
'(parent_id BINARY(40),'
' child_id BINARY(40),'
' PRIMARY KEY (parent_id, child_id))'
)
# add entries, and set children
store.add(RPerson(barack))
store.add(RPerson(ann))
store.flush()
rbarack = store.get(SQLSHAReference, barack.hash).object
rann = store.get(SQLSHAReference, ann.hash).object
rann.children.add(rbarack)
store.flush()
# print results
print 'Found %s: id=%s' % (rbarack.name, rbarack.hash)
print 'Found %s: id=%s' % (rann.name, rann.hash)
print "Ann's children:", list(rann.kid_names)
print "Barack's parents:", list(rbarack.parent_names)
print "rbarack == rbarack.ref.object? ->", rbarack == rbarack.ref.object
print "rbarack is rbarack.ref.object? ->", rbarack is rbarack.ref.object
rbarack2 = RPerson(rbarack)
print "rbarack == rbarack2? ->", rbarack == rbarack2
print "rbarack is rbarack2? ->", rbarack is rbarack2
rbarack3 = store.get(RPerson, barack.hash)
print "rbarack == rbarack3? ->", rbarack == rbarack3
print "rbarack is rbarack3? ->", rbarack is rbarack3
if __name__ == '__main__':
test_references()
--
storm mailing list
[email protected]
Modify settings or unsubscribe at:
https://lists.ubuntu.com/mailman/listinfo/storm