resource-registry/src/main/java/org/gcube/informationsystem/resourceregistry/queries/operators/ComparisonOperator.java

119 lines
6.3 KiB
Java

package org.gcube.informationsystem.resourceregistry.queries.operators;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang.NotImplementedException;
import org.gcube.com.fasterxml.jackson.databind.JsonNode;
import org.gcube.informationsystem.types.PropertyTypeName.BaseTypeGroup;
/**
* @author Luca Frosini (ISTI - CNR)
* See https://www.orientdb.com/docs/3.0.x/sql/SQL-Where.html
* https://www.orientdb.com/docs/3.0.x/sql/SQL-Syntax.html#conditions
* https://www.orientdb.com/docs/3.0.x/sql/SQL-Syntax.html#comparison-operators
* https://www.orientdb.com/docs/3.0.x/sql/SQL-Syntax.html#boolean-operators
*/
public enum ComparisonOperator {
EQ("_eq", " = ", 2, BaseTypeGroup.ANY, "Matches values that are equal to a specified value. E.g. `name = 'Luke'`"),
GT("_gt", " > ", 2, BaseTypeGroup.ANY, "Matches values that are greater than a specified value. "),
GTE("_gte", " >= ", 2, BaseTypeGroup.ANY, "Matches values that are greater than or equal to a specified value."),
LT("_lt", " < ", 2, BaseTypeGroup.ANY, "Matches values that are less than a specified value."),
LTE("_lte", " <= ", 2, BaseTypeGroup.ANY, "Matches values that are less than or equal to a specified value."),
NE("_ne", " <> ", 2, BaseTypeGroup.ANY, "Matches all values that are not equal to a specified value."),
BETWEEN("_between", " BETWEEN %s AND %s", 3, BaseTypeGroup.ANY, "Returns TRUE is a value is between two values, eg. 5 BETWEEN 1 AND 10. The value is between a range. E.g. `price BETWEEN 10 AND 30`. It's equivalent to `price >= 10 AND price <= 30`."),
IS("_is", " IS ", 2, BaseTypeGroup.ANY, "Used to test if a value is NULL"),
LIKE("_like", " LIKE ", 2, BaseTypeGroup.STRING, "For strings, checks if a string contains another string. % is used as a wildcard, eg. 'foobar CONTAINS '%ooba%''. Similar to equals, but allow the wildcard '%' that means 'any'. E.g. `name LIKE 'Luk%'`"),
CONTAINS_TEXT("_containsText", " CONTAINSTEXT ", 2, BaseTypeGroup.STRING, "The string contains such text. E.g. `text CONTAINSTEXT 'jay'`"),
MATCHES("_matches", " MATCHES ", 2, BaseTypeGroup.STRING, "Checks if a string matches a regular expression. Matches the string using a Regular Expression. E.g. `text MATCHES '\b[A-Z0-9.%+-]+@[A-Z0-9.-]+.[A-Z]{2,4}\b'`"),
IN("_in", " IN ", 2, BaseTypeGroup.COLLECTION, "The same as CONTAINS, but with inverted operands. Matches any of the values specified in an array. E.g. `name in ['European','Asiatic']`"),
CONTAINS("_contains", " CONTAINS ", 2, BaseTypeGroup.COLLECTION, "Checks if the left collection contains the right element. The left argument has to be a colleciton, otherwise it returns FALSE. It's NOT the check of colleciton intersections, so ['a', 'b', 'c'] CONTAINS ['a', 'b'] will return FALSE, while ['a', 'b', 'c'] CONTAINS 'a' will return TRUE. True if the collection contains at least one element that satisfy the next condition. Condition can be a single item: in this case the behaviour is like the IN operator. E.g. `children contains (name = 'Luke')` - `map.values() contains (name = 'Luke')`"),
CONTAINS_ALL("_containsAll", " CONTAINSALL ", 2, BaseTypeGroup.COLLECTION, "True if all the elements of the collection satisfy the next condition. E.g. `children CONTAINSALL (name = 'Luke')`"),
CONTAINS_ANY("_containsAny", " CONTAINSANY ", 2, BaseTypeGroup.COLLECTION, "True if all the elements of the collection satisfy the next condition. E.g. `children CONTAINSANY (name = 'Luke')`"),
CONTAINS_KEY("_containsKey", " CONTAINSKEY ", 2, BaseTypeGroup.MAP, "For maps, the same as for CONTAINS, but checks on the map keys. True if the map contains at least one key equals to the requested. You can also use map.keys() CONTAINS in place of it. E.g. `connections CONTAINSKEY 'Luke'`"),
CONTAINS_VALUE("_containsValue", " CONTAINSVALUE ", 2, BaseTypeGroup.MAP , "For maps, the same as for CONTAINS, but checks on the map values. True if the map contains at least one value equals to the requested. You can also use map.values() CONTAINS in place of it. E.g. `connections containsValue 10:3`"),
IS_DEFINED("_isDefined", " IS DEFINED ", 1, BaseTypeGroup.ANY, "Returns TRUE is a field is defined in a document"),
IS_NOT_DEFINED("_isNotDefined", " IS NOT DEFINED ", 1, BaseTypeGroup.ANY, "Returns TRUE is a field is not defined in a document");
protected final String operatorKey;
protected final int numberOfOperand;
protected final String dbOperator;
protected final BaseTypeGroup allowed;
protected final String description;
private ComparisonOperator(String operatorKey, String dbOperator, int numberOfOperand, BaseTypeGroup allowed, String description) {
this.operatorKey = operatorKey;
this.dbOperator = dbOperator;
this.numberOfOperand = numberOfOperand;
this.allowed = allowed;
this.description = description;
}
protected String getOperatorKey() {
return operatorKey;
}
public String getDbOperator() {
return dbOperator;
}
public String getDescription() {
return description;
}
private static Set<String> operators;
private static Map<String,ComparisonOperator> operatorByKey;
static {
ComparisonOperator.operators = new HashSet<>();
ComparisonOperator.operatorByKey = new HashMap<>();
for(ComparisonOperator queryComparisonOperator : ComparisonOperator.values()) {
ComparisonOperator.operators.add(queryComparisonOperator.getOperatorKey());
ComparisonOperator.operatorByKey.put(queryComparisonOperator.getOperatorKey(), queryComparisonOperator);
}
}
public static Set<String> getOperators() {
return ComparisonOperator.operators;
}
public static ComparisonOperator getOperator(String key) {
return operatorByKey.get(key);
}
public StringBuffer addCondition(String... operands) {
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append(operands[0]);
stringBuffer.append(getDbOperator());
stringBuffer.append(operands[1]);
return stringBuffer;
}
public static String getValue(JsonNode jsonNode) {
StringBuffer stringBuffer = new StringBuffer();
String value = jsonNode.asText();
if(jsonNode.isNumber()) {
stringBuffer.append(value);
} else {
stringBuffer.append("\"");
stringBuffer.append(value);
stringBuffer.append("\"");
}
return stringBuffer.toString();
}
public StringBuffer addCondition(JsonNode jn, String fieldNamePrefix) {
throw new NotImplementedException();
}
}