Skip to content

Commit ecda614

Browse files
[release] feat: add option to override string to DateTime for Sqlite (#317)
* feat: add option to override string to DateTime for Sqlite * feat: add option to override integer to DateTime for Sqlite --------- Co-authored-by: Doron Eli <doron050@gmail.com>
1 parent 843cbcc commit ecda614

34 files changed

Lines changed: 756 additions & 180 deletions

Drivers/ColumnMapping.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
1-
using System;
21
using System.Collections.Generic;
32

43
namespace SqlcGenCsharp.Drivers;
54

65
public record DbTypeInfo(int? Length = null, string? NpgsqlTypeOverride = null);
76

8-
public delegate string ReaderFn(int ordinal);
7+
public delegate string ReaderFn(int ordinal, string dbType);
98

10-
public delegate string WriterFn(string el, bool notNull, bool isDapper);
9+
public delegate string WriterFn(string el, string dbType, bool notNull, bool isDapper, bool isLegacy);
1110

1211
public delegate string ConvertFunc(string el);
1312

Drivers/DbDriver.cs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -257,8 +257,10 @@ protected bool CopyFromQueryExists()
257257
{
258258
if (query is null)
259259
return null;
260-
return Options.Overrides.FirstOrDefault(o =>
261-
o.Column == $"{query.Name}:{column.Name}" || o.Column == $"*:{column.Name}");
260+
foreach (var overrideOption in Options.Overrides)
261+
if (overrideOption.Column == $"{query.Name}:{column.Name}" || overrideOption.Column == $"*:{column.Name}")
262+
return overrideOption;
263+
return null;
262264
}
263265

264266
// If the column data type is overridden, we need to check for nulls in generated code
@@ -337,29 +339,29 @@ private static bool DoesColumnMappingApply(ColumnMapping columnMapping, Column c
337339
if (writerFn is not null)
338340
return writerFn;
339341

340-
static string DefaultWriterFn(string el, bool notNull, bool isDapper) => notNull ? el : $"{el} ?? (object)DBNull.Value";
342+
static string DefaultWriterFn(string el, string dbType, bool notNull, bool isDapper, bool isLegacy) => notNull ? el : $"{el} ?? (object)DBNull.Value";
341343
return Options.UseDapper ? null : DefaultWriterFn;
342344
}
343345

344346
/* Column reader methods */
345-
private string GetColumnReader(CsharpTypeOption csharpTypeOption, int ordinal)
347+
private string GetColumnReader(CsharpTypeOption csharpTypeOption, Column column, int ordinal)
346348
{
347349
if (ColumnMappings.TryGetValue(csharpTypeOption.Type, out var value))
348-
return value.ReaderFn(ordinal);
350+
return value.ReaderFn(ordinal, column.Type.Name);
349351
throw new NotSupportedException($"Could not find column mapping for type override: {csharpTypeOption.Type}");
350352
}
351353

352354
public virtual string GetColumnReader(Column column, int ordinal, Query? query)
353355
{
354356
if (FindOverrideForQueryColumn(query, column) is { CsharpType: var csharpType })
355-
return GetColumnReader(csharpType, ordinal);
357+
return GetColumnReader(csharpType, column, ordinal);
356358

357359
foreach (var columnMapping in ColumnMappings.Values
358360
.Where(columnMapping => DoesColumnMappingApply(columnMapping, column)))
359361
{
360362
if (column.IsArray)
361-
return columnMapping.ReaderArrayFn?.Invoke(ordinal) ?? throw new InvalidOperationException("ReaderArrayFn is null");
362-
return columnMapping.ReaderFn(ordinal);
363+
return columnMapping.ReaderArrayFn?.Invoke(ordinal, column.Type.Name) ?? throw new InvalidOperationException("ReaderArrayFn is null");
364+
return columnMapping.ReaderFn(ordinal, column.Type.Name);
363365
}
364366
throw new NotSupportedException($"column {column.Name} has unsupported column type: {column.Type.Name} in {GetType().Name}");
365367
}

Drivers/Generators/CommonGen.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public string AddParametersToCommand(Query query)
2828

2929
var notNull = dbDriver.IsColumnNotNull(p.Column, query);
3030
var writerFn = dbDriver.GetWriterFn(p.Column, query);
31-
var paramToWrite = writerFn is null ? param : writerFn(param, notNull, dbDriver.Options.UseDapper);
31+
var paramToWrite = writerFn is null ? param : writerFn(param, p.Column.Type.Name, notNull, dbDriver.Options.UseDapper, dbDriver.Options.DotnetFramework.IsDotnetLegacy());
3232
var addParamToCommand = $"""{commandVar}.Parameters.AddWithValue("@{p.Column.Name}", {paramToWrite});""";
3333
return addParamToCommand;
3434
}).JoinByNewLine();
@@ -57,7 +57,7 @@ public string ConstructDapperParamsDict(Query query)
5757

