req.py
changeset 3674 387d51af966d
parent 3659 993997b4b41d
child 3720 5376aaadd16b
equal deleted inserted replaced
3661:12ea53a4c0da 3674:387d51af966d
   106     def set_entity_cache(self, entity):
   106     def set_entity_cache(self, entity):
   107         pass
   107         pass
   108 
   108 
   109     # XXX move to CWEntityManager or even better as factory method (unclear
   109     # XXX move to CWEntityManager or even better as factory method (unclear
   110     # where yet...)
   110     # where yet...)
   111     def create_entity(self, etype, *args, **kwargs):
   111     def create_entity(self, etype, **kwargs):
   112         """add a new entity of the given type
   112         """add a new entity of the given type
   113 
   113 
   114         Example (in a shell session):
   114         Example (in a shell session):
   115 
   115 
   116         c = create_entity('Company', name='Logilab')
   116         c = create_entity('Company', name=u'Logilab')
   117         create_entity('Person', ('works_for', 'Y'), Y=c.eid, firstname='John', lastname='Doe')
   117         create_entity('Person', works_for=c, firstname=u'John', lastname=u'Doe')
       
   118 
   118         """
   119         """
   119         rql = 'INSERT %s X' % etype
   120         rql = 'INSERT %s X' % etype
   120         relations = []
   121         relations = []
   121         restrictions = []
   122         restrictions = set()
   122         cachekey = []
   123         cachekey = []
   123         for rtype, rvar in args:
   124         pending_relations = []
   124             relations.append('X %s %s' % (rtype, rvar))
   125         for attr, value in kwargs.iteritems():
   125             restrictions.append('%s eid %%(%s)s' % (rvar, rvar))
   126             if isinstance(value, (tuple, list, set, frozenset)):
   126             cachekey.append(rvar)
   127                 if len(value) == 1:
   127         for attr in kwargs:
   128                     value = iter(value).next()
   128             if attr in cachekey:
   129                 else:
   129                 continue
   130                     pending_relations.append( (attr, value) )
   130             relations.append('X %s %%(%s)s' % (attr, attr))
   131                     continue
       
   132             if hasattr(value, 'eid'): # non final relation
       
   133                 rvar = attr.upper()
       
   134                 # XXX safer detection of object relation
       
   135                 if attr.startswith('reverse_'):
       
   136                     relations.append('%s %s X' % (rvar, attr[len('reverse_'):]))
       
   137                 else:
       
   138                     relations.append('X %s %s' % (attr, rvar))
       
   139                 restriction = '%s eid %%(%s)s' % (rvar, attr)
       
   140                 if not restriction in restrictions:
       
   141                     restrictions.add(restriction)
       
   142                 cachekey.append(attr)
       
   143                 kwargs[attr] = value.eid
       
   144             else: # attribute
       
   145                 relations.append('X %s %%(%s)s' % (attr, attr))
   131         if relations:
   146         if relations:
   132             rql = '%s: %s' % (rql, ', '.join(relations))
   147             rql = '%s: %s' % (rql, ', '.join(relations))
   133         if restrictions:
   148         if restrictions:
   134             rql = '%s WHERE %s' % (rql, ', '.join(restrictions))
   149             rql = '%s WHERE %s' % (rql, ', '.join(restrictions))
   135         return self.execute(rql, kwargs, cachekey).get_entity(0, 0)
   150         created = self.execute(rql, kwargs, cachekey).get_entity(0, 0)
       
   151         for attr, values in pending_relations:
       
   152             if attr.startswith('reverse_'):
       
   153                 restr = 'Y %s X' % attr[len('reverse_'):]
       
   154             else:
       
   155                 restr = 'X %s Y' % attr
       
   156             self.execute('SET %s WHERE X eid %%(x)s, Y eid IN (%s)' % (
       
   157                 restr, ','.join(str(r.eid) for r in values)),
       
   158                          {'x': created.eid}, 'x')
       
   159         return created
   136 
   160 
   137     def ensure_ro_rql(self, rql):
   161     def ensure_ro_rql(self, rql):
   138         """raise an exception if the given rql is not a select query"""
   162         """raise an exception if the given rql is not a select query"""
   139         first = rql.split(' ', 1)[0].lower()
   163         first = rql.split(' ', 1)[0].lower()
   140         if first in ('insert', 'set', 'delete'):
   164         if first in ('insert', 'set', 'delete'):