Skip to content

Commit

Permalink
Fix update remote field metadata (twentyhq#5638)
Browse files Browse the repository at this point in the history
Closes twentyhq#5610.

& update fetch-policy when fetching database on the remote databases
show page to get freshest status.
  • Loading branch information
ijreilly authored May 28, 2024
1 parent 0f483cc commit affdac0
Show file tree
Hide file tree
Showing 9 changed files with 146 additions and 25 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useQuery } from '@apollo/client';
import { useQuery, WatchQueryFetchPolicy } from '@apollo/client';

import { GET_ONE_DATABASE_CONNECTION } from '@/databases/graphql/queries/findOneDatabaseConnection';
import { getForeignDataWrapperType } from '@/databases/utils/getForeignDataWrapperType';
Expand All @@ -12,16 +12,20 @@ type UseGetDatabaseConnectionParams = {
databaseKey: string;
connectionId: string;
skip?: boolean;
fetchPolicy?: WatchQueryFetchPolicy;
};

export const useGetDatabaseConnection = ({
databaseKey,
connectionId,
skip,
fetchPolicy,
}: UseGetDatabaseConnectionParams) => {
const apolloMetadataClient = useApolloMetadataClient();
const foreignDataWrapperType = getForeignDataWrapperType(databaseKey);

const fetchPolicyOption = fetchPolicy ? { fetchPolicy: fetchPolicy } : {};

const { data, loading } = useQuery<
GetOneDatabaseConnectionQuery,
GetOneDatabaseConnectionQueryVariables
Expand All @@ -33,6 +37,7 @@ export const useGetDatabaseConnection = ({
id: connectionId,
},
},
...fetchPolicyOption,
});

const connection = data?.findOneRemoteServerById ?? null;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useQuery } from '@apollo/client';
import { useQuery, WatchQueryFetchPolicy } from '@apollo/client';

import { GET_MANY_REMOTE_TABLES } from '@/databases/graphql/queries/findManyRemoteTables';
import { useApolloMetadataClient } from '@/object-metadata/hooks/useApolloMetadataClient';
Expand All @@ -11,15 +11,19 @@ type UseGetDatabaseConnectionTablesParams = {
connectionId: string;
skip?: boolean;
shouldFetchPendingSchemaUpdates?: boolean;
fetchPolicy?: WatchQueryFetchPolicy;
};

export const useGetDatabaseConnectionTables = ({
connectionId,
skip,
shouldFetchPendingSchemaUpdates,
fetchPolicy,
}: UseGetDatabaseConnectionTablesParams) => {
const apolloMetadataClient = useApolloMetadataClient();

const fetchPolicyOption = fetchPolicy ? { fetchPolicy: fetchPolicy } : {};

const { data, error } = useQuery<
GetManyRemoteTablesQuery,
GetManyRemoteTablesQueryVariables
Expand All @@ -32,6 +36,7 @@ export const useGetDatabaseConnectionTables = ({
shouldFetchPendingSchemaUpdates,
},
},
...fetchPolicyOption,
});

return {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import { useCallback } from 'react';
import { ApolloClient, useMutation } from '@apollo/client';
import { ApolloClient, useApolloClient, useMutation } from '@apollo/client';

import { SYNC_REMOTE_TABLE_SCHEMA_CHANGES } from '@/databases/graphql/mutations/syncRemoteTableSchemaChanges';
import { modifyRemoteTableFromCache } from '@/databases/utils/modifyRemoteTableFromCache';
import { useApolloMetadataClient } from '@/object-metadata/hooks/useApolloMetadataClient';
import { useFindManyObjectMetadataItems } from '@/object-metadata/hooks/useFindManyObjectMetadataItems';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useFindManyRecordsQuery } from '@/object-record/hooks/useFindManyRecordsQuery';
import {
RemoteTableInput,
SyncRemoteTableSchemaChangesMutation,
Expand All @@ -13,6 +16,14 @@ import { isDefined } from '~/utils/isDefined';

export const useSyncRemoteTableSchemaChanges = () => {
const apolloMetadataClient = useApolloMetadataClient();
const apolloClient = useApolloClient();

const { refetch: refetchObjectMetadataItems } =
useFindManyObjectMetadataItems();

const { findManyRecordsQuery: findManyViewsQuery } = useFindManyRecordsQuery({
objectNameSingular: CoreObjectNameSingular.View,
});

const [mutate, mutationInformation] = useMutation<
SyncRemoteTableSchemaChangesMutation,
Expand Down Expand Up @@ -42,9 +53,16 @@ export const useSyncRemoteTableSchemaChanges = () => {
},
});

