An Atop Example that Actually Frikkin' Works and Is Informative



The atop examples in Quotient/examples suck. They mostly only show you how to write into the database; they don't show you how to extract stuff out of it. This example assumes you've at least read Getting Started with Atop and maybe read a few of the crappier examples.




I had a data structure along these lines:




class Thingy:
def __init__(self):
self.bars = []

def addBar(self):
b = Bar(self)
self.bars.append(b)

def getBar(self, i):
return self.bars[i]

class Bar:
def __init__(self, thingy):
self.thingy = thingy

def doIt():
t1 = Thingy()
t1.addBar(); t1.addBar()

t2 = Thingy()
t2.addBar(); t2.addBar(); t2.addBar()

structure = {20000: t1, 20001: t2}

print structure[20000]
print structure[20001]
print structure[20002]

doIt()



Now, how do I convert this 'structure' to atop? After a bunch of fiddling, I came up with this:




from atop import store
from twisted.python import components

class Thingy(store.Item):
number = store.indexed(store.IntIndex)
def __init__(self, st, number):
store.Item.__init__(self, st)
self.bars = []
self.number = number

def addBar(self):
b = Bar(self)
self.bars.append(b.referenceTo())
self.touch()
addBar = store.transacted(addBar)

def getBar(self):
return self.bars[i].getItem()
getBar = store.transacted(getBar)

class Bar(store.Item):
thingy = store.referenced
def __init__(self, thingy):
store.Item.__init__(self, thingy.store)
self.thingy = thingy

class IThingies(components.Interface):
pass

st = store.Store('thingies/db', 'thingies/fs')
def setPool():
if IThingies(st, None) is None:
print "Setting up initial stuff!"
pool = store.Pool(st)
pool.addIndex(store.IntIndex)
st.setComponent(IThingies, pool)
st.transact(setPool)

def doIt():
t1 = Thingy(st, 20000)
t1.addBar(); t1.addBar()

t2 = Thingy(st, 20001)
t2.addBar(); t2.addBar(); t2.addBar()

IThingies(st).addItem(t1)
IThingies(st).addItem(t2)

print IThingies(st).getIndexItem(store.IntIndex, 20000)
print IThingies(st).getIndexItem(store.IntIndex, 20001)
print IThingies(st).getIndexItem(store.IntIndex, 20002)

st.transact(doIt)

st.close()



Several things to note. Firstly, we've turned the dict somewhat inside-out; now, the key is instead an attribute of Thingy (which won't work in all cases, but it does in mine). The pool is basically a big glob of objects: in our case, Thingy instances. The IntIndex that we add to the pool is what gives those objects the form of a dict; we can query the pool via the IntIndex and the particular number to get our Thingy back.




The IThingies interface is just a way to get a "top-level" object (the pool of Thingy instances) out of our store. Some people mumbled some things about using Storeups instead, but this was a lot simpler.