Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/deletion by marking as removed #300

Open
wants to merge 34 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
04293d1
ASC.Files: EF: added removed property to DbFile, DbFolder
andreysavihin Mar 29, 2024
fb2609a
ASC.Files: Dao: added MarkAsRemoved methods to FileDao, FolderDao
andreysavihin Mar 29, 2024
9e8818e
ASC.Files: FileOperations: ability to create hidden operations
andreysavihin Mar 29, 2024
ce43844
ASC.Files: Dao: methods for retrieving files and folders taking into …
andreysavihin Mar 29, 2024
e66e96e
ASC.Files: FileOperations: optimization of working with headers
andreysavihin Mar 29, 2024
527e32c
ASC.Files: FileDeleteOperation: The trash bin emptying method is divi…
andreysavihin Mar 29, 2024
e08f99d
ASC.Files: FileDeleteOperation: MarkAsRemoved refactoring
andreysavihin Apr 1, 2024
bb223b8
ASC.Files: Dao: added CanMarkAsRemoved methods to FileDao, FolderDao
andreysavihin Apr 1, 2024
713bfb0
ASC.Files: FileDeleteOperation: applying method MarkAsRemoved if dao …
andreysavihin Apr 1, 2024
2ee7a8f
ASC.Files: FileDeleteOperation: passing headers to hidden operation
andreysavihin Apr 1, 2024
b45070a
ASC.Files: FolderDao: receiving rooms without marked as removed
andreysavihin Apr 1, 2024
3ddf6dc
ASC.Files: FileDeleteOperation: calling the rights check method befor…
andreysavihin Apr 1, 2024
55a1461
ASC.Files:
andreysavihin Apr 3, 2024
bb3e9a4
ASC.Files: FileOperation: HiddenOperation property Moved to FileDelet…
andreysavihin Apr 3, 2024
348f9c5
ASC.Files: Dao: methods for retrieving files and folders taking into …
andreysavihin Apr 4, 2024
039b9c5
ASC.Files: FileDeleteOperation: calling the ProgressStep method when …
andreysavihin Apr 4, 2024
a0993ad
Merge remote-tracking branch 'remotes/origin/develop' into feature/de…
andreysavihin Apr 4, 2024
fe4b835
Migrations: added removed column to files_file, files_folder
andreysavihin Apr 4, 2024
7ff244c
Merge remote-tracking branch 'remotes/origin/develop' into feature/de…
andreysavihin Apr 15, 2024
a555ba6
ASC.Files: Dao: removed unnecessary MarkAsRemoved methods from FileDa…
andreysavihin Apr 19, 2024
e9d7525
ASC.Files: EmptyTrashIntegrationEventHandler removed, MarkAsRemoved m…
andreysavihin Apr 22, 2024
7159cec
ASC.Files: added CleanupMarkedEntriesService
andreysavihin Apr 23, 2024
b32205f
ASC.Files: renaming in CleanupMarkedEntriesService
andreysavihin Apr 24, 2024
8732668
ASC.Files: fix CleanupMarkedEntriesService
andreysavihin Apr 24, 2024
3e0e6f9
Merge remote-tracking branch 'remotes/origin/develop' into feature/de…
andreysavihin Apr 25, 2024
69e696a
ASC.Files: RemovalMarker has been moved from FileOperationsManager
andreysavihin Apr 25, 2024
72e3a71
ASC.Files: Dao: removed unnecessary CanMarkAsRemoved methods from Fil…
andreysavihin Apr 25, 2024
9c2e808
Merge remote-tracking branch 'remotes/origin/develop' into feature/de…
andreysavihin Apr 26, 2024
f488ca0
Merge remote-tracking branch 'remotes/origin/develop' into feature/de…
andreysavihin May 16, 2024
d93ec83
ASC.Files: FileDeleteOperation: unused code removed
andreysavihin May 16, 2024
a29e4ff
ASC.Files: FileDeleteOperation: revert ProtoMembers order
andreysavihin May 17, 2024
4150851
ASC.Files: FileDeleteOperation: ability to transfer empty data
andreysavihin May 17, 2024
1d6e759
ASC.Files: FileDao: one wait for multiple tasks
andreysavihin May 20, 2024
332e960
Merge remote-tracking branch 'remotes/origin/develop' into feature/de…
andreysavihin Jun 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions common/ASC.Common/Threading/DistributedTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -110,4 +110,9 @@ public override int GetHashCode()
{
return Id.GetHashCode();
}

