feat: workspace health default-value fix (#3894)

* feat: workspace health default-value fix

* fix: rename function regarding review
This commit is contained in:
Jérémy M 2024-02-09 14:16:11 +01:00 committed by GitHub
parent 201a2c8acc
commit 2560ce25e0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 134 additions and 0 deletions

View File

@ -0,0 +1,117 @@
import { Injectable } from '@nestjs/common';
import { EntityManager } from 'typeorm';
import {
WorkspaceHealthColumnIssue,
WorkspaceHealthIssueType,
} from 'src/workspace/workspace-health/interfaces/workspace-health-issue.interface';
import { WorkspaceMigrationBuilderAction } from 'src/workspace/workspace-migration-builder/interfaces/workspace-migration-builder-action.interface';
import { FieldMetadataDefaultValue } from 'src/metadata/field-metadata/interfaces/field-metadata-default-value.interface';
import { ObjectMetadataEntity } from 'src/metadata/object-metadata/object-metadata.entity';
import { WorkspaceMigrationEntity } from 'src/metadata/workspace-migration/workspace-migration.entity';
import { WorkspaceMigrationFieldFactory } from 'src/workspace/workspace-migration-builder/factories/workspace-migration-field.factory';
type WorkspaceHealthDefaultValueIssue =
WorkspaceHealthColumnIssue<WorkspaceHealthIssueType.COLUMN_DEFAULT_VALUE_CONFLICT>;
@Injectable()
export class WorkspaceFixDefaultValueService {
constructor(
private readonly workspaceMigrationFieldFactory: WorkspaceMigrationFieldFactory,
) {}
async fix(
manager: EntityManager,
objectMetadataCollection: ObjectMetadataEntity[],
issues: WorkspaceHealthDefaultValueIssue[],
): Promise<Partial<WorkspaceMigrationEntity>[]> {
const workspaceMigrations: Partial<WorkspaceMigrationEntity>[] = [];
for (const issue of issues) {
switch (issue.type) {
case WorkspaceHealthIssueType.COLUMN_DEFAULT_VALUE_CONFLICT: {
const columnNullabilityWorkspaceMigrations =
await this.fixColumnDefaultValueIssues(
objectMetadataCollection,
issues.filter(
(issue) =>
issue.type ===
WorkspaceHealthIssueType.COLUMN_DEFAULT_VALUE_CONFLICT,
) as WorkspaceHealthColumnIssue<WorkspaceHealthIssueType.COLUMN_DEFAULT_VALUE_CONFLICT>[],
);
workspaceMigrations.push(...columnNullabilityWorkspaceMigrations);
break;
}
}
}
return workspaceMigrations;
}
private async fixColumnDefaultValueIssues(
objectMetadataCollection: ObjectMetadataEntity[],
issues: WorkspaceHealthColumnIssue<WorkspaceHealthIssueType.COLUMN_DEFAULT_VALUE_CONFLICT>[],
): Promise<Partial<WorkspaceMigrationEntity>[]> {
const fieldMetadataUpdateCollection = issues.map((issue) => {
const oldDefaultValue =
this.computeFieldMetadataDefaultValueFromColumnDefault(
issue.columnStructure?.columnDefault,
);
return {
current: {
...issue.fieldMetadata,
defaultValue: oldDefaultValue,
},
altered: issue.fieldMetadata,
};
});
return this.workspaceMigrationFieldFactory.create(
objectMetadataCollection,
fieldMetadataUpdateCollection,
WorkspaceMigrationBuilderAction.UPDATE,
);
}
private computeFieldMetadataDefaultValueFromColumnDefault(
columnDefault: string | undefined,
): FieldMetadataDefaultValue<'default'> {
if (
columnDefault === undefined ||
columnDefault === null ||
columnDefault === 'NULL'
) {
return null;
}
if (!isNaN(Number(columnDefault))) {
return { value: +columnDefault };
}
if (columnDefault === 'true') {
return { value: true };
}
if (columnDefault === 'false') {
return { value: false };
}
if (columnDefault === '') {
return { value: '' };
}
if (columnDefault === 'now()') {
return { type: 'now' };
}
if (columnDefault.startsWith('public.uuid_generate_v4')) {
return { type: 'uuid' };
}
return { value: columnDefault };
}
}

View File

@ -8,18 +8,21 @@ import { WorkspaceHealthIssue } from 'src/workspace/workspace-health/interfaces/
import { WorkspaceMigrationEntity } from 'src/metadata/workspace-migration/workspace-migration.entity';
import { ObjectMetadataEntity } from 'src/metadata/object-metadata/object-metadata.entity';
import {
isWorkspaceHealthDefaultValueIssue,
isWorkspaceHealthNullableIssue,
isWorkspaceHealthTypeIssue,
} from 'src/workspace/workspace-health/utils/is-workspace-health-issue-type.util';
import { WorkspaceFixNullableService } from './workspace-fix-nullable.service';
import { WorkspaceFixTypeService } from './workspace-fix-type.service';
import { WorkspaceFixDefaultValueService } from './workspace-fix-default-value.service';
@Injectable()
export class WorkspaceFixService {
constructor(
private readonly workspaceFixNullableService: WorkspaceFixNullableService,
private readonly workspaceFixTypeService: WorkspaceFixTypeService,
private readonly workspaceFixDefaultValueService: WorkspaceFixDefaultValueService,
) {}
async fix(
@ -41,6 +44,12 @@ export class WorkspaceFixService {
isWorkspaceHealthTypeIssue(issue.type),
),
},
[WorkspaceHealthFixKind.DefaultValue]: {
service: this.workspaceFixDefaultValueService,
issues: issues.filter((issue) =>
isWorkspaceHealthDefaultValueIssue(issue.type),
),
},
};
return services[type].service.fix(

View File

@ -11,3 +11,9 @@ export const isWorkspaceHealthTypeIssue = (
): type is WorkspaceHealthIssueType.COLUMN_DATA_TYPE_CONFLICT => {
return type === WorkspaceHealthIssueType.COLUMN_DATA_TYPE_CONFLICT;
};
export const isWorkspaceHealthDefaultValueIssue = (
type: WorkspaceHealthIssueType,
): type is WorkspaceHealthIssueType.COLUMN_DEFAULT_VALUE_CONFLICT => {
return type === WorkspaceHealthIssueType.COLUMN_DEFAULT_VALUE_CONFLICT;
};

View File

@ -15,6 +15,7 @@ import { WorkspaceMigrationRunnerModule } from 'src/workspace/workspace-migratio
import { WorkspaceFixService } from './services/workspace-fix.service';
import { WorkspaceFixNullableService } from './services/workspace-fix-nullable.service';
import { WorkspaceFixTypeService } from './services/workspace-fix-type.service';
import { WorkspaceFixDefaultValueService } from './services/workspace-fix-default-value.service';
@Module({
imports: [
@ -33,6 +34,7 @@ import { WorkspaceFixTypeService } from './services/workspace-fix-type.service';
RelationMetadataHealthService,
WorkspaceFixNullableService,
WorkspaceFixTypeService,
WorkspaceFixDefaultValueService,
WorkspaceFixService,
],
exports: [WorkspaceHealthService],