Skip to content

Commit

Permalink
[release] [minor] add sqlite3 support (#33)
Browse files Browse the repository at this point in the history
  • Loading branch information
SockworkOrange authored Jul 14, 2024
1 parent 03ad3ac commit 746a854
Show file tree
Hide file tree
Showing 27 changed files with 509 additions and 110 deletions.
4 changes: 3 additions & 1 deletion CodeGenerator/CodeGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ private DbDriver InstantiateDriver()
{
DriverName.Mysql2 => new Mysql2Driver(),
DriverName.Pg => new PgDriver(),
DriverName.Sqlite3 => new Sqlite3Driver(),
_ => throw new ArgumentException($"unknown driver: {Options.DriverName}")
};
}
Expand Down Expand Up @@ -194,7 +195,8 @@ private MethodDeclaration GetMethodDeclaration(Query query)
":many" => DbDriver.ManyDeclare(funcName, queryTextConstant, argInterface, returnInterface,
query.Params, query.Columns),
":exec" => DbDriver.ExecDeclare(funcName, queryTextConstant, argInterface, query.Params),
":execlastid" => DbDriver.ExecLastIdDeclare(funcName, queryTextConstant, argInterface, query.Params),
":execlastid" => ((Mysql2Driver)DbDriver)
.ExecLastIdDeclare(funcName, queryTextConstant, argInterface, query.Params),
_ => throw new InvalidDataException()
};

Expand Down
2 changes: 2 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,5 @@ RUN bundle install

COPY examples examples
COPY tests tests

RUN apt-get update && apt-get install sqlite3
9 changes: 9 additions & 0 deletions Drivers/ColumnMappingConfig.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using System.Collections.Generic;

namespace SqlcGenRuby.Drivers;

public readonly record struct ColumnMappingConfig(
string rubyType,
HashSet<string> dbTypes,
bool isPrefixBased
);
25 changes: 17 additions & 8 deletions Drivers/DbDriver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using RubyCodegen;
using System;
using System.Collections.Generic;
using System.Linq;

namespace SqlcGenRuby.Drivers;

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

public abstract MethodDeclaration GetInitMethod();

protected abstract List<(string, HashSet<string>)> GetColumnMapping();
protected abstract IEnumerable<ColumnMappingConfig> GetColumnMapping();

public string GetColumnType(Column column)
{
var columnType = column.Type.Name.ToLower();
foreach (var (csharpType, dbTypes) in GetColumnMapping())
var dbType = column.Type.Name.ToLower(); // from SQLC - char(5), char(10), int4, int8, float8, blob, etc.
foreach (var columnMapping in GetColumnMapping())
{
if (dbTypes.Contains(columnType))
return csharpType;
var rubyType = columnMapping.isPrefixBased ? GetByPrefix(columnMapping) : GetByValue(columnMapping);
if (rubyType is not null)
return rubyType;
}
throw new NotSupportedException($"Unsupported column type: {column.Type.Name}");

string? GetByValue(ColumnMappingConfig columnMapping)
{
return columnMapping.dbTypes.Contains(dbType) ? columnMapping.rubyType : null;
}

string? GetByPrefix(ColumnMappingConfig columnMapping)
{
return columnMapping.dbTypes.Any(d => d.StartsWith(dbType)) ? columnMapping.rubyType : null;
}
}

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

public abstract MethodDeclaration ExecDeclare(string funcName, string text, string argInterface,
IList<Parameter> parameters);

public abstract MethodDeclaration ExecLastIdDeclare(string funcName, string queryTextConstant, string argInterface,
IList<Parameter> parameters);
}
82 changes: 41 additions & 41 deletions Drivers/MethodGen.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
using Plugin;
using RubyCodegen;
using System;
using System.Collections.Generic;
using System.Linq;

namespace SqlcGenRuby.Drivers;

public class MethodGen(DbDriver dbDriver)
{
private static string? GetMethodArgs(string argInterface, IList<Parameter> parameters)
{
return parameters.Count == 0 ? null : argInterface.SnakeCase();
}

public MethodDeclaration OneDeclare(string funcName, string queryTextConstant, string argInterface,
string returnInterface, IList<Parameter> parameters, IList<Column> columns)
string returnInterface, IList<Parameter> parameters, IList<Column> columns, bool poolingEnabled = true,
RowDataType rowDataType = RowDataType.Hash)
{
var newObjectExpression = new NewObject(returnInterface, GetColumnsInitExpressions(columns));
var newObjectExpression = new NewObject(returnInterface, GetColumnsInitExpressions(columns, rowDataType));
IEnumerable<IComposable> withResourceBody = new List<IComposable>();
var queryParams = GetQueryParams(argInterface, parameters);
withResourceBody = withResourceBody.AppendIfNotNull(queryParams);
Expand All @@ -26,27 +33,34 @@ public MethodDeclaration OneDeclare(string funcName, string queryTextConstant, s
]
).ToList();

