Contact: fumanchu@aminus.org

Log in as guest/dejavu to create tickets

I think I've seen this ORM somewhere before...

root/trunk/dejavu/views.py

Revision 601 (checked in by fumanchu, 3 years ago)

Removed a couple stray imports.

  • Property svn:eol-style set to native
Line 
1 """OLAP Views and Snapshots (materialized views).
2
3 Notice in particular that Snapshot and View are _temporary_ Units.
4 Even when you memorize them, they won't be persistent unless you set
5 each instance's Expiration to None.
6 """
7
8 import datetime
9 import dejavu
10 from dejavu import errors, recur
11
12
13 class TemporaryUnit(dejavu.Unit):
14    
15     Expiration = dejavu.UnitProperty(datetime.datetime)
16    
17     def on_recall(self):
18         if self.Expiration is not None:
19             if self.Expiration <= datetime.datetime.now():
20                 self.forget()
21                 raise errors.UnrecallableError
22             else:
23                 self.decay(minutes=15)
24    
25     def decay(self, **kw):
26         """decay(**kw) -> Set Expiration to now() + timedelta(**kw)."""
27         self.Expiration = datetime.datetime.now() + datetime.timedelta(**kw)
28
29
30 class TemporarySweeper(recur.Worker):
31     """A worker to sweep out expired TemporaryUnit's."""
32    
33     def work(self):
34         """Start a cycle of scheduled work."""
35         now = datetime.datetime.now()
36         f = lambda x: x.Expiration != None and x.Expiration <= now
37         box = self.store.new_sandbox()
38        
39         for cls in self.store.classes:
40             if issubclass(cls, TemporaryUnit):
41                 # Running box.recall will call TemporaryUnit.on_recall,
42                 # which should forget expired units.
43                 box.recall(cls, f)
44         box.flush_all()
45
46
47 class View(TemporaryUnit):
48     """A selector from (possibly multiple and/or aggregated) relations.
49     
50     When a View is called, it returns a Snapshot.
51     """
52    
53     Name = dejavu.UnitProperty()
54     Created = dejavu.UnitProperty(datetime.datetime)
55    
56     # The following are equivalent to:
57     # "SELECT Attributes FROM Relation WHERE Restriction"
58     Query = dejavu.UnitProperty(dejavu.Query)
59    
60     def __init__(self, Query=None, Created=None, **kwargs):
61         if Created is None:
62             Created = datetime.datetime.today()
63         if not isinstance(Query, dejavu.Query):
64             Query = dejavu.Query(*Query)
65         TemporaryUnit.__init__(self, Query=Query, Created=Created, **kwargs)
66    
67     def on_forget(self):
68         # Snapshots shouldn't persist past the life of their View.
69         for mv in self.Snapshot():
70             mv.forget()
71    
72     def __call__(self, name, store=None):
73         """Execute self and return a Snapshot."""
74         if store is None:
75             store = self.sandbox.store
76         newcls = store.insert_into(name, self.Query)
77         snap = Snapshot(ViewID=self.ID, ResultName=name)
78         snap.decay(minutes=15)
79         return snap
80     results = __call__
81    
82     def __copy__(self):
83         view = TemporaryUnit.__copy__(self)
84         view.Name = "Copy of %s" % self.Name
85         view.Created = datetime.datetime.now()
86         return view
87
88
89 class Snapshot(TemporaryUnit):
90     """A materialized view; the result set obtained by calling a View.
91     
92     Each Snapshot Unit instance possesses its own additional, dynamic
93     unit class which contains the actual result data. The 'ResultName'
94     attribute of the Snapshot must match the class name of the actual
95     result data.
96     """
97    
98     ViewID = dejavu.UnitProperty(int, index=True)
99     Timestamp = dejavu.UnitProperty(datetime.datetime)
100     ResultName = dejavu.UnitProperty()
101    
102     def __init__(self, Timestamp=None, **kwargs):
103         if Timestamp is None:
104             Timestamp = datetime.datetime.now()
105         TemporaryUnit.__init__(self, Timestamp=Timestamp, **kwargs)
106    
107     def unitclass(self, store=None):
108         if store is None:
109             store = self.sandbox.store
110         try:
111             return store.class_by_name(self.ResultName)
112         except KeyError:
113             newclass = store.make_class(self.ResultName)
114             store.register(newclass)
115             return newclass
116
117
118 View.one_to_many('ID', Snapshot, 'ViewID')
119
120
121 def register_classes(store):
122     store.register(View)
123     store.register(Snapshot)
124
Note: See TracBrowser for help on using the browser.