Implementing projection
This commit is contained in:
parent
f2cf0a4f17
commit
9450134790
|
@ -6,6 +6,8 @@ import java.util.Iterator;
|
|||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.ws.rs.InternalServerErrorException;
|
||||
|
||||
import org.gcube.com.fasterxml.jackson.databind.JsonNode;
|
||||
import org.gcube.com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.gcube.com.fasterxml.jackson.databind.node.ArrayNode;
|
||||
|
@ -20,6 +22,7 @@ import org.gcube.informationsystem.resourceregistry.api.exceptions.types.SchemaE
|
|||
import org.gcube.informationsystem.resourceregistry.api.exceptions.types.SchemaNotFoundException;
|
||||
import org.gcube.informationsystem.resourceregistry.queries.operators.ConditionalOperator;
|
||||
import org.gcube.informationsystem.resourceregistry.queries.operators.LogicalOperator;
|
||||
import org.gcube.informationsystem.resourceregistry.queries.operators.ProjectionOperator;
|
||||
import org.gcube.informationsystem.resourceregistry.types.TypesCache;
|
||||
import org.gcube.informationsystem.utils.TypeUtility;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -113,6 +116,8 @@ public abstract class JsonQueryERElement {
|
|||
this.caller = null;
|
||||
this.breadcrumb = new ArrayList<>();
|
||||
this.position = 0;
|
||||
this.alias = null;
|
||||
this.fieldsToEmit = new ArrayList<>();
|
||||
|
||||
|
||||
this.fieldNamesToRemove = new HashSet<>();
|
||||
|
@ -149,9 +154,13 @@ public abstract class JsonQueryERElement {
|
|||
}
|
||||
|
||||
public void setProjection(boolean projection) {
|
||||
if(!projection) {
|
||||
throw new InternalServerErrorException("Projection can only be set to true from code. This is a server side bug. Please contact the administrator.");
|
||||
}
|
||||
this.projection = projection;
|
||||
if(projection && !entryPoint) {
|
||||
breadcrumb.get(0).setEntryPoint(projection);
|
||||
if(!entryPoint) {
|
||||
// Set the projection in the parent
|
||||
breadcrumb.get(breadcrumb.size()-2).setProjection(projection);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -205,12 +214,11 @@ public abstract class JsonQueryERElement {
|
|||
* @param fieldToEmit
|
||||
*/
|
||||
protected void addFieldToEmit(String fieldToEmit) {
|
||||
if(entryPoint) {
|
||||
fieldsToEmit.add(fieldToEmit);
|
||||
logger.trace("The field to emit ({}) has been added to entry point, i.e. {} with alias {}", fieldToEmit, this.type, this.alias);
|
||||
}else {
|
||||
logger.trace("The field to emit ({}) will be added to entry point", fieldToEmit);
|
||||
breadcrumb.get(0).addFieldToEmit(fieldToEmit);
|
||||
fieldsToEmit.add(fieldToEmit);
|
||||
logger.trace("The field to emit ({}) has been added to {} with alias {}", fieldToEmit, this.type, this.alias);
|
||||
if(!entryPoint) {
|
||||
logger.trace("The field to emit ({}) will be added to the parent too", fieldToEmit);
|
||||
breadcrumb.get(breadcrumb.size()-2).addFieldToEmit(fieldToEmit);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -288,6 +296,25 @@ public abstract class JsonQueryERElement {
|
|||
}
|
||||
|
||||
protected StringBuffer evaluateNode(JsonNode jsonNode, String fieldName, String fieldNamePrefix) throws InvalidQueryException {
|
||||
|
||||
if(ProjectionOperator.getOperators().contains(fieldName)) {
|
||||
setProjection(true);
|
||||
Iterator<String> iterator = jsonNode.fieldNames();
|
||||
while(iterator.hasNext()) {
|
||||
String fieldNameToEmit = iterator.next();
|
||||
String nameOfFieldToEmit = jsonNode.get(fieldNameToEmit).asText();
|
||||
StringBuffer b = new StringBuffer();
|
||||
b.append(getAlias(true));
|
||||
b.append(".");
|
||||
b.append(fieldNameToEmit);
|
||||
b.append(" AS ");
|
||||
b.append(nameOfFieldToEmit);
|
||||
addFieldToEmit(b.toString());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
StringBuffer stringBuffer = new StringBuffer();
|
||||
|
||||
if(LogicalOperator.getOperators().contains(fieldName)) {
|
||||
|
@ -441,7 +468,7 @@ public abstract class JsonQueryERElement {
|
|||
List<JsonQueryERElement> childrenBreadcrumb = getChildrenBreadcrumb();
|
||||
|
||||
if(entryPoint) {
|
||||
alias = getAlias();
|
||||
getAlias(true);
|
||||
}
|
||||
|
||||
StringBuffer buffer = getSpecificMatchQuery(childrenBreadcrumb);
|
||||
|
|
|
@ -95,7 +95,7 @@ public class JsonQueryFacet extends JsonQueryEntity {
|
|||
protected StringBuffer getSpecificMatchQuery(List<JsonQueryERElement> childrenBreadcrumb)
|
||||
throws SchemaException, ResourceRegistryException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
return new StringBuffer();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -123,7 +123,7 @@ public class JsonQueryResource extends JsonQueryEntity {
|
|||
StringBuffer buffer = new StringBuffer();
|
||||
|
||||
if(!entryPoint) {
|
||||
buffer.append("\n\t");
|
||||
buffer.append("\n\t.");
|
||||
buffer.append(direction.name().toLowerCase());
|
||||
buffer.append("V('");
|
||||
buffer.append(type);
|
||||
|
@ -160,13 +160,14 @@ public class JsonQueryResource extends JsonQueryEntity {
|
|||
buffer = jsonQueryIsRelatedTo.createMatchQuery(buffer);
|
||||
|
||||
if(traverseBack) {
|
||||
buffer.append(jsonQueryIsRelatedTo.getDirection().opposite().name().toLowerCase());
|
||||
buffer.append("\n\t.");
|
||||
buffer.append(jsonQueryIsRelatedTo.getDirection().name().toLowerCase());
|
||||
buffer.append("V('");
|
||||
buffer.append(type);
|
||||
buffer.append("') ");
|
||||
if(alias!=null || entryPoint) {
|
||||
if(getAlias()!=null || entryPoint) {
|
||||
buffer.append("{ where: ($matched.");
|
||||
buffer.append(alias);
|
||||
buffer.append(getAlias());
|
||||
buffer.append(" == $currentMatch)}\n");
|
||||
}
|
||||
}
|
||||
|
@ -194,13 +195,14 @@ public class JsonQueryResource extends JsonQueryEntity {
|
|||
buffer = jsonQueryConsistsOf.createMatchQuery(buffer);
|
||||
|
||||
if(traverseBack) {
|
||||
buffer.append(jsonQueryConsistsOf.getDirection().opposite().name().toLowerCase());
|
||||
buffer.append("\n\t.");
|
||||
buffer.append(jsonQueryConsistsOf.getDirection().name().toLowerCase());
|
||||
buffer.append("V('");
|
||||
buffer.append(type);
|
||||
buffer.append("') ");
|
||||
if(alias!=null || entryPoint) {
|
||||
if(getAlias()!=null || entryPoint) {
|
||||
buffer.append("{ where: ($matched.");
|
||||
buffer.append(alias);
|
||||
buffer.append(getAlias());
|
||||
buffer.append(" == $currentMatch)}\n");
|
||||
}
|
||||
}
|
||||
|
@ -210,5 +212,4 @@ public class JsonQueryResource extends JsonQueryEntity {
|
|||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -167,14 +167,20 @@ public class JsonQueryConsistsOf extends JsonQueryRelation {
|
|||
buffer.append(direction.name().toLowerCase());
|
||||
buffer.append("E('");
|
||||
buffer.append(type);
|
||||
buffer.append("'");
|
||||
buffer.append("')");
|
||||
|
||||
if(size>0) {
|
||||
alias = getAlias(true);
|
||||
buffer.append("{ where: ($matched.");
|
||||
buffer.append(alias);
|
||||
buffer.append(" == $currentMatch)");
|
||||
buffer.append(addConstraints(jsonNode, null, alias));
|
||||
|
||||
StringBuffer sb = addConstraints(jsonNode, null, alias);
|
||||
if(sb!=null && sb.length()>0) {
|
||||
buffer.append(" AND ");
|
||||
buffer.append(sb);
|
||||
}
|
||||
|
||||
buffer.append("}\n");
|
||||
}
|
||||
|
||||
|
@ -187,7 +193,7 @@ public class JsonQueryConsistsOf extends JsonQueryRelation {
|
|||
buffer.append(direction.opposite().name().toLowerCase());
|
||||
buffer.append("E('");
|
||||
buffer.append(type);
|
||||
buffer.append("'");
|
||||
buffer.append("')");
|
||||
}
|
||||
|
||||
return buffer;
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
package org.gcube.informationsystem.resourceregistry.queries.operators;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author Luca Frosini (ISTI - CNR)
|
||||
* See https://www.orientdb.com/docs/3.0.x/sql/SQL-Where.html
|
||||
*/
|
||||
public enum ProjectionOperator {
|
||||
|
||||
EMIT("_emit", "");
|
||||
|
||||
protected final String operator;
|
||||
protected final String description;
|
||||
|
||||
private ProjectionOperator(String operator, String description) {
|
||||
this.operator = operator;
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public String getOperator() {
|
||||
return operator;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
private static Set<String> operators;
|
||||
private static Map<String,ProjectionOperator> operatorByKey;
|
||||
|
||||
static {
|
||||
ProjectionOperator.operators = new HashSet<>();
|
||||
ProjectionOperator.operatorByKey = new HashMap<>();
|
||||
|
||||
for(ProjectionOperator po : ProjectionOperator.values()) {
|
||||
ProjectionOperator.operators.add(po.getOperator());
|
||||
ProjectionOperator.operatorByKey.put(po.getOperator(), po);
|
||||
}
|
||||
}
|
||||
|
||||
public static Set<String> getOperators() {
|
||||
return ProjectionOperator.operators;
|
||||
}
|
||||
|
||||
public static ProjectionOperator getQueryLogicalOperator(String key) {
|
||||
return operatorByKey.get(key);
|
||||
}
|
||||
|
||||
}
|
|
@ -35,6 +35,13 @@ public class JsonQueryTest extends ContextTest {
|
|||
return new File(resourcesDirectory, "queries");
|
||||
}
|
||||
|
||||
public File getProjectionQueriesDirectory() throws Exception {
|
||||
URL logbackFileURL = JsonQueryTest.class.getClassLoader().getResource("logback-test.xml");
|
||||
File logbackFile = new File(logbackFileURL.toURI());
|
||||
File resourcesDirectory = logbackFile.getParentFile();
|
||||
return new File(resourcesDirectory, "projection-queries");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJsonQueries() throws Exception {
|
||||
ContextTest.setContextByName(DEVVRE);
|
||||
|
@ -191,8 +198,8 @@ public class JsonQueryTest extends ContextTest {
|
|||
|
||||
@Test
|
||||
public void testCreateMatchQuery() throws Exception {
|
||||
File queriesDirectory = getQueriesDirectory();
|
||||
File jsonQueryFile = new File(queriesDirectory, "query6.json");
|
||||
File queriesDirectory = getProjectionQueriesDirectory();
|
||||
File jsonQueryFile = new File(queriesDirectory, "EService-query.json");
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
JsonNode jsonNode = objectMapper.readTree(jsonQueryFile);
|
||||
logger.info("Going to test the following JSON query {}", jsonNode.toString());
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_projection" : {
|
||||
|
||||
"type": "EService",
|
||||
"_emit" : {
|
||||
"id" : "id"
|
||||
|
@ -45,5 +45,5 @@
|
|||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue