using Mapster; using Microsoft.EntityFrameworkCore; using Persistence.Database.Model; using Persistence.Models; using Persistence.Repositories; namespace Persistence.Repository.Repositories; public class ChangeLogRepository : IChangeLogRepository { private DbContext db; public ChangeLogRepository(DbContext db) { this.db = db; } public async Task Clear(Guid idUser, Guid idDiscriminator, CancellationToken token) { var updateTime = DateTimeOffset.UtcNow; var dbSet = db.Set(); var query = dbSet .Where(s => s.IdDiscriminator == idDiscriminator) .Where(e => e.Obsolete == null); var entitiesToDelete = await query.ToArrayAsync(token); foreach (var entity in entitiesToDelete) { entity.Obsolete = updateTime; entity.IdEditor = idUser; } return await db.SaveChangesAsync(token); } public async Task ClearAndInsertRange(Guid idUser, Guid idDiscriminator, IEnumerable dtos, CancellationToken token) { var result = 0; using var transaction = await db.Database.BeginTransactionAsync(token); try { result += await Clear(idUser, idDiscriminator, token); result += await InsertRange(idUser, idDiscriminator, dtos, token); await transaction.CommitAsync(token); return result; } catch { await transaction.RollbackAsync(token); throw; } } public async Task> GetChangeLogForDate(Guid idDiscriminator, DateTimeOffset dateBegin, DateTimeOffset dateEnd, CancellationToken token) { var dbSet = db.Set(); var query = dbSet.Where(s => s.IdDiscriminator == idDiscriminator); var min = dateBegin; var max = dateEnd; 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.ToListAsync(token); var dtos = entities.Select(e => new ChangeLogDto { Creation = e.Creation, IdAuthor = e.IdAuthor, IdEditor = e.IdEditor, IdNext = e.IdNext, Obsolete = e.Obsolete, Value = new DataWithWellDepthAndSectionDto() { Value = e.Value, IdSection = e.IdSection, Id = e.Id, DepthEnd = e.DepthEnd, DepthStart = e.DepthStart } }); return dtos; } public async Task> GetByDate(Guid idDiscriminator, DateTimeOffset momentUtc, CancellationToken token) { var dbSet = db.Set(); var dbQuery = dbSet .Where(s => s.IdDiscriminator == idDiscriminator) .Where(e => e.Creation <= momentUtc) .Where(e => e.Obsolete == null || e.Obsolete >= momentUtc); var entities = await dbQuery.ToArrayAsync(token); var dtos = entities.Select(e => e.Adapt()); return dtos; } public Task> GetDatesChange(CancellationToken token) { throw new NotImplementedException(); } public Task>> GetGtDate(DateTimeOffset dateBegin, CancellationToken token) { throw new NotImplementedException(); } public Task InsertRange(Guid idUser, Guid idDiscriminator, IEnumerable dtos, CancellationToken token) { foreach (var dto in dtos) { var entity = CreateEntityFromDto(idUser, idDiscriminator, dto); db.Set().Add(entity); } var result = db.SaveChangesAsync(token); return result; } private ChangeLog CreateEntityFromDto(Guid idUser, Guid idDiscriminator, DataWithWellDepthAndSectionDto dto) { var entity = new ChangeLog() { Id = default, Creation = DateTimeOffset.UtcNow, IdAuthor = idUser, IdDiscriminator = idDiscriminator, IdEditor = idUser, Value = dto.Value, IdSection = dto.IdSection, DepthStart = dto.DepthStart, DepthEnd = dto.DepthEnd, }; return entity; } public async Task MarkAsDeleted(Guid idUser, IEnumerable ids, CancellationToken token) { var result = 0; var dbSet = db.Set(); var updatedEntity = dbSet .Where(s => ids.Contains(s.Id)) .FirstOrDefault(); if (updatedEntity != null) { updatedEntity.Obsolete = DateTimeOffset.UtcNow; result = await db.SaveChangesAsync(token); } return result; } public Task UpdateOrInsertRange(int idUser, IEnumerable> dtos, CancellationToken token) { throw new NotImplementedException(); } public async Task UpdateRange(Guid idUser, Guid idDiscriminator, IEnumerable dtos, CancellationToken token) { var dbSet = db.Set(); var updatedIds = dtos.Select(d => d.Id); var updatedEntities = dbSet .Where(s => updatedIds.Contains(s.Id)) .ToDictionary(s => s.Id); //todo foreach (var dto in dtos) { var newEntity = CreateEntityFromDto(idUser, idDiscriminator, dto); dbSet.Add(newEntity); var updatedEntity = updatedEntities.GetValueOrDefault(dto.Id)!; updatedEntity.IdNext = newEntity.Id; updatedEntity.Obsolete = DateTimeOffset.UtcNow; updatedEntity.IdEditor = idUser; } var result = await db.SaveChangesAsync(token); return result; } }