299 lines
9.5 KiB
C#
299 lines
9.5 KiB
C#
using Mapster;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Persistence.Database.Model;
|
|
using Persistence.Models;
|
|
using Persistence.Models.Requests;
|
|
using Persistence.Repositories;
|
|
|
|
namespace Persistence.Repository.Repositories;
|
|
public class ChangeLogRepository : IChangeLogRepository
|
|
{
|
|
private DbContext db;
|
|
|
|
public ChangeLogRepository(DbContext db)
|
|
{
|
|
this.db = db;
|
|
}
|
|
|
|
public async Task<int> AddRange(Guid idAuthor, Guid idDiscriminator, IEnumerable<DataWithWellDepthAndSectionDto> dtos, CancellationToken token)
|
|
{
|
|
foreach (var dto in dtos)
|
|
{
|
|
var entity = CreateEntityFromDto(idAuthor, idDiscriminator, dto);
|
|
db.Set<ChangeLog>().Add(entity);
|
|
}
|
|
|
|
var result = await db.SaveChangesAsync(token);
|
|
|
|
return result;
|
|
}
|
|
|
|
public async Task<int> MarkAsDeleted(Guid idEditor, IEnumerable<Guid> ids, CancellationToken token)
|
|
{
|
|
var query = db.Set<ChangeLog>().Where(s => ids.Contains(s.Id));
|
|
var entities = await query.ToArrayAsync(token);
|
|
|
|
var result = await Clear(idEditor, entities, token);
|
|
|
|
return result;
|
|
}
|
|
|
|
public async Task<int> MarkAsDeleted(Guid idEditor, Guid idDiscriminator, CancellationToken token)
|
|
{
|
|
var query = db.Set<ChangeLog>()
|
|
.Where(s => s.IdDiscriminator == idDiscriminator)
|
|
.Where(e => e.Obsolete == null);
|
|
var entities = await query.ToArrayAsync(token);
|
|
|
|
var result = await Clear(idEditor, entities, token);
|
|
|
|
return result;
|
|
}
|
|
|
|
private async Task<int> Clear(Guid idEditor, IEnumerable<ChangeLog> entities, CancellationToken token)
|
|
{
|
|
var updateTime = DateTimeOffset.UtcNow;
|
|
|
|
foreach (var entity in entities)
|
|
{
|
|
entity.Obsolete = updateTime;
|
|
entity.IdEditor = idEditor;
|
|
}
|
|
|
|
return await db.SaveChangesAsync(token);
|
|
}
|
|
|
|
public async Task<int> ClearAndAddRange(Guid idAuthor, Guid idDiscriminator, IEnumerable<DataWithWellDepthAndSectionDto> dtos, CancellationToken token)
|
|
{
|
|
var result = 0;
|
|
using var transaction = await db.Database.BeginTransactionAsync(token);
|
|
try
|
|
{
|
|
result += await MarkAsDeleted(idAuthor, idDiscriminator, token);
|
|
result += await AddRange(idAuthor, idDiscriminator, dtos, token);
|
|
|
|
await transaction.CommitAsync(token);
|
|
return result;
|
|
}
|
|
catch
|
|
{
|
|
await transaction.RollbackAsync(token);
|
|
throw;
|
|
}
|
|
}
|
|
|
|
public async Task<int> UpdateRange(Guid idEditor, IEnumerable<DataWithWellDepthAndSectionDto> dtos, CancellationToken token)
|
|
{
|
|
var dbSet = db.Set<ChangeLog>();
|
|
|
|
var updatedIds = dtos.Select(d => d.Id);
|
|
var updatedEntities = dbSet
|
|
.Where(s => updatedIds.Contains(s.Id))
|
|
.ToDictionary(s => s.Id);
|
|
|
|
var result = 0;
|
|
using var transaction = await db.Database.BeginTransactionAsync(token);
|
|
try
|
|
{
|
|
foreach (var dto in dtos)
|
|
{
|
|
var updatedEntity = updatedEntities.GetValueOrDefault(dto.Id);
|
|
if(updatedEntity is null)
|
|
{
|
|
throw new ArgumentNullException($"Entity with id = {dto.Id} doesn't exist in Db", nameof(dto));
|
|
}
|
|
|
|
var newEntity = CreateEntityFromDto(idEditor, updatedEntity.IdDiscriminator, dto);
|
|
dbSet.Add(newEntity);
|
|
|
|
updatedEntity.IdNext = newEntity.Id;
|
|
updatedEntity.Obsolete = DateTimeOffset.UtcNow;
|
|
updatedEntity.IdEditor = idEditor;
|
|
}
|
|
|
|
result = await db.SaveChangesAsync(token);
|
|
await transaction.CommitAsync(token);
|
|
|
|
return result;
|
|
}
|
|
catch
|
|
{
|
|
await transaction.RollbackAsync(token);
|
|
throw;
|
|
}
|
|
}
|
|
|
|
public async Task<PaginationContainer<DataWithWellDepthAndSectionDto>> GetByDate(
|
|
Guid idDiscriminator,
|
|
DateTimeOffset momentUtc,
|
|
SectionPartRequest filterRequest,
|
|
PaginationRequest paginationRequest,
|
|
CancellationToken token)
|
|
{
|
|
var query = BuildQuery(idDiscriminator, momentUtc, filterRequest);
|
|
var result = await BuildPaginationContainer(query, paginationRequest, token);
|
|
|
|
return result;
|
|
}
|
|
|
|
private IQueryable<ChangeLog> BuildQuery(Guid idDiscriminator, DateTimeOffset momentUtc, SectionPartRequest request)
|
|
{
|
|
var query = db.Set<ChangeLog>()
|
|
.Where(e => e.IdDiscriminator == idDiscriminator)
|
|
.Where(e => e.Creation <= momentUtc)
|
|
.Where(e => e.Obsolete == null || e.Obsolete >= momentUtc);
|
|
|
|
if (request.IdSection.HasValue)
|
|
{
|
|
query = query.Where(e => e.IdSection == request.IdSection);
|
|
}
|
|
if (request.DepthStart.HasValue)
|
|
{
|
|
query = query.Where(e => e.DepthStart >= request.DepthStart);
|
|
}
|
|
if (request.DepthEnd.HasValue)
|
|
{
|
|
query = query.Where(e => e.DepthEnd <= request.DepthEnd);
|
|
}
|
|
|
|
return query;
|
|
}
|
|
|
|
public async Task<IEnumerable<ChangeLogDto>> GetChangeLogForInterval(Guid idDiscriminator, DateTimeOffset dateBegin, DateTimeOffset dateEnd, CancellationToken token)
|
|
{
|
|
var query = db.Set<ChangeLog>().Where(s => s.IdDiscriminator == idDiscriminator);
|
|
|
|
var min = new DateTimeOffset(dateBegin.Year, dateBegin.Month, dateBegin.Day, 0, 0, 0, TimeSpan.Zero);
|
|
var max = new DateTimeOffset(dateEnd.Year, dateEnd.Month, dateEnd.Day, 0, 0, 0, TimeSpan.Zero);
|
|
|
|
var createdQuery = query.Where(e => e.Creation >= min && e.Creation <= max);
|
|
var editedQuery = query.Where(e => e.Obsolete != null && e.Obsolete >= min && e.Obsolete <= max);
|
|
|
|
query = createdQuery.Union(editedQuery);
|
|
var entities = await query.ToArrayAsync(token);
|
|
|
|
var dtos = entities.Select(e => e.Adapt<ChangeLogDto>());
|
|
|
|
return dtos;
|
|
}
|
|
|
|
|
|
|
|
private async Task<PaginationContainer<DataWithWellDepthAndSectionDto>> BuildPaginationContainer(IQueryable<ChangeLog> query, PaginationRequest request, CancellationToken token)
|
|
{
|
|
var result = new PaginationContainer<DataWithWellDepthAndSectionDto>
|
|
{
|
|
Skip = request.Skip,
|
|
Take = request.Take,
|
|
Items = Enumerable.Empty<DataWithWellDepthAndSectionDto>(),
|
|
Count = await query.CountAsync(token)
|
|
};
|
|
|
|
if (!String.IsNullOrEmpty(request.SortSettings))
|
|
{
|
|
query = query.SortBy(request.SortSettings);
|
|
}
|
|
else
|
|
{
|
|
query = query
|
|
.OrderBy(e => e.IdSection)
|
|
.ThenBy(e => e.DepthStart)
|
|
.ThenBy(e => e.DepthEnd);
|
|
}
|
|
|
|
var entities = await query
|
|
.Skip(result.Skip)
|
|
.Take(result.Take)
|
|
.ToArrayAsync(token);
|
|
|
|
var dtos = entities.Select(e => e.Adapt<DataWithWellDepthAndSectionDto>());
|
|
result.Items = dtos;
|
|
|
|
return result;
|
|
}
|
|
|
|
public async Task<IEnumerable<DateOnly>> GetDatesChange(Guid idDiscriminator, CancellationToken token)
|
|
{
|
|
var query = db.Set<ChangeLog>().Where(e => e.IdDiscriminator == idDiscriminator);
|
|
|
|
var datesCreateQuery = query
|
|
.Select(e => e.Creation)
|
|
.Distinct();
|
|
|
|
var datesCreate = await datesCreateQuery.ToArrayAsync(token);
|
|
|
|
var datesUpdateQuery = query
|
|
.Where(e => e.Obsolete != null)
|
|
.Select(e => e.Obsolete!.Value)
|
|
.Distinct();
|
|
|
|
var datesUpdate = await datesUpdateQuery.ToArrayAsync(token);
|
|
|
|
var dates = Enumerable.Concat(datesCreate, datesUpdate);
|
|
var datesOnly = dates
|
|
.Select(d => new DateOnly(d.Year, d.Month, d.Day))
|
|
.Distinct()
|
|
.OrderBy(d => d);
|
|
|
|
return datesOnly;
|
|
}
|
|
|
|
private ChangeLog CreateEntityFromDto(Guid idAuthor, Guid idDiscriminator, DataWithWellDepthAndSectionDto dto)
|
|
{
|
|
var entity = new ChangeLog()
|
|
{
|
|
Id = default,
|
|
Creation = DateTimeOffset.UtcNow,
|
|
IdAuthor = idAuthor,
|
|
IdDiscriminator = idDiscriminator,
|
|
IdEditor = idAuthor,
|
|
|
|
Value = dto.Value,
|
|
IdSection = dto.IdSection,
|
|
DepthStart = dto.DepthStart,
|
|
DepthEnd = dto.DepthEnd,
|
|
};
|
|
|
|
return entity;
|
|
}
|
|
|
|
public async Task<IEnumerable<DataWithWellDepthAndSectionDto>> GetGtDate(Guid idDiscriminator, DateTimeOffset dateBegin, CancellationToken token)
|
|
{
|
|
var date = dateBegin.ToUniversalTime();
|
|
var query = this.db.Set<ChangeLog>()
|
|
.Where(e => e.IdDiscriminator == idDiscriminator)
|
|
.Where(e => e.Creation >= date || e.Obsolete >= date);
|
|
|
|
var entities = await query.ToArrayAsync(token);
|
|
|
|
var dtos = entities.Select(e => e.Adapt<DataWithWellDepthAndSectionDto>());
|
|
|
|
return dtos;
|
|
}
|
|
|
|
public async Task<DatesRangeDto?> GetDatesRange(Guid idDiscriminator, CancellationToken token)
|
|
{
|
|
var query = db.Set<ChangeLog>()
|
|
.Where(e => e.IdDiscriminator == idDiscriminator)
|
|
.GroupBy(e => 1)
|
|
.Select(group => new
|
|
{
|
|
Min = group.Min(e => e.Creation),
|
|
Max = group.Max(e => e.Creation),
|
|
});
|
|
|
|
var values = await query.FirstOrDefaultAsync(token);
|
|
|
|
if(values is null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
return new DatesRangeDto
|
|
{
|
|
From = values.Min,
|
|
To = values.Max,
|
|
};
|
|
}
|
|
}
|