Commit b74c66d7 authored by Sylvain Thénault's avatar Sylvain Thénault
Browse files

[entity] move req.create_entity content to a cw_instantiate factory method on...

[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

--HG--
branch : stable
parent cf8292f80384
......@@ -202,6 +202,59 @@ class Entity(AppObject, dict):
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)
......
......@@ -119,9 +119,6 @@ class RequestSessionBase(object):
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 @@ class RequestSessionBase(object):
"""
_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"""
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment