public bool RemoveMark(params int[] fileList) { if (fileList.IsNullOrEmpty()) { return(true); } try { using (var db = new Db.DataContext()) using (var scope = db.CreateScope(TransactionScopeOption.Required)) { var query = db.File.Where(x => !x.IsRemoved && !x.IsRemoving).In(fileList, x => x.IdFile); if (query.ForEach(file => { file.IsRemoving = true; }) > 0) { db.SaveChanges(); scope.Complete(); } } return(true); } catch (Exception ex) { this.RegisterEvent(EventType.Error, "Ошибка удаления файлов с истекшим сроком", null, null, ex); return(false); } }
public bool UpdateExpiration(int[] fileList, DateTime?dateExpires = null) { if (fileList == null) { throw new ArgumentNullException(nameof(fileList)); } if (fileList.IsNullOrEmpty()) { return(true); } try { using (var db = new Db.DataContext()) { var query = db.File.Where(x => !x.IsRemoved && !x.IsRemoving).In(fileList, x => x.IdFile); if (query.ForEach(file => file.DateExpire = dateExpires) > 0) { db.SaveChanges(); } } return(true); } catch (Exception ex) { this.RegisterEvent( EventType.Error, "Ошибка обновления срока хранения файлов", $"Идентификаторы файлов: {string.Join(", ", fileList)}.\r\nНовый срок: {dateExpires?.ToString("dd.MM.yyyy HH:mm:ss")}.", null, ex); return(false); } }
public bool UpdateExpiration(int idFile, DateTime?dateExpires = null) { try { using (var db = new Db.DataContext()) { var file = db.File.Where(x => x.IdFile == idFile && !x.IsRemoved && !x.IsRemoving).FirstOrDefault(); if (file != null) { file.DateExpire = dateExpires; db.SaveChanges(); } } return(true); } catch (Exception ex) { this.RegisterEvent( EventType.Error, "Ошибка обновления срока хранения файла", $"Идентификатор файла: {idFile}.\r\nНовый срок: {dateExpires?.ToString("dd.MM.yyyy HH:mm:ss")}.", null, ex); return(false); } }
public DictionaryFiles GetList(IEnumerable <int> fileList) { if (fileList == null) { throw new ArgumentNullException(nameof(fileList)); } try { var ids = new List <int>(fileList); if (ids.Count > 0) { using (var db = new Db.DataContext()) { var query = db.File.Where(x => !x.IsRemoved && !x.IsRemoving).In(ids, x => x.IdFile); var data = query.OrderBy(x => x.NameFile).ToDictionary(x => x.IdFile, x => x); return(fileList.ToDictionary(x => x, x => data.ContainsKey(x) ? data[x] : null)); } } return(new Dictionary <int, Db.File>()); } catch (Exception ex) { this.RegisterEvent(EventType.Error, "Ошибка получения списка файлов", $"Идентификаторы файлов: {string.Join(", ", fileList)}.", null, ex); return(null); } }
public NotFound TryGetFiles(Expression <Func <Db.File, bool> > searchExpression, out List <Db.File> result) { if (searchExpression == null) { throw new ArgumentNullException(nameof(searchExpression)); } try { using (var db = new Db.DataContext()) { try { var query = db.File.Where(x => !x.IsRemoved && !x.IsRemoving).Where(searchExpression); result = query.ToList(); } catch (NotSupportedException) { throw new ArgumentException("Некорректное выражение", nameof(searchExpression)); } return(result != null && result.Count > 0 ? NotFound.Success : NotFound.NotFound); } } catch (ArgumentException) { throw; } catch (Exception ex) { result = null; this.RegisterEvent(EventType.Error, "Ошибка получения файлов", $"Выражение поиска: {searchExpression.ToString()}.", null, ex); return(NotFound.Error); } }
public void UpdateFileCount() { try { using (var db = new Db.DataContext()) { db.StoredProcedure <object>("FileManager_FileCountUpdate"); } } catch (Exception ex) { this.RegisterEvent(EventType.Error, "Ошибка обновления количества файловых связей", null, null, ex); } }
public NotFound TryGetFile(int idFile, out Db.File result) { try { using (var db = new Db.DataContext()) { result = db.File.Where(x => x.IdFile == idFile && !x.IsRemoved && !x.IsRemoving).FirstOrDefault(); return(result != null ? NotFound.Success : NotFound.NotFound); } } catch (Exception ex) { result = null; this.RegisterEvent(EventType.Error, "Ошибка получения файла", $"Идентификатор файла: {idFile}.", null, ex); return(NotFound.Error); } }
public bool RemoveCompletely(params int[] fileList) { if (fileList.IsNullOrEmpty()) { return(true); } try { var rootDirectory = AppCore.ApplicationWorkingFolder; using (var db = new Db.DataContext()) using (var scope = db.CreateScope(TransactionScopeOption.RequiresNew)) { var query = db.File.Where(x => !x.IsRemoved && !x.IsRemoving).In(fileList, x => x.IdFile); if (query.ForEach(file => { try { var pathCombined = Path.Combine(rootDirectory, file.PathFile); if (File.Exists(pathCombined)) { File.Delete(pathCombined); } } catch (IOException) { return; } catch (UnauthorizedAccessException) { return; } catch { } db.File.Remove(file); }) > 0) { db.SaveChanges(); scope.Complete(); } } return(true); } catch (Exception ex) { this.RegisterEvent(EventType.Error, "Ошибка удаления файлов с истекшим сроком", null, null, ex); return(false); } }
internal static void PlaceFileIntoQueue() { if (!_servicesFlags.TryLock("PlaceFileIntoQueue")) { return; } try { using (var db = new Db.DataContext()) { db.StoredProcedure <object>("FileManager_PlaceFileIntoQueue"); } } catch (ThreadAbortException) { } catch (Exception ex) { _thisModule?.RegisterEvent(EventType.Error, "Ошибка заполнения очереди удаления", null, ex); } finally { _servicesFlags.ReleaseLock("PlaceFileIntoQueue"); } }
internal static void CheckRemovedFiles() { // Не запускать не машине разработчика, иначе может быть так, что при подключении базе на удаленном сервере файлы физически останутся, а из базы будут удалены. if (Debug.IsDeveloper) { return; } if (!_servicesFlags.TryLock("CheckRemovedFiles")) { return; } bool isFinalized = false; int countFiles = 0; int checkRemovedFilesMax = 0; var startTime = DateTime.Now.Date.AddHours(3); try { if (_thisModule?.AppCore?.GetState() != CoreComponentState.Started) { return; } if (!_thisModule.GetConfiguration <FileManagerConfiguration>().IsCheckRemovedFiles) { return; } var journalResult = _thisModule.GetJournal(); if (!journalResult.IsSuccess) { Debug.WriteLine("Ошибка получения журнала файлового менеджера."); _thisModule?.RegisterEvent(EventType.Error, "Проверка удаленных файлов", $"Ошибка получения журнала файлового менеджера: {journalResult.Message}", null); return; } var dbAccessor = _thisModule.AppCore.Get <Journaling.DB.JournalingManagerDatabaseAccessor>(); using (var dbJournal = new Journaling.DB.DataContext()) { var range = new DateRange(DateTime.Now.Date, DateTime.Now.Date.AddDays(1)); var queryBase = dbAccessor.CreateQueryJournalData(dbJournal).Where(x => x.JournalName.IdJournal == journalResult.Result.IdJournal && x.JournalData.DateEvent >= range.Start && x.JournalData.DateEvent < range.End); if (queryBase.Where(x => x.JournalData.EventCode == EventCodeCheckRemovedFilesExecuted).Count() > 0) { return; } var lastRunInfo = queryBase.Where(x => x.JournalData.EventCode == EventCodeCheckRemovedFilesInfo).OrderByDescending(x => x.JournalData.IdJournalData).FirstOrDefault(); if (lastRunInfo == null) { if (DateTime.Now < startTime) { return; } _thisModule?.RegisterEvent(EventType.Info, "Проверка удаленных файлов", "Запуск регулярной задачи проверки файлов."); } else if (int.TryParse(lastRunInfo.JournalData.EventInfoDetailed, out int checkRemovedFilesMaxTmp)) { checkRemovedFilesMax = checkRemovedFilesMaxTmp; } } var executionTimeLimit = new TimeSpan(0, 4, 30); var dateStart = DateTime.Now; int idFileMax = checkRemovedFilesMax; var rootDirectory = _thisModule?.AppCore?.ApplicationWorkingFolder; using (var db = new Db.DataContext()) { while ((DateTime.Now - dateStart) < executionTimeLimit) { var filesQuery = db.File. AsNoTracking(). Where(x => !x.IsRemoved && !x.IsRemoving && x.IdFile > idFileMax). Select(x => new Db.File() { IdFile = x.IdFile, PathFile = x.PathFile, IsRemoving = x.IsRemoving, IsRemoved = x.IsRemoved }). OrderBy(x => x.IdFile). Take(5000); var filesList = filesQuery.ToList(); if (filesList.Count == 0) { isFinalized = true; break; } var updateList = new List <Db.File>(); filesList.ForEach(file => { try { if (!File.Exists(Path.Combine(rootDirectory, file.PathFile))) { file.IsRemoving = true; updateList.Add(file); } } catch (IOException) { return; } catch (UnauthorizedAccessException) { return; } catch { } idFileMax = file.IdFile; }); if (updateList.Count > 0) { using (var scope = db.CreateScope(TransactionScopeOption.RequiresNew)) { db.File. UpsertRange(updateList). AllowIdentityMatch(). On(x => x.IdFile). WhenMatched((xDb, xIns) => new Db.File() { IsRemoved = xIns.IsRemoved, IsRemoving = xIns.IsRemoving }). Run(); scope.Complete(); } countFiles += updateList.Count; } checkRemovedFilesMax = idFileMax; } } if (!isFinalized) { _thisModule?.RegisterEvent(EventType.Info, EventCodeCheckRemovedFilesInfo, "Проверка удаленных файлов", checkRemovedFilesMax.ToString()); } else { _thisModule?.RegisterEvent(EventType.Info, EventCodeCheckRemovedFilesExecuted, "Проверка удаленных файлов", "Удаление регулярной задачи проверки файлов."); } } catch (ThreadAbortException) { } catch (Exception ex) { _thisModule?.RegisterEvent(EventType.Error, "Проверка удаленных файлов", "Ошибка заполнения очереди удаления", ex); } finally { _servicesFlags.ReleaseLock("CheckRemovedFiles"); if (countFiles > 0) { _thisModule?.RegisterEvent(EventType.Info, "Проверка удаленных файлов", $"На удаление помечено {countFiles} файлов.", null); } } }
internal static void RemoveMarkedFiles() { if (_thisModule?.AppCore?.GetState() != CoreComponentState.Started) { return; } if (!_servicesFlags.TryLock("RemoveMarkedFiles")) { return; } int countFiles = 0; try { var executionTimeLimit = TimeSpan.FromSeconds(50); var dateStart = DateTime.Now; int idFileMax = 0; var rootDirectory = _thisModule?.AppCore?.ApplicationWorkingFolder; using (var db = new Db.DataContext()) { while ((DateTime.Now - dateStart) < executionTimeLimit) { var fileToRemoveQuery = (from FileRemoveQueue in db.FileRemoveQueue join File in db.File.AsNoTracking() on FileRemoveQueue.IdFile equals File.IdFile into File_j from File in File_j.DefaultIfEmpty() where FileRemoveQueue.IdFile > idFileMax orderby FileRemoveQueue.IdFile ascending select new { FileRemoveQueue, File }).Take(100); var fileToRemoveList = fileToRemoveQuery.ToList(); if (fileToRemoveList.Count == 0) { break; } var removeList = new List <int>(); var updateList = new List <Db.File>(); fileToRemoveList.ForEach(row => { try { if (row.File == null) { removeList.Add(row.FileRemoveQueue.IdFile); } else { var pathCombined = Path.Combine(rootDirectory, row.File.PathFile); if (File.Exists(pathCombined)) { File.Delete(pathCombined); } removeList.Add(row.FileRemoveQueue.IdFile); row.File.IsRemoving = false; row.File.IsRemoved = true; updateList.Add(row.File); } } catch (IOException) { return; } catch (UnauthorizedAccessException) { return; } catch { } idFileMax = row.FileRemoveQueue.IdFile; }); if (removeList.Count > 0 || updateList.Count > 0) { using (var scope = db.CreateScope(TransactionScopeOption.RequiresNew)) { if (removeList.Count > 0) { var query = db.FileRemoveQueue.In(removeList, x => x.IdFile); db.FileRemoveQueue.RemoveRange(query); db.SaveChanges <Db.FileRemoveQueue>(); } if (updateList.Count > 0) { if (updateList.Any(x => x.IsRemoving || !x.IsRemoved)) { throw new Exception("Флаги удаления сбросились!"); } db.File. UpsertRange(updateList). AllowIdentityMatch(). On(x => x.IdFile). WhenMatched((xDb, xIns) => new Db.File() { IsRemoved = xIns.IsRemoved, IsRemoving = xIns.IsRemoving }). Run(); } scope.Complete(); } countFiles += updateList.Count; } } } } catch (ThreadAbortException) { } catch (Exception ex) { _thisModule?.RegisterEvent(EventType.Error, "Ошибка заполнения очереди удаления", null, ex); } finally { _servicesFlags.ReleaseLock("RemoveMarkedFiles"); if (countFiles > 0) { _thisModule?.RegisterEvent(EventType.Info, "Удаление файлов", $"Удалено {countFiles} файлов.", null); } } }
public RegisterResult Register(out Db.File result, string nameFile, string pathFile, Guid?uniqueKey = null, DateTime?dateExpires = null) { if (string.IsNullOrEmpty(nameFile)) { throw new ArgumentNullException(nameof(nameFile)); } if (string.IsNullOrEmpty(pathFile)) { throw new ArgumentNullException(nameof(pathFile)); } if (Path.GetInvalidFileNameChars().Any(x => nameFile.Contains(x))) { throw new ArgumentException("Содержит символы, не разрешенные в имени файла.", nameof(nameFile)); } result = null; var pathFileFull = Path.Combine(AppCore.ApplicationWorkingFolder, pathFile); if (!File.Exists(pathFileFull)) { return(RegisterResult.NotFound); // throw new FileNotFoundException("Файл не существует", pathFile); } try { var context = AppCore.GetUserContextManager().GetCurrentUserContext(); var pathFileOld = string.Empty; using (var db = new Db.DataContext()) { var data = uniqueKey.HasValue ? (db.File.Where(x => x.UniqueKey == uniqueKey).FirstOrDefault() ?? null) : null; if (data != null && pathFile != data.PathFile) { pathFileOld = data.PathFile; } var isNew = false; if (data == null) { isNew = true; data = new Db.File(); } data.IdModule = 0; data.NameFile = nameFile; data.PathFile = pathFile; data.DateChange = DateTime.Now.Timestamp(); data.DateExpire = dateExpires; data.IdUserChange = context.IdUser; data.UniqueKey = uniqueKey; data.IsRemoved = false; data.IsRemoving = false; var fileInfo = new FileInfo(pathFileFull); var fileType = fileInfo.GetFileType(); data.TypeConcrete = fileType.Mime; if (fileType == MimeTypes.JPEG || fileType == MimeTypes.PNG || fileType == MimeTypes.BMP || fileType == MimeTypes.GIF) { data.TypeCommon = FileTypeCommon.Image; } if (isNew) { db.File.Add(data); } if (db.SaveChanges() > 0) { if (!string.IsNullOrEmpty(pathFileOld)) { var pathFileFullOld = Path.Combine(AppCore.ApplicationWorkingFolder, pathFileOld); if (File.Exists(pathFileFullOld)) { File.Delete(pathFileFullOld); } } } result = data; return(RegisterResult.Success); } } catch (Exception ex) { this.RegisterEvent(EventType.Error, "Ошибка регистрации файла", $"nameFile='{nameFile}'.\r\npathFile='{pathFile}'.\r\nuniqueKey='{uniqueKey}'.\r\ndateExpires={dateExpires?.ToString("dd.MM.yyyy HH:mm:ss")}.", null, ex); return(RegisterResult.Error); } }