Added GameServer data model #238

This commit is contained in:
Sven Heidemann 2023-03-04 19:34:11 +01:00
parent f03416d05f
commit a7c4765f55
10 changed files with 222 additions and 111 deletions

View File

@ -18,6 +18,10 @@ class ApiKeyRepositoryABC(ABC):
def get_api_key(self, identifier: str, key: str) -> ApiKey: def get_api_key(self, identifier: str, key: str) -> ApiKey:
pass pass
@abstractmethod
def get_api_key_by_id(self, id: int) -> ApiKey:
pass
@abstractmethod @abstractmethod
def get_api_key_by_key(self, key: str) -> ApiKey: def get_api_key_by_key(self, key: str) -> ApiKey:
pass pass

View File

@ -18,15 +18,15 @@ class UserJoinedGameServerMigration(MigrationABC):
self._cursor.execute( self._cursor.execute(
str( str(
f""" f"""
CREATE TABLE IF NOT EXISTS `UserJoinedGameServer` ( CREATE TABLE IF NOT EXISTS `GameServers` (
`Id` BIGINT NOT NULL AUTO_INCREMENT, `Id` BIGINT NOT NULL AUTO_INCREMENT,
`UserId` BIGINT NOT NULL, `Name` VARCHAR(255) NOT NULL,
`GameServer` VARCHAR(255) NOT NULL, `ServerId` BIGINT NOT NULL,
`JoinedOn` DATETIME(6) NOT NULL, `ApiKeyId` BIGINT NOT NULL,
`LeavedOn` DATETIME(6),
`CreatedAt` DATETIME(6), `CreatedAt` DATETIME(6),
`LastModifiedAt` 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`) PRIMARY KEY(`Id`)
); );
""" """
@ -36,17 +36,22 @@ class UserJoinedGameServerMigration(MigrationABC):
self._cursor.execute( self._cursor.execute(
str( str(
f""" 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): def downgrade(self):
self._cursor.execute("DROP TABLE `GameServers`;")
self._cursor.execute("DROP TABLE `UserJoinedGameServer`;") self._cursor.execute("DROP TABLE `UserJoinedGameServer`;")
self._cursor.execute(
str(
f"""
ALTER TABLE Users DROP COLUMN MinecraftId;
"""
)
)

View File

@ -25,6 +25,10 @@ class ApiKey(TableABC):
self._created_at = created_at if created_at is not None else self._created_at 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 self._modified_at = modified_at if modified_at is not None else self._modified_at
@property
def id(self) -> int:
return self._id
@property @property
def identifier(self) -> str: def identifier(self) -> str:
return self._identifier 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 @staticmethod
def get_select_by_key(key: str) -> str: def get_select_by_key(key: str) -> str:
return str( return str(

View File

@ -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}
"""
)

View File

@ -14,7 +14,6 @@ class User(TableABC):
self, self,
dc_id: int, dc_id: int,
xp: int, xp: int,
minecraft_id: Optional[str],
server: Optional[Server], server: Optional[Server],
created_at: datetime = None, created_at: datetime = None,
modified_at: datetime = None, modified_at: datetime = None,
@ -23,7 +22,6 @@ class User(TableABC):
self._user_id = id self._user_id = id
self._discord_id = dc_id self._discord_id = dc_id
self._xp = xp self._xp = xp
self._minecraft_id = minecraft_id
self._server = server self._server = server
TableABC.__init__(self) TableABC.__init__(self)
@ -77,14 +75,6 @@ class User(TableABC):
levels: LevelService = services.get_service(LevelService) levels: LevelService = services.get_service(LevelService)
return levels.get_level(self) 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 @property
def server(self) -> Optional[Server]: def server(self) -> Optional[Server]:
return self._server return self._server
@ -150,11 +140,10 @@ class User(TableABC):
return str( return str(
f""" f"""
INSERT INTO `Users` ( INSERT INTO `Users` (
`DiscordId`, `XP`, `MinecraftId`, `ServerId`, `CreatedAt`, `LastModifiedAt` `DiscordId`, `XP`, `ServerId`, `CreatedAt`, `LastModifiedAt`
) VALUES ( ) VALUES (
{self._discord_id}, {self._discord_id},
{self._xp}, {self._xp},
{"NULL" if self._minecraft_id is None else f"'{self._minecraft_id}'"},
{self._server.id}, {self._server.id},
'{self._created_at}', '{self._created_at}',
'{self._modified_at}' '{self._modified_at}'
@ -168,7 +157,6 @@ class User(TableABC):
f""" f"""
UPDATE `Users` UPDATE `Users`
SET `XP` = {self._xp}, SET `XP` = {self._xp},
`MinecraftId` = {"NULL" if self._minecraft_id is None else f"'{self._minecraft_id}'"},
`LastModifiedAt` = '{self._modified_at}' `LastModifiedAt` = '{self._modified_at}'
WHERE `UserId` = {self._user_id}; WHERE `UserId` = {self._user_id};
""" """

View File

@ -2,6 +2,7 @@ from datetime import datetime
from cpl_core.database import TableABC from cpl_core.database import TableABC
from bot_data.model.game_server import GameServer
from bot_data.model.user import User from bot_data.model.user import User
@ -9,7 +10,7 @@ class UserJoinedGameServer(TableABC):
def __init__( def __init__(
self, self,
user: User, user: User,
game_server: str, game_server: GameServer,
joined_on: datetime, joined_on: datetime,
leaved_on: datetime = None, leaved_on: datetime = None,
created_at: datetime = None, created_at: datetime = None,
@ -35,7 +36,7 @@ class UserJoinedGameServer(TableABC):
return self._user return self._user
@property @property
def game_server(self) -> str: def game_server(self) -> GameServer:
return self._game_server return self._game_server
@property @property
@ -101,10 +102,10 @@ class UserJoinedGameServer(TableABC):
return str( return str(
f""" f"""
INSERT INTO `UserJoinedGameServer` ( INSERT INTO `UserJoinedGameServer` (
`UserId`, `GameServer`, `JoinedOn`, `LeavedOn`, `CreatedAt`, `LastModifiedAt` `UserId`, `GameServerId`, `JoinedOn`, `LeavedOn`, `CreatedAt`, `LastModifiedAt`
) VALUES ( ) VALUES (
{self._user.id}, {self._user.id},
'{self._game_server}', '{self._game_server.id}',
'{self._joined_on}', '{self._joined_on}',
{"NULL" if self._leaved_on is None else f"'{self._leaved_on}'"}, {"NULL" if self._leaved_on is None else f"'{self._leaved_on}'"},
'{self._created_at}', '{self._created_at}',

View File

@ -56,6 +56,10 @@ class ApiKeyRepositoryService(ApiKeyRepositoryABC):
self._logger.trace(__name__, f"Send SQL command: {ApiKey.get_select_string(identifier, key)}") 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]) 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: def get_api_key_by_key(self, key: str) -> ApiKey:
self._logger.trace(__name__, f"Send SQL command: {ApiKey.get_select_by_key(key)}") 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]) return self._api_key_from_result(self._context.select(ApiKey.get_select_by_key(key))[0])

View File

@ -4,10 +4,13 @@ from cpl_core.database.context import DatabaseContextABC
from cpl_query.extension import List from cpl_query.extension import List
from bot_core.logging.database_logger import DatabaseLogger 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 ( from bot_data.abc.user_joined_game_server_repository_abc import (
UserJoinedGameServerRepositoryABC, UserJoinedGameServerRepositoryABC,
) )
from bot_data.abc.user_repository_abc import UserRepositoryABC 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 from bot_data.model.user_joined_game_server import UserJoinedGameServer
@ -17,14 +20,44 @@ class UserJoinedGameServerRepositoryService(UserJoinedGameServerRepositoryABC):
logger: DatabaseLogger, logger: DatabaseLogger,
db_context: DatabaseContextABC, db_context: DatabaseContextABC,
users: UserRepositoryABC, users: UserRepositoryABC,
servers: ServerRepositoryABC,
api_keys: ApiKeyRepositoryABC,
): ):
self._logger = logger self._logger = logger
self._context = db_context self._context = db_context
self._users = users self._users = users
self._servers = servers
self._api_keys = api_keys
UserJoinedGameServerRepositoryABC.__init__(self) 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]: def get_user_joined_game_servers(self) -> List[UserJoinedGameServer]:
joins = List(UserJoinedGameServer) joins = List(UserJoinedGameServer)
self._logger.trace( self._logger.trace(
@ -34,16 +67,7 @@ class UserJoinedGameServerRepositoryService(UserJoinedGameServerRepositoryABC):
results = self._context.select(UserJoinedGameServer.get_select_all_string()) results = self._context.select(UserJoinedGameServer.get_select_all_string())
for result in results: for result in results:
self._logger.trace(__name__, f"Get user-joined-game-server with id {result[0]}") self._logger.trace(__name__, f"Get user-joined-game-server with id {result[0]}")
joins.append( joins.append(self._from_result(result))
UserJoinedGameServer(
self._users.get_user_by_id(result[1]),
result[2],
result[3],
result[4],
result[5],
id=result[0],
)
)
return joins return joins

View File

@ -23,23 +23,23 @@ class UserRepositoryService(UserRepositoryABC):
UserRepositoryABC.__init__(self) 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]: def get_users(self) -> List[User]:
users = List(User) users = List(User)
self._logger.trace(__name__, f"Send SQL command: {User.get_select_all_string()}") self._logger.trace(__name__, f"Send SQL command: {User.get_select_all_string()}")
results = self._context.select(User.get_select_all_string()) results = self._context.select(User.get_select_all_string())
for result in results: for result in results:
self._logger.trace(__name__, f"Get user with id {result[0]}") self._logger.trace(__name__, f"Get user with id {result[0]}")
users.append( users.append(self._from_result(result))
User(
result[1],
result[2],
result[3],
self._servers.get_server_by_id(result[4]),
result[5],
result[6],
id=result[0],
)
)
return users return users
@ -47,15 +47,7 @@ class UserRepositoryService(UserRepositoryABC):
self._logger.trace(__name__, f"Send SQL command: {User.get_select_by_id_string(id)}") 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] result = self._context.select(User.get_select_by_id_string(id))[0]
return User( return self._from_result(result)
result[1],
result[2],
result[3],
self._servers.get_server_by_id(result[4]),
result[5],
result[6],
id=result[0],
)
def find_user_by_id(self, id: int) -> Optional[User]: 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)}") 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] result = result[0]
return User( return self._from_result(result)
result[1],
result[2],
result[3],
self._servers.get_server_by_id(result[4]),
result[5],
result[6],
id=result[0],
)
def get_users_by_discord_id(self, discord_id: int) -> List[User]: def get_users_by_discord_id(self, discord_id: int) -> List[User]:
users = 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)) results = self._context.select(User.get_select_by_discord_id_string(discord_id))
for result in results: for result in results:
users.append( users.append(self._from_result(result))
User(
result[1],
result[2],
result[3],
self._servers.get_server_by_id(result[4]),
result[5],
result[6],
id=result[0],
)
)
return users return users
@ -105,17 +79,7 @@ class UserRepositoryService(UserRepositoryABC):
) )
results = self._context.select(User.get_select_by_server_id_string(server_id)) results = self._context.select(User.get_select_by_server_id_string(server_id))
for result in results: for result in results:
users.append( users.append(self._from_result(result))
User(
result[1],
result[2],
result[3],
self._servers.get_server_by_id(result[4]),
result[5],
result[6],
id=result[0],
)
)
return users 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] result = self._context.select(User.get_select_by_discord_id_and_server_id_string(discord_id, server_id))[0]
return User( return self._from_result(result)
result[1],
result[2],
result[3],
self._servers.get_server_by_id(result[4]),
result[5],
result[6],
id=result[0],
)
def find_user_by_discord_id_and_server_id(self, discord_id: int, server_id: int) -> Optional[User]: def find_user_by_discord_id_and_server_id(self, discord_id: int, server_id: int) -> Optional[User]:
self._logger.trace( self._logger.trace(
@ -147,15 +103,7 @@ class UserRepositoryService(UserRepositoryABC):
result = result[0] result = result[0]
return User( return self._from_result(result)
result[1],
result[2],
result[3],
self._servers.get_server_by_id(result[4]),
result[5],
result[6],
id=result[0],
)
def add_user(self, user: User): def add_user(self, user: User):
self._logger.trace(__name__, f"Send SQL command: {user.insert_string}") self._logger.trace(__name__, f"Send SQL command: {user.insert_string}")

View File

@ -193,7 +193,7 @@ class DatabaseOnReadyEvent(OnReadyABC):
self._logger.warn(__name__, f"User not found in database: {u.id}") self._logger.warn(__name__, f"User not found in database: {u.id}")
self._logger.debug(__name__, f"Add user: {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._db_context.save_changes()
self._logger.debug(__name__, f"Added User: {u.id}") self._logger.debug(__name__, f"Added User: {u.id}")