diff --git a/SDG-Backend-Barracuda/Models/GameModel.cs b/SDG-Backend-Barracuda/Models/GameModel.cs new file mode 100644 index 0000000..8e2cf82 --- /dev/null +++ b/SDG-Backend-Barracuda/Models/GameModel.cs @@ -0,0 +1,73 @@ +using Dapper; +using Npgsql; + +namespace SDG_Backend_Barracuda.Models; + +public record Game(int Id, string Name, string URL); +public record GameInformation(string Name, string URL); + +public interface IGameModel : IDatabaseModel +{ +} + +public class GameModel(NpgsqlDataSource dataSource) : IGameModel, IEndpointRouteHandler +{ + public static void MapEndpoints(IEndpointRouteBuilder router) + { + var gameEndpoint = router.MapGroup("/game"); + + gameEndpoint.MapPost("/", async (GameInformation input, IGameModel model) => + { + var newGame = await model.Create(input); + return Results.Created($"/game/{newGame.Id}", newGame); + }); + + gameEndpoint.MapGet("/", async (IGameModel model) => + Results.Ok(await model.GetAll())); + + gameEndpoint.MapGet("/{id}", async (int id, IGameModel model) => + await model.GetById(id) is { } g ? Results.Ok(g) : Results.NotFound()); + + gameEndpoint.MapPut("/{id}", async (int id, GameInformation input, IGameModel model) => + await model.Update(id, input) is { } g ? Results.Ok(g) : Results.NotFound()); + + gameEndpoint.MapDelete("/{id}", async (int id, IGameModel model) => + await model.Delete(id) ? Results.NoContent() : Results.NotFound()); + } + + public async Task> GetAll() + { + await using var connection = await dataSource.OpenConnectionAsync(); + var sql = """SELECT * FROM "Game";"""; + return await connection.QueryAsync(sql); + } + + public async Task GetById(int id) + { + await using var connection = await dataSource.OpenConnectionAsync(); + var sql = """SELECT * FROM "Game" WHERE "Id" = @Id;"""; + return await connection.QueryFirstOrDefaultAsync(sql, new { Id = id }); + } + + public async Task Create(GameInformation input) + { + await using var connection = await dataSource.OpenConnectionAsync(); + var sql = """INSERT INTO "Game" ("Name", "URL") VALUES (@Name, @URL) RETURNING "Id", "Name", "URL";"""; + return await connection.QuerySingleAsync(sql, input); + } + + public async Task Update(int id, GameInformation input) + { + await using var connection = await dataSource.OpenConnectionAsync(); + var sql = """UPDATE "Game" SET "Name" = @Name, "URL" = @URL WHERE "Id" = @Id RETURNING "Id", "Name", "URL";"""; + return await connection.QueryFirstOrDefaultAsync(sql, new { Id = id, input.Name, input.URL }); + } + + public async Task Delete(int id) + { + await using var connection = await dataSource.OpenConnectionAsync(); + var sql = """DELETE FROM "Game" WHERE "Id" = @Id;"""; + var rowsAffected = await connection.ExecuteAsync(sql, new { Id = id }); + return rowsAffected > 0; + } +} diff --git a/SDG-Backend-Barracuda/Program.cs b/SDG-Backend-Barracuda/Program.cs index 14d9539..5504bbc 100644 --- a/SDG-Backend-Barracuda/Program.cs +++ b/SDG-Backend-Barracuda/Program.cs @@ -15,6 +15,8 @@ builder.Services.AddNpgsqlDataSource(connectionString!); // Register Data Tables builder.Services.AddScoped(); builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); var app = builder.Build(); @@ -40,6 +42,21 @@ using (var scope = app.Services.CreateScope()) ""CardListId"" INTEGER NOT NULL REFERENCES ""CardList""(""Id"") ON DELETE CASCADE, ""SubCardListId"" INTEGER NOT NULL REFERENCES ""CardList""(""Id"") ON DELETE CASCADE, PRIMARY KEY (""CardListId"", ""SubCardListId"") + ); + CREATE TABLE IF NOT EXISTS ""Game"" ( + ""Id"" SERIAL PRIMARY KEY, + ""Name"" VARCHAR(64) NOT NULL, + ""URL"" TEXT NOT NULL + ); + CREATE TABLE IF NOT EXISTS ""Deck"" ( + ""Id"" SERIAL PRIMARY KEY, + ""Name"" TEXT NOT NULL, + ""CardListId"" INTEGER NOT NULL REFERENCES ""CardList""(""Id"") ON DELETE CASCADE + ); + CREATE TABLE IF NOT EXISTS ""DeckGame"" ( + ""DeckId"" INTEGER NOT NULL REFERENCES ""Deck""(""Id"") ON DELETE CASCADE, + ""GameId"" INTEGER NOT NULL REFERENCES ""Game""(""Id"") ON DELETE CASCADE, + PRIMARY KEY (""DeckId"", ""GameId"") );"); } @@ -53,5 +70,7 @@ app.UseHttpsRedirection(); CardModel.MapEndpoints(app); CardListModel.MapEndpoints(app); +GameModel.MapEndpoints(app); +DeckModel.MapEndpoints(app); app.Run(); \ No newline at end of file