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