From 1755efb5d9cc8107256f3aa0c7811d6385c87b79 Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Mon, 6 Mar 2023 12:50:01 +0100 Subject: [PATCH] [WIP] Added migration and basics for history logic #246 --- .../migration/db_history_migration.py | 352 ++++++++++++++++++ kdb-bot/src/bot_data/model/api_key.py | 9 +- 2 files changed, 355 insertions(+), 6 deletions(-) create mode 100644 kdb-bot/src/bot_data/migration/db_history_migration.py diff --git a/kdb-bot/src/bot_data/migration/db_history_migration.py b/kdb-bot/src/bot_data/migration/db_history_migration.py new file mode 100644 index 00000000..580944d4 --- /dev/null +++ b/kdb-bot/src/bot_data/migration/db_history_migration.py @@ -0,0 +1,352 @@ +from bot_core.logging.database_logger import DatabaseLogger +from bot_data.abc.migration_abc import MigrationABC +from bot_data.db_context import DBContext + + +class DBHistoryMigration(MigrationABC): + name = "1.0.0_DBHistoryMigration" + + def __init__(self, logger: DatabaseLogger, db: DBContext): + MigrationABC.__init__(self) + self._logger = logger + self._db = db + self._cursor = db.cursor + + def _api_keys(self): + self._cursor.execute( + f""" + ALTER TABLE `ApiKeys` + MODIFY `LastModifiedAt` DATETIME(6) NULL ON UPDATE CURRENT_TIMESTAMP(6); + + ALTER TABLE `ApiKeys` + ALTER COLUMN `CreatedAt` SET DEFAULT CURRENT_TIMESTAMP(6); + + ALTER TABLE `ApiKeys` + ALTER COLUMN `LastModifiedAt` SET DEFAULT CURRENT_TIMESTAMP(6); + + CREATE TABLE IF NOT EXISTS `ApiKeysHistory` + ( + `Id` BIGINT(20) NOT NULL, + `Identifier` VARCHAR(255) NOT NULL, + `Key` VARCHAR(255) NOT NULL, + `CreatorId` BIGINT(20) DEFAULT NULL, + `Deleted` BOOL DEFAULT FALSE, + `DateFrom` DATETIME(6) NOT NULL, + `DateTo` DATETIME(6) NOT NULL + ); + + DROP TRIGGER IF EXISTS `TR_ApiKeysUpdate`; + + CREATE TRIGGER `TR_ApiKeysUpdate` + AFTER UPDATE + ON `ApiKeys` + FOR EACH ROW + BEGIN + INSERT INTO `ApiKeysHistory` (`Id`, `Identifier`, `Key`, `CreatorId`, `DateFrom`, `DateTo`) + VALUES (OLD.Id, OLD.Identifier, OLD.Key, OLD.CreatorId, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6)); + END; + + DROP TRIGGER IF EXISTS `TR_ApiKeysDelete`; + + CREATE TRIGGER `TR_ApiKeysDelete` + AFTER DELETE + ON `ApiKeys` + FOR EACH ROW + BEGIN + INSERT INTO `ApiKeysHistory` (`Id`, `Identifier`, `Key`, `CreatorId`, `Deleted`, `DateFrom`, `DateTo`) + VALUES (OLD.Id, OLD.Identifier, OLD.Key, OLD.CreatorId, TRUE, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6)); + END; + """ + ) + + def _auth_users(self): + self._cursor.execute( + f""" + CREATE TABLE IF NOT EXISTS `AuthUsersHistory` + ( + `Id` bigint(20) NOT NULL, + `FirstName` varchar(255) DEFAULT NULL, + `LastName` varchar(255) DEFAULT NULL, + `EMail` varchar(255) DEFAULT NULL, + `Password` varchar(255) DEFAULT NULL, + `PasswordSalt` varchar(255) DEFAULT NULL, + `RefreshToken` varchar(255) DEFAULT NULL, + `ConfirmationId` varchar(255) DEFAULT NULL, + `ForgotPasswordId` varchar(255) DEFAULT NULL, + `OAuthId` varchar(255) DEFAULT NULL, + `RefreshTokenExpiryTime` datetime(6) NOT NULL, + `AuthRole` int(11) NOT NULL DEFAULT 0, + `DateFrom` datetime(6) NOT NULL, + `DateTo` datetime(6) NOT NULL + ); + """ + ) + + def _auth_user_users_relation(self): + self._cursor.execute( + f""" + CREATE TABLE IF NOT EXISTS `AuthUserUsersRelationsHistory` + ( + `Id` bigint(20) NOT NULL, + `AuthUserId` bigint(20) DEFAULT NULL, + `UserId` bigint(20) DEFAULT NULL, + `DateFrom` datetime(6) NOT NULL, + `DateTo` datetime(6) NOT NULL + ); + """ + ) + + def _auto_role_rules(self): + self._cursor.execute( + f""" + CREATE TABLE IF NOT EXISTS `AutoRoleRulesHistory` + ( + `AutoRoleRuleId` bigint(20) NOT NULL, + `AutoRoleId` bigint(20) DEFAULT NULL, + `DiscordEmojiName` varchar(64) DEFAULT NULL, + `DiscordRoleId` bigint(20) NOT NULL, + `DateFrom` datetime(6) NOT NULL, + `DateTo` datetime(6) NOT NULL + ); + """ + ) + + def _auto_roles(self): + self._cursor.execute( + f""" + CREATE TABLE IF NOT EXISTS `AutoRolesHistory` + ( + `AutoRoleId` bigint(20) NOT NULL, + `ServerId` bigint(20) DEFAULT NULL, + `DiscordChannelId` bigint(20) NOT NULL, + `DiscordMessageId` bigint(20) NOT NULL, + `DateFrom` datetime(6) NOT NULL, + `DateTo` datetime(6) NOT NULL + ); + """ + ) + + def _clients_history(self): + self._cursor.execute( + f""" + CREATE TABLE IF NOT EXISTS `ClientsHistory` + ( + `ClientId` bigint(20) NOT NULL, + `DiscordClientId` bigint(20) NOT NULL, + `SentMessageCount` bigint(20) NOT NULL DEFAULT 0, + `ReceivedMessageCount` bigint(20) NOT NULL DEFAULT 0, + `DeletedMessageCount` bigint(20) NOT NULL DEFAULT 0, + `ReceivedCommandsCount` bigint(20) NOT NULL DEFAULT 0, + `MovedUsersCount` bigint(20) NOT NULL DEFAULT 0, + `ServerId` bigint(20) DEFAULT NULL, + `DateFrom` datetime(6) NOT NULL, + `DateTo` datetime(6) NOT NULL + ); + """ + ) + + def _game_servers(self): + self._cursor.execute( + f""" + CREATE TABLE IF NOT EXISTS `GameServersHistory` + ( + `Id` bigint(20) NOT NULL, + `Name` varchar(255) NOT NULL, + `ServerId` bigint(20) NOT NULL, + `ApiKeyId` bigint(20) NOT NULL, + `DateFrom` datetime(6) NOT NULL, + `DateTo` datetime(6) NOT NULL + ); + """ + ) + + def _known_users(self): + self._cursor.execute( + f""" + CREATE TABLE IF NOT EXISTS `KnownUsersHistory` + ( + `KnownUserId` bigint(20) NOT NULL, + `DiscordId` bigint(20) NOT NULL, + `DateFrom` datetime(6) NOT NULL, + `DateTo` datetime(6) NOT NULL + ); + """ + ) + + def _levels(self): + self._cursor.execute( + f""" + CREATE TABLE IF NOT EXISTS `LevelsHistory` + ( + `Id` bigint(20) NOT NULL, + `Name` varchar(255) NOT NULL, + `Color` varchar(8) NOT NULL, + `MinXp` bigint(20) NOT NULL, + `PermissionInt` bigint(20) NOT NULL, + `ServerId` bigint(20) DEFAULT NULL, + `DateFrom` datetime(6) NOT NULL, + `DateTo` datetime(6) NOT NULL + ); + """ + ) + + def _servers(self): + self._cursor.execute( + f""" + CREATE TABLE IF NOT EXISTS `ServersHistory` + ( + `ServerId` bigint(20) NOT NULL, + `DiscordServerId` bigint(20) NOT NULL, + `DateFrom` datetime(6) NOT NULL, + `DateTo` datetime(6) NOT NULL + ); + """ + ) + + def _user_game_idents(self): + self._cursor.execute( + f""" + CREATE TABLE IF NOT EXISTS `UserGameIdentsHistory` + ( + `Id` bigint(20) NOT NULL, + `UserId` bigint(20) NOT NULL, + `GameServerId` bigint(20) NOT NULL, + `Ident` varchar(255) NOT NULL, + `DateFrom` datetime(6) NOT NULL, + `DateTo` datetime(6) NOT NULL + ); + """ + ) + + def _user_joined_game_server(self): + self._cursor.execute( + f""" + CREATE TABLE IF NOT EXISTS `UserJoinedGameServerHistory` + ( + `Id` bigint(20) NOT NULL, + `UserId` bigint(20) NOT NULL, + `GameServerId` bigint(20) NOT NULL, + `JoinedOn` datetime(6) NOT NULL, + `LeavedOn` datetime(6) DEFAULT NULL, + `DateFrom` datetime(6) NOT NULL, + `DateTo` datetime(6) NOT NULL + ); + """ + ) + + def _user_joined_server(self): + self._cursor.execute( + f""" + CREATE TABLE IF NOT EXISTS `UserJoinedServersHistory` + ( + `JoinId` bigint(20) NOT NULL, + `UserId` bigint(20) NOT NULL, + `JoinedOn` datetime(6) NOT NULL, + `LeavedOn` datetime(6) DEFAULT NULL, + `DateFrom` datetime(6) NOT NULL, + `DateTo` datetime(6) NOT NULL + ); + """ + ) + + def _user_joined_voice_channel(self): + self._cursor.execute( + f""" + CREATE TABLE IF NOT EXISTS `UserJoinedVoiceChannelHistory` + ( + `JoinId` bigint(20) NOT NULL, + `UserId` bigint(20) NOT NULL, + `DiscordChannelId` bigint(20) NOT NULL, + `JoinedOn` datetime(6) NOT NULL, + `LeavedOn` datetime(6) DEFAULT NULL, + `DateFrom` datetime(6) NOT NULL, + `DateTo` datetime(6) NOT NULL + ); + """ + ) + + def _user_message_count_per_hour(self): + self._cursor.execute( + f""" + CREATE TABLE IF NOT EXISTS `UserMessageCountPerHourHistory` + ( + `Id` bigint(20) NOT NULL, + `Date` datetime(6) NOT NULL, + `Hour` bigint(20) DEFAULT NULL, + `XPCount` bigint(20) DEFAULT NULL, + `UserId` bigint(20) DEFAULT NULL, + `DateFrom` datetime(6) NOT NULL, + `DateTo` datetime(6) NOT NULL + ); + """ + ) + + def _users(self): + self._cursor.execute( + f""" + CREATE TABLE IF NOT EXISTS `UsersHistory` + ( + `UserId` bigint(20) NOT NULL, + `DiscordId` bigint(20) NOT NULL, + `XP` bigint(20) NOT NULL DEFAULT 0, + `ServerId` bigint(20) DEFAULT NULL, + `DateFrom` datetime(6) NOT NULL, + `DateTo` datetime(6) NOT NULL + ); + """ + ) + + def _user_warnings(self): + self._cursor.execute( + f""" + CREATE TABLE IF NOT EXISTS `UserWarningsHistory` + ( + `Id` bigint(20) NOT NULL, + `Description` varchar(255) NOT NULL, + `UserId` bigint(20) NOT NULL, + `Author` bigint(20) DEFAULT NULL, + `DateFrom` datetime(6) NOT NULL, + `DateTo` datetime(6) NOT NULL + ); + """ + ) + + def upgrade(self): + self._logger.debug(__name__, "Running upgrade") + + self._api_keys() + self._auth_users() + self._auth_user_users_relation() + self._auto_role_rules() + self._auto_roles() + self._clients_history() + self._game_servers() + self._known_users() + self._levels() + self._servers() + self._user_game_idents() + self._user_joined_game_server() + self._user_joined_server() + self._user_joined_voice_channel() + self._user_message_count_per_hour() + self._users() + self._user_warnings() + + def downgrade(self): + self._cursor.execute("DROP TABLE `ApiKeysHistory`;") + self._cursor.execute("DROP TABLE `AuthUsersHistory`;") + self._cursor.execute("DROP TABLE `AuthUserUsersRelationsHistory`;") + self._cursor.execute("DROP TABLE `AutoRoleRulesHistory`;") + self._cursor.execute("DROP TABLE `AutoRolesHistory`;") + self._cursor.execute("DROP TABLE `ClientsHistory`;") + self._cursor.execute("DROP TABLE `GameServersHistory`;") + self._cursor.execute("DROP TABLE `KnownUsersHistory`;") + self._cursor.execute("DROP TABLE `LevelsHistory`;") + self._cursor.execute("DROP TABLE `ServersHistory`;") + self._cursor.execute("DROP TABLE `UserGameIdentsHistory`;") + self._cursor.execute("DROP TABLE `UserJoinedGameServerHistory`;") + self._cursor.execute("DROP TABLE `UserJoinedServersHistory`;") + self._cursor.execute("DROP TABLE `UserJoinedVoiceChannelHistory`;") + self._cursor.execute("DROP TABLE `UserMessageCountPerHourHistory`;") + self._cursor.execute("DROP TABLE `UsersHistory`;") + self._cursor.execute("DROP TABLE `UserWarningsHistory`;") diff --git a/kdb-bot/src/bot_data/model/api_key.py b/kdb-bot/src/bot_data/model/api_key.py index e4bc6e9c..d63c4d1b 100644 --- a/kdb-bot/src/bot_data/model/api_key.py +++ b/kdb-bot/src/bot_data/model/api_key.py @@ -82,13 +82,11 @@ class ApiKey(TableABC): return str( f""" INSERT INTO `ApiKeys` ( - `Identifier`, `Key`, `CreatorId`, `CreatedAt`, `LastModifiedAt` + `Identifier`, `Key`, `CreatorId` ) VALUES ( '{self._identifier}', '{self._key}', - {"NULL" if self._creator is None else f"'{self._creator.id}'"}, - '{self._created_at}', - '{self._modified_at}' + {"NULL" if self._creator is None else f"'{self._creator.id}'"} ); """ ) @@ -100,8 +98,7 @@ class ApiKey(TableABC): UPDATE `ApiKeys` SET `Identifier` = '{self._identifier}', `Key` = '{self._key}', - `CreatorId` = {"NULL" if self._creator is None else f"'{self._creator.id}'"}, - `LastModifiedAt` = '{self._modified_at}' + `CreatorId` = {"NULL" if self._creator is None else f"'{self._creator.id}'"} WHERE `Id` = {self._id}; """ )