feat: add deletion support on sync metadata command (#3826)
* feat: add deletion support on sync metadata command * fix: remove debug
This commit is contained in:
@ -1,3 +1,6 @@
|
|||||||
export function generateMigrationName(name?: string): string {
|
export function generateMigrationName(
|
||||||
return `${new Date().getTime()}${name ? `-${name}` : ''}`;
|
name?: string,
|
||||||
|
addMilliseconds: number = 0,
|
||||||
|
): string {
|
||||||
|
return `${new Date().getTime() + addMilliseconds}${name ? `-${name}` : ''}`;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,133 @@
|
|||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
|
||||||
|
import {
|
||||||
|
FieldMetadataEntity,
|
||||||
|
FieldMetadataType,
|
||||||
|
} from 'src/metadata/field-metadata/field-metadata.entity';
|
||||||
|
import { ObjectMetadataEntity } from 'src/metadata/object-metadata/object-metadata.entity';
|
||||||
|
import {
|
||||||
|
WorkspaceMigrationColumnActionType,
|
||||||
|
WorkspaceMigrationEntity,
|
||||||
|
WorkspaceMigrationTableAction,
|
||||||
|
} from 'src/metadata/workspace-migration/workspace-migration.entity';
|
||||||
|
import { computeObjectTargetTable } from 'src/workspace/utils/compute-object-target-table.util';
|
||||||
|
import { WorkspaceMigrationFactory } from 'src/metadata/workspace-migration/workspace-migration.factory';
|
||||||
|
import { generateMigrationName } from 'src/metadata/workspace-migration/utils/generate-migration-name.util';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class FieldWorkspaceMigrationFactory {
|
||||||
|
constructor(
|
||||||
|
private readonly workspaceMigrationFactory: WorkspaceMigrationFactory,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
async create(
|
||||||
|
originalObjectMetadataCollection: ObjectMetadataEntity[],
|
||||||
|
createFieldMetadataCollection: FieldMetadataEntity[],
|
||||||
|
deleteFieldMetadataCollection: FieldMetadataEntity[],
|
||||||
|
): Promise<Partial<WorkspaceMigrationEntity>[]> {
|
||||||
|
const workspaceMigrations: Partial<WorkspaceMigrationEntity>[] = [];
|
||||||
|
const originalObjectMetadataMap = originalObjectMetadataCollection.reduce(
|
||||||
|
(result, currentObject) => {
|
||||||
|
result[currentObject.id] = currentObject;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
{} as Record<string, ObjectMetadataEntity>,
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create field migrations
|
||||||
|
*/
|
||||||
|
if (createFieldMetadataCollection.length > 0) {
|
||||||
|
const createFieldWorkspaceMigrations = await this.createFieldMigration(
|
||||||
|
originalObjectMetadataMap,
|
||||||
|
createFieldMetadataCollection,
|
||||||
|
);
|
||||||
|
|
||||||
|
workspaceMigrations.push(...createFieldWorkspaceMigrations);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete field migrations
|
||||||
|
*/
|
||||||
|
if (deleteFieldMetadataCollection.length > 0) {
|
||||||
|
const deleteFieldWorkspaceMigrations = await this.deleteFieldMigration(
|
||||||
|
originalObjectMetadataMap,
|
||||||
|
deleteFieldMetadataCollection,
|
||||||
|
);
|
||||||
|
|
||||||
|
workspaceMigrations.push(...deleteFieldWorkspaceMigrations);
|
||||||
|
}
|
||||||
|
|
||||||
|
return workspaceMigrations;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async createFieldMigration(
|
||||||
|
originalObjectMetadataMap: Record<string, ObjectMetadataEntity>,
|
||||||
|
fieldMetadataCollection: FieldMetadataEntity[],
|
||||||
|
): Promise<Partial<WorkspaceMigrationEntity>[]> {
|
||||||
|
const workspaceMigrations: Partial<WorkspaceMigrationEntity>[] = [];
|
||||||
|
|
||||||
|
for (const fieldMetadata of fieldMetadataCollection) {
|
||||||
|
const migrations: WorkspaceMigrationTableAction[] = [
|
||||||
|
{
|
||||||
|
name: computeObjectTargetTable(
|
||||||
|
originalObjectMetadataMap[fieldMetadata.objectMetadataId],
|
||||||
|
),
|
||||||
|
action: 'alter',
|
||||||
|
columns: this.workspaceMigrationFactory.createColumnActions(
|
||||||
|
WorkspaceMigrationColumnActionType.CREATE,
|
||||||
|
fieldMetadata,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
workspaceMigrations.push({
|
||||||
|
workspaceId: fieldMetadata.workspaceId,
|
||||||
|
name: generateMigrationName(`create-${fieldMetadata.name}`),
|
||||||
|
isCustom: false,
|
||||||
|
migrations,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return workspaceMigrations;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async deleteFieldMigration(
|
||||||
|
originalObjectMetadataMap: Record<string, ObjectMetadataEntity>,
|
||||||
|
fieldMetadataCollection: FieldMetadataEntity[],
|
||||||
|
): Promise<Partial<WorkspaceMigrationEntity>[]> {
|
||||||
|
const workspaceMigrations: Partial<WorkspaceMigrationEntity>[] = [];
|
||||||
|
|
||||||
|
for (const fieldMetadata of fieldMetadataCollection) {
|
||||||
|
// We're skipping relation fields, because they're just representation and not real columns
|
||||||
|
if (fieldMetadata.type === FieldMetadataType.RELATION) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const migrations: WorkspaceMigrationTableAction[] = [
|
||||||
|
{
|
||||||
|
name: computeObjectTargetTable(
|
||||||
|
originalObjectMetadataMap[fieldMetadata.objectMetadataId],
|
||||||
|
),
|
||||||
|
action: 'alter',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
action: WorkspaceMigrationColumnActionType.DROP,
|
||||||
|
columnName: fieldMetadata.name,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
workspaceMigrations.push({
|
||||||
|
workspaceId: fieldMetadata.workspaceId,
|
||||||
|
name: generateMigrationName(`delete-${fieldMetadata.name}`),
|
||||||
|
isCustom: false,
|
||||||
|
migrations,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return workspaceMigrations;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,11 +1,15 @@
|
|||||||
import { FeatureFlagFactory } from './feature-flags.factory';
|
import { FeatureFlagFactory } from './feature-flags.factory';
|
||||||
import { StandardObjectFactory } from './standard-object.factory';
|
import { StandardObjectFactory } from './standard-object.factory';
|
||||||
import { StandardRelationFactory } from './standard-relation.factory';
|
import { StandardRelationFactory } from './standard-relation.factory';
|
||||||
import { WorkspaceSyncFactory } from './workspace-sync.factory';
|
import { ObjectWorkspaceMigrationFactory } from './object-workspace-migration.factory';
|
||||||
|
import { FieldWorkspaceMigrationFactory } from './field-workspace-migration.factory';
|
||||||
|
import { RelationWorkspaceMigrationFactory } from './relation-workspace-migration.factory';
|
||||||
|
|
||||||
export const workspaceSyncMetadataFactories = [
|
export const workspaceSyncMetadataFactories = [
|
||||||
FeatureFlagFactory,
|
FeatureFlagFactory,
|
||||||
StandardObjectFactory,
|
StandardObjectFactory,
|
||||||
StandardRelationFactory,
|
StandardRelationFactory,
|
||||||
WorkspaceSyncFactory,
|
ObjectWorkspaceMigrationFactory,
|
||||||
|
FieldWorkspaceMigrationFactory,
|
||||||
|
RelationWorkspaceMigrationFactory,
|
||||||
];
|
];
|
||||||
|
|||||||
@ -0,0 +1,114 @@
|
|||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
|
||||||
|
import { FieldMetadataType } from 'src/metadata/field-metadata/field-metadata.entity';
|
||||||
|
import { ObjectMetadataEntity } from 'src/metadata/object-metadata/object-metadata.entity';
|
||||||
|
import {
|
||||||
|
WorkspaceMigrationColumnActionType,
|
||||||
|
WorkspaceMigrationEntity,
|
||||||
|
WorkspaceMigrationTableAction,
|
||||||
|
} from 'src/metadata/workspace-migration/workspace-migration.entity';
|
||||||
|
import { computeObjectTargetTable } from 'src/workspace/utils/compute-object-target-table.util';
|
||||||
|
import { WorkspaceMigrationFactory } from 'src/metadata/workspace-migration/workspace-migration.factory';
|
||||||
|
import { generateMigrationName } from 'src/metadata/workspace-migration/utils/generate-migration-name.util';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class ObjectWorkspaceMigrationFactory {
|
||||||
|
constructor(
|
||||||
|
private readonly workspaceMigrationFactory: WorkspaceMigrationFactory,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
async create(
|
||||||
|
createObjectMetadataCollection: ObjectMetadataEntity[],
|
||||||
|
deleteObjectMetadataCollection: ObjectMetadataEntity[],
|
||||||
|
): Promise<Partial<WorkspaceMigrationEntity>[]> {
|
||||||
|
const workspaceMigrations: Partial<WorkspaceMigrationEntity>[] = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create object migrations
|
||||||
|
*/
|
||||||
|
if (createObjectMetadataCollection.length > 0) {
|
||||||
|
const createObjectWorkspaceMigrations = await this.createObjectMigration(
|
||||||
|
createObjectMetadataCollection,
|
||||||
|
);
|
||||||
|
|
||||||
|
workspaceMigrations.push(...createObjectWorkspaceMigrations);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete object migrations
|
||||||
|
*/
|
||||||
|
if (deleteObjectMetadataCollection.length > 0) {
|
||||||
|
const deleteObjectWorkspaceMigrations = await this.deleteObjectMigration(
|
||||||
|
deleteObjectMetadataCollection,
|
||||||
|
);
|
||||||
|
|
||||||
|
workspaceMigrations.push(...deleteObjectWorkspaceMigrations);
|
||||||
|
}
|
||||||
|
|
||||||
|
return workspaceMigrations;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async createObjectMigration(
|
||||||
|
objectMetadataCollection: ObjectMetadataEntity[],
|
||||||
|
): Promise<Partial<WorkspaceMigrationEntity>[]> {
|
||||||
|
const workspaceMigrations: Partial<WorkspaceMigrationEntity>[] = [];
|
||||||
|
|
||||||
|
for (const objectMetadata of objectMetadataCollection) {
|
||||||
|
const migrations: WorkspaceMigrationTableAction[] = [
|
||||||
|
{
|
||||||
|
name: computeObjectTargetTable(objectMetadata),
|
||||||
|
action: 'create',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const field of objectMetadata.fields) {
|
||||||
|
if (field.type === FieldMetadataType.RELATION) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
migrations.push({
|
||||||
|
name: computeObjectTargetTable(objectMetadata),
|
||||||
|
action: 'alter',
|
||||||
|
columns: this.workspaceMigrationFactory.createColumnActions(
|
||||||
|
WorkspaceMigrationColumnActionType.CREATE,
|
||||||
|
field,
|
||||||
|
),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
workspaceMigrations.push({
|
||||||
|
workspaceId: objectMetadata.workspaceId,
|
||||||
|
name: generateMigrationName(`create-${objectMetadata.nameSingular}`),
|
||||||
|
isCustom: false,
|
||||||
|
migrations,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return workspaceMigrations;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async deleteObjectMigration(
|
||||||
|
objectMetadataCollection: ObjectMetadataEntity[],
|
||||||
|
): Promise<Partial<WorkspaceMigrationEntity>[]> {
|
||||||
|
const workspaceMigrations: Partial<WorkspaceMigrationEntity>[] = [];
|
||||||
|
|
||||||
|
for (const objectMetadata of objectMetadataCollection) {
|
||||||
|
const migrations: WorkspaceMigrationTableAction[] = [
|
||||||
|
{
|
||||||
|
name: computeObjectTargetTable(objectMetadata),
|
||||||
|
action: 'drop',
|
||||||
|
columns: [],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
workspaceMigrations.push({
|
||||||
|
workspaceId: objectMetadata.workspaceId,
|
||||||
|
name: generateMigrationName(`delete-${objectMetadata.nameSingular}`),
|
||||||
|
isCustom: false,
|
||||||
|
migrations,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return workspaceMigrations;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,115 @@
|
|||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
|
||||||
|
import { ObjectMetadataEntity } from 'src/metadata/object-metadata/object-metadata.entity';
|
||||||
|
import {
|
||||||
|
WorkspaceMigrationColumnActionType,
|
||||||
|
WorkspaceMigrationEntity,
|
||||||
|
WorkspaceMigrationTableAction,
|
||||||
|
} from 'src/metadata/workspace-migration/workspace-migration.entity';
|
||||||
|
import { computeObjectTargetTable } from 'src/workspace/utils/compute-object-target-table.util';
|
||||||
|
import {
|
||||||
|
RelationMetadataEntity,
|
||||||
|
RelationMetadataType,
|
||||||
|
} from 'src/metadata/relation-metadata/relation-metadata.entity';
|
||||||
|
import { camelCase } from 'src/utils/camel-case';
|
||||||
|
import { generateMigrationName } from 'src/metadata/workspace-migration/utils/generate-migration-name.util';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class RelationWorkspaceMigrationFactory {
|
||||||
|
constructor() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletion of the relation is handled by field deletion
|
||||||
|
*/
|
||||||
|
async create(
|
||||||
|
originalObjectMetadataCollection: ObjectMetadataEntity[],
|
||||||
|
createRelationMetadataCollection: RelationMetadataEntity[],
|
||||||
|
): Promise<Partial<WorkspaceMigrationEntity>[]> {
|
||||||
|
const workspaceMigrations: Partial<WorkspaceMigrationEntity>[] = [];
|
||||||
|
const originalObjectMetadataMap = originalObjectMetadataCollection.reduce(
|
||||||
|
(result, currentObject) => {
|
||||||
|
result[currentObject.id] = currentObject;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
{} as Record<string, ObjectMetadataEntity>,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (createRelationMetadataCollection.length > 0) {
|
||||||
|
const createRelationWorkspaceMigrations =
|
||||||
|
await this.createRelationMigration(
|
||||||
|
originalObjectMetadataMap,
|
||||||
|
createRelationMetadataCollection,
|
||||||
|
);
|
||||||
|
|
||||||
|
workspaceMigrations.push(...createRelationWorkspaceMigrations);
|
||||||
|
}
|
||||||
|
|
||||||
|
return workspaceMigrations;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async createRelationMigration(
|
||||||
|
originalObjectMetadataMap: Record<string, ObjectMetadataEntity>,
|
||||||
|
relationMetadataCollection: RelationMetadataEntity[],
|
||||||
|
): Promise<Partial<WorkspaceMigrationEntity>[]> {
|
||||||
|
const workspaceMigrations: Partial<WorkspaceMigrationEntity>[] = [];
|
||||||
|
|
||||||
|
for (const relationMetadata of relationMetadataCollection) {
|
||||||
|
const toObjectMetadata =
|
||||||
|
originalObjectMetadataMap[relationMetadata.toObjectMetadataId];
|
||||||
|
const fromObjectMetadata =
|
||||||
|
originalObjectMetadataMap[relationMetadata.fromObjectMetadataId];
|
||||||
|
|
||||||
|
if (!toObjectMetadata) {
|
||||||
|
throw new Error(
|
||||||
|
`ObjectMetadata with id ${relationMetadata.toObjectMetadataId} not found`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fromObjectMetadata) {
|
||||||
|
throw new Error(
|
||||||
|
`ObjectMetadata with id ${relationMetadata.fromObjectMetadataId} not found`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const toFieldMetadata = toObjectMetadata.fields.find(
|
||||||
|
(field) => field.id === relationMetadata.toFieldMetadataId,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!toFieldMetadata) {
|
||||||
|
throw new Error(
|
||||||
|
`FieldMetadata with id ${relationMetadata.toFieldMetadataId} not found`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const migrations: WorkspaceMigrationTableAction[] = [
|
||||||
|
{
|
||||||
|
name: computeObjectTargetTable(toObjectMetadata),
|
||||||
|
action: 'alter',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
action: WorkspaceMigrationColumnActionType.RELATION,
|
||||||
|
columnName: `${camelCase(toFieldMetadata.name)}Id`,
|
||||||
|
referencedTableName: computeObjectTargetTable(fromObjectMetadata),
|
||||||
|
referencedTableColumnName: 'id',
|
||||||
|
isUnique:
|
||||||
|
relationMetadata.relationType ===
|
||||||
|
RelationMetadataType.ONE_TO_ONE,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
workspaceMigrations.push({
|
||||||
|
workspaceId: relationMetadata.workspaceId,
|
||||||
|
name: generateMigrationName(
|
||||||
|
`create-relation-from-${fromObjectMetadata.nameSingular}-to-${toObjectMetadata.nameSingular}`,
|
||||||
|
),
|
||||||
|
isCustom: false,
|
||||||
|
migrations,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return workspaceMigrations;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -6,7 +6,7 @@ import { FeatureFlagMap } from 'src/core/feature-flag/interfaces/feature-flag-ma
|
|||||||
import { PartialFieldMetadata } from 'src/workspace/workspace-sync-metadata/interfaces/partial-field-metadata.interface';
|
import { PartialFieldMetadata } from 'src/workspace/workspace-sync-metadata/interfaces/partial-field-metadata.interface';
|
||||||
|
|
||||||
import { BaseObjectMetadata } from 'src/workspace/workspace-sync-metadata/standard-objects/base.object-metadata';
|
import { BaseObjectMetadata } from 'src/workspace/workspace-sync-metadata/standard-objects/base.object-metadata';
|
||||||
import { standardObjectMetadata } from 'src/workspace/workspace-sync-metadata/standard-objects';
|
import { standardObjectMetadataCollection } from 'src/workspace/workspace-sync-metadata/standard-objects';
|
||||||
import { TypedReflect } from 'src/utils/typed-reflect';
|
import { TypedReflect } from 'src/utils/typed-reflect';
|
||||||
import { isGatedAndNotEnabled } from 'src/workspace/workspace-sync-metadata/utils/is-gate-and-not-enabled.util';
|
import { isGatedAndNotEnabled } from 'src/workspace/workspace-sync-metadata/utils/is-gate-and-not-enabled.util';
|
||||||
|
|
||||||
@ -16,7 +16,7 @@ export class StandardObjectFactory {
|
|||||||
context: WorkspaceSyncContext,
|
context: WorkspaceSyncContext,
|
||||||
workspaceFeatureFlagsMap: FeatureFlagMap,
|
workspaceFeatureFlagsMap: FeatureFlagMap,
|
||||||
): PartialObjectMetadata[] {
|
): PartialObjectMetadata[] {
|
||||||
return standardObjectMetadata
|
return standardObjectMetadataCollection
|
||||||
.map((metadata) =>
|
.map((metadata) =>
|
||||||
this.createObjectMetadata(metadata, context, workspaceFeatureFlagsMap),
|
this.createObjectMetadata(metadata, context, workspaceFeatureFlagsMap),
|
||||||
)
|
)
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import { WorkspaceSyncContext } from 'src/workspace/workspace-sync-metadata/inte
|
|||||||
import { FeatureFlagMap } from 'src/core/feature-flag/interfaces/feature-flag-map.interface';
|
import { FeatureFlagMap } from 'src/core/feature-flag/interfaces/feature-flag-map.interface';
|
||||||
|
|
||||||
import { BaseObjectMetadata } from 'src/workspace/workspace-sync-metadata/standard-objects/base.object-metadata';
|
import { BaseObjectMetadata } from 'src/workspace/workspace-sync-metadata/standard-objects/base.object-metadata';
|
||||||
import { standardObjectMetadata } from 'src/workspace/workspace-sync-metadata/standard-objects';
|
import { standardObjectMetadataCollection } from 'src/workspace/workspace-sync-metadata/standard-objects';
|
||||||
import { TypedReflect } from 'src/utils/typed-reflect';
|
import { TypedReflect } from 'src/utils/typed-reflect';
|
||||||
import { isGatedAndNotEnabled } from 'src/workspace/workspace-sync-metadata/utils/is-gate-and-not-enabled.util';
|
import { isGatedAndNotEnabled } from 'src/workspace/workspace-sync-metadata/utils/is-gate-and-not-enabled.util';
|
||||||
import { assert } from 'src/utils/assert';
|
import { assert } from 'src/utils/assert';
|
||||||
@ -18,7 +18,7 @@ export class StandardRelationFactory {
|
|||||||
originalObjectMetadataMap: Record<string, ObjectMetadataEntity>,
|
originalObjectMetadataMap: Record<string, ObjectMetadataEntity>,
|
||||||
workspaceFeatureFlagsMap: FeatureFlagMap,
|
workspaceFeatureFlagsMap: FeatureFlagMap,
|
||||||
): Partial<RelationMetadataEntity>[] {
|
): Partial<RelationMetadataEntity>[] {
|
||||||
return standardObjectMetadata.flatMap((standardObjectMetadata) =>
|
return standardObjectMetadataCollection.flatMap((standardObjectMetadata) =>
|
||||||
this.createRelationMetadata(
|
this.createRelationMetadata(
|
||||||
standardObjectMetadata,
|
standardObjectMetadata,
|
||||||
context,
|
context,
|
||||||
|
|||||||
@ -1,268 +0,0 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
|
||||||
|
|
||||||
import {
|
|
||||||
FieldMetadataEntity,
|
|
||||||
FieldMetadataType,
|
|
||||||
} from 'src/metadata/field-metadata/field-metadata.entity';
|
|
||||||
import { ObjectMetadataEntity } from 'src/metadata/object-metadata/object-metadata.entity';
|
|
||||||
import {
|
|
||||||
WorkspaceMigrationColumnActionType,
|
|
||||||
WorkspaceMigrationColumnRelation,
|
|
||||||
WorkspaceMigrationEntity,
|
|
||||||
WorkspaceMigrationTableAction,
|
|
||||||
} from 'src/metadata/workspace-migration/workspace-migration.entity';
|
|
||||||
import { computeObjectTargetTable } from 'src/workspace/utils/compute-object-target-table.util';
|
|
||||||
import { WorkspaceMigrationFactory } from 'src/metadata/workspace-migration/workspace-migration.factory';
|
|
||||||
import {
|
|
||||||
RelationMetadataEntity,
|
|
||||||
RelationMetadataType,
|
|
||||||
} from 'src/metadata/relation-metadata/relation-metadata.entity';
|
|
||||||
import { camelCase } from 'src/utils/camel-case';
|
|
||||||
import { generateMigrationName } from 'src/metadata/workspace-migration/utils/generate-migration-name.util';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class WorkspaceSyncFactory {
|
|
||||||
constructor(
|
|
||||||
private readonly workspaceMigrationFactory: WorkspaceMigrationFactory,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
async createObjectMigration(
|
|
||||||
originalObjectMetadataCollection: ObjectMetadataEntity[],
|
|
||||||
createdObjectMetadataCollection: ObjectMetadataEntity[],
|
|
||||||
objectMetadataDeleteCollection: ObjectMetadataEntity[],
|
|
||||||
createdFieldMetadataCollection: FieldMetadataEntity[],
|
|
||||||
fieldMetadataDeleteCollection: FieldMetadataEntity[],
|
|
||||||
): Promise<Partial<WorkspaceMigrationEntity>[]> {
|
|
||||||
const workspaceMigrations: Partial<WorkspaceMigrationEntity>[] = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create object migrations
|
|
||||||
*/
|
|
||||||
if (createdObjectMetadataCollection.length > 0) {
|
|
||||||
for (const objectMetadata of createdObjectMetadataCollection) {
|
|
||||||
const migrations = [
|
|
||||||
{
|
|
||||||
name: computeObjectTargetTable(objectMetadata),
|
|
||||||
action: 'create',
|
|
||||||
} satisfies WorkspaceMigrationTableAction,
|
|
||||||
...objectMetadata.fields
|
|
||||||
.filter((field) => field.type !== FieldMetadataType.RELATION)
|
|
||||||
.map(
|
|
||||||
(field) =>
|
|
||||||
({
|
|
||||||
name: computeObjectTargetTable(objectMetadata),
|
|
||||||
action: 'alter',
|
|
||||||
columns: this.workspaceMigrationFactory.createColumnActions(
|
|
||||||
WorkspaceMigrationColumnActionType.CREATE,
|
|
||||||
field,
|
|
||||||
),
|
|
||||||
}) satisfies WorkspaceMigrationTableAction,
|
|
||||||
),
|
|
||||||
];
|
|
||||||
|
|
||||||
workspaceMigrations.push({
|
|
||||||
workspaceId: objectMetadata.workspaceId,
|
|
||||||
name: generateMigrationName(`create-${objectMetadata.nameSingular}`),
|
|
||||||
isCustom: false,
|
|
||||||
migrations,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete object migrations
|
|
||||||
* TODO: handle object delete migrations.
|
|
||||||
* Note: we need to delete the relation first due to the DB constraint.
|
|
||||||
*/
|
|
||||||
// if (objectMetadataDeleteCollection.length > 0) {
|
|
||||||
// for (const objectMetadata of objectMetadataDeleteCollection) {
|
|
||||||
// const migrations = [
|
|
||||||
// {
|
|
||||||
// name: computeObjectTargetTable(objectMetadata),
|
|
||||||
// action: 'drop',
|
|
||||||
// columns: [],
|
|
||||||
// } satisfies WorkspaceMigrationTableAction,
|
|
||||||
// ];
|
|
||||||
|
|
||||||
// workspaceMigrations.push({
|
|
||||||
// workspaceId: objectMetadata.workspaceId,
|
|
||||||
// isCustom: false,
|
|
||||||
// migrations,
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create field migrations
|
|
||||||
*/
|
|
||||||
const originalObjectMetadataMap = originalObjectMetadataCollection.reduce(
|
|
||||||
(result, currentObject) => {
|
|
||||||
result[currentObject.id] = currentObject;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
},
|
|
||||||
{} as Record<string, ObjectMetadataEntity>,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (createdFieldMetadataCollection.length > 0) {
|
|
||||||
for (const fieldMetadata of createdFieldMetadataCollection) {
|
|
||||||
if (fieldMetadata.type === FieldMetadataType.RELATION) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const migrations = [
|
|
||||||
{
|
|
||||||
name: computeObjectTargetTable(
|
|
||||||
originalObjectMetadataMap[fieldMetadata.objectMetadataId],
|
|
||||||
),
|
|
||||||
action: 'alter',
|
|
||||||
columns: this.workspaceMigrationFactory.createColumnActions(
|
|
||||||
WorkspaceMigrationColumnActionType.CREATE,
|
|
||||||
fieldMetadata,
|
|
||||||
),
|
|
||||||
} satisfies WorkspaceMigrationTableAction,
|
|
||||||
];
|
|
||||||
|
|
||||||
workspaceMigrations.push({
|
|
||||||
workspaceId: fieldMetadata.workspaceId,
|
|
||||||
name: generateMigrationName(`create-${fieldMetadata.name}`),
|
|
||||||
isCustom: false,
|
|
||||||
migrations,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete field migrations
|
|
||||||
*/
|
|
||||||
if (fieldMetadataDeleteCollection.length > 0) {
|
|
||||||
for (const fieldMetadata of fieldMetadataDeleteCollection) {
|
|
||||||
const migrations = [
|
|
||||||
{
|
|
||||||
name: computeObjectTargetTable(
|
|
||||||
originalObjectMetadataMap[fieldMetadata.objectMetadataId],
|
|
||||||
),
|
|
||||||
action: 'alter',
|
|
||||||
columns: [
|
|
||||||
{
|
|
||||||
action: WorkspaceMigrationColumnActionType.DROP,
|
|
||||||
columnName: fieldMetadata.name,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
} satisfies WorkspaceMigrationTableAction,
|
|
||||||
];
|
|
||||||
|
|
||||||
workspaceMigrations.push({
|
|
||||||
workspaceId: fieldMetadata.workspaceId,
|
|
||||||
name: generateMigrationName(`delete-${fieldMetadata.name}`),
|
|
||||||
isCustom: false,
|
|
||||||
migrations,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return workspaceMigrations;
|
|
||||||
}
|
|
||||||
|
|
||||||
async createRelationMigration(
|
|
||||||
originalObjectMetadataCollection: ObjectMetadataEntity[],
|
|
||||||
createdRelationMetadataCollection: RelationMetadataEntity[],
|
|
||||||
// TODO: handle relation deletion
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
||||||
relationMetadataDeleteCollection: RelationMetadataEntity[],
|
|
||||||
): Promise<Partial<WorkspaceMigrationEntity>[]> {
|
|
||||||
const workspaceMigrations: Partial<WorkspaceMigrationEntity>[] = [];
|
|
||||||
|
|
||||||
if (createdRelationMetadataCollection.length > 0) {
|
|
||||||
for (const relationMetadata of createdRelationMetadataCollection) {
|
|
||||||
const toObjectMetadata = originalObjectMetadataCollection.find(
|
|
||||||
(object) => object.id === relationMetadata.toObjectMetadataId,
|
|
||||||
);
|
|
||||||
|
|
||||||
const fromObjectMetadata = originalObjectMetadataCollection.find(
|
|
||||||
(object) => object.id === relationMetadata.fromObjectMetadataId,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!toObjectMetadata) {
|
|
||||||
throw new Error(
|
|
||||||
`ObjectMetadata with id ${relationMetadata.toObjectMetadataId} not found`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!fromObjectMetadata) {
|
|
||||||
throw new Error(
|
|
||||||
`ObjectMetadata with id ${relationMetadata.fromObjectMetadataId} not found`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const toFieldMetadata = toObjectMetadata.fields.find(
|
|
||||||
(field) => field.id === relationMetadata.toFieldMetadataId,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!toFieldMetadata) {
|
|
||||||
throw new Error(
|
|
||||||
`FieldMetadata with id ${relationMetadata.toFieldMetadataId} not found`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const migrations = [
|
|
||||||
{
|
|
||||||
name: computeObjectTargetTable(toObjectMetadata),
|
|
||||||
action: 'alter',
|
|
||||||
columns: [
|
|
||||||
{
|
|
||||||
action: WorkspaceMigrationColumnActionType.RELATION,
|
|
||||||
columnName: `${camelCase(toFieldMetadata.name)}Id`,
|
|
||||||
referencedTableName:
|
|
||||||
computeObjectTargetTable(fromObjectMetadata),
|
|
||||||
referencedTableColumnName: 'id',
|
|
||||||
isUnique:
|
|
||||||
relationMetadata.relationType ===
|
|
||||||
RelationMetadataType.ONE_TO_ONE,
|
|
||||||
} satisfies WorkspaceMigrationColumnRelation,
|
|
||||||
],
|
|
||||||
} satisfies WorkspaceMigrationTableAction,
|
|
||||||
];
|
|
||||||
|
|
||||||
workspaceMigrations.push({
|
|
||||||
workspaceId: relationMetadata.workspaceId,
|
|
||||||
name: generateMigrationName(
|
|
||||||
`create-relation-from-${fromObjectMetadata.nameSingular}-to-${toObjectMetadata.nameSingular}`,
|
|
||||||
),
|
|
||||||
isCustom: false,
|
|
||||||
migrations,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if (relationMetadataDeleteCollection.length > 0) {
|
|
||||||
// for (const relationMetadata of relationMetadataDeleteCollection) {
|
|
||||||
// const toObjectMetadata = originalObjectMetadataCollection.find(
|
|
||||||
// (object) => object.id === relationMetadata.toObjectMetadataId,
|
|
||||||
// );
|
|
||||||
|
|
||||||
// if (!toObjectMetadata) {
|
|
||||||
// throw new Error(
|
|
||||||
// `ObjectMetadata with id ${relationMetadata.toObjectMetadataId} not found`,
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
|
|
||||||
// const migrations = [
|
|
||||||
// {
|
|
||||||
// name: computeObjectTargetTable(toObjectMetadata),
|
|
||||||
// action: 'drop',
|
|
||||||
// columns: [],
|
|
||||||
// } satisfies WorkspaceMigrationTableAction,
|
|
||||||
// ];
|
|
||||||
|
|
||||||
// workspaceMigrations.push({
|
|
||||||
// workspaceId: relationMetadata.workspaceId,
|
|
||||||
// isCustom: false,
|
|
||||||
// migrations,
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
return workspaceMigrations;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -162,6 +162,7 @@ export class WorkspaceMetadataUpdaterService {
|
|||||||
const relationMetadataRepository = manager.getRepository(
|
const relationMetadataRepository = manager.getRepository(
|
||||||
RelationMetadataEntity,
|
RelationMetadataEntity,
|
||||||
);
|
);
|
||||||
|
const fieldMetadataRepository = manager.getRepository(FieldMetadataEntity);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create relation metadata
|
* Create relation metadata
|
||||||
@ -182,6 +183,20 @@ export class WorkspaceMetadataUpdaterService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete related field metadata
|
||||||
|
*/
|
||||||
|
const fieldMetadataDeleteCollectionOnlyRelation =
|
||||||
|
storage.fieldMetadataDeleteCollection.filter(
|
||||||
|
(field) => field.type === FieldMetadataType.RELATION,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (fieldMetadataDeleteCollectionOnlyRelation.length > 0) {
|
||||||
|
await fieldMetadataRepository.delete(
|
||||||
|
fieldMetadataDeleteCollectionOnlyRelation.map((field) => field.id),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
createdRelationMetadataCollection,
|
createdRelationMetadataCollection,
|
||||||
};
|
};
|
||||||
|
|||||||
@ -13,8 +13,9 @@ import { StandardObjectFactory } from 'src/workspace/workspace-sync-metadata/fac
|
|||||||
import { WorkspaceObjectComparator } from 'src/workspace/workspace-sync-metadata/comparators/workspace-object.comparator';
|
import { WorkspaceObjectComparator } from 'src/workspace/workspace-sync-metadata/comparators/workspace-object.comparator';
|
||||||
import { WorkspaceFieldComparator } from 'src/workspace/workspace-sync-metadata/comparators/workspace-field.comparator';
|
import { WorkspaceFieldComparator } from 'src/workspace/workspace-sync-metadata/comparators/workspace-field.comparator';
|
||||||
import { WorkspaceMetadataUpdaterService } from 'src/workspace/workspace-sync-metadata/services/workspace-metadata-updater.service';
|
import { WorkspaceMetadataUpdaterService } from 'src/workspace/workspace-sync-metadata/services/workspace-metadata-updater.service';
|
||||||
import { WorkspaceSyncFactory } from 'src/workspace/workspace-sync-metadata/factories/workspace-sync.factory';
|
|
||||||
import { WorkspaceSyncStorage } from 'src/workspace/workspace-sync-metadata/storage/workspace-sync.storage';
|
import { WorkspaceSyncStorage } from 'src/workspace/workspace-sync-metadata/storage/workspace-sync.storage';
|
||||||
|
import { ObjectWorkspaceMigrationFactory } from 'src/workspace/workspace-sync-metadata/factories/object-workspace-migration.factory';
|
||||||
|
import { FieldWorkspaceMigrationFactory } from 'src/workspace/workspace-sync-metadata/factories/field-workspace-migration.factory';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class WorkspaceSyncObjectMetadataService {
|
export class WorkspaceSyncObjectMetadataService {
|
||||||
@ -25,7 +26,8 @@ export class WorkspaceSyncObjectMetadataService {
|
|||||||
private readonly workspaceObjectComparator: WorkspaceObjectComparator,
|
private readonly workspaceObjectComparator: WorkspaceObjectComparator,
|
||||||
private readonly workspaceFieldComparator: WorkspaceFieldComparator,
|
private readonly workspaceFieldComparator: WorkspaceFieldComparator,
|
||||||
private readonly workspaceMetadataUpdaterService: WorkspaceMetadataUpdaterService,
|
private readonly workspaceMetadataUpdaterService: WorkspaceMetadataUpdaterService,
|
||||||
private readonly workspaceSyncFactory: WorkspaceSyncFactory,
|
private readonly objectWorkspaceMigrationFactory: ObjectWorkspaceMigrationFactory,
|
||||||
|
private readonly fieldWorkspaceMigrationFactory: FieldWorkspaceMigrationFactory,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async synchronize(
|
async synchronize(
|
||||||
@ -33,12 +35,9 @@ export class WorkspaceSyncObjectMetadataService {
|
|||||||
manager: EntityManager,
|
manager: EntityManager,
|
||||||
storage: WorkspaceSyncStorage,
|
storage: WorkspaceSyncStorage,
|
||||||
workspaceFeatureFlagsMap: FeatureFlagMap,
|
workspaceFeatureFlagsMap: FeatureFlagMap,
|
||||||
): Promise<WorkspaceMigrationEntity[]> {
|
): Promise<Partial<WorkspaceMigrationEntity>[]> {
|
||||||
const objectMetadataRepository =
|
const objectMetadataRepository =
|
||||||
manager.getRepository(ObjectMetadataEntity);
|
manager.getRepository(ObjectMetadataEntity);
|
||||||
const workspaceMigrationRepository = manager.getRepository(
|
|
||||||
WorkspaceMigrationEntity,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Retrieve object metadata collection from DB
|
// Retrieve object metadata collection from DB
|
||||||
const originalObjectMetadataCollection =
|
const originalObjectMetadataCollection =
|
||||||
@ -141,22 +140,21 @@ export class WorkspaceSyncObjectMetadataService {
|
|||||||
this.logger.log('Generating migrations');
|
this.logger.log('Generating migrations');
|
||||||
|
|
||||||
// Create migrations
|
// Create migrations
|
||||||
const workspaceObjectMigrations =
|
const objectWorkspaceMigrations =
|
||||||
await this.workspaceSyncFactory.createObjectMigration(
|
await this.objectWorkspaceMigrationFactory.create(
|
||||||
originalObjectMetadataCollection,
|
|
||||||
metadataObjectUpdaterResult.createdObjectMetadataCollection,
|
metadataObjectUpdaterResult.createdObjectMetadataCollection,
|
||||||
storage.objectMetadataDeleteCollection,
|
storage.objectMetadataDeleteCollection,
|
||||||
|
);
|
||||||
|
|
||||||
|
const fieldWorkspaceMigrations =
|
||||||
|
await this.fieldWorkspaceMigrationFactory.create(
|
||||||
|
originalObjectMetadataCollection,
|
||||||
metadataFieldUpdaterResult.createdFieldMetadataCollection,
|
metadataFieldUpdaterResult.createdFieldMetadataCollection,
|
||||||
storage.fieldMetadataDeleteCollection,
|
storage.fieldMetadataDeleteCollection,
|
||||||
);
|
);
|
||||||
|
|
||||||
this.logger.log('Saving migrations');
|
this.logger.log('Saving migrations');
|
||||||
|
|
||||||
// Save migrations into DB
|
return [...objectWorkspaceMigrations, ...fieldWorkspaceMigrations];
|
||||||
const workspaceMigrations = await workspaceMigrationRepository.save(
|
|
||||||
workspaceObjectMigrations,
|
|
||||||
);
|
|
||||||
|
|
||||||
return workspaceMigrations;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,9 +12,9 @@ import { mapObjectMetadataByUniqueIdentifier } from 'src/workspace/workspace-syn
|
|||||||
import { StandardRelationFactory } from 'src/workspace/workspace-sync-metadata/factories/standard-relation.factory';
|
import { StandardRelationFactory } from 'src/workspace/workspace-sync-metadata/factories/standard-relation.factory';
|
||||||
import { WorkspaceRelationComparator } from 'src/workspace/workspace-sync-metadata/comparators/workspace-relation.comparator';
|
import { WorkspaceRelationComparator } from 'src/workspace/workspace-sync-metadata/comparators/workspace-relation.comparator';
|
||||||
import { WorkspaceMetadataUpdaterService } from 'src/workspace/workspace-sync-metadata/services/workspace-metadata-updater.service';
|
import { WorkspaceMetadataUpdaterService } from 'src/workspace/workspace-sync-metadata/services/workspace-metadata-updater.service';
|
||||||
import { WorkspaceSyncFactory } from 'src/workspace/workspace-sync-metadata/factories/workspace-sync.factory';
|
|
||||||
import { WorkspaceMigrationEntity } from 'src/metadata/workspace-migration/workspace-migration.entity';
|
import { WorkspaceMigrationEntity } from 'src/metadata/workspace-migration/workspace-migration.entity';
|
||||||
import { WorkspaceSyncStorage } from 'src/workspace/workspace-sync-metadata/storage/workspace-sync.storage';
|
import { WorkspaceSyncStorage } from 'src/workspace/workspace-sync-metadata/storage/workspace-sync.storage';
|
||||||
|
import { RelationWorkspaceMigrationFactory } from 'src/workspace/workspace-sync-metadata/factories/relation-workspace-migration.factory';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class WorkspaceSyncRelationMetadataService {
|
export class WorkspaceSyncRelationMetadataService {
|
||||||
@ -26,7 +26,7 @@ export class WorkspaceSyncRelationMetadataService {
|
|||||||
private readonly standardRelationFactory: StandardRelationFactory,
|
private readonly standardRelationFactory: StandardRelationFactory,
|
||||||
private readonly workspaceRelationComparator: WorkspaceRelationComparator,
|
private readonly workspaceRelationComparator: WorkspaceRelationComparator,
|
||||||
private readonly workspaceMetadataUpdaterService: WorkspaceMetadataUpdaterService,
|
private readonly workspaceMetadataUpdaterService: WorkspaceMetadataUpdaterService,
|
||||||
private readonly workspaceSyncFactory: WorkspaceSyncFactory,
|
private readonly relationWorkspaceMigrationFactory: RelationWorkspaceMigrationFactory,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async synchronize(
|
async synchronize(
|
||||||
@ -34,12 +34,9 @@ export class WorkspaceSyncRelationMetadataService {
|
|||||||
manager: EntityManager,
|
manager: EntityManager,
|
||||||
storage: WorkspaceSyncStorage,
|
storage: WorkspaceSyncStorage,
|
||||||
workspaceFeatureFlagsMap: FeatureFlagMap,
|
workspaceFeatureFlagsMap: FeatureFlagMap,
|
||||||
): Promise<WorkspaceMigrationEntity[]> {
|
): Promise<Partial<WorkspaceMigrationEntity>[]> {
|
||||||
const objectMetadataRepository =
|
const objectMetadataRepository =
|
||||||
manager.getRepository(ObjectMetadataEntity);
|
manager.getRepository(ObjectMetadataEntity);
|
||||||
const workspaceMigrationRepository = manager.getRepository(
|
|
||||||
WorkspaceMigrationEntity,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Retrieve object metadata collection from DB
|
// Retrieve object metadata collection from DB
|
||||||
const originalObjectMetadataCollection =
|
const originalObjectMetadataCollection =
|
||||||
@ -99,17 +96,11 @@ export class WorkspaceSyncRelationMetadataService {
|
|||||||
|
|
||||||
// Create migrations
|
// Create migrations
|
||||||
const workspaceRelationMigrations =
|
const workspaceRelationMigrations =
|
||||||
await this.workspaceSyncFactory.createRelationMigration(
|
await this.relationWorkspaceMigrationFactory.create(
|
||||||
originalObjectMetadataCollection,
|
originalObjectMetadataCollection,
|
||||||
metadataRelationUpdaterResult.createdRelationMetadataCollection,
|
metadataRelationUpdaterResult.createdRelationMetadataCollection,
|
||||||
storage.relationMetadataDeleteCollection,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// Save migrations into DB
|
return workspaceRelationMigrations;
|
||||||
const workspaceMigrations = await workspaceMigrationRepository.save(
|
|
||||||
workspaceRelationMigrations,
|
|
||||||
);
|
|
||||||
|
|
||||||
return workspaceMigrations;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,7 +21,7 @@ import { ViewObjectMetadata } from 'src/workspace/workspace-sync-metadata/standa
|
|||||||
import { WebhookObjectMetadata } from 'src/workspace/workspace-sync-metadata/standard-objects/webhook.object-metadata';
|
import { WebhookObjectMetadata } from 'src/workspace/workspace-sync-metadata/standard-objects/webhook.object-metadata';
|
||||||
import { WorkspaceMemberObjectMetadata } from 'src/workspace/workspace-sync-metadata/standard-objects/workspace-member.object-metadata';
|
import { WorkspaceMemberObjectMetadata } from 'src/workspace/workspace-sync-metadata/standard-objects/workspace-member.object-metadata';
|
||||||
|
|
||||||
export const standardObjectMetadata = [
|
export const standardObjectMetadataCollection = [
|
||||||
ActivityTargetObjectMetadata,
|
ActivityTargetObjectMetadata,
|
||||||
ActivityObjectMetadata,
|
ActivityObjectMetadata,
|
||||||
ApiKeyObjectMetadata,
|
ApiKeyObjectMetadata,
|
||||||
|
|||||||
@ -11,6 +11,7 @@ import { WorkspaceSyncObjectMetadataService } from 'src/workspace/workspace-sync
|
|||||||
import { WorkspaceSyncRelationMetadataService } from 'src/workspace/workspace-sync-metadata/services/workspace-sync-relation-metadata.service';
|
import { WorkspaceSyncRelationMetadataService } from 'src/workspace/workspace-sync-metadata/services/workspace-sync-relation-metadata.service';
|
||||||
import { WorkspaceSyncStorage } from 'src/workspace/workspace-sync-metadata/storage/workspace-sync.storage';
|
import { WorkspaceSyncStorage } from 'src/workspace/workspace-sync-metadata/storage/workspace-sync.storage';
|
||||||
import { WorkspaceLogsService } from 'src/workspace/workspace-sync-metadata/services/workspace-logs.service';
|
import { WorkspaceLogsService } from 'src/workspace/workspace-sync-metadata/services/workspace-logs.service';
|
||||||
|
import { WorkspaceMigrationEntity } from 'src/metadata/workspace-migration/workspace-migration.entity';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class WorkspaceSyncMetadataService {
|
export class WorkspaceSyncMetadataService {
|
||||||
@ -48,6 +49,9 @@ export class WorkspaceSyncMetadataService {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const storage = new WorkspaceSyncStorage();
|
const storage = new WorkspaceSyncStorage();
|
||||||
|
const workspaceMigrationRepository = manager.getRepository(
|
||||||
|
WorkspaceMigrationEntity,
|
||||||
|
);
|
||||||
|
|
||||||
// Retrieve feature flags
|
// Retrieve feature flags
|
||||||
const workspaceFeatureFlagsMap =
|
const workspaceFeatureFlagsMap =
|
||||||
@ -71,13 +75,14 @@ export class WorkspaceSyncMetadataService {
|
|||||||
workspaceFeatureFlagsMap,
|
workspaceFeatureFlagsMap,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Save workspace migrations into the database
|
||||||
|
const workspaceMigrations = await workspaceMigrationRepository.save([
|
||||||
|
...workspaceObjectMigrations,
|
||||||
|
...workspaceRelationMigrations,
|
||||||
|
]);
|
||||||
|
|
||||||
// If we're running a dry run, rollback the transaction and do not execute migrations
|
// If we're running a dry run, rollback the transaction and do not execute migrations
|
||||||
if (options?.dryRun) {
|
if (options?.dryRun) {
|
||||||
const workspaceMigrations = [
|
|
||||||
...workspaceObjectMigrations,
|
|
||||||
...workspaceRelationMigrations,
|
|
||||||
];
|
|
||||||
|
|
||||||
this.logger.log('Running in dry run mode, rolling back transaction');
|
this.logger.log('Running in dry run mode, rolling back transaction');
|
||||||
|
|
||||||
await queryRunner.rollbackTransaction();
|
await queryRunner.rollbackTransaction();
|
||||||
|
|||||||
Reference in New Issue
Block a user