Skip to content

Commit f121572

Browse files
enabled type casting in generated pg code
1 parent a04192a commit f121572

File tree

10 files changed

+155
-89
lines changed

10 files changed

+155
-89
lines changed

Drivers/DbDriver.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ protected static IEnumerable<RequireGem> GetCommonGems()
1717

1818
public abstract SimpleStatement QueryTextConstantDeclare(Query query);
1919

20-
public abstract SimpleStatement PrepareStmt(string funcName, string queryTextConstant);
20+
public abstract IComposable PrepareStmt(string funcName, string queryTextConstant);
2121

2222
public abstract SimpleExpression ExecuteStmt(string funcName, SimpleStatement? queryParams);
2323

Drivers/MethodGen.cs

+31-30
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,16 @@ public MethodDeclaration OneDeclare(string funcName, string queryTextConstant, s
1414
IEnumerable<IComposable> withResourceBody = new List<IComposable>();
1515
var queryParams = GetQueryParams(argInterface, parameters);
1616
withResourceBody = withResourceBody.AppendIfNotNull(queryParams);
17-
withResourceBody = withResourceBody.Concat(
18-
[
19-
dbDriver.PrepareStmt(funcName, queryTextConstant),
20-
ExecuteAndAssign(funcName, queryParams),
21-
new SimpleStatement(Variable.Row.AsVar(), new SimpleExpression($"{Variable.Result.AsVar()}.first")),
22-
new SimpleExpression($"return nil if {Variable.Row.AsVar()}.nil?"),
23-
new SimpleStatement($"{Variable.Entity.AsVar()}", newObjectExpression),
24-
new SimpleExpression($"return {Variable.Entity.AsVar()}")
25-
]
17+
withResourceBody = withResourceBody
18+
.Concat(
19+
[
20+
dbDriver.PrepareStmt(funcName, queryTextConstant),
21+
ExecuteAndAssign(funcName, queryParams),
22+
new SimpleStatement(Variable.Row.AsVar(), new SimpleExpression($"{Variable.Result.AsVar()}.first")),
23+
new SimpleExpression($"return nil if {Variable.Row.AsVar()}.nil?"),
24+
new SimpleStatement($"{Variable.Entity.AsVar()}", newObjectExpression),
25+
new SimpleExpression($"return {Variable.Entity.AsVar()}")
26+
]
2627
);
2728

2829
return new MethodDeclaration(funcName, GetMethodArgs(argInterface, parameters),
@@ -45,14 +46,15 @@ public MethodDeclaration ManyDeclare(string funcName, string queryTextConstant,
4546
IEnumerable<IComposable> withResourceBody = new List<IComposable>();
4647
var queryParams = GetQueryParams(argInterface, parameters);
4748
withResourceBody = withResourceBody.AppendIfNotNull(queryParams);
48-
withResourceBody = withResourceBody.Concat(
49-
[
50-
dbDriver.PrepareStmt(funcName, queryTextConstant),
51-
ExecuteAndAssign(funcName, queryParams),
52-
new SimpleStatement(Variable.Entities.AsVar(), new SimpleExpression("[]")),
53-
new ForeachLoop(Variable.Result.AsVar(), Variable.Row.AsVar(), new List<IComposable> { listAppend }),
54-
new SimpleExpression($"return {Variable.Entities.AsVar()}")
55-
]
49+
withResourceBody = withResourceBody
50+
.Concat(
51+
[
52+
dbDriver.PrepareStmt(funcName, queryTextConstant),
53+
ExecuteAndAssign(funcName, queryParams),
54+
new SimpleStatement(Variable.Entities.AsVar(), new SimpleExpression("[]")),
55+
new ForeachLoop(Variable.Result.AsVar(), Variable.Row.AsVar(), new List<IComposable> { listAppend }),
56+
new SimpleExpression($"return {Variable.Entities.AsVar()}")
57+
]
5658
);
5759

5860
return new MethodDeclaration(funcName, GetMethodArgs(argInterface, parameters),
@@ -68,12 +70,10 @@ public MethodDeclaration ExecDeclare(string funcName, string queryTextConstant,
6870
IEnumerable<IComposable> withResourceBody = new List<IComposable>();
6971
var queryParams = GetQueryParams(argInterface, parameters);
7072
withResourceBody = withResourceBody.AppendIfNotNull(queryParams);
71-
withResourceBody = withResourceBody.Concat(
72-
[
73-
dbDriver.PrepareStmt(funcName, queryTextConstant),
74-
dbDriver.ExecuteStmt(funcName, queryParams)
75-
]
76-
);
73+
withResourceBody = withResourceBody
74+
.Append(dbDriver.PrepareStmt(funcName, queryTextConstant))
75+
.Append(dbDriver.ExecuteStmt(funcName, queryParams));
76+
7777
return new MethodDeclaration(funcName, GetMethodArgs(argInterface, parameters),
7878
new List<IComposable>
7979
{
@@ -87,13 +87,14 @@ public MethodDeclaration ExecLastIdDeclare(string funcName, string queryTextCons
8787
IEnumerable<IComposable> withResourceBody = new List<IComposable>();
8888
var queryParams = GetQueryParams(argInterface, parameters);
8989
withResourceBody = withResourceBody.AppendIfNotNull(queryParams);
90-
withResourceBody = withResourceBody.Concat(
91-
[
92-
dbDriver.PrepareStmt(funcName, queryTextConstant),
93-
dbDriver.ExecuteStmt(funcName, queryParams),
94-
new SimpleExpression($"return {Variable.Client.AsVar()}.last_id")
95-
]
96-
);
90+
withResourceBody = withResourceBody
91+
.Concat(
92+
[
93+
dbDriver.PrepareStmt(funcName, queryTextConstant),
94+
dbDriver.ExecuteStmt(funcName, queryParams),
95+
new SimpleExpression($"return {Variable.Client.AsVar()}.last_id")
96+
]
97+
);
9798
return new MethodDeclaration(funcName, GetMethodArgs(argInterface, parameters),
9899
new List<IComposable>
99100
{

Drivers/Mysql2Driver.cs

+5-5
Original file line numberDiff line numberDiff line change
@@ -34,18 +34,18 @@ public override SimpleStatement QueryTextConstantDeclare(Query query)
3434
return new SimpleStatement($"{query.Name}{ClassMember.Sql}", new SimpleExpression($"%q({query.Text})"));
3535
}
3636

37-
public override SimpleStatement PrepareStmt(string _, string queryTextConstant)
37+
public override IComposable PrepareStmt(string _, string queryTextConstant)
3838
{
3939
return new SimpleStatement(Variable.Stmt.AsVar(),
4040
new SimpleExpression($"{Variable.Client.AsVar()}.prepare({queryTextConstant})"));
4141
}
4242

4343
public override SimpleExpression ExecuteStmt(string funcName, SimpleStatement? queryParams)
4444
{
45-
var baseCommand = $"{Variable.Stmt.AsVar()}.execute";
46-
return queryParams is null
47-
? new SimpleExpression(baseCommand)
48-
: new SimpleExpression($"{baseCommand}(*{Variable.QueryParams.AsVar()})");
45+
var command = $"{Variable.Stmt.AsVar()}.execute";
46+
if (queryParams is not null)
47+
command = $"{command}(*{Variable.QueryParams.AsVar()})";
48+
return new SimpleExpression(command);
4949
}
5050

5151
public override MethodDeclaration OneDeclare(string funcName, string queryTextConstant, string argInterface,

Drivers/PgDriver.cs

+22-5
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,26 @@ public PgDriver()
1717

1818
public override IEnumerable<RequireGem> GetRequiredGems()
1919
{
20-
return GetCommonGems().Append(new RequireGem("pg"));
20+
return GetCommonGems()
21+
.Append(new RequireGem("pg"))
22+
.Append(new RequireGem("set"));
2123
}
2224

2325
public override MethodDeclaration GetInitMethod()
2426
{
27+
var pgConnectionInitBody = """
28+
conn = PG.connect(**pg_params)
29+
conn.type_map_for_results = PG::BasicTypeMapForResults.new conn
30+
conn
31+
"""
32+
.TrimTrailingWhitespacesPerLine()
33+
.Indent();
34+
var pgConnectionInit = "{\n" + pgConnectionInitBody + "\n}";
2535
return new MethodDeclaration("initialize", "connection_pool_params, pg_params",
2636
[
2737
new SimpleStatement(Variable.Pool.AsProperty(), new SimpleExpression(
28-
"ConnectionPool::new(**connection_pool_params) { PG.connect(**pg_params) }"))
38+
$"ConnectionPool::new(**connection_pool_params) {pgConnectionInit}")),
39+
new SimpleStatement(Variable.PreparedStatements.AsProperty(), new SimpleExpression("Set[]"))
2940
]
3041
);
3142
}
@@ -38,10 +49,16 @@ public override SimpleStatement QueryTextConstantDeclare(Query query)
3849
new SimpleExpression($"%q({transformedQueryText})"));
3950
}
4051

41-
public override SimpleStatement PrepareStmt(string funcName, string queryTextConstant)
52+
public override IComposable PrepareStmt(string funcName, string queryTextConstant)
4253
{
43-
return new SimpleStatement("_",
44-
new SimpleExpression($"{Variable.Client.AsVar()}.prepare('{funcName}', {queryTextConstant})"));
54+
return new UnlessCondition(
55+
$"{Variable.PreparedStatements.AsProperty()}.include?('{funcName}')",
56+
new List<IComposable>
57+
{
58+
new SimpleExpression($"{Variable.Client.AsVar()}.prepare('{funcName}', {queryTextConstant})"),
59+
new SimpleExpression($"{Variable.PreparedStatements.AsProperty()}.add('{funcName}')")
60+
}
61+
);
4562
}
4663

4764
public override SimpleExpression ExecuteStmt(string funcName, SimpleStatement? queryParams)

Drivers/Variable.cs

+1-3
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@ namespace SqlcGenCsharp.Drivers;
33
public enum Variable
44
{
55
Pool,
6-
PoolParams,
7-
Mysql2Params,
8-
PgParams,
6+
PreparedStatements,
97
QueryParams,
108
Client,
119
Stmt,

RubySyntax/Flows.cs

+38-10
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ public class WithResource(string resourceFrom, string resourceName, IEnumerable<
66
{
77
public string Build()
88
{
9-
var withResourceBody = statements.Select(s => s.Build())
9+
var withResourceBody = statements
10+
.Select(s => s.Build())
1011
.JoinByNewLine()
1112
.TrimTrailingWhitespacesPerLine()
1213
.Indent();
@@ -15,22 +16,49 @@ public string Build()
1516
}
1617
}
1718

18-
public class NewObject(
19-
string objectType,
20-
IEnumerable<SimpleExpression> initExpressions,
21-
IComposable? bodyExpression = null) : IComposable
19+
public class IfCondition(string condition, IList<IComposable> thenStatements,
20+
IList<IComposable>? elseStatements = null) : IComposable
21+
{
22+
public string Build()
23+
{
24+
var thenBody = thenStatements
25+
.Select(s => s.Build())
26+
.JoinByNewLine()
27+
.TrimTrailingWhitespacesPerLine()
28+
.Indent();
29+
if (elseStatements is null || elseStatements.Count == 0)
30+
return $"if {condition}\n{thenBody}\nend";
31+
var elseBody = elseStatements
32+
.Select(s => s.Build())
33+
.JoinByNewLine()
34+
.TrimTrailingWhitespacesPerLine()
35+
.Indent();
36+
return $"if {condition}\n{thenStatements}\nelse\n{elseBody}\nend";
37+
}
38+
}
39+
40+
public class UnlessCondition(string condition, IList<IComposable> thenStatements) : IComposable
41+
{
42+
public string Build()
43+
{
44+
var thenBody = thenStatements
45+
.Select(s => s.Build())
46+
.JoinByNewLine()
47+
.TrimTrailingWhitespacesPerLine()
48+
.Indent();
49+
return $"unless {condition}\n{thenBody}\nend";
50+
}
51+
}
52+
53+
public class NewObject(string objectType, IEnumerable<SimpleExpression> initExpressions) : IComposable
2254
{
2355
public string Build()
2456
{
25-
var optionalBody = bodyExpression is null
26-
? string.Empty
27-
: $$""" { {{bodyExpression.Build()}} }""";
2857
var initParams = initExpressions
2958
.Select(e => e.Build())
3059
.JoinByCommaAndNewLine()
3160
.Indent();
32-
var newObject = $"{objectType}.new(\n{initParams}\n){optionalBody}";
33-
return newObject;
61+
return $"{objectType}.new(\n{initParams}\n)";
3462
}
3563
}
3664

examples/pg/Gemfile

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
source 'https://rubygems.org'
22

33
gem 'connection_pool'
4-
gem 'pg'
4+
gem 'pg'
5+
gem 'set'

examples/pg/query_sql.rb

+28-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# auto-generated by sqlc - do not edit
22
require 'connection_pool'
3-
require 'pg'
3+
require 'pg'
4+
require 'set'
45

56
module PgCodegen
67
GetAuthorSql = %q(SELECT id, name, bio FROM authors
@@ -57,13 +58,21 @@ module PgCodegen
5758

5859
class QuerySql
5960
def initialize(connection_pool_params, pg_params)
60-
@pool = ConnectionPool::new(**connection_pool_params) { PG.connect(**pg_params) }
61+
@pool = ConnectionPool::new(**connection_pool_params) {
62+
conn = PG.connect(**pg_params)
63+
conn.type_map_for_results = PG::BasicTypeMapForResults.new conn
64+
conn
65+
}
66+
@prepared_statements = Set[]
6167
end
6268

6369
def get_author(get_author_args)
6470
@pool.with do |client|
6571
query_params = [get_author_args.id]
66-
_ = client.prepare('get_author', GetAuthorSql)
72+
unless @prepared_statements.include?('get_author')
73+
client.prepare('get_author', GetAuthorSql)
74+
@prepared_statements.add('get_author')
75+
end
6776
result = client.exec_prepared('get_author', query_params)
6877
row = result.first
6978
return nil if row.nil?
@@ -78,7 +87,10 @@ def get_author(get_author_args)
7887

7988
def list_authors
8089
@pool.with do |client|
81-
_ = client.prepare('list_authors', ListAuthorsSql)
90+
unless @prepared_statements.include?('list_authors')
91+
client.prepare('list_authors', ListAuthorsSql)
92+
@prepared_statements.add('list_authors')
93+
end
8294
result = client.exec_prepared('list_authors')
8395
entities = []
8496
result.each do |row|
@@ -95,7 +107,10 @@ def list_authors
95107
def create_author(create_author_args)
96108
@pool.with do |client|
97109
query_params = [create_author_args.name, create_author_args.bio]
98-
_ = client.prepare('create_author', CreateAuthorSql)
110+
unless @prepared_statements.include?('create_author')
111+
client.prepare('create_author', CreateAuthorSql)
112+
@prepared_statements.add('create_author')
113+
end
99114
result = client.exec_prepared('create_author', query_params)
100115
row = result.first
101116
return nil if row.nil?
@@ -111,14 +126,20 @@ def create_author(create_author_args)
111126
def delete_author(delete_author_args)
112127
@pool.with do |client|
113128
query_params = [delete_author_args.id]
114-
_ = client.prepare('delete_author', DeleteAuthorSql)
129+
unless @prepared_statements.include?('delete_author')
130+
client.prepare('delete_author', DeleteAuthorSql)
131+
@prepared_statements.add('delete_author')
132+
end
115133
client.exec_prepared('delete_author', query_params)
116134
end
117135
end
118136

119137
def test
120138
@pool.with do |client|
121-
_ = client.prepare('test', TestSql)
139+
unless @prepared_statements.include?('test')
140+
client.prepare('test', TestSql)
141+
@prepared_statements.add('test')
142+
end
122143
result = client.exec_prepared('test')
123144
row = result.first
124145
return nil if row.nil?

tests/end2end_mysql2.rb

+13-13
Original file line numberDiff line numberDiff line change
@@ -36,18 +36,18 @@ def create_first_author_and_assert
3636
end
3737

3838
def create_second_author_and_assert
39-
# create_author_args = Mysql2Codegen::CreateAuthorArgs.new(
40-
# name: Consts::DR_SEUSS_AUTHOR,
41-
# bio: Consts::DR_SEUSS_QUOTE
42-
# )
43-
# @query_sql.create_author(create_author_args)
44-
# get_author_args = Mysql2Codegen::GetAuthorArgs.new(id: 1)
45-
# actual = @query_sql.get_author(get_author_args)
46-
# expected = Mysql2Codegen::GetAuthorRow.new(
47-
# id: 2,
48-
# name: Consts::DR_SEUSS_AUTHOR,
49-
# bio: Consts::DR_SEUSS_QUOTE
50-
# )
51-
# assert_equal(expected, actual)
39+
create_author_args = Mysql2Codegen::CreateAuthorArgs.new(
40+
name: Consts::DR_SEUSS_AUTHOR,
41+
bio: Consts::DR_SEUSS_QUOTE
42+
)
43+
@query_sql.create_author(create_author_args)
44+
get_author_args = Mysql2Codegen::GetAuthorArgs.new(id: 2)
45+
actual = @query_sql.get_author(get_author_args)
46+
expected = Mysql2Codegen::GetAuthorRow.new(
47+
id: 2,
48+
name: Consts::DR_SEUSS_AUTHOR,
49+
bio: Consts::DR_SEUSS_QUOTE
50+
)
51+
assert_equal(expected, actual)
5252
end
5353
end

0 commit comments

Comments
 (0)