Files
twenty/packages/twenty-server/src/workspace/workspace-manager/workspace-manager.service.ts
Jérémy M 73f6876641 feat: workspace sync (#3505)
* feat: wip workspace sync

* feat: wip lot of debugging

* feat: refactor and fix sync

* fix: clean

fix: clean

* feat: add simple comparator tests

* fix: remove debug

* feat: wip drop table

* fix: main merge

* fix: some issues, and prepare storage system to handle complex deletion

* feat: wip clean and fix

* fix: reflect issue when using array instead of map and clean

* fix: test & sync

* fix: yarn files

* fix: unecesary if-else

* fix: if condition not needed

* fix: remove debug

* fix: replace EQUAL by SKIP

* fix: sync metadata relation not applied properly

* fix: lint issues

* fix: merge issue
2024-01-30 14:40:55 +01:00

176 lines
5.4 KiB
TypeScript

import { Injectable } from '@nestjs/common';
import { DataSourceService } from 'src/metadata/data-source/data-source.service';
import { ObjectMetadataService } from 'src/metadata/object-metadata/object-metadata.service';
import { WorkspaceMigrationService } from 'src/metadata/workspace-migration/workspace-migration.service';
import { standardObjectsPrefillData } from 'src/workspace/workspace-manager/standard-objects-prefill-data/standard-objects-prefill-data';
import { demoObjectsPrefillData } from 'src/workspace/workspace-manager/demo-objects-prefill-data/demo-objects-prefill-data';
import { WorkspaceDataSourceService } from 'src/workspace/workspace-datasource/workspace-datasource.service';
import { DataSourceEntity } from 'src/metadata/data-source/data-source.entity';
import { WorkspaceSyncMetadataService } from 'src/workspace/workspace-sync-metadata/workspace-sync-metadata.service';
@Injectable()
export class WorkspaceManagerService {
constructor(
private readonly workspaceDataSourceService: WorkspaceDataSourceService,
private readonly workspaceMigrationService: WorkspaceMigrationService,
private readonly objectMetadataService: ObjectMetadataService,
private readonly dataSourceService: DataSourceService,
private readonly workspaceSyncMetadataService: WorkspaceSyncMetadataService,
) {}
/**
* Init a workspace by creating a new data source and running all migrations
* @param workspaceId
* @returns Promise<void>
*/
public async init(workspaceId: string): Promise<void> {
const schemaName =
await this.workspaceDataSourceService.createWorkspaceDBSchema(
workspaceId,
);
const dataSourceMetadata =
await this.dataSourceService.createDataSourceMetadata(
workspaceId,
schemaName,
);
await this.setWorkspaceMaxRow(workspaceId, schemaName);
await this.workspaceSyncMetadataService.syncStandardObjectsAndFieldsMetadata(
{
workspaceId,
dataSourceId: dataSourceMetadata.id,
},
);
await this.prefillWorkspaceWithStandardObjects(
dataSourceMetadata,
workspaceId,
);
}
/**
* InitDemo a workspace by creating a new data source and running all migrations
* @param workspaceId
* @returns Promise<void>
*/
public async initDemo(workspaceId: string): Promise<void> {
const schemaName =
await this.workspaceDataSourceService.createWorkspaceDBSchema(
workspaceId,
);
const dataSourceMetadata =
await this.dataSourceService.createDataSourceMetadata(
workspaceId,
schemaName,
);
await this.setWorkspaceMaxRow(workspaceId, schemaName);
await this.workspaceSyncMetadataService.syncStandardObjectsAndFieldsMetadata(
{
workspaceId,
dataSourceId: dataSourceMetadata.id,
},
);
await this.prefillWorkspaceWithDemoObjects(dataSourceMetadata, workspaceId);
}
/**
*
* We are updating the pg_graphql max_rows from 30 (default value) to 60
*
* @params workspaceId, schemaName
* @param workspaceId
*/
private async setWorkspaceMaxRow(workspaceId, schemaName) {
const workspaceDataSource =
await this.workspaceDataSourceService.connectToWorkspaceDataSource(
workspaceId,
);
await workspaceDataSource.query(
`comment on schema ${schemaName} is e'@graphql({"max_rows": 60})'`,
);
}
/**
*
* We are prefilling a few standard objects with data to make it easier for the user to get started.
*
* @param dataSourceMetadata
* @param workspaceId
*/
private async prefillWorkspaceWithStandardObjects(
dataSourceMetadata: DataSourceEntity,
workspaceId: string,
) {
const workspaceDataSource =
await this.workspaceDataSourceService.connectToWorkspaceDataSource(
workspaceId,
);
if (!workspaceDataSource) {
throw new Error('Could not connect to workspace data source');
}
const createdObjectMetadata =
await this.objectMetadataService.findManyWithinWorkspace(workspaceId);
await standardObjectsPrefillData(
workspaceDataSource,
dataSourceMetadata.schema,
createdObjectMetadata,
);
}
/**
*
* We are prefilling a few demo objects with data to make it easier for the user to get started.
*
* @param dataSourceMetadata
* @param workspaceId
*/
private async prefillWorkspaceWithDemoObjects(
dataSourceMetadata: DataSourceEntity,
workspaceId: string,
) {
const workspaceDataSource =
await this.workspaceDataSourceService.connectToWorkspaceDataSource(
workspaceId,
);
if (!workspaceDataSource) {
throw new Error('Could not connect to workspace data source');
}
const createdObjectMetadata =
await this.objectMetadataService.findManyWithinWorkspace(workspaceId);
await demoObjectsPrefillData(
workspaceDataSource,
dataSourceMetadata.schema,
createdObjectMetadata,
);
}
/**
*
* Delete a workspace by deleting all metadata and the schema
*
* @param workspaceId
*/
public async delete(workspaceId: string): Promise<void> {
// Delete data from metadata tables
await this.objectMetadataService.deleteObjectsMetadata(workspaceId);
await this.workspaceMigrationService.delete(workspaceId);
await this.dataSourceService.delete(workspaceId);
// Delete schema
await this.workspaceDataSourceService.deleteWorkspaceDBSchema(workspaceId);
}
}