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

Reply via email to