Skip to content

Commit 746a854

Browse files
[release] [minor] add sqlite3 support (#33)
1 parent 03ad3ac commit 746a854

27 files changed

+509
-110
lines changed

CodeGenerator/CodeGenerator.cs

+3-1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ private DbDriver InstantiateDriver()
3636
{
3737
DriverName.Mysql2 => new Mysql2Driver(),
3838
DriverName.Pg => new PgDriver(),
39+
DriverName.Sqlite3 => new Sqlite3Driver(),
3940
_ => throw new ArgumentException($"unknown driver: {Options.DriverName}")
4041
};
4142
}
@@ -194,7 +195,8 @@ private MethodDeclaration GetMethodDeclaration(Query query)
194195
":many" => DbDriver.ManyDeclare(funcName, queryTextConstant, argInterface, returnInterface,
195196
query.Params, query.Columns),
196197
":exec" => DbDriver.ExecDeclare(funcName, queryTextConstant, argInterface, query.Params),
197-
":execlastid" => DbDriver.ExecLastIdDeclare(funcName, queryTextConstant, argInterface, query.Params),
198+
":execlastid" => ((Mysql2Driver)DbDriver)
199+
.ExecLastIdDeclare(funcName, queryTextConstant, argInterface, query.Params),
198200
_ => throw new InvalidDataException()
199201
};
200202

Dockerfile

+2
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,5 @@ RUN bundle install
1010

1111
COPY examples examples
1212
COPY tests tests
13+
14+
RUN apt-get update && apt-get install sqlite3

Drivers/ColumnMappingConfig.cs

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
using System.Collections.Generic;
2+
3+
namespace SqlcGenRuby.Drivers;
4+
5+
public readonly record struct ColumnMappingConfig(
6+
string rubyType,
7+
HashSet<string> dbTypes,
8+
bool isPrefixBased
9+
);

Drivers/DbDriver.cs

+17-8
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using RubyCodegen;
33
using System;
44
using System.Collections.Generic;
5+
using System.Linq;
56

67
namespace SqlcGenRuby.Drivers;
78

@@ -16,17 +17,28 @@ protected static IEnumerable<RequireGem> GetCommonGems()
1617

1718
public abstract MethodDeclaration GetInitMethod();
1819

19-
protected abstract List<(string, HashSet<string>)> GetColumnMapping();
20+
protected abstract IEnumerable<ColumnMappingConfig> GetColumnMapping();
2021

2122
public string GetColumnType(Column column)
2223
{
23-
var columnType = column.Type.Name.ToLower();
24-
foreach (var (csharpType, dbTypes) in GetColumnMapping())
24+
var dbType = column.Type.Name.ToLower(); // from SQLC - char(5), char(10), int4, int8, float8, blob, etc.
25+
foreach (var columnMapping in GetColumnMapping())
2526
{
26-
if (dbTypes.Contains(columnType))
27-
return csharpType;
27+
var rubyType = columnMapping.isPrefixBased ? GetByPrefix(columnMapping) : GetByValue(columnMapping);
28+
if (rubyType is not null)
29+
return rubyType;
2830
}
2931
throw new NotSupportedException($"Unsupported column type: {column.Type.Name}");
32+
33+
string? GetByValue(ColumnMappingConfig columnMapping)
34+
{
35+
return columnMapping.dbTypes.Contains(dbType) ? columnMapping.rubyType : null;
36+
}
37+
38+
string? GetByPrefix(ColumnMappingConfig columnMapping)
39+
{
40+
return columnMapping.dbTypes.Any(d => d.StartsWith(dbType)) ? columnMapping.rubyType : null;
41+
}
3042
}
3143

3244
public abstract PropertyDeclaration QueryTextConstantDeclare(Query query);
@@ -43,7 +55,4 @@ public abstract MethodDeclaration ManyDeclare(string funcName, string sqlTextCon
4355

4456
public abstract MethodDeclaration ExecDeclare(string funcName, string text, string argInterface,
4557
IList<Parameter> parameters);
46-
47-
public abstract MethodDeclaration ExecLastIdDeclare(string funcName, string queryTextConstant, string argInterface,
48-
IList<Parameter> parameters);
4958
}

Drivers/MethodGen.cs

