From a7c4765f55fdabe97f6cf6d9cd0aa7bbb1707390 Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Sat, 4 Mar 2023 19:34:11 +0100 Subject: [PATCH] Added GameServer data model #238 --- .../bot_data/abc/api_key_repository_abc.py | 4 + .../user_joined_game_server_migration.py | 33 +++-- kdb-bot/src/bot_data/model/api_key.py | 13 ++ kdb-bot/src/bot_data/model/game_server.py | 124 ++++++++++++++++++ kdb-bot/src/bot_data/model/user.py | 14 +- .../bot_data/model/user_joined_game_server.py | 9 +- .../service/api_key_repository_service.py | 4 + ...r_joined_game_server_repository_service.py | 44 +++++-- .../service/user_repository_service.py | 86 +++--------- .../database/database_on_ready_event.py | 2 +- 10 files changed, 222 insertions(+), 111 deletions(-) create mode 100644 kdb-bot/src/bot_data/model/game_server.py diff --git a/kdb-bot/src/bot_data/abc/api_key_repository_abc.py b/kdb-bot/src/bot_data/abc/api_key_repository_abc.py index c21d22df..aaa22dbe 100644 --- a/kdb-bot/src/bot_data/abc/api_key_repository_abc.py +++ b/kdb-bot/src/bot_data/abc/api_key_repository_abc.py @@ -18,6 +18,10 @@ class ApiKeyRepositoryABC(ABC): def get_api_key(self, identifier: str, key: str) -> ApiKey: pass + @abstractmethod + def get_api_key_by_id(self, id: int) -> ApiKey: + pass + @abstractmethod def get_api_key_by_key(self, key: str) -> ApiKey: pass diff --git a/kdb-bot/src/bot_data/migration/user_joined_game_server_migration.py b/kdb-bot/src/bot_data/migration/user_joined_game_server_migration.py index e29854aa..6e1588b2 100644 --- a/kdb-bot/src/bot_data/migration/user_joined_game_server_migration.py +++ b/kdb-bot/src/bot_data/migration/user_joined_game_server_migration.py @@ -18,15 +18,15 @@ class UserJoinedGameServerMigration(MigrationABC): self._cursor.execute( str( f""" - CREATE TABLE IF NOT EXISTS `UserJoinedGameServer` ( + CREATE TABLE IF NOT EXISTS `GameServers` ( `Id` BIGINT NOT NULL AUTO_INCREMENT, - `UserId` BIGINT NOT NULL, - `GameServer` VARCHAR(255) NOT NULL, - `JoinedOn` DATETIME(6) NOT NULL, - `LeavedOn` DATETIME(6), + `Name` VARCHAR(255) NOT NULL, + `ServerId` BIGINT NOT NULL, + `ApiKeyId` BIGINT NOT NULL, `CreatedAt` DATETIME(6), `LastModifiedAt` DATETIME(6), - FOREIGN KEY (`UserId`) REFERENCES Users(`UserId`), + FOREIGN KEY (`ServerId`) REFERENCES Servers(`ServerId`), + FOREIGN KEY (`ApiKeyId`) REFERENCES ApiKeys(`Id`), PRIMARY KEY(`Id`) ); """ @@ -36,17 +36,22 @@ class UserJoinedGameServerMigration(MigrationABC): self._cursor.execute( str( f""" - ALTER TABLE Users ADD MinecraftId VARCHAR(255) NULL AFTER XP; + CREATE TABLE IF NOT EXISTS `UserJoinedGameServer` ( + `Id` BIGINT NOT NULL AUTO_INCREMENT, + `UserId` BIGINT NOT NULL, + `GameServerId` BIGINT NOT NULL, + `JoinedOn` DATETIME(6) NOT NULL, + `LeavedOn` DATETIME(6), + `CreatedAt` DATETIME(6), + `LastModifiedAt` DATETIME(6), + FOREIGN KEY (`UserId`) REFERENCES Users(`UserId`), + FOREIGN KEY (`GameServerId`) REFERENCES GameServers(`Id`), + PRIMARY KEY(`Id`) + ); """ ) ) def downgrade(self): + self._cursor.execute("DROP TABLE `GameServers`;") self._cursor.execute("DROP TABLE `UserJoinedGameServer`;") - self._cursor.execute( - str( - f""" - ALTER TABLE Users DROP COLUMN MinecraftId; - """ - ) - ) diff --git a/kdb-bot/src/bot_data/model/api_key.py b/kdb-bot/src/bot_data/model/api_key.py index 39f69677..e4bc6e9c 100644 --- a/kdb-bot/src/bot_data/model/api_key.py +++ b/kdb-bot/src/bot_data/model/api_key.py @@ -25,6 +25,10 @@ class ApiKey(TableABC): self._created_at = created_at if created_at is not None else self._created_at self._modified_at = modified_at if modified_at is not None else self._modified_at + @property + def id(self) -> int: + return self._id + @property def identifier(self) -> str: return self._identifier @@ -55,6 +59,15 @@ class ApiKey(TableABC): """ ) + @staticmethod + def get_select_by_id(id: int) -> str: + return str( + f""" + SELECT * FROM `ApiKeys` + WHERE `Id` = {id}; + """ + ) + @staticmethod def get_select_by_key(key: str) -> str: return str( diff --git a/kdb-bot/src/bot_data/model/game_server.py b/kdb-bot/src/bot_data/model/game_server.py new file mode 100644 index 00000000..0afc1ab3 --- /dev/null +++ b/kdb-bot/src/bot_data/model/game_server.py @@ -0,0 +1,124 @@ +from datetime import datetime + +from cpl_core.database import TableABC + +from bot_data.model.api_key import ApiKey +from bot_data.model.server import Server + + +class GameServer(TableABC): + def __init__( + self, + name: str, + server: Server, + api_key: ApiKey, + created_at: datetime = None, + modified_at: datetime = None, + id=0, + ): + self._id = id + self._name = name + self._server = server + self._api_key = api_key + + TableABC.__init__(self) + self._created_at = created_at if created_at is not None else self._created_at + self._modified_at = modified_at if modified_at is not None else self._modified_at + + @property + def id(self) -> int: + return self._id + + @property + def name(self) -> str: + return self._name + + @name.setter + def name(self, value: str): + self._name = value + + @property + def server(self) -> Server: + return self._server + + @server.setter + def server(self, value: Server): + self._server = value + + @property + def api_key(self) -> ApiKey: + return self._api_key + + @api_key.setter + def api_key(self, value: ApiKey): + self._api_key = value + + @staticmethod + def get_select_all_string() -> str: + return str( + f""" + SELECT * FROM `GameServer`; + """ + ) + + @staticmethod + def get_select_by_id_string(id: int) -> str: + return str( + f""" + SELECT * FROM `GameServer` + WHERE `Id` = {id}; + """ + ) + + @staticmethod + def get_select_by_user_id_string(id: int) -> str: + return str( + f""" + SELECT * FROM `GameServer` + WHERE `UserId` = {id}; + """ + ) + + @property + def insert_string(self) -> str: + return str( + f""" + INSERT INTO `GameServer` ( + `Name`, `ServerId`, `ApiKeyId`, CreatedAt`, `LastModifiedAt` + ) VALUES ( + '{self._name}', + {self._server.id}, + {self._api_key.id}, + '{self._created_at}', + '{self._modified_at}' + ); + """ + ) + + @property + def udpate_string(self) -> str: + return str( + f""" + UPDATE `GameServer` + SET `LastModifiedAt` = '{self._modified_at}' + WHERE `Id` = {self._id}; + """ + ) + + @property + def delete_string(self) -> str: + return str( + f""" + DELETE FROM `GameServer` + WHERE `Id` = {self._id}; + """ + ) + + @staticmethod + def delete_by_user_id_string(id: int) -> str: + return str( + f""" + DELETE FROM `GameServer` + WHERE `UserId` = {id} + """ + ) diff --git a/kdb-bot/src/bot_data/model/user.py b/kdb-bot/src/bot_data/model/user.py index c153a979..2c4c7a3d 100644 --- a/kdb-bot/src/bot_data/model/user.py +++ b/kdb-bot/src/bot_data/model/user.py @@ -14,7 +14,6 @@ class User(TableABC): self, dc_id: int, xp: int, - minecraft_id: Optional[str], server: Optional[Server], created_at: datetime = None, modified_at: datetime = None, @@ -23,7 +22,6 @@ class User(TableABC): self._user_id = id self._discord_id = dc_id self._xp = xp - self._minecraft_id = minecraft_id self._server = server TableABC.__init__(self) @@ -77,14 +75,6 @@ class User(TableABC): levels: LevelService = services.get_service(LevelService) return levels.get_level(self) - @property - def minecraft_id(self) -> Optional[str]: - return self._minecraft_id - - @minecraft_id.setter - def minecraft_id(self, value: str): - self._minecraft_id = value - @property def server(self) -> Optional[Server]: return self._server @@ -150,11 +140,10 @@ class User(TableABC): return str( f""" INSERT INTO `Users` ( - `DiscordId`, `XP`, `MinecraftId`, `ServerId`, `CreatedAt`, `LastModifiedAt` + `DiscordId`, `XP`, `ServerId`, `CreatedAt`, `LastModifiedAt` ) VALUES ( {self._discord_id}, {self._xp}, - {"NULL" if self._minecraft_id is None else f"'{self._minecraft_id}'"}, {self._server.id}, '{self._created_at}', '{self._modified_at}' @@ -168,7 +157,6 @@ class User(TableABC): f""" UPDATE `Users` SET `XP` = {self._xp}, - `MinecraftId` = {"NULL" if self._minecraft_id is None else f"'{self._minecraft_id}'"}, `LastModifiedAt` = '{self._modified_at}' WHERE `UserId` = {self._user_id}; """ diff --git a/kdb-bot/src/bot_data/model/user_joined_game_server.py b/kdb-bot/src/bot_data/model/user_joined_game_server.py index e25d6b1d..51fcbed2 100644 --- a/kdb-bot/src/bot_data/model/user_joined_game_server.py +++ b/kdb-bot/src/bot_data/model/user_joined_game_server.py @@ -2,6 +2,7 @@ from datetime import datetime from cpl_core.database import TableABC +from bot_data.model.game_server import GameServer from bot_data.model.user import User @@ -9,7 +10,7 @@ class UserJoinedGameServer(TableABC): def __init__( self, user: User, - game_server: str, + game_server: GameServer, joined_on: datetime, leaved_on: datetime = None, created_at: datetime = None, @@ -35,7 +36,7 @@ class UserJoinedGameServer(TableABC): return self._user @property - def game_server(self) -> str: + def game_server(self) -> GameServer: return self._game_server @property @@ -101,10 +102,10 @@ class UserJoinedGameServer(TableABC): return str( f""" INSERT INTO `UserJoinedGameServer` ( - `UserId`, `GameServer`, `JoinedOn`, `LeavedOn`, `CreatedAt`, `LastModifiedAt` + `UserId`, `GameServerId`, `JoinedOn`, `LeavedOn`, `CreatedAt`, `LastModifiedAt` ) VALUES ( {self._user.id}, - '{self._game_server}', + '{self._game_server.id}', '{self._joined_on}', {"NULL" if self._leaved_on is None else f"'{self._leaved_on}'"}, '{self._created_at}', diff --git a/kdb-bot/src/bot_data/service/api_key_repository_service.py b/kdb-bot/src/bot_data/service/api_key_repository_service.py index e7919373..d4f57dfc 100644 --- a/kdb-bot/src/bot_data/service/api_key_repository_service.py +++ b/kdb-bot/src/bot_data/service/api_key_repository_service.py @@ -56,6 +56,10 @@ class ApiKeyRepositoryService(ApiKeyRepositoryABC): self._logger.trace(__name__, f"Send SQL command: {ApiKey.get_select_string(identifier, key)}") return self._api_key_from_result(self._context.select(ApiKey.get_select_string(identifier, key))[0]) + def get_api_key_by_id(self, id: int) -> ApiKey: + self._logger.trace(__name__, f"Send SQL command: {ApiKey.get_select_by_id(id)}") + return self._api_key_from_result(self._context.select(ApiKey.get_select_by_id(id))[0]) + def get_api_key_by_key(self, key: str) -> ApiKey: self._logger.trace(__name__, f"Send SQL command: {ApiKey.get_select_by_key(key)}") return self._api_key_from_result(self._context.select(ApiKey.get_select_by_key(key))[0]) diff --git a/kdb-bot/src/bot_data/service/user_joined_game_server_repository_service.py b/kdb-bot/src/bot_data/service/user_joined_game_server_repository_service.py index 4d8099f6..131e5802 100644 --- a/kdb-bot/src/bot_data/service/user_joined_game_server_repository_service.py +++ b/kdb-bot/src/bot_data/service/user_joined_game_server_repository_service.py @@ -4,10 +4,13 @@ from cpl_core.database.context import DatabaseContextABC from cpl_query.extension import List from bot_core.logging.database_logger import DatabaseLogger +from bot_data.abc.api_key_repository_abc import ApiKeyRepositoryABC +from bot_data.abc.server_repository_abc import ServerRepositoryABC from bot_data.abc.user_joined_game_server_repository_abc import ( UserJoinedGameServerRepositoryABC, ) from bot_data.abc.user_repository_abc import UserRepositoryABC +from bot_data.model.game_server import GameServer from bot_data.model.user_joined_game_server import UserJoinedGameServer @@ -17,14 +20,44 @@ class UserJoinedGameServerRepositoryService(UserJoinedGameServerRepositoryABC): logger: DatabaseLogger, db_context: DatabaseContextABC, users: UserRepositoryABC, + servers: ServerRepositoryABC, + api_keys: ApiKeyRepositoryABC, ): self._logger = logger self._context = db_context self._users = users + self._servers = servers + self._api_keys = api_keys UserJoinedGameServerRepositoryABC.__init__(self) + def _game_server_from_id(self, id: int): + self._logger.trace( + __name__, + f"Send SQL command: {GameServer.get_select_by_id_string(id)}", + ) + result = self._context.select(GameServer.get_select_by_id_string(id))[0] + + return GameServer( + result[1], + self._servers.get_server_by_id(result[2]), + self._api_keys.get_api_key_by_id(result[3]), + result[4], + result[5], + id=result[0], + ) + + def _from_result(self, result: tuple) -> UserJoinedGameServer: + return UserJoinedGameServer( + self._users.get_user_by_id(result[1]), + self._game_server_from_id(result[2]), + result[3], + result[4], + result[5], + id=result[0], + ) + def get_user_joined_game_servers(self) -> List[UserJoinedGameServer]: joins = List(UserJoinedGameServer) self._logger.trace( @@ -34,16 +67,7 @@ class UserJoinedGameServerRepositoryService(UserJoinedGameServerRepositoryABC): results = self._context.select(UserJoinedGameServer.get_select_all_string()) for result in results: self._logger.trace(__name__, f"Get user-joined-game-server with id {result[0]}") - joins.append( - UserJoinedGameServer( - self._users.get_user_by_id(result[1]), - result[2], - result[3], - result[4], - result[5], - id=result[0], - ) - ) + joins.append(self._from_result(result)) return joins diff --git a/kdb-bot/src/bot_data/service/user_repository_service.py b/kdb-bot/src/bot_data/service/user_repository_service.py index 44207824..adc9685c 100644 --- a/kdb-bot/src/bot_data/service/user_repository_service.py +++ b/kdb-bot/src/bot_data/service/user_repository_service.py @@ -23,23 +23,23 @@ class UserRepositoryService(UserRepositoryABC): UserRepositoryABC.__init__(self) + def _from_result(self, result: tuple): + return User( + result[1], + result[2], + self._servers.get_server_by_id(result[3]), + result[4], + result[5], + id=result[0], + ) + def get_users(self) -> List[User]: users = List(User) self._logger.trace(__name__, f"Send SQL command: {User.get_select_all_string()}") results = self._context.select(User.get_select_all_string()) for result in results: self._logger.trace(__name__, f"Get user with id {result[0]}") - users.append( - User( - result[1], - result[2], - result[3], - self._servers.get_server_by_id(result[4]), - result[5], - result[6], - id=result[0], - ) - ) + users.append(self._from_result(result)) return users @@ -47,15 +47,7 @@ class UserRepositoryService(UserRepositoryABC): self._logger.trace(__name__, f"Send SQL command: {User.get_select_by_id_string(id)}") result = self._context.select(User.get_select_by_id_string(id))[0] - return User( - result[1], - result[2], - result[3], - self._servers.get_server_by_id(result[4]), - result[5], - result[6], - id=result[0], - ) + return self._from_result(result) def find_user_by_id(self, id: int) -> Optional[User]: self._logger.trace(__name__, f"Send SQL command: {User.get_select_by_id_string(id)}") @@ -65,15 +57,7 @@ class UserRepositoryService(UserRepositoryABC): result = result[0] - return User( - result[1], - result[2], - result[3], - self._servers.get_server_by_id(result[4]), - result[5], - result[6], - id=result[0], - ) + return self._from_result(result) def get_users_by_discord_id(self, discord_id: int) -> List[User]: users = List(User) @@ -83,17 +67,7 @@ class UserRepositoryService(UserRepositoryABC): ) results = self._context.select(User.get_select_by_discord_id_string(discord_id)) for result in results: - users.append( - User( - result[1], - result[2], - result[3], - self._servers.get_server_by_id(result[4]), - result[5], - result[6], - id=result[0], - ) - ) + users.append(self._from_result(result)) return users @@ -105,17 +79,7 @@ class UserRepositoryService(UserRepositoryABC): ) results = self._context.select(User.get_select_by_server_id_string(server_id)) for result in results: - users.append( - User( - result[1], - result[2], - result[3], - self._servers.get_server_by_id(result[4]), - result[5], - result[6], - id=result[0], - ) - ) + users.append(self._from_result(result)) return users @@ -126,15 +90,7 @@ class UserRepositoryService(UserRepositoryABC): ) result = self._context.select(User.get_select_by_discord_id_and_server_id_string(discord_id, server_id))[0] - return User( - result[1], - result[2], - result[3], - self._servers.get_server_by_id(result[4]), - result[5], - result[6], - id=result[0], - ) + return self._from_result(result) def find_user_by_discord_id_and_server_id(self, discord_id: int, server_id: int) -> Optional[User]: self._logger.trace( @@ -147,15 +103,7 @@ class UserRepositoryService(UserRepositoryABC): result = result[0] - return User( - result[1], - result[2], - result[3], - self._servers.get_server_by_id(result[4]), - result[5], - result[6], - id=result[0], - ) + return self._from_result(result) def add_user(self, user: User): self._logger.trace(__name__, f"Send SQL command: {user.insert_string}") diff --git a/kdb-bot/src/modules/database/database_on_ready_event.py b/kdb-bot/src/modules/database/database_on_ready_event.py index 3b66f5e0..d0d7c78a 100644 --- a/kdb-bot/src/modules/database/database_on_ready_event.py +++ b/kdb-bot/src/modules/database/database_on_ready_event.py @@ -193,7 +193,7 @@ class DatabaseOnReadyEvent(OnReadyABC): self._logger.warn(__name__, f"User not found in database: {u.id}") self._logger.debug(__name__, f"Add user: {u.id}") - self._users.add_user(User(u.id, 0, None, server)) + self._users.add_user(User(u.id, 0, server)) self._db_context.save_changes() self._logger.debug(__name__, f"Added User: {u.id}")