req.py
branchstable
changeset 5199 ebb50479d2ab
parent 4933 433174d9394f
child 5201 2b4267157f85
child 5290 15846058378b
equal deleted inserted replaced
5198:cf8292f80384 5199:ebb50479d2ab
   117         raise KeyError
   117         raise KeyError
   118 
   118 
   119     def set_entity_cache(self, entity):
   119     def set_entity_cache(self, entity):
   120         pass
   120         pass
   121 
   121 
   122     # XXX move to CWEntityManager or even better as factory method (unclear
       
   123     # where yet...)
       
   124 
       
   125     def create_entity(self, etype, **kwargs):
   122     def create_entity(self, etype, **kwargs):
   126         """add a new entity of the given type
   123         """add a new entity of the given type
   127 
   124 
   128         Example (in a shell session):
   125         Example (in a shell session):
   129 
   126 
   131         >>> create_entity('Person', firstname=u'John', lastname=u'Doe',
   128         >>> create_entity('Person', firstname=u'John', lastname=u'Doe',
   132         ...               works_for=c)
   129         ...               works_for=c)
   133 
   130 
   134         """
   131         """
   135         _check_cw_unsafe(kwargs)
   132         _check_cw_unsafe(kwargs)
   136         execute = self.execute
   133         cls = self.vreg['etypes'].etype_class(etype)
   137         rql = 'INSERT %s X' % etype
   134         return cls.cw_instantiate(self.execute, **kwargs)
   138         relations = []
       
   139         restrictions = set()
       
   140         cachekey = []
       
   141         pending_relations = []
       
   142         for attr, value in kwargs.items():
       
   143             if isinstance(value, (tuple, list, set, frozenset)):
       
   144                 if len(value) == 1:
       
   145                     value = iter(value).next()
       
   146                 else:
       
   147                     del kwargs[attr]
       
   148                     pending_relations.append( (attr, value) )
       
   149                     continue
       
   150             if hasattr(value, 'eid'): # non final relation
       
   151                 rvar = attr.upper()
       
   152                 # XXX safer detection of object relation
       
   153                 if attr.startswith('reverse_'):
       
   154                     relations.append('%s %s X' % (rvar, attr[len('reverse_'):]))
       
   155                 else:
       
   156                     relations.append('X %s %s' % (attr, rvar))
       
   157                 restriction = '%s eid %%(%s)s' % (rvar, attr)
       
   158                 if not restriction in restrictions:
       
   159                     restrictions.add(restriction)
       
   160                 cachekey.append(attr)
       
   161                 kwargs[attr] = value.eid
       
   162             else: # attribute
       
   163                 relations.append('X %s %%(%s)s' % (attr, attr))
       
   164         if relations:
       
   165             rql = '%s: %s' % (rql, ', '.join(relations))
       
   166         if restrictions:
       
   167             rql = '%s WHERE %s' % (rql, ', '.join(restrictions))
       
   168         created = execute(rql, kwargs, cachekey).get_entity(0, 0)
       
   169         for attr, values in pending_relations:
       
   170             if attr.startswith('reverse_'):
       
   171                 restr = 'Y %s X' % attr[len('reverse_'):]
       
   172             else:
       
   173                 restr = 'X %s Y' % attr
       
   174             execute('SET %s WHERE X eid %%(x)s, Y eid IN (%s)' % (
       
   175                 restr, ','.join(str(r.eid) for r in values)),
       
   176                     {'x': created.eid}, 'x', build_descr=False)
       
   177         return created
       
   178 
   135 
   179     def ensure_ro_rql(self, rql):
   136     def ensure_ro_rql(self, rql):
   180         """raise an exception if the given rql is not a select query"""
   137         """raise an exception if the given rql is not a select query"""
   181         first = rql.split(' ', 1)[0].lower()
   138         first = rql.split(' ', 1)[0].lower()
   182         if first in ('insert', 'set', 'delete'):
   139         if first in ('insert', 'set', 'delete'):