1 from types import StringTypes
4 and_, or_, inv, add, mul, sub, mod, truediv, lt, le, ne, gt, ge, eq, neg
7 # Define the inclusion operators
8 class contains(type): pass
9 class included(type): pass
12 # New modifier: { contains
24 'CONTAINS' : contains,
41 def __init__(self, *args, **kwargs):
43 \brief Build a predicate (left, operator, right)
45 - three args (left, operator, right)
46 - one argument (list or tuple) containing three elements (variable, operator, value)
47 "operator" is a String defined in operators or in operators_short and refers
48 tMao a binary operation.
49 "left" and "right" refers to a variable/constant involved in the Predicate.
53 elif len(args) == 1 and isinstance(args[0], (tuple,list)) and len(args[0]) == 3:
54 key, op, value = args[0]
55 elif len(args) == 1 and isinstance(args[0], Predicate):
56 key, op, value = args[0].get_tuple()
58 raise Exception, "Bad initializer for Predicate (args=%r)" % args
60 assert not isinstance(value, (frozenset, dict, set)), "Invalid value type (the only valid containers are tuples and lists) (type = %r)" % type(value)
61 if isinstance(value, list):
65 if isinstance(op, StringTypes):
67 if op in self.operators.keys():
68 self.op = self.operators[op]
69 elif op in self.operators_short.keys():
70 self.op = self.operators_short[op]
74 if isinstance(value, list):
75 self.value = tuple(value)
80 key, op, value = self.get_str_tuple()
81 if isinstance(value, (tuple, list, set, frozenset)):
82 value = [repr(v) for v in value]
83 value = "[%s]" % ", ".join(value)
84 return "%s %s %r" % (key, op, value)
87 return "Predicate<%s %s %r>" % self.get_str_tuple()
90 return hash(self.get_tuple())
92 def __eq__(self, predicate):
95 return self.get_tuple() == predicate.get_tuple()
100 def set_key(self, key):
109 def set_value(self, value):
113 return (self.key, self.op, self.value)
116 def get_str_op(self):
117 op_str = [s for s, op in self.operators.iteritems() if op == self.op]
120 def get_str_tuple(self):
121 return (self.key, self.get_str_op(), self.value,)
124 return list(self.get_str_tuple())
126 def match(self, dic, ignore_missing=False):
127 if isinstance(self.key, tuple):
128 print "PREDICATE MATCH", self.key
130 print "-----------------------------"
133 if self.key not in dic:
134 return ignore_missing
137 if isinstance(self.value, list):
138 return (dic[self.key] in self.value) # array ?
140 return (dic[self.key] == self.value)
142 if isinstance(self.value, list):
143 return (dic[self.key] not in self.value) # array ?
145 return (dic[self.key] != self.value) # array ?
147 if isinstance(self.value, StringTypes):
149 return dic[self.key].startswith('%s.' % self.value)
151 return (dic[self.key] < self.value)
153 if isinstance(self.value, StringTypes):
154 return dic[self.key] == self.value or dic[self.key].startswith('%s.' % self.value)
156 return (dic[self.key] <= self.value)
158 if isinstance(self.value, StringTypes):
160 return self.value.startswith('%s.' % dic[self.key])
162 return (dic[self.key] > self.value)
164 if isinstance(self.value, StringTypes):
166 return dic[self.key] == self.value or self.value.startswith('%s.' % dic[self.key])
168 return (dic[self.key] >= self.value)
169 elif self.op == and_:
170 return (dic[self.key] & self.value) # array ?
172 return (dic[self.key] | self.value) # array ?
173 elif self.op == contains:
174 method, subfield = self.key.split('.', 1)
175 return not not [ x for x in dic[method] if x[subfield] == self.value]
176 elif self.op == included:
177 return dic[self.key] in self.value
179 raise Exception, "Unexpected table format: %r" % dic
181 def filter(self, dic):
183 Filter dic according to the current predicate.
188 method, subfield = self.key.split('.', 1)
189 if not method in dic:
192 if isinstance(dic[method], dict):
193 # We have a 1..1 relationship: apply the same filter to the dict
194 subpred = Predicate(subfield, self.op, self.value)
195 match = subpred.match(dic[method])
196 return dic if match else None
198 elif isinstance(dic[method], (list, tuple)):
201 if self.op == contains:
202 return dic if self.match(dic) else None
204 subpred = Predicate(subfield, self.op, self.value)
205 dic[method] = subpred.filter(dic[method])
208 raise Exception, "Unexpected table format: %r", dic
212 # Individual field operations: this could be simplified, since we are now using operators_short !!
214 print "current predicate", self
215 print "matching", dic
217 return dic if self.match(dic) else None
219 def get_field_names(self):
220 if isinstance(self.key, (list, tuple, set, frozenset)):
223 return set([self.key])
225 def get_value_names(self):
226 if isinstance(self.value, (list, tuple, set, frozenset)):
227 return set(self.value)
229 return set([self.value])
231 def has_empty_value(self):
232 if isinstance(self.value, (list, tuple, set, frozenset)):
233 return not any(self.value)
235 return not self.value