Major update

This commit is contained in:
2023-06-01 08:52:05 -05:00
parent d7c0f373f4
commit df84287eb2
264 changed files with 8614 additions and 964 deletions

25
divisions/.dockerignore Normal file
View File

@@ -0,0 +1,25 @@
**/.classpath
**/.dockerignore
**/.env
**/.git
**/.gitignore
**/.project
**/.settings
**/.toolstarget
**/.vs
**/.vscode
**/*.*proj.user
**/*.dbmdl
**/*.jfm
**/azds.yaml
**/bin
**/charts
**/docker-compose*
**/Dockerfile*
**/node_modules
**/npm-debug.log
**/obj
**/secrets.dev.yaml
**/values.dev.yaml
LICENSE
README.md

3
divisions/.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
.vs/
[Bb]in/
[Oo]bj/

View File

@@ -0,0 +1,52 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Divisions.Queries;
using MediatR;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
namespace Divisions.Controllers
{
[ApiController]
[Route("api/divisions")]
public class DivisionsController : ControllerBase
{
private readonly ISender _sender;
public DivisionsController(ISender sender) => _sender = sender;
[HttpGet]
public async Task<ActionResult> GetDivisions([FromQuery] int pageNumber, [FromQuery] int pageSize)
{
var divisions = await _sender.Send(new GetDivisionsQuery
{
PageNumber = pageNumber,
PageSize = pageSize
});
Response.Headers.Add("X-Pagination", JsonConvert.SerializeObject(new
{
divisions.CurrentPage,
divisions.PageSize,
divisions.TotalCount,
divisions.TotalPages
}));
return Ok(divisions);
}
[HttpGet("{id}")]
public async Task<ActionResult> GetDivisionById(int id)
{
var division = await _sender.Send(new GetDivisionByIdQuery
{
DivisionId = id
});
return Ok(division);
}
}
}

View File

@@ -0,0 +1,69 @@
using System;
using System.Collections.Generic;
using Divisions.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;
namespace Divisions.DbContexts
{
public partial class DivisionsContext : DbContext
{
public DivisionsContext()
{
}
public DivisionsContext(DbContextOptions<DivisionsContext> options)
: base(options)
{
}
public virtual DbSet<Division> Divisions { get; set; } = null!;
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
#warning To protect potentially sensitive information in your connection string, you should move it out of source code. You can avoid scaffolding the connection string by using the Name= syntax to read it from configuration - see https://go.microsoft.com/fwlink/?linkid=2131148. For more guidance on storing connection strings, see http://go.microsoft.com/fwlink/?LinkId=723263.
optionsBuilder.UseNpgsql("Host=localhost;Port=5410;Database=divisions;Username=postgres;Password=postgres");
}
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Division>(entity =>
{
entity.HasNoKey();
entity.ToTable("division");
entity.Property(e => e.Abbreviation).HasColumnName("abbreviation");
entity.Property(e => e.Active).HasColumnName("active");
entity.Property(e => e.HasWildcard).HasColumnName("hasWildcard");
entity.Property(e => e.Id).HasColumnName("id");
entity.Property(e => e.LeagueId).HasColumnName("leagueId");
entity.Property(e => e.Link).HasColumnName("link");
entity.Property(e => e.Name).HasColumnName("name");
entity.Property(e => e.NameShort).HasColumnName("nameShort");
entity.Property(e => e.NumPlayoffTeams).HasColumnName("numPlayoffTeams");
entity.Property(e => e.Season).HasColumnName("season");
entity.Property(e => e.SortOrder).HasColumnName("sortOrder");
entity.Property(e => e.SportId).HasColumnName("sportId");
});
OnModelCreatingPartial(modelBuilder);
}
partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
}
}

View File

