Skip to content

Commit 07d99c1

Browse files
committed
Integrated new batcher in Future
1 parent 0481f87 commit 07d99c1

File tree

14 files changed

+367
-12
lines changed

14 files changed

+367
-12
lines changed

src/NHibernate.Test/Async/Futures/LinqFutureFixture.cs

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,5 +412,97 @@ public async Task UsingManyParametersAndQueries_DoesNotCauseParameterNameCollisi
412412
await (tx.CommitAsync());
413413
}
414414
}
415+
416+
[Test]
417+
public async Task FutureCombineCachedAndNonCachedQueriesAsync()
418+
{
419+
using (var s = OpenSession())
420+
using (var tx = s.BeginTransaction())
421+
{
422+
var p1 = new Person
423+
{
424+
Name = "Person name",
425+
Age = 15
426+
};
427+
var p2 = new Person
428+
{
429+
Name = "Person name",
430+
Age = 20
431+
};
432+
433+
await (s.SaveAsync(p1));
434+
await (s.SaveAsync(p2));
435+
await (tx.CommitAsync());
436+
}
437+
438+
using (var s = Sfi.OpenSession())
439+
{
440+
var list = new List<IFutureEnumerable<Person>>();
441+
for (var i = 0; i < 5; i++)
442+
{
443+
var i1 = i;
444+
var query = s.Query<Person>().Where(x => x.Age > i1);
445+
list.Add(query.WithOptions(x => x.SetCacheable(true)).ToFuture());
446+
}
447+
448+
foreach (var query in list)
449+
{
450+
var result = (await (query.GetEnumerableAsync())).ToList();
451+
Assert.That(result.Count, Is.EqualTo(2));
452+
}
453+
}
454+
455+
//Check query.List returns data from cache
456+
Sfi.Statistics.IsStatisticsEnabled = true;
457+
using (var s = Sfi.OpenSession())
458+
{
459+
var list = new List<IEnumerable<Person>>();
460+
for (var i = 0; i < 5; i++)
461+
{
462+
var i1 = i;
463+
var query = s.Query<Person>().Where(x => x.Age > i1);
464+
465+
list.Add(await (query.WithOptions(x => x.SetCacheable(true)).ToListAsync()));
466+
}
467+
468+
foreach (var query in list)
469+
{
470+
var result = query.ToList();
471+
Assert.That(result.Count, Is.EqualTo(2));
472+
}
473+
474+
Assert.That(Sfi.Statistics.PrepareStatementCount, Is.EqualTo(0), "Queries must be retrieved from cache");
475+
}
476+
477+
//Check another Future returns data from cache
478+
Sfi.Statistics.Clear();
479+
using (var s = Sfi.OpenSession())
480+
{
481+
var list = new List<IFutureEnumerable<Person>>();
482+
//Reverse order of queries added to cache
483+
for (var i = 5 - 1; i >= 0; i--)
484+
{
485+
var i1 = i;
486+
var query = s.Query<Person>().Where(x => x.Age > i1);
487+
488+
list.Add(query.WithOptions(x => x.SetCacheable(true)).ToFuture());
489+
}
490+
491+
foreach (var query in list)
492+
{
493+
var result = (await (query.GetEnumerableAsync())).ToList();
494+
Assert.That(result.Count, Is.EqualTo(2));
495+
}
496+
497+
Assert.That(Sfi.Statistics.PrepareStatementCount , Is.EqualTo(0), "Future queries must be retrieved from cache");
498+
}
499+
500+
using (var s = OpenSession())
501+
using (var tx = s.BeginTransaction())
502+
{
503+
await (s.DeleteAsync("from Person"));
504+
await (tx.CommitAsync());
505+
}
506+
}
415507
}
416508
}

src/NHibernate.Test/Async/Futures/MultiAnyQuerytBatchFixture.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,33 @@ public class MultiAnyQuerytBatchFixtureAsync : TestCaseMappingByCode
2828
private Guid _parentId;
2929
private Guid _eagerId;
3030

