File size: 3,129 Bytes
ffd0171
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
import { MigrationInterface, QueryRunner } from 'typeorm';

export class MakeQuestionGroupChapterOptional1780000000004
  implements MigrationInterface
{
  name = 'MakeQuestionGroupChapterOptional1780000000004';

  public async up(queryRunner: QueryRunner): Promise<void> {
    await this.dropForeignKeyIfExists(
      queryRunner,
      'question_bank_question_groups',
      'FK_qb_question_groups_chapter',
    );
    await queryRunner.query(`
      ALTER TABLE \`question_bank_question_groups\`
      MODIFY COLUMN \`chapter_id\` bigint UNSIGNED NULL
    `);
    await this.addForeignKeyIfMissing(
      queryRunner,
      'question_bank_question_groups',
      'FK_qb_question_groups_chapter',
      'FOREIGN KEY (`chapter_id`) REFERENCES `course_chapters`(`chapter_id`) ON DELETE SET NULL ON UPDATE NO ACTION',
    );
  }

  public async down(queryRunner: QueryRunner): Promise<void> {
    await queryRunner.query(`
      UPDATE \`question_bank_question_groups\` g
      JOIN (
        SELECT \`course_id\`, MIN(\`chapter_id\`) AS \`chapter_id\`
        FROM \`course_chapters\`
        GROUP BY \`course_id\`
      ) c ON c.\`course_id\` = g.\`course_id\`
      SET g.\`chapter_id\` = c.\`chapter_id\`
      WHERE g.\`chapter_id\` IS NULL
    `);
    await this.dropForeignKeyIfExists(
      queryRunner,
      'question_bank_question_groups',
      'FK_qb_question_groups_chapter',
    );
    await queryRunner.query(`
      ALTER TABLE \`question_bank_question_groups\`
      MODIFY COLUMN \`chapter_id\` bigint UNSIGNED NOT NULL
    `);
    await this.addForeignKeyIfMissing(
      queryRunner,
      'question_bank_question_groups',
      'FK_qb_question_groups_chapter',
      'FOREIGN KEY (`chapter_id`) REFERENCES `course_chapters`(`chapter_id`) ON DELETE CASCADE ON UPDATE NO ACTION',
    );
  }

  private async addForeignKeyIfMissing(
    queryRunner: QueryRunner,
    tableName: string,
    constraintName: string,
    definition: string,
  ): Promise<void> {
    const exists = await this.constraintExists(
      queryRunner,
      tableName,
      constraintName,
    );
    if (!exists) {
      await queryRunner.query(
        `ALTER TABLE \`${tableName}\` ADD CONSTRAINT \`${constraintName}\` ${definition}`,
      );
    }
  }

  private async dropForeignKeyIfExists(
    queryRunner: QueryRunner,
    tableName: string,
    constraintName: string,
  ): Promise<void> {
    const exists = await this.constraintExists(
      queryRunner,
      tableName,
      constraintName,
    );
    if (exists) {
      await queryRunner.query(
        `ALTER TABLE \`${tableName}\` DROP FOREIGN KEY \`${constraintName}\``,
      );
    }
  }

  private async constraintExists(
    queryRunner: QueryRunner,
    tableName: string,
    constraintName: string,
  ): Promise<boolean> {
    const rows = (await queryRunner.query(
      `
        SELECT 1
        FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
        WHERE TABLE_SCHEMA = DATABASE()
          AND TABLE_NAME = ?
          AND CONSTRAINT_NAME = ?
        LIMIT 1
      `,
      [tableName, constraintName],
    )) as unknown[];
    return rows.length > 0;
  }
}