From a40ba4b41e431d9e8df1a5b34ae8e608d9815f7e Mon Sep 17 00:00:00 2001 From: Philipinho <16838612+Philipinho@users.noreply.github.com> Date: Fri, 22 Mar 2024 23:42:19 +0000 Subject: [PATCH] Re-initialize database migrations (3rd try) --- .../server/src/database/migrations/.gitignore | 3 - .../database/migrations/1711150216801-init.ts | 269 ++++++++++++++++++ .../1711150304333-AddTsvectorTrigger.ts | 28 ++ .../1711150345785-AddTSVColumnIndex.ts | 15 + apps/server/src/database/naming-strategy.ts | 10 +- apps/server/src/database/typeorm.config.ts | 12 +- 6 files changed, 324 insertions(+), 13 deletions(-) delete mode 100644 apps/server/src/database/migrations/.gitignore create mode 100644 apps/server/src/database/migrations/1711150216801-init.ts create mode 100644 apps/server/src/database/migrations/1711150304333-AddTsvectorTrigger.ts create mode 100644 apps/server/src/database/migrations/1711150345785-AddTSVColumnIndex.ts diff --git a/apps/server/src/database/migrations/.gitignore b/apps/server/src/database/migrations/.gitignore deleted file mode 100644 index 5f8b170..0000000 --- a/apps/server/src/database/migrations/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -# don't include frequently changing migrations yet -#* -#!.gitignore diff --git a/apps/server/src/database/migrations/1711150216801-init.ts b/apps/server/src/database/migrations/1711150216801-init.ts new file mode 100644 index 0000000..5d3d531 --- /dev/null +++ b/apps/server/src/database/migrations/1711150216801-init.ts @@ -0,0 +1,269 @@ +import { MigrationInterface, QueryRunner } from 'typeorm'; + +export class Init1711150216801 implements MigrationInterface { + name = 'Init1711150216801'; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TABLE "comments" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "content" jsonb, "selection" character varying(255), "type" character varying(55), "creatorId" uuid NOT NULL, "pageId" uuid NOT NULL, "parentCommentId" uuid, "resolvedById" uuid, "resolvedAt" TIMESTAMP, "workspaceId" uuid NOT NULL, "createdAt" TIMESTAMP NOT NULL DEFAULT now(), "editedAt" TIMESTAMP, "deletedAt" TIMESTAMP, CONSTRAINT "PK_comments" PRIMARY KEY ("id"))`, + ); + await queryRunner.query( + `CREATE TABLE "group_users" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "userId" uuid NOT NULL, "groupId" uuid NOT NULL, "createdAt" TIMESTAMP NOT NULL DEFAULT now(), "updatedAt" TIMESTAMP NOT NULL DEFAULT now(), CONSTRAINT "UQ_group_users_groupId_userId" UNIQUE ("groupId", "userId"), CONSTRAINT "PK_group_users" PRIMARY KEY ("id"))`, + ); + await queryRunner.query( + `CREATE TABLE "groups" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "name" character varying(255) NOT NULL, "description" text, "isDefault" boolean NOT NULL DEFAULT false, "workspaceId" uuid NOT NULL, "creatorId" uuid, "createdAt" TIMESTAMP NOT NULL DEFAULT now(), "updatedAt" TIMESTAMP NOT NULL DEFAULT now(), CONSTRAINT "UQ_groups_name_workspaceId" UNIQUE ("name", "workspaceId"), CONSTRAINT "PK_groups" PRIMARY KEY ("id"))`, + ); + await queryRunner.query( + `CREATE TABLE "space_members" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "userId" uuid, "groupId" uuid, "spaceId" uuid NOT NULL, "role" character varying(100) NOT NULL, "creatorId" uuid, "createdAt" TIMESTAMP NOT NULL DEFAULT now(), "updatedAt" TIMESTAMP NOT NULL DEFAULT now(), CONSTRAINT "UQ_space_members_spaceId_groupId" UNIQUE ("spaceId", "groupId"), CONSTRAINT "UQ_space_members_spaceId_userId" UNIQUE ("spaceId", "userId"), CONSTRAINT "CHK_allow_userId_or_groupId" CHECK (("userId" IS NOT NULL AND "groupId" IS NULL) OR ("userId" IS NULL AND "groupId" IS NOT NULL)), CONSTRAINT "PK_space_members" PRIMARY KEY ("id"))`, + ); + await queryRunner.query( + `CREATE TABLE "spaces" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "name" character varying(255), "description" text, "slug" character varying, "icon" character varying(255), "visibility" character varying(100) NOT NULL DEFAULT 'open', "defaultRole" character varying(100) NOT NULL DEFAULT 'writer', "creatorId" uuid, "workspaceId" uuid NOT NULL, "createdAt" TIMESTAMP NOT NULL DEFAULT now(), "updatedAt" TIMESTAMP NOT NULL DEFAULT now(), CONSTRAINT "UQ_spaces_slug_workspaceId" UNIQUE ("slug", "workspaceId"), CONSTRAINT "PK_spaces" PRIMARY KEY ("id"))`, + ); + await queryRunner.query( + `CREATE TABLE "page_history" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "pageId" uuid NOT NULL, "title" character varying(500), "content" jsonb, "slug" character varying, "icon" character varying, "coverPhoto" character varying, "version" integer NOT NULL, "lastUpdatedById" uuid NOT NULL, "spaceId" uuid NOT NULL, "workspaceId" uuid NOT NULL, "createdAt" TIMESTAMP NOT NULL DEFAULT now(), "updatedAt" TIMESTAMP NOT NULL DEFAULT now(), CONSTRAINT "PK_page_history" PRIMARY KEY ("id"))`, + ); + await queryRunner.query( + `CREATE TABLE "pages" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "title" character varying(500), "icon" character varying, "content" jsonb, "html" text, "textContent" text, "tsv" tsvector, "ydoc" bytea, "slug" character varying, "coverPhoto" character varying, "editor" character varying(255), "shareId" character varying(255), "parentPageId" uuid, "creatorId" uuid NOT NULL, "lastUpdatedById" uuid, "deletedById" uuid, "spaceId" uuid NOT NULL, "workspaceId" uuid NOT NULL, "isLocked" boolean NOT NULL DEFAULT false, "status" character varying(255), "publishedAt" date, "createdAt" TIMESTAMP NOT NULL DEFAULT now(), "updatedAt" TIMESTAMP NOT NULL DEFAULT now(), "deletedAt" TIMESTAMP, CONSTRAINT "PK_pages" PRIMARY KEY ("id"))`, + ); + await queryRunner.query( + `CREATE TABLE "users" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "name" character varying(255), "email" character varying(255) NOT NULL, "emailVerifiedAt" TIMESTAMP, "password" character varying NOT NULL, "avatarUrl" character varying, "role" character varying(100), "workspaceId" uuid, "locale" character varying(100), "timezone" character varying(300), "settings" jsonb, "lastLoginAt" TIMESTAMP, "lastLoginIp" character varying(100), "createdAt" TIMESTAMP NOT NULL DEFAULT now(), "updatedAt" TIMESTAMP NOT NULL DEFAULT now(), CONSTRAINT "UQ_users_email_workspaceId" UNIQUE ("email", "workspaceId"), CONSTRAINT "PK_users" PRIMARY KEY ("id"))`, + ); + await queryRunner.query( + `CREATE TABLE "workspaces" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "name" character varying(255), "description" text, "logo" character varying(255), "hostname" character varying(255), "customDomain" character varying(255), "enableInvite" boolean NOT NULL DEFAULT true, "inviteCode" character varying(255), "settings" jsonb, "defaultRole" character varying NOT NULL DEFAULT 'member', "creatorId" uuid, "defaultSpaceId" uuid, "createdAt" TIMESTAMP NOT NULL DEFAULT now(), "updatedAt" TIMESTAMP NOT NULL DEFAULT now(), "deletedAt" TIMESTAMP, CONSTRAINT "UQ_workspaces_hostname" UNIQUE ("hostname"), CONSTRAINT "UQ_workspaces_inviteCode" UNIQUE ("inviteCode"), CONSTRAINT "REL_workspaces_creatorId" UNIQUE ("creatorId"), CONSTRAINT "REL_workspaces_defaultSpaceId" UNIQUE ("defaultSpaceId"), CONSTRAINT "PK_workspaces" PRIMARY KEY ("id"))`, + ); + await queryRunner.query( + `CREATE TABLE "workspace_invitations" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "workspaceId" uuid NOT NULL, "invitedById" uuid NOT NULL, "email" character varying(255) NOT NULL, "role" character varying(100), "status" character varying(100), "createdAt" TIMESTAMP NOT NULL DEFAULT now(), "updatedAt" TIMESTAMP NOT NULL DEFAULT now(), CONSTRAINT "PK_workspace_invitations" PRIMARY KEY ("id"))`, + ); + await queryRunner.query( + `CREATE TABLE "page_ordering" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "entityId" uuid NOT NULL, "entityType" character varying(50) NOT NULL, "childrenIds" uuid array NOT NULL DEFAULT '{}', "workspaceId" uuid NOT NULL, "spaceId" uuid NOT NULL, "deletedAt" TIMESTAMP, "createdAt" TIMESTAMP NOT NULL DEFAULT now(), "updatedAt" TIMESTAMP NOT NULL DEFAULT now(), CONSTRAINT "UQ_page_ordering_entityId_entityType" UNIQUE ("entityId", "entityType"), CONSTRAINT "PK_page_ordering" PRIMARY KEY ("id"))`, + ); + await queryRunner.query( + `CREATE TABLE "attachments" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "fileName" character varying(255) NOT NULL, "filePath" character varying NOT NULL, "fileSize" bigint NOT NULL, "fileExt" character varying(55) NOT NULL, "mimeType" character varying(255) NOT NULL, "type" character varying(55) NOT NULL, "creatorId" uuid NOT NULL, "pageId" uuid, "workspaceId" uuid, "createdAt" TIMESTAMP NOT NULL DEFAULT now(), "deletedAt" TIMESTAMP, CONSTRAINT "PK_attachments" PRIMARY KEY ("id"))`, + ); + await queryRunner.query( + `ALTER TABLE "comments" ADD CONSTRAINT "FK_comments_users_creatorId" FOREIGN KEY ("creatorId") REFERENCES "users"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "comments" ADD CONSTRAINT "FK_comments_pages_pageId" FOREIGN KEY ("pageId") REFERENCES "pages"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "comments" ADD CONSTRAINT "FK_comments_comments_parentCommentId" FOREIGN KEY ("parentCommentId") REFERENCES "comments"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "comments" ADD CONSTRAINT "FK_comments_users_resolvedById" FOREIGN KEY ("resolvedById") REFERENCES "users"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "comments" ADD CONSTRAINT "FK_comments_workspaces_workspaceId" FOREIGN KEY ("workspaceId") REFERENCES "workspaces"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "group_users" ADD CONSTRAINT "FK_group_users_users_userId" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "group_users" ADD CONSTRAINT "FK_group_users_groups_groupId" FOREIGN KEY ("groupId") REFERENCES "groups"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "groups" ADD CONSTRAINT "FK_groups_workspaces_workspaceId" FOREIGN KEY ("workspaceId") REFERENCES "workspaces"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "groups" ADD CONSTRAINT "FK_groups_users_creatorId" FOREIGN KEY ("creatorId") REFERENCES "users"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "space_members" ADD CONSTRAINT "FK_space_members_users_userId" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "space_members" ADD CONSTRAINT "FK_space_members_groups_groupId" FOREIGN KEY ("groupId") REFERENCES "groups"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "space_members" ADD CONSTRAINT "FK_space_members_spaces_spaceId" FOREIGN KEY ("spaceId") REFERENCES "spaces"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "space_members" ADD CONSTRAINT "FK_space_members_users_creatorId" FOREIGN KEY ("creatorId") REFERENCES "users"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "spaces" ADD CONSTRAINT "FK_spaces_users_creatorId" FOREIGN KEY ("creatorId") REFERENCES "users"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "spaces" ADD CONSTRAINT "FK_spaces_workspaces_workspaceId" FOREIGN KEY ("workspaceId") REFERENCES "workspaces"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "page_history" ADD CONSTRAINT "FK_page_history_pages_pageId" FOREIGN KEY ("pageId") REFERENCES "pages"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "page_history" ADD CONSTRAINT "FK_page_history_users_lastUpdatedById" FOREIGN KEY ("lastUpdatedById") REFERENCES "users"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "page_history" ADD CONSTRAINT "FK_page_history_spaces_spaceId" FOREIGN KEY ("spaceId") REFERENCES "spaces"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "page_history" ADD CONSTRAINT "FK_page_history_workspaces_workspaceId" FOREIGN KEY ("workspaceId") REFERENCES "workspaces"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "pages" ADD CONSTRAINT "FK_pages_users_creatorId" FOREIGN KEY ("creatorId") REFERENCES "users"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "pages" ADD CONSTRAINT "FK_pages_users_lastUpdatedById" FOREIGN KEY ("lastUpdatedById") REFERENCES "users"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "pages" ADD CONSTRAINT "FK_pages_users_deletedById" FOREIGN KEY ("deletedById") REFERENCES "users"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "pages" ADD CONSTRAINT "FK_pages_spaces_spaceId" FOREIGN KEY ("spaceId") REFERENCES "spaces"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "pages" ADD CONSTRAINT "FK_pages_workspaces_workspaceId" FOREIGN KEY ("workspaceId") REFERENCES "workspaces"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "pages" ADD CONSTRAINT "FK_pages_pages_parentPageId" FOREIGN KEY ("parentPageId") REFERENCES "pages"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "users" ADD CONSTRAINT "FK_users_workspaces_workspaceId" FOREIGN KEY ("workspaceId") REFERENCES "workspaces"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "workspaces" ADD CONSTRAINT "FK_workspaces_users_creatorId" FOREIGN KEY ("creatorId") REFERENCES "users"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "workspaces" ADD CONSTRAINT "FK_workspaces_spaces_defaultSpaceId" FOREIGN KEY ("defaultSpaceId") REFERENCES "spaces"("id") ON DELETE SET NULL ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "workspace_invitations" ADD CONSTRAINT "FK_workspace_invitations_workspaces_workspaceId" FOREIGN KEY ("workspaceId") REFERENCES "workspaces"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "workspace_invitations" ADD CONSTRAINT "FK_workspace_invitations_users_invitedById" FOREIGN KEY ("invitedById") REFERENCES "users"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "page_ordering" ADD CONSTRAINT "FK_page_ordering_workspaces_workspaceId" FOREIGN KEY ("workspaceId") REFERENCES "workspaces"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "page_ordering" ADD CONSTRAINT "FK_page_ordering_spaces_spaceId" FOREIGN KEY ("spaceId") REFERENCES "spaces"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "attachments" ADD CONSTRAINT "FK_attachments_users_creatorId" FOREIGN KEY ("creatorId") REFERENCES "users"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "attachments" ADD CONSTRAINT "FK_attachments_pages_pageId" FOREIGN KEY ("pageId") REFERENCES "pages"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "attachments" ADD CONSTRAINT "FK_attachments_workspaces_workspaceId" FOREIGN KEY ("workspaceId") REFERENCES "workspaces"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "attachments" DROP CONSTRAINT "FK_attachments_workspaces_workspaceId"`, + ); + await queryRunner.query( + `ALTER TABLE "attachments" DROP CONSTRAINT "FK_attachments_pages_pageId"`, + ); + await queryRunner.query( + `ALTER TABLE "attachments" DROP CONSTRAINT "FK_attachments_users_creatorId"`, + ); + await queryRunner.query( + `ALTER TABLE "page_ordering" DROP CONSTRAINT "FK_page_ordering_spaces_spaceId"`, + ); + await queryRunner.query( + `ALTER TABLE "page_ordering" DROP CONSTRAINT "FK_page_ordering_workspaces_workspaceId"`, + ); + await queryRunner.query( + `ALTER TABLE "workspace_invitations" DROP CONSTRAINT "FK_workspace_invitations_users_invitedById"`, + ); + await queryRunner.query( + `ALTER TABLE "workspace_invitations" DROP CONSTRAINT "FK_workspace_invitations_workspaces_workspaceId"`, + ); + await queryRunner.query( + `ALTER TABLE "workspaces" DROP CONSTRAINT "FK_workspaces_spaces_defaultSpaceId"`, + ); + await queryRunner.query( + `ALTER TABLE "workspaces" DROP CONSTRAINT "FK_workspaces_users_creatorId"`, + ); + await queryRunner.query( + `ALTER TABLE "users" DROP CONSTRAINT "FK_users_workspaces_workspaceId"`, + ); + await queryRunner.query( + `ALTER TABLE "pages" DROP CONSTRAINT "FK_pages_pages_parentPageId"`, + ); + await queryRunner.query( + `ALTER TABLE "pages" DROP CONSTRAINT "FK_pages_workspaces_workspaceId"`, + ); + await queryRunner.query( + `ALTER TABLE "pages" DROP CONSTRAINT "FK_pages_spaces_spaceId"`, + ); + await queryRunner.query( + `ALTER TABLE "pages" DROP CONSTRAINT "FK_pages_users_deletedById"`, + ); + await queryRunner.query( + `ALTER TABLE "pages" DROP CONSTRAINT "FK_pages_users_lastUpdatedById"`, + ); + await queryRunner.query( + `ALTER TABLE "pages" DROP CONSTRAINT "FK_pages_users_creatorId"`, + ); + await queryRunner.query( + `ALTER TABLE "page_history" DROP CONSTRAINT "FK_page_history_workspaces_workspaceId"`, + ); + await queryRunner.query( + `ALTER TABLE "page_history" DROP CONSTRAINT "FK_page_history_spaces_spaceId"`, + ); + await queryRunner.query( + `ALTER TABLE "page_history" DROP CONSTRAINT "FK_page_history_users_lastUpdatedById"`, + ); + await queryRunner.query( + `ALTER TABLE "page_history" DROP CONSTRAINT "FK_page_history_pages_pageId"`, + ); + await queryRunner.query( + `ALTER TABLE "spaces" DROP CONSTRAINT "FK_spaces_workspaces_workspaceId"`, + ); + await queryRunner.query( + `ALTER TABLE "spaces" DROP CONSTRAINT "FK_spaces_users_creatorId"`, + ); + await queryRunner.query( + `ALTER TABLE "space_members" DROP CONSTRAINT "FK_space_members_users_creatorId"`, + ); + await queryRunner.query( + `ALTER TABLE "space_members" DROP CONSTRAINT "FK_space_members_spaces_spaceId"`, + ); + await queryRunner.query( + `ALTER TABLE "space_members" DROP CONSTRAINT "FK_space_members_groups_groupId"`, + ); + await queryRunner.query( + `ALTER TABLE "space_members" DROP CONSTRAINT "FK_space_members_users_userId"`, + ); + await queryRunner.query( + `ALTER TABLE "groups" DROP CONSTRAINT "FK_groups_users_creatorId"`, + ); + await queryRunner.query( + `ALTER TABLE "groups" DROP CONSTRAINT "FK_groups_workspaces_workspaceId"`, + ); + await queryRunner.query( + `ALTER TABLE "group_users" DROP CONSTRAINT "FK_group_users_groups_groupId"`, + ); + await queryRunner.query( + `ALTER TABLE "group_users" DROP CONSTRAINT "FK_group_users_users_userId"`, + ); + await queryRunner.query( + `ALTER TABLE "comments" DROP CONSTRAINT "FK_comments_workspaces_workspaceId"`, + ); + await queryRunner.query( + `ALTER TABLE "comments" DROP CONSTRAINT "FK_comments_users_resolvedById"`, + ); + await queryRunner.query( + `ALTER TABLE "comments" DROP CONSTRAINT "FK_comments_comments_parentCommentId"`, + ); + await queryRunner.query( + `ALTER TABLE "comments" DROP CONSTRAINT "FK_comments_pages_pageId"`, + ); + await queryRunner.query( + `ALTER TABLE "comments" DROP CONSTRAINT "FK_comments_users_creatorId"`, + ); + await queryRunner.query(`DROP TABLE "attachments"`); + await queryRunner.query(`DROP TABLE "page_ordering"`); + await queryRunner.query(`DROP TABLE "workspace_invitations"`); + await queryRunner.query(`DROP TABLE "workspaces"`); + await queryRunner.query(`DROP TABLE "users"`); + await queryRunner.query(`DROP TABLE "pages"`); + await queryRunner.query(`DROP TABLE "page_history"`); + await queryRunner.query(`DROP TABLE "spaces"`); + await queryRunner.query(`DROP TABLE "space_members"`); + await queryRunner.query(`DROP TABLE "groups"`); + await queryRunner.query(`DROP TABLE "group_users"`); + await queryRunner.query(`DROP TABLE "comments"`); + } +} diff --git a/apps/server/src/database/migrations/1711150304333-AddTsvectorTrigger.ts b/apps/server/src/database/migrations/1711150304333-AddTsvectorTrigger.ts new file mode 100644 index 0000000..e9ffa42 --- /dev/null +++ b/apps/server/src/database/migrations/1711150304333-AddTsvectorTrigger.ts @@ -0,0 +1,28 @@ +import { MigrationInterface, QueryRunner } from 'typeorm'; + +export class AddTsvectorTrigger1711150304333 implements MigrationInterface { + name = 'AddTsvectorTrigger1711150304333'; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + CREATE FUNCTION pages_tsvector_trigger() RETURNS trigger AS $$ + begin + new.tsv := + setweight(to_tsvector('english', coalesce(new.title, '')), 'A') || + setweight(to_tsvector('english', coalesce(new.\"textContent\", '')), 'B'); + return new; + end; + $$ LANGUAGE plpgsql; + `); + + await queryRunner.query(` + CREATE TRIGGER pages_tsvector_update BEFORE INSERT OR UPDATE + ON pages FOR EACH ROW EXECUTE FUNCTION pages_tsvector_trigger(); + `); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`DROP TRIGGER pages_tsvector_update ON Pages`); + await queryRunner.query(`DROP FUNCTION pages_tsvector_trigger`); + } +} diff --git a/apps/server/src/database/migrations/1711150345785-AddTSVColumnIndex.ts b/apps/server/src/database/migrations/1711150345785-AddTSVColumnIndex.ts new file mode 100644 index 0000000..5ac50bf --- /dev/null +++ b/apps/server/src/database/migrations/1711150345785-AddTSVColumnIndex.ts @@ -0,0 +1,15 @@ +import { MigrationInterface, QueryRunner } from 'typeorm'; + +export class AddTSVColumnIndex1711150345785 implements MigrationInterface { + name = 'AddTSVColumnIndex1711150345785'; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE INDEX "IDX_pages_tsv" ON pages USING GIN ("tsv");`, + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`DROP INDEX IF EXISTS "IDX_pages_tsv";`); + } +} diff --git a/apps/server/src/database/naming-strategy.ts b/apps/server/src/database/naming-strategy.ts index 120f4fa..1ea0214 100644 --- a/apps/server/src/database/naming-strategy.ts +++ b/apps/server/src/database/naming-strategy.ts @@ -3,7 +3,7 @@ import { DefaultNamingStrategy, Table } from 'typeorm'; export class NamingStrategy extends DefaultNamingStrategy { primaryKeyName(tableOrName: Table | string, columnNames: string[]): string { const tableName = this.normalizeTableName(tableOrName); - return `pk_${tableName}_${columnNames.join('_')}`; + return `PK_${tableName}`; } indexName( @@ -16,7 +16,7 @@ export class NamingStrategy extends DefaultNamingStrategy { let name = `${tableName}_${columnNames.join('_')}`; if (where) name += '_' + where; - return `idx_${name}`; + return `IDX_${name}`; } uniqueConstraintName( @@ -25,7 +25,7 @@ export class NamingStrategy extends DefaultNamingStrategy { ): string { const tableName = this.normalizeTableName(tableOrName); - return `uq_${tableName}_${columnNames.join('_')}`; + return `UQ_${tableName}_${columnNames.join('_')}`; } foreignKeyName( @@ -38,7 +38,7 @@ export class NamingStrategy extends DefaultNamingStrategy { const targetTable = this.normalizeTableName(_referencedTablePath); const name = `${tableName}_${targetTable}_${columnNames.join('_')}`; - return `fk_${name}`; + return `FK_${name}`; } relationConstraintName( @@ -51,7 +51,7 @@ export class NamingStrategy extends DefaultNamingStrategy { let name = `${tableName}_${columnNames.join('_')}`; if (where) name += '_' + where; - return `rel_${name}`; + return `REL_${name}`; } normalizeTableName(tableOrName: Table | string): string { diff --git a/apps/server/src/database/typeorm.config.ts b/apps/server/src/database/typeorm.config.ts index 4a96c2a..544dfcd 100644 --- a/apps/server/src/database/typeorm.config.ts +++ b/apps/server/src/database/typeorm.config.ts @@ -1,16 +1,18 @@ import { DataSource } from 'typeorm'; import * as dotenv from 'dotenv'; import { NamingStrategy } from './naming-strategy'; -dotenv.config(); +import * as path from 'path'; +const envPath = path.resolve(process.cwd(), '..', '..', '.env'); + +dotenv.config({ path: envPath }); + export const AppDataSource: DataSource = new DataSource({ type: 'postgres', - url: - process.env.DATABASE_URL || - 'postgresql://postgres:password@localhost:5432/dc?schema=public', + url: process.env.DATABASE_URL, entities: ['src/**/*.entity.{ts,js}'], migrations: ['src/**/migrations/*.{ts,js}'], subscribers: [], synchronize: false, - //namingStrategy: new NamingStrategy(), + namingStrategy: new NamingStrategy(), logging: process.env.NODE_ENV === 'development', });