denormalize Events/Notes relation

This commit is contained in:
ssmucny 2023-04-16 16:13:11 -04:00
parent a56561f8aa
commit 173a901eee
4 changed files with 75 additions and 1 deletions

View File

@ -0,0 +1,29 @@
export class Event1681675881633 {
name = 'Event1681675881633'
async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "note" RENAME COLUMN "isEvent" TO "hasEvent"`);
await queryRunner.query(`CREATE TYPE "public"."event_notevisibility_enum" AS ENUM('public', 'home', 'followers', 'specified')`);
await queryRunner.query(`ALTER TABLE "event" ADD "noteVisibility" "public"."event_notevisibility_enum" NOT NULL`);
await queryRunner.query(`COMMENT ON COLUMN "event"."noteVisibility" IS '[Denormalized]'`);
await queryRunner.query(`ALTER TABLE "event" ADD "userId" character varying(32) NOT NULL`);
await queryRunner.query(`COMMENT ON COLUMN "event"."userId" IS '[Denormalized]'`);
await queryRunner.query(`ALTER TABLE "event" ADD "userHost" character varying(128)`);
await queryRunner.query(`COMMENT ON COLUMN "event"."userHost" IS '[Denormalized]'`);
await queryRunner.query(`CREATE INDEX "IDX_01cd2b829e0263917bf570cb67" ON "event" ("userId") `);
await queryRunner.query(`CREATE INDEX "IDX_f6ba57dff679ccbcfe004698ec" ON "event" ("userHost") `);
}
async down(queryRunner) {
await queryRunner.query(`DROP INDEX "public"."IDX_f6ba57dff679ccbcfe004698ec"`);
await queryRunner.query(`DROP INDEX "public"."IDX_01cd2b829e0263917bf570cb67"`);
await queryRunner.query(`COMMENT ON COLUMN "event"."userHost" IS '[Denormalized]'`);
await queryRunner.query(`ALTER TABLE "event" DROP COLUMN "userHost"`);
await queryRunner.query(`COMMENT ON COLUMN "event"."userId" IS '[Denormalized]'`);
await queryRunner.query(`ALTER TABLE "event" DROP COLUMN "userId"`);
await queryRunner.query(`COMMENT ON COLUMN "event"."noteVisibility" IS '[Denormalized]'`);
await queryRunner.query(`ALTER TABLE "event" DROP COLUMN "noteVisibility"`);
await queryRunner.query(`DROP TYPE "public"."event_notevisibility_enum"`);
await queryRunner.query(`ALTER TABLE "note" RENAME COLUMN "hasEvent" TO "isEvent"`);
}
}

View File

@ -1,6 +1,8 @@
import { Entity, Index, Column, PrimaryColumn, OneToOne, JoinColumn } from 'typeorm';
import { id } from '../id.js';
import { noteVisibilities } from '../../types.js';
import { Note } from './Note.js';
import type { User } from './User.js';
@Entity()
export class Event {
@ -37,4 +39,41 @@ export class Event {
comment: 'metadata mapping for event with more user configurable optional information',
})
public metadata: Record<string, string>;
//#region Denormalized fields
@Column('enum', {
enum: noteVisibilities,
comment: '[Denormalized]',
})
public noteVisibility: typeof noteVisibilities[number];
@Index()
@Column({
...id(),
comment: '[Denormalized]',
})
public userId: User['id'];
@Index()
@Column('varchar', {
length: 128, nullable: true,
comment: '[Denormalized]',
})
public userHost: string | null;
//#endregion
constructor(data: Partial<Event>) {
if (data == null) return;
for (const [k, v] of Object.entries(data)) {
(this as any)[k] = v;
}
}
}
export type IEvent = {
start: Date;
end: Date | null
title: string;
metadata: Record<string, string>;
}

View File

@ -56,7 +56,7 @@ export class Note {
@Column('boolean', {
default: false,
})
public isEvent: boolean;
public hasEvent: boolean;
// TODO: varcharにしたい
@Column('text', {

View File

@ -150,6 +150,12 @@ export type Note = {
replyId: Note['id'];
renote?: Note;
renoteId: Note['id'];
event?: {
title: string,
start: DateString,
end: DateString | null,
metadata: Record<string, string>,
};
files: DriveFile[];
fileIds: DriveFile['id'][];
visibility: 'public' | 'home' | 'followers' | 'specified';