Skip to content

Commit efdec80

Browse files
VoragoFylmTM
authored andcommitted
File context menu (#43)
* File context menu * Checkstyle fix * Review fixes
1 parent 01914bd commit efdec80

File tree

11 files changed

+376
-12
lines changed

11 files changed

+376
-12
lines changed

database/api/src/main/java/com/neueda/jetbrains/plugin/graphdb/database/api/GraphDatabaseApi.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,14 @@
22

33
import com.neueda.jetbrains.plugin.graphdb.database.api.query.GraphQueryResult;
44

5+
import java.util.List;
56
import java.util.Map;
67

78
public interface GraphDatabaseApi {
89

910
GraphQueryResult execute(String query);
1011

1112
GraphQueryResult execute(String query, Map<String, Object> statementParameters);
13+
14+
GraphQueryResult executeBatch(List<String> query, Map<String, Object> statementParameters);
1215
}

database/neo4j/src/main/java/com/neueda/jetbrains/plugin/graphdb/database/neo4j/bolt/Neo4jBoltDatabase.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import org.neo4j.driver.v1.StatementResult;
1313

1414
import java.util.Collections;
15+
import java.util.List;
1516
import java.util.Map;
1617

1718
/**
@@ -47,7 +48,7 @@ public GraphQueryResult execute(String query) {
4748
@Override
4849
public GraphQueryResult execute(String query, Map<String, Object> statementParameters) {
4950
try (Driver driver = GraphDatabase.driver(url, auth);
50-
Session session = driver.session()) {
51+
Session session = driver.session()) {
5152

5253
Neo4jBoltBuffer buffer = new Neo4jBoltBuffer();
5354

@@ -65,4 +66,21 @@ public GraphQueryResult execute(String query, Map<String, Object> statementParam
6566
return new Neo4jBoltQueryResult(endTime - startTime, buffer);
6667
}
6768
}
69+
70+
@Override
71+
public GraphQueryResult executeBatch(List<String> queries, Map<String, Object> statementParameters) {
72+
try (Driver driver = GraphDatabase.driver(url, auth);
73+
Session session = driver.session()) {
74+
75+
Neo4jBoltBuffer buffer = new Neo4jBoltBuffer();
76+
77+
long startTime = System.currentTimeMillis();
78+
for (String query : queries) {
79+
session.run(query, statementParameters).consume();
80+
}
81+
long endTime = System.currentTimeMillis();
82+
83+
return new Neo4jBoltQueryResult(endTime - startTime, buffer);
84+
}
85+
}
6886
}

graph-database-support-plugin/src/main/resources/META-INF/plugin.xml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,5 +215,16 @@
215215
description="Clean canvas">
216216
</action>
217217
</group>
218+
219+
<group id="GraphDatabaseFileActions"
220+
text="Graph Database File Actions" description="Graph Database File Actions"
221+
icon="/graphdb/icons/window/graph_13x13.png" popup="true">
222+
<action id="GraphDatabaseFileActions.ExecuteAll"
223+
class="com.neueda.jetbrains.plugin.graphdb.jetbrains.actions.execute.ExecuteAllAction"
224+
text="Execute All"
225+
icon="/general/run.png">
226+
</action>
227+
<add-to-group group-id="ProjectViewPopupMenu"/>
228+
</group>
218229
</actions>
219230
</idea-plugin>

testing/integration-neo4j/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ dependencies {
99
testCompile project(':testing:database:neo4j-common')
1010
testCompile 'org.xeustechnologies:jcl-core:2.8'
1111
testCompile "org.assertj:assertj-core:$versionAssertj"
12+
testCompile "org.mockito:mockito-core:$versionMockito"
1213
}
1314

1415
test {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
package com.neueda.jetbrains.plugin.graphdb.test.integration.neo4j.tests.jetbrains;
2+
3+
import com.intellij.psi.PsiFile;
4+
import com.intellij.util.messages.MessageBus;
5+
import com.neueda.jetbrains.plugin.graphdb.jetbrains.actions.execute.StatementCollector;
6+
import com.neueda.jetbrains.plugin.graphdb.jetbrains.ui.console.event.QueryParametersRetrievalErrorEvent;
7+
import com.neueda.jetbrains.plugin.graphdb.jetbrains.ui.console.params.ParametersService;
8+
import com.neueda.jetbrains.plugin.graphdb.test.integration.neo4j.tests.cypher.util.BaseGenericTest;
9+
import org.mockito.Mockito;
10+
11+
import static org.assertj.core.api.Assertions.*;
12+
import static org.mockito.Mockito.*;
13+
14+
public class StatementCollectorTest extends BaseGenericTest {
15+
16+
private static final String EMPTY_PARAMETERS = "{}";
17+
private static final String PARAMETERS = "{\"name\": \"Andrew\"}";
18+
private static final String WRONG_PARAMETERS = "{wrong json}";
19+
private StatementCollector statementCollector;
20+
private ParametersService parametersService;
21+
private MessageBus messageBusMock;
22+
private QueryParametersRetrievalErrorEvent eventMock;
23+
24+
@Override
25+
public void setUp() throws Exception {
26+
super.setUp();
27+
messageBusMock = Mockito.mock(MessageBus.class);
28+
eventMock = Mockito.mock(QueryParametersRetrievalErrorEvent.class);
29+
when(messageBusMock.syncPublisher(any())).thenReturn(eventMock);
30+
31+
parametersService = new ParametersService();
32+
statementCollector = new StatementCollector(messageBusMock, parametersService);
33+
}
34+
35+
public void testSingleQuery() {
36+
parametersService.registerParametersProvider(() -> EMPTY_PARAMETERS);
37+
PsiFile psiFile = myFixture.configureByText("test.cyp", "MATCH (n) RETURN n;");
38+
psiFile.accept(statementCollector);
39+
40+
verify(eventMock, times(0)).handleError(any(), any());
41+
42+
assertThat(statementCollector.hasErrors())
43+
.isFalse();
44+
assertThat(statementCollector.getParameters())
45+
.isEmpty();
46+
assertThat(statementCollector.getQueries())
47+
.containsExactly("MATCH (n) RETURN n;");
48+
}
49+
50+
public void testMultipleQueriesInOneLine() {
51+
parametersService.registerParametersProvider(() -> EMPTY_PARAMETERS);
52+
PsiFile psiFile = myFixture.configureByText("test.cyp", "MATCH (n) RETURN n;MATCH (m) RETURN m;");
53+
psiFile.acceptChildren(statementCollector);
54+
55+
verify(eventMock, times(0)).handleError(any(), any());
56+
57+
assertThat(statementCollector.hasErrors())
58+
.isFalse();
59+
assertThat(statementCollector.getParameters())
60+
.isEmpty();
61+
assertThat(statementCollector.getQueries())
62+
.containsExactly("MATCH (n) RETURN n;", "MATCH (m) RETURN m;");
63+
}
64+
65+
public void testOneQueryWithError() {
66+
parametersService.registerParametersProvider(() -> EMPTY_PARAMETERS);
67+
PsiFile psiFile = myFixture.configureByText("test.cyp", "MATCH () ETURN n;");
68+
psiFile.accept(statementCollector);
69+
70+
verify(eventMock, times(0)).handleError(any(), any());
71+
72+
assertThat(statementCollector.hasErrors())
73+
.isTrue();
74+
assertThat(statementCollector.getParameters())
75+
.isEmpty();
76+
assertThat(statementCollector.getQueries())
77+
.isEmpty();
78+
}
79+
80+
public void testMultipleQueriesInDifferentLinesWithError() {
81+
parametersService.registerParametersProvider(() -> EMPTY_PARAMETERS);
82+
PsiFile psiFile = myFixture.configureByText("test.cyp", "MATCH (n) RETURN *;\nMATCH () ETURN n;");
83+
psiFile.accept(statementCollector);
84+
85+
verify(eventMock, times(0)).handleError(any(), any());
86+
87+
assertThat(statementCollector.hasErrors())
88+
.isTrue();
89+
assertThat(statementCollector.getParameters())
90+
.isEmpty();
91+
assertThat(statementCollector.getQueries())
92+
.isEmpty();
93+
}
94+
95+
public void testMultipleCorrectQueriesInDifferentLines() {
96+
parametersService.registerParametersProvider(() -> EMPTY_PARAMETERS);
97+
PsiFile psiFile = myFixture.configureByText("test.cyp", "MATCH (n) RETURN *;\nMATCH (m) RETURN m;");
98+
psiFile.accept(statementCollector);
99+
100+
verify(eventMock, times(0)).handleError(any(), any());
101+
102+
assertThat(statementCollector.hasErrors())
103+
.isFalse();
104+
assertThat(statementCollector.getParameters())
105+
.isEmpty();
106+
assertThat(statementCollector.getQueries())
107+
.containsExactly("MATCH (n) RETURN *;", "MATCH (m) RETURN m;");
108+
}
109+
110+
public void testMultipleCorrectQueriesInDifferentLinesWithParameters() {
111+
parametersService.registerParametersProvider(() -> PARAMETERS);
112+
PsiFile psiFile = myFixture.configureByText("test.cyp", "CREATE (n {name: $name});\nMATCH (m) RETURN m;");
113+
psiFile.accept(statementCollector);
114+
115+
verify(eventMock, times(0)).handleError(any(), any());
116+
117+
assertThat(statementCollector.hasErrors())
118+
.isFalse();
119+
assertThat(statementCollector.getParameters())
120+
.containsValues("Andrew");
121+
assertThat(statementCollector.getQueries())
122+
.containsExactly("CREATE (n {name: $name});", "MATCH (m) RETURN m;");
123+
}
124+
125+
public void testParameterExtractionErrorOccurs() {
126+
parametersService.registerParametersProvider(() -> WRONG_PARAMETERS);
127+
PsiFile psiFile = myFixture.configureByText("test.cyp", "CREATE (n {name: $name});\nMATCH (m) RETURN m;");
128+
psiFile.accept(statementCollector);
129+
130+
verify(eventMock, times(1)).handleError(any(), any());
131+
132+
assertThat(statementCollector.hasErrors())
133+
.isTrue();
134+
assertThat(statementCollector.getParameters())
135+
.isEmpty();
136+
assertThat(statementCollector.getQueries())
137+
.isEmpty();
138+
}
139+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package com.neueda.jetbrains.plugin.graphdb.jetbrains.actions.execute;
2+
3+
import com.intellij.openapi.actionSystem.AnAction;
4+
import com.intellij.openapi.actionSystem.AnActionEvent;
5+
import com.intellij.openapi.actionSystem.CommonDataKeys;
6+
import com.intellij.openapi.actionSystem.PlatformDataKeys;
7+
import com.intellij.openapi.components.ServiceManager;
8+
import com.intellij.openapi.project.Project;
9+
import com.intellij.openapi.ui.popup.JBPopupFactory;
10+
import com.intellij.openapi.ui.popup.ListPopup;
11+
import com.intellij.psi.PsiFile;
12+
import com.intellij.util.messages.MessageBus;
13+
import com.neueda.jetbrains.plugin.graphdb.jetbrains.component.datasource.DataSourcesComponent;
14+
import com.neueda.jetbrains.plugin.graphdb.jetbrains.ui.console.ConsoleToolWindow;
15+
import com.neueda.jetbrains.plugin.graphdb.jetbrains.ui.console.params.ParametersService;
16+
import com.neueda.jetbrains.plugin.graphdb.jetbrains.util.Notifier;
17+
import com.neueda.jetbrains.plugin.graphdb.language.cypher.file.CypherFileType;
18+
19+
public class ExecuteAllAction extends AnAction {
20+
@Override
21+
public void update(AnActionEvent e) {
22+
if (e.getDataContext().getData(PlatformDataKeys.PSI_FILE).getFileType() instanceof CypherFileType) {
23+
e.getPresentation().setEnabled(true);
24+
} else {
25+
e.getPresentation().setEnabled(false);
26+
}
27+
}
28+
@Override
29+
public void actionPerformed(AnActionEvent e) {
30+
Project project = getEventProject(e);
31+
MessageBus messageBus = project.getMessageBus();
32+
ParametersService parameterService = ServiceManager.getService(project, ParametersService.class);
33+
PsiFile psiFile = e.getData(CommonDataKeys.PSI_FILE);
34+
35+
StatementCollector statementCollector = new StatementCollector(messageBus, parameterService);
36+
psiFile.acceptChildren(statementCollector);
37+
if (!statementCollector.hasErrors()) {
38+
ExecuteQueryPayload executeQueryPayload =
39+
new ExecuteQueryPayload(statementCollector.getQueries(), statementCollector.getParameters(), psiFile.getName());
40+
ConsoleToolWindow.ensureOpen(project);
41+
42+
DataSourcesComponent dataSourcesComponent = project.getComponent(DataSourcesComponent.class);
43+
ListPopup popup = JBPopupFactory.getInstance().createActionGroupPopup(
44+
"Choose Data Source",
45+
new ChooseDataSourceActionGroup(messageBus, dataSourcesComponent, executeQueryPayload),
46+
e.getDataContext(),
47+
JBPopupFactory.ActionSelectionAid.SPEEDSEARCH,
48+
false
49+
);
50+
popup.showInBestPositionFor(e.getDataContext());
51+
} else {
52+
System.out.println("NOTIFY");
53+
Notifier.error("Query execution error", "File contains errors");
54+
}
55+
}
56+
}

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

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,32 +4,48 @@
44
import org.jetbrains.annotations.NotNull;
55

66
import java.util.Collections;
7+
import java.util.List;
78
import java.util.Map;
89
import java.util.Optional;
910

1011
public class ExecuteQueryPayload {
1112

12-
private final String content;
13+
private final List<String> queries;
1314

1415
private final Map<String, Object> parameters;
1516

1617
private final Editor editor;
1718

19+
private final String fileName;
20+
1821
public ExecuteQueryPayload(String content) {
19-
this.content = content;
22+
this.queries = Collections.singletonList(content);
2023
this.editor = null;
2124
this.parameters = Collections.emptyMap();
25+
this.fileName = null;
26+
}
27+
28+
public ExecuteQueryPayload(List<String> queries, Map<String, Object> parameters, String fileName) {
29+
this.queries = queries;
30+
this.parameters = parameters;
31+
this.editor = null;
32+
this.fileName = fileName;
2233
}
2334

2435
public ExecuteQueryPayload(String content, Map<String, Object> parameters, Editor editor) {
25-
this.content = content;
36+
this.queries = Collections.singletonList(content);
2637
this.parameters = parameters;
2738
this.editor = editor;
39+
this.fileName = null;
2840
}
2941

3042
@NotNull
31-
public String getContent() {
32-
return content;
43+
public List<String> getQueries() {
44+
return queries;
45+
}
46+
47+
public Optional<String> getFileName() {
48+
return Optional.ofNullable(fileName);
3349
}
3450

3551
public Map<String, Object> getParameters() {

0 commit comments

Comments
 (0)