This commit is contained in:
@@ -6,6 +6,7 @@ using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
||||
namespace AyaNova.Biz
|
||||
@@ -64,53 +65,78 @@ namespace AyaNova.Biz
|
||||
await JobsBiz.LogJobAsync(job.GId, $"Starting...");
|
||||
apiServerState.SetOpsOnly("Attachment file maintenance");
|
||||
|
||||
|
||||
|
||||
//get a list of all attachment files currently on disk
|
||||
var AllAttachmentFilesOnDisk = FileUtil.GetAllAttachmentFilePaths();
|
||||
List<string> AllDBFileFullPath = new List<string>();
|
||||
|
||||
// EXISTENCE CHECK
|
||||
//iterate all records in chunks
|
||||
//iterate all records in chunks, update the existence bool field if it's incorrect only
|
||||
bool moreRecords = true;
|
||||
int skip = 0;
|
||||
int chunkSize = 100;
|
||||
do
|
||||
{
|
||||
var chunk = await ct.FileAttachment.AsNoTracking().OrderBy(z => z.Id).Skip(skip).Take(chunkSize).Select(z => new NameIdItem { Id = z.Id, Name = z.StoredFileName }).ToListAsync();
|
||||
var chunk = await ct.FileAttachment.AsNoTracking().OrderBy(z => z.Id).Skip(skip).Take(chunkSize).Select(z => new { z.Id, z.StoredFileName, z.Exists }).ToListAsync();
|
||||
if (chunk.Count < chunkSize)
|
||||
{
|
||||
//we've reached the end
|
||||
moreRecords = false;
|
||||
}
|
||||
skip += chunkSize;
|
||||
foreach (NameIdItem i in chunk)
|
||||
foreach (var i in chunk)
|
||||
{
|
||||
//Does file exists where it's supposed to be?
|
||||
if (!FileUtil.AttachmentFileExists(i.Name))
|
||||
var FullPathName = FileUtil.GetPermanentAttachmentFilePath(i.StoredFileName);
|
||||
AllDBFileFullPath.Add(FullPathName);
|
||||
var FileExistsInReality = AllAttachmentFilesOnDisk.Contains(FullPathName);
|
||||
//does the db record reflect the same status as reality?
|
||||
if (FileExistsInReality != i.Exists)
|
||||
{
|
||||
//Nope so update it to be the same
|
||||
var f = await ct.FileAttachment.FirstOrDefaultAsync(z => z.Id == i.Id);
|
||||
if (f != null)
|
||||
{
|
||||
f.Exists = false;
|
||||
f.Exists = FileExistsInReality;
|
||||
await ct.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} while (moreRecords);
|
||||
// long totalRecs = await ct.FileAttachment.LongCountAsync();
|
||||
|
||||
var allAttachments = FileUtil.GetAllAttachmentFilePaths();
|
||||
//I kept this block because I did a lot of work to figure it out but in the end I don't need it because
|
||||
//a user will be moving attachments so they would no longer be existing on their old NOTYPE orphan location anyway
|
||||
// //DE-ORPHANIZE ACTION (clean up former orphans)
|
||||
// //people can attach an orphan to another record so this cleans that up
|
||||
// //also, potentiallly
|
||||
// //iterate orphaned file attachments to NOTHING type, if found to be attached to any other object remove the orphaned object attachment record in db
|
||||
// //but keeping the physical file since it's attached to something else
|
||||
// var AllOrphansInDb = await ct.FileAttachment.Where(z => z.AttachToObjectType == AyaType.NoType).ToListAsync();
|
||||
// foreach (FileAttachment OrphanInDb in AllOrphansInDb)
|
||||
// {
|
||||
// if (await ct.FileAttachment.AnyAsync(z => z.StoredFileName==OrphanInDb.StoredFileName && z.AttachToObjectType != AyaType.NoType))
|
||||
// {
|
||||
// //It is also attached to something else so remove it from the nothing type
|
||||
// ct.FileAttachment.Remove(OrphanInDb);
|
||||
// await ct.SaveChangesAsync();
|
||||
// }
|
||||
// }
|
||||
|
||||
// iterate FileAttachment records, if physically present then flag as such
|
||||
// make sure it has a short circuit that if there are NO files physically then all are out of sync
|
||||
// this scenario is someone moving a db and not moving physical files
|
||||
// ORPHANED FILES CHECK
|
||||
// These should never be out of sync due to timing issues, the file would be deleted before teh db record
|
||||
// iterate physical files, if not in db then make a FileAttachment record for it AyaType nothing id 0
|
||||
// if user want's to move them, they can download and then attach and then remove the generated attachment (Nothing id 0) the holder of orphaned files
|
||||
// (Or move feature)
|
||||
// DE-ORPHANIZE ACTION
|
||||
// iterate orphaned file attachments to NOTHING type, if found to be attached to any other object remove the orphaned object attachement
|
||||
|
||||
var FilesOnDiskNotInDb = AllAttachmentFilesOnDisk.Except(AllDBFileFullPath);
|
||||
//Attach any found into the NOTHING object type with id 0 so they will be represented in attachment list for being dealt with
|
||||
foreach (string orphan in FilesOnDiskNotInDb)
|
||||
{
|
||||
FileAttachment fa = new FileAttachment();
|
||||
fa.AttachToObjectId = 0;
|
||||
fa.AttachToObjectType = AyaType.NoType;
|
||||
fa.ContentType = "application/octet-stream";//most generic type, we don't know what it is
|
||||
fa.DisplayFileName = "FOUND" + FileUtil.GetSafeDateFileName();
|
||||
fa.LastModified = DateTime.UtcNow;
|
||||
fa.Notes = "Found in attachments folder not linked to an object";
|
||||
fa.StoredFileName = System.IO.Path.GetFileName(orphan);
|
||||
await ct.FileAttachment.AddAsync(fa);
|
||||
await ct.SaveChangesAsync();
|
||||
}
|
||||
|
||||
|
||||
await JobsBiz.LogJobAsync(job.GId, "Finished.");
|
||||
|
||||
Reference in New Issue
Block a user