Convert metadata tables to camel_case (#2420)

* Convert metadata tables to camelcase

* refactor folder structure

* rename datasourcemetadata

* regenerate metadata schema

* rename dataSourceMetadata to dataSource
This commit is contained in:
Weiko
2023-11-10 15:33:25 +01:00
committed by GitHub
parent 6e7ad5eabc
commit 04c618284f
98 changed files with 1189 additions and 1735 deletions

View File

@ -0,0 +1,66 @@
import { InjectDataSource } from '@nestjs/typeorm';
import { Command, CommandRunner } from 'nest-commander';
import { DataSource } from 'typeorm';
import { DataSourceService } from 'src/metadata/data-source/data-source.service';
import { TenantMigrationService } from 'src/metadata/tenant-migration/tenant-migration.service';
import { TenantMigrationRunnerService } from 'src/tenant-migration-runner/tenant-migration-runner.service';
import { seedCompanies } from 'src/database/typeorm-seeds/tenant/companies';
import { seedViewFields } from 'src/database/typeorm-seeds/tenant/view-fields';
import { seedViews } from 'src/database/typeorm-seeds/tenant/views';
import { seedFieldMetadata } from 'src/database/typeorm-seeds/metadata/field-metadata';
import { seedObjectMetadata } from 'src/database/typeorm-seeds/metadata/object-metadata';
import { TypeORMService } from 'src/database/typeorm/typeorm.service';
// TODO: implement dry-run
@Command({
name: 'tenant:seed',
description:
'Seed tenant with initial data. This command is intended for development only.',
})
export class DataSeedTenantCommand extends CommandRunner {
workspaceId = 'twenty-7ed9d212-1c25-4d02-bf25-6aeccf7ea419';
constructor(
@InjectDataSource('metadata')
private readonly metadataDataSource: DataSource,
private readonly dataSourceService: DataSourceService,
private readonly typeORMService: TypeORMService,
private readonly tenantMigrationService: TenantMigrationService,
private readonly migrationRunnerService: TenantMigrationRunnerService,
) {
super();
}
async run(): Promise<void> {
const dataSourceMetadata =
await this.dataSourceService.getLastDataSourceMetadataFromWorkspaceIdOrFail(
this.workspaceId,
);
const workspaceDataSource = await this.typeORMService.connectToDataSource(
dataSourceMetadata,
);
if (!workspaceDataSource) {
throw new Error('Could not connect to workspace data source');
}
await seedObjectMetadata(this.metadataDataSource, 'metadata');
await seedFieldMetadata(this.metadataDataSource, 'metadata');
await this.tenantMigrationService.insertStandardMigrations(
this.workspaceId,
);
await this.migrationRunnerService.executeMigrationFromPendingMigrations(
this.workspaceId,
);
await seedCompanies(workspaceDataSource, dataSourceMetadata.schema);
await seedViewFields(workspaceDataSource, dataSourceMetadata.schema);
await seedViews(workspaceDataSource, dataSourceMetadata.schema);
await this.typeORMService.disconnectFromDataSource(dataSourceMetadata.id);
}
}

View File

@ -2,21 +2,36 @@ import { Module } from '@nestjs/common';
import { DataCleanInactiveCommand } from 'src/database/commands/clean-inactive-workspaces.command';
import { ConfirmationQuestion } from 'src/database/commands/questions/confirmation.question';
import { WorkspaceService } from 'src/core/workspace/services/workspace.service';
import { PipelineModule } from 'src/core/pipeline/pipeline.module';
import { CompanyModule } from 'src/core/company/company.module';
import { PersonModule } from 'src/core/person/person.module';
import { TenantInitialisationModule } from 'src/metadata/tenant-initialisation/tenant-initialisation.module';
import { PrismaModule } from 'src/database/prisma.module';
import { TenantManagerModule } from 'src/tenant-manager/tenant-manager.module';
import { DataSourceModule } from 'src/metadata/data-source/data-source.module';
import { TenantMigrationModule } from 'src/metadata/tenant-migration/tenant-migration.module';
import { TenantMigrationRunnerModule } from 'src/tenant-migration-runner/tenant-migration-runner.module';
import { TypeORMModule } from 'src/database/typeorm/typeorm.module';
import { WorkspaceModule } from 'src/core/workspace/workspace.module';
import { DataSeedTenantCommand } from './data-seed-tenant.command';
@Module({
imports: [
PipelineModule,
CompanyModule,
PersonModule,
TenantInitialisationModule,
TenantManagerModule,
PrismaModule,
DataSourceModule,
TypeORMModule,
TenantMigrationModule,
TenantMigrationRunnerModule,
WorkspaceModule,
],
providers: [
DataSeedTenantCommand,
DataCleanInactiveCommand,
ConfirmationQuestion,
],
providers: [DataCleanInactiveCommand, ConfirmationQuestion, WorkspaceService],
})
export class DatabaseCommandModule {}

View File

@ -5,8 +5,8 @@ export const seedMetadata = async (prisma: PrismaClient) => {
'CREATE SCHEMA IF NOT EXISTS workspace_twenty_7icsva0r6s00mpcp6cwg4w4rd',
);
await prisma.$queryRawUnsafe(
`INSERT INTO metadata.data_source_metadata(
id, schema, type, workspace_id
`INSERT INTO metadata."dataSource"(
id, schema, type, "workspaceId"
)
VALUES (
'b37b2163-7f63-47a9-b1b3-6c7290ca9fb1', 'workspace_twenty_7icsva0r6s00mpcp6cwg4w4rd', 'postgres', 'twenty-7ed9d212-1c25-4d02-bf25-6aeccf7ea419'

View File

@ -1,6 +1,6 @@
import { DataSource } from 'typeorm';
const tableName = 'field_metadata';
const tableName = 'fieldMetadata';
export const seedFieldMetadata = async (
workspaceDataSource: DataSource,
@ -10,7 +10,7 @@ export const seedFieldMetadata = async (
.createQueryBuilder()
.insert()
.into(`${schemaName}.${tableName}`, [
'objectId',
'objectMetadataId',
'isCustom',
'workspaceId',
'isActive',
@ -26,7 +26,7 @@ export const seedFieldMetadata = async (
.values([
// Companies
{
objectId: '1a8487a0-480c-434e-b4c7-e22408b97047',
objectMetadataId: '1a8487a0-480c-434e-b4c7-e22408b97047',
isCustom: false,
workspaceId: 'twenty-7ed9d212-1c25-4d02-bf25-6aeccf7ea419',
isActive: true,
@ -41,7 +41,7 @@ export const seedFieldMetadata = async (
isNullable: false,
},
{
objectId: '1a8487a0-480c-434e-b4c7-e22408b97047',
objectMetadataId: '1a8487a0-480c-434e-b4c7-e22408b97047',
isCustom: false,
workspaceId: 'twenty-7ed9d212-1c25-4d02-bf25-6aeccf7ea419',
isActive: true,
@ -56,7 +56,7 @@ export const seedFieldMetadata = async (
isNullable: true,
},
{
objectId: '1a8487a0-480c-434e-b4c7-e22408b97047',
objectMetadataId: '1a8487a0-480c-434e-b4c7-e22408b97047',
isCustom: false,
workspaceId: 'twenty-7ed9d212-1c25-4d02-bf25-6aeccf7ea419',
isActive: true,
@ -71,7 +71,7 @@ export const seedFieldMetadata = async (
isNullable: true,
},
{
objectId: '1a8487a0-480c-434e-b4c7-e22408b97047',
objectMetadataId: '1a8487a0-480c-434e-b4c7-e22408b97047',
isCustom: false,
workspaceId: 'twenty-7ed9d212-1c25-4d02-bf25-6aeccf7ea419',
isActive: true,
@ -87,7 +87,7 @@ export const seedFieldMetadata = async (
},
// Views
{
objectId: '9ab6b3dc-767f-473f-8fd0-6cdbefbf8dbe',
objectMetadataId: '9ab6b3dc-767f-473f-8fd0-6cdbefbf8dbe',
isCustom: false,
workspaceId: 'twenty-7ed9d212-1c25-4d02-bf25-6aeccf7ea419',
isActive: true,
@ -102,13 +102,13 @@ export const seedFieldMetadata = async (
isNullable: false,
},
{
objectId: '9ab6b3dc-767f-473f-8fd0-6cdbefbf8dbe',
objectMetadataId: '9ab6b3dc-767f-473f-8fd0-6cdbefbf8dbe',
isCustom: false,
workspaceId: 'twenty-7ed9d212-1c25-4d02-bf25-6aeccf7ea419',
isActive: true,
type: 'TEXT',
name: 'objectMetadataId',
label: 'Object Id',
label: 'Object Metadata Id',
targetColumnMap: {
value: 'objectMetadataId',
},
@ -117,7 +117,7 @@ export const seedFieldMetadata = async (
isNullable: false,
},
{
objectId: '9ab6b3dc-767f-473f-8fd0-6cdbefbf8dbe',
objectMetadataId: '9ab6b3dc-767f-473f-8fd0-6cdbefbf8dbe',
isCustom: false,
workspaceId: 'twenty-7ed9d212-1c25-4d02-bf25-6aeccf7ea419',
isActive: true,
@ -133,13 +133,13 @@ export const seedFieldMetadata = async (
},
// View Fields
{
objectId: '61d9000b-485c-4c48-a22e-0d9a164f9647',
objectMetadataId: '61d9000b-485c-4c48-a22e-0d9a164f9647',
isCustom: false,
workspaceId: 'twenty-7ed9d212-1c25-4d02-bf25-6aeccf7ea419',
isActive: true,
type: 'TEXT',
name: 'fieldMetadataId',
label: 'Field Id',
label: 'Field Metadata Id',
targetColumnMap: {
value: 'fieldMetadataId',
},
@ -148,7 +148,7 @@ export const seedFieldMetadata = async (
isNullable: false,
},
{
objectId: '61d9000b-485c-4c48-a22e-0d9a164f9647',
objectMetadataId: '61d9000b-485c-4c48-a22e-0d9a164f9647',
isCustom: false,
workspaceId: 'twenty-7ed9d212-1c25-4d02-bf25-6aeccf7ea419',
isActive: true,
@ -163,7 +163,7 @@ export const seedFieldMetadata = async (
isNullable: false,
},
{
objectId: '61d9000b-485c-4c48-a22e-0d9a164f9647',
objectMetadataId: '61d9000b-485c-4c48-a22e-0d9a164f9647',
isCustom: false,
workspaceId: 'twenty-7ed9d212-1c25-4d02-bf25-6aeccf7ea419',
isActive: true,
@ -178,7 +178,7 @@ export const seedFieldMetadata = async (
isNullable: false,
},
{
objectId: '61d9000b-485c-4c48-a22e-0d9a164f9647',
objectMetadataId: '61d9000b-485c-4c48-a22e-0d9a164f9647',
isCustom: false,
workspaceId: 'twenty-7ed9d212-1c25-4d02-bf25-6aeccf7ea419',
isActive: true,
@ -193,7 +193,7 @@ export const seedFieldMetadata = async (
isNullable: false,
},
{
objectId: '61d9000b-485c-4c48-a22e-0d9a164f9647',
objectMetadataId: '61d9000b-485c-4c48-a22e-0d9a164f9647',
isCustom: false,
workspaceId: 'twenty-7ed9d212-1c25-4d02-bf25-6aeccf7ea419',
isActive: true,
@ -209,13 +209,13 @@ export const seedFieldMetadata = async (
},
// View Filters
{
objectId: '5d9b1ab9-4461-4e2d-bf9e-9b47e68846d3',
objectMetadataId: '5d9b1ab9-4461-4e2d-bf9e-9b47e68846d3',
isCustom: false,
workspaceId: 'twenty-7ed9d212-1c25-4d02-bf25-6aeccf7ea419',
isActive: true,
type: 'TEXT',
name: 'fieldMetadataId',
label: 'Field Id',
label: 'Field Metadata Id',
targetColumnMap: {
value: 'fieldMetadataId',
},
@ -224,7 +224,7 @@ export const seedFieldMetadata = async (
isNullable: false,
},
{
objectId: '5d9b1ab9-4461-4e2d-bf9e-9b47e68846d3',
objectMetadataId: '5d9b1ab9-4461-4e2d-bf9e-9b47e68846d3',
isCustom: false,
workspaceId: 'twenty-7ed9d212-1c25-4d02-bf25-6aeccf7ea419',
isActive: true,
@ -239,7 +239,7 @@ export const seedFieldMetadata = async (
isNullable: false,
},
{
objectId: '5d9b1ab9-4461-4e2d-bf9e-9b47e68846d3',
objectMetadataId: '5d9b1ab9-4461-4e2d-bf9e-9b47e68846d3',
isCustom: false,
workspaceId: 'twenty-7ed9d212-1c25-4d02-bf25-6aeccf7ea419',
isActive: true,
@ -254,7 +254,7 @@ export const seedFieldMetadata = async (
isNullable: false,
},
{
objectId: '5d9b1ab9-4461-4e2d-bf9e-9b47e68846d3',
objectMetadataId: '5d9b1ab9-4461-4e2d-bf9e-9b47e68846d3',
isCustom: false,
workspaceId: 'twenty-7ed9d212-1c25-4d02-bf25-6aeccf7ea419',
isActive: true,
@ -269,7 +269,7 @@ export const seedFieldMetadata = async (
isNullable: false,
},
{
objectId: '5d9b1ab9-4461-4e2d-bf9e-9b47e68846d3',
objectMetadataId: '5d9b1ab9-4461-4e2d-bf9e-9b47e68846d3',
isCustom: false,
workspaceId: 'twenty-7ed9d212-1c25-4d02-bf25-6aeccf7ea419',
isActive: true,
@ -285,7 +285,7 @@ export const seedFieldMetadata = async (
},
// View Sorts
{
objectId: '6f8dcd4b-cf28-41dd-b98b-d6e1f5b3a251',
objectMetadataId: '6f8dcd4b-cf28-41dd-b98b-d6e1f5b3a251',
isCustom: false,
workspaceId: 'twenty-7ed9d212-1c25-4d02-bf25-6aeccf7ea419',
isActive: true,
@ -300,7 +300,7 @@ export const seedFieldMetadata = async (
isNullable: false,
},
{
objectId: '6f8dcd4b-cf28-41dd-b98b-d6e1f5b3a251',
objectMetadataId: '6f8dcd4b-cf28-41dd-b98b-d6e1f5b3a251',
isCustom: false,
workspaceId: 'twenty-7ed9d212-1c25-4d02-bf25-6aeccf7ea419',
isActive: true,
@ -315,7 +315,7 @@ export const seedFieldMetadata = async (
isNullable: false,
},
{
objectId: '6f8dcd4b-cf28-41dd-b98b-d6e1f5b3a251',
objectMetadataId: '6f8dcd4b-cf28-41dd-b98b-d6e1f5b3a251',
isCustom: false,
workspaceId: 'twenty-7ed9d212-1c25-4d02-bf25-6aeccf7ea419',
isActive: true,

View File

@ -1,6 +1,6 @@
import { DataSource } from 'typeorm';
const tableName = 'object_metadata';
const tableName = 'objectMetadata';
export const seedObjectMetadata = async (
workspaceDataSource: DataSource,

View File

@ -0,0 +1,21 @@
import { ConfigService } from '@nestjs/config';
import { TypeOrmModuleOptions } from '@nestjs/typeorm';
import { DataSource, DataSourceOptions } from 'typeorm';
import { config } from 'dotenv';
config();
const configService = new ConfigService();
export const typeORMMetadataModuleOptions: TypeOrmModuleOptions = {
url: configService.get<string>('PG_DATABASE_URL'),
type: 'postgres',
logging: ['error'],
schema: 'metadata',
entities: ['dist/src/metadata/**/*.entity{.ts,.js}'],
synchronize: false,
migrationsRun: false,
migrationsTableName: '_typeorm_migrations',
migrations: [__dirname + '/migrations/*{.ts,.js}'],
};
export const connectionSource = new DataSource(
typeORMMetadataModuleOptions as DataSourceOptions,
);

View File

@ -0,0 +1,65 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
export class SetupMetadataTables1699619603804 implements MigrationInterface {
name = 'SetupMetadataTables1699619603804';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`CREATE TYPE "metadata"."dataSource_type_enum" AS ENUM('postgres')`,
);
await queryRunner.query(
`CREATE TABLE "metadata"."dataSource" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "url" character varying, "schema" character varying, "type" "metadata"."dataSource_type_enum" NOT NULL DEFAULT 'postgres', "label" character varying, "isRemote" boolean NOT NULL DEFAULT false, "workspaceId" character varying NOT NULL, "createdAt" TIMESTAMP NOT NULL DEFAULT now(), "updatedAt" TIMESTAMP NOT NULL DEFAULT now(), CONSTRAINT "PK_6d01ae6c0f47baf4f8e37342268" PRIMARY KEY ("id"))`,
);
await queryRunner.query(
`CREATE TABLE "metadata"."relationMetadata" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "relationType" character varying NOT NULL, "fromObjectMetadataId" uuid NOT NULL, "toObjectMetadataId" uuid NOT NULL, "fromFieldMetadataId" uuid NOT NULL, "toFieldMetadataId" uuid NOT NULL, "workspaceId" character varying NOT NULL, "createdAt" TIMESTAMP NOT NULL DEFAULT now(), "updatedAt" TIMESTAMP NOT NULL DEFAULT now(), CONSTRAINT "REL_3deb257254145a3bdde9575e7d" UNIQUE ("fromFieldMetadataId"), CONSTRAINT "REL_9dea8f90d04edbbf9c541a95c3" UNIQUE ("toFieldMetadataId"), CONSTRAINT "PK_2724f60cb4f17a89481a7e8d7d3" PRIMARY KEY ("id"))`,
);
await queryRunner.query(
`CREATE TABLE "metadata"."fieldMetadata" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "objectMetadataId" uuid NOT NULL, "type" character varying NOT NULL, "name" character varying NOT NULL, "label" character varying NOT NULL, "targetColumnMap" jsonb NOT NULL, "description" text, "icon" character varying, "enums" text array, "isCustom" boolean NOT NULL DEFAULT false, "isActive" boolean NOT NULL DEFAULT false, "isNullable" boolean DEFAULT true, "workspaceId" character varying NOT NULL, "createdAt" TIMESTAMP NOT NULL DEFAULT now(), "updatedAt" TIMESTAMP NOT NULL DEFAULT now(), CONSTRAINT "IndexOnNameObjectMetadataIdAndWorkspaceIdUnique" UNIQUE ("name", "objectMetadataId", "workspaceId"), CONSTRAINT "PK_d046b1c7cea325ebc4cdc25e7a9" PRIMARY KEY ("id"))`,
);
await queryRunner.query(
`CREATE TABLE "metadata"."objectMetadata" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "dataSourceId" character varying NOT NULL, "nameSingular" character varying NOT NULL, "namePlural" character varying NOT NULL, "labelSingular" character varying NOT NULL, "labelPlural" character varying NOT NULL, "description" text, "icon" character varying, "targetTableName" character varying NOT NULL, "isCustom" boolean NOT NULL DEFAULT false, "isActive" boolean NOT NULL DEFAULT false, "workspaceId" character varying NOT NULL, "createdAt" TIMESTAMP NOT NULL DEFAULT now(), "updatedAt" TIMESTAMP NOT NULL DEFAULT now(), CONSTRAINT "IndexOnNamePluralAndWorkspaceIdUnique" UNIQUE ("namePlural", "workspaceId"), CONSTRAINT "IndexOnNameSingularAndWorkspaceIdUnique" UNIQUE ("nameSingular", "workspaceId"), CONSTRAINT "PK_81fb7f4f4244211cfbd188af1e8" PRIMARY KEY ("id"))`,
);
await queryRunner.query(
`CREATE TABLE "metadata"."tenantMigration" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "migrations" jsonb, "name" character varying, "isCustom" boolean NOT NULL DEFAULT false, "appliedAt" TIMESTAMP, "workspaceId" character varying NOT NULL, "createdAt" TIMESTAMP NOT NULL DEFAULT now(), CONSTRAINT "PK_f9b06eb42494795f73acb5c2350" PRIMARY KEY ("id"))`,
);
await queryRunner.query(
`ALTER TABLE "metadata"."relationMetadata" ADD CONSTRAINT "FK_f2a0acd3a548ee446a1a35df44d" FOREIGN KEY ("fromObjectMetadataId") REFERENCES "metadata"."objectMetadata"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`,
);
await queryRunner.query(
`ALTER TABLE "metadata"."relationMetadata" ADD CONSTRAINT "FK_0f781f589e5a527b8f3d3a4b824" FOREIGN KEY ("toObjectMetadataId") REFERENCES "metadata"."objectMetadata"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`,
);
await queryRunner.query(
`ALTER TABLE "metadata"."relationMetadata" ADD CONSTRAINT "FK_3deb257254145a3bdde9575e7d6" FOREIGN KEY ("fromFieldMetadataId") REFERENCES "metadata"."fieldMetadata"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`,
);
await queryRunner.query(
`ALTER TABLE "metadata"."relationMetadata" ADD CONSTRAINT "FK_9dea8f90d04edbbf9c541a95c3b" FOREIGN KEY ("toFieldMetadataId") REFERENCES "metadata"."fieldMetadata"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`,
);
await queryRunner.query(
`ALTER TABLE "metadata"."fieldMetadata" ADD CONSTRAINT "FK_de2a09b9e3e690440480d2dee26" FOREIGN KEY ("objectMetadataId") REFERENCES "metadata"."objectMetadata"("id") ON DELETE CASCADE ON UPDATE NO ACTION`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "metadata"."fieldMetadata" DROP CONSTRAINT "FK_de2a09b9e3e690440480d2dee26"`,
);
await queryRunner.query(
`ALTER TABLE "metadata"."relationMetadata" DROP CONSTRAINT "FK_9dea8f90d04edbbf9c541a95c3b"`,
);
await queryRunner.query(
`ALTER TABLE "metadata"."relationMetadata" DROP CONSTRAINT "FK_3deb257254145a3bdde9575e7d6"`,
);
await queryRunner.query(
`ALTER TABLE "metadata"."relationMetadata" DROP CONSTRAINT "FK_0f781f589e5a527b8f3d3a4b824"`,
);
await queryRunner.query(
`ALTER TABLE "metadata"."relationMetadata" DROP CONSTRAINT "FK_f2a0acd3a548ee446a1a35df44d"`,
);
await queryRunner.query(`DROP TABLE "metadata"."tenantMigration"`);
await queryRunner.query(`DROP TABLE "metadata"."objectMetadata"`);
await queryRunner.query(`DROP TABLE "metadata"."fieldMetadata"`);
await queryRunner.query(`DROP TABLE "metadata"."relationMetadata"`);
await queryRunner.query(`DROP TABLE "metadata"."dataSource"`);
await queryRunner.query(`DROP TYPE "metadata"."dataSource_type_enum"`);
}
}

View File

@ -0,0 +1,23 @@
import { Module } from '@nestjs/common';
import { TypeOrmModule, TypeOrmModuleOptions } from '@nestjs/typeorm';
import { TypeORMService } from './typeorm.service';
import { typeORMMetadataModuleOptions } from './metadata/metadata.datasource';
const metadataTypeORMFactory = async (): Promise<TypeOrmModuleOptions> => ({
...typeORMMetadataModuleOptions,
name: 'metadata',
});
@Module({
imports: [
TypeOrmModule.forRootAsync({
useFactory: metadataTypeORMFactory,
name: 'metadata',
}),
],
providers: [TypeORMService],
exports: [TypeORMService],
})
export class TypeORMModule {}

View File

@ -0,0 +1,105 @@
import { Injectable, OnModuleDestroy, OnModuleInit } from '@nestjs/common';
import { DataSource } from 'typeorm';
import { EnvironmentService } from 'src/integrations/environment/environment.service';
import { DataSourceEntity } from 'src/metadata/data-source/data-source.entity';
@Injectable()
export class TypeORMService implements OnModuleInit, OnModuleDestroy {
private mainDataSource: DataSource;
private dataSources: Map<string, DataSource> = new Map();
constructor(private readonly environmentService: EnvironmentService) {
this.mainDataSource = new DataSource({
url: environmentService.getPGDatabaseUrl(),
type: 'postgres',
logging: false,
schema: 'public',
});
}
/**
* Connects to a data source using metadata. Returns a cached connection if it exists.
* @param dataSource DataSourceEntity
* @returns Promise<DataSource | undefined>
*/
public async connectToDataSource(
dataSource: DataSourceEntity,
): Promise<DataSource | undefined> {
if (this.dataSources.has(dataSource.id)) {
return this.dataSources.get(dataSource.id);
}
const schema = dataSource.schema;
const workspaceDataSource = new DataSource({
url: dataSource.url ?? this.environmentService.getPGDatabaseUrl(),
type: 'postgres',
logging: ['query'],
schema,
});
await workspaceDataSource.initialize();
this.dataSources.set(dataSource.id, workspaceDataSource);
return workspaceDataSource;
}
/**
* Disconnects from a workspace data source.
* @param dataSourceId
* @returns Promise<void>
*
*/
public async disconnectFromDataSource(dataSourceId: string) {
if (!this.dataSources.has(dataSourceId)) {
return;
}
const dataSource = this.dataSources.get(dataSourceId);
await dataSource?.destroy();
this.dataSources.delete(dataSourceId);
}
/**
* Creates a new schema
* @param workspaceId
* @returns Promise<void>
*/
public async createSchema(schemaName: string): Promise<string> {
const queryRunner = this.mainDataSource.createQueryRunner();
await queryRunner.createSchema(schemaName, true);
await queryRunner.release();
return schemaName;
}
public async deleteSchema(schemaName: string) {
const queryRunner = this.mainDataSource.createQueryRunner();
await queryRunner.dropSchema(schemaName, true, true);
await queryRunner.release();
}
async onModuleInit() {
// Init main data source "default" schema
await this.mainDataSource.initialize();
}
async onModuleDestroy() {
// Destroy main data source "default" schema
await this.mainDataSource.destroy();
// Destroy all workspace data sources
for (const [, dataSource] of this.dataSources) {
await dataSource.destroy();
}
}
}