120 lines
4.2 KiB
TypeScript
120 lines
4.2 KiB
TypeScript
import { Injectable, Logger } from '@nestjs/common';
|
|
import { InjectDataSource } from '@nestjs/typeorm';
|
|
|
|
import { DataSource } from 'typeorm';
|
|
|
|
import { WorkspaceSyncContext } from 'src/workspace/workspace-sync-metadata/interfaces/workspace-sync-context.interface';
|
|
|
|
import { WorkspaceMigrationRunnerService } from 'src/workspace/workspace-migration-runner/workspace-migration-runner.service';
|
|
import { FeatureFlagFactory } from 'src/workspace/workspace-sync-metadata/factories/feature-flags.factory';
|
|
import { WorkspaceSyncObjectMetadataService } from 'src/workspace/workspace-sync-metadata/services/workspace-sync-object-metadata.service';
|
|
import { WorkspaceSyncRelationMetadataService } from 'src/workspace/workspace-sync-metadata/services/workspace-sync-relation-metadata.service';
|
|
import { WorkspaceSyncStorage } from 'src/workspace/workspace-sync-metadata/storage/workspace-sync.storage';
|
|
import { WorkspaceMigrationEntity } from 'src/metadata/workspace-migration/workspace-migration.entity';
|
|
|
|
@Injectable()
|
|
export class WorkspaceSyncMetadataService {
|
|
private readonly logger = new Logger(WorkspaceSyncMetadataService.name);
|
|
|
|
constructor(
|
|
@InjectDataSource('metadata')
|
|
private readonly metadataDataSource: DataSource,
|
|
private readonly featureFlagFactory: FeatureFlagFactory,
|
|
private readonly workspaceMigrationRunnerService: WorkspaceMigrationRunnerService,
|
|
private readonly workspaceSyncObjectMetadataService: WorkspaceSyncObjectMetadataService,
|
|
private readonly workspaceSyncRelationMetadataService: WorkspaceSyncRelationMetadataService,
|
|
) {}
|
|
|
|
/**
|
|
*
|
|
* Sync all standard objects and fields metadata for a given workspace and data source
|
|
* This will update the metadata if it has changed and generate migrations based on the diff.
|
|
*
|
|
* @param dataSourceId
|
|
* @param workspaceId
|
|
*/
|
|
public async syncStandardObjectsAndFieldsMetadata(
|
|
context: WorkspaceSyncContext,
|
|
options: { applyChanges?: boolean } = { applyChanges: true },
|
|
): Promise<{
|
|
workspaceMigrations: WorkspaceMigrationEntity[];
|
|
storage: WorkspaceSyncStorage;
|
|
}> {
|
|
let workspaceMigrations: WorkspaceMigrationEntity[] = [];
|
|
const storage = new WorkspaceSyncStorage();
|
|
const queryRunner = this.metadataDataSource.createQueryRunner();
|
|
|
|
this.logger.log('Syncing standard objects and fields metadata');
|
|
|
|
await queryRunner.connect();
|
|
await queryRunner.startTransaction();
|
|
|
|
const manager = queryRunner.manager;
|
|
|
|
try {
|
|
const workspaceMigrationRepository = manager.getRepository(
|
|
WorkspaceMigrationEntity,
|
|
);
|
|
|
|
// Retrieve feature flags
|
|
const workspaceFeatureFlagsMap =
|
|
await this.featureFlagFactory.create(context);
|
|
|
|
this.logger.log('Syncing standard objects and fields metadata');
|
|
|
|
const workspaceObjectMigrations =
|
|
await this.workspaceSyncObjectMetadataService.synchronize(
|
|
context,
|
|
manager,
|
|
storage,
|
|
workspaceFeatureFlagsMap,
|
|
);
|
|
|
|
const workspaceRelationMigrations =
|
|
await this.workspaceSyncRelationMetadataService.synchronize(
|
|
context,
|
|
manager,
|
|
storage,
|
|
workspaceFeatureFlagsMap,
|
|
);
|
|
|
|
// Save workspace migrations into the database
|
|
workspaceMigrations = await workspaceMigrationRepository.save([
|
|
...workspaceObjectMigrations,
|
|
...workspaceRelationMigrations,
|
|
]);
|
|
|
|
// If we're running a dry run, rollback the transaction and do not execute migrations
|
|
if (!options.applyChanges) {
|
|
this.logger.log('Running in dry run mode, rolling back transaction');
|
|
|
|
await queryRunner.rollbackTransaction();
|
|
|
|
await queryRunner.release();
|
|
|
|
return {
|
|
workspaceMigrations,
|
|
storage,
|
|
};
|
|
}
|
|
|
|
await queryRunner.commitTransaction();
|
|
|
|
// Execute migrations
|
|
await this.workspaceMigrationRunnerService.executeMigrationFromPendingMigrations(
|
|
context.workspaceId,
|
|
);
|
|
} catch (error) {
|
|
console.error('Sync of standard objects failed with:', error);
|
|
await queryRunner.rollbackTransaction();
|
|
} finally {
|
|
await queryRunner.release();
|
|
}
|
|
|
|
return {
|
|
workspaceMigrations,
|
|
storage,
|
|
};
|
|
}
|
|
}
|