Merge pull request 'Als Nutzer möchte ich Datenänderungen nach verfolgen können #246' (#248) from #246 into 1.0.0

Reviewed-on: sh-edraft.de/kd_discord_bot#248
Reviewed-by: Ebola-Chan <nick.jungmann@gmail.com>
Reviewed-by: Jonas <joni.drescher@web.de>
This commit is contained in:
Jonas 2023-03-14 18:31:36 +01:00
commit 283eaabef6
112 changed files with 2518 additions and 214 deletions

View File

@ -18,7 +18,7 @@
"Dependencies": [ "Dependencies": [
"cpl-core==2022.12.1.post3", "cpl-core==2022.12.1.post3",
"cpl-translation==2022.12.1", "cpl-translation==2022.12.1",
"cpl-query==2022.12.2.post1", "cpl-query==2022.12.2.post2",
"Flask==2.2.2", "Flask==2.2.2",
"Flask-Classful==0.14.2", "Flask-Classful==0.14.2",
"Flask-Cors==3.0.10", "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.api_migration import ApiMigration
from bot_data.migration.auto_role_fix1_migration import AutoRoleFix1Migration from bot_data.migration.auto_role_fix1_migration import AutoRoleFix1Migration
from bot_data.migration.auto_role_migration import AutoRoleMigration 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.initial_migration import InitialMigration
from bot_data.migration.level_migration import LevelMigration from bot_data.migration.level_migration import LevelMigration
from bot_data.migration.remove_stats_migration import RemoveStatsMigration 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, UserJoinedGameServerMigration) # 12.02.2023 #181 - 1.0.0
services.add_transient(MigrationABC, RemoveStatsMigration) # 19.02.2023 #190 - 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, 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): class MigrationABC(ABC):
name = None name = None
prio = 0
@abstractmethod @abstractmethod
def __init__(self): 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): class ApiKeyMigration(MigrationABC):
name = "1.0_ApiKeyMigration" name = "1.0.0_ApiKeyMigration"
def __init__(self, logger: DatabaseLogger, db: DBContext): def __init__(self, logger: DatabaseLogger, db: DBContext):
MigrationABC.__init__(self) 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): class RemoveStatsMigration(MigrationABC):
name = "1.0_RemoveStatsMigration" name = "1.0.0_RemoveStatsMigration"
def __init__(self, logger: DatabaseLogger, db: DBContext): def __init__(self, logger: DatabaseLogger, db: DBContext):
MigrationABC.__init__(self) MigrationABC.__init__(self)

View File

@ -4,7 +4,7 @@ from bot_data.db_context import DBContext
class UserJoinedGameServerMigration(MigrationABC): class UserJoinedGameServerMigration(MigrationABC):
name = "1.0_UserJoinedGameServerMigration" name = "1.0.0_UserJoinedGameServerMigration"
def __init__(self, logger: DatabaseLogger, db: DBContext): def __init__(self, logger: DatabaseLogger, db: DBContext):
MigrationABC.__init__(self) MigrationABC.__init__(self)

View File

@ -4,7 +4,7 @@ from bot_data.db_context import DBContext
class UserWarningMigration(MigrationABC): class UserWarningMigration(MigrationABC):
name = "1.0_UserWarningMigration" name = "1.0.0_UserWarningMigration"
def __init__(self, logger: DatabaseLogger, db: DBContext): def __init__(self, logger: DatabaseLogger, db: DBContext):
MigrationABC.__init__(self) MigrationABC.__init__(self)

View File

@ -82,13 +82,11 @@ class ApiKey(TableABC):
return str( return str(
f""" f"""
INSERT INTO `ApiKeys` ( INSERT INTO `ApiKeys` (
`Identifier`, `Key`, `CreatorId`, `CreatedAt`, `LastModifiedAt` `Identifier`, `Key`, `CreatorId`
) VALUES ( ) VALUES (
'{self._identifier}', '{self._identifier}',
'{self._key}', '{self._key}',
{"NULL" if self._creator is None else f"'{self._creator.id}'"}, {"NULL" if self._creator is None else f"'{self._creator.id}'"}
'{self._created_at}',
'{self._modified_at}'
); );
""" """
) )
@ -100,8 +98,7 @@ class ApiKey(TableABC):
UPDATE `ApiKeys` UPDATE `ApiKeys`
SET `Identifier` = '{self._identifier}', SET `Identifier` = '{self._identifier}',
`Key` = '{self._key}', `Key` = '{self._key}',
`CreatorId` = {"NULL" if self._creator is None else f"'{self._creator.id}'"}, `CreatorId` = {"NULL" if self._creator is None else f"'{self._creator.id}'"}
`LastModifiedAt` = '{self._modified_at}'
WHERE `Id` = {self._id}; WHERE `Id` = {self._id};
""" """
) )

View File

