Skip to content

Commit 0bf7921

Browse files
Generate async files
1 parent 94aa1de commit 0bf7921

File tree

2 files changed

+132
-59
lines changed

2 files changed

+132
-59
lines changed

src/NHibernate.Test/Async/SqlTest/Query/NativeSQLQueriesFixture.cs

Lines changed: 66 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@
1010

1111
using System.Collections;
1212
using System.Linq;
13+
using NHibernate.Criterion;
14+
using NHibernate.Multi;
1315
using NHibernate.Transform;
1416
using NUnit.Framework;
15-
using NHibernate.Criterion;
1617

1718
namespace NHibernate.Test.SqlTest.Query
1819
{
@@ -62,6 +63,20 @@ protected override string MappingsAssembly
6263
get { return "NHibernate.Test"; }
6364
}
6465

66+
protected override void OnTearDown()
67+
{
68+
using (var session = OpenSession())
69+
using (var transaction = session.BeginTransaction())
70+
{
71+
session.CreateQuery("delete from Employment").ExecuteUpdate();
72+
session.CreateQuery("delete from System.Object").ExecuteUpdate();
73+
74+
transaction.Commit();
75+
}
76+
77+
Sfi.QueryCache.Clear();
78+
}
79+
6580
[Test]
6681
public async Task FailOnNoAddEntityOrScalarAsync()
6782
{
@@ -136,18 +151,6 @@ public async Task SQLQueryInterfaceAsync()
136151
await (t.CommitAsync());
137152
s.Close();
138153
}
139-
140-
using (var s = OpenSession())
141-
using (var t = s.BeginTransaction())
142-
{
143-
await (s.DeleteAsync(emp));
144-
await (s.DeleteAsync(gavin));
145-
await (s.DeleteAsync(ifa));
146-
await (s.DeleteAsync(jboss));
147-
148-
await (t.CommitAsync());
149-
s.Close();
150-
}
151154
}
152155

153156
[Test]
@@ -202,18 +205,6 @@ public async Task SQLQueryInterfaceCacheableAsync()
202205
await (t.CommitAsync());
203206
s.Close();
204207
}
205-
206-
using (var s = OpenSession())
207-
using (var t = s.BeginTransaction())
208-
{
209-
await (s.DeleteAsync(emp));
210-
await (s.DeleteAsync(gavin));
211-
await (s.DeleteAsync(ifa));
212-
await (s.DeleteAsync(jboss));
213-
214-
await (t.CommitAsync());
215-
s.Close();
216-
}
217208
}
218209

219210
[Test(Description = "GH-2904")]
@@ -270,20 +261,11 @@ Task<IList> GetCacheableSqlQueryResultsAsync()
270261
Assert.That(Sfi.Statistics.QueryCacheHitCount, Is.EqualTo(1), "results are expected from cache");
271262
}
272263
}
273-
274-
using (var s = OpenSession())
275-
using (var t = s.BeginTransaction())
276-
{
277-
await (s.DeleteAsync(emp));
278-
await (s.DeleteAsync(gavin));
279-
await (s.DeleteAsync(ifa));
280-
await (s.DeleteAsync(jboss));
281-
await (t.CommitAsync());
282-
}
283264
}
284265

285266
class ResultDto
286267
{
268+
public long orgId { get; set; }
287269
public string regionCode { get; set; }
288270
}
289271

@@ -312,23 +294,64 @@ async Task AssertQueryAsync(bool fromCache)
312294
.ListAsync());
313295
await (t.CommitAsync());
314296

315-
Assert.AreEqual(1, l.Count);
316-
//TODO: Uncomment if we properly fix caching auto discovery type queries with transformers
317-
// var msg = "results are expected from " + (fromCache ? "cache" : "DB");
318-
// Assert.That(Sfi.Statistics.QueryCacheMissCount, Is.EqualTo(fromCache ? 0 : 1), msg);
319-
// Assert.That(Sfi.Statistics.QueryCacheHitCount, Is.EqualTo(fromCache ? 1 : 0), msg);
297+
Assert.That(l.Count, Is.EqualTo(1));
298+
var msg = "Results are expected from " + (fromCache ? "cache" : "DB");
299+
Assert.That(Sfi.Statistics.QueryCacheMissCount, Is.EqualTo(fromCache ? 0 : 1), msg);
300+
Assert.That(Sfi.Statistics.QueryCacheHitCount, Is.EqualTo(fromCache ? 1 : 0), msg);
320301
}
321302
}
322303

323304
await (AssertQueryAsync(false));
324305
await (AssertQueryAsync(true));
306+
}
325307

