747 |
747 |
748 def __call__(self): |
748 def __call__(self): |
749 # final entities can't be deleted, don't care about that |
749 # final entities can't be deleted, don't care about that |
750 name = self.entity.name |
750 name = self.entity.name |
751 if name in CORE_ETYPES: |
751 if name in CORE_ETYPES: |
752 raise ValidationError(self.entity.eid, {None: self.cw_req._('can\'t be deleted')}) |
752 raise ValidationError(self.entity.eid, {None: self._cw._('can\'t be deleted')}) |
753 # delete every entities of this type |
753 # delete every entities of this type |
754 self.cw_req.unsafe_execute('DELETE %s X' % name) |
754 self._cw.unsafe_execute('DELETE %s X' % name) |
755 DropTable(self.cw_req, table=SQL_PREFIX + name) |
755 DropTable(self._cw, table=SQL_PREFIX + name) |
756 MemSchemaCWETypeDel(self.cw_req, name) |
756 MemSchemaCWETypeDel(self._cw, name) |
757 |
757 |
758 |
758 |
759 class AfterDelCWETypeHook(DelCWETypeHook): |
759 class AfterDelCWETypeHook(DelCWETypeHook): |
760 __id__ = 'wfcleanup' |
760 __id__ = 'wfcleanup' |
761 events = ('after_delete_entity',) |
761 events = ('after_delete_entity',) |
762 |
762 |
763 def __call__(self): |
763 def __call__(self): |
764 # workflow cleanup |
764 # workflow cleanup |
765 self.cw_req.execute('DELETE State X WHERE NOT X state_of Y') |
765 self._cw.execute('DELETE State X WHERE NOT X state_of Y') |
766 self.cw_req.execute('DELETE Transition X WHERE NOT X transition_of Y') |
766 self._cw.execute('DELETE Transition X WHERE NOT X transition_of Y') |
767 |
767 |
768 |
768 |
769 class AfterAddCWETypeHook(DelCWETypeHook): |
769 class AfterAddCWETypeHook(DelCWETypeHook): |
770 """after adding a CWEType entity: |
770 """after adding a CWEType entity: |
771 * create the necessary table |
771 * create the necessary table |
780 |
780 |
781 def __call__(self): |
781 def __call__(self): |
782 entity = self.entity |
782 entity = self.entity |
783 if entity.get('final'): |
783 if entity.get('final'): |
784 return |
784 return |
785 schema = self.cw_req.schema |
785 schema = self._cw.schema |
786 name = entity['name'] |
786 name = entity['name'] |
787 etype = EntityType(name=name, description=entity.get('description'), |
787 etype = EntityType(name=name, description=entity.get('description'), |
788 meta=entity.get('meta')) # don't care about final |
788 meta=entity.get('meta')) # don't care about final |
789 # fake we add it to the schema now to get a correctly initialized schema |
789 # fake we add it to the schema now to get a correctly initialized schema |
790 # but remove it before doing anything more dangerous... |
790 # but remove it before doing anything more dangerous... |
791 schema = self.cw_req.schema |
791 schema = self._cw.schema |
792 eschema = schema.add_entity_type(etype) |
792 eschema = schema.add_entity_type(etype) |
793 eschema.set_default_groups() |
793 eschema.set_default_groups() |
794 # generate table sql and rql to add metadata |
794 # generate table sql and rql to add metadata |
795 tablesql = eschema2sql(self.cw_req.pool.source('system').dbhelper, eschema, |
795 tablesql = eschema2sql(self._cw.pool.source('system').dbhelper, eschema, |
796 prefix=SQL_PREFIX) |
796 prefix=SQL_PREFIX) |
797 relrqls = [] |
797 relrqls = [] |
798 for rtype in (META_RTYPES - VIRTUAL_RTYPES): |
798 for rtype in (META_RTYPES - VIRTUAL_RTYPES): |
799 rschema = schema[rtype] |
799 rschema = schema[rtype] |
800 sampletype = rschema.subjects()[0] |
800 sampletype = rschema.subjects()[0] |
804 # now remove it ! |
804 # now remove it ! |
805 schema.del_entity_type(name) |
805 schema.del_entity_type(name) |
806 # create the necessary table |
806 # create the necessary table |
807 for sql in tablesql.split(';'): |
807 for sql in tablesql.split(';'): |
808 if sql.strip(): |
808 if sql.strip(): |
809 self.cw_req.system_sql(sql) |
809 self._cw.system_sql(sql) |
810 # register operation to modify the schema on commit |
810 # register operation to modify the schema on commit |
811 # this have to be done before adding other relations definitions |
811 # this have to be done before adding other relations definitions |
812 # or permission settings |
812 # or permission settings |
813 etype.eid = entity.eid |
813 etype.eid = entity.eid |
814 MemSchemaCWETypeAdd(self.cw_req, etype) |
814 MemSchemaCWETypeAdd(self._cw, etype) |
815 # add meta relations |
815 # add meta relations |
816 for rql, kwargs in relrqls: |
816 for rql, kwargs in relrqls: |
817 self.cw_req.execute(rql, kwargs) |
817 self._cw.execute(rql, kwargs) |
818 |
818 |
819 |
819 |
820 class BeforeUpdateCWETypeHook(DelCWETypeHook): |
820 class BeforeUpdateCWETypeHook(DelCWETypeHook): |
821 """check name change, handle final""" |
821 """check name change, handle final""" |
822 __id__ = 'syncupdatecwetype' |
822 __id__ = 'syncupdatecwetype' |
823 events = ('before_update_entity',) |
823 events = ('before_update_entity',) |
824 |
824 |
825 def __call__(self): |
825 def __call__(self): |
826 entity = self.entity |
826 entity = self.entity |
827 check_valid_changes(self.cw_req, entity, ro_attrs=('final',)) |
827 check_valid_changes(self._cw, entity, ro_attrs=('final',)) |
828 # don't use getattr(entity, attr), we would get the modified value if any |
828 # don't use getattr(entity, attr), we would get the modified value if any |
829 if 'name' in entity.edited_attributes: |
829 if 'name' in entity.edited_attributes: |
830 newname = entity.pop('name') |
830 newname = entity.pop('name') |
831 oldname = entity.name |
831 oldname = entity.name |
832 if newname.lower() != oldname.lower(): |
832 if newname.lower() != oldname.lower(): |
833 SourceDbCWETypeRename(self.cw_req, oldname=oldname, newname=newname) |
833 SourceDbCWETypeRename(self._cw, oldname=oldname, newname=newname) |
834 MemSchemaCWETypeRename(self.cw_req, oldname=oldname, newname=newname) |
834 MemSchemaCWETypeRename(self._cw, oldname=oldname, newname=newname) |
835 entity['name'] = newname |
835 entity['name'] = newname |
836 |
836 |
837 |
837 |
838 # CWRType hooks ################################################################ |
838 # CWRType hooks ################################################################ |
839 |
839 |
848 events = ('before_delete_entity',) |
848 events = ('before_delete_entity',) |
849 |
849 |
850 def __call__(self): |
850 def __call__(self): |
851 name = self.entity.name |
851 name = self.entity.name |
852 if name in CORE_ETYPES: |
852 if name in CORE_ETYPES: |
853 raise ValidationError(self.entity.eid, {None: self.cw_req._('can\'t be deleted')}) |
853 raise ValidationError(self.entity.eid, {None: self._cw._('can\'t be deleted')}) |
854 # delete relation definitions using this relation type |
854 # delete relation definitions using this relation type |
855 self.cw_req.execute('DELETE CWAttribute X WHERE X relation_type Y, Y eid %(x)s', |
855 self._cw.execute('DELETE CWAttribute X WHERE X relation_type Y, Y eid %(x)s', |
856 {'x': self.entity.eid}) |
856 {'x': self.entity.eid}) |
857 self.cw_req.execute('DELETE CWRelation X WHERE X relation_type Y, Y eid %(x)s', |
857 self._cw.execute('DELETE CWRelation X WHERE X relation_type Y, Y eid %(x)s', |
858 {'x': self.entity.eid}) |
858 {'x': self.entity.eid}) |
859 MemSchemaCWRTypeDel(self.cw_req, name) |
859 MemSchemaCWRTypeDel(self._cw, name) |
860 |
860 |
861 |
861 |
862 class AfterAddCWRTypeHook(DelCWRTypeHook): |
862 class AfterAddCWRTypeHook(DelCWRTypeHook): |
863 """after a CWRType entity has been added: |
863 """after a CWRType entity has been added: |
864 * register an operation to add the relation type to the instance's |
864 * register an operation to add the relation type to the instance's |
875 description=entity.get('description'), |
875 description=entity.get('description'), |
876 meta=entity.get('meta', False), |
876 meta=entity.get('meta', False), |
877 inlined=entity.get('inlined', False), |
877 inlined=entity.get('inlined', False), |
878 symetric=entity.get('symetric', False), |
878 symetric=entity.get('symetric', False), |
879 eid=entity.eid) |
879 eid=entity.eid) |
880 MemSchemaCWRTypeAdd(self.cw_req, rtype) |
880 MemSchemaCWRTypeAdd(self._cw, rtype) |
881 |
881 |
882 |
882 |
883 class BeforeUpdateCWRTypeHook(DelCWRTypeHook): |
883 class BeforeUpdateCWRTypeHook(DelCWRTypeHook): |
884 """check name change, handle final""" |
884 """check name change, handle final""" |
885 __id__ = 'checkupdatecwrtype' |
885 __id__ = 'checkupdatecwrtype' |
886 events = ('before_update_entity',) |
886 events = ('before_update_entity',) |
887 |
887 |
888 def __call__(self): |
888 def __call__(self): |
889 check_valid_changes(self.cw_req, self.entity) |
889 check_valid_changes(self._cw, self.entity) |
890 |
890 |
891 |
891 |
892 class AfterUpdateCWRTypeHook(DelCWRTypeHook): |
892 class AfterUpdateCWRTypeHook(DelCWRTypeHook): |
893 __id__ = 'syncupdatecwrtype' |
893 __id__ = 'syncupdatecwrtype' |
894 events = ('after_update_entity',) |
894 events = ('after_update_entity',) |
895 |
895 |
896 def __call__(self): |
896 def __call__(self): |
897 entity = self.entity |
897 entity = self.entity |
898 rschema = self.cw_req.schema.rschema(entity.name) |
898 rschema = self._cw.schema.rschema(entity.name) |
899 newvalues = {} |
899 newvalues = {} |
900 for prop in ('meta', 'symetric', 'inlined'): |
900 for prop in ('meta', 'symetric', 'inlined'): |
901 if prop in entity: |
901 if prop in entity: |
902 newvalues[prop] = entity[prop] |
902 newvalues[prop] = entity[prop] |
903 if newvalues: |
903 if newvalues: |
904 MemSchemaCWRTypeUpdate(self.cw_req, rschema=rschema, values=newvalues) |
904 MemSchemaCWRTypeUpdate(self._cw, rschema=rschema, values=newvalues) |
905 SourceDbCWRTypeUpdate(self.cw_req, rschema=rschema, values=newvalues, |
905 SourceDbCWRTypeUpdate(self._cw, rschema=rschema, values=newvalues, |
906 entity=entity) |
906 entity=entity) |
907 |
907 |
908 |
908 |
909 # relation_type hooks ########################################################## |
909 # relation_type hooks ########################################################## |
910 |
910 |
920 __id__ = 'syncdelrelationtype' |
920 __id__ = 'syncdelrelationtype' |
921 __select__ = SyncSchemaHook.__select__ & hook.match_rtype('relation_type') |
921 __select__ = SyncSchemaHook.__select__ & hook.match_rtype('relation_type') |
922 events = ('after_delete_relation',) |
922 events = ('after_delete_relation',) |
923 |
923 |
924 def __call__(self): |
924 def __call__(self): |
925 session = self.cw_req |
925 session = self._cw |
926 subjschema, rschema, objschema = session.schema.schema_by_eid(self.eidfrom) |
926 subjschema, rschema, objschema = session.schema.schema_by_eid(self.eidfrom) |
927 pendings = session.transaction_data.get('pendingeids', ()) |
927 pendings = session.transaction_data.get('pendingeids', ()) |
928 # first delete existing relation if necessary |
928 # first delete existing relation if necessary |
929 if rschema.is_final(): |
929 if rschema.is_final(): |
930 rdeftype = 'CWAttribute' |
930 rdeftype = 'CWAttribute' |
966 __id__ = 'syncaddcwattribute' |
966 __id__ = 'syncaddcwattribute' |
967 __select__ = SyncSchemaHook.__select__ & entity_implements('CWAttribute') |
967 __select__ = SyncSchemaHook.__select__ & entity_implements('CWAttribute') |
968 events = ('after_add_entity',) |
968 events = ('after_add_entity',) |
969 |
969 |
970 def __call__(self): |
970 def __call__(self): |
971 SourceDbCWAttributeAdd(self.cw_req, entity=self.entity) |
971 SourceDbCWAttributeAdd(self._cw, entity=self.entity) |
972 |
972 |
973 |
973 |
974 class AfterAddCWRelationHook(AfterAddCWAttributeHook): |
974 class AfterAddCWRelationHook(AfterAddCWAttributeHook): |
975 __id__ = 'syncaddcwrelation' |
975 __id__ = 'syncaddcwrelation' |
976 __select__ = SyncSchemaHook.__select__ & entity_implements('CWRelation') |
976 __select__ = SyncSchemaHook.__select__ & entity_implements('CWRelation') |
977 |
977 |
978 def __call__(self): |
978 def __call__(self): |
979 SourceDbCWRelationAdd(self.cw_req, entity=self.entity) |
979 SourceDbCWRelationAdd(self._cw, entity=self.entity) |
980 |
980 |
981 |
981 |
982 class AfterUpdateCWRDefHook(SyncSchemaHook): |
982 class AfterUpdateCWRDefHook(SyncSchemaHook): |
983 __id__ = 'syncaddcwattribute' |
983 __id__ = 'syncaddcwattribute' |
984 __select__ = SyncSchemaHook.__select__ & entity_implements('CWAttribute', |
984 __select__ = SyncSchemaHook.__select__ & entity_implements('CWAttribute', |
985 'CWRelation') |
985 'CWRelation') |
986 events = ('after_update_entity',) |
986 events = ('after_update_entity',) |
987 |
987 |
988 def __call__(self): |
988 def __call__(self): |
989 entity = self.entity |
989 entity = self.entity |
990 if self.cw_req.deleted_in_transaction(entity.eid): |
990 if self._cw.deleted_in_transaction(entity.eid): |
991 return |
991 return |
992 desttype = entity.otype.name |
992 desttype = entity.otype.name |
993 rschema = self.cw_req.schema[entity.rtype.name] |
993 rschema = self._cw.schema[entity.rtype.name] |
994 newvalues = {} |
994 newvalues = {} |
995 for prop in rschema.rproperty_defs(desttype): |
995 for prop in rschema.rproperty_defs(desttype): |
996 if prop == 'constraints': |
996 if prop == 'constraints': |
997 continue |
997 continue |
998 if prop == 'order': |
998 if prop == 'order': |
999 prop = 'ordernum' |
999 prop = 'ordernum' |
1000 if prop in entity.edited_attributes: |
1000 if prop in entity.edited_attributes: |
1001 newvalues[prop] = entity[prop] |
1001 newvalues[prop] = entity[prop] |
1002 if newvalues: |
1002 if newvalues: |
1003 subjtype = entity.stype.name |
1003 subjtype = entity.stype.name |
1004 MemSchemaRDefUpdate(self.cw_req, kobj=(subjtype, desttype), |
1004 MemSchemaRDefUpdate(self._cw, kobj=(subjtype, desttype), |
1005 rschema=rschema, values=newvalues) |
1005 rschema=rschema, values=newvalues) |
1006 SourceDbRDefUpdate(self.cw_req, kobj=(subjtype, desttype), |
1006 SourceDbRDefUpdate(self._cw, kobj=(subjtype, desttype), |
1007 rschema=rschema, values=newvalues) |
1007 rschema=rschema, values=newvalues) |
1008 |
1008 |
1009 |
1009 |
1010 # constraints synchronization hooks ############################################ |
1010 # constraints synchronization hooks ############################################ |
1011 |
1011 |
1013 __id__ = 'syncaddcwconstraint' |
1013 __id__ = 'syncaddcwconstraint' |
1014 __select__ = SyncSchemaHook.__select__ & entity_implements('CWConstraint') |
1014 __select__ = SyncSchemaHook.__select__ & entity_implements('CWConstraint') |
1015 events = ('after_add_entity', 'after_update_entity') |
1015 events = ('after_add_entity', 'after_update_entity') |
1016 |
1016 |
1017 def __call__(self): |
1017 def __call__(self): |
1018 MemSchemaCWConstraintAdd(self.cw_req, entity=self.entity) |
1018 MemSchemaCWConstraintAdd(self._cw, entity=self.entity) |
1019 SourceDbCWConstraintAdd(self.cw_req, entity=self.entity) |
1019 SourceDbCWConstraintAdd(self._cw, entity=self.entity) |
1020 |
1020 |
1021 |
1021 |
1022 class AfterAddConstrainedByHook(SyncSchemaHook): |
1022 class AfterAddConstrainedByHook(SyncSchemaHook): |
1023 __id__ = 'syncdelconstrainedby' |
1023 __id__ = 'syncdelconstrainedby' |
1024 __select__ = SyncSchemaHook.__select__ & hook.match_rtype('constrainted_by') |
1024 __select__ = SyncSchemaHook.__select__ & hook.match_rtype('constrainted_by') |
1025 events = ('after_add_relation',) |
1025 events = ('after_add_relation',) |
1026 |
1026 |
1027 def __call__(self): |
1027 def __call__(self): |
1028 if self.cw_req.added_in_transaction(self.eidfrom): |
1028 if self._cw.added_in_transaction(self.eidfrom): |
1029 self.cw_req.transaction_data.setdefault(self.eidfrom, []).append(self.eidto) |
1029 self._cw.transaction_data.setdefault(self.eidfrom, []).append(self.eidto) |
1030 |
1030 |
1031 |
1031 |
1032 class BeforeDeleteConstrainedByHook(AfterAddConstrainedByHook): |
1032 class BeforeDeleteConstrainedByHook(AfterAddConstrainedByHook): |
1033 __id__ = 'syncdelconstrainedby' |
1033 __id__ = 'syncdelconstrainedby' |
1034 events = ('before_delete_relation',) |
1034 events = ('before_delete_relation',) |
1035 |
1035 |
1036 def __call__(self): |
1036 def __call__(self): |
1037 if self.cw_req.deleted_in_transaction(self.eidfrom): |
1037 if self._cw.deleted_in_transaction(self.eidfrom): |
1038 return |
1038 return |
1039 schema = self.cw_req.schema |
1039 schema = self._cw.schema |
1040 entity = self.cw_req.entity_from_eid(self.eidto) |
1040 entity = self._cw.entity_from_eid(self.eidto) |
1041 subjtype, rtype, objtype = schema.schema_by_eid(self.eidfrom) |
1041 subjtype, rtype, objtype = schema.schema_by_eid(self.eidfrom) |
1042 try: |
1042 try: |
1043 cstr = rtype.constraint_by_type(subjtype, objtype, |
1043 cstr = rtype.constraint_by_type(subjtype, objtype, |
1044 entity.cstrtype[0].name) |
1044 entity.cstrtype[0].name) |
1045 except IndexError: |
1045 except IndexError: |
1046 self.cw_req.critical('constraint type no more accessible') |
1046 self._cw.critical('constraint type no more accessible') |
1047 else: |
1047 else: |
1048 SourceDbCWConstraintDel(self.cw_req, subjtype=subjtype, rtype=rtype, |
1048 SourceDbCWConstraintDel(self._cw, subjtype=subjtype, rtype=rtype, |
1049 objtype=objtype, cstr=cstr) |
1049 objtype=objtype, cstr=cstr) |
1050 MemSchemaCWConstraintDel(self.cw_req, subjtype=subjtype, rtype=rtype, |
1050 MemSchemaCWConstraintDel(self._cw, subjtype=subjtype, rtype=rtype, |
1051 objtype=objtype, cstr=cstr) |
1051 objtype=objtype, cstr=cstr) |
1052 |
1052 |
1053 |
1053 |
1054 # permissions synchronization hooks ############################################ |
1054 # permissions synchronization hooks ############################################ |
1055 |
1055 |
1062 'update_permission') |
1062 'update_permission') |
1063 events = ('after_add_relation',) |
1063 events = ('after_add_relation',) |
1064 |
1064 |
1065 def __call__(self): |
1065 def __call__(self): |
1066 perm = self.rtype.split('_', 1)[0] |
1066 perm = self.rtype.split('_', 1)[0] |
1067 if self.cw_req.describe(self.eidto)[0] == 'CWGroup': |
1067 if self._cw.describe(self.eidto)[0] == 'CWGroup': |
1068 MemSchemaPermCWGroupAdd(self.cw_req, perm, self.eidfrom, self.eidto) |
1068 MemSchemaPermCWGroupAdd(self._cw, perm, self.eidfrom, self.eidto) |
1069 else: # RQLExpression |
1069 else: # RQLExpression |
1070 expr = self.cw_req.entity_from_eid(self.eidto).expression |
1070 expr = self._cw.entity_from_eid(self.eidto).expression |
1071 MemSchemaPermRQLExpressionAdd(self.cw_req, perm, self.eidfrom, expr) |
1071 MemSchemaPermRQLExpressionAdd(self._cw, perm, self.eidfrom, expr) |
1072 |
1072 |
1073 |
1073 |
1074 class BeforeDelPermissionHook(AfterAddPermissionHook): |
1074 class BeforeDelPermissionHook(AfterAddPermissionHook): |
1075 """delete entity/relation *_permission, need to update schema |
1075 """delete entity/relation *_permission, need to update schema |
1076 |
1076 |
1078 """ |
1078 """ |
1079 __id__ = 'syncdelperm' |
1079 __id__ = 'syncdelperm' |
1080 events = ('before_delete_relation',) |
1080 events = ('before_delete_relation',) |
1081 |
1081 |
1082 def __call__(self): |
1082 def __call__(self): |
1083 if self.cw_req.deleted_in_transaction(self.eidfrom): |
1083 if self._cw.deleted_in_transaction(self.eidfrom): |
1084 return |
1084 return |
1085 perm = self.rtype.split('_', 1)[0] |
1085 perm = self.rtype.split('_', 1)[0] |
1086 if self.cw_req.describe(self.eidto)[0] == 'CWGroup': |
1086 if self._cw.describe(self.eidto)[0] == 'CWGroup': |
1087 MemSchemaPermCWGroupDel(self.cw_req, perm, self.eidfrom, self.eidto) |
1087 MemSchemaPermCWGroupDel(self._cw, perm, self.eidfrom, self.eidto) |
1088 else: # RQLExpression |
1088 else: # RQLExpression |
1089 expr = self.cw_req.entity_from_eid(self.eidto).expression |
1089 expr = self._cw.entity_from_eid(self.eidto).expression |
1090 MemSchemaPermRQLExpressionDel(self.cw_req, perm, self.eidfrom, expr) |
1090 MemSchemaPermRQLExpressionDel(self._cw, perm, self.eidfrom, expr) |
1091 |
1091 |
1092 |
1092 |
1093 |
1093 |
1094 class ModifySpecializesHook(SyncSchemaHook): |
1094 class ModifySpecializesHook(SyncSchemaHook): |
1095 __id__ = 'syncspecializes' |
1095 __id__ = 'syncspecializes' |