5858
var notNull = dbDriver.IsColumnNotNull(p.Column, query);
5959
var writerFn = dbDriver.GetWriterFn(p.Column, query);
60-
var paramToWrite = writerFn is null ? $"{argsVar}.{param}" : writerFn($"{argsVar}.{param}", notNull, dbDriver.Options.UseDapper);
60+
var paramToWrite = writerFn is null ? $"{argsVar}.{param}" : writerFn($"{argsVar}.{param}", p.Column.Type.Name, notNull, dbDriver.Options.UseDapper, dbDriver.Options.DotnetFramework.IsDotnetLegacy());
6161
var addParamToDict = $"{queryParamsVar}.Add(\"{p.Column.Name}\", {paramToWrite});";
6262
return addParamToDict;
6363
});

Drivers/MySqlConnectorDriver.cs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public sealed partial class MySqlConnectorDriver(
2626
{
2727
{ "tinyint", new(Length: 1) }
2828
},
29-
ordinal => $"reader.GetBoolean({ordinal})"
29+
readerFn: (ordinal, _) => $"reader.GetBoolean({ordinal})"
3030
),
3131
["short"] = new(
3232
new()
@@ -35,7 +35,7 @@ public sealed partial class MySqlConnectorDriver(
3535
{ "smallint", new() },
3636
{ "year", new() }
3737
},
38-
ordinal => $"reader.GetInt16({ordinal})"
38+
readerFn: (ordinal, _) => $"reader.GetInt16({ordinal})"
3939
),
4040
["int"] = new(
4141
new()
@@ -44,15 +44,15 @@ public sealed partial class MySqlConnectorDriver(
4444
{ "integer", new() },
4545
{ "mediumint", new() }
4646
},
47-
ordinal => $"reader.GetInt32({ordinal})",
47+
readerFn: (ordinal, _) => $"reader.GetInt32({ordinal})",
4848
convertFunc: x => $"Convert.ToInt32{x}"
4949
),
5050
["long"] = new(
5151
new()
5252
{
5353
{ "bigint", new() }
5454
},
55-
ordinal => $"reader.GetInt64({ordinal})",
55+
readerFn: (ordinal, _) => $"reader.GetInt64({ordinal})",
5656
convertFunc: x => $"Convert.ToInt64{x}"
5757
),
5858
["double"] = new(
@@ -61,14 +61,14 @@ public sealed partial class MySqlConnectorDriver(
6161
{ "double", new() },
6262
{ "float", new() }
6363
},
64-
ordinal => $"reader.GetDouble({ordinal})"
64+
readerFn: (ordinal, _) => $"reader.GetDouble({ordinal})"
6565
),
6666
["decimal"] = new(
6767
new()
6868
{
6969
{ "decimal", new() }
7070
},
71-
ordinal => $"reader.GetDecimal({ordinal})"
71+
readerFn: (ordinal, _) => $"reader.GetDecimal({ordinal})"
7272
),
7373

