66 |
66 |
67 def _extract_eid_consts(plan, rqlst): |
67 def _extract_eid_consts(plan, rqlst): |
68 """return a dict mapping rqlst variable object to their eid if specified in |
68 """return a dict mapping rqlst variable object to their eid if specified in |
69 the syntax tree |
69 the syntax tree |
70 """ |
70 """ |
71 session = plan.session |
71 cnx = plan.cnx |
72 if rqlst.where is None: |
72 if rqlst.where is None: |
73 return {} |
73 return {} |
74 eidconsts = {} |
74 eidconsts = {} |
75 neweids = session.transaction_data.get('neweids', ()) |
75 neweids = cnx.transaction_data.get('neweids', ()) |
76 checkread = session.read_security |
76 checkread = cnx.read_security |
77 eschema = session.vreg.schema.eschema |
77 eschema = cnx.vreg.schema.eschema |
78 for rel in rqlst.where.get_nodes(Relation): |
78 for rel in rqlst.where.get_nodes(Relation): |
79 # only care for 'eid' relations ... |
79 # only care for 'eid' relations ... |
80 if (rel.r_type == 'eid' |
80 if (rel.r_type == 'eid' |
81 # ... that are not part of a NOT clause ... |
81 # ... that are not part of a NOT clause ... |
82 and not rel.neged(strict=True) |
82 and not rel.neged(strict=True) |
87 eid = int(rhs.eval(plan.args)) |
87 eid = int(rhs.eval(plan.args)) |
88 # check read permission here since it may not be done by |
88 # check read permission here since it may not be done by |
89 # the generated select substep if not emited (eg nothing |
89 # the generated select substep if not emited (eg nothing |
90 # to be selected) |
90 # to be selected) |
91 if checkread and eid not in neweids: |
91 if checkread and eid not in neweids: |
92 with session.security_enabled(read=False): |
92 with cnx.security_enabled(read=False): |
93 eschema(session.entity_metas(eid)['type']).check_perm( |
93 eschema(cnx.entity_metas(eid)['type']).check_perm( |
94 session, 'read', eid=eid) |
94 cnx, 'read', eid=eid) |
95 eidconsts[lhs.variable] = eid |
95 eidconsts[lhs.variable] = eid |
96 return eidconsts |
96 return eidconsts |
97 |
97 |
98 def _build_substep_query(select, origrqlst): |
98 def _build_substep_query(select, origrqlst): |
99 """Finalize substep select query that should be executed to get proper |
99 """Finalize substep select query that should be executed to get proper |
149 |
149 |
150 def build_insert_plan(self, plan, rqlst): |
150 def build_insert_plan(self, plan, rqlst): |
151 """get an execution plan from an INSERT RQL query""" |
151 """get an execution plan from an INSERT RQL query""" |
152 # each variable in main variables is a new entity to insert |
152 # each variable in main variables is a new entity to insert |
153 to_build = {} |
153 to_build = {} |
154 session = plan.session |
154 cnx = plan.cnx |
155 etype_class = session.vreg['etypes'].etype_class |
155 etype_class = cnx.vreg['etypes'].etype_class |
156 for etype, var in rqlst.main_variables: |
156 for etype, var in rqlst.main_variables: |
157 # need to do this since entity class is shared w. web client code ! |
157 # need to do this since entity class is shared w. web client code ! |
158 to_build[var.name] = EditedEntity(etype_class(etype)(session)) |
158 to_build[var.name] = EditedEntity(etype_class(etype)(cnx)) |
159 plan.add_entity_def(to_build[var.name]) |
159 plan.add_entity_def(to_build[var.name]) |
160 # add constant values to entity def, mark variables to be selected |
160 # add constant values to entity def, mark variables to be selected |
161 to_select = _extract_const_attributes(plan, rqlst, to_build) |
161 to_select = _extract_const_attributes(plan, rqlst, to_build) |
162 # add necessary steps to add relations and update attributes |
162 # add necessary steps to add relations and update attributes |
163 step = InsertStep(plan) # insert each entity and its relations |
163 step = InsertStep(plan) # insert each entity and its relations |
351 def execute(self): |
351 def execute(self): |
352 """call .syntax_tree_search with the given syntax tree on each |
352 """call .syntax_tree_search with the given syntax tree on each |
353 source for each solution |
353 source for each solution |
354 """ |
354 """ |
355 self.execute_children() |
355 self.execute_children() |
356 session = self.plan.session |
356 cnx = self.plan.cnx |
357 args = self.plan.args |
357 args = self.plan.args |
358 inputmap = self.inputmap |
358 inputmap = self.inputmap |
359 union = self.union |
359 union = self.union |
360 # do we have to use a inputmap from a previous step ? If so disable |
360 # do we have to use a inputmap from a previous step ? If so disable |
361 # cachekey |
361 # cachekey |
368 cachekey[0] = union.as_string() |
368 cachekey[0] = union.as_string() |
369 cachekey = tuple(cachekey) |
369 cachekey = tuple(cachekey) |
370 else: |
370 else: |
371 cachekey = union.as_string() |
371 cachekey = union.as_string() |
372 # get results for query |
372 # get results for query |
373 source = session.repo.system_source |
373 source = cnx.repo.system_source |
374 result = source.syntax_tree_search(session, union, args, cachekey, inputmap) |
374 result = source.syntax_tree_search(cnx, union, args, cachekey, inputmap) |
375 #print 'ONEFETCH RESULT %s' % (result) |
375 #print 'ONEFETCH RESULT %s' % (result) |
376 return result |
376 return result |
377 |
377 |
378 def mytest_repr(self): |
378 def mytest_repr(self): |
379 """return a representation of this step suitable for test""" |
379 """return a representation of this step suitable for test""" |
464 def execute(self): |
464 def execute(self): |
465 """execute this step""" |
465 """execute this step""" |
466 results = self.execute_child() |
466 results = self.execute_child() |
467 if results: |
467 if results: |
468 todelete = frozenset(int(eid) for eid, in results) |
468 todelete = frozenset(int(eid) for eid, in results) |
469 session = self.plan.session |
469 cnx = self.plan.cnx |
470 session.repo.glob_delete_entities(session, todelete) |
470 cnx.repo.glob_delete_entities(cnx, todelete) |
471 return results |
471 return results |
472 |
472 |
473 class DeleteRelationsStep(Step): |
473 class DeleteRelationsStep(Step): |
474 """step consisting in deleting relations""" |
474 """step consisting in deleting relations""" |
475 |
475 |
477 Step.__init__(self, plan) |
477 Step.__init__(self, plan) |
478 self.rtype = rtype |
478 self.rtype = rtype |
479 |
479 |
480 def execute(self): |
480 def execute(self): |
481 """execute this step""" |
481 """execute this step""" |
482 session = self.plan.session |
482 cnx = self.plan.cnx |
483 delete = session.repo.glob_delete_relation |
483 delete = cnx.repo.glob_delete_relation |
484 for subj, obj in self.execute_child(): |
484 for subj, obj in self.execute_child(): |
485 delete(session, subj, self.rtype, obj) |
485 delete(cnx, subj, self.rtype, obj) |
486 |
486 |
487 |
487 |
488 class UpdateStep(Step): |
488 class UpdateStep(Step): |
489 """step consisting in updating entities / adding relations from relations |
489 """step consisting in updating entities / adding relations from relations |
490 definitions and from results fetched in previous step |
490 definitions and from results fetched in previous step |
513 if rschema.final or rschema.inlined: |
513 if rschema.final or rschema.inlined: |
514 eid = int(lhsval) |
514 eid = int(lhsval) |
515 try: |
515 try: |
516 edited = edefs[eid] |
516 edited = edefs[eid] |
517 except KeyError: |
517 except KeyError: |
518 edef = session.entity_from_eid(eid) |
518 edef = cnx.entity_from_eid(eid) |
519 edefs[eid] = edited = EditedEntity(edef) |
519 edefs[eid] = edited = EditedEntity(edef) |
520 edited.edited_attribute(str(rschema), rhsval) |
520 edited.edited_attribute(str(rschema), rhsval) |
521 else: |
521 else: |
522 str_rschema = str(rschema) |
522 str_rschema = str(rschema) |
523 if str_rschema in relations: |
523 if str_rschema in relations: |
524 relations[str_rschema].append((lhsval, rhsval)) |
524 relations[str_rschema].append((lhsval, rhsval)) |
525 else: |
525 else: |
526 relations[str_rschema] = [(lhsval, rhsval)] |
526 relations[str_rschema] = [(lhsval, rhsval)] |
527 result[i] = newrow |
527 result[i] = newrow |
528 # update entities |
528 # update entities |
529 repo.glob_add_relations(session, relations) |
529 repo.glob_add_relations(cnx, relations) |
530 for eid, edited in edefs.iteritems(): |
530 for eid, edited in edefs.iteritems(): |
531 repo.glob_update_entity(session, edited) |
531 repo.glob_update_entity(cnx, edited) |
532 return result |
532 return result |
533 |
533 |
534 def _handle_relterm(info, row, newrow): |
534 def _handle_relterm(info, row, newrow): |
535 if info[0] is _CONSTANT: |
535 if info[0] is _CONSTANT: |
536 val = info[1] |
536 val = info[1] |