@@ -0,0 +1,46 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<DockerComposeProjectPath>docker-compose.dcproj</DockerComposeProjectPath>
<UserSecretsId>07d66bce-2467-4c09-8d6a-48491296895e</UserSecretsId>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.14" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.14">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="6.0.8" />
<PackageReference Include="MediatR" Version="11.1.0" />
<PackageReference Include="MediatR.Extensions.Microsoft.DependencyInjection" Version="11.1.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
</ItemGroup>
<ItemGroup>
<None Remove="Microsoft.EntityFrameworkCore" />
<None Remove="Microsoft.EntityFrameworkCore.Tools" />
<None Remove="Npgsql.EntityFrameworkCore.PostgreSQL" />
<None Remove="MediatR" />
<None Remove="MediatR.Extensions.Microsoft.DependencyInjection" />
<None Remove="DbContexts\" />
<None Remove="Controllers\" />
<None Remove="Handlers\" />
<None Remove="Queries\" />
<None Remove="Helpers\" />
<None Remove="Commands\" />
<None Remove="Newtonsoft.Json" />
</ItemGroup>
<ItemGroup>
<Folder Include="DbContexts\" />
<Folder Include="Controllers\" />
<Folder Include="Handlers\" />
<Folder Include="Queries\" />
<Folder Include="Helpers\" />
<Folder Include="Commands\" />
</ItemGroup>
</Project>

31
divisions/Divisions.sln Normal file
View File

@@ -0,0 +1,31 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 25.0.1704.2
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Divisions", "Divisions.csproj", "{12C34E18-6743-41CA-84A9-869AE3380A00}"
EndProject
Project("{E53339B2-1760-4266-BCC7-CA923CBCF16C}") = "docker-compose", "docker-compose.dcproj", "{45DAD415-0174-4434-8A71-B31EC558BB4B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{12C34E18-6743-41CA-84A9-869AE3380A00}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{12C34E18-6743-41CA-84A9-869AE3380A00}.Debug|Any CPU.Build.0 = Debug|Any CPU
{12C34E18-6743-41CA-84A9-869AE3380A00}.Release|Any CPU.ActiveCfg = Release|Any CPU
{12C34E18-6743-41CA-84A9-869AE3380A00}.Release|Any CPU.Build.0 = Release|Any CPU
{45DAD415-0174-4434-8A71-B31EC558BB4B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{45DAD415-0174-4434-8A71-B31EC558BB4B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{45DAD415-0174-4434-8A71-B31EC558BB4B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{45DAD415-0174-4434-8A71-B31EC558BB4B}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {4ADED0C0-1E06-4BEB-99D1-9190772B5244}
EndGlobalSection
EndGlobal

22
divisions/Dockerfile Normal file
View File

@@ -0,0 +1,22 @@
#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["Divisions.csproj", "."]
RUN dotnet restore "./Divisions.csproj"
COPY . .
WORKDIR "/src/."
RUN dotnet build "Divisions.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "Divisions.csproj" -c Release -o /app/publish /p:UseAppHost=false
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "Divisions.dll"]

View File

@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
namespace Divisions.Entities
{
public partial class Division
{
public int? Id { get; set; }
public string? Name { get; set; }
public int? Season { get; set; }
public string? NameShort { get; set; }
public string? Link { get; set; }
public string? Abbreviation { get; set; }
public int? LeagueId { get; set; }
public int? SportId { get; set; }
public string? HasWildcard { get; set; }
public int? SortOrder { get; set; }
public int? NumPlayoffTeams { get; set; }
public string? Active { get; set; }
}
}

View File

@@ -0,0 +1,25 @@
using System;
using Divisions.DbContexts;
using Divisions.Entities;
using Divisions.Queries;
using MediatR;
using Microsoft.EntityFrameworkCore;
namespace Divisions.Handlers
{
public class GetDivisionByIdQueryHandler : IRequestHandler<GetDivisionByIdQuery, Division>
{
private readonly DivisionsContext _dbContext;
public GetDivisionByIdQueryHandler(DivisionsContext dbContext)
{
_dbContext = dbContext ?? throw new ArgumentNullException(nameof(dbContext));
}
public async Task<Division> Handle(GetDivisionByIdQuery request, CancellationToken cancellation)
{
return await _dbContext.Divisions.Where(d => d.Id == request.DivisionId).FirstOrDefaultAsync();
}
}
}

View File

@@ -0,0 +1,26 @@
using System;
using Divisions.DbContexts;
using Divisions.Entities;
using Divisions.Helpers;
using Divisions.Queries;
using MediatR;
using Microsoft.EntityFrameworkCore;
namespace Divisions.Handlers
{
public class GetDivisionsQueryHandler : IRequestHandler<GetDivisionsQuery, PagedList<Division>>
{
private readonly DivisionsContext _dbContext;
public GetDivisionsQueryHandler(DivisionsContext dbContext)
{
_dbContext = dbContext ?? throw new ArgumentNullException(nameof(dbContext));
}
public async Task<PagedList<Division>> Handle(GetDivisionsQuery request, CancellationToken cancellationToken)
{
return PagedList<Division>.ToPagedList(await _dbContext.Divisions.ToListAsync(), request.PageNumber, request.PageSize);
}
}
}

View File

@@ -0,0 +1,32 @@
using System;
namespace Divisions.Helpers
{
public class PagedList<T> : List<T>
{
public int CurrentPage { get; set; }
public int PageSize { get; private set; }
public int TotalCount { get; private set; }
public int TotalPages { get; private set; }
public PagedList(List<T> items, int count, int pageNumber, int pageSize)
{
CurrentPage = pageNumber;
PageSize = pageSize;
TotalCount = count;
TotalPages = (int)Math.Ceiling(count / (double)pageSize);
AddRange(items);
}
public static PagedList<T> ToPagedList(List<T> source, int pageNumber, int pageSize)
{
var count = source.Count();
var items = source.Skip((pageNumber - 1) * pageSize)
.Take(pageSize)
.ToList();
return new PagedList<T>(items, count, pageNumber, pageSize);
}
}
}

36
divisions/Program.cs Normal file
View File

@@ -0,0 +1,36 @@
using Divisions.DbContexts;
using MediatR;
using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddMediatR(typeof(Program));
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddDbContext<DivisionsContext>(dbContextOptions =>
dbContextOptions.UseNpgsql(builder.Configuration["ConnectionStrings:DBConnectionString"])
);
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();

View File

@@ -0,0 +1,30 @@
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:13971",
"sslPort": 44378
}
},
"profiles": {
"Divisions": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "https://localhost:75100;http://localhost:5510",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@@ -0,0 +1,12 @@
using System;
using Divisions.Entities;
using MediatR;
namespace Divisions.Queries
{
public record GetDivisionByIdQuery : IRequest<Division>
{
public int DivisionId { get; set; }
}
}

View File

@@ -0,0 +1,14 @@
using System;
using Divisions.Entities;
using Divisions.Helpers;
using MediatR;
namespace Divisions.Queries
{
public record GetDivisionsQuery : IRequest<PagedList<Division>>
{
public int PageNumber { get; set; }
public int PageSize { get; set; }
}
}

View File

@@ -0,0 +1,12 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"DBConnectionString": "Host=localhost;Port=5410;Database=divisions;Username=postgres;Password=postgres"
}
}