await refetchObjectMetadataItems();

await apolloClient.query({
query: findManyViewsQuery,
fetchPolicy: 'network-only',
});

return remoteTable;
},
[mutate],
[mutate, refetchObjectMetadataItems, findManyViewsQuery, apolloClient],
);

return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
export const SettingsIntegrationDatabaseConnectionShowContainer = () => {
const navigate = useNavigate();
const { connection, integration, databaseKey, tables } =
useDatabaseConnection();
useDatabaseConnection({ fetchPolicy: 'network-only' });

const { deleteOneDatabaseConnection } = useDeleteOneDatabaseConnection();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useDatabaseConnection } from '@/settings/integrations/database-connecti

export const SettingsIntegrationEditDatabaseConnectionContainer = () => {
const { connection, integration, databaseKey, tables } =
useDatabaseConnection();
useDatabaseConnection({});

if (!connection || !integration) return null;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
import { useEffect } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import { WatchQueryFetchPolicy } from '@apollo/client';

import { useGetDatabaseConnection } from '@/databases/hooks/useGetDatabaseConnection';
import { useGetDatabaseConnectionTables } from '@/databases/hooks/useGetDatabaseConnectionTables';
import { useIsSettingsIntegrationEnabled } from '@/settings/integrations/hooks/useIsSettingsIntegrationEnabled';
import { useSettingsIntegrationCategories } from '@/settings/integrations/hooks/useSettingsIntegrationCategories';
import { AppPath } from '@/types/AppPath';

export const useDatabaseConnection = () => {
export const useDatabaseConnection = ({
fetchPolicy,
}: {
fetchPolicy?: WatchQueryFetchPolicy;
}) => {
const { databaseKey = '', connectionId = '' } = useParams();
const navigate = useNavigate();

Expand All @@ -24,6 +29,7 @@ export const useDatabaseConnection = () => {
databaseKey,
connectionId,
skip: !isIntegrationAvailable,
fetchPolicy,
});

useEffect(() => {
Expand All @@ -43,6 +49,7 @@ export const useDatabaseConnection = () => {
connectionId,
skip: !connection,
shouldFetchPendingSchemaUpdates: true,
fetchPolicy,
});

return { connection, integration, databaseKey, tables };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,9 @@ export class DistantTableService {
return distantTables;
}

private async getDistantTablesFromStaticSchema(
private getDistantTablesFromStaticSchema(
remoteServer: RemoteServerEntity<RemoteServerType>,
): Promise<DistantTables> {
): DistantTables {
switch (remoteServer.foreignDataWrapperType) {
case RemoteServerType.STRIPE_FDW:
return STRIPE_DISTANT_TABLES;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ export class ForeignTableService {
public async updateForeignTable(
foreignTableName: string,
workspaceId: string,
columnsUpdates?: WorkspaceMigrationColumnAction[],
columnsUpdates: WorkspaceMigrationColumnAction[],
) {
const workspaceMigration =
await this.workspaceMigrationService.createCustomMigration(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,14 @@ import {
RemoteTableStatus,
} from 'src/engine/metadata-modules/remote-server/remote-table/dtos/remote-table.dto';
import {
mapUdtNameToFieldType,
mapUdtNameToFieldSettings,
mapUdtNameToFieldType,
} from 'src/engine/metadata-modules/remote-server/remote-table/utils/udt-name-mapper.util';
import { RemoteTableInput } from 'src/engine/metadata-modules/remote-server/remote-table/dtos/remote-table-input';
import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service';
import { ObjectMetadataService } from 'src/engine/metadata-modules/object-metadata/object-metadata.service';
import { CreateObjectInput } from 'src/engine/metadata-modules/object-metadata/dtos/create-object.input';
import { FieldMetadataService } from 'src/engine/metadata-modules/field-metadata/field-metadata.service';
import { CreateFieldInput } from 'src/engine/metadata-modules/field-metadata/dtos/create-field.input';
import { WorkspaceCacheVersionService } from 'src/engine/metadata-modules/workspace-cache-version/workspace-cache-version.service';
import { camelCase } from 'src/utils/camel-case';
import { camelToTitleCase } from 'src/utils/camel-to-title-case';
Expand All @@ -35,6 +34,12 @@ import { fetchTableColumns } from 'src/engine/metadata-modules/remote-server/rem
import { ForeignTableService } from 'src/engine/metadata-modules/remote-server/remote-table/foreign-table/foreign-table.service';
import { RemoteTableSchemaUpdateService } from 'src/engine/metadata-modules/remote-server/remote-table/remote-table-schema-update/remote-table-schema-update.service';
import { sortDistantTables } from 'src/engine/metadata-modules/remote-server/remote-table/distant-table/utils/sort-distant-tables.util';
import {
WorkspaceMigrationColumnAction,
WorkspaceMigrationColumnActionType,
} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
import { CreateFieldInput } from 'src/engine/metadata-modules/field-metadata/dtos/create-field.input';
import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';

export class RemoteTableService {
private readonly logger = new Logger(RemoteTableService.name);
Expand Down Expand Up @@ -353,7 +358,7 @@ export class RemoteTableService {
};
}

const updatedTable = await this.foreignTableService.updateForeignTable(
const updatedTable = await this.updateForeignTableAndFieldsMetadata(
remoteTable.localTableName,
workspaceId,
columnsUpdates,
Expand Down Expand Up @@ -436,18 +441,12 @@ export class RemoteTableService {

// TODO: return error to the user when a column cannot be managed
try {
const field = await this.fieldMetadataService.createOne({
name: columnName,
label: camelToTitleCase(columnName),
description: 'Field of remote',
type: mapUdtNameToFieldType(column.udtName),
workspaceId: workspaceId,
objectMetadataId: objectMetadata.id,
isRemoteCreation: true,
isNullable: true,
icon: 'IconPlug',
settings: mapUdtNameToFieldSettings(column.udtName),
} satisfies CreateFieldInput);
const field = await this.createFieldMetadataForForeignTableColumn(
workspaceId,
columnName,
column.udtName,
objectMetadata.id,
);

if (columnName === 'id') {
await this.objectMetadataService.updateOne(objectMetadata.id, {
Expand Down Expand Up @@ -489,4 +488,91 @@ export class RemoteTableService {

return [...distantTablesWithUpdates, ...deletedTables];
}

private async updateForeignTableAndFieldsMetadata(
foreignTableName: string,
workspaceId: string,
columnsUpdates: WorkspaceMigrationColumnAction[],
) {
const updatedForeignTable =
await this.foreignTableService.updateForeignTable(
foreignTableName,
workspaceId,
columnsUpdates,
);

const objectMetadata =
await this.objectMetadataService.findOneWithinWorkspace(workspaceId, {
where: { nameSingular: foreignTableName },
});

if (!objectMetadata) {
throw new NotFoundException(
`Cannot find associated object for table ${foreignTableName}`,
);
}
for (const columnUpdate of columnsUpdates) {
this.updateFieldMetadataFromColumnUpdate(
columnUpdate,
workspaceId,
objectMetadata.id,
);
}

return updatedForeignTable;
}

private async updateFieldMetadataFromColumnUpdate(
columnUpdate: WorkspaceMigrationColumnAction,
workspaceId: string,
objectMetadataId: string,
) {
if (columnUpdate.action === WorkspaceMigrationColumnActionType.CREATE) {
await this.createFieldMetadataForForeignTableColumn(
workspaceId,
columnUpdate.columnName,
columnUpdate.columnType,
objectMetadataId,
);
}
if (columnUpdate.action === WorkspaceMigrationColumnActionType.DROP) {
const columnName = columnUpdate.columnName;

const fieldMetadataToDelete =
await this.fieldMetadataService.findOneWithinWorkspace(workspaceId, {
where: {
objectMetadataId: objectMetadataId,
name: columnName,
},
});

if (!fieldMetadataToDelete) {
throw new NotFoundException(
`Cannot find associated field metadata for column ${columnName}`,
);
}

await this.fieldMetadataService.deleteOne(fieldMetadataToDelete.id);
}
}

private async createFieldMetadataForForeignTableColumn(
workspaceId: string,
columnName: string,
columnType: string,
objectMetadataId: string,
): Promise<FieldMetadataEntity<'default'>> {
return this.fieldMetadataService.createOne({
name: columnName,
label: camelToTitleCase(columnName),
description: 'Field of remote',
type: mapUdtNameToFieldType(columnType),
workspaceId: workspaceId,
objectMetadataId: objectMetadataId,
isRemoteCreation: true,
isNullable: true,
icon: 'IconPlug',
settings: mapUdtNameToFieldSettings(columnType),
} satisfies CreateFieldInput);
}
}

0 comments on commit affdac0

Please sign in to comment.