31+
[Test]
32+
public async Task CanCombineCriteriaAndHqlInFutureAsync()
33+
{
34+
using (var sqlLog = new SqlLogSpy())
35+
using (var session = OpenSession())
36+
{
37+
var future1 = session.QueryOver<EntityComplex>()
38+
.Where(x => x.Version >= 0)
39+
.TransformUsing(new ListTransformerToInt()).Future<int>();
40+
41+
var future2 = session.Query<EntityComplex>().Where(ec => ec.Version > 2).ToFuture();
42+
var future3 = session.Query<EntitySimpleChild>().Select(sc => sc.Name).ToFuture();
43+
44+
var future4 = session
45+
.Query<EntitySimpleChild>()
46+
.ToFutureValue(sc => sc.FirstOrDefault());
47+
48+
Assert.That((await (future1.GetEnumerableAsync())).Count(), Is.GreaterThan(0), "Empty results are not expected");
49+
Assert.That((await (future2.GetEnumerableAsync())).Count(), Is.EqualTo(0), "This query should not return results");
50+
Assert.That((await (future3.GetEnumerableAsync())).Count(), Is.GreaterThan(1), "Empty results are not expected");
51+
Assert.That(await (future4.GetValueAsync()), Is.Not.Null, "Loaded entity should not be null");
52+
53+
if (SupportsMultipleQueries)
54+
Assert.That(sqlLog.Appender.GetEvents().Length, Is.EqualTo(1));
55+
}
56+
}
57+
3158
[Test]
3259
public async Task CanCombineCriteriaAndHqlInBatchAsync()
3360
{

src/NHibernate.Test/Async/NHSpecificTest/NH1989/Fixture.cs

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,6 @@ public async Task SecondLevelCacheWithMixedCacheableAndNonCacheableFutureAsync()
163163
.SetCacheable(true)
164164
.FutureValue<User>();
165165

166-
// non cacheable Future causes batch to be non-cacheable
167166
int count =
168167
await (s.CreateCriteria<User>()
169168
.SetProjection(Projections.RowCount())
@@ -190,7 +189,9 @@ public async Task SecondLevelCacheWithMixedCacheableAndNonCacheableFutureAsync()
190189
.FutureValue<int>()
191190
.GetValueAsync());
192191

193-
Assert.That(await (userFuture.GetValueAsync()), Is.Null,
192+
Assert.That(await (userFuture.GetValueAsync()), Is.Not.Null,
193+
"query results should come from cache");
194+
Assert.That(count, Is.EqualTo(0),
194195
"query results should not come from cache");
195196
}
196197
}
@@ -216,7 +217,6 @@ public async Task SecondLevelCacheWithMixedCacheRegionsFutureAsync()
216217
.SetCacheRegion("region1")
217218
.FutureValue<User>();
218219

219-
// different cache-region causes batch to be non-cacheable
220220
int count =
221221
await (s.CreateCriteria<User>()
222222
.SetProjection(Projections.RowCount())
@@ -240,6 +240,13 @@ public async Task SecondLevelCacheWithMixedCacheRegionsFutureAsync()
240240
.SetCacheRegion("region1")
241241
.FutureValue<User>();
242242

243+
IFutureValue<User> userFutureWrongRegion =
244+
s.CreateCriteria<User>()
245+
.Add(Restrictions.NaturalId().Set("Name", "test"))
246+
.SetCacheable(true)
247+
.SetCacheRegion("region2")
248+
.FutureValue<User>();
249+
243250
int count =
244251
await (s.CreateCriteria<User>()
245252
.SetProjection(Projections.RowCount())
@@ -248,8 +255,23 @@ public async Task SecondLevelCacheWithMixedCacheRegionsFutureAsync()
248255
.FutureValue<int>()
249256
.GetValueAsync());
250257

251-
Assert.That(await (userFuture.GetValueAsync()), Is.Null,
252-
"query results should not come from cache");
258+
int countWrongRegion =
259+
await (s.CreateCriteria<User>()
260+
.SetProjection(Projections.RowCount())
261+
.SetCacheable(true)
262+
.SetCacheRegion("region1")
263+
.FutureValue<int>()
264+
.GetValueAsync());
265+
266+
Assert.That(await (userFuture.GetValueAsync()), Is.Not.Null,
267+
"query results should come from cache");
268+
Assert.That(count, Is.EqualTo(1),
269+
"query results should come from cache");
270+
271+
Assert.That(await (userFutureWrongRegion.GetValueAsync()), Is.Null,
272+
"query results from wrong cache region");
273+
Assert.That(countWrongRegion, Is.EqualTo(0),
274+
"query results from wrong cache region");
253275
}
254276
}
255277

