Skip to content

Commit 8883f6c

Browse files
fixup! Fix shortcomings of QueryBatcher initial implementation
Additional cleanup/doc originating from #1788 but which should be here
1 parent 7cfce06 commit 8883f6c

File tree

7 files changed

+56
-41
lines changed

7 files changed

+56
-41
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,7 @@ public async Task UsingHqlToFutureWithCacheAndTransformerDoesntThrowAsync()
384384
.ToList();
385385

386386
Assert.That(results.Count, Is.EqualTo(2));
387+
await (t.CommitAsync());
387388
}
388389
}
389390

src/NHibernate/Async/Multi/IQueryBatchItem.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,10 @@ public partial interface IQueryBatchItem
2323
{
2424

2525
/// <summary>
26-
/// Returns commands generated by query
26+
/// Get the commands to execute for getting the not-already cached results of this query.
2727
/// </summary>
2828
/// <param name="cancellationToken">A cancellation token that can be used to cancel the work</param>
29+
/// <returns>The commands for obtaining the results not already cached.</returns>
2930
Task<IEnumerable<ISqlCommand>> GetCommandsAsync(CancellationToken cancellationToken);
3031

3132
/// <summary>
@@ -36,13 +37,16 @@ public partial interface IQueryBatchItem
3637
Task<int> ProcessResultsSetAsync(DbDataReader reader, CancellationToken cancellationToken);
3738

3839
/// <summary>
39-
/// Executed after all commands in batch are processed
40+
/// Process the results of the query, including cached results.
4041
/// </summary>
4142
/// <param name="cancellationToken">A cancellation token that can be used to cancel the work</param>
43+
/// <remarks>Any result from the database must have been previously processed
44+
/// through <see cref="ProcessResultsSet"/>.</remarks>
4245
Task ProcessResultsAsync(CancellationToken cancellationToken);
4346

4447
/// <summary>
45-
/// Immediate query execution in case the dialect does not support batches
48+
/// Execute immediately the query as a single standalone query. Used in case the data-provider
49+
/// does not support batches.
4650
/// </summary>
4751
/// <param name="cancellationToken">A cancellation token that can be used to cancel the work</param>
4852
Task ExecuteNonBatchedAsync(CancellationToken cancellationToken);

src/NHibernate/Async/Multi/QueryBatch.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ protected async Task ExecuteBatchedAsync(CancellationToken cancellationToken)
119119
// calling CombineQueries.
120120
await (CombineQueriesAsync(resultSetsCommand, cancellationToken)).ConfigureAwait(false);
121121

122-
bool statsEnabled = Session.Factory.Statistics.IsStatisticsEnabled;
122+
var statsEnabled = Session.Factory.Statistics.IsStatisticsEnabled;
123123
Stopwatch stopWatch = null;
124124
if (statsEnabled)
125125
{
@@ -132,7 +132,7 @@ protected async Task ExecuteBatchedAsync(CancellationToken cancellationToken)
132132
Log.Debug("Multi query with {0} queries: {1}", _queries.Count, resultSetsCommand.Sql);
133133
}
134134

135-
int rowCount = 0;
135+
var rowCount = 0;
136136
try
137137
{
138138
if (resultSetsCommand.HasQueries)

src/NHibernate/Async/Multi/QueryBatchItemBase.cs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,7 @@ namespace NHibernate.Multi
2525
public abstract partial class QueryBatchItemBase<TResult> : IQueryBatchItem<TResult>
2626
{
2727

28-
/// <summary>
29-
/// Gets the commands to execute for getting the not-already cached results of this query. Does retrieves
30-
/// already cached results by side-effect.
31-
/// </summary>
32-
/// <param name="cancellationToken">A cancellation token that can be used to cancel the work</param>
33-
/// <returns>The commands for obtaining the results not already cached.</returns>
28+
/// <inheritdoc />
3429
public async Task<IEnumerable<ISqlCommand>> GetCommandsAsync(CancellationToken cancellationToken)
3530
{
3631
cancellationToken.ThrowIfCancellationRequested();
@@ -60,6 +55,7 @@ public async Task<IEnumerable<ISqlCommand>> GetCommandsAsync(CancellationToken c
6055
return yields;
6156
}
6257

58+
/// <inheritdoc />
6359
public async Task<int> ProcessResultsSetAsync(DbDataReader reader, CancellationToken cancellationToken)
6460
{
6561
cancellationToken.ThrowIfCancellationRequested();
@@ -140,10 +136,11 @@ public async Task<int> ProcessResultsSetAsync(DbDataReader reader, CancellationT
140136
return rowCount;
141137
}
142138

139+
/// <inheritdoc />
143140
public async Task ProcessResultsAsync(CancellationToken cancellationToken)
144141
{
145142
cancellationToken.ThrowIfCancellationRequested();
146-
for (int i = 0; i < _queryInfos.Count; i++)
143+
for (var i = 0; i < _queryInfos.Count; i++)
147144
{
148145
var queryInfo = _queryInfos[i];
149146
if (_subselectResultKeys[i] != null)
@@ -172,6 +169,7 @@ public async Task ProcessResultsAsync(CancellationToken cancellationToken)
172169
AfterLoadCallback?.Invoke(GetResults());
173170
}
174171

172+
/// <inheritdoc />
175173
public async Task ExecuteNonBatchedAsync(CancellationToken cancellationToken)
176174
{
177175
cancellationToken.ThrowIfCancellationRequested();

src/NHibernate/Multi/IQueryBatchItem.cs

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,38 +7,49 @@
77
namespace NHibernate.Multi
88
{
99
/// <summary>
10-
/// Interface for wrapping query to be batched by <see cref="IQueryBatch"/>
10+
/// Interface for wrapping query to be batched by <see cref="IQueryBatch"/>.
1111
/// </summary>
1212
public interface IQueryBatchItem<TResult> : IQueryBatchItem
1313
{
1414
/// <summary>
15-
/// Returns loaded typed results by query.
15+
/// Return loaded typed results by query.
1616
/// Must be called only after <see cref="IQueryBatch.Execute"/>.
1717
/// </summary>
1818
IList<TResult> GetResults();
1919

2020
/// <summary>
21-
/// Callback is executed after results are loaded by batch.
22-
/// Loaded results are provided in action parameter.
21+
/// A callback, executed after results are loaded by the batch.
22+
/// Loaded results are provided as the action parameter.
2323
/// </summary>
2424
Action<IList<TResult>> AfterLoadCallback { get; set; }
2525
}
2626

2727
/// <summary>
28-
/// Interface for wrapping query to be batched by <see cref="IQueryBatch"/>
28+
/// Interface for wrapping query to be batched by <see cref="IQueryBatch"/>.
2929
/// </summary>
3030
public partial interface IQueryBatchItem
3131
{
3232
/// <summary>
33-
/// Method is called right before batch execution.
33+
/// Initialize the query. Method is called right before batch execution.
3434
/// Can be used for various delayed initialization logic.
3535
/// </summary>
3636
/// <param name="session"></param>
3737
void Init(ISessionImplementor session);
38+
39+
/// <summary>
40+
/// Get the query spaces.
41+
/// </summary>
42+
/// <remarks>
43+
/// Query spaces indicates which entity classes are used by the query and need to be flushed
44+
/// when auto-flush is enabled. It also indicates which cache update timestamps needs to be
45+
/// checked for up-to-date-ness.
46+
/// </remarks>
47+
IEnumerable<string> GetQuerySpaces();
3848

3949
/// <summary>
40-
/// Returns commands generated by query
50+
/// Get the commands to execute for getting the not-already cached results of this query.
4151
/// </summary>
52+
/// <returns>The commands for obtaining the results not already cached.</returns>
4253
IEnumerable<ISqlCommand> GetCommands();
4354

4455
/// <summary>
@@ -49,18 +60,16 @@ public partial interface IQueryBatchItem
4960
int ProcessResultsSet(DbDataReader reader);
5061

5162
/// <summary>
52-
/// Executed after all commands in batch are processed
63+
/// Process the results of the query, including cached results.
5364
/// </summary>
65+
/// <remarks>Any result from the database must have been previously processed
66+
/// through <see cref="ProcessResultsSet"/>.</remarks>
5467
void ProcessResults();
5568

5669
/// <summary>
57-
/// Immediate query execution in case the dialect does not support batches
70+
/// Execute immediately the query as a single standalone query. Used in case the data-provider
71+
/// does not support batches.
5872
/// </summary>
5973
void ExecuteNonBatched();
60-
61-
/// <summary>
62-
/// Get cache query spaces
63-
/// </summary>
64-
IEnumerable<string> GetQuerySpaces();
6574
}
6675
}

src/NHibernate/Multi/QueryBatch.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ protected void ExecuteBatched()
144144
// calling CombineQueries.
145145
CombineQueries(resultSetsCommand);
146146

147-
bool statsEnabled = Session.Factory.Statistics.IsStatisticsEnabled;
147+
var statsEnabled = Session.Factory.Statistics.IsStatisticsEnabled;
148148
Stopwatch stopWatch = null;
149149
if (statsEnabled)
150150
{
@@ -157,7 +157,7 @@ protected void ExecuteBatched()
157157
Log.Debug("Multi query with {0} queries: {1}", _queries.Count, resultSetsCommand.Sql);
158158
}
159159

160-
int rowCount = 0;
160+
var rowCount = 0;
161161
try
162162
{
163163
if (resultSetsCommand.HasQueries)

src/NHibernate/Multi/QueryBatchItemBase.cs

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ protected class QueryLoadInfo
3737

3838
protected abstract List<QueryLoadInfo> GetQueryLoadInfo();
3939

40+
/// <inheritdoc />
4041
public virtual void Init(ISessionImplementor session)
4142
{
4243
Session = session;
@@ -50,11 +51,13 @@ public virtual void Init(ISessionImplementor session)
5051
_finalResults = null;
5152
}
5253

53-
/// <summary>
54-
/// Gets the commands to execute for getting the not-already cached results of this query. Does retrieves
55-
/// already cached results by side-effect.
56-
/// </summary>
57-
/// <returns>The commands for obtaining the results not already cached.</returns>
54+
/// <inheritdoc />
55+
public IEnumerable<string> GetQuerySpaces()
56+
{
57+
return _queryInfos.SelectMany(q => q.QuerySpaces);
58+
}
59+
60+
/// <inheritdoc />
5861
public IEnumerable<ISqlCommand> GetCommands()
5962
{
6063
for (var index = 0; index < _queryInfos.Count; index++)
@@ -82,6 +85,7 @@ public IEnumerable<ISqlCommand> GetCommands()
8285
}
8386
}
8487

88+
/// <inheritdoc />
8589
public int ProcessResultsSet(DbDataReader reader)
8690
{
8791
var dialect = Session.Factory.Dialect;
@@ -161,9 +165,10 @@ public int ProcessResultsSet(DbDataReader reader)
161165
return rowCount;
162166
}
163167

168+
/// <inheritdoc />
164169
public void ProcessResults()
165170
{
166-
for (int i = 0; i < _queryInfos.Count; i++)
171+
for (var i = 0; i < _queryInfos.Count; i++)
167172
{
168173
var queryInfo = _queryInfos[i];
169174
if (_subselectResultKeys[i] != null)
@@ -192,17 +197,13 @@ public void ProcessResults()
192197
AfterLoadCallback?.Invoke(GetResults());
193198
}
194199

200+
/// <inheritdoc />
195201
public void ExecuteNonBatched()
196202
{
197203
_finalResults = GetResultsNonBatched();
198204
AfterLoadCallback?.Invoke(_finalResults);
199205
}
200206

201-
public IEnumerable<string> GetQuerySpaces()
202-
{
203-
return _queryInfos.SelectMany(q => q.QuerySpaces);
204-
}
205-
206207
protected abstract IList<TResult> GetResultsNonBatched();
207208

208209
protected List<T> GetTypedResults<T>()
@@ -211,8 +212,8 @@ protected List<T> GetTypedResults<T>()
211212
{
212213
throw new HibernateException("Batch wasn't executed. You must call IQueryBatch.Execute() before accessing results.");
213214
}
214-
List<T> results = new List<T>(_loaderResults.Sum(tr => tr.Count));
215-
for (int i = 0; i < _queryInfos.Count; i++)
215+
var results = new List<T>(_loaderResults.Sum(tr => tr.Count));
216+
for (var i = 0; i < _queryInfos.Count; i++)
216217
{
217218
var list = _queryInfos[i].Loader.GetResultList(
218219
_loaderResults[i],
@@ -223,11 +224,13 @@ protected List<T> GetTypedResults<T>()
223224
return results;
224225
}
225226

227+
/// <inheritdoc />
226228
public IList<TResult> GetResults()
227229
{
228230
return _finalResults ?? (_finalResults = DoGetResults());
229231
}
230232

233+
/// <inheritdoc />
231234
public Action<IList<TResult>> AfterLoadCallback { get; set; }
232235

233236
protected abstract List<TResult> DoGetResults();

0 commit comments

Comments
 (0)