7474
/* Binary data types */
@@ -77,7 +77,7 @@ public sealed partial class MySqlConnectorDriver(
7777
{
7878
{ "bit", new() }
7979
},
80-
ordinal => $"reader.GetFieldValue<byte>({ordinal})"
80+
readerFn: (ordinal, _) => $"reader.GetFieldValue<byte>({ordinal})"
8181
),
8282
["byte[]"] = new(
8383
new()
@@ -89,7 +89,7 @@ public sealed partial class MySqlConnectorDriver(
8989
{ "tinyblob", new() },
9090
{ "varbinary", new() }
9191
},
92-
ordinal => $"reader.GetFieldValue<byte[]>({ordinal})"
92+
readerFn: (ordinal, _) => $"reader.GetFieldValue<byte[]>({ordinal})"
9393
),
9494

9595
/* String data types */
@@ -104,7 +104,7 @@ public sealed partial class MySqlConnectorDriver(
104104
{ "varchar", new() },
105105
{ "var_string", new() },
106106
},
107-
ordinal => $"reader.GetString({ordinal})"
107+
readerFn: (ordinal, _) => $"reader.GetString({ordinal})"
108108
),
109109

110110
/* Date and time data types */
@@ -115,14 +115,14 @@ public sealed partial class MySqlConnectorDriver(
115115
{ "datetime", new() },
116116
{ "timestamp", new() }
117117
},
118-
readerFn: ordinal => $"reader.GetDateTime({ordinal})"
118+
readerFn: (ordinal, _) => $"reader.GetDateTime({ordinal})"
119119
),
120120
["TimeSpan"] = new(
121121
new()
122122
{
123123
{ "time", new() }
124124
},
125-
readerFn: ordinal => $"reader.GetFieldValue<TimeSpan>({ordinal})"
125+
readerFn: (ordinal, _) => $"reader.GetFieldValue<TimeSpan>({ordinal})"
126126
),
127127

128128
/* Unstructured data types */
@@ -131,8 +131,8 @@ public sealed partial class MySqlConnectorDriver(
131131
{
132132
{ "json", new() }
133133
},
134-
readerFn: ordinal => $"JsonSerializer.Deserialize<JsonElement>(reader.GetString({ordinal}))",
135-
writerFn: (el, notNull, isDapper) =>
134+
readerFn: (ordinal, _) => $"JsonSerializer.Deserialize<JsonElement>(reader.GetString({ordinal}))",
135+
writerFn: (el, _, notNull, isDapper, isLegacy) =>
136136
{
137137
if (notNull)
138138
return $"{el}.GetRawText()";
@@ -150,7 +150,7 @@ public sealed partial class MySqlConnectorDriver(
150150
{
151151
{ "any", new() }
152152
},
153-
ordinal => $"reader.GetValue({ordinal})"
153+
readerFn: (ordinal, _) => $"reader.GetValue({ordinal})"
154154
)
155155
};
156156

@@ -621,7 +621,7 @@ private bool IsSetDataType(Column column)
621621
return writerFn;
622622

623623
if (GetEnumType(column) is { } enumType && IsSetDataType(column, enumType))
624-
return (el, notNull, isDapper) =>
624+
return (el, dbType, notNull, isDapper, isLegacy) =>
625625
{
626626
var stringJoinStmt = $"string.Join(\",\", {el})";
627627
var nullValue = isDapper ? "null" : "(object)DBNull.Value";
@@ -630,7 +630,7 @@ private bool IsSetDataType(Column column)
630630
: $"{el} != null ? {stringJoinStmt} : {nullValue}";
631631
};
632632

633-
static string DefaultWriterFn(string el, bool notNull, bool isDapper) => notNull ? el : $"{el} ?? (object)DBNull.Value";
633+
static string DefaultWriterFn(string el, string dbType, bool notNull, bool isDapper, bool isLegacy) => notNull ? el : $"{el} ?? (object)DBNull.Value";
634634
return Options.UseDapper ? null : DefaultWriterFn;
635635
}
636636

0 commit comments

Comments
 (0)