From c6e11efdf207b74f13dad7d0d8475b64290ecc23 Mon Sep 17 00:00:00 2001 From: max Date: Mon, 17 Feb 2025 19:58:50 +0100 Subject: [PATCH] [ADD] Added repository implementations --- .../Repositories/AttributeRepository.cs | 103 +++++++++++++++-- .../Repositories/GroupRepository.cs | 105 ++++++++++++++++-- .../Authority/AuthorityAttributeItem.cs | 4 + .../Models/Authority/AuthorityGroupItem.cs | 4 +- .../Repositories/IAttributeRepository.cs | 2 +- .../Repositories/IGroupRepository.cs | 6 +- 6 files changed, 197 insertions(+), 27 deletions(-) diff --git a/DotBased.AspNet.Authority.EFCore/Repositories/AttributeRepository.cs b/DotBased.AspNet.Authority.EFCore/Repositories/AttributeRepository.cs index 438e75d..b986ccc 100644 --- a/DotBased.AspNet.Authority.EFCore/Repositories/AttributeRepository.cs +++ b/DotBased.AspNet.Authority.EFCore/Repositories/AttributeRepository.cs @@ -1,33 +1,114 @@ using DotBased.AspNet.Authority.Models.Authority; using DotBased.AspNet.Authority.Repositories; +using Microsoft.EntityFrameworkCore; namespace DotBased.AspNet.Authority.EFCore.Repositories; -public class AttributeRepository : IAttributeRepository +public class AttributeRepository(IDbContextFactory contextFactory) : RepositoryBase, IAttributeRepository { - public Task> GetAttributesAsync(int limit = 20, int offset = 0, string search = "", + public async Task> GetAttributesAsync(int limit = 20, int offset = 0, string search = "", CancellationToken cancellationToken = default) { - throw new NotImplementedException(); + try + { + await using var context = await contextFactory.CreateDbContextAsync(cancellationToken); + var query = context.Attributes.AsQueryable(); + if (!string.IsNullOrEmpty(search)) + { + query = query.Where(a => $"{a.AttributeKey} {a.BoundId} {a.AttributeValue}".Contains(search, StringComparison.CurrentCultureIgnoreCase)); + } + + var total = await query.CountAsync(cancellationToken); + var select = await query.OrderBy(a => a.AttributeKey).Skip(offset).Take(limit).Select(a => new AuthorityAttributeItem() + { + BoundId = a.BoundId, + AttributeKey = a.AttributeKey, + AttributeValue = a.AttributeValue + }).ToListAsync(cancellationToken); + return ListResult.Ok(select, total, limit, offset); + } + catch (Exception e) + { + return HandleExceptionListResult("Failed to get attributes", e); + } } - public Task> GetAttributeByIdAsync(string id, CancellationToken cancellationToken = default) + public async Task> GetAttributeByKeyAsync(string key, CancellationToken cancellationToken = default) { - throw new NotImplementedException(); + try + { + await using var context = await contextFactory.CreateDbContextAsync(cancellationToken); + var attribute = await context.Attributes.FirstOrDefaultAsync(a => a.AttributeKey == key, cancellationToken); + return attribute == null ? Result.Failed("Attribute not found") : Result.Ok(attribute); + } + catch (Exception e) + { + return HandleExceptionResult("Failed to get attribute by id", e); + } } - public Task> CreateAttributeAsync(AuthorityAttribute attribute, CancellationToken cancellationToken = default) + public async Task> CreateAttributeAsync(AuthorityAttribute attribute, CancellationToken cancellationToken = default) { - throw new NotImplementedException(); + try + { + await using var context = await contextFactory.CreateDbContextAsync(cancellationToken); + if (string.IsNullOrWhiteSpace(attribute.AttributeKey) || attribute.BoundId == Guid.Empty) + { + return Result.Failed("Attribute key and/or bound id is empty"); + } + var entry = context.Attributes.Add(attribute); + var saveResult = await context.SaveChangesAsync(cancellationToken); + return saveResult <= 0 ? Result.Failed("Failed to create attribute") : Result.Ok(entry.Entity); + } + catch (Exception e) + { + return HandleExceptionResult("Failed to create attribute", e); + } } - public Task> UpdateAttributeAsync(AuthorityAttribute attribute, CancellationToken cancellationToken = default) + public async Task> UpdateAttributeAsync(AuthorityAttribute attribute, CancellationToken cancellationToken = default) { - throw new NotImplementedException(); + try + { + await using var context = await contextFactory.CreateDbContextAsync(cancellationToken); + var currentAttribute = await context.Attributes.FirstOrDefaultAsync(a => a.AttributeKey == attribute.AttributeKey, cancellationToken); + if (currentAttribute == null) + { + return Result.Failed("Attribute not found"); + } + + if (currentAttribute.Version != attribute.Version) + { + return Result.Failed("Attribute version doesn't match"); + } + + var entry = context.Attributes.Update(currentAttribute); + var saveResult = await context.SaveChangesAsync(cancellationToken); + return saveResult <= 0 ? Result.Failed("Failed to update attribute") : Result.Ok(entry.Entity); + } + catch (Exception e) + { + return HandleExceptionResult("Failed to update attribute", e); + } } - public Task DeleteAttributeAsync(AuthorityAttribute attribute, CancellationToken cancellationToken = default) + public async Task DeleteAttributeAsync(AuthorityAttribute attribute, CancellationToken cancellationToken = default) { - throw new NotImplementedException(); + try + { + await using var context = await contextFactory.CreateDbContextAsync(cancellationToken); + var currentAttribute = await context.Attributes.FirstOrDefaultAsync(a => a.AttributeKey == attribute.AttributeKey, cancellationToken); + if (currentAttribute == null) + { + return Result.Failed("Attribute not found"); + } + context.Attributes.Remove(currentAttribute); + var saveResult = await context.SaveChangesAsync(cancellationToken); + return saveResult <= 0 ? Result.Failed("Failed to delete attribute") : Result.Ok(); + } + catch (Exception e) + { + return HandleException("Failed to delete attribute", e); + } } } \ No newline at end of file diff --git a/DotBased.AspNet.Authority.EFCore/Repositories/GroupRepository.cs b/DotBased.AspNet.Authority.EFCore/Repositories/GroupRepository.cs index a6fb010..212ed61 100644 --- a/DotBased.AspNet.Authority.EFCore/Repositories/GroupRepository.cs +++ b/DotBased.AspNet.Authority.EFCore/Repositories/GroupRepository.cs @@ -1,32 +1,115 @@ using DotBased.AspNet.Authority.Models.Authority; using DotBased.AspNet.Authority.Repositories; +using Microsoft.EntityFrameworkCore; namespace DotBased.AspNet.Authority.EFCore.Repositories; -public class GroupRepository : IGroupRepository +public class GroupRepository(IDbContextFactory contextFactory) : RepositoryBase, IGroupRepository { - public Task> GetGroupsAsync(int limit = 20, int offset = 0, string search = "", CancellationToken cancellationToken = default) + public async Task> GetGroupsAsync(int limit = 20, int offset = 0, string search = "", CancellationToken cancellationToken = default) { - throw new NotImplementedException(); + try + { + await using var context = await contextFactory.CreateDbContextAsync(cancellationToken); + var query = context.Groups.AsQueryable(); + if (!string.IsNullOrWhiteSpace(search)) + { + query = query.Where(g => $"{g.Name} {g.Id}".Contains(search)); + } + var total = await query.CountAsync(cancellationToken); + var select = await query.OrderBy(g => g.Name).Skip(offset).Take(limit).Select(g => new AuthorityGroupItem() + { + Id = g.Id, + Name = g.Name + }).ToListAsync(cancellationToken); + return ListResult.Ok(select, total, limit, offset); + } + catch (Exception e) + { + return HandleExceptionListResult("Failed to get Groups", e); + } } - public Task> GetGroupByIdAsync(string id, CancellationToken cancellationToken = default) + public async Task> GetGroupByIdAsync(string id, CancellationToken cancellationToken = default) { - throw new NotImplementedException(); + try + { + await using var context = await contextFactory.CreateDbContextAsync(cancellationToken); + if (!Guid.TryParse(id, out var groupId)) + { + return Result.Failed("Invalid group id"); + } + var group = await context.Groups.Where(g => g.Id == groupId).Include(g => g.Attributes).FirstOrDefaultAsync(cancellationToken: cancellationToken); + return Result.HandleResult(group, "Group not found"); + } + catch (Exception e) + { + return HandleExceptionResult("Failed to get Group", e); + } } - public Task> CreateGroupAsync(AuthorityGroup group, CancellationToken cancellationToken = default) + public async Task> CreateGroupAsync(AuthorityGroup group, CancellationToken cancellationToken = default) { - throw new NotImplementedException(); + try + { + await using var context = await contextFactory.CreateDbContextAsync(cancellationToken); + if (group.Id == Guid.Empty) + { + return Result.Failed("Id cannot be empty."); + } + var entry = context.Groups.Add(group); + var saveResult = await context.SaveChangesAsync(cancellationToken); + return saveResult <= 0 ? Result.Failed("Failed to create group.") : Result.Ok(entry.Entity); + } + catch (Exception e) + { + return HandleExceptionResult("Failed to create group!", e); + } } - public Task> UpdateGroupAsync(AuthorityGroup group, CancellationToken cancellationToken = default) + public async Task> UpdateGroupAsync(AuthorityGroup group, CancellationToken cancellationToken = default) { - throw new NotImplementedException(); + try + { + await using var context = await contextFactory.CreateDbContextAsync(cancellationToken); + var currentGroup = await context.Groups.FirstOrDefaultAsync(g => g.Id == group.Id ,cancellationToken); + if (currentGroup == null) + { + return Result.Failed("Group not found."); + } + + if (currentGroup.Version != group.Version) + { + return Result.Failed("Group version does not match, version validation failed!"); + } + + var entry = context.Groups.Update(group); + var saveResult = await context.SaveChangesAsync(cancellationToken); + return saveResult <= 0 ? Result.Failed("Failed to update group.") : Result.Ok(entry.Entity); + } + catch (Exception e) + { + return HandleExceptionResult("Failed to update group!", e); + } } - public Task DeleteGroupAsync(AuthorityGroup group, CancellationToken cancellationToken = default) + public async Task DeleteGroupAsync(AuthorityGroup group, CancellationToken cancellationToken = default) { - throw new NotImplementedException(); + try + { + await using var context = await contextFactory.CreateDbContextAsync(cancellationToken); + var currentGroup = await context.Groups.FirstOrDefaultAsync(g => g.Id == group.Id, cancellationToken); + if (currentGroup == null) + { + return Result.Failed("Group not found, cannot delete group!"); + } + context.Groups.Remove(currentGroup); + var saveResult = await context.SaveChangesAsync(cancellationToken); + return saveResult <= 0 ? Result.Failed("Failed to delete group.") : Result.Ok(); + } + catch (Exception e) + { + return HandleException("Failed to delete group!", e); + } } } \ No newline at end of file diff --git a/DotBased.AspNet.Authority/Models/Authority/AuthorityAttributeItem.cs b/DotBased.AspNet.Authority/Models/Authority/AuthorityAttributeItem.cs index 44a0211..aa802bf 100644 --- a/DotBased.AspNet.Authority/Models/Authority/AuthorityAttributeItem.cs +++ b/DotBased.AspNet.Authority/Models/Authority/AuthorityAttributeItem.cs @@ -2,5 +2,9 @@ namespace DotBased.AspNet.Authority.Models.Authority; public class AuthorityAttributeItem { + public Guid BoundId { get; set; } + public string AttributeKey { get; set; } = string.Empty; + + public string AttributeValue { get; set; } = string.Empty; } \ No newline at end of file diff --git a/DotBased.AspNet.Authority/Models/Authority/AuthorityGroupItem.cs b/DotBased.AspNet.Authority/Models/Authority/AuthorityGroupItem.cs index 2b9bbcc..f9cbecb 100644 --- a/DotBased.AspNet.Authority/Models/Authority/AuthorityGroupItem.cs +++ b/DotBased.AspNet.Authority/Models/Authority/AuthorityGroupItem.cs @@ -2,5 +2,7 @@ namespace DotBased.AspNet.Authority.Models.Authority; public class AuthorityGroupItem { - + public Guid Id { get; set; } = Guid.NewGuid(); + + public string? Name { get; set; } } \ No newline at end of file diff --git a/DotBased.AspNet.Authority/Repositories/IAttributeRepository.cs b/DotBased.AspNet.Authority/Repositories/IAttributeRepository.cs index 7fcca43..bf045f6 100755 --- a/DotBased.AspNet.Authority/Repositories/IAttributeRepository.cs +++ b/DotBased.AspNet.Authority/Repositories/IAttributeRepository.cs @@ -5,7 +5,7 @@ namespace DotBased.AspNet.Authority.Repositories; public interface IAttributeRepository { public Task> GetAttributesAsync(int limit = 20, int offset = 0, string search = "", CancellationToken cancellationToken = default); - public Task> GetAttributeByIdAsync(string id, CancellationToken cancellationToken = default); + public Task> GetAttributeByKeyAsync(string id, CancellationToken cancellationToken = default); public Task> CreateAttributeAsync(AuthorityAttribute attribute, CancellationToken cancellationToken = default); public Task> UpdateAttributeAsync(AuthorityAttribute attribute, CancellationToken cancellationToken = default); public Task DeleteAttributeAsync(AuthorityAttribute attribute, CancellationToken cancellationToken = default); diff --git a/DotBased.AspNet.Authority/Repositories/IGroupRepository.cs b/DotBased.AspNet.Authority/Repositories/IGroupRepository.cs index f8eb385..3e8e814 100755 --- a/DotBased.AspNet.Authority/Repositories/IGroupRepository.cs +++ b/DotBased.AspNet.Authority/Repositories/IGroupRepository.cs @@ -5,8 +5,8 @@ namespace DotBased.AspNet.Authority.Repositories; public interface IGroupRepository { public Task> GetGroupsAsync(int limit = 20, int offset = 0, string search = "", CancellationToken cancellationToken = default); - public Task> GetGroupByIdAsync(string id, CancellationToken cancellationToken = default); - public Task> CreateGroupAsync(AuthorityGroup group, CancellationToken cancellationToken = default); - public Task> UpdateGroupAsync(AuthorityGroup group, CancellationToken cancellationToken = default); + public Task> GetGroupByIdAsync(string id, CancellationToken cancellationToken = default); + public Task> CreateGroupAsync(AuthorityGroup group, CancellationToken cancellationToken = default); + public Task> UpdateGroupAsync(AuthorityGroup group, CancellationToken cancellationToken = default); public Task DeleteGroupAsync(AuthorityGroup group, CancellationToken cancellationToken = default); } \ No newline at end of file