return new MethodDeclaration(
funcName,
argInterface,
GetMethodArgs(argInterface, parameters),
$"{returnInterface}?",
new List<IComposable>
{
new WithResource(Variable.Pool.AsProperty(), Variable.Client.AsVar(), withResourceBody.ToList())
});
var methodArgs = GetMethodArgs(argInterface, parameters);
var methodBody = OptionallyAddPoolUsage(poolingEnabled, withResourceBody);
return new MethodDeclaration(funcName, argInterface, methodArgs, $"{returnInterface}?", methodBody);
}

private static string? GetMethodArgs(string argInterface, IList<Parameter> parameters)
private static IEnumerable<IComposable> OptionallyAddPoolUsage(bool poolingEnabled, IEnumerable<IComposable> body)
{
return parameters.Count == 0 ? null : argInterface.SnakeCase();
return poolingEnabled
?
[
new WithResource(
Variable.Db.AsProperty(),
Variable.Client.AsVar(),
body.ToList())
]
: new List<IComposable>
{
new SimpleExpression($"{Variable.Client.AsVar()} = {Variable.Db.AsProperty()}")
}
.Concat(body);
}

public MethodDeclaration ManyDeclare(string funcName, string queryTextConstant, string argInterface,
string returnInterface, IList<Parameter> parameters, IList<Column> columns)
string returnInterface, IList<Parameter> parameters, IList<Column> columns, bool poolingEnabled = true,
RowDataType rowDataType = RowDataType.Hash)
{
var listAppend = new ListAppend(Variable.Entities.AsVar(),
new NewObject(returnInterface, GetColumnsInitExpressions(columns)));
new NewObject(returnInterface, GetColumnsInitExpressions(columns, rowDataType)));
IEnumerable<IComposable> withResourceBody = new List<IComposable>();
var queryParams = GetQueryParams(argInterface, parameters);
withResourceBody = withResourceBody.AppendIfNotNull(queryParams);
Expand All @@ -65,23 +79,13 @@ public MethodDeclaration ManyDeclare(string funcName, string queryTextConstant,
]
);

return new MethodDeclaration(
funcName,
argInterface,
GetMethodArgs(argInterface, parameters),
$"Array[{returnInterface}]",
new List<IComposable>
{
new WithResource(
Variable.Pool.AsProperty(),
Variable.Client.AsVar(),
withResourceBody.ToList()
)
});
var methodArgs = GetMethodArgs(argInterface, parameters);
var methodBody = OptionallyAddPoolUsage(poolingEnabled, withResourceBody);
return new MethodDeclaration(funcName, argInterface, methodArgs, null, methodBody);
}

public MethodDeclaration ExecDeclare(string funcName, string queryTextConstant, string argInterface,
IList<Parameter> parameters)
IList<Parameter> parameters, bool poolingEnabled = true)
{
IEnumerable<IComposable> withResourceBody = new List<IComposable>();
var queryParams = GetQueryParams(argInterface, parameters);
Expand All @@ -91,15 +95,9 @@ public MethodDeclaration ExecDeclare(string funcName, string queryTextConstant,
.Append(dbDriver.ExecuteStmt(funcName, queryParams))
.ToList();

return new MethodDeclaration(funcName,
argInterface,
GetMethodArgs(argInterface, parameters),
null,
new List<IComposable>
{
new WithResource(Variable.Pool.AsProperty(), Variable.Client.AsVar(), withResourceBody.ToList()
)
});
var methodArgs = GetMethodArgs(argInterface, parameters);
var methodBody = OptionallyAddPoolUsage(poolingEnabled, withResourceBody);
return new MethodDeclaration(funcName, argInterface, methodArgs, null, methodBody);
}

public MethodDeclaration ExecLastIdDeclare(string funcName, string queryTextConstant, string argInterface,
Expand All @@ -124,7 +122,7 @@ public MethodDeclaration ExecLastIdDeclare(string funcName, string queryTextCons
"Integer",
new List<IComposable>
{
new WithResource(Variable.Pool.AsProperty(), Variable.Client.AsVar(),
new WithResource(Variable.Db.AsProperty(), Variable.Client.AsVar(),
withResourceBody.ToList())
}
);
Expand All @@ -139,9 +137,11 @@ public MethodDeclaration ExecLastIdDeclare(string funcName, string queryTextCons
new SimpleExpression($"[{queryParams.JoinByCommaAndFormat()}]"));
}

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

private SimpleStatement ExecuteAndAssign(string funcName, SimpleStatement? queryParams)
Expand Down
20 changes: 10 additions & 10 deletions Drivers/Mysql2Driver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,25 +30,25 @@ public override MethodDeclaration GetInitMethod()
"connection_pool_params, mysql2_params",
null,
[
new PropertyDeclaration(Variable.Pool.AsProperty(), "untyped", connectionPoolInit)
new PropertyDeclaration(Variable.Db.AsProperty(), "untyped", connectionPoolInit)
]
);
}

