Skip to content

Commit 77412f7

Browse files
VoragoFylmTM
authored andcommitted
Count labels and relationship types (#35)
* Count labels and relationship types * Count each label and rel type * Fixes
1 parent c5359d9 commit 77412f7

File tree

13 files changed

+254
-68
lines changed

13 files changed

+254
-68
lines changed

ui/jetbrains/src/main/java/com/neueda/jetbrains/plugin/graphdb/jetbrains/component/datasource/metadata/DataSourcesComponentMetadata.java

Lines changed: 60 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import com.intellij.util.messages.MessageBus;
77
import com.neueda.jetbrains.plugin.graphdb.database.api.GraphDatabaseApi;
88
import com.neueda.jetbrains.plugin.graphdb.database.api.query.GraphQueryResult;
9+
import com.neueda.jetbrains.plugin.graphdb.database.api.query.GraphQueryResultColumn;
910
import com.neueda.jetbrains.plugin.graphdb.jetbrains.component.datasource.state.DataSourceApi;
1011
import com.neueda.jetbrains.plugin.graphdb.jetbrains.database.DatabaseManagerService;
1112
import com.neueda.jetbrains.plugin.graphdb.jetbrains.ui.datasource.metadata.MetadataRetrieveEvent;
@@ -16,6 +17,7 @@
1617
import java.util.List;
1718
import java.util.Map;
1819
import java.util.Optional;
20+
import java.util.stream.Collectors;
1921

2022
public class DataSourcesComponentMetadata implements ProjectComponent {
2123

@@ -37,7 +39,7 @@ public Optional<DataSourceMetadata> getMetadata(DataSourceApi dataSource) {
3739
case NEO4J_BOLT:
3840
try {
3941
DataSourceMetadata metadata = getNeo4jBoltMetadata(dataSource);
40-
updateNeo4jBoltMetadata(dataSource, metadata);
42+
updateNeo4jBoltMetadata(dataSource, (Neo4jBoltCypherDataSourceMetadata) metadata);
4143
metadataRetrieveEvent.metadataRefreshSucceed(dataSource);
4244
return Optional.of(metadata);
4345
} catch (Exception exception) {
@@ -60,14 +62,24 @@ private DataSourceMetadata getNeo4jBoltMetadata(DataSourceApi dataSource) {
6062
GraphQueryResult propertyKeysResult = db.execute("CALL db.propertyKeys()");
6163
GraphQueryResult storedProceduresResult = db.execute("CALL dbms.procedures()");
6264

63-
metadata.addLabels(labelsQueryResult);
64-
metadata.addRelationshipTypes(relationshipQueryResult);
65+
List<String> listOfLabels = extractLabels(labelsQueryResult);
66+
if (!listOfLabels.isEmpty()) {
67+
GraphQueryResult labelCount = db.execute(queryLabelCount(listOfLabels));
68+
metadata.addLabels(labelCount, listOfLabels);
69+
}
70+
71+
List<String> listOfRelationshipTypes = extractRelationshipTypes(relationshipQueryResult);
72+
if (!listOfRelationshipTypes.isEmpty()) {
73+
GraphQueryResult relationshipTypeCountResult = db.execute(queryRelationshipTypeCount(listOfRelationshipTypes));
74+
metadata.addRelationshipTypes(relationshipTypeCountResult, listOfRelationshipTypes);
75+
}
76+
6577
metadata.addPropertyKeys(propertyKeysResult);
6678
metadata.addStoredProcedures(storedProceduresResult);
6779

6880
boolean supportsUserFunctions = metadata.getMetadata(Neo4jBoltCypherDataSourceMetadata.STORED_PROCEDURES)
69-
.stream()
70-
.anyMatch((map) -> map.get("name").equals("dbms.functions"));
81+
.stream()
82+
.anyMatch((map) -> map.get("name").equals("dbms.functions"));
7183

7284
if (supportsUserFunctions) {
7385
GraphQueryResult userFunctionsResult = db.execute("CALL dbms.functions()");
@@ -77,27 +89,59 @@ private DataSourceMetadata getNeo4jBoltMetadata(DataSourceApi dataSource) {
7789
return metadata;
7890
}
7991

80-
private void updateNeo4jBoltMetadata(DataSourceApi dataSource, DataSourceMetadata metadata) {
92+
private List<String> extractRelationshipTypes(GraphQueryResult relationshipQueryResult) {
93+
GraphQueryResultColumn column = relationshipQueryResult.getColumns().get(0);
94+
return relationshipQueryResult.getRows()
95+
.stream()
96+
.map(row -> (String) row.getValue(column))
97+
.collect(Collectors.toList());
98+
}
99+
100+
private List<String> extractLabels(GraphQueryResult labelsQueryResult) {
101+
GraphQueryResultColumn column = labelsQueryResult.getColumns().get(0);
102+
return labelsQueryResult.getRows()
103+
.stream()
104+
.map(row -> (String) row.getValue(column))
105+
.collect(Collectors.toList());
106+
}
107+
108+
private String queryRelationshipTypeCount(List<String> relationshipTypes) {
109+
return relationshipTypes
110+
.stream()
111+
.map(relationshipType -> "MATCH ()-[r:" + relationshipType + "]->() RETURN count(r)")
112+
.collect(Collectors.joining(" UNION "));
113+
}
114+
115+
private String queryLabelCount(List<String> labels) {
116+
return labels
117+
.stream()
118+
.map(label -> "MATCH (n:" + label + ") RETURN count(n)")
119+
.collect(Collectors.joining(" UNION "));
120+
}
121+
122+
private void updateNeo4jBoltMetadata(DataSourceApi dataSource, Neo4jBoltCypherDataSourceMetadata metadata) {
81123
// Refresh cypher metadata provider
82124
cypherMetadataProviderService.wipeContainer(dataSource.getName());
83125
CypherMetadataContainer container = cypherMetadataProviderService.getContainer(dataSource.getName());
84126

85-
metadata.getMetadata(Neo4jBoltCypherDataSourceMetadata.LABELS).stream()
86-
.map((row) -> row.get("label"))
87-
.forEach(container::addLabel);
88-
metadata.getMetadata(Neo4jBoltCypherDataSourceMetadata.RELATIONSHIP_TYPES).stream()
89-
.map((row) -> row.get("relationshipType"))
90-
.forEach(container::addRelationshipType);
127+
metadata.getLabels()
128+
.stream()
129+
.map(Neo4jLabelMetadata::getName)
130+
.forEach(container::addLabel);
131+
metadata.getRelationshipTypes()
132+
.stream()
133+
.map(Neo4jRelationshipTypeMetadata::getName)
134+
.forEach(container::addRelationshipType);
91135
metadata.getMetadata(Neo4jBoltCypherDataSourceMetadata.PROPERTY_KEYS).stream()
92-
.map((row) -> row.get("propertyKey"))
93-
.forEach(container::addPropertyKey);
136+
.map((row) -> row.get("propertyKey"))
137+
.forEach(container::addPropertyKey);
94138
metadata.getMetadata(Neo4jBoltCypherDataSourceMetadata.STORED_PROCEDURES)
95-
.forEach(row -> container.addProcedure(row.get("name"), row.get("signature"), row.get("description")));
139+
.forEach(row -> container.addProcedure(row.get("name"), row.get("signature"), row.get("description")));
96140

97141
List<Map<String, String>> userFunctionMetadata = metadata.getMetadata(Neo4jBoltCypherDataSourceMetadata.USER_FUNCTIONS);
98142
if (userFunctionMetadata != null) {
99143
userFunctionMetadata
100-
.forEach(row -> container.addUserFunction(row.get("name"), row.get("signature"), row.get("description")));
144+
.forEach(row -> container.addUserFunction(row.get("name"), row.get("signature"), row.get("description")));
101145
}
102146
}
103147

ui/jetbrains/src/main/java/com/neueda/jetbrains/plugin/graphdb/jetbrains/component/datasource/metadata/Neo4jBoltCypherDataSourceMetadata.java

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,15 @@
1111

1212
public class Neo4jBoltCypherDataSourceMetadata implements DataSourceMetadata {
1313

14-
public static final String LABELS = "labels";
15-
public static final String RELATIONSHIP_TYPES = "relationships";
1614
public static final String PROPERTY_KEYS = "propertyKeys";
1715
public static final String STORED_PROCEDURES = "procedures";
1816
public static final String USER_FUNCTIONS = "functions";
1917

2018
private Map<String, List<Map<String, String>>> dataReceiver = new HashMap<>();
2119

20+
private List<Neo4jLabelMetadata> labels = new ArrayList<>();
21+
private List<Neo4jRelationshipTypeMetadata> relationshipTypes = new ArrayList<>();
22+
2223
@Override
2324
public List<Map<String, String>> getMetadata(String metadataKey) {
2425
return dataReceiver.get(metadataKey);
@@ -29,14 +30,6 @@ public boolean isMetadataExists(final String metadataKey) {
2930
return dataReceiver.containsKey(metadataKey);
3031
}
3132

32-
public void addLabels(GraphQueryResult labelsQueryResult) {
33-
addDataSourceMetadata(LABELS, labelsQueryResult);
34-
}
35-
36-
public void addRelationshipTypes(GraphQueryResult relationshipQueryResult) {
37-
addDataSourceMetadata(RELATIONSHIP_TYPES, relationshipQueryResult);
38-
}
39-
4033
public void addPropertyKeys(GraphQueryResult propertyKeysResult) {
4134
addDataSourceMetadata(PROPERTY_KEYS, propertyKeysResult);
4235
}
@@ -69,4 +62,36 @@ private void addDataSourceMetadata(String key, GraphQueryResult graphQueryResult
6962
public void addDataSourceMetadata(String key, List<Map<String, String>> data) {
7063
dataReceiver.put(key, data);
7164
}
65+
66+
public void addLabels(GraphQueryResult labelCountResult, List<String> labelNames) {
67+
GraphQueryResultColumn column = labelCountResult.getColumns().get(0);
68+
for (int i = 0; i < labelCountResult.getRows().size(); i++) {
69+
GraphQueryResultRow row = labelCountResult.getRows().get(i);
70+
labels.add(new Neo4jLabelMetadata(labelNames.get(i), (Long) row.getValue(column)));
71+
}
72+
}
73+
74+
public void addLabel(Neo4jLabelMetadata labelMetadata) {
75+
labels.add(labelMetadata);
76+
}
77+
78+
public List<Neo4jLabelMetadata> getLabels() {
79+
return labels;
80+
}
81+
82+
public void addRelationshipTypes(GraphQueryResult relationshipTypeCountResult, List<String> relationshipTypeNames) {
83+
GraphQueryResultColumn column = relationshipTypeCountResult.getColumns().get(0);
84+
for (int i = 0; i < relationshipTypeCountResult.getRows().size(); i++) {
85+
GraphQueryResultRow row = relationshipTypeCountResult.getRows().get(i);
86+
relationshipTypes.add(new Neo4jRelationshipTypeMetadata(relationshipTypeNames.get(i), (Long) row.getValue(column)));
87+
}
88+
}
89+
90+
public void addRelationshipType(Neo4jRelationshipTypeMetadata relationshipTypeMetadata) {
91+
relationshipTypes.add(relationshipTypeMetadata);
92+
}
93+
94+
public List<Neo4jRelationshipTypeMetadata> getRelationshipTypes() {
95+
return relationshipTypes;
96+
}
7297
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.neueda.jetbrains.plugin.graphdb.jetbrains.component.datasource.metadata;
2+
3+
public class Neo4jLabelMetadata {
4+
private String name;
5+
private Long count;
6+
7+
public Neo4jLabelMetadata(String name, Long count) {
8+
this.name = name;
9+
this.count = count;
10+
}
11+
12+
public String getName() {
13+
return name;
14+
}
15+
16+
public void setName(String name) {
17+
this.name = name;
18+
}
19+
20+
public Long getCount() {
21+
return count;
22+
}
23+
24+
public void setCount(Long count) {
25+
this.count = count;
26+
}
27+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.neueda.jetbrains.plugin.graphdb.jetbrains.component.datasource.metadata;
2+
3+
public class Neo4jRelationshipTypeMetadata {
4+
private String name;
5+
private Long count;
6+
7+
public Neo4jRelationshipTypeMetadata(String name, Long count) {
8+
this.name = name;
9+
this.count = count;
10+
}
11+
12+
public String getName() {
13+
return name;
14+
}
15+
16+
public void setName(String name) {
17+
this.name = name;
18+
}
19+
20+
public Long getCount() {
21+
return count;
22+
}
23+
24+
public void setCount(Long count) {
25+
this.count = count;
26+
}
27+
}

ui/jetbrains/src/main/java/com/neueda/jetbrains/plugin/graphdb/jetbrains/ui/datasource/metadata/DataSourceMetadataUi.java

Lines changed: 40 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,22 @@
11
package com.neueda.jetbrains.plugin.graphdb.jetbrains.ui.datasource.metadata;
22

33
import com.intellij.ui.treeStructure.PatchedDefaultMutableTreeNode;
4-
import com.neueda.jetbrains.plugin.graphdb.jetbrains.component.datasource.metadata.DataSourceMetadata;
54
import com.neueda.jetbrains.plugin.graphdb.jetbrains.component.datasource.metadata.DataSourcesComponentMetadata;
65
import com.neueda.jetbrains.plugin.graphdb.jetbrains.component.datasource.metadata.Neo4jBoltCypherDataSourceMetadata;
76
import com.neueda.jetbrains.plugin.graphdb.jetbrains.component.datasource.state.DataSourceApi;
7+
import com.neueda.jetbrains.plugin.graphdb.jetbrains.ui.datasource.tree.LabelTreeNodeModel;
88
import com.neueda.jetbrains.plugin.graphdb.jetbrains.ui.datasource.tree.MetadataTreeNodeModel;
9+
import com.neueda.jetbrains.plugin.graphdb.jetbrains.ui.datasource.tree.RelationshipTypeTreeNodeModel;
910
import com.neueda.jetbrains.plugin.graphdb.jetbrains.ui.datasource.tree.TreeNodeModelApi;
1011
import com.neueda.jetbrains.plugin.graphdb.platform.GraphIcons;
1112

1213
import static com.neueda.jetbrains.plugin.graphdb.jetbrains.ui.datasource.tree.Neo4jTreeNodeType.*;
1314

1415
public class DataSourceMetadataUi {
1516

16-
private static final String RELATIONSHIP_TYPES_TITLE = "relationship types";
17+
private static final String RELATIONSHIP_TYPES_TITLE = "relationship types (%s)";
1718
private static final String PROPERTY_KEYS_TITLE = "property keys";
18-
private static final String LABELS_TITLE = "labels";
19+
private static final String LABELS_TITLE = "labels (%s)";
1920
private static final String STORED_PROCEDURES_TITLE = "stored procedures";
2021
private static final String USER_FUNCTIONS_TITLE = "user functions";
2122

@@ -29,71 +30,77 @@ public boolean updateDataSourceMetadataUi(PatchedDefaultMutableTreeNode node, Da
2930
switch (nodeDataSource.getDataSourceType()) {
3031
case NEO4J_BOLT:
3132
return dataSourcesComponent.getMetadata(nodeDataSource)
32-
.map(dataSourceMetadata -> updateNeo4jBoltCypherMetadataUi(node, dataSourceMetadata))
33-
.orElse(false);
33+
.map(genericMetadata -> (Neo4jBoltCypherDataSourceMetadata) genericMetadata)
34+
.map(neo4jMetadata -> updateNeo4jBoltCypherMetadataUi(node, neo4jMetadata))
35+
.orElse(false);
3436
default:
3537
return false;
3638
}
3739
}
3840

3941
// ui
4042
boolean updateNeo4jBoltCypherMetadataUi(PatchedDefaultMutableTreeNode dataSourceRootTreeNode,
41-
DataSourceMetadata dataSourceMetadata) {
43+
Neo4jBoltCypherDataSourceMetadata dataSourceMetadata) {
4244
// Remove existing metadata from ui
4345
dataSourceRootTreeNode.removeAllChildren();
4446
TreeNodeModelApi model = (TreeNodeModelApi) dataSourceRootTreeNode.getUserObject();
4547
DataSourceApi dataSourceApi = model.getDataSourceApi();
4648

4749
// Labels
50+
int labelCount = dataSourceMetadata.getLabels().size();
4851
PatchedDefaultMutableTreeNode labelsTreeNode = new PatchedDefaultMutableTreeNode(
49-
new MetadataTreeNodeModel(LABELS, dataSourceApi, LABELS_TITLE, GraphIcons.Nodes.LABEL));
50-
dataSourceMetadata
51-
.getMetadata(Neo4jBoltCypherDataSourceMetadata.LABELS)
52-
.forEach((row) -> labelsTreeNode.add(of(new MetadataTreeNodeModel(LABEL, dataSourceApi, row.get("label")))));
52+
new MetadataTreeNodeModel(LABELS, dataSourceApi, String.format(LABELS_TITLE, labelCount), GraphIcons.Nodes.LABEL));
53+
dataSourceMetadata.getLabels()
54+
.stream()
55+
.map(label -> new LabelTreeNodeModel(LABEL, dataSourceApi, label.getName(), label.getCount()))
56+
.forEach(labelModel -> labelsTreeNode.add(of(labelModel)));
5357
dataSourceRootTreeNode.add(labelsTreeNode);
5458

5559
// RelTypes
60+
int relationshipTypesCount = dataSourceMetadata.getRelationshipTypes().size();
61+
String relationshipTypesName = String.format(RELATIONSHIP_TYPES_TITLE, relationshipTypesCount);
5662
PatchedDefaultMutableTreeNode relationshipTypesTreeNode = new PatchedDefaultMutableTreeNode(
57-
new MetadataTreeNodeModel(RELATIONSHIPS, dataSourceApi, RELATIONSHIP_TYPES_TITLE, GraphIcons.Nodes.RELATIONSHIP_TYPE));
58-
dataSourceMetadata
59-
.getMetadata(Neo4jBoltCypherDataSourceMetadata.RELATIONSHIP_TYPES)
60-
.forEach((row) -> relationshipTypesTreeNode.add(of(new MetadataTreeNodeModel(RELATIONSHIP, dataSourceApi, row.get("relationshipType")))));
63+
new MetadataTreeNodeModel(RELATIONSHIPS, dataSourceApi, relationshipTypesName, GraphIcons.Nodes.RELATIONSHIP_TYPE));
64+
dataSourceMetadata.getRelationshipTypes()
65+
.stream()
66+
.map(rel -> new RelationshipTypeTreeNodeModel(RELATIONSHIP, dataSourceApi, rel.getName(), rel.getCount()))
67+
.forEach(relModel -> relationshipTypesTreeNode.add(of(relModel)));
6168
dataSourceRootTreeNode.add(relationshipTypesTreeNode);
6269

6370
// Property Keys
6471
PatchedDefaultMutableTreeNode propertyKeysTreeNode = new PatchedDefaultMutableTreeNode(
65-
new MetadataTreeNodeModel(PROPERTY_KEYS, dataSourceApi, PROPERTY_KEYS_TITLE, GraphIcons.Nodes.PROPERTY_KEY));
72+
new MetadataTreeNodeModel(PROPERTY_KEYS, dataSourceApi, PROPERTY_KEYS_TITLE, GraphIcons.Nodes.PROPERTY_KEY));
6673
dataSourceMetadata
67-
.getMetadata(Neo4jBoltCypherDataSourceMetadata.PROPERTY_KEYS)
68-
.forEach((row) -> propertyKeysTreeNode.add(of(new MetadataTreeNodeModel(PROPERTY_KEY, dataSourceApi, row.get("propertyKey")))));
74+
.getMetadata(Neo4jBoltCypherDataSourceMetadata.PROPERTY_KEYS)
75+
.forEach((row) -> propertyKeysTreeNode.add(of(new MetadataTreeNodeModel(PROPERTY_KEY, dataSourceApi, row.get("propertyKey")))));
6976
dataSourceRootTreeNode.add(propertyKeysTreeNode);
7077

7178
// Stored procedures
7279
PatchedDefaultMutableTreeNode storedProceduresTreeNode = new PatchedDefaultMutableTreeNode(
73-
new MetadataTreeNodeModel(STORED_PROCEDURES, dataSourceApi, STORED_PROCEDURES_TITLE, GraphIcons.Nodes.STORED_PROCEDURE));
80+
new MetadataTreeNodeModel(STORED_PROCEDURES, dataSourceApi, STORED_PROCEDURES_TITLE, GraphIcons.Nodes.STORED_PROCEDURE));
7481
dataSourceMetadata
75-
.getMetadata(Neo4jBoltCypherDataSourceMetadata.STORED_PROCEDURES)
76-
.forEach((row) -> {
77-
PatchedDefaultMutableTreeNode nameNode = of(new MetadataTreeNodeModel(STORED_PROCEDURE, dataSourceApi, row.get("name")));
78-
PatchedDefaultMutableTreeNode descriptionNode = of(new MetadataTreeNodeModel(STORED_PROCEDURE, dataSourceApi, row.get("signature")));
79-
nameNode.add(descriptionNode);
80-
storedProceduresTreeNode.add(nameNode);
81-
});
82+
.getMetadata(Neo4jBoltCypherDataSourceMetadata.STORED_PROCEDURES)
83+
.forEach((row) -> {
84+
PatchedDefaultMutableTreeNode nameNode = of(new MetadataTreeNodeModel(STORED_PROCEDURE, dataSourceApi, row.get("name")));
85+
PatchedDefaultMutableTreeNode descriptionNode = of(new MetadataTreeNodeModel(STORED_PROCEDURE, dataSourceApi, row.get("signature")));
86+
nameNode.add(descriptionNode);
87+
storedProceduresTreeNode.add(nameNode);
88+
});
8289
dataSourceRootTreeNode.add(storedProceduresTreeNode);
8390

8491
// User Functions
8592
if (dataSourceMetadata.isMetadataExists(Neo4jBoltCypherDataSourceMetadata.USER_FUNCTIONS)) {
8693
PatchedDefaultMutableTreeNode userFunctionTreeNode = new PatchedDefaultMutableTreeNode(
87-
new MetadataTreeNodeModel(USER_FUNCTIONS, dataSourceApi, USER_FUNCTIONS_TITLE, GraphIcons.Nodes.USER_FUNCTION));
94+
new MetadataTreeNodeModel(USER_FUNCTIONS, dataSourceApi, USER_FUNCTIONS_TITLE, GraphIcons.Nodes.USER_FUNCTION));
8895

8996
dataSourceMetadata
90-
.getMetadata(Neo4jBoltCypherDataSourceMetadata.USER_FUNCTIONS)
91-
.forEach((row) -> {
92-
PatchedDefaultMutableTreeNode nameNode = of(new MetadataTreeNodeModel(USER_FUNCTION, dataSourceApi, row.get("name")));
93-
PatchedDefaultMutableTreeNode descriptionNode = of(new MetadataTreeNodeModel(USER_FUNCTION, dataSourceApi, row.get("signature")));
94-
nameNode.add(descriptionNode);
95-
userFunctionTreeNode.add(nameNode);
96-
});
97+
.getMetadata(Neo4jBoltCypherDataSourceMetadata.USER_FUNCTIONS)
98+
.forEach((row) -> {
99+
PatchedDefaultMutableTreeNode nameNode = of(new MetadataTreeNodeModel(USER_FUNCTION, dataSourceApi, row.get("name")));
100+
PatchedDefaultMutableTreeNode descriptionNode = of(new MetadataTreeNodeModel(USER_FUNCTION, dataSourceApi, row.get("signature")));
101+
nameNode.add(descriptionNode);
102+
userFunctionTreeNode.add(nameNode);
103+
});
97104

98105
dataSourceRootTreeNode.add(userFunctionTreeNode);
99106
}

0 commit comments

Comments
 (0)