1616using Xtensive . Orm . Upgrade . Internals ;
1717using Xtensive . Orm . Upgrade . Model ;
1818using Xtensive . Reflection ;
19+ using DataDeletionInfo = Xtensive . Modelling . Comparison . Hints . DeleteDataHint . DeleteDataHintInfo ;
1920
2021namespace Xtensive . Orm . Upgrade
2122{
@@ -222,75 +223,102 @@ private void GenerateRecordCleanupHints(List<StoredTypeInfo> removedTypes,
222223 Dictionary < StoredTypeInfo , StoredTypeInfo > conflictsByTable , bool isMovedToAnotherHierarchy )
223224 {
224225 if ( ! isMovedToAnotherHierarchy ) {
225- removedTypes . ForEach ( GenerateCleanupByForeignKeyHints ) ;
226+ removedTypes . ForEach ( ( rType ) => GenerateCleanupByForeignKeyHints ( rType , GetDeleteReasonFK ( rType ) ) ) ;
227+ }
228+ removedTypes . ForEach ( type =>
229+ GenerateCleanupByPrimaryKeyHints ( type , isMovedToAnotherHierarchy , conflictsByTable . ContainsKey ( type . Hierarchy . Root ) ) ) ;
230+
231+ return ;
232+
233+ DataDeletionInfo GetDeleteReasonFK ( StoredTypeInfo removedType )
234+ {
235+ return conflictsByTable . ContainsKey ( removedType . Hierarchy . Root )
236+ ? DataDeletionInfo . TableMovement
237+ : DataDeletionInfo . None ;
226238 }
227- removedTypes . ForEach ( type => GenerateCleanupByPrimaryKeyHints ( type , isMovedToAnotherHierarchy , conflictsByTable . ContainsKey ( type . Hierarchy . Root ) ) ) ;
228239 }
229240
230241 private void GenerateCleanupByPrimaryKeyHints ( StoredTypeInfo removedType , bool isMovedToAnotherHierarchy , bool conflictsWithNewType )
231242 {
232- var hierarchy = removedType . Hierarchy ;
233- switch ( hierarchy . InheritanceSchema ) {
243+ var inheritanceSchema = removedType . Hierarchy . InheritanceSchema ;
244+
245+ IEnumerable < ( StoredTypeInfo type , IdentityPair [ ] pairs ) > hintInfo ;
246+ switch ( inheritanceSchema ) {
234247 case InheritanceSchema . ClassTable : {
235- if ( ! conflictsWithNewType ) {
236- var typesToProcess = ! isMovedToAnotherHierarchy
237- ? EnumerableUtils . One ( removedType ) . Concat ( removedType . AllAncestors )
238- : ( IEnumerable < StoredTypeInfo > ) removedType . AllAncestors ;
239- foreach ( var type in typesToProcess ) {
240- var identities1 = new [ ] { new IdentityPair (
241- GetColumnPath ( type , GetTypeIdMappingName ( type ) ) ,
242- removedType . TypeId . ToString ( ) ,
243- true )
244- } ;
245- schemaHints . Add (
246- new DeleteDataHint ( GetTablePath ( type ) , identities1 , isMovedToAnotherHierarchy , conflictsWithNewType ) ) ;
247- }
248- }
249- else if ( isMovedToAnotherHierarchy ) {
250- foreach ( var type in hierarchy . Types ) {
251- schemaHints . Add (
252- new DeleteDataHint ( GetTablePath ( type ) , Array . Empty < IdentityPair > ( ) , isMovedToAnotherHierarchy , conflictsWithNewType ) ) ;
253- }
254- }
248+ hintInfo = GetTypesToCleanForClassTable ( removedType , isMovedToAnotherHierarchy , conflictsWithNewType ) ;
255249 break ;
256250 }
257- case InheritanceSchema . SingleTable :
258- if ( ! conflictsWithNewType ) {
259- var rootType = hierarchy . Root ;
260- var identities2 = new [ ] { new IdentityPair (
261- GetColumnPath ( rootType , GetTypeIdMappingName ( rootType ) ) ,
262- removedType . TypeId . ToString ( ) ,
263- true ) } ;
264- schemaHints . Add (
265- new DeleteDataHint ( GetTablePath ( rootType ) , identities2 , isMovedToAnotherHierarchy , conflictsWithNewType ) ) ;
266- }
267- else if ( ! isMovedToAnotherHierarchy ) {
268- var rootType = hierarchy . Root ;
269- schemaHints . Add (
270- new DeleteDataHint ( GetTablePath ( rootType ) , Array . Empty < IdentityPair > ( ) , isMovedToAnotherHierarchy , conflictsWithNewType ) ) ;
271- }
251+ case InheritanceSchema . SingleTable : {
252+ hintInfo = GetTypesToCleanForSinleTable ( removedType , isMovedToAnotherHierarchy , conflictsWithNewType ) ;
272253 break ;
254+ }
273255 case InheritanceSchema . ConcreteTable : {
274256 //ConcreteTable schema doesn't include TypeId
275- if ( ! conflictsWithNewType ) {
276- schemaHints . Add (
277- new DeleteDataHint ( GetTablePath ( removedType ) , Array . Empty < IdentityPair > ( ) , isMovedToAnotherHierarchy ) ) ;
278- }
279- else if ( ! isMovedToAnotherHierarchy ) {
280- var typesToProcess = hierarchy . Types ;
281- foreach ( var type in typesToProcess ) {
282- schemaHints . Add (
283- new DeleteDataHint ( GetTablePath ( type ) , Array . Empty < IdentityPair > ( ) , isMovedToAnotherHierarchy , conflictsWithNewType ) ) ;
284- }
285- }
257+ hintInfo = GetTypesToCleanForConcreteTable ( removedType , isMovedToAnotherHierarchy , conflictsWithNewType ) ;
286258 break ;
287259 }
288260 default :
289- throw Exceptions . InternalError ( string . Format ( Strings . ExInheritanceSchemaIsInvalid , hierarchy . InheritanceSchema ) , UpgradeLog . Instance ) ;
261+ throw Exceptions . InternalError (
262+ string . Format ( Strings . ExInheritanceSchemaIsInvalid , inheritanceSchema ) , UpgradeLog . Instance ) ;
290263 }
264+
265+ var deleteReason = DataDeletionInfo . None ;
266+ if ( isMovedToAnotherHierarchy )
267+ deleteReason |= DataDeletionInfo . PostCopy ;
268+ if ( conflictsWithNewType )
269+ deleteReason |= DataDeletionInfo . TableMovement ;
270+
271+ foreach ( var item in hintInfo ) {
272+ schemaHints . Add ( new DeleteDataHint ( GetTablePath ( item . type ) , item . pairs , deleteReason ) ) ;
273+ }
274+ }
275+
276+ private IEnumerable < ( StoredTypeInfo type , IdentityPair [ ] pairs ) > GetTypesToCleanForClassTable (
277+ StoredTypeInfo removedType , bool isMovedToAnotherHierarchy , bool conflictsWithNewType )
278+ {
279+ if ( ! conflictsWithNewType ) {
280+ var typesToProcess = ! isMovedToAnotherHierarchy
281+ ? EnumerableUtils . One ( removedType ) . Concat ( removedType . AllAncestors )
282+ : removedType . AllAncestors ;
283+ return typesToProcess . Select ( t => ( t , new [ ] {
284+ new IdentityPair (
285+ GetColumnPath ( t , GetTypeIdMappingName ( t ) ) ,
286+ removedType . TypeId . ToString ( ) ,
287+ true ) } ) ) ;
288+ }
289+ else if ( ! isMovedToAnotherHierarchy ) {
290+ return removedType . Hierarchy . Types . Select ( t => ( t , Array . Empty < IdentityPair > ( ) ) ) ;
291+ }
292+ return Enumerable . Empty < ( StoredTypeInfo type , IdentityPair [ ] pairs ) > ( ) ;
293+ }
294+
295+ private IEnumerable < ( StoredTypeInfo type , IdentityPair [ ] pairs ) > GetTypesToCleanForSinleTable (
296+ StoredTypeInfo removedType , bool isMovedToAnotherHierarchy , bool conflictsWithNewType )
297+ {
298+ var hierarchy = removedType . Hierarchy ;
299+ if ( ! conflictsWithNewType ) {
300+ return EnumerableUtils . One ( hierarchy . Root )
301+ . Select ( t => ( t , new [ ] {
302+ new IdentityPair ( GetColumnPath ( t , GetTypeIdMappingName ( t ) ) , removedType . TypeId . ToString ( ) , true ) } ) ) ;
303+ }
304+ else if ( ! isMovedToAnotherHierarchy ) {
305+ return EnumerableUtils . One ( ( hierarchy . Root , Array . Empty < IdentityPair > ( ) ) ) ;
306+ }
307+ return Enumerable . Empty < ( StoredTypeInfo type , IdentityPair [ ] pairs ) > ( ) ;
308+ }
309+
310+ private IEnumerable < ( StoredTypeInfo type , IdentityPair [ ] pairs ) > GetTypesToCleanForConcreteTable (
311+ StoredTypeInfo removedType , bool isMovedToAnotherHierarchy , bool conflictsWithNewType )
312+ {
313+ var hierarchy = removedType . Hierarchy ;
314+ return ( ! conflictsWithNewType )
315+ ? EnumerableUtils . One ( removedType ) . Select ( t => ( t , Array . Empty < IdentityPair > ( ) ) )
316+ : ( ! isMovedToAnotherHierarchy )
317+ ? hierarchy . Types . Select ( t => ( t , Array . Empty < IdentityPair > ( ) ) )
318+ : Enumerable . Empty < ( StoredTypeInfo type , IdentityPair [ ] pairs ) > ( ) ;
291319 }
292320
293- private void GenerateCleanupByForeignKeyHints ( StoredTypeInfo removedType )
321+ private void GenerateCleanupByForeignKeyHints ( StoredTypeInfo removedType , DataDeletionInfo dataDeletionInfo )
294322 {
295323 var removedTypeAndAncestors = new HashSet < StoredTypeInfo > ( removedType . AllAncestors . Length + 1 ) ;
296324 removedType . AllAncestors . Append ( removedType ) . ForEach ( t => removedTypeAndAncestors . Add ( t ) ) ;
@@ -329,7 +357,8 @@ from association in extractedModel.Associations
329357 removedType ,
330358 GetAffectedMappedTypesAsArray ( candidate , inheritanceSchema == InheritanceSchema . ConcreteTable ) ,
331359 association ,
332- requiresInverseCleanup ) ;
360+ requiresInverseCleanup ,
361+ dataDeletionInfo ) ;
333362 }
334363 }
335364 else {
@@ -338,7 +367,8 @@ from association in extractedModel.Associations
338367 removedType ,
339368 GetAffectedMappedTypesAsArray ( declaringType , inheritanceSchema == InheritanceSchema . ConcreteTable ) ,
340369 association ,
341- requiresInverseCleanup ) ;
370+ requiresInverseCleanup ,
371+ dataDeletionInfo ) ;
342372 }
343373 }
344374 else {
@@ -347,7 +377,8 @@ from association in extractedModel.Associations
347377 removedType ,
348378 new [ ] { association . ConnectorType } ,
349379 association ,
350- requiresInverseCleanup ) ;
380+ requiresInverseCleanup ,
381+ dataDeletionInfo ) ;
351382 }
352383 }
353384 }
@@ -356,18 +387,20 @@ private void GenerateClearReferenceHints(
356387 StoredTypeInfo removedType ,
357388 StoredTypeInfo [ ] updatedTypes ,
358389 StoredAssociationInfo association ,
359- bool inverse )
390+ bool inverse ,
391+ DataDeletionInfo dataDeletionInfo )
360392 {
361393 foreach ( var updatedType in updatedTypes ) {
362- GenerateClearReferenceHint ( removedType , updatedType , association , inverse ) ;
394+ GenerateClearReferenceHint ( removedType , updatedType , association , inverse , dataDeletionInfo ) ;
363395 }
364396 }
365397
366398 private void GenerateClearReferenceHint (
367399 StoredTypeInfo removedType ,
368400 StoredTypeInfo updatedType ,
369401 StoredAssociationInfo association ,
370- bool inverse )
402+ bool inverse ,
403+ DataDeletionInfo dataDeletionInfo )
371404 {
372405 if ( association . ReferencingField . IsEntitySet && association . ConnectorType == null ) {
373406 // There is nothing to cleanup in class containing EntitySet<T> property,
@@ -407,7 +440,7 @@ private void GenerateClearReferenceHint(
407440 schemaHints . Add ( new UpdateDataHint ( sourceTablePath , identities , updatedColumns ) ) ;
408441 }
409442 else {
410- schemaHints . Add ( new DeleteDataHint ( sourceTablePath , identities ) ) ;
443+ schemaHints . Add ( new DeleteDataHint ( sourceTablePath , identities , dataDeletionInfo ) ) ;
411444 }
412445 }
413446
0 commit comments