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';
|
import { connectionSource, performQuery } from './utils';
|
||||||
|
|
||||||
connectionSource
|
async function dropSchemasSequentially() {
|
||||||
.initialize()
|
try {
|
||||||
.then(async () => {
|
await connectionSource.initialize();
|
||||||
await performQuery(
|
|
||||||
|
// Fetch all schemas
|
||||||
|
const schemas = await performQuery(
|
||||||
`
|
`
|
||||||
CREATE OR REPLACE FUNCTION drop_all() RETURNS VOID AS $$
|
SELECT n.nspname AS "schema_name"
|
||||||
DECLARE schema_item RECORD;
|
FROM pg_catalog.pg_namespace n
|
||||||
BEGIN
|
WHERE n.nspname !~ '^pg_' AND n.nspname <> 'information_schema'
|
||||||
FOR schema_item IN
|
`,
|
||||||
SELECT subrequest."name" as schema_name
|
'Fetching schemas...',
|
||||||
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...',
|
|
||||||
);
|
);
|
||||||
})
|
|
||||||
.catch((err) => {
|
// Iterate over each schema and drop it
|
||||||
console.error('Error during Data Source initialization:', err);
|
// 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: '',
|
firstName: '',
|
||||||
lastName: '',
|
lastName: '',
|
||||||
};
|
};
|
||||||
|
case FieldMetadataType.LINK:
|
||||||
|
return {
|
||||||
|
url: '',
|
||||||
|
label: '',
|
||||||
|
};
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable, Logger } from '@nestjs/common';
|
||||||
|
|
||||||
import { EntityManager } from 'typeorm';
|
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 { ObjectMetadataEntity } from 'src/metadata/object-metadata/object-metadata.entity';
|
||||||
import { WorkspaceMigrationEntity } from 'src/metadata/workspace-migration/workspace-migration.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 { DatabaseStructureService } from 'src/workspace/workspace-health/services/database-structure.service';
|
||||||
|
|
||||||
import { AbstractWorkspaceFixer } from './abstract-workspace.fixer';
|
import { AbstractWorkspaceFixer } from './abstract-workspace.fixer';
|
||||||
|
|
||||||
|
const oldDataTypes = ['integer'];
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class WorkspaceTypeFixer extends AbstractWorkspaceFixer<WorkspaceHealthIssueType.COLUMN_DATA_TYPE_CONFLICT> {
|
export class WorkspaceTypeFixer extends AbstractWorkspaceFixer<WorkspaceHealthIssueType.COLUMN_DATA_TYPE_CONFLICT> {
|
||||||
|
private readonly logger = new Logger(WorkspaceTypeFixer.name);
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private readonly workspaceMigrationFieldFactory: WorkspaceMigrationFieldFactory,
|
private readonly workspaceMigrationFieldFactory: WorkspaceMigrationFieldFactory,
|
||||||
private readonly databaseStructureService: DatabaseStructureService,
|
private readonly databaseStructureService: DatabaseStructureService,
|
||||||
@ -40,28 +47,39 @@ export class WorkspaceTypeFixer extends AbstractWorkspaceFixer<WorkspaceHealthIs
|
|||||||
objectMetadataCollection: ObjectMetadataEntity[],
|
objectMetadataCollection: ObjectMetadataEntity[],
|
||||||
issues: WorkspaceHealthColumnIssue<WorkspaceHealthIssueType.COLUMN_DATA_TYPE_CONFLICT>[],
|
issues: WorkspaceHealthColumnIssue<WorkspaceHealthIssueType.COLUMN_DATA_TYPE_CONFLICT>[],
|
||||||
): Promise<Partial<WorkspaceMigrationEntity>[]> {
|
): Promise<Partial<WorkspaceMigrationEntity>[]> {
|
||||||
const fieldMetadataUpdateCollection = issues.map((issue) => {
|
const fieldMetadataUpdateCollection: FieldMetadataUpdate[] = [];
|
||||||
if (!issue.columnStructure?.dataType) {
|
|
||||||
|
for (const issue of issues) {
|
||||||
|
const dataType = issue.columnStructure?.dataType;
|
||||||
|
|
||||||
|
if (!dataType) {
|
||||||
throw new Error('Column structure data type is missing');
|
throw new Error('Column structure data type is missing');
|
||||||
}
|
}
|
||||||
|
|
||||||
const type =
|
const type =
|
||||||
this.databaseStructureService.getFieldMetadataTypeFromPostgresDataType(
|
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) {
|
if (!type) {
|
||||||
throw new Error("Can't find field metadata type from column structure");
|
throw new Error("Can't find field metadata type from column structure");
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
fieldMetadataUpdateCollection.push({
|
||||||
current: {
|
current: {
|
||||||
...issue.fieldMetadata,
|
...issue.fieldMetadata,
|
||||||
type,
|
type,
|
||||||
},
|
},
|
||||||
altered: issue.fieldMetadata,
|
altered: issue.fieldMetadata,
|
||||||
};
|
});
|
||||||
});
|
}
|
||||||
|
|
||||||
return this.workspaceMigrationFieldFactory.create(
|
return this.workspaceMigrationFieldFactory.create(
|
||||||
objectMetadataCollection,
|
objectMetadataCollection,
|
||||||
|
|||||||
@ -16,6 +16,8 @@ import {
|
|||||||
} from 'src/metadata/field-metadata/field-metadata.entity';
|
} from 'src/metadata/field-metadata/field-metadata.entity';
|
||||||
import { fieldMetadataTypeToColumnType } from 'src/metadata/workspace-migration/utils/field-metadata-type-to-column-type.util';
|
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 { 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()
|
@Injectable()
|
||||||
export class DatabaseStructureService {
|
export class DatabaseStructureService {
|
||||||
@ -165,8 +167,20 @@ export class DatabaseStructureService {
|
|||||||
postgresDataType: string,
|
postgresDataType: string,
|
||||||
): FieldMetadataType | null {
|
): FieldMetadataType | null {
|
||||||
const mainDataSource = this.typeORMService.getMainDataSource();
|
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(
|
const typeORMType = fieldMetadataTypeToColumnType(
|
||||||
FieldMetadataType[type],
|
FieldMetadataType[type],
|
||||||
) as ColumnType;
|
) 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 { WorkspaceMigrationFactory } from 'src/metadata/workspace-migration/workspace-migration.factory';
|
||||||
import { generateMigrationName } from 'src/metadata/workspace-migration/utils/generate-migration-name.util';
|
import { generateMigrationName } from 'src/metadata/workspace-migration/utils/generate-migration-name.util';
|
||||||
|
|
||||||
interface FieldMetadataUpdate {
|
export interface FieldMetadataUpdate {
|
||||||
current: FieldMetadataEntity;
|
current: FieldMetadataEntity;
|
||||||
altered: FieldMetadataEntity;
|
altered: FieldMetadataEntity;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user