entity.py
branchstable
changeset 5199 ebb50479d2ab
parent 5144 5a09bea07302
child 5201 2b4267157f85
child 5320 848e92bb81cc
equal deleted inserted replaced
5198:cf8292f80384 5199:ebb50479d2ab
   199                     needcheck = False
   199                     needcheck = False
   200                     break
   200                     break
   201         if mainattr == 'eid':
   201         if mainattr == 'eid':
   202             needcheck = False
   202             needcheck = False
   203         return mainattr, needcheck
   203         return mainattr, needcheck
       
   204 
       
   205     @classmethod
       
   206     def cw_instantiate(cls, execute, **kwargs):
       
   207         """add a new entity of this given type
       
   208 
       
   209         Example (in a shell session):
       
   210 
       
   211         >>> companycls = vreg['etypes'].etype_class(('Company')
       
   212         >>> personcls = vreg['etypes'].etype_class(('Person')
       
   213         >>> c = companycls.cw_instantiate(req.execute, name=u'Logilab')
       
   214         >>> personcls.cw_instantiate(req.execute, firstname=u'John', lastname=u'Doe',
       
   215         ...                          works_for=c)
       
   216 
       
   217         """
       
   218         rql = 'INSERT %s X' % cls.__regid__
       
   219         relations = []
       
   220         restrictions = set()
       
   221         pending_relations = []
       
   222         for attr, value in kwargs.items():
       
   223             if isinstance(value, (tuple, list, set, frozenset)):
       
   224                 if len(value) == 1:
       
   225                     value = iter(value).next()
       
   226                 else:
       
   227                     del kwargs[attr]
       
   228                     pending_relations.append( (attr, value) )
       
   229                     continue
       
   230             if hasattr(value, 'eid'): # non final relation
       
   231                 rvar = attr.upper()
       
   232                 # XXX safer detection of object relation
       
   233                 if attr.startswith('reverse_'):
       
   234                     relations.append('%s %s X' % (rvar, attr[len('reverse_'):]))
       
   235                 else:
       
   236                     relations.append('X %s %s' % (attr, rvar))
       
   237                 restriction = '%s eid %%(%s)s' % (rvar, attr)
       
   238                 if not restriction in restrictions:
       
   239                     restrictions.add(restriction)
       
   240                 kwargs[attr] = value.eid
       
   241             else: # attribute
       
   242                 relations.append('X %s %%(%s)s' % (attr, attr))
       
   243         if relations:
       
   244             rql = '%s: %s' % (rql, ', '.join(relations))
       
   245         if restrictions:
       
   246             rql = '%s WHERE %s' % (rql, ', '.join(restrictions))
       
   247         created = execute(rql, kwargs).get_entity(0, 0)
       
   248         for attr, values in pending_relations:
       
   249             if attr.startswith('reverse_'):
       
   250                 restr = 'Y %s X' % attr[len('reverse_'):]
       
   251             else:
       
   252                 restr = 'X %s Y' % attr
       
   253             execute('SET %s WHERE X eid %%(x)s, Y eid IN (%s)' % (
       
   254                 restr, ','.join(str(r.eid) for r in values)),
       
   255                     {'x': created.eid}, build_descr=False)
       
   256         return created
   204 
   257 
   205     def __init__(self, req, rset=None, row=None, col=0):
   258     def __init__(self, req, rset=None, row=None, col=0):
   206         AppObject.__init__(self, req, rset=rset, row=row, col=col)
   259         AppObject.__init__(self, req, rset=rset, row=row, col=col)
   207         dict.__init__(self)
   260         dict.__init__(self)
   208         self._related_cache = {}
   261         self._related_cache = {}