Improved achievement logic #268_achievements
This commit is contained in:
@@ -3,6 +3,7 @@ from abc import ABC, abstractmethod
|
||||
from cpl_query.extension import List
|
||||
|
||||
from bot_data.model.achievement import Achievement
|
||||
from bot_data.model.user_got_achievement import UserGotAchievement
|
||||
|
||||
|
||||
class AchievementRepositoryABC(ABC):
|
||||
@@ -22,6 +23,10 @@ class AchievementRepositoryABC(ABC):
|
||||
def get_achievements_by_server_id(self, server_id: int) -> List[Achievement]:
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def get_achievements_by_user_id(self, user_id: int) -> List[Achievement]:
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def add_achievement(self, achievement: Achievement):
|
||||
pass
|
||||
@@ -33,3 +38,11 @@ class AchievementRepositoryABC(ABC):
|
||||
@abstractmethod
|
||||
def delete_achievement(self, achievement: Achievement):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def add_user_got_achievement(self, join: UserGotAchievement):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def delete_user_got_achievement(self, join: UserGotAchievement):
|
||||
pass
|
||||
|
@@ -45,7 +45,7 @@ class AchievementsMigration(MigrationABC):
|
||||
`Attribute` VARCHAR(255) NOT NULL,
|
||||
`Operator` VARCHAR(2) NOT NULL,
|
||||
`Value` VARCHAR(255) NOT NULL,
|
||||
`Deleted` BOOL DEFAULT FALSE,
|
||||
`Deleted` BOOL DEFAULT FALSE,
|
||||
`DateFrom` DATETIME(6) NOT NULL,
|
||||
`DateTo` DATETIME(6) NOT NULL
|
||||
);
|
||||
@@ -53,6 +53,25 @@ class AchievementsMigration(MigrationABC):
|
||||
)
|
||||
)
|
||||
|
||||
self._cursor.execute(
|
||||
str(
|
||||
f"""
|
||||
CREATE TABLE IF NOT EXISTS `UserGotAchievements` (
|
||||
`Id` BIGINT NOT NULL AUTO_INCREMENT,
|
||||
`UserId` BIGINT,
|
||||
`AchievementId` BIGINT,
|
||||
`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 (`UserId`) REFERENCES `Users`(`UserId`),
|
||||
FOREIGN KEY (`AchievementId`) REFERENCES `Achievements`(`Id`)
|
||||
);
|
||||
"""
|
||||
)
|
||||
)
|
||||
|
||||
# A join table history between users and achievements is not necessary.
|
||||
|
||||
self._cursor.execute(str(f"""ALTER TABLE Users ADD MessageCount BIGINT NOT NULL DEFAULT 0 AFTER XP;"""))
|
||||
self._cursor.execute(str(f"""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;"""))
|
||||
|
99
kdb-bot/src/bot_data/model/user_got_achievement.py
Normal file
99
kdb-bot/src/bot_data/model/user_got_achievement.py
Normal file
@@ -0,0 +1,99 @@
|
||||
from datetime import datetime
|
||||
from typing import Optional
|
||||
|
||||
from cpl_core.database import TableABC
|
||||
|
||||
from bot_data.model.achievement import Achievement
|
||||
from bot_data.model.server import Server
|
||||
from bot_data.model.user import User
|
||||
|
||||
|
||||
class UserGotAchievement(TableABC):
|
||||
def __init__(
|
||||
self,
|
||||
user: Optional[User],
|
||||
achievement: Optional[Achievement],
|
||||
server: Optional[Server],
|
||||
created_at: datetime = None,
|
||||
modified_at: datetime = None,
|
||||
id=0,
|
||||
):
|
||||
self._id = id
|
||||
self._user = user
|
||||
self._achievement = achievement
|
||||
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 user(self) -> User:
|
||||
return self._user
|
||||
|
||||
@property
|
||||
def achievement(self) -> Achievement:
|
||||
return self._achievement
|
||||
|
||||
@staticmethod
|
||||
def get_select_all_string() -> str:
|
||||
return str(
|
||||
f"""
|
||||
SELECT * FROM `UserGotAchievements`;
|
||||
"""
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def get_select_by_id_string(id: int) -> str:
|
||||
return str(
|
||||
f"""
|
||||
SELECT * FROM `UserGotAchievements`
|
||||
WHERE `Id` = {id};
|
||||
"""
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def get_select_by_user_id_string(id: int) -> str:
|
||||
return str(
|
||||
f"""
|
||||
SELECT * FROM `UserGotAchievements`
|
||||
WHERE `UserId` = {id};
|
||||
"""
|
||||
)
|
||||
|
||||
@property
|
||||
def insert_string(self) -> str:
|
||||
return str(
|
||||
f"""
|
||||
INSERT INTO `UserGotAchievements` (
|
||||
`UserId`, `AchievementId`
|
||||
) VALUES (
|
||||
{self._user.id},
|
||||
{self._achievement.id}
|
||||
);
|
||||
"""
|
||||
)
|
||||
|
||||
@property
|
||||
def udpate_string(self) -> str:
|
||||
return str(
|
||||
f"""
|
||||
UPDATE `UserGotAchievements`
|
||||
SET `UserId` = '{self._user.id}',
|
||||
`AchievementId` = '{self._achievement.id}'
|
||||
WHERE `Id` = {self._id};
|
||||
"""
|
||||
)
|
||||
|
||||
@property
|
||||
def delete_string(self) -> str:
|
||||
return str(
|
||||
f"""
|
||||
DELETE FROM `UserGotAchievements`
|
||||
WHERE `Id` = {self._id};
|
||||
"""
|
||||
)
|
@@ -4,7 +4,9 @@ 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.abc.user_repository_abc import UserRepositoryABC
|
||||
from bot_data.model.achievement import Achievement
|
||||
from bot_data.model.user_got_achievement import UserGotAchievement
|
||||
|
||||
|
||||
class AchievementRepositoryService(AchievementRepositoryABC):
|
||||
@@ -13,11 +15,13 @@ class AchievementRepositoryService(AchievementRepositoryABC):
|
||||
logger: DatabaseLogger,
|
||||
db_context: DatabaseContextABC,
|
||||
servers: ServerRepositoryABC,
|
||||
users: UserRepositoryABC,
|
||||
):
|
||||
self._logger = logger
|
||||
self._context = db_context
|
||||
|
||||
self._servers = servers
|
||||
self._users = users
|
||||
|
||||
AchievementRepositoryABC.__init__(self)
|
||||
|
||||
@@ -33,6 +37,15 @@ class AchievementRepositoryService(AchievementRepositoryABC):
|
||||
id=result[0],
|
||||
)
|
||||
|
||||
def _join_from_result(self, result: tuple):
|
||||
return UserGotAchievement(
|
||||
self._users.get_user_by_id(result[1]),
|
||||
self.get_achievement_by_id(result[2]),
|
||||
self._servers.get_server_by_id(result[3]),
|
||||
result[5],
|
||||
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()}")
|
||||
@@ -59,6 +72,23 @@ class AchievementRepositoryService(AchievementRepositoryABC):
|
||||
|
||||
return achievements
|
||||
|
||||
def get_achievements_by_user_id(self, user_id: int) -> List[Achievement]:
|
||||
achievements = List(Achievement)
|
||||
achievements_joins = List(UserGotAchievement)
|
||||
self._logger.trace(__name__, f"Send SQL command: {UserGotAchievement.get_select_by_user_id_string(user_id)}")
|
||||
results = self._context.select(UserGotAchievement.get_select_all_string())
|
||||
for result in results:
|
||||
self._logger.trace(__name__, f"Got UserGotAchievement with id {result[0]}")
|
||||
achievements_joins.append(self._join_from_result(result))
|
||||
|
||||
for achievements_join in achievements_joins:
|
||||
results = self._context.select(Achievement.get_select_by_id_string(achievements_join.achievement.id))
|
||||
for result in results:
|
||||
self._logger.trace(__name__, f"Got Achievement 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)
|
||||
@@ -70,3 +100,11 @@ class AchievementRepositoryService(AchievementRepositoryABC):
|
||||
def delete_achievement(self, achievement: Achievement):
|
||||
self._logger.trace(__name__, f"Send SQL command: {achievement.delete_string}")
|
||||
self._context.cursor.execute(achievement.delete_string)
|
||||
|
||||
def add_user_got_achievement(self, join: UserGotAchievement):
|
||||
self._logger.trace(__name__, f"Send SQL command: {join.insert_string}")
|
||||
self._context.cursor.execute(join.insert_string)
|
||||
|
||||
def delete_user_got_achievement(self, join: UserGotAchievement):
|
||||
self._logger.trace(__name__, f"Send SQL command: {join.delete_string}")
|
||||
self._context.cursor.execute(join.delete_string)
|
||||
|
Reference in New Issue
Block a user