From 6fcd0d70b708c28a311ad17a2c74ce595962c3e1 Mon Sep 17 00:00:00 2001
From: ilmalte <17677294+ilmalte@users.noreply.github.com>
Date: Fri, 21 Jul 2023 09:07:28 +0200
Subject: [PATCH] feat: support half for Sqlite #30931
---
.../Internal/SqliteDatabaseModelFactory.cs | 5 +++++
.../SqliteDataReader.cs | 15 +++++++++++++++
.../SqliteValueBinder.cs | 7 +++++++
.../SqliteValueReader.cs | 12 ++++++++++++
.../SqliteDataReaderTest.cs | 9 +++++++++
5 files changed, 48 insertions(+)
diff --git a/src/EFCore.Sqlite.Core/Scaffolding/Internal/SqliteDatabaseModelFactory.cs b/src/EFCore.Sqlite.Core/Scaffolding/Internal/SqliteDatabaseModelFactory.cs
index 7a4fc2c378f..c2d5a60764f 100644
--- a/src/EFCore.Sqlite.Core/Scaffolding/Internal/SqliteDatabaseModelFactory.cs
+++ b/src/EFCore.Sqlite.Core/Scaffolding/Internal/SqliteDatabaseModelFactory.cs
@@ -711,6 +711,11 @@ protected virtual void InferClrTypes(DbConnection connection, DatabaseTable tabl
column["ClrType"] = typeof(double);
}
+ if (defaultClrTpe != typeof(Half))
+ {
+ column["ClrType"] = typeof(Half);
+ }
+
continue;
}
diff --git a/src/Microsoft.Data.Sqlite.Core/SqliteDataReader.cs b/src/Microsoft.Data.Sqlite.Core/SqliteDataReader.cs
index f18627a43e7..6c1d759c3b7 100644
--- a/src/Microsoft.Data.Sqlite.Core/SqliteDataReader.cs
+++ b/src/Microsoft.Data.Sqlite.Core/SqliteDataReader.cs
@@ -440,6 +440,21 @@ public override float GetFloat(int ordinal)
? throw new InvalidOperationException(Resources.NoData)
: _record.GetFloat(ordinal);
+
+#if NET6_0_OR_GREATER
+ ///
+ /// Gets the value of the specified column as a .
+ ///
+ /// The zero-based column ordinal.
+ /// The value of the column.
+ public virtual Half GetHalf(int ordinal)
+ => _closed
+ ? throw new InvalidOperationException(Resources.DataReaderClosed(nameof(GetHalf)))
+ : _record == null
+ ? throw new InvalidOperationException(Resources.NoData)
+ : _record.GetHalf(ordinal);
+#endif
+
///
/// Gets the value of the specified column as a .
///
diff --git a/src/Microsoft.Data.Sqlite.Core/SqliteValueBinder.cs b/src/Microsoft.Data.Sqlite.Core/SqliteValueBinder.cs
index 137a50fe080..50b87899bb3 100644
--- a/src/Microsoft.Data.Sqlite.Core/SqliteValueBinder.cs
+++ b/src/Microsoft.Data.Sqlite.Core/SqliteValueBinder.cs
@@ -163,6 +163,13 @@ public virtual void Bind()
var value = (double)(float)_value;
BindDouble(value);
}
+#if NET6_0_OR_GREATER
+ else if (type == typeof(Half))
+ {
+ var value = (double)(Half)_value;
+ BindDouble(value);
+ }
+#endif
else if (type == typeof(Guid))
{
var guid = (Guid)_value;
diff --git a/src/Microsoft.Data.Sqlite.Core/SqliteValueReader.cs b/src/Microsoft.Data.Sqlite.Core/SqliteValueReader.cs
index 0a8b9b36a70..d78b442aa3a 100644
--- a/src/Microsoft.Data.Sqlite.Core/SqliteValueReader.cs
+++ b/src/Microsoft.Data.Sqlite.Core/SqliteValueReader.cs
@@ -99,6 +99,11 @@ public virtual double GetDouble(int ordinal)
public virtual float GetFloat(int ordinal)
=> (float)GetDouble(ordinal);
+ #if NET6_0_OR_GREATER
+ public virtual Half GetHalf(int ordinal)
+ => (Half)GetDouble(ordinal);
+ #endif
+
public virtual Guid GetGuid(int ordinal)
{
var sqliteType = GetSqliteType(ordinal);
@@ -320,6 +325,13 @@ public virtual string GetString(int ordinal)
return (T)(object)GetFloat(ordinal);
}
+#if NET6_0_OR_GREATER
+ if (type == typeof(Half))
+ {
+ return (T)(object)GetFloat(ordinal);
+ }
+#endif
+
if (type == typeof(Guid))
{
return (T)(object)GetGuid(ordinal);
diff --git a/test/Microsoft.Data.Sqlite.Tests/SqliteDataReaderTest.cs b/test/Microsoft.Data.Sqlite.Tests/SqliteDataReaderTest.cs
index f8866e09aef..1d65e04553f 100644
--- a/test/Microsoft.Data.Sqlite.Tests/SqliteDataReaderTest.cs
+++ b/test/Microsoft.Data.Sqlite.Tests/SqliteDataReaderTest.cs
@@ -1168,6 +1168,15 @@ public void GetFloat_throws_when_closed()
public void GetFloat_throws_when_non_query()
=> X_throws_when_non_query(r => r.GetFloat(0));
+#if NET6_0_OR_GREATER
+ [Fact]
+ public void GetHalf_throws_when_closed()
+ => X_throws_when_closed(r => r.GetHalf(0), nameof(SqliteDataReader.GetHalf));
+
+ [Fact]
+ public void GetHalf_throws_when_non_query()
+ => X_throws_when_non_query(r => r.GetHalf(0));
+#endif
[Theory]
[InlineData("2.0", 2.0)]
[InlineData("9e999", double.PositiveInfinity)]