|
1 from copy import deepcopy |
|
2 from datetime import datetime |
|
3 |
|
4 from django.utils import tree |
|
5 |
|
6 class ExpressionNode(tree.Node): |
|
7 """ |
|
8 Base class for all query expressions. |
|
9 """ |
|
10 # Arithmetic connectors |
|
11 ADD = '+' |
|
12 SUB = '-' |
|
13 MUL = '*' |
|
14 DIV = '/' |
|
15 MOD = '%%' # This is a quoted % operator - it is quoted |
|
16 # because it can be used in strings that also |
|
17 # have parameter substitution. |
|
18 |
|
19 # Bitwise operators |
|
20 AND = '&' |
|
21 OR = '|' |
|
22 |
|
23 def __init__(self, children=None, connector=None, negated=False): |
|
24 if children is not None and len(children) > 1 and connector is None: |
|
25 raise TypeError('You have to specify a connector.') |
|
26 super(ExpressionNode, self).__init__(children, connector, negated) |
|
27 |
|
28 def _combine(self, other, connector, reversed, node=None): |
|
29 if reversed: |
|
30 obj = ExpressionNode([other], connector) |
|
31 obj.add(node or self, connector) |
|
32 else: |
|
33 obj = node or ExpressionNode([self], connector) |
|
34 obj.add(other, connector) |
|
35 return obj |
|
36 |
|
37 ################### |
|
38 # VISITOR METHODS # |
|
39 ################### |
|
40 |
|
41 def prepare(self, evaluator, query, allow_joins): |
|
42 return evaluator.prepare_node(self, query, allow_joins) |
|
43 |
|
44 def evaluate(self, evaluator, qn): |
|
45 return evaluator.evaluate_node(self, qn) |
|
46 |
|
47 ############# |
|
48 # OPERATORS # |
|
49 ############# |
|
50 |
|
51 def __add__(self, other): |
|
52 return self._combine(other, self.ADD, False) |
|
53 |
|
54 def __sub__(self, other): |
|
55 return self._combine(other, self.SUB, False) |
|
56 |
|
57 def __mul__(self, other): |
|
58 return self._combine(other, self.MUL, False) |
|
59 |
|
60 def __div__(self, other): |
|
61 return self._combine(other, self.DIV, False) |
|
62 |
|
63 def __mod__(self, other): |
|
64 return self._combine(other, self.MOD, False) |
|
65 |
|
66 def __and__(self, other): |
|
67 return self._combine(other, self.AND, False) |
|
68 |
|
69 def __or__(self, other): |
|
70 return self._combine(other, self.OR, False) |
|
71 |
|
72 def __radd__(self, other): |
|
73 return self._combine(other, self.ADD, True) |
|
74 |
|
75 def __rsub__(self, other): |
|
76 return self._combine(other, self.SUB, True) |
|
77 |
|
78 def __rmul__(self, other): |
|
79 return self._combine(other, self.MUL, True) |
|
80 |
|
81 def __rdiv__(self, other): |
|
82 return self._combine(other, self.DIV, True) |
|
83 |
|
84 def __rmod__(self, other): |
|
85 return self._combine(other, self.MOD, True) |
|
86 |
|
87 def __rand__(self, other): |
|
88 return self._combine(other, self.AND, True) |
|
89 |
|
90 def __ror__(self, other): |
|
91 return self._combine(other, self.OR, True) |
|
92 |
|
93 def prepare_database_save(self, unused): |
|
94 return self |
|
95 |
|
96 class F(ExpressionNode): |
|
97 """ |
|
98 An expression representing the value of the given field. |
|
99 """ |
|
100 def __init__(self, name): |
|
101 super(F, self).__init__(None, None, False) |
|
102 self.name = name |
|
103 |
|
104 def __deepcopy__(self, memodict): |
|
105 obj = super(F, self).__deepcopy__(memodict) |
|
106 obj.name = self.name |
|
107 return obj |
|
108 |
|
109 def prepare(self, evaluator, query, allow_joins): |
|
110 return evaluator.prepare_leaf(self, query, allow_joins) |
|
111 |
|
112 def evaluate(self, evaluator, qn): |
|
113 return evaluator.evaluate_leaf(self, qn) |