Contact: fumanchu@aminus.org

Log in as guest/dejavu to create tickets

root/branches/crazycache/dejavu/__init__.py

Revision 560 (checked in by fumanchu, 1 year ago)

New dejavu.Statement class for use with Units which map to DB Views. These should possess a 'view_statement' attribute. Currently only DB stores support this. It also needs tests.

  • Property svn:eol-style set to native
Line 
1 """Dejavu is an Object-Relational Mapper.
2
3 Persisted objects are called "Units", and are served into Sandboxes bound
4 to a StorageManager. Each Unit instance has a class, which maintains its
5 schema via Unit Properties.
6
7 "Dejavu", to quote Flying Circus episode 16, means "that strange feeling
8 we sometimes get that we've lived through something before." What better
9 name for a persistence system? Our terminology reflects this cognitive bent:
10 sandboxes "memorize", "recall" and "forget" Units.
11
12 Most Unit lifecycles follow the same pattern:
13     aUnit = sandbox.unit(cls, ID=ID)
14     val = aUnit.propertyName
15     aUnit.propertyName = newValue
16     del aUnit # or otherwise release the reference, e.g. close the scope.
17
18 When creating new Units, a similar pattern would be:
19     newUnit = unit_class()
20     newUnit.propertyName = newValue
21     sandbox.memorize(newUnit)
22     del newUnit # or otherwise release the reference.
23
24 Using recall(), you get a list; using xrecall(), you get an iterator:
25     for unit in sandbox.recall(cls, expr):
26         do_something_with(unit)
27
28 You destroy a Unit via Unit.forget().
29
30 Applications only need to call Unit.repress() when they wish to stop
31 caching the object, returning it to storage. This is very rare, and
32 should really only be performed within dejavu code.
33 """
34
35 __version__ =  "2.0alpha"
36
37
38 import datetime as _datetime
39
40 from geniusql import logic, logicfuncs, _AttributeDocstrings
41
42 from dejavu import logflags
43 from dejavu import analysis
44 sort = analysis.sort
45
46 from dejavu.sandboxes import Sandbox
47 from dejavu.schemas import *
48 from dejavu.units import *
49
50
51 class Query(object):
52     """A query with relation, attributes, and restriction expressions."""
53    
54     __metaclass__ = _AttributeDocstrings
55    
56     relation = None
57     relation__doc = """A single Unit class or a UnitJoin (of Unit classes)."""
58    
59     attributes = None
60     attributes__doc = """
61     If None (the default), all attributes are returned.
62     Otherwise, if the relation is a single Unit class, this value
63     must be a sequence of attribute names for that class. If the
64     relation is a UnitJoin, this must be a sequence of sequences
65     of attribute names. That is:
66         [('ID', 'Size', ...),
67          ('ID', 'Value', ...),
68          ...]
69     The order of sequences must match the order of classes given in the
70     relation (and therefore the restriction args, if applicable).
71     A final option is to pass a lambda (or Expression) which returns
72     the attributes as a tuple or list; e.g.:
73         lambda x, y: (x.a, x.b - now(), x.c + y.a)
74     This allows access to binary operations and builtin functions."""
75    
76     restriction = None
77     restriction__doc = """
78     An Expression (or lambda, or dict) to restrict the rows returned.
79     
80     For SQL backends, this will be used to construct a WHERE clause.
81     The args must be in the same order as the classes in the relation."""
82    
83     def __init__(self, relation, attributes=None, restriction=None):
84         self.relation = relation
85        
86         from types import FunctionType
87         if isinstance(attributes, FunctionType):
88             attributes = logic.Expression(attributes)
89         self.attributes = attributes
90        
91         if restriction is None:
92             restriction = logic.Expression(lambda *args: True)
93         elif not isinstance(restriction, logic.Expression):
94             restriction = logic.Expression(restriction)
95        
96         self.restriction = restriction
97    
98     def __str__(self):
99         if isinstance(self.relation, UnitJoin):
100             rel = str(self.relation)
101         elif self.relation is None:
102             rel = None
103         else:
104             rel = self.relation.__name__
105         return "Query(%s, %s, %s)" % (rel, self.attributes, self.restriction)
106
107
108 class Statement(object):
109     """A relational statement, including query, order, limit, offset, and distinct.
110     
111     query: a Query instance, or a tuple of arguments to form a Query.
112     
113     order: if given, this will be used to order the results of the Query.
114         If the relation is a single Unit class, this value may be a sequence
115         of property names for the class. If the relation is a Join, this must
116         be an Expression (or lambda) which returns a tuple or list of
117         attributes; the args must be in the same order as the classes in
118         the relation.
119     """
120    
121     def __init__(self, query, order=None, limit=None, offset=None, distinct=None):
122         if not isinstance(query, Query):
123             query = Query(*query)
124         self.query = query
125        
126         self.order = order
127         self.limit = limit
128         self.offset = offset
129         self.distinct = distinct
130
Note: See TracBrowser for help on using the browser.