Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert listing address jsonb columns to separate address tables #1512

Merged
merged 3 commits into from
Jul 20, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ All notable changes to this project will be documented in this file. The format

- Changed:
- User module has been removed and incorporated into Auth module
- convert listing address jsonb columns to separate address tables
- removed unused inverse relations from entities

### Frontend

Expand Down Expand Up @@ -79,7 +81,6 @@ All notable changes to this project will be documented in this file. The format
- Cleanup seed data generation and add more variety ([#1312](https://github.com/bloom-housing/bloom/pull/1312)) Emily Jablonski
- Moved Property model to Listing (https://github.com/bloom-housing/bloom/issues/1328)
- removed eager relation to listing from User model
- removed unused inverse relations from entities

### Frontend

Expand Down
20 changes: 12 additions & 8 deletions backend/core/src/listings/dto/listing.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ import { ReservedCommunityTypeDto } from "../../reserved-community-type/dto/rese
import { AssetCreateDto, AssetDto, AssetUpdateDto } from "../../assets/dto/asset.dto"

export class ListingDto extends OmitType(Listing, [
"applicationAddress",
"applicationPickUpAddress",
"applicationDropOffAddress",
"applicationMailingAddress",
"applications",
"image",
"jurisdiction",
Expand Down Expand Up @@ -63,14 +67,14 @@ export class ListingDto extends OmitType(Listing, [
@Expose()
@IsOptional({ groups: [ValidationsGroupsEnum.default] })
@ValidateNested({ groups: [ValidationsGroupsEnum.default] })
@Type(() => AddressCreateDto)
applicationDropOffAddress: AddressCreateDto | null
@Type(() => AddressDto)
applicationDropOffAddress: AddressDto | null

@Expose()
@IsOptional({ groups: [ValidationsGroupsEnum.default] })
@ValidateNested({ groups: [ValidationsGroupsEnum.default] })
@Type(() => AddressCreateDto)
applicationMailingAddress: AddressCreateDto | null
@Type(() => AddressDto)
applicationMailingAddress: AddressDto | null

@Expose()
@IsOptional({ groups: [ValidationsGroupsEnum.default] })
Expand Down Expand Up @@ -543,14 +547,14 @@ export class ListingUpdateDto extends OmitType(ListingDto, [
@Expose()
@IsOptional({ groups: [ValidationsGroupsEnum.default] })
@ValidateNested({ groups: [ValidationsGroupsEnum.default] })
@Type(() => AddressCreateDto)
applicationDropOffAddress: AddressCreateDto | null
@Type(() => AddressUpdateDto)
applicationDropOffAddress: AddressUpdateDto | null

@Expose()
@IsOptional({ groups: [ValidationsGroupsEnum.default] })
@ValidateNested({ groups: [ValidationsGroupsEnum.default] })
@Type(() => AddressCreateDto)
applicationMailingAddress: AddressCreateDto | null
@Type(() => AddressUpdateDto)
applicationMailingAddress: AddressUpdateDto | null

@Expose()
@IsOptional({ groups: [ValidationsGroupsEnum.default] })
Expand Down
32 changes: 16 additions & 16 deletions backend/core/src/listings/entities/listing.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@ import { ListingEventDto } from "../dto/listing-event.dto"
import { ApplicationMethodDto } from "../dto/application-method.dto"
import { CSVFormattingType } from "../../csv/types/csv-formatting-type-enum"
import { CountyCode } from "../../shared/types/county-code"
import { AddressDto } from "../../shared/dto/address.dto"
import { Jurisdiction } from "../../jurisdictions/entities/jurisdiction.entity"
import { ReservedCommunityType } from "../../reserved-community-type/entities/reserved-community-type.entity"
import { Asset } from "../../assets/entities/asset.entity"
import { AssetCreateDto } from "../../assets/dto/asset.dto"
import { ListingApplicationAddressType } from "../types/listing-application-address-type"
import { Address } from "../../shared/entities/address.entity"

@Entity({ name: "listings" })
class Listing extends BaseEntity {
Expand Down Expand Up @@ -137,19 +137,19 @@ class Listing extends BaseEntity {
@IsString({ groups: [ValidationsGroupsEnum.default] })
applicationOrganization?: string | null

@Column({ type: "jsonb", nullable: true })
@ManyToOne(() => Address, { eager: true, nullable: true, cascade: true })
@Expose()
@IsOptional({ groups: [ValidationsGroupsEnum.default] })
@ValidateNested({ groups: [ValidationsGroupsEnum.default] })
@Type(() => AddressDto)
applicationAddress?: AddressDto | null
@Type(() => Address)
applicationAddress?: Address | null

@Column({ type: "jsonb", nullable: true })
@ManyToOne(() => Address, { eager: true, nullable: true, cascade: true })
@Expose()
@IsOptional({ groups: [ValidationsGroupsEnum.default] })
@ValidateNested({ groups: [ValidationsGroupsEnum.default] })
@Type(() => AddressDto)
applicationPickUpAddress?: AddressDto | null
@Type(() => Address)
applicationPickUpAddress?: Address | null

@Column({ type: "text", nullable: true })
@Expose()
Expand All @@ -167,12 +167,12 @@ class Listing extends BaseEntity {
})
applicationPickUpAddressType?: ListingApplicationAddressType | null

@Column({ type: "jsonb", nullable: true })
@ManyToOne(() => Address, { eager: true, nullable: true, cascade: true })
@Expose()
@IsOptional({ groups: [ValidationsGroupsEnum.default] })
@ValidateNested({ groups: [ValidationsGroupsEnum.default] })
@Type(() => AddressDto)
applicationDropOffAddress?: AddressDto | null
@Type(() => Address)
applicationDropOffAddress?: Address | null

@Column({ type: "text", nullable: true })
@Expose()
Expand All @@ -190,12 +190,12 @@ class Listing extends BaseEntity {
})
applicationDropOffAddressType?: ListingApplicationAddressType | null

@Column({ type: "jsonb", nullable: true })
@ManyToOne(() => Address, { eager: true, nullable: true, cascade: true })
@Expose()
@IsOptional({ groups: [ValidationsGroupsEnum.default] })
@ValidateNested({ groups: [ValidationsGroupsEnum.default] })
@Type(() => AddressDto)
applicationMailingAddress?: AddressDto | null
@Type(() => Address)
applicationMailingAddress?: Address | null

@Column({ type: "text", nullable: true })
@Expose()
Expand Down Expand Up @@ -246,12 +246,12 @@ class Listing extends BaseEntity {
@Type(() => Jurisdiction)
jurisdiction?: Jurisdiction | null

@Column({ type: "jsonb", nullable: true })
@ManyToOne(() => Address, { eager: true, nullable: true, cascade: true })
@Expose()
@IsOptional({ groups: [ValidationsGroupsEnum.default] })
@ValidateNested({ groups: [ValidationsGroupsEnum.default] })
@Type(() => AddressDto)
leasingAgentAddress?: AddressDto | null
@Type(() => Address)
leasingAgentAddress?: Address | null

@Column({ type: "text", nullable: true })
@Expose()
Expand Down
5 changes: 5 additions & 0 deletions backend/core/src/listings/listings.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ export class ListingsService {
return Listing.createQueryBuilder("listings")
.leftJoinAndSelect("listings.image", "image")
.leftJoinAndSelect("listings.result", "result")
.leftJoinAndSelect("listings.applicationAddress", "applicationAddress")
.leftJoinAndSelect("listings.leasingAgentAddress", "leasingAgentAddress")
.leftJoinAndSelect("listings.applicationPickUpAddress", "applicationPickUpAddress")
.leftJoinAndSelect("listings.applicationMailingAddress", "applicationMailingAddress")
.leftJoinAndSelect("listings.applicationDropOffAddress", "applicationDropOffAddress")
.leftJoinAndSelect("listings.leasingAgents", "leasingAgents")
.leftJoinAndSelect("listings.preferences", "preferences")
.leftJoinAndSelect("listings.property", "property")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import {MigrationInterface, QueryRunner} from "typeorm";
import { Address } from "../shared/entities/address.entity"

export class convertListingAddressesJsonbsToTables1626258763008 implements MigrationInterface {
name = 'convertListingAddressesJsonbsToTables1626258763008'

public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "listings" ADD "application_address_id" uuid`);
await queryRunner.query(`ALTER TABLE "listings" ADD "application_pick_up_address_id" uuid`);
await queryRunner.query(`ALTER TABLE "listings" ADD "application_drop_off_address_id" uuid`);
await queryRunner.query(`ALTER TABLE "listings" ADD "application_mailing_address_id" uuid`);
await queryRunner.query(`ALTER TABLE "listings" ADD "leasing_agent_address_id" uuid`);

const listings = await queryRunner.query(`SELECT id, application_address, leasing_agent_address, application_pick_up_address, application_mailing_address, application_drop_off_address FROM listings`)
for(const listing of listings) {
const addressKeys = ["application_address", "leasing_agent_address", "application_pick_up_address", "application_mailing_address", "application_drop_off_address"]
for(const addressKey of addressKeys) {
if (listing[addressKey]) {
const addr = listing[addressKey] as Address
const [addrId] = await queryRunner.query(`INSERT INTO "address" (place_name, city, county, state, street, street2, zip_code, latitude, longitude) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) RETURNING id`, [
addr.placeName, addr.city, addr.county, addr.state, addr.street, addr.street2, addr.zipCode, addr.latitude, addr.longitude
]);
await queryRunner.query(`UPDATE listings SET ${addressKey}_id = ($1) WHERE id = ($2)`, [addrId.id, listing.id])
}
}
}

await queryRunner.query(`ALTER TABLE "listings" DROP COLUMN "application_address"`);
await queryRunner.query(`ALTER TABLE "listings" DROP COLUMN "leasing_agent_address"`);
await queryRunner.query(`ALTER TABLE "listings" DROP COLUMN "application_pick_up_address"`);
await queryRunner.query(`ALTER TABLE "listings" DROP COLUMN "application_mailing_address"`);
await queryRunner.query(`ALTER TABLE "listings" DROP COLUMN "application_drop_off_address"`);
await queryRunner.query(`ALTER TABLE "listings" ALTER COLUMN "name" SET NOT NULL`);
await queryRunner.query(`ALTER TABLE "listings" ADD CONSTRAINT "FK_42385e47be1780d1491f0c8c1c3" FOREIGN KEY ("application_address_id") REFERENCES "address"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "listings" ADD CONSTRAINT "FK_d54596fd877e83a3126d3953f36" FOREIGN KEY ("application_pick_up_address_id") REFERENCES "address"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "listings" ADD CONSTRAINT "FK_17e861d96c1bde13c1f4c344cb6" FOREIGN KEY ("application_drop_off_address_id") REFERENCES "address"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "listings" ADD CONSTRAINT "FK_7cedb0a800e3c0af7ede27ab1ec" FOREIGN KEY ("application_mailing_address_id") REFERENCES "address"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "listings" ADD CONSTRAINT "FK_8a93cc462d190d3f1a04fa69156" FOREIGN KEY ("leasing_agent_address_id") REFERENCES "address"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`);
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "listings" DROP CONSTRAINT "FK_8a93cc462d190d3f1a04fa69156"`);
await queryRunner.query(`ALTER TABLE "listings" DROP CONSTRAINT "FK_7cedb0a800e3c0af7ede27ab1ec"`);
await queryRunner.query(`ALTER TABLE "listings" DROP CONSTRAINT "FK_17e861d96c1bde13c1f4c344cb6"`);
await queryRunner.query(`ALTER TABLE "listings" DROP CONSTRAINT "FK_d54596fd877e83a3126d3953f36"`);
await queryRunner.query(`ALTER TABLE "listings" DROP CONSTRAINT "FK_42385e47be1780d1491f0c8c1c3"`);
await queryRunner.query(`ALTER TABLE "listings" ALTER COLUMN "name" DROP NOT NULL`);
await queryRunner.query(`ALTER TABLE "listings" DROP COLUMN "leasing_agent_address_id"`);
await queryRunner.query(`ALTER TABLE "listings" DROP COLUMN "application_mailing_address_id"`);
await queryRunner.query(`ALTER TABLE "listings" DROP COLUMN "application_drop_off_address_id"`);
await queryRunner.query(`ALTER TABLE "listings" DROP COLUMN "application_pick_up_address_id"`);
await queryRunner.query(`ALTER TABLE "listings" DROP COLUMN "application_address_id"`);
await queryRunner.query(`ALTER TABLE "listings" ADD "application_drop_off_address" jsonb`);
await queryRunner.query(`ALTER TABLE "listings" ADD "application_mailing_address" jsonb`);
await queryRunner.query(`ALTER TABLE "listings" ADD "application_pick_up_address" jsonb`);
await queryRunner.query(`ALTER TABLE "listings" ADD "leasing_agent_address" jsonb`);
await queryRunner.query(`ALTER TABLE "listings" ADD "application_address" jsonb`);
}

}
4 changes: 2 additions & 2 deletions backend/core/types/src/backend-swagger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4931,8 +4931,8 @@ export enum ListingEventType {
}
export type CombinedApplicationAddressTypes = AddressUpdate;
export type CombinedApplicationPickUpAddressTypes = AddressUpdate;
export type CombinedApplicationDropOffAddressTypes = AddressCreate;
export type CombinedApplicationMailingAddressTypes = AddressCreate;
export type CombinedApplicationDropOffAddressTypes = AddressUpdate;
export type CombinedApplicationMailingAddressTypes = AddressUpdate;
export type CombinedImageTypes = AssetCreate;
export type CombinedLeasingAgentAddressTypes = AddressUpdate;
export type CombinedResultTypes = AssetCreate;
Expand Down