Skip to content

Commit 0be5676

Browse files
fix: refactor enum extensions members (#309)
1 parent e13d586 commit 0be5676

15 files changed

Lines changed: 141 additions & 386 deletions

File tree

CodeGenerator/CodeGenerator.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,10 +115,11 @@ public Task<GenerateResponse> Generate(GenerateRequest generateRequest)
115115
}
116116
});
117117

118+
var enums = DbDriver is EnumDbDriver enumDbDriver ? enumDbDriver.Enums : [];
118119
var files = GetFileQueries()
119120
.Select(fq => QueriesGen.GenerateFile(fq.Value, fq.Key))
120121
.AddRangeExcludeNulls([
121-
ModelsGen.GenerateFile(DbDriver.Tables, DbDriver.Enums),
122+
ModelsGen.GenerateFile(DbDriver.Tables, enums),
122123
UtilsGen.GenerateFile()
123124
])
124125
.AddRangeIf([CsprojGen.GenerateFile()], Options.GenerateCsproj);

CodeGenerator/Generators/EnumsGen.cs

Lines changed: 15 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -10,52 +10,27 @@ internal class EnumsGen(DbDriver dbDriver)
1010
{
1111
public MemberDeclarationSyntax[] Generate(string name, IList<string> possibleValues)
1212
{
13+
if (dbDriver is not EnumDbDriver enumDbDriver)
14+
return [];
15+
1316
var enumValuesDef = possibleValues
1417
.Select((v, i) => $"{v.ToPascalCase()} = {i + 1}")
1518
.JoinByComma();
1619

1720
var enumType = ParseMemberDeclaration($$"""
18-
public enum {{name}}
19-
{
20-
Invalid = 0, // reserved for invalid enum value
21-
{{enumValuesDef}}
22-
}
23-
""")!;
24-
var enumExtensions = ParseMemberDeclaration($$"""
25-
public static class {{name}}Extensions
26-
{
27-
private static readonly Dictionary<string, {{name}}> StringToEnum = new Dictionary<string, {{name}}>()
28-
{
29-
[string.Empty] = {{name}}.Invalid,
30-
{{possibleValues
31-
.Select(v => $"[\"{v}\"] = {name}.{v.ToPascalCase()}")
32-
.JoinByComma()}}
33-
};
34-
35-
private static readonly Dictionary<{{name}}, string> EnumToString = new Dictionary<{{name}}, string>()
36-
{
37-
[{{name}}.Invalid] = string.Empty,
38-
{{possibleValues
39-
.Select(v => $"[{name}.{v.ToPascalCase()}] = \"{v}\"")
40-
.JoinByComma()}}
41-
};
42-
43-
public static {{name}} To{{name}}(this string me)
44-
{
45-
return StringToEnum[me];
46-
}
21+
public enum {{name}}
22+
{
23+
Invalid = 0, // reserved for invalid enum value
24+
{{enumValuesDef}}
25+
}
26+
""")!;
4727

48-
public static string Stringify(this {{name}} me)
49-
{
50-
return EnumToString[me];
51-
}
28+
var classMembers = enumDbDriver.GetEnumExtensionsMembers(name, possibleValues);
29+
if (classMembers.Length == 0)
30+
return [enumType];
5231

53-
public static HashSet<{{name}}> To{{name}}Set(this string me)
54-
{
55-
return new HashSet<{{name}}>(me.Split(',').ToList().Select(v => StringToEnum[v]));
56-
}
57-
}
58-
""")!;
59-
return [enumType, enumExtensions];
32+
var enumExtensionsClass = (ClassDeclarationSyntax)ParseMemberDeclaration(
33+
$$"""public static class {{name}}Extensions { }""")!;
34+
return [enumType, enumExtensionsClass.AddMembers(classMembers)];
6035
}
6136
}

Drivers/DbDriver.cs

Lines changed: 11 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@ public abstract class DbDriver
1919

2020
public Dictionary<string, Dictionary<string, Table>> Tables { get; }
2121

22-
public Dictionary<string, Dictionary<string, Plugin.Enum>> Enums { get; }
23-
2422
protected IList<Query> Queries { get; }
2523

2624
private HashSet<string> NullableTypesInDotnetCore { get; } =
@@ -31,7 +29,7 @@ public abstract class DbDriver
3129
"IPAddress"
3230
];
3331

34-
private HashSet<string> NullableTypes { get; } =
32+
protected HashSet<string> NullableTypes { get; } =
3533
[
3634
"bool",
3735
"byte",
@@ -79,11 +77,6 @@ protected DbDriver(
7977
DefaultSchema = catalog.DefaultSchema;
8078
Tables = ConstructTablesLookup(catalog);
8179
Queries = queries;
82-
Enums = ConstructEnumsLookup(catalog);
83-
84-
foreach (var schemaEnums in Enums)
85-
foreach (var e in schemaEnums.Value)
86-
NullableTypes.Add(e.Key.ToModelName(schemaEnums.Key, DefaultSchema));
8780

8881
if (!Options.DotnetFramework.IsDotnetCore())
8982
return;
@@ -108,21 +101,6 @@ private static Dictionary<string, Dictionary<string, Table>> ConstructTablesLook
108101
);
109102
}
110103

111-
private static Dictionary<string, Dictionary<string, Plugin.Enum>> ConstructEnumsLookup(Catalog catalog)
112-
{
113-
return catalog
114-
.Schemas
115-
.SelectMany(s => s.Enums.Select(e => new { EnumItem = e, Schema = s.Name }))
116-
.GroupBy(x => x.Schema == catalog.DefaultSchema ? string.Empty : x.Schema)
117-
.ToDictionary(
118-
group => group.Key,
119-
group => group.ToDictionary(
120-
x => x.EnumItem.Name,
121-
x => x.EnumItem
122-
)
123-
);
124-
}
125-
126104
public virtual ISet<string> GetUsingDirectivesForQueries()
127105
{
128106
return new HashSet<string>
@@ -193,15 +171,10 @@ protected virtual ISet<string> GetConfigureSqlMappings()
193171

194172
public virtual MemberDeclarationSyntax[] GetMemberDeclarationsForUtils()
195173
{
196-
var memberDeclarations = new List<MemberDeclarationSyntax>();
197174
if (!Options.UseDapper)
198-
return [.. memberDeclarations];
199-
200-
memberDeclarations.AddRange(ColumnMappings
201-
.Where(m => TypeExistsInQueries(m.Key) && m.Value.SqlMapperImpl is not null)
202-
.Select(m => ParseMemberDeclaration(m.Value.SqlMapperImpl!)!));
203-
204-
return [.. memberDeclarations,
175+
return [];
176+
return [..
177+
GetSqlMapperMemberDeclarations(),
205178
ParseMemberDeclaration($$"""
206179
public static void ConfigureSqlMapper()
207180
{
@@ -210,6 +183,13 @@ public static void ConfigureSqlMapper()
210183
""")!];
211184
}
212185

186+
private MemberDeclarationSyntax[] GetSqlMapperMemberDeclarations()
187+
{
188+
return [.. ColumnMappings
189+
.Where(m => TypeExistsInQueries(m.Key) && m.Value.SqlMapperImpl is not null)
190+
.Select(m => ParseMemberDeclaration(m.Value.SqlMapperImpl!)!)];
191+
}
192+
213193
public abstract string TransformQueryText(Query query);
214194

215195
public abstract ConnectionGenCommands EstablishConnection(Query query);

Drivers/EnumDbDriver.cs

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,49 @@
1+
using Microsoft.CodeAnalysis.CSharp.Syntax;
12
using Plugin;
23
using SqlcGenCsharp;
34
using SqlcGenCsharp.Drivers;
45
using System.Collections.Generic;
6+
using System.Linq;
7+
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
58

6-
public abstract class EnumDbDriver(Options options, Catalog catalog, IList<Query> queries) : DbDriver(options, catalog, queries)
9+
public abstract class EnumDbDriver : DbDriver
710
{
11+
public Dictionary<string, Dictionary<string, Enum>> Enums { get; }
12+
13+
public EnumDbDriver(Options options, Catalog catalog, IList<Query> queries) : base(options, catalog, queries)
14+
{
15+
Enums = ConstructEnumsLookup(catalog);
16+
17+
foreach (var schemaEnums in Enums)
18+
foreach (var e in schemaEnums.Value)
19+
NullableTypes.Add(e.Key.ToModelName(schemaEnums.Key, DefaultSchema));
20+
}
21+
22+
public virtual MemberDeclarationSyntax[] GetEnumExtensionsMembers(string name, IList<string> possibleValues)
23+
{
24+
return [.. new List<MemberDeclarationSyntax>()
25+
{
26+
ParseMemberDeclaration($$"""
27+
private static readonly Dictionary<string, {{name}}> StringToEnum = new Dictionary<string, {{name}}>()
28+
{
29+
[string.Empty] = {{name}}.Invalid,
30+
{{possibleValues
31+
.Select(v => $"[\"{v}\"] = {name}.{v.ToPascalCase()}")
32+
.JoinByComma()}}
33+
};
34+
""")!
35+
}.AddRangeIf(
36+
[
37+
ParseMemberDeclaration($$"""
38+
public static {{name}} To{{name}}(this string me)
39+
{
40+
return StringToEnum[me];
41+
}
42+
""")!
43+
],
44+
!Options.UseDapper)];
45+
}
46+
847
protected abstract Enum? GetEnumType(Column column);
948

1049
protected abstract string EnumToCsharpDataType(Column column);
@@ -28,4 +67,19 @@ protected override string GetCsharpTypeWithoutNullableSuffix(Column column, Quer
2867
return EnumToCsharpDataType(column);
2968
return base.GetCsharpTypeWithoutNullableSuffix(column, query);
3069
}
70+
71+
private static Dictionary<string, Dictionary<string, Enum>> ConstructEnumsLookup(Catalog catalog)
72+
{
73+
return catalog
74+
.Schemas
75+
.SelectMany(s => s.Enums.Select(e => new { EnumItem = e, Schema = s.Name }))
76+
.GroupBy(x => x.Schema == catalog.DefaultSchema ? string.Empty : x.Schema)
77+
.ToDictionary(
78+
group => group.Key,
79+
group => group.ToDictionary(
80+
x => x.EnumItem.Name,
81+
x => x.EnumItem
82+
)
83+
);
84+
}
3185
}

Drivers/Generators/CommonGen.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public string ConstructDapperParamsDict(Query query)
5252
{{queryParamsVar}}.Add($"@{{p.Column.Name}}Arg{i}", {{argsVar}}.{{param}}[i]);
5353
""";
5454

55-
if (dbDriver.Enums.ContainsKey(p.Column.Type.Name))
55+
if (dbDriver is EnumDbDriver enumDbDriver && enumDbDriver.Enums.ContainsKey(p.Column.Type.Name))
5656
param += "?.ToEnumString()";
5757

5858
var notNull = dbDriver.IsColumnNotNull(p.Column, query);

Drivers/MySqlConnectorDriver.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,20 @@ protected override ISet<string> GetConfigureSqlMappings()
275275
.AddRangeExcludeNulls(setSqlMappings);
276276
}
277277

278+
public override MemberDeclarationSyntax[] GetEnumExtensionsMembers(string name, IList<string> possibleValues)
279+
{
280+
return [.. base
281+
.GetEnumExtensionsMembers(name, possibleValues)
282+
.AddRangeExcludeNulls([
283+
ParseMemberDeclaration($$"""
284+
public static HashSet<{{name}}> To{{name}}Set(this string me)
285+
{
286+
return new HashSet<{{name}}>(me.Split(',').ToList().Select(v => StringToEnum[v]));
287+
}
288+
""")!
289+
])];
290+
}
291+
278292
private MemberDeclarationSyntax[] GetSetTypeHandlers()
279293
{
280294
var setTypeHandlerFunc = (string x) =>

Drivers/NpgsqlDriver.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,29 @@ public override void SetValue(IDbDataParameter parameter, T{{optionalDotnetCoreN
479479
];
480480
}
481481

482+
public override MemberDeclarationSyntax[] GetEnumExtensionsMembers(string name, IList<string> possibleValues)
483+
{
484+
return [.. base
485+
.GetEnumExtensionsMembers(name, possibleValues)
486+
.AddRangeExcludeNulls([
487+
ParseMemberDeclaration($$"""
488+
private static readonly Dictionary<{{name}}, string> EnumToString = new Dictionary<{{name}}, string>()
489+
{
490+
[{{name}}.Invalid] = string.Empty,
491+
{{possibleValues
492+
.Select(v => $"[{name}.{v.ToPascalCase()}] = \"{v}\"")
493+
.JoinByComma()}}
494+
};
495+
""")!,
496+
ParseMemberDeclaration($$"""
497+
public static string Stringify(this {{name}} me)
498+
{
499+
return EnumToString[me];
500+
}
501+
""")!
502+
])];
503+
}
504+
482505
public override ConnectionGenCommands EstablishConnection(Query query)
483506
{
484507
var connectionStringVar = Variable.ConnectionString.AsPropertyName();

examples/MySqlConnectorDapperExample/Models.cs

Lines changed: 0 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -93,23 +93,6 @@ public static class BiosBioTypeExtensions
9393
["Biography"] = BiosBioType.Biography,
9494
["Memoir"] = BiosBioType.Memoir
9595
};
96-
private static readonly Dictionary<BiosBioType, string> EnumToString = new Dictionary<BiosBioType, string>()
97-
{
98-
[BiosBioType.Invalid] = string.Empty,
99-
[BiosBioType.Autobiography] = "Autobiography",
100-
[BiosBioType.Biography] = "Biography",
101-
[BiosBioType.Memoir] = "Memoir"
102-
};
103-
public static BiosBioType ToBiosBioType(this string me)
104-
{
105-
return StringToEnum[me];
106-
}
107-
108-
public static string Stringify(this BiosBioType me)
109-
{
110-
return EnumToString[me];
111-
}
112-
11396
public static HashSet<BiosBioType> ToBiosBioTypeSet(this string me)
11497
{
11598
return new HashSet<BiosBioType>(me.Split(',').ToList().Select(v => StringToEnum[v]));
@@ -133,23 +116,6 @@ public static class BiosAuthorTypeExtensions
133116
["Editor"] = BiosAuthorType.Editor,
134117
["Translator"] = BiosAuthorType.Translator
135118
};
136-
private static readonly Dictionary<BiosAuthorType, string> EnumToString = new Dictionary<BiosAuthorType, string>()
137-
{
138-
[BiosAuthorType.Invalid] = string.Empty,
139-
[BiosAuthorType.Author] = "Author",
140-
[BiosAuthorType.Editor] = "Editor",
141-
[BiosAuthorType.Translator] = "Translator"
142-
};
143-
public static BiosAuthorType ToBiosAuthorType(this string me)
144-
{
145-
return StringToEnum[me];
146-
}
147-
148-
public static string Stringify(this BiosAuthorType me)
149-
{
150-
return EnumToString[me];
151-
}
152-
153119
public static HashSet<BiosAuthorType> ToBiosAuthorTypeSet(this string me)
154120
{
155121
return new HashSet<BiosAuthorType>(me.Split(',').ToList().Select(v => StringToEnum[v]));
@@ -173,23 +139,6 @@ public static class MysqlStringTypesCEnumExtensions
173139
["medium"] = MysqlStringTypesCEnum.Medium,
174140
["big"] = MysqlStringTypesCEnum.Big
175141
};
176-
private static readonly Dictionary<MysqlStringTypesCEnum, string> EnumToString = new Dictionary<MysqlStringTypesCEnum, string>()
177-
{
178-
[MysqlStringTypesCEnum.Invalid] = string.Empty,
179-
[MysqlStringTypesCEnum.Small] = "small",
180-
[MysqlStringTypesCEnum.Medium] = "medium",
181-
[MysqlStringTypesCEnum.Big] = "big"
182-
};
183-
public static MysqlStringTypesCEnum ToMysqlStringTypesCEnum(this string me)
184-
{
185-
return StringToEnum[me];
186-
}
187-
188-
public static string Stringify(this MysqlStringTypesCEnum me)
189-
{
190-
return EnumToString[me];
191-
}
192-
193142
public static HashSet<MysqlStringTypesCEnum> ToMysqlStringTypesCEnumSet(this string me)
194143
{
195144
return new HashSet<MysqlStringTypesCEnum>(me.Split(',').ToList().Select(v => StringToEnum[v]));
@@ -213,23 +162,6 @@ public static class MysqlStringTypesCSetExtensions
213162
["coffee"] = MysqlStringTypesCSet.Coffee,
214163
["milk"] = MysqlStringTypesCSet.Milk
215164
};
216-
private static readonly Dictionary<MysqlStringTypesCSet, string> EnumToString = new Dictionary<MysqlStringTypesCSet, string>()
217-
{
218-
[MysqlStringTypesCSet.Invalid] = string.Empty,
219-
[MysqlStringTypesCSet.Tea] = "tea",
220-
[MysqlStringTypesCSet.Coffee] = "coffee",
221-
[MysqlStringTypesCSet.Milk] = "milk"
222-
};
223-
public static MysqlStringTypesCSet ToMysqlStringTypesCSet(this string me)
224-
{
225-
return StringToEnum[me];
226-
}
227-
228-
public static string Stringify(this MysqlStringTypesCSet me)
229-
{
230-
return EnumToString[me];
231-
}
232-
233165
public static HashSet<MysqlStringTypesCSet> ToMysqlStringTypesCSetSet(this string me)
234166
{
235167
return new HashSet<MysqlStringTypesCSet>(me.Split(',').ToList().Select(v => StringToEnum[v]));

0 commit comments

Comments
 (0)