Remove old relations (#11993)
This is a first PR to remove old relation logic Next steps: - remove relationMetadata from cache - remove relationMetadata table content and structure - refactor relationDefinition to leverage field.settings instead
This commit is contained in:
@ -26,10 +26,7 @@ type EntitySchemaColumnMap = {
|
||||
|
||||
@Injectable()
|
||||
export class EntitySchemaColumnFactory {
|
||||
create(
|
||||
fieldMetadataMapByName: FieldMetadataMap,
|
||||
isNewRelationEnabled: boolean,
|
||||
): EntitySchemaColumnMap {
|
||||
create(fieldMetadataMapByName: FieldMetadataMap): EntitySchemaColumnMap {
|
||||
let entitySchemaColumnMap: EntitySchemaColumnMap = {};
|
||||
|
||||
const fieldMetadataCollection = Object.values(fieldMetadataMapByName);
|
||||
@ -43,57 +40,28 @@ export class EntitySchemaColumnFactory {
|
||||
FieldMetadataType.RELATION,
|
||||
)
|
||||
) {
|
||||
if (!isNewRelationEnabled) {
|
||||
const relationMetadata =
|
||||
fieldMetadata.fromRelationMetadata ??
|
||||
fieldMetadata.toRelationMetadata;
|
||||
|
||||
if (!relationMetadata) {
|
||||
throw new Error(
|
||||
`Relation metadata is missing for field ${fieldMetadata.name}`,
|
||||
);
|
||||
}
|
||||
|
||||
const joinColumnKey = fieldMetadata.name + 'Id';
|
||||
const joinColumn = fieldMetadataCollection.find(
|
||||
(field) => field.name === joinColumnKey,
|
||||
)
|
||||
? joinColumnKey
|
||||
: null;
|
||||
|
||||
if (joinColumn) {
|
||||
entitySchemaColumnMap[joinColumn] = {
|
||||
name: joinColumn,
|
||||
type: 'uuid',
|
||||
nullable: fieldMetadata.isNullable,
|
||||
};
|
||||
}
|
||||
|
||||
continue;
|
||||
} else {
|
||||
const isManyToOneRelation =
|
||||
fieldMetadata.settings?.relationType === RelationType.MANY_TO_ONE;
|
||||
const joinColumnName = fieldMetadata.settings?.joinColumnName;
|
||||
|
||||
if (!isManyToOneRelation) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isDefined(joinColumnName)) {
|
||||
throw new TwentyORMException(
|
||||
`Field ${fieldMetadata.id} of type ${fieldMetadata.type} is a many to one relation but does not have a join column name`,
|
||||
TwentyORMExceptionCode.MALFORMED_METADATA,
|
||||
);
|
||||
}
|
||||
|
||||
entitySchemaColumnMap[joinColumnName] = {
|
||||
name: joinColumnName,
|
||||
type: 'uuid',
|
||||
nullable: fieldMetadata.isNullable,
|
||||
};
|
||||
const isManyToOneRelation =
|
||||
fieldMetadata.settings?.relationType === RelationType.MANY_TO_ONE;
|
||||
const joinColumnName = fieldMetadata.settings?.joinColumnName;
|
||||
|
||||
if (!isManyToOneRelation) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isDefined(joinColumnName)) {
|
||||
throw new TwentyORMException(
|
||||
`Field ${fieldMetadata.id} of type ${fieldMetadata.type} is a many to one relation but does not have a join column name`,
|
||||
TwentyORMExceptionCode.MALFORMED_METADATA,
|
||||
);
|
||||
}
|
||||
|
||||
entitySchemaColumnMap[joinColumnName] = {
|
||||
name: joinColumnName,
|
||||
type: 'uuid',
|
||||
nullable: fieldMetadata.isNullable,
|
||||
};
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isCompositeFieldMetadataType(fieldMetadata.type)) {
|
||||
|
||||
@ -5,7 +5,6 @@ import { EntitySchemaRelationOptions } from 'typeorm';
|
||||
|
||||
import { FieldMetadataMap } from 'src/engine/metadata-modules/types/field-metadata-map';
|
||||
import { ObjectMetadataMaps } from 'src/engine/metadata-modules/types/object-metadata-maps';
|
||||
import { determineRelationDetails } from 'src/engine/twenty-orm/utils/determine-relation-details.util';
|
||||
import { determineSchemaRelationDetails } from 'src/engine/twenty-orm/utils/determine-schema-relation-details.util';
|
||||
import { isFieldMetadataInterfaceOfType } from 'src/engine/utils/is-field-metadata-of-type.util';
|
||||
|
||||
@ -20,7 +19,6 @@ export class EntitySchemaRelationFactory {
|
||||
async create(
|
||||
fieldMetadataMapByName: FieldMetadataMap,
|
||||
objectMetadataMaps: ObjectMetadataMaps,
|
||||
isNewRelationEnabled: boolean,
|
||||
): Promise<EntitySchemaRelationMap> {
|
||||
const entitySchemaRelationMap: EntitySchemaRelationMap = {};
|
||||
|
||||
@ -36,48 +34,23 @@ export class EntitySchemaRelationFactory {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isNewRelationEnabled) {
|
||||
const relationMetadata =
|
||||
fieldMetadata.fromRelationMetadata ??
|
||||
fieldMetadata.toRelationMetadata;
|
||||
|
||||
if (!relationMetadata) {
|
||||
throw new Error(
|
||||
`Relation metadata is missing for field ${fieldMetadata.name}`,
|
||||
);
|
||||
}
|
||||
|
||||
const relationDetails = await determineRelationDetails(
|
||||
fieldMetadata,
|
||||
relationMetadata,
|
||||
objectMetadataMaps,
|
||||
if (!fieldMetadata.settings) {
|
||||
throw new Error(
|
||||
`Field metadata settings are missing for field ${fieldMetadata.name}`,
|
||||
);
|
||||
|
||||
entitySchemaRelationMap[fieldMetadata.name] = {
|
||||
type: relationDetails.relationType,
|
||||
target: relationDetails.target,
|
||||
inverseSide: relationDetails.inverseSide,
|
||||
joinColumn: relationDetails.joinColumn,
|
||||
} satisfies EntitySchemaRelationOptions;
|
||||
} else {
|
||||
if (!fieldMetadata.settings) {
|
||||
throw new Error(
|
||||
`Field metadata settings are missing for field ${fieldMetadata.name}`,
|
||||
);
|
||||
}
|
||||
|
||||
const schemaRelationDetails = await determineSchemaRelationDetails(
|
||||
fieldMetadata,
|
||||
objectMetadataMaps,
|
||||
);
|
||||
|
||||
entitySchemaRelationMap[fieldMetadata.name] = {
|
||||
type: schemaRelationDetails.relationType,
|
||||
target: schemaRelationDetails.target,
|
||||
inverseSide: schemaRelationDetails.inverseSide,
|
||||
joinColumn: schemaRelationDetails.joinColumn,
|
||||
} satisfies EntitySchemaRelationOptions;
|
||||
}
|
||||
|
||||
const schemaRelationDetails = await determineSchemaRelationDetails(
|
||||
fieldMetadata,
|
||||
objectMetadataMaps,
|
||||
);
|
||||
|
||||
entitySchemaRelationMap[fieldMetadata.name] = {
|
||||
type: schemaRelationDetails.relationType,
|
||||
target: schemaRelationDetails.target,
|
||||
inverseSide: schemaRelationDetails.inverseSide,
|
||||
joinColumn: schemaRelationDetails.joinColumn,
|
||||
} satisfies EntitySchemaRelationOptions;
|
||||
}
|
||||
|
||||
return entitySchemaRelationMap;
|
||||
|
||||
@ -2,7 +2,6 @@ import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { EntitySchema } from 'typeorm';
|
||||
|
||||
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
|
||||
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
|
||||
import { ObjectMetadataItemWithFieldMaps } from 'src/engine/metadata-modules/types/object-metadata-item-with-field-maps';
|
||||
import { ObjectMetadataMaps } from 'src/engine/metadata-modules/types/object-metadata-maps';
|
||||
@ -25,20 +24,13 @@ export class EntitySchemaFactory {
|
||||
objectMetadata: ObjectMetadataItemWithFieldMaps,
|
||||
objectMetadataMaps: ObjectMetadataMaps,
|
||||
): Promise<EntitySchema> {
|
||||
const isNewRelationEnabled = await this.featureFlagService.isFeatureEnabled(
|
||||
FeatureFlagKey.IsNewRelationEnabled,
|
||||
workspaceId,
|
||||
);
|
||||
|
||||
const columns = this.entitySchemaColumnFactory.create(
|
||||
objectMetadata.fieldsByName,
|
||||
isNewRelationEnabled,
|
||||
);
|
||||
|
||||
const relations = await this.entitySchemaRelationFactory.create(
|
||||
objectMetadata.fieldsByName,
|
||||
objectMetadataMaps,
|
||||
isNewRelationEnabled,
|
||||
);
|
||||
|
||||
const entitySchema = new EntitySchema({
|
||||
|
||||
@ -729,14 +729,7 @@ export class WorkspaceRepository<
|
||||
objectMetadata ??= await this.getObjectMetadataFromTarget();
|
||||
|
||||
const objectMetadataMaps = this.internalContext.objectMetadataMaps;
|
||||
const isNewRelationEnabled =
|
||||
this.internalContext.featureFlagsMap[FeatureFlagKey.IsNewRelationEnabled];
|
||||
|
||||
return formatResult(
|
||||
data,
|
||||
objectMetadata,
|
||||
objectMetadataMaps,
|
||||
isNewRelationEnabled,
|
||||
) as T;
|
||||
return formatResult(data, objectMetadata, objectMetadataMaps) as T;
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,10 +8,8 @@ import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metada
|
||||
|
||||
import { compositeTypeDefinitions } from 'src/engine/metadata-modules/field-metadata/composite-types';
|
||||
import { computeCompositeColumnName } from 'src/engine/metadata-modules/field-metadata/utils/compute-column-name.util';
|
||||
import { RelationMetadataEntity } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity';
|
||||
import { ObjectMetadataItemWithFieldMaps } from 'src/engine/metadata-modules/types/object-metadata-item-with-field-maps';
|
||||
import { ObjectMetadataMaps } from 'src/engine/metadata-modules/types/object-metadata-maps';
|
||||
import { computeRelationType } from 'src/engine/twenty-orm/utils/compute-relation-type.util';
|
||||
import { getCompositeFieldMetadataCollection } from 'src/engine/twenty-orm/utils/get-composite-field-metadata-collection';
|
||||
import { isFieldMetadataInterfaceOfType } from 'src/engine/utils/is-field-metadata-of-type.util';
|
||||
import { isDate } from 'src/utils/date/isDate';
|
||||
@ -21,7 +19,6 @@ export function formatResult<T>(
|
||||
data: any,
|
||||
objectMetadataItemWithFieldMaps: ObjectMetadataItemWithFieldMaps,
|
||||
objectMetadataMaps: ObjectMetadataMaps,
|
||||
isNewRelationEnabled: boolean,
|
||||
): T {
|
||||
if (!data) {
|
||||
return data;
|
||||
@ -29,12 +26,7 @@ export function formatResult<T>(
|
||||
|
||||
if (Array.isArray(data)) {
|
||||
return data.map((item) =>
|
||||
formatResult(
|
||||
item,
|
||||
objectMetadataItemWithFieldMaps,
|
||||
objectMetadataMaps,
|
||||
isNewRelationEnabled,
|
||||
),
|
||||
formatResult(item, objectMetadataItemWithFieldMaps, objectMetadataMaps),
|
||||
) as T;
|
||||
}
|
||||
|
||||
@ -50,36 +42,6 @@ export function formatResult<T>(
|
||||
objectMetadataItemWithFieldMaps,
|
||||
);
|
||||
|
||||
const relationMetadataMap: Map<
|
||||
string,
|
||||
{
|
||||
relationMetadata: RelationMetadataEntity | undefined;
|
||||
relationType: string;
|
||||
}
|
||||
> = isNewRelationEnabled
|
||||
? new Map()
|
||||
: new Map(
|
||||
Object.values(objectMetadataItemWithFieldMaps.fieldsById)
|
||||
.filter((fieldMetadata) =>
|
||||
isFieldMetadataInterfaceOfType(
|
||||
fieldMetadata,
|
||||
FieldMetadataType.RELATION,
|
||||
),
|
||||
)
|
||||
.map((fieldMetadata) => [
|
||||
fieldMetadata.name,
|
||||
{
|
||||
relationMetadata:
|
||||
fieldMetadata.fromRelationMetadata ??
|
||||
fieldMetadata.toRelationMetadata,
|
||||
relationType: computeRelationType(
|
||||
fieldMetadata,
|
||||
fieldMetadata.fromRelationMetadata ??
|
||||
(fieldMetadata.toRelationMetadata as RelationMetadataEntity),
|
||||
),
|
||||
},
|
||||
]),
|
||||
);
|
||||
const newData: object = {};
|
||||
const objectMetadaItemFieldsByName =
|
||||
objectMetadataMaps.byId[objectMetadataItemWithFieldMaps.id]?.fieldsByName;
|
||||
@ -104,7 +66,6 @@ export function formatResult<T>(
|
||||
value,
|
||||
objectMetadataItemWithFieldMaps,
|
||||
objectMetadataMaps,
|
||||
isNewRelationEnabled,
|
||||
);
|
||||
} else if (objectMetadaItemFieldsByName[key]) {
|
||||
newData[key] = formatFieldMetadataValue(
|
||||
@ -118,63 +79,27 @@ export function formatResult<T>(
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isNewRelationEnabled) {
|
||||
const { relationMetadata, relationType } =
|
||||
relationMetadataMap.get(key) ?? {};
|
||||
|
||||
if (relationMetadata) {
|
||||
const toObjectMetadata =
|
||||
objectMetadataMaps.byId[relationMetadata.toObjectMetadataId];
|
||||
|
||||
const fromObjectMetadata =
|
||||
objectMetadataMaps.byId[relationMetadata.fromObjectMetadataId];
|
||||
|
||||
if (!toObjectMetadata) {
|
||||
throw new Error(
|
||||
`Object metadata for object metadataId "${relationMetadata.toObjectMetadataId}" is missing`,
|
||||
);
|
||||
}
|
||||
|
||||
if (!fromObjectMetadata) {
|
||||
throw new Error(
|
||||
`Object metadata for object metadataId "${relationMetadata.fromObjectMetadataId}" is missing`,
|
||||
);
|
||||
}
|
||||
|
||||
newData[key] = formatResult(
|
||||
value,
|
||||
relationType === 'one-to-many'
|
||||
? toObjectMetadata
|
||||
: fromObjectMetadata,
|
||||
objectMetadataMaps,
|
||||
isNewRelationEnabled,
|
||||
);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if (isRelation) {
|
||||
if (!isDefined(fieldMetadata?.relationTargetObjectMetadataId)) {
|
||||
throw new Error(
|
||||
`Relation target object metadata ID is missing for field "${key}"`,
|
||||
);
|
||||
}
|
||||
|
||||
const targetObjectMetadata =
|
||||
objectMetadataMaps.byId[fieldMetadata.relationTargetObjectMetadataId];
|
||||
|
||||
if (!targetObjectMetadata) {
|
||||
throw new Error(
|
||||
`Object metadata for object metadataId "${fieldMetadata.relationTargetObjectMetadataId}" is missing`,
|
||||
);
|
||||
}
|
||||
|
||||
newData[key] = formatResult(
|
||||
value,
|
||||
targetObjectMetadata,
|
||||
objectMetadataMaps,
|
||||
isNewRelationEnabled,
|
||||
if (isRelation) {
|
||||
if (!isDefined(fieldMetadata?.relationTargetObjectMetadataId)) {
|
||||
throw new Error(
|
||||
`Relation target object metadata ID is missing for field "${key}"`,
|
||||
);
|
||||
}
|
||||
|
||||
const targetObjectMetadata =
|
||||
objectMetadataMaps.byId[fieldMetadata.relationTargetObjectMetadataId];
|
||||
|
||||
if (!targetObjectMetadata) {
|
||||
throw new Error(
|
||||
`Object metadata for object metadataId "${fieldMetadata.relationTargetObjectMetadataId}" is missing`,
|
||||
);
|
||||
}
|
||||
|
||||
newData[key] = formatResult(
|
||||
value,
|
||||
targetObjectMetadata,
|
||||
objectMetadataMaps,
|
||||
);
|
||||
}
|
||||
|
||||
if (!compositePropertyArgs) {
|
||||
|
||||
Reference in New Issue
Block a user