diff --git a/kdb-bot/src/bot/bot.json b/kdb-bot/src/bot/bot.json index 887c87bd..3b9deda7 100644 --- a/kdb-bot/src/bot/bot.json +++ b/kdb-bot/src/bot/bot.json @@ -18,7 +18,7 @@ "Dependencies": [ "cpl-core==2022.12.1.post3", "cpl-translation==2022.12.1", - "cpl-query==2022.12.2.post1", + "cpl-query==2022.12.2.post2", "Flask==2.2.2", "Flask-Classful==0.14.2", "Flask-Cors==3.0.10", diff --git a/kdb-bot/src/bot/config b/kdb-bot/src/bot/config index 781aa3f6..0bd4bb02 160000 --- a/kdb-bot/src/bot/config +++ b/kdb-bot/src/bot/config @@ -1 +1 @@ -Subproject commit 781aa3f6ab861343d1635005ec7dc1814065b3c7 +Subproject commit 0bd4bb020b1a058e0a1fa9d4ffa1d4a3bffb28b8 diff --git a/kdb-bot/src/bot/startup_migration_extension.py b/kdb-bot/src/bot/startup_migration_extension.py index a41b19cb..5eba461b 100644 --- a/kdb-bot/src/bot/startup_migration_extension.py +++ b/kdb-bot/src/bot/startup_migration_extension.py @@ -8,6 +8,7 @@ from bot_data.migration.api_key_migration import ApiKeyMigration from bot_data.migration.api_migration import ApiMigration from bot_data.migration.auto_role_fix1_migration import AutoRoleFix1Migration from bot_data.migration.auto_role_migration import AutoRoleMigration +from bot_data.migration.db_history_migration import DBHistoryMigration from bot_data.migration.initial_migration import InitialMigration from bot_data.migration.level_migration import LevelMigration from bot_data.migration.remove_stats_migration import RemoveStatsMigration @@ -40,3 +41,4 @@ class StartupMigrationExtension(StartupExtensionABC): services.add_transient(MigrationABC, UserJoinedGameServerMigration) # 12.02.2023 #181 - 1.0.0 services.add_transient(MigrationABC, RemoveStatsMigration) # 19.02.2023 #190 - 1.0.0 services.add_transient(MigrationABC, UserWarningMigration) # 21.02.2023 #35 - 1.0.0 + services.add_transient(MigrationABC, DBHistoryMigration) # 06.03.2023 #246 - 1.0.0 diff --git a/kdb-bot/src/bot_data/abc/history_table_abc.py b/kdb-bot/src/bot_data/abc/history_table_abc.py new file mode 100644 index 00000000..4f96da31 --- /dev/null +++ b/kdb-bot/src/bot_data/abc/history_table_abc.py @@ -0,0 +1,27 @@ +from abc import ABC, abstractmethod +from datetime import datetime + + +class HistoryTableABC(ABC): + @abstractmethod + def __init__(self): + self._id = 0 + self._deleted = False + self._date_from = datetime.now().isoformat() + self._date_to = datetime.now().isoformat() + + @property + def id(self) -> int: + return self._id + + @property + def deleted(self) -> bool: + return self._deleted + + @property + def date_from(self) -> str: + return self._date_from + + @property + def date_to(self) -> str: + return self._date_to diff --git a/kdb-bot/src/bot_data/abc/migration_abc.py b/kdb-bot/src/bot_data/abc/migration_abc.py index f6af458c..e44e0bc2 100644 --- a/kdb-bot/src/bot_data/abc/migration_abc.py +++ b/kdb-bot/src/bot_data/abc/migration_abc.py @@ -3,6 +3,7 @@ from abc import ABC, abstractmethod class MigrationABC(ABC): name = None + prio = 0 @abstractmethod def __init__(self): diff --git a/kdb-bot/src/bot_data/abc/table_with_id_abc.py b/kdb-bot/src/bot_data/abc/table_with_id_abc.py new file mode 100644 index 00000000..720941cf --- /dev/null +++ b/kdb-bot/src/bot_data/abc/table_with_id_abc.py @@ -0,0 +1,15 @@ +from abc import abstractmethod + +from cpl_core.database import TableABC + + +class TableWithIdABC(TableABC): + @abstractmethod + def __init__(self): + self.__init__() + + self._id = 0 + + @property + def id(self) -> int: + return self._id diff --git a/kdb-bot/src/bot_data/migration/api_key_migration.py b/kdb-bot/src/bot_data/migration/api_key_migration.py index 76004f13..0712974b 100644 --- a/kdb-bot/src/bot_data/migration/api_key_migration.py +++ b/kdb-bot/src/bot_data/migration/api_key_migration.py @@ -4,7 +4,7 @@ from bot_data.db_context import DBContext class ApiKeyMigration(MigrationABC): - name = "1.0_ApiKeyMigration" + name = "1.0.0_ApiKeyMigration" def __init__(self, logger: DatabaseLogger, db: DBContext): MigrationABC.__init__(self) 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..e7322ad9 --- /dev/null +++ b/kdb-bot/src/bot_data/migration/db_history_migration.py @@ -0,0 +1,65 @@ +import os + +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" + prio = 1 + + def __init__(self, logger: DatabaseLogger, db: DBContext): + MigrationABC.__init__(self) + self._logger = logger + self._db = db + self._cursor = db.cursor + + def _exec(self, file: str): + path = f"{os.path.dirname(os.path.realpath(__file__))}/db_history_scripts" + sql = open(f"{path}/{file}").read() + + for statement in sql.split("\n\n"): + self._cursor.execute(statement + ";") + + def upgrade(self): + self._logger.debug(__name__, "Running upgrade") + + self._exec("api_keys.sql") + self._exec("auth_users.sql") + self._exec("auth_user_users_relation.sql") + self._exec("auto_role_rules.sql") + self._exec("auto_roles.sql") + self._exec("clients.sql") + self._exec("game_servers.sql") + self._exec("known_users.sql") + self._exec("levels.sql") + self._exec("servers.sql") + self._exec("user_game_idents.sql") + self._exec("user_joined_game_servers.sql") + self._exec("user_joined_servers.sql") + self._exec("user_joined_voice_channel.sql") + self._exec("user_message_count_per_hour.sql") + self._exec("users.sql") + self._exec("user_warnings.sql") + + self._logger.debug(__name__, "Finished history upgrade") + + 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/migration/db_history_scripts/api_keys.sql b/kdb-bot/src/bot_data/migration/db_history_scripts/api_keys.sql new file mode 100644 index 00000000..10285da4 --- /dev/null +++ b/kdb-bot/src/bot_data/migration/db_history_scripts/api_keys.sql @@ -0,0 +1,46 @@ +ALTER TABLE `ApiKeys` + CHANGE `CreatedAt` `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6); + +ALTER TABLE `ApiKeys` + CHANGE `LastModifiedAt` `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE 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; \ No newline at end of file diff --git a/kdb-bot/src/bot_data/migration/db_history_scripts/auth_user_users_relation.sql b/kdb-bot/src/bot_data/migration/db_history_scripts/auth_user_users_relation.sql new file mode 100644 index 00000000..2ce0d762 --- /dev/null +++ b/kdb-bot/src/bot_data/migration/db_history_scripts/auth_user_users_relation.sql @@ -0,0 +1,46 @@ +ALTER TABLE `AuthUserUsersRelations` + CHANGE `CreatedAt` `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6); + +ALTER TABLE `AuthUserUsersRelations` + CHANGE `LastModifiedAt` `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6); + + +CREATE TABLE IF NOT EXISTS `AuthUserUsersRelationsHistory` +( + `Id` BIGINT(20) NOT NULL, + `AuthUserId` BIGINT(20) DEFAULT NULL, + `UserId` BIGINT(20) DEFAULT NULL, + `Deleted` BOOL DEFAULT FALSE, + `DateFrom` DATETIME(6) NOT NULL, + `DateTo` DATETIME(6) NOT NULL +); + +DROP TRIGGER IF EXISTS `TR_AuthUserUsersRelationsUpdate`; + +CREATE TRIGGER `TR_AuthUserUsersRelationsUpdate` + AFTER UPDATE + ON `AuthUserUsersRelations` + FOR EACH ROW +BEGIN + INSERT INTO `AuthUserUsersRelationsHistory` ( + `Id`, `AuthUserId`, `UserId`, `DateFrom`, `DateTo` + ) + VALUES ( + OLD.Id, OLD.AuthUserId, OLD.UserId, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) + ); +END; + +DROP TRIGGER IF EXISTS `TR_AuthUserUsersRelationsDelete`; + +CREATE TRIGGER `TR_AuthUserUsersRelationsDelete` + AFTER DELETE + ON `AuthUserUsersRelations` + FOR EACH ROW +BEGIN + INSERT INTO `AuthUserUsersRelationsHistory` ( + `Id`, `AuthUserId`, `UserId`, `Deleted`, `DateFrom`, `DateTo` + ) + VALUES ( + OLD.Id, OLD.AuthUserId, OLD.UserId, TRUE, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) + ); +END; \ No newline at end of file diff --git a/kdb-bot/src/bot_data/migration/db_history_scripts/auth_users.sql b/kdb-bot/src/bot_data/migration/db_history_scripts/auth_users.sql new file mode 100644 index 00000000..ab22cc65 --- /dev/null +++ b/kdb-bot/src/bot_data/migration/db_history_scripts/auth_users.sql @@ -0,0 +1,62 @@ +ALTER TABLE `AuthUsers` + CHANGE `CreatedAt` `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6); + +ALTER TABLE `AuthUsers` + CHANGE `LastModifiedAt` `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6); + +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` BIGINT(11) NOT NULL DEFAULT 0, + `Deleted` BOOL DEFAULT FALSE, + `DateFrom` DATETIME(6) NOT NULL, + `DateTo` DATETIME(6) NOT NULL +); + +DROP TRIGGER IF EXISTS `TR_AuthUsersUpdate`; + +CREATE TRIGGER `TR_AuthUsersUpdate` + AFTER UPDATE + ON `AuthUsers` + FOR EACH ROW +BEGIN + INSERT INTO `AuthUsersHistory` ( + `Id`, `FirstName`, `LastName`, `EMail`, `Password`, `PasswordSalt`, + `RefreshToken`, `ConfirmationId`, `ForgotPasswordId`, `OAuthId`, + `RefreshTokenExpiryTime`, `AuthRole`, `DateFrom`, `DateTo` + ) + VALUES ( + OLD.Id, OLD.FirstName, OLD.LastName, OLD.EMail, OLD.Password, OLD.PasswordSalt, OLD.RefreshToken, + OLD.ConfirmationId, OLD.ForgotPasswordId, OLD.OAuthId, OLD.RefreshTokenExpiryTime, OLD.AuthRole, + OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) + ); +END; + +DROP TRIGGER IF EXISTS `TR_AuthUsersDelete`; + +CREATE TRIGGER `TR_AuthUsersDelete` + AFTER DELETE + ON `AuthUsers` + FOR EACH ROW +BEGIN + INSERT INTO `AuthUsersHistory` ( + `Id`, `FirstName`, `LastName`, `EMail`, `Password`, `PasswordSalt`, `RefreshToken`, + `ConfirmationId`, `ForgotPasswordId`, `OAuthId`, `RefreshTokenExpiryTime`, + `AuthRole`, `Deleted`, `DateFrom`, `DateTo` + ) + VALUES ( + OLD.Id, OLD.FirstName, OLD.LastName, OLD.EMail, OLD.Password, OLD.PasswordSalt, OLD.RefreshToken, + OLD.ConfirmationId, OLD.ForgotPasswordId, OLD.OAuthId, OLD.RefreshTokenExpiryTime, OLD.AuthRole, TRUE, + OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) + ); +END; \ No newline at end of file diff --git a/kdb-bot/src/bot_data/migration/db_history_scripts/auto_role_rules.sql b/kdb-bot/src/bot_data/migration/db_history_scripts/auto_role_rules.sql new file mode 100644 index 00000000..bcfa5f77 --- /dev/null +++ b/kdb-bot/src/bot_data/migration/db_history_scripts/auto_role_rules.sql @@ -0,0 +1,46 @@ +ALTER TABLE `AutoRoleRules` + CHANGE `CreatedAt` `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6); + +ALTER TABLE `AutoRoleRules` + CHANGE `LastModifiedAt` `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6); + +CREATE TABLE IF NOT EXISTS `AutoRoleRulesHistory` +( + `Id` BIGINT(20) NOT NULL, + `AutoRoleId` BIGINT(20) DEFAULT NULL, + `DiscordEmojiName` VARCHAR(64) DEFAULT NULL, + `DiscordRoleId` BIGINT(20) NOT NULL, + `Deleted` BOOL DEFAULT FALSE, + `DateFrom` DATETIME(6) NOT NULL, + `DateTo` DATETIME(6) NOT NULL +); + +DROP TRIGGER IF EXISTS `TR_AutoRoleRulesUpdate`; + +CREATE TRIGGER `TR_AutoRoleRulesUpdate` + AFTER UPDATE + ON `AutoRoleRules` + FOR EACH ROW +BEGIN + INSERT INTO `AutoRoleRulesHistory` ( + `Id`, `AutoRoleId`, `DiscordEmojiName`, `DiscordRoleId`, `DateFrom`, `DateTo` + ) + VALUES ( + OLD.AutoRoleRuleId, OLD.AutoRoleId, OLD.DiscordEmojiName, OLD.DiscordRoleId, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) + ); +END; + +DROP TRIGGER IF EXISTS `TR_AutoRoleRulesDelete`; + +CREATE TRIGGER `TR_AutoRoleRulesDelete` + AFTER DELETE + ON `AutoRoleRules` + FOR EACH ROW +BEGIN + INSERT INTO `AutoRoleRulesHistory` ( + `Id`, `AutoRoleId`, `DiscordEmojiName`, `DiscordRoleId`, `Deleted`, `DateFrom`, `DateTo` + ) + VALUES ( + OLD.AutoRoleRuleId, OLD.AutoRoleId, OLD.DiscordEmojiName, OLD.DiscordRoleId, TRUE, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) + ); +END; \ No newline at end of file diff --git a/kdb-bot/src/bot_data/migration/db_history_scripts/auto_roles.sql b/kdb-bot/src/bot_data/migration/db_history_scripts/auto_roles.sql new file mode 100644 index 00000000..7b78ea02 --- /dev/null +++ b/kdb-bot/src/bot_data/migration/db_history_scripts/auto_roles.sql @@ -0,0 +1,48 @@ +ALTER TABLE `AutoRoles` + CHANGE `CreatedAt` `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6); + +ALTER TABLE `AutoRoles` + CHANGE `LastModifiedAt` `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6); + +CREATE TABLE IF NOT EXISTS `AutoRolesHistory` +( + `Id` BIGINT(20) NOT NULL, + `ServerId` BIGINT(20) DEFAULT NULL, + `DiscordChannelId` BIGINT(20) NOT NULL, + `DiscordMessageId` BIGINT(20) NOT NULL, + `Deleted` BOOL DEFAULT FALSE, + `DateFrom` DATETIME(6) NOT NULL, + `DateTo` DATETIME(6) NOT NULL +); + +DROP TRIGGER IF EXISTS `TR_AutoRolesUpdate`; + +CREATE TRIGGER `TR_AutoRolesUpdate` + AFTER UPDATE + ON `AutoRoles` + FOR EACH ROW +BEGIN + INSERT INTO `AutoRolesHistory` ( + `Id`, `ServerId`, `DiscordChannelId`, `DiscordMessageId`, `DateFrom`, `DateTo` + ) + VALUES ( + OLD.AutoRoleId, OLD.ServerId, OLD.DiscordChannelId, OLD.DiscordMessageId, OLD.LastModifiedAt, + CURRENT_TIMESTAMP(6) + ); +END; + +DROP TRIGGER IF EXISTS `TR_AutoRolesDelete`; + +CREATE TRIGGER `TR_AutoRolesDelete` + AFTER DELETE + ON `AutoRoles` + FOR EACH ROW +BEGIN + INSERT INTO `AutoRolesHistory` ( + `Id`, `ServerId`, `DiscordChannelId`, `DiscordMessageId`, `Deleted`, `DateFrom`, `DateTo` + ) + VALUES ( + OLD.AutoRoleId, OLD.ServerId, OLD.DiscordChannelId, OLD.DiscordMessageId, TRUE, OLD.LastModifiedAt, + CURRENT_TIMESTAMP(6) + ); +END; \ No newline at end of file diff --git a/kdb-bot/src/bot_data/migration/db_history_scripts/clients.sql b/kdb-bot/src/bot_data/migration/db_history_scripts/clients.sql new file mode 100644 index 00000000..b1048785 --- /dev/null +++ b/kdb-bot/src/bot_data/migration/db_history_scripts/clients.sql @@ -0,0 +1,54 @@ +ALTER TABLE `Clients` + CHANGE `CreatedAt` `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6); + +ALTER TABLE `Clients` + CHANGE `LastModifiedAt` `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6); + +CREATE TABLE IF NOT EXISTS `ClientsHistory` +( + `Id` BIGINT(20) NOT NULL, + `DiscordId` 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, + `Deleted` BOOL DEFAULT FALSE, + `DateFrom` DATETIME(6) NOT NULL, + `DateTo` DATETIME(6) NOT NULL +); + +DROP TRIGGER IF EXISTS `TR_ClientsUpdate`; + +CREATE TRIGGER `TR_ClientsUpdate` + AFTER UPDATE + ON `Clients` + FOR EACH ROW +BEGIN + INSERT INTO `ClientsHistory` ( + `Id`, `DiscordId`, `SentMessageCount`, `ReceivedMessageCount`, `DeletedMessageCount`, + `ReceivedCommandsCount`, `MovedUsersCount`, `ServerId`, `DateFrom`, `DateTo` + ) + VALUES ( + OLD.ClientId, OLD.DiscordClientId, OLD.SentMessageCount, OLD.ReceivedMessageCount, OLD.DeletedMessageCount, + OLD.ReceivedCommandsCount, OLD.MovedUsersCount, OLD.ServerId, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) + ); +END; + +DROP TRIGGER IF EXISTS `TR_ClientsDelete`; + +CREATE TRIGGER `TR_ClientsDelete` + AFTER DELETE + ON `Clients` + FOR EACH ROW +BEGIN + INSERT INTO `ClientsHistory` ( + `Id`, `DiscordId`, `SentMessageCount`, `ReceivedMessageCount`, `DeletedMessageCount`, + `ReceivedCommandsCount`, `MovedUsersCount`, `ServerId`, `Deleted`, `DateFrom`, `DateTo` + ) + VALUES ( + OLD.ClientId, OLD.DiscordClientId, OLD.SentMessageCount, OLD.ReceivedMessageCount, OLD.DeletedMessageCount, + OLD.ReceivedCommandsCount, OLD.MovedUsersCount, OLD.ServerId, TRUE, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) + ); +END; \ No newline at end of file diff --git a/kdb-bot/src/bot_data/migration/db_history_scripts/game_servers.sql b/kdb-bot/src/bot_data/migration/db_history_scripts/game_servers.sql new file mode 100644 index 00000000..091cbf51 --- /dev/null +++ b/kdb-bot/src/bot_data/migration/db_history_scripts/game_servers.sql @@ -0,0 +1,46 @@ +ALTER TABLE `GameServers` + CHANGE `CreatedAt` `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6); + +ALTER TABLE `GameServers` + CHANGE `LastModifiedAt` `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6); + +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, + `Deleted` BOOL DEFAULT FALSE, + `DateFrom` DATETIME(6) NOT NULL, + `DateTo` DATETIME(6) NOT NULL +); + +DROP TRIGGER IF EXISTS `TR_GameServersUpdate`; + +CREATE TRIGGER `TR_GameServersUpdate` + AFTER UPDATE + ON `GameServers` + FOR EACH ROW +BEGIN + INSERT INTO `GameServersHistory` ( + `Id`, `Name`, `ServerId`, `ApiKeyId`, `DateFrom`, `DateTo` + ) + VALUES ( + OLD.Id, OLD.Name, OLD.ServerId, OLD.ApiKeyId, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) + ); +END; + +DROP TRIGGER IF EXISTS `TR_GameServersDelete`; + +CREATE TRIGGER `TR_GameServersDelete` + AFTER DELETE + ON `GameServers` + FOR EACH ROW +BEGIN + INSERT INTO `GameServersHistory` ( + `Id`, `Name`, `ServerId`, `ApiKeyId`, `Deleted`, `DateFrom`, `DateTo` + ) + VALUES ( + OLD.Id, OLD.Name, OLD.ServerId, OLD.ApiKeyId, TRUE, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) + ); +END; \ No newline at end of file diff --git a/kdb-bot/src/bot_data/migration/db_history_scripts/known_users.sql b/kdb-bot/src/bot_data/migration/db_history_scripts/known_users.sql new file mode 100644 index 00000000..5263aa8d --- /dev/null +++ b/kdb-bot/src/bot_data/migration/db_history_scripts/known_users.sql @@ -0,0 +1,44 @@ +ALTER TABLE `KnownUsers` + CHANGE `CreatedAt` `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6); + +ALTER TABLE `KnownUsers` + CHANGE `LastModifiedAt` `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6); + +CREATE TABLE IF NOT EXISTS `KnownUsersHistory` +( + `Id` BIGINT(20) NOT NULL, + `DiscordId` BIGINT(20) NOT NULL, + `Deleted` BOOL DEFAULT FALSE, + `DateFrom` DATETIME(6) NOT NULL, + `DateTo` DATETIME(6) NOT NULL +); + +DROP TRIGGER IF EXISTS `TR_KnownUsersUpdate`; + +CREATE TRIGGER `TR_KnownUsersUpdate` + AFTER UPDATE + ON `KnownUsers` + FOR EACH ROW +BEGIN + INSERT INTO `KnownUsersHistory` ( + `Id`, `DiscordId`, `DateFrom`, `DateTo` + ) + VALUES ( + OLD.KnownUserId, OLD.DiscordId, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) + ); +END; + +DROP TRIGGER IF EXISTS `TR_KnownUsersDelete`; + +CREATE TRIGGER `TR_KnownUsersDelete` + AFTER DELETE + ON `KnownUsers` + FOR EACH ROW +BEGIN + INSERT INTO `KnownUsersHistory` ( + `Id`, `DiscordId`, `Deleted`, `DateFrom`, `DateTo` + ) + VALUES ( + OLD.KnownUserId, OLD.DiscordId, TRUE, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) + ); +END; \ No newline at end of file diff --git a/kdb-bot/src/bot_data/migration/db_history_scripts/levels.sql b/kdb-bot/src/bot_data/migration/db_history_scripts/levels.sql new file mode 100644 index 00000000..6ba534e2 --- /dev/null +++ b/kdb-bot/src/bot_data/migration/db_history_scripts/levels.sql @@ -0,0 +1,50 @@ +ALTER TABLE `Levels` + CHANGE `CreatedAt` `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6); + +ALTER TABLE `Levels` + CHANGE `LastModifiedAt` `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6); + +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, + `Deleted` BOOL DEFAULT FALSE, + `DateFrom` DATETIME(6) NOT NULL, + `DateTo` DATETIME(6) NOT NULL +); + +DROP TRIGGER IF EXISTS `TR_LevelsUpdate`; + +CREATE TRIGGER `TR_LevelsUpdate` + AFTER UPDATE + ON `Levels` + FOR EACH ROW +BEGIN + INSERT INTO `LevelsHistory` ( + `Id`, `Name`, `Color`, `MinXp`, `PermissionInt`, `ServerId`, `DateFrom`, `DateTo` + ) + VALUES ( + OLD.Id, OLD.Name, OLD.Color, OLD.MinXp, OLD.PermissionInt, OLD.ServerId, OLD.LastModifiedAt, + CURRENT_TIMESTAMP(6) + ); +END; + +DROP TRIGGER IF EXISTS `TR_LevelsDelete`; + +CREATE TRIGGER `TR_LevelsDelete` + AFTER DELETE + ON `Levels` + FOR EACH ROW +BEGIN + INSERT INTO `LevelsHistory` ( + `Id`, `Name`, `Color`, `MinXp`, `PermissionInt`, `ServerId`, `Deleted`, `DateFrom`, `DateTo` + ) + VALUES ( + OLD.Id, OLD.Name, OLD.Color, OLD.MinXp, OLD.PermissionInt, OLD.ServerId, TRUE, OLD.LastModifiedAt, + CURRENT_TIMESTAMP(6) + ); +END; \ No newline at end of file diff --git a/kdb-bot/src/bot_data/migration/db_history_scripts/servers.sql b/kdb-bot/src/bot_data/migration/db_history_scripts/servers.sql new file mode 100644 index 00000000..2d9d6c49 --- /dev/null +++ b/kdb-bot/src/bot_data/migration/db_history_scripts/servers.sql @@ -0,0 +1,44 @@ +ALTER TABLE `Servers` + CHANGE `CreatedAt` `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6); + +ALTER TABLE `Servers` + CHANGE `LastModifiedAt` `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6); + +CREATE TABLE IF NOT EXISTS `ServersHistory` +( + `Id` BIGINT(20) NOT NULL, + `DiscordId` BIGINT(20) NOT NULL, + `Deleted` BOOL DEFAULT FALSE, + `DateFrom` DATETIME(6) NOT NULL, + `DateTo` DATETIME(6) NOT NULL +); + +DROP TRIGGER IF EXISTS `TR_ServersUpdate`; + +CREATE TRIGGER `TR_ServersUpdate` + AFTER UPDATE + ON `Servers` + FOR EACH ROW +BEGIN + INSERT INTO `ServersHistory` ( + `Id`, `DiscordId`, `DateFrom`, `DateTo` + ) + VALUES ( + OLD.ServerId, OLD.DiscordServerId, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) + ); +END; + +DROP TRIGGER IF EXISTS `TR_ServersDelete`; + +CREATE TRIGGER `TR_ServersDelete` + AFTER DELETE + ON `Servers` + FOR EACH ROW +BEGIN + INSERT INTO `ServersHistory` ( + `Id`, `DiscordId`, `Deleted`, `DateFrom`, `DateTo` + ) + VALUES ( + OLD.ServerId, OLD.DiscordServerId, TRUE, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) + ); +END; \ No newline at end of file diff --git a/kdb-bot/src/bot_data/migration/db_history_scripts/user_game_idents.sql b/kdb-bot/src/bot_data/migration/db_history_scripts/user_game_idents.sql new file mode 100644 index 00000000..fab7a21b --- /dev/null +++ b/kdb-bot/src/bot_data/migration/db_history_scripts/user_game_idents.sql @@ -0,0 +1,46 @@ +ALTER TABLE `UserGameIdents` + CHANGE `CreatedAt` `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6); + +ALTER TABLE `UserGameIdents` + CHANGE `LastModifiedAt` `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6); + +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, + `Deleted` BOOL DEFAULT FALSE, + `DateFrom` DATETIME(6) NOT NULL, + `DateTo` DATETIME(6) NOT NULL +); + +DROP TRIGGER IF EXISTS `TR_UserGameIdentsUpdate`; + +CREATE TRIGGER `TR_UserGameIdentsUpdate` + AFTER UPDATE + ON `UserGameIdents` + FOR EACH ROW +BEGIN + INSERT INTO `UserGameIdentsHistory` ( + `Id`, `UserId`, `GameServerId`, `Ident`, `DateFrom`, `DateTo` + ) + VALUES ( + OLD.Id, OLD.UserId, OLD.GameServerId, OLD.Ident, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) + ); +END; + +DROP TRIGGER IF EXISTS `TR_UserGameIdentsDelete`; + +CREATE TRIGGER `TR_UserGameIdentsDelete` + AFTER DELETE + ON `UserGameIdents` + FOR EACH ROW +BEGIN + INSERT INTO `UserGameIdentsHistory` ( + `Id`, `UserId`, `GameServerId`, `Ident`, `Deleted`, `DateFrom`, `DateTo` + ) + VALUES ( + OLD.Id, OLD.UserId, OLD.GameServerId, OLD.Ident, TRUE, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) + ); +END; \ No newline at end of file diff --git a/kdb-bot/src/bot_data/migration/db_history_scripts/user_joined_game_servers.sql b/kdb-bot/src/bot_data/migration/db_history_scripts/user_joined_game_servers.sql new file mode 100644 index 00000000..203df921 --- /dev/null +++ b/kdb-bot/src/bot_data/migration/db_history_scripts/user_joined_game_servers.sql @@ -0,0 +1,47 @@ +ALTER TABLE `UserJoinedGameServer` + CHANGE `CreatedAt` `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6); + +ALTER TABLE `UserJoinedGameServer` + CHANGE `LastModifiedAt` `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6); + +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, + `Deleted` BOOL DEFAULT FALSE, + `DateFrom` DATETIME(6) NOT NULL, + `DateTo` DATETIME(6) NOT NULL +); + +DROP TRIGGER IF EXISTS `TR_UserJoinedGameServerUpdate`; + +CREATE TRIGGER `TR_UserJoinedGameServerUpdate` + AFTER UPDATE + ON `UserJoinedGameServer` + FOR EACH ROW +BEGIN + INSERT INTO `UserJoinedGameServerHistory` ( + `Id`, `UserId`, `GameServerId`, `JoinedOn`, `LeavedOn`, `DateFrom`, `DateTo` + ) + VALUES ( + OLD.Id, OLD.UserId, OLD.GameServerId, OLD.JoinedOn, OLD.LeavedOn, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) + ); +END; + +DROP TRIGGER IF EXISTS `TR_UserJoinedGameServerDelete`; + +CREATE TRIGGER `TR_UserJoinedGameServerDelete` + AFTER DELETE + ON `UserJoinedGameServer` + FOR EACH ROW +BEGIN + INSERT INTO `UserJoinedGameServerHistory` ( + `Id`, `UserId`, `GameServerId`, `JoinedOn`, `LeavedOn`, `Deleted`, `DateFrom`, `DateTo` + ) + VALUES ( + OLD.Id, OLD.UserId, OLD.GameServerId, OLD.JoinedOn, OLD.LeavedOn, TRUE, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) + ); +END; \ No newline at end of file diff --git a/kdb-bot/src/bot_data/migration/db_history_scripts/user_joined_servers.sql b/kdb-bot/src/bot_data/migration/db_history_scripts/user_joined_servers.sql new file mode 100644 index 00000000..45bc7d1e --- /dev/null +++ b/kdb-bot/src/bot_data/migration/db_history_scripts/user_joined_servers.sql @@ -0,0 +1,46 @@ +ALTER TABLE `UserJoinedServers` + CHANGE `CreatedAt` `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6); + +ALTER TABLE `UserJoinedServers` + CHANGE `LastModifiedAt` `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6); + +CREATE TABLE IF NOT EXISTS `UserJoinedServersHistory` +( + `Id` BIGINT(20) NOT NULL, + `UserId` BIGINT(20) NOT NULL, + `JoinedOn` DATETIME(6) NOT NULL, + `LeavedOn` DATETIME(6) DEFAULT NULL, + `Deleted` BOOL DEFAULT FALSE, + `DateFrom` DATETIME(6) NOT NULL, + `DateTo` DATETIME(6) NOT NULL +); + +DROP TRIGGER IF EXISTS `TR_UserJoinedServersUpdate`; + +CREATE TRIGGER `TR_UserJoinedServersUpdate` + AFTER UPDATE + ON `UserJoinedServers` + FOR EACH ROW +BEGIN + INSERT INTO `UserJoinedServersHistory` ( + `Id`, `UserId`, `JoinedOn`, `LeavedOn`, `DateFrom`, `DateTo` + ) + VALUES ( + OLD.JoinId, OLD.UserId, OLD.JoinedOn, OLD.LeavedOn, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) + ); +END; + +DROP TRIGGER IF EXISTS `TR_UserJoinedServersDelete`; + +CREATE TRIGGER `TR_UserJoinedServersDelete` + AFTER DELETE + ON `UserJoinedServers` + FOR EACH ROW +BEGIN + INSERT INTO `UserJoinedServersHistory` ( + `Id`, `UserId`, `JoinedOn`, `LeavedOn`, `Deleted`, `DateFrom`, `DateTo` + ) + VALUES ( + OLD.JoinId, OLD.UserId, OLD.JoinedOn, OLD.LeavedOn, TRUE, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) + ); +END; \ No newline at end of file diff --git a/kdb-bot/src/bot_data/migration/db_history_scripts/user_joined_voice_channel.sql b/kdb-bot/src/bot_data/migration/db_history_scripts/user_joined_voice_channel.sql new file mode 100644 index 00000000..8d439f7b --- /dev/null +++ b/kdb-bot/src/bot_data/migration/db_history_scripts/user_joined_voice_channel.sql @@ -0,0 +1,49 @@ +ALTER TABLE `UserJoinedVoiceChannel` + CHANGE `CreatedAt` `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6); + +ALTER TABLE `UserJoinedVoiceChannel` + CHANGE `LastModifiedAt` `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6); + +CREATE TABLE IF NOT EXISTS `UserJoinedVoiceChannelHistory` +( + `Id` BIGINT(20) NOT NULL, + `UserId` BIGINT(20) NOT NULL, + `DiscordChannelId` BIGINT(20) NOT NULL, + `JoinedOn` DATETIME(6) NOT NULL, + `LeavedOn` DATETIME(6) DEFAULT NULL, + `Deleted` BOOL DEFAULT FALSE, + `DateFrom` DATETIME(6) NOT NULL, + `DateTo` DATETIME(6) NOT NULL +); + +DROP TRIGGER IF EXISTS `TR_UserJoinedVoiceChannelUpdate`; + +CREATE TRIGGER `TR_UserJoinedVoiceChannelUpdate` + AFTER UPDATE + ON `UserJoinedVoiceChannel` + FOR EACH ROW +BEGIN + INSERT INTO `UserJoinedVoiceChannelHistory` ( + `Id`, `UserId`, `DiscordChannelId`, `JoinedOn`, `LeavedOn`, `DateFrom`, `DateTo` + ) + VALUES ( + OLD.JoinId, OLD.UserId, OLD.DiscordChannelId, OLD.JoinedOn, OLD.LeavedOn, OLD.LastModifiedAt, + CURRENT_TIMESTAMP(6) + ); +END; + +DROP TRIGGER IF EXISTS `TR_UserJoinedVoiceChannelDelete`; + +CREATE TRIGGER `TR_UserJoinedVoiceChannelDelete` + AFTER DELETE + ON `UserJoinedVoiceChannel` + FOR EACH ROW +BEGIN + INSERT INTO `UserJoinedVoiceChannelHistory` ( + `Id`, `UserId`, `DiscordChannelId`, `JoinedOn`, `LeavedOn`, `Deleted`, `DateFrom`, `DateTo` + ) + VALUES ( + OLD.JoinId, OLD.UserId, OLD.DiscordChannelId, OLD.JoinedOn, OLD.LeavedOn, TRUE, OLD.LastModifiedAt, + CURRENT_TIMESTAMP(6) + ); +END; \ No newline at end of file diff --git a/kdb-bot/src/bot_data/migration/db_history_scripts/user_message_count_per_hour.sql b/kdb-bot/src/bot_data/migration/db_history_scripts/user_message_count_per_hour.sql new file mode 100644 index 00000000..a86841b8 --- /dev/null +++ b/kdb-bot/src/bot_data/migration/db_history_scripts/user_message_count_per_hour.sql @@ -0,0 +1,47 @@ +ALTER TABLE `UserMessageCountPerHour` + CHANGE `CreatedAt` `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6); + +ALTER TABLE `UserMessageCountPerHour` + CHANGE `LastModifiedAt` `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6); + +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, + `Deleted` BOOL DEFAULT FALSE, + `DateFrom` DATETIME(6) NOT NULL, + `DateTo` DATETIME(6) NOT NULL +); + +DROP TRIGGER IF EXISTS `TR_UserMessageCountPerHourUpdate`; + +CREATE TRIGGER `TR_UserMessageCountPerHourUpdate` + AFTER UPDATE + ON `UserMessageCountPerHour` + FOR EACH ROW +BEGIN + INSERT INTO `UserMessageCountPerHourHistory` ( + `Id`, `UserId`, `Date`, `Hour`, `XPCount`, `DateFrom`, `DateTo` + ) + VALUES ( + OLD.Id, OLD.UserId, OLD.Date, OLD.Hour, OLD.XPCount, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) + ); +END; + +DROP TRIGGER IF EXISTS `TR_UserMessageCountPerHourDelete`; + +CREATE TRIGGER `TR_UserMessageCountPerHourDelete` + AFTER DELETE + ON `UserMessageCountPerHour` + FOR EACH ROW +BEGIN + INSERT INTO `UserMessageCountPerHourHistory` ( + `Id`, `UserId`, `Date`, `Hour`, `XPCount`, `Deleted`, `DateFrom`, `DateTo` + ) + VALUES ( + OLD.Id, OLD.UserId, OLD.Date, OLD.Hour, OLD.XPCount, TRUE, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) + ); +END; \ No newline at end of file diff --git a/kdb-bot/src/bot_data/migration/db_history_scripts/user_warnings.sql b/kdb-bot/src/bot_data/migration/db_history_scripts/user_warnings.sql new file mode 100644 index 00000000..4371b207 --- /dev/null +++ b/kdb-bot/src/bot_data/migration/db_history_scripts/user_warnings.sql @@ -0,0 +1,46 @@ +ALTER TABLE `UserWarnings` + CHANGE `CreatedAt` `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6); + +ALTER TABLE `UserWarnings` + CHANGE `LastModifiedAt` `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6); + +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, + `Deleted` BOOL DEFAULT FALSE, + `DateFrom` DATETIME(6) NOT NULL, + `DateTo` DATETIME(6) NOT NULL +); + +DROP TRIGGER IF EXISTS `TR_UserWarningsUpdate`; + +CREATE TRIGGER `TR_UserWarningsUpdate` + AFTER UPDATE + ON `UserWarnings` + FOR EACH ROW +BEGIN + INSERT INTO `UserWarningsHistory` ( + `Id`, `Description`, `UserId`, `Author`, `DateFrom`, `DateTo` + ) + VALUES ( + OLD.Id, OLD.Description, OLD.UserId, OLD.Author, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) + ); +END; + +DROP TRIGGER IF EXISTS `TR_UserWarningsDelete`; + +CREATE TRIGGER `TR_UserWarningsDelete` + AFTER DELETE + ON `UserWarnings` + FOR EACH ROW +BEGIN + INSERT INTO `UserWarningsHistory` ( + `Id`, `Description`, `UserId`, `Author`, `Deleted`, `DateFrom`, `DateTo` + ) + VALUES ( + OLD.Id, OLD.Description, OLD.UserId, OLD.Author, TRUE, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) + ); +END; \ No newline at end of file diff --git a/kdb-bot/src/bot_data/migration/db_history_scripts/users.sql b/kdb-bot/src/bot_data/migration/db_history_scripts/users.sql new file mode 100644 index 00000000..8dfebf63 --- /dev/null +++ b/kdb-bot/src/bot_data/migration/db_history_scripts/users.sql @@ -0,0 +1,46 @@ +ALTER TABLE `Users` + CHANGE `CreatedAt` `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6); + +ALTER TABLE `Users` + CHANGE `LastModifiedAt` `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6); + +CREATE TABLE IF NOT EXISTS `UsersHistory` +( + `Id` BIGINT(20) NOT NULL, + `DiscordId` BIGINT(20) NOT NULL, + `XP` BIGINT(20) NOT NULL DEFAULT 0, + `ServerId` BIGINT(20) DEFAULT NULL, + `Deleted` BOOL DEFAULT FALSE, + `DateFrom` DATETIME(6) NOT NULL, + `DateTo` DATETIME(6) NOT NULL +); + +DROP TRIGGER IF EXISTS `TR_UsersUpdate`; + +CREATE TRIGGER `TR_UsersUpdate` + AFTER UPDATE + ON `Users` + FOR EACH ROW +BEGIN + INSERT INTO `UsersHistory` ( + `Id`, `DiscordId`, `XP`, `ServerId`, `DateFrom`, `DateTo` + ) + VALUES ( + OLD.UserId, OLD.DiscordId, OLD.XP, OLD.ServerId, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) + ); +END; + +DROP TRIGGER IF EXISTS `TR_UsersDelete`; + +CREATE TRIGGER `TR_UsersDelete` + AFTER DELETE + ON `Users` + FOR EACH ROW +BEGIN + INSERT INTO `UsersHistory` ( + `Id`, `DiscordId`, `XP`, `ServerId`, `Deleted`, `DateFrom`, `DateTo` + ) + VALUES ( + OLD.UserId, OLD.DiscordId, OLD.XP, OLD.ServerId, TRUE, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) + ); +END; \ No newline at end of file diff --git a/kdb-bot/src/bot_data/migration/remove_stats_migration.py b/kdb-bot/src/bot_data/migration/remove_stats_migration.py index bbc029b5..e5e621a5 100644 --- a/kdb-bot/src/bot_data/migration/remove_stats_migration.py +++ b/kdb-bot/src/bot_data/migration/remove_stats_migration.py @@ -4,7 +4,7 @@ from bot_data.db_context import DBContext class RemoveStatsMigration(MigrationABC): - name = "1.0_RemoveStatsMigration" + name = "1.0.0_RemoveStatsMigration" def __init__(self, logger: DatabaseLogger, db: DBContext): MigrationABC.__init__(self) 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 22302a9f..bef8e5aa 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 @@ -4,7 +4,7 @@ from bot_data.db_context import DBContext class UserJoinedGameServerMigration(MigrationABC): - name = "1.0_UserJoinedGameServerMigration" + name = "1.0.0_UserJoinedGameServerMigration" def __init__(self, logger: DatabaseLogger, db: DBContext): MigrationABC.__init__(self) diff --git a/kdb-bot/src/bot_data/migration/user_warning_migration.py b/kdb-bot/src/bot_data/migration/user_warning_migration.py index 074cf929..06e446a0 100644 --- a/kdb-bot/src/bot_data/migration/user_warning_migration.py +++ b/kdb-bot/src/bot_data/migration/user_warning_migration.py @@ -4,7 +4,7 @@ from bot_data.db_context import DBContext class UserWarningMigration(MigrationABC): - name = "1.0_UserWarningMigration" + name = "1.0.0_UserWarningMigration" def __init__(self, logger: DatabaseLogger, db: DBContext): MigrationABC.__init__(self) 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}; """ ) diff --git a/kdb-bot/src/bot_data/model/auth_user.py b/kdb-bot/src/bot_data/model/auth_user.py index 9255bede..47bdf41a 100644 --- a/kdb-bot/src/bot_data/model/auth_user.py +++ b/kdb-bot/src/bot_data/model/auth_user.py @@ -220,9 +220,7 @@ class AuthUser(TableABC): `ForgotPasswordId`, `OAuthId`, `RefreshTokenExpiryTime`, - `AuthRole`, - `CreatedAt`, - `LastModifiedAt` + `AuthRole` ) VALUES ( {self._auth_user_id}, '{self._first_name}', @@ -235,9 +233,7 @@ class AuthUser(TableABC): {"NULL" if self._forgot_password_id is None else f"'{self._forgot_password_id}'"}, {"NULL" if self._oauth_id is None else f"'{self._oauth_id}'"}, '{self._refresh_token_expire_time.isoformat()}', - {self._auth_role_id.value}, - '{self._created_at}', - '{self._modified_at}' + {self._auth_role_id.value} ) """ ) @@ -257,8 +253,7 @@ class AuthUser(TableABC): `ForgotPasswordId` = {"NULL" if self._forgot_password_id is None else f"'{self._forgot_password_id}'"}, `OAuthId` = {"NULL" if self._oauth_id is None else f"'{self._oauth_id}'"}, `RefreshTokenExpiryTime` = '{self._refresh_token_expire_time.isoformat()}', - `AuthRole` = {self._auth_role_id.value}, - `LastModifiedAt` = '{self._modified_at}' + `AuthRole` = {self._auth_role_id.value} WHERE `AuthUsers`.`Id` = {self._auth_user_id}; """ ) diff --git a/kdb-bot/src/bot_data/model/auth_user_users_relation.py b/kdb-bot/src/bot_data/model/auth_user_users_relation.py index 6d5f7f30..23b9ceab 100644 --- a/kdb-bot/src/bot_data/model/auth_user_users_relation.py +++ b/kdb-bot/src/bot_data/model/auth_user_users_relation.py @@ -68,12 +68,10 @@ class AuthUserUsersRelation(TableABC): return str( f""" INSERT INTO `AuthUserUsersRelations` ( - `AuthUserId`, `UserId`, `CreatedAt`, `LastModifiedAt` + `AuthUserId`, `UserId` ) VALUES ( {self._auth_user.id}, - {self._user.id}, - '{self._created_at}', - '{self._modified_at}' + {self._user.id} ); """ ) @@ -83,9 +81,8 @@ class AuthUserUsersRelation(TableABC): return str( f""" UPDATE `AuthUserUsersRelations` - SET `AuthUserId` = '{self._auth_user.id}',, + SET `AuthUserId` = '{self._auth_user.id}', `UserId` = '{self._user.id}' - `LastModifiedAt` = '{self._modified_at}' WHERE `AuthUserId` = {self._auth_user.id} AND `UserId` = {self._user.id}; """ diff --git a/kdb-bot/src/bot_data/model/auto_role.py b/kdb-bot/src/bot_data/model/auto_role.py index 28ad489d..a1ff7934 100644 --- a/kdb-bot/src/bot_data/model/auto_role.py +++ b/kdb-bot/src/bot_data/model/auto_role.py @@ -97,13 +97,11 @@ class AutoRole(TableABC): return str( f""" INSERT INTO `AutoRoles` ( - `ServerId`, `DiscordChannelId`, `DiscordMessageId`, `CreatedAt`, `LastModifiedAt` + `ServerId`, `DiscordChannelId`, `DiscordMessageId` ) VALUES ( {self._server.id}, {self._discord_channel_id}, - {self._discord_message_id}, - '{self._created_at}', - '{self._modified_at}' + {self._discord_message_id} ); """ ) @@ -115,8 +113,7 @@ class AutoRole(TableABC): UPDATE `AutoRoles` SET `ServerId` = {self._server.id}, `DiscordChannelId` = {self._discord_channel_id}, - `DiscordMessageId` = {self._discord_message_id}, - `LastModifiedAt` = '{self._modified_at}' + `DiscordMessageId` = {self._discord_message_id} WHERE `AutoRoleId` = {self._auto_role_id}; """ ) diff --git a/kdb-bot/src/bot_data/model/auto_role_history.py b/kdb-bot/src/bot_data/model/auto_role_history.py new file mode 100644 index 00000000..0c9d7c5c --- /dev/null +++ b/kdb-bot/src/bot_data/model/auto_role_history.py @@ -0,0 +1,49 @@ +from cpl_core.dependency_injection import ServiceProviderABC +from cpl_discord.service import DiscordBotServiceABC + +from bot_data.abc.history_table_abc import HistoryTableABC + + +class AutoRoleHistory(HistoryTableABC): + def __init__( + self, + server: int, + channel_id: int, + dc_message_id: int, + deleted: bool, + date_from: str, + date_to: str, + id=0, + ): + HistoryTableABC.__init__(self) + + self._auto_role_id = id + self._server = server + self._discord_channel_id = channel_id + self._discord_message_id = dc_message_id + + self._deleted = deleted + self._date_from = date_from + self._date_to = date_to + + @property + def id(self) -> int: + return self._auto_role_id + + @property + def server(self) -> int: + return self._server + + @property + def discord_channel_id(self) -> int: + return self._discord_channel_id + + @property + @ServiceProviderABC.inject + def discord_channel_name(self, bot: DiscordBotServiceABC) -> str: + channel = bot.get_channel(self.discord_channel_id) + return None if channel is None else channel.name + + @property + def discord_message_id(self) -> int: + return self._discord_message_id diff --git a/kdb-bot/src/bot_data/model/auto_role_rule.py b/kdb-bot/src/bot_data/model/auto_role_rule.py index 34188caa..8729b6ec 100644 --- a/kdb-bot/src/bot_data/model/auto_role_rule.py +++ b/kdb-bot/src/bot_data/model/auto_role_rule.py @@ -87,13 +87,11 @@ class AutoRoleRule(TableABC): return str( f""" INSERT INTO `AutoRoleRules` ( - `AutoRoleId`, `DiscordEmojiName`, `DiscordRoleId`, `CreatedAt`, `LastModifiedAt` + `AutoRoleId`, `DiscordEmojiName`, `DiscordRoleId` ) VALUES ( {self._auto_role.id}, '{self._discord_emoji_name}', - {self._discord_role_id}, - '{self._created_at}', - '{self._modified_at}' + {self._discord_role_id} ); """ ) @@ -105,8 +103,7 @@ class AutoRoleRule(TableABC): UPDATE `AutoRoleRules` SET `AutoRoleId` = {self._auto_role.id}, `DiscordEmojiName` = '{self._discord_emoji_name}', - `DiscordRoleId` = {self._discord_role_id}, - `LastModifiedAt` = '{self._modified_at}' + `DiscordRoleId` = {self._discord_role_id} WHERE `AutoRoleRuleId` = {self._auto_role_rule_id}; """ ) diff --git a/kdb-bot/src/bot_data/model/auto_role_rule_history.py b/kdb-bot/src/bot_data/model/auto_role_rule_history.py new file mode 100644 index 00000000..c5a5ccd9 --- /dev/null +++ b/kdb-bot/src/bot_data/model/auto_role_rule_history.py @@ -0,0 +1,48 @@ +from cpl_core.dependency_injection import ServiceProviderABC +from cpl_discord.service import DiscordBotServiceABC + +from bot_data.abc.history_table_abc import HistoryTableABC + + +class AutoRoleRuleHistory(HistoryTableABC): + def __init__( + self, + auto_role: int, + discord_emoji_name: str, + discord_role_id: int, + deleted: bool, + date_from: str, + date_to: str, + id=0, + ): + HistoryTableABC.__init__(self) + self._auto_role_rule_id = id + self._auto_role = auto_role + self._discord_emoji_name = discord_emoji_name + self._discord_role_id = discord_role_id + + self._deleted = deleted + self._date_from = date_from + self._date_to = date_to + + @property + def id(self) -> int: + return self._auto_role_rule_id + + @property + def auto_role(self) -> int: + return self._auto_role + + @property + def emoji_name(self) -> str: + return self._discord_emoji_name + + @property + def role_id(self) -> int: + return self._discord_role_id + + @property + @ServiceProviderABC.inject + def role_name(self, bot: DiscordBotServiceABC) -> str: + guild = bot.get_guild(self.auto_role.server.discord_id) + return guild.get_role(self.role_id).name diff --git a/kdb-bot/src/bot_data/model/client.py b/kdb-bot/src/bot_data/model/client.py index 79f5c0fe..b6c163c9 100644 --- a/kdb-bot/src/bot_data/model/client.py +++ b/kdb-bot/src/bot_data/model/client.py @@ -53,7 +53,6 @@ class Client(TableABC): @sent_message_count.setter def sent_message_count(self, value: int): - self._modified_at = datetime.now().isoformat() self._sent_message_count = value @property @@ -62,7 +61,6 @@ class Client(TableABC): @received_message_count.setter def received_message_count(self, value: int): - self._modified_at = datetime.now().isoformat() self._received_message_count = value @property @@ -71,7 +69,6 @@ class Client(TableABC): @deleted_message_count.setter def deleted_message_count(self, value: int): - self._modified_at = datetime.now().isoformat() self._deleted_message_count = value @property @@ -80,7 +77,6 @@ class Client(TableABC): @received_command_count.setter def received_command_count(self, value: int): - self._modified_at = datetime.now().isoformat() self._received_command_count = value @property @@ -89,7 +85,6 @@ class Client(TableABC): @moved_users_count.setter def moved_users_count(self, value: int): - self._modified_at = datetime.now().isoformat() self._moved_users_count = value @property @@ -152,9 +147,7 @@ class Client(TableABC): `DeletedMessageCount`, `ReceivedCommandsCount`, `MovedUsersCount`, - `ServerId`, - `CreatedAt`, - `LastModifiedAt` + `ServerId` ) VALUES ( {self._discord_client_id}, {self._sent_message_count}, @@ -162,9 +155,7 @@ class Client(TableABC): {self._deleted_message_count}, {self._received_message_count}, {self._moved_users_count}, - {self._server.id}, - '{self._created_at}', - '{self._modified_at}' + {self._server.id} ); """ ) @@ -178,8 +169,7 @@ class Client(TableABC): `ReceivedMessageCount` = {self._received_message_count}, `DeletedMessageCount` = {self._deleted_message_count}, `ReceivedCommandsCount` = {self._received_command_count}, - `MovedUsersCount` = {self._moved_users_count}, - `LastModifiedAt` = '{self._modified_at}' + `MovedUsersCount` = {self._moved_users_count} WHERE `ClientId` = {self._client_id}; """ ) diff --git a/kdb-bot/src/bot_data/model/client_history.py b/kdb-bot/src/bot_data/model/client_history.py new file mode 100644 index 00000000..c16a306b --- /dev/null +++ b/kdb-bot/src/bot_data/model/client_history.py @@ -0,0 +1,72 @@ +from cpl_core.dependency_injection import ServiceProviderABC +from cpl_discord.service import DiscordBotServiceABC + +from bot_data.abc.history_table_abc import HistoryTableABC + + +class ClientHistory(HistoryTableABC): + def __init__( + self, + dc_id: int, + smc: int, + rmc: int, + dmc: int, + rcc: int, + muc: int, + server: int, + deleted: bool, + date_from: str, + date_to: str, + id=0, + ): + HistoryTableABC.__init__(self) + + self._client_id = id + self._discord_client_id = dc_id + self._sent_message_count = smc + self._received_message_count = rmc + self._deleted_message_count = dmc + self._received_command_count = rcc + self._moved_users_count = muc + self._server = server + + self._deleted = deleted + self._date_from = date_from + self._date_to = date_to + + @property + def id(self) -> int: + return self._client_id + + @property + def discord_id(self) -> int: + return self._discord_client_id + + @property + @ServiceProviderABC.inject + def name(self, bot: DiscordBotServiceABC) -> str: + return bot.user.name + + @property + def sent_message_count(self) -> int: + return self._sent_message_count + + @property + def received_message_count(self) -> int: + return self._received_message_count + + @property + def deleted_message_count(self) -> int: + return self._deleted_message_count + + @property + def received_command_count(self) -> int: + return self._received_command_count + + @property + def moved_users_count(self) -> int: + return self._moved_users_count + + @property + def server(self) -> int: + return self._server diff --git a/kdb-bot/src/bot_data/model/game_server.py b/kdb-bot/src/bot_data/model/game_server.py index ff886044..eeea20d8 100644 --- a/kdb-bot/src/bot_data/model/game_server.py +++ b/kdb-bot/src/bot_data/model/game_server.py @@ -102,13 +102,11 @@ class GameServer(TableABC): return str( f""" INSERT INTO `GameServers` ( - `Name`, `ServerId`, `ApiKeyId`, `CreatedAt`, `LastModifiedAt` + `Name`, `ServerId`, `ApiKeyId` ) VALUES ( '{self._name}', {self._server.id}, - {self._api_key.id}, - '{self._created_at}', - '{self._modified_at}' + {self._api_key.id} ); """ ) @@ -118,7 +116,7 @@ class GameServer(TableABC): return str( f""" UPDATE `GameServers` - SET `LastModifiedAt` = '{self._modified_at}' + SET `Name` = '{self._name}' WHERE `Id` = {self._id}; """ ) diff --git a/kdb-bot/src/bot_data/model/known_user.py b/kdb-bot/src/bot_data/model/known_user.py index b17a13ce..37d375f0 100644 --- a/kdb-bot/src/bot_data/model/known_user.py +++ b/kdb-bot/src/bot_data/model/known_user.py @@ -57,11 +57,9 @@ class KnownUser(TableABC): return str( f""" INSERT INTO `KnownUsers` ( - `DiscordId`, `CreatedAt`, `LastModifiedAt` + `DiscordId` ) VALUES ( - {self._discord_id}, - '{self._created_at}', - '{self._modified_at}' + {self._discord_id} ); """ ) diff --git a/kdb-bot/src/bot_data/model/known_user_history.py b/kdb-bot/src/bot_data/model/known_user_history.py new file mode 100644 index 00000000..35ced7dc --- /dev/null +++ b/kdb-bot/src/bot_data/model/known_user_history.py @@ -0,0 +1,28 @@ +from bot_data.abc.history_table_abc import HistoryTableABC + + +class KnownUserHistory(HistoryTableABC): + def __init__( + self, + dc_id: int, + deleted: bool, + date_from: str, + date_to: str, + id=0, + ): + HistoryTableABC.__init__(self) + + self._known_user_id = id + self._discord_id = dc_id + + self._deleted = deleted + self._date_from = date_from + self._date_to = date_to + + @property + def id(self) -> int: + return self._known_user_id + + @property + def discord_id(self) -> int: + return self._discord_id diff --git a/kdb-bot/src/bot_data/model/level.py b/kdb-bot/src/bot_data/model/level.py index b47f6fd4..a20d268b 100644 --- a/kdb-bot/src/bot_data/model/level.py +++ b/kdb-bot/src/bot_data/model/level.py @@ -39,7 +39,6 @@ class Level(TableABC): @name.setter def name(self, value: str): - self._modified_at = datetime.now().isoformat() self._name = value @property @@ -48,7 +47,6 @@ class Level(TableABC): @color.setter def color(self, value: str): - self._modified_at = datetime.now().isoformat() self._color = value @property @@ -57,7 +55,6 @@ class Level(TableABC): @min_xp.setter def min_xp(self, value: int): - self._modified_at = datetime.now().isoformat() self._min_xp = value @property @@ -66,7 +63,6 @@ class Level(TableABC): @permissions.setter def permissions(self, value: int): - self._modified_at = datetime.now().isoformat() self._permissions = value @property @@ -75,7 +71,6 @@ class Level(TableABC): @server.setter def server(self, value: Server): - self._modified_at = datetime.now().isoformat() self._server = value @staticmethod @@ -109,15 +104,13 @@ class Level(TableABC): return str( f""" INSERT INTO `Levels` ( - `Name`, `Color`, `MinXp`, `PermissionInt`, `ServerId`, `CreatedAt`, `LastModifiedAt` + `Name`, `Color`, `MinXp`, `PermissionInt`, `ServerId` ) VALUES ( '{self._name}', '{self._color}', {self._min_xp}, {self._permissions}, - {self._server.id}, - '{self._created_at}', - '{self._modified_at}' + {self._server.id} ); """ ) @@ -130,8 +123,7 @@ class Level(TableABC): SET `Name` = '{self._name}', `Color` = '{self._color}', `MinXp` = {self._min_xp}, - `PermissionInt` = {self._permissions}, - `LastModifiedAt` = '{self._modified_at}' + `PermissionInt` = {self._permissions} WHERE `Id` = {self._id}; """ ) diff --git a/kdb-bot/src/bot_data/model/level_history.py b/kdb-bot/src/bot_data/model/level_history.py new file mode 100644 index 00000000..748acaf7 --- /dev/null +++ b/kdb-bot/src/bot_data/model/level_history.py @@ -0,0 +1,55 @@ +from typing import Optional + +from bot_data.abc.history_table_abc import HistoryTableABC +from bot_data.model.server import Server + + +class LevelHistory(HistoryTableABC): + def __init__( + self, + name: str, + color: str, + min_xp: int, + permissions: int, + server: Optional[Server], + deleted: bool, + date_from: str, + date_to: str, + id=0, + ): + HistoryTableABC.__init__(self) + + self._id = id + self._name = name + self._color = color + self._min_xp = min_xp + self._permissions = permissions + 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 + + @property + def color(self) -> str: + return self._color + + @property + def min_xp(self) -> int: + return self._min_xp + + @property + def permissions(self) -> int: + return self._permissions + + @property + def server(self) -> Server: + return self._server diff --git a/kdb-bot/src/bot_data/model/server.py b/kdb-bot/src/bot_data/model/server.py index e2412295..d86c6e97 100644 --- a/kdb-bot/src/bot_data/model/server.py +++ b/kdb-bot/src/bot_data/model/server.py @@ -71,11 +71,9 @@ class Server(TableABC): return str( f""" INSERT INTO `Servers` ( - `DiscordServerId`, `CreatedAt`, `LastModifiedAt` + `DiscordServerId` ) VALUES ( - {self._discord_server_id}, - '{self._created_at}', - '{self._modified_at}' + {self._discord_server_id} ); """ ) @@ -85,8 +83,7 @@ class Server(TableABC): return str( f""" UPDATE `Servers` - SET `DiscordServerId` = {self._discord_server_id}, - `LastModifiedAt` = '{self._modified_at}' + SET `DiscordServerId` = {self._discord_server_id} WHERE `ServerId` = {self._server_id}; """ ) diff --git a/kdb-bot/src/bot_data/model/server_history.py b/kdb-bot/src/bot_data/model/server_history.py new file mode 100644 index 00000000..e8c95934 --- /dev/null +++ b/kdb-bot/src/bot_data/model/server_history.py @@ -0,0 +1,43 @@ +from cpl_core.dependency_injection import ServiceProviderABC +from cpl_discord.service import DiscordBotServiceABC + +from bot_data.abc.history_table_abc import HistoryTableABC + + +class ServerHistory(HistoryTableABC): + def __init__( + self, + dc_id: int, + deleted: bool, + date_from: str, + date_to: str, + id=0, + ): + HistoryTableABC.__init__(self) + + self._server_id = id + self._discord_server_id = dc_id + + self._deleted = deleted + self._date_from = date_from + self._date_to = date_to + + @property + def id(self) -> int: + return self._server_id + + @property + def discord_id(self) -> int: + return self._discord_server_id + + @property + @ServiceProviderABC.inject + def name(self, bot: DiscordBotServiceABC) -> str: + guild = bot.get_guild(self.discord_id) + return None if guild is None else guild.name + + @property + @ServiceProviderABC.inject + def icon_url(self, bot: DiscordBotServiceABC) -> str: + guild = bot.get_guild(self.discord_id) + return None if guild is None else guild.icon.url diff --git a/kdb-bot/src/bot_data/model/user.py b/kdb-bot/src/bot_data/model/user.py index 9f975550..7472e689 100644 --- a/kdb-bot/src/bot_data/model/user.py +++ b/kdb-bot/src/bot_data/model/user.py @@ -57,7 +57,6 @@ class User(TableABC): @xp.setter def xp(self, value: int): - self._modified_at = datetime.now().isoformat() self._xp = value @property @@ -152,13 +151,11 @@ class User(TableABC): return str( f""" INSERT INTO `Users` ( - `DiscordId`, `XP`, `ServerId`, `CreatedAt`, `LastModifiedAt` + `DiscordId`, `XP`, `ServerId` ) VALUES ( {self._discord_id}, {self._xp}, - {self._server.id}, - '{self._created_at}', - '{self._modified_at}' + {self._server.id} ); """ ) @@ -168,8 +165,7 @@ class User(TableABC): return str( f""" UPDATE `Users` - SET `XP` = {self._xp}, - `LastModifiedAt` = '{self._modified_at}' + SET `XP` = {self._xp} WHERE `UserId` = {self._user_id}; """ ) diff --git a/kdb-bot/src/bot_data/model/user_game_ident.py b/kdb-bot/src/bot_data/model/user_game_ident.py index 6d6bf781..22e7946f 100644 --- a/kdb-bot/src/bot_data/model/user_game_ident.py +++ b/kdb-bot/src/bot_data/model/user_game_ident.py @@ -91,26 +91,18 @@ class UserGameIdent(TableABC): return str( f""" INSERT INTO `UserGameIdents` ( - `UserId`, `GameServerId`, `Ident`, `CreatedAt`, `LastModifiedAt` + `UserId`, `GameServerId`, `Ident` ) VALUES ( {self._user.id}, '{self._game_server.id}', - '{self._ident}', - '{self._created_at}', - '{self._modified_at}' + '{self._ident}' ); """ ) @property def udpate_string(self) -> str: - return str( - f""" - UPDATE `UserGameIdents` - SET `LastModifiedAt` = '{self._modified_at}' - WHERE `Id` = {self._id}; - """ - ) + return "" @property def delete_string(self) -> str: diff --git a/kdb-bot/src/bot_data/model/user_history.py b/kdb-bot/src/bot_data/model/user_history.py new file mode 100644 index 00000000..d3b88ca7 --- /dev/null +++ b/kdb-bot/src/bot_data/model/user_history.py @@ -0,0 +1,65 @@ +from cpl_core.dependency_injection import ServiceProviderABC +from cpl_query.extension import List + +from bot_data.abc.history_table_abc import HistoryTableABC + + +class UserHistory(HistoryTableABC): + def __init__( + self, + dc_id: int, + xp: int, + server: int, + deleted: bool, + date_from: str, + date_to: str, + id=0, + ): + HistoryTableABC.__init__(self) + + self._user_id = id + self._discord_id = dc_id + self._xp = xp + self._server = server + + self._deleted = deleted + self._date_from = date_from + self._date_to = date_to + + @property + def id(self) -> int: + return self._user_id + + @property + def discord_id(self) -> int: + return self._discord_id + + @property + def xp(self) -> int: + return self._xp + + @property + def server(self) -> int: + return self._server + + @property + @ServiceProviderABC.inject + def left_server( + self, + services: ServiceProviderABC, + ) -> bool: + from bot_data.abc.user_joined_server_repository_abc import UserJoinedServerRepositoryABC + + ujs: UserJoinedServerRepositoryABC = services.get_service(UserJoinedServerRepositoryABC) + return ujs.find_active_user_joined_server_by_user_id(self.id) is None + + @property + @ServiceProviderABC.inject + def game_idents( + self, + services: ServiceProviderABC, + ) -> List["UserGameIdent"]: + from bot_data.abc.user_game_ident_repository_abc import UserGameIdentRepositoryABC + + game_idents_repo: UserGameIdentRepositoryABC = services.get_service(UserGameIdentRepositoryABC) + return game_idents_repo.get_user_game_idents_by_user_id(self.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 90c68d44..cf60229d 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 @@ -104,14 +104,12 @@ class UserJoinedGameServer(TableABC): return str( f""" INSERT INTO `UserJoinedGameServer` ( - `UserId`, `GameServerId`, `JoinedOn`, `LeavedOn`, `CreatedAt`, `LastModifiedAt` + `UserId`, `GameServerId`, `JoinedOn`, `LeavedOn` ) VALUES ( {self._user.id}, '{self._game_server.id}', '{self._joined_on}', - {"NULL" if self._leaved_on is None else f"'{self._leaved_on}'"}, - '{self._created_at}', - '{self._modified_at}' + {"NULL" if self._leaved_on is None else f"'{self._leaved_on}'"} ); """ ) @@ -121,8 +119,7 @@ class UserJoinedGameServer(TableABC): return str( f""" UPDATE `UserJoinedGameServer` - SET `LeavedOn` = {"NULL" if self._leaved_on is None else f"'{self._leaved_on}'"}, - `LastModifiedAt` = '{self._modified_at}' + SET `LeavedOn` = {"NULL" if self._leaved_on is None else f"'{self._leaved_on}'"} WHERE `Id` = {self._id}; """ ) diff --git a/kdb-bot/src/bot_data/model/user_joined_game_server_history.py b/kdb-bot/src/bot_data/model/user_joined_game_server_history.py new file mode 100644 index 00000000..24da148a --- /dev/null +++ b/kdb-bot/src/bot_data/model/user_joined_game_server_history.py @@ -0,0 +1,54 @@ +from datetime import datetime + +from bot_data.abc.history_table_abc import HistoryTableABC + + +class UserJoinedGameServerHistory(HistoryTableABC): + def __init__( + self, + user: int, + game_server: int, + joined_on: datetime, + leaved_on: datetime, + deleted: bool, + date_from: str, + date_to: str, + id=0, + ): + HistoryTableABC.__init__(self) + + self._id = id + self._user = user + self._game_server = game_server + self._joined_on = joined_on + self._leaved_on = leaved_on + + self._deleted = deleted + self._date_from = date_from + self._date_to = date_to + + @property + def id(self) -> int: + return self._id + + @property + def user(self) -> int: + return self._user + + @property + def game_server(self) -> int: + return self._game_server + + @property + def time(self) -> float: + if self._leaved_on is None or self._joined_on is None: + return 0 + return round((self.leaved_on - self.joined_on).total_seconds() / 3600, 2) + + @property + def joined_on(self) -> datetime: + return self._joined_on + + @property + def leaved_on(self) -> datetime: + return self._leaved_on diff --git a/kdb-bot/src/bot_data/model/user_joined_server.py b/kdb-bot/src/bot_data/model/user_joined_server.py index 5946104a..e55cb60d 100644 --- a/kdb-bot/src/bot_data/model/user_joined_server.py +++ b/kdb-bot/src/bot_data/model/user_joined_server.py @@ -100,13 +100,11 @@ class UserJoinedServer(TableABC): return str( f""" INSERT INTO `UserJoinedServers` ( - `UserId`, `JoinedOn`, `LeavedOn`, `CreatedAt`, `LastModifiedAt` + `UserId`, `JoinedOn`, `LeavedOn` ) VALUES ( {self._user.id}, '{self._joined_on}', - {"NULL" if self._leaved_on is None else f"'{self._leaved_on}'"}, - '{self._created_at}', - '{self._modified_at}' + {"NULL" if self._leaved_on is None else f"'{self._leaved_on}'"} ); """ ) @@ -116,8 +114,7 @@ class UserJoinedServer(TableABC): return str( f""" UPDATE `UserJoinedServers` - SET `LeavedOn` = {"NULL" if self._leaved_on is None else f"'{self._leaved_on}'"}, - `LastModifiedAt` = '{self._modified_at}' + SET `LeavedOn` = {"NULL" if self._leaved_on is None else f"'{self._leaved_on}'"} WHERE `UserId` = {self._user.id}; """ ) diff --git a/kdb-bot/src/bot_data/model/user_joined_server_history.py b/kdb-bot/src/bot_data/model/user_joined_server_history.py new file mode 100644 index 00000000..639300a0 --- /dev/null +++ b/kdb-bot/src/bot_data/model/user_joined_server_history.py @@ -0,0 +1,42 @@ +from datetime import datetime + +from bot_data.abc.history_table_abc import HistoryTableABC + + +class UserJoinedServerHistory(HistoryTableABC): + def __init__( + self, + user: int, + joined_on: datetime, + leaved_on: datetime, + deleted: bool, + date_from: str, + date_to: str, + id=0, + ): + HistoryTableABC.__init__(self) + + self._join_id = id + self._user = user + self._joined_on = joined_on + self._leaved_on = leaved_on + + self._deleted = deleted + self._date_from = date_from + self._date_to = date_to + + @property + def id(self) -> int: + return self._join_id + + @property + def user(self) -> int: + return self._user + + @property + def joined_on(self) -> datetime: + return self._joined_on + + @property + def leaved_on(self) -> datetime: + return self._leaved_on diff --git a/kdb-bot/src/bot_data/model/user_joined_voice_channel.py b/kdb-bot/src/bot_data/model/user_joined_voice_channel.py index f99ca0e2..dda013e6 100644 --- a/kdb-bot/src/bot_data/model/user_joined_voice_channel.py +++ b/kdb-bot/src/bot_data/model/user_joined_voice_channel.py @@ -110,14 +110,12 @@ class UserJoinedVoiceChannel(TableABC): return str( f""" INSERT INTO `UserJoinedVoiceChannel` ( - `UserId`, `DiscordChannelId`, `JoinedOn`, `LeavedOn`, `CreatedAt`, `LastModifiedAt` + `UserId`, `DiscordChannelId`, `JoinedOn`, `LeavedOn` ) VALUES ( {self._user.id}, {self._channel_id}, '{self._joined_on}', - {"NULL" if self._leaved_on is None else f"'{self._leaved_on}'"}, - '{self._created_at}', - '{self._modified_at}' + {"NULL" if self._leaved_on is None else f"'{self._leaved_on}'"} ); """ ) @@ -127,8 +125,7 @@ class UserJoinedVoiceChannel(TableABC): return str( f""" UPDATE `UserJoinedVoiceChannel` - SET `LeavedOn` = {"NULL" if self._leaved_on is None else f"'{self._leaved_on}'"}, - `LastModifiedAt` = '{self._modified_at}' + SET `LeavedOn` = {"NULL" if self._leaved_on is None else f"'{self._leaved_on}'"} WHERE `JoinId` = {self._join_id}; """ ) diff --git a/kdb-bot/src/bot_data/model/user_joined_voice_channel_history.py b/kdb-bot/src/bot_data/model/user_joined_voice_channel_history.py new file mode 100644 index 00000000..5c1ee49a --- /dev/null +++ b/kdb-bot/src/bot_data/model/user_joined_voice_channel_history.py @@ -0,0 +1,62 @@ +from datetime import datetime + +from cpl_core.dependency_injection import ServiceProviderABC +from cpl_discord.service import DiscordBotServiceABC + +from bot_data.abc.history_table_abc import HistoryTableABC + + +class UserJoinedVoiceChannelHistory(HistoryTableABC): + def __init__( + self, + user: int, + channel_id: int, + joined_on: datetime, + leaved_on: datetime, + deleted: bool, + date_from: str, + date_to: str, + id=0, + ): + HistoryTableABC.__init__(self) + + self._join_id = id + self._channel_id = channel_id + self._user = user + self._joined_on = joined_on + self._leaved_on = leaved_on + + self._deleted = deleted + self._date_from = date_from + self._date_to = date_to + + @property + def id(self) -> int: + return self._join_id + + @property + def channel_id(self) -> int: + return self._channel_id + + @property + @ServiceProviderABC.inject + def channel_name(self, bot: DiscordBotServiceABC) -> str: + return bot.get_channel(self.channel_id).name + + @property + def user(self) -> int: + return self._user + + @property + def time(self) -> float: + if self._leaved_on is None or self._joined_on is None: + return 0 + return round((self.leaved_on - self.joined_on).total_seconds() / 3600, 2) + + @property + def joined_on(self) -> datetime: + return self._joined_on + + @property + def leaved_on(self) -> datetime: + return self._leaved_on diff --git a/kdb-bot/src/bot_data/model/user_message_count_per_hour.py b/kdb-bot/src/bot_data/model/user_message_count_per_hour.py index f7a83663..7815ffa4 100644 --- a/kdb-bot/src/bot_data/model/user_message_count_per_hour.py +++ b/kdb-bot/src/bot_data/model/user_message_count_per_hour.py @@ -44,7 +44,6 @@ class UserMessageCountPerHour(TableABC): @xp_count.setter def xp_count(self, value: int): - self._modified_at = datetime.now().isoformat() self._xp_count = value @property @@ -95,14 +94,12 @@ class UserMessageCountPerHour(TableABC): return str( f""" INSERT INTO `UserMessageCountPerHour` ( - `UserId`, `Date`, `Hour`, `XPCount`, `CreatedAt`, `LastModifiedAt` + `UserId`, `Date`, `Hour`, `XPCount` ) VALUES ( {self._user.id}, '{self._date}', {self._hour}, - {self._xp_count}, - '{self._created_at}', - '{self._modified_at}' + {self._xp_count} ); """ ) @@ -112,8 +109,7 @@ class UserMessageCountPerHour(TableABC): return str( f""" UPDATE `UserMessageCountPerHour` - SET `XPCount` = '{self._xp_count}', - `LastModifiedAt` = '{self._modified_at}' + SET `XPCount` = '{self._xp_count}' WHERE `Id` = {self._id}; """ ) diff --git a/kdb-bot/src/bot_data/model/user_warnings.py b/kdb-bot/src/bot_data/model/user_warnings.py index 06b59ff5..99610a5f 100644 --- a/kdb-bot/src/bot_data/model/user_warnings.py +++ b/kdb-bot/src/bot_data/model/user_warnings.py @@ -73,13 +73,11 @@ class UserWarnings(TableABC): return str( f""" INSERT INTO `UserWarnings` ( - `Description`, `UserId`, {"" if self._author is None else f"`Author`,"} `CreatedAt`, `LastModifiedAt` + `Description`, `UserId`, `Author` ) VALUES ( '{self._description}', {self._user.id}, - {"" if self._author is None else f"{self._author.id},"} - '{self._created_at}', - '{self._modified_at}' + {"NULL" if self._author is None else f"{self._author.id}"} ); """ ) @@ -89,8 +87,7 @@ class UserWarnings(TableABC): return str( f""" UPDATE `UserWarnings` - SET `Description` = '{self._description}', - `LastModifiedAt` = '{self._modified_at}' + SET `Description` = '{self._description}' WHERE `Id` = {self._id}; """ ) diff --git a/kdb-bot/src/bot_data/service/migration_service.py b/kdb-bot/src/bot_data/service/migration_service.py index 7b924f90..dc6436a7 100644 --- a/kdb-bot/src/bot_data/service/migration_service.py +++ b/kdb-bot/src/bot_data/service/migration_service.py @@ -1,5 +1,3 @@ -from typing import Type - from cpl_core.database.context import DatabaseContextABC from cpl_core.dependency_injection import ServiceProviderABC from cpl_query.extension import List @@ -22,7 +20,9 @@ class MigrationService: self._db = db self._cursor = db.cursor - self._migrations = List(type, MigrationABC.__subclasses__()).order_by(lambda x: x.name) + self._migrations: List[MigrationABC] = ( + List(type, MigrationABC.__subclasses__()).order_by(lambda x: x.name).order_by(lambda x: x.prio) + ) def migrate(self): self._logger.info(__name__, f"Running Migrations") diff --git a/kdb-bot/src/bot_graphql/abc/data_query_with_history_abc.py b/kdb-bot/src/bot_graphql/abc/data_query_with_history_abc.py new file mode 100644 index 00000000..71ec3318 --- /dev/null +++ b/kdb-bot/src/bot_graphql/abc/data_query_with_history_abc.py @@ -0,0 +1,42 @@ +from typing import Type + +from cpl_core.database.context import DatabaseContextABC +from cpl_query.extension import List + +from bot_data.abc.history_table_abc import HistoryTableABC +from bot_data.abc.table_with_id_abc import TableWithIdABC +from bot_graphql.abc.data_query_abc import DataQueryABC + + +class DataQueryWithHistoryABC(DataQueryABC): + def __init__( + self, + name: str, + table_name: str, + history_type: Type[HistoryTableABC], + db: DatabaseContextABC, + ): + self._table_name = table_name + self._history_type = history_type + self._db = db + + DataQueryABC.__init__(self, name) + + self.set_field("history", self.resolve_history) + + def resolve_history(self, entry: TableWithIdABC, *_): + history = List(self._history_type) + + results = self._db.select( + f""" + SELECT * + FROM {self._table_name} + WHERE Id = {entry.id} + ORDER BY DateTo DESC; + """ + ) + + for result in results: + history.add(self._history_type(*result[1:], result[0])) + + return history diff --git a/kdb-bot/src/bot_graphql/abc/history_query_abc.py b/kdb-bot/src/bot_graphql/abc/history_query_abc.py new file mode 100644 index 00000000..b60541cd --- /dev/null +++ b/kdb-bot/src/bot_graphql/abc/history_query_abc.py @@ -0,0 +1,10 @@ +from bot_graphql.abc.query_abc import QueryABC + + +class HistoryQueryABC(QueryABC): + def __init__(self, name: str): + QueryABC.__init__(self, f"{name}History") + + self.set_field("deleted", lambda x, *_: x.deleted) + self.set_field("dateFrom", lambda x, *_: x.date_from) + self.set_field("dateTo", lambda x, *_: x.date_to) diff --git a/kdb-bot/src/bot_graphql/graphql_module.py b/kdb-bot/src/bot_graphql/graphql_module.py index 77b98a86..5ef7df09 100644 --- a/kdb-bot/src/bot_graphql/graphql_module.py +++ b/kdb-bot/src/bot_graphql/graphql_module.py @@ -24,14 +24,24 @@ from bot_graphql.mutations.auto_role_rule_mutation import AutoRoleRuleMutation from bot_graphql.mutations.level_mutation import LevelMutation from bot_graphql.mutations.user_joined_game_server_mutation import UserJoinedGameServerMutation from bot_graphql.mutations.user_mutation import UserMutation +from bot_graphql.queries.auto_role_history_query import AutoRoleHistoryQuery from bot_graphql.queries.auto_role_query import AutoRoleQuery +from bot_graphql.queries.auto_role_rule_history_query import AutoRoleRuleHistoryQuery from bot_graphql.queries.auto_role_rule_query import AutoRoleRuleQuery +from bot_graphql.queries.client_history_query import ClientHistoryQuery from bot_graphql.queries.client_query import ClientQuery +from bot_graphql.queries.known_user_history_query import KnownUserHistoryQuery from bot_graphql.queries.known_user_query import KnownUserQuery +from bot_graphql.queries.level_history_query import LevelHistoryQuery from bot_graphql.queries.level_query import LevelQuery +from bot_graphql.queries.server_history_query import ServerHistoryQuery from bot_graphql.queries.server_query import ServerQuery +from bot_graphql.queries.user_history_query import UserHistoryQuery +from bot_graphql.queries.user_joined_game_server_history_query import UserJoinedGameServerHistoryQuery from bot_graphql.queries.user_joined_game_server_query import UserJoinedGameServerQuery +from bot_graphql.queries.user_joined_server_history_query import UserJoinedServerHistoryQuery from bot_graphql.queries.user_joined_server_query import UserJoinedServerQuery +from bot_graphql.queries.user_joined_voice_channel_history_query import UserJoinedVoiceChannelHistoryQuery from bot_graphql.queries.user_joined_voice_channel_query import UserJoinedVoiceChannelQuery from bot_graphql.queries.user_query import UserQuery from bot_graphql.query import Query @@ -52,15 +62,25 @@ class GraphQLModule(ModuleABC): services.add_singleton(Mutation) # queries + services.add_transient(QueryABC, AutoRoleHistoryQuery) services.add_transient(QueryABC, AutoRoleQuery) + services.add_transient(QueryABC, AutoRoleRuleHistoryQuery) services.add_transient(QueryABC, AutoRoleRuleQuery) + services.add_transient(QueryABC, ClientHistoryQuery) services.add_transient(QueryABC, ClientQuery) + services.add_transient(QueryABC, KnownUserHistoryQuery) services.add_transient(QueryABC, KnownUserQuery) + services.add_transient(QueryABC, LevelHistoryQuery) services.add_transient(QueryABC, LevelQuery) + services.add_transient(QueryABC, ServerHistoryQuery) services.add_transient(QueryABC, ServerQuery) + services.add_transient(QueryABC, UserHistoryQuery) services.add_transient(QueryABC, UserQuery) + services.add_transient(QueryABC, UserJoinedServerHistoryQuery) services.add_transient(QueryABC, UserJoinedServerQuery) + services.add_transient(QueryABC, UserJoinedVoiceChannelHistoryQuery) services.add_transient(QueryABC, UserJoinedVoiceChannelQuery) + services.add_transient(QueryABC, UserJoinedGameServerHistoryQuery) services.add_transient(QueryABC, UserJoinedGameServerQuery) # filters diff --git a/kdb-bot/src/bot_graphql/model/autoRole.gql b/kdb-bot/src/bot_graphql/model/autoRole.gql index 0b523583..e859a364 100644 --- a/kdb-bot/src/bot_graphql/model/autoRole.gql +++ b/kdb-bot/src/bot_graphql/model/autoRole.gql @@ -1,4 +1,4 @@ -type AutoRole implements TableQuery { +type AutoRole implements TableWithHistoryQuery { id: ID channelId: String channelName: String @@ -11,6 +11,20 @@ type AutoRole implements TableQuery { createdAt: String modifiedAt: String + + history: [AutoRoleHistory] +} + +type AutoRoleHistory implements HistoryTableQuery { + id: ID + channelId: String + messageId: String + + server: ID + + deleted: Boolean + dateFrom: String + dateTo: String } input AutoRoleFilter { diff --git a/kdb-bot/src/bot_graphql/model/autoRoleRule.gql b/kdb-bot/src/bot_graphql/model/autoRoleRule.gql index 2484c8bd..2008424e 100644 --- a/kdb-bot/src/bot_graphql/model/autoRoleRule.gql +++ b/kdb-bot/src/bot_graphql/model/autoRoleRule.gql @@ -1,4 +1,4 @@ -type AutoRoleRule implements TableQuery { +type AutoRoleRule implements TableWithHistoryQuery { id: ID emojiName: String roleId: String @@ -8,6 +8,20 @@ type AutoRoleRule implements TableQuery { createdAt: String modifiedAt: String + + history: [AutoRoleRuleHistory] +} + +type AutoRoleRuleHistory implements HistoryTableQuery { + id: ID + emojiName: String + roleId: String + + autoRole: ID + + deleted: Boolean + dateFrom: String + dateTo: String } input AutoRoleRuleFilter { diff --git a/kdb-bot/src/bot_graphql/model/base.gql b/kdb-bot/src/bot_graphql/model/base.gql index dcb3b17d..2e664a4d 100644 --- a/kdb-bot/src/bot_graphql/model/base.gql +++ b/kdb-bot/src/bot_graphql/model/base.gql @@ -3,6 +3,18 @@ interface TableQuery { modifiedAt: String } +interface TableWithHistoryQuery { + createdAt: String + modifiedAt: String + history: [HistoryTableQuery] +} + +interface HistoryTableQuery { + deleted: Boolean + dateFrom: String + dateTo: String +} + input Page { pageIndex: Int pageSize: Int diff --git a/kdb-bot/src/bot_graphql/model/client.gql b/kdb-bot/src/bot_graphql/model/client.gql index 8afc7c73..58a805b9 100644 --- a/kdb-bot/src/bot_graphql/model/client.gql +++ b/kdb-bot/src/bot_graphql/model/client.gql @@ -12,6 +12,25 @@ type Client implements TableQuery { createdAt: String modifiedAt: String + + history: [ClientHistory] +} + +type ClientHistory implements HistoryTableQuery { + id: ID + discordId: String + name: String + sentMessageCount: Int + receivedMessageCount: Int + deletedMessageCount: Int + receivedCommandCount: Int + movedUsersCount: Int + + server: ID + + deleted: Boolean + dateFrom: String + dateTo: String } input ClientFilter { diff --git a/kdb-bot/src/bot_graphql/model/knownUser.gql b/kdb-bot/src/bot_graphql/model/knownUser.gql index bb96cd3d..fe26dbe4 100644 --- a/kdb-bot/src/bot_graphql/model/knownUser.gql +++ b/kdb-bot/src/bot_graphql/model/knownUser.gql @@ -1,7 +1,18 @@ -type KnownUser implements TableQuery { +type KnownUser implements TableWithHistoryQuery { id: ID discordId: String createdAt: String modifiedAt: String + + history: [KnownUserHistory] +} + +type KnownUserHistory implements HistoryTableQuery { + id: ID + discordId: String + + deleted: Boolean + dateFrom: String + dateTo: String } \ No newline at end of file diff --git a/kdb-bot/src/bot_graphql/model/level.gql b/kdb-bot/src/bot_graphql/model/level.gql index 2ef07540..cc937291 100644 --- a/kdb-bot/src/bot_graphql/model/level.gql +++ b/kdb-bot/src/bot_graphql/model/level.gql @@ -1,4 +1,4 @@ -type Level implements TableQuery { +type Level implements TableWithHistoryQuery { id: ID name: String color: String @@ -9,6 +9,22 @@ type Level implements TableQuery { createdAt: String modifiedAt: String + + history: [LevelHistory] +} + +type LevelHistory implements HistoryTableQuery { + id: ID + name: String + color: String + minXp: Int + permissions: String + + server: ID + + deleted: Boolean + dateFrom: String + dateTo: String } input LevelFilter { diff --git a/kdb-bot/src/bot_graphql/model/server.gql b/kdb-bot/src/bot_graphql/model/server.gql index a777b792..db94dc89 100644 --- a/kdb-bot/src/bot_graphql/model/server.gql +++ b/kdb-bot/src/bot_graphql/model/server.gql @@ -1,4 +1,4 @@ -type Server implements TableQuery { +type Server implements TableWithHistoryQuery { id: ID discordId: String name: String @@ -18,6 +18,19 @@ type Server implements TableQuery { createdAt: String modifiedAt: String + + history: [HistoryTableQuery] +} + +type ServerHistory implements HistoryTableQuery { + id: ID + discordId: String + name: String + iconURL: String + + deleted: Boolean + dateFrom: String + dateTo: String } input ServerFilter { diff --git a/kdb-bot/src/bot_graphql/model/user.gql b/kdb-bot/src/bot_graphql/model/user.gql index 37d84b00..e7f03f38 100644 --- a/kdb-bot/src/bot_graphql/model/user.gql +++ b/kdb-bot/src/bot_graphql/model/user.gql @@ -1,4 +1,4 @@ -type User implements TableQuery { +type User implements TableWithHistoryQuery { id: ID discordId: String name: String @@ -20,6 +20,20 @@ type User implements TableQuery { createdAt: String modifiedAt: String + + history: [UserHistory] +} + +type UserHistory implements HistoryTableQuery { + id: ID + discordId: String + xp: Int + + server: ID + + deleted: Boolean + dateFrom: String + dateTo: String } input UserFilter { diff --git a/kdb-bot/src/bot_graphql/model/userJoinedGameServer.gql b/kdb-bot/src/bot_graphql/model/userJoinedGameServer.gql index 90475043..93d344a2 100644 --- a/kdb-bot/src/bot_graphql/model/userJoinedGameServer.gql +++ b/kdb-bot/src/bot_graphql/model/userJoinedGameServer.gql @@ -1,4 +1,4 @@ -type UserJoinedGameServer implements TableQuery { +type UserJoinedGameServer implements TableWithHistoryQuery { id: ID gameServer: String user: User @@ -8,6 +8,21 @@ type UserJoinedGameServer implements TableQuery { createdAt: String modifiedAt: String + + history: [UserJoinedGameServerHistory] +} + +type UserJoinedGameServerHistory implements HistoryTableQuery { + id: ID + gameServer: String + user: ID + time: Float + joinedOn: String + leavedOn: String + + deleted: Boolean + dateFrom: String + dateTo: String } input UserJoinedGameServerFilter { diff --git a/kdb-bot/src/bot_graphql/model/userJoinedServer.gql b/kdb-bot/src/bot_graphql/model/userJoinedServer.gql index a8cbb343..bb73b40d 100644 --- a/kdb-bot/src/bot_graphql/model/userJoinedServer.gql +++ b/kdb-bot/src/bot_graphql/model/userJoinedServer.gql @@ -1,4 +1,4 @@ -type UserJoinedServer implements TableQuery { +type UserJoinedServer implements TableWithHistoryQuery { id: ID user: User joinedOn: String @@ -6,6 +6,19 @@ type UserJoinedServer implements TableQuery { createdAt: String modifiedAt: String + + history: [UserJoinedServerHistory] +} + +type UserJoinedServerHistory implements HistoryTableQuery { + id: ID + user: ID + joinedOn: String + leavedOn: String + + deleted: Boolean + dateFrom: String + dateTo: String } input UserJoinedServerFilter { diff --git a/kdb-bot/src/bot_graphql/model/userJoinedVoiceChannel.gql b/kdb-bot/src/bot_graphql/model/userJoinedVoiceChannel.gql index 7fb983b5..8cc73e15 100644 --- a/kdb-bot/src/bot_graphql/model/userJoinedVoiceChannel.gql +++ b/kdb-bot/src/bot_graphql/model/userJoinedVoiceChannel.gql @@ -1,4 +1,4 @@ -type UserJoinedVoiceChannel implements TableQuery { +type UserJoinedVoiceChannel implements TableWithHistoryQuery { id: ID channelId: String channelName: String @@ -9,6 +9,22 @@ type UserJoinedVoiceChannel implements TableQuery { createdAt: String modifiedAt: String + + history: [UserJoinedVoiceChannelHistory] +} + +type UserJoinedVoiceChannelHistory implements HistoryTableQuery { + id: ID + channelId: String + channelName: String + user: ID + time: Float + joinedOn: String + leavedOn: String + + deleted: Boolean + dateFrom: String + dateTo: String } input UserJoinedVoiceChannelFilter { diff --git a/kdb-bot/src/bot_graphql/queries/auto_role_history_query.py b/kdb-bot/src/bot_graphql/queries/auto_role_history_query.py new file mode 100644 index 00000000..7a96ad1d --- /dev/null +++ b/kdb-bot/src/bot_graphql/queries/auto_role_history_query.py @@ -0,0 +1,40 @@ +from cpl_discord.service import DiscordBotServiceABC + +from bot_data.abc.auto_role_repository_abc import AutoRoleRepositoryABC +from bot_data.abc.server_repository_abc import ServerRepositoryABC +from bot_data.model.auto_role import AutoRole +from bot_graphql.abc.history_query_abc import HistoryQueryABC + + +class AutoRoleHistoryQuery(HistoryQueryABC): + def __init__( + self, + bot: DiscordBotServiceABC, + auto_role_rules: AutoRoleRepositoryABC, + servers: ServerRepositoryABC, + ): + HistoryQueryABC.__init__(self, "AutoRole") + + self._bot = bot + self._auto_role_rules = auto_role_rules + self._servers = servers + + self.set_field("id", self.resolve_id) + self.set_field("channelId", self.resolve_channel_id) + self.set_field("messageId", self.resolve_message_id) + self.set_field("server", self.resolve_server) + + @staticmethod + def resolve_id(x: AutoRole, *_): + return x.id + + @staticmethod + def resolve_channel_id(x: AutoRole, *_): + return x.discord_channel_id + + @staticmethod + def resolve_message_id(x: AutoRole, *_): + return x.discord_message_id + + def resolve_server(self, x: AutoRole, *_): + return x.server diff --git a/kdb-bot/src/bot_graphql/queries/auto_role_query.py b/kdb-bot/src/bot_graphql/queries/auto_role_query.py index 26f8b390..aaf694b7 100644 --- a/kdb-bot/src/bot_graphql/queries/auto_role_query.py +++ b/kdb-bot/src/bot_graphql/queries/auto_role_query.py @@ -1,21 +1,24 @@ +from cpl_core.database.context import DatabaseContextABC from cpl_discord.service import DiscordBotServiceABC from bot_data.abc.auto_role_repository_abc import AutoRoleRepositoryABC from bot_data.abc.server_repository_abc import ServerRepositoryABC from bot_data.model.auto_role import AutoRole -from bot_graphql.abc.data_query_abc import DataQueryABC +from bot_data.model.auto_role_history import AutoRoleHistory +from bot_graphql.abc.data_query_with_history_abc import DataQueryWithHistoryABC from bot_graphql.filter.auto_role_filter import AutoRoleFilter from bot_graphql.filter.server_filter import ServerFilter -class AutoRoleQuery(DataQueryABC): +class AutoRoleQuery(DataQueryWithHistoryABC): def __init__( self, bot: DiscordBotServiceABC, auto_role_rules: AutoRoleRepositoryABC, servers: ServerRepositoryABC, + db: DatabaseContextABC, ): - DataQueryABC.__init__(self, "AutoRole") + DataQueryWithHistoryABC.__init__(self, "AutoRole", "AutoRolesHistory", AutoRoleHistory, db) self._bot = bot self._auto_role_rules = auto_role_rules diff --git a/kdb-bot/src/bot_graphql/queries/auto_role_rule_history_query.py b/kdb-bot/src/bot_graphql/queries/auto_role_rule_history_query.py new file mode 100644 index 00000000..8cfb6869 --- /dev/null +++ b/kdb-bot/src/bot_graphql/queries/auto_role_rule_history_query.py @@ -0,0 +1,37 @@ +from cpl_discord.service import DiscordBotServiceABC + +from bot_data.abc.auto_role_repository_abc import AutoRoleRepositoryABC +from bot_data.model.auto_role_rule import AutoRoleRule +from bot_graphql.abc.history_query_abc import HistoryQueryABC + + +class AutoRoleRuleHistoryQuery(HistoryQueryABC): + def __init__( + self, + bot: DiscordBotServiceABC, + auto_roles: AutoRoleRepositoryABC, + ): + HistoryQueryABC.__init__(self, "AutoRoleRule") + + self._bot = bot + self._auto_roles = auto_roles + + self.set_field("id", self.resolve_id) + self.set_field("emojiName", self.resolve_emoji_name) + self.set_field("roleId", self.resolve_role_id) + self.set_field("autoRole", self.resolve_auto_role) + + @staticmethod + def resolve_id(x: AutoRoleRule, *_): + return x.id + + @staticmethod + def resolve_emoji_name(x: AutoRoleRule, *_): + return x.emoji_name + + @staticmethod + def resolve_role_id(x: AutoRoleRule, *_): + return x.role_id + + def resolve_auto_role(self, x: AutoRoleRule, *_): + return x.auto_role diff --git a/kdb-bot/src/bot_graphql/queries/auto_role_rule_query.py b/kdb-bot/src/bot_graphql/queries/auto_role_rule_query.py index faa8df8f..e847a605 100644 --- a/kdb-bot/src/bot_graphql/queries/auto_role_rule_query.py +++ b/kdb-bot/src/bot_graphql/queries/auto_role_rule_query.py @@ -1,17 +1,15 @@ +from cpl_core.database.context import DatabaseContextABC from cpl_discord.service import DiscordBotServiceABC from bot_data.abc.auto_role_repository_abc import AutoRoleRepositoryABC from bot_data.model.auto_role_rule import AutoRoleRule -from bot_graphql.abc.data_query_abc import DataQueryABC +from bot_data.model.auto_role_rule_history import AutoRoleRuleHistory +from bot_graphql.abc.data_query_with_history_abc import DataQueryWithHistoryABC -class AutoRoleRuleQuery(DataQueryABC): - def __init__( - self, - bot: DiscordBotServiceABC, - auto_roles: AutoRoleRepositoryABC, - ): - DataQueryABC.__init__(self, "AutoRoleRule") +class AutoRoleRuleQuery(DataQueryWithHistoryABC): + def __init__(self, bot: DiscordBotServiceABC, auto_roles: AutoRoleRepositoryABC, db: DatabaseContextABC): + DataQueryWithHistoryABC.__init__(self, "AutoRoleRule", "AutoRoleRulesHistory", AutoRoleRuleHistory, db) self._bot = bot self._auto_roles = auto_roles diff --git a/kdb-bot/src/bot_graphql/queries/client_history_query.py b/kdb-bot/src/bot_graphql/queries/client_history_query.py new file mode 100644 index 00000000..3d1e340f --- /dev/null +++ b/kdb-bot/src/bot_graphql/queries/client_history_query.py @@ -0,0 +1,60 @@ +from cpl_discord.service import DiscordBotServiceABC + +from bot_data.model.client import Client +from bot_graphql.abc.history_query_abc import HistoryQueryABC + + +class ClientHistoryQuery(HistoryQueryABC): + def __init__( + self, + bot: DiscordBotServiceABC, + ): + HistoryQueryABC.__init__(self, "Client") + + self._bot = bot + + self.set_field("id", self.resolve_id) + self.set_field("discordId", self.resolve_discord_id) + self.set_field("name", self.resolve_name) + self.set_field("sentMessageCount", self.resolve_sent_message_count) + self.set_field("receivedMessageCount", self.resolve_received_message_count) + self.set_field("deletedMessageCount", self.resolve_deleted_message_count) + self.set_field("receivedCommandCount", self.resolve_received_command_count) + self.set_field("movedUsersCount", self.resolve_moved_users_count) + self.set_field("server", self.resolve_server) + + @staticmethod + def resolve_id(client: Client, *_): + return client.id + + @staticmethod + def resolve_discord_id(client: Client, *_): + return client.discord_id + + @staticmethod + def resolve_name(client: Client, *_): + return client.name + + @staticmethod + def resolve_sent_message_count(client: Client, *_): + return client.sent_message_count + + @staticmethod + def resolve_received_message_count(client: Client, *_): + return client.received_command_count + + @staticmethod + def resolve_deleted_message_count(client: Client, *_): + return client.deleted_message_count + + @staticmethod + def resolve_received_command_count(client: Client, *_): + return client.received_command_count + + @staticmethod + def resolve_moved_users_count(client: Client, *_): + return client.moved_users_count + + @staticmethod + def resolve_server(client: Client, *_): + return client.server diff --git a/kdb-bot/src/bot_graphql/queries/client_query.py b/kdb-bot/src/bot_graphql/queries/client_query.py index fe2312b7..e5cd4c68 100644 --- a/kdb-bot/src/bot_graphql/queries/client_query.py +++ b/kdb-bot/src/bot_graphql/queries/client_query.py @@ -1,15 +1,14 @@ +from cpl_core.database.context import DatabaseContextABC from cpl_discord.service import DiscordBotServiceABC from bot_data.model.client import Client -from bot_graphql.abc.data_query_abc import DataQueryABC +from bot_data.model.client_history import ClientHistory +from bot_graphql.abc.data_query_with_history_abc import DataQueryWithHistoryABC -class ClientQuery(DataQueryABC): - def __init__( - self, - bot: DiscordBotServiceABC, - ): - DataQueryABC.__init__(self, "Client") +class ClientQuery(DataQueryWithHistoryABC): + def __init__(self, bot: DiscordBotServiceABC, db: DatabaseContextABC): + DataQueryWithHistoryABC.__init__(self, "Client", "ClientsHistory", ClientHistory, db) self._bot = bot diff --git a/kdb-bot/src/bot_graphql/queries/known_user_history_query.py b/kdb-bot/src/bot_graphql/queries/known_user_history_query.py new file mode 100644 index 00000000..052bf291 --- /dev/null +++ b/kdb-bot/src/bot_graphql/queries/known_user_history_query.py @@ -0,0 +1,18 @@ +from bot_data.model.known_user import KnownUser +from bot_graphql.abc.history_query_abc import HistoryQueryABC + + +class KnownUserHistoryQuery(HistoryQueryABC): + def __init__(self): + HistoryQueryABC.__init__(self, "KnownUser") + + self.set_field("id", self.resolve_id) + self.set_field("discordId", self.resolve_discord_id) + + @staticmethod + def resolve_id(x: KnownUser, *_): + return x.id + + @staticmethod + def resolve_discord_id(x: KnownUser, *_): + return x.discord_id diff --git a/kdb-bot/src/bot_graphql/queries/known_user_query.py b/kdb-bot/src/bot_graphql/queries/known_user_query.py index 8892e2c7..d3435735 100644 --- a/kdb-bot/src/bot_graphql/queries/known_user_query.py +++ b/kdb-bot/src/bot_graphql/queries/known_user_query.py @@ -1,10 +1,13 @@ +from cpl_core.database.context import DatabaseContextABC + from bot_data.model.known_user import KnownUser -from bot_graphql.abc.data_query_abc import DataQueryABC +from bot_data.model.known_user_history import KnownUserHistory +from bot_graphql.abc.data_query_with_history_abc import DataQueryWithHistoryABC -class KnownUserQuery(DataQueryABC): - def __init__(self): - DataQueryABC.__init__(self, "KnownUser") +class KnownUserQuery(DataQueryWithHistoryABC): + def __init__(self, db: DatabaseContextABC): + DataQueryWithHistoryABC.__init__(self, "KnownUser", "KnownUsersHistory", KnownUserHistory, db) self.set_field("id", self.resolve_id) self.set_field("discordId", self.resolve_discord_id) diff --git a/kdb-bot/src/bot_graphql/queries/level_history_query.py b/kdb-bot/src/bot_graphql/queries/level_history_query.py new file mode 100644 index 00000000..fecf8ffb --- /dev/null +++ b/kdb-bot/src/bot_graphql/queries/level_history_query.py @@ -0,0 +1,38 @@ +from bot_data.model.level import Level +from bot_graphql.abc.history_query_abc import HistoryQueryABC + + +class LevelHistoryQuery(HistoryQueryABC): + def __init__(self): + HistoryQueryABC.__init__(self, "Level") + + self.set_field("id", self.resolve_id) + self.set_field("name", self.resolve_name) + self.set_field("color", self.resolve_color) + self.set_field("minXp", self.resolve_min_xp) + self.set_field("permissions", self.resolve_permissions) + self.set_field("server", self.resolve_server) + + @staticmethod + def resolve_id(level: Level, *_): + return level.id + + @staticmethod + def resolve_name(level: Level, *_): + return level.name + + @staticmethod + def resolve_color(level: Level, *_): + return level.color + + @staticmethod + def resolve_min_xp(level: Level, *_): + return level.min_xp + + @staticmethod + def resolve_permissions(level: Level, *_): + return level.permissions + + @staticmethod + def resolve_server(level: Level, *_): + return level.server diff --git a/kdb-bot/src/bot_graphql/queries/level_query.py b/kdb-bot/src/bot_graphql/queries/level_query.py index a0f22453..5f726c5b 100644 --- a/kdb-bot/src/bot_graphql/queries/level_query.py +++ b/kdb-bot/src/bot_graphql/queries/level_query.py @@ -1,10 +1,13 @@ +from cpl_core.database.context import DatabaseContextABC + from bot_data.model.level import Level -from bot_graphql.abc.data_query_abc import DataQueryABC +from bot_data.model.level_history import LevelHistory +from bot_graphql.abc.data_query_with_history_abc import DataQueryWithHistoryABC -class LevelQuery(DataQueryABC): - def __init__(self): - DataQueryABC.__init__(self, "Level") +class LevelQuery(DataQueryWithHistoryABC): + def __init__(self, db: DatabaseContextABC): + DataQueryWithHistoryABC.__init__(self, "Level", "LevelsHistory", LevelHistory, db) self.set_field("id", self.resolve_id) self.set_field("name", self.resolve_name) diff --git a/kdb-bot/src/bot_graphql/queries/server_history_query.py b/kdb-bot/src/bot_graphql/queries/server_history_query.py new file mode 100644 index 00000000..1578d331 --- /dev/null +++ b/kdb-bot/src/bot_graphql/queries/server_history_query.py @@ -0,0 +1,30 @@ +from bot_data.model.server import Server +from bot_graphql.abc.history_query_abc import HistoryQueryABC + + +class ServerHistoryQuery(HistoryQueryABC): + def __init__( + self, + ): + HistoryQueryABC.__init__(self, "Server") + + self.set_field("id", self.resolve_id) + self.set_field("discordId", self.resolve_discord_id) + self.set_field("name", self.resolve_name) + self.set_field("iconURL", self.resolve_icon_url) + + @staticmethod + def resolve_id(server: Server, *_): + return server.id + + @staticmethod + def resolve_discord_id(server: Server, *_): + return server.discord_id + + @staticmethod + def resolve_name(server: Server, *_): + return server.name + + @staticmethod + def resolve_icon_url(server: Server, *_): + return server.icon_url diff --git a/kdb-bot/src/bot_graphql/queries/server_query.py b/kdb-bot/src/bot_graphql/queries/server_query.py index 059a87fd..39012d49 100644 --- a/kdb-bot/src/bot_graphql/queries/server_query.py +++ b/kdb-bot/src/bot_graphql/queries/server_query.py @@ -1,3 +1,4 @@ +from cpl_core.database.context import DatabaseContextABC from cpl_discord.service import DiscordBotServiceABC from bot_data.abc.auto_role_repository_abc import AutoRoleRepositoryABC @@ -7,17 +8,20 @@ from bot_data.abc.user_joined_server_repository_abc import UserJoinedServerRepos from bot_data.abc.user_joined_voice_channel_repository_abc import UserJoinedVoiceChannelRepositoryABC from bot_data.abc.user_repository_abc import UserRepositoryABC from bot_data.model.server import Server +from bot_data.model.server_history import ServerHistory from bot_graphql.abc.data_query_abc import DataQueryABC +from bot_graphql.abc.data_query_with_history_abc import DataQueryWithHistoryABC from bot_graphql.filter.auto_role_filter import AutoRoleFilter from bot_graphql.filter.client_filter import ClientFilter from bot_graphql.filter.level_filter import LevelFilter from bot_graphql.filter.user_filter import UserFilter -class ServerQuery(DataQueryABC): +class ServerQuery(DataQueryWithHistoryABC): def __init__( self, bot: DiscordBotServiceABC, + db: DatabaseContextABC, auto_roles: AutoRoleRepositoryABC, clients: ClientRepositoryABC, levels: LevelRepositoryABC, @@ -25,7 +29,7 @@ class ServerQuery(DataQueryABC): ujs: UserJoinedServerRepositoryABC, ujvs: UserJoinedVoiceChannelRepositoryABC, ): - DataQueryABC.__init__(self, "Server") + DataQueryWithHistoryABC.__init__(self, "Server", "ServersHistory", ServerHistory, db) self._bot = bot self._auto_roles = auto_roles diff --git a/kdb-bot/src/bot_graphql/queries/user_history_query.py b/kdb-bot/src/bot_graphql/queries/user_history_query.py new file mode 100644 index 00000000..14d3867b --- /dev/null +++ b/kdb-bot/src/bot_graphql/queries/user_history_query.py @@ -0,0 +1,28 @@ +from bot_data.model.user import User +from bot_graphql.abc.history_query_abc import HistoryQueryABC + + +class UserHistoryQuery(HistoryQueryABC): + def __init__(self): + HistoryQueryABC.__init__(self, "User") + + self.set_field("id", self.resolve_id) + self.set_field("discordId", self.resolve_discord_id) + self.set_field("xp", self.resolve_xp) + self.set_field("server", self.resolve_server) + + @staticmethod + def resolve_id(user: User, *_): + return user.id + + @staticmethod + def resolve_discord_id(user: User, *_): + return user.discord_id + + @staticmethod + def resolve_xp(user: User, *_): + return user.xp + + @staticmethod + def resolve_server(user: User, *_): + return user.server diff --git a/kdb-bot/src/bot_graphql/queries/user_joined_game_server_history_query.py b/kdb-bot/src/bot_graphql/queries/user_joined_game_server_history_query.py new file mode 100644 index 00000000..d0997b5a --- /dev/null +++ b/kdb-bot/src/bot_graphql/queries/user_joined_game_server_history_query.py @@ -0,0 +1,41 @@ +from cpl_discord.service import DiscordBotServiceABC + +from bot_data.model.user_joined_game_server import UserJoinedGameServer +from bot_graphql.abc.history_query_abc import HistoryQueryABC + + +class UserJoinedGameServerHistoryQuery(HistoryQueryABC): + def __init__(self, bot: DiscordBotServiceABC): + HistoryQueryABC.__init__(self, "UserJoinedGameServer") + + self._bot = bot + + self.set_field("id", self.resolve_id) + self.set_field("gameServer", self.resolve_game_server) + self.set_field("user", self.resolve_user) + self.set_field("joinedOn", self.resolve_joined_on) + self.set_field("leavedOn", self.resolve_leaved_on) + + @staticmethod + def resolve_id(x: UserJoinedGameServer, *_): + return x.id + + @staticmethod + def resolve_game_server(x: UserJoinedGameServer, *_): + return x.game_server.name + + @staticmethod + def resolve_user(x: UserJoinedGameServer, *_): + return x.user + + @staticmethod + def resolve_time(x: UserJoinedGameServer, *_): + return x.time + + @staticmethod + def resolve_joined_on(x: UserJoinedGameServer, *_): + return x.joined_on + + @staticmethod + def resolve_leaved_on(x: UserJoinedGameServer, *_): + return x.leaved_on diff --git a/kdb-bot/src/bot_graphql/queries/user_joined_game_server_query.py b/kdb-bot/src/bot_graphql/queries/user_joined_game_server_query.py index 854419e5..6a5befaa 100644 --- a/kdb-bot/src/bot_graphql/queries/user_joined_game_server_query.py +++ b/kdb-bot/src/bot_graphql/queries/user_joined_game_server_query.py @@ -1,12 +1,16 @@ +from cpl_core.database.context import DatabaseContextABC from cpl_discord.service import DiscordBotServiceABC from bot_data.model.user_joined_game_server import UserJoinedGameServer -from bot_graphql.abc.data_query_abc import DataQueryABC +from bot_data.model.user_joined_game_server_history import UserJoinedGameServerHistory +from bot_graphql.abc.data_query_with_history_abc import DataQueryWithHistoryABC -class UserJoinedGameServerQuery(DataQueryABC): - def __init__(self, bot: DiscordBotServiceABC): - DataQueryABC.__init__(self, "UserJoinedGameServer") +class UserJoinedGameServerQuery(DataQueryWithHistoryABC): + def __init__(self, bot: DiscordBotServiceABC, db: DatabaseContextABC): + DataQueryWithHistoryABC.__init__( + self, "UserJoinedGameServer", "UserJoinedGameServersHistory", UserJoinedGameServerHistory, db + ) self._bot = bot diff --git a/kdb-bot/src/bot_graphql/queries/user_joined_server_history_query.py b/kdb-bot/src/bot_graphql/queries/user_joined_server_history_query.py new file mode 100644 index 00000000..3d7beed5 --- /dev/null +++ b/kdb-bot/src/bot_graphql/queries/user_joined_server_history_query.py @@ -0,0 +1,28 @@ +from bot_data.model.user_joined_server import UserJoinedServer +from bot_graphql.abc.data_query_abc import DataQueryABC + + +class UserJoinedServerHistoryQuery(DataQueryABC): + def __init__(self): + DataQueryABC.__init__(self, "UserJoinedServer") + + self.set_field("id", self.resolve_id) + self.set_field("user", self.resolve_user) + self.set_field("joinedOn", self.resolve_joined_on) + self.set_field("leavedOn", self.resolve_leaved_on) + + @staticmethod + def resolve_id(x: UserJoinedServer, *_): + return x.id + + @staticmethod + def resolve_user(x: UserJoinedServer, *_): + return x.user + + @staticmethod + def resolve_joined_on(x: UserJoinedServer, *_): + return x.joined_on + + @staticmethod + def resolve_leaved_on(x: UserJoinedServer, *_): + return x.leaved_on diff --git a/kdb-bot/src/bot_graphql/queries/user_joined_server_query.py b/kdb-bot/src/bot_graphql/queries/user_joined_server_query.py index 6036e115..a8e236ff 100644 --- a/kdb-bot/src/bot_graphql/queries/user_joined_server_query.py +++ b/kdb-bot/src/bot_graphql/queries/user_joined_server_query.py @@ -1,10 +1,15 @@ +from cpl_core.database.context import DatabaseContextABC + from bot_data.model.user_joined_server import UserJoinedServer -from bot_graphql.abc.data_query_abc import DataQueryABC +from bot_data.model.user_joined_server_history import UserJoinedServerHistory +from bot_graphql.abc.data_query_with_history_abc import DataQueryWithHistoryABC -class UserJoinedServerQuery(DataQueryABC): - def __init__(self): - DataQueryABC.__init__(self, "UserJoinedServer") +class UserJoinedServerQuery(DataQueryWithHistoryABC): + def __init__(self, db: DatabaseContextABC): + DataQueryWithHistoryABC.__init__( + self, "UserJoinedServer", "UserJoinedServersHistory", UserJoinedServerHistory, db + ) self.set_field("id", self.resolve_id) self.set_field("user", self.resolve_user) diff --git a/kdb-bot/src/bot_graphql/queries/user_joined_voice_channel_history_query.py b/kdb-bot/src/bot_graphql/queries/user_joined_voice_channel_history_query.py new file mode 100644 index 00000000..c9cae071 --- /dev/null +++ b/kdb-bot/src/bot_graphql/queries/user_joined_voice_channel_history_query.py @@ -0,0 +1,47 @@ +from cpl_discord.service import DiscordBotServiceABC + +from bot_data.model.user_joined_voice_channel import UserJoinedVoiceChannel +from bot_graphql.abc.history_query_abc import HistoryQueryABC + + +class UserJoinedVoiceChannelHistoryQuery(HistoryQueryABC): + def __init__(self, bot: DiscordBotServiceABC): + HistoryQueryABC.__init__(self, "UserJoinedVoiceChannel") + + self._bot = bot + + self.set_field("id", self.resolve_id) + self.set_field("channelId", self.resolve_channel_id) + self.set_field("channelName", self.resolve_channel_name) + self.set_field("user", self.resolve_user) + self.set_field("time", self.resolve_time) + self.set_field("joinedOn", self.resolve_joined_on) + self.set_field("leavedOn", self.resolve_leaved_on) + + @staticmethod + def resolve_id(x: UserJoinedVoiceChannel, *_): + return x.id + + @staticmethod + def resolve_channel_id(x: UserJoinedVoiceChannel, *_): + return x.channel_id + + @staticmethod + def resolve_channel_name(x: UserJoinedVoiceChannel, *_): + return x.channel_name + + @staticmethod + def resolve_user(x: UserJoinedVoiceChannel, *_): + return x.user + + @staticmethod + def resolve_time(x: UserJoinedVoiceChannel, *_): + return x.time + + @staticmethod + def resolve_joined_on(x: UserJoinedVoiceChannel, *_): + return x.joined_on + + @staticmethod + def resolve_leaved_on(x: UserJoinedVoiceChannel, *_): + return x.leaved_on diff --git a/kdb-bot/src/bot_graphql/queries/user_joined_voice_channel_query.py b/kdb-bot/src/bot_graphql/queries/user_joined_voice_channel_query.py index 2640307d..a5465581 100644 --- a/kdb-bot/src/bot_graphql/queries/user_joined_voice_channel_query.py +++ b/kdb-bot/src/bot_graphql/queries/user_joined_voice_channel_query.py @@ -1,12 +1,16 @@ +from cpl_core.database.context import DatabaseContextABC from cpl_discord.service import DiscordBotServiceABC from bot_data.model.user_joined_voice_channel import UserJoinedVoiceChannel -from bot_graphql.abc.data_query_abc import DataQueryABC +from bot_data.model.user_joined_voice_channel_history import UserJoinedVoiceChannelHistory +from bot_graphql.abc.data_query_with_history_abc import DataQueryWithHistoryABC -class UserJoinedVoiceChannelQuery(DataQueryABC): - def __init__(self, bot: DiscordBotServiceABC): - DataQueryABC.__init__(self, "UserJoinedVoiceChannel") +class UserJoinedVoiceChannelQuery(DataQueryWithHistoryABC): + def __init__(self, bot: DiscordBotServiceABC, db: DatabaseContextABC): + DataQueryWithHistoryABC.__init__( + self, "UserJoinedVoiceChannel", "UserJoinedVoiceChannelsHistory", UserJoinedVoiceChannelHistory, db + ) self._bot = bot diff --git a/kdb-bot/src/bot_graphql/queries/user_query.py b/kdb-bot/src/bot_graphql/queries/user_query.py index d9439981..9e924f5f 100644 --- a/kdb-bot/src/bot_graphql/queries/user_query.py +++ b/kdb-bot/src/bot_graphql/queries/user_query.py @@ -1,3 +1,4 @@ +from cpl_core.database.context import DatabaseContextABC from cpl_discord.service import DiscordBotServiceABC from bot_core.abc.client_utils_abc import ClientUtilsABC @@ -5,7 +6,8 @@ from bot_data.abc.user_joined_game_server_repository_abc import UserJoinedGameSe from bot_data.abc.user_joined_server_repository_abc import UserJoinedServerRepositoryABC from bot_data.abc.user_joined_voice_channel_repository_abc import UserJoinedVoiceChannelRepositoryABC from bot_data.model.user import User -from bot_graphql.abc.data_query_abc import DataQueryABC +from bot_data.model.user_history import UserHistory +from bot_graphql.abc.data_query_with_history_abc import DataQueryWithHistoryABC from bot_graphql.filter.user_joined_game_server_filter import UserJoinedGameServerFilter from bot_graphql.filter.user_joined_server_filter import UserJoinedServerFilter from bot_graphql.filter.user_joined_voice_channel_filter import UserJoinedVoiceChannelFilter @@ -13,10 +15,11 @@ from modules.level.service.level_service import LevelService from modules.permission.abc.permission_service_abc import PermissionServiceABC -class UserQuery(DataQueryABC): +class UserQuery(DataQueryWithHistoryABC): def __init__( self, bot: DiscordBotServiceABC, + db: DatabaseContextABC, levels: LevelService, client_utils: ClientUtilsABC, ujs: UserJoinedServerRepositoryABC, @@ -24,7 +27,7 @@ class UserQuery(DataQueryABC): user_joined_game_server: UserJoinedGameServerRepositoryABC, permissions: PermissionServiceABC, ): - DataQueryABC.__init__(self, "User") + DataQueryWithHistoryABC.__init__(self, "User", "UsersHistory", UserHistory, db) self._bot = bot self._levels = levels diff --git a/kdb-web/package.json b/kdb-web/package.json index f35affd8..b4bb8e1f 100644 --- a/kdb-web/package.json +++ b/kdb-web/package.json @@ -1,6 +1,6 @@ { "name": "kdb-web", - "version": "1.0.dev247", + "version": "1.0.dev246", "scripts": { "ng": "ng", "update-version": "ts-node-esm update-version.ts", diff --git a/kdb-web/src/app/models/data/data.model.ts b/kdb-web/src/app/models/data/data.model.ts index dcd3c42c..768d637f 100644 --- a/kdb-web/src/app/models/data/data.model.ts +++ b/kdb-web/src/app/models/data/data.model.ts @@ -2,3 +2,16 @@ export interface Data { createdAt?: string; modifiedAt?: string; } + +export interface DataWithHistory { + createdAt?: string; + modifiedAt?: string; + history?: History[]; +} + +export interface History { + deleted?: boolean; + dateFrom?: string; + dateTo?: string; + [x: string | number | symbol]: unknown; +} diff --git a/kdb-web/src/app/models/data/user.model.ts b/kdb-web/src/app/models/data/user.model.ts index 89d69806..671da870 100644 --- a/kdb-web/src/app/models/data/user.model.ts +++ b/kdb-web/src/app/models/data/user.model.ts @@ -1,11 +1,11 @@ -import { Data } from "./data.model"; +import { DataWithHistory } from "./data.model"; import { Level, LevelFilter } from "./level.model"; import { Server, ServerFilter } from "./server.model"; import { UserJoinedServer } from "./user_joined_server.model"; import { UserJoinedVoiceChannel } from "./user_joined_voice_channel.model"; import { UserJoinedGameServer } from "./user_joined_game_server.model"; -export interface User extends Data { +export interface User extends DataWithHistory { id?: number; discordId?: number; name?: string; @@ -23,6 +23,17 @@ export interface User extends Data { userJoinedGameServerCount?: number; userJoinedGameServers?: UserJoinedGameServer[]; + + // history?: UserHistory[]; +} + +export interface UserHistory extends History { + id?: number; + discordId?: number; + xp?: number; + level?: number; + server?: number; + leftServer?: boolean; } export interface UserFilter { diff --git a/kdb-web/src/app/models/graphql/queries.model.ts b/kdb-web/src/app/models/graphql/queries.model.ts index 96d52ea3..29b8dbcf 100644 --- a/kdb-web/src/app/models/graphql/queries.model.ts +++ b/kdb-web/src/app/models/graphql/queries.model.ts @@ -62,6 +62,18 @@ export class Queries { } createdAt modifiedAt + + history { + id + name + color + minXp + permissions + server + deleted + dateFrom + dateTo + } } } } @@ -115,6 +127,16 @@ export class Queries { createdAt modifiedAt + + history { + id + discordId + xp + server + deleted + dateFrom + dateTo + } } } } @@ -137,6 +159,16 @@ export class Queries { createdAt modifiedAt + + history { + id + channelId + messageId + server + deleted + dateFrom + dateTo + } } } } @@ -159,6 +191,16 @@ export class Queries { createdAt modifiedAt + + history { + id + emojiName + roleId + autoRole + deleted + dateFrom + dateTo + } } } } diff --git a/kdb-web/src/app/modules/shared/components/history-btn/history-btn.component.html b/kdb-web/src/app/modules/shared/components/history-btn/history-btn.component.html new file mode 100644 index 00000000..9f9b4f53 --- /dev/null +++ b/kdb-web/src/app/modules/shared/components/history-btn/history-btn.component.html @@ -0,0 +1,21 @@ + + + +

{{translationKey | translate}} {{'common.history.header' | translate}}

+ +
+
+
+
+ {{getAttributeTranslationKey(item.key) | translate}} +
+
+ -> +
+
+ {{item.value}} +
+
+
+
+
diff --git a/kdb-web/src/app/modules/shared/components/history-btn/history-btn.component.scss b/kdb-web/src/app/modules/shared/components/history-btn/history-btn.component.scss new file mode 100644 index 00000000..e69de29b diff --git a/kdb-web/src/app/modules/shared/components/history-btn/history-btn.component.spec.ts b/kdb-web/src/app/modules/shared/components/history-btn/history-btn.component.spec.ts new file mode 100644 index 00000000..2d1e4520 --- /dev/null +++ b/kdb-web/src/app/modules/shared/components/history-btn/history-btn.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { HistoryBtnComponent } from './history-btn.component'; + +describe('HistoryBtnComponent', () => { + let component: HistoryBtnComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ HistoryBtnComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(HistoryBtnComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/kdb-web/src/app/modules/shared/components/history-btn/history-btn.component.ts b/kdb-web/src/app/modules/shared/components/history-btn/history-btn.component.ts new file mode 100644 index 00000000..db89ea41 --- /dev/null +++ b/kdb-web/src/app/modules/shared/components/history-btn/history-btn.component.ts @@ -0,0 +1,43 @@ +import { Component, Input, OnInit } from "@angular/core"; +import { History } from "../../../../models/data/data.model"; + +@Component({ + selector: "app-history-btn", + templateUrl: "./history-btn.component.html", + styleUrls: ["./history-btn.component.scss"] +}) +export class HistoryBtnComponent implements OnInit { + + @Input() history: History[] = []; + @Input() translationKey: string = ""; + + public showSidebar: boolean = false; + + public constructor() { + } + + public ngOnInit(): void { + } + + public openHistory(): void { + this.showSidebar = true; + let oldHistory: Partial = {}; + for (const history of this.history) { + const attributes = Object.keys(history).map((key) => { + return key; + }); + for (const attribute of attributes) { + if (history[attribute] === oldHistory[attribute]) { + delete oldHistory[attribute]; + } + } + + oldHistory = history; + } + } + + public getAttributeTranslationKey(key: string): string { + return `common.history.${key}`; + } + +} diff --git a/kdb-web/src/app/modules/shared/shared.module.ts b/kdb-web/src/app/modules/shared/shared.module.ts index 986ddd26..e2d14884 100644 --- a/kdb-web/src/app/modules/shared/shared.module.ts +++ b/kdb-web/src/app/modules/shared/shared.module.ts @@ -1,28 +1,29 @@ -import { CommonModule } from '@angular/common'; -import { HttpClientModule } from '@angular/common/http'; -import { NgModule } from '@angular/core'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { TranslateModule } from '@ngx-translate/core'; -import { ButtonModule } from 'primeng/button'; -import { CheckboxModule } from 'primeng/checkbox'; -import { ConfirmDialogModule } from 'primeng/confirmdialog'; -import { DialogModule } from 'primeng/dialog'; -import { DropdownModule } from 'primeng/dropdown'; -import { DynamicDialogModule } from 'primeng/dynamicdialog'; -import { InputTextModule } from 'primeng/inputtext'; -import { MenuModule } from 'primeng/menu'; -import { PasswordModule } from 'primeng/password'; -import { ProgressSpinnerModule } from 'primeng/progressspinner'; -import { TableModule } from 'primeng/table'; -import { ToastModule } from 'primeng/toast'; -import { AuthRolePipe } from './pipes/auth-role.pipe'; -import { IpAddressPipe } from './pipes/ip-address.pipe'; -import { BoolPipe } from './pipes/bool.pipe'; -import { PanelMenuModule } from 'primeng/panelmenu'; +import { CommonModule } from "@angular/common"; +import { HttpClientModule } from "@angular/common/http"; +import { NgModule } from "@angular/core"; +import { FormsModule, ReactiveFormsModule } from "@angular/forms"; +import { TranslateModule } from "@ngx-translate/core"; +import { ButtonModule } from "primeng/button"; +import { CheckboxModule } from "primeng/checkbox"; +import { ConfirmDialogModule } from "primeng/confirmdialog"; +import { DialogModule } from "primeng/dialog"; +import { DropdownModule } from "primeng/dropdown"; +import { DynamicDialogModule } from "primeng/dynamicdialog"; +import { InputTextModule } from "primeng/inputtext"; +import { MenuModule } from "primeng/menu"; +import { PasswordModule } from "primeng/password"; +import { ProgressSpinnerModule } from "primeng/progressspinner"; +import { TableModule } from "primeng/table"; +import { ToastModule } from "primeng/toast"; +import { AuthRolePipe } from "./pipes/auth-role.pipe"; +import { IpAddressPipe } from "./pipes/ip-address.pipe"; +import { BoolPipe } from "./pipes/bool.pipe"; +import { PanelMenuModule } from "primeng/panelmenu"; import { PanelModule } from "primeng/panel"; -import { InputNumberModule } from 'primeng/inputnumber'; +import { InputNumberModule } from "primeng/inputnumber"; import { ImageModule } from "primeng/image"; - +import { SidebarModule } from "primeng/sidebar"; +import { HistoryBtnComponent } from './components/history-btn/history-btn.component'; @NgModule({ @@ -30,6 +31,7 @@ import { ImageModule } from "primeng/image"; AuthRolePipe, IpAddressPipe, BoolPipe, + HistoryBtnComponent, ], imports: [ CommonModule, @@ -52,7 +54,8 @@ import { ImageModule } from "primeng/image"; PanelMenuModule, PanelModule, InputNumberModule, - ImageModule + ImageModule, + SidebarModule, ], exports: [ ButtonModule, @@ -77,7 +80,9 @@ import { ImageModule } from "primeng/image"; IpAddressPipe, BoolPipe, InputNumberModule, - ImageModule + ImageModule, + SidebarModule, + HistoryBtnComponent ] }) export class SharedModule { } diff --git a/kdb-web/src/app/modules/view/server/auto-role/components/auto-roles-rules/auto-roles-rules.component.html b/kdb-web/src/app/modules/view/server/auto-role/components/auto-roles-rules/auto-roles-rules.component.html index 8a6bfdaf..60c0d0eb 100644 --- a/kdb-web/src/app/modules/view/server/auto-role/components/auto-roles-rules/auto-roles-rules.component.html +++ b/kdb-web/src/app/modules/view/server/auto-role/components/auto-roles-rules/auto-roles-rules.component.html @@ -160,6 +160,7 @@
+ diff --git a/kdb-web/src/app/modules/view/server/auto-role/components/auto-roles/auto-roles.component.html b/kdb-web/src/app/modules/view/server/auto-role/components/auto-roles/auto-roles.component.html index 6b332b3e..f6695fca 100644 --- a/kdb-web/src/app/modules/view/server/auto-role/components/auto-roles/auto-roles.component.html +++ b/kdb-web/src/app/modules/view/server/auto-role/components/auto-roles/auto-roles.component.html @@ -193,6 +193,7 @@
+ diff --git a/kdb-web/src/app/modules/view/server/levels/components/levels/levels.component.html b/kdb-web/src/app/modules/view/server/levels/components/levels/levels.component.html index 0e5ed0ed..83f32aa3 100644 --- a/kdb-web/src/app/modules/view/server/levels/components/levels/levels.component.html +++ b/kdb-web/src/app/modules/view/server/levels/components/levels/levels.component.html @@ -184,6 +184,7 @@
+