Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CodeGenerator/CodeGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,11 @@ public Task<GenerateResponse> Generate(GenerateRequest generateRequest)
}
});

var enums = DbDriver is EnumDbDriver enumDbDriver ? enumDbDriver.Enums : [];
var files = GetFileQueries()
.Select(fq => QueriesGen.GenerateFile(fq.Value, fq.Key))
.AddRangeExcludeNulls([
ModelsGen.GenerateFile(DbDriver.Tables, DbDriver.Enums),
ModelsGen.GenerateFile(DbDriver.Tables, enums),
UtilsGen.GenerateFile()
])
.AddRangeIf([CsprojGen.GenerateFile()], Options.GenerateCsproj);
Expand Down
55 changes: 15 additions & 40 deletions CodeGenerator/Generators/EnumsGen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,52 +10,27 @@ internal class EnumsGen(DbDriver dbDriver)
{
public MemberDeclarationSyntax[] Generate(string name, IList<string> possibleValues)
{
if (dbDriver is not EnumDbDriver enumDbDriver)
return [];

var enumValuesDef = possibleValues
.Select((v, i) => $"{v.ToPascalCase()} = {i + 1}")
.JoinByComma();

var enumType = ParseMemberDeclaration($$"""
public enum {{name}}
{
Invalid = 0, // reserved for invalid enum value
{{enumValuesDef}}
}
""")!;
var enumExtensions = ParseMemberDeclaration($$"""
public static class {{name}}Extensions
{
private static readonly Dictionary<string, {{name}}> StringToEnum = new Dictionary<string, {{name}}>()
{
[string.Empty] = {{name}}.Invalid,
{{possibleValues
.Select(v => $"[\"{v}\"] = {name}.{v.ToPascalCase()}")
.JoinByComma()}}
};

private static readonly Dictionary<{{name}}, string> EnumToString = new Dictionary<{{name}}, string>()
{
[{{name}}.Invalid] = string.Empty,
{{possibleValues
.Select(v => $"[{name}.{v.ToPascalCase()}] = \"{v}\"")
.JoinByComma()}}
};

public static {{name}} To{{name}}(this string me)
{
return StringToEnum[me];
}
public enum {{name}}
{
Invalid = 0, // reserved for invalid enum value
{{enumValuesDef}}
}
""")!;

public static string Stringify(this {{name}} me)
{
return EnumToString[me];
}
var classMembers = enumDbDriver.GetEnumExtensionsMembers(name, possibleValues);
if (classMembers.Length == 0)
return [enumType];

public static HashSet<{{name}}> To{{name}}Set(this string me)
{
return new HashSet<{{name}}>(me.Split(',').ToList().Select(v => StringToEnum[v]));
}
}
""")!;
return [enumType, enumExtensions];
var enumExtensionsClass = (ClassDeclarationSyntax)ParseMemberDeclaration(
$$"""public static class {{name}}Extensions { }""")!;
return [enumType, enumExtensionsClass.AddMembers(classMembers)];
}
}
42 changes: 11 additions & 31 deletions Drivers/DbDriver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ public abstract class DbDriver

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

public Dictionary<string, Dictionary<string, Plugin.Enum>> Enums { get; }

protected IList<Query> Queries { get; }

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

private HashSet<string> NullableTypes { get; } =
protected HashSet<string> NullableTypes { get; } =
[
"bool",
"byte",
Expand Down Expand Up @@ -79,11 +77,6 @@ protected DbDriver(
DefaultSchema = catalog.DefaultSchema;
Tables = ConstructTablesLookup(catalog);
Queries = queries;
Enums = ConstructEnumsLookup(catalog);

foreach (var schemaEnums in Enums)
foreach (var e in schemaEnums.Value)
NullableTypes.Add(e.Key.ToModelName(schemaEnums.Key, DefaultSchema));

if (!Options.DotnetFramework.IsDotnetCore())
return;
Expand All @@ -108,21 +101,6 @@ private static Dictionary<string, Dictionary<string, Table>> ConstructTablesLook
);
}

private static Dictionary<string, Dictionary<string, Plugin.Enum>> ConstructEnumsLookup(Catalog catalog)
{
return catalog
.Schemas
.SelectMany(s => s.Enums.Select(e => new { EnumItem = e, Schema = s.Name }))
.GroupBy(x => x.Schema == catalog.DefaultSchema ? string.Empty : x.Schema)
.ToDictionary(
group => group.Key,
group => group.ToDictionary(
x => x.EnumItem.Name,
x => x.EnumItem
)
);
}

public virtual ISet<string> GetUsingDirectivesForQueries()
{
return new HashSet<string>
Expand Down Expand Up @@ -193,15 +171,10 @@ protected virtual ISet<string> GetConfigureSqlMappings()

public virtual MemberDeclarationSyntax[] GetMemberDeclarationsForUtils()
{
var memberDeclarations = new List<MemberDeclarationSyntax>();
if (!Options.UseDapper)
return [.. memberDeclarations];

memberDeclarations.AddRange(ColumnMappings
.Where(m => TypeExistsInQueries(m.Key) && m.Value.SqlMapperImpl is not null)
.Select(m => ParseMemberDeclaration(m.Value.SqlMapperImpl!)!));

return [.. memberDeclarations,
return [];
return [..
GetSqlMapperMemberDeclarations(),
ParseMemberDeclaration($$"""
public static void ConfigureSqlMapper()
{
Expand All @@ -210,6 +183,13 @@ public static void ConfigureSqlMapper()
""")!];
}

private MemberDeclarationSyntax[] GetSqlMapperMemberDeclarations()
{
return [.. ColumnMappings
.Where(m => TypeExistsInQueries(m.Key) && m.Value.SqlMapperImpl is not null)
.Select(m => ParseMemberDeclaration(m.Value.SqlMapperImpl!)!)];
}

public abstract string TransformQueryText(Query query);

public abstract ConnectionGenCommands EstablishConnection(Query query);
Expand Down
56 changes: 55 additions & 1 deletion Drivers/EnumDbDriver.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,49 @@
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Plugin;
using SqlcGenCsharp;
using SqlcGenCsharp.Drivers;
using System.Collections.Generic;
using System.Linq;
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;

public abstract class EnumDbDriver(Options options, Catalog catalog, IList<Query> queries) : DbDriver(options, catalog, queries)
public abstract class EnumDbDriver : DbDriver
{
public Dictionary<string, Dictionary<string, Enum>> Enums { get; }

public EnumDbDriver(Options options, Catalog catalog, IList<Query> queries) : base(options, catalog, queries)
{
Enums = ConstructEnumsLookup(catalog);

foreach (var schemaEnums in Enums)
foreach (var e in schemaEnums.Value)
NullableTypes.Add(e.Key.ToModelName(schemaEnums.Key, DefaultSchema));
}

public virtual MemberDeclarationSyntax[] GetEnumExtensionsMembers(string name, IList<string> possibleValues)
{
return [.. new List<MemberDeclarationSyntax>()
{
ParseMemberDeclaration($$"""
private static readonly Dictionary<string, {{name}}> StringToEnum = new Dictionary<string, {{name}}>()
{
[string.Empty] = {{name}}.Invalid,
{{possibleValues
.Select(v => $"[\"{v}\"] = {name}.{v.ToPascalCase()}")
.JoinByComma()}}
};
""")!
}.AddRangeIf(
[
ParseMemberDeclaration($$"""
public static {{name}} To{{name}}(this string me)
{
return StringToEnum[me];
}
""")!
],
!Options.UseDapper)];
}

protected abstract Enum? GetEnumType(Column column);

protected abstract string EnumToCsharpDataType(Column column);
Expand All @@ -28,4 +67,19 @@ protected override string GetCsharpTypeWithoutNullableSuffix(Column column, Quer
return EnumToCsharpDataType(column);
return base.GetCsharpTypeWithoutNullableSuffix(column, query);
}

private static Dictionary<string, Dictionary<string, Enum>> ConstructEnumsLookup(Catalog catalog)
{
return catalog
.Schemas
.SelectMany(s => s.Enums.Select(e => new { EnumItem = e, Schema = s.Name }))
.GroupBy(x => x.Schema == catalog.DefaultSchema ? string.Empty : x.Schema)
.ToDictionary(
group => group.Key,
group => group.ToDictionary(
x => x.EnumItem.Name,
x => x.EnumItem
)
);
}
}
2 changes: 1 addition & 1 deletion Drivers/Generators/CommonGen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public string ConstructDapperParamsDict(Query query)
{{queryParamsVar}}.Add($"@{{p.Column.Name}}Arg{i}", {{argsVar}}.{{param}}[i]);
""";

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

var notNull = dbDriver.IsColumnNotNull(p.Column, query);
Expand Down
14 changes: 14 additions & 0 deletions Drivers/MySqlConnectorDriver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,20 @@ protected override ISet<string> GetConfigureSqlMappings()
.AddRangeExcludeNulls(setSqlMappings);
}

public override MemberDeclarationSyntax[] GetEnumExtensionsMembers(string name, IList<string> possibleValues)
{
return [.. base
.GetEnumExtensionsMembers(name, possibleValues)
.AddRangeExcludeNulls([
ParseMemberDeclaration($$"""
public static HashSet<{{name}}> To{{name}}Set(this string me)
{
return new HashSet<{{name}}>(me.Split(',').ToList().Select(v => StringToEnum[v]));
}
""")!
])];
}

private MemberDeclarationSyntax[] GetSetTypeHandlers()
{
var setTypeHandlerFunc = (string x) =>
Expand Down
23 changes: 23 additions & 0 deletions Drivers/NpgsqlDriver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,29 @@ public override void SetValue(IDbDataParameter parameter, T{{optionalDotnetCoreN
];
}

public override MemberDeclarationSyntax[] GetEnumExtensionsMembers(string name, IList<string> possibleValues)
{
return [.. base
.GetEnumExtensionsMembers(name, possibleValues)
.AddRangeExcludeNulls([
ParseMemberDeclaration($$"""
private static readonly Dictionary<{{name}}, string> EnumToString = new Dictionary<{{name}}, string>()
{
[{{name}}.Invalid] = string.Empty,
{{possibleValues
.Select(v => $"[{name}.{v.ToPascalCase()}] = \"{v}\"")
.JoinByComma()}}
};
""")!,
ParseMemberDeclaration($$"""
public static string Stringify(this {{name}} me)
{
return EnumToString[me];
}
""")!
])];
}

public override ConnectionGenCommands EstablishConnection(Query query)
{
var connectionStringVar = Variable.ConnectionString.AsPropertyName();
Expand Down
68 changes: 0 additions & 68 deletions examples/MySqlConnectorDapperExample/Models.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,23 +93,6 @@ public static class BiosBioTypeExtensions
["Biography"] = BiosBioType.Biography,
["Memoir"] = BiosBioType.Memoir
};
private static readonly Dictionary<BiosBioType, string> EnumToString = new Dictionary<BiosBioType, string>()
{
[BiosBioType.Invalid] = string.Empty,
[BiosBioType.Autobiography] = "Autobiography",
[BiosBioType.Biography] = "Biography",
[BiosBioType.Memoir] = "Memoir"
};
public static BiosBioType ToBiosBioType(this string me)
{
return StringToEnum[me];
}

public static string Stringify(this BiosBioType me)
{
return EnumToString[me];
}

public static HashSet<BiosBioType> ToBiosBioTypeSet(this string me)
{
return new HashSet<BiosBioType>(me.Split(',').ToList().Select(v => StringToEnum[v]));
Expand All @@ -133,23 +116,6 @@ public static class BiosAuthorTypeExtensions
["Editor"] = BiosAuthorType.Editor,
["Translator"] = BiosAuthorType.Translator
};
private static readonly Dictionary<BiosAuthorType, string> EnumToString = new Dictionary<BiosAuthorType, string>()
{
[BiosAuthorType.Invalid] = string.Empty,
[BiosAuthorType.Author] = "Author",
[BiosAuthorType.Editor] = "Editor",
[BiosAuthorType.Translator] = "Translator"
};
public static BiosAuthorType ToBiosAuthorType(this string me)
{
return StringToEnum[me];
}

public static string Stringify(this BiosAuthorType me)
{
return EnumToString[me];
}

public static HashSet<BiosAuthorType> ToBiosAuthorTypeSet(this string me)
{
return new HashSet<BiosAuthorType>(me.Split(',').ToList().Select(v => StringToEnum[v]));
Expand All @@ -173,23 +139,6 @@ public static class MysqlStringTypesCEnumExtensions
["medium"] = MysqlStringTypesCEnum.Medium,
["big"] = MysqlStringTypesCEnum.Big
};
private static readonly Dictionary<MysqlStringTypesCEnum, string> EnumToString = new Dictionary<MysqlStringTypesCEnum, string>()
{
[MysqlStringTypesCEnum.Invalid] = string.Empty,
[MysqlStringTypesCEnum.Small] = "small",
[MysqlStringTypesCEnum.Medium] = "medium",
[MysqlStringTypesCEnum.Big] = "big"
};
public static MysqlStringTypesCEnum ToMysqlStringTypesCEnum(this string me)
{
return StringToEnum[me];
}

public static string Stringify(this MysqlStringTypesCEnum me)
{
return EnumToString[me];
}

public static HashSet<MysqlStringTypesCEnum> ToMysqlStringTypesCEnumSet(this string me)
{
return new HashSet<MysqlStringTypesCEnum>(me.Split(',').ToList().Select(v => StringToEnum[v]));
Expand All @@ -213,23 +162,6 @@ public static class MysqlStringTypesCSetExtensions
["coffee"] = MysqlStringTypesCSet.Coffee,
["milk"] = MysqlStringTypesCSet.Milk
};
private static readonly Dictionary<MysqlStringTypesCSet, string> EnumToString = new Dictionary<MysqlStringTypesCSet, string>()
{
[MysqlStringTypesCSet.Invalid] = string.Empty,
[MysqlStringTypesCSet.Tea] = "tea",
[MysqlStringTypesCSet.Coffee] = "coffee",
[MysqlStringTypesCSet.Milk] = "milk"
};
public static MysqlStringTypesCSet ToMysqlStringTypesCSet(this string me)
{
return StringToEnum[me];
}

public static string Stringify(this MysqlStringTypesCSet me)
{
return EnumToString[me];
}

public static HashSet<MysqlStringTypesCSet> ToMysqlStringTypesCSetSet(this string me)
{
return new HashSet<MysqlStringTypesCSet>(me.Split(',').ToList().Select(v => StringToEnum[v]));
Expand Down
Loading
Loading