branch | tls-sprint |
changeset 1787 | 71c143c0ada3 |
parent 1398 | 5fe84a5f7035 |
child 1977 | 606923dff11b |
1786:eccd1885d42e | 1787:71c143c0ada3 |
---|---|
9 |
9 |
10 config = TestServerConfiguration('data') |
10 config = TestServerConfiguration('data') |
11 config.bootstrap_cubes() |
11 config.bootstrap_cubes() |
12 schema = config.load_schema() |
12 schema = config.load_schema() |
13 schema.add_relation_def(mock_object(subject='Card', name='in_state', object='State', cardinality='1*')) |
13 schema.add_relation_def(mock_object(subject='Card', name='in_state', object='State', cardinality='1*')) |
14 |
14 |
15 rqlhelper = RQLHelper(schema, special_relations={'eid': 'uid', |
15 rqlhelper = RQLHelper(schema, special_relations={'eid': 'uid', |
16 'has_text': 'fti'}) |
16 'has_text': 'fti'}) |
17 |
17 |
18 def setup_module(*args): |
18 def setup_module(*args): |
19 repotest.do_monkey_patch() |
19 repotest.do_monkey_patch() |
20 |
20 |
21 def teardown_module(*args): |
21 def teardown_module(*args): |
22 repotest.undo_monkey_patch() |
22 repotest.undo_monkey_patch() |
23 |
23 |
24 def eid_func_map(eid): |
24 def eid_func_map(eid): |
25 return {1: 'CWUser', |
25 return {1: 'CWUser', |
26 2: 'Card'}[eid] |
26 2: 'Card'}[eid] |
27 |
27 |
28 def rewrite(rqlst, snippets_map, kwargs): |
28 def rewrite(rqlst, snippets_map, kwargs): |
39 def simplify(mainrqlst, needcopy=False): |
39 def simplify(mainrqlst, needcopy=False): |
40 rqlhelper.simplify(rqlst, needcopy) |
40 rqlhelper.simplify(rqlst, needcopy) |
41 rewriter = RQLRewriter(FakeQuerier, mock_object(user=(mock_object(eid=1)))) |
41 rewriter = RQLRewriter(FakeQuerier, mock_object(user=(mock_object(eid=1)))) |
42 for v, snippets in snippets_map.items(): |
42 for v, snippets in snippets_map.items(): |
43 snippets_map[v] = [mock_object(snippet_rqlst=parse('Any X WHERE '+snippet).children[0], |
43 snippets_map[v] = [mock_object(snippet_rqlst=parse('Any X WHERE '+snippet).children[0], |
44 expression='Any X WHERE '+snippet) |
44 expression='Any X WHERE '+snippet) |
45 for snippet in snippets] |
45 for snippet in snippets] |
46 rqlhelper.compute_solutions(rqlst.children[0], {'eid': eid_func_map}, kwargs=kwargs) |
46 rqlhelper.compute_solutions(rqlst.children[0], {'eid': eid_func_map}, kwargs=kwargs) |
47 solutions = rqlst.children[0].solutions |
47 solutions = rqlst.children[0].solutions |
48 rewriter.rewrite(rqlst.children[0], snippets_map.items(), solutions, kwargs) |
48 rewriter.rewrite(rqlst.children[0], snippets_map.items(), solutions, kwargs) |
49 test_vrefs(rqlst.children[0]) |
49 test_vrefs(rqlst.children[0]) |
60 class RQLRewriteTC(TestCase): |
60 class RQLRewriteTC(TestCase): |
61 """a faire: |
61 """a faire: |
62 |
62 |
63 * optimisation: detecter les relations utilisees dans les rqlexpressions qui |
63 * optimisation: detecter les relations utilisees dans les rqlexpressions qui |
64 sont presentes dans la requete de depart pour les reutiliser si possible |
64 sont presentes dans la requete de depart pour les reutiliser si possible |
65 |
65 |
66 * "has_<ACTION>_permission" ? |
66 * "has_<ACTION>_permission" ? |
67 """ |
67 """ |
68 |
68 |
69 def test_base_var(self): |
69 def test_base_var(self): |
70 card_constraint = ('X in_state S, U in_group G, P require_state S,' |
70 card_constraint = ('X in_state S, U in_group G, P require_state S,' |
71 'P name "read", P require_group G') |
71 'P name "read", P require_group G') |
72 rqlst = parse('Card C') |
72 rqlst = parse('Card C') |
73 rewrite(rqlst, {'C': (card_constraint,)}, {}) |
73 rewrite(rqlst, {'C': (card_constraint,)}, {}) |
74 self.failUnlessEqual(rqlst.as_string(), |
74 self.failUnlessEqual(rqlst.as_string(), |
75 u"Any C WHERE C is Card, B eid %(D)s, " |
75 u"Any C WHERE C is Card, B eid %(D)s, " |
76 "EXISTS(C in_state A, B in_group E, F require_state A, " |
76 "EXISTS(C in_state A, B in_group E, F require_state A, " |
77 "F name 'read', F require_group E, A is State, E is CWGroup, F is CWPermission)") |
77 "F name 'read', F require_group E, A is State, E is CWGroup, F is CWPermission)") |
78 |
78 |
79 def test_multiple_var(self): |
79 def test_multiple_var(self): |
80 card_constraint = ('X in_state S, U in_group G, P require_state S,' |
80 card_constraint = ('X in_state S, U in_group G, P require_state S,' |
81 'P name "read", P require_group G') |
81 'P name "read", P require_group G') |
82 affaire_constraints = ('X ref LIKE "PUBLIC%"', 'U in_group G, G name "public"') |
82 affaire_constraints = ('X ref LIKE "PUBLIC%"', 'U in_group G, G name "public"') |
83 kwargs = {'u':2} |
83 kwargs = {'u':2} |
89 "EXISTS(C in_state A, B in_group E, F require_state A, " |
89 "EXISTS(C in_state A, B in_group E, F require_state A, " |
90 "F name 'read', F require_group E, A is State, E is CWGroup, F is CWPermission), " |
90 "F name 'read', F require_group E, A is State, E is CWGroup, F is CWPermission), " |
91 "(EXISTS(S ref LIKE 'PUBLIC%')) OR (EXISTS(B in_group G, G name 'public', G is CWGroup)), " |
91 "(EXISTS(S ref LIKE 'PUBLIC%')) OR (EXISTS(B in_group G, G name 'public', G is CWGroup)), " |
92 "S is Affaire") |
92 "S is Affaire") |
93 self.failUnless('D' in kwargs) |
93 self.failUnless('D' in kwargs) |
94 |
94 |
95 def test_or(self): |
95 def test_or(self): |
96 constraint = '(X identity U) OR (X in_state ST, CL identity U, CL in_state ST, ST name "subscribed")' |
96 constraint = '(X identity U) OR (X in_state ST, CL identity U, CL in_state ST, ST name "subscribed")' |
97 rqlst = parse('Any S WHERE S owned_by C, C eid %(u)s') |
97 rqlst = parse('Any S WHERE S owned_by C, C eid %(u)s') |
98 rewrite(rqlst, {'C': (constraint,)}, {'u':1}) |
98 rewrite(rqlst, {'C': (constraint,)}, {'u':1}) |
99 self.failUnlessEqual(rqlst.as_string(), |
99 self.failUnlessEqual(rqlst.as_string(), |
100 "Any S WHERE S owned_by C, C eid %(u)s, A eid %(B)s, " |
100 "Any S WHERE S owned_by C, C eid %(u)s, A eid %(B)s, " |
101 "EXISTS((C identity A) OR (C in_state D, E identity A, " |
101 "EXISTS((C identity A) OR (C in_state D, E identity A, " |
102 "E in_state D, D name 'subscribed'), D is State, E is CWUser), " |
102 "E in_state D, D name 'subscribed'), D is State, E is CWUser), " |
103 "S is IN(Affaire, Basket, Bookmark, Card, Comment, Division, CWCache, CWConstraint, CWConstraintType, CWEType, CWAttribute, CWGroup, CWRelation, CWPermission, CWProperty, CWRType, CWUser, Email, EmailAddress, EmailPart, EmailThread, File, Folder, Image, Note, Personne, RQLExpression, Societe, State, SubDivision, Tag, TrInfo, Transition)") |
103 "S is IN(Affaire, Basket, Bookmark, CWAttribute, CWCache, CWConstraint, CWConstraintType, CWEType, CWGroup, CWPermission, CWProperty, CWRType, CWRelation, CWUser, Card, Comment, Division, Email, EmailAddress, EmailPart, EmailThread, File, Folder, Image, Note, Personne, RQLExpression, Societe, State, SubDivision, Tag, TrInfo, Transition)") |
104 |
104 |
105 def test_simplified_rqlst(self): |
105 def test_simplified_rqlst(self): |
106 card_constraint = ('X in_state S, U in_group G, P require_state S,' |
106 card_constraint = ('X in_state S, U in_group G, P require_state S,' |
107 'P name "read", P require_group G') |
107 'P name "read", P require_group G') |
108 rqlst = parse('Any 2') # this is the simplified rql st for Any X WHERE X eid 12 |
108 rqlst = parse('Any 2') # this is the simplified rql st for Any X WHERE X eid 12 |
127 self.failUnlessEqual(rqlst.as_string(), |
127 self.failUnlessEqual(rqlst.as_string(), |
128 "Any A,C,T WHERE A documented_by C?, A is Affaire " |
128 "Any A,C,T WHERE A documented_by C?, A is Affaire " |
129 "WITH C,T BEING " |
129 "WITH C,T BEING " |
130 "(Any C,T WHERE C in_state B, D in_group F, G require_state B, G name 'read', " |
130 "(Any C,T WHERE C in_state B, D in_group F, G require_state B, G name 'read', " |
131 "G require_group F, C title T, D eid %(A)s, C is Card)") |
131 "G require_group F, C title T, D eid %(A)s, C is Card)") |
132 |
132 |
133 def test_relation_optimization(self): |
133 def test_relation_optimization(self): |
134 # since Card in_state State as monovalued cardinality, the in_state |
134 # since Card in_state State as monovalued cardinality, the in_state |
135 # relation used in the rql expression can be ignored and S replaced by |
135 # relation used in the rql expression can be ignored and S replaced by |
136 # the variable from the incoming query |
136 # the variable from the incoming query |
137 card_constraint = ('X in_state S, U in_group G, P require_state S,' |
137 card_constraint = ('X in_state S, U in_group G, P require_state S,' |
147 def test_unsupported_constraint_1(self): |
147 def test_unsupported_constraint_1(self): |
148 # CWUser doesn't have require_permission |
148 # CWUser doesn't have require_permission |
149 trinfo_constraint = ('X wf_info_for Y, Y require_permission P, P name "read"') |
149 trinfo_constraint = ('X wf_info_for Y, Y require_permission P, P name "read"') |
150 rqlst = parse('Any U,T WHERE U is CWUser, T wf_info_for U') |
150 rqlst = parse('Any U,T WHERE U is CWUser, T wf_info_for U') |
151 self.assertRaises(Unauthorized, rewrite, rqlst, {'T': (trinfo_constraint,)}, {}) |
151 self.assertRaises(Unauthorized, rewrite, rqlst, {'T': (trinfo_constraint,)}, {}) |
152 |
152 |
153 def test_unsupported_constraint_2(self): |
153 def test_unsupported_constraint_2(self): |
154 trinfo_constraint = ('X wf_info_for Y, Y require_permission P, P name "read"') |
154 trinfo_constraint = ('X wf_info_for Y, Y require_permission P, P name "read"') |
155 rqlst = parse('Any U,T WHERE U is CWUser, T wf_info_for U') |
155 rqlst = parse('Any U,T WHERE U is CWUser, T wf_info_for U') |
156 rewrite(rqlst, {'T': (trinfo_constraint, 'X wf_info_for Y, Y in_group G, G name "managers"')}, {}) |
156 rewrite(rqlst, {'T': (trinfo_constraint, 'X wf_info_for Y, Y in_group G, G name "managers"')}, {}) |
157 self.failUnlessEqual(rqlst.as_string(), |
157 self.failUnlessEqual(rqlst.as_string(), |
163 trinfo_constraint = ('X wf_info_for Y, Y require_permission P, P name "read"') |
163 trinfo_constraint = ('X wf_info_for Y, Y require_permission P, P name "read"') |
164 rqlst = parse('Any T WHERE T wf_info_for X') |
164 rqlst = parse('Any T WHERE T wf_info_for X') |
165 rewrite(rqlst, {'T': (trinfo_constraint, 'X in_group G, G name "managers"')}, {}) |
165 rewrite(rqlst, {'T': (trinfo_constraint, 'X in_group G, G name "managers"')}, {}) |
166 self.failUnlessEqual(rqlst.as_string(), |
166 self.failUnlessEqual(rqlst.as_string(), |
167 u'XXX dunno what should be generated') |
167 u'XXX dunno what should be generated') |
168 |
168 |
169 def test_add_ambiguity_exists(self): |
169 def test_add_ambiguity_exists(self): |
170 constraint = ('X concerne Y') |
170 constraint = ('X concerne Y') |
171 rqlst = parse('Affaire X') |
171 rqlst = parse('Affaire X') |
172 rewrite(rqlst, {'X': (constraint,)}, {}) |
172 rewrite(rqlst, {'X': (constraint,)}, {}) |
173 self.failUnlessEqual(rqlst.as_string(), |
173 self.failUnlessEqual(rqlst.as_string(), |
174 u"Any X WHERE X is Affaire, (((EXISTS(X concerne A, A is Division)) OR (EXISTS(X concerne D, D is SubDivision))) OR (EXISTS(X concerne C, C is Societe))) OR (EXISTS(X concerne B, B is Note))") |
174 u"Any X WHERE X is Affaire, (((EXISTS(X concerne A, A is Division)) OR (EXISTS(X concerne D, D is SubDivision))) OR (EXISTS(X concerne C, C is Societe))) OR (EXISTS(X concerne B, B is Note))") |
175 |
175 |
176 def test_add_ambiguity_outerjoin(self): |
176 def test_add_ambiguity_outerjoin(self): |
177 constraint = ('X concerne Y') |
177 constraint = ('X concerne Y') |
178 rqlst = parse('Any X,C WHERE X? documented_by C') |
178 rqlst = parse('Any X,C WHERE X? documented_by C') |
179 rewrite(rqlst, {'X': (constraint,)}, {}) |
179 rewrite(rqlst, {'X': (constraint,)}, {}) |
180 # ambiguity are kept in the sub-query, no need to be resolved using OR |
180 # ambiguity are kept in the sub-query, no need to be resolved using OR |
181 self.failUnlessEqual(rqlst.as_string(), |
181 self.failUnlessEqual(rqlst.as_string(), |
182 u"Any X,C WHERE X? documented_by C, C is Card WITH X BEING (Any X WHERE X concerne A, X is Affaire)") |
182 u"Any X,C WHERE X? documented_by C, C is Card WITH X BEING (Any X WHERE X concerne A, X is Affaire)") |
183 |
183 |
184 |
184 |
185 |
185 |
186 if __name__ == '__main__': |
186 if __name__ == '__main__': |
187 unittest_main() |
187 unittest_main() |