55using System ;
66using System . Collections . Generic ;
77using System . Diagnostics ;
8+ using System . Diagnostics . CodeAnalysis ;
89using System . Linq ;
910using System . Reflection ;
10- using JetBrains . Annotations ;
1111using Microsoft . EntityFrameworkCore ;
1212using Microsoft . EntityFrameworkCore . Design ;
1313using Microsoft . EntityFrameworkCore . Infrastructure ;
@@ -20,6 +20,11 @@ namespace EntityFrameworkCore.SingleStore.Design.Internal
2020{
2121 public class SingleStoreAnnotationCodeGenerator : AnnotationCodeGenerator
2222 {
23+ private static readonly MethodInfo _modelUseIdentityColumnsMethodInfo
24+ = typeof ( SingleStoreModelBuilderExtensions ) . GetRequiredRuntimeMethod (
25+ nameof ( SingleStoreModelBuilderExtensions . AutoIncrementColumns ) ,
26+ typeof ( ModelBuilder ) ) ;
27+
2328 private static readonly MethodInfo _modelHasCharSetMethodInfo
2429 = typeof ( SingleStoreModelBuilderExtensions ) . GetRequiredRuntimeMethod (
2530 nameof ( SingleStoreModelBuilderExtensions . HasCharSet ) ,
@@ -40,6 +45,12 @@ private static readonly MethodInfo _modelUseGuidCollationMethodInfo
4045 typeof ( ModelBuilder ) ,
4146 typeof ( string ) ) ;
4247
48+ private static readonly MethodInfo _modelHasAnnotationMethodInfo
49+ = typeof ( ModelBuilder ) . GetRequiredRuntimeMethod (
50+ nameof ( ModelBuilder . HasAnnotation ) ,
51+ typeof ( string ) ,
52+ typeof ( object ) ) ;
53+
4354 private static readonly MethodInfo _entityTypeHasCharSetMethodInfo
4455 = typeof ( SingleStoreEntityTypeBuilderExtensions ) . GetRequiredRuntimeMethod (
4556 nameof ( SingleStoreEntityTypeBuilderExtensions . HasCharSet ) ,
@@ -54,13 +65,24 @@ private static readonly MethodInfo _entityTypeUseCollationMethodInfo
5465 typeof ( string ) ,
5566 typeof ( DelegationModes ? ) ) ;
5667
68+ private static readonly MethodInfo _propertyUseIdentityColumnMethodInfo
69+ = typeof ( SingleStorePropertyBuilderExtensions ) . GetRequiredRuntimeMethod (
70+ nameof ( SingleStorePropertyBuilderExtensions . UseSingleStoreIdentityColumn ) ,
71+ typeof ( PropertyBuilder ) ) ;
72+
73+ private static readonly MethodInfo _propertyUseComputedColumnMethodInfo
74+ = typeof ( SingleStorePropertyBuilderExtensions ) . GetRequiredRuntimeMethod (
75+ nameof ( SingleStorePropertyBuilderExtensions . UseSingleStoreComputedColumn ) ,
76+ typeof ( PropertyBuilder ) ) ;
77+
78+
5779 private static readonly MethodInfo _propertyHasCharSetMethodInfo
5880 = typeof ( SingleStorePropertyBuilderExtensions ) . GetRequiredRuntimeMethod (
5981 nameof ( SingleStorePropertyBuilderExtensions . HasCharSet ) ,
6082 typeof ( PropertyBuilder ) ,
6183 typeof ( string ) ) ;
6284
63- public SingleStoreAnnotationCodeGenerator ( [ NotNull ] AnnotationCodeGeneratorDependencies dependencies )
85+ public SingleStoreAnnotationCodeGenerator ( [ JetBrains . Annotations . NotNull ] AnnotationCodeGeneratorDependencies dependencies )
6486 : base ( dependencies )
6587 {
6688 }
@@ -95,7 +117,7 @@ protected override MethodCallCodeFragment GenerateFluentApi(IModel model, IAnnot
95117 var delegationModes = model [ SingleStoreAnnotationNames . CharSetDelegation ] as DelegationModes ? ;
96118 return new MethodCallCodeFragment (
97119 _modelHasCharSetMethodInfo ,
98- new [ ] { annotation . Value }
120+ new [ ] { annotation . Value }
99121 . AppendIfTrue ( delegationModes . HasValue , delegationModes )
100122 . ToArray ( ) ) ;
101123 }
@@ -116,7 +138,7 @@ protected override MethodCallCodeFragment GenerateFluentApi(IModel model, IAnnot
116138 var delegationModes = model [ SingleStoreAnnotationNames . CollationDelegation ] as DelegationModes ? ;
117139 return new MethodCallCodeFragment (
118140 _modelUseCollationMethodInfo ,
119- new [ ] { annotation . Value }
141+ new [ ] { annotation . Value }
120142 . AppendIfTrue ( delegationModes . HasValue , delegationModes )
121143 . ToArray ( ) ) ;
122144 }
@@ -147,7 +169,7 @@ protected override MethodCallCodeFragment GenerateFluentApi(IEntityType entityTy
147169 var delegationModes = entityType [ SingleStoreAnnotationNames . CharSetDelegation ] as DelegationModes ? ;
148170 return new MethodCallCodeFragment (
149171 _entityTypeHasCharSetMethodInfo ,
150- new [ ] { annotation . Value }
172+ new [ ] { annotation . Value }
151173 . AppendIfTrue ( delegationModes . HasValue , delegationModes )
152174 . ToArray ( ) ) ;
153175 }
@@ -166,7 +188,7 @@ protected override MethodCallCodeFragment GenerateFluentApi(IEntityType entityTy
166188 var delegationModes = entityType [ SingleStoreAnnotationNames . CollationDelegation ] as DelegationModes ? ;
167189 return new MethodCallCodeFragment (
168190 _entityTypeUseCollationMethodInfo ,
169- new [ ] { annotation . Value }
191+ new [ ] { annotation . Value }
170192 . AppendIfTrue ( delegationModes . HasValue , delegationModes )
171193 . ToArray ( ) ) ;
172194 }
@@ -193,7 +215,7 @@ protected override AttributeCodeFragment GenerateDataAnnotation(IEntityType enti
193215 var delegationModes = entityType [ SingleStoreAnnotationNames . CharSetDelegation ] as DelegationModes ? ;
194216 return new AttributeCodeFragment (
195217 typeof ( SingleStoreCharSetAttribute ) ,
196- new [ ] { annotation . Value }
218+ new [ ] { annotation . Value }
197219 . AppendIfTrue ( delegationModes . HasValue , delegationModes )
198220 . ToArray ( ) ) ;
199221 }
@@ -212,7 +234,7 @@ protected override AttributeCodeFragment GenerateDataAnnotation(IEntityType enti
212234 var delegationModes = entityType [ SingleStoreAnnotationNames . CollationDelegation ] as DelegationModes ? ;
213235 return new AttributeCodeFragment (
214236 typeof ( SingleStoreCollationAttribute ) ,
215- new [ ] { annotation . Value }
237+ new [ ] { annotation . Value }
216238 . AppendIfTrue ( delegationModes . HasValue , delegationModes )
217239 . ToArray ( ) ) ;
218240 }
@@ -241,7 +263,7 @@ protected override MethodCallCodeFragment GenerateFluentApi(IProperty property,
241263
242264 switch ( annotation . Name )
243265 {
244- case SingleStoreAnnotationNames . CharSet when annotation . Value is string { Length : > 0 } charSet :
266+ case SingleStoreAnnotationNames . CharSet when annotation . Value is string { Length : > 0 } charSet :
245267 return new MethodCallCodeFragment (
246268 _propertyHasCharSetMethodInfo ,
247269 charSet ) ;
@@ -258,10 +280,75 @@ protected override AttributeCodeFragment GenerateDataAnnotation(IProperty proper
258280
259281 return annotation . Name switch
260282 {
261- SingleStoreAnnotationNames . CharSet when annotation . Value is string { Length : > 0 } charSet => new AttributeCodeFragment ( typeof ( SingleStoreCharSetAttribute ) , charSet ) ,
262- RelationalAnnotationNames . Collation when annotation . Value is string { Length : > 0 } collation => new AttributeCodeFragment ( typeof ( SingleStoreCollationAttribute ) , collation ) ,
283+ SingleStoreAnnotationNames . CharSet when annotation . Value is string { Length : > 0 } charSet => new AttributeCodeFragment (
284+ typeof ( SingleStoreCharSetAttribute ) , charSet ) ,
285+ RelationalAnnotationNames . Collation when annotation . Value is string { Length : > 0 } collation => new AttributeCodeFragment (
286+ typeof ( SingleStoreCollationAttribute ) , collation ) ,
263287 _ => base . GenerateDataAnnotation ( property , annotation )
264288 } ;
265289 }
290+
291+
292+ public override IReadOnlyList < MethodCallCodeFragment > GenerateFluentApiCalls (
293+ IModel model ,
294+ IDictionary < string , IAnnotation > annotations )
295+ {
296+ var fragments = new List < MethodCallCodeFragment > ( base . GenerateFluentApiCalls ( model , annotations ) ) ;
297+
298+ if ( GenerateValueGenerationStrategy ( annotations , onModel : true ) is { } valueGenerationStrategy )
299+ {
300+ fragments . Add ( valueGenerationStrategy ) ;
301+ }
302+
303+ return fragments ;
304+ }
305+
306+ public override IReadOnlyList < MethodCallCodeFragment > GenerateFluentApiCalls (
307+ IProperty property ,
308+ IDictionary < string , IAnnotation > annotations )
309+ {
310+ var fragments = new List < MethodCallCodeFragment > ( base . GenerateFluentApiCalls ( property , annotations ) ) ;
311+
312+ if ( GenerateValueGenerationStrategy ( annotations , onModel : false ) is { } valueGenerationStrategy )
313+ {
314+ fragments . Add ( valueGenerationStrategy ) ;
315+ }
316+
317+ return fragments ;
318+ }
319+
320+ private MethodCallCodeFragment GenerateValueGenerationStrategy ( IDictionary < string , IAnnotation > annotations , bool onModel )
321+ => TryGetAndRemove ( annotations , SingleStoreAnnotationNames . ValueGenerationStrategy , out SingleStoreValueGenerationStrategy strategy )
322+ ? strategy switch
323+ {
324+ SingleStoreValueGenerationStrategy . IdentityColumn => new MethodCallCodeFragment (
325+ onModel
326+ ? _modelUseIdentityColumnsMethodInfo
327+ : _propertyUseIdentityColumnMethodInfo ) ,
328+ SingleStoreValueGenerationStrategy . ComputedColumn => new MethodCallCodeFragment ( _propertyUseComputedColumnMethodInfo ) ,
329+ SingleStoreValueGenerationStrategy . None => new MethodCallCodeFragment (
330+ _modelHasAnnotationMethodInfo ,
331+ SingleStoreAnnotationNames . ValueGenerationStrategy ,
332+ SingleStoreValueGenerationStrategy . None ) ,
333+ _ => throw new ArgumentOutOfRangeException ( strategy . ToString ( ) )
334+ }
335+ : null ;
336+
337+ private static bool TryGetAndRemove < T > (
338+ IDictionary < string , IAnnotation > annotations ,
339+ string annotationName ,
340+ [ NotNullWhen ( true ) ] out T annotationValue )
341+ {
342+ if ( annotations . TryGetValue ( annotationName , out var annotation )
343+ && annotation . Value is not null )
344+ {
345+ annotations . Remove ( annotationName ) ;
346+ annotationValue = ( T ) annotation . Value ;
347+ return true ;
348+ }
349+
350+ annotationValue = default ;
351+ return false ;
352+ }
266353 }
267354}
0 commit comments