fix: prevent echo and audible duplicates

This commit is contained in:
Roardom
2025-11-27 07:41:05 +00:00
parent 3a2ef9e315
commit 39fd2df7c3
2 changed files with 97 additions and 2 deletions

View File

@@ -0,0 +1,90 @@
<?php
declare(strict_types=1);
/**
* NOTICE OF LICENSE.
*
* UNIT3D Community Edition is open-sourced software licensed under the GNU Affero General Public License v3.0
* The details is bundled with this project in the file LICENSE.txt.
*
* @project UNIT3D Community Edition
*
* @author Roardom <roardom@protonmail.com>
* @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0
*/
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
return new class () extends Migration {
/**
* Run the migrations.
*/
public function up(): void
{
// Remove existing echo duplicates
DB::table('user_echoes as e1')
->join('user_echoes as e2', function ($join): void {
$join->on('e1.id', '<', 'e2.id')
->whereColumn('e1.user_id', '=', 'e2.user_id')
->whereColumn('e1.room_id', '=', 'e2.room_id');
})
->delete();
DB::table('user_echoes as e1')
->join('user_echoes as e2', function ($join): void {
$join->on('e1.id', '<', 'e2.id')
->whereColumn('e1.user_id', '=', 'e2.user_id')
->whereColumn('e1.target_id', '=', 'e2.target_id');
})
->delete();
DB::table('user_echoes as e1')
->join('user_echoes as e2', function ($join): void {
$join->on('e1.id', '<', 'e2.id')
->whereColumn('e1.user_id', '=', 'e2.user_id')
->whereColumn('e1.bot_id', '=', 'e2.bot_id');
})
->delete();
Schema::table('user_echoes', function (Blueprint $table): void {
$table->unique(['user_id', 'room_id']);
$table->unique(['user_id', 'target_id']);
$table->unique(['user_id', 'bot_id']);
});
// Remove existing audible duplicates
DB::table('user_audibles as a1')
->join('user_audibles as a2', function ($join): void {
$join->on('a1.id', '<', 'a2.id')
->whereColumn('a1.user_id', '=', 'a2.user_id')
->whereColumn('a1.room_id', '=', 'a2.room_id');
})
->delete();
DB::table('user_audibles as a1')
->join('user_audibles as a2', function ($join): void {
$join->on('a1.id', '<', 'a2.id')
->whereColumn('a1.user_id', '=', 'a2.user_id')
->whereColumn('a1.target_id', '=', 'a2.target_id');
})
->delete();
DB::table('user_audibles as a1')
->join('user_audibles as a2', function ($join): void {
$join->on('a1.id', '<', 'a2.id')
->whereColumn('a1.user_id', '=', 'a2.user_id')
->whereColumn('a1.bot_id', '=', 'a2.bot_id');
})
->delete();
Schema::table('user_audibles', function (Blueprint $table): void {
$table->unique(['user_id', 'room_id']);
$table->unique(['user_id', 'target_id']);
$table->unique(['user_id', 'bot_id']);
});
}
};

View File

@@ -2259,10 +2259,12 @@ CREATE TABLE `user_audibles` (
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `user_audibles_user_id_room_id_unique` (`user_id`,`room_id`),
UNIQUE KEY `user_audibles_user_id_target_id_unique` (`user_id`,`target_id`),
UNIQUE KEY `user_audibles_user_id_bot_id_unique` (`user_id`,`bot_id`),
KEY `user_audibles_room_id_index` (`room_id`),
KEY `user_audibles_bot_id_index` (`bot_id`),
KEY `user_audibles_status_index` (`status`),
KEY `user_audibles_user_id_foreign` (`user_id`),
KEY `user_audibles_target_id_foreign` (`target_id`),
CONSTRAINT `user_audibles_target_id_foreign` FOREIGN KEY (`target_id`) REFERENCES `users` (`id`) ON UPDATE CASCADE,
CONSTRAINT `user_audibles_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON UPDATE CASCADE
@@ -2280,9 +2282,11 @@ CREATE TABLE `user_echoes` (
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `user_echoes_user_id_room_id_unique` (`user_id`,`room_id`),
UNIQUE KEY `user_echoes_user_id_target_id_unique` (`user_id`,`target_id`),
UNIQUE KEY `user_echoes_user_id_bot_id_unique` (`user_id`,`bot_id`),
KEY `user_echoes_room_id_index` (`room_id`),
KEY `user_echoes_bot_id_index` (`bot_id`),
KEY `user_echoes_user_id_foreign` (`user_id`),
KEY `user_echoes_target_id_foreign` (`target_id`),
CONSTRAINT `user_echoes_target_id_foreign` FOREIGN KEY (`target_id`) REFERENCES `users` (`id`) ON UPDATE CASCADE,
CONSTRAINT `user_echoes_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON UPDATE CASCADE
@@ -3042,3 +3046,4 @@ INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (363,'2025_09_07_23
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (364,'2025_09_08_000029_make_audits_morphable',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (365,'2025_09_25_110038_alter_reports_create_assignee',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (366,'2025_11_08_094209_rename_warnings_torrent_to_torrent_id',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (367,'2025_11_18_080804_echoes_audibles_unique_keys',1);