feat: workspace health default-value fix (#3894)
* feat: workspace health default-value fix * fix: rename function regarding review
This commit is contained in:
@ -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 };
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -8,18 +8,21 @@ import { WorkspaceHealthIssue } from 'src/workspace/workspace-health/interfaces/
|
|||||||
import { WorkspaceMigrationEntity } from 'src/metadata/workspace-migration/workspace-migration.entity';
|
import { WorkspaceMigrationEntity } from 'src/metadata/workspace-migration/workspace-migration.entity';
|
||||||
import { ObjectMetadataEntity } from 'src/metadata/object-metadata/object-metadata.entity';
|
import { ObjectMetadataEntity } from 'src/metadata/object-metadata/object-metadata.entity';
|
||||||
import {
|
import {
|
||||||
|
isWorkspaceHealthDefaultValueIssue,
|
||||||
isWorkspaceHealthNullableIssue,
|
isWorkspaceHealthNullableIssue,
|
||||||
isWorkspaceHealthTypeIssue,
|
isWorkspaceHealthTypeIssue,
|
||||||
} from 'src/workspace/workspace-health/utils/is-workspace-health-issue-type.util';
|
} from 'src/workspace/workspace-health/utils/is-workspace-health-issue-type.util';
|
||||||
|
|
||||||
import { WorkspaceFixNullableService } from './workspace-fix-nullable.service';
|
import { WorkspaceFixNullableService } from './workspace-fix-nullable.service';
|
||||||
import { WorkspaceFixTypeService } from './workspace-fix-type.service';
|
import { WorkspaceFixTypeService } from './workspace-fix-type.service';
|
||||||
|
import { WorkspaceFixDefaultValueService } from './workspace-fix-default-value.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class WorkspaceFixService {
|
export class WorkspaceFixService {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly workspaceFixNullableService: WorkspaceFixNullableService,
|
private readonly workspaceFixNullableService: WorkspaceFixNullableService,
|
||||||
private readonly workspaceFixTypeService: WorkspaceFixTypeService,
|
private readonly workspaceFixTypeService: WorkspaceFixTypeService,
|
||||||
|
private readonly workspaceFixDefaultValueService: WorkspaceFixDefaultValueService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async fix(
|
async fix(
|
||||||
@ -41,6 +44,12 @@ export class WorkspaceFixService {
|
|||||||
isWorkspaceHealthTypeIssue(issue.type),
|
isWorkspaceHealthTypeIssue(issue.type),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
[WorkspaceHealthFixKind.DefaultValue]: {
|
||||||
|
service: this.workspaceFixDefaultValueService,
|
||||||
|
issues: issues.filter((issue) =>
|
||||||
|
isWorkspaceHealthDefaultValueIssue(issue.type),
|
||||||
|
),
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
return services[type].service.fix(
|
return services[type].service.fix(
|
||||||
|
|||||||
@ -11,3 +11,9 @@ export const isWorkspaceHealthTypeIssue = (
|
|||||||
): type is WorkspaceHealthIssueType.COLUMN_DATA_TYPE_CONFLICT => {
|
): type is WorkspaceHealthIssueType.COLUMN_DATA_TYPE_CONFLICT => {
|
||||||
return type === 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;
|
||||||
|
};
|
||||||
|
|||||||
@ -15,6 +15,7 @@ import { WorkspaceMigrationRunnerModule } from 'src/workspace/workspace-migratio
|
|||||||
import { WorkspaceFixService } from './services/workspace-fix.service';
|
import { WorkspaceFixService } from './services/workspace-fix.service';
|
||||||
import { WorkspaceFixNullableService } from './services/workspace-fix-nullable.service';
|
import { WorkspaceFixNullableService } from './services/workspace-fix-nullable.service';
|
||||||
import { WorkspaceFixTypeService } from './services/workspace-fix-type.service';
|
import { WorkspaceFixTypeService } from './services/workspace-fix-type.service';
|
||||||
|
import { WorkspaceFixDefaultValueService } from './services/workspace-fix-default-value.service';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
@ -33,6 +34,7 @@ import { WorkspaceFixTypeService } from './services/workspace-fix-type.service';
|
|||||||
RelationMetadataHealthService,
|
RelationMetadataHealthService,
|
||||||
WorkspaceFixNullableService,
|
WorkspaceFixNullableService,
|
||||||
WorkspaceFixTypeService,
|
WorkspaceFixTypeService,
|
||||||
|
WorkspaceFixDefaultValueService,
|
||||||
WorkspaceFixService,
|
WorkspaceFixService,
|
||||||
],
|
],
|
||||||
exports: [WorkspaceHealthService],
|
exports: [WorkspaceHealthService],
|
||||||
|
|||||||
Reference in New Issue
Block a user