🗑️ Clean up the cloud file table unused fields
This commit is contained in:
@@ -42,9 +42,11 @@ public class UsageService(AppDatabase db)
|
|||||||
PoolName = p.Name,
|
PoolName = p.Name,
|
||||||
UsageBytes = fileQuery
|
UsageBytes = fileQuery
|
||||||
.Where(f => f.PoolId == p.Id)
|
.Where(f => f.PoolId == p.Id)
|
||||||
|
.Include(f => f.Object)
|
||||||
.Sum(f => f.Size),
|
.Sum(f => f.Size),
|
||||||
Cost = fileQuery
|
Cost = fileQuery
|
||||||
.Where(f => f.PoolId == p.Id)
|
.Where(f => f.PoolId == p.Id)
|
||||||
|
.Include(f => f.Object)
|
||||||
.Sum(f => f.Size) / 1024.0 / 1024.0 *
|
.Sum(f => f.Size) / 1024.0 / 1024.0 *
|
||||||
(p.BillingConfig.CostMultiplier ?? 1.0),
|
(p.BillingConfig.CostMultiplier ?? 1.0),
|
||||||
FileCount = fileQuery
|
FileCount = fileQuery
|
||||||
@@ -80,6 +82,7 @@ public class UsageService(AppDatabase db)
|
|||||||
.AsQueryable();
|
.AsQueryable();
|
||||||
|
|
||||||
var usageBytes = await fileQuery
|
var usageBytes = await fileQuery
|
||||||
|
.Include(f => f.Object)
|
||||||
.SumAsync(f => f.Size);
|
.SumAsync(f => f.Size);
|
||||||
|
|
||||||
var fileCount = await fileQuery
|
var fileCount = await fileQuery
|
||||||
@@ -106,6 +109,7 @@ public class UsageService(AppDatabase db)
|
|||||||
.Where(f => f.PoolId.HasValue)
|
.Where(f => f.PoolId.HasValue)
|
||||||
.Where(f => !f.IsMarkedRecycle)
|
.Where(f => !f.IsMarkedRecycle)
|
||||||
.Include(f => f.Pool)
|
.Include(f => f.Pool)
|
||||||
|
.Include(f => f.Object)
|
||||||
.Where(f => !f.ExpiredAt.HasValue || f.ExpiredAt > now)
|
.Where(f => !f.ExpiredAt.HasValue || f.ExpiredAt > now)
|
||||||
.Select(f => new
|
.Select(f => new
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -216,6 +216,7 @@ public class FileIndexController(
|
|||||||
&& f.IsMarkedRecycle == recycled
|
&& f.IsMarkedRecycle == recycled
|
||||||
&& !db.FileIndexes.Any(fi => fi.FileId == f.Id && fi.AccountId == accountId)
|
&& !db.FileIndexes.Any(fi => fi.FileId == f.Id && fi.AccountId == accountId)
|
||||||
)
|
)
|
||||||
|
.Include(f => f.Object)
|
||||||
.AsQueryable();
|
.AsQueryable();
|
||||||
|
|
||||||
// Apply sorting
|
// Apply sorting
|
||||||
|
|||||||
@@ -167,6 +167,7 @@ public class FileIndexService(AppDatabase db)
|
|||||||
return await db.FileIndexes
|
return await db.FileIndexes
|
||||||
.Where(fi => fi.AccountId == accountId)
|
.Where(fi => fi.AccountId == accountId)
|
||||||
.Include(fi => fi.File)
|
.Include(fi => fi.File)
|
||||||
|
.ThenInclude(f => f.Object)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -314,9 +314,12 @@ public class BroadcastEventHandler(
|
|||||||
await scopedDb.Files.Where(f => f.Id == fileId).ExecuteUpdateAsync(setter => setter
|
await scopedDb.Files.Where(f => f.Id == fileId).ExecuteUpdateAsync(setter => setter
|
||||||
.SetProperty(f => f.UploadedAt, now)
|
.SetProperty(f => f.UploadedAt, now)
|
||||||
.SetProperty(f => f.PoolId, destPool)
|
.SetProperty(f => f.PoolId, destPool)
|
||||||
.SetProperty(f => f.MimeType, newMimeType)
|
);
|
||||||
.SetProperty(f => f.HasCompression, hasCompression)
|
|
||||||
.SetProperty(f => f.HasThumbnail, hasThumbnail)
|
await scopedDb.FileObjects.Where(fo => fo.Id == fileId).ExecuteUpdateAsync(setter => setter
|
||||||
|
.SetProperty(fo => fo.MimeType, newMimeType)
|
||||||
|
.SetProperty(fo => fo.HasCompression, hasCompression)
|
||||||
|
.SetProperty(fo => fo.HasThumbnail, hasThumbnail)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Only delete temp file after successful upload and db update
|
// Only delete temp file after successful upload and db update
|
||||||
|
|||||||
@@ -303,6 +303,7 @@ public class FileController(
|
|||||||
.Where(e => e.IsMarkedRecycle == recycled)
|
.Where(e => e.IsMarkedRecycle == recycled)
|
||||||
.Where(e => e.AccountId == accountId)
|
.Where(e => e.AccountId == accountId)
|
||||||
.Include(e => e.Pool)
|
.Include(e => e.Pool)
|
||||||
|
.Include(e => e.Object)
|
||||||
.AsQueryable();
|
.AsQueryable();
|
||||||
|
|
||||||
if (pool.HasValue) filesQuery = filesQuery.Where(e => e.PoolId == pool);
|
if (pool.HasValue) filesQuery = filesQuery.Where(e => e.PoolId == pool);
|
||||||
|
|||||||
@@ -64,7 +64,10 @@ public class FileUploadController(
|
|||||||
var accountId = Guid.Parse(currentUser.Id);
|
var accountId = Guid.Parse(currentUser.Id);
|
||||||
|
|
||||||
// Check if a file with the same hash already exists
|
// Check if a file with the same hash already exists
|
||||||
var existingFile = await db.Files.FirstOrDefaultAsync(f => f.Hash == request.Hash);
|
var existingFile = await db.Files
|
||||||
|
.Include(f => f.Object)
|
||||||
|
.Where(f => f.Object != null && f.Object.Hash == request.Hash)
|
||||||
|
.FirstOrDefaultAsync();
|
||||||
if (existingFile != null)
|
if (existingFile != null)
|
||||||
{
|
{
|
||||||
// Create the file index if a path is provided, even for existing files
|
// Create the file index if a path is provided, even for existing files
|
||||||
|
|||||||
@@ -20,14 +20,14 @@ public class SnCloudFile : ModelBase, ICloudFile, IIdentifiedResource
|
|||||||
|
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
[Column(TypeName = "jsonb")]
|
[Column(TypeName = "jsonb")]
|
||||||
public Dictionary<string, object?> FileMeta => Object!.Meta ?? [];
|
public Dictionary<string, object?> FileMeta => Object?.Meta ?? [];
|
||||||
[NotMapped] [MaxLength(256)] public string? MimeType => Object!.MimeType;
|
[NotMapped] [MaxLength(256)] public string? MimeType => Object?.MimeType;
|
||||||
[NotMapped] [MaxLength(256)] public string? Hash => Object!.Hash;
|
[NotMapped] [MaxLength(256)] public string? Hash => Object?.Hash;
|
||||||
public Instant? ExpiredAt { get; set; }
|
public Instant? ExpiredAt { get; set; }
|
||||||
[NotMapped] public long Size => Object!.Size;
|
[NotMapped] public long Size => Object?.Size ?? 0;
|
||||||
public Instant? UploadedAt { get; set; }
|
public Instant? UploadedAt { get; set; }
|
||||||
[NotMapped] public bool HasCompression => Object!.HasCompression;
|
[NotMapped] public bool HasCompression => Object?.HasCompression ?? false;
|
||||||
[NotMapped] public bool HasThumbnail => Object!.HasThumbnail;
|
[NotMapped] public bool HasThumbnail => Object?.HasThumbnail ?? false;
|
||||||
|
|
||||||
[MaxLength(32)] public string? ObjectId { get; set; }
|
[MaxLength(32)] public string? ObjectId { get; set; }
|
||||||
public SnFileObject? Object { get; set; }
|
public SnFileObject? Object { get; set; }
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace DysonNetwork.Shared.Models;
|
namespace DysonNetwork.Shared.Models;
|
||||||
|
|
||||||
@@ -33,7 +34,7 @@ public class SnFileReplica : ModelBase
|
|||||||
public Guid Id { get; set; }
|
public Guid Id { get; set; }
|
||||||
|
|
||||||
[MaxLength(32)] public string ObjectId { get; set; }
|
[MaxLength(32)] public string ObjectId { get; set; }
|
||||||
public SnFileObject Object { get; set; } = null!;
|
[JsonIgnore] public SnFileObject Object { get; set; } = null!;
|
||||||
|
|
||||||
public Guid? PoolId { get; set; }
|
public Guid? PoolId { get; set; }
|
||||||
public FilePool? Pool { get; set; } = null!;
|
public FilePool? Pool { get; set; } = null!;
|
||||||
|
|||||||
@@ -145,6 +145,7 @@
|
|||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003APutObjectArgs_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003F6efe388c7585d5dd5587416a55298550b030c2a107edf45f988791297c3ffa_003FPutObjectArgs_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003APutObjectArgs_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003F6efe388c7585d5dd5587416a55298550b030c2a107edf45f988791297c3ffa_003FPutObjectArgs_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AQueryable_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F42d8f09d6a294d00a6f49efc989927492fe00_003F4e_003F26d1ee34_003FQueryable_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AQueryable_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F42d8f09d6a294d00a6f49efc989927492fe00_003F4e_003F26d1ee34_003FQueryable_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AQueryable_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fcbafb95b4df34952928f87356db00c8f2fe00_003F9b_003F8ba036bb_003FQueryable_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AQueryable_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fcbafb95b4df34952928f87356db00c8f2fe00_003F9b_003F8ba036bb_003FQueryable_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AQueryCompilationContext_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fbb7b06734dde412ab7a17876ecec5dc22b0e20_003F5c_003Fa9a8ee00_003FQueryCompilationContext_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ARazorPage_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F81d2924a2bbd4b0c864a1d23cbf5f0893d200_003F5f_003Fc110be1c_003FRazorPage_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ARazorPage_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F81d2924a2bbd4b0c864a1d23cbf5f0893d200_003F5f_003Fc110be1c_003FRazorPage_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ARepeatedField_00601_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F331aca3f6f414013b09964063341351379060_003Fc1_003F67c16263_003FRepeatedField_00601_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ARepeatedField_00601_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F331aca3f6f414013b09964063341351379060_003Fc1_003F67c16263_003FRepeatedField_00601_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ARequestTimeoutPolicy_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fb162d8ea71a447288973b864f5e7dea24ec00_003F46_003Ff75653ca_003FRequestTimeoutPolicy_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ARequestTimeoutPolicy_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fb162d8ea71a447288973b864f5e7dea24ec00_003F46_003Ff75653ca_003FRequestTimeoutPolicy_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
|
|||||||
Reference in New Issue
Block a user