Skip to content

Commit ff89ce1

Browse files
committed
Fixed recursion error in WithTotalCount and added Reset method to Adapter
1 parent d7a2c7a commit ff89ce1

File tree

13 files changed

+150
-58
lines changed

13 files changed

+150
-58
lines changed

Simple.Data.Ado/AdoAdapter.cs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,14 @@ private IEnumerable<IDictionary<string, object>> RunQueryWithCount(SimpleQuery q
116116
throw new InvalidOperationException("No WithCountClause specified.");
117117
}
118118

119+
query = query.ClearWithTotalCount();
119120
var countQuery = query.ClearSkip().ClearTake().ReplaceSelect(new CountSpecialReference());
120-
var unhandledClausesList = new List<IEnumerable<SimpleQueryClauseBase>> { Enumerable.Empty<SimpleQueryClauseBase>(), Enumerable.Empty<SimpleQueryClauseBase>() };
121+
var unhandledClausesList = new List<IEnumerable<SimpleQueryClauseBase>>
122+
{
123+
Enumerable.Empty<SimpleQueryClauseBase>(),
124+
Enumerable.Empty<SimpleQueryClauseBase>()
125+
};
126+
121127
using (var enumerator = RunQueries(new[] { countQuery, query }, unhandledClausesList).GetEnumerator())
122128
{
123129
unhandledClauses = unhandledClausesList[1];
@@ -307,7 +313,7 @@ internal IDbConnection CreateConnection()
307313

308314
internal DatabaseSchema GetSchema()
309315
{
310-
return DatabaseSchema.Get(_connectionProvider, _providerHelper);
316+
return _schema ?? (_schema = DatabaseSchema.Get(_connectionProvider, _providerHelper));
311317
}
312318

313319
/// <summary>
@@ -410,5 +416,11 @@ public ISchemaProvider SchemaProvider
410416
{
411417
get { return _connectionProvider.GetSchemaProvider(); }
412418
}
419+
420+
protected override void OnReset()
421+
{
422+
DatabaseSchema.ClearCache();
423+
_schema = DatabaseSchema.Get(_connectionProvider, _providerHelper);
424+
}
413425
}
414426
}

Simple.Data.Ado/Schema/DatabaseSchema.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,5 +96,10 @@ public static DatabaseSchema Get(IConnectionProvider connectionProvider, Provide
9696
return Instances.GetOrAdd(connectionProvider.ConnectionString,
9797
sp => new DatabaseSchema(connectionProvider.GetSchemaProvider(), providerHelper));
9898
}
99+
100+
public static void ClearCache()
101+
{
102+
Instances.Clear();
103+
}
99104
}
100105
}

