136 class MemSchemaNotifyChanges(hook.SingleLastOperation): |
136 class MemSchemaNotifyChanges(hook.SingleLastOperation): |
137 """the update schema operation: |
137 """the update schema operation: |
138 |
138 |
139 special operation which should be called once and after all other schema |
139 special operation which should be called once and after all other schema |
140 operations. It will trigger internal structures rebuilding to consider |
140 operations. It will trigger internal structures rebuilding to consider |
141 schema changes |
141 schema changes. |
142 """ |
142 """ |
143 |
143 |
144 def __init__(self, session): |
144 def __init__(self, session): |
145 hook.SingleLastOperation.__init__(self, session) |
145 hook.SingleLastOperation.__init__(self, session) |
146 |
146 |
147 def commit_event(self): |
147 def commit_event(self): |
148 self.repo.set_schema(self.repo.schema) |
148 self.session.repo.set_schema(self.session.repo.schema) |
149 |
149 |
150 |
150 |
151 class MemSchemaOperation(hook.Operation): |
151 class MemSchemaOperation(hook.Operation): |
152 """base class for schema operations""" |
152 """base class for schema operations""" |
153 def __init__(self, session, kobj=None, **kwargs): |
153 def __init__(self, session, kobj=None, **kwargs): |
367 |
367 |
368 def precommit_event(self): |
368 def precommit_event(self): |
369 session = self.session |
369 session = self.session |
370 entity = self.entity |
370 entity = self.entity |
371 rdef = self.init_rdef(composite=entity.composite) |
371 rdef = self.init_rdef(composite=entity.composite) |
372 schema = session.schema |
372 schema = session.vreg.schema |
373 rtype = rdef.name |
373 rtype = rdef.name |
374 rschema = session.schema.rschema(rtype) |
374 rschema = session.vreg.schema.rschema(rtype) |
375 # this have to be done before permissions setting |
375 # this have to be done before permissions setting |
376 if rschema.inlined: |
376 if rschema.inlined: |
377 # need to add a column if the relation is inlined and if this is the |
377 # need to add a column if the relation is inlined and if this is the |
378 # first occurence of "Subject relation Something" whatever Something |
378 # first occurence of "Subject relation Something" whatever Something |
379 # and if it has not been added during other event of the same |
379 # and if it has not been added during other event of the same |
391 # schema and if it has not been added during other event of the same |
391 # schema and if it has not been added during other event of the same |
392 # transaction |
392 # transaction |
393 if not (rschema.subjects() or |
393 if not (rschema.subjects() or |
394 rtype in session.transaction_data.get('createdtables', ())): |
394 rtype in session.transaction_data.get('createdtables', ())): |
395 try: |
395 try: |
396 rschema = session.schema.rschema(rtype) |
396 rschema = session.vreg.schema.rschema(rtype) |
397 tablesql = rschema2sql(rschema) |
397 tablesql = rschema2sql(rschema) |
398 except KeyError: |
398 except KeyError: |
399 # fake we add it to the schema now to get a correctly |
399 # fake we add it to the schema now to get a correctly |
400 # initialized schema but remove it before doing anything |
400 # initialized schema but remove it before doing anything |
401 # more dangerous... |
401 # more dangerous... |
402 rschema = session.schema.add_relation_type(rdef) |
402 rschema = session.vreg.schema.add_relation_type(rdef) |
403 tablesql = rschema2sql(rschema) |
403 tablesql = rschema2sql(rschema) |
404 session.schema.del_relation_type(rtype) |
404 session.vreg.schema.del_relation_type(rtype) |
405 # create the necessary table |
405 # create the necessary table |
406 for sql in tablesql.split(';'): |
406 for sql in tablesql.split(';'): |
407 if sql.strip(): |
407 if sql.strip(): |
408 session.system_sql(sql) |
408 session.system_sql(sql) |
409 session.transaction_data.setdefault('createdtables', []).append( |
409 session.transaction_data.setdefault('createdtables', []).append( |
451 # when the relation is added in the same transaction, the constraint |
451 # when the relation is added in the same transaction, the constraint |
452 # object is created by the operation adding the attribute or relation, |
452 # object is created by the operation adding the attribute or relation, |
453 # so there is nothing to do here |
453 # so there is nothing to do here |
454 if session.added_in_transaction(rdef.eid): |
454 if session.added_in_transaction(rdef.eid): |
455 return |
455 return |
456 subjtype, rtype, objtype = session.schema.schema_by_eid(rdef.eid) |
456 subjtype, rtype, objtype = session.vreg.schema.schema_by_eid(rdef.eid) |
457 cstrtype = self.entity.type |
457 cstrtype = self.entity.type |
458 oldcstr = rtype.constraint_by_type(subjtype, objtype, cstrtype) |
458 oldcstr = rtype.constraint_by_type(subjtype, objtype, cstrtype) |
459 newcstr = CONSTRAINTS[cstrtype].deserialize(self.entity.value) |
459 newcstr = CONSTRAINTS[cstrtype].deserialize(self.entity.value) |
460 table = SQL_PREFIX + str(subjtype) |
460 table = SQL_PREFIX + str(subjtype) |
461 column = SQL_PREFIX + str(rtype) |
461 column = SQL_PREFIX + str(rtype) |
515 class MemSchemaCWETypeRename(MemSchemaOperation): |
515 class MemSchemaCWETypeRename(MemSchemaOperation): |
516 """this operation updates physical storage accordingly""" |
516 """this operation updates physical storage accordingly""" |
517 oldname = newname = None # make pylint happy |
517 oldname = newname = None # make pylint happy |
518 |
518 |
519 def commit_event(self): |
519 def commit_event(self): |
520 self.session.schema.rename_entity_type(self.oldname, self.newname) |
520 self.session.vreg.schema.rename_entity_type(self.oldname, self.newname) |
521 |
521 |
522 |
522 |
523 class MemSchemaCWETypeDel(MemSchemaOperation): |
523 class MemSchemaCWETypeDel(MemSchemaOperation): |
524 """actually remove the entity type from the instance's schema""" |
524 """actually remove the entity type from the instance's schema""" |
525 def commit_event(self): |
525 def commit_event(self): |
601 # object is created by the operation adding the attribute or relation, |
601 # object is created by the operation adding the attribute or relation, |
602 # so there is nothing to do here |
602 # so there is nothing to do here |
603 if self.session.added_in_transaction(rdef.eid): |
603 if self.session.added_in_transaction(rdef.eid): |
604 self.cancelled = True |
604 self.cancelled = True |
605 return |
605 return |
606 subjtype, rtype, objtype = self.session.schema.schema_by_eid(rdef.eid) |
606 subjtype, rtype, objtype = self.session.vreg.schema.schema_by_eid(rdef.eid) |
607 self.prepare_constraints(subjtype, rtype, objtype) |
607 self.prepare_constraints(subjtype, rtype, objtype) |
608 cstrtype = self.entity.type |
608 cstrtype = self.entity.type |
609 self.cstr = rtype.constraint_by_type(subjtype, objtype, cstrtype) |
609 self.cstr = rtype.constraint_by_type(subjtype, objtype, cstrtype) |
610 self.newcstr = CONSTRAINTS[cstrtype].deserialize(self.entity.value) |
610 self.newcstr = CONSTRAINTS[cstrtype].deserialize(self.entity.value) |
611 self.newcstr.eid = self.entity.eid |
611 self.newcstr.eid = self.entity.eid |
919 __select__ = SyncSchemaHook.__select__ & hook.match_rtype('relation_type') |
919 __select__ = SyncSchemaHook.__select__ & hook.match_rtype('relation_type') |
920 events = ('after_delete_relation',) |
920 events = ('after_delete_relation',) |
921 |
921 |
922 def __call__(self): |
922 def __call__(self): |
923 session = self._cw |
923 session = self._cw |
924 subjschema, rschema, objschema = session.schema.schema_by_eid(self.eidfrom) |
924 subjschema, rschema, objschema = session.vreg.schema.schema_by_eid(self.eidfrom) |
925 pendings = session.transaction_data.get('pendingeids', ()) |
925 pendings = session.transaction_data.get('pendingeids', ()) |
926 # first delete existing relation if necessary |
926 # first delete existing relation if necessary |
927 if rschema.is_final(): |
927 if rschema.is_final(): |
928 rdeftype = 'CWAttribute' |
928 rdeftype = 'CWAttribute' |
929 else: |
929 else: |