701 self.size_cstr_changed = True |
701 self.size_cstr_changed = True |
702 elif cstrtype == 'UniqueConstraint' and oldcstr is None: |
702 elif cstrtype == 'UniqueConstraint' and oldcstr is None: |
703 syssource.update_rdef_unique(session, rdef) |
703 syssource.update_rdef_unique(session, rdef) |
704 self.unique_changed = True |
704 self.unique_changed = True |
705 |
705 |
|
706 class CWUniqueTogetherConstraintAddOp(MemSchemaOperation): |
|
707 entity = None # make pylint happy |
|
708 def precommit_event(self): |
|
709 session = self.session |
|
710 prefix = SQL_PREFIX |
|
711 table = '%s%s' % (prefix, self.entity.constraint_of[0].name) |
|
712 cols = ['%s%s' % (prefix, r.rtype.name) |
|
713 for r in self.entity.relations] |
|
714 dbhelper= session.pool.source('system').dbhelper |
|
715 sql = dbhelper.sql_create_multicol_unique_index(table, cols) |
|
716 session.system_sql(sql) |
|
717 |
|
718 # XXX revertprecommit_event |
|
719 |
|
720 def postcommit_event(self): |
|
721 eschema = self.session.vreg.schema.schema_by_eid(self.entity.constraint_of[0].eid) |
|
722 attrs = [r.rtype.name for r in self.entity.relations] |
|
723 eschema._unique_together.append(attrs) |
|
724 |
|
725 class CWUniqueTogetherConstraintDelOp(MemSchemaOperation): |
|
726 entity = oldcstr = None # for pylint |
|
727 cols = [] # for pylint |
|
728 def precommit_event(self): |
|
729 session = self.session |
|
730 prefix = SQL_PREFIX |
|
731 table = '%s%s' % (prefix, self.entity.type) |
|
732 dbhelper= session.pool.source('system').dbhelper |
|
733 cols = ['%s%s' % (prefix, c) for c in self.cols] |
|
734 sql = dbhelper.sql_drop_multicol_unique_index(table, cols) |
|
735 session.system_sql(sql) |
|
736 |
|
737 # XXX revertprecommit_event |
|
738 |
|
739 def postcommit_event(self): |
|
740 eschema = self.session.vreg.schema.schema_by_eid(self.entity.eid) |
|
741 cols = set(self.cols) |
|
742 unique_together = [ut for ut in eschema._unique_together |
|
743 if set(ut) != cols] |
|
744 eschema._unique_together = unique_together |
706 |
745 |
707 # operations for in-memory schema synchronization ############################# |
746 # operations for in-memory schema synchronization ############################# |
708 |
747 |
709 class MemSchemaCWETypeDel(MemSchemaOperation): |
748 class MemSchemaCWETypeDel(MemSchemaOperation): |
710 """actually remove the entity type from the instance's schema""" |
749 """actually remove the entity type from the instance's schema""" |
1047 def __call__(self): |
1086 def __call__(self): |
1048 CWConstraintAddOp(self._cw, entity=self.entity) |
1087 CWConstraintAddOp(self._cw, entity=self.entity) |
1049 |
1088 |
1050 |
1089 |
1051 class AfterAddConstrainedByHook(SyncSchemaHook): |
1090 class AfterAddConstrainedByHook(SyncSchemaHook): |
|
1091 __regid__ = 'syncaddconstrainedby' |
|
1092 __select__ = SyncSchemaHook.__select__ & hook.match_rtype('constrained_by') |
|
1093 events = ('after_add_relation',) |
|
1094 |
|
1095 def __call__(self): |
|
1096 if self._cw.added_in_transaction(self.eidfrom): |
|
1097 # used by get_constraints() which is called in CWAttributeAddOp |
|
1098 self._cw.transaction_data.setdefault(self.eidfrom, []).append(self.eidto) |
|
1099 |
|
1100 |
|
1101 class BeforeDeleteConstrainedByHook(SyncSchemaHook): |
1052 __regid__ = 'syncdelconstrainedby' |
1102 __regid__ = 'syncdelconstrainedby' |
1053 __select__ = SyncSchemaHook.__select__ & hook.match_rtype('constrained_by') |
1103 __select__ = SyncSchemaHook.__select__ & hook.match_rtype('constrained_by') |
1054 events = ('after_add_relation',) |
|
1055 |
|
1056 def __call__(self): |
|
1057 if self._cw.added_in_transaction(self.eidfrom): |
|
1058 self._cw.transaction_data.setdefault(self.eidfrom, []).append(self.eidto) |
|
1059 |
|
1060 |
|
1061 class BeforeDeleteConstrainedByHook(AfterAddConstrainedByHook): |
|
1062 __regid__ = 'syncdelconstrainedby' |
|
1063 events = ('before_delete_relation',) |
1104 events = ('before_delete_relation',) |
1064 |
1105 |
1065 def __call__(self): |
1106 def __call__(self): |
1066 if self._cw.deleted_in_transaction(self.eidfrom): |
1107 if self._cw.deleted_in_transaction(self.eidfrom): |
1067 return |
1108 return |
1072 cstr = rdef.constraint_by_type(entity.type) |
1113 cstr = rdef.constraint_by_type(entity.type) |
1073 except IndexError: |
1114 except IndexError: |
1074 self._cw.critical('constraint type no more accessible') |
1115 self._cw.critical('constraint type no more accessible') |
1075 else: |
1116 else: |
1076 CWConstraintDelOp(self._cw, rdef=rdef, oldcstr=cstr) |
1117 CWConstraintDelOp(self._cw, rdef=rdef, oldcstr=cstr) |
|
1118 |
|
1119 # unique_together constraints |
|
1120 # XXX: use setoperations and before_add_relation here (on constraint_of and relations) |
|
1121 class AfterAddCWUniqueTogetherConstraintHook(SyncSchemaHook): |
|
1122 __regid__ = 'syncadd_cwuniquetogether_constraint' |
|
1123 __select__ = SyncSchemaHook.__select__ & is_instance('CWUniqueTogetherConstraint') |
|
1124 events = ('after_add_entity', 'after_update_entity') |
|
1125 |
|
1126 def __call__(self): |
|
1127 CWUniqueTogetherConstraintAddOp(self._cw, entity=self.entity) |
|
1128 |
|
1129 |
|
1130 class BeforeDeleteConstraintOfHook(SyncSchemaHook): |
|
1131 __regid__ = 'syncdelconstraintof' |
|
1132 __select__ = SyncSchemaHook.__select__ & hook.match_rtype('constraint_of') |
|
1133 events = ('before_delete_relation',) |
|
1134 |
|
1135 def __call__(self): |
|
1136 if self._cw.deleted_in_transaction(self.eidto): |
|
1137 return |
|
1138 schema = self._cw.vreg.schema |
|
1139 cstr = self._cw.entity_from_eid(self.eidfrom) |
|
1140 entity = schema.schema_by_eid(self.eidto) |
|
1141 cols = [r.rtype.name |
|
1142 for r in cstr.relations] |
|
1143 CWUniqueTogetherConstraintDelOp(self._cw, entity=entity, oldcstr=cstr, cols=cols) |
1077 |
1144 |
1078 |
1145 |
1079 # permissions synchronization hooks ############################################ |
1146 # permissions synchronization hooks ############################################ |
1080 |
1147 |
1081 class AfterAddPermissionHook(SyncSchemaHook): |
1148 class AfterAddPermissionHook(SyncSchemaHook): |