Skip to content

Commit e8f513a

Browse files
committed
Mammoth refactoring and defer methods to Adapter
1 parent 4fd06ca commit e8f513a

25 files changed

Lines changed: 508 additions & 283 deletions

PerformanceTestConsole/Program.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ public void Run(int iterations)
171171
var tests = new Tests();
172172
var simpleDb = Simple.Data.Database.OpenConnection(Program.ConnectionString);
173173
SqlConnection connection = Program.GetOpenConnection();
174-
((AdoAdapter) simpleDb.GetAdapter()).UseSharedConnection(connection);
174+
simpleDb.UseSharedConnection(connection);
175175
simpleDb.Posts.FindById(1);
176176
tests.Add(id => simpleDb.Posts.FindById(id), "Dynamic Simple.Data Query");
177177

Simple.Data.Ado/AdoAdapter.IAdapterWithFunctions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public partial class AdoAdapter : IAdapterWithFunctions
1313

1414
public bool IsValidFunction(string functionName)
1515
{
16-
return _connectionProvider.SupportsStoredProcedures && _schema.FindProcedure(functionName) != null;
16+
return _connectionProvider.SupportsStoredProcedures && _schema.IsProcedure(functionName);
1717
}
1818

1919
public IEnumerable<ResultSet> Execute(string functionName, IDictionary<string, object> parameters)

Simple.Data.Ado/Schema/DatabaseSchema.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,11 @@ public RelationType GetRelationType(string fromTableName, string toTableName)
129129
if (fromTable.GetDetail(toTableName) != null) return RelationType.OneToMany;
130130
return RelationType.None;
131131
}
132+
133+
public bool IsProcedure(string procedureName)
134+
{
135+
return _lazyProcedures.Value.IsProcedure(procedureName);
136+
}
132137
}
133138

134139
public enum RelationType

Simple.Data.Ado/Schema/ProcedureCollection.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,19 @@ public Procedure Find(string procedureName)
4545
return procedure;
4646
}
4747

48+
public bool IsProcedure(string procedureName)
49+
{
50+
if (procedureName.Contains('.'))
51+
{
52+
var schemaDotprocedure = procedureName.Split('.');
53+
if (schemaDotprocedure.Length != 2) throw new InvalidOperationException("Could not resolve qualified procedure name.");
54+
return Find(schemaDotprocedure[1], schemaDotprocedure[0]) != null;
55+
}
56+
return (FindprocedureWithName(procedureName.Homogenize())
57+
?? FindprocedureWithPluralName(procedureName.Homogenize())
58+
?? FindprocedureWithSingularName(procedureName.Homogenize())) != null;
59+
}
60+
4861
/// <summary>
4962
/// Finds the procedure with a name most closely matching the specified procedure name.
5063
/// This method will try an exact match first, then a case-insensitve search, then a pluralized or singular version.
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
6+
namespace Simple.Data
7+
{
8+
using System.Dynamic;
9+
using System.Reflection;
10+
11+
internal class AdapterMethodDynamicInvoker
12+
{
13+
private readonly Adapter _adapter;
14+
15+
public AdapterMethodDynamicInvoker(Adapter adapter)
16+
{
17+
_adapter = adapter;
18+
}
19+
20+
public bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
21+
{
22+
var adapterMethods = _adapter.GetType().GetMethods().Where(m => m.Name == binder.Name).ToList();
23+
24+
foreach (var method in adapterMethods)
25+
{
26+
var parameters = method.GetParameters().ToArray();
27+
if (parameters.Any(p => p.RawDefaultValue != DBNull.Value) && binder.CallInfo.ArgumentNames.Any(s => !string.IsNullOrWhiteSpace(s)))
28+
{
29+
if (TryInvokeMemberWithNamedParameters(binder, args, out result, method, parameters))
30+
{
31+
return true;
32+
}
33+
}
34+
else
35+
{
36+
if (AreCompatible(parameters, args))
37+
{
38+
result = method.Invoke(_adapter, args);
39+
return true;
40+
}
41+
}
42+
}
43+
44+
result = null;
45+
return false;
46+
}
47+
48+
private bool TryInvokeMemberWithNamedParameters(InvokeMemberBinder binder, object[] args, out object result,
49+
MethodInfo method, ParameterInfo[] parameters)
50+
{
51+
var fixedArgs = new List<object>();
52+
for (int i = 0; i < parameters.Length; i++)
53+
{
54+
if (parameters[i].RawDefaultValue == DBNull.Value)
55+
{
56+
fixedArgs.Add(args[i]);
57+
}
58+
else
59+
{
60+
var index = binder.CallInfo.ArgumentNames.IndexOf(parameters[i].Name);
61+
if (index > -1)
62+
{
63+
if (!parameters[i].ParameterType.IsInstanceOfType(args[index]))
64+
{
65+
result = null;
66+
return false;
67+
}
68+
}
69+
else
70+
{
71+
fixedArgs.Add(parameters[i].RawDefaultValue);
72+
}
73+
}
74+
}
75+
76+
result = method.Invoke(_adapter, fixedArgs.ToArray());
77+
return true;
78+
}
79+
80+
private static bool AreCompatible(IList<ParameterInfo> parameters, IList<object> args)
81+
{
82+
if (parameters.Count != args.Count) return false;
83+
for (int i = 0; i < parameters.Count; i++)
84+
{
85+
if (ReferenceEquals(args[i], null)) return !parameters[i].ParameterType.IsValueType;
86+
if (!parameters[i].ParameterType.IsInstanceOfType(args[i])) return false;
87+
}
88+
89+
return true;
90+
}
91+
}
92+
}

