add city entity management
This commit is contained in:
parent
16457fc2cc
commit
0345f58f7b
39
src/Application/Cities/CityDto.cs
Normal file
39
src/Application/Cities/CityDto.cs
Normal file
@ -0,0 +1,39 @@
|
||||
using cuqmbr.TravelGuide.Application.Common.Mappings;
|
||||
using cuqmbr.TravelGuide.Domain.Entities;
|
||||
|
||||
namespace cuqmbr.TravelGuide.Application.Cities;
|
||||
|
||||
public sealed class CityDto : IMapFrom<City>
|
||||
{
|
||||
public Guid Uuid { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
public Guid CountryUuid { get; set; }
|
||||
|
||||
public string CountryName { get; set; }
|
||||
|
||||
public Guid RegionUuid { get; set; }
|
||||
|
||||
public string RegionName { get; set; }
|
||||
|
||||
public void Mapping(MappingProfile profile)
|
||||
{
|
||||
profile.CreateMap<City, CityDto>()
|
||||
.ForMember(
|
||||
d => d.Uuid,
|
||||
opt => opt.MapFrom(s => s.Guid))
|
||||
.ForMember(
|
||||
d => d.CountryUuid,
|
||||
opt => opt.MapFrom(s => s.Region.Country.Guid))
|
||||
.ForMember(
|
||||
d => d.CountryName,
|
||||
opt => opt.MapFrom(s => s.Region.Country.Name))
|
||||
.ForMember(
|
||||
d => d.RegionUuid,
|
||||
opt => opt.MapFrom(s => s.Region.Guid))
|
||||
.ForMember(
|
||||
d => d.RegionName,
|
||||
opt => opt.MapFrom(s => s.Region.Name));
|
||||
}
|
||||
}
|
10
src/Application/Cities/Commands/AddCity/AddCityCommand.cs
Normal file
10
src/Application/Cities/Commands/AddCity/AddCityCommand.cs
Normal file
@ -0,0 +1,10 @@
|
||||
using MediatR;
|
||||
|
||||
namespace cuqmbr.TravelGuide.Application.Cities.Commands.AddCity;
|
||||
|
||||
public record AddCityCommand : IRequest<CityDto>
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
||||
public Guid RegionUuid { get; set; }
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
using cuqmbr.TravelGuide.Application.Common.Authorization;
|
||||
using cuqmbr.TravelGuide.Application.Common.Interfaces.Services;
|
||||
using cuqmbr.TravelGuide.Application.Common.Models;
|
||||
using MediatR.Behaviors.Authorization;
|
||||
|
||||
namespace cuqmbr.TravelGuide.Application.Cities.Commands.AddCity;
|
||||
|
||||
public class AddCityCommandAuthorizer :
|
||||
AbstractRequestAuthorizer<AddCityCommand>
|
||||
{
|
||||
private readonly SessionUserService _sessionUserService;
|
||||
|
||||
public AddCityCommandAuthorizer(SessionUserService sessionUserService)
|
||||
{
|
||||
_sessionUserService = sessionUserService;
|
||||
}
|
||||
|
||||
public override void BuildPolicy(AddCityCommand request)
|
||||
{
|
||||
UseRequirement(new MustBeAuthenticatedRequirement
|
||||
{
|
||||
IsAuthenticated= _sessionUserService.IsAuthenticated
|
||||
});
|
||||
|
||||
UseRequirement(new MustBeInRolesRequirement
|
||||
{
|
||||
RequiredRoles = [IdentityRole.Administrator],
|
||||
UserRoles = _sessionUserService.Roles
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
using MediatR;
|
||||
using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence;
|
||||
using cuqmbr.TravelGuide.Domain.Entities;
|
||||
using AutoMapper;
|
||||
using cuqmbr.TravelGuide.Application.Common.Exceptions;
|
||||
|
||||
namespace cuqmbr.TravelGuide.Application.Cities.Commands.AddCity;
|
||||
|
||||
public class AddCityCommandHandler :
|
||||
IRequestHandler<AddCityCommand, CityDto>
|
||||
{
|
||||
private readonly UnitOfWork _unitOfWork;
|
||||
private readonly IMapper _mapper;
|
||||
|
||||
public AddCityCommandHandler(
|
||||
UnitOfWork unitOfWork,
|
||||
IMapper mapper)
|
||||
{
|
||||
_unitOfWork = unitOfWork;
|
||||
_mapper = mapper;
|
||||
}
|
||||
|
||||
public async Task<CityDto> Handle(
|
||||
AddCityCommand request,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var entity = await _unitOfWork.CityRepository.GetOneAsync(
|
||||
e => e.Name == request.Name && e.Region.Guid == request.RegionUuid,
|
||||
cancellationToken);
|
||||
|
||||
if (entity != null)
|
||||
{
|
||||
throw new DuplicateEntityException(
|
||||
"City with given name already exists.");
|
||||
}
|
||||
|
||||
var parentEntity = await _unitOfWork.RegionRepository.GetOneAsync(
|
||||
e => e.Guid == request.RegionUuid, e => e.Country,
|
||||
cancellationToken);
|
||||
|
||||
if (parentEntity == null)
|
||||
{
|
||||
throw new NotFoundException(
|
||||
$"Parent entity with Guid: {request.RegionUuid} not found.");
|
||||
}
|
||||
|
||||
entity = new City()
|
||||
{
|
||||
Name = request.Name,
|
||||
RegionId = parentEntity.Id
|
||||
};
|
||||
|
||||
entity = await _unitOfWork.CityRepository.AddOneAsync(
|
||||
entity, cancellationToken);
|
||||
|
||||
await _unitOfWork.SaveAsync(cancellationToken);
|
||||
_unitOfWork.Dispose();
|
||||
|
||||
return _mapper.Map<CityDto>(entity);
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
using cuqmbr.TravelGuide.Application.Common.Interfaces.Services;
|
||||
using FluentValidation;
|
||||
using Microsoft.Extensions.Localization;
|
||||
|
||||
namespace cuqmbr.TravelGuide.Application.Cities.Commands.AddCity;
|
||||
|
||||
public class AddCityCommandValidator : AbstractValidator<AddCityCommand>
|
||||
{
|
||||
public AddCityCommandValidator(
|
||||
IStringLocalizer localizer,
|
||||
CultureService cultureService)
|
||||
{
|
||||
RuleFor(v => v.Name)
|
||||
.NotEmpty()
|
||||
.WithMessage(localizer["FluentValidation.NotEmpty"])
|
||||
.MaximumLength(64)
|
||||
.WithMessage(
|
||||
String.Format(
|
||||
cultureService.Culture,
|
||||
localizer["FluentValidation.MaximumLength"],
|
||||
64));
|
||||
|
||||
RuleFor(v => v.RegionUuid)
|
||||
.NotEmpty()
|
||||
.WithMessage(localizer["FluentValidation.NotEmpty"]);
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
using MediatR;
|
||||
|
||||
namespace cuqmbr.TravelGuide.Application.Cities.Commands.DeleteCity;
|
||||
|
||||
public record DeleteCityCommand : IRequest
|
||||
{
|
||||
public Guid Uuid { get; set; }
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
using cuqmbr.TravelGuide.Application.Common.Authorization;
|
||||
using cuqmbr.TravelGuide.Application.Common.Interfaces.Services;
|
||||
using cuqmbr.TravelGuide.Application.Common.Models;
|
||||
using MediatR.Behaviors.Authorization;
|
||||
|
||||
namespace cuqmbr.TravelGuide.Application.Cities.Commands.DeleteCity;
|
||||
|
||||
public class DeleteCityCommandAuthorizer :
|
||||
AbstractRequestAuthorizer<DeleteCityCommand>
|
||||
{
|
||||
private readonly SessionUserService _sessionUserService;
|
||||
|
||||
public DeleteCityCommandAuthorizer(SessionUserService sessionUserService)
|
||||
{
|
||||
_sessionUserService = sessionUserService;
|
||||
}
|
||||
|
||||
public override void BuildPolicy(DeleteCityCommand request)
|
||||
{
|
||||
UseRequirement(new MustBeAuthenticatedRequirement
|
||||
{
|
||||
IsAuthenticated= _sessionUserService.IsAuthenticated
|
||||
});
|
||||
|
||||
UseRequirement(new MustBeInRolesRequirement
|
||||
{
|
||||
RequiredRoles = [IdentityRole.Administrator],
|
||||
UserRoles = _sessionUserService.Roles
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
using MediatR;
|
||||
using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence;
|
||||
using cuqmbr.TravelGuide.Application.Common.Exceptions;
|
||||
|
||||
namespace cuqmbr.TravelGuide.Application.Cities.Commands.DeleteCity;
|
||||
|
||||
public class DeleteCityCommandHandler : IRequestHandler<DeleteCityCommand>
|
||||
{
|
||||
private readonly UnitOfWork _unitOfWork;
|
||||
|
||||
public DeleteCityCommandHandler(UnitOfWork unitOfWork)
|
||||
{
|
||||
_unitOfWork = unitOfWork;
|
||||
}
|
||||
|
||||
public async Task Handle(
|
||||
DeleteCityCommand request,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var entity = await _unitOfWork.CityRepository.GetOneAsync(
|
||||
e => e.Guid == request.Uuid, cancellationToken);
|
||||
|
||||
if (entity == null)
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
await _unitOfWork.CityRepository.DeleteOneAsync(
|
||||
entity, cancellationToken);
|
||||
|
||||
await _unitOfWork.SaveAsync(cancellationToken);
|
||||
_unitOfWork.Dispose();
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
using FluentValidation;
|
||||
using Microsoft.Extensions.Localization;
|
||||
|
||||
namespace cuqmbr.TravelGuide.Application.Cities.Commands.DeleteCity;
|
||||
|
||||
public class DeleteCityCommandValidator : AbstractValidator<DeleteCityCommand>
|
||||
{
|
||||
public DeleteCityCommandValidator(IStringLocalizer localizer)
|
||||
{
|
||||
RuleFor(v => v.Uuid)
|
||||
.NotEmpty()
|
||||
.WithMessage(localizer["FluentValidation.NotEmpty"]);
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
using MediatR;
|
||||
|
||||
namespace cuqmbr.TravelGuide.Application.Cities.Commands.UpdateCity;
|
||||
|
||||
public record UpdateCityCommand : IRequest<CityDto>
|
||||
{
|
||||
public Guid Uuid { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
public Guid RegionUuid { get; set; }
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
using cuqmbr.TravelGuide.Application.Common.Authorization;
|
||||
using cuqmbr.TravelGuide.Application.Common.Interfaces.Services;
|
||||
using cuqmbr.TravelGuide.Application.Common.Models;
|
||||
using MediatR.Behaviors.Authorization;
|
||||
|
||||
namespace cuqmbr.TravelGuide.Application.Cities.Commands.UpdateCity;
|
||||
|
||||
public class UpdateCityCommandAuthorizer :
|
||||
AbstractRequestAuthorizer<UpdateCityCommand>
|
||||
{
|
||||
private readonly SessionUserService _sessionUserService;
|
||||
|
||||
public UpdateCityCommandAuthorizer(SessionUserService sessionUserService)
|
||||
{
|
||||
_sessionUserService = sessionUserService;
|
||||
}
|
||||
|
||||
public override void BuildPolicy(UpdateCityCommand request)
|
||||
{
|
||||
UseRequirement(new MustBeAuthenticatedRequirement
|
||||
{
|
||||
IsAuthenticated= _sessionUserService.IsAuthenticated
|
||||
});
|
||||
|
||||
UseRequirement(new MustBeInRolesRequirement
|
||||
{
|
||||
RequiredRoles = [IdentityRole.Administrator],
|
||||
UserRoles = _sessionUserService.Roles
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
using MediatR;
|
||||
using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence;
|
||||
using AutoMapper;
|
||||
using cuqmbr.TravelGuide.Application.Common.Exceptions;
|
||||
|
||||
namespace cuqmbr.TravelGuide.Application.Cities.Commands.UpdateCity;
|
||||
|
||||
public class UpdateCityCommandHandler :
|
||||
IRequestHandler<UpdateCityCommand, CityDto>
|
||||
{
|
||||
private readonly UnitOfWork _unitOfWork;
|
||||
private readonly IMapper _mapper;
|
||||
|
||||
public UpdateCityCommandHandler(
|
||||
UnitOfWork unitOfWork,
|
||||
IMapper mapper)
|
||||
{
|
||||
_unitOfWork = unitOfWork;
|
||||
_mapper = mapper;
|
||||
}
|
||||
|
||||
public async Task<CityDto> Handle(
|
||||
UpdateCityCommand request,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var entity = await _unitOfWork.CityRepository.GetOneAsync(
|
||||
e => e.Guid == request.Uuid, e => e.Region.Country,
|
||||
cancellationToken);
|
||||
|
||||
if (entity == null)
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
var parentEntity = await _unitOfWork.RegionRepository.GetOneAsync(
|
||||
e => e.Guid == request.RegionUuid, cancellationToken);
|
||||
|
||||
if (parentEntity == null)
|
||||
{
|
||||
throw new NotFoundException(
|
||||
$"Parent entity with Guid: {request.RegionUuid} not found.");
|
||||
}
|
||||
|
||||
entity.Name = request.Name;
|
||||
entity.RegionId = parentEntity.Id;
|
||||
|
||||
entity = await _unitOfWork.CityRepository.UpdateOneAsync(
|
||||
entity, cancellationToken);
|
||||
|
||||
await _unitOfWork.SaveAsync(cancellationToken);
|
||||
_unitOfWork.Dispose();
|
||||
|
||||
return _mapper.Map<CityDto>(entity);
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
using cuqmbr.TravelGuide.Application.Common.Interfaces.Services;
|
||||
using FluentValidation;
|
||||
using Microsoft.Extensions.Localization;
|
||||
|
||||
namespace cuqmbr.TravelGuide.Application.Cities.Commands.UpdateCity;
|
||||
|
||||
public class UpdateCityCommandValidator : AbstractValidator<UpdateCityCommand>
|
||||
{
|
||||
public UpdateCityCommandValidator(
|
||||
IStringLocalizer localizer,
|
||||
CultureService cultureService)
|
||||
{
|
||||
RuleFor(v => v.Uuid)
|
||||
.NotEmpty()
|
||||
.WithMessage(localizer["FluentValidation.NotEmpty"]);
|
||||
|
||||
RuleFor(v => v.Name)
|
||||
.NotEmpty()
|
||||
.WithMessage(localizer["FluentValidation.NotEmpty"])
|
||||
.MaximumLength(64)
|
||||
.WithMessage(
|
||||
String.Format(
|
||||
cultureService.Culture,
|
||||
localizer["FluentValidation.MaximumLength"],
|
||||
64));
|
||||
|
||||
RuleFor(v => v.RegionUuid)
|
||||
.NotEmpty()
|
||||
.WithMessage(localizer["FluentValidation.NotEmpty"]);
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
using cuqmbr.TravelGuide.Application.Common.Models;
|
||||
using MediatR;
|
||||
|
||||
namespace cuqmbr.TravelGuide.Application.Cities.Queries.GetCitiesPage;
|
||||
|
||||
public record GetCitiesPageQuery : IRequest<PaginatedList<CityDto>>
|
||||
{
|
||||
public int PageNumber { get; set; } = 1;
|
||||
|
||||
public int PageSize { get; set; } = 10;
|
||||
|
||||
public string Search { get; set; } = String.Empty;
|
||||
|
||||
public string Sort { get; set; } = String.Empty;
|
||||
|
||||
public Guid? CountryUuid { get; set; }
|
||||
|
||||
public Guid? RegionUuid { get; set; }
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
using cuqmbr.TravelGuide.Application.Common.Authorization;
|
||||
using cuqmbr.TravelGuide.Application.Common.Interfaces.Services;
|
||||
using cuqmbr.TravelGuide.Application.Common.Models;
|
||||
using MediatR.Behaviors.Authorization;
|
||||
|
||||
namespace cuqmbr.TravelGuide.Application.Cities.Queries.GetCitiesPage;
|
||||
|
||||
public class GetCitiesPageQueryAuthorizer :
|
||||
AbstractRequestAuthorizer<GetCitiesPageQuery>
|
||||
{
|
||||
private readonly SessionUserService _sessionUserService;
|
||||
|
||||
public GetCitiesPageQueryAuthorizer(SessionUserService sessionUserService)
|
||||
{
|
||||
_sessionUserService = sessionUserService;
|
||||
}
|
||||
|
||||
public override void BuildPolicy(GetCitiesPageQuery request)
|
||||
{
|
||||
UseRequirement(new MustBeAuthenticatedRequirement
|
||||
{
|
||||
IsAuthenticated= _sessionUserService.IsAuthenticated
|
||||
});
|
||||
|
||||
UseRequirement(new MustBeInRolesRequirement
|
||||
{
|
||||
RequiredRoles = [IdentityRole.Administrator],
|
||||
UserRoles = _sessionUserService.Roles
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
using MediatR;
|
||||
using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence;
|
||||
using AutoMapper;
|
||||
using cuqmbr.TravelGuide.Application.Common.Models;
|
||||
using cuqmbr.TravelGuide.Application.Common.Extensions;
|
||||
|
||||
namespace cuqmbr.TravelGuide.Application.Cities.Queries.GetCitiesPage;
|
||||
|
||||
public class GetCitiesPageQueryHandler :
|
||||
IRequestHandler<GetCitiesPageQuery, PaginatedList<CityDto>>
|
||||
{
|
||||
private readonly UnitOfWork _unitOfWork;
|
||||
private readonly IMapper _mapper;
|
||||
|
||||
public GetCitiesPageQueryHandler(
|
||||
UnitOfWork unitOfWork,
|
||||
IMapper mapper)
|
||||
{
|
||||
_unitOfWork = unitOfWork;
|
||||
_mapper = mapper;
|
||||
}
|
||||
|
||||
public async Task<PaginatedList<CityDto>> Handle(
|
||||
GetCitiesPageQuery request,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var paginatedList = await _unitOfWork.CityRepository.GetPageAsync(
|
||||
e =>
|
||||
(e.Name.ToLower().Contains(request.Search.ToLower()) ||
|
||||
e.Region.Name.ToLower().Contains(request.Search.ToLower()) ||
|
||||
e.Region.Country.Name.ToLower().Contains(request.Search.ToLower())) &&
|
||||
(request.RegionUuid != null
|
||||
? e.Region.Guid == request.RegionUuid
|
||||
: true) &&
|
||||
(request.CountryUuid != null
|
||||
? e.Region.Country.Guid == request.CountryUuid
|
||||
: true),
|
||||
e => e.Region.Country,
|
||||
request.PageNumber, request.PageSize,
|
||||
cancellationToken);
|
||||
|
||||
var mappedItems = _mapper
|
||||
.ProjectTo<CityDto>(paginatedList.Items.AsQueryable());
|
||||
|
||||
mappedItems = QueryableExtension<CityDto>
|
||||
.ApplySort(mappedItems, request.Sort);
|
||||
|
||||
_unitOfWork.Dispose();
|
||||
|
||||
return new PaginatedList<CityDto>(
|
||||
mappedItems.ToList(),
|
||||
paginatedList.TotalCount, request.PageNumber,
|
||||
request.PageSize);
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
using cuqmbr.TravelGuide.Application.Common.Interfaces.Services;
|
||||
using FluentValidation;
|
||||
using Microsoft.Extensions.Localization;
|
||||
|
||||
namespace cuqmbr.TravelGuide.Application.Cities.Queries.GetCitiesPage;
|
||||
|
||||
public class GetCitiesPageQueryValidator : AbstractValidator<GetCitiesPageQuery>
|
||||
{
|
||||
public GetCitiesPageQueryValidator(
|
||||
IStringLocalizer localizer,
|
||||
CultureService cultureService)
|
||||
{
|
||||
RuleFor(v => v.PageNumber)
|
||||
.GreaterThanOrEqualTo(1)
|
||||
.WithMessage(
|
||||
String.Format(
|
||||
cultureService.Culture,
|
||||
localizer["FluentValidation.GreaterThanOrEqualTo"],
|
||||
1));
|
||||
|
||||
RuleFor(v => v.PageSize)
|
||||
.GreaterThanOrEqualTo(1)
|
||||
.WithMessage(
|
||||
String.Format(
|
||||
cultureService.Culture,
|
||||
localizer["FluentValidation.GreaterThanOrEqualTo"],
|
||||
1))
|
||||
.LessThanOrEqualTo(50)
|
||||
.WithMessage(
|
||||
String.Format(
|
||||
cultureService.Culture,
|
||||
localizer["FluentValidation.LessThanOrEqualTo"],
|
||||
50));
|
||||
|
||||
RuleFor(v => v.Search)
|
||||
.MaximumLength(64)
|
||||
.WithMessage(
|
||||
String.Format(
|
||||
cultureService.Culture,
|
||||
localizer["FluentValidation.MaximumLength"],
|
||||
64));
|
||||
}
|
||||
}
|
8
src/Application/Cities/Queries/GetCity/GetCityQuery.cs
Normal file
8
src/Application/Cities/Queries/GetCity/GetCityQuery.cs
Normal file
@ -0,0 +1,8 @@
|
||||
using MediatR;
|
||||
|
||||
namespace cuqmbr.TravelGuide.Application.Cities.Queries.GetCity;
|
||||
|
||||
public record GetCityQuery : IRequest<CityDto>
|
||||
{
|
||||
public Guid Uuid { get; set; }
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
using cuqmbr.TravelGuide.Application.Common.Authorization;
|
||||
using cuqmbr.TravelGuide.Application.Common.Interfaces.Services;
|
||||
using cuqmbr.TravelGuide.Application.Common.Models;
|
||||
using MediatR.Behaviors.Authorization;
|
||||
|
||||
namespace cuqmbr.TravelGuide.Application.Cities.Queries.GetCity;
|
||||
|
||||
public class GetCityQueryAuthorizer :
|
||||
AbstractRequestAuthorizer<GetCityQuery>
|
||||
{
|
||||
private readonly SessionUserService _sessionUserService;
|
||||
|
||||
public GetCityQueryAuthorizer(SessionUserService sessionUserService)
|
||||
{
|
||||
_sessionUserService = sessionUserService;
|
||||
}
|
||||
|
||||
public override void BuildPolicy(GetCityQuery request)
|
||||
{
|
||||
UseRequirement(new MustBeAuthenticatedRequirement
|
||||
{
|
||||
IsAuthenticated= _sessionUserService.IsAuthenticated
|
||||
});
|
||||
|
||||
UseRequirement(new MustBeInRolesRequirement
|
||||
{
|
||||
RequiredRoles = [IdentityRole.Administrator],
|
||||
UserRoles = _sessionUserService.Roles
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
using MediatR;
|
||||
using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence;
|
||||
using cuqmbr.TravelGuide.Application.Common.Exceptions;
|
||||
using AutoMapper;
|
||||
|
||||
namespace cuqmbr.TravelGuide.Application.Cities.Queries.GetCity;
|
||||
|
||||
public class GetCityQueryHandler :
|
||||
IRequestHandler<GetCityQuery, CityDto>
|
||||
{
|
||||
private readonly UnitOfWork _unitOfWork;
|
||||
private readonly IMapper _mapper;
|
||||
|
||||
public GetCityQueryHandler(
|
||||
UnitOfWork unitOfWork,
|
||||
IMapper mapper)
|
||||
{
|
||||
_unitOfWork = unitOfWork;
|
||||
_mapper = mapper;
|
||||
}
|
||||
|
||||
public async Task<CityDto> Handle(
|
||||
GetCityQuery request,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var entity = await _unitOfWork.CityRepository.GetOneAsync(
|
||||
e => e.Guid == request.Uuid, e => e.Region.Country,
|
||||
cancellationToken);
|
||||
|
||||
_unitOfWork.Dispose();
|
||||
|
||||
if (entity == null)
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
return _mapper.Map<CityDto>(entity);
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
using FluentValidation;
|
||||
using Microsoft.Extensions.Localization;
|
||||
|
||||
namespace cuqmbr.TravelGuide.Application.Cities.Queries.GetCity;
|
||||
|
||||
public class GetCityQueryValidator : AbstractValidator<GetCityQuery>
|
||||
{
|
||||
public GetCityQueryValidator(IStringLocalizer localizer)
|
||||
{
|
||||
RuleFor(v => v.Uuid)
|
||||
.NotEmpty()
|
||||
.WithMessage(localizer["FluentValidation.NotEmpty"]);
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
namespace cuqmbr.TravelGuide.Application.Cities.ViewModels;
|
||||
|
||||
public sealed class GetCitiesPageFilterViewModel
|
||||
{
|
||||
public Guid? CountryUuid { get; set; }
|
||||
|
||||
public Guid? RegionUuid { get; set; }
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
using cuqmbr.TravelGuide.Domain.Entities;
|
||||
|
||||
namespace cuqmbr.TravelGuide.Application.Common.Interfaces
|
||||
.Persistence.Repositories;
|
||||
|
||||
public interface CityRepository : BaseRepository<City> { }
|
@ -5,8 +5,12 @@ namespace cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence;
|
||||
public interface UnitOfWork : IDisposable
|
||||
{
|
||||
CountryRepository CountryRepository { get; }
|
||||
|
||||
RegionRepository RegionRepository { get; }
|
||||
|
||||
CityRepository CityRepository { get; }
|
||||
|
||||
int Save();
|
||||
|
||||
Task<int> SaveAsync(CancellationToken cancellationToken);
|
||||
}
|
||||
|
@ -72,9 +72,12 @@ public static class Configuration
|
||||
$"{configuration.Type} datastore is not supported.");
|
||||
}
|
||||
|
||||
// using var serviceProvider = services.BuildServiceProvider();
|
||||
// var unitOfWork = serviceProvider.GetService<UnitOfWork>();
|
||||
// DbSeeder.Seed(unitOfWork);
|
||||
if (configuration.Seed)
|
||||
{
|
||||
using var serviceProvider = services.BuildServiceProvider();
|
||||
var unitOfWork = serviceProvider.GetService<UnitOfWork>();
|
||||
DbSeeder.Seed(unitOfWork);
|
||||
}
|
||||
|
||||
return services;
|
||||
}
|
||||
|
176
src/HttpApi/Controllers/CitiesController.cs
Normal file
176
src/HttpApi/Controllers/CitiesController.cs
Normal file
@ -0,0 +1,176 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Swashbuckle.AspNetCore.Annotations;
|
||||
using cuqmbr.TravelGuide.Application.Common.Models;
|
||||
using cuqmbr.TravelGuide.Application.Common.ViewModels;
|
||||
using cuqmbr.TravelGuide.Application.Cities;
|
||||
using cuqmbr.TravelGuide.Application.Cities.Commands.AddCity;
|
||||
using cuqmbr.TravelGuide.Application.Cities.Queries.GetCitiesPage;
|
||||
using cuqmbr.TravelGuide.Application.Cities.Queries.GetCity;
|
||||
using cuqmbr.TravelGuide.Application.Cities.Commands.UpdateCity;
|
||||
using cuqmbr.TravelGuide.Application.Cities.Commands.DeleteCity;
|
||||
using cuqmbr.TravelGuide.Application.Cities.ViewModels;
|
||||
|
||||
namespace cuqmbr.TravelGuide.HttpApi.Controllers;
|
||||
|
||||
[Route("cities")]
|
||||
public class CitiesController : ControllerBase
|
||||
{
|
||||
[HttpPost]
|
||||
[SwaggerOperation("Create a city")]
|
||||
[SwaggerResponse(
|
||||
StatusCodes.Status201Created, "Object successfuly created",
|
||||
typeof(CityDto))]
|
||||
[SwaggerResponse(
|
||||
StatusCodes.Status400BadRequest, "Object already exists",
|
||||
typeof(ProblemDetails))]
|
||||
[SwaggerResponse(
|
||||
StatusCodes.Status400BadRequest, "Input data validation error",
|
||||
typeof(HttpValidationProblemDetails))]
|
||||
[SwaggerResponse(
|
||||
StatusCodes.Status401Unauthorized, "Unauthorized to perform an action",
|
||||
typeof(ProblemDetails))]
|
||||
[SwaggerResponse(
|
||||
StatusCodes.Status403Forbidden,
|
||||
"Not enough privileges to perform an action",
|
||||
typeof(ProblemDetails))]
|
||||
[SwaggerResponse(
|
||||
StatusCodes.Status404NotFound, "Parent object not found",
|
||||
typeof(ProblemDetails))]
|
||||
[SwaggerResponse(
|
||||
StatusCodes.Status500InternalServerError, "Internal server error",
|
||||
typeof(ProblemDetails))]
|
||||
public async Task<ActionResult<CityDto>> Add(
|
||||
[FromBody] AddCityCommand command,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
return StatusCode(
|
||||
StatusCodes.Status201Created,
|
||||
await Mediator.Send(command, cancellationToken));
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[SwaggerOperation("Get a list of all cities")]
|
||||
[SwaggerResponse(
|
||||
StatusCodes.Status200OK, "Request successful",
|
||||
typeof(PaginatedList<CityDto>))]
|
||||
[SwaggerResponse(
|
||||
StatusCodes.Status400BadRequest, "Input data validation error",
|
||||
typeof(HttpValidationProblemDetails))]
|
||||
[SwaggerResponse(
|
||||
StatusCodes.Status401Unauthorized, "Unauthorized to perform an action",
|
||||
typeof(ProblemDetails))]
|
||||
[SwaggerResponse(
|
||||
StatusCodes.Status403Forbidden,
|
||||
"Not enough privileges to perform an action",
|
||||
typeof(ProblemDetails))]
|
||||
[SwaggerResponse(
|
||||
StatusCodes.Status500InternalServerError, "Internal server error",
|
||||
typeof(ProblemDetails))]
|
||||
public async Task<PaginatedList<CityDto>> GetPage(
|
||||
[FromQuery] PageQuery pageQuery, [FromQuery] SearchQuery searchQuery,
|
||||
[FromQuery] SortQuery sortQuery,
|
||||
[FromQuery] GetCitiesPageFilterViewModel filterQuery,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
return await Mediator.Send(
|
||||
new GetCitiesPageQuery()
|
||||
{
|
||||
PageNumber = pageQuery.PageNumber,
|
||||
PageSize = pageQuery.PageSize,
|
||||
Search = searchQuery.Search,
|
||||
Sort = sortQuery.Sort,
|
||||
CountryUuid = filterQuery.CountryUuid,
|
||||
RegionUuid = filterQuery.RegionUuid
|
||||
},
|
||||
cancellationToken);
|
||||
}
|
||||
|
||||
[HttpGet("{uuid:guid}")]
|
||||
[SwaggerOperation("Get city by uuid")]
|
||||
[SwaggerResponse(
|
||||
StatusCodes.Status200OK, "Request successful", typeof(CityDto))]
|
||||
[SwaggerResponse(
|
||||
StatusCodes.Status400BadRequest, "Input data validation error",
|
||||
typeof(HttpValidationProblemDetails))]
|
||||
[SwaggerResponse(
|
||||
StatusCodes.Status401Unauthorized, "Unauthorized to perform an action",
|
||||
typeof(ProblemDetails))]
|
||||
[SwaggerResponse(
|
||||
StatusCodes.Status403Forbidden,
|
||||
"Not enough privileges to perform an action",
|
||||
typeof(ProblemDetails))]
|
||||
[SwaggerResponse(
|
||||
StatusCodes.Status404NotFound, "Object not found", typeof(CityDto))]
|
||||
[SwaggerResponse(
|
||||
StatusCodes.Status500InternalServerError, "Internal server error",
|
||||
typeof(ProblemDetails))]
|
||||
public async Task<CityDto> Get(
|
||||
[FromRoute] Guid uuid,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
return await Mediator.Send(new GetCityQuery() { Uuid = uuid },
|
||||
cancellationToken);
|
||||
}
|
||||
|
||||
[HttpPut("{uuid:guid}")]
|
||||
[SwaggerOperation("Update city")]
|
||||
[SwaggerResponse(
|
||||
StatusCodes.Status200OK, "Request successful", typeof(CityDto))]
|
||||
[SwaggerResponse(
|
||||
StatusCodes.Status400BadRequest, "Object already exists",
|
||||
typeof(ProblemDetails))]
|
||||
[SwaggerResponse(
|
||||
StatusCodes.Status400BadRequest, "Input data validation error",
|
||||
typeof(HttpValidationProblemDetails))]
|
||||
[SwaggerResponse(
|
||||
StatusCodes.Status401Unauthorized, "Unauthorized to perform an action",
|
||||
typeof(ProblemDetails))]
|
||||
[SwaggerResponse(
|
||||
StatusCodes.Status403Forbidden,
|
||||
"Not enough privileges to perform an action",
|
||||
typeof(ProblemDetails))]
|
||||
[SwaggerResponse(
|
||||
StatusCodes.Status404NotFound, "Object not found", typeof(CityDto))]
|
||||
[SwaggerResponse(
|
||||
StatusCodes.Status404NotFound, "Parent object not found",
|
||||
typeof(ProblemDetails))]
|
||||
[SwaggerResponse(
|
||||
StatusCodes.Status500InternalServerError, "Internal server error",
|
||||
typeof(ProblemDetails))]
|
||||
public async Task<CityDto> Update(
|
||||
[FromRoute] Guid uuid,
|
||||
[FromBody] UpdateCityCommand command,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
command.Uuid = uuid;
|
||||
return await Mediator.Send(command, cancellationToken);
|
||||
}
|
||||
|
||||
[HttpDelete("{uuid:guid}")]
|
||||
[SwaggerOperation("Delete city")]
|
||||
[SwaggerResponse(StatusCodes.Status204NoContent, "Request successful")]
|
||||
[SwaggerResponse(
|
||||
StatusCodes.Status400BadRequest, "Input data validation error",
|
||||
typeof(HttpValidationProblemDetails))]
|
||||
[SwaggerResponse(
|
||||
StatusCodes.Status401Unauthorized, "Unauthorized to perform an action",
|
||||
typeof(ProblemDetails))]
|
||||
[SwaggerResponse(
|
||||
StatusCodes.Status403Forbidden,
|
||||
"Not enough privileges to perform an action",
|
||||
typeof(ProblemDetails))]
|
||||
[SwaggerResponse(
|
||||
StatusCodes.Status404NotFound, "Object not found", typeof(CityDto))]
|
||||
[SwaggerResponse(
|
||||
StatusCodes.Status500InternalServerError, "Internal server error",
|
||||
typeof(ProblemDetails))]
|
||||
public async Task<IActionResult> Delete(
|
||||
[FromRoute] Guid uuid,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
await Mediator.Send(
|
||||
new DeleteCityCommand() { Uuid = uuid },
|
||||
cancellationToken);
|
||||
return StatusCode(StatusCodes.Status204NoContent);
|
||||
}
|
||||
}
|
@ -53,9 +53,6 @@ public class RegionsController : ControllerBase
|
||||
[SwaggerResponse(
|
||||
StatusCodes.Status200OK, "Request successful",
|
||||
typeof(PaginatedList<RegionDto>))]
|
||||
[SwaggerResponse(
|
||||
StatusCodes.Status400BadRequest, "Object already exists",
|
||||
typeof(ProblemDetails))]
|
||||
[SwaggerResponse(
|
||||
StatusCodes.Status400BadRequest, "Input data validation error",
|
||||
typeof(HttpValidationProblemDetails))]
|
||||
@ -91,9 +88,6 @@ public class RegionsController : ControllerBase
|
||||
[SwaggerOperation("Get region by uuid")]
|
||||
[SwaggerResponse(
|
||||
StatusCodes.Status200OK, "Request successful", typeof(RegionDto))]
|
||||
[SwaggerResponse(
|
||||
StatusCodes.Status400BadRequest, "Object already exists",
|
||||
typeof(ProblemDetails))]
|
||||
[SwaggerResponse(
|
||||
StatusCodes.Status400BadRequest, "Input data validation error",
|
||||
typeof(HttpValidationProblemDetails))]
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System.Reflection;
|
||||
// using System.Reflection;
|
||||
// using cuqmbr.TravelGuide.Domain.Enums;
|
||||
using cuqmbr.TravelGuide.Domain.Entities;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
// using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
|
||||
@ -10,6 +11,10 @@ public class InMemoryDbContext : DbContext
|
||||
public InMemoryDbContext(DbContextOptions<InMemoryDbContext> options)
|
||||
: base(options) { }
|
||||
|
||||
public DbSet<Country> Countries { get => Set<Country>(); }
|
||||
public DbSet<Region> Regions { get => Set<Region>(); }
|
||||
public DbSet<City> Cities { get => Set<City>(); }
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder builder)
|
||||
{
|
||||
base.OnModelCreating(builder);
|
||||
@ -18,11 +23,6 @@ public class InMemoryDbContext : DbContext
|
||||
// "vehicle_type",
|
||||
// VehicleType.Enumerations.Select(e => e.Value.Name).ToArray());
|
||||
//
|
||||
builder
|
||||
.ApplyConfigurationsFromAssembly(
|
||||
Assembly.GetExecutingAssembly(),
|
||||
t => t.Namespace ==
|
||||
"cuqmbr.TravelGuide.Persistence.InMemory.Configurations");
|
||||
}
|
||||
|
||||
protected override void ConfigureConventions(
|
||||
|
@ -15,11 +15,15 @@ public sealed class InMemoryUnitOfWork : UnitOfWork
|
||||
|
||||
CountryRepository = new InMemoryCountryRepository(_dbContext);
|
||||
RegionRepository = new InMemoryRegionRepository(_dbContext);
|
||||
CityRepository = new InMemoryCityRepository(_dbContext);
|
||||
}
|
||||
|
||||
public CountryRepository CountryRepository { get; init; }
|
||||
|
||||
public RegionRepository RegionRepository { get; init; }
|
||||
|
||||
public CityRepository CityRepository { get; init; }
|
||||
|
||||
public int Save()
|
||||
{
|
||||
return _dbContext.SaveChanges();
|
||||
|
@ -0,0 +1,11 @@
|
||||
using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence.Repositories;
|
||||
using cuqmbr.TravelGuide.Domain.Entities;
|
||||
|
||||
namespace cuqmbr.TravelGuide.Persistence.InMemory.Repositories;
|
||||
|
||||
public sealed class InMemoryCityRepository :
|
||||
InMemoryBaseRepository<City>, CityRepository
|
||||
{
|
||||
public InMemoryCityRepository(InMemoryDbContext dbContext)
|
||||
: base(dbContext) { }
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
using cuqmbr.TravelGuide.Domain.Entities;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace cuqmbr.TravelGuide.Persistence.PostgreSql.Configurations;
|
||||
|
||||
public class AddressConfiguration : BaseConfiguration<Address>
|
||||
{
|
||||
public override void Configure(EntityTypeBuilder<Address> builder)
|
||||
{
|
||||
builder
|
||||
.ToTable("addresses");
|
||||
|
||||
base.Configure(builder);
|
||||
|
||||
|
||||
builder
|
||||
.Property(a => a.Name)
|
||||
.HasColumnName("name")
|
||||
.HasColumnType("varchar(128)")
|
||||
.IsRequired(true);
|
||||
|
||||
// builder
|
||||
// .Property(a => a.VehicleType)
|
||||
// .HasColumnName("vehicle_type")
|
||||
// .HasColumnType($"{PostgreSqlDbContext.DefaultSchema}.vehicle_type")
|
||||
// .HasConversion<VehicleTypeConverter>()
|
||||
// .IsRequired(true);
|
||||
|
||||
|
||||
builder
|
||||
.Property(a => a.CityId)
|
||||
.HasColumnName("city_id")
|
||||
.HasColumnType("bigint")
|
||||
.IsRequired(true);
|
||||
|
||||
builder
|
||||
.HasOne(a => a.City)
|
||||
.WithMany(c => c.Addresses)
|
||||
.HasForeignKey(a => a.CityId)
|
||||
.HasConstraintName(
|
||||
"fk_" +
|
||||
$"{builder.Metadata.GetTableName()}_" +
|
||||
$"{builder.Property(a => a.CityId).Metadata.GetColumnName()}")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
builder
|
||||
.HasIndex(a => a.CityId)
|
||||
.HasDatabaseName(
|
||||
"ix_" +
|
||||
$"{builder.Metadata.GetTableName()}_" +
|
||||
$"{builder.Property(a => a.CityId).Metadata.GetColumnName()}")
|
||||
.IsUnique();
|
||||
}
|
||||
}
|
@ -36,13 +36,5 @@ public class CityConfiguration : BaseConfiguration<City>
|
||||
$"{builder.Metadata.GetTableName()}_" +
|
||||
$"{builder.Property(c => c.RegionId).Metadata.GetColumnName()}")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
builder
|
||||
.HasIndex(c => c.RegionId)
|
||||
.HasDatabaseName(
|
||||
"ix_" +
|
||||
$"{builder.Metadata.GetTableName()}_" +
|
||||
$"{builder.Property(c => c.RegionId).Metadata.GetColumnName()}")
|
||||
.IsUnique();
|
||||
}
|
||||
}
|
||||
|
@ -1,83 +0,0 @@
|
||||
using cuqmbr.TravelGuide.Domain.Entities;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace cuqmbr.TravelGuide.Persistence.PostgreSql.Configurations;
|
||||
|
||||
public class RouteAddressConfiguration : BaseConfiguration<RouteAddress>
|
||||
{
|
||||
public override void Configure(EntityTypeBuilder<RouteAddress> builder)
|
||||
{
|
||||
builder
|
||||
.ToTable("route_addresses");
|
||||
|
||||
base.Configure(builder);
|
||||
|
||||
|
||||
builder
|
||||
.Property(ra => ra.Order)
|
||||
.HasColumnName("order")
|
||||
.HasColumnType("smallint")
|
||||
.IsRequired(true);
|
||||
|
||||
|
||||
builder
|
||||
.Property(ra => ra.AddressId)
|
||||
.HasColumnName("address_id")
|
||||
.HasColumnType("bigint")
|
||||
.IsRequired(true);
|
||||
|
||||
builder
|
||||
.HasOne(ra => ra.Address)
|
||||
.WithMany(a => a.AddressRoutes)
|
||||
.HasForeignKey(ra => ra.AddressId)
|
||||
.HasConstraintName(
|
||||
"fk_" +
|
||||
$"{builder.Metadata.GetTableName()}_" +
|
||||
$"{builder.Property(ra => ra.AddressId).Metadata.GetColumnName()}")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
builder
|
||||
.HasIndex(ra => ra.AddressId)
|
||||
.HasDatabaseName(
|
||||
"ix_" +
|
||||
$"{builder.Metadata.GetTableName()}_" +
|
||||
$"{builder.Property(ra => ra.AddressId).Metadata.GetColumnName()}")
|
||||
.IsUnique();
|
||||
|
||||
|
||||
builder
|
||||
.Property(ra => ra.RouteId)
|
||||
.HasColumnName("route_id")
|
||||
.HasColumnType("bigint")
|
||||
.IsRequired(true);
|
||||
|
||||
builder
|
||||
.HasOne(ra => ra.Route)
|
||||
.WithMany(a => a.RouteAddresses)
|
||||
.HasForeignKey(ra => ra.RouteId)
|
||||
.HasConstraintName(
|
||||
"fk_" +
|
||||
$"{builder.Metadata.GetTableName()}_" +
|
||||
$"{builder.Property(ra => ra.RouteId).Metadata.GetColumnName()}")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
builder
|
||||
.HasIndex(ra => ra.RouteId)
|
||||
.HasDatabaseName(
|
||||
"ix_" +
|
||||
$"{builder.Metadata.GetTableName()}_" +
|
||||
$"{builder.Property(ra => ra.RouteId).Metadata.GetColumnName()}")
|
||||
.IsUnique();
|
||||
|
||||
|
||||
builder
|
||||
.HasAlternateKey(ra => new { ra.AddressId, ra.RouteId, ra.Order })
|
||||
.HasName(
|
||||
"altk_" +
|
||||
$"{builder.Metadata.GetTableName()}_" +
|
||||
$"{builder.Property(ra => ra.AddressId).Metadata.GetColumnName()}_" +
|
||||
$"{builder.Property(ra => ra.RouteId).Metadata.GetColumnName()}_" +
|
||||
$"{builder.Property(ra => ra.Order).Metadata.GetColumnName()}");
|
||||
}
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
using cuqmbr.TravelGuide.Domain.Entities;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace cuqmbr.TravelGuide.Persistence.PostgreSql.Configurations;
|
||||
|
||||
public class RouteConfiguration : BaseConfiguration<Route>
|
||||
{
|
||||
public override void Configure(EntityTypeBuilder<Route> builder)
|
||||
{
|
||||
builder
|
||||
.ToTable("routes");
|
||||
|
||||
base.Configure(builder);
|
||||
|
||||
|
||||
builder
|
||||
.Property(r => r.Name)
|
||||
.HasColumnName("name")
|
||||
.HasColumnType("varchar(64)")
|
||||
.IsRequired(true);
|
||||
|
||||
// builder
|
||||
// .Property(r => r.VehicleType)
|
||||
// .HasColumnName("vehicle_type")
|
||||
// .HasColumnType($"{PostgreSqlDbContext.DefaultSchema}.vehicle_type")
|
||||
// .HasConversion<VehicleTypeConverter>()
|
||||
// .IsRequired(true);
|
||||
}
|
||||
}
|
@ -12,8 +12,8 @@ using cuqmbr.TravelGuide.Persistence.PostgreSql;
|
||||
namespace Persistence.PostgreSql.Migrations
|
||||
{
|
||||
[DbContext(typeof(PostgreSqlDbContext))]
|
||||
[Migration("20250427160059_Initial_migration")]
|
||||
partial class Initial_migration
|
||||
[Migration("20250430113338_Countries_Regions_Cities")]
|
||||
partial class Countries_Regions_Cities
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
@ -27,65 +27,35 @@ namespace Persistence.PostgreSql.Migrations
|
||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "vehicle_type", new[] { "bus", "train", "aircraft" });
|
||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||
|
||||
modelBuilder.HasSequence("addresses_id_sequence");
|
||||
|
||||
modelBuilder.HasSequence("cities_id_sequence");
|
||||
|
||||
modelBuilder.HasSequence("countries_id_sequence");
|
||||
|
||||
modelBuilder.HasSequence("regions_id_sequence");
|
||||
|
||||
modelBuilder.HasSequence("route_addresses_id_sequence");
|
||||
|
||||
modelBuilder.HasSequence("routes_id_sequence");
|
||||
|
||||
modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Address", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("bigint")
|
||||
.HasColumnName("id")
|
||||
.HasDefaultValueSql("nextval('application.addresses_id_sequence')");
|
||||
.HasColumnType("bigint");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseSequence(b.Property<long>("Id"), "addresses_id_sequence");
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
|
||||
|
||||
b.Property<long>("CityId")
|
||||
.HasColumnType("bigint")
|
||||
.HasColumnName("city_id");
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<Guid>("Guid")
|
||||
.HasColumnType("uuid")
|
||||
.HasColumnName("uuid");
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(128)")
|
||||
.HasColumnName("name");
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("VehicleType")
|
||||
.IsRequired()
|
||||
.HasColumnType("application.vehicle_type")
|
||||
.HasColumnName("vehicle_type");
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasKey("Id")
|
||||
.HasName("pk_addresses");
|
||||
b.HasIndex("CityId");
|
||||
|
||||
b.HasAlternateKey("Guid")
|
||||
.HasName("altk_addresses_Guid");
|
||||
|
||||
b.HasIndex("CityId")
|
||||
.IsUnique()
|
||||
.HasDatabaseName("ix_addresses_city_id");
|
||||
|
||||
b.HasIndex("Guid")
|
||||
.IsUnique()
|
||||
.HasDatabaseName("ix_addresses_uuid");
|
||||
|
||||
b.HasIndex("Id")
|
||||
.IsUnique()
|
||||
.HasDatabaseName("ix_addresses_id");
|
||||
|
||||
b.ToTable("addresses", "application");
|
||||
b.ToTable("Address", "application");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.City", b =>
|
||||
@ -125,9 +95,7 @@ namespace Persistence.PostgreSql.Migrations
|
||||
.IsUnique()
|
||||
.HasDatabaseName("ix_cities_id");
|
||||
|
||||
b.HasIndex("RegionId")
|
||||
.IsUnique()
|
||||
.HasDatabaseName("ix_cities_region_id");
|
||||
b.HasIndex("RegionId");
|
||||
|
||||
b.ToTable("cities", "application");
|
||||
});
|
||||
@ -214,95 +182,49 @@ namespace Persistence.PostgreSql.Migrations
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("bigint")
|
||||
.HasColumnName("id")
|
||||
.HasDefaultValueSql("nextval('application.routes_id_sequence')");
|
||||
.HasColumnType("bigint");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseSequence(b.Property<long>("Id"), "routes_id_sequence");
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
|
||||
|
||||
b.Property<Guid>("Guid")
|
||||
.HasColumnType("uuid")
|
||||
.HasColumnName("uuid");
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(64)")
|
||||
.HasColumnName("name");
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("VehicleType")
|
||||
.IsRequired()
|
||||
.HasColumnType("application.vehicle_type")
|
||||
.HasColumnName("vehicle_type");
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasKey("Id")
|
||||
.HasName("pk_routes");
|
||||
|
||||
b.HasAlternateKey("Guid")
|
||||
.HasName("altk_routes_Guid");
|
||||
|
||||
b.HasIndex("Guid")
|
||||
.IsUnique()
|
||||
.HasDatabaseName("ix_routes_uuid");
|
||||
|
||||
b.HasIndex("Id")
|
||||
.IsUnique()
|
||||
.HasDatabaseName("ix_routes_id");
|
||||
|
||||
b.ToTable("routes", "application");
|
||||
b.ToTable("Route", "application");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.RouteAddress", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("bigint")
|
||||
.HasColumnName("id")
|
||||
.HasDefaultValueSql("nextval('application.route_addresses_id_sequence')");
|
||||
.HasColumnType("bigint");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseSequence(b.Property<long>("Id"), "route_addresses_id_sequence");
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
|
||||
|
||||
b.Property<long>("AddressId")
|
||||
.HasColumnType("bigint")
|
||||
.HasColumnName("address_id");
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<Guid>("Guid")
|
||||
.HasColumnType("uuid")
|
||||
.HasColumnName("uuid");
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<short>("Order")
|
||||
.HasColumnType("smallint")
|
||||
.HasColumnName("order");
|
||||
.HasColumnType("smallint");
|
||||
|
||||
b.Property<long>("RouteId")
|
||||
.HasColumnType("bigint")
|
||||
.HasColumnName("route_id");
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.HasKey("Id")
|
||||
.HasName("pk_route_addresses");
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasAlternateKey("Guid")
|
||||
.HasName("altk_route_addresses_Guid");
|
||||
b.HasIndex("AddressId");
|
||||
|
||||
b.HasAlternateKey("AddressId", "RouteId", "Order")
|
||||
.HasName("altk_route_addresses_address_id_route_id_order");
|
||||
b.HasIndex("RouteId");
|
||||
|
||||
b.HasIndex("AddressId")
|
||||
.IsUnique()
|
||||
.HasDatabaseName("ix_route_addresses_address_id");
|
||||
|
||||
b.HasIndex("Guid")
|
||||
.IsUnique()
|
||||
.HasDatabaseName("ix_route_addresses_uuid");
|
||||
|
||||
b.HasIndex("Id")
|
||||
.IsUnique()
|
||||
.HasDatabaseName("ix_route_addresses_id");
|
||||
|
||||
b.HasIndex("RouteId")
|
||||
.IsUnique()
|
||||
.HasDatabaseName("ix_route_addresses_route_id");
|
||||
|
||||
b.ToTable("route_addresses", "application");
|
||||
b.ToTable("RouteAddress", "application");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Address", b =>
|
||||
@ -311,8 +233,7 @@ namespace Persistence.PostgreSql.Migrations
|
||||
.WithMany("Addresses")
|
||||
.HasForeignKey("CityId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired()
|
||||
.HasConstraintName("fk_addresses_city_id");
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("City");
|
||||
});
|
||||
@ -347,15 +268,13 @@ namespace Persistence.PostgreSql.Migrations
|
||||
.WithMany("AddressRoutes")
|
||||
.HasForeignKey("AddressId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired()
|
||||
.HasConstraintName("fk_route_addresses_address_id");
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("cuqmbr.TravelGuide.Domain.Entities.Route", "Route")
|
||||
.WithMany("RouteAddresses")
|
||||
.HasForeignKey("RouteId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired()
|
||||
.HasConstraintName("fk_route_addresses_route_id");
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Address");
|
||||
|
@ -1,12 +1,13 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Persistence.PostgreSql.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class Initial_migration : Migration
|
||||
public partial class Countries_Regions_Cities : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
@ -17,10 +18,6 @@ namespace Persistence.PostgreSql.Migrations
|
||||
migrationBuilder.AlterDatabase()
|
||||
.Annotation("Npgsql:Enum:vehicle_type", "bus,train,aircraft");
|
||||
|
||||
migrationBuilder.CreateSequence(
|
||||
name: "addresses_id_sequence",
|
||||
schema: "application");
|
||||
|
||||
migrationBuilder.CreateSequence(
|
||||
name: "cities_id_sequence",
|
||||
schema: "application");
|
||||
@ -33,14 +30,6 @@ namespace Persistence.PostgreSql.Migrations
|
||||
name: "regions_id_sequence",
|
||||
schema: "application");
|
||||
|
||||
migrationBuilder.CreateSequence(
|
||||
name: "route_addresses_id_sequence",
|
||||
schema: "application");
|
||||
|
||||
migrationBuilder.CreateSequence(
|
||||
name: "routes_id_sequence",
|
||||
schema: "application");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "countries",
|
||||
schema: "application",
|
||||
@ -57,19 +46,18 @@ namespace Persistence.PostgreSql.Migrations
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "routes",
|
||||
name: "Route",
|
||||
schema: "application",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<long>(type: "bigint", nullable: false, defaultValueSql: "nextval('application.routes_id_sequence')"),
|
||||
name = table.Column<string>(type: "varchar(64)", nullable: false),
|
||||
vehicle_type = table.Column<string>(type: "application.vehicle_type", nullable: false),
|
||||
uuid = table.Column<Guid>(type: "uuid", nullable: false)
|
||||
Id = table.Column<long>(type: "bigint", nullable: false)
|
||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||
Name = table.Column<string>(type: "text", nullable: false),
|
||||
Guid = table.Column<Guid>(type: "uuid", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("pk_routes", x => x.id);
|
||||
table.UniqueConstraint("altk_routes_Guid", x => x.uuid);
|
||||
table.PrimaryKey("PK_Route", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
@ -119,23 +107,22 @@ namespace Persistence.PostgreSql.Migrations
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "addresses",
|
||||
name: "Address",
|
||||
schema: "application",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<long>(type: "bigint", nullable: false, defaultValueSql: "nextval('application.addresses_id_sequence')"),
|
||||
name = table.Column<string>(type: "varchar(128)", nullable: false),
|
||||
vehicle_type = table.Column<string>(type: "application.vehicle_type", nullable: false),
|
||||
city_id = table.Column<long>(type: "bigint", nullable: false),
|
||||
uuid = table.Column<Guid>(type: "uuid", nullable: false)
|
||||
Id = table.Column<long>(type: "bigint", nullable: false)
|
||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||
Name = table.Column<string>(type: "text", nullable: false),
|
||||
CityId = table.Column<long>(type: "bigint", nullable: false),
|
||||
Guid = table.Column<Guid>(type: "uuid", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("pk_addresses", x => x.id);
|
||||
table.UniqueConstraint("altk_addresses_Guid", x => x.uuid);
|
||||
table.PrimaryKey("PK_Address", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "fk_addresses_city_id",
|
||||
column: x => x.city_id,
|
||||
name: "FK_Address_cities_CityId",
|
||||
column: x => x.CityId,
|
||||
principalSchema: "application",
|
||||
principalTable: "cities",
|
||||
principalColumn: "id",
|
||||
@ -143,57 +130,41 @@ namespace Persistence.PostgreSql.Migrations
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "route_addresses",
|
||||
name: "RouteAddress",
|
||||
schema: "application",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<long>(type: "bigint", nullable: false, defaultValueSql: "nextval('application.route_addresses_id_sequence')"),
|
||||
order = table.Column<short>(type: "smallint", nullable: false),
|
||||
address_id = table.Column<long>(type: "bigint", nullable: false),
|
||||
route_id = table.Column<long>(type: "bigint", nullable: false),
|
||||
uuid = table.Column<Guid>(type: "uuid", nullable: false)
|
||||
Id = table.Column<long>(type: "bigint", nullable: false)
|
||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||
Order = table.Column<short>(type: "smallint", nullable: false),
|
||||
AddressId = table.Column<long>(type: "bigint", nullable: false),
|
||||
RouteId = table.Column<long>(type: "bigint", nullable: false),
|
||||
Guid = table.Column<Guid>(type: "uuid", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("pk_route_addresses", x => x.id);
|
||||
table.UniqueConstraint("altk_route_addresses_address_id_route_id_order", x => new { x.address_id, x.route_id, x.order });
|
||||
table.UniqueConstraint("altk_route_addresses_Guid", x => x.uuid);
|
||||
table.PrimaryKey("PK_RouteAddress", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "fk_route_addresses_address_id",
|
||||
column: x => x.address_id,
|
||||
name: "FK_RouteAddress_Address_AddressId",
|
||||
column: x => x.AddressId,
|
||||
principalSchema: "application",
|
||||
principalTable: "addresses",
|
||||
principalColumn: "id",
|
||||
principalTable: "Address",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "fk_route_addresses_route_id",
|
||||
column: x => x.route_id,
|
||||
name: "FK_RouteAddress_Route_RouteId",
|
||||
column: x => x.RouteId,
|
||||
principalSchema: "application",
|
||||
principalTable: "routes",
|
||||
principalColumn: "id",
|
||||
principalTable: "Route",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_addresses_city_id",
|
||||
name: "IX_Address_CityId",
|
||||
schema: "application",
|
||||
table: "addresses",
|
||||
column: "city_id",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_addresses_id",
|
||||
schema: "application",
|
||||
table: "addresses",
|
||||
column: "id",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_addresses_uuid",
|
||||
schema: "application",
|
||||
table: "addresses",
|
||||
column: "uuid",
|
||||
unique: true);
|
||||
table: "Address",
|
||||
column: "CityId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_cities_id",
|
||||
@ -203,11 +174,10 @@ namespace Persistence.PostgreSql.Migrations
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_cities_region_id",
|
||||
name: "IX_cities_region_id",
|
||||
schema: "application",
|
||||
table: "cities",
|
||||
column: "region_id",
|
||||
unique: true);
|
||||
column: "region_id");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_cities_uuid",
|
||||
@ -251,61 +221,31 @@ namespace Persistence.PostgreSql.Migrations
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_route_addresses_address_id",
|
||||
name: "IX_RouteAddress_AddressId",
|
||||
schema: "application",
|
||||
table: "route_addresses",
|
||||
column: "address_id",
|
||||
unique: true);
|
||||
table: "RouteAddress",
|
||||
column: "AddressId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_route_addresses_id",
|
||||
name: "IX_RouteAddress_RouteId",
|
||||
schema: "application",
|
||||
table: "route_addresses",
|
||||
column: "id",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_route_addresses_route_id",
|
||||
schema: "application",
|
||||
table: "route_addresses",
|
||||
column: "route_id",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_route_addresses_uuid",
|
||||
schema: "application",
|
||||
table: "route_addresses",
|
||||
column: "uuid",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_routes_id",
|
||||
schema: "application",
|
||||
table: "routes",
|
||||
column: "id",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_routes_uuid",
|
||||
schema: "application",
|
||||
table: "routes",
|
||||
column: "uuid",
|
||||
unique: true);
|
||||
table: "RouteAddress",
|
||||
column: "RouteId");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "route_addresses",
|
||||
name: "RouteAddress",
|
||||
schema: "application");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "addresses",
|
||||
name: "Address",
|
||||
schema: "application");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "routes",
|
||||
name: "Route",
|
||||
schema: "application");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
@ -320,10 +260,6 @@ namespace Persistence.PostgreSql.Migrations
|
||||
name: "countries",
|
||||
schema: "application");
|
||||
|
||||
migrationBuilder.DropSequence(
|
||||
name: "addresses_id_sequence",
|
||||
schema: "application");
|
||||
|
||||
migrationBuilder.DropSequence(
|
||||
name: "cities_id_sequence",
|
||||
schema: "application");
|
||||
@ -335,14 +271,6 @@ namespace Persistence.PostgreSql.Migrations
|
||||
migrationBuilder.DropSequence(
|
||||
name: "regions_id_sequence",
|
||||
schema: "application");
|
||||
|
||||
migrationBuilder.DropSequence(
|
||||
name: "route_addresses_id_sequence",
|
||||
schema: "application");
|
||||
|
||||
migrationBuilder.DropSequence(
|
||||
name: "routes_id_sequence",
|
||||
schema: "application");
|
||||
}
|
||||
}
|
||||
}
|
@ -24,65 +24,35 @@ namespace Persistence.PostgreSql.Migrations
|
||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "vehicle_type", new[] { "bus", "train", "aircraft" });
|
||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||
|
||||
modelBuilder.HasSequence("addresses_id_sequence");
|
||||
|
||||
modelBuilder.HasSequence("cities_id_sequence");
|
||||
|
||||
modelBuilder.HasSequence("countries_id_sequence");
|
||||
|
||||
modelBuilder.HasSequence("regions_id_sequence");
|
||||
|
||||
modelBuilder.HasSequence("route_addresses_id_sequence");
|
||||
|
||||
modelBuilder.HasSequence("routes_id_sequence");
|
||||
|
||||
modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Address", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("bigint")
|
||||
.HasColumnName("id")
|
||||
.HasDefaultValueSql("nextval('application.addresses_id_sequence')");
|
||||
.HasColumnType("bigint");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseSequence(b.Property<long>("Id"), "addresses_id_sequence");
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
|
||||
|
||||
b.Property<long>("CityId")
|
||||
.HasColumnType("bigint")
|
||||
.HasColumnName("city_id");
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<Guid>("Guid")
|
||||
.HasColumnType("uuid")
|
||||
.HasColumnName("uuid");
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(128)")
|
||||
.HasColumnName("name");
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("VehicleType")
|
||||
.IsRequired()
|
||||
.HasColumnType("application.vehicle_type")
|
||||
.HasColumnName("vehicle_type");
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasKey("Id")
|
||||
.HasName("pk_addresses");
|
||||
b.HasIndex("CityId");
|
||||
|
||||
b.HasAlternateKey("Guid")
|
||||
.HasName("altk_addresses_Guid");
|
||||
|
||||
b.HasIndex("CityId")
|
||||
.IsUnique()
|
||||
.HasDatabaseName("ix_addresses_city_id");
|
||||
|
||||
b.HasIndex("Guid")
|
||||
.IsUnique()
|
||||
.HasDatabaseName("ix_addresses_uuid");
|
||||
|
||||
b.HasIndex("Id")
|
||||
.IsUnique()
|
||||
.HasDatabaseName("ix_addresses_id");
|
||||
|
||||
b.ToTable("addresses", "application");
|
||||
b.ToTable("Address", "application");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.City", b =>
|
||||
@ -122,9 +92,7 @@ namespace Persistence.PostgreSql.Migrations
|
||||
.IsUnique()
|
||||
.HasDatabaseName("ix_cities_id");
|
||||
|
||||
b.HasIndex("RegionId")
|
||||
.IsUnique()
|
||||
.HasDatabaseName("ix_cities_region_id");
|
||||
b.HasIndex("RegionId");
|
||||
|
||||
b.ToTable("cities", "application");
|
||||
});
|
||||
@ -211,95 +179,49 @@ namespace Persistence.PostgreSql.Migrations
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("bigint")
|
||||
.HasColumnName("id")
|
||||
.HasDefaultValueSql("nextval('application.routes_id_sequence')");
|
||||
.HasColumnType("bigint");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseSequence(b.Property<long>("Id"), "routes_id_sequence");
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
|
||||
|
||||
b.Property<Guid>("Guid")
|
||||
.HasColumnType("uuid")
|
||||
.HasColumnName("uuid");
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(64)")
|
||||
.HasColumnName("name");
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("VehicleType")
|
||||
.IsRequired()
|
||||
.HasColumnType("application.vehicle_type")
|
||||
.HasColumnName("vehicle_type");
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasKey("Id")
|
||||
.HasName("pk_routes");
|
||||
|
||||
b.HasAlternateKey("Guid")
|
||||
.HasName("altk_routes_Guid");
|
||||
|
||||
b.HasIndex("Guid")
|
||||
.IsUnique()
|
||||
.HasDatabaseName("ix_routes_uuid");
|
||||
|
||||
b.HasIndex("Id")
|
||||
.IsUnique()
|
||||
.HasDatabaseName("ix_routes_id");
|
||||
|
||||
b.ToTable("routes", "application");
|
||||
b.ToTable("Route", "application");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.RouteAddress", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("bigint")
|
||||
.HasColumnName("id")
|
||||
.HasDefaultValueSql("nextval('application.route_addresses_id_sequence')");
|
||||
.HasColumnType("bigint");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseSequence(b.Property<long>("Id"), "route_addresses_id_sequence");
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
|
||||
|
||||
b.Property<long>("AddressId")
|
||||
.HasColumnType("bigint")
|
||||
.HasColumnName("address_id");
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<Guid>("Guid")
|
||||
.HasColumnType("uuid")
|
||||
.HasColumnName("uuid");
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<short>("Order")
|
||||
.HasColumnType("smallint")
|
||||
.HasColumnName("order");
|
||||
.HasColumnType("smallint");
|
||||
|
||||
b.Property<long>("RouteId")
|
||||
.HasColumnType("bigint")
|
||||
.HasColumnName("route_id");
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.HasKey("Id")
|
||||
.HasName("pk_route_addresses");
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasAlternateKey("Guid")
|
||||
.HasName("altk_route_addresses_Guid");
|
||||
b.HasIndex("AddressId");
|
||||
|
||||
b.HasAlternateKey("AddressId", "RouteId", "Order")
|
||||
.HasName("altk_route_addresses_address_id_route_id_order");
|
||||
b.HasIndex("RouteId");
|
||||
|
||||
b.HasIndex("AddressId")
|
||||
.IsUnique()
|
||||
.HasDatabaseName("ix_route_addresses_address_id");
|
||||
|
||||
b.HasIndex("Guid")
|
||||
.IsUnique()
|
||||
.HasDatabaseName("ix_route_addresses_uuid");
|
||||
|
||||
b.HasIndex("Id")
|
||||
.IsUnique()
|
||||
.HasDatabaseName("ix_route_addresses_id");
|
||||
|
||||
b.HasIndex("RouteId")
|
||||
.IsUnique()
|
||||
.HasDatabaseName("ix_route_addresses_route_id");
|
||||
|
||||
b.ToTable("route_addresses", "application");
|
||||
b.ToTable("RouteAddress", "application");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Address", b =>
|
||||
@ -308,8 +230,7 @@ namespace Persistence.PostgreSql.Migrations
|
||||
.WithMany("Addresses")
|
||||
.HasForeignKey("CityId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired()
|
||||
.HasConstraintName("fk_addresses_city_id");
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("City");
|
||||
});
|
||||
@ -344,15 +265,13 @@ namespace Persistence.PostgreSql.Migrations
|
||||
.WithMany("AddressRoutes")
|
||||
.HasForeignKey("AddressId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired()
|
||||
.HasConstraintName("fk_route_addresses_address_id");
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("cuqmbr.TravelGuide.Domain.Entities.Route", "Route")
|
||||
.WithMany("RouteAddresses")
|
||||
.HasForeignKey("RouteId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired()
|
||||
.HasConstraintName("fk_route_addresses_route_id");
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Address");
|
||||
|
||||
|
@ -15,11 +15,15 @@ public sealed class PostgreSqlUnitOfWork : UnitOfWork
|
||||
|
||||
CountryRepository = new PostgreSqlCountryRepository(_dbContext);
|
||||
RegionRepository = new PostgreSqlRegionRepository(_dbContext);
|
||||
CityRepository = new PostgreSqlCityRepository(_dbContext);
|
||||
}
|
||||
|
||||
public CountryRepository CountryRepository { get; init; }
|
||||
|
||||
public RegionRepository RegionRepository { get; init; }
|
||||
|
||||
public CityRepository CityRepository { get; init; }
|
||||
|
||||
public int Save()
|
||||
{
|
||||
return _dbContext.SaveChanges();
|
||||
|
@ -0,0 +1,11 @@
|
||||
using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence.Repositories;
|
||||
using cuqmbr.TravelGuide.Domain.Entities;
|
||||
|
||||
namespace cuqmbr.TravelGuide.Persistence.PostgreSql.Repositories;
|
||||
|
||||
public sealed class PostgreSqlCityRepository :
|
||||
PostgreSqlBaseRepository<City>, CityRepository
|
||||
{
|
||||
public PostgreSqlCityRepository(PostgreSqlDbContext dbContext)
|
||||
: base(dbContext) { }
|
||||
}
|
1576
tst/Application.IntegrationTests/CitiesTests.cs
Normal file
1576
tst/Application.IntegrationTests/CitiesTests.cs
Normal file
File diff suppressed because it is too large
Load Diff
@ -28,7 +28,7 @@ public class RegionsTests : TestBase
|
||||
Name = countryName
|
||||
}, TestContext.Current.CancellationToken);
|
||||
|
||||
string regionName = "Regin Name";
|
||||
string regionName = "Region Name";
|
||||
|
||||
var createRegionResult = await mediator.Send(
|
||||
new AddRegionCommand()
|
||||
@ -65,7 +65,7 @@ public class RegionsTests : TestBase
|
||||
Name = countryName
|
||||
}, TestContext.Current.CancellationToken);
|
||||
|
||||
string regionName = "Regin Name";
|
||||
string regionName = "Region Name";
|
||||
|
||||
var createRegionResult = await mediator.Send(
|
||||
new AddRegionCommand()
|
||||
@ -106,7 +106,7 @@ public class RegionsTests : TestBase
|
||||
Name = countryName2
|
||||
}, TestContext.Current.CancellationToken);
|
||||
|
||||
string regionName = "Regin Name";
|
||||
string regionName = "Region Name";
|
||||
|
||||
var createRegionResult1 = await mediator.Send(
|
||||
new AddRegionCommand()
|
||||
@ -517,8 +517,6 @@ public class RegionsTests : TestBase
|
||||
// TODO: Add more tests with unauthenticated user
|
||||
// (copy tests with admin role)
|
||||
|
||||
// TODO: Add test for GetRegion and GetRegionPage
|
||||
|
||||
[Fact]
|
||||
public async Task GetRegion_WithAdminRole_RegionReturned()
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user