public IList Get(QueryKey key, ICacheAssembler[] returnTypes, Iesi.Collections.Generic.ISet<string> spaces, ISessionImplementor session) { if (log.IsDebugEnabled) { log.Debug("checking cached query results in region: " + regionName); } IList cacheable = (IList) queryCache.Get(key); if (cacheable == null) { log.Debug("query results were not found in cache"); return null; } IList result = new ArrayList(cacheable.Count - 1); long timestamp = (long) cacheable[0]; log.Debug("Checking query spaces for up-to-dateness [" + spaces + "]"); if (! IsUpToDate(spaces, timestamp)) { log.Debug("cached query results were not up to date"); return null; } log.Debug("returning cached query results"); for (int i = 1; i < cacheable.Count; i++) { if (returnTypes.Length == 1) { result.Add(returnTypes[0].Assemble(cacheable[i], session, null)); } else { result.Add(TypeFactory.Assemble((object[]) cacheable[i], returnTypes, session, null)); } } return result; }
public bool Put(QueryKey key, ICacheAssembler[] returnTypes, IList result, bool isNaturalKeyLookup, ISessionImplementor session) { if (isNaturalKeyLookup && result.Count == 0) return false; long ts = session.Timestamp; if (Log.IsDebugEnabled) Log.DebugFormat("caching query results in region: '{0}'; {1}", _regionName, key); IList cacheable = new List<object>(result.Count + 1) {ts}; for (int i = 0; i < result.Count; i++) { if (returnTypes.Length == 1 && !key.HasResultTransformer) { cacheable.Add(returnTypes[0].Disassemble(result[i], session, null)); } else { cacheable.Add(TypeHelper.Disassemble((object[]) result[i], returnTypes, null, session, null)); } } _queryCache.Put(key, cacheable); return true; }
bool IQueryCache.Put(QueryKey key, ICacheAssembler[] returnTypes, IList result, bool isNaturalKeyLookup, ISessionImplementor session) { //if the returntypes contains simple values, assume it's a projection: if (returnTypes.OfType<IType>().Any(t => t.ReturnedClass != null && (t.ReturnedClass.IsValueType || t.ReturnedClass.IsPrimitive || t.ReturnedClass == typeof(String)))) return false; return this.Put(key, returnTypes, result, isNaturalKeyLookup, session); }
/// <summary> /// Get query results from the cache. /// </summary> /// <param name="queryCache">The cache.</param> /// <param name="key">The query key.</param> /// <param name="queryParameters">The query parameters.</param> /// <param name="returnTypes">The query result row types.</param> /// <param name="spaces">The query spaces.</param> /// <param name="session">The session for which the query is executed.</param> /// <param name="cancellationToken">A cancellation token that can be used to cancel the work</param> /// <returns>The query results, if cached.</returns> public static async Task <IList> GetAsync( this IQueryCache queryCache, QueryKey key, QueryParameters queryParameters, ICacheAssembler[] returnTypes, ISet <string> spaces, ISessionImplementor session, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); if (queryCache is IBatchableQueryCache batchableQueryCache) { return(await(batchableQueryCache.GetAsync( key, queryParameters, returnTypes, spaces, session, cancellationToken)).ConfigureAwait(false)); } if (!_hasWarnForObsoleteQueryCache) { _hasWarnForObsoleteQueryCache = true; Log.Warn("{0} is obsolete, it should implement {1}", queryCache, nameof(IBatchableQueryCache)); } var persistenceContext = session.PersistenceContext; var defaultReadOnlyOrig = persistenceContext.DefaultReadOnly; if (queryParameters.IsReadOnlyInitialized) { persistenceContext.DefaultReadOnly = queryParameters.ReadOnly; } else { queryParameters.ReadOnly = persistenceContext.DefaultReadOnly; } try { #pragma warning disable 618 return(await(queryCache.GetAsync( #pragma warning restore 618 key, returnTypes, queryParameters.NaturalKeyLookup, spaces, session, cancellationToken)).ConfigureAwait(false)); } finally { persistenceContext.DefaultReadOnly = defaultReadOnlyOrig; } }
private static ICacheAssembler[] GetReturnTypes( QueryKey key, ICacheAssembler[] returnTypes, IList cacheable) { if (key.ResultTransformer?.AutoDiscoverTypes == true && cacheable.Count > 0) { returnTypes = GuessTypes(cacheable); } return(returnTypes); }
/// <summary> /// Get query results from the cache. /// </summary> /// <param name="queryCache">The cache.</param> /// <param name="key">The query key.</param> /// <param name="queryParameters">The query parameters.</param> /// <param name="returnTypes">The query result row types.</param> /// <param name="spaces">The query spaces.</param> /// <param name="session">The session for which the query is executed.</param> /// <returns>The query results, if cached.</returns> public static IList Get( this IQueryCache queryCache, QueryKey key, QueryParameters queryParameters, ICacheAssembler[] returnTypes, ISet <string> spaces, ISessionImplementor session) { if (queryCache is IBatchableQueryCache batchableQueryCache) { return(batchableQueryCache.Get( key, queryParameters, returnTypes, spaces, session)); } if (!_hasWarnForObsoleteQueryCache) { _hasWarnForObsoleteQueryCache = true; Log.Warn("{0} is obsolete, it should implement {1}", queryCache, nameof(IBatchableQueryCache)); } var persistenceContext = session.PersistenceContext; var defaultReadOnlyOrig = persistenceContext.DefaultReadOnly; if (queryParameters.IsReadOnlyInitialized) { persistenceContext.DefaultReadOnly = queryParameters.ReadOnly; } else { queryParameters.ReadOnly = persistenceContext.DefaultReadOnly; } try { #pragma warning disable 618 return(queryCache.Get( #pragma warning restore 618 key, returnTypes, queryParameters.NaturalKeyLookup, spaces, session)); } finally { persistenceContext.DefaultReadOnly = defaultReadOnlyOrig; } }
/// <inheritdoc /> public bool Put( QueryKey key, QueryParameters queryParameters, ICacheAssembler[] returnTypes, IList result, ISessionImplementor session) { // 6.0 TODO: inline the call. #pragma warning disable 612 return Put(key, returnTypes, result, queryParameters.NaturalKeyLookup, session); #pragma warning restore 612 }
public override bool Equals(object other) { QueryKey that = ( QueryKey )other; if (!sqlQueryString.Equals(that.sqlQueryString)) { return(false); } if (firstRow != that.firstRow || maxRows != that.maxRows) { return(false); } if (types == null) { if (that.types != null) { return(false); } } else { if (that.types == null) { return(false); } if (types.Length != that.types.Length) { return(false); } for (int i = 0; i < types.Length; i++) { if (!types[i].Equals(that.types[i])) { return(false); } if (!object.Equals(values[i], that.values[i])) { return(false); } } } if (!DictionariesAreEqual(namedParameters, that.namedParameters)) { return(false); } return(true); }
public bool Put(QueryKey key, ICacheAssembler[] returnTypes, IList result, bool isNaturalKeyLookup, ISessionImplementor session) { if (isNaturalKeyLookup && result.Count == 0) return false; var ts = session.Factory.Settings.CacheProvider.NextTimestamp(); Log.Debug("caching query results in region: '{0}'; {1}", _regionName, key); Cache.Put(key, GetCacheableResult(returnTypes, session, result, ts)); return true; }
private void QueryKeyFilterDescLikeToCompare(out QueryKey qk, out QueryKey qk1) { const string filterName = "DescriptionLike"; var f = new FilterImpl(sessions.GetFilterDefinition(filterName)); f.SetParameter("pLike", "so%"); var fk = new FilterKey(filterName, f.Parameters, f.FilterDefinition.ParameterTypes, EntityMode.Poco); ISet<FilterKey> fks = new HashSet<FilterKey> { fk }; qk = new QueryKey(sessions, SqlAll, new QueryParameters(), fks); var f1 = new FilterImpl(sessions.GetFilterDefinition(filterName)); f1.SetParameter("pLike", "%ing"); var fk1 = new FilterKey(filterName, f.Parameters, f.FilterDefinition.ParameterTypes, EntityMode.Poco); fks = new HashSet<FilterKey> { fk1 }; qk1 = new QueryKey(sessions, SqlAll, new QueryParameters(), fks); }
private void QueryKeyFilterDescValueToCompare(out QueryKey qk, out QueryKey qk1) { const string filterName = "DescriptionEqualAndValueGT"; var f = new FilterImpl(sessions.GetFilterDefinition(filterName)); f.SetParameter("pDesc", "something").SetParameter("pValue", 10); var fk = new FilterKey(filterName, f.Parameters, f.FilterDefinition.ParameterTypes, EntityMode.Poco); ISet<FilterKey> fks = new HashedSet<FilterKey> { fk }; qk = new QueryKey(sessions, SqlAll, new QueryParameters(), (ISet)fks); var f1 = new FilterImpl(sessions.GetFilterDefinition(filterName)); f1.SetParameter("pDesc", "something").SetParameter("pValue", 11); var fk1 = new FilterKey(filterName, f.Parameters, f.FilterDefinition.ParameterTypes, EntityMode.Poco); fks = new HashedSet<FilterKey> { fk1 }; qk1 = new QueryKey(sessions, SqlAll, new QueryParameters(), (ISet)fks); }
public async Task <bool> PutAsync(QueryKey key, ICacheAssembler[] returnTypes, IList result, bool isNaturalKeyLookup, ISessionImplementor session, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); if (isNaturalKeyLookup && result.Count == 0) { return(false); } var ts = session.Factory.Settings.CacheProvider.NextTimestamp(); Log.Debug("caching query results in region: '{0}'; {1}", _regionName, key); await(Cache.PutAsync(key, await(GetCacheableResultAsync(returnTypes, session, result, ts, cancellationToken)).ConfigureAwait(false), cancellationToken)).ConfigureAwait(false); return(true); }
public IList GetResultFromQueryCache(ISessionImplementor session, QueryParameters queryParameters, ISet<string> querySpaces, IQueryCache queryCache, QueryKey key) { if (!queryParameters.ForceCacheRefresh) { IList list = queryCache.Get(key, new ICacheAssembler[] {this}, queryParameters.NaturalKeyLookup, querySpaces, session); //we had to wrap the query results in another list in order to save all //the queries in the same bucket, now we need to do it the other way around. if (list != null) { list = (IList) list[0]; } return list; } return null; }
/// <inheritdoc /> public Task <bool> PutAsync( QueryKey key, QueryParameters queryParameters, ICacheAssembler[] returnTypes, IList result, ISessionImplementor session, CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested) { return(Task.FromCanceled <bool>(cancellationToken)); } // 6.0 TODO: inline the call. #pragma warning disable 612 return(PutAsync(key, returnTypes, result, queryParameters.NaturalKeyLookup, session, cancellationToken)); #pragma warning restore 612 }
public void Put(QueryKey key, ICacheAssembler[] returnTypes, IList result, ISessionImplementor session) { if (log.IsDebugEnabled) { log.Debug("caching query results in region: " + regionName); } IList cacheable = new ArrayList(result.Count + 1); cacheable.Add(session.Timestamp); for (int i = 0; i < result.Count; i++) { if (returnTypes.Length == 1) { cacheable.Add(returnTypes[0].Disassemble(result[i], session)); } else { cacheable.Add(TypeFactory.Disassemble((object[]) result[i], returnTypes, session)); } } queryCache.Put(key, cacheable); }
public void Put(QueryKey key, IType[] returnTypes, IList result, ISessionImplementor session) { if (log.IsDebugEnabled) { log.Debug("caching query results in region: " + regionName); } IList cacheable = new ArrayList(result.Count + 1); cacheable.Add(session.Timestamp); for (int i = 0; i < result.Count; i++) { if (returnTypes.Length == 1) { cacheable.Add(returnTypes[0].Disassemble(result[i], session)); } else { cacheable.Add(TypeFactory.Disassemble(( object[] )result[i], returnTypes, session)); } } queryCache.Put(key, cacheable); }
private IList GetResultFromCacheable( QueryKey key, ICacheAssembler[] returnTypes, bool isNaturalKeyLookup, ISessionImplementor session, IList cacheable) { Log.Debug("returning cached query results for: {0}", key); returnTypes = GetReturnTypes(key, returnTypes, cacheable); try { session.PersistenceContext.BatchFetchQueue.InitializeQueryCacheQueue(); PerformBeforeAssemble(returnTypes, session, cacheable); var result = PerformAssemble(key, returnTypes, isNaturalKeyLookup, session, cacheable); InitializeCollections(returnTypes, session, result, cacheable); return(result); } finally { session.PersistenceContext.BatchFetchQueue.TerminateQueryCacheQueue(); } }
public async Task <bool> PutAsync(QueryKey key, ICacheAssembler[] returnTypes, IList result, bool isNaturalKeyLookup, ISessionImplementor session, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); if (isNaturalKeyLookup && result.Count == 0) { return(false); } long ts = session.Timestamp; if (Log.IsDebugEnabled()) { Log.Debug("caching query results in region: '{0}'; {1}", _regionName, key); } IList cacheable = new List <object>(result.Count + 1) { ts }; for (int i = 0; i < result.Count; i++) { if (returnTypes.Length == 1) { cacheable.Add(await(returnTypes[0].DisassembleAsync(result[i], session, null, cancellationToken)).ConfigureAwait(false)); } else { cacheable.Add(await(TypeHelper.DisassembleAsync((object[])result[i], returnTypes, null, session, null, cancellationToken)).ConfigureAwait(false)); } } await(_queryCache.PutAsync(key, cacheable, cancellationToken)).ConfigureAwait(false); return(true); }
private async Task <IList> GetResultFromCacheableAsync( QueryKey key, ICacheAssembler[] returnTypes, bool isNaturalKeyLookup, ISessionImplementor session, IList cacheable, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); Log.Debug("returning cached query results for: {0}", key); returnTypes = GetReturnTypes(key, returnTypes, cacheable); try { session.PersistenceContext.BatchFetchQueue.InitializeQueryCacheQueue(); await(PerformBeforeAssembleAsync(returnTypes, session, cacheable, cancellationToken)).ConfigureAwait(false); var result = await(PerformAssembleAsync(key, returnTypes, isNaturalKeyLookup, session, cacheable, cancellationToken)).ConfigureAwait(false); await(InitializeCollectionsAsync(returnTypes, session, result, cacheable, cancellationToken)).ConfigureAwait(false); return(result); } finally { session.PersistenceContext.BatchFetchQueue.TerminateQueryCacheQueue(); } }
public IList Get(QueryKey key, IType[] returnTypes, ISet spaces, ISessionImplementor session) { if (log.IsDebugEnabled) { log.Debug("checking cached query results in region: " + regionName); } IList cacheable = ( IList )queryCache.Get(key); if (cacheable == null) { log.Debug("query results were not found in cache"); return(null); } IList result = new ArrayList(cacheable.Count - 1); long timestamp = ( long )cacheable[0]; log.Debug("Checking query spaces for up-to-dateness [" + spaces + "]"); if (!IsUpToDate(spaces, timestamp)) { log.Debug("cached query results were not up to date"); return(null); } log.Debug("returning cached query results"); for (int i = 1; i < cacheable.Count; i++) { if (returnTypes.Length == 1) { result.Add(returnTypes[0].Assemble(cacheable[i], session, null)); } else { result.Add(TypeFactory.Assemble(( object[] )cacheable[i], returnTypes, session, null)); } } return(result); }
/// <summary> /// Put query results in the cache. /// </summary> /// <param name="queryCache">The cache.</param> /// <param name="key">The query key.</param> /// <param name="queryParameters">The query parameters.</param> /// <param name="returnTypes">The query result row types.</param> /// <param name="result">The query result.</param> /// <param name="session">The session for which the query was executed.</param> /// <param name="cancellationToken">A cancellation token that can be used to cancel the work</param> /// <returns><see langword="true" /> if the result has been cached, <see langword="false" /> /// otherwise.</returns> public static Task <bool> PutAsync( this IQueryCache queryCache, QueryKey key, QueryParameters queryParameters, ICacheAssembler[] returnTypes, IList result, ISessionImplementor session, CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested) { return(Task.FromCanceled <bool>(cancellationToken)); } try { if (queryCache is IBatchableQueryCache batchableQueryCache) { return(batchableQueryCache.PutAsync( key, queryParameters, returnTypes, result, session, cancellationToken)); } #pragma warning disable 618 return(queryCache.PutAsync( #pragma warning restore 618 key, returnTypes, result, queryParameters.NaturalKeyLookup, session, cancellationToken)); } catch (Exception ex) { return(Task.FromException <bool>(ex)); } }
public async Task <IList> GetAsync(QueryKey key, ICacheAssembler[] returnTypes, bool isNaturalKeyLookup, ISet <string> spaces, ISessionImplementor session, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); if (Log.IsDebugEnabled()) { Log.Debug("checking cached query results in region: '{0}'; {1}", _regionName, key); } var cacheable = (IList)await(_queryCache.GetAsync(key, cancellationToken)).ConfigureAwait(false); if (cacheable == null) { Log.Debug("query results were not found in cache: {0}", key); return(null); } var timestamp = (long)cacheable[0]; if (Log.IsDebugEnabled()) { Log.Debug("Checking query spaces for up-to-dateness [{0}]", StringHelper.CollectionToString(spaces)); } if (!isNaturalKeyLookup && !await(IsUpToDateAsync(spaces, timestamp, cancellationToken)).ConfigureAwait(false)) { Log.Debug("cached query results were not up to date for: {0}", key); return(null); } Log.Debug("returning cached query results for: {0}", key); for (int i = 1; i < cacheable.Count; i++) { if (returnTypes.Length == 1) { await(returnTypes[0].BeforeAssembleAsync(cacheable[i], session, cancellationToken)).ConfigureAwait(false); } else { await(TypeHelper.BeforeAssembleAsync((object[])cacheable[i], returnTypes, session, cancellationToken)).ConfigureAwait(false); } } IList result = new List <object>(cacheable.Count - 1); for (int i = 1; i < cacheable.Count; i++) { try { if (returnTypes.Length == 1) { result.Add(await(returnTypes[0].AssembleAsync(cacheable[i], session, null, cancellationToken)).ConfigureAwait(false)); } else { result.Add(await(TypeHelper.AssembleAsync((object[])cacheable[i], returnTypes, session, null, cancellationToken)).ConfigureAwait(false)); } } catch (UnresolvableObjectException ex) { if (isNaturalKeyLookup) { //TODO: not really completely correct, since // the UnresolvableObjectException could occur while resolving // associations, leaving the PC in an inconsistent state Log.Debug(ex, "could not reassemble cached result set"); await(_queryCache.RemoveAsync(key, cancellationToken)).ConfigureAwait(false); return(null); } throw; } } return(result); }
public override bool Equals(object other) { QueryKey that = (QueryKey)other; if (!sqlQueryString.Equals(that.sqlQueryString)) { return(false); } if (firstRow != that.firstRow || maxRows != that.maxRows) { return(false); } if (!Equals(customTransformer, that.customTransformer)) { return(false); } if (types == null) { if (that.types != null) { return(false); } } else { if (that.types == null) { return(false); } if (types.Length != that.types.Length) { return(false); } for (int i = 0; i < types.Length; i++) { if (!types[i].Equals(that.types[i])) { return(false); } if (!Equals(values[i], that.values[i])) { return(false); } } } if (!CollectionHelper.SetEquals(filters, that.filters)) { return(false); } if (!CollectionHelper.DictionaryEquals(namedParameters, that.namedParameters)) { return(false); } if (!CollectionHelper.CollectionEquals <int>(multiQueriesFirstRows, that.multiQueriesFirstRows)) { return(false); } if (!CollectionHelper.CollectionEquals <int>(multiQueriesMaxRows, that.multiQueriesMaxRows)) { return(false); } return(true); }
public override bool Equals(object other) { QueryKey that = (QueryKey)other; if (!_sqlQueryString.Equals(that._sqlQueryString)) { return(false); } if (_firstRow != that._firstRow || _maxRows != that._maxRows) { return(false); } if (!Equals(_customTransformer, that._customTransformer)) { return(false); } if (_types == null) { if (that._types != null) { return(false); } } else { if (that._types == null) { return(false); } if (_types.Length != that._types.Length) { return(false); } for (int i = 0; i < _types.Length; i++) { if (!_types[i].Equals(that._types[i])) { return(false); } if (!Equals(_values[i], that._values[i])) { return(false); } } } if (!CollectionHelper.SetEquals(_filters, that._filters)) { return(false); } if (!CollectionHelper.DictionaryEquals(_namedParameters, that._namedParameters)) { return(false); } if (!CollectionHelper.SequenceEquals <int>(_multiQueriesFirstRows, that._multiQueriesFirstRows)) { return(false); } if (!CollectionHelper.SequenceEquals <int>(_multiQueriesMaxRows, that._multiQueriesMaxRows)) { return(false); } return(true); }
private IList ListUsingQueryCache() { IQueryCache queryCache = session.Factory.GetQueryCache(cacheRegion); ISet filterKeys = FilterKey.CreateFilterKeys(session.EnabledFilters, session.EntityMode); Iesi.Collections.Generic.ISet<string> querySpaces = new HashedSet<string>(); ArrayList resultTypesList = new ArrayList(); int[] maxRows = new int[loaders.Count]; int[] firstRows = new int[loaders.Count]; for (int i = 0; i < loaders.Count; i++) { querySpaces.AddAll(loaders[i].QuerySpaces); resultTypesList.Add(loaders[i].ResultTypes); firstRows[i] = parameters[i].RowSelection.FirstRow; maxRows[i] = parameters[i].RowSelection.MaxRows; } MultipleQueriesCacheAssembler assembler = new MultipleQueriesCacheAssembler(resultTypesList); QueryParameters combinedParameters = CreateCombinedQueryParameters(); QueryKey key = new QueryKey(session.Factory, SqlString, combinedParameters, filterKeys) .SetFirstRows(firstRows) .SetMaxRows(maxRows); IList result = assembler.GetResultFromQueryCache(session, combinedParameters, querySpaces, queryCache, key); if (result == null) { log.Debug("Cache miss for multi criteria query"); IList list = DoList(); queryCache.Put(key, new ICacheAssembler[] {assembler}, new object[] {list}, session); result = list; } return GetResultList(result); }
private IList GetResultFromQueryCache(ISessionImplementor session, QueryParameters queryParameters, ISet<string> querySpaces, IType[] resultTypes, IQueryCache queryCache, QueryKey key) { IList result = null; if ((!queryParameters.ForceCacheRefresh) && (session.CacheMode & CacheMode.Get) == CacheMode.Get) { result = queryCache.Get(key, resultTypes, queryParameters.NaturalKeyLookup, querySpaces, session); if (factory.Statistics.IsStatisticsEnabled) { if (result == null) { factory.StatisticsImplementor.QueryCacheMiss(QueryIdentifier, queryCache.RegionName); } else { factory.StatisticsImplementor.QueryCacheHit(QueryIdentifier, queryCache.RegionName); } } } return result; }
public IList Get(QueryKey key, ICacheAssembler[] returnTypes, bool isNaturalKeyLookup, ISet <string> spaces, ISessionImplementor session) { if (Log.IsDebugEnabled) { Log.DebugFormat("checking cached query results in region: '{0}'; {1}", _regionName, key); } var cacheable = (IList)_queryCache.Get(key); if (cacheable == null) { Log.DebugFormat("query results were not found in cache: {0}", key); return(null); } var timestamp = (long)cacheable[0]; if (Log.IsDebugEnabled) { Log.DebugFormat("Checking query spaces for up-to-dateness [{0}]", StringHelper.CollectionToString(spaces)); } if (!isNaturalKeyLookup && !IsUpToDate(spaces, timestamp)) { Log.DebugFormat("cached query results were not up to date for: {0}", key); return(null); } Log.DebugFormat("returning cached query results for: {0}", key); for (int i = 1; i < cacheable.Count; i++) { if (returnTypes.Length == 1 && !key.HasResultTransformer) { returnTypes[0].BeforeAssemble(cacheable[i], session); } else { TypeHelper.BeforeAssemble((object[])cacheable[i], returnTypes, session); } } IList result = new List <object>(cacheable.Count - 1); for (int i = 1; i < cacheable.Count; i++) { try { if (returnTypes.Length == 1 && !key.HasResultTransformer) { result.Add(returnTypes[0].Assemble(cacheable[i], session, null)); } else { result.Add(TypeHelper.Assemble((object[])cacheable[i], returnTypes, session, null)); } } catch (UnresolvableObjectException) { if (isNaturalKeyLookup) { //TODO: not really completely correct, since // the UnresolvableObjectException could occur while resolving // associations, leaving the PC in an inconsistent state Log.Debug("could not reassemble cached result set"); _queryCache.Remove(key); return(null); } throw; } } return(result); }
public void ToStringWithMoreFilters() { string filterName = "DescriptionLike"; var f = new FilterImpl(sessions.GetFilterDefinition(filterName)); f.SetParameter("pLike", "so%"); var fk = new FilterKey(filterName, f.Parameters, f.FilterDefinition.ParameterTypes, EntityMode.Poco); filterName = "DescriptionEqualAndValueGT"; var fv = new FilterImpl(sessions.GetFilterDefinition(filterName)); fv.SetParameter("pDesc", "something").SetParameter("pValue", 10); var fvk = new FilterKey(filterName, f.Parameters, f.FilterDefinition.ParameterTypes, EntityMode.Poco); ISet<FilterKey> fks = new HashSet<FilterKey> { fk, fvk }; var qk = new QueryKey(sessions, SqlAll, new QueryParameters(), fks); Assert.That(qk.ToString(), Is.StringContaining(string.Format("filters: ['{0}', '{1}']", fk, fvk))); }
/// <summary> /// Return the query results, using the query cache, called /// by subclasses that implement cacheable queries /// </summary> /// <param name="session"></param> /// <param name="queryParameters"></param> /// <param name="querySpaces"></param> /// <param name="resultTypes"></param> /// <returns></returns> protected IList List( ISessionImplementor session, QueryParameters queryParameters, ISet querySpaces, IType[ ] resultTypes ) { ISessionFactoryImplementor factory = session.Factory; bool cacheable = factory.IsQueryCacheEnabled && queryParameters.Cacheable; if( cacheable ) { IQueryCache queryCache = factory.GetQueryCache( queryParameters.CacheRegion ); QueryKey key = new QueryKey( SqlString, queryParameters ); IList result = null; if( !queryParameters.ForceCacheRefresh ) { result = queryCache.Get( key, resultTypes, querySpaces, session ); } if( result == null ) { result = DoList( session, queryParameters ); queryCache.Put( key, resultTypes, result, session ); } return GetResultList( result ); } else { return GetResultList( DoList( session, queryParameters ) ); } }
private IList ListUsingQueryCache() { IQueryCache queryCache = session.Factory.GetQueryCache(cacheRegion); ISet filterKeys = FilterKey.CreateFilterKeys(session.EnabledFilters, session.EntityMode); ISet<string> querySpaces = new HashedSet<string>(); ArrayList resultTypesList = new ArrayList(); for (int i = 0; i < Translators.Count; i++) { QueryTranslator queryTranslator = (QueryTranslator)Translators[i]; querySpaces.AddAll(queryTranslator.QuerySpaces); resultTypesList.Add(queryTranslator.ActualReturnTypes); } int[] firstRows = new int[Parameters.Count]; int[] maxRows = new int[Parameters.Count]; for (int i = 0; i < Parameters.Count; i++) { RowSelection rowSelection = ((QueryParameters)Parameters[i]).RowSelection; firstRows[i] = rowSelection.FirstRow; maxRows[i] = rowSelection.MaxRows; } MultipleQueriesCacheAssembler assembler = new MultipleQueriesCacheAssembler(resultTypesList); QueryKey key = new QueryKey(session.Factory, SqlString, combinedParameters, filterKeys) .SetFirstRows(firstRows) .SetMaxRows(maxRows); IList result = assembler.GetResultFromQueryCache(session, combinedParameters, querySpaces, queryCache, key); if (result == null) { log.Debug("Cache miss for multi query"); ArrayList list = DoList(); queryCache.Put(key, new ICacheAssembler[] { assembler }, new object[] { list }, session); result = list; } return GetResultList(result); }
private async Task <IList> GetResultFromCacheableAsync( QueryKey key, ICacheAssembler[] returnTypes, bool isNaturalKeyLookup, ISessionImplementor session, IList cacheable, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); Log.Debug("returning cached query results for: {0}", key); if (key.ResultTransformer?.AutoDiscoverTypes == true && cacheable.Count > 0) { returnTypes = GuessTypes(cacheable); } try { var result = new List <object>(cacheable.Count - 1); if (returnTypes.Length == 1) { var returnType = returnTypes[0]; // Skip first element, it is the timestamp for (var i = 1; i < cacheable.Count; i++) { await(returnType.BeforeAssembleAsync(cacheable[i], session, cancellationToken)).ConfigureAwait(false); } for (var i = 1; i < cacheable.Count; i++) { result.Add(await(returnType.AssembleAsync(cacheable[i], session, null, cancellationToken)).ConfigureAwait(false)); } } else { var collectionIndexes = new Dictionary <int, ICollectionPersister>(); var nonCollectionTypeIndexes = new List <int>(); for (var i = 0; i < returnTypes.Length; i++) { if (returnTypes[i] is CollectionType collectionType) { collectionIndexes.Add(i, session.Factory.GetCollectionPersister(collectionType.Role)); } else { nonCollectionTypeIndexes.Add(i); } } // Skip first element, it is the timestamp for (var i = 1; i < cacheable.Count; i++) { await(TypeHelper.BeforeAssembleAsync((object[])cacheable[i], returnTypes, session, cancellationToken)).ConfigureAwait(false); } for (var i = 1; i < cacheable.Count; i++) { result.Add(await(TypeHelper.AssembleAsync((object[])cacheable[i], returnTypes, nonCollectionTypeIndexes, session, cancellationToken)).ConfigureAwait(false)); } // Initialization of the fetched collection must be done at the end in order to be able to batch fetch them // from the cache or database. The collections were already created in the previous for statement so we only // have to initialize them. if (collectionIndexes.Count > 0) { for (var i = 1; i < cacheable.Count; i++) { await(TypeHelper.InitializeCollectionsAsync((object[])cacheable[i], (object[])result[i - 1], collectionIndexes, session, cancellationToken)).ConfigureAwait(false); } } } return(result); } catch (UnresolvableObjectException ex) { if (isNaturalKeyLookup) { //TODO: not really completely correct, since // the UnresolvableObjectException could occur while resolving // associations, leaving the PC in an inconsistent state Log.Debug(ex, "could not reassemble cached result set"); // Handling a RemoveMany here does not look worth it, as this case short-circuits // the result-set. So a Many could only benefit batched queries, and only if many // of them are natural key lookup with an unresolvable object case. await(Cache.RemoveAsync(key, cancellationToken)).ConfigureAwait(false); return(null); } throw; } }
private static IList GetResultFromQueryCache(ISessionImplementor session, QueryParameters queryParameters, ISet querySpaces, IType[] resultTypes, IQueryCache queryCache, QueryKey key) { if (!queryParameters.ForceCacheRefresh) { return queryCache.Get(key, resultTypes, querySpaces, session); } return null; }
private IList GetResultFromQueryCache(ISessionImplementor session, QueryParameters queryParameters, ISet<string> querySpaces, IType[] resultTypes, IQueryCache queryCache, QueryKey key) { IList result = null; if ((!queryParameters.ForceCacheRefresh) && (session.CacheMode & CacheMode.Get) == CacheMode.Get) { IPersistenceContext persistenceContext = session.PersistenceContext; bool defaultReadOnlyOrig = persistenceContext.DefaultReadOnly; if (queryParameters.IsReadOnlyInitialized) persistenceContext.DefaultReadOnly = queryParameters.ReadOnly; else queryParameters.ReadOnly = persistenceContext.DefaultReadOnly; try { result = queryCache.Get(key, resultTypes, queryParameters.NaturalKeyLookup, querySpaces, session); if (_factory.Statistics.IsStatisticsEnabled) { if (result == null) { _factory.StatisticsImplementor.QueryCacheMiss(QueryIdentifier, queryCache.RegionName); } else { _factory.StatisticsImplementor.QueryCacheHit(QueryIdentifier, queryCache.RegionName); } } } finally { persistenceContext.DefaultReadOnly = defaultReadOnlyOrig; } } return result; }
private async Task <IList> GetResultFromCacheableAsync( QueryKey key, ICacheAssembler[] returnTypes, bool isNaturalKeyLookup, ISessionImplementor session, IList cacheable, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); Log.Debug("returning cached query results for: {0}", key); if (key.ResultTransformer?.AutoDiscoverTypes == true && cacheable.Count > 0) { returnTypes = GuessTypes(cacheable); } try { var result = new List <object>(cacheable.Count - 1); if (returnTypes.Length == 1) { var returnType = returnTypes[0]; // Skip first element, it is the timestamp var rows = new List <object>(cacheable.Count - 1); for (var i = 1; i < cacheable.Count; i++) { rows.Add(cacheable[i]); } foreach (var row in rows) { await(returnType.BeforeAssembleAsync(row, session, cancellationToken)).ConfigureAwait(false); } foreach (var row in rows) { result.Add(await(returnType.AssembleAsync(row, session, null, cancellationToken)).ConfigureAwait(false)); } } else { // Skip first element, it is the timestamp var rows = new List <object[]>(cacheable.Count - 1); for (var i = 1; i < cacheable.Count; i++) { rows.Add((object[])cacheable[i]); } foreach (var row in rows) { await(TypeHelper.BeforeAssembleAsync(row, returnTypes, session, cancellationToken)).ConfigureAwait(false); } foreach (var row in rows) { result.Add(await(TypeHelper.AssembleAsync(row, returnTypes, session, null, cancellationToken)).ConfigureAwait(false)); } } return(result); } catch (UnresolvableObjectException ex) { if (isNaturalKeyLookup) { //TODO: not really completely correct, since // the UnresolvableObjectException could occur while resolving // associations, leaving the PC in an inconsistent state Log.Debug(ex, "could not reassemble cached result set"); // Handling a RemoveMany here does not look worth it, as this case short-circuits // the result-set. So a Many could only benefit batched queries, and only if many // of them are natural key lookup with an unresolvable object case. await(Cache.RemoveAsync(key, cancellationToken)).ConfigureAwait(false); return(null); } throw; } }
private IList ListUsingQueryCache(ISessionImplementor session, QueryParameters queryParameters, ISet<string> querySpaces, IType[] resultTypes) { IQueryCache queryCache = factory.GetQueryCache(queryParameters.CacheRegion); ISet filterKeys = FilterKey.CreateFilterKeys(session.EnabledFilters, session.EntityMode); QueryKey key = new QueryKey(Factory, SqlString, queryParameters, filterKeys); IList result = GetResultFromQueryCache(session, queryParameters, querySpaces, resultTypes, queryCache, key); if (result == null) { result = DoList(session, queryParameters); PutResultInQueryCache(session, queryParameters, resultTypes, queryCache, key, result); } return GetResultList(result, queryParameters.ResultTransformer); }
public IList Get(QueryKey key, ICacheAssembler[] returnTypes, bool isNaturalKeyLookup, Iesi.Collections.Generic.ISet<string> spaces, ISessionImplementor session) { if (Log.IsDebugEnabled) Log.DebugFormat("checking cached query results in region: '{0}'; {1}", _regionName, key); var cacheable = (IList)_queryCache.Get(key); if (cacheable == null) { Log.DebugFormat("query results were not found in cache: {0}", key); return null; } var timestamp = (long)cacheable[0]; if (Log.IsDebugEnabled) Log.DebugFormat("Checking query spaces for up-to-dateness [{0}]", StringHelper.CollectionToString((ICollection)spaces)); if (!isNaturalKeyLookup && !IsUpToDate(spaces, timestamp)) { Log.DebugFormat("cached query results were not up to date for: {0}", key); return null; } Log.DebugFormat("returning cached query results for: {0}", key); for (int i = 1; i < cacheable.Count; i++) { if (returnTypes.Length == 1 && !key.HasResultTransformer) { returnTypes[0].BeforeAssemble(cacheable[i], session); } else { TypeHelper.BeforeAssemble((object[])cacheable[i], returnTypes, session); } } IList result = new List<object>(cacheable.Count - 1); for (int i = 1; i < cacheable.Count; i++) { try { if (returnTypes.Length == 1 && !key.HasResultTransformer) { result.Add(returnTypes[0].Assemble(cacheable[i], session, null)); } else { result.Add(TypeHelper.Assemble((object[])cacheable[i], returnTypes, session, null)); } } catch (UnresolvableObjectException) { if (isNaturalKeyLookup) { //TODO: not really completely correct, since // the UnresolvableObjectException could occur while resolving // associations, leaving the PC in an inconsistent state Log.Debug("could not reassemble cached result set"); _queryCache.Remove(key); return null; } throw; } } return result; }
private void PutResultInQueryCache(ISessionImplementor session, QueryParameters queryParameters, IType[] resultTypes, IQueryCache queryCache, QueryKey key, IList result) { if ((session.CacheMode & CacheMode.Put) == CacheMode.Put) { bool put = queryCache.Put(key, resultTypes, result, queryParameters.NaturalKeyLookup, session); if (put && factory.Statistics.IsStatisticsEnabled) { factory.StatisticsImplementor.QueryCachePut(QueryIdentifier, queryCache.RegionName); } } }
public override bool Equals(object other) { QueryKey that = (QueryKey)other; if (!_sqlQueryString.Equals(that._sqlQueryString)) { return(false); } if (_firstRow != that._firstRow || _maxRows != that._maxRows) { return(false); } if (!Equals(_customTransformer, that._customTransformer)) { return(false); } if (_types == null) { if (that._types != null) { return(false); } } else { if (that._types == null) { return(false); } if (_types.Length != that._types.Length) { return(false); } for (int i = 0; i < _types.Length; i++) { if (!_types[i].Equals(that._types[i])) { return(false); } if (!Equals(_values[i], that._values[i])) { return(false); } } } // BagEquals is less efficient than a SetEquals or DictionaryEquals, but serializing dictionaries causes // issues on deserialization if GetHashCode or Equals are called in its deserialization callback. And // building sets or dictionaries on the fly will in most cases be worst than BagEquals, unless re-coding // its short-circuits. if (!CollectionHelper.BagEquals(_filters, that._filters)) { return(false); } if (!CollectionHelper.BagEquals(_namedParameters, that._namedParameters, NamedParameterComparer.Instance)) { return(false); } if (!CollectionHelper.SequenceEquals <int>(_multiQueriesFirstRows, that._multiQueriesFirstRows)) { return(false); } if (!CollectionHelper.SequenceEquals <int>(_multiQueriesMaxRows, that._multiQueriesMaxRows)) { return(false); } return(true); }