Simple.Data/Commands/DeleteAllCommand.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@ public object Execute(DataStrategy dataStrategy, DynamicTable table, InvokeMembe
1717

1818
if (args.Length == 0)
1919
{
20-
deletedCount = dataStrategy.Delete(table.GetQualifiedName(), new SimpleEmptyExpression());
20+
deletedCount = dataStrategy.Run.Delete(table.GetQualifiedName(), new SimpleEmptyExpression());
2121
}
2222

2323
if (args.Length == 1 && args[0] is SimpleExpression)
2424
{
25-
deletedCount = dataStrategy.Delete(table.GetQualifiedName(), (SimpleExpression)args[0]);
25+
deletedCount = dataStrategy.Run.Delete(table.GetQualifiedName(), (SimpleExpression)args[0]);
2626
}
2727

2828
return deletedCount.ResultSetFromModifiedRowCount();

Simple.Data/Commands/DeleteByCommand.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public bool IsCommandFor(string method)
1616
public object Execute(DataStrategy dataStrategy, DynamicTable table, InvokeMemberBinder binder, object[] args)
1717
{
1818
SimpleExpression criteriaExpression = GetCriteriaExpression(binder, args, table);
19-
return dataStrategy.Delete(table.GetQualifiedName(), criteriaExpression);
19+
return dataStrategy.Run.Delete(table.GetQualifiedName(), criteriaExpression);
2020
}
2121

2222
public object Execute(DataStrategy dataStrategy, SimpleQuery query, InvokeMemberBinder binder, object[] args)

Simple.Data/Commands/FindByCommand.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ public object Execute(DataStrategy dataStrategy, DynamicTable table, InvokeMembe
8080
var criteriaExpression = ExpressionHelper.CriteriaDictionaryToExpression(table.GetQualifiedName(),
8181
CreateCriteriaDictionary(binder,
8282
args));
83-
var data = dataStrategy.FindOne(table.GetQualifiedName(), criteriaExpression);
83+
var data = dataStrategy.Run.FindOne(table.GetQualifiedName(), criteriaExpression);
8484
return data != null ? new SimpleRecord(data, table.GetQualifiedName(), dataStrategy) : null;
8585
}
8686

Simple.Data/Commands/FindCommand.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public object Execute(DataStrategy dataStrategy, DynamicTable table, InvokeMembe
3232
{
3333
if (args.Length == 1 && args[0] is SimpleExpression)
3434
{
35-
var data = dataStrategy.FindOne(table.GetQualifiedName(), (SimpleExpression)args[0]);
35+
var data = dataStrategy.Run.FindOne(table.GetQualifiedName(), (SimpleExpression)args[0]);
3636
return data != null ? new SimpleRecord(data, table.GetQualifiedName(), dataStrategy) : null;
3737
}
3838

Simple.Data/Commands/GetCommand.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public bool IsCommandFor(string method)
1717

1818
public object Execute(DataStrategy dataStrategy, DynamicTable table, InvokeMemberBinder binder, object[] args)
1919
{
20-
var result = dataStrategy.Get(table.GetName(), args);
20+
var result = dataStrategy.Run.Get(table.GetName(), args);
2121
if (result == null || result.Count == 0) return null;
2222
return binder.Name.Equals("get", StringComparison.OrdinalIgnoreCase)
2323
? new SimpleRecord(result, table.GetQualifiedName(), dataStrategy)

0 commit comments

Comments
 (0)