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 = {} |