Skip to content
This repository was archived by the owner on Sep 3, 2021. It is now read-only.

Commit 387c6dd

Browse files
Fix for #218 (#485)
* fixes #218 by setting appropriate cypher variables * tests for #218 fix covers add, remove, and update (merge / update use the same translation function)
1 parent b548e71 commit 387c6dd

File tree

2 files changed

+150
-8
lines changed

2 files changed

+150
-8
lines changed

src/translate.js

+25-8
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,9 @@ export const relationTypeFieldOnNodeType = ({
344344
}) => {
345345
let translation = '';
346346
if (innerSchemaTypeRelation.from === innerSchemaTypeRelation.to) {
347-
translation = `${initial}${fieldName}: {${subSelection[0]}}${skipLimit} ${commaIfTail}`;
347+
translation = `${initial}${fieldName}: {${
348+
subSelection[0]
349+
}}${skipLimit} ${commaIfTail}`;
348350
} else {
349351
const relationshipVariableName = `${nestedVariable}_relation`;
350352

@@ -481,22 +483,25 @@ export const nodeTypeFieldOnRelationType = ({
481483
fieldArgs,
482484
cypherParams
483485
}) => {
484-
const safeVariableName = safeVar(variableName);
485486
if (
486487
isRootSelection({
487488
selectionInfo: parentSelectionInfo,
488489
rootType: 'relationship'
489490
}) &&
490491
isRelationTypeDirectedField(fieldName)
491492
) {
493+
const nodeFieldVariableName = decideRootRelationshipTypeNodeVariable({
494+
parentSelectionInfo,
495+
fieldName
496+
});
492497
const [mapProjection, labelPredicate] = buildMapProjection({
493498
schemaType: innerSchemaType,
494499
isObjectType: isObjectTypeField,
495500
isInterfaceType: isInterfaceTypeField,
496501
isUnionType: isUnionTypeField,
497-
usesFragments,
498-
safeVariableName,
502+
safeVariableName: nodeFieldVariableName,
499503
subQuery: subSelection[0],
504+
usesFragments,
500505
schemaTypeFields,
501506
derivedTypeMap,
502507
resolveInfo
@@ -544,6 +549,19 @@ export const nodeTypeFieldOnRelationType = ({
544549
});
545550
};
546551

552+
const decideRootRelationshipTypeNodeVariable = ({
553+
parentSelectionInfo = {},
554+
fieldName
555+
}) => {
556+
const fromVariable = parentSelectionInfo.from;
557+
const toVariable = parentSelectionInfo.to;
558+
// assume incoming
559+
let variableName = safeVar(fromVariable);
560+
// else set as outgoing
561+
if (fieldName === 'to') variableName = safeVar(toVariable);
562+
return variableName;
563+
};
564+
547565
const relationTypeMutationPayloadField = ({
548566
initial,
549567
fieldName,
@@ -871,7 +889,9 @@ export const neo4jType = ({
871889
return {
872890
initial: `${initial}${fieldName}: ${
873891
fieldIsArray
874-
? `reduce(a = [], INSTANCE IN ${variableName}.${fieldName} | a + {${subSelection[0]}})${commaIfTail}`
892+
? `reduce(a = [], INSTANCE IN ${variableName}.${fieldName} | a + {${
893+
subSelection[0]
894+
}})${commaIfTail}`
875895
: usesTemporalOrdering
876896
? `${safeVariableName}.${fieldName}${commaIfTail}`
877897
: `{${subSelection[0]}}${commaIfTail}`
@@ -1816,7 +1836,6 @@ const relationshipCreate = ({
18161836
to: toVar,
18171837
variableName: lowercased
18181838
},
1819-
variableName: schemaType.name === fromType ? `${toVar}` : `${fromVar}`,
18201839
cypherParams: getCypherParams(context)
18211840
});
18221841
params = { ...preparedParams, ...subParams };
@@ -1942,7 +1961,6 @@ const relationshipDelete = ({
19421961
from: `_${fromVar}`,
19431962
to: `_${toVar}`
19441963
},
1945-
variableName: schemaType.name === fromType ? `_${toVar}` : `_${fromVar}`,
19461964
cypherParams: getCypherParams(context)
19471965
});
19481966
params = { ...params, ...subParams };
@@ -2068,7 +2086,6 @@ const relationshipMergeOrUpdate = ({
20682086
to: toVar,
20692087
variableName: lowercased
20702088
},
2071-
variableName: schemaType.name === fromType ? `${toVar}` : `${fromVar}`,
20722089
cypherParams: getCypherParams(context)
20732090
});
20742091
let cypherOperation = '';

test/unit/cypherTest.test.js

+125
Original file line numberDiff line numberDiff line change
@@ -778,6 +778,39 @@ test('Add relationship mutation', t => {
778778
);
779779
});
780780

781+
test('Add relationship mutation and query only outgoing nodes', t => {
782+
const graphQLQuery = `mutation someMutation {
783+
AddMovieGenres(
784+
from: { movieId: "123" },
785+
to: { name: "Action" }
786+
) {
787+
to {
788+
name
789+
}
790+
}
791+
}`,
792+
expectedCypherQuery = `
793+
MATCH (\`movie_from\`:\`Movie\`${ADDITIONAL_MOVIE_LABELS} {movieId: $from.movieId})
794+
MATCH (\`genre_to\`:\`Genre\` {name: $to.name})
795+
CREATE (\`movie_from\`)-[\`in_genre_relation\`:\`IN_GENRE\`]->(\`genre_to\`)
796+
RETURN \`in_genre_relation\` { to: \`genre_to\` { .name } } AS \`_AddMovieGenresPayload\`;
797+
`;
798+
799+
t.plan(1);
800+
return augmentedSchemaCypherTestRunner(
801+
t,
802+
graphQLQuery,
803+
{
804+
from: { movieId: '123' },
805+
to: { name: 'Action' },
806+
first: -1,
807+
offset: 0
808+
},
809+
expectedCypherQuery,
810+
{}
811+
);
812+
});
813+
781814
test('Merge relationship mutation', t => {
782815
const graphQLQuery = `mutation someMutation {
783816
MergeMovieGenres(
@@ -1053,6 +1086,63 @@ test('Update relationship mutation with relationship property', t => {
10531086
);
10541087
});
10551088

1089+
test('Update relationship mutation with relationship property and query only outgoing nodes', t => {
1090+
const graphQLQuery = `mutation someMutation {
1091+
UpdateUserRated(
1092+
from: { userId: "123" }
1093+
to: { movieId: "2kljghd" }
1094+
data: {
1095+
rating: 1
1096+
location: { longitude: 3.0, latitude: 4.5, height: 12.5 }
1097+
}
1098+
) {
1099+
to {
1100+
_id
1101+
movieId
1102+
title
1103+
ratings {
1104+
rating
1105+
User {
1106+
_id
1107+
userId
1108+
name
1109+
}
1110+
}
1111+
}
1112+
rating
1113+
}
1114+
}
1115+
`,
1116+
expectedCypherQuery = `
1117+
MATCH (\`user_from\`:\`User\` {userId: $from.userId})
1118+
MATCH (\`movie_to\`:\`Movie\`${ADDITIONAL_MOVIE_LABELS} {movieId: $to.movieId})
1119+
MATCH (\`user_from\`)-[\`rated_relation\`:\`RATED\`]->(\`movie_to\`)
1120+
SET \`rated_relation\` += {rating:$data.rating,location: point($data.location)}
1121+
RETURN \`rated_relation\` { to: \`movie_to\` {_id: ID(\`movie_to\`), .movieId , .title ,ratings: [(\`movie_to\`)<-[\`movie_to_ratings_relation\`:\`RATED\`]-(:\`User\`) | movie_to_ratings_relation { .rating ,User: head([(:\`Movie\`${ADDITIONAL_MOVIE_LABELS})<-[\`movie_to_ratings_relation\`]-(\`movie_to_ratings_User\`:\`User\`) | movie_to_ratings_User {_id: ID(\`movie_to_ratings_User\`), .userId , .name }]) }] } , .rating } AS \`_UpdateUserRatedPayload\`;
1122+
`;
1123+
1124+
t.plan(1);
1125+
return augmentedSchemaCypherTestRunner(
1126+
t,
1127+
graphQLQuery,
1128+
{
1129+
from: { userId: '123' },
1130+
to: { movieId: '2kljghd' },
1131+
data: {
1132+
rating: 1,
1133+
location: {
1134+
longitude: 3.0,
1135+
latitude: 4.5,
1136+
height: 12.5
1137+
}
1138+
},
1139+
first: -1,
1140+
offset: 0
1141+
},
1142+
expectedCypherQuery
1143+
);
1144+
});
1145+
10561146
test('Add reflexive relationship mutation with relationship property', t => {
10571147
const graphQLQuery = `mutation {
10581148
AddUserFriends(
@@ -1755,6 +1845,41 @@ test('Remove relationship mutation', t => {
17551845
);
17561846
});
17571847

1848+
test('Remove relationship mutation and query only outgoing nodes', t => {
1849+
const graphQLQuery = `mutation someMutation {
1850+
RemoveMovieGenres(
1851+
from: { movieId: "123" },
1852+
to: { name: "Action" }
1853+
) {
1854+
to {
1855+
_id
1856+
name
1857+
}
1858+
}
1859+
}`,
1860+
expectedCypherQuery = `
1861+
MATCH (\`movie_from\`:\`Movie\`${ADDITIONAL_MOVIE_LABELS} {movieId: $from.movieId})
1862+
MATCH (\`genre_to\`:\`Genre\` {name: $to.name})
1863+
OPTIONAL MATCH (\`movie_from\`)-[\`movie_fromgenre_to\`:\`IN_GENRE\`]->(\`genre_to\`)
1864+
DELETE \`movie_fromgenre_to\`
1865+
WITH COUNT(*) AS scope, \`movie_from\` AS \`_movie_from\`, \`genre_to\` AS \`_genre_to\`
1866+
RETURN {to: \`_genre_to\` {_id: ID(\`_genre_to\`), .name } } AS \`_RemoveMovieGenresPayload\`;
1867+
`;
1868+
1869+
t.plan(1);
1870+
return augmentedSchemaCypherTestRunner(
1871+
t,
1872+
graphQLQuery,
1873+
{
1874+
from: { movieId: '123' },
1875+
to: { name: 'Action' },
1876+
first: -1,
1877+
offset: 0
1878+
},
1879+
expectedCypherQuery
1880+
);
1881+
});
1882+
17581883
test('Remove reflexive relationship mutation', t => {
17591884
const graphQLQuery = `mutation {
17601885
RemoveUserFriends(

0 commit comments

Comments
 (0)