From e8a6a4b47add62d5a5f912817528470fe17fbc0d Mon Sep 17 00:00:00 2001 From: EGREX Date: Mon, 25 Dec 2023 21:57:52 +0500 Subject: [PATCH] done --- ConsoleApp/Program.cs | 12 +++++--- Game/Domain/GameEntity.cs | 21 +++++++++----- Game/Domain/MongoGameRepository.cs | 30 ++++++++------------ Game/Domain/MongoUserRepositoty.cs | 45 +++++++++++++----------------- Game/Domain/Player.cs | 11 ++++---- Tests/TestMongoDatabase.cs | 2 +- 6 files changed, 59 insertions(+), 62 deletions(-) diff --git a/ConsoleApp/Program.cs b/ConsoleApp/Program.cs index cf39300..85268b3 100644 --- a/ConsoleApp/Program.cs +++ b/ConsoleApp/Program.cs @@ -1,19 +1,23 @@ using System; using System.Linq; using Game.Domain; +using MongoDB.Driver; namespace ConsoleApp { class Program { - private readonly IUserRepository userRepo; - private readonly IGameRepository gameRepo; + private readonly MongoUserRepository userRepo; + private readonly MongoGameRepository gameRepo; private readonly Random random = new Random(); private Program(string[] args) { - userRepo = new InMemoryUserRepository(); - gameRepo = new InMemoryGameRepository(); + var mongoConnectionString = Environment.GetEnvironmentVariable("PROJECT5100_MONGO_CONNECTION_STRING") + ?? "mongodb+srv://loginMongo:Q8I4k4zhefpOEq5M@cluster0.jwlsdu6.mongodb.net/"; + var mongoClient = new MongoClient(mongoConnectionString); + userRepo = new MongoUserRepository(mongoClient.GetDatabase("users")); + gameRepo = new MongoGameRepository(mongoClient.GetDatabase("game")); } public static void Main(string[] args) diff --git a/Game/Domain/GameEntity.cs b/Game/Domain/GameEntity.cs index ec7b5ec..b36a4db 100644 --- a/Game/Domain/GameEntity.cs +++ b/Game/Domain/GameEntity.cs @@ -1,18 +1,21 @@ using System; using System.Collections.Generic; using System.Linq; +using MongoDB.Bson.Serialization.Attributes; namespace Game.Domain { public class GameEntity - { + { + [BsonElement] private readonly List players; - + public GameEntity(int turnsCount) : this(Guid.Empty, GameStatus.WaitingToStart, turnsCount, 0, new List()) { } - + + [BsonConstructor] public GameEntity(Guid id, GameStatus status, int turnsCount, int currentTurnIndex, List players) { Id = id; @@ -21,7 +24,8 @@ public GameEntity(Guid id, GameStatus status, int turnsCount, int currentTurnInd CurrentTurnIndex = currentTurnIndex; this.players = players; } - + + [BsonElement] public Guid Id { get; @@ -30,11 +34,14 @@ public Guid Id } public IReadOnlyList Players => players.AsReadOnly(); - + + [BsonElement] public int TurnsCount { get; } - + + [BsonElement] public int CurrentTurnIndex { get; private set; } - + + [BsonElement] public GameStatus Status { get; private set; } public void AddPlayer(UserEntity user) diff --git a/Game/Domain/MongoGameRepository.cs b/Game/Domain/MongoGameRepository.cs index 86873d4..19a2337 100644 --- a/Game/Domain/MongoGameRepository.cs +++ b/Game/Domain/MongoGameRepository.cs @@ -4,42 +4,34 @@ namespace Game.Domain { - // TODO Сделать по аналогии с MongoUserRepository public class MongoGameRepository : IGameRepository { + private readonly IMongoCollection gameCollection; public const string CollectionName = "games"; public MongoGameRepository(IMongoDatabase db) { + gameCollection = db.GetCollection(CollectionName); } public GameEntity Insert(GameEntity game) { - throw new NotImplementedException(); + gameCollection.InsertOne(game); + return FindById(game.Id); } - public GameEntity FindById(Guid gameId) - { - throw new NotImplementedException(); - } + public GameEntity FindById(Guid gameId) => gameCollection.Find(game => game.Id == gameId).FirstOrDefault(); - public void Update(GameEntity game) - { - throw new NotImplementedException(); - } + public void Update(GameEntity game) => gameCollection.ReplaceOne(gameEntity => gameEntity.Id == game.Id, game); - // Возвращает не более чем limit игр со статусом GameStatus.WaitingToStart - public IList FindWaitingToStart(int limit) - { - //TODO: Используй Find и Limit - throw new NotImplementedException(); - } + public IList FindWaitingToStart(int limit) => + gameCollection.Find(game => game.Status == GameStatus.WaitingToStart).Limit(limit).ToList(); - // Обновляет игру, если она находится в статусе GameStatus.WaitingToStart public bool TryUpdateWaitingToStart(GameEntity game) { - //TODO: Для проверки успешности используй IsAcknowledged и ModifiedCount из результата - throw new NotImplementedException(); + var result = gameCollection + .ReplaceOne(gameEntity => gameEntity.Id == game.Id && gameEntity.Status == GameStatus.WaitingToStart, game); + return result.IsAcknowledged && result.ModifiedCount > 0; } } } \ No newline at end of file diff --git a/Game/Domain/MongoUserRepositoty.cs b/Game/Domain/MongoUserRepositoty.cs index 51aeba5..3f8d905 100644 --- a/Game/Domain/MongoUserRepositoty.cs +++ b/Game/Domain/MongoUserRepositoty.cs @@ -11,43 +11,36 @@ public class MongoUserRepository : IUserRepository public MongoUserRepository(IMongoDatabase database) { userCollection = database.GetCollection(CollectionName); + userCollection.Indexes.CreateOne(new CreateIndexModel(Builders.IndexKeys.Ascending(u => u.Login), + new CreateIndexOptions { Unique = true })); } public UserEntity Insert(UserEntity user) { - //TODO: Ищи в документации InsertXXX. - throw new NotImplementedException(); - } - - public UserEntity FindById(Guid id) - { - //TODO: Ищи в документации FindXXX - throw new NotImplementedException(); + userCollection.InsertOne(user); + return FindById(user.Id); } - public UserEntity GetOrCreateByLogin(string login) - { - //TODO: Это Find или Insert - throw new NotImplementedException(); - } + public UserEntity FindById(Guid id) => userCollection.Find(user => user.Id == id).FirstOrDefault(); - public void Update(UserEntity user) - { - //TODO: Ищи в документации ReplaceXXX - throw new NotImplementedException(); - } + public UserEntity GetOrCreateByLogin(string login) => + userCollection.Find(user => user.Login == login).FirstOrDefault() ?? Insert(new UserEntity {Login = login}); - public void Delete(Guid id) - { - throw new NotImplementedException(); - } + public void Update(UserEntity user) => userCollection.ReplaceOne(userEntity => userEntity.Id == user.Id, user); - // Для вывода списка всех пользователей (упорядоченных по логину) - // страницы нумеруются с единицы + public void Delete(Guid id) => userCollection.DeleteOne(user => user.Id == id); + public PageList GetPage(int pageNumber, int pageSize) { - //TODO: Тебе понадобятся SortBy, Skip и Limit - throw new NotImplementedException(); + var items = userCollection + .Find(user => true) + .SortBy(user => user.Login) + .Skip(pageSize * (pageNumber - 1)) + .Limit(pageSize) + .ToList(); + + var totalCount = userCollection.CountDocuments(d => true); + return new PageList(items, totalCount, pageNumber, pageSize); } // Не нужно реализовывать этот метод diff --git a/Game/Domain/Player.cs b/Game/Domain/Player.cs index 9c4f838..a865613 100644 --- a/Game/Domain/Player.cs +++ b/Game/Domain/Player.cs @@ -1,4 +1,5 @@ using System; +using MongoDB.Bson.Serialization.Attributes; namespace Game.Domain { @@ -7,17 +8,17 @@ namespace Game.Domain /// public class Player { + [BsonConstructor] public Player(Guid userId, string name) { UserId = userId; Name = name; } - + + [BsonElement] public Guid UserId { get; } - - /// - /// Снэпшот имени игрока на момент старта игры. Считайте, что это такое требование к игре. - /// + + [BsonElement] public string Name { get; } /// diff --git a/Tests/TestMongoDatabase.cs b/Tests/TestMongoDatabase.cs index 1dda6e0..20967a6 100644 --- a/Tests/TestMongoDatabase.cs +++ b/Tests/TestMongoDatabase.cs @@ -8,7 +8,7 @@ public static class TestMongoDatabase public static IMongoDatabase Create() { var mongoConnectionString = Environment.GetEnvironmentVariable("PROJECT5100_MONGO_CONNECTION_STRING") - ?? "mongodb://localhost:27017"; + ?? "mongodb+srv://loginMongo:Q8I4k4zhefpOEq5M@cluster0.jwlsdu6.mongodb.net/"; var mongoClient = new MongoClient(mongoConnectionString); return mongoClient.GetDatabase("game-tests"); }