Skip to content

Commit 7e88364

Browse files
authored
Merge pull request #383 from DataObjects-NET/6.0-renamefieldhint-validation-bug
Adds dedicated exception when RenameFieldHint.TargetType is absent in storage model
2 parents 42471b3 + 5648360 commit 7e88364

File tree

5 files changed

+101
-14
lines changed

5 files changed

+101
-14
lines changed

ChangeLog/6.0.13_dev.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
[main] Fixed certain cases of bad translation of casts via 'as' operator in LINQ queries
22
[main] Addressed certain issues of translation connected with comparison with local entity instace within LINQ queries
33
[main] Fixed rare issues of incorrect translation of filtered index expressions including conditional expressions
4-
[main] Join/LeftJoin is denied to have the same expression instance for both inner/outer selector.
4+
[main] Join/LeftJoin is denied to have the same expression instance for both inner/outer selector
55
[main] Addressed issue when wrong type of join was chosen when .First/FirstOrDefalult() method was used as subquery
6+
[main] Added dedicated exception when RenameFieldHint.TargetType exists in current model but absent in storage model
67
[postgresql] Fixed issue of incorrect translation of contitional expressions including comparison with nullable fields
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// Copyright (C) 2024 Xtensive LLC.
2+
// This code is distributed under MIT license terms.
3+
// See the License.txt file in the project root for more information.
4+
5+
using System;
6+
using NUnit.Framework;
7+
using Xtensive.Collections;
8+
using Xtensive.Orm.Upgrade;
9+
using Xtensive.Orm.Tests.Issues.IssueJira0804_RenameFieldHintValidationBugModel;
10+
11+
12+
namespace Xtensive.Orm.Tests.Issues.IssueJira0804_RenameFieldHintValidationBugModel
13+
{
14+
[Serializable]
15+
[HierarchyRoot]
16+
public class Person : Entity
17+
{
18+
[Key, Field]
19+
public long Id { get; private set; }
20+
}
21+
22+
[Serializable]
23+
[HierarchyRoot]
24+
public class Address : Entity
25+
{
26+
[Key, Field]
27+
public long Id { get; private set; }
28+
[Field]
29+
public Person Person { get; set; }
30+
[Field]
31+
public bool NewName { get; set; }
32+
}
33+
34+
public class Upgrader : UpgradeHandler
35+
{
36+
public override bool CanUpgradeFrom(string oldVersion) => true;
37+
38+
protected override void AddUpgradeHints(ISet<UpgradeHint> hints)
39+
{
40+
base.AddUpgradeHints(hints);
41+
_ = hints.Add(
42+
new RenameFieldHint(typeof(Address), "FieldToRename", "NewName")
43+
);
44+
}
45+
}
46+
}
47+
48+
namespace Xtensive.Orm.Tests.Issues
49+
{
50+
[TestFixture]
51+
public sealed class IssueJira0804_RenameFieldHintValidationBug
52+
{
53+
[Test]
54+
public void MainTest()
55+
{
56+
var initConfig = DomainConfigurationFactory.Create();
57+
initConfig.Types.Register(typeof(Person));
58+
// I don't include this type for it to not exist in database before upgrade
59+
// this type is delcared in the hint
60+
//initConfig.Types.Register(typeof(Address));
61+
initConfig.UpgradeMode = DomainUpgradeMode.Recreate;
62+
63+
using (var domain = Domain.Build(initConfig)) { }
64+
65+
var upgradeConfig = DomainConfigurationFactory.Create();
66+
upgradeConfig.Types.Register(typeof(Person));
67+
upgradeConfig.Types.Register(typeof(Address));
68+
upgradeConfig.Types.Register(typeof(Upgrader));
69+
upgradeConfig.UpgradeMode = DomainUpgradeMode.PerformSafely;
70+
71+
_ = Assert.Throws<InvalidOperationException>(() => {
72+
using var domain = Domain.Build(upgradeConfig);
73+
});
74+
}
75+
}
76+
}

Orm/Xtensive.Orm/Orm/Upgrade/Internals/UpgradeHintValidator.cs

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ private void ValidateRenameFieldHints(IEnumerable<RenameFieldHint> hints)
6565
var targetType = currentModel.Types.SingleOrDefault(type => type.UnderlyingType == targetTypeName);
6666
if (targetType==null)
6767
throw TypeNotFound(targetTypeName);
68-
var sourceType = reverseTypeMapping[targetType];
68+
if (!reverseTypeMapping.TryGetValue(targetType, out var sourceType))
69+
throw TypeNotFoundInStorageModel(targetTypeName, hint.OldFieldName);
6970
var sourceTypeName = sourceType.UnderlyingType;
7071
if (sourceType.GetField(hint.OldFieldName)==null)
7172
throw FieldNotFound(sourceTypeName, hint.OldFieldName);
@@ -145,20 +146,17 @@ private void ValidateRemoveTypeHints(IEnumerable<RemoveTypeHint> hints)
145146
}
146147
}
147148

148-
private static InvalidOperationException TypeNotFound(string name)
149-
{
150-
return new InvalidOperationException(string.Format(Strings.ExTypeXIsNotFound, name));
151-
}
149+
private static InvalidOperationException TypeNotFound(string name) =>
150+
new InvalidOperationException(string.Format(Strings.ExTypeXIsNotFound, name));
152151

153-
private static InvalidOperationException FieldNotFound(string typeName, string fieldName)
154-
{
155-
return new InvalidOperationException(string.Format(Strings.ExFieldXYIsNotFound, typeName, fieldName));
156-
}
152+
private static InvalidOperationException TypeNotFoundInStorageModel(string typeName, string oldFieldName) =>
153+
new InvalidOperationException(string.Format(Strings.ExTypeXWhichContainsRenamingFieldYDoesntExistInStorageModel, typeName, oldFieldName));
157154

158-
private static InvalidOperationException HintConflict(UpgradeHint hintOne, UpgradeHint hintTwo)
159-
{
160-
return new InvalidOperationException(string.Format(Strings.ExHintXIsConflictingWithHintY, hintOne, hintTwo));
161-
}
155+
private static InvalidOperationException FieldNotFound(string typeName, string fieldName) =>
156+
new InvalidOperationException(string.Format(Strings.ExFieldXYIsNotFound, typeName, fieldName));
157+
158+
private static InvalidOperationException HintConflict(UpgradeHint hintOne, UpgradeHint hintTwo) =>
159+
new InvalidOperationException(string.Format(Strings.ExHintXIsConflictingWithHintY, hintOne, hintTwo));
162160

163161
public UpgradeHintValidator(StoredDomainModel currentModel, StoredDomainModel extractedModel, Dictionary<StoredTypeInfo, StoredTypeInfo> typeMapping, Dictionary<StoredTypeInfo, StoredTypeInfo> reverseTypeMapping)
164162
{

Orm/Xtensive.Orm/Strings.Designer.cs

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Orm/Xtensive.Orm/Strings.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3479,4 +3479,7 @@ Error: {1}</value>
34793479
<data name="ExJoinHasSameInnerAndOuterParameterInstances" xml:space="preserve">
34803480
<value>Inner and outer selector expressions have the same parameter instance. Probably you use the same lambda expression for both selectors, which is currently not supported.</value>
34813481
</data>
3482+
<data name="ExTypeXWhichContainsRenamingFieldYDoesntExistInStorageModel" xml:space="preserve">
3483+
<value>The type '{0}',which contains renaming field '{1}', doesn't exist in storage model.</value>
3484+
</data>
34823485
</root>

0 commit comments

Comments
 (0)