@ -220,9 +220,7 @@ class AuthUser(TableABC):
`ForgotPasswordId`, `ForgotPasswordId`,
`OAuthId`, `OAuthId`,
`RefreshTokenExpiryTime`, `RefreshTokenExpiryTime`,
`AuthRole`, `AuthRole`
`CreatedAt`,
`LastModifiedAt`
) VALUES ( ) VALUES (
{self._auth_user_id}, {self._auth_user_id},
'{self._first_name}', '{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._forgot_password_id is None else f"'{self._forgot_password_id}'"},
{"NULL" if self._oauth_id is None else f"'{self._oauth_id}'"}, {"NULL" if self._oauth_id is None else f"'{self._oauth_id}'"},
'{self._refresh_token_expire_time.isoformat()}', '{self._refresh_token_expire_time.isoformat()}',
{self._auth_role_id.value}, {self._auth_role_id.value}
'{self._created_at}',
'{self._modified_at}'
) )
""" """
) )
@ -257,8 +253,7 @@ class AuthUser(TableABC):
`ForgotPasswordId` = {"NULL" if self._forgot_password_id is None else f"'{self._forgot_password_id}'"}, `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}'"}, `OAuthId` = {"NULL" if self._oauth_id is None else f"'{self._oauth_id}'"},
`RefreshTokenExpiryTime` = '{self._refresh_token_expire_time.isoformat()}', `RefreshTokenExpiryTime` = '{self._refresh_token_expire_time.isoformat()}',
`AuthRole` = {self._auth_role_id.value}, `AuthRole` = {self._auth_role_id.value}
`LastModifiedAt` = '{self._modified_at}'
WHERE `AuthUsers`.`Id` = {self._auth_user_id}; WHERE `AuthUsers`.`Id` = {self._auth_user_id};
""" """
) )

View File

@ -68,12 +68,10 @@ class AuthUserUsersRelation(TableABC):
return str( return str(
f""" f"""
INSERT INTO `AuthUserUsersRelations` ( INSERT INTO `AuthUserUsersRelations` (
`AuthUserId`, `UserId`, `CreatedAt`, `LastModifiedAt` `AuthUserId`, `UserId`
) VALUES ( ) VALUES (
{self._auth_user.id}, {self._auth_user.id},
{self._user.id}, {self._user.id}
'{self._created_at}',
'{self._modified_at}'
); );
""" """
) )
@ -83,9 +81,8 @@ class AuthUserUsersRelation(TableABC):
return str( return str(
f""" f"""
UPDATE `AuthUserUsersRelations` UPDATE `AuthUserUsersRelations`
SET `AuthUserId` = '{self._auth_user.id}',, SET `AuthUserId` = '{self._auth_user.id}',
`UserId` = '{self._user.id}' `UserId` = '{self._user.id}'
`LastModifiedAt` = '{self._modified_at}'
WHERE `AuthUserId` = {self._auth_user.id} WHERE `AuthUserId` = {self._auth_user.id}
AND `UserId` = {self._user.id}; AND `UserId` = {self._user.id};
""" """

View File

@ -97,13 +97,11 @@ class AutoRole(TableABC):
return str( return str(
f""" f"""
INSERT INTO `AutoRoles` ( INSERT INTO `AutoRoles` (
`ServerId`, `DiscordChannelId`, `DiscordMessageId`, `CreatedAt`, `LastModifiedAt` `ServerId`, `DiscordChannelId`, `DiscordMessageId`
) VALUES ( ) VALUES (
{self._server.id}, {self._server.id},
{self._discord_channel_id}, {self._discord_channel_id},
{self._discord_message_id}, {self._discord_message_id}
'{self._created_at}',
'{self._modified_at}'
); );
""" """
) )
@ -115,8 +113,7 @@ class AutoRole(TableABC):
UPDATE `AutoRoles` UPDATE `AutoRoles`
SET `ServerId` = {self._server.id}, SET `ServerId` = {self._server.id},
`DiscordChannelId` = {self._discord_channel_id}, `DiscordChannelId` = {self._discord_channel_id},
`DiscordMessageId` = {self._discord_message_id}, `DiscordMessageId` = {self._discord_message_id}
`LastModifiedAt` = '{self._modified_at}'
WHERE `AutoRoleId` = {self._auto_role_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( return str(
f""" f"""
INSERT INTO `AutoRoleRules` ( INSERT INTO `AutoRoleRules` (
`AutoRoleId`, `DiscordEmojiName`, `DiscordRoleId`, `CreatedAt`, `LastModifiedAt` `AutoRoleId`, `DiscordEmojiName`, `DiscordRoleId`
) VALUES ( ) VALUES (
{self._auto_role.id}, {self._auto_role.id},
'{self._discord_emoji_name}', '{self._discord_emoji_name}',
{self._discord_role_id}, {self._discord_role_id}
'{self._created_at}',
'{self._modified_at}'
); );
""" """
) )
@ -105,8 +103,7 @@ class AutoRoleRule(TableABC):
UPDATE `AutoRoleRules` UPDATE `AutoRoleRules`
SET `AutoRoleId` = {self._auto_role.id}, SET `AutoRoleId` = {self._auto_role.id},
`DiscordEmojiName` = '{self._discord_emoji_name}', `DiscordEmojiName` = '{self._discord_emoji_name}',
`DiscordRoleId` = {self._discord_role_id}, `DiscordRoleId` = {self._discord_role_id}
`LastModifiedAt` = '{self._modified_at}'
WHERE `AutoRoleRuleId` = {self._auto_role_rule_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 @sent_message_count.setter
def sent_message_count(self, value: int): def sent_message_count(self, value: int):
self._modified_at = datetime.now().isoformat()
self._sent_message_count = value self._sent_message_count = value
@property @property
@ -62,7 +61,6 @@ class Client(TableABC):
@received_message_count.setter @received_message_count.setter
def received_message_count(self, value: int): def received_message_count(self, value: int):
self._modified_at = datetime.now().isoformat()
self._received_message_count = value self._received_message_count = value
@property @property
@ -71,7 +69,6 @@ class Client(TableABC):
@deleted_message_count.setter @deleted_message_count.setter
def deleted_message_count(self, value: int): def deleted_message_count(self, value: int):
self._modified_at = datetime.now().isoformat()
self._deleted_message_count = value self._deleted_message_count = value
@property @property
@ -80,7 +77,6 @@ class Client(TableABC):
@received_command_count.setter @received_command_count.setter
def received_command_count(self, value: int): def received_command_count(self, value: int):
self._modified_at = datetime.now().isoformat()
self._received_command_count = value self._received_command_count = value
@property @property
@ -89,7 +85,6 @@ class Client(TableABC):
@moved_users_count.setter @moved_users_count.setter
def moved_users_count(self, value: int): def moved_users_count(self, value: int):
self._modified_at = datetime.now().isoformat()
self._moved_users_count = value self._moved_users_count = value
@property @property
@ -152,9 +147,7 @@ class Client(TableABC):
`DeletedMessageCount`, `DeletedMessageCount`,
`ReceivedCommandsCount`, `ReceivedCommandsCount`,
`MovedUsersCount`, `MovedUsersCount`,
`ServerId`, `ServerId`
`CreatedAt`,
`LastModifiedAt`
) VALUES ( ) VALUES (
{self._discord_client_id}, {self._discord_client_id},
{self._sent_message_count}, {self._sent_message_count},
@ -162,9 +155,7 @@ class Client(TableABC):
{self._deleted_message_count}, {self._deleted_message_count},
{self._received_message_count}, {self._received_message_count},
{self._moved_users_count}, {self._moved_users_count},
{self._server.id}, {self._server.id}
'{self._created_at}',
'{self._modified_at}'
); );
""" """
) )
@ -178,8 +169,7 @@ class Client(TableABC):
`ReceivedMessageCount` = {self._received_message_count}, `ReceivedMessageCount` = {self._received_message_count},
`DeletedMessageCount` = {self._deleted_message_count}, `DeletedMessageCount` = {self._deleted_message_count},
`ReceivedCommandsCount` = {self._received_command_count}, `ReceivedCommandsCount` = {self._received_command_count},
`MovedUsersCount` = {self._moved_users_count}, `MovedUsersCount` = {self._moved_users_count}
`LastModifiedAt` = '{self._modified_at}'
WHERE `ClientId` = {self._client_id}; 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( return str(
f""" f"""
INSERT INTO `GameServers` ( INSERT INTO `GameServers` (
`Name`, `ServerId`, `ApiKeyId`, `CreatedAt`, `LastModifiedAt` `Name`, `ServerId`, `ApiKeyId`
) VALUES ( ) VALUES (
'{self._name}', '{self._name}',
{self._server.id}, {self._server.id},
{self._api_key.id}, {self._api_key.id}
'{self._created_at}',
'{self._modified_at}'
); );
""" """
) )
@ -118,7 +116,7 @@ class GameServer(TableABC):
return str( return str(
f""" f"""
UPDATE `GameServers` UPDATE `GameServers`
SET `LastModifiedAt` = '{self._modified_at}' SET `Name` = '{self._name}'
WHERE `Id` = {self._id}; WHERE `Id` = {self._id};
""" """
) )

View File

@ -57,11 +57,9 @@ class KnownUser(TableABC):
return str( return str(
f""" f"""
INSERT INTO `KnownUsers` ( INSERT INTO `KnownUsers` (
`DiscordId`, `CreatedAt`, `LastModifiedAt` `DiscordId`
) VALUES ( ) VALUES (
{self._discord_id}, {self._discord_id}
'{self._created_at}',
'{self._modified_at}'
); );
""" """
) )

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 @name.setter
def name(self, value: str): def name(self, value: str):
self._modified_at = datetime.now().isoformat()
self._name = value self._name = value
@property @property
@ -48,7 +47,6 @@ class Level(TableABC):
@color.setter @color.setter
def color(self, value: str): def color(self, value: str):
self._modified_at = datetime.now().isoformat()
self._color = value self._color = value
@property @property
@ -57,7 +55,6 @@ class Level(TableABC):
@min_xp.setter @min_xp.setter
def min_xp(self, value: int): def min_xp(self, value: int):
self._modified_at = datetime.now().isoformat()
self._min_xp = value self._min_xp = value
@property @property
@ -66,7 +63,6 @@ class Level(TableABC):
@permissions.setter @permissions.setter
def permissions(self, value: int): def permissions(self, value: int):
self._modified_at = datetime.now().isoformat()
self._permissions = value self._permissions = value
@property @property
@ -75,7 +71,6 @@ class Level(TableABC):
@server.setter @server.setter
def server(self, value: Server): def server(self, value: Server):
self._modified_at = datetime.now().isoformat()
self._server = value self._server = value
@staticmethod @staticmethod
@ -109,15 +104,13 @@ class Level(TableABC):
return str( return str(
f""" f"""
INSERT INTO `Levels` ( INSERT INTO `Levels` (
`Name`, `Color`, `MinXp`, `PermissionInt`, `ServerId`, `CreatedAt`, `LastModifiedAt` `Name`, `Color`, `MinXp`, `PermissionInt`, `ServerId`
) VALUES ( ) VALUES (
'{self._name}', '{self._name}',
'{self._color}', '{self._color}',
{self._min_xp}, {self._min_xp},
{self._permissions}, {self._permissions},
{self._server.id}, {self._server.id}
'{self._created_at}',
'{self._modified_at}'
); );
""" """
) )
@ -130,8 +123,7 @@ class Level(TableABC):
SET `Name` = '{self._name}', SET `Name` = '{self._name}',
`Color` = '{self._color}', `Color` = '{self._color}',
`MinXp` = {self._min_xp}, `MinXp` = {self._min_xp},
`PermissionInt` = {self._permissions}, `PermissionInt` = {self._permissions}
`LastModifiedAt` = '{self._modified_at}'
WHERE `Id` = {self._id}; 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( return str(
f""" f"""
INSERT INTO `Servers` ( INSERT INTO `Servers` (
`DiscordServerId`, `CreatedAt`, `LastModifiedAt` `DiscordServerId`
) VALUES ( ) VALUES (
{self._discord_server_id}, {self._discord_server_id}
'{self._created_at}',
'{self._modified_at}'
); );
""" """
) )
@ -85,8 +83,7 @@ class Server(TableABC):
return str( return str(
f""" f"""
UPDATE `Servers` UPDATE `Servers`
SET `DiscordServerId` = {self._discord_server_id}, SET `DiscordServerId` = {self._discord_server_id}
`LastModifiedAt` = '{self._modified_at}'
WHERE `ServerId` = {self._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

View File

@ -57,7 +57,6 @@ class User(TableABC):
@xp.setter @xp.setter
def xp(self, value: int): def xp(self, value: int):
self._modified_at = datetime.now().isoformat()
self._xp = value self._xp = value
@property @property
@ -152,13 +151,11 @@ class User(TableABC):
return str( return str(
f""" f"""
INSERT INTO `Users` ( INSERT INTO `Users` (
`DiscordId`, `XP`, `ServerId`, `CreatedAt`, `LastModifiedAt` `DiscordId`, `XP`, `ServerId`
) VALUES ( ) VALUES (
{self._discord_id}, {self._discord_id},
{self._xp}, {self._xp},
{self._server.id}, {self._server.id}
'{self._created_at}',
'{self._modified_at}'
); );
""" """
) )
@ -168,8 +165,7 @@ class User(TableABC):
return str( return str(
f""" f"""
UPDATE `Users` UPDATE `Users`
SET `XP` = {self._xp}, SET `XP` = {self._xp}
`LastModifiedAt` = '{self._modified_at}'
WHERE `UserId` = {self._user_id}; WHERE `UserId` = {self._user_id};
""" """
) )

View File

@ -91,26 +91,18 @@ class UserGameIdent(TableABC):
return str( return str(
f""" f"""
INSERT INTO `UserGameIdents` ( INSERT INTO `UserGameIdents` (
`UserId`, `GameServerId`, `Ident`, `CreatedAt`, `LastModifiedAt` `UserId`, `GameServerId`, `Ident`
) VALUES ( ) VALUES (
{self._user.id}, {self._user.id},
'{self._game_server.id}', '{self._game_server.id}',
'{self._ident}', '{self._ident}'
'{self._created_at}',
'{self._modified_at}'
); );
""" """
) )
@property @property
def udpate_string(self) -> str: def udpate_string(self) -> str:
return str( return ""
f"""
UPDATE `UserGameIdents`
SET `LastModifiedAt` = '{self._modified_at}'
WHERE `Id` = {self._id};
"""
)
@property @property
def delete_string(self) -> str: 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( return str(
f""" f"""
INSERT INTO `UserJoinedGameServer` ( INSERT INTO `UserJoinedGameServer` (
`UserId`, `GameServerId`, `JoinedOn`, `LeavedOn`, `CreatedAt`, `LastModifiedAt` `UserId`, `GameServerId`, `JoinedOn`, `LeavedOn`
) VALUES ( ) VALUES (
{self._user.id}, {self._user.id},
'{self._game_server.id}', '{self._game_server.id}',
'{self._joined_on}', '{self._joined_on}',
{"NULL" if self._leaved_on is None else f"'{self._leaved_on}'"}, {"NULL" if self._leaved_on is None else f"'{self._leaved_on}'"}
'{self._created_at}',
'{self._modified_at}'
); );
""" """
) )
@ -121,8 +119,7 @@ class UserJoinedGameServer(TableABC):
return str( return str(
f""" f"""
UPDATE `UserJoinedGameServer` UPDATE `UserJoinedGameServer`
SET `LeavedOn` = {"NULL" if self._leaved_on is None else f"'{self._leaved_on}'"}, SET `LeavedOn` = {"NULL" if self._leaved_on is None else f"'{self._leaved_on}'"}
`LastModifiedAt` = '{self._modified_at}'
WHERE `Id` = {self._id}; 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( return str(
f""" f"""
INSERT INTO `UserJoinedServers` ( INSERT INTO `UserJoinedServers` (
`UserId`, `JoinedOn`, `LeavedOn`, `CreatedAt`, `LastModifiedAt` `UserId`, `JoinedOn`, `LeavedOn`
) VALUES ( ) VALUES (
{self._user.id}, {self._user.id},
'{self._joined_on}', '{self._joined_on}',
{"NULL" if self._leaved_on is None else f"'{self._leaved_on}'"}, {"NULL" if self._leaved_on is None else f"'{self._leaved_on}'"}
'{self._created_at}',
'{self._modified_at}'
); );
""" """
) )
@ -116,8 +114,7 @@ class UserJoinedServer(TableABC):
return str( return str(
f""" f"""
UPDATE `UserJoinedServers` UPDATE `UserJoinedServers`
SET `LeavedOn` = {"NULL" if self._leaved_on is None else f"'{self._leaved_on}'"}, SET `LeavedOn` = {"NULL" if self._leaved_on is None else f"'{self._leaved_on}'"}
`LastModifiedAt` = '{self._modified_at}'
WHERE `UserId` = {self._user.id}; 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( return str(
f""" f"""
INSERT INTO `UserJoinedVoiceChannel` ( INSERT INTO `UserJoinedVoiceChannel` (
`UserId`, `DiscordChannelId`, `JoinedOn`, `LeavedOn`, `CreatedAt`, `LastModifiedAt` `UserId`, `DiscordChannelId`, `JoinedOn`, `LeavedOn`
) VALUES ( ) VALUES (
{self._user.id}, {self._user.id},
{self._channel_id}, {self._channel_id},
'{self._joined_on}', '{self._joined_on}',
{"NULL" if self._leaved_on is None else f"'{self._leaved_on}'"}, {"NULL" if self._leaved_on is None else f"'{self._leaved_on}'"}
'{self._created_at}',
'{self._modified_at}'
); );
""" """
) )
@ -127,8 +125,7 @@ class UserJoinedVoiceChannel(TableABC):
return str( return str(
f""" f"""
UPDATE `UserJoinedVoiceChannel` UPDATE `UserJoinedVoiceChannel`
SET `LeavedOn` = {"NULL" if self._leaved_on is None else f"'{self._leaved_on}'"}, SET `LeavedOn` = {"NULL" if self._leaved_on is None else f"'{self._leaved_on}'"}
`LastModifiedAt` = '{self._modified_at}'
WHERE `JoinId` = {self._join_id}; 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 @xp_count.setter
def xp_count(self, value: int): def xp_count(self, value: int):
self._modified_at = datetime.now().isoformat()
self._xp_count = value self._xp_count = value
@property @property
@ -95,14 +94,12 @@ class UserMessageCountPerHour(TableABC):
return str( return str(
f""" f"""
INSERT INTO `UserMessageCountPerHour` ( INSERT INTO `UserMessageCountPerHour` (
`UserId`, `Date`, `Hour`, `XPCount`, `CreatedAt`, `LastModifiedAt` `UserId`, `Date`, `Hour`, `XPCount`
) VALUES ( ) VALUES (
{self._user.id}, {self._user.id},
'{self._date}', '{self._date}',
{self._hour}, {self._hour},
{self._xp_count}, {self._xp_count}
'{self._created_at}',
'{self._modified_at}'
); );
""" """
) )
@ -112,8 +109,7 @@ class UserMessageCountPerHour(TableABC):
return str( return str(
f""" f"""
UPDATE `UserMessageCountPerHour` UPDATE `UserMessageCountPerHour`
SET `XPCount` = '{self._xp_count}', SET `XPCount` = '{self._xp_count}'
`LastModifiedAt` = '{self._modified_at}'
WHERE `Id` = {self._id}; WHERE `Id` = {self._id};
""" """
) )

View File

@ -73,13 +73,11 @@ class UserWarnings(TableABC):
return str( return str(
f""" f"""
INSERT INTO `UserWarnings` ( INSERT INTO `UserWarnings` (
`Description`, `UserId`, {"" if self._author is None else f"`Author`,"} `CreatedAt`, `LastModifiedAt` `Description`, `UserId`, `Author`
) VALUES ( ) VALUES (
'{self._description}', '{self._description}',
{self._user.id}, {self._user.id},
{"" if self._author is None else f"{self._author.id},"} {"NULL" if self._author is None else f"{self._author.id}"}
'{self._created_at}',
'{self._modified_at}'
); );
""" """
) )
@ -89,8 +87,7 @@ class UserWarnings(TableABC):
return str( return str(
f""" f"""
UPDATE `UserWarnings` UPDATE `UserWarnings`
SET `Description` = '{self._description}', SET `Description` = '{self._description}'
`LastModifiedAt` = '{self._modified_at}'
WHERE `Id` = {self._id}; WHERE `Id` = {self._id};
""" """
) )

View File

@ -1,5 +1,3 @@
from typing import Type
from cpl_core.database.context import DatabaseContextABC from cpl_core.database.context import DatabaseContextABC
from cpl_core.dependency_injection import ServiceProviderABC from cpl_core.dependency_injection import ServiceProviderABC
from cpl_query.extension import List from cpl_query.extension import List
@ -22,7 +20,9 @@ class MigrationService:
self._db = db self._db = db
self._cursor = db.cursor 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): def migrate(self):
self._logger.info(__name__, f"Running Migrations") 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.level_mutation import LevelMutation
from bot_graphql.mutations.user_joined_game_server_mutation import UserJoinedGameServerMutation from bot_graphql.mutations.user_joined_game_server_mutation import UserJoinedGameServerMutation
from bot_graphql.mutations.user_mutation import UserMutation 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_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.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.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.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.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.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_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_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_joined_voice_channel_query import UserJoinedVoiceChannelQuery
from bot_graphql.queries.user_query import UserQuery from bot_graphql.queries.user_query import UserQuery
from bot_graphql.query import Query from bot_graphql.query import Query
@ -52,15 +62,25 @@ class GraphQLModule(ModuleABC):
services.add_singleton(Mutation) services.add_singleton(Mutation)
# queries # queries
services.add_transient(QueryABC, AutoRoleHistoryQuery)
services.add_transient(QueryABC, AutoRoleQuery) services.add_transient(QueryABC, AutoRoleQuery)
services.add_transient(QueryABC, AutoRoleRuleHistoryQuery)
services.add_transient(QueryABC, AutoRoleRuleQuery) services.add_transient(QueryABC, AutoRoleRuleQuery)
services.add_transient(QueryABC, ClientHistoryQuery)
services.add_transient(QueryABC, ClientQuery) services.add_transient(QueryABC, ClientQuery)
services.add_transient(QueryABC, KnownUserHistoryQuery)
services.add_transient(QueryABC, KnownUserQuery) services.add_transient(QueryABC, KnownUserQuery)
services.add_transient(QueryABC, LevelHistoryQuery)
services.add_transient(QueryABC, LevelQuery) services.add_transient(QueryABC, LevelQuery)
services.add_transient(QueryABC, ServerHistoryQuery)
services.add_transient(QueryABC, ServerQuery) services.add_transient(QueryABC, ServerQuery)
services.add_transient(QueryABC, UserHistoryQuery)
services.add_transient(QueryABC, UserQuery) services.add_transient(QueryABC, UserQuery)
services.add_transient(QueryABC, UserJoinedServerHistoryQuery)
services.add_transient(QueryABC, UserJoinedServerQuery) services.add_transient(QueryABC, UserJoinedServerQuery)
services.add_transient(QueryABC, UserJoinedVoiceChannelHistoryQuery)
services.add_transient(QueryABC, UserJoinedVoiceChannelQuery) services.add_transient(QueryABC, UserJoinedVoiceChannelQuery)
services.add_transient(QueryABC, UserJoinedGameServerHistoryQuery)
services.add_transient(QueryABC, UserJoinedGameServerQuery) services.add_transient(QueryABC, UserJoinedGameServerQuery)
# filters # filters

View File

@ -1,4 +1,4 @@
type AutoRole implements TableQuery { type AutoRole implements TableWithHistoryQuery {
id: ID id: ID
channelId: String channelId: String
channelName: String channelName: String
@ -11,6 +11,20 @@ type AutoRole implements TableQuery {
createdAt: String createdAt: String
modifiedAt: 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 { input AutoRoleFilter {

View File

@ -1,4 +1,4 @@
type AutoRoleRule implements TableQuery { type AutoRoleRule implements TableWithHistoryQuery {
id: ID id: ID
emojiName: String emojiName: String
roleId: String roleId: String
@ -8,6 +8,20 @@ type AutoRoleRule implements TableQuery {
createdAt: String createdAt: String
modifiedAt: 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 { input AutoRoleRuleFilter {

View File

@ -3,6 +3,18 @@ interface TableQuery {
modifiedAt: String modifiedAt: String
} }
interface TableWithHistoryQuery {
createdAt: String
modifiedAt: String
history: [HistoryTableQuery]
}
interface HistoryTableQuery {
deleted: Boolean
dateFrom: String
dateTo: String
}
input Page { input Page {
pageIndex: Int pageIndex: Int
pageSize: Int pageSize: Int

View File

@ -12,6 +12,25 @@ type Client implements TableQuery {
createdAt: String createdAt: String
modifiedAt: 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 { input ClientFilter {

View File

@ -1,7 +1,18 @@
type KnownUser implements TableQuery { type KnownUser implements TableWithHistoryQuery {
id: ID id: ID
discordId: String discordId: String
createdAt: String createdAt: String
modifiedAt: 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 id: ID
name: String name: String
color: String color: String
@ -9,6 +9,22 @@ type Level implements TableQuery {
createdAt: String createdAt: String
modifiedAt: 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 { input LevelFilter {

View File

@ -1,4 +1,4 @@
type Server implements TableQuery { type Server implements TableWithHistoryQuery {
id: ID id: ID
discordId: String discordId: String
name: String name: String
@ -18,6 +18,19 @@ type Server implements TableQuery {
createdAt: String createdAt: String
modifiedAt: 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 { input ServerFilter {

View File

@ -1,4 +1,4 @@
type User implements TableQuery { type User implements TableWithHistoryQuery {
id: ID id: ID
discordId: String discordId: String
name: String name: String
@ -20,6 +20,20 @@ type User implements TableQuery {
createdAt: String createdAt: String
modifiedAt: 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 { input UserFilter {

View File

@ -1,4 +1,4 @@
type UserJoinedGameServer implements TableQuery { type UserJoinedGameServer implements TableWithHistoryQuery {
id: ID id: ID
gameServer: String gameServer: String
user: User user: User
@ -8,6 +8,21 @@ type UserJoinedGameServer implements TableQuery {
createdAt: String createdAt: String
modifiedAt: 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 { input UserJoinedGameServerFilter {

View File

@ -1,4 +1,4 @@
type UserJoinedServer implements TableQuery { type UserJoinedServer implements TableWithHistoryQuery {
id: ID id: ID
user: User user: User
joinedOn: String joinedOn: String
@ -6,6 +6,19 @@ type UserJoinedServer implements TableQuery {
createdAt: String createdAt: String
modifiedAt: 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 { input UserJoinedServerFilter {

View File

@ -1,4 +1,4 @@
type UserJoinedVoiceChannel implements TableQuery { type UserJoinedVoiceChannel implements TableWithHistoryQuery {
id: ID id: ID
channelId: String channelId: String
channelName: String channelName: String
@ -9,6 +9,22 @@ type UserJoinedVoiceChannel implements TableQuery {
createdAt: String createdAt: String
modifiedAt: 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 { 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 cpl_discord.service import DiscordBotServiceABC
from bot_data.abc.auto_role_repository_abc import AutoRoleRepositoryABC from bot_data.abc.auto_role_repository_abc import AutoRoleRepositoryABC
from bot_data.abc.server_repository_abc import ServerRepositoryABC from bot_data.abc.server_repository_abc import ServerRepositoryABC
from bot_data.model.auto_role import AutoRole 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.auto_role_filter import AutoRoleFilter
from bot_graphql.filter.server_filter import ServerFilter from bot_graphql.filter.server_filter import ServerFilter
class AutoRoleQuery(DataQueryABC): class AutoRoleQuery(DataQueryWithHistoryABC):
def __init__( def __init__(
self, self,
bot: DiscordBotServiceABC, bot: DiscordBotServiceABC,
auto_role_rules: AutoRoleRepositoryABC, auto_role_rules: AutoRoleRepositoryABC,
servers: ServerRepositoryABC, servers: ServerRepositoryABC,
db: DatabaseContextABC,
): ):
DataQueryABC.__init__(self, "AutoRole") DataQueryWithHistoryABC.__init__(self, "AutoRole", "AutoRolesHistory", AutoRoleHistory, db)
self._bot = bot self._bot = bot
self._auto_role_rules = auto_role_rules 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 cpl_discord.service import DiscordBotServiceABC
from bot_data.abc.auto_role_repository_abc import AutoRoleRepositoryABC from bot_data.abc.auto_role_repository_abc import AutoRoleRepositoryABC
from bot_data.model.auto_role_rule import AutoRoleRule 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): class AutoRoleRuleQuery(DataQueryWithHistoryABC):
def __init__( def __init__(self, bot: DiscordBotServiceABC, auto_roles: AutoRoleRepositoryABC, db: DatabaseContextABC):
self, DataQueryWithHistoryABC.__init__(self, "AutoRoleRule", "AutoRoleRulesHistory", AutoRoleRuleHistory, db)
bot: DiscordBotServiceABC,
auto_roles: AutoRoleRepositoryABC,
):
DataQueryABC.__init__(self, "AutoRoleRule")
self._bot = bot self._bot = bot
self._auto_roles = auto_roles 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 cpl_discord.service import DiscordBotServiceABC
from bot_data.model.client import Client 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): class ClientQuery(DataQueryWithHistoryABC):
def __init__( def __init__(self, bot: DiscordBotServiceABC, db: DatabaseContextABC):
self, DataQueryWithHistoryABC.__init__(self, "Client", "ClientsHistory", ClientHistory, db)
bot: DiscordBotServiceABC,
):
DataQueryABC.__init__(self, "Client")
self._bot = bot 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_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): class KnownUserQuery(DataQueryWithHistoryABC):
def __init__(self): def __init__(self, db: DatabaseContextABC):
DataQueryABC.__init__(self, "KnownUser") DataQueryWithHistoryABC.__init__(self, "KnownUser", "KnownUsersHistory", KnownUserHistory, db)
self.set_field("id", self.resolve_id) self.set_field("id", self.resolve_id)
self.set_field("discordId", self.resolve_discord_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_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): class LevelQuery(DataQueryWithHistoryABC):
def __init__(self): def __init__(self, db: DatabaseContextABC):
DataQueryABC.__init__(self, "Level") DataQueryWithHistoryABC.__init__(self, "Level", "LevelsHistory", LevelHistory, db)
self.set_field("id", self.resolve_id) self.set_field("id", self.resolve_id)
self.set_field("name", self.resolve_name) 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 cpl_discord.service import DiscordBotServiceABC
from bot_data.abc.auto_role_repository_abc import AutoRoleRepositoryABC 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_joined_voice_channel_repository_abc import UserJoinedVoiceChannelRepositoryABC
from bot_data.abc.user_repository_abc import UserRepositoryABC from bot_data.abc.user_repository_abc import UserRepositoryABC
from bot_data.model.server import Server 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_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.auto_role_filter import AutoRoleFilter
from bot_graphql.filter.client_filter import ClientFilter from bot_graphql.filter.client_filter import ClientFilter
from bot_graphql.filter.level_filter import LevelFilter from bot_graphql.filter.level_filter import LevelFilter
from bot_graphql.filter.user_filter import UserFilter from bot_graphql.filter.user_filter import UserFilter
class ServerQuery(DataQueryABC): class ServerQuery(DataQueryWithHistoryABC):
def __init__( def __init__(
self, self,
bot: DiscordBotServiceABC, bot: DiscordBotServiceABC,
db: DatabaseContextABC,
auto_roles: AutoRoleRepositoryABC, auto_roles: AutoRoleRepositoryABC,
clients: ClientRepositoryABC, clients: ClientRepositoryABC,
levels: LevelRepositoryABC, levels: LevelRepositoryABC,
@ -25,7 +29,7 @@ class ServerQuery(DataQueryABC):
ujs: UserJoinedServerRepositoryABC, ujs: UserJoinedServerRepositoryABC,
ujvs: UserJoinedVoiceChannelRepositoryABC, ujvs: UserJoinedVoiceChannelRepositoryABC,
): ):
DataQueryABC.__init__(self, "Server") DataQueryWithHistoryABC.__init__(self, "Server", "ServersHistory", ServerHistory, db)
self._bot = bot self._bot = bot
self._auto_roles = auto_roles 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 cpl_discord.service import DiscordBotServiceABC
from bot_data.model.user_joined_game_server import UserJoinedGameServer 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): class UserJoinedGameServerQuery(DataQueryWithHistoryABC):
def __init__(self, bot: DiscordBotServiceABC): def __init__(self, bot: DiscordBotServiceABC, db: DatabaseContextABC):
DataQueryABC.__init__(self, "UserJoinedGameServer") DataQueryWithHistoryABC.__init__(
self, "UserJoinedGameServer", "UserJoinedGameServersHistory", UserJoinedGameServerHistory, db
)
self._bot = bot 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_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): class UserJoinedServerQuery(DataQueryWithHistoryABC):
def __init__(self): def __init__(self, db: DatabaseContextABC):
DataQueryABC.__init__(self, "UserJoinedServer") DataQueryWithHistoryABC.__init__(
self, "UserJoinedServer", "UserJoinedServersHistory", UserJoinedServerHistory, db
)
self.set_field("id", self.resolve_id) self.set_field("id", self.resolve_id)
self.set_field("user", self.resolve_user) 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 cpl_discord.service import DiscordBotServiceABC
from bot_data.model.user_joined_voice_channel import UserJoinedVoiceChannel 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): class UserJoinedVoiceChannelQuery(DataQueryWithHistoryABC):
def __init__(self, bot: DiscordBotServiceABC): def __init__(self, bot: DiscordBotServiceABC, db: DatabaseContextABC):
DataQueryABC.__init__(self, "UserJoinedVoiceChannel") DataQueryWithHistoryABC.__init__(
self, "UserJoinedVoiceChannel", "UserJoinedVoiceChannelsHistory", UserJoinedVoiceChannelHistory, db
)
self._bot = bot self._bot = bot

View File

@ -1,3 +1,4 @@
from cpl_core.database.context import DatabaseContextABC
from cpl_discord.service import DiscordBotServiceABC from cpl_discord.service import DiscordBotServiceABC
from bot_core.abc.client_utils_abc import ClientUtilsABC 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_server_repository_abc import UserJoinedServerRepositoryABC
from bot_data.abc.user_joined_voice_channel_repository_abc import UserJoinedVoiceChannelRepositoryABC from bot_data.abc.user_joined_voice_channel_repository_abc import UserJoinedVoiceChannelRepositoryABC
from bot_data.model.user import User 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_game_server_filter import UserJoinedGameServerFilter
from bot_graphql.filter.user_joined_server_filter import UserJoinedServerFilter from bot_graphql.filter.user_joined_server_filter import UserJoinedServerFilter
from bot_graphql.filter.user_joined_voice_channel_filter import UserJoinedVoiceChannelFilter 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 from modules.permission.abc.permission_service_abc import PermissionServiceABC
class UserQuery(DataQueryABC): class UserQuery(DataQueryWithHistoryABC):
def __init__( def __init__(
self, self,
bot: DiscordBotServiceABC, bot: DiscordBotServiceABC,
db: DatabaseContextABC,
levels: LevelService, levels: LevelService,
client_utils: ClientUtilsABC, client_utils: ClientUtilsABC,
ujs: UserJoinedServerRepositoryABC, ujs: UserJoinedServerRepositoryABC,
@ -24,7 +27,7 @@ class UserQuery(DataQueryABC):
user_joined_game_server: UserJoinedGameServerRepositoryABC, user_joined_game_server: UserJoinedGameServerRepositoryABC,
permissions: PermissionServiceABC, permissions: PermissionServiceABC,
): ):
DataQueryABC.__init__(self, "User") DataQueryWithHistoryABC.__init__(self, "User", "UsersHistory", UserHistory, db)
self._bot = bot self._bot = bot
self._levels = levels self._levels = levels

View File

@ -1,6 +1,6 @@
{ {
"name": "kdb-web", "name": "kdb-web",
"version": "1.0.dev247", "version": "1.0.dev246",
"scripts": { "scripts": {
"ng": "ng", "ng": "ng",
"update-version": "ts-node-esm update-version.ts", "update-version": "ts-node-esm update-version.ts",

View File

@ -2,3 +2,16 @@ export interface Data {
createdAt?: string; createdAt?: string;
modifiedAt?: 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 { Level, LevelFilter } from "./level.model";
import { Server, ServerFilter } from "./server.model"; import { Server, ServerFilter } from "./server.model";
import { UserJoinedServer } from "./user_joined_server.model"; import { UserJoinedServer } from "./user_joined_server.model";
import { UserJoinedVoiceChannel } from "./user_joined_voice_channel.model"; import { UserJoinedVoiceChannel } from "./user_joined_voice_channel.model";
import { UserJoinedGameServer } from "./user_joined_game_server.model"; import { UserJoinedGameServer } from "./user_joined_game_server.model";
export interface User extends Data { export interface User extends DataWithHistory {
id?: number; id?: number;
discordId?: number; discordId?: number;
name?: string; name?: string;
@ -23,6 +23,17 @@ export interface User extends Data {
userJoinedGameServerCount?: number; userJoinedGameServerCount?: number;
userJoinedGameServers?: UserJoinedGameServer[]; userJoinedGameServers?: UserJoinedGameServer[];
// history?: UserHistory[];
}
export interface UserHistory extends History {
id?: number;
discordId?: number;
xp?: number;
level?: number;
server?: number;
leftServer?: boolean;
} }
export interface UserFilter { export interface UserFilter {

View File

@ -62,6 +62,18 @@ export class Queries {
} }
createdAt createdAt
modifiedAt modifiedAt
history {
id
name
color
minXp
permissions
server
deleted
dateFrom
dateTo
}
} }
} }
} }
@ -115,6 +127,16 @@ export class Queries {
createdAt createdAt
modifiedAt modifiedAt
history {
id
discordId
xp
server
deleted
dateFrom
dateTo
}
} }
} }
} }
@ -137,6 +159,16 @@ export class Queries {
createdAt createdAt
modifiedAt modifiedAt
history {
id
channelId
messageId
server
deleted
dateFrom
dateTo
}
} }
} }
} }
@ -159,6 +191,16 @@ export class Queries {
createdAt createdAt
modifiedAt 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();
});
});

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

View File

@ -1,28 +1,29 @@
import { CommonModule } from '@angular/common'; import { CommonModule } from "@angular/common";
import { HttpClientModule } from '@angular/common/http'; import { HttpClientModule } from "@angular/common/http";
import { NgModule } from '@angular/core'; import { NgModule } from "@angular/core";
import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { FormsModule, ReactiveFormsModule } from "@angular/forms";
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from "@ngx-translate/core";
import { ButtonModule } from 'primeng/button'; import { ButtonModule } from "primeng/button";
import { CheckboxModule } from 'primeng/checkbox'; import { CheckboxModule } from "primeng/checkbox";
import { ConfirmDialogModule } from 'primeng/confirmdialog'; import { ConfirmDialogModule } from "primeng/confirmdialog";
import { DialogModule } from 'primeng/dialog'; import { DialogModule } from "primeng/dialog";
import { DropdownModule } from 'primeng/dropdown'; import { DropdownModule } from "primeng/dropdown";
import { DynamicDialogModule } from 'primeng/dynamicdialog'; import { DynamicDialogModule } from "primeng/dynamicdialog";
import { InputTextModule } from 'primeng/inputtext'; import { InputTextModule } from "primeng/inputtext";
import { MenuModule } from 'primeng/menu'; import { MenuModule } from "primeng/menu";
import { PasswordModule } from 'primeng/password'; import { PasswordModule } from "primeng/password";
import { ProgressSpinnerModule } from 'primeng/progressspinner'; import { ProgressSpinnerModule } from "primeng/progressspinner";
import { TableModule } from 'primeng/table'; import { TableModule } from "primeng/table";
import { ToastModule } from 'primeng/toast'; import { ToastModule } from "primeng/toast";
import { AuthRolePipe } from './pipes/auth-role.pipe'; import { AuthRolePipe } from "./pipes/auth-role.pipe";
import { IpAddressPipe } from './pipes/ip-address.pipe'; import { IpAddressPipe } from "./pipes/ip-address.pipe";
import { BoolPipe } from './pipes/bool.pipe'; import { BoolPipe } from "./pipes/bool.pipe";
import { PanelMenuModule } from 'primeng/panelmenu'; import { PanelMenuModule } from "primeng/panelmenu";
import { PanelModule } from "primeng/panel"; import { PanelModule } from "primeng/panel";
import { InputNumberModule } from 'primeng/inputnumber'; import { InputNumberModule } from "primeng/inputnumber";
import { ImageModule } from "primeng/image"; import { ImageModule } from "primeng/image";
import { SidebarModule } from "primeng/sidebar";
import { HistoryBtnComponent } from './components/history-btn/history-btn.component';
@NgModule({ @NgModule({
@ -30,6 +31,7 @@ import { ImageModule } from "primeng/image";
AuthRolePipe, AuthRolePipe,
IpAddressPipe, IpAddressPipe,
BoolPipe, BoolPipe,
HistoryBtnComponent,
], ],
imports: [ imports: [
CommonModule, CommonModule,
@ -52,7 +54,8 @@ import { ImageModule } from "primeng/image";
PanelMenuModule, PanelMenuModule,
PanelModule, PanelModule,
InputNumberModule, InputNumberModule,
ImageModule ImageModule,
SidebarModule,
], ],
exports: [ exports: [
ButtonModule, ButtonModule,
@ -77,7 +80,9 @@ import { ImageModule } from "primeng/image";
IpAddressPipe, IpAddressPipe,
BoolPipe, BoolPipe,
InputNumberModule, InputNumberModule,
ImageModule ImageModule,
SidebarModule,
HistoryBtnComponent
] ]
}) })
export class SharedModule { } export class SharedModule { }

View File

@ -160,6 +160,7 @@
<td> <td>
<div class="btn-wrapper"> <div class="btn-wrapper">
<app-history-btn [history]="autoRoleRule.history" translationKey="view.server.auto_roles.rules.header"></app-history-btn>
<button *ngIf="!editing" pButton pInitEditableRow class="btn icon-btn" icon="pi pi-pencil" (click)="onRowEditInit(dt, autoRoleRule, ri)"></button> <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" <button *ngIf="!editing" pButton class="btn icon-btn danger-icon-btn" icon="pi pi-trash"
(click)="deleteAutoRoleRule(autoRoleRule)"></button> (click)="deleteAutoRoleRule(autoRoleRule)"></button>

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