Compare commits
3 Commits
d4ee0f043e
...
9b73c84256
| Author | SHA1 | Date | |
|---|---|---|---|
| 9b73c84256 | |||
| 8d95a78cbf | |||
| 5d5d091dbe |
@@ -3,4 +3,9 @@ namespace LiquidCode.Api.Authentication.Requests;
|
||||
/// <summary>
|
||||
/// Модель запроса для входа пользователя
|
||||
/// </summary>
|
||||
public record LoginRequest(string Username, string Password);
|
||||
/// <param name="Username">Имя пользователя</param>
|
||||
/// <param name="Password">Пароль</param>
|
||||
public record LoginRequest(
|
||||
string Username,
|
||||
string Password
|
||||
);
|
||||
|
||||
@@ -7,15 +7,6 @@ namespace LiquidCode.Domain.Interfaces.Repositories;
|
||||
/// </summary>
|
||||
public interface IMissionRepository : IRepository<DbMission>
|
||||
{
|
||||
/// <summary>
|
||||
/// Получает миссии с пагинацией
|
||||
/// </summary>
|
||||
/// <param name="pageSize">Количество элементов на странице</param>
|
||||
/// <param name="pageNumber">Номер страницы (начиная с нуля)</param>
|
||||
/// <param name="cancellationToken">Токен отмены</param>
|
||||
/// <returns>Кортеж (миссии, естьСледующаяСтраница)</returns>
|
||||
Task<(IEnumerable<DbMission> Missions, bool HasNextPage)> GetMissionsPageAsync(
|
||||
int pageSize, int pageNumber, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Получает миссии по автору
|
||||
@@ -35,12 +26,12 @@ public interface IMissionRepository : IRepository<DbMission>
|
||||
/// <summary>
|
||||
/// Добавляет текстовые данные миссии
|
||||
/// </summary>
|
||||
Task AddMissionTextAsync(DbMissionPublicTextData textData, CancellationToken cancellationToken = default);
|
||||
Task CreateMissionTextAsync(DbMissionPublicTextData textData, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Добавляет несколько записей текстовых данных миссии
|
||||
/// </summary>
|
||||
Task AddMissionTextsAsync(IEnumerable<DbMissionPublicTextData> textData, CancellationToken cancellationToken = default);
|
||||
Task CreateMissionTextsAsync(IEnumerable<DbMissionPublicTextData> textData, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Подсчитывает общее количество миссий
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
using LiquidCode.Infrastructure.Database.Entities;
|
||||
|
||||
namespace LiquidCode.Domain.Interfaces.Repositories;
|
||||
|
||||
/// <summary>
|
||||
/// Базовый интерфейс репозитория для общих операций CRUD
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity">Тип сущности, управляемой этим репозиторием</typeparam>
|
||||
public interface IRepository<TEntity> where TEntity : class
|
||||
public interface IRepository<TEntity> where TEntity : class, ISoftDeletable
|
||||
{
|
||||
/// <summary>
|
||||
/// Находит сущность по ее ID
|
||||
@@ -12,14 +14,19 @@ public interface IRepository<TEntity> where TEntity : class
|
||||
Task<TEntity?> FindByIdAsync(int id, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Получает все сущности
|
||||
/// Получает все сущности с пагинацией
|
||||
/// </summary>
|
||||
Task<IEnumerable<TEntity>> GetAllAsync(CancellationToken cancellationToken = default);
|
||||
/// <param name="pageSize">Количество элементов на странице</param>
|
||||
/// <param name="pageNumber">Номер страницы (начиная с 0)</param>
|
||||
/// <param name="cancellationToken">Токен отмены</param>
|
||||
/// <returns>Кортеж (сущности, естьСледующаяСтраница)</returns>
|
||||
Task<(IEnumerable<TEntity> Items, bool HasNextPage)> GetPageAsync(
|
||||
int pageSize, int pageNumber, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Добавляет новую сущность
|
||||
/// </summary>
|
||||
Task AddAsync(TEntity entity, CancellationToken cancellationToken = default);
|
||||
Task CreateAsync(TEntity entity, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Обновляет существующую сущность
|
||||
@@ -29,7 +36,12 @@ public interface IRepository<TEntity> where TEntity : class
|
||||
/// <summary>
|
||||
/// Удаляет сущность
|
||||
/// </summary>
|
||||
Task RemoveAsync(TEntity entity, CancellationToken cancellationToken = default);
|
||||
Task DeleteAsync(TEntity entity, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Мягко удаляет сущность
|
||||
/// </summary>
|
||||
Task SoftDeleteAsync(TEntity entity, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Сохраняет все изменения, сделанные в базе данных
|
||||
|
||||
@@ -23,12 +23,12 @@ public interface ISubmitRepository : IRepository<DbUserSubmit>
|
||||
Task<DbUserSubmit?> GetSubmissionWithDetailsAsync(int submissionId, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Получает решение для отправки
|
||||
/// Получает решение
|
||||
/// </summary>
|
||||
Task<DbSolution?> GetSolutionAsync(int submissionId, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Добавляет решение для отправки
|
||||
/// Добавляет решение
|
||||
/// </summary>
|
||||
Task AddSolutionAsync(DbSolution solution, CancellationToken cancellationToken = default);
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ public class AuthenticationService : IAuthenticationService
|
||||
Salt = "" // BCrypt управляет солью внутренне
|
||||
};
|
||||
|
||||
await _userRepository.AddAsync(newUser, cancellationToken);
|
||||
await _userRepository.CreateAsync(newUser, cancellationToken);
|
||||
_logger.LogInformation("User registered successfully: {Username}", request.Username);
|
||||
|
||||
// Автоматически войти пользователю
|
||||
|
||||
@@ -83,7 +83,7 @@ public class MissionService : IMissionService
|
||||
UpdatedAt = DateTime.UtcNow
|
||||
};
|
||||
|
||||
await _missionRepository.AddAsync(dbMission, cancellationToken);
|
||||
await _missionRepository.CreateAsync(dbMission, cancellationToken);
|
||||
|
||||
// Распарсить и сохранить текстовые данные миссии
|
||||
var missionTexts = ExtractMissionTexts(statementSectionsPath, dbMission.Id);
|
||||
@@ -104,7 +104,7 @@ public class MissionService : IMissionService
|
||||
}
|
||||
|
||||
// Добавить текстовые данные миссии в базу данных
|
||||
await _missionRepository.AddMissionTextsAsync(missionTexts, cancellationToken);
|
||||
await _missionRepository.CreateMissionTextsAsync(missionTexts, cancellationToken);
|
||||
await _missionRepository.SaveChangesAsync(cancellationToken);
|
||||
|
||||
_logger.LogInformation("Mission uploaded successfully: {MissionId}", dbMission.Id);
|
||||
@@ -159,7 +159,7 @@ public class MissionService : IMissionService
|
||||
return null;
|
||||
}
|
||||
|
||||
var (missions, hasNextPage) = await _missionRepository.GetMissionsPageAsync(pageSize, pageNumber, cancellationToken);
|
||||
var (missions, hasNextPage) = await _missionRepository.GetPageAsync(pageSize, pageNumber, cancellationToken);
|
||||
var apiList = missions.Select(MissionResponse.FromEntity);
|
||||
|
||||
return new MissionsPageResponse(hasNextPage, apiList);
|
||||
|
||||
@@ -72,7 +72,7 @@ public class SubmitService : ISubmitService
|
||||
Solution = solution
|
||||
};
|
||||
|
||||
await _submitRepository.AddAsync(submission, cancellationToken);
|
||||
await _submitRepository.CreateAsync(submission, cancellationToken);
|
||||
_logger.LogInformation("Solution submitted: UserId={UserId}, MissionId={MissionId}, SolutionId={SolutionId}", userId, missionId, solution.Id);
|
||||
|
||||
return solution;
|
||||
|
||||
70
LiquidCode/Infrastructure/Database/Repositories/DbCrud.cs
Normal file
70
LiquidCode/Infrastructure/Database/Repositories/DbCrud.cs
Normal file
@@ -0,0 +1,70 @@
|
||||
using LiquidCode.Domain.Interfaces.Repositories;
|
||||
using LiquidCode.Infrastructure.Database;
|
||||
using LiquidCode.Infrastructure.Database.Entities;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace LiquidCode.Infrastructure.Database.Repositories;
|
||||
|
||||
/// <summary>
|
||||
/// Базовая реализация репозитория, предоставляющая общие операции CRUD
|
||||
/// </summary>
|
||||
public class DbCrud<TEntity> : IRepository<TEntity> where TEntity : class, ISoftDeletable
|
||||
{
|
||||
private readonly LiquidDbContext _dbContext;
|
||||
public readonly DbSet<TEntity> DbSet;
|
||||
|
||||
public DbCrud(LiquidDbContext dbContext)
|
||||
{
|
||||
_dbContext = dbContext;
|
||||
DbSet = dbContext.Set<TEntity>();
|
||||
}
|
||||
|
||||
public virtual async Task<TEntity?> FindByIdAsync(int id, CancellationToken cancellationToken = default) =>
|
||||
await DbSet.FindAsync(new object?[] { id }, cancellationToken);
|
||||
|
||||
public virtual async Task<(IEnumerable<TEntity> Items, bool HasNextPage)> GetPageAsync(
|
||||
int pageSize, int pageNumber, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (pageSize <= 0 || pageNumber < 0)
|
||||
throw new ArgumentException("Page size must be positive, page number must be non-negative");
|
||||
|
||||
var totalCount = await DbSet.CountAsync(cancellationToken);
|
||||
var hasNextPage = totalCount > pageSize * (pageNumber + 1);
|
||||
|
||||
var items = await DbSet
|
||||
.OrderBy(x => EF.Property<int>(x, "Id"))
|
||||
.Skip(pageSize * pageNumber)
|
||||
.Take(pageSize)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
return (items, hasNextPage);
|
||||
}
|
||||
|
||||
public virtual async Task CreateAsync(TEntity entity, CancellationToken cancellationToken = default)
|
||||
{
|
||||
await DbSet.AddAsync(entity, cancellationToken);
|
||||
await SaveChangesAsync(cancellationToken);
|
||||
}
|
||||
|
||||
public virtual async Task UpdateAsync(TEntity entity, CancellationToken cancellationToken = default)
|
||||
{
|
||||
DbSet.Update(entity);
|
||||
await SaveChangesAsync(cancellationToken);
|
||||
}
|
||||
|
||||
public virtual async Task DeleteAsync(TEntity entity, CancellationToken cancellationToken = default)
|
||||
{
|
||||
DbSet.Remove(entity);
|
||||
await SaveChangesAsync(cancellationToken);
|
||||
}
|
||||
|
||||
public virtual async Task SoftDeleteAsync(TEntity entity, CancellationToken cancellationToken = default)
|
||||
{
|
||||
entity.IsDeleted = true;
|
||||
DbSet.Update(entity);
|
||||
await SaveChangesAsync(cancellationToken);
|
||||
}
|
||||
|
||||
public async Task SaveChangesAsync(CancellationToken cancellationToken = default) =>
|
||||
await _dbContext.SaveChangesAsync(cancellationToken);
|
||||
}
|
||||
@@ -8,52 +8,63 @@ namespace LiquidCode.Infrastructure.Database.Repositories;
|
||||
/// <summary>
|
||||
/// Реализация репозитория для операций с базой данных, связанных с миссиями
|
||||
/// </summary>
|
||||
public class MissionRepository : Repository<DbMission>, IMissionRepository
|
||||
public class MissionRepository : IMissionRepository
|
||||
{
|
||||
public MissionRepository(LiquidDbContext dbContext) : base(dbContext)
|
||||
private readonly LiquidDbContext _dbContext;
|
||||
private readonly DbCrud<DbMission> _missionRepository;
|
||||
|
||||
public MissionRepository(LiquidDbContext dbContext)
|
||||
{
|
||||
_dbContext = dbContext;
|
||||
_missionRepository = new DbCrud<DbMission>(dbContext);
|
||||
}
|
||||
|
||||
public async Task<(IEnumerable<DbMission> Missions, bool HasNextPage)> GetMissionsPageAsync(
|
||||
int pageSize, int pageNumber, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (pageSize <= 0 || pageNumber < 0)
|
||||
throw new ArgumentException("Page size must be positive, page number must be non-negative");
|
||||
// IRepository<DbMission> implementation (delegated to _missionRepository)
|
||||
public Task<DbMission?> FindByIdAsync(int id, CancellationToken cancellationToken = default) =>
|
||||
_missionRepository.FindByIdAsync(id, cancellationToken);
|
||||
|
||||
var totalCount = await DbSet.CountAsync(cancellationToken);
|
||||
var hasNextPage = totalCount > pageSize * (pageNumber + 1);
|
||||
public Task<(IEnumerable<DbMission> Items, bool HasNextPage)> GetPageAsync(
|
||||
int pageSize, int pageNumber, CancellationToken cancellationToken = default) =>
|
||||
_missionRepository.GetPageAsync(pageSize, pageNumber, cancellationToken);
|
||||
|
||||
var missions = await DbSet
|
||||
.OrderBy(m => m.Id)
|
||||
.Skip(pageSize * pageNumber)
|
||||
.Take(pageSize)
|
||||
.ToListAsync(cancellationToken);
|
||||
public Task CreateAsync(DbMission entity, CancellationToken cancellationToken = default) =>
|
||||
_missionRepository.CreateAsync(entity, cancellationToken);
|
||||
|
||||
return (missions, hasNextPage);
|
||||
}
|
||||
public Task UpdateAsync(DbMission entity, CancellationToken cancellationToken = default) =>
|
||||
_missionRepository.UpdateAsync(entity, cancellationToken);
|
||||
|
||||
public Task DeleteAsync(DbMission entity, CancellationToken cancellationToken = default) =>
|
||||
_missionRepository.DeleteAsync(entity, cancellationToken);
|
||||
|
||||
public Task SoftDeleteAsync(DbMission entity, CancellationToken cancellationToken = default) =>
|
||||
_missionRepository.SoftDeleteAsync(entity, cancellationToken);
|
||||
|
||||
public Task SaveChangesAsync(CancellationToken cancellationToken = default) =>
|
||||
_missionRepository.SaveChangesAsync(cancellationToken);
|
||||
|
||||
// IMissionRepository specific methods
|
||||
public async Task<IEnumerable<DbMission>> GetMissionsByAuthorAsync(int authorId, CancellationToken cancellationToken = default) =>
|
||||
await DbSet
|
||||
await _dbContext.Set<DbMission>()
|
||||
.Where(m => m.Author.Id == authorId)
|
||||
.OrderByDescending(m => m.CreatedAt)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
public async Task<DbMissionPublicTextData?> GetMissionTextAsync(int missionId, string language, CancellationToken cancellationToken = default) =>
|
||||
await DbContext.MissionsTextData
|
||||
await _dbContext.MissionsTextData
|
||||
.FirstOrDefaultAsync(m => m.MissionId == missionId && m.Language == language, cancellationToken);
|
||||
|
||||
public async Task<IEnumerable<string>> GetMissionLanguagesAsync(int missionId, CancellationToken cancellationToken = default) =>
|
||||
await DbContext.MissionsTextData
|
||||
await _dbContext.MissionsTextData
|
||||
.Where(m => m.MissionId == missionId)
|
||||
.Select(m => m.Language)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
public async Task AddMissionTextAsync(DbMissionPublicTextData textData, CancellationToken cancellationToken = default) =>
|
||||
await DbContext.MissionsTextData.AddAsync(textData, cancellationToken);
|
||||
public async Task CreateMissionTextAsync(DbMissionPublicTextData textData, CancellationToken cancellationToken = default) =>
|
||||
await _dbContext.MissionsTextData.AddAsync(textData, cancellationToken);
|
||||
|
||||
public async Task AddMissionTextsAsync(IEnumerable<DbMissionPublicTextData> textData, CancellationToken cancellationToken = default) =>
|
||||
await DbContext.MissionsTextData.AddRangeAsync(textData, cancellationToken);
|
||||
public async Task CreateMissionTextsAsync(IEnumerable<DbMissionPublicTextData> textData, CancellationToken cancellationToken = default) =>
|
||||
await _dbContext.MissionsTextData.AddRangeAsync(textData, cancellationToken);
|
||||
|
||||
public async Task<int> CountMissionsAsync(CancellationToken cancellationToken = default) =>
|
||||
await DbSet.CountAsync(cancellationToken);
|
||||
await _dbContext.Set<DbMission>().CountAsync(cancellationToken);
|
||||
}
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
using LiquidCode.Domain.Interfaces.Repositories;
|
||||
using LiquidCode.Infrastructure.Database;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace LiquidCode.Infrastructure.Database.Repositories;
|
||||
|
||||
/// <summary>
|
||||
/// Базовая реализация репозитория, предоставляющая общие операции CRUD
|
||||
/// </summary>
|
||||
public class Repository<TEntity> : IRepository<TEntity> where TEntity : class
|
||||
{
|
||||
protected readonly LiquidDbContext DbContext;
|
||||
protected readonly DbSet<TEntity> DbSet;
|
||||
|
||||
public Repository(LiquidDbContext dbContext)
|
||||
{
|
||||
DbContext = dbContext;
|
||||
DbSet = dbContext.Set<TEntity>();
|
||||
}
|
||||
|
||||
public virtual async Task<TEntity?> FindByIdAsync(int id, CancellationToken cancellationToken = default) =>
|
||||
await DbSet.FindAsync(new object?[] { id }, cancellationToken);
|
||||
|
||||
public virtual async Task<IEnumerable<TEntity>> GetAllAsync(CancellationToken cancellationToken = default) =>
|
||||
await DbSet.ToListAsync(cancellationToken);
|
||||
|
||||
public virtual async Task AddAsync(TEntity entity, CancellationToken cancellationToken = default)
|
||||
{
|
||||
await DbSet.AddAsync(entity, cancellationToken);
|
||||
await SaveChangesAsync(cancellationToken);
|
||||
}
|
||||
|
||||
public virtual async Task UpdateAsync(TEntity entity, CancellationToken cancellationToken = default)
|
||||
{
|
||||
DbSet.Update(entity);
|
||||
await SaveChangesAsync(cancellationToken);
|
||||
}
|
||||
|
||||
public virtual async Task RemoveAsync(TEntity entity, CancellationToken cancellationToken = default)
|
||||
{
|
||||
DbSet.Remove(entity);
|
||||
await SaveChangesAsync(cancellationToken);
|
||||
}
|
||||
|
||||
public async Task SaveChangesAsync(CancellationToken cancellationToken = default) =>
|
||||
await DbContext.SaveChangesAsync(cancellationToken);
|
||||
}
|
||||
@@ -8,34 +8,63 @@ namespace LiquidCode.Infrastructure.Database.Repositories;
|
||||
/// <summary>
|
||||
/// Реализация репозитория для операций с базой данных, связанных с отправками пользователей
|
||||
/// </summary>
|
||||
public class SubmitRepository : Repository<DbUserSubmit>, ISubmitRepository
|
||||
public class SubmitRepository : ISubmitRepository
|
||||
{
|
||||
public SubmitRepository(LiquidDbContext dbContext) : base(dbContext)
|
||||
private readonly LiquidDbContext _dbContext;
|
||||
private readonly DbCrud<DbUserSubmit> _submitRepository;
|
||||
|
||||
public SubmitRepository(LiquidDbContext dbContext)
|
||||
{
|
||||
_dbContext = dbContext;
|
||||
_submitRepository = new DbCrud<DbUserSubmit>(dbContext);
|
||||
}
|
||||
|
||||
// IRepository<DbUserSubmit> implementation (delegated to _submitRepository)
|
||||
public Task<DbUserSubmit?> FindByIdAsync(int id, CancellationToken cancellationToken = default) =>
|
||||
_submitRepository.FindByIdAsync(id, cancellationToken);
|
||||
|
||||
public Task<(IEnumerable<DbUserSubmit> Items, bool HasNextPage)> GetPageAsync(
|
||||
int pageSize, int pageNumber, CancellationToken cancellationToken = default) =>
|
||||
_submitRepository.GetPageAsync(pageSize, pageNumber, cancellationToken);
|
||||
|
||||
public Task CreateAsync(DbUserSubmit entity, CancellationToken cancellationToken = default) =>
|
||||
_submitRepository.CreateAsync(entity, cancellationToken);
|
||||
|
||||
public Task UpdateAsync(DbUserSubmit entity, CancellationToken cancellationToken = default) =>
|
||||
_submitRepository.UpdateAsync(entity, cancellationToken);
|
||||
|
||||
public Task DeleteAsync(DbUserSubmit entity, CancellationToken cancellationToken = default) =>
|
||||
_submitRepository.DeleteAsync(entity, cancellationToken);
|
||||
|
||||
public Task SoftDeleteAsync(DbUserSubmit entity, CancellationToken cancellationToken = default) =>
|
||||
_submitRepository.SoftDeleteAsync(entity, cancellationToken);
|
||||
|
||||
public Task SaveChangesAsync(CancellationToken cancellationToken = default) =>
|
||||
_submitRepository.SaveChangesAsync(cancellationToken);
|
||||
|
||||
// ISubmitRepository specific methods
|
||||
public async Task<IEnumerable<DbUserSubmit>> GetSubmissionsByUserAsync(int userId, CancellationToken cancellationToken = default) =>
|
||||
await DbSet
|
||||
await _dbContext.Set<DbUserSubmit>()
|
||||
.Where(s => s.User.Id == userId)
|
||||
.OrderByDescending(s => s.Solution!.Time)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
public async Task<IEnumerable<DbUserSubmit>> GetSubmissionsByMissionAsync(int missionId, CancellationToken cancellationToken = default) =>
|
||||
await DbSet
|
||||
await _dbContext.Set<DbUserSubmit>()
|
||||
.Where(s => s.Solution!.Mission.Id == missionId)
|
||||
.OrderByDescending(s => s.Solution!.Time)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
public async Task<DbUserSubmit?> GetSubmissionWithDetailsAsync(int submissionId, CancellationToken cancellationToken = default) =>
|
||||
await DbSet
|
||||
await _dbContext.Set<DbUserSubmit>()
|
||||
.Include(s => s.User)
|
||||
.Include(s => s.Solution)
|
||||
.FirstOrDefaultAsync(s => s.Id == submissionId, cancellationToken);
|
||||
|
||||
public async Task<DbSolution?> GetSolutionAsync(int solutionId, CancellationToken cancellationToken = default) =>
|
||||
await DbContext.Solutions
|
||||
await _dbContext.Solutions
|
||||
.FirstOrDefaultAsync(s => s.Id == solutionId, cancellationToken);
|
||||
|
||||
public async Task AddSolutionAsync(DbSolution solution, CancellationToken cancellationToken = default) =>
|
||||
await DbContext.Solutions.AddAsync(solution, cancellationToken);
|
||||
await _dbContext.Solutions.AddAsync(solution, cancellationToken);
|
||||
}
|
||||
|
||||
@@ -8,39 +8,68 @@ namespace LiquidCode.Infrastructure.Database.Repositories;
|
||||
/// <summary>
|
||||
/// Реализация репозитория для операций с базой данных, связанных с пользователями
|
||||
/// </summary>
|
||||
public class UserRepository : Repository<DbUser>, IUserRepository
|
||||
public class UserRepository : IUserRepository
|
||||
{
|
||||
public UserRepository(LiquidDbContext dbContext) : base(dbContext)
|
||||
private readonly LiquidDbContext _dbContext;
|
||||
private readonly DbCrud<DbUser> _userRepository;
|
||||
|
||||
public UserRepository(LiquidDbContext dbContext)
|
||||
{
|
||||
_dbContext = dbContext;
|
||||
_userRepository = new DbCrud<DbUser>(dbContext);
|
||||
}
|
||||
|
||||
// IRepository<DbUser> implementation (delegated to _userRepository)
|
||||
public Task<DbUser?> FindByIdAsync(int id, CancellationToken cancellationToken = default) =>
|
||||
_userRepository.FindByIdAsync(id, cancellationToken);
|
||||
|
||||
public Task<(IEnumerable<DbUser> Items, bool HasNextPage)> GetPageAsync(
|
||||
int pageSize, int pageNumber, CancellationToken cancellationToken = default) =>
|
||||
_userRepository.GetPageAsync(pageSize, pageNumber, cancellationToken);
|
||||
|
||||
public Task CreateAsync(DbUser entity, CancellationToken cancellationToken = default) =>
|
||||
_userRepository.CreateAsync(entity, cancellationToken);
|
||||
|
||||
public Task UpdateAsync(DbUser entity, CancellationToken cancellationToken = default) =>
|
||||
_userRepository.UpdateAsync(entity, cancellationToken);
|
||||
|
||||
public Task DeleteAsync(DbUser entity, CancellationToken cancellationToken = default) =>
|
||||
_userRepository.DeleteAsync(entity, cancellationToken);
|
||||
|
||||
public Task SoftDeleteAsync(DbUser entity, CancellationToken cancellationToken = default) =>
|
||||
_userRepository.SoftDeleteAsync(entity, cancellationToken);
|
||||
|
||||
public Task SaveChangesAsync(CancellationToken cancellationToken = default) =>
|
||||
_userRepository.SaveChangesAsync(cancellationToken);
|
||||
|
||||
// IUserRepository specific methods
|
||||
public async Task<DbUser?> FindByUsernameAsync(string username, CancellationToken cancellationToken = default) =>
|
||||
await DbSet.FirstOrDefaultAsync(u => u.Username == username, cancellationToken);
|
||||
await _dbContext.Users.FirstOrDefaultAsync(u => u.Username == username, cancellationToken);
|
||||
|
||||
public async Task<bool> UserExistsAsync(string username, CancellationToken cancellationToken = default) =>
|
||||
await DbSet.AnyAsync(u => u.Username == username, cancellationToken);
|
||||
await _dbContext.Users.AnyAsync(u => u.Username == username, cancellationToken);
|
||||
|
||||
public async Task<int> GetRefreshTokenCountAsync(int userId, CancellationToken cancellationToken = default) =>
|
||||
await DbContext.RefreshTokens.CountAsync(t => t.DbUser.Id == userId, cancellationToken);
|
||||
await _dbContext.RefreshTokens.CountAsync(t => t.DbUser.Id == userId, cancellationToken);
|
||||
|
||||
public async Task<DbRefreshToken?> GetOldestRefreshTokenAsync(int userId, CancellationToken cancellationToken = default) =>
|
||||
await DbContext.RefreshTokens
|
||||
await _dbContext.RefreshTokens
|
||||
.Where(t => t.DbUser.Id == userId)
|
||||
.OrderBy(t => t.Expires)
|
||||
.FirstOrDefaultAsync(cancellationToken);
|
||||
|
||||
public async Task AddRefreshTokenAsync(DbRefreshToken token, CancellationToken cancellationToken = default) =>
|
||||
await DbContext.RefreshTokens.AddAsync(token, cancellationToken);
|
||||
await _dbContext.RefreshTokens.AddAsync(token, cancellationToken);
|
||||
|
||||
public async Task RemoveRefreshTokenAsync(string tokenString, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var token = await DbContext.RefreshTokens.FirstOrDefaultAsync(t => t.Token == tokenString, cancellationToken);
|
||||
var token = await _dbContext.RefreshTokens.FirstOrDefaultAsync(t => t.Token == tokenString, cancellationToken);
|
||||
if (token != null)
|
||||
DbContext.RefreshTokens.Remove(token);
|
||||
_dbContext.RefreshTokens.Remove(token);
|
||||
}
|
||||
|
||||
public async Task<DbRefreshToken?> FindRefreshTokenAsync(string tokenString, CancellationToken cancellationToken = default) =>
|
||||
await DbContext.RefreshTokens
|
||||
await _dbContext.RefreshTokens
|
||||
.Include(t => t.DbUser)
|
||||
.FirstOrDefaultAsync(t => t.Token == tokenString, cancellationToken);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user