+41-41
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,23 @@
11
using Plugin;
22
using RubyCodegen;
3+
using System;
34
using System.Collections.Generic;
45
using System.Linq;
56

67
namespace SqlcGenRuby.Drivers;
78

89
public class MethodGen(DbDriver dbDriver)
910
{
11+
private static string? GetMethodArgs(string argInterface, IList<Parameter> parameters)
12+
{
13+
return parameters.Count == 0 ? null : argInterface.SnakeCase();
14+
}
15+
1016
public MethodDeclaration OneDeclare(string funcName, string queryTextConstant, string argInterface,
11-
string returnInterface, IList<Parameter> parameters, IList<Column> columns)
17+
string returnInterface, IList<Parameter> parameters, IList<Column> columns, bool poolingEnabled = true,
18+
RowDataType rowDataType = RowDataType.Hash)
1219
{
13-
var newObjectExpression = new NewObject(returnInterface, GetColumnsInitExpressions(columns));
20+
var newObjectExpression = new NewObject(returnInterface, GetColumnsInitExpressions(columns, rowDataType));
1421
IEnumerable<IComposable> withResourceBody = new List<IComposable>();
1522
var queryParams = GetQueryParams(argInterface, parameters);
1623
withResourceBody = withResourceBody.AppendIfNotNull(queryParams);
@@ -26,27 +33,34 @@ public MethodDeclaration OneDeclare(string funcName, string queryTextConstant, s
2633
]
2734
).ToList();
2835

29-
return new MethodDeclaration(
30-
funcName,
31-
argInterface,
32-
GetMethodArgs(argInterface, parameters),
33-
$"{returnInterface}?",
34-
new List<IComposable>
35-
{
36-
new WithResource(Variable.Pool.AsProperty(), Variable.Client.AsVar(), withResourceBody.ToList())
37-
});
36+
var methodArgs = GetMethodArgs(argInterface, parameters);
37+
var methodBody = OptionallyAddPoolUsage(poolingEnabled, withResourceBody);
38+
return new MethodDeclaration(funcName, argInterface, methodArgs, $"{returnInterface}?", methodBody);
3839
}
3940

40-
private static string? GetMethodArgs(string argInterface, IList<Parameter> parameters)
41+
private static IEnumerable<IComposable> OptionallyAddPoolUsage(bool poolingEnabled, IEnumerable<IComposable> body)
4142
{
42-
return parameters.Count == 0 ? null : argInterface.SnakeCase();
43+
return poolingEnabled
44+
?
45+
[
46+
new WithResource(
47+
Variable.Db.AsProperty(),
48+
Variable.Client.AsVar(),
49+
body.ToList())
50+
]
51+
: new List<IComposable>
52+
{
53+
new SimpleExpression($"{Variable.Client.AsVar()} = {Variable.Db.AsProperty()}")
54+
}
55+
.Concat(body);
4356
}
4457

4558
public MethodDeclaration ManyDeclare(string funcName, string queryTextConstant, string argInterface,
46-
string returnInterface, IList<Parameter> parameters, IList<Column> columns)
59+
string returnInterface, IList<Parameter> parameters, IList<Column> columns, bool poolingEnabled = true,
60+
RowDataType rowDataType = RowDataType.Hash)
4761
{
4862
var listAppend = new ListAppend(Variable.Entities.AsVar(),
49-
new NewObject(returnInterface, GetColumnsInitExpressions(columns)));
63+
new NewObject(returnInterface, GetColumnsInitExpressions(columns, rowDataType)));
5064
IEnumerable<IComposable> withResourceBody = new List<IComposable>();
5165
var queryParams = GetQueryParams(argInterface, parameters);
5266
withResourceBody = withResourceBody.AppendIfNotNull(queryParams);
@@ -65,23 +79,13 @@ public MethodDeclaration ManyDeclare(string funcName, string queryTextConstant,
6579
]
6680
);
6781

68-
return new MethodDeclaration(
69-
funcName,
70-
argInterface,
71-
GetMethodArgs(argInterface, parameters),
72-
$"Array[{returnInterface}]",
73-
new List<IComposable>
74-
{
75-
new WithResource(
76-
Variable.Pool.AsProperty(),
77-
Variable.Client.AsVar(),
78-
withResourceBody.ToList()
79-
)
80-
});
82+
var methodArgs = GetMethodArgs(argInterface, parameters);
83+
var methodBody = OptionallyAddPoolUsage(poolingEnabled, withResourceBody);
84+
return new MethodDeclaration(funcName, argInterface, methodArgs, null, methodBody);
8185
}
8286

