357 # final relations are not infered, propagate |
357 # final relations are not infered, propagate |
358 try: |
358 try: |
359 eschema = self.schema.eschema(rdef.subject) |
359 eschema = self.schema.eschema(rdef.subject) |
360 except KeyError: |
360 except KeyError: |
361 return # entity type currently being added |
361 return # entity type currently being added |
|
362 # propagate attribute to children classes |
362 rschema = self.schema.rschema(rdef.name) |
363 rschema = self.schema.rschema(rdef.name) |
|
364 # if relation type has been inserted in the same transaction, its final |
|
365 # attribute is still set to False, so we've to ensure it's False |
|
366 rschema.final = True |
|
367 # XXX 'infered': True/False, not clear actually |
363 props.update({'constraints': rdef.constraints, |
368 props.update({'constraints': rdef.constraints, |
364 'description': rdef.description, |
369 'description': rdef.description, |
365 'cardinality': rdef.cardinality, |
370 'cardinality': rdef.cardinality, |
366 'constraints': rdef.constraints, |
371 'constraints': rdef.constraints, |
367 'order': rdef.order}) |
372 'order': rdef.order}) |
369 if rschema.has_rdef(specialization, rdef.object): |
374 if rschema.has_rdef(specialization, rdef.object): |
370 continue |
375 continue |
371 for rql, args in ss.frdef2rql(rschema, str(specialization), |
376 for rql, args in ss.frdef2rql(rschema, str(specialization), |
372 rdef.object, props): |
377 rdef.object, props): |
373 session.execute(rql, args) |
378 session.execute(rql, args) |
|
379 # set default value, using sql for performance and to avoid |
|
380 # modification_date update |
|
381 if default: |
|
382 session.system_sql('UPDATE %s SET %s=%%(default)s' % (table, column), |
|
383 {'default': default}) |
374 |
384 |
375 |
385 |
376 class SourceDbCWRelationAdd(SourceDbCWAttributeAdd): |
386 class SourceDbCWRelationAdd(SourceDbCWAttributeAdd): |
377 """an actual relation has been added: |
387 """an actual relation has been added: |
378 * if this is an inlined relation, add the necessary column |
388 * if this is an inlined relation, add the necessary column |
963 |
973 |
964 def __call__(self): |
974 def __call__(self): |
965 session = self._cw |
975 session = self._cw |
966 subjschema, rschema, objschema = session.vreg.schema.schema_by_eid(self.eidfrom) |
976 subjschema, rschema, objschema = session.vreg.schema.schema_by_eid(self.eidfrom) |
967 pendings = session.transaction_data.get('pendingeids', ()) |
977 pendings = session.transaction_data.get('pendingeids', ()) |
|
978 pendingrdefs = session.transaction_data.setdefault('pendingrdefs', set()) |
968 # first delete existing relation if necessary |
979 # first delete existing relation if necessary |
969 if rschema.is_final(): |
980 if rschema.is_final(): |
970 rdeftype = 'CWAttribute' |
981 rdeftype = 'CWAttribute' |
|
982 pendingrdefs.add((subjschema, rschema)) |
971 else: |
983 else: |
972 rdeftype = 'CWRelation' |
984 rdeftype = 'CWRelation' |
|
985 pendingrdefs.add((subjschema, rschema, objschema)) |
973 if not (subjschema.eid in pendings or objschema.eid in pendings): |
986 if not (subjschema.eid in pendings or objschema.eid in pendings): |
974 pending = session.transaction_data.setdefault('pendingrdefs', set()) |
|
975 pending.add((subjschema, rschema, objschema)) |
|
976 session.execute('DELETE X %s Y WHERE X is %s, Y is %s' |
987 session.execute('DELETE X %s Y WHERE X is %s, Y is %s' |
977 % (rschema, subjschema, objschema)) |
988 % (rschema, subjschema, objschema)) |
978 execute = session.unsafe_execute |
989 execute = session.unsafe_execute |
979 rteid = self.eidto |
990 rteid = self.eidto |
980 rset = execute('Any COUNT(X) WHERE X is %s, X relation_type R,' |
991 rset = execute('Any COUNT(X) WHERE X is %s, X relation_type R,' |