setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); echo "Starting migration 033: Standardize bni_group_id in meeting_attendance. "; // Ensure bni_group_id column exists and is nullable for now $stmt_bni = $db->query("SHOW COLUMNS FROM meeting_attendance LIKE 'bni_group_id'"); $result_bni = $stmt_bni->fetch(PDO::FETCH_ASSOC); if (!$result_bni) { $db->exec("ALTER TABLE meeting_attendance ADD COLUMN bni_group_id INT(11) NULL;"); echo "SUCCESS: Added nullable 'bni_group_id' column. "; } else { $db->exec("ALTER TABLE meeting_attendance MODIFY bni_group_id INT(11) NULL;"); echo "SUCCESS: Modified 'bni_group_id' to be nullable. "; } // Check for orphaned bni_group_ids $orphan_check = $db->query("SELECT ma.bni_group_id, COUNT(*) as count FROM meeting_attendance ma LEFT JOIN bni_groups bg ON ma.bni_group_id = bg.id WHERE bg.id IS NULL AND ma.bni_group_id IS NOT NULL GROUP BY ma.bni_group_id;"); $orphans = $orphan_check->fetchAll(PDO::FETCH_ASSOC); if (count($orphans) > 0) { echo "WARNING: Found orphaned bni_group_ids in meeting_attendance table. "; foreach ($orphans as $orphan) { echo " - bni_group_id: " . $orphan['bni_group_id'] . " (" . $orphan['count'] . " rows) "; } // For now, we will set them to NULL to allow FK creation foreach ($orphans as $orphan) { if ($orphan['bni_group_id'] !== 0) { // we don't want to update rows that have 0 as this is default $update_stmt = $db->prepare("UPDATE meeting_attendance SET bni_group_id = NULL WHERE bni_group_id = :orphan_id;"); $update_stmt->execute(['orphan_id' => $orphan['bni_group_id']]); echo "Set " . $update_stmt->rowCount() . " rows with orphaned bni_group_id " . $orphan['bni_group_id'] . " to NULL. "; } } } else { echo "INFO: No orphaned bni_group_ids found. "; } // Add foreign key if it doesn't exist $fk_check = $db->query("SELECT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'meeting_attendance' AND COLUMN_NAME = 'bni_group_id' AND REFERENCED_TABLE_NAME = 'bni_groups';")->fetch(); if (!$fk_check) { echo "Adding foreign key on 'bni_group_id' to 'bni_groups.id'. "; $db->exec("ALTER TABLE meeting_attendance ADD CONSTRAINT fk_meeting_attendance_bni_group FOREIGN KEY (bni_group_id) REFERENCES bni_groups(id) ON DELETE CASCADE;"); echo "SUCCESS: Foreign key added. "; } else { echo "INFO: Foreign key on 'bni_group_id' already exists. "; } // Now, alter the column to be NOT NULL. This will fail if there are any NULLs left. // I will not do this for now, as the user might want to check the orphaned data first. // I will let the column be nullable for now. echo "Migration 033 completed successfully (bni_group_id is currently nullable). "; } catch (Exception $e) { error_log("Migration 033 failed: " . $e->getMessage()); die("FATAL: Migration 033 failed: " . $e->getMessage() . "\n"); }