public bool HasProperty(string propName)
{
return _props.ContainsKey(propName);
}
}

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using Microsoft.EntityFrameworkCore.Migrations;

#nullable disable

namespace ASC.Migrations.MySql.SaaS.Migrations
{
/// <inheritdoc />
public partial class MigrationContext_Upgrade20 : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<bool>(
name: "removed",
table: "files_folder",
type: "tinyint(1)",
nullable: false,
defaultValueSql: "'0'");

migrationBuilder.AddColumn<bool>(
name: "removed",
table: "files_file",
type: "tinyint(1)",
nullable: false,
defaultValueSql: "'0'");
}

/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "removed",
table: "files_folder");

migrationBuilder.DropColumn(
name: "removed",
table: "files_file");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5853,6 +5853,12 @@ protected override void BuildModel(ModelBuilder modelBuilder)
.HasColumnName("folder_id")
.HasDefaultValueSql("'0'");

b.Property<bool>("Removed")
.ValueGeneratedOnAdd()
.HasColumnType("tinyint(1)")
.HasColumnName("removed")
.HasDefaultValueSql("'0'");

b.Property<int>("ThumbnailStatus")
.ValueGeneratedOnAdd()
.HasColumnType("int")
Expand Down Expand Up @@ -6413,6 +6419,12 @@ protected override void BuildModel(ModelBuilder modelBuilder)
.HasColumnName("parent_id")
.HasDefaultValueSql("'0'");

b.Property<bool>("Removed")
.ValueGeneratedOnAdd()
.HasColumnType("tinyint(1)")
.HasColumnName("removed")
.HasDefaultValueSql("'0'");

b.Property<int>("TenantId")
.HasColumnType("int")
.HasColumnName("tenant_id");
Expand Down
8 changes: 6 additions & 2 deletions products/ASC.Files/Core/Core/Dao/Interfaces/IFileDao.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@ public interface IFileDao<T>
/// Receive file
/// </summary>
/// <param name="fileId">file id</param>
/// <param name="includeRemoved"></param>
/// <returns></returns>
Task<File<T>> GetFileAsync(T fileId);
Task<File<T>> GetFileAsync(T fileId, bool includeRemoved = false);

/// <summary>
/// Receive file
Expand Down Expand Up @@ -96,8 +97,9 @@ IAsyncEnumerable<File<T>> GetFilesFilteredAsync(IEnumerable<T> fileIds, FilterTy
///
/// </summary>
/// <param name="parentId"></param>
/// <param name="includeRemoved"></param>
/// <returns></returns>
IAsyncEnumerable<T> GetFilesAsync(T parentId);
IAsyncEnumerable<T> GetFilesAsync(T parentId, bool includeRemoved = false);

/// <summary>
/// Get files in folder
Expand Down Expand Up @@ -358,5 +360,7 @@ IAsyncEnumerable<File<T>> GetFilesByTagAsync(Guid? tagOwner, TagType tagType, Fi
Task<int> GetFilesByTagCountAsync(Guid? tagOwner, TagType tagType, FilterType filterType, bool subjectGroup, Guid subjectId,
string searchText, string[] extension, bool searchInContent, bool excludeSubject);

Task MarkFilesAsRemovedAsync(IEnumerable<T> fileIds);

#endregion
}
10 changes: 7 additions & 3 deletions products/ASC.Files/Core/Core/Dao/Interfaces/IFolderDao.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@ public interface IFolderDao<T>
/// Get folder by id.
/// </summary>
/// <param name="folderId">folder id</param>
/// <param name="includeRemoved"></param>
/// <returns>folder</returns>
Task<Folder<T>> GetFolderAsync(T folderId);
Task<Folder<T>> GetFolderAsync(T folderId, bool includeRemoved = false);

/// <summary>
/// Returns the folder with the given name and id of the root
Expand Down Expand Up @@ -72,7 +73,8 @@ IAsyncEnumerable<Folder<T>> GetProviderBasedRoomsAsync(SearchArea searchArea, IE
/// Get a list of folders in current folder.
/// </summary>
/// <param name="parentId"></param>
IAsyncEnumerable<Folder<T>> GetFoldersAsync(T parentId);
/// <param name="includeRemoved"></param>
IAsyncEnumerable<Folder<T>> GetFoldersAsync(T parentId, bool includeRemoved = false);

/// <summary>
/// Get a list of folders in current folder.
Expand Down Expand Up @@ -412,6 +414,8 @@ Task<int> GetFoldersCountAsync(T parentId, FilterType filterType, bool subjectGr
Task SetCustomOrder(T folderId, T parentFolderId, int order);

Task InitCustomOrder(IEnumerable<T> folderIds, T parentFolderId);


Task MarkFoldersAsRemovedAsync(IEnumerable<T> folderIds);

#endregion
}
39 changes: 29 additions & 10 deletions products/ASC.Files/Core/Core/Dao/TeamlabDao/FileDao.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,13 @@ public Task InvalidateCacheAsync(int fileId)
return Task.CompletedTask;
}

public async Task<File<int>> GetFileAsync(int fileId)
public async Task<File<int>> GetFileAsync(int fileId, bool includeRemoved = false)
{
var tenantId = await _tenantManager.GetCurrentTenantIdAsync();

await using var filesDbContext = await _dbContextFactory.CreateDbContextAsync();

var dbFile = await filesDbContext.DbFileQueryAsync(tenantId, fileId);
var dbFile = await filesDbContext.DbFileQueryAsync(tenantId, fileId, includeRemoved);

return mapper.Map<DbFileQuery, File<int>>(dbFile);
}
Expand Down Expand Up @@ -250,13 +250,13 @@ public async IAsyncEnumerable<File<int>> GetFilesFilteredAsync(IEnumerable<int>
}
}

