req.py
changeset 5201 2b4267157f85
parent 5174 78438ad513ca
parent 5199 ebb50479d2ab
child 5302 dfd147de06b2
equal deleted inserted replaced
5196:d14bfd477c44 5201:2b4267157f85
   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         pending_relations = []
       
   141         for attr, value in kwargs.items():
       
   142             if isinstance(value, (tuple, list, set, frozenset)):
       
   143                 if len(value) == 1:
       
   144                     value = iter(value).next()
       
   145                 else:
       
   146                     del kwargs[attr]
       
   147                     pending_relations.append( (attr, value) )
       
   148                     continue
       
   149             if hasattr(value, 'eid'): # non final relation
       
   150                 rvar = attr.upper()
       
   151                 # XXX safer detection of object relation
       
   152                 if attr.startswith('reverse_'):
       
   153                     relations.append('%s %s X' % (rvar, attr[len('reverse_'):]))
       
   154                 else:
       
   155                     relations.append('X %s %s' % (attr, rvar))
       
   156                 restriction = '%s eid %%(%s)s' % (rvar, attr)
       
   157                 if not restriction in restrictions:
       
   158                     restrictions.add(restriction)
       
   159                 kwargs[attr] = value.eid
       
   160             else: # attribute
       
   161                 relations.append('X %s %%(%s)s' % (attr, attr))
       
   162         if relations:
       
   163             rql = '%s: %s' % (rql, ', '.join(relations))
       
   164         if restrictions:
       
   165             rql = '%s WHERE %s' % (rql, ', '.join(restrictions))
       
   166         created = execute(rql, kwargs).get_entity(0, 0)
       
   167         for attr, values in pending_relations:
       
   168             if attr.startswith('reverse_'):
       
   169                 restr = 'Y %s X' % attr[len('reverse_'):]
       
   170             else:
       
   171                 restr = 'X %s Y' % attr
       
   172             execute('SET %s WHERE X eid %%(x)s, Y eid IN (%s)' % (
       
   173                 restr, ','.join(str(r.eid) for r in values)),
       
   174                     {'x': created.eid}, build_descr=False)
       
   175         return created
       
   176 
   135 
   177     def ensure_ro_rql(self, rql):
   136     def ensure_ro_rql(self, rql):
   178         """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"""
   179         first = rql.split(' ', 1)[0].lower()
   138         first = rql.split(' ', 1)[0].lower()
   180         if first in ('insert', 'set', 'delete'):
   139         if first in ('insert', 'set', 'delete'):