Fix/workspace health type (#4053)
* fix: memory issue with truncate command * fix: LINK doesn't have any default value * fix: Cannot convert LINK to column type. * fix: handle old column type and add a warn to fix them manually
This commit is contained in:
@ -2,31 +2,35 @@ import console from 'console';
|
||||
|
||||
import { connectionSource, performQuery } from './utils';
|
||||
|
||||
connectionSource
|
||||
.initialize()
|
||||
.then(async () => {
|
||||
await performQuery(
|
||||
async function dropSchemasSequentially() {
|
||||
try {
|
||||
await connectionSource.initialize();
|
||||
|
||||
// Fetch all schemas
|
||||
const schemas = await performQuery(
|
||||
`
|
||||
CREATE OR REPLACE FUNCTION drop_all() RETURNS VOID AS $$
|
||||
DECLARE schema_item RECORD;
|
||||
BEGIN
|
||||
FOR schema_item IN
|
||||
SELECT subrequest."name" as schema_name
|
||||
FROM (SELECT n.nspname AS "name"
|
||||
FROM pg_catalog.pg_namespace n
|
||||
WHERE n.nspname !~ '^pg_' AND n.nspname <> 'information_schema') as subrequest
|
||||
LOOP
|
||||
EXECUTE 'DROP SCHEMA ' || schema_item.schema_name || ' CASCADE';
|
||||
END LOOP;
|
||||
RETURN;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
SELECT drop_all ();
|
||||
`,
|
||||
'Dropping all schemas...',
|
||||
SELECT n.nspname AS "schema_name"
|
||||
FROM pg_catalog.pg_namespace n
|
||||
WHERE n.nspname !~ '^pg_' AND n.nspname <> 'information_schema'
|
||||
`,
|
||||
'Fetching schemas...',
|
||||
);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error('Error during Data Source initialization:', err);
|
||||
});
|
||||
|
||||
// Iterate over each schema and drop it
|
||||
// This is to avoid dropping all schemas at once, which would cause an out of shared memory error
|
||||
for (const schema of schemas) {
|
||||
await performQuery(
|
||||
`
|
||||
DROP SCHEMA IF EXISTS "${schema.schema_name}" CASCADE;
|
||||
`,
|
||||
`Dropping schema ${schema.schema_name}...`,
|
||||
);
|
||||
}
|
||||
|
||||
console.log('All schemas dropped successfully.');
|
||||
} catch (err) {
|
||||
console.error('Error during schema dropping:', err);
|
||||
}
|
||||
}
|
||||
|
||||
dropSchemasSequentially();
|
||||
|
||||
@ -17,6 +17,11 @@ export function generateDefaultValue(
|
||||
firstName: '',
|
||||
lastName: '',
|
||||
};
|
||||
case FieldMetadataType.LINK:
|
||||
return {
|
||||
url: '',
|
||||
label: '',
|
||||
};
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
|
||||
import { EntityManager } from 'typeorm';
|
||||
|
||||
@ -10,13 +10,20 @@ import { WorkspaceMigrationBuilderAction } from 'src/workspace/workspace-migrati
|
||||
|
||||
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';
|
||||
import {
|
||||
FieldMetadataUpdate,
|
||||
WorkspaceMigrationFieldFactory,
|
||||
} from 'src/workspace/workspace-migration-builder/factories/workspace-migration-field.factory';
|
||||
import { DatabaseStructureService } from 'src/workspace/workspace-health/services/database-structure.service';
|
||||
|
||||
import { AbstractWorkspaceFixer } from './abstract-workspace.fixer';
|
||||
|
||||
const oldDataTypes = ['integer'];
|
||||
|
||||
@Injectable()
|
||||
export class WorkspaceTypeFixer extends AbstractWorkspaceFixer<WorkspaceHealthIssueType.COLUMN_DATA_TYPE_CONFLICT> {
|
||||
private readonly logger = new Logger(WorkspaceTypeFixer.name);
|
||||
|
||||
constructor(
|
||||
private readonly workspaceMigrationFieldFactory: WorkspaceMigrationFieldFactory,
|
||||
private readonly databaseStructureService: DatabaseStructureService,
|
||||
@ -40,28 +47,39 @@ export class WorkspaceTypeFixer extends AbstractWorkspaceFixer<WorkspaceHealthIs
|
||||
objectMetadataCollection: ObjectMetadataEntity[],
|
||||
issues: WorkspaceHealthColumnIssue<WorkspaceHealthIssueType.COLUMN_DATA_TYPE_CONFLICT>[],
|
||||
): Promise<Partial<WorkspaceMigrationEntity>[]> {
|
||||
const fieldMetadataUpdateCollection = issues.map((issue) => {
|
||||
if (!issue.columnStructure?.dataType) {
|
||||
const fieldMetadataUpdateCollection: FieldMetadataUpdate[] = [];
|
||||
|
||||
for (const issue of issues) {
|
||||
const dataType = issue.columnStructure?.dataType;
|
||||
|
||||
if (!dataType) {
|
||||
throw new Error('Column structure data type is missing');
|
||||
}
|
||||
|
||||
const type =
|
||||
this.databaseStructureService.getFieldMetadataTypeFromPostgresDataType(
|
||||
issue.columnStructure?.dataType,
|
||||
dataType,
|
||||
);
|
||||
|
||||
if (oldDataTypes.includes(dataType)) {
|
||||
this.logger.warn(
|
||||
`Old data type detected for column ${issue.columnStructure?.columnName} with data type ${dataType}. Please update the column data type manually.`,
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!type) {
|
||||
throw new Error("Can't find field metadata type from column structure");
|
||||
}
|
||||
|
||||
return {
|
||||
fieldMetadataUpdateCollection.push({
|
||||
current: {
|
||||
...issue.fieldMetadata,
|
||||
type,
|
||||
},
|
||||
altered: issue.fieldMetadata,
|
||||
};
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return this.workspaceMigrationFieldFactory.create(
|
||||
objectMetadataCollection,
|
||||
|
||||
@ -16,6 +16,8 @@ import {
|
||||
} from 'src/metadata/field-metadata/field-metadata.entity';
|
||||
import { fieldMetadataTypeToColumnType } from 'src/metadata/workspace-migration/utils/field-metadata-type-to-column-type.util';
|
||||
import { serializeTypeDefaultValue } from 'src/metadata/field-metadata/utils/serialize-type-default-value.util';
|
||||
import { isCompositeFieldMetadataType } from 'src/metadata/field-metadata/utils/is-composite-field-metadata-type.util';
|
||||
import { isRelationFieldMetadataType } from 'src/workspace/utils/is-relation-field-metadata-type.util';
|
||||
|
||||
@Injectable()
|
||||
export class DatabaseStructureService {
|
||||
@ -165,8 +167,20 @@ export class DatabaseStructureService {
|
||||
postgresDataType: string,
|
||||
): FieldMetadataType | null {
|
||||
const mainDataSource = this.typeORMService.getMainDataSource();
|
||||
const types = Object.values(FieldMetadataType).filter((type) => {
|
||||
// We're skipping composite and relation types, as they're not directly mapped to a column type
|
||||
if (isCompositeFieldMetadataType(type)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const type in FieldMetadataType) {
|
||||
if (isRelationFieldMetadataType(type)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
for (const type of types) {
|
||||
const typeORMType = fieldMetadataTypeToColumnType(
|
||||
FieldMetadataType[type],
|
||||
) as ColumnType;
|
||||
|
||||
@ -16,7 +16,7 @@ import { computeObjectTargetTable } from 'src/workspace/utils/compute-object-tar
|
||||
import { WorkspaceMigrationFactory } from 'src/metadata/workspace-migration/workspace-migration.factory';
|
||||
import { generateMigrationName } from 'src/metadata/workspace-migration/utils/generate-migration-name.util';
|
||||
|
||||
interface FieldMetadataUpdate {
|
||||
export interface FieldMetadataUpdate {
|
||||
current: FieldMetadataEntity;
|
||||
altered: FieldMetadataEntity;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user