diff --git a/src/Microsoft.Data.Sqlite.Core/SqliteParameter.cs b/src/Microsoft.Data.Sqlite.Core/SqliteParameter.cs index 265634b0100..e71073b8300 100644 --- a/src/Microsoft.Data.Sqlite.Core/SqliteParameter.cs +++ b/src/Microsoft.Data.Sqlite.Core/SqliteParameter.cs @@ -200,7 +200,7 @@ public override void ResetDbType() public virtual void ResetSqliteType() { DbType = DbType.String; - SqliteType = SqliteType.Text; + _sqliteType = null; } internal bool Bind(sqlite3_stmt stmt) diff --git a/src/Microsoft.Data.Sqlite.Core/SqliteValueBinder.cs b/src/Microsoft.Data.Sqlite.Core/SqliteValueBinder.cs index 3e7ac998b8a..137a50fe080 100644 --- a/src/Microsoft.Data.Sqlite.Core/SqliteValueBinder.cs +++ b/src/Microsoft.Data.Sqlite.Core/SqliteValueBinder.cs @@ -246,6 +246,10 @@ public virtual void Bind() { typeof(char), SqliteType.Text }, { typeof(DateTime), SqliteType.Text }, { typeof(DateTimeOffset), SqliteType.Text }, +#if NET6_0_OR_GREATER + { typeof(DateOnly), SqliteType.Text }, + { typeof(TimeOnly), SqliteType.Text }, +#endif { typeof(DBNull), SqliteType.Text }, { typeof(decimal), SqliteType.Text }, { typeof(double), SqliteType.Real }, @@ -255,7 +259,7 @@ public virtual void Bind() { typeof(long), SqliteType.Integer }, { typeof(sbyte), SqliteType.Integer }, { typeof(short), SqliteType.Integer }, - { typeof(string), SqliteType.Integer }, + { typeof(string), SqliteType.Text }, { typeof(TimeSpan), SqliteType.Text }, { typeof(uint), SqliteType.Integer }, { typeof(ulong), SqliteType.Integer }, diff --git a/test/Microsoft.Data.Sqlite.Tests/SqliteParameterTest.cs b/test/Microsoft.Data.Sqlite.Tests/SqliteParameterTest.cs index 1779cad3e0b..e7758f21dac 100644 --- a/test/Microsoft.Data.Sqlite.Tests/SqliteParameterTest.cs +++ b/test/Microsoft.Data.Sqlite.Tests/SqliteParameterTest.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Collections.Generic; using System.Data; using System.Data.Common; using Microsoft.Data.Sqlite.Properties; @@ -93,6 +94,21 @@ public void SqliteType_defaults_to_text() Assert.Equal(SqliteType.Text, new SqliteParameter().SqliteType); } + [Theory] + [MemberData(nameof(TypesData))] + public void SqliteType_is_inferred_from_value(object value, SqliteType expectedType) + { + var parameter = new SqliteParameter { Value = value }; + Assert.Equal(expectedType, parameter.SqliteType); + } + + [Fact] + public void SqliteType_overrides_inferred_value() + { + var parameter = new SqliteParameter { Value = 'A', SqliteType = SqliteType.Integer }; + Assert.Equal(SqliteType.Integer, parameter.SqliteType); + } + [Fact] public void Direction_input_by_default() { @@ -128,6 +144,16 @@ public void ResetSqliteType_works() Assert.Equal(SqliteType.Text, parameter.SqliteType); } + [Fact] + public void ResetSqliteType_works_when_value() + { + var parameter = new SqliteParameter { Value = new byte[0], SqliteType = SqliteType.Text }; + + parameter.ResetSqliteType(); + + Assert.Equal(SqliteType.Blob, parameter.SqliteType); + } + [Fact] public void Bind_requires_set_name() { @@ -557,6 +583,36 @@ public void Add_range_of_parameters_using_DbCommand_base_class() } } + public static IEnumerable TypesData + => new List + { + new object[] { default(DateTime), SqliteType.Text }, + new object[] { default(DateTimeOffset), SqliteType.Text }, + new object[] { DBNull.Value, SqliteType.Text }, + new object[] { 0m, SqliteType.Text }, + new object[] { default(Guid), SqliteType.Text }, + new object[] { default(TimeSpan), SqliteType.Text }, + new object[] { default(TimeSpan), SqliteType.Text }, +#if NET6_0_OR_GREATER + new object[] { default(DateOnly), SqliteType.Text }, + new object[] { default(TimeOnly), SqliteType.Text }, +#endif + new object[] { 'A', SqliteType.Text }, + new object[] { "", SqliteType.Text }, + new object[] { false, SqliteType.Integer }, + new object[] { (byte)0, SqliteType.Integer }, + new object[] { 0, SqliteType.Integer }, + new object[] { 0L, SqliteType.Integer }, + new object[] { (sbyte)0, SqliteType.Integer }, + new object[] { (short)0, SqliteType.Integer }, + new object[] { 0u, SqliteType.Integer }, + new object[] { 0ul, SqliteType.Integer }, + new object[] { (ushort)0, SqliteType.Integer }, + new object[] { 0.0, SqliteType.Real }, + new object[] { 0f, SqliteType.Real }, + new object[] { new byte[0], SqliteType.Blob }, + }; + private enum MyEnum { One = 1