Skip to content

Commit 9ac4f3c

Browse files
NH-2319 - Refactoring to be squashed.
1 parent 7ad9b99 commit 9ac4f3c

File tree

4 files changed

+101
-192
lines changed

4 files changed

+101
-192
lines changed

src/NHibernate/Async/Impl/SessionImpl.cs

Lines changed: 49 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -228,52 +228,42 @@ async Task<IList> FindAsync(string query, object[] values, IType[] types, Cancel
228228
}
229229
}
230230

231-
public override async Task ListAsync(IQueryExpression queryExpression, QueryParameters queryParameters, IList results, CancellationToken cancellationToken)
231+
public override Task ListAsync(IQueryExpression queryExpression, QueryParameters queryParameters, IList results, CancellationToken cancellationToken)
232232
{
233-
cancellationToken.ThrowIfCancellationRequested();
234-
using (new SessionIdLoggingContext(SessionId))
233+
if (cancellationToken.IsCancellationRequested)
235234
{
236-
CheckAndUpdateSessionStatus();
237-
queryParameters.ValidateParameters();
238-
var plan = GetHQLQueryPlan(queryExpression, false);
239-
240-
await (AutoFlushIfRequiredAsync(plan.QuerySpaces, cancellationToken)).ConfigureAwait(false);
235+
return Task.FromCanceled<object>(cancellationToken);
236+
}
237+
return ListAsync(queryExpression, queryParameters, results, null, cancellationToken);
238+
}
241239

242-
bool success = false;
243-
using (SuspendAutoFlush()) //stops flush being called multiple times if this method is recursively called
244-
{
245-
try
246-
{
247-
await (plan.PerformListAsync(queryParameters, this, results, cancellationToken)).ConfigureAwait(false);
248-
success = true;
249-
}
250-
catch (HibernateException)
251-
{
252-
// Do not call Convert on HibernateExceptions
253-
throw;
254-
}
255-
catch (Exception e)
256-
{
257-
throw Convert(e, "Could not execute query");
258-
}
259-
finally
260-
{
261-
await (AfterOperationAsync(success, cancellationToken)).ConfigureAwait(false);
262-
}
263-
}
240+
protected override Task ListFilterAsync(object collection, IQueryExpression queryExpression, QueryParameters queryParameters, IList results, CancellationToken cancellationToken)
241+
{
242+
if (collection == null)
243+
throw new ArgumentNullException(nameof(collection));
244+
if (cancellationToken.IsCancellationRequested)
245+
{
246+
return Task.FromCanceled<object>(cancellationToken);
264247
}
248+
return ListAsync(queryExpression, queryParameters, results, collection, cancellationToken);
265249
}
266250