326-
using (var s = OpenSession())
327-
using (var t = s.BeginTransaction())
308+
[Test(Description = "GH-3169")]
309+
public async Task CacheableScalarSQLMultiQueryWithTransformerAsync()
310+
{
311+
Organization ifa = new Organization("IFA");
312+
313+
using (ISession s = OpenSession())
314+
using (ITransaction t = s.BeginTransaction())
328315
{
329-
await (s.DeleteAsync(ifa));
316+
await (s.SaveAsync(ifa));
330317
await (t.CommitAsync());
331318
}
319+
320+
async Task AssertQueryAsync(bool fromCache)
321+
{
322+
using (var s = OpenSession())
323+
using (var t = s.BeginTransaction())
324+
using (EnableStatisticsScope())
325+
{
326+
var q1 = s.CreateSQLQuery("select org.NAME as regionCode from ORGANIZATION org")
327+
.AddScalar("regionCode", NHibernateUtil.String)
328+
.SetResultTransformer(Transformers.AliasToBean<ResultDto>())
329+
.SetCacheable(true);
330+
var q2 = s.CreateSQLQuery("select org.ORGID as orgId from ORGANIZATION org")
331+
.AddScalar("orgId", NHibernateUtil.Int64)
332+
.SetResultTransformer(Transformers.AliasToBean<ResultDto>())
333+
.SetCacheable(true);
334+
335+
var batch = s.CreateQueryBatch();
336+
batch.Add<ResultDto>(q1);
337+
batch.Add<ResultDto>(q2);
338+
await (batch.ExecuteAsync());
339+
340+
var l1 = await (batch.GetResultAsync<ResultDto>(0));
341+
var l2 = await (batch.GetResultAsync<ResultDto>(1));
342+
343+
await (t.CommitAsync());
344+
345+
Assert.That(l1.Count, Is.EqualTo(1), "Unexpected results count for the first query.");
346+
Assert.That(l2.Count, Is.EqualTo(1), "Unexpected results count for the second query.");
347+
var msg = "Results are expected from " + (fromCache ? "cache" : "DB");
348+
Assert.That(Sfi.Statistics.QueryCacheMissCount, Is.EqualTo(fromCache ? 0 : 2), msg);
349+
Assert.That(Sfi.Statistics.QueryCacheHitCount, Is.EqualTo(fromCache ? 2 : 0), msg);
350+
}
351+
}
352+
353+
await (AssertQueryAsync(false));
354+
await (AssertQueryAsync(true));
332355
}
333356

334357
[Test]
@@ -356,11 +379,6 @@ public async Task ResultSetMappingDefinitionAsync()
356379
.ListAsync());
357380
Assert.AreEqual(l.Count, 1);
358381

359-
await (s.DeleteAsync(emp));
360-
await (s.DeleteAsync(gavin));
361-
await (s.DeleteAsync(ifa));
362-
await (s.DeleteAsync(jboss));
363-
364382
await (t.CommitAsync());
365383
s.Close();
366384
}
@@ -443,8 +461,6 @@ public async Task ScalarValuesAsync()
443461
Assert.AreEqual(o[1], "JBoss");
444462
Assert.AreEqual(o[0], idJBoss);
445463

446-
await (s.DeleteAsync(ifa));
447-
await (s.DeleteAsync(jboss));
448464
await (t.CommitAsync());
449465
s.Close();
450466
}

src/NHibernate/Async/Cache/StandardQueryCache.cs

Lines changed: 66 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
using System.Collections.Generic;
1414
using System.Linq;
1515
using NHibernate.Cfg;
16-
using NHibernate.Collection;
1716
using NHibernate.Engine;
1817
using NHibernate.Persister.Collection;
1918
using NHibernate.Type;
@@ -38,21 +37,25 @@ public Task ClearAsync(CancellationToken cancellationToken)
3837
}
3938

