void.cat/VoidCat/Services/Files/PostgresFileMetadataStore.cs

135 lines
4.0 KiB
C#
Raw Normal View History

using Microsoft.EntityFrameworkCore;
2022-06-06 21:51:25 +00:00
using VoidCat.Model;
using VoidCat.Services.Abstractions;
namespace VoidCat.Services.Files;
2022-06-08 16:17:53 +00:00
/// <inheritdoc />
public class PostgresFileMetadataStore : IFileMetadataStore
2022-06-06 21:51:25 +00:00
{
private readonly VoidContext _db;
private readonly IServiceScopeFactory _scopeFactory;
2022-06-06 21:51:25 +00:00
public PostgresFileMetadataStore(VoidContext db, IServiceScopeFactory scopeFactory)
2022-06-06 21:51:25 +00:00
{
_db = db;
_scopeFactory = scopeFactory;
2022-06-06 21:51:25 +00:00
}
public string? Key => "postgres";
2022-06-06 21:51:25 +00:00
2022-06-08 16:17:53 +00:00
/// <inheritdoc />
public async ValueTask<Database.File?> Get(Guid id)
2022-06-08 16:17:53 +00:00
{
return await _db.Files
.AsNoTracking()
.Include(a => a.Paywall)
.SingleOrDefaultAsync(a => a.Id == id);
2022-06-08 16:17:53 +00:00
}
public async ValueTask Add(Database.File f)
2022-06-06 21:51:25 +00:00
{
_db.Files.Add(f);
await _db.SaveChangesAsync();
2022-06-06 21:51:25 +00:00
}
2022-06-08 16:17:53 +00:00
/// <inheritdoc />
2022-06-06 21:51:25 +00:00
public async ValueTask Delete(Guid id)
{
await _db.Files
.Where(a => a.Id == id)
.ExecuteDeleteAsync();
2022-06-06 21:51:25 +00:00
}
2022-06-08 16:17:53 +00:00
/// <inheritdoc />
public async ValueTask<IReadOnlyList<Database.File>> Get(Guid[] ids)
2022-06-06 21:51:25 +00:00
{
return await _db.Files
.Include(a => a.Paywall)
.Where(a => ids.Contains(a.Id))
.ToArrayAsync();
2022-06-06 21:51:25 +00:00
}
2022-06-08 16:17:53 +00:00
/// <inheritdoc />
public async ValueTask Update(Guid id, Database.File obj)
2022-06-06 21:51:25 +00:00
{
var existing = await _db.Files.FindAsync(id);
if (existing == default)
{
return;
}
2022-06-06 21:51:25 +00:00
existing.Patch(obj);
await _db.SaveChangesAsync();
2022-06-06 21:51:25 +00:00
}
2022-06-08 16:17:53 +00:00
/// <inheritdoc />
public async ValueTask<PagedResult<Database.File>> ListFiles(PagedRequest request)
2022-06-08 16:17:53 +00:00
{
2023-08-24 09:51:07 +00:00
IQueryable<Database.File> MakeQuery(VoidContext db)
2022-06-08 16:17:53 +00:00
{
var q = db.Files.AsNoTracking().AsQueryable();
switch (request.SortBy, request.SortOrder)
2022-06-09 14:15:28 +00:00
{
case (PagedSortBy.Id, PageSortOrder.Asc):
q = q.OrderBy(a => a.Id);
break;
case (PagedSortBy.Id, PageSortOrder.Dsc):
q = q.OrderByDescending(a => a.Id);
break;
case (PagedSortBy.Name, PageSortOrder.Asc):
q = q.OrderBy(a => a.Name);
break;
case (PagedSortBy.Name, PageSortOrder.Dsc):
q = q.OrderByDescending(a => a.Name);
break;
case (PagedSortBy.Date, PageSortOrder.Asc):
q = q.OrderBy(a => a.Uploaded);
break;
case (PagedSortBy.Date, PageSortOrder.Dsc):
q = q.OrderByDescending(a => a.Uploaded);
break;
case (PagedSortBy.Size, PageSortOrder.Asc):
q = q.OrderBy(a => a.Size);
break;
case (PagedSortBy.Size, PageSortOrder.Dsc):
q = q.OrderByDescending(a => a.Size);
break;
}
2023-08-24 09:51:07 +00:00
return q.Skip(request.Page * request.PageSize).Take(request.PageSize);
}
async IAsyncEnumerable<Database.File> Enumerate()
{
using var scope = _scopeFactory.CreateScope();
var db = scope.ServiceProvider.GetRequiredService<VoidContext>();
await foreach (var r in MakeQuery(db).AsAsyncEnumerable())
2022-06-08 16:17:53 +00:00
{
yield return r;
2022-06-08 16:17:53 +00:00
}
}
return new()
{
2023-08-24 10:53:12 +00:00
TotalResults = await _db.Files.CountAsync(),
Results = await MakeQuery(_db).CountAsync(),
2022-06-08 16:17:53 +00:00
PageSize = request.PageSize,
Page = request.Page,
2023-08-24 10:53:12 +00:00
Data = Enumerate()
2022-06-08 16:17:53 +00:00
};
}
/// <inheritdoc />
2022-06-06 21:51:25 +00:00
public async ValueTask<IFileMetadataStore.StoreStats> Stats()
{
var size = await _db.Files
.AsNoTracking()
.SumAsync(a => (long)a.Size);
var count = await _db.Files.CountAsync();
return new(count, (ulong)size);
2022-06-06 21:51:25 +00:00
}
}