Simple.Data.BehaviourTest/DatabaseIntegrationContext.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ namespace Simple.Data.IntegrationTest
88
{
99
public abstract class DatabaseIntegrationContext
1010
{
11-
private MockDatabase _mockDatabase;
11+
protected MockDatabase _mockDatabase;
1212
protected dynamic _db;
1313

1414
protected abstract void SetSchema(MockSchemaProvider schemaProvider);
Lines changed: 55 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,56 @@
1-
using System;
2-
using System.Collections.Generic;
3-
using System.Linq;
4-
using System.Text;
5-
6-
namespace Simple.Data.IntegrationTest.Query
7-
{
8-
using Mocking.Ado;
9-
using NUnit.Framework;
10-
11-
[TestFixture]
12-
public class WithCountTest : DatabaseIntegrationContext
13-
{
14-
protected override void SetSchema(MockSchemaProvider schemaProvider)
15-
{
16-
schemaProvider.SetTables(new[] { "dbo", "Users", "BASE TABLE" });
17-
18-
schemaProvider.SetColumns(new[] { "dbo", "Users", "Name" },
19-
new[] { "dbo", "Users", "Password" });
20-
}
21-
22-
[Test]
23-
public void WithTotalCountShouldCreateCompoundQuery_ObsoleteFutureVersion()
24-
{
25-
const string expected = @"select count(*) from [dbo].[users] where [dbo].[users].[name] = @p1_c0; " +
26-
@"select [dbo].[users].[name],[dbo].[users].[password] from [dbo].[users] where [dbo].[users].[name] = @p1_c1";
27-
28-
Future<int> count;
29-
var q = _db.Users.QueryByName("Foo")
30-
.WithTotalCount(out count);
31-
32-
EatException<InvalidOperationException>(() => q.ToList());
33-
34-
GeneratedSqlIs(expected);
35-
}
36-
37-
[Test]
38-
public void WithTotalCountShouldCreateCompoundQuery()
39-
{
40-
const string expected = @"select count(*) from [dbo].[users] where [dbo].[users].[name] = @p1_c0; " +
41-
@"select [dbo].[users].[name],[dbo].[users].[password] from [dbo].[users] where [dbo].[users].[name] = @p1_c1";
42-
43-
Promise<int> count;
44-
var q = _db.Users.QueryByName("Foo")
45-
.WithTotalCount(out count);
46-
47-
EatException<InvalidOperationException>(() => q.ToList());
48-
49-
GeneratedSqlIs(expected);
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using Simple.Data.Ado;
6+
using Simple.Data.Mocking;
7+
8+
namespace Simple.Data.IntegrationTest.Query
9+
{
10+
using Mocking.Ado;
11+
using NUnit.Framework;
12+
13+
[TestFixture]
14+
public class WithCountTest : DatabaseIntegrationContext
15+
{
16+
protected override void SetSchema(MockSchemaProvider schemaProvider)
17+
{
18+
schemaProvider.SetTables(new[] { "dbo", "Users", "BASE TABLE" });
19+
20+
schemaProvider.SetColumns(new[] { "dbo", "Users", "Name" },
21+
new[] { "dbo", "Users", "Password" });
22+
}
23+
24+
[Test]
25+
// ReSharper disable InconsistentNaming
26+
public void WithTotalCountShouldCreateCompoundQuery_ObsoleteFutureVersion()
27+
// ReSharper restore InconsistentNaming
28+
{
29+
const string expected = @"select count(*) from [dbo].[users] where [dbo].[users].[name] = @p1_c0; " +
30+
@"select [dbo].[users].[name],[dbo].[users].[password] from [dbo].[users] where [dbo].[users].[name] = @p1_c1";
31+
32+
Future<int> count;
33+
var q = _db.Users.QueryByName("Foo")
34+
.WithTotalCount(out count);
35+
36+
EatException<InvalidOperationException>(() => q.ToList());
37+
38+
GeneratedSqlIs(expected);
39+
}
40+
41+
[Test]
42+
public void WithTotalCountShouldCreateCompoundQuery()
43+
{
44+
const string expected = @"select count(*) from [dbo].[users] where [dbo].[users].[name] = @p1_c0; " +
45+
@"select [dbo].[users].[name],[dbo].[users].[password] from [dbo].[users] where [dbo].[users].[name] = @p1_c1";
46+
47+
Promise<int> count;
48+
var q = _db.Users.QueryByName("Foo")
49+
.WithTotalCount(out count);
50+
51+
EatException<InvalidOperationException>(() => q.ToList());
52+
53+
GeneratedSqlIs(expected);
5054
}
5155

5256
[Test]
@@ -64,5 +68,5 @@ public void WithTotalCountWithExplicitSelectShouldCreateCompoundQuery()
6468

6569
GeneratedSqlIs(expected);
6670
}
67-
}
68-
}
71+
}
72+
}

Simple.Data.Mocking/Ado/MockConnectionProvider.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,11 @@ public IProcedureExecutor GetProcedureExecutor(AdoAdapter adapter, ObjectName pr
5858
return new ProcedureExecutor(adapter, procedureName);
5959
}
6060

61+
private bool _supportsCompoundStatements = true;
6162
public bool SupportsCompoundStatements
6263
{
63-
get { return true; }
64+
get { return _supportsCompoundStatements; }
65+
set { _supportsCompoundStatements = value; }
6466
}
6567
}
6668
}

