88//------------------------------------------------------------------------------
99
1010
11+ using System ;
1112using System . Collections ;
1213using System . Collections . Generic ;
1314using NHibernate . Engine ;
@@ -20,8 +21,273 @@ namespace NHibernate.Cache
2021 public partial interface IQueryCache
2122 {
2223
24+ /// <summary>
25+ /// Clear the cache.
26+ /// </summary>
27+ /// <param name="cancellationToken">A cancellation token that can be used to cancel the work</param>
2328 Task ClearAsync ( CancellationToken cancellationToken ) ;
29+ // Since 5.2
30+ [ Obsolete ( "Have the query cache implement IBatchableQueryCache, and use IBatchableQueryCache.Put" ) ]
2431 Task < bool > PutAsync ( QueryKey key , ICacheAssembler [ ] returnTypes , IList result , bool isNaturalKeyLookup , ISessionImplementor session , CancellationToken cancellationToken ) ;
32+ // Since 5.2
33+ [ Obsolete ( "Have the query cache implement IBatchableQueryCache, and use IBatchableQueryCache.Get" ) ]
2534 Task < IList > GetAsync ( QueryKey key , ICacheAssembler [ ] returnTypes , bool isNaturalKeyLookup , ISet < string > spaces , ISessionImplementor session , CancellationToken cancellationToken ) ;
2635 }
36+
37+ public partial interface IBatchableQueryCache : IQueryCache
38+ {
39+ /// <summary>
40+ /// Get query results from the cache.
41+ /// </summary>
42+ /// <param name="key">The query key.</param>
43+ /// <param name="queryParameters">The query parameters.</param>
44+ /// <param name="returnTypes">The query result row types.</param>
45+ /// <param name="spaces">The query spaces.</param>
46+ /// <param name="session">The session for which the query is executed.</param>
47+ /// <param name="cancellationToken">A cancellation token that can be used to cancel the work</param>
48+ /// <returns>The query results, if cached.</returns>
49+ Task < IList > GetAsync (
50+ QueryKey key , QueryParameters queryParameters , ICacheAssembler [ ] returnTypes , ISet < string > spaces ,
51+ ISessionImplementor session , CancellationToken cancellationToken ) ;
52+
53+ /// <summary>
54+ /// Put query results in the cache.
55+ /// </summary>
56+ /// <param name="key">The query key.</param>
57+ /// <param name="queryParameters">The query parameters.</param>
58+ /// <param name="returnTypes">The query result row types.</param>
59+ /// <param name="result">The query result.</param>
60+ /// <param name="session">The session for which the query was executed.</param>
61+ /// <param name="cancellationToken">A cancellation token that can be used to cancel the work</param>
62+ /// <returns><see langword="true" /> if the result has been cached, <see langword="false" />
63+ /// otherwise.</returns>
64+ Task < bool > PutAsync (
65+ QueryKey key , QueryParameters queryParameters , ICacheAssembler [ ] returnTypes , IList result ,
66+ ISessionImplementor session , CancellationToken cancellationToken ) ;
67+
68+ /// <summary>
69+ /// Retrieve multiple query results from the cache.
70+ /// </summary>
71+ /// <param name="keys">The query keys.</param>
72+ /// <param name="queryParameters">The array of query parameters matching <paramref name="keys"/>.</param>
73+ /// <param name="returnTypes">The array of query result row types matching <paramref name="keys"/>.</param>
74+ /// <param name="spaces">The array of query spaces matching <paramref name="keys"/>.</param>
75+ /// <param name="session">The session for which the queries are executed.</param>
76+ /// <param name="cancellationToken">A cancellation token that can be used to cancel the work</param>
77+ /// <returns>The cached query results, matching each key of <paramref name="keys"/> respectively. For each
78+ /// missed key, it will contain a <see langword="null" />.</returns>
79+ Task < IList [ ] > GetManyAsync (
80+ QueryKey [ ] keys , QueryParameters [ ] queryParameters , ICacheAssembler [ ] [ ] returnTypes ,
81+ ISet < string > [ ] spaces , ISessionImplementor session , CancellationToken cancellationToken ) ;
82+
83+ /// <summary>
84+ /// Attempt to cache objects, after loading them from the database.
85+ /// </summary>
86+ /// <param name="keys">The query keys.</param>
87+ /// <param name="queryParameters">The array of query parameters matching <paramref name="keys"/>.</param>
88+ /// <param name="returnTypes">The array of query result row types matching <paramref name="keys"/>.</param>
89+ /// <param name="results">The array of query results matching <paramref name="keys"/>.</param>
90+ /// <param name="session">The session for which the queries were executed.</param>
91+ /// <param name="cancellationToken">A cancellation token that can be used to cancel the work</param>
92+ /// <returns>An array of boolean indicating if each query was successfully cached.</returns>
93+ /// <exception cref="CacheException"></exception>
94+ Task < bool [ ] > PutManyAsync (
95+ QueryKey [ ] keys , QueryParameters [ ] queryParameters , ICacheAssembler [ ] [ ] returnTypes , IList [ ] results ,
96+ ISessionImplementor session , CancellationToken cancellationToken ) ;
97+ }
98+
99+ internal static partial class QueryCacheExtensions
100+ {
101+
102+ /// <summary>
103+ /// Get query results from the cache.
104+ /// </summary>
105+ /// <param name="queryCache">The cache.</param>
106+ /// <param name="key">The query key.</param>
107+ /// <param name="queryParameters">The query parameters.</param>
108+ /// <param name="returnTypes">The query result row types.</param>
109+ /// <param name="spaces">The query spaces.</param>
110+ /// <param name="session">The session for which the query is executed.</param>
111+ /// <param name="cancellationToken">A cancellation token that can be used to cancel the work</param>
112+ /// <returns>The query results, if cached.</returns>
113+ public static async Task < IList > GetAsync (
114+ this IQueryCache queryCache ,
115+ QueryKey key ,
116+ QueryParameters queryParameters ,
117+ ICacheAssembler [ ] returnTypes ,
118+ ISet < string > spaces ,
119+ ISessionImplementor session , CancellationToken cancellationToken )
120+ {
121+ cancellationToken . ThrowIfCancellationRequested ( ) ;
122+ if ( queryCache is IBatchableQueryCache batchableQueryCache )
123+ {
124+ return await ( batchableQueryCache . GetAsync (
125+ key ,
126+ queryParameters ,
127+ returnTypes ,
128+ spaces ,
129+ session , cancellationToken ) ) . ConfigureAwait ( false ) ;
130+ }
131+
132+ if ( ! _hasWarnForObsoleteQueryCache )
133+ {
134+ _hasWarnForObsoleteQueryCache = true ;
135+ Log . Warn ( "{0} is obsolete, it should implement {1}" , queryCache , nameof ( IBatchableQueryCache ) ) ;
136+ }
137+
138+ var persistenceContext = session . PersistenceContext ;
139+
140+ var defaultReadOnlyOrig = persistenceContext . DefaultReadOnly ;
141+
142+ if ( queryParameters . IsReadOnlyInitialized )
143+ persistenceContext . DefaultReadOnly = queryParameters . ReadOnly ;
144+ else
145+ queryParameters . ReadOnly = persistenceContext . DefaultReadOnly ;
146+
147+ try
148+ {
149+ #pragma warning disable 618
150+ return await ( queryCache . GetAsync (
151+ #pragma warning restore 618
152+ key ,
153+ returnTypes ,
154+ queryParameters . NaturalKeyLookup ,
155+ spaces ,
156+ session , cancellationToken ) ) . ConfigureAwait ( false ) ;
157+ }
158+ finally
159+ {
160+ persistenceContext . DefaultReadOnly = defaultReadOnlyOrig ;
161+ }
162+ }
163+
164+ /// <summary>
165+ /// Put query results in the cache.
166+ /// </summary>
167+ /// <param name="queryCache">The cache.</param>
168+ /// <param name="key">The query key.</param>
169+ /// <param name="queryParameters">The query parameters.</param>
170+ /// <param name="returnTypes">The query result row types.</param>
171+ /// <param name="result">The query result.</param>
172+ /// <param name="session">The session for which the query was executed.</param>
173+ /// <param name="cancellationToken">A cancellation token that can be used to cancel the work</param>
174+ /// <returns><see langword="true" /> if the result has been cached, <see langword="false" />
175+ /// otherwise.</returns>
176+ public static Task < bool > PutAsync (
177+ this IQueryCache queryCache ,
178+ QueryKey key ,
179+ QueryParameters queryParameters ,
180+ ICacheAssembler [ ] returnTypes ,
181+ IList result ,
182+ ISessionImplementor session , CancellationToken cancellationToken )
183+ {
184+ if ( cancellationToken . IsCancellationRequested )
185+ {
186+ return Task . FromCanceled < bool > ( cancellationToken ) ;
187+ }
188+ try
189+ {
190+ if ( queryCache is IBatchableQueryCache batchableQueryCache )
191+ {
192+ return batchableQueryCache . PutAsync (
193+ key , queryParameters ,
194+ returnTypes ,
195+ result , session , cancellationToken ) ;
196+ }
197+
198+ #pragma warning disable 618
199+ return queryCache . PutAsync (
200+ #pragma warning restore 618
201+ key ,
202+ returnTypes ,
203+ result ,
204+ queryParameters . NaturalKeyLookup ,
205+ session , cancellationToken ) ;
206+ }
207+ catch ( Exception ex )
208+ {
209+ return Task . FromException < bool > ( ex ) ;
210+ }
211+ }
212+
213+ /// <summary>
214+ /// Retrieve multiple query results from the cache.
215+ /// </summary>
216+ /// <param name="queryCache">The cache.</param>
217+ /// <param name="keys">The query keys.</param>
218+ /// <param name="queryParameters">The array of query parameters matching <paramref name="keys"/>.</param>
219+ /// <param name="returnTypes">The array of query result row types matching <paramref name="keys"/>.</param>
220+ /// <param name="spaces">The array of query spaces matching <paramref name="keys"/>.</param>
221+ /// <param name="session">The session for which the queries are executed.</param>
222+ /// <param name="cancellationToken">A cancellation token that can be used to cancel the work</param>
223+ /// <returns>The cached query results, matching each key of <paramref name="keys"/> respectively. For each
224+ /// missed key, it will contain a <see langword="null" />.</returns>
225+ public static async Task < IList [ ] > GetManyAsync (
226+ this IQueryCache queryCache ,
227+ QueryKey [ ] keys ,
228+ QueryParameters [ ] queryParameters ,
229+ ICacheAssembler [ ] [ ] returnTypes ,
230+ ISet < string > [ ] spaces ,
231+ ISessionImplementor session , CancellationToken cancellationToken )
232+ {
233+ cancellationToken . ThrowIfCancellationRequested ( ) ;
234+ if ( queryCache is IBatchableQueryCache batchableQueryCache )
235+ {
236+ return await ( batchableQueryCache . GetManyAsync (
237+ keys ,
238+ queryParameters ,
239+ returnTypes ,
240+ spaces ,
241+ session , cancellationToken ) ) . ConfigureAwait ( false ) ;
242+ }
243+
244+ var results = new IList [ keys . Length ] ;
245+ for ( var i = 0 ; i < keys . Length ; i ++ )
246+ {
247+ results [ i ] = await ( queryCache . GetAsync ( keys [ i ] , queryParameters [ i ] , returnTypes [ i ] , spaces [ i ] , session , cancellationToken ) ) . ConfigureAwait ( false ) ;
248+ }
249+
250+ return results ;
251+ }
252+
253+ /// <summary>
254+ /// Attempt to cache objects, after loading them from the database.
255+ /// </summary>
256+ /// <param name="queryCache">The cache.</param>
257+ /// <param name="keys">The query keys.</param>
258+ /// <param name="queryParameters">The array of query parameters matching <paramref name="keys"/>.</param>
259+ /// <param name="returnTypes">The array of query result row types matching <paramref name="keys"/>.</param>
260+ /// <param name="results">The array of query results matching <paramref name="keys"/>.</param>
261+ /// <param name="session">The session for which the queries were executed.</param>
262+ /// <param name="cancellationToken">A cancellation token that can be used to cancel the work</param>
263+ /// <returns>An array of boolean indicating if each query was successfully cached.</returns>
264+ /// <exception cref="CacheException"></exception>
265+ public static async Task < bool [ ] > PutManyAsync (
266+ this IQueryCache queryCache ,
267+ QueryKey [ ] keys ,
268+ QueryParameters [ ] queryParameters ,
269+ ICacheAssembler [ ] [ ] returnTypes ,
270+ IList [ ] results ,
271+ ISessionImplementor session , CancellationToken cancellationToken )
272+ {
273+ cancellationToken . ThrowIfCancellationRequested ( ) ;
274+ if ( queryCache is IBatchableQueryCache batchableQueryCache )
275+ {
276+ return await ( batchableQueryCache . PutManyAsync (
277+ keys ,
278+ queryParameters ,
279+ returnTypes ,
280+ results ,
281+ session , cancellationToken ) ) . ConfigureAwait ( false ) ;
282+ }
283+
284+ var puts = new bool [ keys . Length ] ;
285+ for ( var i = 0 ; i < keys . Length ; i ++ )
286+ {
287+ puts [ i ] = await ( queryCache . PutAsync ( keys [ i ] , queryParameters [ i ] , returnTypes [ i ] , results [ i ] , session , cancellationToken ) ) . ConfigureAwait ( false ) ;
288+ }
289+
290+ return puts ;
291+ }
292+ }
27293}
0 commit comments