74 lines
2.3 KiB
PHP
74 lines
2.3 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Database\Migrations;
|
|
|
|
use CodeIgniter\Database\Migration;
|
|
use RuntimeException;
|
|
|
|
final class EnsureWhatsappGroupLinksUniquePerSchoolYear extends Migration
|
|
{
|
|
public function up(): void
|
|
{
|
|
if ($this->db->DBDriver !== 'MySQLi') {
|
|
throw new RuntimeException('This migration requires MySQL/MariaDB through the MySQLi driver.');
|
|
}
|
|
|
|
if (! $this->db->tableExists('whatsapp_group_links')
|
|
|| ! $this->db->fieldExists('class_section_id', 'whatsapp_group_links')
|
|
|| ! $this->db->fieldExists('school_year', 'whatsapp_group_links')) {
|
|
return;
|
|
}
|
|
|
|
$duplicates = $this->db->query(
|
|
'SELECT class_section_id, school_year, COUNT(*) AS row_count
|
|
FROM `whatsapp_group_links`
|
|
GROUP BY class_section_id, school_year
|
|
HAVING COUNT(*) > 1
|
|
LIMIT 5'
|
|
)->getResultArray();
|
|
|
|
if ($duplicates !== []) {
|
|
throw new RuntimeException(
|
|
'Cannot add whatsapp_group_links unique key by school year because duplicate class_section_id/school_year rows exist: '
|
|
. json_encode($duplicates)
|
|
);
|
|
}
|
|
|
|
$this->dropIndexIfExists('whatsapp_group_links', 'uq_section_term');
|
|
|
|
$this->db->query(
|
|
'ALTER TABLE `whatsapp_group_links`
|
|
ADD UNIQUE INDEX `uq_section_term` (`class_section_id`, `school_year`)'
|
|
);
|
|
}
|
|
|
|
public function down(): void
|
|
{
|
|
throw new RuntimeException('This migration is intentionally irreversible because reverting can fail once multiple school years exist for the same section.');
|
|
}
|
|
|
|
private function dropIndexIfExists(string $table, string $index): void
|
|
{
|
|
$exists = $this->db->query(
|
|
'SELECT COUNT(*) AS aggregate
|
|
FROM information_schema.STATISTICS
|
|
WHERE TABLE_SCHEMA = DATABASE()
|
|
AND TABLE_NAME = ?
|
|
AND INDEX_NAME = ?',
|
|
[$table, $index]
|
|
)->getRow();
|
|
|
|
if ((int) ($exists->aggregate ?? 0) === 0) {
|
|
return;
|
|
}
|
|
|
|
$this->db->query(sprintf(
|
|
'ALTER TABLE `%s` DROP INDEX `%s`',
|
|
str_replace('`', '``', $table),
|
|
str_replace('`', '``', $index)
|
|
));
|
|
}
|
|
}
|