Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions Simple.Data.Ado.Test/ProviderHelperTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,16 @@ public IProcedureExecutor GetProcedureExecutor(AdoAdapter adapter, ObjectName pr
throw new NotImplementedException();
}

public void SetSharedConnection(object sharedConnection)
{
throw new NotImplementedException();
}

public bool IsSharedConnection()
{
return false;
}

public Type RequestedServiceType { get; private set; }
public Object GetService(Type serviceType)
{
Expand Down
10 changes: 10 additions & 0 deletions Simple.Data.Ado.Test/TestCustomInserter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,16 @@ public IProcedureExecutor GetProcedureExecutor(AdoAdapter adapter, ObjectName pr
{
throw new NotImplementedException();
}

public void SetSharedConnection(object sharedConnection)
{
throw new NotImplementedException();
}

public bool IsSharedConnection()
{
return false;
}
}

public class StubSchemaProvider : ISchemaProvider
Expand Down
1 change: 1 addition & 0 deletions Simple.Data.Ado/AdoAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,7 @@ internal int Execute(ICommandBuilder commandBuilder, IDbTransaction dbTransactio
public void UseSharedConnection(IDbConnection connection)
{
_sharedConnection = connection;
_connectionProvider.SetSharedConnection(connection);
}

public void StopUsingSharedConnection()
Expand Down
2 changes: 2 additions & 0 deletions Simple.Data.Ado/IConnectionProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,7 @@ public interface IConnectionProvider
string GetIdentityFunction();
bool SupportsStoredProcedures { get; }
IProcedureExecutor GetProcedureExecutor(AdoAdapter adapter, ObjectName procedureName);
void SetSharedConnection(object sharedConnection);
bool IsSharedConnection();
}
}
31 changes: 31 additions & 0 deletions Simple.Data.InMemoryTest/InMemoryTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,37 @@ public void TestDeleteBy()
Assert.IsNull(record);
}

[Test]
public void TestFindAcrossJoinAfterDelete()
{
var adapter = new InMemoryAdapter();
adapter.SetKeyColumn("Thing1Table", "Id");
adapter.SetKeyColumn("Thing2Table", "Id");
adapter.Join.Master("Thing1Table", "Id").Detail("ThingJoin", "Thing1Id");
adapter.Join.Master("Thing2Table", "Id").Detail("ThingJoin", "Thing2Id");

Database.UseMockAdapter(adapter);
var db = Database.Open();

var thing1 = new {Id = 1, Name = "Thing1"};
var thing2 = new {Id = 2, Name = "Thing2"};
var thingJoin = new {Thing1Id = 1, Thing2Id = 2};

db.Thing1Table.Insert(thing1);
db.Thing2Table.Insert(thing2);
db.ThingJoin.Insert(thingJoin);

//Delete the join object.
db.ThingJoin.DeleteAll(db.ThingJoin.Thing1Id == 1 && db.ThingJoin.Thing2Id == 2);

//Ensure after we drop one of the relationships, there is only no records left in the join table.
Assert.AreEqual(0, db.ThingJoin.All().ToList().Count);

//Ensure we don't find the Thing across the join after the delete
var foundByJoin = db.Thing1Table.FindAll(db.Thing1Table.ThingJoin.Thing1Id == 1).FirstOrDefault();
Assert.IsNull(foundByJoin);
}