8387
public MethodDeclaration ExecDeclare(string funcName, string queryTextConstant, string argInterface,
84-
IList<Parameter> parameters)
88+
IList<Parameter> parameters, bool poolingEnabled = true)
8589
{
8690
IEnumerable<IComposable> withResourceBody = new List<IComposable>();
8791
var queryParams = GetQueryParams(argInterface, parameters);
@@ -91,15 +95,9 @@ public MethodDeclaration ExecDeclare(string funcName, string queryTextConstant,
9195
.Append(dbDriver.ExecuteStmt(funcName, queryParams))
9296
.ToList();
9397

94-
return new MethodDeclaration(funcName,
95-
argInterface,
96-
GetMethodArgs(argInterface, parameters),
97-
null,
98-
new List<IComposable>
99-
{
100-
new WithResource(Variable.Pool.AsProperty(), Variable.Client.AsVar(), withResourceBody.ToList()
101-
)
102-
});
98+
var methodArgs = GetMethodArgs(argInterface, parameters);
99+
var methodBody = OptionallyAddPoolUsage(poolingEnabled, withResourceBody);
100+
return new MethodDeclaration(funcName, argInterface, methodArgs, null, methodBody);
103101
}
104102

105103
public MethodDeclaration ExecLastIdDeclare(string funcName, string queryTextConstant, string argInterface,
@@ -124,7 +122,7 @@ public MethodDeclaration ExecLastIdDeclare(string funcName, string queryTextCons
124122
"Integer",
125123
new List<IComposable>
126124
{
127-
new WithResource(Variable.Pool.AsProperty(), Variable.Client.AsVar(),
125+
new WithResource(Variable.Db.AsProperty(), Variable.Client.AsVar(),
128126
withResourceBody.ToList())
129127
}
130128
);
@@ -139,9 +137,11 @@ public MethodDeclaration ExecLastIdDeclare(string funcName, string queryTextCons
139137
new SimpleExpression($"[{queryParams.JoinByCommaAndFormat()}]"));
140138
}
141139

142-
private static IList<SimpleExpression> GetColumnsInitExpressions(IList<Column> columns)
140+
private static IList<SimpleExpression> GetColumnsInitExpressions(IList<Column> columns, RowDataType rowDataType)
143141
{
144-
return columns.Select(c => new SimpleExpression($"{Variable.Row.AsVar()}['{c.Name}']")).ToList();
142+
return rowDataType == RowDataType.Hash
143+
? columns.Select(c => new SimpleExpression($"{Variable.Row.AsVar()}['{c.Name}']")).ToList()
144+
: columns.Select((_, i) => new SimpleExpression($"{Variable.Row.AsVar()}[{i}]")).ToList();
145145
}
146146

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

Drivers/Mysql2Driver.cs

+10-10
Original file line numberDiff line numberDiff line change
@@ -30,25 +30,25 @@ public override MethodDeclaration GetInitMethod()
3030
"connection_pool_params, mysql2_params",
3131
null,
3232
[
33-
new PropertyDeclaration(Variable.Pool.AsProperty(), "untyped", connectionPoolInit)
33+
new PropertyDeclaration(Variable.Db.AsProperty(), "untyped", connectionPoolInit)
3434
]
3535
);
3636
}
3737

38-
protected override List<(string, HashSet<string>)> GetColumnMapping()
38+
protected override IEnumerable<ColumnMappingConfig> GetColumnMapping()
3939
{
4040
return
4141
[
42-
("Array[Integer]", [
42+
new ColumnMappingConfig("Array[Integer]", [
4343
"binary",
4444
"bit",
4545
"blob",
4646
"longblob",
4747
"mediumblob",
4848
"tinyblob",
4949
"varbinary"
50-
]),
51-
("String", [
50+
], false),
51+
new ColumnMappingConfig("String", [
5252
"char",
5353
"date",
5454
"datetime",
@@ -61,16 +61,16 @@ public override MethodDeclaration GetInitMethod()
6161
"tinytext",
6262
"varchar",
6363
"json"
64-
]),
65-
("Integer", [
64+
], false),
65+
new ColumnMappingConfig("Integer", [
6666
"bigint",
6767
"int",
6868
"mediumint",
6969
"smallint",
7070
"tinyint",
7171
"year"
72-
]),
73-
("Float", ["double", "float"]),
72+
], false),
73+
new ColumnMappingConfig("Float", ["double", "float"], false),
7474
];
7575
}
7676

