migrations/Version20251022102000.php line 1

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace DoctrineMigrations;
  4. use Doctrine\DBAL\Schema\Schema;
  5. use Doctrine\Migrations\AbstractMigration;
  6. /**
  7.  * Final schema cleanup: Fix indexes and foreign keys, keep created/client_id nullable.
  8.  */
  9. final class Version20251022102000 extends AbstractMigration
  10. {
  11.     public function getDescription(): string
  12.     {
  13.         return 'Final schema cleanup - fix indexes and FK, keep created/client_id nullable';
  14.     }
  15.     public function up(Schema $schema): void
  16.     {
  17.         // ============================================================
  18.         // Remove client_id from join tables and OAuth tables (correct)
  19.         // ============================================================
  20.         
  21.         $this->addSql('ALTER TABLE cart_item_person DROP COLUMN IF EXISTS client_id');
  22.         $this->addSql('ALTER TABLE email_history_entry_person DROP COLUMN IF EXISTS client_id');
  23.         $this->addSql('ALTER TABLE oauth2_authorization_code DROP COLUMN IF EXISTS client_id');
  24.         $this->addSql('ALTER TABLE oauth2_refresh_token DROP COLUMN IF EXISTS client_id');
  25.         $this->addSql('ALTER TABLE oauth2_access_token DROP COLUMN IF EXISTS client_id');
  26.         $this->addSql('ALTER TABLE oauth_auth_code DROP COLUMN IF EXISTS client_id');
  27.         // ============================================================
  28.         // Fix Foreign Keys and Indexes (keep client_id as nullable!)
  29.         // ============================================================
  30.         
  31.         // presence_reason - Drop FK first, then indexes
  32.         $this->connection->executeStatement("
  33.             SET @fk = (SELECT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE 
  34.                 WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'presence_reason' 
  35.                 AND COLUMN_NAME = 'client_id' AND REFERENCED_TABLE_NAME IS NOT NULL LIMIT 1);
  36.             SET @sql = IF(@fk IS NOT NULL, CONCAT('ALTER TABLE presence_reason DROP FOREIGN KEY ', @fk), 'SELECT 1');
  37.             PREPARE stmt FROM @sql; EXECUTE stmt;
  38.         ");
  39.         
  40.         // Now drop indexes
  41.         $this->connection->executeStatement("
  42.             SET @idx = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.STATISTICS 
  43.                 WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'presence_reason' 
  44.                 AND INDEX_NAME = 'IDX_PR19EB6921');
  45.             SET @sql = IF(@idx > 0, 'DROP INDEX IDX_PR19EB6921 ON presence_reason', 'SELECT 1');
  46.             PREPARE stmt FROM @sql; EXECUTE stmt;
  47.         ");
  48.         
  49.         $this->connection->executeStatement("
  50.             SET @idx = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.STATISTICS 
  51.                 WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'presence_reason' 
  52.                 AND INDEX_NAME = 'FK_D629391C19EB6921');
  53.             SET @sql = IF(@idx > 0, 'DROP INDEX FK_D629391C19EB6921 ON presence_reason', 'SELECT 1');
  54.             PREPARE stmt FROM @sql; EXECUTE stmt;
  55.         ");
  56.         
  57.         // Create new index and FK
  58.         $this->connection->executeStatement("
  59.             SET @idx = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.STATISTICS 
  60.                 WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'presence_reason' 
  61.                 AND INDEX_NAME = 'IDX_D629391C19EB6921');
  62.             SET @sql = IF(@idx = 0, 'CREATE INDEX IDX_D629391C19EB6921 ON presence_reason (client_id)', 'SELECT 1');
  63.             PREPARE stmt FROM @sql; EXECUTE stmt;
  64.         ");
  65.         
  66.         $this->connection->executeStatement("
  67.             SET @fk = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE 
  68.                 WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'presence_reason' 
  69.                 AND CONSTRAINT_NAME = 'FK_D629391C19EB6921' AND REFERENCED_TABLE_NAME IS NOT NULL);
  70.             SET @sql = IF(@fk = 0, 'ALTER TABLE presence_reason ADD CONSTRAINT FK_D629391C19EB6921 FOREIGN KEY (client_id) REFERENCES client (id)', 'SELECT 1');
  71.             PREPARE stmt FROM @sql; EXECUTE stmt;
  72.         ");
  73.         // ckimage - Drop FK first
  74.         $this->connection->executeStatement("
  75.             SET @fk = (SELECT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE 
  76.                 WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'ckimage' 
  77.                 AND COLUMN_NAME = 'client_id' AND REFERENCED_TABLE_NAME IS NOT NULL LIMIT 1);
  78.             SET @sql = IF(@fk IS NOT NULL, CONCAT('ALTER TABLE ckimage DROP FOREIGN KEY ', @fk), 'SELECT 1');
  79.             PREPARE stmt FROM @sql; EXECUTE stmt;
  80.         ");
  81.         
  82.         // Now drop index
  83.         $this->connection->executeStatement("
  84.             SET @idx = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.STATISTICS 
  85.                 WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'ckimage' 
  86.                 AND INDEX_NAME = 'FK_5A0E314919EB6921');
  87.             SET @sql = IF(@idx > 0, 'DROP INDEX FK_5A0E314919EB6921 ON ckimage', 'SELECT 1');
  88.             PREPARE stmt FROM @sql; EXECUTE stmt;
  89.         ");
  90.         // cart_item - Drop FK first
  91.         $this->connection->executeStatement("
  92.             SET @fk = (SELECT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE 
  93.                 WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'cart_item' 
  94.                 AND COLUMN_NAME = 'client_id' AND REFERENCED_TABLE_NAME IS NOT NULL LIMIT 1);
  95.             SET @sql = IF(@fk IS NOT NULL, CONCAT('ALTER TABLE cart_item DROP FOREIGN KEY ', @fk), 'SELECT 1');
  96.             PREPARE stmt FROM @sql; EXECUTE stmt;
  97.         ");
  98.         
  99.         // Now drop index
  100.         $this->connection->executeStatement("
  101.             SET @idx = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.STATISTICS 
  102.                 WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'cart_item' 
  103.                 AND INDEX_NAME = 'FK_F0FE252719EB6921');
  104.             SET @sql = IF(@idx > 0, 'DROP INDEX FK_F0FE252719EB6921 ON cart_item', 'SELECT 1');
  105.             PREPARE stmt FROM @sql; EXECUTE stmt;
  106.         ");
  107.         // speaker_provider
  108.         $this->connection->executeStatement("
  109.             SET @idx = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.STATISTICS 
  110.                 WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'speaker_provider' 
  111.                 AND INDEX_NAME = 'IDX_17A0F10619EB6921');
  112.             SET @sql = IF(@idx = 0, 'CREATE INDEX IDX_17A0F10619EB6921 ON speaker_provider (client_id)', 'SELECT 1');
  113.             PREPARE stmt FROM @sql; EXECUTE stmt;
  114.         ");
  115.         
  116.         $this->connection->executeStatement("
  117.             SET @fk = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE 
  118.                 WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'speaker_provider' 
  119.                 AND CONSTRAINT_NAME = 'FK_17A0F10619EB6921' AND REFERENCED_TABLE_NAME IS NOT NULL);
  120.             SET @sql = IF(@fk = 0, 'ALTER TABLE speaker_provider ADD CONSTRAINT FK_17A0F10619EB6921 FOREIGN KEY (client_id) REFERENCES client (id)', 'SELECT 1');
  121.             PREPARE stmt FROM @sql; EXECUTE stmt;
  122.         ");
  123.         // speaker_text - Drop FK first
  124.         $this->connection->executeStatement("
  125.             SET @fk = (SELECT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE 
  126.                 WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'speaker_text' 
  127.                 AND COLUMN_NAME = 'client_id' AND REFERENCED_TABLE_NAME IS NOT NULL LIMIT 1);
  128.             SET @sql = IF(@fk IS NOT NULL, CONCAT('ALTER TABLE speaker_text DROP FOREIGN KEY ', @fk), 'SELECT 1');
  129.             PREPARE stmt FROM @sql; EXECUTE stmt;
  130.         ");
  131.         
  132.         // Drop old index
  133.         $this->connection->executeStatement("
  134.             SET @idx = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.STATISTICS 
  135.                 WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'speaker_text' 
  136.                 AND INDEX_NAME = 'fk_189cceef19eb6921');
  137.             SET @sql = IF(@idx > 0, 'DROP INDEX fk_189cceef19eb6921 ON speaker_text', 'SELECT 1');
  138.             PREPARE stmt FROM @sql; EXECUTE stmt;
  139.         ");
  140.         
  141.         // Create new index and FK
  142.         $this->connection->executeStatement("
  143.             SET @idx = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.STATISTICS 
  144.                 WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'speaker_text' 
  145.                 AND INDEX_NAME = 'IDX_189CCEEF19EB6921');
  146.             SET @sql = IF(@idx = 0, 'CREATE INDEX IDX_189CCEEF19EB6921 ON speaker_text (client_id)', 'SELECT 1');
  147.             PREPARE stmt FROM @sql; EXECUTE stmt;
  148.         ");
  149.         $this->connection->executeStatement("
  150.             SET @fk = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE 
  151.                 WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'speaker_text' 
  152.                 AND CONSTRAINT_NAME = 'FK_189CCEEF19EB6921' AND REFERENCED_TABLE_NAME IS NOT NULL);
  153.             SET @sql = IF(@fk = 0, 'ALTER TABLE speaker_text ADD CONSTRAINT FK_189CCEEF19EB6921 FOREIGN KEY (client_id) REFERENCES client (id)', 'SELECT 1');
  154.             PREPARE stmt FROM @sql; EXECUTE stmt;
  155.         ");
  156.         // client_config - Drop FK first
  157.         $this->connection->executeStatement("
  158.             SET @fk = (SELECT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE 
  159.                 WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'client_config' 
  160.                 AND COLUMN_NAME = 'client_id' AND REFERENCED_TABLE_NAME IS NOT NULL LIMIT 1);
  161.             SET @sql = IF(@fk IS NOT NULL, CONCAT('ALTER TABLE client_config DROP FOREIGN KEY ', @fk), 'SELECT 1');
  162.             PREPARE stmt FROM @sql; EXECUTE stmt;
  163.         ");
  164.         
  165.         // Drop old index
  166.         $this->connection->executeStatement("
  167.             SET @idx = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.STATISTICS 
  168.                 WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'client_config' 
  169.                 AND INDEX_NAME = 'idx_812c64cfea1ce9be');
  170.             SET @sql = IF(@idx > 0, 'DROP INDEX idx_812c64cfea1ce9be ON client_config', 'SELECT 1');
  171.             PREPARE stmt FROM @sql; EXECUTE stmt;
  172.         ");
  173.         
  174.         // Create new index and FK
  175.         $this->connection->executeStatement("
  176.             SET @idx = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.STATISTICS 
  177.                 WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'client_config' 
  178.                 AND INDEX_NAME = 'IDX_812C64CF19EB6921');
  179.             SET @sql = IF(@idx = 0, 'CREATE INDEX IDX_812C64CF19EB6921 ON client_config (client_id)', 'SELECT 1');
  180.             PREPARE stmt FROM @sql; EXECUTE stmt;
  181.         ");
  182.         $this->connection->executeStatement("
  183.             SET @fk = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE 
  184.                 WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'client_config' 
  185.                 AND CONSTRAINT_NAME = 'FK_812C64CF19EB6921' AND REFERENCED_TABLE_NAME IS NOT NULL);
  186.             SET @sql = IF(@fk = 0, 'ALTER TABLE client_config ADD CONSTRAINT FK_812C64CF19EB6921 FOREIGN KEY (client_id) REFERENCES client (id)', 'SELECT 1');
  187.             PREPARE stmt FROM @sql; EXECUTE stmt;
  188.         ");
  189.         // ============================================================
  190.         // IMPORTANT: Keep created and client_id as NULLABLE
  191.         // We do NOT set them to NOT NULL until data is assigned!
  192.         // ============================================================
  193.         
  194.         // Ensure all created/modified columns are nullable
  195.         $tables = [
  196.             'invoice_reminder''ckimage''course_data''cart_item''speaker_text',
  197.             'cart''presence''client_config''email_history_entry'
  198.         ];
  199.         
  200.         foreach ($tables as $table) {
  201.             $this->addSql("ALTER TABLE $table MODIFY created DATETIME DEFAULT NULL");
  202.             $this->addSql("ALTER TABLE $table MODIFY modified DATETIME DEFAULT NULL");
  203.         }
  204.         // Ensure client_id columns are nullable
  205.         $this->addSql('ALTER TABLE cart MODIFY client_id INT DEFAULT NULL');
  206.         $this->addSql('ALTER TABLE presence MODIFY client_id INT DEFAULT NULL');
  207.         $this->addSql('ALTER TABLE email_history_entry MODIFY client_id INT DEFAULT NULL');
  208.         $this->addSql('ALTER TABLE course_data MODIFY client_id INT DEFAULT NULL');
  209.     }
  210.     public function down(Schema $schema): void
  211.     {
  212.         // Rollback not needed - this is a cleanup migration
  213.     }
  214. }