Exemplo n.º 1
0
        /// <summary>
        ///     Return the result of the <paramref name="query" /> from the cache. If the query is not cached
        ///     yet, the query is materialized asynchronously and cached before being returned.
        /// </summary>
        /// <typeparam name="T">Generic type parameter.</typeparam>
        /// <param name="query">The query to cache in the QueryCacheManager.</param>
        /// <param name="absoluteExpiration">The fixed date and time at which the cache entry will expire.</param>
        /// <param name="tags">
        ///     A variable-length parameters list containing tags to expire cached
        ///     entries.
        /// </param>
        /// <returns>The result of the query.</returns>
        public static Task <T> FromCacheAsync <T>(this QueryDeferred <T> query, DateTimeOffset absoluteExpiration, params string[] tags)
        {
            var key = QueryCacheManager.GetCacheKey(query, tags);

            var result = Task.Run(() =>
            {
                var item = QueryCacheManager.Cache.Get(key);

                if (item == null)
                {
                    item = query.Execute();
                    item = QueryCacheManager.Cache.AddOrGetExisting(key, item ?? DBNull.Value, absoluteExpiration) ?? item;
                    QueryCacheManager.AddCacheTag(key, tags);
                }
                else
                {
                    if (item == DBNull.Value)
                    {
                        item = null;
                    }
                }

                return((T)item);
            });

            return(result);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Executes the query on the database irrespective of the fact that the result could have been in the cache
        /// and could have been served from there and updates the result in the cache.
        /// </summary>
        /// <typeparam name="T">The generic type of the collection</typeparam>
        /// <param name="query">The query to be executed.</param>
        /// <param name="options">The option that will be used to store the result.</param>
        /// <returns>Returns the result of the query (encapsulated in a task) after executing it on the databse and storing it in the cache.
        /// </returns>
        public static async Task <T> LoadIntoCacheAsync <T>(this QueryDeferred <T> query, CachingOptions options)
        {
            Logger.Log(
                "Async operation requested.",
                Microsoft.Extensions.Logging.LogLevel.Trace
                );
            Task <T> task = Task.Factory.StartNew(
                () => LoadIntoCache(query, options)
                );

            return(await task);
        }
Exemplo n.º 3
0
        /* ************************************************************************************************************************ */
        /*                                                                                                                          */
        /*                  OUR IMPLEMENTATIONS FOR [FromCache, FromCacheOnly AND LoadIntoCache] ASYNC METHODS                      */
        /*                                                                                                                          */
        /* ************************************************************************************************************************ */

        /// <summary>
        /// Executes the query on the cache Asynchronously and returns the result set as generic IEnumerable encapsulated as a task.
        /// </summary>
        /// <typeparam name="T">The generic type of the result</typeparam>
        /// <param name="query">The query to be executed. </param>
        /// <returns>Returns the result of the query (encapsulated in a task) after executing it in the cache. In case of no result return the
        /// default value.</returns>
        public static async Task <T> FromCacheOnlyAsync <T>(this QueryDeferred <T> query)
        {
            Logger.Log(
                "Async operation requested.",
                Microsoft.Extensions.Logging.LogLevel.Trace
                );
            Task <T> task = Task.Factory.StartNew(
                () => FromCacheOnly(query)
                );

            return(await task);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Executes the query on the cache and returns the result as generic type.
        /// </summary>
        /// <typeparam name="T">The generic type of the result.</typeparam>
        /// <param name="query">The query to be executed.</param>
        /// <returns>Returns the result of the query after executing it in the cache. In case of no result return the
        /// default value.</returns>
        public static T FromCacheOnly <T>(this QueryDeferred <T> query)
        {
            string oqlQuery = OQLBuilder.ExpressionToOQL(query.Query.GetDbContext(), query.Expression, out OQLBuilder builder);

            Logger.Log("OQL Query Generated for deferred operation: " + oqlQuery, Microsoft.Extensions.Logging.LogLevel.Debug);

            IEnumerable <T> enumerable = new NCacheOqlEnumerable <T>(
                NCacheOqlEnumerable <T> .EnumerableType.Deferred,
                QueryCacheManager.Cache.NCacheInstance.ExecuteReader(oqlQuery, new System.Collections.Hashtable(), true)
                );

            string aggregateUsed = builder.GetAggregateUsed();

            if (aggregateUsed != null)
            {
                aggregateUsed = aggregateUsed.Split('(')[0].ToLower();

                Logger.Log("Aggregate function used: " + aggregateUsed, Microsoft.Extensions.Logging.LogLevel.Trace);

                if (aggregateUsed.Equals("count"))
                {
                    dynamic expando = new ExpandoObject();
                    var     list    = enumerable.ToList();

                    if (list.Count == 1)
                    {
                        expando.Value = list[0];
                    }
                    else
                    {
                        expando.Value = list.Count;
                    }
                    return((T)expando.Value);
                }
            }

            return(enumerable.FirstOrDefault());
        }
Exemplo n.º 5
0
        /// <summary>
        ///     Return the result of the <paramref name="query" /> from the cache. If the query is not cached
        ///     yet, the query is materialized asynchronously and cached before being returned.
        /// </summary>
        /// <typeparam name="T">Generic type parameter.</typeparam>
        /// <param name="query">The query to cache in the QueryCacheManager.</param>
        /// <param name="absoluteExpiration">The fixed date and time at which the cache entry will expire.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <param name="tags">
        ///     A variable-length parameters list containing tags to expire cached
        ///     entries.
        /// </param>
        /// <returns>The result of the query.</returns>
        public static async Task <T> FromCacheAsync <T>(this QueryDeferred <T> query, DateTimeOffset absoluteExpiration, CancellationToken cancellationToken = default(CancellationToken), params string[] tags)
        {
            var key = QueryCacheManager.GetCacheKey(query, tags);

            var item = QueryCacheManager.Cache.Get(key);

            if (item == null)
            {
                item = await query.ExecuteAsync(cancellationToken).ConfigureAwait(false);

                item = QueryCacheManager.Cache.AddOrGetExisting(key, item ?? DBNull.Value, absoluteExpiration) ?? item;
                QueryCacheManager.AddCacheTag(key, tags);
            }
            else
            {
                if (item == DBNull.Value)
                {
                    item = null;
                }
            }

            return((T)item);
        }
Exemplo n.º 6
0
        /// <summary>
        ///     Return the result of the <paramref name="query" /> from the cache. If the query is not cached
        ///     yet, the query is materialized and cached before being returned.
        /// </summary>
        /// <typeparam name="T">The generic type of the query.</typeparam>
        /// <param name="query">The query to cache in the QueryCacheManager.</param>
        /// <param name="policy">The policy to use to cache the query.</param>
        /// <param name="tags">
        ///     A variable-length parameters list containing tags to expire cached
        ///     entries.
        /// </param>
        /// <returns>The result of the query.</returns>
        public static T FromCache <T>(this QueryDeferred <T> query, CacheItemPolicy policy, params string[] tags)
        {
            var key = QueryCacheManager.GetCacheKey(query, tags);

            var item = QueryCacheManager.Cache.Get(key);

            if (item == null)
            {
                item = query.Execute();

                item = QueryCacheManager.Cache.AddOrGetExisting(key, item ?? DBNull.Value, policy) ?? item;
                QueryCacheManager.AddCacheTag(key, tags);
            }
            else
            {
                if (item == DBNull.Value)
                {
                    item = null;
                }
            }

            return((T)item);
        }
Exemplo n.º 7
0
 /// <summary>Gets cached keys used to cache or retrieve a query from the QueryCacheManager.</summary>
 /// <typeparam name="T">Generic type parameter.</typeparam>
 /// <param name="query">The query to cache or retrieve from the QueryCacheManager.</param>
 /// <param name="tags">A variable-length parameters list containing tags to create the cache key.</param>
 /// <returns>The cache key used to cache or retrieve a query from the QueryCacheManager.</returns>
 internal static string GetCacheKey <T>(QueryDeferred <T> query, string tag)
 {
     return(GetQueryCacheKey(query.Query, tag));
 }
Exemplo n.º 8
0
 /// <summary>
 ///     Return the result of the <paramref name="query" /> from the cache. If the query is not cached
 ///     yet, the query is materialized asynchronously and cached before being returned.
 /// </summary>
 /// <typeparam name="T">Generic type parameter.</typeparam>
 /// <param name="query">The query to cache in the QueryCacheManager.</param>
 /// <param name="cancellationToken">The cancellation token.</param>
 /// <param name="tags">
 ///     A variable-length parameters list containing tags to expire cached
 ///     entries.
 /// </param>
 /// <returns>The result of the query.</returns>
 public static Task <T> FromCacheAsync <T>(this QueryDeferred <T> query, CancellationToken cancellationToken = default(CancellationToken), params string[] tags)
 {
     return(query.FromCacheAsync(QueryCacheManager.DefaultCacheItemPolicy, cancellationToken, tags));
 }
Exemplo n.º 9
0
 /// <summary>
 ///     Return the result of the <paramref name="query" /> from the cache. If the query is not cached
 ///     yet, the query is materialized asynchronously and cached before being returned.
 /// </summary>
 /// <typeparam name="T">Generic type parameter.</typeparam>
 /// <param name="query">The query to cache in the QueryCacheManager.</param>
 /// <param name="absoluteExpiration">The fixed date and time at which the cache entry will expire.</param>
 /// <param name="tags">
 ///     A variable-length parameters list containing tags to expire cached
 ///     entries.
 /// </param>
 /// <returns>The result of the query.</returns>
 public static Task <T> FromCacheAsync <T>(this QueryDeferred <T> query, DateTimeOffset absoluteExpiration, params string[] tags)
 {
     return(query.FromCacheAsync(absoluteExpiration, default(CancellationToken), tags));
 }
Exemplo n.º 10
0
 /// <summary>
 ///     Return the result of the <paramref name="query" /> from the cache. If the query is not cached
 ///     yet, the query is materialized asynchronously and cached before being returned.
 /// </summary>
 /// <typeparam name="T">Generic type parameter.</typeparam>
 /// <param name="query">The query to cache in the QueryCacheManager.</param>
 /// <param name="policy">The policy to use to cache the query.</param>
 /// <param name="tags">
 ///     A variable-length parameters list containing tags to expire cached
 ///     entries.
 /// </param>
 /// <returns>The result of the query.</returns>
 public static Task <T> FromCacheAsync <T>(this QueryDeferred <T> query, CacheItemPolicy policy, params string[] tags)
 {
     return(query.FromCacheAsync(policy, default(CancellationToken), tags));
 }
Exemplo n.º 11
0
 /// <summary>
 ///     Return the result of the <paramref name="query" /> from the cache. If the query is not cached
 ///     yet, the query is materialized asynchronously and cached before being returned.
 /// </summary>
 /// <typeparam name="T">Generic type parameter.</typeparam>
 /// <param name="query">The query to cache in the QueryCacheManager.</param>
 /// <param name="tags">
 ///     A variable-length parameters list containing tags to expire cached
 ///     entries.
 /// </param>
 /// <returns>The result of the query.</returns>
 public static Task <T> FromCacheAsync <T>(this QueryDeferred <T> query, params string[] tags)
 {
     return(query.FromCacheAsync(QueryCacheManager.DefaultCacheItemPolicy, tags));
 }
Exemplo n.º 12
0
        // Main implementation
        private static T FromCacheImplementation <T>(CachingMethod cachingMethod, QueryDeferred <T> query, out string cacheKey, CachingOptions options)
        {
            Logger.Log(
                "Performing " + cachingMethod + " for " + query.ToString() + " with options " + options.ToLog() + ".",
                Microsoft.Extensions.Logging.LogLevel.Trace
                );
            options = (CachingOptions)options.Clone();
            // Always store as collection
            options.StoreAs = StoreAs.Collection;

            bool        cacheHit    = false;
            IDictionary cacheResult = default(Hashtable);

            cacheKey = QueryCacheManager.GetQueryCacheKey(query.Query, options.QueryIdentifier);

            // If user has specified tag, leave it as it is
            // Otherwise overwrite it with 'cacheKey'
            options.QueryIdentifier = options.QueryIdentifier ?? cacheKey;

            /* NOTE: If user stored result with a tag and is trying to query
             *       it without the tag, it's a different query so don't
             *       worry about that.
             */

            // Get result into 'cacheResult' hashtable if it exists
            if (cachingMethod == CachingMethod.FromCache)
            {
                // Get by the tag (more reliable)
                cacheHit = QueryCacheManager.Cache.GetByKey(options.QueryIdentifier, out cacheResult);
            }
            // If result wasn't found OR result was meant to be stored fresh
            if (cachingMethod == CachingMethod.LoadIntoCache || !cacheHit)
            {
                CacheDependency dbDependency = null;

                if (options.CreateDbDependency)
                {
                    IRelationalCommand command = query.Query.CreateCommand(out RelationalQueryContext queryContext);

                    string connectionString = queryContext.Connection.ConnectionString;

                    dbDependency = GetDependency(NCacheConfiguration.DatabaseType, command.CommandText, connectionString);
                }

                object item = query.Execute();

                QueryCacheManager.Cache.SetAsCacheEntry(cacheKey, item ?? Null.Value, options, dbDependency);

                return(item == null ? default(T) : (T)item);
            }
            // If result was meant to be fetched instead of stored fresh AND it was found (somewhat)
            else
            {
                object returnVal = default(T);

                if (cacheResult != default(Hashtable))
                {
                    returnVal = cacheResult.Values.Cast <CacheEntry>().FirstOrDefault().Value;
                }
                return(returnVal != null ? (returnVal is Null ? default(T) : (T)returnVal) : default(T));
            }
        }
Exemplo n.º 13
0
 /// <summary>
 /// Checks if the result is available in cache or not. If it is available it is fetched from the cache and returned
 /// however if it is not available the query is executed on the database and the result is stored in cache as well
 /// as returned.
 /// </summary>
 /// <typeparam name="T">The generic type of the result</typeparam>
 /// <param name="query">The query to be executed.</param>
 /// <param name="cacheKey">The key against which the result will be cached is returned as out parameter.</param>
 /// <param name="options">The option that will be used to store the result.</param>
 /// <returns>Returns the result of the query from cache if available else from the database and stores it in
 /// the cache.
 /// </returns>
 public static T FromCache <T>(this QueryDeferred <T> query, out string cacheKey, CachingOptions options)
 {
     return(FromCacheImplementation(CachingMethod.FromCache, query, out cacheKey, options));
 }
Exemplo n.º 14
0
 /// <summary>
 /// Checks if the result is available in cache or not. If it is available it is fetched from the cache and returned
 /// however if it is not available the query is executed on the database and the result is stored in cache as well
 /// as returned.
 /// </summary>
 /// <typeparam name="T">The generic type of the collection</typeparam>
 /// <param name="query">The query to be executed.</param>
 /// <param name="options">The option that will be used to store the result set.</param>
 /// <returns>Returns the result set of the query from cache if available else from the database and stores it in
 /// the cache.
 /// </returns>
 public static T FromCache <T>(this QueryDeferred <T> query, CachingOptions options)
 {
     return(query.FromCache(out string cacheKey, options));
 }