267-
protected override async Task ListFilterAsync(object collection, IQueryExpression queryExpression, QueryParameters queryParameters, IList results, CancellationToken cancellationToken)
251+
private async Task ListAsync(IQueryExpression queryExpression, QueryParameters queryParameters, IList results, object filterConnection, CancellationToken cancellationToken)
268252
{
269253
cancellationToken.ThrowIfCancellationRequested();
270254
using (new SessionIdLoggingContext(SessionId))
271255
{
272256
CheckAndUpdateSessionStatus();
273257
queryParameters.ValidateParameters();
274-
var plan = await (GetFilterQueryPlanAsync(collection, queryExpression, queryParameters, false, cancellationToken)).ConfigureAwait(false);
275258

276-
await (AutoFlushIfRequiredAsync(plan.QuerySpaces, cancellationToken)).ConfigureAwait(false);
259+
var isFilter = filterConnection != null;
260+
var plan = isFilter
261+
? await (GetFilterQueryPlanAsync(filterConnection, queryExpression, queryParameters, false, cancellationToken)).ConfigureAwait(false)
262+
: GetHQLQueryPlan(queryExpression, false);
263+
264+
// GetFilterQueryPlan has already auto flushed or fully flush.
265+
if (!isFilter)
266+
await (AutoFlushIfRequiredAsync(plan.QuerySpaces, cancellationToken)).ConfigureAwait(false);
277267

278268
bool success = false;
279269
using (SuspendAutoFlush()) //stops flush being called multiple times if this method is recursively called
@@ -441,73 +431,39 @@ public override async Task<IQuery> CreateFilterAsync(object collection, IQueryEx
441431
}
442432
}
443433

444-
private async Task<IQueryExpressionPlan> GetFilterQueryPlanAsync(object collection, IQueryExpression queryExpression, QueryParameters parameters, bool shallow, CancellationToken cancellationToken)
434+
private Task<IQueryExpressionPlan> GetFilterQueryPlanAsync(object collection, IQueryExpression queryExpression, QueryParameters parameters, bool shallow, CancellationToken cancellationToken)
445435
{
446-
cancellationToken.ThrowIfCancellationRequested();
447-
using (new SessionIdLoggingContext(SessionId))
436+
if (cancellationToken.IsCancellationRequested)
448437
{
449-
CollectionEntry entry = persistenceContext.GetCollectionEntryOrNull(collection);
450-
ICollectionPersister roleBeforeFlush = (entry == null) ? null : entry.LoadedPersister;
451-
452-
IQueryExpressionPlan plan;
453-
if (roleBeforeFlush == null)
454-
{
455-
// if it was previously unreferenced, we need to flush in order to
456-
// get its state into the database in order to execute query
457-
await (FlushAsync(cancellationToken)).ConfigureAwait(false);
458-
entry = persistenceContext.GetCollectionEntryOrNull(collection);
459-
ICollectionPersister roleAfterFlush = (entry == null) ? null : entry.LoadedPersister;
460-
if (roleAfterFlush == null)
461-
{
462-
throw new QueryException("The collection was unreferenced");
463-
}
464-
plan = Factory.QueryPlanCache.GetFilterQueryPlan(queryExpression, roleAfterFlush.Role, shallow, EnabledFilters);
465-
}
466-
else
467-
{
468-
// otherwise, we only need to flush if there are in-memory changes
469-
// to the queried tables
470-
plan = Factory.QueryPlanCache.GetFilterQueryPlan(queryExpression, roleBeforeFlush.Role, shallow, EnabledFilters);
471-
472-
if (await (AutoFlushIfRequiredAsync(plan.QuerySpaces, cancellationToken)).ConfigureAwait(false))
473-
{
474-
// might need to run a different filter entirely after the flush
475-
// because the collection role may have changed
476-
entry = persistenceContext.GetCollectionEntryOrNull(collection);
477-
ICollectionPersister roleAfterFlush = (entry == null) ? null : entry.LoadedPersister;
478-
if (roleBeforeFlush != roleAfterFlush)
479-
{
480-
if (roleAfterFlush == null)
481-
{
482-
throw new QueryException("The collection was dereferenced");
483-
}
484-
plan = Factory.QueryPlanCache.GetFilterQueryPlan(queryExpression, roleAfterFlush.Role, shallow, EnabledFilters);
485-
}
486-
}
487-
}
488-
489-
if (parameters != null)
490-
{
491-
parameters.PositionalParameterValues[0] = entry.LoadedKey;
492-
parameters.PositionalParameterTypes[0] = entry.LoadedPersister.KeyType;
493-
}
438+
return Task.FromCanceled<IQueryExpressionPlan>(cancellationToken);
439+
}
440+
return GetFilterQueryPlanAsync(collection, parameters, shallow, null, queryExpression, cancellationToken);
441+
}
494442

495-
return plan;
443+
private Task<IQueryExpressionPlan> GetFilterQueryPlanAsync(object collection, string filter, QueryParameters parameters, bool shallow, CancellationToken cancellationToken)
444+
{
445+
if (cancellationToken.IsCancellationRequested)
446+
{
447+
return Task.FromCanceled<IQueryExpressionPlan>(cancellationToken);
496448
}
449+
return GetFilterQueryPlanAsync(collection, parameters, shallow, filter, null, cancellationToken);
497450
}
498451

499-
private async Task<IQueryExpressionPlan> GetFilterQueryPlanAsync(object collection, string filter, QueryParameters parameters, bool shallow, CancellationToken cancellationToken)
452+
private async Task<IQueryExpressionPlan> GetFilterQueryPlanAsync(object collection, QueryParameters parameters, bool shallow,
453+
string filter, IQueryExpression queryExpression, CancellationToken cancellationToken)
500454
{
501455
cancellationToken.ThrowIfCancellationRequested();
502456
using (new SessionIdLoggingContext(SessionId))
503457
{
504458
if (collection == null)
505-
{
506-
throw new ArgumentNullException("collection", "null collection passed to filter");
507-
}
459+
throw new ArgumentNullException(nameof(collection), "null collection passed to filter");
460+
if (filter != null && queryExpression != null)
461+
throw new ArgumentException($"Either {nameof(filter)} or {nameof(queryExpression)} must be specified, not both.");
462+
if (filter == null && queryExpression == null)
463+
throw new ArgumentException($"{nameof(filter)} and {nameof(queryExpression)} were both null.");
508464

509-
CollectionEntry entry = persistenceContext.GetCollectionEntryOrNull(collection);
510-
ICollectionPersister roleBeforeFlush = (entry == null) ? null : entry.LoadedPersister;
465+
var entry = persistenceContext.GetCollectionEntryOrNull(collection);
466+
var roleBeforeFlush = entry?.LoadedPersister;
511467

512468
IQueryExpressionPlan plan;
513469
if (roleBeforeFlush == null)
@@ -516,31 +472,31 @@ private async Task<IQueryExpressionPlan> GetFilterQueryPlanAsync(object collecti
516472
// get its state into the database in order to execute query
517473
await (FlushAsync(cancellationToken)).ConfigureAwait(false);
518474
entry = persistenceContext.GetCollectionEntryOrNull(collection);
519-
ICollectionPersister roleAfterFlush = (entry == null) ? null : entry.LoadedPersister;
475+
var roleAfterFlush = entry?.LoadedPersister;
520476
if (roleAfterFlush == null)
521477
{
522478
throw new QueryException("The collection was unreferenced");
523479
}
524-
plan = Factory.QueryPlanCache.GetFilterQueryPlan(filter, roleAfterFlush.Role, shallow, EnabledFilters);
480+
plan = GetFilterQueryPlan(roleAfterFlush.Role, shallow, filter, queryExpression);
525481
}
526482
else
527483
{
528484
// otherwise, we only need to flush if there are in-memory changes
529485
// to the queried tables
530-
plan = Factory.QueryPlanCache.GetFilterQueryPlan(filter, roleBeforeFlush.Role, shallow, EnabledFilters);
486+
plan = GetFilterQueryPlan(roleBeforeFlush.Role, shallow, filter, queryExpression);
531487
if (await (AutoFlushIfRequiredAsync(plan.QuerySpaces, cancellationToken)).ConfigureAwait(false))
532488
{
533489
// might need to run a different filter entirely after the flush
534490
// because the collection role may have changed
535491
entry = persistenceContext.GetCollectionEntryOrNull(collection);
536-
ICollectionPersister roleAfterFlush = (entry == null) ? null : entry.LoadedPersister;
492+
var roleAfterFlush = entry?.LoadedPersister;
537493
if (roleBeforeFlush != roleAfterFlush)
538494
{
539495
if (roleAfterFlush == null)
540496
{
541497
throw new QueryException("The collection was dereferenced");
542498
}
543-
plan = Factory.QueryPlanCache.GetFilterQueryPlan(filter, roleAfterFlush.Role, shallow, EnabledFilters);
499+
plan = GetFilterQueryPlan(roleAfterFlush.Role, shallow, filter, queryExpression);
544500
}
545501
}
546502
}

0 commit comments

Comments
 (0)