feat: implement cleaning up table
This commit is contained in:
@@ -36,9 +36,11 @@ public class DatabaseMaintainerTests : DatabaseTest, IDisposable
|
||||
_ofacFileServiceOptions
|
||||
);
|
||||
|
||||
var uow = new EfUnitOfWork(_context, _loggerFactory);
|
||||
var logger = _loggerFactory.CreateLogger<DatabaseMaintainer>();
|
||||
_databaseMaintainer = new DatabaseMaintainer(uow, ofacFileService, logger);
|
||||
var uowLogger = _loggerFactory.CreateLogger<EfUnitOfWork>();
|
||||
var dbMaintainerLogger = _loggerFactory.CreateLogger<DatabaseMaintainer>();
|
||||
|
||||
var uow = new EfUnitOfWork(_context, uowLogger, _loggerFactory);
|
||||
_databaseMaintainer = new DatabaseMaintainer(uow, ofacFileService, dbMaintainerLogger);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
@@ -10,9 +10,10 @@ public class EfUnitOfWorkTests : DatabaseTest
|
||||
|
||||
public EfUnitOfWorkTests()
|
||||
{
|
||||
var logger = LoggerFactory.Create(c => c.ClearProviders());
|
||||
var loggerFactory = LoggerFactory.Create(c => c.ClearProviders());
|
||||
var logger = loggerFactory.CreateLogger<EfUnitOfWork>();
|
||||
|
||||
_uow = new(_context, logger);
|
||||
_uow = new(_context, logger, loggerFactory);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -78,4 +79,14 @@ public class EfUnitOfWorkTests : DatabaseTest
|
||||
|
||||
await action.Should().ThrowAsync<ObjectDisposedException>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Dispose_WhenCalled_ItShouldDisposeContext()
|
||||
{
|
||||
_uow.Dispose();
|
||||
|
||||
var action = () => _context.SaveChangesAsync();
|
||||
|
||||
action.Should().ThrowAsync<ObjectDisposedException>();
|
||||
}
|
||||
}
|
||||
@@ -82,4 +82,33 @@ public class SdnRepositoryTests : RepositoryTest
|
||||
result.Should().HaveCount(1);
|
||||
result.First().Should().BeEquivalentTo(target);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task DeleteWhereAsync_WithPredicate_ShouldDeleteEntitiesMatchingPredicate()
|
||||
{
|
||||
var entities = _faker.Generate(3);
|
||||
var entityIds = entities.Select(x => x.Id).ToList();
|
||||
|
||||
foreach (var entity in entities)
|
||||
{
|
||||
await _repository.Upsert(entity);
|
||||
}
|
||||
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
var createdEntities = await _context.Set<Sdn>()
|
||||
.Where(x => entityIds.Contains(x.Id))
|
||||
.ToListAsync();
|
||||
|
||||
createdEntities.Should().HaveCount(3);
|
||||
|
||||
var target = entities[0];
|
||||
await _repository.DeleteWhereAsync(x => entityIds.Contains(x.Id));
|
||||
|
||||
var remainingEntities = await _context.Set<Sdn>()
|
||||
.Where(x => entityIds.Contains(x.Id))
|
||||
.ToListAsync();
|
||||
|
||||
remainingEntities.Should().HaveCount(0);
|
||||
}
|
||||
}
|
||||
@@ -3,12 +3,13 @@ namespace SanctionsSearch.Worker.Tests.Unit;
|
||||
public class EfUnitOfWorkTests
|
||||
{
|
||||
private readonly Mock<DbContext> _contextMock = new();
|
||||
private readonly Mock<ILogger<EfUnitOfWork>> _loggerMock = new();
|
||||
private readonly Mock<ILoggerFactory> _loggerFactoryMock = new();
|
||||
private readonly EfUnitOfWork _unitOfWork;
|
||||
|
||||
public EfUnitOfWorkTests()
|
||||
{
|
||||
_unitOfWork = new(_contextMock.Object, _loggerFactoryMock.Object);
|
||||
_unitOfWork = new(_contextMock.Object, _loggerMock.Object, _loggerFactoryMock.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -66,7 +67,19 @@ public class EfUnitOfWorkTests
|
||||
.Setup(x => x.DisposeAsync())
|
||||
.Throws(new Exception());
|
||||
|
||||
var action = _unitOfWork.DisposeAsync;
|
||||
var action = async () => await _unitOfWork.DisposeAsync();
|
||||
|
||||
action.Should().NotThrowAsync();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Dispose_WhenExceptionIsThrown_ItShouldBeCaught()
|
||||
{
|
||||
_contextMock
|
||||
.Setup(x => x.Dispose())
|
||||
.Throws(new Exception());
|
||||
|
||||
var action = _unitOfWork.Dispose;
|
||||
|
||||
action.Should().NotThrow();
|
||||
}
|
||||
|
||||
@@ -6,4 +6,5 @@ interface IDatabaseMaintainer
|
||||
Task BuildAddressTableAsync();
|
||||
Task BuiltAliasTableAsync();
|
||||
Task BuildCommentTableAsync();
|
||||
Task CleanupTablesAsync();
|
||||
}
|
||||
@@ -2,4 +2,5 @@ namespace SanctionsSearch.Worker.Interfaces;
|
||||
|
||||
interface ISdnRepository : IRepository<Sdn>
|
||||
{
|
||||
Task DeleteWhereAsync(Expression<Func<Sdn, bool>> predicate);
|
||||
}
|
||||
@@ -167,6 +167,27 @@ class DatabaseMaintainer(
|
||||
_logger.LogInformation("Comment table built");
|
||||
}
|
||||
|
||||
public async Task CleanupTablesAsync()
|
||||
{
|
||||
_logger.LogInformation("Cleaning up tables");
|
||||
|
||||
var result = await _ofacFileService.GetSdnFileAsync();
|
||||
|
||||
if (result.IsFailed)
|
||||
{
|
||||
_logger.LogError("Failed to get SDN file from OFAC.");
|
||||
return;
|
||||
}
|
||||
|
||||
using var stream = result.Value;
|
||||
var records = GetRecordsFromStream<Sdn>(stream);
|
||||
var sdnIds = records.Select(s => s.Id).ToList();
|
||||
|
||||
await _unitOfWork.Sdns.DeleteWhereAsync(s => sdnIds.Contains(s.Id) == false);
|
||||
|
||||
_logger.LogInformation("Tables cleaned up");
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_csvReaders.ForEach(csv => csv.Dispose());
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
namespace SanctionsSearch.Worker.Persistence;
|
||||
|
||||
class EfUnitOfWork(DbContext context, ILoggerFactory loggerFactory) : IUnitOfWork, IAsyncDisposable, IDisposable
|
||||
class EfUnitOfWork(
|
||||
DbContext context,
|
||||
ILogger<EfUnitOfWork> logger,
|
||||
ILoggerFactory loggerFactory
|
||||
) : IUnitOfWork, IAsyncDisposable, IDisposable
|
||||
{
|
||||
private readonly DbContext _context = context;
|
||||
private readonly ILogger<EfUnitOfWork> _logger = loggerFactory.CreateLogger<EfUnitOfWork>();
|
||||
private readonly ILogger<EfUnitOfWork> _logger = logger;
|
||||
public ISdnRepository Sdns { get; } = new SdnRepository(context, loggerFactory.CreateLogger<SdnRepository>());
|
||||
public IAddressRepository Addresses { get; } = new AddressRepository(context, loggerFactory.CreateLogger<AddressRepository>());
|
||||
public IAliasRepository Aliases { get; } = new AliasRepository(context, loggerFactory.CreateLogger<AliasRepository>());
|
||||
|
||||
@@ -5,4 +5,8 @@ class SdnRepository(
|
||||
ILogger<SdnRepository> logger
|
||||
) : EfRepository<Sdn>(dbContext, logger), ISdnRepository
|
||||
{
|
||||
public Task DeleteWhereAsync(Expression<Func<Sdn, bool>> predicate)
|
||||
{
|
||||
return _context.Set<Sdn>().Where(predicate).ExecuteDeleteAsync();
|
||||
}
|
||||
}
|
||||
@@ -52,6 +52,7 @@ public class DatabaseWorker(
|
||||
await databaseMaintainer.BuildAddressTableAsync();
|
||||
await databaseMaintainer.BuiltAliasTableAsync();
|
||||
await databaseMaintainer.BuildCommentTableAsync();
|
||||
await databaseMaintainer.CleanupTablesAsync();
|
||||
|
||||
_logger.LogInformation("Database updated");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user