import { Injectable } from '@nestjs/common'; import { DataSource } from 'typeorm'; import { DataSourceMetadataService } from 'src/metadata/data-source-metadata/data-source-metadata.service'; import { TypeORMService } from 'src/database/typeorm/typeorm.service'; @Injectable() export class TenantDataSourceService { constructor( private readonly dataSourceMetadataService: DataSourceMetadataService, private readonly typeormService: TypeORMService, ) {} /** * * Connect to the workspace data source * * @param workspaceId * @returns */ public async connectToWorkspaceDataSource( workspaceId: string, ): Promise { const dataSourceMetadata = await this.dataSourceMetadataService.getLastDataSourceMetadataFromWorkspaceIdOrFail( workspaceId, ); const dataSource = await this.typeormService.connectToDataSource( dataSourceMetadata, ); if (!dataSource) { throw new Error( `Could not connect to workspace data source for workspace ${workspaceId}`, ); } return dataSource; } /** * * Create a new DB schema for a workspace * * @param workspaceId * @returns */ public async createWorkspaceDBSchema(workspaceId: string): Promise { const schemaName = this.getSchemaName(workspaceId); return await this.typeormService.createSchema(schemaName); } /** * * Delete a DB schema for a workspace * * @param workspaceId * @returns */ public async deleteWorkspaceDBSchema(workspaceId: string): Promise { const schemaName = this.getSchemaName(workspaceId); return await this.typeormService.deleteSchema(schemaName); } /** * * Get the schema name for a workspace * * @param workspaceId * @returns string */ public getSchemaName(workspaceId: string): string { return `workspace_${this.uuidToBase36(workspaceId)}`; } /** * * Convert a uuid to base36 * * @param uuid * @returns string */ private uuidToBase36(uuid: string): string { let devId = false; if (uuid.startsWith('twenty-')) { devId = true; // Clean dev uuids (twenty-) uuid = uuid.replace('twenty-', ''); } const hexString = uuid.replace(/-/g, ''); const base10Number = BigInt('0x' + hexString); const base36String = base10Number.toString(36); return `${devId ? 'twenty_' : ''}${base36String}`; } }