Skip to content

Commit 72bb53b

Browse files
committed
find query parameters in PsiTree
1 parent 04c320c commit 72bb53b

File tree

4 files changed

+73
-82
lines changed

4 files changed

+73
-82
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
1-
package com.neueda.jetbrains.plugin.graphdb.jetbrains.ui.console.params;
1+
package com.neueda.jetbrains.plugin.graphdb.test.integration.neo4j.tests.cypher.parameters;
22

3-
import com.fasterxml.jackson.databind.JsonMappingException;
4-
import org.junit.Before;
5-
import org.junit.Test;
3+
import com.intellij.psi.PsiElement;
4+
import com.neueda.jetbrains.plugin.graphdb.jetbrains.ui.console.params.ParametersProvider;
5+
import com.neueda.jetbrains.plugin.graphdb.jetbrains.ui.console.params.ParametersService;
6+
import com.neueda.jetbrains.plugin.graphdb.test.integration.neo4j.util.base.BaseIntegrationTest;
67

78
import java.util.Map;
9+
import java.util.Optional;
810

911
import static org.assertj.core.api.Assertions.*;
1012

11-
public class ParametersServiceTest {
13+
public class CypherParametersProviderTest extends BaseIntegrationTest {
1214

1315
private class TestParametersProvider implements ParametersProvider {
1416

15-
String parametersJson;
17+
private String parametersJson;
1618

1719
@Override
1820
public String getParametersJson() {
@@ -24,127 +26,95 @@ public void setParametersJson(String parametersJson) {
2426
}
2527
}
2628

27-
private ParametersService parametersService = new ParametersService();
29+
private ParametersService parametersService;
2830
private TestParametersProvider parametersProvider = new TestParametersProvider();
2931

30-
@Before
31-
public void setup() {
32-
parametersService.registerParametersProvider(parametersProvider);
32+
@Override
33+
public void setUp() throws Exception {
34+
super.setUp();
35+
36+
parametersService = new ParametersService();
37+
38+
if (!parametersService.isParametersProviderRegistered()) {
39+
parametersService.registerParametersProvider(parametersProvider);
40+
}
3341
}
3442

35-
@Test
3643
public void testParsingEmptyJsonObject() throws Exception {
3744
parametersProvider.setParametersJson("{}");
38-
Map<String, Object> result = parametersService
39-
.getParameters("match (p:Person) return p;");
45+
Map<String, Object> parameters = parametersService.getParameters(getPsiFile("RETURN $param"));
4046

41-
assertThat(result.isEmpty()).isTrue();
47+
assertThat(parameters).isEmpty();
4248
}
4349

44-
@Test
4550
public void testParsingEmptyParameters() throws Exception {
4651
parametersProvider.setParametersJson("");
47-
Map<String, Object> result = parametersService.getParameters();
52+
Map<String, Object> result = parametersService.getParameters(getPsiFile("RETURN $param"));
4853

4954
assertThat(result.isEmpty()).isTrue();
5055
}
5156

52-
@Test
5357
public void testParsingStringParameter() throws Exception {
5458
parametersProvider.setParametersJson("{\"name\": \"Anna\"}");
5559
Map<String, Object> result = parametersService
56-
.getParameters("match (p:Person) where p.name = $name return *");
60+
.getParameters(getPsiFile("match (p:Person) where p.name = $name return *"));
5761

58-
assertThat(result.keySet().contains("name")).isTrue();
59-
assertThat(result.values().contains("Anna")).isTrue();
62+
assertThat(result.keySet().contains("name"));
63+
assertThat(result.values().contains("Anna"));
6064
}
6165

62-
@Test
6366
public void testParsingIntegerParameter() throws Exception {
6467
parametersProvider.setParametersJson("{\"p1\": 17}");
6568
Map<String, Object> result = parametersService
66-
.getParameters("match (p:Person) where p.age = $p1 return *");
69+
.getParameters(getPsiFile("match (p:Person) where p.age = $p1 return *"));
6770

6871
assertThat(result.get("p1").toString()).isEqualTo("17");
6972
}
7073

71-
@Test
7274
public void testParsingBooleanParameter() throws Exception {
7375
parametersProvider.setParametersJson("{\"p2\": false}");
7476
Map<String, Object> result = parametersService.
75-
getParameters("match (p:Person) where p.is_citizen = $p2 return *");
77+
getParameters(getPsiFile("match (p:Person) where p.is_citizen = $p2 return *"));
7678

7779
assertThat(result.get("p2").toString()).isEqualTo("false");
7880
}
7981

80-
@Test
8182
public void testParsingJsonObjectParameter() throws Exception {
8283
parametersProvider.setParametersJson("{\"p3\": {\"name\":\"Alex\"}}");
8384
Map<String, Object> result = parametersService.
84-
getParameters("match (p:Person) where p.father = $p3 return *");
85+
getParameters(getPsiFile("match (p:Person) where p.father = $p3 return *"));
8586

8687
Map<String, Object> jsonVal = (Map<String, Object>) result.get("p3");
8788
assertThat(jsonVal).containsKey("name");
8889
assertThat(jsonVal).containsValue("Alex");
8990
}
9091

91-
@Test
9292
public void testParsingMultipleParameters() throws Exception {
9393
parametersProvider.setParametersJson("{\"firstName\": \"Kaleb\", \"lastName\": \"Johnson\"}");
9494
Map<String, Object> result = parametersService
95-
.getParameters("match (p:Person)\n" +
95+
.getParameters(getPsiFile("match (p:Person)\n" +
9696
"where p.first_name = $firstName " +
97-
" and p.last_name = $lastName return *");
97+
" and p.last_name = $lastName return *"));
9898

9999
assertThat(result.get("firstName").toString()).isEqualTo("Kaleb");
100100
assertThat(result.get("lastName").toString()).isEqualTo("Johnson");
101101
}
102102

103-
@Test
104103
public void testParsingCommentOnly() throws Exception {
105104
parametersProvider.setParametersJson("// Provide query parameters in JSON format here:");
106-
Map<String, Object> result = parametersService.getParameters();
105+
Map<String, Object> result = parametersService.getParameters(getPsiFile("RETURN $param"));
107106

108107
assertThat(result.isEmpty()).isTrue();
109108
}
110109

111-
112-
@Test
113110
public void testParsingCommentWithParameter() throws Exception {
114111
parametersProvider.setParametersJson("// Provide query parameters in JSON format here:\n{\"name\": \"Eva\"}");
115-
Map<String, Object> result = parametersService.getParameters();
112+
Map<String, Object> result = parametersService.getParameters(getPsiFile("RETURN $name"));
116113

117114
assertThat(result.size() == 1).isTrue();
118115
}
119116

120-
@Test(expected = Exception.class)
121-
public void testParsingJsonArray() throws Exception {
122-
parametersProvider.setParametersJson("// Provide query parameters in JSON format here:\n[\"item1\",\"item2\"]");
123-
parametersService.getParameters();
124-
}
125-
126-
@Test(expected = JsonMappingException.class)
127-
public void testParsingNumber() throws Exception {
128-
parametersProvider.setParametersJson("1");
129-
parametersService.getParameters();
117+
private Optional<PsiElement> getPsiFile(String queryText) {
118+
return Optional.of(myFixture.configureByText("test.cypher", queryText));
130119
}
131-
132-
@Test(expected = JsonMappingException.class)
133-
public void testParsingString() throws Exception {
134-
parametersProvider.setParametersJson("\"abc\"");
135-
parametersService.getParameters();
136-
}
137-
138-
@Test(expected = JsonMappingException.class)
139-
public void testParsingUnwrappedParameter() throws Exception {
140-
parametersProvider.setParametersJson("\"param1\":\"val1\"");
141-
parametersService.getParameters();
142-
}
143-
144-
@Test(expected = Exception.class)
145-
public void testParsingParamWithObjAccessor() throws Exception {
146-
parametersProvider.setParametersJson("{\"param1\": person[\"name\"]}");
147-
parametersService.getParameters();
148-
}
149-
150120
}

ui/jetbrains/src/main/java/com/neueda/jetbrains/plugin/graphdb/jetbrains/actions/execute/ExecuteQueryAction.java

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,17 +68,20 @@ public void actionPerformed(AnActionEvent e) {
6868
Caret caret = editor.getCaretModel().getPrimaryCaret();
6969

7070
String content = null;
71+
Optional<PsiElement> cypherStatement = Optional.empty();
7172
if (caret.hasSelection()) {
7273
content = caret.getSelectedText();
7374
} else if (psiFile != null) {
7475
if (psiFile.getLanguage().getID().equals(GraphLanguages.CYPHER)) {
75-
String cypherStatement = getCypherStatement(psiFile, caret);
76-
if (cypherStatement != null) {
77-
content = cypherStatement;
76+
cypherStatement = getCypherStatement(psiFile, caret);
77+
if (cypherStatement.isPresent()) {
78+
content = cypherStatement.get().getText();
7879
}
7980
}
8081
}
8182

83+
Analytics.event("query-content", caret.hasSelection() ? "contentFromSelect" : "contentFromCaret");
84+
8285
if (content == null) {
8386
Notifier.error("Query execution error", "No query selected");
8487
return;
@@ -87,7 +90,7 @@ public void actionPerformed(AnActionEvent e) {
8790
Map<String, Object> parameters;
8891
try {
8992
ParametersService service = ServiceManager.getService(project, ParametersService.class);
90-
parameters = service.getParameters(content);
93+
parameters = service.getParameters(cypherStatement); // support parameters for PsiElement only
9194
} catch (Exception exception) {
9295
sendParametersRetrievalErrorEvent(messageBus, exception, editor);
9396
return;
@@ -129,13 +132,13 @@ public void executeQuery(MessageBus messageBus, DataSourceApi dataSource, Execut
129132
executeQueryEvent.executeQuery(dataSource, payload);
130133
}
131134

132-
private String getCypherStatement(PsiFile psiFile, Caret caret) {
135+
private Optional<PsiElement> getCypherStatement(PsiFile psiFile, Caret caret) {
133136
PsiElement element = PsiTraversalUtilities.Cypher.getCypherStatementAtOffset(psiFile, caret.getOffset());
134137

135138
if (element == null) {
136-
return null;
139+
return Optional.empty();
137140
} else {
138-
return element.getText();
141+
return Optional.of(element);
139142
}
140143
}
141144

ui/jetbrains/src/main/java/com/neueda/jetbrains/plugin/graphdb/jetbrains/ui/console/params/ParametersPanel.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package com.neueda.jetbrains.plugin.graphdb.jetbrains.ui.console.params;
22

3-
import com.fasterxml.jackson.core.JsonParseException;
43
import com.intellij.codeInsight.hint.HintManager;
54
import com.intellij.json.JsonFileType;
65
import com.intellij.openapi.application.ApplicationManager;
@@ -40,7 +39,7 @@ public void initialize(GraphConsoleView graphConsoleView, Project project) {
4039
messageBus.connect().subscribe(QueryParametersRetrievalErrorEvent.QUERY_PARAMETERS_RETRIEVAL_ERROR_EVENT_TOPIC,
4140
(exception, editor) -> {
4241
String errorMessage;
43-
if (exception instanceof JsonParseException && exception.getMessage() != null) {
42+
if (exception.getMessage() != null) {
4443
errorMessage = String.format("%s: %s", PARAMS_ERROR_COMMON_MSG, exception.getMessage());
4544
} else {
4645
errorMessage = PARAMS_ERROR_COMMON_MSG;

ui/jetbrains/src/main/java/com/neueda/jetbrains/plugin/graphdb/jetbrains/ui/console/params/ParametersService.java

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,16 @@
66
import com.fasterxml.jackson.databind.JsonNode;
77
import com.fasterxml.jackson.databind.ObjectMapper;
88
import com.google.common.base.Throwables;
9+
import com.intellij.psi.PsiElement;
10+
import com.neueda.jetbrains.plugin.graphdb.language.cypher.psi.CypherTypes;
11+
import com.neueda.jetbrains.plugin.graphdb.language.cypher.util.TraverseUtil;
912
import org.apache.commons.lang.StringUtils;
1013

1114
import java.util.Collections;
1215
import java.util.List;
1316
import java.util.Map;
17+
import java.util.Optional;
1418
import java.util.stream.Collectors;
15-
import java.util.stream.Stream;
1619

1720
public class ParametersService {
1821

@@ -27,26 +30,33 @@ public class ParametersService {
2730

2831
private ParametersProvider parametersProvider;
2932

33+
public boolean isParametersProviderRegistered() {
34+
return parametersProvider != null;
35+
}
36+
3037
public void registerParametersProvider(final ParametersProvider parametersProvider) {
31-
if (this.parametersProvider != null) {
38+
if (isParametersProviderRegistered()) {
3239
throw new IllegalStateException("Parameters provider already registered");
3340
}
3441
this.parametersProvider = parametersProvider;
3542
}
3643

37-
public Map<String, Object> getParameters(String queryContent) throws Exception {
44+
public Map<String, Object> getParameters(Optional<PsiElement> query) throws Exception {
45+
if (!query.isPresent()) {
46+
return Collections.emptyMap();
47+
}
3848
if (!isValidParametersMap(parametersProvider.getParametersJson())) {
3949
return Collections.emptyMap();
4050
}
4151

4252
Map<String, Object> allParameters = MAPPER
4353
.readValue(parametersProvider.getParametersJson(), new TypeReference<Map<String, Object>>() { });
4454

45-
return extractQueryParameters(queryContent, allParameters);
55+
return extractQueryParameters(query.get(), allParameters);
4656
}
4757

48-
private Map<String, Object> extractQueryParameters(String query, Map<String, Object> allParameters) {
49-
if (StringUtils.isBlank(query)) {
58+
private Map<String, Object> extractQueryParameters(PsiElement query, Map<String, Object> allParameters) {
59+
if (query == null) {
5060
return Collections.emptyMap();
5161
}
5262

@@ -60,11 +70,20 @@ private Map<String, Object> extractQueryParameters(String query, Map<String, Obj
6070
.collect(Collectors.toMap(p -> p.getKey(), p -> p.getValue()));
6171
}
6272

63-
private List<String> extractParameterNames(String query) {
64-
return Stream.of(query.split("\\s")) // split by whitespace character
65-
.filter(w -> w.startsWith("$"))
66-
.map(w -> w.substring(1))
73+
private List<String> extractParameterNames(PsiElement query) {
74+
List<PsiElement> parameterElements = TraverseUtil.collectPsiElementsByType(query, CypherTypes.PARAMETER);
75+
return parameterElements.stream()
76+
.map(elem -> extractParameterName(elem.getText()))
77+
.distinct()
6778
.collect(Collectors.toList());
79+
80+
}
81+
82+
/**
83+
* Extract name from parameter labels like $param, {param}, {0}, $0
84+
*/
85+
private static String extractParameterName(String parameterLabel) {
86+
return parameterLabel.startsWith("$") ? parameterLabel.substring(1) : parameterLabel.substring(1, parameterLabel.length() - 1);
6887
}
6988

7089
private static boolean isValidParametersMap(String parametersJson) {

0 commit comments

Comments
 (0)