diff --git a/Shogi.Contracts/Api/Queries/ReadSessionResponse.cs b/Shogi.Contracts/Api/Queries/ReadSessionResponse.cs
index f5e9191..e8300ab 100644
--- a/Shogi.Contracts/Api/Queries/ReadSessionResponse.cs
+++ b/Shogi.Contracts/Api/Queries/ReadSessionResponse.cs
@@ -2,7 +2,7 @@
namespace Shogi.Contracts.Api;
- public class ReadSessionResponse
- {
- public Session Session { get; set; }
- }
+public class ReadSessionResponse
+{
+ public Session Session { get; set; }
+}
diff --git a/Shogi.Contracts/Types/Session.cs b/Shogi.Contracts/Types/Session.cs
index d781feb..0a67ed1 100644
--- a/Shogi.Contracts/Types/Session.cs
+++ b/Shogi.Contracts/Types/Session.cs
@@ -1,10 +1,10 @@
-namespace Shogi.Contracts.Types
+namespace Shogi.Contracts.Types;
+
+public class Session
{
- public class Session
- {
- public string Player1 { get; set; }
- public string? Player2 { get; set; }
- public string SessionName { get; set; }
- public BoardState BoardState { get; set; }
- }
+ public string Player1 { get; set; } = string.Empty;
+ public string? Player2 { get; set; }
+ public string SessionName { get; set; } = string.Empty;
+ public bool GameOver { get; set; }
+ public BoardState BoardState { get; set; }
}
diff --git a/Shogi.Database/Session/Stored Procedures/CreateSession.sql b/Shogi.Database/Session/Stored Procedures/CreateSession.sql
index 8d68ac2..78cc9a8 100644
--- a/Shogi.Database/Session/Stored Procedures/CreateSession.sql
+++ b/Shogi.Database/Session/Stored Procedures/CreateSession.sql
@@ -1,24 +1,14 @@
CREATE PROCEDURE [session].[CreateSession]
- @SessionName [session].[SessionName],
- @Player1Name [user].[UserName],
@InitialBoardStateDocument [session].[JsonDocument]
AS
BEGIN
+ SET NOCOUNT ON
-SET NOCOUNT ON
-SET XACT_ABORT ON
-
-BEGIN TRANSACTION
- INSERT INTO [session].[Session] ([Name], Player1Id)
+ INSERT INTO [session].[Session] ([Name], BoardState, Player1Id)
SELECT
- @SessionName,
+ JSON_VALUE(@InitialBoardStateDocument, '$.Name'),
+ @InitialBoardStateDocument,
Id
FROM [user].[User]
- WHERE [Name] = @Player1Name;
-
- INSERT INTO [session].[BoardState] (Document, SessionId)
- VALUES
- (@InitialBoardStateDocument, SCOPE_IDENTITY());
-COMMIT
-
+ WHERE [Name] = JSON_VALUE(@InitialBoardStateDocument, '$.Player1');
END
\ No newline at end of file
diff --git a/Shogi.Database/Session/Stored Procedures/ReadAllSessionsMetadata.sql b/Shogi.Database/Session/Stored Procedures/ReadAllSessionsMetadata.sql
index 2ff1c70..88252d5 100644
--- a/Shogi.Database/Session/Stored Procedures/ReadAllSessionsMetadata.sql
+++ b/Shogi.Database/Session/Stored Procedures/ReadAllSessionsMetadata.sql
@@ -1,12 +1,13 @@
CREATE PROCEDURE [session].[ReadAllSessionsMetadata]
AS
+BEGIN
+ SET NOCOUNT ON;
-SET NOCOUNT ON;
-
-SELECT
- [Name],
- CASE
- WHEN Player2Id IS NULL THEN 1
- ELSE 2
- END AS PlayerCount
-FROM [session].[Session];
+ SELECT
+ [Name],
+ CASE
+ WHEN Player2Id IS NULL THEN 1
+ ELSE 2
+ END AS PlayerCount
+ FROM [session].[Session];
+END
\ No newline at end of file
diff --git a/Shogi.Database/Session/Stored Procedures/ReadSession.sql b/Shogi.Database/Session/Stored Procedures/ReadSession.sql
new file mode 100644
index 0000000..5bf4d8c
--- /dev/null
+++ b/Shogi.Database/Session/Stored Procedures/ReadSession.sql
@@ -0,0 +1,17 @@
+CREATE PROCEDURE [session].[ReadSession]
+ @Name [session].[SessionName]
+AS
+BEGIN
+ SET NOCOUNT ON
+
+ SELECT
+ sess.[Name],
+ GameOver,
+ BoardState,
+ p1.[Name] as Player1,
+ p2.[Name] as Player2
+ FROM [session].[Session] sess
+ INNER JOIN [user].[User] p1 on sess.Player1Id = p1.Id
+ LEFT JOIN [user].[User] p2 on sess.Player2Id = p2.Id
+ WHERE sess.[Name] = @Name;
+END
diff --git a/Shogi.Database/Session/Tables/BoardState.sql b/Shogi.Database/Session/Tables/BoardState.sql
deleted file mode 100644
index e55d176..0000000
--- a/Shogi.Database/Session/Tables/BoardState.sql
+++ /dev/null
@@ -1,10 +0,0 @@
-CREATE TABLE [session].[BoardState]
-(
- [Id] BIGINT NOT NULL PRIMARY KEY IDENTITY,
- [Document] NVARCHAR(max) NOT NULL,
- [SessionId] BIGINT NOT NULL,
-
- CONSTRAINT [Document must be json] CHECK (isjson(Document)=1),
- CONSTRAINT FK_BoardState_Session FOREIGN KEY (SessionId)
- REFERENCES [session].[Session] (Id) ON DELETE CASCADE ON UPDATE CASCADE
-)
diff --git a/Shogi.Database/Session/Tables/Session.sql b/Shogi.Database/Session/Tables/Session.sql
index f570c64..0497464 100644
--- a/Shogi.Database/Session/Tables/Session.sql
+++ b/Shogi.Database/Session/Tables/Session.sql
@@ -1,12 +1,13 @@
CREATE TABLE [session].[Session]
(
Id BIGINT NOT NULL PRIMARY KEY IDENTITY,
- [Name] [session].[SessionName] NOT NULL UNIQUE,
Created DATETIMEOFFSET NOT NULL DEFAULT SYSDATETIMEOFFSET(),
- GameOver BIT NOT NULL DEFAULT 0,
+ DomainDocument [session].[JsonDocument] NOT NULL,
+ [Name] AS JSON_VALUE(DomainDocument, '$.Name') UNIQUE,
Player1Id BIGINT NOT NULL,
Player2Id BIGINT NULL,
+ CONSTRAINT [BoardState must be json] CHECK (isjson(DomainDocument)=1),
CONSTRAINT FK_Player1_User FOREIGN KEY (Player1Id) REFERENCES [user].[User] (Id)
ON DELETE CASCADE
ON UPDATE CASCADE,
diff --git a/Shogi.Database/Shogi.Database.sqlproj b/Shogi.Database/Shogi.Database.sqlproj
index ea8b694..eee8fd4 100644
--- a/Shogi.Database/Shogi.Database.sqlproj
+++ b/Shogi.Database/Shogi.Database.sqlproj
@@ -71,7 +71,6 @@
-
@@ -84,6 +83,7 @@
+
diff --git a/Shogi.Domain/Aggregates/Session.cs b/Shogi.Domain/Aggregates/Session.cs
index 5bd0afc..f5bf0b2 100644
--- a/Shogi.Domain/Aggregates/Session.cs
+++ b/Shogi.Domain/Aggregates/Session.cs
@@ -8,11 +8,11 @@ namespace Shogi.Domain;
/// The board is always from Player1's perspective.
/// [0,0] is the lower-left position, [8,8] is the higher-right position
///
-public sealed class Session
+public sealed class ShogiBoard
{
private readonly StandardRules rules;
- public Session(string name, BoardState initialState, string player1, string? player2 = null)
+ public ShogiBoard(string name, BoardState initialState, string player1, string? player2 = null)
{
Name = name;
Player1 = player1;
@@ -23,8 +23,6 @@ public sealed class Session
public BoardState BoardState { get; }
public string Name { get; }
- public string Player1 { get; }
- public string? Player2 { get; }
///
/// Move a piece from a board position to another board position, potentially capturing an opponents piece. Respects all rules of the game.
diff --git a/Shogi.Sockets/Controllers/SessionController.cs b/Shogi.Sockets/Controllers/SessionController.cs
index 865041f..c9993d3 100644
--- a/Shogi.Sockets/Controllers/SessionController.cs
+++ b/Shogi.Sockets/Controllers/SessionController.cs
@@ -37,7 +37,7 @@ public class SessionController : ControllerBase
{
var userId = User.GetShogiUserId();
if (string.IsNullOrWhiteSpace(userId)) return this.Unauthorized();
- var session = new Domain.Session(request.Name, Domain.BoardState.StandardStarting, userId);
+ var session = new Domain.ShogiBoard(request.Name, Domain.BoardState.StandardStarting, userId);
try
{
await sessionRepository.CreateSession(session);
@@ -161,6 +161,13 @@ public class SessionController : ControllerBase
});
}
+ [HttpGet("{name}")]
+ public async Task> GetSession(string name)
+ {
+ await Task.CompletedTask;
+ return new ReadSessionResponse();
+ }
+
//[HttpPut("{sessionName}")]
//public async Task PutJoinSession([FromRoute] string sessionName)
//{
diff --git a/Shogi.Sockets/Repositories/CouchModels/CouchDocument.cs b/Shogi.Sockets/Repositories/CouchModels/CouchDocument.cs
index 95f743d..ecf2f41 100644
--- a/Shogi.Sockets/Repositories/CouchModels/CouchDocument.cs
+++ b/Shogi.Sockets/Repositories/CouchModels/CouchDocument.cs
@@ -3,24 +3,25 @@ using System;
namespace Shogi.Api.Repositories.CouchModels
{
- public abstract class CouchDocument
- {
- [JsonProperty("_id")] public string Id { get; set; }
- [JsonProperty("_rev")] public string? RevisionId { get; set; }
- public WhichDocumentType DocumentType { get; }
- public DateTimeOffset CreatedDate { get; set; }
+ [Obsolete]
+ public abstract class CouchDocument
+ {
+ [JsonProperty("_id")] public string Id { get; set; }
+ [JsonProperty("_rev")] public string? RevisionId { get; set; }
+ public WhichDocumentType DocumentType { get; }
+ public DateTimeOffset CreatedDate { get; set; }
- public CouchDocument(WhichDocumentType documentType)
- : this(string.Empty, documentType, DateTimeOffset.UtcNow) { }
+ public CouchDocument(WhichDocumentType documentType)
+ : this(string.Empty, documentType, DateTimeOffset.UtcNow) { }
- public CouchDocument(string id, WhichDocumentType documentType)
- : this(id, documentType, DateTimeOffset.UtcNow) { }
+ public CouchDocument(string id, WhichDocumentType documentType)
+ : this(id, documentType, DateTimeOffset.UtcNow) { }
- public CouchDocument(string id, WhichDocumentType documentType, DateTimeOffset createdDate)
- {
- Id = id;
- DocumentType = documentType;
- CreatedDate = createdDate;
- }
- }
+ public CouchDocument(string id, WhichDocumentType documentType, DateTimeOffset createdDate)
+ {
+ Id = id;
+ DocumentType = documentType;
+ CreatedDate = createdDate;
+ }
+ }
}
diff --git a/Shogi.Sockets/Repositories/Dto/SessionDto.cs b/Shogi.Sockets/Repositories/Dto/SessionDto.cs
new file mode 100644
index 0000000..7b70d5b
--- /dev/null
+++ b/Shogi.Sockets/Repositories/Dto/SessionDto.cs
@@ -0,0 +1,11 @@
+namespace Shogi.Api.Repositories.Dto
+{
+ public class SessionDto
+ {
+ public string Name { get; set; }
+ public string Player1 { get; set; }
+ public string Player2 { get; set; }
+ public bool GameOver { get; set; }
+ public string BoardState { get; set; }
+ }
+}
diff --git a/Shogi.Sockets/Repositories/QueryRepository.cs b/Shogi.Sockets/Repositories/QueryRepository.cs
index 14d0eaa..ca336dd 100644
--- a/Shogi.Sockets/Repositories/QueryRepository.cs
+++ b/Shogi.Sockets/Repositories/QueryRepository.cs
@@ -6,23 +6,33 @@ namespace Shogi.Api.Repositories;
public class QueryRepository : IQueryRespository
{
- private readonly string connectionString;
+ private readonly string connectionString;
- public QueryRepository(IConfiguration configuration)
- {
- connectionString = configuration.GetConnectionString("ShogiDatabase");
- }
+ public QueryRepository(IConfiguration configuration)
+ {
+ connectionString = configuration.GetConnectionString("ShogiDatabase");
+ }
- public async Task> ReadAllSessionsMetadata()
- {
- using var connection = new SqlConnection(connectionString);
- return await connection.QueryAsync(
- "session.ReadAllSessionsMetadata",
- commandType: System.Data.CommandType.StoredProcedure);
- }
+ public async Task> ReadAllSessionsMetadata()
+ {
+ using var connection = new SqlConnection(connectionString);
+ return await connection.QueryAsync(
+ "session.ReadAllSessionsMetadata",
+ commandType: System.Data.CommandType.StoredProcedure);
+ }
+
+ public async Task ReadSession(string name)
+ {
+ using var connection = new SqlConnection(connectionString);
+ var results = await connection.QueryAsync(
+ "session.ReadSession",
+ commandType: System.Data.CommandType.StoredProcedure);
+ return results.SingleOrDefault();
+ }
}
public interface IQueryRespository
{
- Task> ReadAllSessionsMetadata();
+ Task> ReadAllSessionsMetadata();
+ Task ReadSession(string name);
}
\ No newline at end of file
diff --git a/Shogi.Sockets/Repositories/SessionRepository.cs b/Shogi.Sockets/Repositories/SessionRepository.cs
index bf3570e..d7e2d9e 100644
--- a/Shogi.Sockets/Repositories/SessionRepository.cs
+++ b/Shogi.Sockets/Repositories/SessionRepository.cs
@@ -1,4 +1,5 @@
using Dapper;
+using Shogi.Api.Repositories.Dto;
using Shogi.Domain;
using System.Data;
using System.Data.SqlClient;
@@ -8,30 +9,48 @@ namespace Shogi.Api.Repositories;
public class SessionRepository : ISessionRepository
{
- private readonly string connectionString;
+ private readonly string connectionString;
- public SessionRepository(IConfiguration configuration)
- {
- connectionString = configuration.GetConnectionString("ShogiDatabase");
- }
+ public SessionRepository(IConfiguration configuration)
+ {
+ connectionString = configuration.GetConnectionString("ShogiDatabase");
+ }
- public async Task CreateSession(Session session)
- {
- var initialBoardState = JsonSerializer.Serialize(session.BoardState);
- using var connection = new SqlConnection(connectionString);
- await connection.ExecuteAsync(
- "session.CreateSession",
- new
- {
- SessionName = session.Name,
- Player1Name = session.Player1,
- InitialBoardStateDocument = initialBoardState
- },
- commandType: CommandType.StoredProcedure);
- }
+ public async Task CreateSession(ShogiBoard session, string player1)
+ {
+ var initialBoardState = JsonSerializer.Serialize(session.BoardState);
+ using var connection = new SqlConnection(connectionString);
+ await connection.ExecuteAsync(
+ "session.CreateSession",
+ new
+ {
+ SessionName = session.Name,
+ Player1Name = player1,
+ InitialBoardStateDocument = initialBoardState
+ },
+ commandType: CommandType.StoredProcedure);
+ }
+
+ public async Task ReadSession(string name)
+ {
+ using var connection = new SqlConnection(connectionString);
+ var results = await connection.QueryAsync(
+ "session.ReadSession",
+ commandType: CommandType.StoredProcedure);
+
+ if (!results.Any())
+ {
+ return null;
+ }
+
+ var dto = results.First();
+ return new Session(
+ name: dto.Name,
+ initialState: JsonSerializer.Deserialize< dto.BoardState)
+ }
}
public interface ISessionRepository
{
- Task CreateSession(Session session);
+ Task CreateSession(ShogiBoard session);
}
\ No newline at end of file
diff --git a/Shogi.Sockets/Shogi.Api.csproj b/Shogi.Sockets/Shogi.Api.csproj
index 0566d83..bf92b1c 100644
--- a/Shogi.Sockets/Shogi.Api.csproj
+++ b/Shogi.Sockets/Shogi.Api.csproj
@@ -11,6 +11,17 @@
973a1f5f-ef25-4f1c-a24d-b0fc7d016ab8
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Tests/UnitTests/ShogiShould.cs b/Tests/UnitTests/ShogiShould.cs
index 7ac9993..946dbed 100644
--- a/Tests/UnitTests/ShogiShould.cs
+++ b/Tests/UnitTests/ShogiShould.cs
@@ -457,6 +457,6 @@ namespace Shogi.Domain.UnitTests
board.InCheck.Should().Be(WhichPlayer.Player2);
}
- private static Session MockSession() => new Session("Test Session", BoardState.StandardStarting, "Test P1", "Test P2");
+ private static ShogiBoard MockSession() => new ShogiBoard("Test Session", BoardState.StandardStarting, "Test P1", "Test P2");
}
}