Integrate relations for remote objects (#4754)
Foreign table id cannot be a foreign key of a base table. But the current code use foreign keys to link object metadata with activities, events... So we will: - create a column without creating a foreign key - add a comment on the table schema so pg_graphql sees it as a foreign key This PR: - refactor a bit object metadata service so the mutation creation is separated into an util - adds the mutation creation for remote object relations - add a new type of mutation to create a comment --------- Co-authored-by: Thomas Trompette <thomast@twenty.com>
This commit is contained in:
@ -47,10 +47,9 @@ export const useLoadRecordIndexBoard = ({
|
|||||||
recordIndexFilters,
|
recordIndexFilters,
|
||||||
objectMetadataItem?.fields ?? [],
|
objectMetadataItem?.fields ?? [],
|
||||||
);
|
);
|
||||||
const orderBy = turnSortsIntoOrderBy(
|
const orderBy = !objectMetadataItem.isRemote
|
||||||
recordIndexSorts,
|
? turnSortsIntoOrderBy(recordIndexSorts, objectMetadataItem?.fields ?? [])
|
||||||
objectMetadataItem?.fields ?? [],
|
: undefined;
|
||||||
);
|
|
||||||
|
|
||||||
const recordIndexIsCompactModeActive = useRecoilValue(
|
const recordIndexIsCompactModeActive = useRecoilValue(
|
||||||
recordIndexIsCompactModeActiveState,
|
recordIndexIsCompactModeActiveState,
|
||||||
|
|||||||
@ -189,7 +189,7 @@ export const RecordShowContainer = ({
|
|||||||
objectRecordId={objectRecordId}
|
objectRecordId={objectRecordId}
|
||||||
objectNameSingular={objectNameSingular}
|
objectNameSingular={objectNameSingular}
|
||||||
/>
|
/>
|
||||||
{relationFieldMetadataItems.map((fieldMetadataItem, index) => (
|
{relationFieldMetadataItems?.map((fieldMetadataItem, index) => (
|
||||||
<FieldContext.Provider
|
<FieldContext.Provider
|
||||||
key={objectRecordId + fieldMetadataItem.id}
|
key={objectRecordId + fieldMetadataItem.id}
|
||||||
value={{
|
value={{
|
||||||
|
|||||||
@ -25,7 +25,8 @@ export class ForeignDataWrapperQueryFactory {
|
|||||||
foreignDataWrapperId: string,
|
foreignDataWrapperId: string,
|
||||||
userMappingOptions: UserMappingOptions,
|
userMappingOptions: UserMappingOptions,
|
||||||
) {
|
) {
|
||||||
return `CREATE USER MAPPING IF NOT EXISTS FOR ${userMappingOptions.username} SERVER "${foreignDataWrapperId}" OPTIONS (user '${userMappingOptions.username}', password '${userMappingOptions.password}')`;
|
// CURRENT_USER works for now since we are using only one user. But if we switch to a user per workspace, we need to change this.
|
||||||
|
return `CREATE USER MAPPING IF NOT EXISTS FOR CURRENT_USER SERVER "${foreignDataWrapperId}" OPTIONS (user '${userMappingOptions.username}', password '${userMappingOptions.password}')`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private buildNameAndOptionsFromType(
|
private buildNameAndOptionsFromType(
|
||||||
|
|||||||
@ -15,9 +15,7 @@ import { WorkspaceMigrationService } from 'src/engine/metadata-modules/workspace
|
|||||||
import { WorkspaceMigrationRunnerService } from 'src/engine/workspace-manager/workspace-migration-runner/workspace-migration-runner.service';
|
import { WorkspaceMigrationRunnerService } from 'src/engine/workspace-manager/workspace-migration-runner/workspace-migration-runner.service';
|
||||||
import {
|
import {
|
||||||
WorkspaceMigrationColumnActionType,
|
WorkspaceMigrationColumnActionType,
|
||||||
WorkspaceMigrationColumnCreate,
|
|
||||||
WorkspaceMigrationColumnDrop,
|
WorkspaceMigrationColumnDrop,
|
||||||
WorkspaceMigrationTableAction,
|
|
||||||
} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
|
} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
|
||||||
import {
|
import {
|
||||||
FieldMetadataEntity,
|
FieldMetadataEntity,
|
||||||
@ -47,6 +45,8 @@ import {
|
|||||||
createForeignKeyDeterministicUuid,
|
createForeignKeyDeterministicUuid,
|
||||||
createRelationDeterministicUuid,
|
createRelationDeterministicUuid,
|
||||||
} from 'src/engine/workspace-manager/workspace-sync-metadata/utils/create-deterministic-uuid.util';
|
} from 'src/engine/workspace-manager/workspace-sync-metadata/utils/create-deterministic-uuid.util';
|
||||||
|
import { buildWorkspaceMigrationsForCustomObject } from 'src/engine/metadata-modules/object-metadata/utils/build-workspace-migrations-for-custom-object';
|
||||||
|
import { buildWorkspaceMigrationsForRemoteObject } from 'src/engine/metadata-modules/object-metadata/utils/build-workspace-migrations-for-remote-object';
|
||||||
|
|
||||||
import { ObjectMetadataEntity } from './object-metadata.entity';
|
import { ObjectMetadataEntity } from './object-metadata.entity';
|
||||||
|
|
||||||
@ -232,15 +232,17 @@ export class ObjectMetadataService extends TypeOrmQueryService<ObjectMetadataEnt
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isCustom = !objectMetadataInput.isRemote;
|
||||||
|
|
||||||
const createdObjectMetadata = await super.createOne({
|
const createdObjectMetadata = await super.createOne({
|
||||||
...objectMetadataInput,
|
...objectMetadataInput,
|
||||||
dataSourceId: lastDataSourceMetadata.id,
|
dataSourceId: lastDataSourceMetadata.id,
|
||||||
targetTableName: 'DEPRECATED',
|
targetTableName: 'DEPRECATED',
|
||||||
isActive: true,
|
isActive: true,
|
||||||
isCustom: !objectMetadataInput.isRemote,
|
isCustom: isCustom,
|
||||||
isSystem: false,
|
isSystem: false,
|
||||||
isRemote: !!objectMetadataInput.isRemote,
|
isRemote: objectMetadataInput.isRemote,
|
||||||
fields: !objectMetadataInput.isRemote
|
fields: isCustom
|
||||||
? // Creating default fields.
|
? // Creating default fields.
|
||||||
// No need to create a custom migration for this though as the default columns are already
|
// No need to create a custom migration for this though as the default columns are already
|
||||||
// created with default values which is not supported yet by workspace migrations.
|
// created with default values which is not supported yet by workspace migrations.
|
||||||
@ -333,200 +335,47 @@ export class ObjectMetadataService extends TypeOrmQueryService<ObjectMetadataEnt
|
|||||||
[],
|
[],
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!objectMetadataInput.isRemote) {
|
const { eventObjectMetadata } = await this.createEventRelation(
|
||||||
const { eventObjectMetadata } = await this.createEventRelation(
|
objectMetadataInput.workspaceId,
|
||||||
|
createdObjectMetadata,
|
||||||
|
);
|
||||||
|
|
||||||
|
const { activityTargetObjectMetadata } =
|
||||||
|
await this.createActivityTargetRelation(
|
||||||
objectMetadataInput.workspaceId,
|
objectMetadataInput.workspaceId,
|
||||||
createdObjectMetadata,
|
createdObjectMetadata,
|
||||||
);
|
);
|
||||||
|
|
||||||
const { activityTargetObjectMetadata } =
|
const { favoriteObjectMetadata } = await this.createFavoriteRelation(
|
||||||
await this.createActivityTargetRelation(
|
objectMetadataInput.workspaceId,
|
||||||
objectMetadataInput.workspaceId,
|
createdObjectMetadata,
|
||||||
createdObjectMetadata,
|
);
|
||||||
);
|
|
||||||
|
|
||||||
const { favoriteObjectMetadata } = await this.createFavoriteRelation(
|
const { attachmentObjectMetadata } = await this.createAttachmentRelation(
|
||||||
objectMetadataInput.workspaceId,
|
objectMetadataInput.workspaceId,
|
||||||
createdObjectMetadata,
|
createdObjectMetadata,
|
||||||
);
|
);
|
||||||
|
|
||||||
const { attachmentObjectMetadata } = await this.createAttachmentRelation(
|
await this.workspaceMigrationService.createCustomMigration(
|
||||||
objectMetadataInput.workspaceId,
|
generateMigrationName(`create-${createdObjectMetadata.nameSingular}`),
|
||||||
createdObjectMetadata,
|
createdObjectMetadata.workspaceId,
|
||||||
);
|
isCustom
|
||||||
|
? buildWorkspaceMigrationsForCustomObject(
|
||||||
await this.workspaceMigrationService.createCustomMigration(
|
createdObjectMetadata,
|
||||||
generateMigrationName(`create-${createdObjectMetadata.nameSingular}`),
|
activityTargetObjectMetadata,
|
||||||
createdObjectMetadata.workspaceId,
|
attachmentObjectMetadata,
|
||||||
[
|
eventObjectMetadata,
|
||||||
{
|
favoriteObjectMetadata,
|
||||||
name: computeObjectTargetTable(createdObjectMetadata),
|
)
|
||||||
action: 'create',
|
: buildWorkspaceMigrationsForRemoteObject(
|
||||||
} satisfies WorkspaceMigrationTableAction,
|
createdObjectMetadata,
|
||||||
// Add activity target relation
|
activityTargetObjectMetadata,
|
||||||
{
|
attachmentObjectMetadata,
|
||||||
name: computeObjectTargetTable(activityTargetObjectMetadata),
|
eventObjectMetadata,
|
||||||
action: 'alter',
|
favoriteObjectMetadata,
|
||||||
columns: [
|
lastDataSourceMetadata.schema,
|
||||||
{
|
),
|
||||||
action: WorkspaceMigrationColumnActionType.CREATE,
|
);
|
||||||
columnName: `${computeCustomName(
|
|
||||||
createdObjectMetadata.nameSingular,
|
|
||||||
false,
|
|
||||||
)}Id`,
|
|
||||||
columnType: 'uuid',
|
|
||||||
isNullable: true,
|
|
||||||
} satisfies WorkspaceMigrationColumnCreate,
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: computeObjectTargetTable(activityTargetObjectMetadata),
|
|
||||||
action: 'alter',
|
|
||||||
columns: [
|
|
||||||
{
|
|
||||||
action: WorkspaceMigrationColumnActionType.CREATE_FOREIGN_KEY,
|
|
||||||
columnName: `${computeCustomName(
|
|
||||||
createdObjectMetadata.nameSingular,
|
|
||||||
false,
|
|
||||||
)}Id`,
|
|
||||||
referencedTableName: computeObjectTargetTable(
|
|
||||||
createdObjectMetadata,
|
|
||||||
),
|
|
||||||
referencedTableColumnName: 'id',
|
|
||||||
onDelete: RelationOnDeleteAction.CASCADE,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
// Add attachment relation
|
|
||||||
{
|
|
||||||
name: computeObjectTargetTable(attachmentObjectMetadata),
|
|
||||||
action: 'alter',
|
|
||||||
columns: [
|
|
||||||
{
|
|
||||||
action: WorkspaceMigrationColumnActionType.CREATE,
|
|
||||||
columnName: `${computeCustomName(
|
|
||||||
createdObjectMetadata.nameSingular,
|
|
||||||
false,
|
|
||||||
)}Id`,
|
|
||||||
columnType: 'uuid',
|
|
||||||
isNullable: true,
|
|
||||||
} satisfies WorkspaceMigrationColumnCreate,
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: computeObjectTargetTable(attachmentObjectMetadata),
|
|
||||||
action: 'alter',
|
|
||||||
columns: [
|
|
||||||
{
|
|
||||||
action: WorkspaceMigrationColumnActionType.CREATE_FOREIGN_KEY,
|
|
||||||
columnName: `${computeCustomName(
|
|
||||||
createdObjectMetadata.nameSingular,
|
|
||||||
false,
|
|
||||||
)}Id`,
|
|
||||||
referencedTableName: computeObjectTargetTable(
|
|
||||||
createdObjectMetadata,
|
|
||||||
),
|
|
||||||
referencedTableColumnName: 'id',
|
|
||||||
onDelete: RelationOnDeleteAction.CASCADE,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
// Add event relation
|
|
||||||
{
|
|
||||||
name: computeObjectTargetTable(eventObjectMetadata),
|
|
||||||
action: 'alter',
|
|
||||||
columns: [
|
|
||||||
{
|
|
||||||
action: WorkspaceMigrationColumnActionType.CREATE,
|
|
||||||
columnName: `${computeCustomName(
|
|
||||||
createdObjectMetadata.nameSingular,
|
|
||||||
false,
|
|
||||||
)}Id`,
|
|
||||||
columnType: 'uuid',
|
|
||||||
isNullable: true,
|
|
||||||
} satisfies WorkspaceMigrationColumnCreate,
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: computeObjectTargetTable(eventObjectMetadata),
|
|
||||||
action: 'alter',
|
|
||||||
columns: [
|
|
||||||
{
|
|
||||||
action: WorkspaceMigrationColumnActionType.CREATE_FOREIGN_KEY,
|
|
||||||
columnName: `${computeCustomName(
|
|
||||||
createdObjectMetadata.nameSingular,
|
|
||||||
false,
|
|
||||||
)}Id`,
|
|
||||||
referencedTableName: computeObjectTargetTable(
|
|
||||||
createdObjectMetadata,
|
|
||||||
),
|
|
||||||
referencedTableColumnName: 'id',
|
|
||||||
onDelete: RelationOnDeleteAction.CASCADE,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
// Add favorite relation
|
|
||||||
{
|
|
||||||
name: computeObjectTargetTable(favoriteObjectMetadata),
|
|
||||||
action: 'alter',
|
|
||||||
columns: [
|
|
||||||
{
|
|
||||||
action: WorkspaceMigrationColumnActionType.CREATE,
|
|
||||||
columnName: `${computeCustomName(
|
|
||||||
createdObjectMetadata.nameSingular,
|
|
||||||
false,
|
|
||||||
)}Id`,
|
|
||||||
columnType: 'uuid',
|
|
||||||
isNullable: true,
|
|
||||||
} satisfies WorkspaceMigrationColumnCreate,
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: computeObjectTargetTable(favoriteObjectMetadata),
|
|
||||||
action: 'alter',
|
|
||||||
columns: [
|
|
||||||
{
|
|
||||||
action: WorkspaceMigrationColumnActionType.CREATE_FOREIGN_KEY,
|
|
||||||
columnName: `${computeCustomName(
|
|
||||||
createdObjectMetadata.nameSingular,
|
|
||||||
false,
|
|
||||||
)}Id`,
|
|
||||||
referencedTableName: computeObjectTargetTable(
|
|
||||||
createdObjectMetadata,
|
|
||||||
),
|
|
||||||
referencedTableColumnName: 'id',
|
|
||||||
onDelete: RelationOnDeleteAction.CASCADE,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: computeObjectTargetTable(createdObjectMetadata),
|
|
||||||
action: 'alter',
|
|
||||||
columns: [
|
|
||||||
{
|
|
||||||
action: WorkspaceMigrationColumnActionType.CREATE,
|
|
||||||
columnName: 'position',
|
|
||||||
columnType: 'float',
|
|
||||||
isNullable: true,
|
|
||||||
} satisfies WorkspaceMigrationColumnCreate,
|
|
||||||
],
|
|
||||||
} satisfies WorkspaceMigrationTableAction,
|
|
||||||
// This is temporary until we implement mainIdentifier
|
|
||||||
{
|
|
||||||
name: computeObjectTargetTable(createdObjectMetadata),
|
|
||||||
action: 'alter',
|
|
||||||
columns: [
|
|
||||||
{
|
|
||||||
action: WorkspaceMigrationColumnActionType.CREATE,
|
|
||||||
columnName: 'name',
|
|
||||||
columnType: 'text',
|
|
||||||
defaultValue: "'Untitled'",
|
|
||||||
} satisfies WorkspaceMigrationColumnCreate,
|
|
||||||
],
|
|
||||||
} satisfies WorkspaceMigrationTableAction,
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
await this.workspaceMigrationRunnerService.executeMigrationFromPendingMigrations(
|
await this.workspaceMigrationRunnerService.executeMigrationFromPendingMigrations(
|
||||||
createdObjectMetadata.workspaceId,
|
createdObjectMetadata.workspaceId,
|
||||||
|
|||||||
@ -0,0 +1,175 @@
|
|||||||
|
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||||
|
import { RelationOnDeleteAction } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity';
|
||||||
|
import {
|
||||||
|
WorkspaceMigrationTableAction,
|
||||||
|
WorkspaceMigrationColumnActionType,
|
||||||
|
WorkspaceMigrationColumnCreate,
|
||||||
|
} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
|
||||||
|
import { computeCustomName } from 'src/engine/utils/compute-custom-name.util';
|
||||||
|
import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util';
|
||||||
|
|
||||||
|
export const buildWorkspaceMigrationsForCustomObject = (
|
||||||
|
createdObjectMetadata: ObjectMetadataEntity,
|
||||||
|
activityTargetObjectMetadata: ObjectMetadataEntity,
|
||||||
|
attachmentObjectMetadata: ObjectMetadataEntity,
|
||||||
|
eventObjectMetadata: ObjectMetadataEntity,
|
||||||
|
favoriteObjectMetadata: ObjectMetadataEntity,
|
||||||
|
): WorkspaceMigrationTableAction[] => [
|
||||||
|
{
|
||||||
|
name: computeObjectTargetTable(createdObjectMetadata),
|
||||||
|
action: 'create',
|
||||||
|
} satisfies WorkspaceMigrationTableAction,
|
||||||
|
// Add activity target relation
|
||||||
|
{
|
||||||
|
name: computeObjectTargetTable(activityTargetObjectMetadata),
|
||||||
|
action: 'alter',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
action: WorkspaceMigrationColumnActionType.CREATE,
|
||||||
|
columnName: `${computeCustomName(
|
||||||
|
createdObjectMetadata.nameSingular,
|
||||||
|
false,
|
||||||
|
)}Id`,
|
||||||
|
columnType: 'uuid',
|
||||||
|
isNullable: true,
|
||||||
|
} satisfies WorkspaceMigrationColumnCreate,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: computeObjectTargetTable(activityTargetObjectMetadata),
|
||||||
|
action: 'alter',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
action: WorkspaceMigrationColumnActionType.CREATE_FOREIGN_KEY,
|
||||||
|
columnName: `${computeCustomName(
|
||||||
|
createdObjectMetadata.nameSingular,
|
||||||
|
false,
|
||||||
|
)}Id`,
|
||||||
|
referencedTableName: computeObjectTargetTable(createdObjectMetadata),
|
||||||
|
referencedTableColumnName: 'id',
|
||||||
|
onDelete: RelationOnDeleteAction.CASCADE,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
// Add attachment relation
|
||||||
|
{
|
||||||
|
name: computeObjectTargetTable(attachmentObjectMetadata),
|
||||||
|
action: 'alter',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
action: WorkspaceMigrationColumnActionType.CREATE,
|
||||||
|
columnName: `${computeCustomName(
|
||||||
|
createdObjectMetadata.nameSingular,
|
||||||
|
false,
|
||||||
|
)}Id`,
|
||||||
|
columnType: 'uuid',
|
||||||
|
isNullable: true,
|
||||||
|
} satisfies WorkspaceMigrationColumnCreate,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: computeObjectTargetTable(attachmentObjectMetadata),
|
||||||
|
action: 'alter',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
action: WorkspaceMigrationColumnActionType.CREATE_FOREIGN_KEY,
|
||||||
|
columnName: `${computeCustomName(
|
||||||
|
createdObjectMetadata.nameSingular,
|
||||||
|
false,
|
||||||
|
)}Id`,
|
||||||
|
referencedTableName: computeObjectTargetTable(createdObjectMetadata),
|
||||||
|
referencedTableColumnName: 'id',
|
||||||
|
onDelete: RelationOnDeleteAction.CASCADE,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
// Add event relation
|
||||||
|
{
|
||||||
|
name: computeObjectTargetTable(eventObjectMetadata),
|
||||||
|
action: 'alter',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
action: WorkspaceMigrationColumnActionType.CREATE,
|
||||||
|
columnName: `${computeCustomName(
|
||||||
|
createdObjectMetadata.nameSingular,
|
||||||
|
false,
|
||||||
|
)}Id`,
|
||||||
|
columnType: 'uuid',
|
||||||
|
isNullable: true,
|
||||||
|
} satisfies WorkspaceMigrationColumnCreate,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: computeObjectTargetTable(eventObjectMetadata),
|
||||||
|
action: 'alter',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
action: WorkspaceMigrationColumnActionType.CREATE_FOREIGN_KEY,
|
||||||
|
columnName: `${computeCustomName(
|
||||||
|
createdObjectMetadata.nameSingular,
|
||||||
|
false,
|
||||||
|
)}Id`,
|
||||||
|
referencedTableName: computeObjectTargetTable(createdObjectMetadata),
|
||||||
|
referencedTableColumnName: 'id',
|
||||||
|
onDelete: RelationOnDeleteAction.CASCADE,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
// Add favorite relation
|
||||||
|
{
|
||||||
|
name: computeObjectTargetTable(favoriteObjectMetadata),
|
||||||
|
action: 'alter',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
action: WorkspaceMigrationColumnActionType.CREATE,
|
||||||
|
columnName: `${computeCustomName(
|
||||||
|
createdObjectMetadata.nameSingular,
|
||||||
|
false,
|
||||||
|
)}Id`,
|
||||||
|
columnType: 'uuid',
|
||||||
|
isNullable: true,
|
||||||
|
} satisfies WorkspaceMigrationColumnCreate,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: computeObjectTargetTable(favoriteObjectMetadata),
|
||||||
|
action: 'alter',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
action: WorkspaceMigrationColumnActionType.CREATE_FOREIGN_KEY,
|
||||||
|
columnName: `${computeCustomName(
|
||||||
|
createdObjectMetadata.nameSingular,
|
||||||
|
false,
|
||||||
|
)}Id`,
|
||||||
|
referencedTableName: computeObjectTargetTable(createdObjectMetadata),
|
||||||
|
referencedTableColumnName: 'id',
|
||||||
|
onDelete: RelationOnDeleteAction.CASCADE,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: computeObjectTargetTable(createdObjectMetadata),
|
||||||
|
action: 'alter',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
action: WorkspaceMigrationColumnActionType.CREATE,
|
||||||
|
columnName: 'position',
|
||||||
|
columnType: 'float',
|
||||||
|
isNullable: true,
|
||||||
|
} satisfies WorkspaceMigrationColumnCreate,
|
||||||
|
],
|
||||||
|
} satisfies WorkspaceMigrationTableAction,
|
||||||
|
// This is temporary until we implement mainIdentifier
|
||||||
|
{
|
||||||
|
name: computeObjectTargetTable(createdObjectMetadata),
|
||||||
|
action: 'alter',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
action: WorkspaceMigrationColumnActionType.CREATE,
|
||||||
|
columnName: 'name',
|
||||||
|
columnType: 'text',
|
||||||
|
defaultValue: "'Untitled'",
|
||||||
|
} satisfies WorkspaceMigrationColumnCreate,
|
||||||
|
],
|
||||||
|
} satisfies WorkspaceMigrationTableAction,
|
||||||
|
];
|
||||||
@ -0,0 +1,204 @@
|
|||||||
|
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||||
|
import {
|
||||||
|
WorkspaceMigrationTableAction,
|
||||||
|
WorkspaceMigrationColumnActionType,
|
||||||
|
WorkspaceMigrationColumnCreate,
|
||||||
|
} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
|
||||||
|
import { computeCustomName } from 'src/engine/utils/compute-custom-name.util';
|
||||||
|
import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util';
|
||||||
|
|
||||||
|
const buildCommentForRemoteObjectForeignKey = (
|
||||||
|
localObjectMetadataName: string,
|
||||||
|
remoteObjectMetadataName: string,
|
||||||
|
schema: string,
|
||||||
|
): string =>
|
||||||
|
`@graphql({"totalCount":{"enabled": true},"foreign_keys":[{"local_name":"${localObjectMetadataName}Collection","local_columns":["${remoteObjectMetadataName}Id"],"foreign_name":"${remoteObjectMetadataName}","foreign_schema":"${schema}","foreign_table":"${remoteObjectMetadataName}","foreign_columns":["id"]}]})`;
|
||||||
|
|
||||||
|
export const buildWorkspaceMigrationsForRemoteObject = (
|
||||||
|
createdObjectMetadata: ObjectMetadataEntity,
|
||||||
|
activityTargetObjectMetadata: ObjectMetadataEntity,
|
||||||
|
attachmentObjectMetadata: ObjectMetadataEntity,
|
||||||
|
eventObjectMetadata: ObjectMetadataEntity,
|
||||||
|
favoriteObjectMetadata: ObjectMetadataEntity,
|
||||||
|
schema: string,
|
||||||
|
): WorkspaceMigrationTableAction[] => {
|
||||||
|
const createdObjectName = createdObjectMetadata.nameSingular;
|
||||||
|
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
name: computeObjectTargetTable(activityTargetObjectMetadata),
|
||||||
|
action: 'alter',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
action: WorkspaceMigrationColumnActionType.CREATE,
|
||||||
|
columnName: `${computeCustomName(
|
||||||
|
createdObjectMetadata.nameSingular,
|
||||||
|
false,
|
||||||
|
)}Id`,
|
||||||
|
columnType: 'uuid',
|
||||||
|
isNullable: true,
|
||||||
|
} satisfies WorkspaceMigrationColumnCreate,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: computeObjectTargetTable(activityTargetObjectMetadata),
|
||||||
|
action: 'alter',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
action: WorkspaceMigrationColumnActionType.CREATE,
|
||||||
|
columnName: `${computeCustomName(
|
||||||
|
createdObjectMetadata.nameSingular,
|
||||||
|
false,
|
||||||
|
)}Id`,
|
||||||
|
columnType: 'uuid',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: computeObjectTargetTable(activityTargetObjectMetadata),
|
||||||
|
action: 'alter',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
action: WorkspaceMigrationColumnActionType.CREATE_COMMENT,
|
||||||
|
comment: buildCommentForRemoteObjectForeignKey(
|
||||||
|
activityTargetObjectMetadata.nameSingular,
|
||||||
|
createdObjectName,
|
||||||
|
schema,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
// Add attachment relation
|
||||||
|
{
|
||||||
|
name: computeObjectTargetTable(attachmentObjectMetadata),
|
||||||
|
action: 'alter',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
action: WorkspaceMigrationColumnActionType.CREATE,
|
||||||
|
columnName: `${computeCustomName(
|
||||||
|
createdObjectMetadata.nameSingular,
|
||||||
|
false,
|
||||||
|
)}Id`,
|
||||||
|
columnType: 'uuid',
|
||||||
|
isNullable: true,
|
||||||
|
} satisfies WorkspaceMigrationColumnCreate,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: computeObjectTargetTable(attachmentObjectMetadata),
|
||||||
|
action: 'alter',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
action: WorkspaceMigrationColumnActionType.CREATE,
|
||||||
|
columnName: `${computeCustomName(
|
||||||
|
createdObjectMetadata.nameSingular,
|
||||||
|
false,
|
||||||
|
)}Id`,
|
||||||
|
columnType: 'uuid',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: computeObjectTargetTable(attachmentObjectMetadata),
|
||||||
|
action: 'alter',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
action: WorkspaceMigrationColumnActionType.CREATE_COMMENT,
|
||||||
|
comment: buildCommentForRemoteObjectForeignKey(
|
||||||
|
attachmentObjectMetadata.nameSingular,
|
||||||
|
createdObjectName,
|
||||||
|
schema,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
// Add event relation
|
||||||
|
{
|
||||||
|
name: computeObjectTargetTable(eventObjectMetadata),
|
||||||
|
action: 'alter',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
action: WorkspaceMigrationColumnActionType.CREATE,
|
||||||
|
columnName: `${computeCustomName(
|
||||||
|
createdObjectMetadata.nameSingular,
|
||||||
|
false,
|
||||||
|
)}Id`,
|
||||||
|
columnType: 'uuid',
|
||||||
|
isNullable: true,
|
||||||
|
} satisfies WorkspaceMigrationColumnCreate,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: computeObjectTargetTable(eventObjectMetadata),
|
||||||
|
action: 'alter',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
action: WorkspaceMigrationColumnActionType.CREATE,
|
||||||
|
columnName: `${computeCustomName(
|
||||||
|
createdObjectMetadata.nameSingular,
|
||||||
|
false,
|
||||||
|
)}Id`,
|
||||||
|
columnType: 'uuid',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: computeObjectTargetTable(eventObjectMetadata),
|
||||||
|
action: 'alter',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
action: WorkspaceMigrationColumnActionType.CREATE_COMMENT,
|
||||||
|
comment: buildCommentForRemoteObjectForeignKey(
|
||||||
|
eventObjectMetadata.nameSingular,
|
||||||
|
createdObjectName,
|
||||||
|
schema,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
// Add favorite relation
|
||||||
|
{
|
||||||
|
name: computeObjectTargetTable(favoriteObjectMetadata),
|
||||||
|
action: 'alter',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
action: WorkspaceMigrationColumnActionType.CREATE,
|
||||||
|
columnName: `${computeCustomName(
|
||||||
|
createdObjectMetadata.nameSingular,
|
||||||
|
false,
|
||||||
|
)}Id`,
|
||||||
|
columnType: 'uuid',
|
||||||
|
isNullable: true,
|
||||||
|
} satisfies WorkspaceMigrationColumnCreate,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: computeObjectTargetTable(favoriteObjectMetadata),
|
||||||
|
action: 'alter',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
action: WorkspaceMigrationColumnActionType.CREATE,
|
||||||
|
columnName: `${computeCustomName(
|
||||||
|
createdObjectMetadata.nameSingular,
|
||||||
|
false,
|
||||||
|
)}Id`,
|
||||||
|
columnType: 'uuid',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: computeObjectTargetTable(favoriteObjectMetadata),
|
||||||
|
action: 'alter',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
action: WorkspaceMigrationColumnActionType.CREATE_COMMENT,
|
||||||
|
comment: buildCommentForRemoteObjectForeignKey(
|
||||||
|
favoriteObjectMetadata.nameSingular,
|
||||||
|
createdObjectName,
|
||||||
|
schema,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
};
|
||||||
@ -1,4 +1,4 @@
|
|||||||
const INPUT_REGEX = /^([A-Za-z0-9\-\_]+)$/;
|
const INPUT_REGEX = /^([A-Za-z0-9\-\_\.]+)$/;
|
||||||
|
|
||||||
export const validateObject = (input: object) => {
|
export const validateObject = (input: object) => {
|
||||||
for (const [key, value] of Object.entries(input)) {
|
for (const [key, value] of Object.entries(input)) {
|
||||||
|
|||||||
@ -13,6 +13,7 @@ export enum WorkspaceMigrationColumnActionType {
|
|||||||
CREATE_FOREIGN_KEY = 'CREATE_FOREIGN_KEY',
|
CREATE_FOREIGN_KEY = 'CREATE_FOREIGN_KEY',
|
||||||
DROP_FOREIGN_KEY = 'DROP_FOREIGN_KEY',
|
DROP_FOREIGN_KEY = 'DROP_FOREIGN_KEY',
|
||||||
DROP = 'DROP',
|
DROP = 'DROP',
|
||||||
|
CREATE_COMMENT = 'CREATE_COMMENT',
|
||||||
}
|
}
|
||||||
|
|
||||||
export type WorkspaceMigrationEnum = string | { from: string; to: string };
|
export type WorkspaceMigrationEnum = string | { from: string; to: string };
|
||||||
@ -56,6 +57,11 @@ export type WorkspaceMigrationColumnDrop = {
|
|||||||
columnName: string;
|
columnName: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type WorkspaceMigrationCreateComment = {
|
||||||
|
action: WorkspaceMigrationColumnActionType.CREATE_COMMENT;
|
||||||
|
comment: string;
|
||||||
|
};
|
||||||
|
|
||||||
export type WorkspaceMigrationColumnAction = {
|
export type WorkspaceMigrationColumnAction = {
|
||||||
action: WorkspaceMigrationColumnActionType;
|
action: WorkspaceMigrationColumnActionType;
|
||||||
} & (
|
} & (
|
||||||
@ -64,6 +70,7 @@ export type WorkspaceMigrationColumnAction = {
|
|||||||
| WorkspaceMigrationColumnCreateRelation
|
| WorkspaceMigrationColumnCreateRelation
|
||||||
| WorkspaceMigrationColumnDropRelation
|
| WorkspaceMigrationColumnDropRelation
|
||||||
| WorkspaceMigrationColumnDrop
|
| WorkspaceMigrationColumnDrop
|
||||||
|
| WorkspaceMigrationCreateComment
|
||||||
);
|
);
|
||||||
|
|
||||||
export type WorkspaceMigrationTableAction = {
|
export type WorkspaceMigrationTableAction = {
|
||||||
|
|||||||
@ -224,6 +224,14 @@ export class WorkspaceMigrationRunnerService {
|
|||||||
columnMigration.columnName,
|
columnMigration.columnName,
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
case WorkspaceMigrationColumnActionType.CREATE_COMMENT:
|
||||||
|
await this.createComment(
|
||||||
|
queryRunner,
|
||||||
|
schemaName,
|
||||||
|
tableName,
|
||||||
|
columnMigration.comment,
|
||||||
|
);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new Error(`Migration column action not supported`);
|
throw new Error(`Migration column action not supported`);
|
||||||
}
|
}
|
||||||
@ -412,4 +420,15 @@ export class WorkspaceMigrationRunnerService {
|
|||||||
|
|
||||||
return foreignKeys[0]?.constraint_name;
|
return foreignKeys[0]?.constraint_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async createComment(
|
||||||
|
queryRunner: QueryRunner,
|
||||||
|
schemaName: string,
|
||||||
|
tableName: string,
|
||||||
|
comment: string,
|
||||||
|
) {
|
||||||
|
await queryRunner.query(`
|
||||||
|
COMMENT ON TABLE "${schemaName}"."${tableName}" IS e'${comment}';
|
||||||
|
`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user