202 lines
8.0 KiB
C#
202 lines
8.0 KiB
C#
using System.Diagnostics;
|
|
using System.Linq.Expressions;
|
|
using e_suite.API.Common;
|
|
using e_suite.API.Common.exceptions;
|
|
using e_suite.API.Common.models;
|
|
using e_suite.API.Common.repository;
|
|
using e_suite.Database.Audit;
|
|
using e_suite.Utilities.Pagination;
|
|
using eSuite.Core.Clock;
|
|
using eSuite.Core.Miscellaneous;
|
|
|
|
namespace e_suite.Modules.SequenceManager;
|
|
|
|
public class SequenceManager : ISequenceManager
|
|
{
|
|
private readonly ISequenceManagerRepository _sequenceManagerRepository;
|
|
private readonly IClock _clock;
|
|
|
|
public SequenceManager(ISequenceManagerRepository sequenceManagerRepository, IClock clock)
|
|
{
|
|
_sequenceManagerRepository = sequenceManagerRepository;
|
|
_clock = clock;
|
|
}
|
|
|
|
public async Task<Sequence> GetSequence(IGeneralIdRef generalIdRef, CancellationToken cancellationToken)
|
|
{
|
|
var sequence = await _sequenceManagerRepository.GetSequenceById(generalIdRef, cancellationToken);
|
|
|
|
if (sequence == null)
|
|
throw new NotFoundException();
|
|
|
|
if (sequence.Deleted)
|
|
throw new NotFoundException();
|
|
|
|
var sequenceModel = new Sequence
|
|
{
|
|
GeneralIdRef = new GeneralIdRef
|
|
{
|
|
Guid = sequence.Guid,
|
|
Id = sequence.Id
|
|
},
|
|
Name = sequence.Name,
|
|
Pattern = sequence.Pattern,
|
|
Increment = sequence.Increment,
|
|
Seed = sequence.Seed,
|
|
RolloverType = sequence.Rollover
|
|
};
|
|
|
|
return sequenceModel;
|
|
}
|
|
|
|
public async Task<IPaginatedData<ReadSequence>> GetSequences(Paging paging, CancellationToken cancellationToken)
|
|
{
|
|
var sequences = _sequenceManagerRepository.GetSequenceList();
|
|
|
|
var paginatedData = await PaginatedData.Paginate(sequences, paging,
|
|
KeySelector, cancellationToken);
|
|
|
|
var paginatedResult = new PaginatedData<ReadSequence>()
|
|
{
|
|
Count = paginatedData.Count,
|
|
Page = paginatedData.Page,
|
|
PageSize = paginatedData.PageSize,
|
|
Data = paginatedData.Data.Select(x => new ReadSequence
|
|
{
|
|
Id = x.Id,
|
|
Guid = x.Guid,
|
|
Name = x.Name
|
|
})
|
|
|
|
};
|
|
|
|
return paginatedResult;
|
|
}
|
|
|
|
private Expression<Func<Database.Core.Tables.Sequences.Sequence, object>> KeySelector(string? sortKey)
|
|
{
|
|
return sortKey?.ToLowerInvariant() switch
|
|
{
|
|
"id" => x => x.Id,
|
|
"guid" => x => x.Guid,
|
|
_ => x => x.Name
|
|
};
|
|
}
|
|
|
|
public async Task CreateSequence(AuditUserDetails auditUserDetails, NewSequence sequence, CancellationToken cancellationToken)
|
|
{
|
|
await _sequenceManagerRepository.TransactionAsync(async () =>
|
|
{
|
|
var existingSequence = sequence.Guid == null
|
|
? null
|
|
: await _sequenceManagerRepository.GetSequenceById(new GeneralIdRef
|
|
{
|
|
Guid = sequence.Guid
|
|
}, cancellationToken);
|
|
|
|
if (existingSequence != null && !existingSequence.Deleted)
|
|
throw new ExistsException($"Sequence with guid '{sequence.Guid}' already exists");
|
|
|
|
|
|
if (existingSequence == null)
|
|
{
|
|
existingSequence = await _sequenceManagerRepository.GetSequenceByName(sequence.Name, cancellationToken);
|
|
if (existingSequence != null && !existingSequence.Deleted)
|
|
throw new ExistsException($"Sequence with name '{sequence.Name}' already exists");
|
|
|
|
}
|
|
|
|
existingSequence ??= new Database.Core.Tables.Sequences.Sequence
|
|
{
|
|
Guid = sequence.Guid ?? Guid.NewGuid()
|
|
};
|
|
|
|
existingSequence.Name = sequence.Name;
|
|
existingSequence.Seed = sequence.Seed;
|
|
existingSequence.Increment = sequence.Increment;
|
|
existingSequence.Pattern = sequence.Pattern;
|
|
existingSequence.Rollover = sequence.RolloverType;
|
|
|
|
if (existingSequence.Deleted)
|
|
{
|
|
existingSequence.Deleted = false;
|
|
await _sequenceManagerRepository.EditSequence(auditUserDetails, existingSequence, cancellationToken);
|
|
}
|
|
else
|
|
{
|
|
await _sequenceManagerRepository.AddSequence(auditUserDetails, existingSequence, cancellationToken);
|
|
}
|
|
});
|
|
}
|
|
|
|
public async Task EditSequence(AuditUserDetails auditUserDetails, Sequence editSequence, CancellationToken cancellationToken)
|
|
{
|
|
await _sequenceManagerRepository.TransactionAsync(async () =>
|
|
{
|
|
var existingSequence =
|
|
await _sequenceManagerRepository.GetSequenceById(editSequence.GeneralIdRef!, cancellationToken);
|
|
|
|
if (existingSequence == null || existingSequence.Deleted)
|
|
throw new NotFoundException("A sequence with this Id doesn't exist");
|
|
|
|
var identicalNameSequence =
|
|
await _sequenceManagerRepository.GetSequenceByName(editSequence.Name, cancellationToken);
|
|
if (identicalNameSequence != null && (identicalNameSequence.Id != editSequence.GeneralIdRef!.Id &&
|
|
identicalNameSequence.Guid != editSequence.GeneralIdRef.Guid))
|
|
throw new ExistsException($"Sequence with name '{editSequence.Name}' already exists");
|
|
|
|
existingSequence.Name = editSequence.Name;
|
|
existingSequence.Increment = editSequence.Increment;
|
|
existingSequence.Seed = editSequence.Seed;
|
|
existingSequence.Pattern = editSequence.Pattern;
|
|
existingSequence.Rollover = editSequence.RolloverType;
|
|
|
|
await _sequenceManagerRepository.EditSequence(auditUserDetails, existingSequence, cancellationToken);
|
|
});
|
|
}
|
|
|
|
public async Task DeleteSequence(AuditUserDetails auditUserDetails, IGeneralIdRef generalIdRef, CancellationToken cancellationToken)
|
|
{
|
|
await _sequenceManagerRepository.TransactionAsync(async () =>
|
|
{
|
|
var existingSequence = await _sequenceManagerRepository.GetSequenceById(generalIdRef, cancellationToken);
|
|
if (existingSequence == null || existingSequence.Deleted)
|
|
throw new NotFoundException("A sequence with this Id doesn't exist");
|
|
|
|
existingSequence.Deleted = true;
|
|
|
|
await _sequenceManagerRepository.EditSequence(auditUserDetails, existingSequence, cancellationToken);
|
|
});
|
|
}
|
|
|
|
public async Task<IEnumerable<string>> NextValue(AuditUserDetails auditUserDetails, IGeneralIdRef generalIdRef,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
return await NextValue( auditUserDetails, generalIdRef, 1, cancellationToken).ConfigureAwait(false);
|
|
}
|
|
|
|
public async Task<IEnumerable<string>> NextValue(AuditUserDetails auditUserDetails, IGeneralIdRef generalIdRef, int number, CancellationToken cancellationToken)
|
|
{
|
|
return await _sequenceManagerRepository.TransactionAsync(async () =>
|
|
{
|
|
var existingSequence = await _sequenceManagerRepository.GetSequenceById(generalIdRef, cancellationToken);
|
|
if (existingSequence == null || existingSequence.Deleted)
|
|
throw new NotFoundException("A sequence with this Id doesn't exist");
|
|
|
|
var result = new List<string>();
|
|
|
|
var stopwatch = Stopwatch.StartNew();
|
|
while (result.Count < number)
|
|
{
|
|
if (stopwatch.ElapsedMilliseconds > 2000)
|
|
throw new TimeoutException($"Took more than 2 seconds to create count list. Created {result.Count} values in the available time");
|
|
cancellationToken.ThrowIfCancellationRequested();
|
|
result.Add(SequenceNumberBuilder.GetNextSequenceNumber(existingSequence, _clock));
|
|
}
|
|
|
|
await _sequenceManagerRepository.EditSequence(auditUserDetails, existingSequence, cancellationToken);
|
|
|
|
return result;
|
|
});
|
|
}
|
|
} |