Added achievement data model #268_achievements
This commit is contained in:
35
kdb-bot/src/bot_data/abc/achievement_repository_abc.py
Normal file
35
kdb-bot/src/bot_data/abc/achievement_repository_abc.py
Normal file
@@ -0,0 +1,35 @@
|
||||
from abc import ABC, abstractmethod
|
||||
|
||||
from cpl_query.extension import List
|
||||
|
||||
from bot_data.model.achievement import Achievement
|
||||
|
||||
|
||||
class AchievementRepositoryABC(ABC):
|
||||
@abstractmethod
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def get_achievements(self) -> List[Achievement]:
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def get_achievement_by_id(self, id: int) -> Achievement:
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def get_achievements_by_server_id(self, server_id: int) -> List[Achievement]:
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def add_achievement(self, achievement: Achievement):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def update_achievement(self, achievement: Achievement):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def delete_achievement(self, achievement: Achievement):
|
||||
pass
|
@@ -5,6 +5,7 @@ from cpl_discord.service.discord_collection_abc import DiscordCollectionABC
|
||||
|
||||
from bot_core.abc.module_abc import ModuleABC
|
||||
from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum
|
||||
from bot_data.abc.achievement_repository_abc import AchievementRepositoryABC
|
||||
from bot_data.abc.api_key_repository_abc import ApiKeyRepositoryABC
|
||||
from bot_data.abc.auth_user_repository_abc import AuthUserRepositoryABC
|
||||
from bot_data.abc.auto_role_repository_abc import AutoRoleRepositoryABC
|
||||
@@ -24,6 +25,7 @@ from bot_data.abc.user_message_count_per_hour_repository_abc import (
|
||||
)
|
||||
from bot_data.abc.user_repository_abc import UserRepositoryABC
|
||||
from bot_data.abc.user_warnings_repository_abc import UserWarningsRepositoryABC
|
||||
from bot_data.service.achievements_repository_service import AchievementRepositoryService
|
||||
from bot_data.service.api_key_repository_service import ApiKeyRepositoryService
|
||||
from bot_data.service.auth_user_repository_service import AuthUserRepositoryService
|
||||
from bot_data.service.auto_role_repository_service import AutoRoleRepositoryService
|
||||
@@ -77,5 +79,6 @@ class DataModule(ModuleABC):
|
||||
)
|
||||
services.add_transient(GameServerRepositoryABC, GameServerRepositoryService)
|
||||
services.add_transient(UserGameIdentRepositoryABC, UserGameIdentRepositoryService)
|
||||
services.add_transient(AchievementRepositoryABC, AchievementRepositoryService)
|
||||
|
||||
services.add_transient(SeederService)
|
||||
|
95
kdb-bot/src/bot_data/migration/achievements_migration.py
Normal file
95
kdb-bot/src/bot_data/migration/achievements_migration.py
Normal file
@@ -0,0 +1,95 @@
|
||||
from bot_core.logging.database_logger import DatabaseLogger
|
||||
from bot_data.abc.migration_abc import MigrationABC
|
||||
from bot_data.db_context import DBContext
|
||||
|
||||
|
||||
class AchievementsMigration(MigrationABC):
|
||||
name = "1.1.0_AchievementsMigration"
|
||||
|
||||
def __init__(self, logger: DatabaseLogger, db: DBContext):
|
||||
MigrationABC.__init__(self)
|
||||
self._logger = logger
|
||||
self._db = db
|
||||
self._cursor = db.cursor
|
||||
|
||||
def upgrade(self):
|
||||
self._logger.debug(__name__, "Running upgrade")
|
||||
|
||||
self._cursor.execute(
|
||||
str(
|
||||
f"""
|
||||
CREATE TABLE IF NOT EXISTS `Achievements` (
|
||||
`Id` BIGINT NOT NULL AUTO_INCREMENT,
|
||||
`ServerId` BIGINT,
|
||||
`Name` VARCHAR(255) NOT NULL,
|
||||
`Attribute` VARCHAR(255) NOT NULL,
|
||||
`Operator` VARCHAR(2) NOT NULL,
|
||||
`Value` VARCHAR(255) NOT NULL,
|
||||
`CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6),
|
||||
`LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
||||
PRIMARY KEY(`Id`),
|
||||
FOREIGN KEY (`ServerId`) REFERENCES `Servers`(`ServerId`)
|
||||
);
|
||||
"""
|
||||
)
|
||||
)
|
||||
|
||||
self._cursor.execute(
|
||||
str(
|
||||
f"""
|
||||
ALTER TABLE Users ADD MessageCount BIGINT NOT NULL DEFAULT 0 AFTER XP;
|
||||
ALTER TABLE Users ADD ReactionCount BIGINT NOT NULL DEFAULT 0 AFTER XP;
|
||||
"""
|
||||
)
|
||||
)
|
||||
|
||||
self._cursor.execute(
|
||||
str(
|
||||
f"""
|
||||
ALTER TABLE UsersHistory ADD MessageCount BIGINT NOT NULL DEFAULT 0 AFTER XP;
|
||||
ALTER TABLE UsersHistory ADD ReactionCount BIGINT NOT NULL DEFAULT 0 AFTER XP;
|
||||
"""
|
||||
)
|
||||
)
|
||||
|
||||
self._cursor.execute(
|
||||
str(
|
||||
f"""
|
||||
DROP TRIGGER IF EXISTS `TR_AchievementsUpdate`;
|
||||
|
||||
CREATE TRIGGER `TR_AchievementsUpdate`
|
||||
AFTER UPDATE
|
||||
ON `Achievements`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
INSERT INTO `AchievementsHistory` (
|
||||
`Id`, `Name`, `Attribute`, `Operator`, `Value`, `ServerId`, `DateFrom`, `DateTo`
|
||||
)
|
||||
VALUES (
|
||||
OLD.Id, OLD.Name, OLD.Attribute, OLD.Operator, OLD.Value, OLD.ServerId, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6)
|
||||
);
|
||||
END;
|
||||
|
||||
DROP TRIGGER IF EXISTS `TR_AchievementsDelete`;
|
||||
|
||||
CREATE TRIGGER `TR_AchievementsDelete`
|
||||
AFTER DELETE
|
||||
ON `Achievements`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
INSERT INTO `AchievementsHistory` (
|
||||
`Id`, `Name`, `Attribute`, `Operator`, `Value`, `ServerId`, `Deleted`, `DateFrom`, `DateTo`
|
||||
)
|
||||
VALUES (
|
||||
OLD.Id, OLD.Name, OLD.Attribute, OLD.Operator, OLD.Value, OLD.ServerId, TRUE, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6)
|
||||
);
|
||||
END;
|
||||
"""
|
||||
)
|
||||
)
|
||||
|
||||
def downgrade(self):
|
||||
self._cursor.execute("DROP TABLE `Achievements`;")
|
||||
|
||||
self._cursor.execute(str(f"""ALTER TABLE Users DROP COLUMN MessageCount;"""))
|
||||
self._cursor.execute(str(f"""ALTER TABLE Users DROP COLUMN ReactionCount;"""))
|
117
kdb-bot/src/bot_data/model/achievement.py
Normal file
117
kdb-bot/src/bot_data/model/achievement.py
Normal file
@@ -0,0 +1,117 @@
|
||||
from datetime import datetime
|
||||
from typing import Optional
|
||||
|
||||
from cpl_core.database import TableABC
|
||||
|
||||
from bot_data.model.server import Server
|
||||
|
||||
|
||||
class Achievement(TableABC):
|
||||
def __init__(
|
||||
self,
|
||||
name: str,
|
||||
attribute: str,
|
||||
operator: str,
|
||||
value: str,
|
||||
server: Optional[Server],
|
||||
created_at: datetime = None,
|
||||
modified_at: datetime = None,
|
||||
id=0,
|
||||
):
|
||||
self._id = id
|
||||
self._name = name
|
||||
self._attribute = attribute
|
||||
self._operator = operator
|
||||
self._value = value
|
||||
self._server = server
|
||||
|
||||
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 operator(self) -> str:
|
||||
return self._operator
|
||||
|
||||
@operator.setter
|
||||
def operator(self, value: str):
|
||||
self._operator = value
|
||||
|
||||
@property
|
||||
def value(self) -> str:
|
||||
return self._value
|
||||
|
||||
@value.setter
|
||||
def value(self, value: str):
|
||||
self._value = value
|
||||
|
||||
@property
|
||||
def server(self) -> Server:
|
||||
return self._server
|
||||
|
||||
@staticmethod
|
||||
def get_select_all_string() -> str:
|
||||
return str(
|
||||
f"""
|
||||
SELECT * FROM `Achievements`;
|
||||
"""
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def get_select_by_id_string(id: int) -> str:
|
||||
return str(
|
||||
f"""
|
||||
SELECT * FROM `Achievements`
|
||||
WHERE `Id` = {id};
|
||||
"""
|
||||
)
|
||||
|
||||
@property
|
||||
def insert_string(self) -> str:
|
||||
return str(
|
||||
f"""
|
||||
INSERT INTO `Achievements` (
|
||||
`Name`, `Attribute`, `Operator`, `Value`, `ServerId`
|
||||
) VALUES (
|
||||
'{self._name}',
|
||||
'{self._attribute}',
|
||||
'{self._operator}',
|
||||
'{self._value}',
|
||||
{self._server.id}
|
||||
);
|
||||
"""
|
||||
)
|
||||
|
||||
@property
|
||||
def udpate_string(self) -> str:
|
||||
return str(
|
||||
f"""
|
||||
UPDATE `Levels`
|
||||
SET `Name` = '{self._name}',
|
||||
`Attribute` = '{self._attribute}',
|
||||
`Operator` = '{self._operator}',
|
||||
`Value` = '{self._value}'
|
||||
WHERE `Id` = {self._id};
|
||||
"""
|
||||
)
|
||||
|
||||
@property
|
||||
def delete_string(self) -> str:
|
||||
return str(
|
||||
f"""
|
||||
DELETE FROM `Achievements`
|
||||
WHERE `Id` = {self._id};
|
||||
"""
|
||||
)
|
66
kdb-bot/src/bot_data/model/achievement_history.py
Normal file
66
kdb-bot/src/bot_data/model/achievement_history.py
Normal file
@@ -0,0 +1,66 @@
|
||||
from datetime import datetime
|
||||
from typing import Optional
|
||||
|
||||
from cpl_core.database import TableABC
|
||||
|
||||
from bot_data.abc.history_table_abc import HistoryTableABC
|
||||
from bot_data.model.server import Server
|
||||
|
||||
|
||||
class Achievement(HistoryTableABC):
|
||||
def __init__(
|
||||
self,
|
||||
name: str,
|
||||
attribute: str,
|
||||
operator: str,
|
||||
value: str,
|
||||
server: Optional[Server],
|
||||
deleted: bool,
|
||||
date_from: str,
|
||||
date_to: str,
|
||||
id=0,
|
||||
):
|
||||
HistoryTableABC.__init__(self)
|
||||
|
||||
self._id = id
|
||||
self._name = name
|
||||
self._attribute = attribute
|
||||
self._operator = operator
|
||||
self._value = value
|
||||
self._server = server
|
||||
|
||||
self._deleted = deleted
|
||||
self._date_from = date_from
|
||||
self._date_to = date_to
|
||||
|
||||
@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 operator(self) -> str:
|
||||
return self._operator
|
||||
|
||||
@operator.setter
|
||||
def operator(self, value: str):
|
||||
self._operator = value
|
||||
|
||||
@property
|
||||
def value(self) -> str:
|
||||
return self._value
|
||||
|
||||
@value.setter
|
||||
def value(self, value: str):
|
||||
self._value = value
|
||||
|
||||
@property
|
||||
def server(self) -> Server:
|
||||
return self._server
|
@@ -0,0 +1,72 @@
|
||||
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.achievement_repository_abc import AchievementRepositoryABC
|
||||
from bot_data.abc.server_repository_abc import ServerRepositoryABC
|
||||
from bot_data.model.achievement import Achievement
|
||||
|
||||
|
||||
class AchievementRepositoryService(AchievementRepositoryABC):
|
||||
def __init__(
|
||||
self,
|
||||
logger: DatabaseLogger,
|
||||
db_context: DatabaseContextABC,
|
||||
servers: ServerRepositoryABC,
|
||||
):
|
||||
self._logger = logger
|
||||
self._context = db_context
|
||||
|
||||
self._servers = servers
|
||||
|
||||
AchievementRepositoryABC.__init__(self)
|
||||
|
||||
def _from_result(self, result: tuple):
|
||||
return Achievement(
|
||||
result[3],
|
||||
result[4],
|
||||
result[5],
|
||||
result[6],
|
||||
self._servers.get_server_by_id(result[2]),
|
||||
result[6],
|
||||
result[7],
|
||||
id=result[0],
|
||||
)
|
||||
|
||||
def get_achievements(self) -> List[Achievement]:
|
||||
achievements = List(Achievement)
|
||||
self._logger.trace(__name__, f"Send SQL command: {Achievement.get_select_all_string()}")
|
||||
results = self._context.select(Achievement.get_select_all_string())
|
||||
for result in results:
|
||||
self._logger.trace(__name__, f"Get user with id {result[0]}")
|
||||
achievements.append(self._from_result(result))
|
||||
|
||||
return achievements
|
||||
|
||||
def get_achievement_by_id(self, id: int) -> Achievement:
|
||||
self._logger.trace(__name__, f"Send SQL command: {Achievement.get_select_by_id_string(id)}")
|
||||
result = self._context.select(Achievement.get_select_by_id_string(id))[0]
|
||||
|
||||
return self._from_result(result)
|
||||
|
||||
def get_achievements_by_server_id(self, server_id: int) -> List[Achievement]:
|
||||
achievements = List(Achievement)
|
||||
self._logger.trace(__name__, f"Send SQL command: {Achievement.get_select_by_id_string(server_id)}")
|
||||
results = self._context.select(Achievement.get_select_all_string())
|
||||
for result in results:
|
||||
self._logger.trace(__name__, f"Get user with id {result[0]}")
|
||||
achievements.append(self._from_result(result))
|
||||
|
||||
return achievements
|
||||
|
||||
def add_achievement(self, achievement: Achievement):
|
||||
self._logger.trace(__name__, f"Send SQL command: {achievement.insert_string}")
|
||||
self._context.cursor.execute(achievement.insert_string)
|
||||
|
||||
def update_achievement(self, achievement: Achievement):
|
||||
self._logger.trace(__name__, f"Send SQL command: {achievement.udpate_string}")
|
||||
self._context.cursor.execute(achievement.udpate_string)
|
||||
|
||||
def delete_achievement(self, achievement: Achievement):
|
||||
self._logger.trace(__name__, f"Send SQL command: {achievement.delete_string}")
|
||||
self._context.cursor.execute(achievement.delete_string)
|
Reference in New Issue
Block a user