Skip to content

Commit 56c06a4

Browse files
authored
Merge pull request #1059 from inforithmics/FastColumnArgumentException
Fix for issue "1.8.0-beta - System.ArgumentException: method arguments are incompatible" and Unit Tests
2 parents 4479f31 + e1d4ce7 commit 56c06a4

File tree

2 files changed

+78
-13
lines changed

2 files changed

+78
-13
lines changed

src/SQLite.cs

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3004,20 +3004,30 @@ public IEnumerable<T> ExecuteDeferredQuery<T> (TableMapping map)
30043004
var stmt = Prepare ();
30053005
try {
30063006
var cols = new TableMapping.Column[SQLite3.ColumnCount (stmt)];
3007-
var fastColumnSetters = new Action<T, Sqlite3Statement, int>[SQLite3.ColumnCount (stmt)];
3007+
var fastColumnSetters = new Action<object, Sqlite3Statement, int>[SQLite3.ColumnCount (stmt)];
30083008

30093009
if (map.Method == TableMapping.MapMethod.ByPosition)
30103010
{
30113011
Array.Copy(map.Columns, cols, Math.Min(cols.Length, map.Columns.Length));
30123012
}
3013-
else if (map.Method == TableMapping.MapMethod.ByName)
3014-
{
3015-
for (int i = 0; i < cols.Length; i++)
3016-
{
3013+
else if (map.Method == TableMapping.MapMethod.ByName) {
3014+
MethodInfo getSetter = null;
3015+
if (typeof(T) != map.MappedType) {
3016+
getSetter = typeof(FastColumnSetter)
3017+
.GetMethod (nameof(FastColumnSetter.GetFastSetter),
3018+
BindingFlags.NonPublic | BindingFlags.Static).MakeGenericMethod (map.MappedType);
3019+
}
3020+
3021+
for (int i = 0; i < cols.Length; i++) {
30173022
var name = SQLite3.ColumnName16 (stmt, i);
30183023
cols[i] = map.FindColumn (name);
30193024
if (cols[i] != null)
3020-
fastColumnSetters[i] = FastColumnSetter.GetFastSetter<T> (_conn, cols[i]);
3025+
if (getSetter != null) {
3026+
fastColumnSetters[i] = (Action<object, Sqlite3Statement, int>)getSetter.Invoke(null, new object[]{ _conn, cols[i]});
3027+
}
3028+
else {
3029+
fastColumnSetters[i] = FastColumnSetter.GetFastSetter<T>(_conn, cols[i]);
3030+
}
30213031
}
30223032
}
30233033

@@ -3028,7 +3038,7 @@ public IEnumerable<T> ExecuteDeferredQuery<T> (TableMapping map)
30283038
continue;
30293039

30303040
if (fastColumnSetters[i] != null) {
3031-
fastColumnSetters[i].Invoke ((T)obj, stmt, i);
3041+
fastColumnSetters[i].Invoke (obj, stmt, i);
30323042
}
30333043
else {
30343044
var colType = SQLite3.ColumnType (stmt, i);
@@ -3369,9 +3379,9 @@ internal class FastColumnSetter
33693379
///
33703380
/// If no fast setter is available for the requested column (enums in particular cause headache), then this function returns null.
33713381
/// </returns>
3372-
internal static Action<T, Sqlite3Statement, int> GetFastSetter<T> (SQLiteConnection conn, TableMapping.Column column)
3382+
internal static Action<object, Sqlite3Statement, int> GetFastSetter<T> (SQLiteConnection conn, TableMapping.Column column)
33733383
{
3374-
Action<T, Sqlite3Statement, int> fastSetter = null;
3384+
Action<object, Sqlite3Statement, int> fastSetter = null;
33753385

33763386
Type clrType = column.PropertyInfo.PropertyType;
33773387

@@ -3528,7 +3538,7 @@ internal static Action<T, Sqlite3Statement, int> GetFastSetter<T> (SQLiteConnect
35283538
/// <param name="column">The column mapping that identifies the target member of the destination object</param>
35293539
/// <param name="getColumnValue">A lambda that can be used to retrieve the column value at query-time</param>
35303540
/// <returns>A strongly-typed delegate</returns>
3531-
private static Action<ObjectType, Sqlite3Statement, int> CreateNullableTypedSetterDelegate<ObjectType, ColumnMemberType> (TableMapping.Column column, Func<Sqlite3Statement, int, ColumnMemberType> getColumnValue) where ColumnMemberType : struct
3541+
private static Action<object, Sqlite3Statement, int> CreateNullableTypedSetterDelegate<ObjectType, ColumnMemberType> (TableMapping.Column column, Func<Sqlite3Statement, int, ColumnMemberType> getColumnValue) where ColumnMemberType : struct
35323542
{
35333543
var clrTypeInfo = column.PropertyInfo.PropertyType.GetTypeInfo();
35343544
bool isNullable = false;
@@ -3545,7 +3555,7 @@ private static Action<ObjectType, Sqlite3Statement, int> CreateNullableTypedSett
35453555
return (o, stmt, i) => {
35463556
var colType = SQLite3.ColumnType (stmt, i);
35473557
if (colType != SQLite3.ColType.Null)
3548-
setProperty.Invoke (o, getColumnValue.Invoke (stmt, i));
3558+
setProperty.Invoke ((ObjectType)o, getColumnValue.Invoke (stmt, i));
35493559
};
35503560
}
35513561

@@ -3560,7 +3570,7 @@ private static Action<ObjectType, Sqlite3Statement, int> CreateNullableTypedSett
35603570
/// <param name="column">The column mapping that identifies the target member of the destination object</param>
35613571
/// <param name="getColumnValue">A lambda that can be used to retrieve the column value at query-time</param>
35623572
/// <returns>A strongly-typed delegate</returns>
3563-
private static Action<ObjectType, Sqlite3Statement, int> CreateTypedSetterDelegate<ObjectType, ColumnMemberType> (TableMapping.Column column, Func<Sqlite3Statement, int, ColumnMemberType> getColumnValue)
3573+
private static Action<object, Sqlite3Statement, int> CreateTypedSetterDelegate<ObjectType, ColumnMemberType> (TableMapping.Column column, Func<Sqlite3Statement, int, ColumnMemberType> getColumnValue)
35643574
{
35653575
var setProperty = (Action<ObjectType, ColumnMemberType>)Delegate.CreateDelegate (
35663576
typeof (Action<ObjectType, ColumnMemberType>), null,
@@ -3569,7 +3579,7 @@ private static Action<ObjectType, Sqlite3Statement, int> CreateTypedSetterDelega
35693579
return (o, stmt, i) => {
35703580
var colType = SQLite3.ColumnType (stmt, i);
35713581
if (colType != SQLite3.ColType.Null)
3572-
setProperty.Invoke (o, getColumnValue.Invoke (stmt, i));
3582+
setProperty.Invoke ((ObjectType)o, getColumnValue.Invoke (stmt, i));
35733583
};
35743584
}
35753585
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
using System.Linq;
2+
using System.Text;
3+
using SQLite;
4+
using System.Threading.Tasks;
5+
using System.IO;
6+
7+
#if NETFX_CORE
8+
using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
9+
using SetUp = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestInitializeAttribute;
10+
using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute;
11+
using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute;
12+
#else
13+
using NUnit.Framework;
14+
#endif
15+
16+
namespace SQLite.Tests
17+
{
18+
[TestFixture]
19+
public class DbCommandTest
20+
{
21+
[Test]
22+
public void QueryCommand()
23+
{
24+
var db = new SQLiteConnection (Path.GetTempFileName(), true);
25+
db.CreateTable<Product>();
26+
var b = new Product();
27+
db.Insert(b);
28+
29+
var test = db.CreateCommand("select * from Product")
30+
.ExecuteDeferredQuery<Product>(new TableMapping(typeof(Product))).ToList();
31+
32+
33+
Assert.AreEqual (test.Count, 1);
34+
}
35+
36+
#region Issue #1048
37+
38+
[Test]
39+
public void QueryCommandCastToObject()
40+
{
41+
var db = new SQLiteConnection (Path.GetTempFileName(), true);
42+
db.CreateTable<Product>();
43+
var b = new Product();
44+
db.Insert(b);
45+
46+
var test = db.CreateCommand("select * from Product")
47+
.ExecuteDeferredQuery<object>(new TableMapping(typeof(Product))).ToList();
48+
49+
50+
Assert.AreEqual (test.Count, 1);
51+
}
52+
53+
#endregion
54+
}
55+
}

0 commit comments

Comments
 (0)