// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Caching;
namespace Tools.CrashReporter.CrashReportWebSite.Models
{
///
/// A class to handle caching of database results on the web server.
///
public class CachedDataService : IDisposable
{
private CrashRepository LocalCrashRepository;
private BuggRepository BuggRepositoryInstance;
private Cache CacheInstance;
private const string CacheKeyPrefix = "_CachedDataService_";
private const string CallstackKeyPrefix = "_CallStack_";
private const string FunctionCallKeyPrefix = "_FunctionCallStack_";
private const string UserNameKeyPrefix = "_UserName_";
///
/// Link the Http context cache to a crash repository.
///
/// The current Http context cache.
/// The repository to associate the cache with.
public CachedDataService( Cache InCache, CrashRepository InCrashRepository )
{
CacheInstance = InCache;
LocalCrashRepository = InCrashRepository;
}
///
/// Link the Http context cache to a Bugg repository.
///
/// The current Http context cache.
/// The repository to associate the cache with.
public CachedDataService( Cache InCache, BuggRepository InBuggRepository )
{
CacheInstance = InCache;
BuggRepositoryInstance = InBuggRepository;
}
///
/// Implementing Dispose.
///
public void Dispose()
{
Dispose( true );
GC.SuppressFinalize( this );
}
///
/// Disposes the resources.
///
/// true if the Dispose call is from user code, and not system code.
protected virtual void Dispose( bool Disposing )
{
LocalCrashRepository.Dispose();
BuggRepositoryInstance.Dispose();
}
///
/// Retrieve a cached (and pre-parsed) callstack container from the cache, or parse the raw callstack, and add to the cache.
///
/// The crash to retrieve the parsed callstack for.
/// A parsed callstack.
public CallStackContainer GetCallStack( Crash CurrentCrash )
{
string Key = CacheKeyPrefix + CallstackKeyPrefix + CurrentCrash.Id;
CallStackContainer CallStack = ( CallStackContainer )CacheInstance[Key];
if( CallStack == null )
{
CallStack = new CallStackContainer( CurrentCrash );
CallStack.bDisplayFunctionNames = true;
CacheInstance.Insert( Key, CallStack );
}
return CallStack;
}
///
/// Retrieve a list of crashes from the cache, or retrieve a list from the database, and add to the cache.
///
/// The date of the earliest crash to consider.
/// The date of the most recent crash to consider.
/// A list of crashes between the start and end dates.
public List GetCrashes( DateTime DateFrom, DateTime DateTo )
{
string Key = CacheKeyPrefix + DateFrom + DateTo;
List Data = ( List )CacheInstance[Key];
if( Data == null )
{
IQueryable DataQuery = LocalCrashRepository.ListAll();
DataQuery = LocalCrashRepository.FilterByDate( DataQuery, DateFrom, DateTo );
Data = DataQuery.ToList();
CacheInstance.Insert( Key, Data );
}
return Data;
}
///
/// Retrieve a list of function call names from an encoded pattern. This is either from the cache, or from the database and then added to the cache.
///
/// A callstack pattern in the form '1+3+34+2'.
/// A list of function names.
public List GetFunctionCalls( string Pattern )
{
string Key = CacheKeyPrefix + FunctionCallKeyPrefix + Pattern;
List FunctionCalls = ( List )CacheInstance[Key];
if( FunctionCalls == null )
{
string[] Ids = Pattern.Split( "+".ToCharArray() );
List IdList = new List();
foreach( string id in Ids )
{
int i;
if( int.TryParse( id, out i ) )
{
IdList.Add( i );
}
}
FunctionCalls = BuggRepositoryInstance.GetFunctionCalls( IdList );
CacheInstance.Insert( Key, FunctionCalls );
}
return FunctionCalls;
}
}
}