4039
/// <inheritdoc />
41-
public Task<bool> PutAsync(
40+
public async Task<bool> PutAsync(
4241
QueryKey key,
4342
QueryParameters queryParameters,
4443
ICacheAssembler[] returnTypes,
4544
IList result,
4645
ISessionImplementor session, CancellationToken cancellationToken)
4746
{
48-
if (cancellationToken.IsCancellationRequested)
49-
{
50-
return Task.FromCanceled<bool>(cancellationToken);
51-
}
47+
cancellationToken.ThrowIfCancellationRequested();
5248
// 6.0 TODO: inline the call.
5349
#pragma warning disable 612
54-
return PutAsync(key, returnTypes, result, queryParameters.NaturalKeyLookup, session, cancellationToken);
50+
var cached = await (PutAsync(key, returnTypes, result, queryParameters.NaturalKeyLookup, session, cancellationToken)).ConfigureAwait(false);
5551
#pragma warning restore 612
52+
53+
if (cached && key.ResultTransformer?.AutoDiscoverTypes == true && key.ResultTransformer.AutoDiscoveredAliases != null)
54+
{
55+
await (Cache.PutAsync(new QueryAliasesKey(key), key.ResultTransformer.AutoDiscoveredAliases, cancellationToken)).ConfigureAwait(false);
56+
}
57+
58+
return cached;
5659
}
5760

5861
// Since 5.2
@@ -93,8 +96,22 @@ public async Task<IList> GetAsync(
9396
{
9497
// 6.0 TODO: inline the call.
9598
#pragma warning disable 612
96-
return await (GetAsync(key, returnTypes, queryParameters.NaturalKeyLookup, spaces, session, cancellationToken)).ConfigureAwait(false);
99+
var result = await (GetAsync(key, returnTypes, queryParameters.NaturalKeyLookup, spaces, session, cancellationToken)).ConfigureAwait(false);
97100
#pragma warning restore 612
101+
102+
if (result != null && key.ResultTransformer?.AutoDiscoverTypes == true && result.Count > 0)
103+
{
104+
var aliasesKey = new QueryAliasesKey(key);
105+
if (!(await (Cache.GetAsync(aliasesKey, cancellationToken)).ConfigureAwait(false) is string[] aliases))
106+
{
107+
// Cannot properly initialize the result transformer, treat it as a cache miss
108+
Log.Debug("query aliases were not found in cache: {0}", aliasesKey);
109+
return null;
110+
}
111+
key.ResultTransformer.SupplyAutoDiscoveredParameters(queryParameters.ResultTransformer, aliases);
112+
}
113+
114+
return result;
98115
}
99116
finally
100117
{
@@ -153,9 +170,16 @@ public async Task<bool[]> PutManyAsync(
153170
if (queryParameters[i].NaturalKeyLookup && result.Count == 0)
154171
continue;
155172

173+
var key = keys[i];
156174
cached[i] = true;
157-
cachedKeys.Add(keys[i]);
175+
cachedKeys.Add(key);
158176
cachedResults.Add(await (GetCacheableResultAsync(returnTypes[i], session, result, ts, cancellationToken)).ConfigureAwait(false));
177+
178+
if (key.ResultTransformer?.AutoDiscoverTypes == true && key.ResultTransformer.AutoDiscoveredAliases != null)
179+
{
180+
cachedKeys.Add(new QueryAliasesKey(key));
181+
cachedResults.Add(key.ResultTransformer.AutoDiscoveredAliases);
182+
}
159183
}
160184

161185
await (_cache.PutManyAsync(cachedKeys.ToArray(), cachedResults.ToArray(), cancellationToken)).ConfigureAwait(false);
@@ -214,6 +238,8 @@ public async Task<IList[]> GetManyAsync(
214238
{
215239
session.PersistenceContext.BatchFetchQueue.InitializeQueryCacheQueue();
216240

241+
var queryAliasesKeys = new QueryAliasesKey[keys.Length];
242+
var hasAliasesToFetch = false;
217243
for (var i = 0; i < keys.Length; i++)
218244
{
219245
var cacheable = (IList) cacheables[i];
@@ -237,6 +263,37 @@ public async Task<IList[]> GetManyAsync(
237263

238264
finalReturnTypes[i] = GetReturnTypes(key, returnTypes[i], cacheable);
239265
await (PerformBeforeAssembleAsync(finalReturnTypes[i], session, cacheable, cancellationToken)).ConfigureAwait(false);
266+
267+
if (key.ResultTransformer?.AutoDiscoverTypes == true && cacheable.Count > 0)
268+
{
269+
queryAliasesKeys[i] = new QueryAliasesKey(key);
270+
hasAliasesToFetch = true;
271+
}
272+
}
273+
274+
if (hasAliasesToFetch)
275+
{
276+
var allAliases = await (_cache.GetManyAsync(queryAliasesKeys.Where(k => k != null).ToArray(), cancellationToken)).ConfigureAwait(false);
277+
278+
var aliasesIndex = 0;
279+
for (var i = 0; i < keys.Length; i++)
280+
{
281+
var queryAliasesKey = queryAliasesKeys[i];
282+
if (queryAliasesKey == null)
283+
continue;
284+
285+
if (allAliases[aliasesIndex] is string[] aliases)
286+
{
287+
keys[i].ResultTransformer.SupplyAutoDiscoveredParameters(queryParameters[i].ResultTransformer, aliases);
288+
}
289+
else
290+
{
291+
// Cannot properly initialize the result transformer, treat it as a cache miss
292+
Log.Debug("query aliases were not found in cache: {0}", queryAliasesKey);
293+
finalReturnTypes[i] = null;
294+
}
295+
aliasesIndex++;
296+
}
240297
}
241298

242299
for (var i = 0; i < keys.Length; i++)

0 commit comments

Comments
 (0)