Skip to content

Commit f028ef8

Browse files
MetaurFylmTM
authored andcommitted
Fixed plan tab, added some docs (#27)
1 parent 8c7468c commit f028ef8

File tree

8 files changed

+72
-14
lines changed

8 files changed

+72
-14
lines changed

docs/SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
* [Canvas](console/graph/canvas.md)
1010
* [Table](console/table.md)
1111
* [Parameters](console/parameters.md)
12+
* [Plan](console/plan.md)
1213
* [Cypher](cypher/index.md)
1314
* [Syntax](cypher/syntax.md)
1415
* [Autocompletion](cypher/autocompletion.md)

docs/console/plan.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Console - Plan
2+
3+
When any `EXPLAIN` or `PROFILE` queries are executed, plugin creates a closeable tab in console, which contains the plan
4+
of query, rendered as tree table.
5+
6+
![EXPLAIN plan](../screenshots/explain_plan.png)
7+
8+
The plan tab consists of label with an executed query, tree table with plan and label with metadata.
9+
Note, that `PROFILE` plan table has more columns, because the query is actually executed.
10+
11+
![PROFILE plan](../screenshots/profile_plan.png)

docs/cypher/inspections.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,14 @@
22

33
### EXPLAIN warnings
44

5-
TODO
5+
Graph database plugin provides a functionality to automatically find any problems with your queries,
6+
using `EXPLAIN` queries. Then, all database notifications are displayed as warnings, highlighting problematic parts of
7+
query.
8+
9+
![explain warning screenshot](../screenshots/explain_warning.png)
10+
11+
Under the hood, IntelliJ platform launches inspection for a query without syntax errors, inspection prepends to the
12+
query an `EXPLAIN` keyword and executes it against the active data-source silently.
13+
After all results have been received, database notifications are displayed as warnings.
14+
15+
Inspection is enabled by default, but you can disable it at any time.

docs/screenshots/explain_plan.png

52 KB
Loading

docs/screenshots/explain_warning.png

33.8 KB
Loading

docs/screenshots/profile_plan.png

54.8 KB
Loading

ui/jetbrains/src/main/java/com/neueda/jetbrains/plugin/graphdb/jetbrains/ui/console/plan/ColumnDefinitions.java

Lines changed: 46 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
package com.neueda.jetbrains.plugin.graphdb.jetbrains.ui.console.plan;
22

3+
import com.intellij.openapi.util.text.StringUtil;
34
import com.intellij.ui.treeStructure.treetable.TreeTableModel;
45
import com.intellij.util.ui.ColumnInfo;
56
import com.neueda.jetbrains.plugin.graphdb.database.api.query.GraphQueryPlan;
7+
import org.jetbrains.annotations.NonNls;
68
import org.jetbrains.annotations.NotNull;
79
import org.jetbrains.annotations.Nullable;
810

911
import javax.swing.tree.DefaultMutableTreeNode;
12+
import java.text.DecimalFormat;
13+
import java.text.NumberFormat;
1014
import java.util.Map;
1115
import java.util.Set;
1216
import java.util.stream.Stream;
@@ -19,23 +23,25 @@ class ColumnDefinitions {
1923
static ColumnInfo[] getQueryPlanColumns() {
2024
return new ColumnInfo[]{
2125
OPERATOR_COL,
22-
ESTIMATED_ROWS_COL,
2326
ARGUMENTS_COL,
27+
ESTIMATED_ROWS_COL,
2428
IDENTIFIERS_COL
2529
};
2630
}
2731

2832
static ColumnInfo[] getProfileQueryPlanColumns() {
2933
return new ColumnInfo[]{
3034
OPERATOR_COL,
35+
ARGUMENTS_COL,
3136
ROWS_COL,
3237
DB_HITS_COL,
3338
ESTIMATED_ROWS_COL,
34-
ARGUMENTS_COL,
3539
IDENTIFIERS_COL
3640
};
3741
}
3842

43+
private static final NumberFormat FORMATTER = new DecimalFormat("#0.00");
44+
3945
private static final Set<String> RESERVED_KEYS = Stream.of(QueryPlanArgumentKeys.values())
4046
.map(QueryPlanArgumentKeys::getKey)
4147
.collect(toSet());
@@ -52,16 +58,22 @@ public Class<?> getColumnClass() {
5258
public String valueOf(DefaultMutableTreeNode o) {
5359
return ((GraphQueryPlan) o.getUserObject()).getOperatorType();
5460
}
61+
62+
@Override
63+
@NonNls
64+
public String getPreferredStringValue() {
65+
return StringUtil.repeatSymbol('m', 25);
66+
}
5567
};
5668

5769
private static final ColumnInfo<DefaultMutableTreeNode, String> ESTIMATED_ROWS_COL =
58-
getArgumentColumn("Estimated rows", ESTIMATED_ROWS.getKey(), "0");
70+
getArgumentColumn("Estimated rows", ESTIMATED_ROWS.getKey());
5971

6072
private static final ColumnInfo<DefaultMutableTreeNode, String> DB_HITS_COL =
61-
getArgumentColumn("DB Hits", DB_HITS.getKey(), "0");
73+
getArgumentColumn("DB Hits", DB_HITS.getKey());
6274

6375
private static final ColumnInfo<DefaultMutableTreeNode, String> ROWS_COL =
64-
getArgumentColumn("Rows", ROWS.getKey(), "0");
76+
getArgumentColumn("Rows", ROWS.getKey());
6577

6678
private static final ColumnInfo<DefaultMutableTreeNode, String> ARGUMENTS_COL =
6779
new ColumnInfo<DefaultMutableTreeNode, String>("Arguments") {
@@ -74,6 +86,12 @@ public String valueOf(DefaultMutableTreeNode o) {
7486
.map(Object::toString)
7587
.collect(joining(", "));
7688
}
89+
90+
@Override
91+
@NonNls
92+
public String getPreferredStringValue() {
93+
return StringUtil.repeatSymbol('m', 15);
94+
}
7795
};
7896

7997
private static final ColumnInfo<DefaultMutableTreeNode, String> IDENTIFIERS_COL =
@@ -84,21 +102,38 @@ public String valueOf(DefaultMutableTreeNode o) {
84102
return ((GraphQueryPlan) o.getUserObject()).getIdentifiers().stream()
85103
.collect(joining(", "));
86104
}
105+
106+
@Override
107+
@NonNls
108+
public String getPreferredStringValue() {
109+
return StringUtil.repeatSymbol('m', 12);
110+
}
87111
};
88112

89113
@NotNull
90-
private static <T> ColumnInfo<DefaultMutableTreeNode, T> getArgumentColumn(String title, String argumentKey,
91-
T defaultValue) {
92-
return new ColumnInfo<DefaultMutableTreeNode, T>(title) {
114+
private static ColumnInfo<DefaultMutableTreeNode, String> getArgumentColumn(String title, String argumentKey) {
115+
return new ColumnInfo<DefaultMutableTreeNode, String>(title) {
93116
@Nullable
94117
@Override
95-
public T valueOf(DefaultMutableTreeNode o) {
118+
public String valueOf(DefaultMutableTreeNode o) {
96119
return ((GraphQueryPlan) o.getUserObject()).getArguments().entrySet().stream()
97120
.filter(e -> e.getKey().equalsIgnoreCase(argumentKey))
98121
.map(Map.Entry::getValue)
99122
.findFirst()
100-
.map(a -> (T) a)
101-
.orElse(defaultValue);
123+
.map(val -> {
124+
if (val instanceof Double) {
125+
return FORMATTER.format(val);
126+
}
127+
128+
return val.toString();
129+
})
130+
.orElse("0");
131+
}
132+
133+
@Override
134+
@NonNls
135+
public String getPreferredStringValue() {
136+
return StringUtil.repeatSymbol('m', 5);
102137
}
103138
};
104139
}

ui/jetbrains/src/main/java/com/neueda/jetbrains/plugin/graphdb/jetbrains/ui/console/plan/QueryPlanPanel.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,10 @@ public void initialize(Container container) {
5656
ListTreeTableModelOnColumns model = createModel(graphQueryPlan, result.isProfilePlan());
5757

5858
treeTable = new TreeTableView(model);
59-
treeTable.setAutoResizeMode(JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS);
6059
treeTable.setAutoCreateColumnsFromModel(true);
6160
treeTable.setRootVisible(true);
6261
treeTable.setCellSelectionEnabled(false);
62+
treeTable.setAutoResizeMode(TreeTableView.AUTO_RESIZE_OFF);
6363

6464
treeTable.getTree().setShowsRootHandles(true);
6565

@@ -72,7 +72,8 @@ public void initialize(Container container) {
7272

7373
container.add(new JBScrollPane(queryLabel), BorderLayout.NORTH);
7474
// scroll pane is needed to correctly fit all the tree content and to show table header
75-
container.add(new JBScrollPane(treeTable), BorderLayout.CENTER);
75+
container.add(new JBScrollPane(treeTable, JBScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
76+
JBScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER);
7677
container.add(infoLabel, BorderLayout.SOUTH);
7778
}
7879

0 commit comments

Comments
 (0)