81 for rschema, _ in eschema.attribute_definitions(): |
81 for rschema, _ in eschema.attribute_definitions(): |
82 if rschema.type == 'eid': |
82 if rschema.type == 'eid': |
83 continue |
83 continue |
84 setattr(cls, rschema.type, Attribute(rschema.type)) |
84 setattr(cls, rschema.type, Attribute(rschema.type)) |
85 mixins = [] |
85 mixins = [] |
86 for rschema, _, x in eschema.relation_definitions(): |
86 for rschema, _, role in eschema.relation_definitions(): |
87 if (rschema, x) in MI_REL_TRIGGERS: |
87 if (rschema, role) in MI_REL_TRIGGERS: |
88 mixin = MI_REL_TRIGGERS[(rschema, x)] |
88 mixin = MI_REL_TRIGGERS[(rschema, role)] |
89 if not (issubclass(cls, mixin) or mixin in mixins): # already mixed ? |
89 if not (issubclass(cls, mixin) or mixin in mixins): # already mixed ? |
90 mixins.append(mixin) |
90 mixins.append(mixin) |
91 for iface in getattr(mixin, '__implements__', ()): |
91 for iface in getattr(mixin, '__implements__', ()): |
92 if not interface.implements(cls, iface): |
92 if not interface.implements(cls, iface): |
93 interface.extend(cls, iface) |
93 interface.extend(cls, iface) |
94 if x == 'subject': |
94 if role == 'subject': |
95 setattr(cls, rschema.type, SubjectRelation(rschema)) |
95 setattr(cls, rschema.type, SubjectRelation(rschema)) |
96 else: |
96 else: |
97 attr = 'reverse_%s' % rschema.type |
97 attr = 'reverse_%s' % rschema.type |
98 setattr(cls, attr, ObjectRelation(rschema)) |
98 setattr(cls, attr, ObjectRelation(rschema)) |
99 if mixins: |
99 if mixins: |
150 if not rschema.is_final(): |
150 if not rschema.is_final(): |
151 # XXX this does not handle several destination types |
151 # XXX this does not handle several destination types |
152 desttype = rschema.objects(eschema.type)[0] |
152 desttype = rschema.objects(eschema.type)[0] |
153 card = rschema.rproperty(eschema, desttype, 'cardinality')[0] |
153 card = rschema.rproperty(eschema, desttype, 'cardinality')[0] |
154 if card not in '?1': |
154 if card not in '?1': |
155 self.warning('bad relation %s specified in fetch attrs for %s', |
155 cls.warning('bad relation %s specified in fetch attrs for %s', |
156 attr, self.__class__) |
156 attr, cls) |
157 selection.pop() |
157 selection.pop() |
158 restrictions.pop() |
158 restrictions.pop() |
159 continue |
159 continue |
160 # XXX we need outer join in case the relation is not mandatory |
160 # XXX we need outer join in case the relation is not mandatory |
161 # (card == '?') *or if the entity is being added*, since in |
161 # (card == '?') *or if the entity is being added*, since in |
377 # skip already defined relations |
377 # skip already defined relations |
378 if getattr(self, rschema.type): |
378 if getattr(self, rschema.type): |
379 continue |
379 continue |
380 if rschema.type in self.skip_copy_for: |
380 if rschema.type in self.skip_copy_for: |
381 continue |
381 continue |
382 if rschema.type == 'in_state': |
|
383 # if the workflow is defining an initial state (XXX AND we are |
|
384 # not in the managers group? not done to be more consistent) |
|
385 # don't try to copy in_state |
|
386 if execute('Any S WHERE S state_of ET, ET initial_state S,' |
|
387 'ET name %(etype)s', {'etype': str(self.e_schema)}): |
|
388 continue |
|
389 # skip composite relation |
382 # skip composite relation |
390 if self.e_schema.subjrproperty(rschema, 'composite'): |
383 if self.e_schema.subjrproperty(rschema, 'composite'): |
391 continue |
384 continue |
392 # skip relation with card in ?1 else we either change the copied |
385 # skip relation with card in ?1 else we either change the copied |
393 # object (inlined relation) or inserting some inconsistency |
386 # object (inlined relation) or inserting some inconsistency |
514 # handle attributes |
507 # handle attributes |
515 for i in xrange(1, lastattr): |
508 for i in xrange(1, lastattr): |
516 self[str(selected[i-1][0])] = rset[i] |
509 self[str(selected[i-1][0])] = rset[i] |
517 # handle relations |
510 # handle relations |
518 for i in xrange(lastattr, len(rset)): |
511 for i in xrange(lastattr, len(rset)): |
519 rtype, x = selected[i-1][0] |
512 rtype, role = selected[i-1][0] |
520 value = rset[i] |
513 value = rset[i] |
521 if value is None: |
514 if value is None: |
522 rrset = ResultSet([], rql, {'x': self.eid}) |
515 rrset = ResultSet([], rql, {'x': self.eid}) |
523 self.req.decorate_rset(rrset) |
516 self.req.decorate_rset(rrset) |
524 else: |
517 else: |
525 rrset = self.req.eid_rset(value) |
518 rrset = self.req.eid_rset(value) |
526 self.set_related_cache(rtype, x, rrset) |
519 self.set_related_cache(rtype, role, rrset) |
527 |
520 |
528 def get_value(self, name): |
521 def get_value(self, name): |
529 """get value for the attribute relation <name>, query the repository |
522 """get value for the attribute relation <name>, query the repository |
530 to get the value if necessary. |
523 to get the value if necessary. |
531 |
524 |
710 self._related_cache = {} |
703 self._related_cache = {} |
711 else: |
704 else: |
712 assert role |
705 assert role |
713 self._related_cache.pop('%s_%s' % (rtype, role), None) |
706 self._related_cache.pop('%s_%s' % (rtype, role), None) |
714 |
707 |
|
708 def clear_all_caches(self): |
|
709 self.clear() |
|
710 for rschema, _, role in self.e_schema.relation_definitions(): |
|
711 self.clear_related_cache(rschema.type, role) |
|
712 |
715 # raw edition utilities ################################################### |
713 # raw edition utilities ################################################### |
716 |
714 |
717 def set_attributes(self, _cw_unsafe=False, **kwargs): |
715 def set_attributes(self, _cw_unsafe=False, **kwargs): |
718 assert kwargs |
716 assert kwargs |
719 relations = [] |
717 relations = [] |