using LiteDB; using System; using System.Collections.Generic; using System.Data.Entity; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using Tango.BL; using Tango.BL.Enumerations; namespace Tango.Insights { public class InsightsManager : IDisposable { private const string INSIGHTS_COLLECTION = "Insights"; private const string STATUSES_COLLECTION = "Statuses"; private const string APPLICATION_EXCEPTIONS_COLLECTION = "ApplicationExceptions"; private bool _disposed; private static InsightsManager _instance; public static InsightsManager Default { get { if (_instance == null) { _instance = new InsightsManager(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Twine", "Tango", "Insights", Path.GetFileNameWithoutExtension(AppDomain.CurrentDomain.FriendlyName) + ".insights")); } return _instance; } } private LiteDatabase _database; public String DatabasePath { get; private set; } private InsightsManager(String databasePath) { DatabasePath = databasePath; Directory.CreateDirectory(Path.GetDirectoryName(DatabasePath)); _database = new LiteDatabase($"Filename={DatabasePath}"); _database.Pragma("TIMEOUT", 10); //Read Timeout _database.Pragma("UTC_DATE", true); //Keep time as UTC when getting data _database.Commit(); } public virtual void Dispose() { if (_database != null) { try { _disposed = true; _database.Dispose(); _database = null; } catch { } } } ~InsightsManager() { Dispose(); } private ILiteCollection GetInsightsCollection() { return _database.GetCollection(INSIGHTS_COLLECTION); } private ILiteCollection GetStatusesCollection() { return _database.GetCollection(STATUSES_COLLECTION); } private ILiteCollection GetApplicationExceptionsCollection() { return _database.GetCollection(APPLICATION_EXCEPTIONS_COLLECTION); } public virtual void InsertFrame(InsightsFrame frame) { if (_disposed) return; var collection = GetInsightsCollection(); collection.Insert(frame); } public virtual void InsertStatus(InsightsStatus status) { if (_disposed) return; var collection = GetStatusesCollection(); collection.Insert(status); } public virtual void InsertApplicationException(InsightsApplicationException appException) { if (_disposed) return; var collection = GetApplicationExceptionsCollection(); appException.Time = appException.Time.Subtract(TimeSpan.FromSeconds(30)); collection.Insert(appException); } public virtual List GetFrames(DateTime startUTC, DateTime endUTC) { var collection = GetInsightsCollection(); return collection.Find(x => x.Time >= startUTC && x.Time <= endUTC).ToList().OrderBy(x => x.Time).ToList(); } public virtual List GetStatuses(DateTime startUTC, DateTime endUTC) { var collection = GetStatusesCollection(); return collection.Find(x => x.Time >= startUTC && x.Time <= endUTC).ToList().OrderBy(x => x.Time).ToList(); } public virtual List GetApplicationExceptions(DateTime startUTC, DateTime endUTC) { var collection = GetApplicationExceptionsCollection(); return collection.Find(x => x.Time >= startUTC && x.Time <= endUTC).ToList().OrderBy(x => x.Time).ToList(); } public virtual int DeleteFrames(DateTime maxDateUTC) { if (_disposed) return 0; var collection = GetInsightsCollection(); return collection.DeleteMany(x => x.Time < maxDateUTC); } public virtual int DeleteStatuses(DateTime maxDateUTC) { if (_disposed) return 0; var collection = GetStatusesCollection(); return collection.DeleteMany(x => x.Time < maxDateUTC); } public virtual int DeleteApplicationExceptions(DateTime maxDateUTC) { if (_disposed) return 0; var collection = GetApplicationExceptionsCollection(); return collection.DeleteMany(x => x.Time < maxDateUTC); } public DateTime? GetFramesMinDate() { if (_disposed) return null; var collection = GetInsightsCollection(); if (collection.Count() > 0) { return collection.Min(x => x.Time); } else { return null; } } public virtual List GetEvents(DateTime startUTC, DateTime endUTC, bool limitToMinFramesTime = true) { using (ObservablesContext db = ObservablesContext.CreateDefault()) { List events = db.MachinesEvents .Where(x => x.DateTime >= startUTC && x.DateTime <= endUTC) .Include(x => x.EventType) .Select(x => new InsightsEvent() { Time = x.DateTime, EventCode = x.EventType.Code, Description = x.Description }) .ToList() .Where(x => (EventTypes)x.EventCode != EventTypes.APPLICATION_EXCEPTION) .Select(x => new InsightsEvent() { Time = x.Time, EventCode = x.EventCode, Description = ((EventTypes)x.EventCode == EventTypes.JOB_FAILED ? x.Description : null) }) .OrderBy(x => x.Time) .ToList(); if (limitToMinFramesTime) { var collection = GetInsightsCollection(); if (collection.Count() > 0) { var minTime = collection.Min(x => x.Time); events.RemoveAll(x => x.Time < minTime); } } return events; } } } }