Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

respect designated DbType when explicitly specified #100

Merged
merged 2 commits into from
Dec 13, 2023
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: 1 addition & 0 deletions src/Dapper.AOT.Analyzers/Internal/Inspection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,7 @@ public readonly struct ElementMember
if (preferredType != dbType)
{ // only preserve the reader method if this matches
readerMethod = null;
dbType = preferredType;
}
}
return dbType;
Expand Down
28 changes: 28 additions & 0 deletions test/Dapper.AOT.Test/Interceptors/DbValueUsage.input.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using Dapper;
using System;
using System.Data.Common;
using System.Threading.Tasks;

[DapperAot(enabled: true)]
public static class UsersSqlQueries
{
public sealed class UserIncrementParams
{
[DbValue(Name = "userId")]
public int UserId { get; set; }

[DbValue(Name = "date", DbType = System.Data.DbType.Date)]
public DateTime Date { get; set; }
}

public static async Task IncrementAsync(DbConnection connection, int userId)
{
var date = DateTime.Today;

await connection.ExecuteAsync("""
UPDATE [dbo].[table]
SET [column] = ([column] + 1)
WHERE [Id] = @userId and [Date] = @date
""", new UserIncrementParams() { UserId = userId, Date = date });
}
}
91 changes: 91 additions & 0 deletions test/Dapper.AOT.Test/Interceptors/DbValueUsage.output.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
#nullable enable
namespace Dapper.AOT // interceptors must be in a known namespace
{
file static class DapperGeneratedInterceptors
{
[global::System.Runtime.CompilerServices.InterceptsLocationAttribute("Interceptors\\DbValueUsage.input.cs", 22, 26)]
internal static global::System.Threading.Tasks.Task<int> ExecuteAsync0(this global::System.Data.IDbConnection cnn, string sql, object? param, global::System.Data.IDbTransaction? transaction, int? commandTimeout, global::System.Data.CommandType? commandType)
{
// Execute, Async, HasParameters, Text, KnownParameters
// takes parameter: global::UsersSqlQueries.UserIncrementParams
// parameter map: Date UserId
global::System.Diagnostics.Debug.Assert(!string.IsNullOrWhiteSpace(sql));
global::System.Diagnostics.Debug.Assert((commandType ?? global::Dapper.DapperAotExtensions.GetCommandType(sql)) == global::System.Data.CommandType.Text);
global::System.Diagnostics.Debug.Assert(param is not null);

return global::Dapper.DapperAotExtensions.Command(cnn, transaction, sql, global::System.Data.CommandType.Text, commandTimeout.GetValueOrDefault(), CommandFactory0.Instance).ExecuteAsync((global::UsersSqlQueries.UserIncrementParams)param!);

}

private class CommonCommandFactory<T> : global::Dapper.CommandFactory<T>
{
public override global::System.Data.Common.DbCommand GetCommand(global::System.Data.Common.DbConnection connection, string sql, global::System.Data.CommandType commandType, T args)
{
var cmd = base.GetCommand(connection, sql, commandType, args);
// apply special per-provider command initialization logic for OracleCommand
if (cmd is global::Oracle.ManagedDataAccess.Client.OracleCommand cmd0)
{
cmd0.BindByName = true;
cmd0.InitialLONGFetchSize = -1;

}
return cmd;
}

}

private static readonly CommonCommandFactory<object?> DefaultCommandFactory = new();

private sealed class CommandFactory0 : CommonCommandFactory<global::UsersSqlQueries.UserIncrementParams>
{
internal static readonly CommandFactory0 Instance = new();
public override void AddParameters(in global::Dapper.UnifiedCommand cmd, global::UsersSqlQueries.UserIncrementParams args)
{
var ps = cmd.Parameters;
global::System.Data.Common.DbParameter p;
p = cmd.CreateParameter();
p.ParameterName = "userId";
p.DbType = global::System.Data.DbType.Int32;
p.Direction = global::System.Data.ParameterDirection.Input;
p.Value = AsValue(args.UserId);
ps.Add(p);

p = cmd.CreateParameter();
p.ParameterName = "date";
p.DbType = global::System.Data.DbType.Date;
p.Direction = global::System.Data.ParameterDirection.Input;
p.Value = AsValue(args.Date);
ps.Add(p);

}
public override void UpdateParameters(in global::Dapper.UnifiedCommand cmd, global::UsersSqlQueries.UserIncrementParams args)
{
var ps = cmd.Parameters;
ps[0].Value = AsValue(args.UserId);
ps[1].Value = AsValue(args.Date);

}
public override bool CanPrepare => true;

}


}
}
namespace System.Runtime.CompilerServices
{
// this type is needed by the compiler to implement interceptors - it doesn't need to
// come from the runtime itself, though

[global::System.Diagnostics.Conditional("DEBUG")] // not needed post-build, so: evaporate
[global::System.AttributeUsage(global::System.AttributeTargets.Method, AllowMultiple = true)]
sealed file class InterceptsLocationAttribute : global::System.Attribute
{
public InterceptsLocationAttribute(string path, int lineNumber, int columnNumber)
{
_ = path;
_ = lineNumber;
_ = columnNumber;
}
}
}
91 changes: 91 additions & 0 deletions test/Dapper.AOT.Test/Interceptors/DbValueUsage.output.netfx.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
#nullable enable
namespace Dapper.AOT // interceptors must be in a known namespace
{
file static class DapperGeneratedInterceptors
{
[global::System.Runtime.CompilerServices.InterceptsLocationAttribute("Interceptors\\DbValueUsage.input.cs", 22, 26)]
internal static global::System.Threading.Tasks.Task<int> ExecuteAsync0(this global::System.Data.IDbConnection cnn, string sql, object? param, global::System.Data.IDbTransaction? transaction, int? commandTimeout, global::System.Data.CommandType? commandType)
{
// Execute, Async, HasParameters, Text, KnownParameters
// takes parameter: global::UsersSqlQueries.UserIncrementParams
// parameter map: Date UserId
global::System.Diagnostics.Debug.Assert(!string.IsNullOrWhiteSpace(sql));
global::System.Diagnostics.Debug.Assert((commandType ?? global::Dapper.DapperAotExtensions.GetCommandType(sql)) == global::System.Data.CommandType.Text);
global::System.Diagnostics.Debug.Assert(param is not null);

return global::Dapper.DapperAotExtensions.Command(cnn, transaction, sql, global::System.Data.CommandType.Text, commandTimeout.GetValueOrDefault(), CommandFactory0.Instance).ExecuteAsync((global::UsersSqlQueries.UserIncrementParams)param!);

}

private class CommonCommandFactory<T> : global::Dapper.CommandFactory<T>
{
public override global::System.Data.Common.DbCommand GetCommand(global::System.Data.Common.DbConnection connection, string sql, global::System.Data.CommandType commandType, T args)
{
var cmd = base.GetCommand(connection, sql, commandType, args);
// apply special per-provider command initialization logic for OracleCommand
if (cmd is global::Oracle.ManagedDataAccess.Client.OracleCommand cmd0)
{
cmd0.BindByName = true;
cmd0.InitialLONGFetchSize = -1;

}
return cmd;
}

}

private static readonly CommonCommandFactory<object?> DefaultCommandFactory = new();

private sealed class CommandFactory0 : CommonCommandFactory<global::UsersSqlQueries.UserIncrementParams>
{
internal static readonly CommandFactory0 Instance = new();
public override void AddParameters(in global::Dapper.UnifiedCommand cmd, global::UsersSqlQueries.UserIncrementParams args)
{
var ps = cmd.Parameters;
global::System.Data.Common.DbParameter p;
p = cmd.CreateParameter();
p.ParameterName = "userId";
p.DbType = global::System.Data.DbType.Int32;
p.Direction = global::System.Data.ParameterDirection.Input;
p.Value = AsValue(args.UserId);
ps.Add(p);

p = cmd.CreateParameter();
p.ParameterName = "date";
p.DbType = global::System.Data.DbType.Date;
p.Direction = global::System.Data.ParameterDirection.Input;
p.Value = AsValue(args.Date);
ps.Add(p);

}
public override void UpdateParameters(in global::Dapper.UnifiedCommand cmd, global::UsersSqlQueries.UserIncrementParams args)
{
var ps = cmd.Parameters;
ps[0].Value = AsValue(args.UserId);
ps[1].Value = AsValue(args.Date);

}
public override bool CanPrepare => true;

}


}
}
namespace System.Runtime.CompilerServices
{
// this type is needed by the compiler to implement interceptors - it doesn't need to
// come from the runtime itself, though

[global::System.Diagnostics.Conditional("DEBUG")] // not needed post-build, so: evaporate
[global::System.AttributeUsage(global::System.AttributeTargets.Method, AllowMultiple = true)]
sealed file class InterceptsLocationAttribute : global::System.Attribute
{
public InterceptsLocationAttribute(string path, int lineNumber, int columnNumber)
{
_ = path;
_ = lineNumber;
_ = columnNumber;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Generator produced 1 diagnostics:

Hidden DAP000 L1 C1
Dapper.AOT handled 1 of 1 possible call-sites using 1 interceptors, 1 commands and 0 readers
4 changes: 4 additions & 0 deletions test/Dapper.AOT.Test/Interceptors/DbValueUsage.output.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Generator produced 1 diagnostics:

Hidden DAP000 L1 C1
Dapper.AOT handled 1 of 1 possible call-sites using 1 interceptors, 1 commands and 0 readers
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ public override void AddParameters(in global::Dapper.UnifiedCommand cmd, global:
global::System.Data.Common.DbParameter p;
p = cmd.CreateParameter();
p.ParameterName = "f";
p.DbType = global::System.Data.DbType.String;
p.DbType = global::System.Data.DbType.AnsiString;
p.Size = 200;
p.Direction = global::System.Data.ParameterDirection.Input;
p.Value = AsValue(args.B);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ public override void AddParameters(in global::Dapper.UnifiedCommand cmd, global:
global::System.Data.Common.DbParameter p;
p = cmd.CreateParameter();
p.ParameterName = "f";
p.DbType = global::System.Data.DbType.String;
p.DbType = global::System.Data.DbType.AnsiString;
p.Size = 200;
p.Direction = global::System.Data.ParameterDirection.Input;
p.Value = AsValue(args.B);
Expand Down
Loading