Skip to content

Commit

Permalink
general refactoring around the C# code
Browse files Browse the repository at this point in the history
  • Loading branch information
SockworkOrange committed Jun 27, 2024
1 parent 603680c commit 597022a
Show file tree
Hide file tree
Showing 10 changed files with 88 additions and 64 deletions.
22 changes: 13 additions & 9 deletions CodeGenerator/CodeGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using RubyCodegen;
using SqlcGenCsharp.Drivers;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
Expand All @@ -13,7 +14,7 @@ namespace SqlcGenCsharp;

public class CodeGenerator
{
public const string AutoGeneratedComment = "# auto-generated by sqlc - do not edit";
private const string AutoGeneratedComment = "# auto-generated by sqlc - do not edit";

private DbDriver? _dbDriver;
private Options? _options;
Expand Down Expand Up @@ -48,7 +49,6 @@ public Task<GenerateResponse> Generate(GenerateRequest generateRequest)
var files = fileQueries
.Select(fq => GenerateFile(fq.Value, fq.Key))
.AppendIfNotNull(GenerateGemfile());

return Task.FromResult(new GenerateResponse { Files = { files } });

Dictionary<string, Query[]> GetFileQueries()
Expand Down Expand Up @@ -77,14 +77,18 @@ private File GenerateFile(IList<Query> queries, string className)

{moduleDeclaration.Build()}
""";
return new File { Name = $"{className.SnakeCase()}.rb", Contents = ByteString.CopyFromUtf8(contents) };
return new File
{
Name = $"{className.SnakeCase()}.rb",
Contents = ByteString.CopyFromUtf8(contents)
};
}

private File? GenerateGemfile()
{
if (!Options.GenerateGemfile)
return null;
var requireGems = DbDriver.GetRequiredGems().Select(gem => $"gem '{gem.GetName()}'").JoinByNewLine();
var requireGems = DbDriver.GetRequiredGems().Select(gem => $"gem '{gem.Name()}'").JoinByNewLine();
return new File
{
Name = "Gemfile",
Expand Down Expand Up @@ -120,7 +124,10 @@ ModuleDeclaration GetModuleDeclaration()

ClassDeclaration GetClassDeclaration()
{
return new ClassDeclaration(className, new[] { initMethod }.Concat(queries.Select(GetMethodDeclaration)));
return new ClassDeclaration(
className,
new[] { initMethod }.Concat(queries.Select(GetMethodDeclaration))
);
}
}

Expand All @@ -129,10 +136,7 @@ private static SimpleStatement GenerateDataclass(string name, ClassMember classM
{
var dataclassName = $"{name.FirstCharToUpper()}{classMember.Name()}";
var dataColumns = columns.Select(c => $":{c.Name.ToLower()}").ToList();
var dataColumnsStr = dataColumns.Count < 5
? dataColumns.JoinByComma().Indent() :
$"\n{dataColumns.JoinByCommaAndNewLine().Indent()}\n";

var dataColumnsStr = dataColumns.JoinByCommaAndFormat();
return new SimpleStatement(dataclassName,
new SimpleExpression(options.RubyVersion.LatestRubySupported()
? $"Struct.new({dataColumnsStr})"
Expand Down
2 changes: 1 addition & 1 deletion Drivers/ClassMember.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System;

namespace SqlcGenCsharp;
namespace SqlcGenCsharp.Drivers;

public enum ClassMember
{
Expand Down
34 changes: 21 additions & 13 deletions Drivers/MethodGen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ public MethodDeclaration OneDeclare(string funcName, string queryTextConstant, s
new SimpleStatement($"{Variable.Entity.AsVar()}", newObjectExpression),
new SimpleExpression($"return {Variable.Entity.AsVar()}")
]
);
).ToList();

return new MethodDeclaration(funcName, GetMethodArgs(argInterface, parameters),
new List<IComposable>
{
new WithResource(Variable.Pool.AsProperty(), Variable.Client.AsVar(), withResourceBody)
new WithResource(Variable.Pool.AsProperty(), Variable.Client.AsVar(), withResourceBody.ToList())
});
}

Expand All @@ -52,15 +52,16 @@ public MethodDeclaration ManyDeclare(string funcName, string queryTextConstant,
dbDriver.PrepareStmt(funcName, queryTextConstant),
ExecuteAndAssign(funcName, queryParams),
new SimpleStatement(Variable.Entities.AsVar(), new SimpleExpression("[]")),
new ForeachLoop(Variable.Result.AsVar(), Variable.Row.AsVar(), new List<IComposable> { listAppend }),
new ForeachLoop(Variable.Result.AsVar(), Variable.Row.AsVar(),
new List<IComposable> { listAppend }),
new SimpleExpression($"return {Variable.Entities.AsVar()}")
]
);
);

return new MethodDeclaration(funcName, GetMethodArgs(argInterface, parameters),
new List<IComposable>
{
new WithResource(Variable.Pool.AsProperty(), Variable.Client.AsVar(), withResourceBody)
new WithResource(Variable.Pool.AsProperty(), Variable.Client.AsVar(), withResourceBody.ToList())
});
}

Expand All @@ -72,12 +73,14 @@ public MethodDeclaration ExecDeclare(string funcName, string queryTextConstant,
withResourceBody = withResourceBody.AppendIfNotNull(queryParams);
withResourceBody = withResourceBody
.Append(dbDriver.PrepareStmt(funcName, queryTextConstant))
.Append(dbDriver.ExecuteStmt(funcName, queryParams));
.Append(dbDriver.ExecuteStmt(funcName, queryParams))
.ToList();

return new MethodDeclaration(funcName, GetMethodArgs(argInterface, parameters),
new List<IComposable>
{
new WithResource(Variable.Pool.AsProperty(), Variable.Client.AsVar(), withResourceBody)
new WithResource(Variable.Pool.AsProperty(), Variable.Client.AsVar(), withResourceBody.ToList()
)
});
}

Expand All @@ -95,24 +98,29 @@ public MethodDeclaration ExecLastIdDeclare(string funcName, string queryTextCons
new SimpleExpression($"return {Variable.Client.AsVar()}.last_id")
]
);
return new MethodDeclaration(funcName, GetMethodArgs(argInterface, parameters),

return new MethodDeclaration(
funcName, GetMethodArgs(argInterface, parameters),
new List<IComposable>
{
new WithResource(Variable.Pool.AsProperty(), Variable.Client.AsVar(), withResourceBody)
});
new WithResource(Variable.Pool.AsProperty(), Variable.Client.AsVar(),
withResourceBody.ToList())
}
);
}

private static SimpleStatement? GetQueryParams(string argInterface, IList<Parameter> parameters)
{
var queryParams = parameters.Select(p => $"{argInterface}.{p.Column.Name}").ToList();
return queryParams.Count == 0
? null
: new SimpleStatement(Variable.QueryParams.AsVar(), new SimpleExpression($"[{queryParams.JoinByComma()}]"));
: new SimpleStatement(Variable.QueryParams.AsVar(),
new SimpleExpression($"[{queryParams.JoinByCommaAndFormat()}]"));
}

private static IEnumerable<SimpleExpression> GetColumnsInitExpressions(IEnumerable<Column> columns)
private static IList<SimpleExpression> GetColumnsInitExpressions(IList<Column> columns)
{
return columns.Select(c => new SimpleExpression($"{Variable.Row.AsVar()}['{c.Name}']"));
return columns.Select(c => new SimpleExpression($"{Variable.Row.AsVar()}['{c.Name}']")).ToList();
}

private SimpleStatement ExecuteAndAssign(string funcName, SimpleStatement? queryParams)
Expand Down
2 changes: 1 addition & 1 deletion Drivers/PgDriver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public override MethodDeclaration GetInitMethod()
]
);

IEnumerable<IComposable> PgClientCreate()
IList<IComposable> PgClientCreate()
{
return new List<IComposable>
{
Expand Down
13 changes: 6 additions & 7 deletions Extensions/ListExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

public static class ListExtensions
{
private const int MaxElementsPerLine = 5;

public static IEnumerable<T> AppendIfNotNull<T>(this IEnumerable<T> me, T? item)
{
return item is not null ? me.Append(item) : me;
Expand All @@ -12,13 +14,10 @@ public static string JoinByNewLine(this IEnumerable<string> me, int cnt = 1)
return string.Join(new string('\n', cnt), me);
}

public static string JoinByComma(this IEnumerable<string> me)
{
return string.Join(", ", me);
}

public static string JoinByCommaAndNewLine(this IEnumerable<string> me)
public static string JoinByCommaAndFormat(this IList<string> me)
{
return string.Join(",\n", me);
return me.Count < MaxElementsPerLine
? string.Join(", ", me).Indent()
: $"\n{string.Join(",\n", me).Indent()}\n";
}
}
4 changes: 2 additions & 2 deletions PluginOptions/Options.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ public Options(GenerateRequest generateRequest)

Enum.TryParse(rawOptions.DriverName, true, out DriverName outDriverName);
DriverName = outDriverName;
GenerateGemfile = rawOptions.GenerateCsproj;
RubyVersion = DotnetFrameworkExtensions.ParseName(rawOptions.TargetFramework);
GenerateGemfile = rawOptions.GenerateGemfile;
RubyVersion = RubyVersionExtensions.ParseName(rawOptions.RubyVersionPattern);
}

public DriverName DriverName { get; }
Expand Down
8 changes: 4 additions & 4 deletions PluginOptions/RawOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ internal class RawOptions
{
[JsonPropertyName("driver")] public required string DriverName { get; init; }

[JsonPropertyName("generateCsproj")]
public bool GenerateCsproj { get; init; } = true; // generating .csproj files by default
[JsonPropertyName("generateGemfile")]
public bool GenerateGemfile { get; init; } // not generating Gemfile files by default

[JsonPropertyName("targetFramework")]
public string TargetFramework { get; init; } = RubyVersion.Ruby1.ToName();
[JsonPropertyName("rubyVersionPattern")]
public string RubyVersionPattern { get; init; } = RubyVersion.V33.ToString();

[JsonPropertyName("filePerQuery")] public bool FilePerQuery { get; init; } // generating single file by default
}
55 changes: 34 additions & 21 deletions PluginOptions/RubyMajorVersion.cs
Original file line number Diff line number Diff line change
@@ -1,38 +1,51 @@
using System.Collections.Generic;
using System.Linq;
using System;
using System.Text.RegularExpressions;
using Enum = System.Enum;

namespace SqlcGenCsharp;

public enum RubyVersion
{
Ruby1,
Ruby2,
Ruby3
V31,
V32,
V33
}

public static class DotnetFrameworkExtensions
public static partial class RubyVersionExtensions
{
private static readonly Dictionary<RubyVersion, string> EnumToString = new()
public static RubyVersion ParseName(string versionPattern)
{
{ RubyVersion.Ruby1, "ruby1.0" },
{ RubyVersion.Ruby2, "ruby2.7" },
{ RubyVersion.Ruby3, "ruby3.3" }
};
var semanticVersionRegex = SemanticVersionRegex();
var match = semanticVersionRegex.Match(versionPattern);
if (!match.Success)
throw new ArgumentException($"version {versionPattern} can't be parsed to a ruby version");

public static string ToName(this RubyVersion me)
{
return EnumToString[me];
}
var major = short.Parse(match.Groups[1].Value);
if (major != 3)
throw new ArgumentException($"Ruby versions older than Ruby3 are not supported");

public static RubyVersion ParseName(string dotnetFramework)
{
return EnumToString
.ToDictionary(x => x.Value, x => x.Key)
[dotnetFramework];
short? minor = null;
if (match.Groups[2].Success)
minor = short.Parse(match.Groups[2].Value);
if ((minor is < 1 or > 3))
throw new ArgumentException($"Ruby versions newer than Ruby3.3 do not exist");

// short? patch = null; patch version is currently not interesting
// if (match.Groups[3].Success)
// patch = short.Parse(match.Groups[3].Value);

var rubyVersionStr = $"V{major}.{minor}";
var valid = Enum.TryParse(rubyVersionStr, out RubyVersion rubyVersion);
if (!valid)
throw new ArgumentException($"Failed to parse {rubyVersionStr} to {nameof(RubyVersion)}");
return rubyVersion;
}

public static bool LatestRubySupported(this RubyVersion me)
{
return me == RubyVersion.Ruby3;
return me is RubyVersion.V32 or RubyVersion.V33;
}

[GeneratedRegex(@"^(0|[1-9][0-9]*)(?:\.(0|[1-9][0-9]*))?(?:\.(0|[1-9][0-9]*))?$")]
private static partial Regex SemanticVersionRegex();
}
2 changes: 1 addition & 1 deletion RubySyntax/Basic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public string Build()
return $"require '{gem}'";
}

public string GetName()
public string Name()
{
return gem;
}
Expand Down
10 changes: 5 additions & 5 deletions RubySyntax/Flows.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace RubyCodegen;

public class WithResource(string resourceFrom, string resourceName, IEnumerable<IComposable> statements) : IComposable
public class WithResource(string resourceFrom, string resourceName, IList<IComposable> statements) : IComposable
{
public string Build()
{
Expand Down Expand Up @@ -50,14 +50,14 @@ public string Build()
}
}

public class NewObject(string objectType, IEnumerable<SimpleExpression> initExpressions,
IEnumerable<IComposable>? bodyStatements = null) : IComposable
public class NewObject(string objectType, IList<SimpleExpression> initExpressions,
IList<IComposable>? bodyStatements = null) : IComposable
{
public string Build()
{
var initParams = initExpressions
.Select(e => e.Build())
.JoinByCommaAndNewLine()
.JoinByNewLine()
.Indent();
var baseCommand = $"{objectType}.new(\n{initParams}\n)";
if (bodyStatements is null)
Expand All @@ -72,7 +72,7 @@ public string Build()
}
}

public class ForeachLoop(string collectionVar, string controlVar, IEnumerable<IComposable> statements) : IComposable
public class ForeachLoop(string collectionVar, string controlVar, IList<IComposable> statements) : IComposable
{
public string Build()
{
Expand Down

0 comments on commit 597022a

Please sign in to comment.