1
+ // Copyright (C) 2009-2025 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
+ // Created by: Ivan Galkin
5
+ // Created: 2009.05.20
6
+
7
+ using System ;
8
+ using System . Collections . Generic ;
9
+ using Xtensive . Core ;
10
+ using Xtensive . Orm . Upgrade ;
11
+ using Xtensive . Orm . Tests . Upgrade . Models . Version2 ;
12
+
13
+ namespace Xtensive . Orm . Tests . Upgrade . Models
14
+ {
15
+ [ Serializable ]
16
+ public class Upgrader : UpgradeHandler
17
+ {
18
+ [ Flags ]
19
+ public enum ModelParts
20
+ {
21
+ Order = 1 << 0 ,
22
+ Product = 1 << 1 ,
23
+ BoyGirl = 1 << 2 ,
24
+ CrazyAssociations = 1 << 3 ,
25
+ ComplexFieldCopy = 1 << 4 ,
26
+ Generics = Order | BoyGirl | 1 << 5 ,
27
+ All = Order | Product | BoyGirl | CrazyAssociations | ComplexFieldCopy | Generics
28
+ }
29
+
30
+ private const string Version1Ns = "Xtensive.Orm.Tests.Upgrade.Models.Version1" ;
31
+
32
+ private static bool isEnabled = false ;
33
+ private static int ? runningVersion ;
34
+ private static ModelParts modelParts = ModelParts . All ;
35
+
36
+ /// <exception cref="InvalidOperationException">Handler is already enabled.</exception>
37
+ public static IDisposable EnableForVersion ( int version )
38
+ {
39
+ if ( isEnabled )
40
+ throw new InvalidOperationException ( ) ;
41
+ isEnabled = true ;
42
+ runningVersion = version ;
43
+ return new Disposable ( _ => {
44
+ isEnabled = false ;
45
+ runningVersion = null ;
46
+ } ) ;
47
+ }
48
+
49
+ /// <exception cref="InvalidOperationException">Handler is already enabled.</exception>
50
+ public static IDisposable EnableForVersion ( int version , ModelParts parts )
51
+ {
52
+ if ( isEnabled )
53
+ throw new InvalidOperationException ( ) ;
54
+ isEnabled = true ;
55
+ runningVersion = version ;
56
+ modelParts = parts ;
57
+ return new Disposable ( _ => {
58
+ isEnabled = false ;
59
+ runningVersion = null ;
60
+ modelParts = ModelParts . All ;
61
+ } ) ;
62
+ }
63
+
64
+
65
+ public override bool IsEnabled => isEnabled ;
66
+
67
+ protected override string DetectAssemblyVersion ( ) => runningVersion . ToString ( ) ;
68
+
69
+ public override bool CanUpgradeFrom ( string oldVersion ) => true ;
70
+
71
+ protected override void AddUpgradeHints ( Collections . ISet < UpgradeHint > hints )
72
+ {
73
+ if ( runningVersion == 2 )
74
+ Version1To2Hints . ForEach ( hint => hints . Add ( hint ) ) ;
75
+ if ( runningVersion == 3 )
76
+ Version1To3Hints . ForEach ( hint => hints . Add ( hint ) ) ;
77
+ }
78
+
79
+ public override void OnUpgrade ( )
80
+ {
81
+ }
82
+
83
+ public override bool IsTypeAvailable ( Type type , UpgradeStage upgradeStage )
84
+ {
85
+ string suffix = $ ".Version{ runningVersion } ";
86
+ var originalNamespace = type . Namespace ;
87
+ var nameSpace = originalNamespace . TryCutSuffix ( suffix ) ;
88
+ return nameSpace != originalNamespace
89
+ && base . IsTypeAvailable ( type , upgradeStage ) ;
90
+ }
91
+
92
+ private static IEnumerable < UpgradeHint > Version1To2Hints
93
+ {
94
+ get {
95
+ // renaming types
96
+ if ( modelParts . HasFlag ( ModelParts . Order ) ) {
97
+ yield return new RenameTypeHint (
98
+ $ "{ Version1Ns } .BusinessContact", typeof ( Person ) ) ;
99
+ yield return new RenameTypeHint (
100
+ $ "{ Version1Ns } .Person", typeof ( BusinessContact ) ) ;
101
+ yield return new RenameTypeHint (
102
+ $ "{ Version1Ns } .Address", typeof ( Address ) ) ;
103
+ yield return new RenameTypeHint (
104
+ $ "{ Version1Ns } .Employee", typeof ( Employee ) ) ;
105
+ yield return new RenameTypeHint (
106
+ $ "{ Version1Ns } .Order", typeof ( Order ) ) ;
107
+ }
108
+
109
+ if ( modelParts . HasFlag ( ModelParts . Product ) ) {
110
+ yield return new RenameTypeHint (
111
+ $ "{ Version1Ns } .Product", typeof ( Product ) ) ;
112
+ yield return new RenameTypeHint (
113
+ $ "{ Version1Ns } .Category", typeof ( ProductGroup ) ) ;
114
+ }
115
+
116
+ if ( modelParts . HasFlag ( ModelParts . BoyGirl ) ) {
117
+ yield return new RenameTypeHint (
118
+ $ "{ Version1Ns } .Boy", typeof ( Boy ) ) ;
119
+ yield return new RenameTypeHint (
120
+ $ "{ Version1Ns } .Girl", typeof ( Girl ) ) ;
121
+ }
122
+
123
+ if ( modelParts . HasFlag ( ModelParts . CrazyAssociations ) ) {
124
+ yield return new RenameTypeHint (
125
+ $ "{ Version1Ns } .Entity1", typeof ( Entity1 ) ) ;
126
+ yield return new RenameTypeHint (
127
+ $ "{ Version1Ns } .Entity2", typeof ( Entity2 ) ) ;
128
+ yield return new RenameTypeHint (
129
+ $ "{ Version1Ns } .Entity3", typeof ( Entity3 ) ) ;
130
+ yield return new RenameTypeHint (
131
+ $ "{ Version1Ns } .Entity4", typeof ( Entity4 ) ) ;
132
+
133
+ yield return new RenameTypeHint (
134
+ $ "{ Version1Ns } .Structure1", typeof ( Structure1 ) ) ;
135
+ yield return new RenameTypeHint (
136
+ $ "{ Version1Ns } .Structure2", typeof ( Structure2 ) ) ;
137
+ yield return new RenameTypeHint (
138
+ $ "{ Version1Ns } .Structure3", typeof ( Structure3 ) ) ;
139
+ yield return new RenameTypeHint (
140
+ $ "{ Version1Ns } .Structure4", typeof ( Structure4 ) ) ;
141
+
142
+ yield return new RenameTypeHint (
143
+ $ "{ Version1Ns } .StructureContainer1", typeof ( StructureContainer1 ) ) ;
144
+ yield return new RenameTypeHint (
145
+ $ "{ Version1Ns } .StructureContainer2", typeof ( StructureContainer2 ) ) ;
146
+ yield return new RenameTypeHint (
147
+ $ "{ Version1Ns } .StructureContainer3", typeof ( StructureContainer3 ) ) ;
148
+ yield return new RenameTypeHint (
149
+ $ "{ Version1Ns } .StructureContainer4", typeof ( StructureContainer4 ) ) ;
150
+ }
151
+
152
+ if ( modelParts . HasFlag ( ModelParts . ComplexFieldCopy ) ) {
153
+ yield return new RenameTypeHint (
154
+ $ "{ Version1Ns } .MyStructureOwner", typeof ( MyStructureOwner ) ) ;
155
+ yield return new RenameTypeHint (
156
+ $ "{ Version1Ns } .ReferencedEntity", typeof ( ReferencedEntity ) ) ;
157
+ }
158
+
159
+ if ( modelParts . HasFlag ( ModelParts . Generics ) ) {
160
+ yield return new RenameTypeHint (
161
+ $ "{ Version1Ns } .Sync<>", typeof ( NewSync < > ) ) ;
162
+ }
163
+
164
+ // renaming fields
165
+ if ( modelParts . HasFlag ( ModelParts . Order ) ) {
166
+ yield return new RenameFieldHint ( typeof ( Order ) , "OrderNumber" , "Number" ) ;
167
+ }
168
+
169
+ if ( modelParts . HasFlag ( ModelParts . Product ) ) {
170
+ yield return new RenameFieldHint ( typeof ( Product ) , "Name" , "Title" ) ;
171
+ yield return new RenameFieldHint ( typeof ( Product ) , "Category" , "Group" ) ;
172
+ yield return new RenameFieldHint ( typeof ( ProductGroup ) , "Id" , "GroupId" ) ;
173
+ }
174
+
175
+ if ( modelParts . HasFlag ( ModelParts . BoyGirl ) ) {
176
+ yield return new RenameFieldHint ( typeof ( Boy ) , "FriendlyGirls" , "MeetWith" ) ;
177
+ yield return new RenameFieldHint ( typeof ( Girl ) , "FriendlyBoys" , "MeetWith" ) ;
178
+ }
179
+
180
+ if ( modelParts . HasFlag ( ModelParts . CrazyAssociations ) ) {
181
+ yield return new RenameFieldHint ( typeof ( Entity1 ) , "Id" , "Code" ) ;
182
+ yield return new RenameFieldHint ( typeof ( Entity2 ) , "Id" , "Code" ) ;
183
+ yield return new RenameFieldHint ( typeof ( Entity3 ) , "Id" , "Code" ) ;
184
+ yield return new RenameFieldHint ( typeof ( Entity4 ) , "Id" , "Code" ) ;
185
+ yield return new RenameFieldHint ( typeof ( Structure1 ) , "E1" , "MyE1" ) ;
186
+ yield return new RenameFieldHint ( typeof ( Structure2 ) , "E2" , "MyE2" ) ;
187
+ yield return new RenameFieldHint ( typeof ( Structure3 ) , "E3" , "MyE3" ) ;
188
+ yield return new RenameFieldHint ( typeof ( Structure4 ) , "E4" , "MyE4" ) ;
189
+ }
190
+
191
+ if ( modelParts . HasFlag ( ModelParts . Generics ) ) {
192
+ yield return new RenameFieldHint ( typeof ( NewSync < > ) , "Root" , "NewRoot" ) ;
193
+ }
194
+
195
+ // type changes
196
+ if ( modelParts . HasFlag ( ModelParts . Order ) ) {
197
+ yield return new ChangeFieldTypeHint ( typeof ( Person ) , "PassportNumber" ) ;
198
+ yield return new ChangeFieldTypeHint ( typeof ( Order ) , "Number" ) ;
199
+ }
200
+
201
+ // copying data
202
+ if ( modelParts . HasFlag ( ModelParts . Order ) ) {
203
+ yield return new CopyFieldHint (
204
+ $ "{ Version1Ns } .Employee", "FirstName" , typeof ( BusinessContact ) ) ;
205
+ yield return new CopyFieldHint (
206
+ $ "{ Version1Ns } .Employee", "LastName" , typeof ( BusinessContact ) ) ;
207
+ }
208
+ if ( ! IncludeTypeIdModifier . IsEnabled && modelParts . HasFlag ( ModelParts . ComplexFieldCopy ) )
209
+ yield return new CopyFieldHint (
210
+ $ "{ Version1Ns } .MyStructureOwner", "Structure" , typeof ( MyStructureOwner ) , "Reference" ) ;
211
+
212
+ }
213
+ }
214
+
215
+ private IEnumerable < UpgradeHint > Version1To3Hints
216
+ {
217
+ get {
218
+ yield return new RenameTypeHint (
219
+ $ "{ Version1Ns } .Order", typeof ( Models . Version3 . Order ) ) ;
220
+ yield return new RenameTypeHint (
221
+ $ "{ Version1Ns } .Person", typeof ( Models . Version3 . Person ) ) ;
222
+ }
223
+ }
224
+ }
225
+ }
0 commit comments