Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion CodeGenerator/CodeGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,6 @@ private string FindEnumSchema(Enum e)
return schemaTables.Key;
}
}
// TODO fix why not mapping default schema to string.Empty
throw new InvalidDataException($"No enum {e.Name} schema found.");
}

Expand Down
2 changes: 0 additions & 2 deletions Drivers/ColumnMapping.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,8 @@ namespace SqlcGenCsharp.Drivers;
public record DbTypeInfo(int? Length = null, string? NpgsqlTypeOverride = null);

public class ColumnMapping(
string csharpType,
Dictionary<string, DbTypeInfo> dbTypes, Func<int, string> readerFn, Func<int, string>? readerArrayFn = null)
{
public string CsharpType { get; } = csharpType;
public Func<int, string> ReaderFn { get; } = readerFn;
public Func<int, string>? ReaderArrayFn { get; } = readerArrayFn;
public Dictionary<string, DbTypeInfo> DbTypes { get; } = dbTypes;
Expand Down
24 changes: 13 additions & 11 deletions Drivers/DbDriver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public abstract class DbDriver
"NpgsqlCircle"
];

protected abstract List<ColumnMapping> ColumnMappings { get; }
protected abstract Dictionary<string, ColumnMapping> ColumnMappings { get; }

protected const string TransformQueryForSliceArgsImpl = """
public static string TransformQueryForSliceArgs(string originalSql, int sliceSize, string paramName)
Expand Down Expand Up @@ -155,10 +155,10 @@ private string GetCsharpTypeWithoutNullableSuffix(Column column, Query? query)
}

foreach (var columnMapping in ColumnMappings
.Where(columnMapping => DoesColumnMappingApply(columnMapping, column)))
.Where(columnMapping => DoesColumnMappingApply(columnMapping.Value, column)))
{
if (column.IsArray || column.IsSqlcSlice) return $"{columnMapping.CsharpType}[]";
return columnMapping.CsharpType;
if (column.IsArray || column.IsSqlcSlice) return $"{columnMapping.Key}[]";
return columnMapping.Key;
}

throw new NotSupportedException($"Column {column.Name} has unsupported column type: {column.Type.Name}");
Expand Down Expand Up @@ -186,7 +186,7 @@ private static bool DoesColumnMappingApply(ColumnMapping columnMapping, Column c

private string GetColumnReader(OverrideOption overrideOption, int ordinal)
{
var columnMapping = ColumnMappings.Find(c => c.CsharpType == overrideOption.CsharpType.Type);
var columnMapping = ColumnMappings.GetValueOrDefault(overrideOption.CsharpType.Type);
if (columnMapping is not null)
return columnMapping.ReaderFn(ordinal);
throw new NotSupportedException($"Column {overrideOption.Column} has unsupported column type: {overrideOption.CsharpType.Type}");
Expand All @@ -207,7 +207,7 @@ public string GetColumnReader(Column column, int ordinal, Query? query)
return GetColumnReader(foundOverride, ordinal);
}

foreach (var columnMapping in ColumnMappings
foreach (var columnMapping in ColumnMappings.Values
.Where(columnMapping => DoesColumnMappingApply(columnMapping, column)))
{
if (column.IsArray)
Expand All @@ -220,7 +220,7 @@ public string GetColumnReader(Column column, int ordinal, Query? query)
protected string? GetColumnDbTypeOverride(Column column)
{
var columnType = column.Type.Name.ToLower();
foreach (var columnMapping in ColumnMappings)
foreach (var columnMapping in ColumnMappings.Values)
{
if (columnMapping.DbTypes.TryGetValue(columnType, out var dbTypeOverride))
return dbTypeOverride.NpgsqlTypeOverride;
Expand All @@ -240,10 +240,12 @@ public bool IsTypeNullable(string csharpType)
return Options.DotnetFramework.IsDotnetCore(); // non-primitives in .Net Core are inherently nullable
}

/*
Since there is no indication of the primary key column in SQLC protobuf (assuming it is a single column),
this method uses a few heuristics to assess the data type of the id column
*/
/// <summary>
/// Since there is no indication of the primary key column in SQLC protobuf (assuming it is a single column),
/// this method uses a few heuristics to assess the data type of the id column
/// </summary>
/// <param name="query"></param>
/// <returns>The data type of the id column</returns>
public string GetIdColumnType(Query query)
{
var tableColumns = Tables[query.InsertIntoTable.Schema][query.InsertIntoTable.Name].Columns;
Expand Down
4 changes: 2 additions & 2 deletions Drivers/Generators/CommonGen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ public static string GetSqlTransformations(Query query, string queryTextConstant
""";
}