Simple.Data.SqlCe40Test/QueryTest.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,22 @@ public void ShouldSelectFromOneToTen()
2424
}
2525
}
2626

27+
[Test]
28+
public void ShouldSelectFromOneToTenWithCount()
29+
{
30+
var db = Database.Opener.OpenFile(DatabasePath);
31+
Promise<int> count;
32+
var query = db.PagingTest.QueryById(1.to(100)).WithTotalCount(out count).Take(10);
33+
int index = 1;
34+
foreach (var row in query)
35+
{
36+
Assert.AreEqual(index, row.Id);
37+
index++;
38+
}
39+
Assert.IsTrue(count.HasValue);
40+
Assert.AreEqual(100, count.Value);
41+
}
42+
2743
[Test]
2844
public void ShouldSelectFromElevenToTwenty()
2945
{

Simple.Data.SqlTest/SchemaTests/DatabaseSchemaTests.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Data.SqlClient;
23
using System.IO;
34
using System.Linq;
45
using System.Reflection;
@@ -61,5 +62,29 @@ public void TestIdentityIsFalseWhenItShouldBe()
6162
var column = Schema.FindTable("Customers").FindColumn("Name");
6263
Assert.IsFalse(column.IsIdentity);
6364
}
65+
66+
[Test]
67+
public void TestNewTableIsAddedToSchemaAfterReset()
68+
{
69+
dynamic db = GetDatabase();
70+
db.Users.FindById(1); // Forces population of schema...
71+
72+
using (var cn = new SqlConnection(Properties.Settings.Default.ConnectionString))
73+
using (var cmd = cn.CreateCommand())
74+
{
75+
cn.Open();
76+
77+
cmd.CommandText = @"IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[RuntimeTable]') AND type in (N'U'))
78+
DROP TABLE [dbo].[RuntimeTable]";
79+
cmd.ExecuteNonQuery();
80+
cmd.CommandText = "CREATE TABLE [dbo].[RuntimeTable] ([Id] int)";
81+
cmd.ExecuteNonQuery();
82+
}
83+
84+
db.GetAdapter().Reset();
85+
db.RuntimeTable.Insert(Id: 1);
86+
var row = db.RuntimeTable.FindById(1);
87+
Assert.AreEqual(1, row.Id);
88+
}
6489
}
6590
}

Simple.Data/Adapter.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,5 +278,14 @@ protected static SimpleExpression GetCriteria(string tableName, IEnumerable<stri
278278
}
279279
return ExpressionHelper.CriteriaDictionaryToExpression(tableName, criteria);
280280
}
281+
282+
public void Reset()
283+
{
284+
OnReset();
285+
}
286+
287+
protected virtual void OnReset()
288+
{
289+
}
281290
}
282291
}

Simple.Data/CachingAdapterFactory.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,10 @@ private static string HashSettings(string adapterName, IEnumerable<KeyValuePair<
4242
return adapterName +
4343
string.Join("#", settings.Select(kvp => kvp.Key + "=" + kvp.Value));
4444
}
45+
46+
public void Reset()
47+
{
48+
_cache.Clear();
49+
}
4550
}
4651
}

Simple.Data/Database.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System;
2-
using System.Collections.Concurrent;
32
using System.Collections.Generic;
43
using System.Dynamic;
54
using System.Linq;
@@ -16,7 +15,6 @@ public partial class Database : DataStrategy
1615
{
1716
private static readonly IDatabaseOpener DatabaseOpener;
1817
private static IPluralizer _pluralizer;
19-
private readonly ConcurrentDictionary<string, dynamic> _members = new ConcurrentDictionary<string, dynamic>();
2018
private readonly Adapter _adapter;
2119

2220
static Database()
@@ -164,5 +162,10 @@ public static void SetPluralizer(IPluralizer pluralizer)
164162
_pluralizer = pluralizer;
165163
Extensions.StringExtensions.SetPluralizer(pluralizer);
166164
}
165+
166+
public static void ClearAdapterCache()
167+
{
168+
DatabaseOpener.ClearAdapterCache();
169+
}
167170
}
168171
}

0 commit comments

Comments
 (0)