refactor: remove unnecessary code related to suggested relationships

PR-URL: https://github.com/hasura/graphql-engine-mono/pull/9590
GitOrigin-RevId: 493707ac2b0edc567bf651b74d88f4ce19eb9735
This commit is contained in:
Luca Restagno 2023-06-23 14:47:13 +02:00 committed by hasura-bot
parent 63e3dd2684
commit 9179135148
7 changed files with 80 additions and 271 deletions

View File

@ -35,11 +35,8 @@ export const UntrackedRelationships: React.VFC<UntrackedRelationshipsProps> = ({
const [selectedRelationship, setSelectedRelationship] = const [selectedRelationship, setSelectedRelationship] =
useState<SuggestedRelationshipWithName | null>(null); useState<SuggestedRelationshipWithName | null>(null);
const { const { suggestedRelationships, isLoadingSuggestedRelationships } =
suggestedRelationships, useAllSuggestedRelationships({
isLoadingSuggestedRelationships,
// onAddMultipleSuggestedRelationships,
} = useAllSuggestedRelationships({
dataSourceName, dataSourceName,
isEnabled: true, isEnabled: true,
omitTracked: true, omitTracked: true,

View File

@ -25,7 +25,6 @@ export const SuggestedRelationshipTrackModal: React.VFC<
const { refetchSuggestedRelationships } = useSuggestedRelationships({ const { refetchSuggestedRelationships } = useSuggestedRelationships({
dataSourceName, dataSourceName,
table: relationship.from.table, table: relationship.from.table,
existingRelationships: [],
isEnabled: true, isEnabled: true,
}); });

View File

@ -12,13 +12,11 @@ import {
} from 'react-icons/fa'; } from 'react-icons/fa';
import { MetadataSelectors, useMetadata } from '../../../hasura-metadata-api'; import { MetadataSelectors, useMetadata } from '../../../hasura-metadata-api';
import { getSupportsForeignKeys } from '../../../hasura-metadata-api/utils'; import { getSupportsForeignKeys } from '../../../hasura-metadata-api/utils';
import { useListAllDatabaseRelationships } from '../../hooks/useListAllDatabaseRelationships';
import { getTableDisplayName } from '../../utils/helpers'; import { getTableDisplayName } from '../../utils/helpers';
import { import {
SuggestedRelationshipWithName, SuggestedRelationshipWithName,
useSuggestedRelationships, useSuggestedRelationships,
} from './hooks/useSuggestedRelationships'; } from './hooks/useSuggestedRelationships';
import type { LocalRelationship } from '../../types';
import Skeleton from 'react-loading-skeleton'; import Skeleton from 'react-loading-skeleton';
import { SuggestedRelationshipTrackModal } from '../SuggestedRelationshipTrackModal/SuggestedRelationshipTrackModal'; import { SuggestedRelationshipTrackModal } from '../SuggestedRelationshipTrackModal/SuggestedRelationshipTrackModal';
@ -31,17 +29,6 @@ export const SuggestedRelationships = ({
dataSourceName, dataSourceName,
table, table,
}: SuggestedRelationshipsProps) => { }: SuggestedRelationshipsProps) => {
const { data: existingRelationships } = useListAllDatabaseRelationships({
dataSourceName,
table,
});
const localRelationships = existingRelationships.filter(rel => {
if (rel.type === 'localRelationship') {
return true;
}
return false;
}) as LocalRelationship[];
const { data: source } = useMetadata( const { data: source } = useMetadata(
MetadataSelectors.findSource(dataSourceName) MetadataSelectors.findSource(dataSourceName)
); );
@ -52,7 +39,6 @@ export const SuggestedRelationships = ({
useSuggestedRelationships({ useSuggestedRelationships({
dataSourceName, dataSourceName,
table, table,
existingRelationships: localRelationships,
isEnabled: supportsForeignKeys, isEnabled: supportsForeignKeys,
}); });

View File

@ -1,5 +1,5 @@
import { useEffect } from 'react'; import { useEffect } from 'react';
import { useQuery, useQueryClient } from 'react-query'; import { useQuery } from 'react-query';
import { LocalRelationship } from '../../../types'; import { LocalRelationship } from '../../../types';
import { getDriverPrefix, runMetadataQuery } from '../../../../DataSource'; import { getDriverPrefix, runMetadataQuery } from '../../../../DataSource';
import { MetadataSelectors } from '../../../../hasura-metadata-api'; import { MetadataSelectors } from '../../../../hasura-metadata-api';
@ -8,47 +8,8 @@ import { useHttpClient } from '../../../../Network';
import { import {
addConstraintName, addConstraintName,
SuggestedRelationshipsResponse, SuggestedRelationshipsResponse,
SuggestedRelationshipWithName,
} from './useSuggestedRelationships'; } from './useSuggestedRelationships';
import { import { NamingConvention, Table } from '../../../../hasura-metadata-types';
allowedMetadataTypes,
useMetadataMigration,
} from '../../../../MetadataAPI';
import {
BulkKeepGoingResponse,
NamingConvention,
Table,
} from '../../../../hasura-metadata-types';
import { getTrackedRelationshipsCacheKey } from '../../../../Data/TrackResources/components/hooks/useTrackedRelationships';
import { hasuraToast } from '../../../../../new-components/Toasts';
import { useDriverRelationshipSupport } from '../../../../Data/hooks/useDriverRelationshipSupport';
import adaptTrackRelationship from '../../../../Data/TrackResources/components/utils/adaptTrackRelationship';
import {
getLocalRelationshipPayload,
LocalRelationshipQuery,
} from '../adapters/getLocalRelationshipPayload';
type QueriesType =
| {
type: allowedMetadataTypes;
args: LocalRelationshipQuery;
}[]
| {
type: allowedMetadataTypes;
args: {
table: unknown;
name: string;
source: string;
definition: {
to_source: {
relationship_type: 'object' | 'array';
source: any;
table: any;
field_mapping: { [x: string]: string };
};
};
};
}[];
export type AddSuggestedRelationship = { export type AddSuggestedRelationship = {
name: string; name: string;
@ -81,11 +42,6 @@ export const useAllSuggestedRelationships = ({
MetadataSelectors.findSource(dataSourceName) MetadataSelectors.findSource(dataSourceName)
); );
const { driverSupportsLocalRelationship, driverSupportsRemoteRelationship } =
useDriverRelationshipSupport({
dataSourceName,
});
const dataSourcePrefix = metadataSource?.kind const dataSourcePrefix = metadataSource?.kind
? getDriverPrefix(metadataSource?.kind) ? getDriverPrefix(metadataSource?.kind)
: undefined; : undefined;
@ -132,106 +88,6 @@ export const useAllSuggestedRelationships = ({
const rawSuggestedRelationships = data?.relationships || []; const rawSuggestedRelationships = data?.relationships || [];
const metadataMutation = useMetadataMigration<BulkKeepGoingResponse>({});
const queryClient = useQueryClient();
const onAddMultipleSuggestedRelationships = async (
suggestedRelationships: SuggestedRelationshipWithName[]
) => {
const relationships = suggestedRelationships.map(adaptTrackRelationship);
let queries: QueriesType = [];
if (!driverSupportsLocalRelationship && !driverSupportsRemoteRelationship) {
hasuraToast({
type: 'error',
title: 'Not able to track',
message: `This datasource does not support tracking of relationships.`,
});
return;
}
if (driverSupportsLocalRelationship) {
queries = relationships.map(relationship =>
getLocalRelationshipPayload({
dataSourcePrefix: dataSourcePrefix || '',
dataSourceName,
relationship,
})
);
} else if (driverSupportsRemoteRelationship) {
queries = relationships.map(relationship => {
return {
type: `${dataSourcePrefix}_create_remote_relationship`,
args: {
table: relationship.fromTable,
name: relationship.name,
source: dataSourceName,
definition: {
to_source: {
relationship_type: relationship.relationshipType,
source: dataSourceName,
table: relationship.fromTable,
field_mapping: relationship?.fromColumnNames?.reduce(
(tally, curr, i) => {
return {
...tally,
[curr]: relationship.toColumnNames[i],
};
},
{}
),
},
},
},
};
});
}
await metadataMutation.mutateAsync(
{
query: {
type: 'bulk_keep_going',
args: queries,
},
},
{
onSuccess: response => {
response.forEach(result => {
if ('error' in result) {
hasuraToast({
type: 'error',
title: 'Error while tracking foreign key',
children: result.error,
});
}
});
const successfullyTrackedCounter = response.filter(
result => 'message' in result && result.message === 'success'
).length;
const plural = successfullyTrackedCounter > 1 ? 's' : '';
hasuraToast({
type: 'success',
title: 'Successfully tracked',
message: `${successfullyTrackedCounter} foreign key${plural} tracked`,
});
},
onSettled: () => {
queryClient.invalidateQueries({
queryKey: getAllSuggestedRelationshipsCacheQuery(
dataSourceName,
omitTracked
),
});
queryClient.invalidateQueries({
queryKey: getTrackedRelationshipsCacheKey(dataSourceName),
});
},
}
);
};
const relationshipsWithConstraintName = addConstraintName( const relationshipsWithConstraintName = addConstraintName(
rawSuggestedRelationships, rawSuggestedRelationships,
namingConvention namingConvention
@ -242,7 +98,6 @@ export const useAllSuggestedRelationships = ({
isLoadingSuggestedRelationships: isLoadingAllSuggestedRelationships, isLoadingSuggestedRelationships: isLoadingAllSuggestedRelationships,
isFetchingSuggestedRelationships: isFetchingAllSuggestedRelationships, isFetchingSuggestedRelationships: isFetchingAllSuggestedRelationships,
refetchSuggestedRelationships: refetchAllSuggestedRelationships, refetchSuggestedRelationships: refetchAllSuggestedRelationships,
onAddMultipleSuggestedRelationships,
...rest, ...rest,
}; };
}; };

View File

@ -1,7 +1,7 @@
import { useEffect, useState } from 'react'; import { useEffect } from 'react';
import inflection from 'inflection'; import inflection from 'inflection';
import camelCase from 'lodash/camelCase'; import camelCase from 'lodash/camelCase';
import { LocalRelationship, SuggestedRelationship } from '../../../types'; import { SuggestedRelationship } from '../../../types';
import { getTableDisplayName } from '../../../utils/helpers'; import { getTableDisplayName } from '../../../utils/helpers';
import { getDriverPrefix, runMetadataQuery } from '../../../../DataSource'; import { getDriverPrefix, runMetadataQuery } from '../../../../DataSource';
import { import {
@ -11,18 +11,11 @@ import {
import { useMetadata } from '../../../../hasura-metadata-api/useMetadata'; import { useMetadata } from '../../../../hasura-metadata-api/useMetadata';
import { NamingConvention, Table } from '../../../../hasura-metadata-types'; import { NamingConvention, Table } from '../../../../hasura-metadata-types';
import { useHttpClient } from '../../../../Network'; import { useHttpClient } from '../../../../Network';
import { useQuery, useQueryClient } from 'react-query'; import { useQuery } from 'react-query';
import { generateQueryKeys } from '../../../utils/queryClientUtils';
import { useMetadataMigration } from '../../../../MetadataAPI';
import { useDriverRelationshipSupport } from '../../../../Data/hooks/useDriverRelationshipSupport';
import { hasuraToast } from '../../../../../new-components/Toasts/hasuraToast';
import adaptTrackRelationship from '../../../../Data/TrackResources/components/utils/adaptTrackRelationship';
import { getLocalRelationshipPayload } from '../adapters/getLocalRelationshipPayload';
type UseSuggestedRelationshipsArgs = { type UseSuggestedRelationshipsArgs = {
dataSourceName: string; dataSourceName: string;
table?: Table; table?: Table;
existingRelationships?: LocalRelationship[];
isEnabled: boolean; isEnabled: boolean;
}; };
@ -103,25 +96,15 @@ export const getSuggestedRelationshipsCacheQuery = (
export const useSuggestedRelationships = ({ export const useSuggestedRelationships = ({
dataSourceName, dataSourceName,
table, table,
existingRelationships = [],
isEnabled, isEnabled,
}: UseSuggestedRelationshipsArgs) => { }: UseSuggestedRelationshipsArgs) => {
const { data: metadataSource, isFetching } = useMetadata( const { data: metadataSource, isFetching } = useMetadata(
MetadataSelectors.findSource(dataSourceName) MetadataSelectors.findSource(dataSourceName)
); );
const { driverSupportsLocalRelationship, driverSupportsRemoteRelationship } =
useDriverRelationshipSupport({
dataSourceName,
});
const namingConvention: NamingConvention = const namingConvention: NamingConvention =
metadataSource?.customization?.naming_convention || 'hasura-default'; metadataSource?.customization?.naming_convention || 'hasura-default';
const metadataMutation = useMetadataMigration({});
const queryClient = useQueryClient();
const dataSourcePrefix = metadataSource?.kind const dataSourcePrefix = metadataSource?.kind
? getDriverPrefix(metadataSource?.kind) ? getDriverPrefix(metadataSource?.kind)
: undefined; : undefined;
@ -154,83 +137,6 @@ export const useSuggestedRelationships = ({
refetchOnWindowFocus: false, refetchOnWindowFocus: false,
}); });
const [isAddingSuggestedRelationship, setAddingSuggestedRelationship] =
useState(false);
const onAddSuggestedRelationship = async (
relationship: SuggestedRelationshipWithName
) => {
const addRelationship = adaptTrackRelationship(relationship);
setAddingSuggestedRelationship(true);
if (!driverSupportsLocalRelationship && !driverSupportsRemoteRelationship) {
hasuraToast({
type: 'error',
title: 'Not able to track',
message: `This datasource does not support tracking of relationships.`,
});
return;
}
if (driverSupportsLocalRelationship) {
await metadataMutation.mutateAsync({
query: getLocalRelationshipPayload({
dataSourcePrefix: dataSourcePrefix || '',
dataSourceName,
relationship: addRelationship,
}),
});
} else if (driverSupportsRemoteRelationship) {
const {
fromTable,
name,
relationshipType,
fromColumnNames,
toColumnNames,
} = addRelationship;
await metadataMutation.mutateAsync({
query: {
type: `${dataSourcePrefix}_create_remote_relationship`,
args: {
table: fromTable || table,
name,
source: dataSourceName,
definition: {
to_source: {
relationship_type: relationshipType,
source: dataSourceName,
table: fromTable || table,
field_mapping: fromColumnNames?.reduce((tally, curr, i) => {
return {
...tally,
[curr]: toColumnNames[i],
};
}, {}),
},
},
},
},
});
}
hasuraToast({
title: 'Success',
message: 'Relationship tracked',
type: 'success',
});
setAddingSuggestedRelationship(false);
queryClient.invalidateQueries({
queryKey: generateQueryKeys.metadata(),
});
queryClient.invalidateQueries({
queryKey: getSuggestedRelationshipsCacheQuery(dataSourceName, table),
});
};
useEffect(() => { useEffect(() => {
if (dataSourcePrefix) { if (dataSourcePrefix) {
refetchSuggestedRelationships(); refetchSuggestedRelationships();
@ -265,7 +171,5 @@ export const useSuggestedRelationships = ({
suggestedRelationships: relationshipsWithConstraintName, suggestedRelationships: relationshipsWithConstraintName,
isLoadingSuggestedRelationships, isLoadingSuggestedRelationships,
refetchSuggestedRelationships, refetchSuggestedRelationships,
onAddSuggestedRelationship,
isAddingSuggestedRelationship,
}; };
}; };

View File

@ -126,6 +126,74 @@ describe('adaptLocalArrayRelationshipWithFkConstraint', () => {
expect(result).toEqual(expected); expect(result).toEqual(expected);
}); });
describe('scenario two', () => {
it('returns the correct array relationships', () => {
const table: Table = { name: 'table_a', schema: 'public' };
const dataSourceName = 'aPostgres';
const relationship: LocalTableArrayRelationship = {
name: 'table_a_table_cs',
using: {
foreign_key_constraint_on: {
column: 'id_a',
table: { name: 'table_c', schema: 'public' },
},
},
};
const suggestedRelationships: SuggestedRelationship[] = [
{
type: 'array',
from: {
table: { schema: 'public', name: 'table_a' },
columns: ['id'],
},
to: {
table: { schema: 'public', name: 'table_c' },
columns: ['id_a'],
constraint_name: 'table_c_id_a_fkey',
},
},
{
type: 'array',
from: {
table: { schema: 'public', name: 'table_b' },
columns: ['id'],
},
to: {
table: { schema: 'public', name: 'table_c' },
columns: ['id_b'],
constraint_name: 'table_c_id_b_fkey',
},
},
];
const expected: LocalRelationship = {
name: 'table_a_table_cs',
fromSource: 'aPostgres',
fromTable: { schema: 'public', name: 'table_a' },
relationshipType: 'Array',
type: 'localRelationship',
definition: {
toTable: { schema: 'public', name: 'table_c' },
toColumns: ['id_a'],
fromTable: { schema: 'public', name: 'table_a' },
fromColumns: ['id'],
mapping: { id_a: 'id' },
},
};
const result = adaptLocalArrayRelationshipWithFkConstraint({
table,
dataSourceName,
relationship,
suggestedRelationships,
});
console.log(result);
expect(result).toEqual(expected);
});
});
}); });
describe('adaptLocalObjectRelationshipWithFkConstraint', () => { describe('adaptLocalObjectRelationshipWithFkConstraint', () => {

View File

@ -85,7 +85,7 @@ const getFkDefinition = (
const sameToColumns = isEqual( const sameToColumns = isEqual(
toColumn.sort(), toColumn.sort(),
suggestedRelationship.from.columns suggestedRelationship.to.columns
); );
const sameToTable = areTablesEqual( const sameToTable = areTablesEqual(
relationship.using.foreign_key_constraint_on.table, relationship.using.foreign_key_constraint_on.table,