public string InstantiateDataclass(Column[] columns, string returnInterface, Query? query)
public string InstantiateDataclass(Column[] columns, string returnInterface, Query query)
{
var columnsInit = new List<string>();
var actualOrdinal = 0;
Expand Down Expand Up @@ -120,7 +120,7 @@ public string InstantiateDataclass(Column[] columns, string returnInterface, Que

return InstantiateDataclassInternal(returnInterface, columnsInit);

string[] GetAsEmbeddedTableColumnAssignment(Column tableColumn, int ordinal, Query? query)
string[] GetAsEmbeddedTableColumnAssignment(Column tableColumn, int ordinal, Query query)
{
var schemaName = tableColumn.EmbedTable.Schema == dbDriver.DefaultSchema ? string.Empty : tableColumn.EmbedTable.Schema;
var tableColumns = dbDriver.Tables[schemaName][tableColumn.EmbedTable.Name].Columns;
Expand Down
172 changes: 97 additions & 75 deletions Drivers/MySqlConnectorDriver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,84 +22,106 @@ public partial class MySqlConnectorDriver(
public const string ByteCsvConverter = "ByteCsvConverter";
public const string ByteArrayCsvConverter = "ByteArrayCsvConverter";

protected override List<ColumnMapping> ColumnMappings { get; } =
[
new("bool",
new Dictionary<string, DbTypeInfo>
{
{ "tinyint", new DbTypeInfo(Length: 1) }
}, ordinal => $"reader.GetBoolean({ordinal})"),
new("short",
new Dictionary<string, DbTypeInfo>
{
{ "tinyint", new DbTypeInfo() },
{ "smallint", new DbTypeInfo() },
{ "year", new DbTypeInfo() }
}, ordinal => $"reader.GetInt16({ordinal})"),
new("long",
new Dictionary<string, DbTypeInfo>
{
{ "bigint", new DbTypeInfo() }
}, ordinal => $"reader.GetInt64({ordinal})"),
new("byte",
new Dictionary<string, DbTypeInfo>
{
{ "bit", new DbTypeInfo() }
}, ordinal => $"reader.GetFieldValue<byte>({ordinal})"),
new("byte[]",
new Dictionary<string, DbTypeInfo>
{
{ "binary", new DbTypeInfo() },
{ "blob", new DbTypeInfo() },
{ "longblob", new DbTypeInfo() },
{ "mediumblob", new DbTypeInfo() },
{ "tinyblob", new DbTypeInfo() },
{ "varbinary", new DbTypeInfo() }
}, ordinal => $"reader.GetFieldValue<byte[]>({ordinal})"),
new("string",
new Dictionary<string, DbTypeInfo>
{
{ "char", new DbTypeInfo() },
{ "longtext", new DbTypeInfo() },
{ "mediumtext", new DbTypeInfo() },
{ "text", new DbTypeInfo() },
{ "time", new DbTypeInfo() },
{ "tinytext", new DbTypeInfo() },
{ "varchar", new DbTypeInfo() },
{ "var_string", new DbTypeInfo() },
{ "json", new DbTypeInfo() },
}, ordinal => $"reader.GetString({ordinal})"),
new("DateTime",
new Dictionary<string, DbTypeInfo>
{
{ "date", new DbTypeInfo() },
{ "datetime", new DbTypeInfo() },
{ "timestamp", new DbTypeInfo() }
}, ordinal => $"reader.GetDateTime({ordinal})"),
new("int",
new Dictionary<string, DbTypeInfo>
{
{ "int", new DbTypeInfo() },
{ "mediumint", new DbTypeInfo() },
}, ordinal => $"reader.GetInt32({ordinal})"),
new("double",
new Dictionary<string, DbTypeInfo>
{
{ "double", new DbTypeInfo() },
{ "float", new DbTypeInfo() }
}, ordinal => $"reader.GetDouble({ordinal})"),
new("decimal",
new Dictionary<string, DbTypeInfo>
{
{ "decimal", new DbTypeInfo() }
}, ordinal => $"reader.GetDecimal({ordinal})"),
// last item in the dictionary - enforce TODO
new("object",
protected override Dictionary<string, ColumnMapping> ColumnMappings { get; } =
new()
{
["bool"] = new ColumnMapping(
new Dictionary<string, DbTypeInfo>
{
{ "tinyint", new DbTypeInfo(Length: 1) }
},
ordinal => $"reader.GetBoolean({ordinal})"
),
["short"] = new ColumnMapping(
new Dictionary<string, DbTypeInfo>
{
{ "tinyint", new DbTypeInfo() },
{ "smallint", new DbTypeInfo() },
{ "year", new DbTypeInfo() }
},
ordinal => $"reader.GetInt16({ordinal})"
),
["long"] = new ColumnMapping(
new Dictionary<string, DbTypeInfo>
{
{ "bigint", new DbTypeInfo() }
},
ordinal => $"reader.GetInt64({ordinal})"
),
["byte"] = new ColumnMapping(
new Dictionary<string, DbTypeInfo>
{
{ "bit", new DbTypeInfo() }
},
ordinal => $"reader.GetFieldValue<byte>({ordinal})"
),
["byte[]"] = new ColumnMapping(
new Dictionary<string, DbTypeInfo>
{
{ "binary", new DbTypeInfo() },
{ "blob", new DbTypeInfo() },
{ "longblob", new DbTypeInfo() },
{ "mediumblob", new DbTypeInfo() },
{ "tinyblob", new DbTypeInfo() },
{ "varbinary", new DbTypeInfo() }
},
ordinal => $"reader.GetFieldValue<byte[]>({ordinal})"
),
["string"] = new ColumnMapping(
new Dictionary<string, DbTypeInfo>
{
{ "char", new DbTypeInfo() },
{ "longtext", new DbTypeInfo() },
{ "mediumtext", new DbTypeInfo() },
{ "text", new DbTypeInfo() },
{ "time", new DbTypeInfo() },
{ "tinytext", new DbTypeInfo() },
{ "varchar", new DbTypeInfo() },
{ "var_string", new DbTypeInfo() },
{ "json", new DbTypeInfo() }
},
ordinal => $"reader.GetString({ordinal})"
),
["DateTime"] = new ColumnMapping(
new Dictionary<string, DbTypeInfo>
{
{ "date", new DbTypeInfo() },
{ "datetime", new DbTypeInfo() },
{ "timestamp", new DbTypeInfo() }
},
ordinal => $"reader.GetDateTime({ordinal})"
),
["int"] = new ColumnMapping(
new Dictionary<string, DbTypeInfo>
{
{ "int", new DbTypeInfo() },
{ "mediumint", new DbTypeInfo() }
},
ordinal => $"reader.GetInt32({ordinal})"
),
["double"] = new ColumnMapping(
new Dictionary<string, DbTypeInfo>
{
{ "double", new DbTypeInfo() },
{ "float", new DbTypeInfo() }
},
ordinal => $"reader.GetDouble({ordinal})"
),
["decimal"] = new ColumnMapping(
new Dictionary<string, DbTypeInfo>
{
{ "decimal", new DbTypeInfo() }
},
ordinal => $"reader.GetDecimal({ordinal})"
),
["object"] = new ColumnMapping(
new Dictionary<string, DbTypeInfo>
{
{ "any", new DbTypeInfo() }
}, ordinal => $"reader.GetValue({ordinal})")
];
},
ordinal => $"reader.GetValue({ordinal})"
)
};

public override UsingDirectiveSyntax[] GetUsingDirectivesForQueries()
{
Expand Down
Loading