Skip to content

Commit c1f45df

Browse files
committed
HintGenerator improvements
- GenerateCleanupByPrimaryKeyHints became linear - uses new DeleteDataHintInfo
1 parent 6f768cb commit c1f45df

File tree

1 file changed

+92
-59
lines changed

1 file changed

+92
-59
lines changed

Orm/Xtensive.Orm/Orm/Upgrade/Internals/HintGenerator.cs

Lines changed: 92 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
using Xtensive.Orm.Upgrade.Internals;
1717
using Xtensive.Orm.Upgrade.Model;
1818
using Xtensive.Reflection;
19+
using DataDeletionInfo = Xtensive.Modelling.Comparison.Hints.DeleteDataHint.DeleteDataHintInfo;
1920

2021
namespace 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

Comments
 (0)