Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Adding StoredProcedure stuff to Ado adapter

  • Loading branch information...
commit b457655a2d12d1e6f9868870b699376a479181b0 1 parent 9af7a59
@markrendle authored
Showing with 291 additions and 76 deletions.
  1. +35 −0 Simple.Data.Ado/AdoAdapter.IAdapterWithFunctions.cs
  2. +1 −1  Simple.Data.Ado/AdoAdapter.cs
  3. +1 −1  Simple.Data.Ado/DataRecordExtensions.cs
  4. +37 −0 Simple.Data.Ado/Schema/Parameter.cs
  5. +34 −0 Simple.Data.Ado/Schema/StoredProcedure.cs
  6. +5 −1 Simple.Data.Ado/Schema/Table.cs
  7. +3 −0  Simple.Data.Ado/Simple.Data.Ado.csproj
  8. +2 −2 Simple.Data.BehaviourTest/DatabaseTest.cs
  9. +2 −2 Simple.Data.BehaviourTest/SchemaQualifiedTableTest.cs
  10. +2 −2 Simple.Data.BehaviourTest/TransactionTest.cs
  11. +1 −1  Simple.Data.Mocking.Test/XmlMockAdapterTest.cs
  12. +1 −1  Simple.Data.SqlTest/app.config
  13. +39 −0 Simple.Data.UnitTest/BinderHelperTest.cs
  14. +4 −4 Simple.Data.UnitTest/DynamicEnumerableTest.cs
  15. +4 −4 Simple.Data.UnitTest/DynamicRecordTest.cs
  16. +2 −1  Simple.Data.UnitTest/Simple.Data.UnitTest.csproj
  17. +10 −8 Simple.Data/BinderHelper.cs
  18. +12 −11 Simple.Data/Commands/ExecuteFunctionCommand.cs
  19. +3 −3 Simple.Data/Commands/FindAllByCommand.cs
  20. +2 −2 Simple.Data/Commands/FindAllCommand.cs
  21. +1 −1  Simple.Data/Commands/FindByCommand.cs
  22. +1 −1  Simple.Data/Commands/FindCommand.cs
  23. +1 −1  Simple.Data/Commands/UpdateCommand.cs
  24. +1 −1  Simple.Data/DynamicRecord.Dictionary`2.cs
  25. +1 −1  Simple.Data/DynamicTable.cs
  26. +13 −1 Simple.Data/Extensions/EnumerableExtensions.cs
  27. +6 −6 Simple.Data/Extensions/IDictionaryExtensions.cs
  28. +10 −0 Simple.Data/Extensions/StringExtensions.cs
  29. +1 −1  Simple.Data/HomogenizedKeyDictionary.cs
  30. +2 −2 Simple.Data/Simple.Data.csproj
  31. +8 −8 Simple.Data/{DynamicRecord.cs → SimpleRecord.cs}
  32. +46 −9 Simple.Data/{DynamicEnumerable.cs → SimpleResultSet.cs}
View
35 Simple.Data.Ado/AdoAdapter.IAdapterWithFunctions.cs
@@ -0,0 +1,35 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Simple.Data.Ado
+{
+ internal partial class AdoAdapter : IAdapterWithFunctions
+ {
+ public bool IsValidFunction(string functionName)
+ {
+ throw new NotImplementedException();
+ }
+
+ public FunctionReturnType GetReturnType(string functionName)
+ {
+ throw new NotImplementedException();
+ }
+
+ public object ExecuteScalar(string functionName, IEnumerable<KeyValuePair<string, object>> parameters)
+ {
+ throw new NotImplementedException();
+ }
+
+ public IEnumerable<IEnumerable<KeyValuePair<string, object>>> ExecuteResultSet(string functionName, IEnumerable<KeyValuePair<string, object>> parameters)
+ {
+ throw new NotImplementedException();
+ }
+
+ public IEnumerable<IEnumerable<IEnumerable<KeyValuePair<string, object>>>> ExecuteMultipleResultSets(string functionName, IEnumerable<KeyValuePair<string, object>> parameters)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
View
2  Simple.Data.Ado/AdoAdapter.cs
@@ -12,7 +12,7 @@
namespace Simple.Data.Ado
{
[Export("Ado", typeof(Adapter))]
- internal class AdoAdapter : Adapter, IAdapterWithRelation, IAdapterWithTransactions
+ internal partial class AdoAdapter : Adapter, IAdapterWithRelation, IAdapterWithTransactions
{
private IConnectionProvider _connectionProvider;
private DatabaseSchema _schema;
View
2  Simple.Data.Ado/DataRecordExtensions.cs
@@ -13,7 +13,7 @@ public static dynamic ToDynamicRecord(this IDataRecord dataRecord)
public static dynamic ToDynamicRecord(this IDataRecord dataRecord, string tableName, Database database)
{
- return new DynamicRecord(dataRecord.ToDictionary(), tableName, database);
+ return new SimpleRecord(dataRecord.ToDictionary(), tableName, database);
}
public static Dictionary<string, object> ToDictionary(this IDataRecord dataRecord)
View
37 Simple.Data.Ado/Schema/Parameter.cs
@@ -0,0 +1,37 @@
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Linq;
+using System.Text;
+
+namespace Simple.Data.Ado.Schema
+{
+ public class Parameter
+ {
+ private readonly string _name;
+ private readonly Type _type;
+ private readonly ParameterDirection _direction;
+
+ public Parameter(string name, Type type, ParameterDirection direction)
+ {
+ _name = name;
+ _direction = direction;
+ _type = type;
+ }
+
+ public ParameterDirection Direction
+ {
+ get { return _direction; }
+ }
+
+ public Type Type
+ {
+ get { return _type; }
+ }
+
+ public string Name
+ {
+ get { return _name; }
+ }
+ }
+}
View
34 Simple.Data.Ado/Schema/StoredProcedure.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Simple.Data.Extensions;
+
+namespace Simple.Data.Ado.Schema
+{
+ public class StoredProcedure
+ {
+ private readonly string _name;
+ private readonly string _schema;
+
+ public StoredProcedure(string name) : this(name, null)
+ {
+ }
+
+ public StoredProcedure(string name, string schema)
+ {
+ _name = name;
+ _schema = schema.NullIfWhitespace();
+ }
+
+ public string Schema
+ {
+ get { return _schema; }
+ }
+
+ public string Name
+ {
+ get { return _name; }
+ }
+ }
+}
View
6 Simple.Data.Ado/Schema/Table.cs
@@ -16,10 +16,14 @@ public class Table : IEquatable<Table>
private readonly Lazy<Key> _lazyPrimaryKey;
private readonly Lazy<ForeignKeyCollection> _lazyForeignKeys;
+ public Table(string name, TableType type) : this(name, null, type)
+ {
+ }
+
public Table(string name, string schema, TableType type)
{
_actualName = name;
- _schema = schema;
+ _schema = string.IsNullOrWhiteSpace(schema) ? null : schema;
_type = type;
}
View
3  Simple.Data.Ado/Simple.Data.Ado.csproj
@@ -87,7 +87,9 @@
<Compile Include="Schema\ForeignKeyCollection.cs" />
<Compile Include="Schema\ISchemaProvider.cs" />
<Compile Include="Schema\Key.cs" />
+ <Compile Include="Schema\Parameter.cs" />
<Compile Include="Schema\SchemaSpecificStringExtensions.cs" />
+ <Compile Include="Schema\StoredProcedure.cs" />
<Compile Include="Schema\Table.cs" />
<Compile Include="Schema\TableCollection.cs" />
<Compile Include="Schema\TableJoin.cs" />
@@ -104,6 +106,7 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
+ <Compile Include="AdoAdapter.IAdapterWithFunctions.cs" />
<None Include="app.config" />
<None Include="packages.config" />
<None Include="Properties\Settings.settings">
View
4 Simple.Data.BehaviourTest/DatabaseTest.cs
@@ -146,7 +146,7 @@ public void TestUpdateWithDynamicObject()
{
var mockDatabase = new MockDatabase();
dynamic database = CreateDatabase(mockDatabase);
- dynamic record = new DynamicRecord();
+ dynamic record = new SimpleRecord();
record.Id = 1;
record.Name = "Steve";
record.Age = 50;
@@ -162,7 +162,7 @@ public void TestUpdateByWithDynamicObject()
{
var mockDatabase = new MockDatabase();
dynamic database = CreateDatabase(mockDatabase);
- dynamic record = new DynamicRecord();
+ dynamic record = new SimpleRecord();
record.Id = 1;
record.Name = "Steve";
record.Age = 50;
View
4 Simple.Data.BehaviourTest/SchemaQualifiedTableTest.cs
@@ -145,7 +145,7 @@ public void TestUpdateWithDynamicObject()
{
var mockDatabase = new MockDatabase();
dynamic database = CreateDatabase(mockDatabase);
- dynamic record = new DynamicRecord();
+ dynamic record = new SimpleRecord();
record.Id = 1;
record.Name = "Steve";
record.Age = 50;
@@ -161,7 +161,7 @@ public void TestUpdateByWithDynamicObject()
{
var mockDatabase = new MockDatabase();
dynamic database = CreateDatabase(mockDatabase);
- dynamic record = new DynamicRecord();
+ dynamic record = new SimpleRecord();
record.Id = 1;
record.Name = "Steve";
record.Age = 50;
View
4 Simple.Data.BehaviourTest/TransactionTest.cs
@@ -90,7 +90,7 @@ public void TestUpdateWithDynamicObject()
{
var mockDatabase = new MockDatabase();
dynamic database = CreateDatabase(mockDatabase);
- dynamic record = new DynamicRecord();
+ dynamic record = new SimpleRecord();
record.Id = 1;
record.Name = "Steve";
record.Age = 50;
@@ -111,7 +111,7 @@ public void TestUpdateByWithDynamicObject()
{
var mockDatabase = new MockDatabase();
dynamic database = CreateDatabase(mockDatabase);
- dynamic record = new DynamicRecord();
+ dynamic record = new SimpleRecord();
record.Id = 1;
record.Name = "Steve";
record.Age = 50;
View
2  Simple.Data.Mocking.Test/XmlMockAdapterTest.cs
@@ -93,7 +93,7 @@ public void TestUpdateBy()
[Test]
public void TestUpdate()
{
- dynamic record = new DynamicRecord();
+ dynamic record = new SimpleRecord();
record.Id = 4;
record.Email = "quux";
Database.Default.Users.Update(record);
View
2  Simple.Data.SqlTest/app.config
@@ -4,7 +4,7 @@
</configSections>
<connectionStrings>
<add name="Simple.Data.SqlTest.Properties.Settings.ConnectionString"
- connectionString="Data Source=.\SQLSERVER2008;Initial Catalog=SimpleTest;Integrated Security=True"
+ connectionString="Data Source=.;Initial Catalog=SimpleTest;Integrated Security=True"
providerName="System.Data.SqlClient" />
</connectionStrings>
</configuration>
View
39 Simple.Data.UnitTest/BinderHelperTest.cs
@@ -0,0 +1,39 @@
+using System;
+using System.Collections.Generic;
+using System.Dynamic;
+using System.Linq;
+using System.Text;
+using Simple.Data.Extensions;
+using NUnit.Framework;
+
+namespace Simple.Data.UnitTest
+{
+ [TestFixture]
+ public class BinderHelperTest
+ {
+ [Test]
+ public void ArgumentsToDictionaryShouldNameNamelessArgumentsWithOrdinal()
+ {
+ var binder = new TestInvokeMemberBinder("Test", false, new CallInfo(2, "Foo"));
+ var actual = binder.NamedArgumentsToDictionary(new object[] {1, 2});
+ Assert.AreEqual(2, actual["Foo"]);
+ }
+ }
+
+ class TestInvokeMemberBinder : InvokeMemberBinder
+ {
+ public TestInvokeMemberBinder(string name, bool ignoreCase, CallInfo callInfo) : base(name, ignoreCase, callInfo)
+ {
+ }
+
+ public override DynamicMetaObject FallbackInvokeMember(DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion)
+ {
+ throw new NotImplementedException();
+ }
+
+ public override DynamicMetaObject FallbackInvoke(DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
View
8 Simple.Data.UnitTest/DynamicEnumerableTest.cs
@@ -12,7 +12,7 @@ public class DynamicEnumerableTest
[Test]
public void TestCast()
{
- dynamic test = new DynamicEnumerable(new[] {"Hello", "World"});
+ dynamic test = new SimpleResultSet(new[] {"Hello", "World"});
IEnumerable<string> strings = test.Cast<string>();
Assert.AreEqual(2, strings.Count());
}
@@ -20,7 +20,7 @@ public void TestCast()
[Test]
public void TestOfType()
{
- dynamic test = new DynamicEnumerable(new dynamic[] { "Hello", 1 });
+ dynamic test = new SimpleResultSet(new dynamic[] { "Hello", 1 });
IEnumerable<int> ints = test.OfType<int>();
Assert.AreEqual(1, ints.Count());
Assert.AreEqual(1, ints.Single());
@@ -30,7 +30,7 @@ public void TestOfType()
public void TestCastWithClass()
{
var dict = new Dictionary<string, object> {{"Name", "Bob"}};
- dynamic test = new DynamicEnumerable(new[] {new DynamicRecord(dict)});
+ dynamic test = new SimpleResultSet(new[] {new SimpleRecord(dict)});
IEnumerable<Foo> foos = test.Cast<Foo>();
Assert.AreEqual(1, foos.Count());
}
@@ -39,7 +39,7 @@ public void TestCastWithClass()
public void TestCastWithForeach()
{
var dict = new Dictionary<string, object> { { "Name", "Bob" } };
- dynamic test = new DynamicEnumerable(new[] { new DynamicRecord(dict) });
+ dynamic test = new SimpleResultSet(new[] { new SimpleRecord(dict) });
foreach (Foo foo in test)
{
Assert.AreEqual("Bob", foo.Name);
View
8 Simple.Data.UnitTest/DynamicRecordTest.cs
@@ -25,7 +25,7 @@ public void DynamicRecordDictionaryConstructorTest()
{ "Name", "Bob" },
{ "Age", 42 }
};
- dynamic target = new DynamicRecord(data);
+ dynamic target = new SimpleRecord(data);
Assert.AreEqual("Bob", target.Name);
Assert.AreEqual(42, target.Age);
}
@@ -36,7 +36,7 @@ public void DynamicRecordDictionaryConstructorTest()
[Test()]
public void DynamicRecordSetterTest()
{
- dynamic target = new DynamicRecord();
+ dynamic target = new SimpleRecord();
target.Name = "Bob";
Assert.AreEqual("Bob", target.Name);
}
@@ -44,7 +44,7 @@ public void DynamicRecordSetterTest()
[Test]
public void DynamicCastTest()
{
- dynamic target = new DynamicRecord();
+ dynamic target = new SimpleRecord();
target.Name = "Bob";
target.Age = 42;
@@ -56,7 +56,7 @@ public void DynamicCastTest()
[Test]
public void DynamicCastShouldReturnSameObjectOnSubsequentCalls()
{
- dynamic target = new DynamicRecord();
+ dynamic target = new SimpleRecord();
target.Name = "Bob";
target.Age = 42;
View
3  Simple.Data.UnitTest/Simple.Data.UnitTest.csproj
@@ -50,6 +50,7 @@
</CodeAnalysisDependentAssemblyPaths>
</ItemGroup>
<ItemGroup>
+ <Compile Include="BinderHelperTest.cs" />
<Compile Include="DataRecordExtensionsTest.cs" />
<Compile Include="DynamicEnumerableTest.cs" />
<Compile Include="DynamicRecordTest.cs" />
@@ -76,4 +77,4 @@
<Target Name="AfterBuild">
</Target>
-->
-</Project>
+</Project>
View
18 Simple.Data/BinderHelper.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
@@ -8,19 +9,20 @@ namespace Simple.Data
{
static class BinderHelper
{
- internal static Dictionary<string, object> NamedArgumentsToDictionary(this InvokeMemberBinder binder, IList<object> args)
+ internal static IDictionary<string, object> NamedArgumentsToDictionary(this InvokeMemberBinder binder, IList<object> args)
{
- var dict = new Dictionary<string, object>();
+ var dict = new Dictionary<string, object>() as ICollection<KeyValuePair<string,object>>;
- for (int i = 0; i < args.Count; i++)
+ var keyValuePairs = binder.CallInfo.ArgumentNames
+ .Reverse()
+ .Zip(args.Reverse(), (k, v) => new KeyValuePair<string, object>(k, v));
+
+ foreach (var pair in keyValuePairs)
{
- if (!string.IsNullOrWhiteSpace(binder.CallInfo.ArgumentNames[i]))
- {
- dict.Add(binder.CallInfo.ArgumentNames[i], args[i]);
- }
+ dict.Add(pair);
}
- return dict;
+ return dict as IDictionary<string,object>;
}
}
}
View
23 Simple.Data/Commands/ExecuteFunctionCommand.cs
@@ -3,6 +3,7 @@
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
+using Simple.Data.Extensions;
namespace Simple.Data.Commands
{
@@ -52,28 +53,28 @@ private object ConvertToSimpleTypes(object source)
}
}
- private static IEnumerable<DynamicEnumerable> ToMultipleResultSets(object source)
+ private static IEnumerable<SimpleResultSet> ToMultipleResultSets(object source)
{
- if (source == null) return Enumerable.Empty<DynamicEnumerable>();
+ if (source == null) return Enumerable.Empty<SimpleResultSet>();
var resultSets = source as IEnumerable<IEnumerable<IEnumerable<KeyValuePair<string, object>>>>;
if (resultSets == null) throw new InvalidOperationException("Adapter returned incorrect Type.");
return ToMultipleDynamicEnumerables(resultSets);
}
- private static IEnumerable<DynamicEnumerable> ToMultipleDynamicEnumerables(IEnumerable<IEnumerable<IEnumerable<KeyValuePair<string, object>>>> resultSets)
+ private static IEnumerable<SimpleResultSet> ToMultipleDynamicEnumerables(IEnumerable<IEnumerable<IEnumerable<KeyValuePair<string, object>>>> resultSets)
{
- return resultSets.Select(resultSet => new DynamicEnumerable(resultSet.Select(dict => new DynamicRecord(dict))));
+ return resultSets.Select(resultSet => new SimpleResultSet(resultSet.Select(dict => new SimpleRecord(dict))));
}
- private static DynamicEnumerable ToResultSet(object source)
+ private static SimpleResultSet ToResultSet(object source)
{
- if (source == null) return new DynamicEnumerable(Enumerable.Empty<dynamic>());
+ if (source == null) return new SimpleResultSet(Enumerable.Empty<dynamic>());
var dicts = source as IEnumerable<IEnumerable<KeyValuePair<string, object>>>;
if (dicts == null) throw new InvalidOperationException("Adapter returned incorrect Type.");
- return new DynamicEnumerable(dicts.Select(dict => new DynamicRecord(dict)));
+ return new SimpleResultSet(dicts.Select(dict => new SimpleRecord(dict)));
}
private Func<string, IEnumerable<KeyValuePair<string, object>>, object> GetFunc(FunctionReturnType resultType)
@@ -97,10 +98,10 @@ private static DynamicEnumerable ToResultSet(object source)
private IEnumerable<KeyValuePair<string,object>> MakeArguments()
{
- var argumentNamesWithDefaults =
- _argumentNames.Select((s, i) => string.IsNullOrWhiteSpace(s) ? i.ToString() : s);
- return _arguments.Zip(argumentNamesWithDefaults,
- (v, k) => new KeyValuePair<string, object>(k, v));
+ return _arguments.Reverse()
+ .Zip(_argumentNames.Reverse().ExtendInfinite(), (v, k) => new KeyValuePair<string, object>(k, v))
+ .Reverse()
+ .Select((kvp, i) => kvp.Key == null ? new KeyValuePair<string, object>(i.ToString(), kvp.Value) : kvp);
}
}
}
View
6 Simple.Data/Commands/FindAllByCommand.cs
@@ -15,9 +15,9 @@ public object Execute(DataStrategy dataStrategy, DynamicTable table, InvokeMembe
{
var criteria = ExpressionHelper.CriteriaDictionaryToExpression(table.GetQualifiedName(), MethodNameParser.ParseFromBinder(binder, args));
var data = dataStrategy.Find(table.GetQualifiedName(), criteria);
- return new DynamicEnumerable(data != null
- ? data.Select(dict => new DynamicRecord(dict, table.GetQualifiedName(), dataStrategy))
- : Enumerable.Empty<DynamicRecord>());
+ return new SimpleResultSet(data != null
+ ? data.Select(dict => new SimpleRecord(dict, table.GetQualifiedName(), dataStrategy))
+ : Enumerable.Empty<SimpleRecord>());
}
}
}
View
4 Simple.Data/Commands/FindAllCommand.cs
@@ -30,8 +30,8 @@ public bool IsCommandFor(string method)
/// <returns></returns>
public object Execute(DataStrategy dataStrategy, DynamicTable table, InvokeMemberBinder binder, object[] args)
{
- return new DynamicEnumerable(dataStrategy.Find(table.GetQualifiedName(), null)
- .Select(dict => new DynamicRecord(dict, table.GetQualifiedName(), dataStrategy)));
+ return new SimpleResultSet(dataStrategy.Find(table.GetQualifiedName(), null)
+ .Select(dict => new SimpleRecord(dict, table.GetQualifiedName(), dataStrategy)));
}
}
}
View
2  Simple.Data/Commands/FindByCommand.cs
@@ -16,7 +16,7 @@ public object Execute(DataStrategy dataStrategy, DynamicTable table, InvokeMembe
{
var criteriaExpression = ExpressionHelper.CriteriaDictionaryToExpression(table.GetQualifiedName(), MethodNameParser.ParseFromBinder(binder, args));
var data = dataStrategy.Find(table.GetQualifiedName(), criteriaExpression).FirstOrDefault();
- return data != null ? new DynamicRecord(data, table.GetQualifiedName(), dataStrategy) : null;
+ return data != null ? new SimpleRecord(data, table.GetQualifiedName(), dataStrategy) : null;
}
}
}
View
2  Simple.Data/Commands/FindCommand.cs
@@ -33,7 +33,7 @@ public object Execute(DataStrategy dataStrategy, DynamicTable table, InvokeMembe
if (args.Length == 1 && args[0] is SimpleExpression)
{
var data = dataStrategy.Find(table.GetQualifiedName(), (SimpleExpression)args[0]).FirstOrDefault();
- return data != null ? new DynamicRecord(data, table.GetQualifiedName(), dataStrategy) : null;
+ return data != null ? new SimpleRecord(data, table.GetQualifiedName(), dataStrategy) : null;
}
return null;
View
2  Simple.Data/Commands/UpdateCommand.cs
@@ -54,7 +54,7 @@ internal static object UpdateByKeyFields(string tableName, DataStrategy dataStra
private static IDictionary<string,object> ObjectToDictionary(object obj)
{
- var dynamicRecord = obj as DynamicRecord;
+ var dynamicRecord = obj as SimpleRecord;
if (dynamicRecord != null)
{
return new Dictionary<string, object>(dynamicRecord);
View
2  Simple.Data/DynamicRecord.Dictionary`2.cs
@@ -5,7 +5,7 @@
namespace Simple.Data
{
- sealed partial class DynamicRecord : IDictionary<string, object>
+ sealed partial class SimpleRecord : IDictionary<string, object>
{
IEnumerator<KeyValuePair<string, object>> IEnumerable<KeyValuePair<string, object>>.GetEnumerator()
{
View
2  Simple.Data/DynamicTable.cs
@@ -105,7 +105,7 @@ internal string GetQualifiedName()
private IEnumerable<dynamic> GetAll()
{
- return _dataStrategy.Find(_tableName, null).Select(dict => new DynamicRecord(dict, _tableName, _dataStrategy));
+ return _dataStrategy.Find(_tableName, null).Select(dict => new SimpleRecord(dict, _tableName, _dataStrategy));
}
}
}
View
14 Simple.Data/Extensions/EnumerableExtensions.cs
@@ -71,7 +71,19 @@ public static IEnumerable<T> SkipLast<T>(this IEnumerable<T> source)
yield return Tuple.Create(buffer, enumerator.Current);
buffer = enumerator.Current;
}
-
+ }
+
+ public static IEnumerable<T> ExtendInfinite<T>(this IEnumerable<T> source)
+ {
+ foreach (var item in source)
+ {
+ yield return item;
+ }
+
+ while (true)
+ {
+ yield return default(T);
+ }
}
}
}
View
12 Simple.Data/Extensions/IDictionaryExtensions.cs
@@ -7,19 +7,19 @@ namespace Simple.Data.Extensions
{
internal static class DictionaryExtensions
{
- public static DynamicRecord ToDynamicRecord(this IDictionary<string, object> dictionary)
+ public static SimpleRecord ToDynamicRecord(this IDictionary<string, object> dictionary)
{
- return dictionary == null ? null : new DynamicRecord(dictionary);
+ return dictionary == null ? null : new SimpleRecord(dictionary);
}
- public static DynamicRecord ToDynamicRecord(this IDictionary<string, object> dictionary, string tableName)
+ public static SimpleRecord ToDynamicRecord(this IDictionary<string, object> dictionary, string tableName)
{
- return dictionary == null ? null : new DynamicRecord(dictionary, tableName);
+ return dictionary == null ? null : new SimpleRecord(dictionary, tableName);
}
- public static DynamicRecord ToDynamicRecord(this IDictionary<string, object> dictionary, string tableName, DataStrategy dataStrategy)
+ public static SimpleRecord ToDynamicRecord(this IDictionary<string, object> dictionary, string tableName, DataStrategy dataStrategy)
{
- return dictionary == null ? null : new DynamicRecord(dictionary, tableName, dataStrategy);
+ return dictionary == null ? null : new SimpleRecord(dictionary, tableName, dataStrategy);
}
}
}
View
10 Simple.Data/Extensions/StringExtensions.cs
@@ -37,5 +37,15 @@ public static bool IsAllUpperCase(this string str)
{
return !str.Any(c => char.IsLower(c));
}
+
+ public static string NullIfWhitespace(this string str)
+ {
+ return string.IsNullOrWhiteSpace(str) ? null : str;
+ }
+
+ public static string OrDefault(this string str, string defaultValue)
+ {
+ return str ?? defaultValue;
+ }
}
}
View
2  Simple.Data/HomogenizedKeyDictionary.cs
@@ -8,7 +8,7 @@
namespace Simple.Data
{
/// <summary>
- /// Stores data internally for <see cref="DynamicRecord"/>.
+ /// Stores data internally for <see cref="SimpleRecord"/>.
/// </summary>
internal class HomogenizedKeyDictionary : IDictionary<string,object>
{
View
4 Simple.Data/Simple.Data.csproj
@@ -68,7 +68,7 @@
<Compile Include="ConcreteObject.cs" />
<Compile Include="ConcreteTypeCreator.cs" />
<Compile Include="Database.Obsolete.cs" />
- <Compile Include="DynamicEnumerable.cs" />
+ <Compile Include="SimpleResultSet.cs" />
<Compile Include="DynamicSchema.cs" />
<Compile Include="Extensions\BinderExtensions.cs" />
<Compile Include="Extensions\IDictionaryExtensions.cs" />
@@ -80,7 +80,7 @@
<Compile Include="Commands\FindCommand.cs" />
<Compile Include="Database.cs" />
<Compile Include="DatabaseOpener.cs" />
- <Compile Include="DynamicRecord.cs" />
+ <Compile Include="SimpleRecord.cs" />
<Compile Include="Extensions\DynamicStringExtensions.cs" />
<Compile Include="DynamicTable.cs" />
<Compile Include="DynamicReference.cs" />
View
16 Simple.Data/DynamicRecord.cs → Simple.Data/SimpleRecord.cs
@@ -8,34 +8,34 @@
namespace Simple.Data
{
- public partial class DynamicRecord : DynamicObject
+ public partial class SimpleRecord : DynamicObject
{
private readonly ConcreteObject _concreteObject = new ConcreteObject();
private readonly HomogenizedKeyDictionary _data;
private readonly DataStrategy _database;
private readonly string _tableName;
- public DynamicRecord()
+ public SimpleRecord()
{
_data = new HomogenizedKeyDictionary();
}
- public DynamicRecord(Database database)
+ public SimpleRecord(Database database)
{
_data = new HomogenizedKeyDictionary();
_database = database;
}
- internal DynamicRecord(IEnumerable<KeyValuePair<string, object>> data) : this(data, null)
+ internal SimpleRecord(IEnumerable<KeyValuePair<string, object>> data) : this(data, null)
{
}
- internal DynamicRecord(IEnumerable<KeyValuePair<string, object>> data, string tableName)
+ internal SimpleRecord(IEnumerable<KeyValuePair<string, object>> data, string tableName)
: this(data, tableName, null)
{
}
- internal DynamicRecord(IEnumerable<KeyValuePair<string, object>> data, string tableName, DataStrategy dataStrategy)
+ internal SimpleRecord(IEnumerable<KeyValuePair<string, object>> data, string tableName, DataStrategy dataStrategy)
{
_tableName = tableName;
_database = dataStrategy;
@@ -55,11 +55,11 @@ public override bool TryGetMember(GetMemberBinder binder, out object result)
var relatedRows = relatedAdapter.FindRelated(_tableName, _data, binder.Name);
if (relatedRows.Count() == 1 && !binder.Name.IsPlural())
{
- result = new DynamicRecord(relatedRows.Single(), binder.Name, _database);
+ result = new SimpleRecord(relatedRows.Single(), binder.Name, _database);
}
else
{
- result = new DynamicEnumerable(relatedRows.Select(dict => new DynamicRecord(dict, binder.Name, _database)));
+ result = new SimpleResultSet(relatedRows.Select(dict => new SimpleRecord(dict, binder.Name, _database)));
}
return true;
}
View
55 Simple.Data/DynamicEnumerable.cs → Simple.Data/SimpleResultSet.cs
@@ -9,23 +9,36 @@
namespace Simple.Data
{
- public sealed class DynamicEnumerable : DynamicObject, IEnumerable
+ public sealed class SimpleResultSet : DynamicObject, IEnumerable
{
- private readonly IEnumerable<dynamic> _enumerable;
+ private readonly IEnumerable<IEnumerable<dynamic>> _sources;
+ private readonly IEnumerator<IEnumerable<dynamic>> _sourceEnumerator;
+ private bool _hasCurrent;
- public DynamicEnumerable(IEnumerable<dynamic> source)
+ public SimpleResultSet(params IEnumerable<dynamic>[] sources) : this (sources.AsEnumerable())
{
- _enumerable = source;
+ }
+
+ public SimpleResultSet(IEnumerable<IEnumerable<dynamic>> sources)
+ {
+ _sources = sources;
+ _sourceEnumerator = _sources.GetEnumerator();
+ _hasCurrent = _sourceEnumerator.MoveNext();
+ }
+
+ public bool MoveNext()
+ {
+ return _hasCurrent = (_hasCurrent && _sourceEnumerator.MoveNext());
}
public IEnumerable<T> Cast<T>()
{
- return _enumerable.Select(item => (T) item);
+ return _sourceEnumerator.Current.Select(item => (T) item);
}
public IEnumerable<T> OfType<T>()
{
- foreach (var item in _enumerable)
+ foreach (var item in _sourceEnumerator.Current)
{
bool success = true;
T cast;
@@ -47,12 +60,12 @@ public IEnumerable<T> OfType<T>()
public IList<dynamic> ToList()
{
- return _enumerable.ToList();
+ return _sourceEnumerator.Current.ToList();
}
public dynamic[] ToArray()
{
- return _enumerable.ToArray();
+ return _sourceEnumerator.Current.ToArray();
}
public IList<T> ToList<T>()
@@ -74,7 +87,7 @@ public T[] ToArray<T>()
/// <filterpriority>1</filterpriority>
public IEnumerator GetEnumerator()
{
- return new DynamicEnumerator(_enumerable);
+ return new DynamicEnumerator(_sourceEnumerator.Current);
}
public override bool TryConvert(ConvertBinder binder, out object result)
@@ -138,5 +151,29 @@ public object Current
get { return _enumerator.Current; }
}
}
+
+ /// <summary>
+ /// Creates a single-set <see cref="SimpleResultSet"/> from the specified source.
+ /// </summary>
+ /// <param name="source">The source.</param>
+ public static SimpleResultSet Create(IEnumerable<IEnumerable<KeyValuePair<string,object>>> source)
+ {
+ var q = from dict in source
+ select new SimpleRecord(dict);
+ return new SimpleResultSet(q);
+ }
+
+ /// <summary>
+ /// Creates a multi-set <see cref="SimpleResultSet"/> from the specified sources.
+ /// </summary>
+ /// <param name="sources">The sources.</param>
+ /// <returns></returns>
+ public static SimpleResultSet Create(IEnumerable<IEnumerable<IEnumerable<KeyValuePair<string, object>>>> sources)
+ {
+ var q = from source in sources
+ select from dict in source
+ select new SimpleRecord(dict);
+ return new SimpleResultSet(q);
+ }
}
}
Please sign in to comment.
Something went wrong with that request. Please try again.