@@ -51,11 +51,12 @@ public HintGenerationResult Run()
5151 GenerateCopyColumnHints ( copyFieldHints ) ;
5252
5353 var removedTypes = GetRemovedTypes ( ) ;
54- GenerateRecreateHints ( removedTypes ) ;
55- GenerateRecordCleanupHints ( removedTypes , false ) ;
54+ var conflictsByTable = GetRecreatedTypes ( removedTypes ) ;
55+ //GenerateRecreateHints(removedTypes);
56+ GenerateRecordCleanupHints ( removedTypes , conflictsByTable , false ) ;
5657
5758 var movedTypes = GetMovedTypes ( ) ;
58- GenerateRecordCleanupHints ( movedTypes , true ) ;
59+ GenerateRecordCleanupHints ( movedTypes , conflictsByTable , true ) ;
5960
6061 // Adding useful info
6162 CalculateAffectedTablesAndColumns ( hints ) ;
@@ -218,64 +219,73 @@ private void GenerateCopyColumnHint(CopyFieldHint hint)
218219 }
219220 }
220221
221- private void GenerateRecreateHints ( IList < StoredTypeInfo > removedTypes )
222- {
223- var capacity = currentModel . Types . Length - typeMapping . Count ;
224- var newTypes = new Dictionary < string , StoredTypeInfo > ( capacity , StringComparer . Ordinal ) ;
225- currentNonConnectorTypes
226- . Where ( t => ! reverseTypeMapping . ContainsKey ( t ) )
227- . ForEach ( t => newTypes . Add ( $ "{ t . MappingDatabase } .{ t . MappingSchema } .{ t . MappingName } ", t ) ) ;
228-
229- for ( var i = removedTypes . Count - 1 ; i >= 0 ; i -- ) {
230- var rType = removedTypes [ i ] ;
231- var rTypeIdentifier = $ "{ rType . MappingDatabase } .{ rType . MappingSchema } .{ rType . MappingName } ";
232- if ( suspiciousTypes . Contains ( rType ) && newTypes . ContainsKey ( rTypeIdentifier ) ) {
233- schemaHints . Add ( new DeleteDataHint ( GetTablePath ( rType ) , Array . Empty < IdentityPair > ( ) , true ) ) ;
234- _ = removedTypes . Remove ( rType ) ;
235- }
236- }
237- }
238-
239- private void GenerateRecordCleanupHints ( List < StoredTypeInfo > removedTypes , bool isMovedToAnotherHierarchy )
222+ private void GenerateRecordCleanupHints ( List < StoredTypeInfo > removedTypes ,
223+ Dictionary < StoredTypeInfo , StoredTypeInfo > conflictsByTable , bool isMovedToAnotherHierarchy )
240224 {
241225 if ( ! isMovedToAnotherHierarchy ) {
242226 removedTypes . ForEach ( GenerateCleanupByForeignKeyHints ) ;
243227 }
244- removedTypes . ForEach ( type => GenerateCleanupByPrimaryKeyHints ( type , isMovedToAnotherHierarchy ) ) ;
228+ removedTypes . ForEach ( type => GenerateCleanupByPrimaryKeyHints ( type , isMovedToAnotherHierarchy , conflictsByTable . ContainsKey ( type . Hierarchy . Root ) ) ) ;
245229 }
246230
247- private void GenerateCleanupByPrimaryKeyHints ( StoredTypeInfo removedType , bool isMovedToAnotherHierarchy )
231+ private void GenerateCleanupByPrimaryKeyHints ( StoredTypeInfo removedType , bool isMovedToAnotherHierarchy , bool conflictsWithNewType )
248232 {
249233 var hierarchy = removedType . Hierarchy ;
250234 switch ( hierarchy . InheritanceSchema ) {
251- case InheritanceSchema . ClassTable :
252- IEnumerable < StoredTypeInfo > typesToProcess ;
253- typesToProcess = ! isMovedToAnotherHierarchy
254- ? EnumerableUtils . One ( removedType ) . Concat ( removedType . AllAncestors )
255- : removedType . AllAncestors ;
256- foreach ( var type in typesToProcess ) {
257- var identities1 = new [ ] { new IdentityPair (
258- GetColumnPath ( type , GetTypeIdMappingName ( type ) ) ,
259- removedType . TypeId . ToString ( ) ,
260- true ) } ;
261- schemaHints . Add (
262- new DeleteDataHint ( GetTablePath ( type ) , identities1 , isMovedToAnotherHierarchy ) ) ;
235+ case InheritanceSchema . ClassTable : {
236+ if ( ! conflictsWithNewType ) {
237+ var typesToProcess = ! isMovedToAnotherHierarchy
238+ ? EnumerableUtils . One ( removedType ) . Concat ( removedType . AllAncestors )
239+ : ( IEnumerable < StoredTypeInfo > ) removedType . AllAncestors ;
240+ foreach ( var type in typesToProcess ) {
241+ var identities1 = new [ ] { new IdentityPair (
242+ GetColumnPath ( type , GetTypeIdMappingName ( type ) ) ,
243+ removedType . TypeId . ToString ( ) ,
244+ true )
245+ } ;
246+ schemaHints . Add (
247+ new DeleteDataHint ( GetTablePath ( type ) , identities1 , isMovedToAnotherHierarchy , conflictsWithNewType ) ) ;
248+ }
249+ }
250+ else if ( isMovedToAnotherHierarchy ) {
251+ foreach ( var type in hierarchy . Types ) {
252+ schemaHints . Add (
253+ new DeleteDataHint ( GetTablePath ( type ) , Array . Empty < IdentityPair > ( ) , isMovedToAnotherHierarchy , conflictsWithNewType ) ) ;
254+ }
263255 }
264256 break ;
257+ }
265258 case InheritanceSchema . SingleTable :
266- var rootType = hierarchy . Root ;
267- var identities2 = new [ ] { new IdentityPair (
259+ if ( ! conflictsWithNewType ) {
260+ var rootType = hierarchy . Root ;
261+ var identities2 = new [ ] { new IdentityPair (
268262 GetColumnPath ( rootType , GetTypeIdMappingName ( rootType ) ) ,
269263 removedType . TypeId . ToString ( ) ,
270264 true ) } ;
271- schemaHints . Add (
272- new DeleteDataHint ( GetTablePath ( rootType ) , identities2 , isMovedToAnotherHierarchy ) ) ;
265+ schemaHints . Add (
266+ new DeleteDataHint ( GetTablePath ( rootType ) , identities2 , isMovedToAnotherHierarchy , conflictsWithNewType ) ) ;
267+ }
268+ else if ( ! isMovedToAnotherHierarchy ) {
269+ var rootType = hierarchy . Root ;
270+ schemaHints . Add (
271+ new DeleteDataHint ( GetTablePath ( rootType ) , Array . Empty < IdentityPair > ( ) , isMovedToAnotherHierarchy , conflictsWithNewType ) ) ;
272+ }
273273 break ;
274- case InheritanceSchema . ConcreteTable :
275- // ConcreteTable schema doesn't include TypeId
276- schemaHints . Add (
277- new DeleteDataHint ( GetTablePath ( removedType ) , Array . Empty < IdentityPair > ( ) , isMovedToAnotherHierarchy ) ) ;
274+ case InheritanceSchema . ConcreteTable : {
275+ //ConcreteTable schema doesn't include TypeId
276+ if ( ! conflictsWithNewType ) {
277+ schemaHints . Add (
278+ new DeleteDataHint ( GetTablePath ( removedType ) , Array . Empty < IdentityPair > ( ) , isMovedToAnotherHierarchy ) ) ;
279+ }
280+ else if ( ! isMovedToAnotherHierarchy ) {
281+ var typesToProcess = hierarchy . Types ;
282+ foreach ( var type in typesToProcess ) {
283+ schemaHints . Add (
284+ new DeleteDataHint ( GetTablePath ( type ) , Array . Empty < IdentityPair > ( ) , isMovedToAnotherHierarchy , conflictsWithNewType ) ) ;
285+ }
286+ }
278287 break ;
288+ }
279289 default :
280290 throw Exceptions . InternalError ( string . Format ( Strings . ExInheritanceSchemaIsInvalid , hierarchy . InheritanceSchema ) , UpgradeLog . Instance ) ;
281291 }
@@ -598,6 +608,30 @@ private List<string> GetAffectedColumns(StoredTypeInfo type, StoredFieldInfo fie
598608 return affectedColumns ;
599609 }
600610
611+ private Dictionary < StoredTypeInfo , StoredTypeInfo > GetRecreatedTypes ( IReadOnlyList < StoredTypeInfo > removedTypes )
612+ {
613+ // Return types that were removed but there is a new type
614+ // which uses the same table in database (and|or) schema
615+ // that means further comparison will not find schema changes (table removes or renames),
616+ // but data in the table has different meaning so old data should be cleaned.
617+
618+ var capacity = currentModel . Types . Length - typeMapping . Count ;
619+ var currentTables = new Dictionary < string , StoredTypeInfo > ( capacity , StringComparer . Ordinal ) ;
620+ foreach ( var t in currentNonConnectorTypes . Where ( t => ! reverseTypeMapping . ContainsKey ( t ) ) ) {
621+ currentTables . Add ( $ "{ t . MappingDatabase } .{ t . MappingSchema } .{ t . MappingName } ", t ) ;
622+ }
623+
624+ var conflictsByTable = new Dictionary < StoredTypeInfo , StoredTypeInfo > ( ) ;
625+
626+ foreach ( var rType in removedTypes ) {
627+ var rTypeIdentifier = $ "{ rType . MappingDatabase } .{ rType . MappingSchema } .{ rType . MappingName } ";
628+ if ( suspiciousTypes . Contains ( rType ) && currentTables . TryGetValue ( rTypeIdentifier , out var nType ) ) {
629+ conflictsByTable . Add ( rType , nType ) ;
630+ }
631+ }
632+ return conflictsByTable ;
633+ }
634+
601635 private List < StoredTypeInfo > GetRemovedTypes ( )
602636 {
603637 return (
0 commit comments