From 02b83efc88326275a70cf86baf65ff3199be5818 Mon Sep 17 00:00:00 2001 From: Lucas Morgan Date: Thu, 10 Nov 2022 19:25:55 -0600 Subject: [PATCH] yep --- Shogi.Api/Controllers/SessionsController.cs | 4 +-- Shogi.Api/Extensions/ContractsExtensions.cs | 1 + Shogi.Api/Repositories/Dto/MoveDto.cs | 2 +- Shogi.Api/Repositories/SessionRepository.cs | 12 ++++++- .../Api/Commands/MovePieceCommand.cs | 33 ++++++++++++++++++- .../Session/Stored Procedures/CreateMove.sql | 9 +++++ Shogi.Database/Session/Tables/Move.sql | 12 +++---- Shogi.Database/Shogi.Database.sqlproj | 1 + Shogi.Domain/Aggregates/Session.cs | 2 +- 9 files changed, 64 insertions(+), 12 deletions(-) create mode 100644 Shogi.Database/Session/Stored Procedures/CreateMove.sql diff --git a/Shogi.Api/Controllers/SessionsController.cs b/Shogi.Api/Controllers/SessionsController.cs index 92b7b30..6d8197b 100644 --- a/Shogi.Api/Controllers/SessionsController.cs +++ b/Shogi.Api/Controllers/SessionsController.cs @@ -39,7 +39,7 @@ public class SessionsController : ControllerBase public async Task CreateSession([FromBody] CreateSessionCommand request) { var userId = User.GetShogiUserId(); - var session = new Domain.Aggregates.Session(request.Name, userId); + var session = new Domain.Session(request.Name, userId); try { await sessionRepository.CreateSession(session); @@ -126,7 +126,7 @@ public class SessionsController : ControllerBase } else { - session.Board.Move(command.From!, command.To, command.IsPromotion); + session.Board.Move(command.From!, command.To, command.IsPromotion!.Value); } } catch (InvalidOperationException) diff --git a/Shogi.Api/Extensions/ContractsExtensions.cs b/Shogi.Api/Extensions/ContractsExtensions.cs index 472da1f..9750799 100644 --- a/Shogi.Api/Extensions/ContractsExtensions.cs +++ b/Shogi.Api/Extensions/ContractsExtensions.cs @@ -50,6 +50,7 @@ public static class ContractsExtensions public static Dictionary ToContract(this ReadOnlyDictionary boardState) => boardState.ToDictionary(kvp => kvp.Key, kvp => kvp.Value?.ToContract()); + public static Domain.WhichPiece? ToDomain(this WhichPiece? piece) => piece.HasValue ? piece.Value.ToDomain() : null; public static Domain.WhichPiece ToDomain(this WhichPiece piece) { return piece switch diff --git a/Shogi.Api/Repositories/Dto/MoveDto.cs b/Shogi.Api/Repositories/Dto/MoveDto.cs index f6e2bd3..69b19fa 100644 --- a/Shogi.Api/Repositories/Dto/MoveDto.cs +++ b/Shogi.Api/Repositories/Dto/MoveDto.cs @@ -5,6 +5,6 @@ namespace Shogi.Api.Repositories.Dto; /// /// Useful with Dapper to read from database. /// -public readonly record struct MoveDto(string From, string To, bool IsPromotion, WhichPiece? PieceFromHand) +public readonly record struct MoveDto(string? From, string To, bool? IsPromotion, WhichPiece? PieceFromHand) { } diff --git a/Shogi.Api/Repositories/SessionRepository.cs b/Shogi.Api/Repositories/SessionRepository.cs index 2c9bcd5..b863822 100644 --- a/Shogi.Api/Repositories/SessionRepository.cs +++ b/Shogi.Api/Repositories/SessionRepository.cs @@ -1,6 +1,7 @@ using Dapper; +using Shogi.Api.Extensions; using Shogi.Api.Repositories.Dto; -using Shogi.Domain.Aggregates; +using Shogi.Domain; using System.Data; using System.Data.SqlClient; @@ -65,6 +66,15 @@ public class SessionRepository : ISessionRepository } return session; } + + public async Task CreateMove(string sessionName, Contracts.Api.MovePieceCommand command) + { + using var connection = new SqlConnection(connectionString); + await connection.ExecuteAsync( + "session.CreateMove", + new { }, + commandType: CommandType.StoredProcedure); + } } public interface ISessionRepository diff --git a/Shogi.Contracts/Api/Commands/MovePieceCommand.cs b/Shogi.Contracts/Api/Commands/MovePieceCommand.cs index 56a94d8..3854113 100644 --- a/Shogi.Contracts/Api/Commands/MovePieceCommand.cs +++ b/Shogi.Contracts/Api/Commands/MovePieceCommand.cs @@ -7,6 +7,33 @@ namespace Shogi.Contracts.Api; public class MovePieceCommand : IValidatableObject { + /// + /// For serialization. + /// + public MovePieceCommand() + { + To = string.Empty; + } + + /// + /// Move a piece on the board. + /// + public MovePieceCommand(string from, string to, bool isPromotion) + { + From = from; + To = to; + IsPromotion = isPromotion; + } + + /// + /// Add a piece to the board from the hand. + /// + public MovePieceCommand(WhichPiece pieceFromHand, string to) + { + PieceFromHand = pieceFromHand; + To = to; + } + /// /// Mutually exclusive with . /// Set this property to indicate moving a piece from the hand onto the board. @@ -26,7 +53,7 @@ public class MovePieceCommand : IValidatableObject [Required] public string To { get; set; } - public bool IsPromotion { get; set; } + public bool? IsPromotion { get; set; } public IEnumerable Validate(ValidationContext validationContext) { @@ -34,6 +61,10 @@ public class MovePieceCommand : IValidatableObject { yield return new ValidationResult($"{nameof(PieceFromHand)} and {nameof(From)} are mutually exclusive properties."); } + if (PieceFromHand.HasValue && IsPromotion.HasValue) + { + yield return new ValidationResult($"{nameof(PieceFromHand)} and {nameof(IsPromotion)} are mutually exclusive properties."); + } if (!Regex.IsMatch(To, "[A-I][1-9]")) { yield return new ValidationResult($"{nameof(To)} must be a valid board position, between A1 and I9"); diff --git a/Shogi.Database/Session/Stored Procedures/CreateMove.sql b/Shogi.Database/Session/Stored Procedures/CreateMove.sql new file mode 100644 index 0000000..5f95032 --- /dev/null +++ b/Shogi.Database/Session/Stored Procedures/CreateMove.sql @@ -0,0 +1,9 @@ +CREATE PROCEDURE [session].[CreateMove] + @To VARCHAR(2), + @From VARCHAR(2), + @IsPromotion BIT, + @PieceName NVARCHAR(13), + @SessionName [session].[SessionName] +AS + SELECT @param1, @param2 +RETURN 0 diff --git a/Shogi.Database/Session/Tables/Move.sql b/Shogi.Database/Session/Tables/Move.sql index 4339650..4b4b2f3 100644 --- a/Shogi.Database/Session/Tables/Move.sql +++ b/Shogi.Database/Session/Tables/Move.sql @@ -1,11 +1,11 @@ CREATE TABLE [session].[Move] ( - [Id] INT NOT NULL PRIMARY KEY IDENTITY, - [SessionId] BIGINT NOT NULL, - [From] VARCHAR(2) NOT NULL, - [To] VARCHAR(2) NOT NULL, - [IsPromotion] BIT NOT NULL, - [PieceIdFromHand] INT NULL + [Id] INT NOT NULL PRIMARY KEY IDENTITY, + [SessionId] BIGINT NOT NULL, + [To] VARCHAR(2) NOT NULL, + [From] VARCHAR(2) NULL, + [IsPromotion] BIT NULL, + [PieceIdFromHand] INT NULL CONSTRAINT [Cannot end where you start] CHECK ([From] <> [To]), diff --git a/Shogi.Database/Shogi.Database.sqlproj b/Shogi.Database/Shogi.Database.sqlproj index a9e9bed..a655f76 100644 --- a/Shogi.Database/Shogi.Database.sqlproj +++ b/Shogi.Database/Shogi.Database.sqlproj @@ -87,6 +87,7 @@ + diff --git a/Shogi.Domain/Aggregates/Session.cs b/Shogi.Domain/Aggregates/Session.cs index 3309ebf..1c59c90 100644 --- a/Shogi.Domain/Aggregates/Session.cs +++ b/Shogi.Domain/Aggregates/Session.cs @@ -1,6 +1,6 @@ using Shogi.Domain.ValueObjects; -namespace Shogi.Domain.Aggregates; +namespace Shogi.Domain; public class Session {