mirror of
https://github.com/twentyhq/twenty.git
synced 2024-12-24 20:42:05 +03:00
feat: workspace health default-value fix (#3894)
* feat: workspace health default-value fix * fix: rename function regarding review
This commit is contained in:
parent
201a2c8acc
commit
2560ce25e0
@ -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 { 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(
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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],
|
||||
|
Loading…
Reference in New Issue
Block a user