hooks/syncschema.py
changeset 6225 a176e68b7d0d
parent 6173 eb386e473044
parent 6208 07b176640a8c
child 6279 42079f752a9c
equal deleted inserted replaced
6182:30de0be8f895 6225:a176e68b7d0d
   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):