feat: sync command missing ability to rename standard object (#4819)
We've introduced in PR #4373 standard ids to be able to rename standard fields and objects. Fields part was working properly, but objects part was not yet implemented. This PR is adding the missing parts to make it work.
This commit is contained in:
@ -18,6 +18,7 @@ import {
|
||||
WorkspaceMigrationColumnActionType,
|
||||
WorkspaceMigrationColumnDrop,
|
||||
WorkspaceMigrationTableAction,
|
||||
WorkspaceMigrationTableActionType,
|
||||
} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
|
||||
import { TypeORMService } from 'src/database/typeorm/typeorm.service';
|
||||
import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service';
|
||||
@ -152,7 +153,7 @@ export class FieldMetadataService extends TypeOrmQueryService<FieldMetadataEntit
|
||||
[
|
||||
{
|
||||
name: computeObjectTargetTable(objectMetadata),
|
||||
action: 'alter',
|
||||
action: WorkspaceMigrationTableActionType.ALTER,
|
||||
columns: this.workspaceMigrationFactory.createColumnActions(
|
||||
WorkspaceMigrationColumnActionType.CREATE,
|
||||
createdFieldMetadata,
|
||||
@ -328,7 +329,7 @@ export class FieldMetadataService extends TypeOrmQueryService<FieldMetadataEntit
|
||||
[
|
||||
{
|
||||
name: computeObjectTargetTable(objectMetadata),
|
||||
action: 'alter',
|
||||
action: WorkspaceMigrationTableActionType.ALTER,
|
||||
columns: this.workspaceMigrationFactory.createColumnActions(
|
||||
WorkspaceMigrationColumnActionType.ALTER,
|
||||
existingFieldMetadata,
|
||||
@ -399,7 +400,7 @@ export class FieldMetadataService extends TypeOrmQueryService<FieldMetadataEntit
|
||||
[
|
||||
{
|
||||
name: computeObjectTargetTable(objectMetadata),
|
||||
action: 'alter',
|
||||
action: WorkspaceMigrationTableActionType.ALTER,
|
||||
columns: [
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.DROP,
|
||||
|
||||
@ -16,6 +16,7 @@ import { WorkspaceMigrationRunnerService } from 'src/engine/workspace-manager/wo
|
||||
import {
|
||||
WorkspaceMigrationColumnActionType,
|
||||
WorkspaceMigrationColumnDrop,
|
||||
WorkspaceMigrationTableActionType,
|
||||
} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
|
||||
import {
|
||||
FieldMetadataEntity,
|
||||
@ -177,7 +178,7 @@ export class ObjectMetadataService extends TypeOrmQueryService<ObjectMetadataEnt
|
||||
relationToDelete.toObjectName,
|
||||
relationToDelete.toObjectMetadataIsCustom,
|
||||
),
|
||||
action: 'alter',
|
||||
action: WorkspaceMigrationTableActionType.ALTER,
|
||||
columns: [
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.DROP,
|
||||
@ -203,7 +204,7 @@ export class ObjectMetadataService extends TypeOrmQueryService<ObjectMetadataEnt
|
||||
[
|
||||
{
|
||||
name: computeObjectTargetTable(objectMetadata),
|
||||
action: 'drop',
|
||||
action: WorkspaceMigrationTableActionType.DROP,
|
||||
},
|
||||
],
|
||||
);
|
||||
|
||||
@ -5,6 +5,7 @@ import {
|
||||
WorkspaceMigrationTableAction,
|
||||
WorkspaceMigrationColumnActionType,
|
||||
WorkspaceMigrationColumnCreate,
|
||||
WorkspaceMigrationTableActionType,
|
||||
} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
|
||||
import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util';
|
||||
|
||||
@ -17,12 +18,12 @@ export const buildWorkspaceMigrationsForCustomObject = (
|
||||
): WorkspaceMigrationTableAction[] => [
|
||||
{
|
||||
name: computeObjectTargetTable(createdObjectMetadata),
|
||||
action: 'create',
|
||||
action: WorkspaceMigrationTableActionType.CREATE,
|
||||
} satisfies WorkspaceMigrationTableAction,
|
||||
// Add activity target relation
|
||||
{
|
||||
name: computeObjectTargetTable(activityTargetObjectMetadata),
|
||||
action: 'alter',
|
||||
action: WorkspaceMigrationTableActionType.ALTER,
|
||||
columns: [
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.CREATE,
|
||||
@ -36,7 +37,7 @@ export const buildWorkspaceMigrationsForCustomObject = (
|
||||
},
|
||||
{
|
||||
name: computeObjectTargetTable(activityTargetObjectMetadata),
|
||||
action: 'alter',
|
||||
action: WorkspaceMigrationTableActionType.ALTER,
|
||||
columns: [
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.CREATE_FOREIGN_KEY,
|
||||
@ -52,7 +53,7 @@ export const buildWorkspaceMigrationsForCustomObject = (
|
||||
// Add attachment relation
|
||||
{
|
||||
name: computeObjectTargetTable(attachmentObjectMetadata),
|
||||
action: 'alter',
|
||||
action: WorkspaceMigrationTableActionType.ALTER,
|
||||
columns: [
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.CREATE,
|
||||
@ -66,7 +67,7 @@ export const buildWorkspaceMigrationsForCustomObject = (
|
||||
},
|
||||
{
|
||||
name: computeObjectTargetTable(attachmentObjectMetadata),
|
||||
action: 'alter',
|
||||
action: WorkspaceMigrationTableActionType.ALTER,
|
||||
columns: [
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.CREATE_FOREIGN_KEY,
|
||||
@ -82,7 +83,7 @@ export const buildWorkspaceMigrationsForCustomObject = (
|
||||
// Add event relation
|
||||
{
|
||||
name: computeObjectTargetTable(eventObjectMetadata),
|
||||
action: 'alter',
|
||||
action: WorkspaceMigrationTableActionType.ALTER,
|
||||
columns: [
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.CREATE,
|
||||
@ -96,7 +97,7 @@ export const buildWorkspaceMigrationsForCustomObject = (
|
||||
},
|
||||
{
|
||||
name: computeObjectTargetTable(eventObjectMetadata),
|
||||
action: 'alter',
|
||||
action: WorkspaceMigrationTableActionType.ALTER,
|
||||
columns: [
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.CREATE_FOREIGN_KEY,
|
||||
@ -112,7 +113,7 @@ export const buildWorkspaceMigrationsForCustomObject = (
|
||||
// Add favorite relation
|
||||
{
|
||||
name: computeObjectTargetTable(favoriteObjectMetadata),
|
||||
action: 'alter',
|
||||
action: WorkspaceMigrationTableActionType.ALTER,
|
||||
columns: [
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.CREATE,
|
||||
@ -126,7 +127,7 @@ export const buildWorkspaceMigrationsForCustomObject = (
|
||||
},
|
||||
{
|
||||
name: computeObjectTargetTable(favoriteObjectMetadata),
|
||||
action: 'alter',
|
||||
action: WorkspaceMigrationTableActionType.ALTER,
|
||||
columns: [
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.CREATE_FOREIGN_KEY,
|
||||
@ -141,7 +142,7 @@ export const buildWorkspaceMigrationsForCustomObject = (
|
||||
},
|
||||
{
|
||||
name: computeObjectTargetTable(createdObjectMetadata),
|
||||
action: 'alter',
|
||||
action: WorkspaceMigrationTableActionType.ALTER,
|
||||
columns: [
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.CREATE,
|
||||
@ -154,7 +155,7 @@ export const buildWorkspaceMigrationsForCustomObject = (
|
||||
// This is temporary until we implement mainIdentifier
|
||||
{
|
||||
name: computeObjectTargetTable(createdObjectMetadata),
|
||||
action: 'alter',
|
||||
action: WorkspaceMigrationTableActionType.ALTER,
|
||||
columns: [
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.CREATE,
|
||||
|
||||
@ -6,6 +6,7 @@ import {
|
||||
WorkspaceMigrationTableAction,
|
||||
WorkspaceMigrationColumnActionType,
|
||||
WorkspaceMigrationColumnCreate,
|
||||
WorkspaceMigrationTableActionType,
|
||||
} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
|
||||
import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util';
|
||||
|
||||
@ -61,7 +62,7 @@ export const buildWorkspaceMigrationsForRemoteObject = async (
|
||||
return [
|
||||
{
|
||||
name: computeObjectTargetTable(activityTargetObjectMetadata),
|
||||
action: 'alter',
|
||||
action: WorkspaceMigrationTableActionType.ALTER,
|
||||
columns: [
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.CREATE,
|
||||
@ -75,7 +76,7 @@ export const buildWorkspaceMigrationsForRemoteObject = async (
|
||||
},
|
||||
{
|
||||
name: computeObjectTargetTable(activityTargetObjectMetadata),
|
||||
action: 'alter',
|
||||
action: WorkspaceMigrationTableActionType.ALTER,
|
||||
columns: [
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.CREATE,
|
||||
@ -88,7 +89,7 @@ export const buildWorkspaceMigrationsForRemoteObject = async (
|
||||
},
|
||||
{
|
||||
name: computeObjectTargetTable(activityTargetObjectMetadata),
|
||||
action: 'alter',
|
||||
action: WorkspaceMigrationTableActionType.ALTER,
|
||||
columns: [
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.CREATE_COMMENT,
|
||||
@ -104,7 +105,7 @@ export const buildWorkspaceMigrationsForRemoteObject = async (
|
||||
// Add attachment relation
|
||||
{
|
||||
name: computeObjectTargetTable(attachmentObjectMetadata),
|
||||
action: 'alter',
|
||||
action: WorkspaceMigrationTableActionType.ALTER,
|
||||
columns: [
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.CREATE,
|
||||
@ -118,7 +119,7 @@ export const buildWorkspaceMigrationsForRemoteObject = async (
|
||||
},
|
||||
{
|
||||
name: computeObjectTargetTable(attachmentObjectMetadata),
|
||||
action: 'alter',
|
||||
action: WorkspaceMigrationTableActionType.ALTER,
|
||||
columns: [
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.CREATE,
|
||||
@ -131,7 +132,7 @@ export const buildWorkspaceMigrationsForRemoteObject = async (
|
||||
},
|
||||
{
|
||||
name: computeObjectTargetTable(attachmentObjectMetadata),
|
||||
action: 'alter',
|
||||
action: WorkspaceMigrationTableActionType.ALTER,
|
||||
columns: [
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.CREATE_COMMENT,
|
||||
@ -147,7 +148,7 @@ export const buildWorkspaceMigrationsForRemoteObject = async (
|
||||
// Add event relation
|
||||
{
|
||||
name: computeObjectTargetTable(eventObjectMetadata),
|
||||
action: 'alter',
|
||||
action: WorkspaceMigrationTableActionType.ALTER,
|
||||
columns: [
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.CREATE,
|
||||
@ -161,7 +162,7 @@ export const buildWorkspaceMigrationsForRemoteObject = async (
|
||||
},
|
||||
{
|
||||
name: computeObjectTargetTable(eventObjectMetadata),
|
||||
action: 'alter',
|
||||
action: WorkspaceMigrationTableActionType.ALTER,
|
||||
columns: [
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.CREATE,
|
||||
@ -174,7 +175,7 @@ export const buildWorkspaceMigrationsForRemoteObject = async (
|
||||
},
|
||||
{
|
||||
name: computeObjectTargetTable(eventObjectMetadata),
|
||||
action: 'alter',
|
||||
action: WorkspaceMigrationTableActionType.ALTER,
|
||||
columns: [
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.CREATE_COMMENT,
|
||||
@ -190,7 +191,7 @@ export const buildWorkspaceMigrationsForRemoteObject = async (
|
||||
// Add favorite relation
|
||||
{
|
||||
name: computeObjectTargetTable(favoriteObjectMetadata),
|
||||
action: 'alter',
|
||||
action: WorkspaceMigrationTableActionType.ALTER,
|
||||
columns: [
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.CREATE,
|
||||
@ -204,7 +205,7 @@ export const buildWorkspaceMigrationsForRemoteObject = async (
|
||||
},
|
||||
{
|
||||
name: computeObjectTargetTable(favoriteObjectMetadata),
|
||||
action: 'alter',
|
||||
action: WorkspaceMigrationTableActionType.ALTER,
|
||||
columns: [
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.CREATE,
|
||||
@ -217,7 +218,7 @@ export const buildWorkspaceMigrationsForRemoteObject = async (
|
||||
},
|
||||
{
|
||||
name: computeObjectTargetTable(favoriteObjectMetadata),
|
||||
action: 'alter',
|
||||
action: WorkspaceMigrationTableActionType.ALTER,
|
||||
columns: [
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.CREATE_COMMENT,
|
||||
|
||||
@ -17,7 +17,10 @@ import { CreateRelationInput } from 'src/engine/metadata-modules/relation-metada
|
||||
import { WorkspaceMigrationRunnerService } from 'src/engine/workspace-manager/workspace-migration-runner/workspace-migration-runner.service';
|
||||
import { WorkspaceMigrationService } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.service';
|
||||
import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
|
||||
import { WorkspaceMigrationColumnActionType } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
|
||||
import {
|
||||
WorkspaceMigrationColumnActionType,
|
||||
WorkspaceMigrationTableActionType,
|
||||
} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
|
||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util';
|
||||
import { generateMigrationName } from 'src/engine/metadata-modules/workspace-migration/utils/generate-migration-name.util';
|
||||
@ -171,7 +174,7 @@ export class RelationMetadataService extends TypeOrmQueryService<RelationMetadat
|
||||
name: computeObjectTargetTable(
|
||||
objectMetadataMap[relationMetadataInput.toObjectMetadataId],
|
||||
),
|
||||
action: 'alter',
|
||||
action: WorkspaceMigrationTableActionType.ALTER,
|
||||
columns: [
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.CREATE,
|
||||
@ -186,7 +189,7 @@ export class RelationMetadataService extends TypeOrmQueryService<RelationMetadat
|
||||
name: computeObjectTargetTable(
|
||||
objectMetadataMap[relationMetadataInput.toObjectMetadataId],
|
||||
),
|
||||
action: 'alter',
|
||||
action: WorkspaceMigrationTableActionType.ALTER,
|
||||
columns: [
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.CREATE_FOREIGN_KEY,
|
||||
|
||||
@ -30,6 +30,7 @@ import { generateMigrationName } from 'src/engine/metadata-modules/workspace-mig
|
||||
import {
|
||||
WorkspaceMigrationColumnDefinition,
|
||||
WorkspaceMigrationForeignTable,
|
||||
WorkspaceMigrationTableActionType,
|
||||
} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
|
||||
import { RemoteTableColumn } from 'src/engine/metadata-modules/remote-server/remote-table/types/remote-table-column';
|
||||
import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service';
|
||||
@ -165,7 +166,7 @@ export class RemoteTableService {
|
||||
[
|
||||
{
|
||||
name: remoteTableName,
|
||||
action: 'create_foreign_table',
|
||||
action: WorkspaceMigrationTableActionType.CREATE_FOREIGN_TABLE,
|
||||
foreignTable: {
|
||||
columns: remoteTableColumns.map(
|
||||
(column) =>
|
||||
@ -252,7 +253,7 @@ export class RemoteTableService {
|
||||
[
|
||||
{
|
||||
name: remoteTableName,
|
||||
action: 'drop_foreign_table',
|
||||
action: WorkspaceMigrationTableActionType.DROP_FOREIGN_TABLE,
|
||||
},
|
||||
],
|
||||
);
|
||||
|
||||
@ -80,14 +80,21 @@ export type WorkspaceMigrationColumnAction = {
|
||||
| WorkspaceMigrationCreateComment
|
||||
);
|
||||
|
||||
/**
|
||||
* Enum values are lowercase to avoid issues with already existing enum values
|
||||
*/
|
||||
export enum WorkspaceMigrationTableActionType {
|
||||
CREATE = 'create',
|
||||
ALTER = 'alter',
|
||||
DROP = 'drop',
|
||||
CREATE_FOREIGN_TABLE = 'create_foreign_table',
|
||||
DROP_FOREIGN_TABLE = 'drop_foreign_table'
|
||||
}
|
||||
|
||||
export type WorkspaceMigrationTableAction = {
|
||||
name: string;
|
||||
action:
|
||||
| 'create'
|
||||
| 'alter'
|
||||
| 'drop'
|
||||
| 'create_foreign_table'
|
||||
| 'drop_foreign_table';
|
||||
newName?: string;
|
||||
action: WorkspaceMigrationTableActionType;
|
||||
columns?: WorkspaceMigrationColumnAction[];
|
||||
foreignTable?: WorkspaceMigrationForeignTable;
|
||||
};
|
||||
|
||||
@ -11,6 +11,7 @@ import {
|
||||
WorkspaceMigrationColumnActionType,
|
||||
WorkspaceMigrationEntity,
|
||||
WorkspaceMigrationTableAction,
|
||||
WorkspaceMigrationTableActionType,
|
||||
} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
|
||||
import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util';
|
||||
import { WorkspaceMigrationFactory } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.factory';
|
||||
@ -94,7 +95,7 @@ export class WorkspaceMigrationFieldFactory {
|
||||
name: computeObjectTargetTable(
|
||||
originalObjectMetadataMap[fieldMetadata.objectMetadataId],
|
||||
),
|
||||
action: 'alter',
|
||||
action: WorkspaceMigrationTableActionType.ALTER,
|
||||
columns: this.workspaceMigrationFactory.createColumnActions(
|
||||
WorkspaceMigrationColumnActionType.CREATE,
|
||||
fieldMetadata,
|
||||
@ -132,7 +133,7 @@ export class WorkspaceMigrationFieldFactory {
|
||||
fieldMetadataUpdate.current.objectMetadataId
|
||||
],
|
||||
),
|
||||
action: 'alter',
|
||||
action: WorkspaceMigrationTableActionType.ALTER,
|
||||
columns: this.workspaceMigrationFactory.createColumnActions(
|
||||
WorkspaceMigrationColumnActionType.ALTER,
|
||||
fieldMetadataUpdate.current,
|
||||
@ -171,7 +172,7 @@ export class WorkspaceMigrationFieldFactory {
|
||||
name: computeObjectTargetTable(
|
||||
originalObjectMetadataMap[fieldMetadata.objectMetadataId],
|
||||
),
|
||||
action: 'alter',
|
||||
action: WorkspaceMigrationTableActionType.ALTER,
|
||||
columns: [
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.DROP,
|
||||
|
||||
@ -8,11 +8,17 @@ import {
|
||||
WorkspaceMigrationColumnActionType,
|
||||
WorkspaceMigrationEntity,
|
||||
WorkspaceMigrationTableAction,
|
||||
WorkspaceMigrationTableActionType,
|
||||
} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
|
||||
import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util';
|
||||
import { WorkspaceMigrationFactory } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.factory';
|
||||
import { generateMigrationName } from 'src/engine/metadata-modules/workspace-migration/utils/generate-migration-name.util';
|
||||
|
||||
export interface ObjectMetadataUpdate {
|
||||
current: ObjectMetadataEntity;
|
||||
altered: ObjectMetadataEntity;
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class WorkspaceMigrationObjectFactory {
|
||||
constructor(
|
||||
@ -21,13 +27,35 @@ export class WorkspaceMigrationObjectFactory {
|
||||
|
||||
async create(
|
||||
objectMetadataCollection: ObjectMetadataEntity[],
|
||||
action:
|
||||
| WorkspaceMigrationBuilderAction.CREATE
|
||||
| WorkspaceMigrationBuilderAction.DELETE,
|
||||
): Promise<Partial<WorkspaceMigrationEntity>[]>;
|
||||
|
||||
async create(
|
||||
objectMetadataUpdateCollection: ObjectMetadataUpdate[],
|
||||
action: WorkspaceMigrationBuilderAction.UPDATE,
|
||||
): Promise<Partial<WorkspaceMigrationEntity>[]>;
|
||||
|
||||
async create(
|
||||
objectMetadataCollectionOrObjectMetadataUpdateCollection:
|
||||
| ObjectMetadataEntity[]
|
||||
| ObjectMetadataUpdate[],
|
||||
action: WorkspaceMigrationBuilderAction,
|
||||
): Promise<Partial<WorkspaceMigrationEntity>[]> {
|
||||
switch (action) {
|
||||
case WorkspaceMigrationBuilderAction.CREATE:
|
||||
return this.createObjectMigration(objectMetadataCollection);
|
||||
return this.createObjectMigration(
|
||||
objectMetadataCollectionOrObjectMetadataUpdateCollection as ObjectMetadataEntity[],
|
||||
);
|
||||
case WorkspaceMigrationBuilderAction.UPDATE:
|
||||
return this.updateObjectMigration(
|
||||
objectMetadataCollectionOrObjectMetadataUpdateCollection as ObjectMetadataUpdate[],
|
||||
);
|
||||
case WorkspaceMigrationBuilderAction.DELETE:
|
||||
return this.deleteObjectMigration(objectMetadataCollection);
|
||||
return this.deleteObjectMigration(
|
||||
objectMetadataCollectionOrObjectMetadataUpdateCollection as ObjectMetadataEntity[],
|
||||
);
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
@ -42,7 +70,7 @@ export class WorkspaceMigrationObjectFactory {
|
||||
const migrations: WorkspaceMigrationTableAction[] = [
|
||||
{
|
||||
name: computeObjectTargetTable(objectMetadata),
|
||||
action: 'create',
|
||||
action: WorkspaceMigrationTableActionType.CREATE,
|
||||
},
|
||||
];
|
||||
|
||||
@ -53,7 +81,7 @@ export class WorkspaceMigrationObjectFactory {
|
||||
|
||||
migrations.push({
|
||||
name: computeObjectTargetTable(objectMetadata),
|
||||
action: 'alter',
|
||||
action: WorkspaceMigrationTableActionType.ALTER,
|
||||
columns: this.workspaceMigrationFactory.createColumnActions(
|
||||
WorkspaceMigrationColumnActionType.CREATE,
|
||||
field,
|
||||
@ -72,6 +100,40 @@ export class WorkspaceMigrationObjectFactory {
|
||||
return workspaceMigrations;
|
||||
}
|
||||
|
||||
private async updateObjectMigration(
|
||||
objectMetadataUpdateCollection: ObjectMetadataUpdate[],
|
||||
): Promise<Partial<WorkspaceMigrationEntity>[]> {
|
||||
const workspaceMigrations: Partial<WorkspaceMigrationEntity>[] = [];
|
||||
|
||||
for (const objectMetadataUpdate of objectMetadataUpdateCollection) {
|
||||
const oldTableName = computeObjectTargetTable(
|
||||
objectMetadataUpdate.current,
|
||||
);
|
||||
const newTableName = computeObjectTargetTable(
|
||||
objectMetadataUpdate.altered,
|
||||
);
|
||||
|
||||
if (oldTableName !== newTableName) {
|
||||
workspaceMigrations.push({
|
||||
workspaceId: objectMetadataUpdate.current.workspaceId,
|
||||
name: generateMigrationName(
|
||||
`rename-${objectMetadataUpdate.current.nameSingular}`,
|
||||
),
|
||||
isCustom: false,
|
||||
migrations: [
|
||||
{
|
||||
name: oldTableName,
|
||||
newName: newTableName,
|
||||
action: WorkspaceMigrationTableActionType.ALTER,
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return workspaceMigrations;
|
||||
}
|
||||
|
||||
private async deleteObjectMigration(
|
||||
objectMetadataCollection: ObjectMetadataEntity[],
|
||||
): Promise<Partial<WorkspaceMigrationEntity>[]> {
|
||||
@ -81,8 +143,7 @@ export class WorkspaceMigrationObjectFactory {
|
||||
const migrations: WorkspaceMigrationTableAction[] = [
|
||||
{
|
||||
name: computeObjectTargetTable(objectMetadata),
|
||||
action: 'drop',
|
||||
columns: [],
|
||||
action: WorkspaceMigrationTableActionType.DROP,
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
@ -7,6 +7,7 @@ import {
|
||||
WorkspaceMigrationColumnActionType,
|
||||
WorkspaceMigrationEntity,
|
||||
WorkspaceMigrationTableAction,
|
||||
WorkspaceMigrationTableActionType,
|
||||
} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
|
||||
import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util';
|
||||
import {
|
||||
@ -90,7 +91,7 @@ export class WorkspaceMigrationRelationFactory {
|
||||
const migrations: WorkspaceMigrationTableAction[] = [
|
||||
{
|
||||
name: computeObjectTargetTable(toObjectMetadata),
|
||||
action: 'alter',
|
||||
action: WorkspaceMigrationTableActionType.ALTER,
|
||||
columns: [
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.DROP_FOREIGN_KEY,
|
||||
@ -100,7 +101,7 @@ export class WorkspaceMigrationRelationFactory {
|
||||
},
|
||||
{
|
||||
name: computeObjectTargetTable(toObjectMetadata),
|
||||
action: 'alter',
|
||||
action: WorkspaceMigrationTableActionType.ALTER,
|
||||
columns: [
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.CREATE_FOREIGN_KEY,
|
||||
@ -166,7 +167,7 @@ export class WorkspaceMigrationRelationFactory {
|
||||
const migrations: WorkspaceMigrationTableAction[] = [
|
||||
{
|
||||
name: computeObjectTargetTable(toObjectMetadata),
|
||||
action: 'alter',
|
||||
action: WorkspaceMigrationTableActionType.ALTER,
|
||||
columns: [
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.CREATE_FOREIGN_KEY,
|
||||
|
||||
@ -18,6 +18,7 @@ import {
|
||||
WorkspaceMigrationColumnCreateRelation,
|
||||
WorkspaceMigrationColumnAlter,
|
||||
WorkspaceMigrationColumnDropRelation,
|
||||
WorkspaceMigrationTableActionType,
|
||||
WorkspaceMigrationForeignTable,
|
||||
} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
|
||||
import { WorkspaceCacheVersionService } from 'src/engine/metadata-modules/workspace-cache-version/workspace-cache-version.service';
|
||||
@ -118,18 +119,30 @@ export class WorkspaceMigrationRunnerService {
|
||||
tableMigration: WorkspaceMigrationTableAction,
|
||||
) {
|
||||
switch (tableMigration.action) {
|
||||
case 'create':
|
||||
case WorkspaceMigrationTableActionType.CREATE:
|
||||
await this.createTable(queryRunner, schemaName, tableMigration.name);
|
||||
break;
|
||||
case 'alter':
|
||||
await this.handleColumnChanges(
|
||||
queryRunner,
|
||||
schemaName,
|
||||
tableMigration.name,
|
||||
tableMigration?.columns,
|
||||
);
|
||||
case WorkspaceMigrationTableActionType.ALTER: {
|
||||
if (tableMigration.newName) {
|
||||
await this.renameTable(
|
||||
queryRunner,
|
||||
schemaName,
|
||||
tableMigration.name,
|
||||
tableMigration.newName,
|
||||
);
|
||||
}
|
||||
|
||||
if (tableMigration.columns && tableMigration.columns.length > 0) {
|
||||
await this.handleColumnChanges(
|
||||
queryRunner,
|
||||
schemaName,
|
||||
tableMigration.newName ?? tableMigration.name,
|
||||
tableMigration.columns,
|
||||
);
|
||||
}
|
||||
break;
|
||||
case 'drop':
|
||||
}
|
||||
case WorkspaceMigrationTableActionType.DROP:
|
||||
await queryRunner.dropTable(`${schemaName}.${tableMigration.name}`);
|
||||
break;
|
||||
case 'create_foreign_table':
|
||||
@ -179,6 +192,25 @@ export class WorkspaceMigrationRunnerService {
|
||||
`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename a table
|
||||
* @param queryRunner QueryRunner
|
||||
* @param schemaName string
|
||||
* @param oldTableName string
|
||||
* @param newTableName string
|
||||
*/
|
||||
private async renameTable(
|
||||
queryRunner: QueryRunner,
|
||||
schemaName: string,
|
||||
oldTableName: string,
|
||||
newTableName: string,
|
||||
) {
|
||||
await queryRunner.renameTable(
|
||||
`${schemaName}.${oldTableName}`,
|
||||
newTableName,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles column changes for a given migration
|
||||
*
|
||||
|
||||
@ -42,27 +42,39 @@ export class SyncWorkspaceMetadataCommand extends CommandRunner {
|
||||
: await this.workspaceService.getWorkspaceIds();
|
||||
|
||||
for (const workspaceId of workspaceIds) {
|
||||
const issues = await this.workspaceHealthService.healthCheck(workspaceId);
|
||||
try {
|
||||
const issues =
|
||||
await this.workspaceHealthService.healthCheck(workspaceId);
|
||||
|
||||
// Security: abort if there are issues.
|
||||
if (issues.length > 0) {
|
||||
// Security: abort if there are issues.
|
||||
if (issues.length > 0) {
|
||||
if (!options.force) {
|
||||
this.logger.error(
|
||||
`Workspace contains ${issues.length} issues, aborting.`,
|
||||
);
|
||||
|
||||
this.logger.log(
|
||||
'If you want to force the migration, use --force flag',
|
||||
);
|
||||
this.logger.log(
|
||||
'Please use `workspace:health` command to check issues and fix them before running this command.',
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.logger.warn(
|
||||
`Workspace contains ${issues.length} issues, sync has been forced.`,
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
if (!options.force) {
|
||||
this.logger.error(
|
||||
`Workspace contains ${issues.length} issues, aborting.`,
|
||||
);
|
||||
|
||||
this.logger.log(
|
||||
'If you want to force the migration, use --force flag',
|
||||
);
|
||||
this.logger.log(
|
||||
'Please use `workspace:health` command to check issues and fix them before running this command.',
|
||||
);
|
||||
|
||||
return;
|
||||
throw error;
|
||||
}
|
||||
|
||||
this.logger.warn(
|
||||
`Workspace contains ${issues.length} issues, sync has been forced.`,
|
||||
`Workspace health check failed with error, but sync has been forced.`,
|
||||
error,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -33,7 +33,9 @@ export interface ComparatorDeleteResult<T> {
|
||||
export type ObjectComparatorResult =
|
||||
| ComparatorSkipResult
|
||||
| ComparatorCreateResult<ComputedPartialObjectMetadata>
|
||||
| ComparatorUpdateResult<Partial<ComputedPartialObjectMetadata>>;
|
||||
| ComparatorUpdateResult<
|
||||
Partial<ComputedPartialObjectMetadata> & { id: string }
|
||||
>;
|
||||
|
||||
export type FieldComparatorResult =
|
||||
| ComparatorSkipResult
|
||||
|
||||
@ -1,8 +1,13 @@
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
|
||||
import { EntityManager, In } from 'typeorm';
|
||||
import {
|
||||
EntityManager,
|
||||
EntityTarget,
|
||||
FindOptionsWhere,
|
||||
In,
|
||||
ObjectLiteral,
|
||||
} from 'typeorm';
|
||||
import { v4 as uuidV4 } from 'uuid';
|
||||
import omit from 'lodash.omit';
|
||||
|
||||
import { PartialFieldMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/partial-field-metadata.interface';
|
||||
|
||||
@ -14,6 +19,8 @@ import {
|
||||
import { RelationMetadataEntity } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity';
|
||||
import { FieldMetadataComplexOption } from 'src/engine/metadata-modules/field-metadata/dtos/options.input';
|
||||
import { WorkspaceSyncStorage } from 'src/engine/workspace-manager/workspace-sync-metadata/storage/workspace-sync.storage';
|
||||
import { FieldMetadataUpdate } from 'src/engine/workspace-manager/workspace-migration-builder/factories/workspace-migration-field.factory';
|
||||
import { ObjectMetadataUpdate } from 'src/engine/workspace-manager/workspace-migration-builder/factories/workspace-migration-object.factory';
|
||||
|
||||
@Injectable()
|
||||
export class WorkspaceMetadataUpdaterService {
|
||||
@ -24,7 +31,7 @@ export class WorkspaceMetadataUpdaterService {
|
||||
storage: WorkspaceSyncStorage,
|
||||
): Promise<{
|
||||
createdObjectMetadataCollection: ObjectMetadataEntity[];
|
||||
updatedObjectMetadataCollection: ObjectMetadataEntity[];
|
||||
updatedObjectMetadataCollection: ObjectMetadataUpdate[];
|
||||
}> {
|
||||
const objectMetadataRepository =
|
||||
manager.getRepository(ObjectMetadataEntity);
|
||||
@ -56,10 +63,17 @@ export class WorkspaceMetadataUpdaterService {
|
||||
/**
|
||||
* Update object metadata
|
||||
*/
|
||||
const updatedObjectMetadataCollection = await objectMetadataRepository.save(
|
||||
storage.objectMetadataUpdateCollection.map((objectMetadata) =>
|
||||
omit(objectMetadata, ['fields']),
|
||||
),
|
||||
const updatedObjectMetadataCollection = await this.updateEntities(
|
||||
manager,
|
||||
ObjectMetadataEntity,
|
||||
storage.objectMetadataUpdateCollection,
|
||||
[
|
||||
'fields',
|
||||
'dataSourceId',
|
||||
'workspaceId',
|
||||
'labelIdentifierFieldMetadataId',
|
||||
'imageIdentifierFieldMetadataId',
|
||||
],
|
||||
);
|
||||
|
||||
/**
|
||||
@ -108,10 +122,7 @@ export class WorkspaceMetadataUpdaterService {
|
||||
storage: WorkspaceSyncStorage,
|
||||
): Promise<{
|
||||
createdFieldMetadataCollection: FieldMetadataEntity[];
|
||||
updatedFieldMetadataCollection: {
|
||||
current: FieldMetadataEntity;
|
||||
altered: FieldMetadataEntity;
|
||||
}[];
|
||||
updatedFieldMetadataCollection: FieldMetadataUpdate[];
|
||||
}> {
|
||||
const fieldMetadataRepository = manager.getRepository(FieldMetadataEntity);
|
||||
|
||||
@ -127,41 +138,12 @@ export class WorkspaceMetadataUpdaterService {
|
||||
/**
|
||||
* Update field metadata
|
||||
*/
|
||||
const oldFieldMetadataCollection = await fieldMetadataRepository.findBy({
|
||||
id: In(storage.fieldMetadataUpdateCollection.map((field) => field.id)),
|
||||
});
|
||||
// Pre-process old collection into a mapping for quick access
|
||||
const oldFieldMetadataMap = new Map(
|
||||
oldFieldMetadataCollection.map((field) => [field.id, field]),
|
||||
);
|
||||
// Combine old and new field metadata to get whole updated entities
|
||||
const fieldMetadataUpdateCollection =
|
||||
storage.fieldMetadataUpdateCollection.map((updateFieldMetadata) => {
|
||||
const oldFieldMetadata = oldFieldMetadataMap.get(
|
||||
updateFieldMetadata.id,
|
||||
);
|
||||
|
||||
if (!oldFieldMetadata) {
|
||||
throw new Error(`
|
||||
Field ${updateFieldMetadata.id} not found in oldFieldMetadataCollection`);
|
||||
}
|
||||
|
||||
// TypeORM 😢
|
||||
// If we didn't provide the old value, it will be set to null fields that are not in the updateFieldMetadata
|
||||
// and override the old value with null in the DB.
|
||||
// Also save method doesn't return the whole entity if you give a partial one.
|
||||
// https://github.com/typeorm/typeorm/issues/3490
|
||||
// To avoid calling update in a for loop, we did this hack.
|
||||
return {
|
||||
...omit(oldFieldMetadata, ['objectMetadataId', 'workspaceId']),
|
||||
...omit(updateFieldMetadata, ['objectMetadataId', 'workspaceId']),
|
||||
options: updateFieldMetadata.options ?? oldFieldMetadata.options,
|
||||
};
|
||||
});
|
||||
|
||||
const updatedFieldMetadataCollection = await fieldMetadataRepository.save(
|
||||
fieldMetadataUpdateCollection,
|
||||
);
|
||||
const updatedFieldMetadataCollection = await this.updateEntities<
|
||||
FieldMetadataEntity<'default'>
|
||||
>(manager, FieldMetadataEntity, storage.objectMetadataUpdateCollection, [
|
||||
'objectMetadataId',
|
||||
'workspaceId',
|
||||
]);
|
||||
|
||||
/**
|
||||
* Delete field metadata
|
||||
@ -183,28 +165,7 @@ export class WorkspaceMetadataUpdaterService {
|
||||
return {
|
||||
createdFieldMetadataCollection:
|
||||
createdFieldMetadataCollection as FieldMetadataEntity[],
|
||||
updatedFieldMetadataCollection: updatedFieldMetadataCollection.map(
|
||||
(alteredFieldMetadata) => {
|
||||
const oldFieldMetadata = oldFieldMetadataMap.get(
|
||||
alteredFieldMetadata.id,
|
||||
);
|
||||
|
||||
if (!oldFieldMetadata) {
|
||||
throw new Error(`
|
||||
Field ${alteredFieldMetadata.id} not found in oldFieldMetadataCollection
|
||||
`);
|
||||
}
|
||||
|
||||
return {
|
||||
current: oldFieldMetadata as FieldMetadataEntity,
|
||||
altered: {
|
||||
...alteredFieldMetadata,
|
||||
objectMetadataId: oldFieldMetadata.objectMetadataId,
|
||||
workspaceId: oldFieldMetadata.workspaceId,
|
||||
} as FieldMetadataEntity,
|
||||
};
|
||||
},
|
||||
),
|
||||
updatedFieldMetadataCollection,
|
||||
};
|
||||
}
|
||||
|
||||
@ -267,4 +228,83 @@ export class WorkspaceMetadataUpdaterService {
|
||||
updatedRelationMetadataCollection,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Update entities in the database
|
||||
* @param manager EntityManager
|
||||
* @param entityClass Entity class
|
||||
* @param updateCollection Update collection
|
||||
* @param keysToOmit keys to omit in the merge process
|
||||
* @returns Promise<{ current: Entity; altered: Entity }[]>
|
||||
*/
|
||||
private async updateEntities<Entity extends ObjectLiteral & { id: string }>(
|
||||
manager: EntityManager,
|
||||
entityClass: EntityTarget<Entity>,
|
||||
updateCollection: Array<
|
||||
DeepPartial<Omit<Entity, 'fields'>> & { id: string }
|
||||
>,
|
||||
keysToOmit: (keyof Entity)[] = [],
|
||||
): Promise<{ current: Entity; altered: Entity }[]> {
|
||||
const repository = manager.getRepository(entityClass);
|
||||
|
||||
const oldEntities = await repository.findBy({
|
||||
id: In(updateCollection.map((updateItem) => updateItem.id)),
|
||||
} as FindOptionsWhere<Entity>);
|
||||
|
||||
// Pre-process old collection into a mapping for quick access
|
||||
const oldEntitiesMap = new Map(
|
||||
oldEntities.map((oldEntity) => [oldEntity.id, oldEntity]),
|
||||
);
|
||||
|
||||
// Combine old and new field metadata to get whole updated entities
|
||||
const entityUpdateCollection = updateCollection.map((updateItem) => {
|
||||
const oldEntity = oldEntitiesMap.get(updateItem.id);
|
||||
|
||||
if (!oldEntity) {
|
||||
throw new Error(`
|
||||
Entity ${updateItem.id} not found in oldEntities`);
|
||||
}
|
||||
|
||||
// TypeORM 😢
|
||||
// If we didn't provide the old value, it will be set to null objects that are not in the updateObjectMetadata
|
||||
// and override the old value with null in the DB.
|
||||
// Also save method doesn't return the whole entity if you give a partial one.
|
||||
// https://github.com/typeorm/typeorm/issues/3490
|
||||
// To avoid calling update in a for loop, we did this hack.
|
||||
const mergedUpdate = {
|
||||
...oldEntity,
|
||||
...updateItem,
|
||||
};
|
||||
|
||||
// Omit keys that we don't want to override
|
||||
keysToOmit.forEach((key) => {
|
||||
delete mergedUpdate[key];
|
||||
});
|
||||
|
||||
return mergedUpdate;
|
||||
});
|
||||
|
||||
const updatedEntities = await repository.save(entityUpdateCollection);
|
||||
|
||||
return updatedEntities.map((updatedEntity) => {
|
||||
const oldEntity = oldEntitiesMap.get(updatedEntity.id);
|
||||
|
||||
if (!oldEntity) {
|
||||
throw new Error(`
|
||||
Entity ${updatedEntity.id} not found in oldEntitiesMap
|
||||
`);
|
||||
}
|
||||
|
||||
return {
|
||||
current: oldEntity,
|
||||
altered: {
|
||||
...updatedEntity,
|
||||
...keysToOmit.reduce(
|
||||
(acc, key) => ({ ...acc, [key]: oldEntity[key] }),
|
||||
{},
|
||||
),
|
||||
},
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -154,6 +154,12 @@ export class WorkspaceSyncObjectMetadataService {
|
||||
WorkspaceMigrationBuilderAction.CREATE,
|
||||
);
|
||||
|
||||
const updateObjectWorkspaceMigrations =
|
||||
await this.workspaceMigrationObjectFactory.create(
|
||||
metadataObjectUpdaterResult.updatedObjectMetadataCollection,
|
||||
WorkspaceMigrationBuilderAction.UPDATE,
|
||||
);
|
||||
|
||||
const deleteObjectWorkspaceMigrations =
|
||||
await this.workspaceMigrationObjectFactory.create(
|
||||
storage.objectMetadataDeleteCollection,
|
||||
@ -164,6 +170,7 @@ export class WorkspaceSyncObjectMetadataService {
|
||||
|
||||
return [
|
||||
...createObjectWorkspaceMigrations,
|
||||
...updateObjectWorkspaceMigrations,
|
||||
...deleteObjectWorkspaceMigrations,
|
||||
];
|
||||
}
|
||||
|
||||
@ -10,8 +10,9 @@ export class WorkspaceSyncStorage {
|
||||
// Object metadata
|
||||
private readonly _objectMetadataCreateCollection: ComputedPartialObjectMetadata[] =
|
||||
[];
|
||||
private readonly _objectMetadataUpdateCollection: Partial<ComputedPartialObjectMetadata>[] =
|
||||
[];
|
||||
private readonly _objectMetadataUpdateCollection: (Partial<ComputedPartialObjectMetadata> & {
|
||||
id: string;
|
||||
})[] = [];
|
||||
private readonly _objectMetadataDeleteCollection: ObjectMetadataEntity[] = [];
|
||||
|
||||
// Field metadata
|
||||
@ -72,7 +73,9 @@ export class WorkspaceSyncStorage {
|
||||
this._objectMetadataCreateCollection.push(object);
|
||||
}
|
||||
|
||||
addUpdateObjectMetadata(object: Partial<ComputedPartialObjectMetadata>) {
|
||||
addUpdateObjectMetadata(
|
||||
object: Partial<ComputedPartialObjectMetadata> & { id: string },
|
||||
) {
|
||||
this._objectMetadataUpdateCollection.push(object);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user