# HG changeset patch # User Sylvain Thénault # Date 1270818421 -7200 # Node ID ebb50479d2abd1fd06bd452cb5c6c273ba55a8ae # Parent cf8292f803842dd5c899c1545e8afc3c43d0f941 [entity] move req.create_entity content to a cw_instantiate factory method on entity classes, so cube developpers will be able to easily customize instance creation diff -r cf8292f80384 -r ebb50479d2ab entity.py --- a/entity.py Fri Apr 09 15:04:56 2010 +0200 +++ b/entity.py Fri Apr 09 15:07:01 2010 +0200 @@ -202,6 +202,59 @@ needcheck = False return mainattr, needcheck + @classmethod + def cw_instantiate(cls, execute, **kwargs): + """add a new entity of this given type + + Example (in a shell session): + + >>> companycls = vreg['etypes'].etype_class(('Company') + >>> personcls = vreg['etypes'].etype_class(('Person') + >>> c = companycls.cw_instantiate(req.execute, name=u'Logilab') + >>> personcls.cw_instantiate(req.execute, firstname=u'John', lastname=u'Doe', + ... works_for=c) + + """ + rql = 'INSERT %s X' % cls.__regid__ + relations = [] + restrictions = set() + pending_relations = [] + for attr, value in kwargs.items(): + if isinstance(value, (tuple, list, set, frozenset)): + if len(value) == 1: + value = iter(value).next() + else: + del kwargs[attr] + pending_relations.append( (attr, value) ) + continue + if hasattr(value, 'eid'): # non final relation + rvar = attr.upper() + # XXX safer detection of object relation + if attr.startswith('reverse_'): + relations.append('%s %s X' % (rvar, attr[len('reverse_'):])) + else: + relations.append('X %s %s' % (attr, rvar)) + restriction = '%s eid %%(%s)s' % (rvar, attr) + if not restriction in restrictions: + restrictions.add(restriction) + kwargs[attr] = value.eid + else: # attribute + relations.append('X %s %%(%s)s' % (attr, attr)) + if relations: + rql = '%s: %s' % (rql, ', '.join(relations)) + if restrictions: + rql = '%s WHERE %s' % (rql, ', '.join(restrictions)) + created = execute(rql, kwargs).get_entity(0, 0) + for attr, values in pending_relations: + if attr.startswith('reverse_'): + restr = 'Y %s X' % attr[len('reverse_'):] + else: + restr = 'X %s Y' % attr + execute('SET %s WHERE X eid %%(x)s, Y eid IN (%s)' % ( + restr, ','.join(str(r.eid) for r in values)), + {'x': created.eid}, build_descr=False) + return created + def __init__(self, req, rset=None, row=None, col=0): AppObject.__init__(self, req, rset=rset, row=row, col=col) dict.__init__(self) diff -r cf8292f80384 -r ebb50479d2ab req.py --- a/req.py Fri Apr 09 15:04:56 2010 +0200 +++ b/req.py Fri Apr 09 15:07:01 2010 +0200 @@ -119,9 +119,6 @@ def set_entity_cache(self, entity): pass - # XXX move to CWEntityManager or even better as factory method (unclear - # where yet...) - def create_entity(self, etype, **kwargs): """add a new entity of the given type @@ -133,48 +130,8 @@ """ _check_cw_unsafe(kwargs) - execute = self.execute - rql = 'INSERT %s X' % etype - relations = [] - restrictions = set() - cachekey = [] - pending_relations = [] - for attr, value in kwargs.items(): - if isinstance(value, (tuple, list, set, frozenset)): - if len(value) == 1: - value = iter(value).next() - else: - del kwargs[attr] - pending_relations.append( (attr, value) ) - continue - if hasattr(value, 'eid'): # non final relation - rvar = attr.upper() - # XXX safer detection of object relation - if attr.startswith('reverse_'): - relations.append('%s %s X' % (rvar, attr[len('reverse_'):])) - else: - relations.append('X %s %s' % (attr, rvar)) - restriction = '%s eid %%(%s)s' % (rvar, attr) - if not restriction in restrictions: - restrictions.add(restriction) - cachekey.append(attr) - kwargs[attr] = value.eid - else: # attribute - relations.append('X %s %%(%s)s' % (attr, attr)) - if relations: - rql = '%s: %s' % (rql, ', '.join(relations)) - if restrictions: - rql = '%s WHERE %s' % (rql, ', '.join(restrictions)) - created = execute(rql, kwargs, cachekey).get_entity(0, 0) - for attr, values in pending_relations: - if attr.startswith('reverse_'): - restr = 'Y %s X' % attr[len('reverse_'):] - else: - restr = 'X %s Y' % attr - execute('SET %s WHERE X eid %%(x)s, Y eid IN (%s)' % ( - restr, ','.join(str(r.eid) for r in values)), - {'x': created.eid}, 'x', build_descr=False) - return created + cls = self.vreg['etypes'].etype_class(etype) + return cls.cw_instantiate(self.execute, **kwargs) def ensure_ro_rql(self, rql): """raise an exception if the given rql is not a select query"""