@@ -108,7 +108,7 @@ public override MethodDeclaration ExecDeclare(string funcName, string queryTextC
108108
return MethodGen.ExecDeclare(funcName, queryTextConstant, argInterface, parameters);
109109
}
110110

111-
public override MethodDeclaration ExecLastIdDeclare(string funcName, string queryTextConstant,
111+
public MethodDeclaration ExecLastIdDeclare(string funcName, string queryTextConstant,
112112
string argInterface, IList<Parameter> parameters)
113113
{
114114
return MethodGen.ExecLastIdDeclare(funcName, queryTextConstant, argInterface, parameters);

Drivers/PgDriver.cs

+12-18
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public override MethodDeclaration GetInitMethod()
3333
"connection_pool_params, pg_params",
3434
null,
3535
[
36-
new PropertyDeclaration(Variable.Pool.AsProperty(), "untyped", connectionPoolInit),
36+
new PropertyDeclaration(Variable.Db.AsProperty(), "untyped", connectionPoolInit),
3737
new PropertyDeclaration(Variable.PreparedStatements.AsProperty(), "Set[String]", new SimpleExpression("Set[]"))
3838
]
3939
);
@@ -53,15 +53,15 @@ IList<IComposable> PgClientCreate()
5353
}
5454
}
5555

56-
protected override List<(string, HashSet<string>)> GetColumnMapping()
56+
protected override IEnumerable<ColumnMappingConfig> GetColumnMapping()
5757
{
5858
return
5959
[
60-
("bool", [
60+
new ColumnMappingConfig("bool", [
6161
"bool",
6262
"boolean"
63-
]),
64-
("Array[Integer]", [
63+
], false),
64+
new ColumnMappingConfig("Array[Integer]", [
6565
"binary",
6666
"bit",
6767
"bytea",
@@ -70,8 +70,8 @@ IList<IComposable> PgClientCreate()
7070
"mediumblob",
7171
"tinyblob",
7272
"varbinary"
73-
]),
74-
("String", [
73+
], false),
74+
new ColumnMappingConfig("String", [
7575
"char",
7676
"date",
7777
"datetime",
@@ -84,20 +84,20 @@ IList<IComposable> PgClientCreate()
8484
"tinytext",
8585
"varchar",
8686
"json"
87-
]),
88-
("Integer", [
87+
], false),
88+
new ColumnMappingConfig("Integer", [
8989
"int2",
9090
"int4",
9191
"int8",
9292
"serial",
9393
"bigserial"
94-
]),
95-
("Float", [
94+
], false),
95+
new ColumnMappingConfig("Float", [
9696
"numeric",
9797
"float4",
9898
"float8",
9999
"decimal"
100-
])
100+
], false)
101101
];
102102
}
103103

@@ -141,12 +141,6 @@ public override MethodDeclaration ExecDeclare(string funcName, string queryTextC
141141
return MethodGen.ExecDeclare(funcName, queryTextConstant, argInterface, parameters);
142142
}
143143

144-
public override MethodDeclaration ExecLastIdDeclare(string funcName, string queryTextConstant,
145-
string argInterface, IList<Parameter> parameters)
146-
{
147-
return MethodGen.ExecLastIdDeclare(funcName, queryTextConstant, argInterface, parameters);
148-
}
149-
150144
public override MethodDeclaration ManyDeclare(string funcName, string queryTextConstant, string argInterface,
151145
string returnInterface, IList<Parameter> parameters, IList<Column> columns)
152146
{

Drivers/RowDataType.cs

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
namespace SqlcGenRuby.Drivers;
2+
3+
public enum RowDataType
4+
{
5+
Hash,
6+
Array
7+
}

0 commit comments

Comments
 (0)