src/NHibernate.Test/Futures/LinqFutureFixture.cs

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,5 +401,97 @@ public void UsingManyParametersAndQueries_DoesNotCauseParameterNameCollisions()
401401
tx.Commit();
402402
}
403403
}
404+
405+
[Test]
406+
public void FutureCombineCachedAndNonCachedQueries()
407+
{
408+
using (var s = OpenSession())
409+
using (var tx = s.BeginTransaction())
410+
{
411+
var p1 = new Person
412+
{
413+
Name = "Person name",
414+
Age = 15
415+
};
416+
var p2 = new Person
417+
{
418+
Name = "Person name",
419+
Age = 20
420+
};
421+
422+
s.Save(p1);
423+
s.Save(p2);
424+
tx.Commit();
425+
}
426+
427+
using (var s = Sfi.OpenSession())
428+
{
429+
var list = new List<IFutureEnumerable<Person>>();
430+
for (var i = 0; i < 5; i++)
431+
{
432+
var i1 = i;
433+
var query = s.Query<Person>().Where(x => x.Age > i1);
434+
list.Add(query.WithOptions(x => x.SetCacheable(true)).ToFuture());
435+
}
436+
437+
foreach (var query in list)
438+
{
439+
var result = query.GetEnumerable().ToList();
440+
Assert.That(result.Count, Is.EqualTo(2));
441+
}
442+
}
443+
444+
//Check query.List returns data from cache
445+
Sfi.Statistics.IsStatisticsEnabled = true;
446+
using (var s = Sfi.OpenSession())
447+
{
448+
var list = new List<IEnumerable<Person>>();
449+
for (var i = 0; i < 5; i++)
450+
{
451+
var i1 = i;
452+
var query = s.Query<Person>().Where(x => x.Age > i1);
453+
454+
list.Add(query.WithOptions(x => x.SetCacheable(true)).ToList());
455+
}
456+
457+
foreach (var query in list)
458+
{
459+
var result = query.ToList();
460+
Assert.That(result.Count, Is.EqualTo(2));
461+
}
462+
463+
Assert.That(Sfi.Statistics.PrepareStatementCount, Is.EqualTo(0), "Queries must be retrieved from cache");
464+
}
465+
466+
//Check another Future returns data from cache
467+
Sfi.Statistics.Clear();
468+
using (var s = Sfi.OpenSession())
469+
{
470+
var list = new List<IFutureEnumerable<Person>>();
471+
//Reverse order of queries added to cache
472+
for (var i = 5 - 1; i >= 0; i--)
473+
{
474+
var i1 = i;
475+
var query = s.Query<Person>().Where(x => x.Age > i1);
476+
477+
list.Add(query.WithOptions(x => x.SetCacheable(true)).ToFuture());
478+
}
479+
480+
foreach (var query in list)
481+
{
482+
var result = query.GetEnumerable().ToList();
483+
Assert.That(result.Count, Is.EqualTo(2));
484+
}
485+
486+
Assert.That(Sfi.Statistics.PrepareStatementCount , Is.EqualTo(0), "Future queries must be retrieved from cache");
487+
}
488+
489+
using (var s = OpenSession())
490+
using (var tx = s.BeginTransaction())
491+
{
492+
s.Delete("from Person");
493+
tx.Commit();
494+
}
495+
}
404496
}
405497
}

src/NHibernate.Test/Futures/MultiAnyQuerytBatchFixture.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,33 @@ public class MultiAnyQuerytBatchFixture : TestCaseMappingByCode
1717
private Guid _parentId;
1818
private Guid _eagerId;
1919

