Skip to content

Commit 259d08a

Browse files
committed
Defer handling of WithCount to adapter; renamed Future to Promise (better semantics)
1 parent e9c1a3c commit 259d08a

File tree

10 files changed

+171
-72
lines changed

10 files changed

+171
-72
lines changed

Simple.Data.Ado/AdoAdapter.cs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,16 +95,29 @@ public override IEnumerable<IDictionary<string, object>> Find(string tableName,
9595

9696
public override IEnumerable<IDictionary<string, object>> RunQuery(SimpleQuery query, out IEnumerable<SimpleQueryClauseBase> unhandledClauses)
9797
{
98+
if (query.Clauses.OfType<WithCountClause>().Any()) return RunQueryWithCount(query, out unhandledClauses);
99+
98100
var connection = _connectionProvider.CreateConnection();
99101
return new QueryBuilder(this).Build(query, out unhandledClauses)
100102
.GetCommand(connection)
101103
.ToEnumerable(connection);
102104
}
103105

104-
private IEnumerable<IDictionary<string, object>> RunQueryWithCount(SimpleQuery query, WithCountClause withCountClause, out IEnumerable<SimpleQueryClauseBase> unhandledClauses)
106+
private IEnumerable<IDictionary<string, object>> RunQueryWithCount(SimpleQuery query, out IEnumerable<SimpleQueryClauseBase> unhandledClauses)
105107
{
108+
WithCountClause withCountClause;
109+
try
110+
{
111+
withCountClause = query.Clauses.OfType<WithCountClause>().First();
112+
}
113+
catch (InvalidOperationException)
114+
{
115+
// Rethrow with meaning.
116+
throw new InvalidOperationException("No WithCountClause specified.");
117+
}
118+
106119
var countQuery = query.ClearSkip().ClearTake().Select(new CountSpecialReference());
107-
var unhandledClausesList = new List<IEnumerable<SimpleQueryClauseBase>>(2);
120+
var unhandledClausesList = new List<IEnumerable<SimpleQueryClauseBase>> { Enumerable.Empty<SimpleQueryClauseBase>(), Enumerable.Empty<SimpleQueryClauseBase>() };
108121
using (var enumerator = RunQueries(new[] { countQuery, query }, unhandledClausesList).GetEnumerator())
109122
{
110123
unhandledClauses = unhandledClausesList[1];

Simple.Data.BehaviourTest/Query/WithCountTest.cs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ protected override void SetSchema(MockSchemaProvider schemaProvider)
2020
}
2121

2222
[Test]
23-
public void WithTotalCountShouldCreateCompoundQuery()
23+
public void WithTotalCountShouldCreateCompoundQuery_ObsoleteFutureVersion()
2424
{
2525
const string expected = @"select count(*) from [dbo].[users] where [dbo].[users].[name] = @p1_c0; " +
2626
@"select [dbo].[users].[name],[dbo].[users].[password] from [dbo].[users] where [dbo].[users].[name] = @p1_c1";
@@ -31,6 +31,20 @@ public void WithTotalCountShouldCreateCompoundQuery()
3131

3232
EatException<InvalidOperationException>(() => q.ToList());
3333

34+
GeneratedSqlIs(expected);
35+
}
36+
[Test]
37+
public void WithTotalCountShouldCreateCompoundQuery()
38+
{
39+
const string expected = @"select count(*) from [dbo].[users] where [dbo].[users].[name] = @p1_c0; " +
40+
@"select [dbo].[users].[name],[dbo].[users].[password] from [dbo].[users] where [dbo].[users].[name] = @p1_c1";
41+
42+
Promise<int> count;
43+
var q = _db.Users.QueryByName("Foo")
44+
.WithTotalCount(out count);
45+
46+
EatException<InvalidOperationException>(() => q.ToList());
47+
3448
GeneratedSqlIs(expected);
3549
}
3650
}

Simple.Data.SqlTest/QueryTest.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,21 @@ public void ShouldSelectFromOneHundredToNinetyOne()
120120

121121
[Test]
122122
public void WithTotalCountShouldGiveCount()
123+
{
124+
Promise<int> count;
125+
var db = DatabaseHelper.Open();
126+
var list = db.PagingTest.QueryById(1.to(50))
127+
.WithTotalCount(out count)
128+
.Take(10)
129+
.ToList();
130+
131+
Assert.AreEqual(10, list.Count);
132+
Assert.IsTrue(count.HasValue);
133+
Assert.AreEqual(50, count);
134+
}
135+
136+
[Test]
137+
public void WithTotalCountShouldGiveCount_ObsoleteFutureVersion()
123138
{
124139
Future<int> count;
125140
var db = DatabaseHelper.Open();
Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,40 +9,40 @@ namespace Simple.Data.UnitTest
99
using NUnit.Framework;
1010

1111
[TestFixture]
12-
public class FutureTest
12+
public class PromiseTest
1313
{
1414
[Test]
15-
public void FutureShouldHaveHasValueFalseWhenCreated()
15+
public void PromiseShouldHaveHasValueFalseWhenCreated()
1616
{
1717
Action<int> setAction;
18-
var actual = Future<int>.Create(out setAction);
18+
var actual = Promise<int>.Create(out setAction);
1919
Assert.IsFalse(actual.HasValue);
2020
}
2121

2222
[Test]
23-
public void FutureShouldHaveValueAfterSetActionIsCalled()
23+
public void PromiseShouldHaveValueAfterSetActionIsCalled()
2424
{
2525
Action<int> setAction;
26-
var actual = Future<int>.Create(out setAction);
26+
var actual = Promise<int>.Create(out setAction);
2727
setAction(42);
2828
Assert.IsTrue(actual.HasValue);
2929
Assert.AreEqual(42, actual.Value);
3030
}
3131

3232
[Test]
33-
public void FutureShouldImplicitlyCastToType()
33+
public void PromiseShouldImplicitlyCastToType()
3434
{
3535
Action<int> setAction;
36-
var actual = Future<int>.Create(out setAction);
36+
var actual = Promise<int>.Create(out setAction);
3737
setAction(42);
3838
Assert.AreEqual(42, actual);
3939
}
4040

4141
[Test]
42-
public void FutureShouldSpinWhenValueAccessedButNotSet()
42+
public void PromiseShouldSpinWhenValueAccessedButNotSet()
4343
{
4444
Action<int> setAction;
45-
var actual = Future<int>.Create(out setAction);
45+
var actual = Promise<int>.Create(out setAction);
4646
using (new Timer(_ => setAction(42), null, 100, Timeout.Infinite))
4747
{
4848
Assert.AreEqual(42, actual.Value);

Simple.Data.UnitTest/Simple.Data.UnitTest.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@
7777
<Compile Include="DynamicReferenceTest.cs" />
7878
<Compile Include="DynamicTableTest.cs" />
7979
<Compile Include="ExpressionHelperTest.cs" />
80-
<Compile Include="FutureTest.cs" />
80+
<Compile Include="PromiseTest.cs" />
8181
<Compile Include="ListHelper.cs" />
8282
<Compile Include="MathReferenceTest.cs" />
8383
<Compile Include="MaybeTest.cs" />

Simple.Data/Future1.cs

Lines changed: 52 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,52 @@
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.Threading;
9-
10-
public class Future<T>
11-
{
12-
private T _value;
13-
private bool _hasValue;
14-
15-
private Future()
16-
{
17-
18-
}
19-
20-
public T Value
21-
{
22-
get
23-
{
24-
SpinWait.SpinUntil(() => _hasValue);
25-
return _value;
26-
}
27-
}
28-
29-
public bool HasValue
30-
{
31-
get { return _hasValue; }
32-
}
33-
34-
private void Set(T value)
35-
{
36-
_value = value;
37-
_hasValue = true;
38-
}
39-
40-
public static Future<T> Create(out Action<T> setAction)
41-
{
42-
var future = new Future<T>();
43-
setAction = future.Set;
44-
return future;
45-
}
46-
47-
public static implicit operator T(Future<T> future)
48-
{
49-
return future.Value;
50-
}
51-
}
52-
}
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.Threading;
9+
10+
public class Future<T>
11+
{
12+
private T _value;
13+
private bool _hasValue;
14+
15+
private Future()
16+
{
17+
18+
}
19+
20+
public T Value
21+
{
22+
get
23+
{
24+
SpinWait.SpinUntil(() => _hasValue);
25+
return _value;
26+
}
27+
}
28+
29+
public bool HasValue
30+
{
31+
get { return _hasValue; }
32+
}
33+
34+
private void Set(T value)
35+
{
36+
_value = value;
37+
_hasValue = true;
38+
}
39+
40+
public static Future<T> Create(out Action<T> setAction)
41+
{
42+
var future = new Future<T>();
43+
setAction = future.Set;
44+
return future;
45+
}
46+
47+
public static implicit operator T(Future<T> future)
48+
{
49+
return future.Value;
50+
}
51+
}
52+
}

Simple.Data/Promise.cs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
using System;
2+
using System.Threading;
3+
4+
namespace Simple.Data
5+
{
6+
public class Promise<T>
7+
{
8+
private T _value;
9+
private bool _hasValue;
10+
11+
private Promise()
12+
{
13+
14+
}
15+
16+
public T Value
17+
{
18+
get
19+
{
20+
SpinWait.SpinUntil(() => _hasValue);
21+
return _value;
22+
}
23+
}
24+
25+
public bool HasValue
26+
{
27+
get { return _hasValue; }
28+
}
29+
30+
private void Set(T value)
31+
{
32+
_value = value;
33+
_hasValue = true;
34+
}
35+
36+
public static Promise<T> Create(out Action<T> setAction)
37+
{
38+
var future = new Promise<T>();
39+
setAction = future.Set;
40+
return future;
41+
}
42+
43+
public static implicit operator T(Promise<T> future)
44+
{
45+
return future.Value;
46+
}
47+
}
48+
}

Simple.Data/Simple.Data.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@
9595
<Compile Include="Maybe.cs" />
9696
<Compile Include="OrderByClause.cs" />
9797
<Compile Include="OrderByDirection.cs" />
98+
<Compile Include="Promise.cs" />
9899
<Compile Include="Range.cs" />
99100
<Compile Include="Range1.cs" />
100101
<Compile Include="SelectClause.cs" />

Simple.Data/SimpleQuery.cs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -185,10 +185,10 @@ public SimpleQuery ClearTake()
185185

186186
protected IEnumerable<dynamic> Run()
187187
{
188-
if (_clauses.OfType<WithCountClause>().Any())
189-
{
190-
return RunWithCount();
191-
}
188+
//if (_clauses.OfType<WithCountClause>().Any())
189+
//{
190+
// return RunWithCount();
191+
//}
192192
IEnumerable<SimpleQueryClauseBase> unhandledClauses;
193193
return
194194
_adapter.RunQuery(this, out unhandledClauses).Select(d => new SimpleRecord(d, _tableName, _dataStrategy));
@@ -266,13 +266,21 @@ public SimpleQuery On(SimpleExpression joinExpression)
266266
return AddNewJoin(new JoinClause(_tempJoinWaitingForOn.Table, joinExpression));
267267
}
268268

269+
[Obsolete]
269270
public SimpleQuery WithTotalCount(out Future<int> count)
270271
{
271272
Action<int> setCount;
272273
count = Future<int>.Create(out setCount);
273274
return new SimpleQuery(this, _clauses.Append(new WithCountClause(setCount)));
274275
}
275276

277+
public SimpleQuery WithTotalCount(out Promise<int> count)
278+
{
279+
Action<int> setCount;
280+
count = Promise<int>.Create(out setCount);
281+
return new SimpleQuery(this, _clauses.Append(new WithCountClause(setCount)));
282+
}
283+
276284
private SimpleQuery ParseJoin(InvokeMemberBinder binder, object[] args)
277285
{
278286
var tableToJoin = args[0] as ObjectReference;

Simple.Data/WithCountClause.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ public WithCountClause(Action<int> setCount)
1111
_setCount = setCount;
1212
}
1313

14-
public Action<int> SetCount
15-
{
16-
get { return _setCount; }
14+
public void SetCount(int count)
15+
{
16+
_setCount(count);
1717
}
1818
}
1919
}

0 commit comments

Comments
 (0)