public async IAsyncEnumerable<int> GetFilesAsync(int parentId)
public async IAsyncEnumerable<int> GetFilesAsync(int parentId, bool includeRemoved = false)
{
var tenantId = await _tenantManager.GetCurrentTenantIdAsync();

await using var filesDbContext = await _dbContextFactory.CreateDbContextAsync();

await foreach (var e in filesDbContext.FileIdsAsync(tenantId, parentId))
await foreach (var e in filesDbContext.FileIdsAsync(tenantId, parentId, includeRemoved))
{
yield return e;
}
Expand All @@ -274,7 +274,7 @@ public async IAsyncEnumerable<File<int>> GetFilesAsync(int parentId, OrderBy ord

var q = await GetFilesQueryWithFilters(parentId, orderBy, filterType, subjectGroup, subjectID, searchText, searchInContent, withSubfolders, excludeSubject, roomId, extension, filesDbContext);

q = q.Skip(offset);
q = q.Where(r => !r.Removed).Skip(offset);

if (count > 0)
{
Expand Down Expand Up @@ -650,8 +650,11 @@ public async Task<int> GetFilesCountAsync(int parentId, FilterType filterType, b

var filesDbContext = await _dbContextFactory.CreateDbContextAsync();

return await (await GetFilesQueryWithFilters(parentId, null, filterType, subjectGroup, subjectId, searchText, searchInContent, withSubfolders, excludeSubject, roomId, extension, filesDbContext))
.CountAsync();
var q = await GetFilesQueryWithFilters(parentId, null, filterType, subjectGroup, subjectId, searchText, searchInContent, withSubfolders, excludeSubject, roomId, extension, filesDbContext);

q = q.Where(r => !r.Removed);

return await q.CountAsync();
}

public async Task<File<int>> ReplaceFileVersionAsync(File<int> file, Stream fileStream)
Expand Down Expand Up @@ -989,9 +992,16 @@ await q.ExecuteUpdateAsync(f => f

var tagDao = daoFactory.GetTagDao<int>();
var oldFolder = await folderDao.GetFolderAsync(oldParentId.Value);
var (toFolderRoomId, _) = await folderDao.GetParentRoomInfoFromFileEntryAsync(toFolder);
var (roomId, _) = await folderDao.GetParentRoomInfoFromFileEntryAsync(oldFolder);
var archiveId = await folderDao.GetFolderIDArchive(false);

var toFolderRoomIdTask = folderDao.GetParentRoomInfoFromFileEntryAsync(toFolder);
var roomIdTask = folderDao.GetParentRoomInfoFromFileEntryAsync(oldFolder);
var archiveIdTask = folderDao.GetFolderIDArchive(false);

await Task.WhenAll(toFolderRoomIdTask, roomIdTask, archiveIdTask);

var (toFolderRoomId, _) = await toFolderRoomIdTask;
var (roomId, _) = await roomIdTask;
var archiveId = await archiveIdTask;

if (toFolderId == trashId && oldParentId.HasValue)
{
Expand Down Expand Up @@ -1788,6 +1798,15 @@ private async Task DeleteCustomOrder(FilesDbContext filesDbContext, int fileId)
await DeleteCustomOrder(filesDbContext, fileId, FileEntryType.File);
}

public async Task MarkFilesAsRemovedAsync(IEnumerable<int> fileIds)
{
var tenantId = await _tenantManager.GetCurrentTenantIdAsync();

await using var filesDbContext = await _dbContextFactory.CreateDbContextAsync();

await filesDbContext.MarkFilesAsRemovedAsync(tenantId, fileIds, DateTime.UtcNow, _authContext.CurrentAccount.ID);
}

#endregion

private Func<Selector<DbFile>, Selector<DbFile>> GetFuncForSearch(int? parentId, OrderBy orderBy, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText,
Expand Down
36 changes: 29 additions & 7 deletions products/ASC.Files/Core/Core/Dao/TeamlabDao/FolderDao.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,13 @@ internal class FolderDao(
private const string VirtualRooms = "virtualrooms";
private const string Archive = "archive";

public async Task<Folder<int>> GetFolderAsync(int folderId)
public async Task<Folder<int>> GetFolderAsync(int folderId, bool includeRemoved = false)
{
var tenantId = await _tenantManager.GetCurrentTenantIdAsync();

await using var filesDbContext = await _dbContextFactory.CreateDbContextAsync();

var dbFolder = await filesDbContext.DbFolderQueryWithSharedAsync(tenantId, folderId);
var dbFolder = await filesDbContext.DbFolderQueryWithSharedAsync(tenantId, folderId, includeRemoved);

return mapper.Map<DbFolderQuery, Folder<int>>(dbFolder);
}
Expand Down Expand Up @@ -132,9 +132,9 @@ public async IAsyncEnumerable<Folder<int>> GetFoldersAsync(int parentId, FolderT
}

}
public IAsyncEnumerable<Folder<int>> GetFoldersAsync(int parentId)
public IAsyncEnumerable<Folder<int>> GetFoldersAsync(int parentId, bool includeRemoved = false)
{
return GetFoldersAsync(parentId, default, FilterType.None, false, default, string.Empty);
return GetFoldersAsync(parentId, default, FilterType.None, false, default, string.Empty, includeRemoved: includeRemoved);
}

public async IAsyncEnumerable<Folder<int>> GetRoomsAsync(
Expand All @@ -161,7 +161,7 @@ public async IAsyncEnumerable<Folder<int>> GetRoomsAsync(
var searchByTypes = filterType != FilterType.None && filterType != FilterType.FoldersOnly;

await using var filesDbContext = await _dbContextFactory.CreateDbContextAsync();
var q = await GetFolderQuery(filesDbContext, r => parentsIds.Contains(r.ParentId));
var q = await GetFolderQuery(filesDbContext, r => parentsIds.Contains(r.ParentId) && !r.Removed);

q = !withSubfolders ? BuildRoomsQuery(filesDbContext, q, filter, tags, subjectId, searchByTags, withoutTags, searchByTypes, false, excludeSubject, subjectFilter, subjectEntriesIds, quotaFilter)
: await BuildRoomsWithSubfoldersQuery(filesDbContext, parentsIds, filter, tags, searchByTags, searchByTypes, withoutTags, excludeSubject, subjectId, subjectFilter, subjectEntriesIds);
Expand Down Expand Up @@ -233,16 +233,24 @@ public async Task<int> GetFoldersCountAsync(int parentId, FilterType filterType,

if (filterType == FilterType.None && subjectId == default && string.IsNullOrEmpty(searchText) && !withSubfolders && !excludeSubject && roomId == default)
{
return await filesDbContext.Tree.CountAsync(r => r.ParentId == parentId && r.Level == 1);
return await filesDbContext.CountChildFoldersAsync(parentId);
}

var q = await GetFoldersQueryWithFilters(parentId, null, subjectGroup, subjectId, searchText, withSubfolders, excludeSubject, roomId, filesDbContext);

q = q.Where(r => !r.Removed);

return await q.CountAsync();
}

public async IAsyncEnumerable<Folder<int>> GetFoldersAsync(int parentId, OrderBy orderBy, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool withSubfolders = false,
public IAsyncEnumerable<Folder<int>> GetFoldersAsync(int parentId, OrderBy orderBy, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool withSubfolders = false,
bool excludeSubject = false, int offset = 0, int count = -1, int roomId = default, bool containingMyFiles = false)
{
return GetFoldersAsync(parentId, orderBy, filterType, subjectGroup, subjectID, searchText, withSubfolders, excludeSubject, offset, count, roomId, containingMyFiles, false);
}

private async IAsyncEnumerable<Folder<int>> GetFoldersAsync(int parentId, OrderBy orderBy, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool withSubfolders = false,
bool excludeSubject = false, int offset = 0, int count = -1, int roomId = default, bool containingMyFiles = false, bool includeRemoved = false)
{
if (CheckInvalidFilter(filterType) || count == 0)
{
Expand All @@ -260,6 +268,11 @@ public async IAsyncEnumerable<Folder<int>> GetFoldersAsync(int parentId, OrderBy
.Select(r => r.folder);
}

if (!includeRemoved)
{
q = q.Where(r => !r.Removed);
}

q = q.Skip(offset);

if (count > 0)
Expand Down Expand Up @@ -1359,6 +1372,15 @@ public async IAsyncEnumerable<OriginData> GetOriginsDataAsync(IEnumerable<int> e
}
}

public async Task MarkFoldersAsRemovedAsync(IEnumerable<int> folderIds)
{
var tenantId = await _tenantManager.GetCurrentTenantIdAsync();

await using var filesDbContext = await _dbContextFactory.CreateDbContextAsync();

await filesDbContext.MarkFoldersAsRemovedAsync(tenantId, folderIds, DateTime.UtcNow, _authContext.CurrentAccount.ID);
}

#endregion

private async Task<IQueryable<DbFolder>> GetFolderQuery(FilesDbContext filesDbContext, Expression<Func<DbFolder, bool>> where = null)
Expand Down
8 changes: 8 additions & 0 deletions products/ASC.Files/Core/Core/EF/DbFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ public class DbFile : BaseEntity, IDbFile, IDbSearch, ISearchItemDocument
public bool Encrypted { get; set; }
public ForcesaveType Forcesave { get; set; }
public Thumbnail ThumbnailStatus { get; set; }
public bool Removed { get; set; }

public DbTenant Tenant { get; set; }

Expand Down Expand Up @@ -223,6 +224,11 @@ public static void MySqlAddDbFiles(this ModelBuilder modelBuilder)
entity.Property(e => e.VersionGroup)
.HasColumnName("version_group")
.HasDefaultValueSql("'1'");

entity.Property(e => e.Removed)
.HasColumnType("tinyint(1)")
.HasColumnName("removed")
.HasDefaultValueSql("'0'");
});

}
Expand Down Expand Up @@ -317,6 +323,8 @@ public static void PgSqlAddDbFiles(this ModelBuilder modelBuilder)
entity.Property(e => e.VersionGroup)
.HasColumnName("version_group")
.HasDefaultValueSql("1");

entity.Property(e => e.Removed).HasColumnName("removed");
});

}
Expand Down
10 changes: 9 additions & 1 deletion products/ASC.Files/Core/Core/EF/DbFolder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ public class DbFolder : IDbFile, IDbSearch, ISearchItem
public int FoldersCount { get; set; }
public int FilesCount { get; set; }
public long Counter { get; set; }

public bool Removed { get; set; }

[Ignore]
public DbRoomSettings Settings { get; set; }

Expand Down Expand Up @@ -146,6 +147,11 @@ public static void MySqlAddDbFolder(this ModelBuilder modelBuilder)
entity.Property(e => e.Counter)
.HasColumnName("counter")
.HasDefaultValueSql("'0'");

entity.Property(e => e.Removed)
.HasColumnType("tinyint(1)")
.HasColumnName("removed")
.HasDefaultValueSql("'0'");
});
}
public static void PgSqlAddDbFolder(this ModelBuilder modelBuilder)
Expand Down Expand Up @@ -202,6 +208,8 @@ public static void PgSqlAddDbFolder(this ModelBuilder modelBuilder)
entity.Property(e => e.Counter)
.HasColumnName("counter")
.HasDefaultValueSql("'0'");

entity.Property(e => e.Removed).HasColumnName("removed");
});
}
}
Loading