Als Nutzer möchte ich Datenänderungen nach verfolgen können #246 #248

Merged
Jonas merged 17 commits from #246 into 1.0.0 2023-03-14 18:31:37 +01:00
112 changed files with 2518 additions and 214 deletions

View File

@ -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",

@ -1 +1 @@
Subproject commit 781aa3f6ab861343d1635005ec7dc1814065b3c7
Subproject commit 0bd4bb020b1a058e0a1fa9d4ffa1d4a3bffb28b8

View File

@ -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

View File

@ -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

View File

@ -3,6 +3,7 @@ from abc import ABC, abstractmethod
class MigrationABC(ABC):
name = None
prio = 0
@abstractmethod
def __init__(self):

View File

@ -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

View File

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

View File

@ -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`;")

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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

View File

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

View File

@ -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

View File

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

View File

@ -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

View File

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

View File

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

View File

@ -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

View File

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

View File

@ -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

View File

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

View File

@ -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
edraft marked this conversation as resolved
Review

Gibt es Fälle, bei dem icon null ist?

Gibt es Fälle, bei dem ```icon``` null ist?
Review

Wenn nicht, kann dies ingnoriert werden.

Wenn nicht, kann dies ingnoriert werden.
Review

nope

nope

View File

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

View File

@ -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:

View File

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

View File

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

View File

@ -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

View File

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

View File

@ -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

View File

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

View File

@ -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

View File

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

View File

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

View File

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

View File

@ -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

View File

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

View File

@ -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

View File

@ -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 {

View File

@ -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 {

View File

@ -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

View File

@ -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 {

View File

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

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

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

View File

@ -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

View File

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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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",

View File

@ -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;
}

View File

@ -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 {

View File

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

View File

@ -0,0 +1,21 @@
<button pButton class="btn icon-btn" icon="pi pi-history" (click)="openHistory()"></button>
<p-sidebar styleClass="history p-sidebar-md" [(visible)]="showSidebar" position="right" [baseZIndex]="10000">
<h1>{{translationKey | translate}} {{'common.history.header' | translate}}</h1>
<div class="entry-list">
<div class="entry" *ngFor="let entry of history">
<div class="attribute" *ngFor="let item of entry | keyvalue">
<div class="key">
{{getAttributeTranslationKey(item.key) | translate}}
</div>
<div class="seperator">
->
</div>
<div class="value">
{{item.value}}
</div>
</div>
</div>
</div>
</p-sidebar>

View File

@ -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<HistoryBtnComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ HistoryBtnComponent ]
})
.compileComponents();
fixture = TestBed.createComponent(HistoryBtnComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
edraft marked this conversation as resolved
Review

Tests schreiben üben wir aber nochmal ^^

Tests schreiben üben wir aber nochmal ^^

View File

@ -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;
edraft marked this conversation as resolved
Review

Darf showSidebar keinen Typen bekommen? :(

public showSidebar: boolean = false;

Je nachdem was showSidebar tut, wäre hier vielleicht ein Store als "Single-Source-Of-Truth" sinnvoll, damit wir hier ein Observable haben.
So kann sich egal wo dieser boolische Wert anpassen und DOM-Elemente anschließened gerendert werden oder eben nicht.
Ist aber wie gesagt abhängig vom Use-Case.

Darf showSidebar keinen Typen bekommen? :( public showSidebar: boolean = false; Je nachdem was showSidebar tut, wäre hier vielleicht ein Store als "Single-Source-Of-Truth" sinnvoll, damit wir hier ein Observable haben. So kann sich egal wo dieser boolische Wert anpassen und DOM-Elemente anschließened gerendert werden oder eben nicht. Ist aber wie gesagt abhängig vom Use-Case.
Review

Generell hast du recht. Wäre für das was die Komponente macht jedoch OP.

Generell hast du recht. Wäre für das was die Komponente macht jedoch OP.
public constructor() {
}
public ngOnInit(): void {
}
public openHistory(): void {
this.showSidebar = true;
let oldHistory: Partial<History> = {};
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}`;
}
}
Jonas marked this conversation as resolved
Review

Mir fehlen sämtliche Sichtbarkeitsregeln:

  • public constructor..
  • public ngOnInit()...
  • ...
Mir fehlen sämtliche Sichtbarkeitsregeln: - public constructor.. - public ngOnInit()... - ...

View File

@ -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 { }

View File

@ -160,6 +160,7 @@
<td>
<div class="btn-wrapper">
<app-history-btn [history]="autoRoleRule.history" translationKey="view.server.auto_roles.rules.header"></app-history-btn>
edraft marked this conversation as resolved
Review

"App" als Präfix finde ich immer hässlich irgendwie.
Bin aber vielleicht auch nur ich, lol.

"App" als Präfix finde ich immer hässlich irgendwie. Bin aber vielleicht auch nur ich, lol.
Review

ja bist du xD

ja bist du xD
<button *ngIf="!editing" pButton pInitEditableRow class="btn icon-btn" icon="pi pi-pencil" (click)="onRowEditInit(dt, autoRoleRule, ri)"></button>
<button *ngIf="!editing" pButton class="btn icon-btn danger-icon-btn" icon="pi pi-trash"
(click)="deleteAutoRoleRule(autoRoleRule)"></button>

Some files were not shown because too many files have changed in this diff Show More