Skip to content

Commit 597022a

Browse files
general refactoring around the C# code
1 parent 603680c commit 597022a

File tree

10 files changed

+88
-64
lines changed

10 files changed

+88
-64
lines changed

CodeGenerator/CodeGenerator.cs

+13-9
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using RubyCodegen;
44
using SqlcGenCsharp.Drivers;
55
using System;
6+
using System.Collections;
67
using System.Collections.Generic;
78
using System.IO;
89
using System.Linq;
@@ -13,7 +14,7 @@ namespace SqlcGenCsharp;
1314

1415
public class CodeGenerator
1516
{
16-
public const string AutoGeneratedComment = "# auto-generated by sqlc - do not edit";
17+
private const string AutoGeneratedComment = "# auto-generated by sqlc - do not edit";
1718

1819
private DbDriver? _dbDriver;
1920
private Options? _options;
@@ -48,7 +49,6 @@ public Task<GenerateResponse> Generate(GenerateRequest generateRequest)
4849
var files = fileQueries
4950
.Select(fq => GenerateFile(fq.Value, fq.Key))
5051
.AppendIfNotNull(GenerateGemfile());
51-
5252
return Task.FromResult(new GenerateResponse { Files = { files } });
5353

5454
Dictionary<string, Query[]> GetFileQueries()
@@ -77,14 +77,18 @@ private File GenerateFile(IList<Query> queries, string className)
7777
7878
{moduleDeclaration.Build()}
7979
""";
80-
return new File { Name = $"{className.SnakeCase()}.rb", Contents = ByteString.CopyFromUtf8(contents) };
80+
return new File
81+
{
82+
Name = $"{className.SnakeCase()}.rb",
83+
Contents = ByteString.CopyFromUtf8(contents)
84+
};
8185
}
8286

8387
private File? GenerateGemfile()
8488
{
8589
if (!Options.GenerateGemfile)
8690
return null;
87-
var requireGems = DbDriver.GetRequiredGems().Select(gem => $"gem '{gem.GetName()}'").JoinByNewLine();
91+
var requireGems = DbDriver.GetRequiredGems().Select(gem => $"gem '{gem.Name()}'").JoinByNewLine();
8892
return new File
8993
{
9094
Name = "Gemfile",
@@ -120,7 +124,10 @@ ModuleDeclaration GetModuleDeclaration()
120124

121125
ClassDeclaration GetClassDeclaration()
122126
{
123-
return new ClassDeclaration(className, new[] { initMethod }.Concat(queries.Select(GetMethodDeclaration)));
127+
return new ClassDeclaration(
128+
className,
129+
new[] { initMethod }.Concat(queries.Select(GetMethodDeclaration))
130+
);
124131
}
125132
}
126133

@@ -129,10 +136,7 @@ private static SimpleStatement GenerateDataclass(string name, ClassMember classM
129136
{
130137
var dataclassName = $"{name.FirstCharToUpper()}{classMember.Name()}";
131138
var dataColumns = columns.Select(c => $":{c.Name.ToLower()}").ToList();
132-
var dataColumnsStr = dataColumns.Count < 5
133-
? dataColumns.JoinByComma().Indent() :
134-
$"\n{dataColumns.JoinByCommaAndNewLine().Indent()}\n";
135-
139+
var dataColumnsStr = dataColumns.JoinByCommaAndFormat();
136140
return new SimpleStatement(dataclassName,
137141
new SimpleExpression(options.RubyVersion.LatestRubySupported()
138142
? $"Struct.new({dataColumnsStr})"

Drivers/ClassMember.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
using System;
22

3-
namespace SqlcGenCsharp;
3+
namespace SqlcGenCsharp.Drivers;
44

55
public enum ClassMember
66
{

Drivers/MethodGen.cs

+21-13
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,12 @@ public MethodDeclaration OneDeclare(string funcName, string queryTextConstant, s
2424
new SimpleStatement($"{Variable.Entity.AsVar()}", newObjectExpression),
2525
new SimpleExpression($"return {Variable.Entity.AsVar()}")
2626
]
27-
);
27+
).ToList();
2828

2929
return new MethodDeclaration(funcName, GetMethodArgs(argInterface, parameters),
3030
new List<IComposable>
3131
{
32-
new WithResource(Variable.Pool.AsProperty(), Variable.Client.AsVar(), withResourceBody)
32+
new WithResource(Variable.Pool.AsProperty(), Variable.Client.AsVar(), withResourceBody.ToList())
3333
});
3434
}
3535

@@ -52,15 +52,16 @@ public MethodDeclaration ManyDeclare(string funcName, string queryTextConstant,
5252
dbDriver.PrepareStmt(funcName, queryTextConstant),
5353
ExecuteAndAssign(funcName, queryParams),
5454
new SimpleStatement(Variable.Entities.AsVar(), new SimpleExpression("[]")),
55-
new ForeachLoop(Variable.Result.AsVar(), Variable.Row.AsVar(), new List<IComposable> { listAppend }),
55+
new ForeachLoop(Variable.Result.AsVar(), Variable.Row.AsVar(),
56+
new List<IComposable> { listAppend }),
5657
new SimpleExpression($"return {Variable.Entities.AsVar()}")
5758
]
58-
);
59+
);
5960

6061
return new MethodDeclaration(funcName, GetMethodArgs(argInterface, parameters),
6162
new List<IComposable>
6263
{
63-
new WithResource(Variable.Pool.AsProperty(), Variable.Client.AsVar(), withResourceBody)
64+
new WithResource(Variable.Pool.AsProperty(), Variable.Client.AsVar(), withResourceBody.ToList())
6465
});
6566
}
6667

@@ -72,12 +73,14 @@ public MethodDeclaration ExecDeclare(string funcName, string queryTextConstant,
7273
withResourceBody = withResourceBody.AppendIfNotNull(queryParams);
7374
withResourceBody = withResourceBody
7475
.Append(dbDriver.PrepareStmt(funcName, queryTextConstant))
75-
.Append(dbDriver.ExecuteStmt(funcName, queryParams));
76+
.Append(dbDriver.ExecuteStmt(funcName, queryParams))
77+
.ToList();
7678

7779
return new MethodDeclaration(funcName, GetMethodArgs(argInterface, parameters),
7880
new List<IComposable>
7981
{
80-
new WithResource(Variable.Pool.AsProperty(), Variable.Client.AsVar(), withResourceBody)
82+
new WithResource(Variable.Pool.AsProperty(), Variable.Client.AsVar(), withResourceBody.ToList()
83+
)
8184
});
8285
}
8386

@@ -95,24 +98,29 @@ public MethodDeclaration ExecLastIdDeclare(string funcName, string queryTextCons
9598
new SimpleExpression($"return {Variable.Client.AsVar()}.last_id")
9699
]
97100
);
98-
return new MethodDeclaration(funcName, GetMethodArgs(argInterface, parameters),
101+
102+
return new MethodDeclaration(
103+
funcName, GetMethodArgs(argInterface, parameters),
99104
new List<IComposable>
100105
{
101-
new WithResource(Variable.Pool.AsProperty(), Variable.Client.AsVar(), withResourceBody)
102-
});
106+
new WithResource(Variable.Pool.AsProperty(), Variable.Client.AsVar(),
107+
withResourceBody.ToList())
108+
}
109+
);
103110
}
104111

105112
private static SimpleStatement? GetQueryParams(string argInterface, IList<Parameter> parameters)
106113
{
107114
var queryParams = parameters.Select(p => $"{argInterface}.{p.Column.Name}").ToList();
108115
return queryParams.Count == 0
109116
? null
110-
: new SimpleStatement(Variable.QueryParams.AsVar(), new SimpleExpression($"[{queryParams.JoinByComma()}]"));
117+
: new SimpleStatement(Variable.QueryParams.AsVar(),
118+
new SimpleExpression($"[{queryParams.JoinByCommaAndFormat()}]"));
111119
}
112120

113-
private static IEnumerable<SimpleExpression> GetColumnsInitExpressions(IEnumerable<Column> columns)
121+
private static IList<SimpleExpression> GetColumnsInitExpressions(IList<Column> columns)
114122
{
115-
return columns.Select(c => new SimpleExpression($"{Variable.Row.AsVar()}['{c.Name}']"));
123+
return columns.Select(c => new SimpleExpression($"{Variable.Row.AsVar()}['{c.Name}']")).ToList();
116124
}
117125

118126
private SimpleStatement ExecuteAndAssign(string funcName, SimpleStatement? queryParams)

Drivers/PgDriver.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public override MethodDeclaration GetInitMethod()
3535
]
3636
);
3737

38-
IEnumerable<IComposable> PgClientCreate()
38+
IList<IComposable> PgClientCreate()
3939
{
4040
return new List<IComposable>
4141
{

Extensions/ListExtensions.cs

+6-7
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
public static class ListExtensions
44
{
5+
private const int MaxElementsPerLine = 5;
6+
57
public static IEnumerable<T> AppendIfNotNull<T>(this IEnumerable<T> me, T? item)
68
{
79
return item is not null ? me.Append(item) : me;
@@ -12,13 +14,10 @@ public static string JoinByNewLine(this IEnumerable<string> me, int cnt = 1)
1214
return string.Join(new string('\n', cnt), me);
1315
}
1416

15-
public static string JoinByComma(this IEnumerable<string> me)
16-
{
17-
return string.Join(", ", me);
18-
}
19-
20-
public static string JoinByCommaAndNewLine(this IEnumerable<string> me)
17+
public static string JoinByCommaAndFormat(this IList<string> me)
2118
{
22-
return string.Join(",\n", me);
19+
return me.Count < MaxElementsPerLine
20+
? string.Join(", ", me).Indent()
21+
: $"\n{string.Join(",\n", me).Indent()}\n";
2322
}
2423
}

PluginOptions/Options.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ public Options(GenerateRequest generateRequest)
2121

2222
Enum.TryParse(rawOptions.DriverName, true, out DriverName outDriverName);
2323
DriverName = outDriverName;
24-
GenerateGemfile = rawOptions.GenerateCsproj;
25-
RubyVersion = DotnetFrameworkExtensions.ParseName(rawOptions.TargetFramework);
24+
GenerateGemfile = rawOptions.GenerateGemfile;
25+
RubyVersion = RubyVersionExtensions.ParseName(rawOptions.RubyVersionPattern);
2626
}
2727

2828
public DriverName DriverName { get; }

PluginOptions/RawOptions.cs

+4-4
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ internal class RawOptions
66
{
77
[JsonPropertyName("driver")] public required string DriverName { get; init; }
88

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

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

1515
[JsonPropertyName("filePerQuery")] public bool FilePerQuery { get; init; } // generating single file by default
1616
}

PluginOptions/RubyMajorVersion.cs

+34-21
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,51 @@
1-
using System.Collections.Generic;
2-
using System.Linq;
1+
using System;
2+
using System.Text.RegularExpressions;
3+
using Enum = System.Enum;
34

45
namespace SqlcGenCsharp;
56

67
public enum RubyVersion
78
{
8-
Ruby1,
9-
Ruby2,
10-
Ruby3
9+
V31,
10+
V32,
11+
V33
1112
}
1213

13-
public static class DotnetFrameworkExtensions
14+
public static partial class RubyVersionExtensions
1415
{
15-
private static readonly Dictionary<RubyVersion, string> EnumToString = new()
16+
public static RubyVersion ParseName(string versionPattern)
1617
{
17-
{ RubyVersion.Ruby1, "ruby1.0" },
18-
{ RubyVersion.Ruby2, "ruby2.7" },
19-
{ RubyVersion.Ruby3, "ruby3.3" }
20-
};
18+
var semanticVersionRegex = SemanticVersionRegex();
19+
var match = semanticVersionRegex.Match(versionPattern);
20+
if (!match.Success)
21+
throw new ArgumentException($"version {versionPattern} can't be parsed to a ruby version");
2122

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

27-
public static RubyVersion ParseName(string dotnetFramework)
28-
{
29-
return EnumToString
30-
.ToDictionary(x => x.Value, x => x.Key)
31-
[dotnetFramework];
27+
short? minor = null;
28+
if (match.Groups[2].Success)
29+
minor = short.Parse(match.Groups[2].Value);
30+
if ((minor is < 1 or > 3))
31+
throw new ArgumentException($"Ruby versions newer than Ruby3.3 do not exist");
32+
33+
// short? patch = null; patch version is currently not interesting
34+
// if (match.Groups[3].Success)
35+
// patch = short.Parse(match.Groups[3].Value);
36+
37+
var rubyVersionStr = $"V{major}.{minor}";
38+
var valid = Enum.TryParse(rubyVersionStr, out RubyVersion rubyVersion);
39+
if (!valid)
40+
throw new ArgumentException($"Failed to parse {rubyVersionStr} to {nameof(RubyVersion)}");
41+
return rubyVersion;
3242
}
3343

3444
public static bool LatestRubySupported(this RubyVersion me)
3545
{
36-
return me == RubyVersion.Ruby3;
46+
return me is RubyVersion.V32 or RubyVersion.V33;
3747
}
48+
49+
[GeneratedRegex(@"^(0|[1-9][0-9]*)(?:\.(0|[1-9][0-9]*))?(?:\.(0|[1-9][0-9]*))?$")]
50+
private static partial Regex SemanticVersionRegex();
3851
}

RubySyntax/Basic.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ public string Build()
99
return $"require '{gem}'";
1010
}
1111

12-
public string GetName()
12+
public string Name()
1313
{
1414
return gem;
1515
}

RubySyntax/Flows.cs

+5-5
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
namespace RubyCodegen;
44

5-
public class WithResource(string resourceFrom, string resourceName, IEnumerable<IComposable> statements) : IComposable
5+
public class WithResource(string resourceFrom, string resourceName, IList<IComposable> statements) : IComposable
66
{
77
public string Build()
88
{
@@ -50,14 +50,14 @@ public string Build()
5050
}
5151
}
5252

53-
public class NewObject(string objectType, IEnumerable<SimpleExpression> initExpressions,
54-
IEnumerable<IComposable>? bodyStatements = null) : IComposable
53+
public class NewObject(string objectType, IList<SimpleExpression> initExpressions,
54+
IList<IComposable>? bodyStatements = null) : IComposable
5555
{
5656
public string Build()
5757
{
5858
var initParams = initExpressions
5959
.Select(e => e.Build())
60-
.JoinByCommaAndNewLine()
60+
.JoinByNewLine()
6161
.Indent();
6262
var baseCommand = $"{objectType}.new(\n{initParams}\n)";
6363
if (bodyStatements is null)
@@ -72,7 +72,7 @@ public string Build()
7272
}
7373
}
7474

75-
public class ForeachLoop(string collectionVar, string controlVar, IEnumerable<IComposable> statements) : IComposable
75+
public class ForeachLoop(string collectionVar, string controlVar, IList<IComposable> statements) : IComposable
7676
{
7777
public string Build()
7878
{

0 commit comments

Comments
 (0)