View File

@@ -0,0 +1,10 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" Sdk="Microsoft.Docker.Sdk" DefaultTargets="Build">
<PropertyGroup Label="Globals">
<ProjectVersion>2.1</ProjectVersion>
<DockerTargetOS>Linux</DockerTargetOS>
<ProjectGuid>{45DAD415-0174-4434-8A71-B31EC558BB4B}</ProjectGuid>
<DockerLaunchBrowser>True</DockerLaunchBrowser>
<DockerServiceUrl>{Scheme}://localhost:{ServicePort}/swagger</DockerServiceUrl>
<DockerServiceName>divisions</DockerServiceName>
</PropertyGroup>
<ItemGroup>
<None Include="docker-compose.override.yml">
<DependentUpon>docker-compose.yml</DependentUpon>
</None>
<None Include="docker-compose.yml" />
<None Include=".dockerignore" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,13 @@
version: '3.4'
services:
divisions:
environment:
- ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_URLS=https://+:443;http://+:80
ports:
- "80"
- "443"
volumes:
- ~/.aspnet/https:/root/.aspnet/https:ro
- ~/.microsoft/usersecrets:/root/.microsoft/usersecrets:ro

View File

@@ -0,0 +1,8 @@
version: '3.4'
services:
divisions:
image: ${DOCKER_REGISTRY-}divisions
build:
context: .
dockerfile: ./Dockerfile