Permalink
Browse files

Automatically cast from SimpleQuery to collections and such where pos…

…sible (issue #219)
  • Loading branch information...
1 parent e1556ca commit 590dd559d04390572036f4d01c464a44f8026675 @markrendle committed Aug 29, 2012
View
@@ -0,0 +1,31 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using Simple.Data;
+
+namespace ProfilingApp
+{
+ public class CastTask : IProfileTask
+ {
+ private readonly dynamic _db = Database.OpenConnection(Properties.Settings.Default.ConnectionString);
+
+ public void Run()
+ {
+ var watch = Stopwatch.StartNew();
+
+ List<Post> posts = _db.Posts.All().ToList<Post>();
+ Console.WriteLine(posts.Count);
+ watch.Stop();
+ Console.WriteLine(watch.Elapsed);
+ }
+ }
+
+ public class Post
+ {
+ public int ID { get; set; }
+ public string Title { get; set; }
+ public string Content { get; set; }
+ public DateTime Created { get; set; }
+ }
+}
@@ -43,6 +43,7 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
+ <Compile Include="CastTask.cs" />
<Compile Include="FindAllByTask.cs" />
<Compile Include="FindByTask.cs" />
<Compile Include="IProfileTask.cs" />
View
@@ -12,9 +12,9 @@ class Program
{
static void Main(string[] args)
{
- ResetDatabase();
+ //ResetDatabase();
- new FindByTask().Run();
+ new CastTask().Run();
}
private static void ResetDatabase()
@@ -31,7 +31,7 @@ DECLARE @PostId AS INT
DECLARE @PostIdStr AS NVARCHAR(3)
DECLARE @Loop AS INT
SET @PostId = 1
-WHILE @PostId <= 100
+WHILE @PostId <= 2500
BEGIN
SET @PostIdStr = CAST(@PostId AS NVARCHAR(3))
INSERT INTO [dbo].[Post] ([Id], [Title], [Content], [Created]) VALUES (@PostId, 'Post ' + @PostIdStr, 'This is post number ' + @PostIdStr, GETDATE())
@@ -0,0 +1,58 @@
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using NUnit.Framework;
+
+namespace Simple.Data.InMemoryTest
+{
+ [TestFixture]
+ public class SimpleQueryConversionTests
+ {
+ [Test]
+ public void ShouldCastToList()
+ {
+ Database.UseMockAdapter(new InMemoryAdapter());
+ var db = Database.Open();
+ db.Test.Insert(Id: 1, Name: "Alice");
+ db.Test.Insert(Id: 2, Name: "Bob");
+ List<Person> records = db.Test.All();
+ Assert.IsNotNull(records);
+ Assert.AreEqual(2, records.Count);
+ }
+
+ [Test]
+ public void ShouldCastToPersonCollection()
+ {
+ Database.UseMockAdapter(new InMemoryAdapter());
+ var db = Database.Open();
+ db.Test.Insert(Id: 1, Name: "Alice");
+ db.Test.Insert(Id: 2, Name: "Bob");
+ PersonCollection records = db.Test.All();
+ Assert.IsNotNull(records);
+ Assert.AreEqual(2, records.Count);
+ }
+
+ [Test]
+ public void ShouldCastToIEnumerableOfPerson()
+ {
+ Database.UseMockAdapter(new InMemoryAdapter());
+ var db = Database.Open();
+ db.Test.Insert(Id: 1, Name: "Alice");
+ db.Test.Insert(Id: 2, Name: "Bob");
+ IEnumerable<Person> records = db.Test.All();
+ Assert.IsNotNull(records);
+ Assert.AreEqual(2, records.Count());
+ }
+ }
+
+ public class Person
+ {
+ public int Id { get; set; }
+ public string Name { get; set; }
+ }
+
+ public class PersonCollection : Collection<Person>
+ {
+
+ }
+}
View
@@ -106,9 +106,59 @@ public override bool TryConvert(ConvertBinder binder, out object result)
result = Cast<dynamic>();
return true;
}
+
+ var collectionType = binder.Type.GetInterface("ICollection`1");
+ if (collectionType != null)
+ {
+ if (TryConvertToGenericCollection(binder, out result, collectionType)) return true;
+ }
+
+ if (binder.Type.Name.Equals("IEnumerable`1"))
+ {
+ var genericArguments = binder.Type.GetGenericArguments();
+ var cast =
+ typeof (SimpleQuery).GetMethod("Cast").MakeGenericMethod(genericArguments);
+ result = cast.Invoke(this, null);
+ return true;
+ }
+
return base.TryConvert(binder, out result);
}
+ private bool TryConvertToGenericCollection(ConvertBinder binder, out object result, Type collectionType)
+ {
+ var genericArguments = collectionType.GetGenericArguments();
+ var enumerableConstructor =
+ binder.Type.GetConstructor(new[]
+ {
+ typeof (IEnumerable<>).MakeGenericType(
+ genericArguments)
+ });
+ if (enumerableConstructor != null)
+ {
+ var cast =
+ typeof (SimpleQuery).GetMethod("Cast").MakeGenericMethod(genericArguments);
+ result = Activator.CreateInstance(binder.Type, cast.Invoke(this, null));
+ return true;
+ }
+
+ var defaultConstructor = binder.Type.GetConstructor(new Type[0]);
+ if (defaultConstructor != null)
+ {
+ result = Activator.CreateInstance(binder.Type);
+ var add = binder.Type.GetMethod("Add", genericArguments);
+ var cast =
+ typeof (SimpleQuery).GetMethod("Cast").MakeGenericMethod(genericArguments);
+ foreach (var item in (IEnumerable) cast.Invoke(this, null))
+ {
+ add.Invoke(result, new[] {item});
+ }
+ return true;
+ }
+ result = null;
+ return false;
+ }
+
/// <summary>
/// Selects only the specified columns.
/// </summary>

0 comments on commit 590dd55

Please sign in to comment.