@@ -11,6 +11,10 @@ public record ConnectionGenCommands(string EstablishConnection, string Connectio
1111
1212public abstract class DbDriver
1313{
14+ protected const string DefaultDapperVersion = "2.1.66" ;
15+ protected const string DefaultSystemTextJsonVersion = "9.0.6" ;
16+ protected const string DefaultNodaTimeVersion = "3.2.0" ;
17+
1418 public Options Options { get ; }
1519
1620 public string DefaultSchema { get ; }
@@ -51,6 +55,7 @@ public abstract class DbDriver
5155 "NpgsqlCircle" ,
5256 "JsonElement" ,
5357 "NpgsqlCidr" ,
58+ "Instant"
5459 ] ;
5560
5661 protected abstract Dictionary < string , ColumnMapping > ColumnMappings { get ; }
@@ -68,6 +73,27 @@ public static string TransformQueryForSliceArgs(string originalSql, int sliceSiz
6873 throw new InvalidOperationException("Transaction is provided, but its connection is null.");
6974 """ ;
7075
76+ protected static readonly SqlMapperImplFunc DateTimeNodaInstantTypeHandler = _ => $$ """
77+ private class NodaInstantTypeHandler : SqlMapper.TypeHandler<Instant>
78+ {
79+ public override Instant Parse(object value)
80+ {
81+ if (value is DateTime dt)
82+ {
83+ if (dt.Kind != DateTimeKind.Utc)
84+ dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
85+ return dt.ToInstant();
86+ }
87+ throw new DataException($"Cannot convert {value?.GetType()} to Instant");
88+ }
89+
90+ public override void SetValue(IDbDataParameter parameter, Instant value)
91+ {
92+ parameter.Value = value;
93+ }
94+ }
95+ """ ;
96+
7197 protected DbDriver (
7298 Options options ,
7399 Catalog catalog ,
@@ -101,6 +127,21 @@ private static Dictionary<string, Dictionary<string, Table>> ConstructTablesLook
101127 ) ;
102128 }
103129
130+ public virtual IDictionary < string , string > GetPackageReferences ( )
131+ {
132+ return new Dictionary < string , string > {
133+ { "Dapper" , Options . OverrideDapperVersion != string . Empty ? Options . OverrideDapperVersion : DefaultDapperVersion }
134+ }
135+ . MergeIf ( new Dictionary < string , string >
136+ {
137+ { "System.Text.Json" , DefaultSystemTextJsonVersion }
138+ } , IsSystemTextJsonNeeded ( ) )
139+ . MergeIf ( new Dictionary < string , string >
140+ {
141+ { "NodaTime" , DefaultNodaTimeVersion }
142+ } , TypeExistsInQueries ( "Instant" ) ) ;
143+ }
144+
104145 public virtual ISet < string > GetUsingDirectivesForQueries ( )
105146 {
106147 return new HashSet < string >
@@ -118,17 +159,16 @@ public virtual ISet<string> GetUsingDirectivesForQueries()
118159 private ISet < string > GetUsingDirectivesForColumnMappings ( )
119160 {
120161 var usingDirectives = new HashSet < string > ( ) ;
121- foreach ( var schemaTables in Tables . Values )
122- foreach ( var table in schemaTables . Values )
123- foreach ( var column in table . Columns )
124- {
125- var csharpType = GetCsharpTypeWithoutNullableSuffix ( column , null ) ;
126- if ( ! ColumnMappings . ContainsKey ( csharpType ) )
127- continue ;
162+ foreach ( var query in Queries )
163+ foreach ( var column in query . Columns )
164+ {
165+ var csharpType = GetCsharpTypeWithoutNullableSuffix ( column , query ) ;
166+ if ( ! ColumnMappings . ContainsKey ( csharpType ) )
167+ continue ;
128168
129- var columnMapping = ColumnMappings [ csharpType ] ;
130- usingDirectives . AddRangeExcludeNulls ( [ columnMapping . UsingDirective ] ) ;
131- }
169+ var columnMapping = ColumnMappings [ csharpType ] ;
170+ usingDirectives . AddRangeIf ( columnMapping . UsingDirectives ! , columnMapping . UsingDirectives is not null ) ;
171+ }
132172 return usingDirectives ;
133173 }
134174
@@ -223,6 +263,32 @@ public virtual string[] GetLastIdStatement(Query query)
223263 ] ;
224264 }
225265
266+ public virtual string AddParametersToCommand ( Query query )
267+ {
268+ return query . Params . Select ( p =>
269+ {
270+ var commandVar = Variable . Command . AsVarName ( ) ;
271+ var param = $ "{ Variable . Args . AsVarName ( ) } .{ p . Column . Name . ToPascalCase ( ) } ";
272+ var columnMapping = GetCsharpTypeWithoutNullableSuffix ( p . Column , query ) ;
273+
274+ if ( p . Column . IsSqlcSlice )
275+ return $$ """
276+ for (int i = 0; i < {{ param }} .Length; i++)
277+ {{ commandVar }} .Parameters.AddWithValue($"@{{ p . Column . Name }} Arg{i}", {{ param }} [i]);
278+ """ ;
279+
280+ var writerFn = GetWriterFn ( p . Column , query ) ;
281+ var paramToWrite = writerFn is null ? param : writerFn (
282+ param ,
283+ p . Column . Type . Name ,
284+ IsColumnNotNull ( p . Column , query ) ,
285+ Options . UseDapper ,
286+ Options . DotnetFramework . IsDotnetLegacy ( ) ) ;
287+ var addParamToCommand = $ """ { commandVar } .Parameters.AddWithValue("@{ p . Column . Name } ", { paramToWrite } );""" ;
288+ return addParamToCommand ;
289+ } ) . JoinByNewLine ( ) ;
290+ }
291+
226292 public Column GetColumnFromParam ( Parameter queryParam , Query query )
227293 {
228294 if ( string . IsNullOrEmpty ( queryParam . Column . Name ) )
@@ -285,17 +351,6 @@ public string AddNullableSuffixIfNeeded(string csharpType, bool notNull)
285351 return IsTypeNullable ( csharpType ) ? $ "{ csharpType } ?" : csharpType ;
286352 }
287353
288- protected string ? GetColumnDbTypeOverride ( Column column )
289- {
290- var columnType = column . Type . Name . ToLower ( ) ;
291- foreach ( var columnMapping in ColumnMappings . Values )
292- {
293- if ( columnMapping . DbTypes . TryGetValue ( columnType , out var dbTypeOverride ) )
294- return dbTypeOverride . NpgsqlTypeOverride ;
295- }
296- throw new NotSupportedException ( $ "Column { column . Name } has unsupported column type: { column . Type . Name } ") ;
297- }
298-
299354 public bool IsTypeNullable ( string csharpType )
300355 {
301356 if ( NullableTypes . Contains ( csharpType . Replace ( "?" , "" ) ) ) return true ;
@@ -365,4 +420,11 @@ public virtual string GetColumnReader(Column column, int ordinal, Query? query)
365420 }
366421 throw new NotSupportedException ( $ "column { column . Name } has unsupported column type: { column . Type . Name } in { GetType ( ) . Name } ") ;
367422 }
423+
424+ private bool IsSystemTextJsonNeeded ( )
425+ {
426+ if ( Options . DotnetFramework . IsDotnetCore ( ) )
427+ return false ;
428+ return TypeExistsInQueries ( "JsonElement" ) ;
429+ }
368430}
0 commit comments