2025-04-27 01:54:46 +00:00
|
|
|
using MySqlConnector;
|
2022-08-30 17:00:58 +02:00
|
|
|
|
2025-04-27 01:54:46 +00:00
|
|
|
namespace SharpChat.MariaDB;
|
2022-08-30 17:00:58 +02:00
|
|
|
|
2025-04-27 01:54:46 +00:00
|
|
|
public partial class MariaDBMessageStorage {
|
2025-04-27 00:31:33 +00:00
|
|
|
private async Task DoMigration(string name, Func<Task> action) {
|
|
|
|
bool done = await RunQueryValue<long>(
|
2025-04-26 23:15:54 +00:00
|
|
|
"SELECT COUNT(*) FROM `sqc_migrations` WHERE `migration_name` = @name",
|
|
|
|
new MySqlParameter("name", name)
|
|
|
|
) > 0;
|
|
|
|
if(!done) {
|
|
|
|
Logger.Write($"Running migration '{name}'...");
|
2025-04-27 00:31:33 +00:00
|
|
|
await action();
|
|
|
|
await RunCommand(
|
2025-04-26 23:15:54 +00:00
|
|
|
"INSERT INTO `sqc_migrations` (`migration_name`) VALUES (@name)",
|
|
|
|
new MySqlParameter("name", name)
|
2022-08-30 17:00:58 +02:00
|
|
|
);
|
2025-04-15 20:17:15 +00:00
|
|
|
}
|
2025-04-26 23:15:54 +00:00
|
|
|
}
|
2025-04-15 20:17:15 +00:00
|
|
|
|
2025-04-27 00:31:33 +00:00
|
|
|
public async Task RunMigrations() {
|
|
|
|
await RunCommand(
|
2025-04-26 23:15:54 +00:00
|
|
|
"CREATE TABLE IF NOT EXISTS `sqc_migrations` ("
|
|
|
|
+ "`migration_name` VARCHAR(255) NOT NULL,"
|
|
|
|
+ "`migration_completed` TIMESTAMP NOT NULL DEFAULT current_timestamp(),"
|
|
|
|
+ "UNIQUE INDEX `migration_name` (`migration_name`),"
|
|
|
|
+ "INDEX `migration_completed` (`migration_completed`)"
|
|
|
|
+ ") COLLATE='utf8mb4_unicode_ci' ENGINE=InnoDB;"
|
|
|
|
);
|
2025-04-14 21:57:24 +00:00
|
|
|
|
2025-04-27 00:31:33 +00:00
|
|
|
await DoMigration("create_events_table", CreateEventsTable);
|
|
|
|
await DoMigration("allow_null_target", AllowNullTarget);
|
|
|
|
await DoMigration("event_data_as_medium_blob", EventDataAsMediumBlob);
|
|
|
|
await DoMigration("event_user_and_nick_name_to_1000", EventUserAndNickNameTo1000);
|
2025-04-27 18:45:32 +00:00
|
|
|
await DoMigration("no_more_flags_field", NoMoreFlagsField);
|
|
|
|
await DoMigration("update_event_type_names", UpdateEventTypeNames);
|
|
|
|
}
|
|
|
|
|
|
|
|
private async Task UpdateEventTypeNames() {
|
|
|
|
await RunCommand(@"UPDATE sqc_events SET event_type = ""msg:add"" WHERE event_type = ""SharpChat.Events.ChatMessage""");
|
|
|
|
await RunCommand(@"UPDATE sqc_events SET event_type = ""user:connect"" WHERE event_type = ""SharpChat.Events.UserConnectEvent""");
|
|
|
|
await RunCommand(@"UPDATE sqc_events SET event_type = ""user:disconnect"" WHERE event_type = ""SharpChat.Events.UserDisconnectEvent""");
|
|
|
|
await RunCommand(@"UPDATE sqc_events SET event_type = ""chan:join"" WHERE event_type = ""SharpChat.Events.UserChannelJoinEvent""");
|
|
|
|
await RunCommand(@"UPDATE sqc_events SET event_type = ""chan:leave"" WHERE event_type = ""SharpChat.Events.UserChannelLeaveEvent""");
|
|
|
|
}
|
|
|
|
|
|
|
|
private async Task NoMoreFlagsField() {
|
|
|
|
// MessageFlags.Action is just a field in the data object
|
|
|
|
await RunCommand("UPDATE sqc_events SET event_data = JSON_MERGE_PATCH(event_data, JSON_OBJECT('act', true)) WHERE event_flags & 1");
|
|
|
|
|
|
|
|
// MessageFlags.Broadcast can be implied by just having a NULL as the channel name
|
|
|
|
await RunCommand("UPDATE sqc_events SET event_target = NULL WHERE event_flags & 2");
|
|
|
|
|
|
|
|
// MessageFlags.Log was never meaningfully used by anything and basically just meant "not-msg:add"
|
|
|
|
// MessageFlags.Private was also never meaningfully used, can be determined by checking if the channel name starts with @
|
|
|
|
await RunCommand("ALTER TABLE sqc_events DROP COLUMN event_flags");
|
2025-04-26 23:15:54 +00:00
|
|
|
}
|
2023-07-23 21:31:13 +00:00
|
|
|
|
2025-04-27 00:31:33 +00:00
|
|
|
private async Task EventUserAndNickNameTo1000() {
|
|
|
|
await RunCommand(
|
2025-04-26 23:15:54 +00:00
|
|
|
"ALTER TABLE `sqc_events`"
|
|
|
|
+ " CHANGE COLUMN `event_sender_name` `event_sender_name` VARCHAR(1000) NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_520_ci' AFTER `event_sender`,"
|
|
|
|
+ " CHANGE COLUMN `event_sender_nick` `event_sender_nick` VARCHAR(1000) NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_520_ci' AFTER `event_sender_rank`;"
|
|
|
|
);
|
|
|
|
}
|
2022-08-30 17:00:58 +02:00
|
|
|
|
2025-04-27 00:31:33 +00:00
|
|
|
private async Task EventDataAsMediumBlob() {
|
|
|
|
await RunCommand(
|
2025-04-26 23:15:54 +00:00
|
|
|
"ALTER TABLE `sqc_events`"
|
|
|
|
+ " CHANGE COLUMN `event_data` `event_data` MEDIUMBLOB NULL DEFAULT NULL AFTER `event_flags`;"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2025-04-27 00:31:33 +00:00
|
|
|
private async Task AllowNullTarget() {
|
|
|
|
await RunCommand(
|
2025-04-26 23:15:54 +00:00
|
|
|
"ALTER TABLE `sqc_events`"
|
|
|
|
+ " CHANGE COLUMN `event_target` `event_target` VARBINARY(255) NULL AFTER `event_type`;"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2025-04-27 00:31:33 +00:00
|
|
|
private async Task CreateEventsTable() {
|
|
|
|
await RunCommand(
|
2025-04-26 23:15:54 +00:00
|
|
|
"CREATE TABLE `sqc_events` ("
|
|
|
|
+ "`event_id` BIGINT(20) NOT NULL,"
|
|
|
|
+ "`event_sender` BIGINT(20) UNSIGNED NULL DEFAULT NULL,"
|
|
|
|
+ "`event_sender_name` VARCHAR(255) NULL DEFAULT NULL,"
|
|
|
|
+ "`event_sender_colour` INT(11) NULL DEFAULT NULL,"
|
|
|
|
+ "`event_sender_rank` INT(11) NULL DEFAULT NULL,"
|
|
|
|
+ "`event_sender_nick` VARCHAR(255) NULL DEFAULT NULL,"
|
|
|
|
+ "`event_sender_perms` INT(11) NULL DEFAULT NULL,"
|
|
|
|
+ "`event_created` TIMESTAMP NOT NULL DEFAULT current_timestamp(),"
|
|
|
|
+ "`event_deleted` TIMESTAMP NULL DEFAULT NULL,"
|
|
|
|
+ "`event_type` VARBINARY(255) NOT NULL,"
|
|
|
|
+ "`event_target` VARBINARY(255) NOT NULL,"
|
|
|
|
+ "`event_flags` TINYINT(3) UNSIGNED NOT NULL,"
|
|
|
|
+ "`event_data` BLOB NULL DEFAULT NULL,"
|
|
|
|
+ "PRIMARY KEY (`event_id`),"
|
|
|
|
+ "INDEX `event_target` (`event_target`),"
|
|
|
|
+ "INDEX `event_type` (`event_type`),"
|
|
|
|
+ "INDEX `event_sender` (`event_sender`),"
|
|
|
|
+ "INDEX `event_datetime` (`event_created`),"
|
|
|
|
+ "INDEX `event_deleted` (`event_deleted`)"
|
|
|
|
+ ") COLLATE='utf8mb4_unicode_ci' ENGINE=InnoDB;"
|
|
|
|
);
|
2022-08-30 17:00:58 +02:00
|
|
|
}
|
|
|
|
}
|