diff --git a/.gitignore b/.gitignore
index 257b555e..3c1f23a1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,7 @@ obj
bin
deploy
*.csproj.user
+*.DotSettings.user
*.suo
*.cache
*.nupkg
@@ -21,6 +22,22 @@ NDependOut
*.dotCover
*_mm_cache.bin
Simple.Data.sln.DotSettings.user
+Simple.Data.sln.DotSettings
Simple.Data/Simple.Data.idc
-.DS_Store
-mono-release-*
+.DS_Store
+mono-release-*
+*ncrunch*
+MediumTrustApp
+nohup.out
+packages/EntityFramework.5.0.0/
+packages/Microsoft.AspNet.Mvc.3.0.20105.1/
+packages/Microsoft.AspNet.Providers.Core.1.1/
+packages/Microsoft.AspNet.Providers.LocalDB.1.1/
+packages/Microsoft.AspNet.Razor.1.0.20105.408/
+packages/Microsoft.AspNet.WebPages.1.0.20105.408/
+packages/Microsoft.Web.Infrastructure.1.0.0.0/
+packages/Modernizr.2.5.3/
+packages/jQuery.1.7.1.1/
+packages/jQuery.UI.Combined.1.8.20.1/
+packages/jQuery.Validation.1.9.0.1/
+Simple.Data.sln.ide
diff --git a/Assemblies/Microsoft.SqlServer.Types.dll b/Assemblies/Microsoft.SqlServer.Types.dll
new file mode 100644
index 00000000..a4d5a777
Binary files /dev/null and b/Assemblies/Microsoft.SqlServer.Types.dll differ
diff --git a/CommonAssemblyInfo.cs b/CommonAssemblyInfo.cs
index a1e7751d..3be7ef1c 100644
--- a/CommonAssemblyInfo.cs
+++ b/CommonAssemblyInfo.cs
@@ -19,6 +19,6 @@
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
-[assembly: AssemblyVersion("1.0.0.1")]
-[assembly: AssemblyFileVersion("1.0.0.1")]
+[assembly: AssemblyVersion("0.18.3.1")]
+[assembly: AssemblyFileVersion("0.18.3.1")]
diff --git a/PerformanceTestConsole/Program.cs b/PerformanceTestConsole/Program.cs
index 654cbc75..c7fad05d 100644
--- a/PerformanceTestConsole/Program.cs
+++ b/PerformanceTestConsole/Program.cs
@@ -171,7 +171,7 @@ public void Run(int iterations)
var tests = new Tests();
var simpleDb = Simple.Data.Database.OpenConnection(Program.ConnectionString);
SqlConnection connection = Program.GetOpenConnection();
- ((AdoAdapter) simpleDb.GetAdapter()).UseSharedConnection(connection);
+ simpleDb.UseSharedConnection(connection);
simpleDb.Posts.FindById(1);
tests.Add(id => simpleDb.Posts.FindById(id), "Dynamic Simple.Data Query");
diff --git a/PerformanceTestConsole/app.config b/PerformanceTestConsole/app.config
new file mode 100644
index 00000000..5b242640
--- /dev/null
+++ b/PerformanceTestConsole/app.config
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ProfilingApp/CastTask.cs b/ProfilingApp/CastTask.cs
new file mode 100644
index 00000000..c24ce65d
--- /dev/null
+++ b/ProfilingApp/CastTask.cs
@@ -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 posts = _db.Posts.All().ToList();
+ 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; }
+ }
+}
\ No newline at end of file
diff --git a/ProfilingApp/ProfilingApp.csproj b/ProfilingApp/ProfilingApp.csproj
index dea6f333..9c233236 100644
--- a/ProfilingApp/ProfilingApp.csproj
+++ b/ProfilingApp/ProfilingApp.csproj
@@ -43,6 +43,7 @@
+
diff --git a/ProfilingApp/Program.cs b/ProfilingApp/Program.cs
index 94b0b205..2ff45c74 100644
--- a/ProfilingApp/Program.cs
+++ b/ProfilingApp/Program.cs
@@ -12,9 +12,9 @@ class Program
{
static void Main(string[] args)
{
- ResetDatabase();
+ //ResetDatabase();
- new FindByTask().Run();
+ new CastTask().Run();
}
private static void ResetDatabase()
diff --git a/ProfilingApp/Resources/DatabaseResetSql.txt b/ProfilingApp/Resources/DatabaseResetSql.txt
index 9242624e..892b6a0a 100644
--- a/ProfilingApp/Resources/DatabaseResetSql.txt
+++ b/ProfilingApp/Resources/DatabaseResetSql.txt
@@ -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())
diff --git a/README.md b/README.md
index d88f7e0f..ddaac9b5 100644
--- a/README.md
+++ b/README.md
@@ -28,7 +28,7 @@ why not just write
public User FindUserByEmail(string email)
{
- return Database.Open().Users.FindByEmail(email);
+ return Database.Open().Users.FindAllByEmail(email).FirstOrDefault();
}
and take the rest of the morning off?
@@ -63,7 +63,7 @@ If you'd like to create an adapter or provider and need some help to get started
## Resources
* Simple.Data can be installed from [NuGet](http://nuget.org/)
* Find more information in [the wiki](https://github.com/markrendle/Simple.Data/wiki)
-* [Documentation!](http://simplefx.org/simpledata/docs/)
+* [Documentation!](http://simplefx.org/simpledata/docs/) (and here is the [SimpleFx Github Project](https://github.com/simplefx/simplefx.github.com) if you want to help us improve the documentation)
* Ask questions or report issues on [the mailing list](http://groups.google.com/group/simpledata)
* Follow [@markrendle on Twitter](http://twitter.com/markrendle) for updates
* Check out [my blog](http://blog.markrendle.net/) for the latest news
diff --git a/Simple.Data.Ado.Test/ConnectionModifierTest.cs b/Simple.Data.Ado.Test/ConnectionModifierTest.cs
new file mode 100644
index 00000000..540f8e46
--- /dev/null
+++ b/Simple.Data.Ado.Test/ConnectionModifierTest.cs
@@ -0,0 +1,152 @@
+using System.Data;
+using NUnit.Framework;
+
+namespace Simple.Data.Ado.Test
+{
+ using System;
+
+ [TestFixture]
+ public class ConnectionModifierTest
+ {
+ [Test]
+ public void ModifiesConnection()
+ {
+ var adapter = new AdoAdapter(new StubConnectionProvider());
+ adapter.SetConnectionModifier(c => new FooConnection(c));
+ Assert.IsInstanceOf(adapter.CreateConnection());
+ }
+
+ [Test]
+ public void ClearsConnection()
+ {
+ var adapter = new AdoAdapter(new StubConnectionProvider());
+ adapter.SetConnectionModifier(c => new FooConnection(c));
+ Assert.IsInstanceOf(adapter.CreateConnection());
+ adapter.ClearConnectionModifier();
+ Assert.IsNotInstanceOf(adapter.CreateConnection());
+ }
+
+ [Test]
+ public void ConnectionCreatedEventFires()
+ {
+ bool fired = false;
+ EventHandler handler = (o, e) => { fired = true; };
+ AdoAdapter.ConnectionCreated += handler;
+ var adapter = new AdoAdapter(new StubConnectionProvider());
+ var connection = adapter.CreateConnection();
+ AdoAdapter.ConnectionCreated -= handler;
+ Assert.True(fired);
+ }
+
+ [Test]
+ public void ConnectionCreatedCanOverrideConnection()
+ {
+ EventHandler handler = (o, e) => e.OverrideConnection(new BarConnection(e.Connection));
+ AdoAdapter.ConnectionCreated += handler;
+ var adapter = new AdoAdapter(new StubConnectionProvider());
+ var connection = adapter.CreateConnection();
+ Assert.IsInstanceOf(connection);
+ AdoAdapter.ConnectionCreated -= handler;
+ }
+
+ private class FooConnection : IDbConnection
+ {
+ private readonly IDbConnection _wrapped;
+
+ public FooConnection(IDbConnection wrapped)
+ {
+ _wrapped = wrapped;
+ }
+
+ public void Dispose()
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public IDbTransaction BeginTransaction()
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public IDbTransaction BeginTransaction(IsolationLevel il)
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public void Close()
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public void ChangeDatabase(string databaseName)
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public IDbCommand CreateCommand()
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public void Open()
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public string ConnectionString { get; set; }
+ public int ConnectionTimeout { get; private set; }
+ public string Database { get; private set; }
+ public ConnectionState State { get; private set; }
+ }
+
+ private class BarConnection : IDbConnection
+ {
+ private readonly IDbConnection _wrapped;
+
+ public BarConnection(IDbConnection wrapped)
+ {
+ _wrapped = wrapped;
+ }
+
+ public void Dispose()
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public IDbTransaction BeginTransaction()
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public IDbTransaction BeginTransaction(IsolationLevel il)
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public void Close()
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public void ChangeDatabase(string databaseName)
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public IDbCommand CreateCommand()
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public void Open()
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public string ConnectionString { get; set; }
+ public int ConnectionTimeout { get; private set; }
+ public string Database { get; private set; }
+ public ConnectionState State { get; private set; }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Simple.Data.Ado.Test/Properties/AssemblyInfo.cs b/Simple.Data.Ado.Test/Properties/AssemblyInfo.cs
index 9b49bbae..e8f0789d 100644
--- a/Simple.Data.Ado.Test/Properties/AssemblyInfo.cs
+++ b/Simple.Data.Ado.Test/Properties/AssemblyInfo.cs
@@ -1,6 +1,7 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
+using Simple.Data.Ado.Test;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
@@ -34,3 +35,5 @@
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
+
+[assembly: TestProviderAssembly]
\ No newline at end of file
diff --git a/Simple.Data.Ado.Test/ProviderHelperTest.cs b/Simple.Data.Ado.Test/ProviderHelperTest.cs
index 7c905a1f..a5af8079 100644
--- a/Simple.Data.Ado.Test/ProviderHelperTest.cs
+++ b/Simple.Data.Ado.Test/ProviderHelperTest.cs
@@ -1,109 +1,118 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using NUnit.Framework;
-using System.Data;
-using Simple.Data.Ado.Schema;
-using System.ComponentModel.Composition;
-
-namespace Simple.Data.Ado.Test
-{
- [TestFixture]
- public class ProviderHelperTest
- {
- [Test]
- public void ShouldNotRequestExportableTypeFromServiceProvider()
- {
- var helper = new ProviderHelper();
- var connectionProvider = new StubConnectionAndServiceProvider();
- var actual = helper.GetCustomProvider(connectionProvider);
- Assert.IsNull(connectionProvider.RequestedServiceType);
- }
-
- [Test]
- public void ShouldRequestNonExportedTypeFromServiceProvider()
- {
- var helper = new ProviderHelper();
- var connectionProvider = new StubConnectionAndServiceProvider();
- var actual = helper.GetCustomProvider(connectionProvider);
- Assert.AreEqual(typeof(IQueryPager), connectionProvider.RequestedServiceType);
- }
-
- [Test]
- public void ShouldReturnNonExportedTypeFromServiceProvider()
- {
- var helper = new ProviderHelper();
- var connectionProvider = new StubConnectionAndServiceProvider();
- var actual = helper.GetCustomProvider(connectionProvider);
- Assert.IsInstanceOf(typeof(IQueryPager), actual);
- }
-
- public class StubConnectionAndServiceProvider : IConnectionProvider, IServiceProvider
- {
- public void SetConnectionString(string connectionString)
- {
- throw new NotImplementedException();
- }
-
- public IDbConnection CreateConnection()
- {
- throw new NotImplementedException();
- }
-
- public ISchemaProvider GetSchemaProvider()
- {
- throw new NotImplementedException();
- }
-
- public string ConnectionString
- {
- get { throw new NotImplementedException(); }
- }
-
- public bool SupportsCompoundStatements
- {
- get { throw new NotImplementedException(); }
- }
-
- public string GetIdentityFunction()
- {
- throw new NotImplementedException();
- }
-
- public bool SupportsStoredProcedures
- {
- get { throw new NotImplementedException(); }
- }
-
- public IProcedureExecutor GetProcedureExecutor(AdoAdapter adapter, ObjectName procedureName)
- {
- throw new NotImplementedException();
- }
-
- public Type RequestedServiceType { get; private set; }
- public Object GetService(Type serviceType)
- {
- this.RequestedServiceType = serviceType;
- return new StubQueryPager();
- }
- }
-
- public class StubQueryPager : IQueryPager
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using NUnit.Framework;
+using System.Data;
+using Simple.Data.Ado.Schema;
+using System.ComponentModel.Composition;
+
+namespace Simple.Data.Ado.Test
+{
+ [TestFixture]
+ public class ProviderHelperTest
+ {
+ [Test]
+ public void ShouldNotRequestExportableTypeFromServiceProvider()
+ {
+ var helper = new ProviderHelper();
+ var connectionProvider = new StubConnectionAndServiceProvider();
+ var actual = helper.GetCustomProvider(connectionProvider);
+ Assert.IsNull(connectionProvider.RequestedServiceType);
+ }
+
+ [Test]
+ public void ShouldRequestNonExportedTypeFromServiceProvider()
+ {
+ var helper = new ProviderHelper();
+ var connectionProvider = new StubConnectionAndServiceProvider();
+ var actual = helper.GetCustomProvider(connectionProvider);
+ Assert.AreEqual(typeof(IQueryPager), connectionProvider.RequestedServiceType);
+ }
+
+ [Test]
+ public void ShouldReturnNonExportedTypeFromServiceProvider()
+ {
+ var helper = new ProviderHelper();
+ var connectionProvider = new StubConnectionAndServiceProvider();
+ var actual = helper.GetCustomProvider(connectionProvider);
+ Assert.IsInstanceOf(typeof(IQueryPager), actual);
+ }
+
+ [Test]
+ public void ShouldFindProviderUsingAssemblyAttribute()
+ {
+ IConnectionProvider provider;
+ Assert.True(ProviderHelper.TryLoadAssemblyUsingAttribute("Test", null, out provider));
+ Assert.IsNotNull(provider);
+ Assert.IsInstanceOf(provider);
+ }
+
+ public class StubConnectionAndServiceProvider : IConnectionProvider, IServiceProvider
+ {
+ public void SetConnectionString(string connectionString)
+ {
+ throw new NotImplementedException();
+ }
+
+ public IDbConnection CreateConnection()
+ {
+ throw new NotImplementedException();
+ }
+
+ public ISchemaProvider GetSchemaProvider()
+ {
+ throw new NotImplementedException();
+ }
+
+ public string ConnectionString
+ {
+ get { throw new NotImplementedException(); }
+ }
+
+ public bool SupportsCompoundStatements
+ {
+ get { throw new NotImplementedException(); }
+ }
+
+ public string GetIdentityFunction()
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool SupportsStoredProcedures
+ {
+ get { throw new NotImplementedException(); }
+ }
+
+ public IProcedureExecutor GetProcedureExecutor(AdoAdapter adapter, ObjectName procedureName)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Type RequestedServiceType { get; private set; }
+ public Object GetService(Type serviceType)
+ {
+ this.RequestedServiceType = serviceType;
+ return new StubQueryPager();
+ }
+ }
+
+ public class StubQueryPager : IQueryPager
{
public IEnumerable ApplyLimit(string sql, int take)
{
throw new NotImplementedException();
}
- public IEnumerable ApplyPaging(string sql, int skip, int take)
- {
- throw new NotImplementedException();
- }
- }
-
- public interface ITestInterface { }
- [Export(typeof(ITestInterface))]
- public class TestClass : ITestInterface { }
- }
-}
+ public IEnumerable ApplyPaging(string sql, string[] keys, int skip, int take)
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+ public interface ITestInterface { }
+ [Export(typeof(ITestInterface))]
+ public class TestClass : ITestInterface { }
+ }
+}
diff --git a/Simple.Data.Ado.Test/Simple.Data.Ado.Test.csproj b/Simple.Data.Ado.Test/Simple.Data.Ado.Test.csproj
index e62f20bc..cdebfa7d 100644
--- a/Simple.Data.Ado.Test/Simple.Data.Ado.Test.csproj
+++ b/Simple.Data.Ado.Test/Simple.Data.Ado.Test.csproj
@@ -1,4 +1,4 @@
-
+
Debug
@@ -58,11 +58,13 @@
+
+
diff --git a/Simple.Data.Ado.Test/TestCustomInserter.cs b/Simple.Data.Ado.Test/TestCustomInserter.cs
index 598d27be..5d8afd1e 100644
--- a/Simple.Data.Ado.Test/TestCustomInserter.cs
+++ b/Simple.Data.Ado.Test/TestCustomInserter.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Data;
+using System.Data.OleDb;
using System.Linq;
using System.Text;
using NUnit.Framework;
@@ -31,17 +32,17 @@ public void SetConnectionString(string connectionString)
public IDbConnection CreateConnection()
{
- throw new NotImplementedException();
+ return new OleDbConnection();
}
public ISchemaProvider GetSchemaProvider()
{
- throw new NotImplementedException();
+ return new StubSchemaProvider();
}
public string ConnectionString
{
- get { throw new NotImplementedException(); }
+ get { return "stub"; }
}
public bool SupportsCompoundStatements
@@ -65,10 +66,58 @@ public IProcedureExecutor GetProcedureExecutor(AdoAdapter adapter, ObjectName pr
}
}
+ public class StubSchemaProvider : ISchemaProvider
+ {
+ public IEnumerable GetTables()
+ {
+ throw new NotImplementedException();
+ }
+
+ public IEnumerable GetColumns(Table table)
+ {
+ throw new NotImplementedException();
+ }
+
+ public IEnumerable GetStoredProcedures()
+ {
+ throw new NotImplementedException();
+ }
+
+ public IEnumerable GetParameters(Procedure storedProcedure)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Key GetPrimaryKey(Table table)
+ {
+ throw new NotImplementedException();
+ }
+
+ public IEnumerable GetForeignKeys(Table table)
+ {
+ throw new NotImplementedException();
+ }
+
+ public string QuoteObjectName(string unquotedName)
+ {
+ throw new NotImplementedException();
+ }
+
+ public string NameParameter(string baseName)
+ {
+ throw new NotImplementedException();
+ }
+
+ public string GetDefaultSchema()
+ {
+ throw new NotImplementedException();
+ }
+ }
+
[Export(typeof(ICustomInserter))]
public class StubCustomInserter : ICustomInserter
{
- public IDictionary Insert(AdoAdapter adapter, string tableName, IDictionary data, IDbTransaction transaction = null)
+ public IDictionary Insert(AdoAdapter adapter, string tableName, IDictionary data, IDbTransaction transaction = null, bool resultRequired = false)
{
throw new NotImplementedException();
}
diff --git a/Simple.Data.Ado.Test/TestProviderAssemblyAttribute.cs b/Simple.Data.Ado.Test/TestProviderAssemblyAttribute.cs
new file mode 100644
index 00000000..cbe7bd1a
--- /dev/null
+++ b/Simple.Data.Ado.Test/TestProviderAssemblyAttribute.cs
@@ -0,0 +1,25 @@
+using System;
+
+namespace Simple.Data.Ado.Test
+{
+ public class TestProviderAssemblyAttribute : ProviderAssemblyAttributeBase
+ {
+ public TestProviderAssemblyAttribute()
+ : base("Test")
+ {
+ }
+
+ public override bool TryGetProvider(string connectionString, out IConnectionProvider provider, out Exception exception)
+ {
+ if (connectionString.Equals("Test"))
+ {
+ provider = new StubConnectionProvider();
+ exception = null;
+ return true;
+ }
+ provider = null;
+ exception = null;
+ return false;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Simple.Data.Ado/AdoAdapter.IAdapterWithFunctions.cs b/Simple.Data.Ado/AdoAdapter.IAdapterWithFunctions.cs
index 1ee2299d..f4bca895 100644
--- a/Simple.Data.Ado/AdoAdapter.IAdapterWithFunctions.cs
+++ b/Simple.Data.Ado/AdoAdapter.IAdapterWithFunctions.cs
@@ -13,7 +13,7 @@ public partial class AdoAdapter : IAdapterWithFunctions
public bool IsValidFunction(string functionName)
{
- return _connectionProvider.SupportsStoredProcedures && _schema.FindProcedure(functionName) != null;
+ return _connectionProvider.SupportsStoredProcedures && _schema.IsProcedure(functionName);
}
public IEnumerable Execute(string functionName, IDictionary parameters)
@@ -25,7 +25,7 @@ public IEnumerable Execute(string functionName, IDictionary Execute(string functionName, IDictionary parameters, IAdapterTransaction transaction)
{
var executor = _executors.GetOrAdd(functionName, f => _connectionProvider.GetProcedureExecutor(this, _schema.BuildObjectName(f)));
- return executor.Execute(parameters, ((AdoAdapterTransaction)transaction).Transaction);
+ return executor.Execute(parameters, ((AdoAdapterTransaction)transaction).DbTransaction);
}
}
}
diff --git a/Simple.Data.Ado/AdoAdapter.IAdapterWithTransactions.cs b/Simple.Data.Ado/AdoAdapter.IAdapterWithTransactions.cs
index 42b599e9..915beb12 100644
--- a/Simple.Data.Ado/AdoAdapter.IAdapterWithTransactions.cs
+++ b/Simple.Data.Ado/AdoAdapter.IAdapterWithTransactions.cs
@@ -10,7 +10,7 @@
public partial class AdoAdapter : IAdapterWithTransactions
{
- public IAdapterTransaction BeginTransaction(IsolationLevel isolationLevel)
+ public IAdapterTransaction BeginTransaction(IsolationLevel isolationLevel = IsolationLevel.Unspecified)
{
IDbConnection connection = CreateConnection();
connection.OpenIfClosed();
@@ -18,7 +18,7 @@ public IAdapterTransaction BeginTransaction(IsolationLevel isolationLevel)
return new AdoAdapterTransaction(transaction, _sharedConnection != null);
}
- public IAdapterTransaction BeginTransaction(IsolationLevel isolationLevel, string name)
+ public IAdapterTransaction BeginTransaction(string name, IsolationLevel isolationLevel = IsolationLevel.Unspecified)
{
IDbConnection connection = CreateConnection();
connection.OpenIfClosed();
@@ -35,7 +35,7 @@ public IEnumerable> InsertMany(string tableName,
IAdapterTransaction transaction,
Func, Exception, bool> onError, bool resultRequired)
{
- return new AdoAdapterInserter(this, ((AdoAdapterTransaction)transaction).Transaction).InsertMany(
+ return new AdoAdapterInserter(this, ((AdoAdapterTransaction)transaction).DbTransaction).InsertMany(
tableName, data, onError, resultRequired);
}
@@ -44,7 +44,7 @@ public int UpdateMany(string tableName, IEnumerable>
{
IBulkUpdater bulkUpdater = ProviderHelper.GetCustomProvider(ConnectionProvider) ??
new BulkUpdater();
- return bulkUpdater.Update(this, tableName, data.ToList(), ((AdoAdapterTransaction)transaction).Transaction);
+ return bulkUpdater.Update(this, tableName, data.ToList(), ((AdoAdapterTransaction)transaction).DbTransaction);
}
public int UpdateMany(string tableName, IEnumerable> data,
@@ -52,13 +52,13 @@ public int UpdateMany(string tableName, IEnumerable>
{
IBulkUpdater bulkUpdater = ProviderHelper.GetCustomProvider(ConnectionProvider) ??
new BulkUpdater();
- return bulkUpdater.Update(this, tableName, data.ToList(), ((AdoAdapterTransaction)transaction).Transaction);
+ return bulkUpdater.Update(this, tableName, data.ToList(), ((AdoAdapterTransaction)transaction).DbTransaction);
}
public int Update(string tableName, IDictionary data, IAdapterTransaction adapterTransaction)
{
string[] keyFieldNames = GetKeyNames(tableName).ToArray();
- if (keyFieldNames.Length == 0) throw new AdoAdapterException("No Primary Key found for implicit update");
+ if (keyFieldNames.Length == 0) throw new AdoAdapterException(string.Format("No primary key found for implicit update of table '{0}'.", tableName));
return Update(tableName, data, GetCriteria(tableName, keyFieldNames, data), adapterTransaction);
}
@@ -68,45 +68,51 @@ public int UpdateMany(string tableName, IList> dataL
IBulkUpdater bulkUpdater = ProviderHelper.GetCustomProvider(ConnectionProvider) ??
new BulkUpdater();
return bulkUpdater.Update(this, tableName, dataList, criteriaFieldNames,
- ((AdoAdapterTransaction)adapterTransaction).Transaction);
+ ((AdoAdapterTransaction)adapterTransaction).DbTransaction);
}
- public IAdapterTransaction BeginTransaction()
- {
- IDbConnection connection = CreateConnection();
- connection.OpenIfClosed();
- IDbTransaction transaction = connection.BeginTransaction();
- return new AdoAdapterTransaction(transaction, _sharedConnection != null);
- }
+ //public IAdapterTransaction BeginTransaction()
+ //{
+ // IDbConnection connection = CreateConnection();
+ // connection.OpenIfClosed();
+ // IDbTransaction transaction = connection.BeginTransaction();
+ // return new AdoAdapterTransaction(transaction, _sharedConnection != null);
+ //}
- public IAdapterTransaction BeginTransaction(string name)
- {
- IDbConnection connection = CreateConnection();
- connection.OpenIfClosed();
- var sqlConnection = connection as SqlConnection;
- IDbTransaction transaction = sqlConnection != null
- ? sqlConnection.BeginTransaction(name)
- : connection.BeginTransaction();
+ //public IAdapterTransaction BeginTransaction(string name)
+ //{
+ // IDbConnection connection = CreateConnection();
+ // connection.OpenIfClosed();
+ // var sqlConnection = connection as SqlConnection;
+ // IDbTransaction transaction = sqlConnection != null
+ // ? sqlConnection.BeginTransaction(name)
+ // : connection.BeginTransaction();
- return new AdoAdapterTransaction(transaction, name, _sharedConnection != null);
- }
+ // return new AdoAdapterTransaction(transaction, name, _sharedConnection != null);
+ //}
public IDictionary Get(string tableName, IAdapterTransaction transaction, params object[] parameterValues)
{
- return new AdoAdapterGetter(this, ((AdoAdapterTransaction) transaction).Transaction).Get(tableName,
+ return new AdoAdapterGetter(this, ((AdoAdapterTransaction) transaction).DbTransaction).Get(tableName,
parameterValues);
}
+
+ public IEnumerable> RunQuery(SimpleQuery query, IAdapterTransaction transaction, out IEnumerable unhandledClauses)
+ {
+ return new AdoAdapterQueryRunner(this, (AdoAdapterTransaction)transaction).RunQuery(query, out unhandledClauses);
+ }
+
public IEnumerable> Find(string tableName, SimpleExpression criteria,
IAdapterTransaction transaction)
{
- return new AdoAdapterFinder(this, ((AdoAdapterTransaction)transaction).Transaction).Find(tableName,
+ return new AdoAdapterFinder(this, ((AdoAdapterTransaction)transaction).DbTransaction).Find(tableName,
criteria);
}
public IDictionary Insert(string tableName, IDictionary data,
IAdapterTransaction transaction, bool resultRequired)
{
- return new AdoAdapterInserter(this, ((AdoAdapterTransaction)transaction).Transaction).Insert(tableName,
+ return new AdoAdapterInserter(this, ((AdoAdapterTransaction)transaction).DbTransaction).Insert(tableName,
data, resultRequired);
}
@@ -125,19 +131,19 @@ public int Delete(string tableName, SimpleExpression criteria, IAdapterTransacti
public override IDictionary Upsert(string tableName, IDictionary data, SimpleExpression criteria, bool resultRequired, IAdapterTransaction adapterTransaction)
{
- var transaction = ((AdoAdapterTransaction) adapterTransaction).Transaction;
+ var transaction = ((AdoAdapterTransaction) adapterTransaction).DbTransaction;
return new AdoAdapterUpserter(this, transaction).Upsert(tableName, data, criteria, resultRequired);
}
public override IEnumerable> UpsertMany(string tableName, IList> list, IAdapterTransaction adapterTransaction, bool isResultRequired, Func, Exception, bool> errorCallback)
{
- var transaction = ((AdoAdapterTransaction) adapterTransaction).Transaction;
+ var transaction = ((AdoAdapterTransaction) adapterTransaction).DbTransaction;
return new AdoAdapterUpserter(this, transaction).UpsertMany(tableName, list, isResultRequired, errorCallback);
}
public override IEnumerable> UpsertMany(string tableName, IList> list, IEnumerable keyFieldNames, IAdapterTransaction adapterTransaction, bool isResultRequired, Func, Exception, bool> errorCallback)
{
- var transaction = ((AdoAdapterTransaction) adapterTransaction).Transaction;
+ var transaction = ((AdoAdapterTransaction) adapterTransaction).DbTransaction;
return new AdoAdapterUpserter(this, transaction).UpsertMany(tableName, list, keyFieldNames.ToArray(), isResultRequired, errorCallback);
}
}
diff --git a/Simple.Data.Ado/AdoAdapter.cs b/Simple.Data.Ado/AdoAdapter.cs
index 23da6808..bd713a32 100644
--- a/Simple.Data.Ado/AdoAdapter.cs
+++ b/Simple.Data.Ado/AdoAdapter.cs
@@ -2,8 +2,6 @@
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Data;
-using System.Data.Common;
-using System.Data.SqlClient;
using System.Linq;
using Simple.Data.Ado.Schema;
@@ -21,6 +19,7 @@ public partial class AdoAdapter : Adapter, ICloneable
private Lazy _relatedFinder;
private DatabaseSchema _schema;
private IDbConnection _sharedConnection;
+ private Func _connectionModifier = connection => connection;
public AdoAdapter()
{
@@ -46,6 +45,11 @@ private AdoAdapter(IConnectionProvider connectionProvider, AdoAdapterFinder find
_schema = schema;
}
+ public AdoOptions AdoOptions
+ {
+ get { return Options as AdoOptions; }
+ }
+
public CommandOptimizer CommandOptimizer
{
get { return _commandOptimizer; }
@@ -79,15 +83,17 @@ public ISchemaProvider SchemaProvider
public override IDictionary GetKey(string tableName, IDictionary record)
{
var homogenizedRecord = new Dictionary(record, HomogenizedEqualityComparer.DefaultInstance);
- return GetKeyNames(tableName).ToDictionary(key => key,
- key => homogenizedRecord.ContainsKey(key) ? homogenizedRecord[key] : null);
+ return GetKeyNames(tableName)
+ .Select(k => k.Homogenize())
+ .Where(homogenizedRecord.ContainsKey)
+ .ToDictionary(key => key, key => homogenizedRecord[key]);
}
#region ICloneable Members
public object Clone()
{
- return new AdoAdapter(_connectionProvider);
+ return new AdoAdapter(_connectionProvider) {_connectionModifier = _connectionModifier};
}
#endregion
@@ -99,8 +105,17 @@ protected override void OnSetup()
{
if (settingsKeys.Contains("ProviderName"))
{
- _connectionProvider = ProviderHelper.GetProviderByConnectionString(Settings.ConnectionString,
- Settings.ProviderName);
+ if(settingsKeys.Contains("SchemaName"))
+ {
+ _connectionProvider = ProviderHelper.GetProviderByConnectionString(Settings.ConnectionString
+ , Settings.ProviderName
+ , Settings.SchemaName);
+ }
+ else
+ {
+ _connectionProvider = ProviderHelper.GetProviderByConnectionString(Settings.ConnectionString,
+ Settings.ProviderName);
+ }
}
else
{
@@ -113,7 +128,14 @@ protected override void OnSetup()
}
else if (settingsKeys.Contains("ConnectionName"))
{
- _connectionProvider = ProviderHelper.GetProviderByConnectionName(Settings.ConnectionName);
+ if (settingsKeys.Contains("SchemaName"))
+ {
+ _connectionProvider = ProviderHelper.GetProviderByConnectionName(Settings.ConnectionName, Settings.SchemaName);
+ }
+ else
+ {
+ _connectionProvider = ProviderHelper.GetProviderByConnectionName(Settings.ConnectionName);
+ }
}
_schema = DatabaseSchema.Get(_connectionProvider, _providerHelper);
_relatedFinder = new Lazy(CreateRelatedFinder);
@@ -168,10 +190,15 @@ public override IEnumerable>> RunQueries
public override bool IsExpressionFunction(string functionName, params object[] args)
{
- return (functionName.Equals("like", StringComparison.OrdinalIgnoreCase) ||
- functionName.Equals("notlike", StringComparison.OrdinalIgnoreCase))
- && args.Length == 1
- && args[0] is string;
+ return FunctionIsLikeOrNotLike(functionName, args);
+ }
+
+ private static bool FunctionIsLikeOrNotLike(string functionName, object[] args)
+ {
+ return ((functionName.Equals("like", StringComparison.OrdinalIgnoreCase)
+ || functionName.Equals("notlike", StringComparison.OrdinalIgnoreCase))
+ && args.Length == 1
+ && args[0] is string);
}
public override IObservable> RunQueryAsObservable(SimpleQuery query,
@@ -238,56 +265,53 @@ public override IList GetKeyNames(string tableName)
return _schema.FindTable(tableName).PrimaryKey.AsEnumerable().ToList();
}
+ public void SetConnectionModifier(Func connectionModifer)
+ {
+ _connectionModifier = connectionModifer;
+ }
+
+ public void ClearConnectionModifier()
+ {
+ _connectionModifier = connection => connection;
+ }
+
private int Execute(ICommandBuilder commandBuilder)
{
IDbConnection connection = CreateConnection();
using (connection.MaybeDisposable())
{
- using (IDbCommand command = commandBuilder.GetCommand(connection))
+ using (IDbCommand command = commandBuilder.GetCommand(connection, AdoOptions))
{
connection.OpenIfClosed();
- return TryExecute(command);
+ return command.TryExecuteNonQuery();
}
}
}
- internal static int Execute(ICommandBuilder commandBuilder, IDbConnection connection)
+ internal int Execute(ICommandBuilder commandBuilder, IDbConnection connection)
{
using (connection.MaybeDisposable())
{
- using (IDbCommand command = commandBuilder.GetCommand(connection))
+ using (IDbCommand command = commandBuilder.GetCommand(connection, AdoOptions))
{
connection.OpenIfClosed();
- return TryExecute(command);
+ return command.TryExecuteNonQuery();
}
}
}
- internal static int Execute(ICommandBuilder commandBuilder, IAdapterTransaction transaction)
+ internal int Execute(ICommandBuilder commandBuilder, IAdapterTransaction transaction)
{
- IDbTransaction dbTransaction = ((AdoAdapterTransaction) transaction).Transaction;
+ IDbTransaction dbTransaction = ((AdoAdapterTransaction) transaction).DbTransaction;
return Execute(commandBuilder, dbTransaction);
}
- internal static int Execute(ICommandBuilder commandBuilder, IDbTransaction dbTransaction)
+ internal int Execute(ICommandBuilder commandBuilder, IDbTransaction dbTransaction)
{
- using (IDbCommand command = commandBuilder.GetCommand(dbTransaction.Connection))
+ using (IDbCommand command = commandBuilder.GetCommand(dbTransaction.Connection, AdoOptions))
{
command.Transaction = dbTransaction;
- return TryExecute(command);
- }
- }
-
- private static int TryExecute(IDbCommand command)
- {
- command.WriteTrace();
- try
- {
- return command.ExecuteNonQuery();
- }
- catch (DbException ex)
- {
- throw new AdoAdapterException(ex.Message, command);
+ return command.TryExecuteNonQuery();
}
}
@@ -303,7 +327,14 @@ public void StopUsingSharedConnection()
public IDbConnection CreateConnection()
{
- return _sharedConnection ?? _connectionProvider.CreateConnection();
+ if (_sharedConnection != null) return _sharedConnection;
+ var connection = _connectionModifier(_connectionProvider.CreateConnection());
+ var args = ConnectionCreated.Raise(this, () => new ConnectionCreatedEventArgs(connection));
+ if (args != null && args.OverriddenConnection != null)
+ {
+ return args.OverriddenConnection;
+ }
+ return connection;
}
public DatabaseSchema GetSchema()
@@ -318,7 +349,8 @@ public override IDictionary Upsert(string tableName, IDictionary
public override IEnumerable> UpsertMany(string tableName, IList> list, bool isResultRequired, Func, Exception, bool> errorCallback)
{
- return new AdoAdapterUpserter(this).UpsertMany(tableName, list, isResultRequired, errorCallback);
+ var upserter = new AdoAdapterUpserter(this);
+ return upserter.UpsertMany(tableName, list, isResultRequired, errorCallback);
}
public override IEnumerable> UpsertMany(string tableName, IList> list, IEnumerable keyFieldNames, bool isResultRequired, Func, Exception, bool> errorCallback)
@@ -336,5 +368,29 @@ protected override void OnReset()
DatabaseSchema.ClearCache();
_schema = DatabaseSchema.Get(_connectionProvider, _providerHelper);
}
+
+ public static event EventHandler ConnectionCreated;
+ }
+
+ public class ConnectionCreatedEventArgs : EventArgs
+ {
+ private readonly IDbConnection _connection;
+
+ public ConnectionCreatedEventArgs(IDbConnection connection)
+ {
+ _connection = connection;
+ }
+
+ public IDbConnection Connection
+ {
+ get { return _connection; }
+ }
+
+ internal IDbConnection OverriddenConnection { get; private set; }
+
+ public void OverrideConnection(IDbConnection overridingConnection)
+ {
+ OverriddenConnection = overridingConnection;
+ }
}
-}
\ No newline at end of file
+}
diff --git a/Simple.Data.Ado/AdoAdapterException.cs b/Simple.Data.Ado/AdoAdapterException.cs
index 4ee15798..ff25e6da 100644
--- a/Simple.Data.Ado/AdoAdapterException.cs
+++ b/Simple.Data.Ado/AdoAdapterException.cs
@@ -3,77 +3,75 @@
using System.Data;
using System.Linq;
using System.Runtime.Serialization;
-using System.Text;
using Simple.Data.Extensions;
namespace Simple.Data.Ado
{
- using System.Security;
-
[Serializable]
public class AdoAdapterException : AdapterException
{
public AdoAdapterException() : base(typeof(AdoAdapter))
+ {}
+
+ public AdoAdapterException(string message)
+ : base(message, typeof(AdoAdapter))
+ {}
+
+ public AdoAdapterException(string message, Exception inner)
+ : base(message, inner, typeof(AdoAdapter))
+ {}
+
+ public AdoAdapterException(string message, IDbCommand command)
+ : base(message, typeof(AdoAdapter))
{
+ CommandText = command.CommandText;
+ Parameters = command.Parameters.Cast()
+ .ToDictionary(p => p.ParameterName, p => p.Value);
}
- public AdoAdapterException(string message, IDbCommand command) : base(message, typeof(AdoAdapter))
+ public AdoAdapterException(string message, IDbCommand command, Exception inner)
+ : base(message, inner, typeof(AdoAdapter))
{
CommandText = command.CommandText;
Parameters = command.Parameters.Cast()
.ToDictionary(p => p.ParameterName, p => p.Value);
}
- public AdoAdapterException(string commandText, IEnumerable> parameters)
- :base(typeof(AdoAdapter))
+ public AdoAdapterException(string commandText, IEnumerable> parameters)
+ : base(typeof(AdoAdapter)) // never used outside tests?
{
CommandText = commandText;
Parameters = parameters.ToDictionary();
}
-
- public AdoAdapterException(string message) : base(message, typeof(AdoAdapter))
- {
- }
-
- public AdoAdapterException(string message, string commandText, IEnumerable> parameters)
- :base(message, typeof(AdoAdapter))
+ public AdoAdapterException(string message, string commandText, IEnumerable> parameters)
+ : base(message, typeof(AdoAdapter))
{
CommandText = commandText;
Parameters = parameters.ToDictionary();
}
- public AdoAdapterException(string message, Exception inner) : base(message, inner, typeof(AdoAdapter))
+ public AdoAdapterException(string message, string commandText, IEnumerable> parameters, Exception inner)
+ : base(message, inner, typeof(AdoAdapter))
{
+ CommandText = commandText;
+ Parameters = parameters.ToDictionary();
}
protected AdoAdapterException(SerializationInfo info, StreamingContext context)
: base(info, context)
- {
- //CommandText = info.GetString("CommandText");
- //try
- //{
- // var array = info.GetValue("Parameters", typeof(KeyValuePair[]));
- // if (array != null)
- // {
- // Parameters = ((KeyValuePair[])array);
- // }
- //}
- //catch (SerializationException)
- //{
- //}
- }
+ {}
public IDictionary Parameters
{
- get { return Data.Contains("Parameters") ? ((KeyValuePair[])Data["Parameters"]).ToDictionary() : null; }
+ get { return Data.Contains("Parameters") ? ((KeyValuePair[])Data["Parameters"]).ToDictionary() : null; }
private set { Data["Parameters"] = value.ToArray(); }
}
public string CommandText
{
- get { return Data.Contains("CommandText") ? Data["CommandText"].ToString() : null; }
+ get { return Data.Contains("CommandText") ? Data["CommandText"].ToString() : null; }
private set { Data["CommandText"] = value; }
}
}
-}
+}
\ No newline at end of file
diff --git a/Simple.Data.Ado/AdoAdapterFinder.cs b/Simple.Data.Ado/AdoAdapterFinder.cs
index 4f89fd89..5441b4f5 100644
--- a/Simple.Data.Ado/AdoAdapterFinder.cs
+++ b/Simple.Data.Ado/AdoAdapterFinder.cs
@@ -1,15 +1,12 @@
-using System;
-using System.Collections.Concurrent;
-using System.Collections.Generic;
-using System.Data;
-using System.Data.Common;
-using System.Linq;
-using System.Text;
-
-namespace Simple.Data.Ado
+namespace Simple.Data.Ado
{
- using System.Data.SqlClient;
using System.Dynamic;
+ using System;
+ using System.Collections.Concurrent;
+ using System.Collections.Generic;
+ using System.Data;
+ using System.Data.Common;
+ using System.Linq;
class AdoAdapterFinder
{
@@ -57,7 +54,7 @@ public Func