From b55d0554e44e49f81a911ce53c9674dee375ebe6 Mon Sep 17 00:00:00 2001 From: Julian Krauser Date: Sat, 25 Jan 2025 11:39:34 +0100 Subject: [PATCH] migration update --- src/data-source.ts | 4 + .../1734520998539-memberDataViews.ts | 194 +++++++-------- .../1736084198860-extendViewValues.ts | 194 ++++++++------- .../1737796878058-salutationAsTable.ts | 91 +++++++ src/migrations/1737800468938-updateViews.ts | 229 ++++++++++++++++++ 5 files changed, 517 insertions(+), 195 deletions(-) create mode 100644 src/migrations/1737796878058-salutationAsTable.ts create mode 100644 src/migrations/1737800468938-updateViews.ts diff --git a/src/data-source.ts b/src/data-source.ts index fff12dd..c016ca4 100644 --- a/src/data-source.ts +++ b/src/data-source.ts @@ -72,6 +72,8 @@ import { webapi } from "./entity/user/webapi"; import { webapiPermission } from "./entity/user/webapi_permission"; import { AddWebapiTokens1737453096674 } from "./migrations/1737453096674-addwebapiTokens"; import { salutation } from "./entity/settings/salutation"; +import { SalutationAsTable1737796878058 } from "./migrations/1737796878058-salutationAsTable"; +import { UpdateViews1737800468938 } from "./migrations/1737800468938-updateViews"; const dataSource = new DataSource({ type: DB_TYPE as any, @@ -154,6 +156,8 @@ const dataSource = new DataSource({ FinishInternalIdTransfer1736505324488, ProtocolPresenceExcuse1737287798828, AddWebapiTokens1737453096674, + SalutationAsTable1737796878058, + UpdateViews1737800468938, ], migrationsRun: true, migrationsTransactionMode: "each", diff --git a/src/migrations/1734520998539-memberDataViews.ts b/src/migrations/1734520998539-memberDataViews.ts index 4e0df38..b29b3e2 100644 --- a/src/migrations/1734520998539-memberDataViews.ts +++ b/src/migrations/1734520998539-memberDataViews.ts @@ -8,105 +8,105 @@ export class MemberDataViews1734520998539 implements MigrationInterface { name = "MemberDataViews1734520998539"; public async up(queryRunner: QueryRunner): Promise { - await queryRunner.createView( - new View({ - name: "member_view", - expression: (datasource: DataSource) => - datasource - .getRepository(member) - .createQueryBuilder("member") - .select("member.id", "id") - .addSelect("member.salutation", "salutation") - .addSelect("member.firstname", "firstname") - .addSelect("member.lastname", "lastname") - .addSelect("member.nameaffix", "nameaffix") - .addSelect("member.birthdate", "birthdate") - .addSelect("TIMESTAMPDIFF(YEAR, member.birthdate, CURDATE())", "todayAge") - .addSelect("YEAR(CURDATE()) - YEAR(member.birthdate)", "ageThisYear"), - }), - true - ); - await queryRunner.createView( - new View({ - name: "member_executive_positions_view", - expression: (datasource: DataSource) => - datasource - .getRepository(memberExecutivePositions) - .createQueryBuilder("memberExecutivePositions") - .select("executivePosition.id", "positionId") - .addSelect("executivePosition.position", "position") - .addSelect("member.id", "memberId") - .addSelect("member.salutation", "memberSalutation") - .addSelect("member.firstname", "memberFirstname") - .addSelect("member.lastname", "memberLastname") - .addSelect("member.nameaffix", "memberNameaffix") - .addSelect("member.birthdate", "memberBirthdate") - .addSelect( - "SUM(TIMESTAMPDIFF(DAY, memberExecutivePositions.start, COALESCE(memberExecutivePositions.end, CURRENT_DATE)))", - "durationInDays" - ) - .leftJoin("memberExecutivePositions.executivePosition", "executivePosition") - .leftJoin("memberExecutivePositions.member", "member") - .groupBy("executivePosition.id"), - }), - true - ); - await queryRunner.createView( - new View({ - name: "member_qualifications_view", - expression: (datasource: DataSource) => - datasource - .getRepository(memberQualifications) - .createQueryBuilder("memberQualifications") - .select("qualification.id", "qualificationId") - .addSelect("qualification.qualification", "qualification") - .addSelect("member.id", "memberId") - .addSelect("member.salutation", "memberSalutation") - .addSelect("member.firstname", "memberFirstname") - .addSelect("member.lastname", "memberLastname") - .addSelect("member.nameaffix", "memberNameaffix") - .addSelect("member.birthdate", "memberBirthdate") - .addSelect( - "SUM(TIMESTAMPDIFF(DAY, memberQualifications.start, COALESCE(memberQualifications.end, CURRENT_DATE)))", - "durationInDays" - ) - .leftJoin("memberQualifications.qualification", "qualification") - .leftJoin("memberQualifications.member", "member") - .groupBy("qualification.id"), - }), - true - ); - await queryRunner.createView( - new View({ - name: "membership_view", - expression: (datasource: DataSource) => - datasource - .getRepository(membership) - .createQueryBuilder("membership") - .select("status.id", "statusId") - .addSelect("status.status", "status") - .addSelect("member.id", "memberId") - .addSelect("member.salutation", "memberSalutation") - .addSelect("member.firstname", "memberFirstname") - .addSelect("member.lastname", "memberLastname") - .addSelect("member.nameaffix", "memberNameaffix") - .addSelect("member.birthdate", "memberBirthdate") - .addSelect( - "SUM(TIMESTAMPDIFF(DAY, membership.start, COALESCE(membership.end, CURRENT_DATE)))", - "durationInDays" - ) - .leftJoin("membership.status", "status") - .leftJoin("membership.member", "member") - .groupBy("status.id"), - }), - true - ); + // await queryRunner.createView( + // new View({ + // name: "member_view", + // expression: (datasource: DataSource) => + // datasource + // .getRepository(member) + // .createQueryBuilder("member") + // .select("member.id", "id") + // .addSelect("member.salutation", "salutation") + // .addSelect("member.firstname", "firstname") + // .addSelect("member.lastname", "lastname") + // .addSelect("member.nameaffix", "nameaffix") + // .addSelect("member.birthdate", "birthdate") + // .addSelect("TIMESTAMPDIFF(YEAR, member.birthdate, CURDATE())", "todayAge") + // .addSelect("YEAR(CURDATE()) - YEAR(member.birthdate)", "ageThisYear"), + // }), + // true + // ); + // await queryRunner.createView( + // new View({ + // name: "member_executive_positions_view", + // expression: (datasource: DataSource) => + // datasource + // .getRepository(memberExecutivePositions) + // .createQueryBuilder("memberExecutivePositions") + // .select("executivePosition.id", "positionId") + // .addSelect("executivePosition.position", "position") + // .addSelect("member.id", "memberId") + // .addSelect("member.salutation", "memberSalutation") + // .addSelect("member.firstname", "memberFirstname") + // .addSelect("member.lastname", "memberLastname") + // .addSelect("member.nameaffix", "memberNameaffix") + // .addSelect("member.birthdate", "memberBirthdate") + // .addSelect( + // "SUM(TIMESTAMPDIFF(DAY, memberExecutivePositions.start, COALESCE(memberExecutivePositions.end, CURRENT_DATE)))", + // "durationInDays" + // ) + // .leftJoin("memberExecutivePositions.executivePosition", "executivePosition") + // .leftJoin("memberExecutivePositions.member", "member") + // .groupBy("executivePosition.id"), + // }), + // true + // ); + // await queryRunner.createView( + // new View({ + // name: "member_qualifications_view", + // expression: (datasource: DataSource) => + // datasource + // .getRepository(memberQualifications) + // .createQueryBuilder("memberQualifications") + // .select("qualification.id", "qualificationId") + // .addSelect("qualification.qualification", "qualification") + // .addSelect("member.id", "memberId") + // .addSelect("member.salutation", "memberSalutation") + // .addSelect("member.firstname", "memberFirstname") + // .addSelect("member.lastname", "memberLastname") + // .addSelect("member.nameaffix", "memberNameaffix") + // .addSelect("member.birthdate", "memberBirthdate") + // .addSelect( + // "SUM(TIMESTAMPDIFF(DAY, memberQualifications.start, COALESCE(memberQualifications.end, CURRENT_DATE)))", + // "durationInDays" + // ) + // .leftJoin("memberQualifications.qualification", "qualification") + // .leftJoin("memberQualifications.member", "member") + // .groupBy("qualification.id"), + // }), + // true + // ); + // await queryRunner.createView( + // new View({ + // name: "membership_view", + // expression: (datasource: DataSource) => + // datasource + // .getRepository(membership) + // .createQueryBuilder("membership") + // .select("status.id", "statusId") + // .addSelect("status.status", "status") + // .addSelect("member.id", "memberId") + // .addSelect("member.salutation", "memberSalutation") + // .addSelect("member.firstname", "memberFirstname") + // .addSelect("member.lastname", "memberLastname") + // .addSelect("member.nameaffix", "memberNameaffix") + // .addSelect("member.birthdate", "memberBirthdate") + // .addSelect( + // "SUM(TIMESTAMPDIFF(DAY, membership.start, COALESCE(membership.end, CURRENT_DATE)))", + // "durationInDays" + // ) + // .leftJoin("membership.status", "status") + // .leftJoin("membership.member", "member") + // .groupBy("status.id"), + // }), + // true + // ); } public async down(queryRunner: QueryRunner): Promise { - await queryRunner.dropView("membership_view"); - await queryRunner.dropView("member_qualifications_view"); - await queryRunner.dropView("member_executive_positions_view"); - await queryRunner.dropView("member_view"); + // await queryRunner.dropView("membership_view"); + // await queryRunner.dropView("member_qualifications_view"); + // await queryRunner.dropView("member_executive_positions_view"); + // await queryRunner.dropView("member_view"); } } diff --git a/src/migrations/1736084198860-extendViewValues.ts b/src/migrations/1736084198860-extendViewValues.ts index 9816a83..4a024c9 100644 --- a/src/migrations/1736084198860-extendViewValues.ts +++ b/src/migrations/1736084198860-extendViewValues.ts @@ -8,106 +8,104 @@ export class ExtendViewValues1736084198860 implements MigrationInterface { name = "ExtendViewValues1736084198860"; public async up(queryRunner: QueryRunner): Promise { - await queryRunner.dropView("membership_view"); - await queryRunner.dropView("member_view"); - - await queryRunner.createView( - new View({ - name: "member_view", - expression: (datasource: DataSource) => - datasource - .getRepository(member) - .createQueryBuilder("member") - .select("member.id", "id") - .addSelect("member.salutation", "salutation") - .addSelect("member.firstname", "firstname") - .addSelect("member.lastname", "lastname") - .addSelect("member.nameaffix", "nameaffix") - .addSelect("member.birthdate", "birthdate") - .addSelect("TIMESTAMPDIFF(YEAR, member.birthdate, CURDATE())", "todayAge") - .addSelect("YEAR(CURDATE()) - YEAR(member.birthdate)", "ageThisYear") - .addSelect("CONCAT('_', FROM_DAYS(TIMESTAMPDIFF(DAY, member.birthdate, CURDATE())))", "exactAge"), - }), - true - ); - await queryRunner.createView( - new View({ - name: "membership_view", - expression: (datasource: DataSource) => - datasource - .getRepository(membership) - .createQueryBuilder("membership") - .select("status.id", "statusId") - .addSelect("status.status", "status") - .addSelect("member.id", "memberId") - .addSelect("member.salutation", "memberSalutation") - .addSelect("member.firstname", "memberFirstname") - .addSelect("member.lastname", "memberLastname") - .addSelect("member.nameaffix", "memberNameaffix") - .addSelect("member.birthdate", "memberBirthdate") - .addSelect( - "SUM(TIMESTAMPDIFF(DAY, membership.start, COALESCE(membership.end, CURRENT_DATE)))", - "durationInDays" - ) - .addSelect( - "CONCAT('_', FROM_DAYS(SUM(TIMESTAMPDIFF(DAY, membership.start, COALESCE(membership.end, CURRENT_DATE)))))", - "durationInYears" - ) - .leftJoin("membership.status", "status") - .leftJoin("membership.member", "member") - .groupBy("status.id") - .addGroupBy("member.id"), - }), - true - ); + // await queryRunner.dropView("membership_view"); + // await queryRunner.dropView("member_view"); + // await queryRunner.createView( + // new View({ + // name: "member_view", + // expression: (datasource: DataSource) => + // datasource + // .getRepository(member) + // .createQueryBuilder("member") + // .select("member.id", "id") + // .addSelect("member.salutation", "salutation") + // .addSelect("member.firstname", "firstname") + // .addSelect("member.lastname", "lastname") + // .addSelect("member.nameaffix", "nameaffix") + // .addSelect("member.birthdate", "birthdate") + // .addSelect("TIMESTAMPDIFF(YEAR, member.birthdate, CURDATE())", "todayAge") + // .addSelect("YEAR(CURDATE()) - YEAR(member.birthdate)", "ageThisYear") + // .addSelect("CONCAT('_', FROM_DAYS(TIMESTAMPDIFF(DAY, member.birthdate, CURDATE())))", "exactAge"), + // }), + // true + // ); + // await queryRunner.createView( + // new View({ + // name: "membership_view", + // expression: (datasource: DataSource) => + // datasource + // .getRepository(membership) + // .createQueryBuilder("membership") + // .select("status.id", "statusId") + // .addSelect("status.status", "status") + // .addSelect("member.id", "memberId") + // .addSelect("member.salutation", "memberSalutation") + // .addSelect("member.firstname", "memberFirstname") + // .addSelect("member.lastname", "memberLastname") + // .addSelect("member.nameaffix", "memberNameaffix") + // .addSelect("member.birthdate", "memberBirthdate") + // .addSelect( + // "SUM(TIMESTAMPDIFF(DAY, membership.start, COALESCE(membership.end, CURRENT_DATE)))", + // "durationInDays" + // ) + // .addSelect( + // "CONCAT('_', FROM_DAYS(SUM(TIMESTAMPDIFF(DAY, membership.start, COALESCE(membership.end, CURRENT_DATE)))))", + // "durationInYears" + // ) + // .leftJoin("membership.status", "status") + // .leftJoin("membership.member", "member") + // .groupBy("status.id") + // .addGroupBy("member.id"), + // }), + // true + // ); } public async down(queryRunner: QueryRunner): Promise { - await queryRunner.dropView("membership_view"); - await queryRunner.dropView("member_view"); - - await queryRunner.createView( - new View({ - name: "member_view", - expression: (datasource: DataSource) => - datasource - .getRepository(member) - .createQueryBuilder("member") - .select("member.id", "id") - .addSelect("member.salutation", "salutation") - .addSelect("member.firstname", "firstname") - .addSelect("member.lastname", "lastname") - .addSelect("member.nameaffix", "nameaffix") - .addSelect("member.birthdate", "birthdate") - .addSelect("TIMESTAMPDIFF(YEAR, member.birthdate, CURDATE())", "todayAge") - .addSelect("YEAR(CURDATE()) - YEAR(member.birthdate)", "ageThisYear"), - }), - true - ); - await queryRunner.createView( - new View({ - name: "membership_view", - expression: (datasource: DataSource) => - datasource - .getRepository(membership) - .createQueryBuilder("membership") - .select("status.id", "statusId") - .addSelect("status.status", "status") - .addSelect("member.id", "memberId") - .addSelect("member.salutation", "memberSalutation") - .addSelect("member.firstname", "memberFirstname") - .addSelect("member.lastname", "memberLastname") - .addSelect("member.nameaffix", "memberNameaffix") - .addSelect("member.birthdate", "memberBirthdate") - .addSelect( - "SUM(TIMESTAMPDIFF(DAY, membership.start, COALESCE(membership.end, CURRENT_DATE)))", - "durationInDays" - ) - .leftJoin("membership.status", "status") - .leftJoin("membership.member", "member") - .groupBy("status.id"), - }), - true - ); + // await queryRunner.dropView("membership_view"); + // await queryRunner.dropView("member_view"); + // await queryRunner.createView( + // new View({ + // name: "member_view", + // expression: (datasource: DataSource) => + // datasource + // .getRepository(member) + // .createQueryBuilder("member") + // .select("member.id", "id") + // .addSelect("member.salutation", "salutation") + // .addSelect("member.firstname", "firstname") + // .addSelect("member.lastname", "lastname") + // .addSelect("member.nameaffix", "nameaffix") + // .addSelect("member.birthdate", "birthdate") + // .addSelect("TIMESTAMPDIFF(YEAR, member.birthdate, CURDATE())", "todayAge") + // .addSelect("YEAR(CURDATE()) - YEAR(member.birthdate)", "ageThisYear"), + // }), + // true + // ); + // await queryRunner.createView( + // new View({ + // name: "membership_view", + // expression: (datasource: DataSource) => + // datasource + // .getRepository(membership) + // .createQueryBuilder("membership") + // .select("status.id", "statusId") + // .addSelect("status.status", "status") + // .addSelect("member.id", "memberId") + // .addSelect("member.salutation", "memberSalutation") + // .addSelect("member.firstname", "memberFirstname") + // .addSelect("member.lastname", "memberLastname") + // .addSelect("member.nameaffix", "memberNameaffix") + // .addSelect("member.birthdate", "memberBirthdate") + // .addSelect( + // "SUM(TIMESTAMPDIFF(DAY, membership.start, COALESCE(membership.end, CURRENT_DATE)))", + // "durationInDays" + // ) + // .leftJoin("membership.status", "status") + // .leftJoin("membership.member", "member") + // .groupBy("status.id"), + // }), + // true + // ); } } diff --git a/src/migrations/1737796878058-salutationAsTable.ts b/src/migrations/1737796878058-salutationAsTable.ts new file mode 100644 index 0000000..df84a91 --- /dev/null +++ b/src/migrations/1737796878058-salutationAsTable.ts @@ -0,0 +1,91 @@ +import { MigrationInterface, QueryRunner, Table, TableForeignKey } from "typeorm"; +import { DB_TYPE } from "../env.defaults"; +import { member } from "../entity/club/member/member"; +import { salutation } from "../entity/settings/salutation"; + +export class SalutationAsTable1737796878058 implements MigrationInterface { + name = "SalutationAsTable1737796878058"; + + public async up(queryRunner: QueryRunner): Promise { + const variableType_int = DB_TYPE == "mysql" ? "int" : "integer"; + + await queryRunner.createTable( + new Table({ + name: "salutation", + columns: [ + { name: "id", type: variableType_int, isPrimary: true, isGenerated: true, generationStrategy: "increment" }, + { name: "salutation", type: "varchar", length: "255", isUnique: true, isNullable: false }, + ], + }), + true + ); + + // ! has to be sql. Else the column would be dropped and created - resulting in data loss. + await queryRunner.query( + `ALTER TABLE \`member\` CHANGE \`salutation\` \`salutationId\` varchar(255) NOT NULL DEFAULT ''` + ); + + // ! has to be sql. Else no data is returned. + const existing_salutations = await queryRunner.query( + "SELECT DISTINCT salutationId FROM `member` `member` GROUP BY salutationId" + ); + + for (let s of existing_salutations.map((s: any) => s.salutationId) as Array) { + await queryRunner.manager.getRepository(salutation).save({ salutation: s }); + } + + const salutations = await queryRunner.manager.getRepository(salutation).find(); + + for (let salutation of salutations) { + await queryRunner.manager + .getRepository(member) + .createQueryBuilder("member") + .update({ salutationId: salutation.id }) + .where({ salutationId: salutation.salutation }) + .execute(); + } + + await queryRunner.query( + `ALTER TABLE \`member\` CHANGE \`salutationId\` \`salutationId\` ${variableType_int} NOT NULL` + ); + + await queryRunner.createForeignKey( + "member", + new TableForeignKey({ + columnNames: ["salutationId"], + referencedColumnNames: ["id"], + referencedTableName: "salutation", + onDelete: "RESTRICT", + onUpdate: "RESTRICT", + }) + ); + } + + public async down(queryRunner: QueryRunner): Promise { + const table = await queryRunner.getTable("member"); + const foreignKey = table.foreignKeys.find((fk) => fk.columnNames.indexOf("salutationId") !== -1); + await queryRunner.dropForeignKey("member", foreignKey); + + // ! has to be sql. Else the column would be dropped and created - resulting in data loss. + await queryRunner.query( + `ALTER TABLE \`member\` CHANGE \`salutationId\` \`salutationId\` varchar(255) NOT NULL DEFAULT ''` + ); + + const salutations = await queryRunner.manager.getRepository(salutation).find(); + + for (let salutation of salutations) { + await queryRunner.manager + .getRepository(member) + .createQueryBuilder("member") + .update({ salutationId: salutation.salutation as unknown as number }) + .where({ salutationId: salutation.id }) + .execute(); + } + + await queryRunner.query( + `ALTER TABLE \`member\` CHANGE \`salutationId\` \`salutation\` varchar(255) NOT NULL DEFAULT 'none'` + ); + + await queryRunner.dropTable("webapi"); + } +} diff --git a/src/migrations/1737800468938-updateViews.ts b/src/migrations/1737800468938-updateViews.ts new file mode 100644 index 0000000..64587af --- /dev/null +++ b/src/migrations/1737800468938-updateViews.ts @@ -0,0 +1,229 @@ +import { DataSource, MigrationInterface, QueryRunner, View } from "typeorm"; +import { member } from "../entity/club/member/member"; +import { memberExecutivePositions } from "../entity/club/member/memberExecutivePositions"; +import { memberQualifications } from "../entity/club/member/memberQualifications"; +import { membership } from "../entity/club/member/membership"; + +export class UpdateViews1737800468938 implements MigrationInterface { + name = "UpdateViews1737800468938"; + + public async up(queryRunner: QueryRunner): Promise { + // await queryRunner.dropView("membership_view"); + // await queryRunner.dropView("member_executive_positions_view"); + // await queryRunner.dropView("member_qualifications_view"); + // await queryRunner.dropView("member_view"); + + await queryRunner.createView( + new View({ + name: "member_view", + expression: (datasource: DataSource) => + datasource + .getRepository(member) + .createQueryBuilder("member") + .select("member.id", "id") + .addSelect("member.firstname", "firstname") + .addSelect("member.lastname", "lastname") + .addSelect("member.nameaffix", "nameaffix") + .addSelect("member.birthdate", "birthdate") + .addSelect("salutation.salutation", "salutation") + .addSelect("TIMESTAMPDIFF(YEAR, member.birthdate, CURDATE())", "todayAge") + .addSelect("YEAR(CURDATE()) - YEAR(member.birthdate)", "ageThisYear") + .addSelect("CONCAT('_', FROM_DAYS(TIMESTAMPDIFF(DAY, member.birthdate, CURDATE())))", "exactAge") + .leftJoin("member.salutation", "salutation"), + }), + true + ); + await queryRunner.createView( + new View({ + name: "member_executive_positions_view", + expression: (datasource: DataSource) => + datasource + .getRepository(memberExecutivePositions) + .createQueryBuilder("memberExecutivePositions") + .select("executivePosition.id", "positionId") + .addSelect("executivePosition.position", "position") + .addSelect("member.id", "memberId") + .addSelect("member.firstname", "memberFirstname") + .addSelect("member.lastname", "memberLastname") + .addSelect("member.nameaffix", "memberNameaffix") + .addSelect("member.birthdate", "memberBirthdate") + .addSelect("salutation.salutation", "memberSalutation") + .addSelect( + "SUM(TIMESTAMPDIFF(DAY, memberExecutivePositions.start, COALESCE(memberExecutivePositions.end, CURRENT_DATE)))", + "durationInDays" + ) + .leftJoin("memberExecutivePositions.executivePosition", "executivePosition") + .leftJoin("memberExecutivePositions.member", "member") + .leftJoin("member.salutation", "salutation") + .groupBy("executivePosition.id") + .addGroupBy("member.id"), + }), + true + ); + await queryRunner.createView( + new View({ + name: "member_qualifications_view", + expression: (datasource: DataSource) => + datasource + .getRepository(memberQualifications) + .createQueryBuilder("memberQualifications") + .select("qualification.id", "qualificationId") + .addSelect("qualification.qualification", "qualification") + .addSelect("member.id", "memberId") + .addSelect("member.firstname", "memberFirstname") + .addSelect("member.lastname", "memberLastname") + .addSelect("member.nameaffix", "memberNameaffix") + .addSelect("member.birthdate", "memberBirthdate") + .addSelect("salutation.salutation", "memberSalutation") + .addSelect( + "SUM(TIMESTAMPDIFF(DAY, memberQualifications.start, COALESCE(memberQualifications.end, CURRENT_DATE)))", + "durationInDays" + ) + .leftJoin("memberQualifications.qualification", "qualification") + .leftJoin("memberQualifications.member", "member") + .leftJoin("member.salutation", "salutation") + .groupBy("qualification.id") + .addGroupBy("member.id"), + }), + true + ); + await queryRunner.createView( + new View({ + name: "membership_view", + expression: (datasource: DataSource) => + datasource + .getRepository(membership) + .createQueryBuilder("membership") + .select("status.id", "statusId") + .addSelect("status.status", "status") + .addSelect("member.id", "memberId") + .addSelect("member.firstname", "memberFirstname") + .addSelect("member.lastname", "memberLastname") + .addSelect("member.nameaffix", "memberNameaffix") + .addSelect("member.birthdate", "memberBirthdate") + .addSelect("salutation.salutation", "memberSalutation") + .addSelect( + "SUM(TIMESTAMPDIFF(DAY, membership.start, COALESCE(membership.end, CURRENT_DATE)))", + "durationInDays" + ) + .addSelect( + "CONCAT('_', FROM_DAYS(SUM(TIMESTAMPDIFF(DAY, membership.start, COALESCE(membership.end, CURRENT_DATE)))))", + "durationInYears" + ) + .leftJoin("membership.status", "status") + .leftJoin("membership.member", "member") + .leftJoin("member.salutation", "salutation") + .groupBy("status.id") + .addGroupBy("member.id"), + }), + true + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.dropView("membership_view"); + await queryRunner.dropView("member_executive_positions_view"); + await queryRunner.dropView("member_qualifications_view"); + await queryRunner.dropView("member_view"); + + await queryRunner.createView( + new View({ + name: "member_view", + expression: (datasource: DataSource) => + datasource + .getRepository(member) + .createQueryBuilder("member") + .select("member.id", "id") + .addSelect("member.salutation", "salutation") + .addSelect("member.firstname", "firstname") + .addSelect("member.lastname", "lastname") + .addSelect("member.nameaffix", "nameaffix") + .addSelect("member.birthdate", "birthdate") + .addSelect("TIMESTAMPDIFF(YEAR, member.birthdate, CURDATE())", "todayAge") + .addSelect("YEAR(CURDATE()) - YEAR(member.birthdate)", "ageThisYear") + .addSelect("CONCAT('_', FROM_DAYS(TIMESTAMPDIFF(DAY, member.birthdate, CURDATE())))", "exactAge"), + }), + true + ); + await queryRunner.createView( + new View({ + name: "member_executive_positions_view", + expression: (datasource: DataSource) => + datasource + .getRepository(memberExecutivePositions) + .createQueryBuilder("memberExecutivePositions") + .select("executivePosition.id", "positionId") + .addSelect("executivePosition.position", "position") + .addSelect("member.id", "memberId") + .addSelect("member.salutation", "memberSalutation") + .addSelect("member.firstname", "memberFirstname") + .addSelect("member.lastname", "memberLastname") + .addSelect("member.nameaffix", "memberNameaffix") + .addSelect("member.birthdate", "memberBirthdate") + .addSelect( + "SUM(TIMESTAMPDIFF(DAY, memberExecutivePositions.start, COALESCE(memberExecutivePositions.end, CURRENT_DATE)))", + "durationInDays" + ) + .leftJoin("memberExecutivePositions.executivePosition", "executivePosition") + .leftJoin("memberExecutivePositions.member", "member") + .groupBy("executivePosition.id"), + }), + true + ); + await queryRunner.createView( + new View({ + name: "member_qualifications_view", + expression: (datasource: DataSource) => + datasource + .getRepository(memberQualifications) + .createQueryBuilder("memberQualifications") + .select("qualification.id", "qualificationId") + .addSelect("qualification.qualification", "qualification") + .addSelect("member.id", "memberId") + .addSelect("member.salutation", "memberSalutation") + .addSelect("member.firstname", "memberFirstname") + .addSelect("member.lastname", "memberLastname") + .addSelect("member.nameaffix", "memberNameaffix") + .addSelect("member.birthdate", "memberBirthdate") + .addSelect( + "SUM(TIMESTAMPDIFF(DAY, memberQualifications.start, COALESCE(memberQualifications.end, CURRENT_DATE)))", + "durationInDays" + ) + .leftJoin("memberQualifications.qualification", "qualification") + .leftJoin("memberQualifications.member", "member") + .groupBy("qualification.id"), + }), + true + ); + await queryRunner.createView( + new View({ + name: "membership_view", + expression: (datasource: DataSource) => + datasource + .getRepository(membership) + .createQueryBuilder("membership") + .select("status.id", "statusId") + .addSelect("status.status", "status") + .addSelect("member.id", "memberId") + .addSelect("member.salutation", "memberSalutation") + .addSelect("member.firstname", "memberFirstname") + .addSelect("member.lastname", "memberLastname") + .addSelect("member.nameaffix", "memberNameaffix") + .addSelect("member.birthdate", "memberBirthdate") + .addSelect( + "SUM(TIMESTAMPDIFF(DAY, membership.start, COALESCE(membership.end, CURRENT_DATE)))", + "durationInDays" + ) + .addSelect( + "CONCAT('_', FROM_DAYS(SUM(TIMESTAMPDIFF(DAY, membership.start, COALESCE(membership.end, CURRENT_DATE)))))", + "durationInYears" + ) + .leftJoin("membership.status", "status") + .leftJoin("membership.member", "member") + .groupBy("status.id") + .addGroupBy("member.id"), + }), + true + ); + } +}