using System; using System.Collections; using System.Collections.Generic; using System.Data.Entity; using System.Linq; using LeafWeb.Core.Entities; using MlkPwgen; namespace LeafWeb.Core.DAL { public class DataService : IDisposable { public static void RegisterInitializer() { Database.SetInitializer(new LeafWebInitializer()); new LeafWebContext().Database.Initialize(true); } private readonly LeafWebContext _db = new LeafWebContext(); public void Dispose() { _db.Dispose(); } private void RemoveCollectionFromDbSet(ICollection collection, IDbSet set) where T : class { if (collection == null) return; foreach (var entity in collection.ToArray()) set.Remove(entity); } #region Fluxnet Sites public IQueryable GetFluxnetSites() { return _db.FluxnetSites; } public IQueryable GetFluxnetSitesAutocomplete(string term) { return from fs in GetFluxnetSites() where fs.FluxnetId.StartsWith(term) || fs.SiteName.Contains(term) select fs; } #endregion #region LeafInput public IQueryable GetLeafInputs() { return _db.LeafInputs; } public IQueryable GetLeafInputsOrdered() { return _db.LeafInputs // first by in-progress items .OrderByDescending(li => li.CurrentStatus == LeafInputStatusType.Running || li.CurrentStatus == LeafInputStatusType.Starting || li.CurrentStatus == LeafInputStatusType.Finishing || li.CurrentStatus == LeafInputStatusType.Cancelling || li.CurrentStatus == LeafInputStatusType.CancelPending) // then by pending, by priority .ThenByDescending(li => li.CurrentStatus == LeafInputStatusType.Pending ? (int)li.PendingPriority : int.MinValue) // then by pending, rest by the order they're added in, ascending .ThenBy(li => li.CurrentStatus == LeafInputStatusType.Pending ? li.Id : int.MaxValue) // then the rest descending by the order last status change .ThenByDescending(li => (from s in li.StatusHistory select s).Max(s => s.DateTime)); } public IEnumerable GetLeafInputRecentlyCompleted(int count) { return _db.LeafInputs .Where(li => li.CurrentStatus == LeafInputStatusType.Complete) .Take(count) .ToList() .Where(li => li.OutputErrorMessage == null); } public LeafInput GetLeafInput(int id) { return _db.LeafInputs.FirstOrDefault(li => li.Id == id); } public void DeleteLeafInput(LeafInput leafInput) { RemoveCollectionFromDbSet(leafInput.InputFiles, _db.LeafInputFiles); if (leafInput.OutputFiles != null) foreach (var outputFile in leafInput.OutputFiles.ToArray()) if (outputFile.FileContents != null) _db.LeafOutputFileContents.Remove(outputFile.FileContents); RemoveCollectionFromDbSet(leafInput.OutputFiles, _db.LeafOutputFiles); RemoveCollectionFromDbSet(leafInput.StatusHistory, _db.LeafInputStatus); // Data if (leafInput.LeafInputData != null) foreach (var leafInputData in leafInput.LeafInputData.ToArray()) RemoveLeafInputDataNoUpdate(leafInputData); _db.LeafInputs.Remove(leafInput); _db.SaveChanges(); } private void RemoveLeafInputDataNoUpdate(LeafInputData leafInputData) { if (leafInputData.Data != null) foreach (var curve in leafInputData.Data.ToArray()) _db.LeafInputDataCurves.Remove(curve); if (leafInputData.Photosynthetic != null) _db.LeafInputDataPhotosynthetic.Remove(leafInputData.Photosynthetic); if (leafInputData.Site != null) _db.LeafInputDataSite.Remove(leafInputData.Site); _db.LeafInputData.Remove(leafInputData); } public LeafOutputFile GetLeafOutput_ChartFile(int leafInputId) { return GetLeafOutput_FilenameLike(leafInputId, LeafOutputFile.Filename_LeafChart); } private LeafOutputFile GetLeafOutput_FilenameLike(int leafInputId, string filename) { var leafOutputChartFile = from leafInput in _db.LeafInputs where leafInput.Id == leafInputId from leafOutput in leafInput.OutputFiles where leafOutput.Filename.Contains(filename) select leafOutput; return leafOutputChartFile.FirstOrDefault(); } public LeafInput GetLeafInput(string uniqueToken) { return _db.LeafInputs.FirstOrDefault(li => li.UniqueToken == uniqueToken); } public IQueryable GetLeafInputs(params LeafInputStatusType[] statuses) { return from file in GetLeafInputs() where statuses.Contains(file.CurrentStatus) select file; } public void AddLeafInput(LeafInput leafInput) { leafInput.Added = DateTime.Now; leafInput.UniqueToken = PasswordGenerator.Generate(12); _db.LeafInputs.Add(leafInput); SetLeafInputStatusNoUpdate(leafInput, LeafInputStatusType.Pending, "LeafInput added"); _db.SaveChanges(); } private void SetLeafInputStatusNoUpdate(LeafInput leafInputFile, LeafInputStatusType status, string description = null, string details = null) { leafInputFile.CurrentStatus = status; var leafInputFileStatus = new LeafInputStatus { Status = status, DateTime = DateTime.Now, Description = description, Details = details, LeafInput = leafInputFile }; if (leafInputFile.StatusHistory == null) leafInputFile.StatusHistory = new List(); leafInputFile.StatusHistory.Add(leafInputFileStatus); } public void SetLeafInputStatus(LeafInput leafInput, LeafInputStatusType status, string description = null, string details = null) { SetLeafInputStatusNoUpdate(leafInput, status, description, details); UpdateLeafInput(leafInput); } public void UpdateLeafInput(LeafInput leafInput) { _db.Entry(leafInput).State = EntityState.Modified; _db.SaveChanges(); } #endregion #region LeafInputFile public IQueryable GetLeafInputFiles() { return _db.LeafInputFiles; } public LeafInputFile GetLeafInputFile(int id) { return _db.LeafInputFiles.Find(id); } public void UpdateLeafInputFile(LeafInputFile leafInputFile) { _db.Entry(leafInputFile).State = EntityState.Modified; _db.SaveChanges(); } #endregion #region Photosynthesis Types public IQueryable GetPhotosynthesisTypes() { return _db.PhotosynthesisTypes.OrderBy(pt => pt.SortOrder); } public PhotosynthesisType GetPhotosynthesisType(string id) { return _db.PhotosynthesisTypes.Find(id); } #endregion #region LeafOutputFile public void AddLeafOutputFile(LeafOutputFile leafOutput) { _db.LeafOutputFiles.Add(leafOutput); _db.SaveChanges(); } public IQueryable GetLeafOutputFiles() { return _db.LeafOutputFiles; } public LeafOutputFile GetLeafOutputFile(int id) { return _db.LeafOutputFiles.Find(id); } #endregion } }