20+
[Test]
21+
public void CanCombineCriteriaAndHqlInFuture()
22+
{
23+
using (var sqlLog = new SqlLogSpy())
24+
using (var session = OpenSession())
25+
{
26+
var future1 = session.QueryOver<EntityComplex>()
27+
.Where(x => x.Version >= 0)
28+
.TransformUsing(new ListTransformerToInt()).Future<int>();
29+
30+
var future2 = session.Query<EntityComplex>().Where(ec => ec.Version > 2).ToFuture();
31+
var future3 = session.Query<EntitySimpleChild>().Select(sc => sc.Name).ToFuture();
32+
33+
var future4 = session
34+
.Query<EntitySimpleChild>()
35+
.ToFutureValue(sc => sc.FirstOrDefault());
36+
37+
Assert.That(future1.GetEnumerable().Count(), Is.GreaterThan(0), "Empty results are not expected");
38+
Assert.That(future2.GetEnumerable().Count(), Is.EqualTo(0), "This query should not return results");
39+
Assert.That(future3.GetEnumerable().Count(), Is.GreaterThan(1), "Empty results are not expected");
40+
Assert.That(future4.Value, Is.Not.Null, "Loaded entity should not be null");
41+
42+
if (SupportsMultipleQueries)
43+
Assert.That(sqlLog.Appender.GetEvents().Length, Is.EqualTo(1));
44+
}
45+
}
46+
2047
[Test]
2148
public void CanCombineCriteriaAndHqlInBatch()
2249
{

src/NHibernate.Test/NHSpecificTest/NH1989/Fixture.cs

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,6 @@ public void SecondLevelCacheWithMixedCacheableAndNonCacheableFuture()
151151
.SetCacheable(true)
152152
.FutureValue<User>();
153153

154-
// non cacheable Future causes batch to be non-cacheable
155154
int count =
156155
s.CreateCriteria<User>()
157156
.SetProjection(Projections.RowCount())
@@ -178,7 +177,9 @@ public void SecondLevelCacheWithMixedCacheableAndNonCacheableFuture()
178177
.FutureValue<int>()
179178
.Value;
180179

181-
Assert.That(userFuture.Value, Is.Null,
180+
Assert.That(userFuture.Value, Is.Not.Null,
181+
"query results should come from cache");
182+
Assert.That(count, Is.EqualTo(0),
182183
"query results should not come from cache");
183184
}
184185
}
@@ -204,7 +205,6 @@ public void SecondLevelCacheWithMixedCacheRegionsFuture()
204205
.SetCacheRegion("region1")
205206
.FutureValue<User>();
206207

207-
// different cache-region causes batch to be non-cacheable
208208
int count =
209209
s.CreateCriteria<User>()
210210
.SetProjection(Projections.RowCount())
@@ -228,6 +228,13 @@ public void SecondLevelCacheWithMixedCacheRegionsFuture()
228228
.SetCacheRegion("region1")
229229
.FutureValue<User>();
230230

231+
IFutureValue<User> userFutureWrongRegion =
232+
s.CreateCriteria<User>()
233+
.Add(Restrictions.NaturalId().Set("Name", "test"))
234+
.SetCacheable(true)
235+
.SetCacheRegion("region2")
236+
.FutureValue<User>();
237+
231238
int count =
232239
s.CreateCriteria<User>()
233240
.SetProjection(Projections.RowCount())
@@ -236,8 +243,23 @@ public void SecondLevelCacheWithMixedCacheRegionsFuture()
236243
.FutureValue<int>()
237244
.Value;
238245

239-
Assert.That(userFuture.Value, Is.Null,
240-
"query results should not come from cache");
246+
int countWrongRegion =
247+
s.CreateCriteria<User>()
248+
.SetProjection(Projections.RowCount())
249+
.SetCacheable(true)
250+
.SetCacheRegion("region1")
251+
.FutureValue<int>()
252+
.Value;
253+
254+
Assert.That(userFuture.Value, Is.Not.Null,
255+
"query results should come from cache");
256+
Assert.That(count, Is.EqualTo(1),
257+
"query results should come from cache");
258+
259+
Assert.That(userFutureWrongRegion.Value, Is.Null,
260+
"query results from wrong cache region");
261+
Assert.That(countWrongRegion, Is.EqualTo(0),
262+
"query results from wrong cache region");
241263
}
242264
}
243265

0 commit comments

Comments
 (0)