[Test]
public void TestOrderBy()
{
Expand Down
10 changes: 10 additions & 0 deletions Simple.Data.Mocking/Ado/MockConnectionProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,16 @@ public IProcedureExecutor GetProcedureExecutor(AdoAdapter adapter, ObjectName pr
return new ProcedureExecutor(adapter, procedureName);
}

public void SetSharedConnection(object sharedConnection)
{
throw new NotImplementedException();
}

public bool IsSharedConnection()
{
return false;
}

private bool _supportsCompoundStatements = true;
public bool SupportsCompoundStatements
{
Expand Down
10 changes: 10 additions & 0 deletions Simple.Data.SqlCe40/SqlCe40ConnectionProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,5 +74,15 @@ public IProcedureExecutor GetProcedureExecutor(AdoAdapter adapter, ObjectName pr
{
throw new NotSupportedException("SQL Server Compact Edition does not support stored procedures.");
}

public void SetSharedConnection(object sharedConnection)
{
throw new NotImplementedException();
}

public bool IsSharedConnection()
{
return false;
}
}
}
13 changes: 12 additions & 1 deletion Simple.Data.SqlServer/SqlConnectionProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ namespace Simple.Data.SqlServer
public class SqlConnectionProvider : IConnectionProvider
{
private string _connectionString;
private SqlConnection _sharedConnection;

public SqlConnectionProvider()
{
Expand All @@ -27,7 +28,7 @@ public SqlConnectionProvider(string connectionString)

public IDbConnection CreateConnection()
{
return new SqlConnection(_connectionString);
return _sharedConnection ?? new SqlConnection(_connectionString);
}

public ISchemaProvider GetSchemaProvider()
Expand Down Expand Up @@ -79,5 +80,15 @@ public IProcedureExecutor GetProcedureExecutor(AdoAdapter adapter, ObjectName pr
{
return new ProcedureExecutor(adapter, procedureName);
}

public void SetSharedConnection(object sharedConnection)
{
_sharedConnection = (SqlConnection) sharedConnection;
}

public bool IsSharedConnection()
{
return _sharedConnection != null;
}
}
}
46 changes: 41 additions & 5 deletions Simple.Data.SqlServer/SqlSchemaProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,22 @@ public IEnumerable<Procedure> GetStoredProcedures()

private IEnumerable<DataRow> GetSchema(string collectionName, params string[] constraints)
{
using (var cn = ConnectionProvider.CreateConnection())
var cn = ConnectionProvider.CreateConnection() as SqlConnection;
try
{
cn.Open();
if (!ConnectionProvider.IsSharedConnection())
cn.Open();

return cn.GetSchema(collectionName, constraints).AsEnumerable();
var schema = cn.GetSchema(collectionName, constraints).AsEnumerable();
return schema;
}
finally
{
if (!ConnectionProvider.IsSharedConnection())
{
cn.Close();
cn.Dispose();
}
}
}

Expand All @@ -89,8 +100,13 @@ public IEnumerable<Parameter> GetParameters(Procedure storedProcedure)
{
// GetSchema does not return the return value of e.g. a stored proc correctly,
// i.e. there isn't sufficient information to correctly set up a stored proc.
using (var connection = (SqlConnection)ConnectionProvider.CreateConnection())
var connection = (SqlConnection) ConnectionProvider.CreateConnection();

try
{
if (!ConnectionProvider.IsSharedConnection())
connection.Open();

using (var command = connection.CreateCommand())
{
command.CommandType = CommandType.StoredProcedure;
Expand All @@ -104,6 +120,14 @@ public IEnumerable<Parameter> GetParameters(Procedure storedProcedure)
yield return new Parameter(p.ParameterName, SqlTypeResolver.GetClrType(p.DbType.ToString()), p.Direction, p.DbType, p.Size);
}
}
finally
{
if (!ConnectionProvider.IsSharedConnection())
{
connection.Close();
connection.Dispose();
}
}
}

public Key GetPrimaryKey(Table table)
Expand Down Expand Up @@ -208,15 +232,27 @@ private EnumerableRowCollection<DataRow> GetForeignKeys(string tableName)
private DataTable SelectToDataTable(string sql, params SqlParameter[] parameters)
{
var dataTable = new DataTable();
using (var cn = ConnectionProvider.CreateConnection() as SqlConnection)
var cn = ConnectionProvider.CreateConnection() as SqlConnection;
try
{
if (!ConnectionProvider.IsSharedConnection())
cn.Open();

using (var adapter = new SqlDataAdapter(sql, cn))
{
adapter.SelectCommand.Parameters.AddRange(parameters);
adapter.Fill(dataTable);
}

}
finally
{
if (!ConnectionProvider.IsSharedConnection())
{
cn.Close();
cn.Dispose();
}
}

return dataTable;
}
Expand Down
40 changes: 40 additions & 0 deletions Simple.Data/InMemoryAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,44 @@ var detail in
}
}

private void DeleteAsDetail(string tableName, IDictionary<string, object> data)
{
foreach (var @join in _joins.Where(j => j.DetailTableName.Equals(tableName, StringComparison.OrdinalIgnoreCase)))
{
if (!data.ContainsKey(@join.DetailKey)) continue;
foreach (
var master in
GetTable(@join.MasterTableName).Where(
d => d.ContainsKey(@join.MasterKey) && d[@join.MasterKey].Equals(data[@join.DetailKey])))
{
data[@join.MasterPropertyName] = master;
if (master.ContainsKey(@join.DetailPropertyName))
{
((List<IDictionary<string, object>>)master[@join.DetailPropertyName]).Remove(data);
}
}
}
}

private void DeleteAsMaster(string tableName, IDictionary<string, object> data)
{
foreach (var @join in _joins.Where(j => j.MasterTableName.Equals(tableName, StringComparison.OrdinalIgnoreCase)))
{
if (!data.ContainsKey(@join.MasterKey)) continue;
foreach (
var detail in
GetTable(@join.DetailTableName).Where(
d => d.ContainsKey(@join.DetailKey) && d[@join.DetailKey].Equals(data[@join.MasterKey])))
{
detail[@join.MasterPropertyName] = data;
if (data.ContainsKey(@join.DetailPropertyName))
{
((List<IDictionary<string, object>>)data[@join.DetailPropertyName]).Add(data);
}
}
}
}

public override int Update(string tableName, IDictionary<string, object> data, SimpleExpression criteria)
{
int count = 0;
Expand All @@ -196,6 +234,8 @@ public override int Delete(string tableName, SimpleExpression criteria)
List<IDictionary<string, object>> deletions = Find(tableName, criteria).ToList();
foreach (var record in deletions)
{
DeleteAsDetail(tableName, record);
DeleteAsMaster(tableName, record);
GetTable(tableName).Remove(record);
}
return deletions.Count;
Expand Down