Implement eager load relations on graphqlQueries (#4391)

* Implement eager load relations on graphqlQueries

* Fix tests

* Fixes

* Fixes
This commit is contained in:
Charles Bochet
2024-03-10 23:42:23 +01:00
committed by GitHub
parent 86c0f311f5
commit ec384cc791
42 changed files with 1372 additions and 850 deletions

View File

@ -1,10 +1,10 @@
import { useApolloClient } from '@apollo/client';
import gql from 'graphql-tag';
import { useRecoilCallback } from 'recoil';
import { useRecoilCallback, useRecoilValue } from 'recoil';
import { useMapFieldMetadataToGraphQLQuery } from '@/object-metadata/hooks/useMapFieldMetadataToGraphQLQuery';
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
import { MAX_QUERY_DEPTH_FOR_CACHE_INJECTION } from '@/object-record/cache/constants/MaxQueryDepthForCacheInjection';
import { mapObjectMetadataToGraphQLQuery } from '@/object-metadata/utils/mapObjectMetadataToGraphQLQuery';
import { useInjectIntoFindOneRecordQueryCache } from '@/object-record/cache/hooks/useInjectIntoFindOneRecordQueryCache';
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
@ -15,7 +15,7 @@ export const useAddRecordInCache = ({
}: {
objectMetadataItem: ObjectMetadataItem;
}) => {
const mapFieldMetadataToGraphQLQuery = useMapFieldMetadataToGraphQLQuery();
const objectMetadataItems = useRecoilValue(objectMetadataItemsState());
const apolloClient = useApolloClient();
const { injectIntoFindOneRecordQueryCache } =
@ -29,18 +29,12 @@ export const useAddRecordInCache = ({
const fragment = gql`
fragment Create${capitalize(
objectMetadataItem.nameSingular,
)}InCache on ${capitalize(objectMetadataItem.nameSingular)} {
__typename
id
${objectMetadataItem.fields
.map((field) =>
mapFieldMetadataToGraphQLQuery({
field,
depth: MAX_QUERY_DEPTH_FOR_CACHE_INJECTION,
}),
)
.join('\n')}
}
)}InCache on ${capitalize(
objectMetadataItem.nameSingular,
)} ${mapObjectMetadataToGraphQLQuery({
objectMetadataItems,
objectMetadataItem,
})}
`;
const cachedObjectRecord = {
@ -62,8 +56,8 @@ export const useAddRecordInCache = ({
},
[
objectMetadataItem,
objectMetadataItems,
apolloClient,
mapFieldMetadataToGraphQLQuery,
injectIntoFindOneRecordQueryCache,
],
);

View File

@ -0,0 +1,47 @@
import { useApolloClient } from '@apollo/client/react/hooks/useApolloClient';
import gql from 'graphql-tag';
import { useRecoilValue } from 'recoil';
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
import { QueryMethodName } from '@/object-metadata/types/QueryMethodName';
import { mapObjectMetadataToGraphQLQuery } from '@/object-metadata/utils/mapObjectMetadataToGraphQLQuery';
export const useCachedRootQuery = ({
objectMetadataItem,
queryMethodName,
}: {
objectMetadataItem: ObjectMetadataItem | undefined;
queryMethodName: QueryMethodName;
}) => {
const apolloClient = useApolloClient();
const objectMetadataItems = useRecoilValue(objectMetadataItemsState());
if (!objectMetadataItem) {
return { cachedRootQuery: null };
}
const cacheReadFragment = gql`
fragment RootQuery on Query {
${
QueryMethodName.FindMany === queryMethodName
? objectMetadataItem.namePlural
: objectMetadataItem.nameSingular
}
${QueryMethodName.FindMany === queryMethodName ? '{ edges { node ' : ''}
${mapObjectMetadataToGraphQLQuery({
objectMetadataItems,
objectMetadataItem,
depth: 0,
})}
${QueryMethodName.FindMany === queryMethodName ? '}}' : ''}
}
`;
const cachedRootQuery = apolloClient.readFragment({
id: 'ROOT_QUERY',
fragment: cacheReadFragment,
});
return { cachedRootQuery };
};

View File

@ -1,7 +1,9 @@
import { gql, useApolloClient } from '@apollo/client';
import { useRecoilValue } from 'recoil';
import { useMapFieldMetadataToGraphQLQuery } from '@/object-metadata/hooks/useMapFieldMetadataToGraphQLQuery';
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
import { mapObjectMetadataToGraphQLQuery } from '@/object-metadata/utils/mapObjectMetadataToGraphQLQuery';
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
import { isNullable } from '~/utils/isNullable';
import { capitalize } from '~/utils/string/capitalize';
@ -11,7 +13,8 @@ export const useGetRecordFromCache = ({
}: {
objectMetadataItem: ObjectMetadataItem;
}) => {
const mapFieldMetadataToGraphQLQuery = useMapFieldMetadataToGraphQLQuery();
const objectMetadataItems = useRecoilValue(objectMetadataItemsState());
const apolloClient = useApolloClient();
return <CachedObjectRecord extends ObjectRecord = ObjectRecord>(
@ -25,12 +28,12 @@ export const useGetRecordFromCache = ({
const capitalizedObjectName = capitalize(objectMetadataItem.nameSingular);
const cacheReadFragment = gql`
fragment ${capitalizedObjectName}Fragment on ${capitalizedObjectName} {
id
${objectMetadataItem.fields
.map((field) => mapFieldMetadataToGraphQLQuery({ field }))
.join('\n')}
}
fragment ${capitalizedObjectName}Fragment on ${capitalizedObjectName} ${mapObjectMetadataToGraphQLQuery(
{
objectMetadataItems,
objectMetadataItem,
},
)}
`;
const cachedRecordId = cache.identify({