server/ssplanner.py
changeset 9508 1263f1258796
parent 9469 032825bbacab
child 10314 8f3783dc6358
equal deleted inserted replaced
9507:540cb068a7f9 9508:1263f1258796
    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
   494         Step.__init__(self, plan)
   494         Step.__init__(self, plan)
   495         self.updatedefs = updatedefs
   495         self.updatedefs = updatedefs
   496 
   496 
   497     def execute(self):
   497     def execute(self):
   498         """execute this step"""
   498         """execute this step"""
   499         session = self.plan.session
   499         cnx = self.plan.cnx
   500         repo = session.repo
   500         repo = cnx.repo
   501         edefs = {}
   501         edefs = {}
   502         relations = {}
   502         relations = {}
   503         # insert relations
   503         # insert relations
   504         if self.children:
   504         if self.children:
   505             result = self.execute_child()
   505             result = self.execute_child()
   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]