protected override List<(string, HashSet<string>)> GetColumnMapping()
protected override IEnumerable<ColumnMappingConfig> GetColumnMapping()
{
return
[
("Array[Integer]", [
new ColumnMappingConfig("Array[Integer]", [
"binary",
"bit",
"blob",
"longblob",
"mediumblob",
"tinyblob",
"varbinary"
]),
("String", [
], false),
new ColumnMappingConfig("String", [
"char",
"date",
"datetime",
Expand All @@ -61,16 +61,16 @@ public override MethodDeclaration GetInitMethod()
"tinytext",
"varchar",
"json"
]),
("Integer", [
], false),
new ColumnMappingConfig("Integer", [
"bigint",
"int",
"mediumint",
"smallint",
"tinyint",
"year"
]),
("Float", ["double", "float"]),
], false),
new ColumnMappingConfig("Float", ["double", "float"], false),
];
}

Expand Down Expand Up @@ -108,7 +108,7 @@ public override MethodDeclaration ExecDeclare(string funcName, string queryTextC
return MethodGen.ExecDeclare(funcName, queryTextConstant, argInterface, parameters);
}

public override MethodDeclaration ExecLastIdDeclare(string funcName, string queryTextConstant,
public MethodDeclaration ExecLastIdDeclare(string funcName, string queryTextConstant,
string argInterface, IList<Parameter> parameters)
{
return MethodGen.ExecLastIdDeclare(funcName, queryTextConstant, argInterface, parameters);
Expand Down
30 changes: 12 additions & 18 deletions Drivers/PgDriver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public override MethodDeclaration GetInitMethod()
"connection_pool_params, pg_params",
null,
[
new PropertyDeclaration(Variable.Pool.AsProperty(), "untyped", connectionPoolInit),
new PropertyDeclaration(Variable.Db.AsProperty(), "untyped", connectionPoolInit),
new PropertyDeclaration(Variable.PreparedStatements.AsProperty(), "Set[String]", new SimpleExpression("Set[]"))
]
);
Expand All @@ -53,15 +53,15 @@ IList<IComposable> PgClientCreate()
}
}

protected override List<(string, HashSet<string>)> GetColumnMapping()
protected override IEnumerable<ColumnMappingConfig> GetColumnMapping()
{
return
[
("bool", [
new ColumnMappingConfig("bool", [
"bool",
"boolean"
]),
("Array[Integer]", [
], false),
new ColumnMappingConfig("Array[Integer]", [
"binary",
"bit",
"bytea",
Expand All @@ -70,8 +70,8 @@ IList<IComposable> PgClientCreate()
"mediumblob",
"tinyblob",
"varbinary"
]),
("String", [
], false),
new ColumnMappingConfig("String", [
"char",
"date",
"datetime",
Expand All @@ -84,20 +84,20 @@ IList<IComposable> PgClientCreate()
"tinytext",
"varchar",
"json"
]),
("Integer", [
], false),
new ColumnMappingConfig("Integer", [
"int2",
"int4",
"int8",
"serial",
"bigserial"
]),
("Float", [
], false),
new ColumnMappingConfig("Float", [
"numeric",
"float4",
"float8",
"decimal"
])
], false)
];
}

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

public override MethodDeclaration ExecLastIdDeclare(string funcName, string queryTextConstant,
string argInterface, IList<Parameter> parameters)
{
return MethodGen.ExecLastIdDeclare(funcName, queryTextConstant, argInterface, parameters);
}

public override MethodDeclaration ManyDeclare(string funcName, string queryTextConstant, string argInterface,
string returnInterface, IList<Parameter> parameters, IList<Column> columns)
{
Expand Down
7 changes: 7 additions & 0 deletions Drivers/RowDataType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace SqlcGenRuby.Drivers;

public enum RowDataType
{
Hash,
Array
}
Loading

0 comments on commit 746a854

Please sign in to comment.