Ticket #324: lastupdated.py

File lastupdated.py, 2.4 kB (added by exarkun, 3 years ago)

Contents of deadbeefbabe paste

Line 
1 from axiom import attributes, item, store
2 from epsilon.extime import Time
3
4 class MyAxiomLastUpdatedAttribute(attributes.timestamp):
5     def __init__(self, **kw):
6         super(MyAxiomLastUpdatedAttribute, self).__init__(**kw)
7         if kw.has_key('default'):
8             self.default = self.infilter(kw['default'], None)
9      
10 class ItemWithTriggersMixin(object):
11     triggers = []
12     def __init__(self, **kw):
13         super(ItemWithTriggersMixin, self).__init__(**kw)
14         for triggerSql in self.getTriggers():
15             self.store.createSQL(triggerSql)
16      
17 class ItemWithAutoLastUpdatedStampMixin(ItemWithTriggersMixin):       
18     def getTriggers(self):
19 #        I use strftime("%%s","now") * %(MICRO)d but it has a resolution of 1 second
20 #        as opposed to extime whose resolution is microseconds.
21         return [
22             """
23             CREATE TRIGGER update_%(table)s_lastUpdated UPDATE OF %(othercols)s ON %(table)s
24             BEGIN
25                 UPDATE %(table)s SET %(lucol)s = strftime("%%s","now") * %(MICRO)d WHERE oid = OLD.oid;
26             END;
27             """ % dict(
28                 table     = self.getTableName(),
29                 lucol     = self.__class__.lastUpdated.columnName,
30                 othercols = ",".join(v.columnName for k,v in self.getSchema() if k != "lastUpdated"),
31                 MICRO     = attributes.MICRO
32             )
33         ]
34        
35 class Foo(ItemWithAutoLastUpdatedStampMixin, item.Item):
36     typeName = 'Foo'
37    
38     title = attributes.text()
39     dob = attributes.timestamp()
40     lastUpdated = MyAxiomLastUpdatedAttribute(default=Time())
41    
42     def __repr__(self):
43         return '<Foo title="%s" lastUpdated="%s" schemaVersion="%d" />' % (self.title, self.lastUpdated, self.schemaVersion)
44
45 if __name__ == "__main__":
46     import time
47     s = store.Store(debug=False)
48     Foo(store=s, title=u"Foo:Bar")
49    
50     print "BEFORE: ", s.findFirst(Foo)
51     print "SLEEPING..."
52     time.sleep(5)
53    
54     i = s.findFirst(Foo)
55     i.title = u"F O O  :  B A R !"
56    
57 #    The lastUpdated value has been updated in SQLite, but Axiom won't know
58 #    about it until you uncache the affected record.
59 #    I suppose that unless there is a way for sqlite to alert axiom of underlying changes
60 #    this sqltrigger method is not very practical. In this respect it may be related
61 #    to ticket:450
62     s.objectCache.uncache(i.storeID, i)
63    
64     print "AFTER: ", s.findFirst(Foo)
jethro@divmod.org