optimized updating new tags
This commit is contained in:
parent
4eb5aaa2c0
commit
4632b44767
@ -46,6 +46,7 @@ public interface ITagDao<T>
|
||||
Task<TagInfo> SaveTagInfoAsync(TagInfo tagInfo);
|
||||
Task UpdateNewTags(IEnumerable<Tag> tag, Guid createdBy = default);
|
||||
Task UpdateNewTags(Tag tag);
|
||||
Task IncrementNewTagsAsync(IEnumerable<Tag> tags, Guid createdBy = default);
|
||||
Task RemoveTagsAsync(IEnumerable<int> tagsIds);
|
||||
Task RemoveTagsAsync(FileEntry<T> entry, IEnumerable<int> tagsIds);
|
||||
Task RemoveTags(IEnumerable<Tag> tag);
|
||||
|
@ -468,6 +468,45 @@ internal abstract class BaseTagDao<T> : AbstractDao
|
||||
return t;
|
||||
}
|
||||
|
||||
public async Task IncrementNewTagsAsync(IEnumerable<Tag> tags, Guid createdBy = default)
|
||||
{
|
||||
if (tags == null || !tags.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
await _semaphore.WaitAsync();
|
||||
|
||||
await using var filesDbContext = _dbContextFactory.CreateDbContext();
|
||||
var strategy = filesDbContext.Database.CreateExecutionStrategy();
|
||||
|
||||
await strategy.ExecuteAsync(async () =>
|
||||
{
|
||||
await using var internalFilesDbContext = _dbContextFactory.CreateDbContext();
|
||||
await using var tx = await internalFilesDbContext.Database.BeginTransactionAsync();
|
||||
|
||||
var createOn = _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow());
|
||||
var tenantId = TenantID;
|
||||
|
||||
foreach (var tagsGroup in tags.GroupBy(t => new { t.EntryId, t.EntryType }))
|
||||
{
|
||||
var mappedId = (await MappingIDAsync(tagsGroup.Key.EntryId)).ToString();
|
||||
|
||||
await Queries.IncrementNewTagsAsync(filesDbContext, tenantId, tagsGroup.Select(t => t.Id), tagsGroup.Key.EntryType,
|
||||
mappedId, createdBy, createOn);
|
||||
}
|
||||
|
||||
await tx.CommitAsync();
|
||||
});
|
||||
}
|
||||
finally
|
||||
{
|
||||
_semaphore.Release();
|
||||
}
|
||||
}
|
||||
|
||||
public async Task UpdateNewTags(IEnumerable<Tag> tags, Guid createdBy = default)
|
||||
{
|
||||
if (tags == null || !tags.Any())
|
||||
@ -1323,4 +1362,18 @@ static file class Queries
|
||||
.Where(r => r.TenantId == tenantId)
|
||||
.Where(r => tagsIds.Contains(r.Id))
|
||||
.ExecuteDelete());
|
||||
|
||||
public static readonly Func<FilesDbContext, int, IEnumerable<int>, FileEntryType, string, Guid, DateTime, Task<int>>
|
||||
IncrementNewTagsAsync = Microsoft.EntityFrameworkCore.EF.CompileAsyncQuery(
|
||||
(FilesDbContext ctx, int tenantId, IEnumerable<int> tagsIds, FileEntryType tagEntryType, string mappedId, Guid createdBy,
|
||||
DateTime createOn) =>
|
||||
ctx.TagLink
|
||||
.Where(r => r.TenantId == tenantId)
|
||||
.Where(r => tagsIds.Contains(r.TagId))
|
||||
.Where(r => r.EntryType == tagEntryType)
|
||||
.Where(r => r.EntryId == mappedId)
|
||||
.ExecuteUpdate(f => f
|
||||
.SetProperty(p => p.CreateBy, createdBy)
|
||||
.SetProperty(p => p.CreateOn, createOn)
|
||||
.SetProperty(p => p.Count, p => p.Count + 1)));
|
||||
}
|
||||
|
@ -25,7 +25,7 @@
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
namespace ASC.Web.Files.Utils;
|
||||
|
||||
|
||||
[Singletone]
|
||||
public class FileMarkerHelper
|
||||
{
|
||||
@ -33,7 +33,7 @@ public class FileMarkerHelper
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly ILogger _logger;
|
||||
public DistributedTaskQueue Tasks { get; set; }
|
||||
|
||||
|
||||
public FileMarkerHelper(
|
||||
IServiceProvider serviceProvider,
|
||||
ILogger<FileMarkerHelper> logger,
|
||||
@ -43,12 +43,12 @@ public class FileMarkerHelper
|
||||
_logger = logger;
|
||||
Tasks = queueFactory.CreateQueue(CUSTOM_DISTRIBUTED_TASK_QUEUE_NAME);
|
||||
}
|
||||
|
||||
|
||||
internal void Add<T>(AsyncTaskData<T> taskData)
|
||||
{
|
||||
Tasks.EnqueueTask(async (d, c) => await ExecMarkFileAsNewAsync(taskData), taskData);
|
||||
}
|
||||
|
||||
|
||||
private async Task ExecMarkFileAsNewAsync<T>(AsyncTaskData<T> obj)
|
||||
{
|
||||
try
|
||||
@ -64,14 +64,14 @@ public class FileMarkerHelper
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Scope(Additional = typeof(FileMarkerExtention))]
|
||||
public class FileMarker
|
||||
{
|
||||
private readonly ICache _cache;
|
||||
|
||||
|
||||
private const string CacheKeyFormat = "MarkedAsNew/{0}/folder_{1}";
|
||||
|
||||
|
||||
private readonly TenantManager _tenantManager;
|
||||
private readonly UserManager _userManager;
|
||||
private readonly IDaoFactory _daoFactory;
|
||||
@ -106,14 +106,14 @@ public class FileMarker
|
||||
_roomsNotificationSettingsHelper = roomsNotificationSettingsHelper;
|
||||
_cache = cache;
|
||||
}
|
||||
|
||||
|
||||
internal async Task ExecMarkFileAsNewAsync<T>(AsyncTaskData<T> obj, SocketManager socketManager)
|
||||
{
|
||||
await _tenantManager.SetCurrentTenantAsync(obj.TenantID);
|
||||
|
||||
|
||||
var folderDao = _daoFactory.GetFolderDao<T>();
|
||||
T parentFolderId;
|
||||
|
||||
|
||||
if (obj.FileEntry.FileEntryType == FileEntryType.File)
|
||||
{
|
||||
parentFolderId = ((File<T>)obj.FileEntry).ParentId;
|
||||
@ -122,26 +122,26 @@ public class FileMarker
|
||||
{
|
||||
parentFolderId = ((Folder<T>)obj.FileEntry).Id;
|
||||
}
|
||||
|
||||
|
||||
var parentFolders = await folderDao.GetParentFoldersAsync(parentFolderId).Reverse().ToListAsync();
|
||||
|
||||
|
||||
var userIDs = obj.UserIDs;
|
||||
|
||||
|
||||
var userEntriesData = new Dictionary<Guid, List<FileEntry>>();
|
||||
|
||||
|
||||
if (obj.FileEntry.RootFolderType == FolderType.BUNCH)
|
||||
{
|
||||
if (userIDs.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var projectsFolder = await _globalFolder.GetFolderProjectsAsync<T>(_daoFactory);
|
||||
parentFolders.Add(await folderDao.GetFolderAsync(projectsFolder));
|
||||
|
||||
|
||||
var entries = new List<FileEntry> { obj.FileEntry };
|
||||
entries = entries.Concat(parentFolders).ToList();
|
||||
|
||||
|
||||
userIDs.ForEach(userID =>
|
||||
{
|
||||
if (userEntriesData.TryGetValue(userID, out var value))
|
||||
@ -152,19 +152,20 @@ public class FileMarker
|
||||
{
|
||||
userEntriesData.Add(userID, entries);
|
||||
}
|
||||
|
||||
|
||||
RemoveFromCahce(projectsFolder, userID);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
var filesSecurity = _fileSecurity;
|
||||
|
||||
|
||||
if (userIDs.Count == 0)
|
||||
{
|
||||
var guids = await filesSecurity.WhoCanReadAsync(obj.FileEntry);
|
||||
userIDs = guids.Where(x => x != obj.CurrentAccountId).ToList();
|
||||
}
|
||||
|
||||
if (obj.FileEntry.ProviderEntry)
|
||||
{
|
||||
userIDs = await userIDs.ToAsyncEnumerable().WhereAwait(async u => !await _userManager.IsUserAsync(u)).ToListAsync();
|
||||
@ -203,15 +204,15 @@ public class FileMarker
|
||||
{
|
||||
userEntriesData.Add(id, new List<FileEntry> { parentFolder });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if (obj.FileEntry.RootFolderType == FolderType.USER)
|
||||
{
|
||||
var folderDaoInt = _daoFactory.GetFolderDao<int>();
|
||||
var folderShare = await folderDaoInt.GetFolderAsync(await _globalFolder.GetFolderShareAsync(_daoFactory));
|
||||
|
||||
|
||||
foreach (var userID in userIDs)
|
||||
{
|
||||
var userFolderId = await folderDaoInt.GetFolderIDUserAsync(false, userID);
|
||||
@ -219,13 +220,13 @@ public class FileMarker
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
Folder<int> rootFolder = null;
|
||||
if (obj.FileEntry.ProviderEntry)
|
||||
{
|
||||
rootFolder = obj.FileEntry.RootCreateBy == userID
|
||||
? await folderDaoInt.GetFolderAsync(userFolderId)
|
||||
: folderShare;
|
||||
? await folderDaoInt.GetFolderAsync(userFolderId)
|
||||
: folderShare;
|
||||
}
|
||||
else if (!Equals(obj.FileEntry.RootId, userFolderId))
|
||||
{
|
||||
@ -235,12 +236,12 @@ public class FileMarker
|
||||
{
|
||||
RemoveFromCahce(userFolderId, userID);
|
||||
}
|
||||
|
||||
|
||||
if (rootFolder == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (userEntriesData.TryGetValue(userID, out var value))
|
||||
{
|
||||
value.Add(rootFolder);
|
||||
@ -249,7 +250,7 @@ public class FileMarker
|
||||
{
|
||||
userEntriesData.Add(userID, new List<FileEntry> { rootFolder });
|
||||
}
|
||||
|
||||
|
||||
RemoveFromCahce(rootFolder.Id, userID);
|
||||
}
|
||||
}
|
||||
@ -257,7 +258,7 @@ public class FileMarker
|
||||
{
|
||||
var commonFolderId = await _globalFolder.GetFolderCommonAsync(this, _daoFactory);
|
||||
userIDs.ForEach(userID => RemoveFromCahce(commonFolderId, userID));
|
||||
|
||||
|
||||
if (obj.FileEntry.ProviderEntry)
|
||||
{
|
||||
var commonFolder = await folderDao.GetFolderAsync(await _globalFolder.GetFolderCommonAsync<T>(this, _daoFactory));
|
||||
@ -271,7 +272,7 @@ public class FileMarker
|
||||
{
|
||||
userEntriesData.Add(userID, new List<FileEntry> { commonFolder });
|
||||
}
|
||||
|
||||
|
||||
RemoveFromCahce(commonFolderId, userID);
|
||||
});
|
||||
}
|
||||
@ -338,7 +339,7 @@ public class FileMarker
|
||||
RemoveFromCahce(rootFolder.Id, userID);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
userIDs.ForEach(userID =>
|
||||
{
|
||||
if (userEntriesData.TryGetValue(userID, out var value))
|
||||
@ -351,67 +352,64 @@ public class FileMarker
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
var tagDao = _daoFactory.GetTagDao<T>();
|
||||
var newTags = new List<Tag>();
|
||||
var updateTags = new List<Tag>();
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
await _semaphore.WaitAsync();
|
||||
|
||||
foreach (var userID in userEntriesData.Keys)
|
||||
{
|
||||
if (await tagDao.GetNewTagsAsync(userID, obj.FileEntry).AnyAsync())
|
||||
foreach (var userId in userEntriesData.Keys)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var entries = userEntriesData[userID].Distinct().ToList();
|
||||
|
||||
await GetNewTagsAsync(userID, entries.OfType<FileEntry<int>>().ToList());
|
||||
await GetNewTagsAsync(userID, entries.OfType<FileEntry<string>>().ToList());
|
||||
}
|
||||
if (await tagDao.GetNewTagsAsync(userId, obj.FileEntry).AnyAsync())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (updateTags.Count > 0)
|
||||
{
|
||||
await tagDao.UpdateNewTags(updateTags, obj.CurrentAccountId);
|
||||
}
|
||||
|
||||
if (newTags.Count > 0)
|
||||
{
|
||||
await tagDao.SaveTags(newTags, obj.CurrentAccountId);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw;
|
||||
var entries = userEntriesData[userId].Distinct().ToList();
|
||||
|
||||
await GetNewTagsAsync(userId, entries.OfType<FileEntry<int>>().ToList());
|
||||
await GetNewTagsAsync(userId, entries.OfType<FileEntry<string>>().ToList());
|
||||
}
|
||||
|
||||
if (updateTags.Count > 0)
|
||||
{
|
||||
await tagDao.IncrementNewTagsAsync(updateTags, obj.CurrentAccountId);
|
||||
}
|
||||
|
||||
if (newTags.Count > 0)
|
||||
{
|
||||
await tagDao.SaveTags(newTags, obj.CurrentAccountId);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_semaphore.Release();
|
||||
}
|
||||
|
||||
|
||||
await Task.WhenAll(ExecMarkAsNewRequest(updateTags.Concat(newTags), socketManager));
|
||||
|
||||
async Task GetNewTagsAsync<T1>(Guid userID, List<FileEntry<T1>> entries)
|
||||
return;
|
||||
|
||||
async Task GetNewTagsAsync<T1>(Guid userId, List<FileEntry<T1>> entries)
|
||||
{
|
||||
var tagDao1 = _daoFactory.GetTagDao<T1>();
|
||||
var exist = await tagDao1.GetNewTagsAsync(userID, entries).ToListAsync();
|
||||
var exist = await tagDao1.GetNewTagsAsync(userId, entries).ToListAsync();
|
||||
var update = exist.Where(t => t.EntryType == FileEntryType.Folder).ToList();
|
||||
update.ForEach(t => t.Count++);
|
||||
updateTags.AddRange(update);
|
||||
|
||||
|
||||
entries.ForEach(entry =>
|
||||
{
|
||||
if (entry != null && exist.All(tag => tag != null && !tag.EntryId.Equals(entry.Id)))
|
||||
{
|
||||
newTags.Add(Tag.New(userID, entry));
|
||||
newTags.Add(Tag.New(userId, entry));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public async ValueTask MarkAsNewAsync<T>(FileEntry<T> fileEntry, List<Guid> userIDs = null)
|
||||
{
|
||||
if (fileEntry == null)
|
||||
@ -420,36 +418,36 @@ public class FileMarker
|
||||
}
|
||||
|
||||
userIDs ??= new List<Guid>();
|
||||
|
||||
|
||||
var taskData = _serviceProvider.GetService<AsyncTaskData<T>>();
|
||||
taskData.FileEntry = (FileEntry<T>)fileEntry.Clone();
|
||||
taskData.UserIDs = userIDs;
|
||||
|
||||
|
||||
if (fileEntry.RootFolderType == FolderType.BUNCH && userIDs.Count == 0)
|
||||
{
|
||||
var folderDao = _daoFactory.GetFolderDao<T>();
|
||||
var path = await folderDao.GetBunchObjectIDAsync(fileEntry.RootId);
|
||||
|
||||
|
||||
var projectID = path.Split('/').Last();
|
||||
if (string.IsNullOrEmpty(projectID))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var whoCanRead = await _fileSecurity.WhoCanReadAsync(fileEntry);
|
||||
var projectTeam = whoCanRead.Where(x => x != _authContext.CurrentAccount.ID).ToList();
|
||||
|
||||
|
||||
if (projectTeam.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
taskData.UserIDs = projectTeam;
|
||||
}
|
||||
|
||||
|
||||
_serviceProvider.GetService<FileMarkerHelper>().Add(taskData);
|
||||
}
|
||||
|
||||
|
||||
public async ValueTask RemoveMarkAsNewAsync<T>(FileEntry<T> fileEntry, Guid userID = default)
|
||||
{
|
||||
if (fileEntry == null)
|
||||
@ -458,41 +456,41 @@ public class FileMarker
|
||||
}
|
||||
|
||||
userID = userID.Equals(default) ? _authContext.CurrentAccount.ID : userID;
|
||||
|
||||
|
||||
var tagDao = _daoFactory.GetTagDao<T>();
|
||||
var internalFolderDao = _daoFactory.GetFolderDao<int>();
|
||||
var folderDao = _daoFactory.GetFolderDao<T>();
|
||||
|
||||
|
||||
if (!await tagDao.GetNewTagsAsync(userID, fileEntry).AnyAsync())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
T folderID;
|
||||
int valueNew;
|
||||
var userFolderId = await internalFolderDao.GetFolderIDUserAsync(false, userID);
|
||||
var privacyFolderId = await internalFolderDao.GetFolderIDPrivacyAsync(false, userID);
|
||||
|
||||
|
||||
var removeTags = new List<Tag>();
|
||||
|
||||
|
||||
if (fileEntry.FileEntryType == FileEntryType.File)
|
||||
{
|
||||
folderID = ((File<T>)fileEntry).ParentId;
|
||||
|
||||
|
||||
removeTags.Add(Tag.New(userID, fileEntry));
|
||||
valueNew = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
folderID = fileEntry.Id;
|
||||
|
||||
|
||||
var listTags = await tagDao.GetNewTagsAsync(userID, (Folder<T>)fileEntry, true).ToListAsync();
|
||||
valueNew = listTags.FirstOrDefault(tag => tag.EntryId.Equals(fileEntry.Id)).Count;
|
||||
|
||||
|
||||
if (Equals(fileEntry.Id, userFolderId) || Equals(fileEntry.Id, await _globalFolder.GetFolderCommonAsync(this, _daoFactory)) || Equals(fileEntry.Id, await _globalFolder.GetFolderShareAsync(_daoFactory)))
|
||||
{
|
||||
var folderTags = listTags.Where(tag => tag.EntryType == FileEntryType.Folder);
|
||||
|
||||
|
||||
foreach (var tag in folderTags)
|
||||
{
|
||||
var folderEntry = await folderDao.GetFolderAsync((T)tag.EntryId);
|
||||
@ -500,15 +498,15 @@ public class FileMarker
|
||||
{
|
||||
listTags.Remove(tag);
|
||||
listTags.AddRange(await tagDao.GetNewTagsAsync(userID, folderEntry, true).ToListAsync());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
removeTags.AddRange(listTags);
|
||||
}
|
||||
|
||||
|
||||
var parentFolders = await folderDao.GetParentFoldersAsync(folderID).Reverse().ToListAsync();
|
||||
|
||||
|
||||
var rootFolder = parentFolders.LastOrDefault();
|
||||
int rootFolderId = default;
|
||||
int cacheFolderId = default;
|
||||
@ -561,24 +559,24 @@ public class FileMarker
|
||||
{
|
||||
cacheFolderId = await _globalFolder.GetFolderShareAsync(_daoFactory);
|
||||
}
|
||||
|
||||
|
||||
var updateTags = new List<Tag>();
|
||||
|
||||
|
||||
if (!rootFolderId.Equals(default))
|
||||
{
|
||||
await UpdateRemoveTags(await internalFolderDao.GetFolderAsync(rootFolderId));
|
||||
}
|
||||
|
||||
|
||||
if (!cacheFolderId.Equals(default))
|
||||
{
|
||||
RemoveFromCahce(cacheFolderId, userID);
|
||||
}
|
||||
|
||||
|
||||
foreach (var parentFolder in parentFolders)
|
||||
{
|
||||
await UpdateRemoveTags(parentFolder);
|
||||
}
|
||||
|
||||
|
||||
if (updateTags.Count > 0)
|
||||
{
|
||||
await tagDao.UpdateNewTags(updateTags);
|
||||
@ -604,11 +602,11 @@ public class FileMarker
|
||||
var tagDao = _daoFactory.GetTagDao<TFolder>();
|
||||
var newTags = tagDao.GetNewTagsAsync(userID, folder);
|
||||
var parentTag = await newTags.FirstOrDefaultAsync();
|
||||
|
||||
|
||||
if (parentTag != null)
|
||||
{
|
||||
parentTag.Count -= valueNew;
|
||||
|
||||
|
||||
if (parentTag.Count > 0)
|
||||
{
|
||||
updateTags.Add(parentTag);
|
||||
@ -620,21 +618,21 @@ public class FileMarker
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public async Task RemoveMarkAsNewForAllAsync<T>(FileEntry<T> fileEntry)
|
||||
{
|
||||
IAsyncEnumerable<Guid> userIDs;
|
||||
|
||||
|
||||
var tagDao = _daoFactory.GetTagDao<T>();
|
||||
var tags = tagDao.GetTagsAsync(fileEntry.Id, fileEntry.FileEntryType == FileEntryType.File ? FileEntryType.File : FileEntryType.Folder, TagType.New);
|
||||
userIDs = tags.Select(tag => tag.Owner).Distinct();
|
||||
|
||||
|
||||
await foreach (var userID in userIDs)
|
||||
{
|
||||
await RemoveMarkAsNewAsync(fileEntry, userID);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public async Task<int> GetRootFoldersIdMarkedAsNewAsync<T>(T rootId)
|
||||
{
|
||||
@ -647,24 +645,24 @@ public class FileMarker
|
||||
var requestTag = await requestTags.FirstOrDefaultAsync(tag => tag.EntryId.Equals(rootId));
|
||||
var count = requestTag == null ? 0 : requestTag.Count;
|
||||
InsertToCahce(rootId, count);
|
||||
|
||||
|
||||
return count;
|
||||
}
|
||||
else if (fromCache > 0)
|
||||
{
|
||||
return fromCache;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
public IAsyncEnumerable<FileEntry> MarkedItemsAsync<T>(Folder<T> folder)
|
||||
{
|
||||
if (folder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(folder), FilesCommonResource.ErrorMassage_FolderNotFound);
|
||||
}
|
||||
|
||||
|
||||
return InternalMarkedItemsAsync(folder);
|
||||
}
|
||||
|
||||
@ -675,67 +673,67 @@ public class FileMarker
|
||||
throw new SecurityException(FilesCommonResource.ErrorMassage_SecurityException_ViewFolder);
|
||||
}
|
||||
|
||||
if (folder.RootFolderType == FolderType.TRASH && !Equals(folder.Id, await _globalFolder.GetFolderTrashAsync(_daoFactory)))
|
||||
{
|
||||
throw new SecurityException(FilesCommonResource.ErrorMassage_ViewTrashItem);
|
||||
}
|
||||
if (folder.RootFolderType == FolderType.TRASH && !Equals(folder.Id, await _globalFolder.GetFolderTrashAsync(_daoFactory)))
|
||||
{
|
||||
throw new SecurityException(FilesCommonResource.ErrorMassage_ViewTrashItem);
|
||||
}
|
||||
|
||||
var tagDao = _daoFactory.GetTagDao<T>();
|
||||
var providerFolderDao = _daoFactory.GetFolderDao<string>();
|
||||
var providerTagDao = _daoFactory.GetTagDao<string>();
|
||||
var tags = await (tagDao.GetNewTagsAsync(_authContext.CurrentAccount.ID, folder, true) ?? AsyncEnumerable.Empty<Tag>()).ToListAsync();
|
||||
|
||||
var tagDao = _daoFactory.GetTagDao<T>();
|
||||
var providerFolderDao = _daoFactory.GetFolderDao<string>();
|
||||
var providerTagDao = _daoFactory.GetTagDao<string>();
|
||||
var tags = await (tagDao.GetNewTagsAsync(_authContext.CurrentAccount.ID, folder, true) ?? AsyncEnumerable.Empty<Tag>()).ToListAsync();
|
||||
|
||||
if (!tags.Any())
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
|
||||
if (Equals(folder.Id, await _globalFolder.GetFolderMyAsync(this, _daoFactory)) ||
|
||||
Equals(folder.Id, await _globalFolder.GetFolderCommonAsync(this, _daoFactory)) ||
|
||||
Equals(folder.Id, await _globalFolder.GetFolderShareAsync(_daoFactory)) ||
|
||||
Equals(folder.Id, await _globalFolder.GetFolderVirtualRoomsAsync(_daoFactory)))
|
||||
{
|
||||
var folderTags = tags.Where(tag => tag.EntryType == FileEntryType.Folder && (tag.EntryId is string));
|
||||
|
||||
var providerFolderTags = new List<KeyValuePair<Tag, Folder<string>>>();
|
||||
|
||||
foreach (var tag in folderTags)
|
||||
{
|
||||
var pair = new KeyValuePair<Tag, Folder<string>>(tag, await providerFolderDao.GetFolderAsync(tag.EntryId.ToString()));
|
||||
if (pair.Value != null && pair.Value.ProviderEntry)
|
||||
{
|
||||
providerFolderTags.Add(pair);
|
||||
}
|
||||
}
|
||||
|
||||
providerFolderTags.Reverse();
|
||||
|
||||
foreach (var providerFolderTag in providerFolderTags)
|
||||
|
||||
var providerFolderTags = new List<KeyValuePair<Tag, Folder<string>>>();
|
||||
|
||||
foreach (var tag in folderTags)
|
||||
{
|
||||
tags.AddRange(await providerTagDao.GetNewTagsAsync(_authContext.CurrentAccount.ID, providerFolderTag.Value, true).ToListAsync());
|
||||
var pair = new KeyValuePair<Tag, Folder<string>>(tag, await providerFolderDao.GetFolderAsync(tag.EntryId.ToString()));
|
||||
if (pair.Value != null && pair.Value.ProviderEntry)
|
||||
{
|
||||
providerFolderTags.Add(pair);
|
||||
}
|
||||
}
|
||||
|
||||
providerFolderTags.Reverse();
|
||||
|
||||
foreach (var providerFolderTag in providerFolderTags)
|
||||
{
|
||||
tags.AddRange(await providerTagDao.GetNewTagsAsync(_authContext.CurrentAccount.ID, providerFolderTag.Value, true).ToListAsync());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
tags = tags
|
||||
.Where(r => !Equals(r.EntryId, folder.Id))
|
||||
.Distinct()
|
||||
.Distinct()
|
||||
.ToList();
|
||||
|
||||
//TODO: refactoring
|
||||
var entryTagsProvider = await GetEntryTagsAsync<string>(tags.Where(r => r.EntryId is string).ToAsyncEnumerable());
|
||||
var entryTagsInternal = await GetEntryTagsAsync<int>(tags.Where(r => r.EntryId is int).ToAsyncEnumerable());
|
||||
|
||||
var entryTagsInternal = await GetEntryTagsAsync<int>(tags.Where(r => r.EntryId is int).ToAsyncEnumerable());
|
||||
|
||||
foreach (var entryTag in entryTagsInternal)
|
||||
{
|
||||
var parentEntry = entryTagsInternal.Keys
|
||||
.FirstOrDefault(entryCountTag => Equals(entryCountTag.Id, entryTag.Key.ParentId));
|
||||
|
||||
|
||||
if (parentEntry != null)
|
||||
{
|
||||
entryTagsInternal[parentEntry].Count -= entryTag.Value.Count;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
foreach (var entryTag in entryTagsProvider)
|
||||
{
|
||||
if (int.TryParse(entryTag.Key.ParentId, out var fId))
|
||||
@ -746,20 +744,20 @@ public class FileMarker
|
||||
if (parentEntryInt != null)
|
||||
{
|
||||
entryTagsInternal[parentEntryInt].Count -= entryTag.Value.Count;
|
||||
}
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
var parentEntry = entryTagsProvider.Keys
|
||||
.FirstOrDefault(entryCountTag => Equals(entryCountTag.Id, entryTag.Key.ParentId));
|
||||
|
||||
|
||||
if (parentEntry != null)
|
||||
{
|
||||
entryTagsProvider[parentEntry].Count -= entryTag.Value.Count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
await foreach (var r in GetResultAsync(entryTagsInternal))
|
||||
{
|
||||
yield return r;
|
||||
@ -772,28 +770,28 @@ public class FileMarker
|
||||
|
||||
async IAsyncEnumerable<FileEntry> GetResultAsync<TEntry>(Dictionary<FileEntry<TEntry>, Tag> entryTags)
|
||||
{
|
||||
foreach (var entryTag in entryTags)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(entryTag.Key.Error))
|
||||
{
|
||||
await RemoveMarkAsNewAsync(entryTag.Key);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (entryTag.Value.Count > 0)
|
||||
foreach (var entryTag in entryTags)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(entryTag.Key.Error))
|
||||
{
|
||||
yield return entryTag.Key;
|
||||
}
|
||||
}
|
||||
}
|
||||
await RemoveMarkAsNewAsync(entryTag.Key);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (entryTag.Value.Count > 0)
|
||||
{
|
||||
yield return entryTag.Key;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private async Task<Dictionary<FileEntry<T>, Tag>> GetEntryTagsAsync<T>(IAsyncEnumerable<Tag> tags)
|
||||
{
|
||||
var fileDao = _daoFactory.GetFileDao<T>();
|
||||
var folderDao = _daoFactory.GetFolderDao<T>();
|
||||
var entryTags = new Dictionary<FileEntry<T>, Tag>();
|
||||
|
||||
|
||||
await foreach (var tag in tags)
|
||||
{
|
||||
var entry = tag.EntryType == FileEntryType.File
|
||||
@ -817,7 +815,7 @@ public class FileMarker
|
||||
var tagDao = _daoFactory.GetTagDao<T>();
|
||||
var folderDao = _daoFactory.GetFolderDao<T>();
|
||||
var totalTags = await tagDao.GetNewTagsAsync(_authContext.CurrentAccount.ID, parent, false).ToListAsync();
|
||||
|
||||
|
||||
if (totalTags.Count <= 0)
|
||||
{
|
||||
return;
|
||||
@ -977,13 +975,13 @@ public class FileMarker
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void InsertToCahce(object folderId, int count)
|
||||
{
|
||||
var key = string.Format(CacheKeyFormat, _authContext.CurrentAccount.ID, folderId);
|
||||
_cache.Insert(key, count.ToString(), TimeSpan.FromMinutes(10));
|
||||
}
|
||||
|
||||
|
||||
private int GetCountFromCahce(object folderId)
|
||||
{
|
||||
var key = string.Format(CacheKeyFormat, _authContext.CurrentAccount.ID, folderId);
|
||||
@ -991,12 +989,12 @@ public class FileMarker
|
||||
|
||||
return count == null ? -1 : int.Parse(count);
|
||||
}
|
||||
|
||||
|
||||
private void RemoveFromCahce(object folderId)
|
||||
{
|
||||
RemoveFromCahce(folderId, _authContext.CurrentAccount.ID);
|
||||
}
|
||||
|
||||
|
||||
private void RemoveFromCahce(object folderId, Guid userId)
|
||||
{
|
||||
var key = string.Format(CacheKeyFormat, userId, folderId);
|
||||
@ -1018,7 +1016,7 @@ public class FileMarker
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Transient]
|
||||
public class AsyncTaskData<T> : DistributedTask
|
||||
{
|
||||
@ -1027,13 +1025,13 @@ public class AsyncTaskData<T> : DistributedTask
|
||||
TenantID = tenantManager.GetCurrentTenant().Id;
|
||||
CurrentAccountId = authContext.CurrentAccount.ID;
|
||||
}
|
||||
|
||||
|
||||
public int TenantID { get; private set; }
|
||||
public FileEntry<T> FileEntry { get; set; }
|
||||
public List<Guid> UserIDs { get; set; }
|
||||
public Guid CurrentAccountId { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public static class FileMarkerExtention
|
||||
{
|
||||
public static void Register(DIHelper services)
|
||||
@ -1043,4 +1041,4 @@ public static class FileMarkerExtention
|
||||
|
||||
services.TryAdd<AsyncTaskData<string>>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user