Improving code

This commit is contained in:
luca.frosini 2023-11-24 15:36:43 +01:00
parent 6657543a63
commit 78ea9c2307
6 changed files with 117 additions and 74 deletions

View File

@ -368,7 +368,7 @@ public abstract class JsonQueryERElement {
StringBuffer stringBuffer = new StringBuffer();
if(fieldNamePrefix!=null) {
stringBuffer.append(fieldNamePrefix.trim());
if(fieldName!=null && fieldName.trim().length()==0) {
if(fieldName!=null && fieldName.trim().length()!=0) {
stringBuffer.append(".");
}
}

View File

@ -16,39 +16,41 @@ import org.gcube.informationsystem.types.PropertyTypeName.BaseTypeGroup;
*/
public enum ConditionalOperator {
EQ("_eq", " = ", BaseTypeGroup.ANY, "Matches values that are equal to a specified value. E.g. `name = 'Luke'`"),
GT("_gt", " > ", BaseTypeGroup.ANY, "Matches values that are greater than a specified value. "),
GTE("_gte", " >= ", BaseTypeGroup.ANY, "Matches values that are greater than or equal to a specified value."),
LT("_lt", " < ", BaseTypeGroup.ANY, "Matches values that are less than a specified value."),
LTE("_lte", " <= ", BaseTypeGroup.ANY, "Matches values that are less than or equal to a specified value."),
NE("_ne", " <> ", BaseTypeGroup.ANY, "Matches all values that are not equal to a specified value."),
BETWEEN("_between", " BETWEEN %s AND %s", 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 ", BaseTypeGroup.ANY, "Used to test if a value is NULL"),
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 ", 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 ", BaseTypeGroup.STRING, "The string contains such text. E.g. `text CONTAINSTEXT 'jay'`"),
MATCHES("_matches", " MATCHES ", 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'`"),
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 ", 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 ", 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 ", BaseTypeGroup.COLLECTION, "True if all the elements of the collection satisfy the next condition. E.g. `children CONTAINSALL (name = 'Luke')`"),
CONTAINS_ANY("_containsAny", " CONTAINSANY ", BaseTypeGroup.COLLECTION, "True if all the elements of the collection satisfy the next condition. E.g. `children CONTAINSANY (name = 'Luke')`"),
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 ", 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 ", 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`"),
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 ", BaseTypeGroup.ANY, "Returns TRUE is a field is defined in a document"),
IS_NOT_DEFINED("_isNotDefined", " IS NOT DEFINED ", BaseTypeGroup.ANY, "Returns TRUE is a field is not defined in a document");
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 dbConditionalOperator;
protected final BaseTypeGroup allowed;
protected final String description;
private ConditionalOperator(String operatorKey, String conditionalOperator, BaseTypeGroup allowed, String description) {
private ConditionalOperator(String operatorKey, String conditionalOperator, int numberOfOperand, BaseTypeGroup allowed, String description) {
this.operatorKey = operatorKey;
this.dbConditionalOperator = conditionalOperator;
this.numberOfOperand = numberOfOperand;
this.allowed = allowed;
this.description = description;
}
@ -86,11 +88,11 @@ public enum ConditionalOperator {
return operatorByKey.get(key);
}
public StringBuffer addCondition(String key, String value) {
public StringBuffer addCondition(String... operands) {
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append(key);
stringBuffer.append(operands[0]);
stringBuffer.append(getDbConditionalOperator());
stringBuffer.append(value);
stringBuffer.append(operands[1]);
return stringBuffer;
}
}

View File

@ -1,6 +1,7 @@
package org.gcube.informationsystem.resourceregistry.queries.operators;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
@ -28,17 +29,17 @@ import org.slf4j.LoggerFactory;
*/
public enum MatemathicsOperator {
SUM("_sum", " + ", ""),
MINUS("_minus", " - ", ""),
MULTIPLY("_multiply", " * ", ""),
DIVIDE("_divide", " / ", ""),
MODULE("_mod", " % ", ""),
BITWISE_RIGHT_SHIFT("_bitrshift", " >> ", ""),
BITWISE_LEFT_SHIFT("_bitlshift", " << ", ""),
BITWISE_AND("_bitand", " & ", ""),
BITWISE_OR("_bitor", " | ", ""),
BITWISE_XOR("_bitxor", " ^ ", ""),
ARRAY_CONCATENATION("_arrayconcat", " || ", "");
SUM("_sum", "+", ""),
MINUS("_minus", "-", ""),
MULTIPLY("_multiply", "*", ""),
DIVIDE("_divide", "/", ""),
MODULE("_mod", "%", ""),
BITWISE_RIGHT_SHIFT("_bitrshift", ">>", ""),
BITWISE_LEFT_SHIFT("_bitlshift", "<<", ""),
BITWISE_AND("_bitand", "&", ""),
BITWISE_OR("_bitor", "|", ""),
BITWISE_XOR("_bitxor", "^", ""),
ARRAY_CONCATENATION("_arrayconcat", "||", "");
protected static Logger logger = LoggerFactory.getLogger(MatemathicsOperator.class);
@ -72,6 +73,7 @@ public enum MatemathicsOperator {
private static Map<String,MatemathicsOperator> operatorByKey;
static {
MatemathicsOperator.operators = new HashSet<>();
MatemathicsOperator.operatorByKey = new HashMap<>();
for(MatemathicsOperator matemathicsOperator : MatemathicsOperator.values()) {

View File

@ -56,7 +56,7 @@ public class JsonQueryTest extends ContextTest {
};
for(File jsonQueryFile : queriesDirectory.listFiles(filenameFilter)) {
logger.info("Going to read JSON query frtm file {}", jsonQueryFile.getAbsolutePath());
logger.info("Going to read JSON query from file {}", jsonQueryFile.getAbsolutePath());
ObjectMapper objectMapper = new ObjectMapper();
JsonNode jsonNode = objectMapper.readTree(jsonQueryFile);
@ -197,7 +197,7 @@ public class JsonQueryTest extends ContextTest {
}
@Test
public void testCreateMatchQuery() throws Exception {
public void testSingleMatchQuery() throws Exception {
File queriesDirectory = getProjectionQueriesDirectory();
File jsonQueryFile = new File(queriesDirectory, "HostingNode-query.json");
ObjectMapper objectMapper = new ObjectMapper();
@ -210,19 +210,58 @@ public class JsonQueryTest extends ContextTest {
logger.info("Created Query from JSON:\n{}", createdStringBuffer.toString());
// StringBuffer expectedStringBuffer = new StringBuffer();
// File expectedQueryFile = new File(queriesDirectory, jsonQueryFile.getName().replace("json", "match.oquery"));
// try(BufferedReader br = new BufferedReader(new FileReader(expectedQueryFile))) {
// for(String line; (line = br.readLine()) != null; ) {
// expectedStringBuffer.append(line);
// }
// }
//
// logger.info("Expected Query from JSON: {}", expectedStringBuffer.toString());
//
// Assert.assertTrue(createdStringBuffer.toString().compareTo(expectedStringBuffer.toString())==0);
//
StringBuffer expectedStringBuffer = new StringBuffer();
File expectedQueryFile = new File(queriesDirectory, jsonQueryFile.getName().replace("-query.json", ".match.oquery"));
try(BufferedReader br = new BufferedReader(new FileReader(expectedQueryFile))) {
for(String line; (line = br.readLine()) != null; ) {
expectedStringBuffer.append(line);
}
}
logger.info("Expected Query from JSON: {}", expectedStringBuffer.toString());
Assert.assertTrue(createdStringBuffer.toString().replaceAll("\n", "").compareTo(expectedStringBuffer.toString().replaceAll("\n", ""))==0);
// String result = jsonQuery.query();
// logger.info("Result : {}", result);
}
@Test
public void testMatchQueries() throws Exception {
File queriesDirectory = getProjectionQueriesDirectory();
FilenameFilter filenameFilter = new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.endsWith("-query.json");
}
};
for(File jsonQueryFile : queriesDirectory.listFiles(filenameFilter)) {
ObjectMapper objectMapper = new ObjectMapper();
JsonNode jsonNode = objectMapper.readTree(jsonQueryFile);
logger.info("Going to test the following JSON query {}", jsonNode.toString());
JsonQuery jsonQuery = new JsonQuery();
jsonQuery.setJsonQuery(jsonNode);
StringBuffer createdStringBuffer = jsonQuery.createMatchQuery();
logger.info("Created Query from JSON:\n{}", createdStringBuffer.toString());
StringBuffer expectedStringBuffer = new StringBuffer();
File expectedQueryFile = new File(queriesDirectory, jsonQueryFile.getName().replace("-query.json", ".match.oquery"));
try(BufferedReader br = new BufferedReader(new FileReader(expectedQueryFile))) {
for(String line; (line = br.readLine()) != null; ) {
expectedStringBuffer.append(line);
}
}
logger.info("Expected Query from JSON: {}", expectedStringBuffer.toString());
Assert.assertTrue(createdStringBuffer.toString().replaceAll("\n", "").compareTo(expectedStringBuffer.toString().replaceAll("\n", ""))==0);
//String result = jsonQuery.query();
//logger.info("Result : {}", result);
}
}
}

View File

@ -1,29 +1,29 @@
MATCH
{class: EService, as: eservice00, where: ($currentMatch['@class'] INSTANCEOF 'EService')}
{class: EService, as: eservice0, where: ($currentMatch['@class'] INSTANCEOF 'EService')}
.inE('Activates') { as: activates10, where: ($currentMatch['@class'] INSTANCEOF 'Activates')}
.outV('HostingNode') { as: hostingnode20, where: ($currentMatch['@class'] INSTANCEOF 'HostingNode')}
.outE('IsIdentifiedBy') { as: isidentifiedby30, where: ($currentMatch['@class'] INSTANCEOF 'IsIdentifiedBy')}
.inV('NetworkingFacet') { as: networkingfacet40, where: ($currentMatch['@class'] INSTANCEOF 'NetworkingFacet')}
.inE('IsIdentifiedBy') { where: ($matched.isidentifiedby30 == $currentMatch)}
.outV('HostingNode') { where: ($matched.hostingnode20 == $currentMatch)}
.outE('Activates') { where: ($matched.activates10 == $currentMatch)}
.inV('EService') { where: ($matched.eservice00 == $currentMatch)}
.inE('Activates') { as: activates00, where: ($currentMatch['@class'] INSTANCEOF 'Activates')}
.outV('HostingNode') { as: hostingnode000, where: ($currentMatch['@class'] INSTANCEOF 'HostingNode')}
.outE('IsIdentifiedBy') { as: isidentifiedby0000, where: ($currentMatch['@class'] INSTANCEOF 'IsIdentifiedBy')}
.inV('NetworkingFacet') { as: networkingfacet00000, where: ($currentMatch['@class'] INSTANCEOF 'NetworkingFacet')}
.inE('IsIdentifiedBy') { where: ($matched.isidentifiedby0000 == $currentMatch)}
.outV('HostingNode') { where: ($matched.hostingnode000 == $currentMatch)}
.outE('Activates') { where: ($matched.activates00 == $currentMatch)}
.inV('EService') { where: ($matched.eservice0 == $currentMatch)}
.outE('IsIdentifiedBy') { as: isidentifiedby11, where: ($currentMatch['@class'] INSTANCEOF 'IsIdentifiedBy')}
.inV('SoftwareFacet') { as: softwarefacet20, where: ($currentMatch['@class'] INSTANCEOF 'SoftwareFacet')}
.inE('IsIdentifiedBy') { where: ($matched.isidentifiedby11 == $currentMatch)}
.outV('EService') { where: ($matched.eservice00 == $currentMatch)}
.outE('IsIdentifiedBy') { as: isidentifiedby01, where: ($currentMatch['@class'] INSTANCEOF 'IsIdentifiedBy')}
.inV('SoftwareFacet') { as: softwarefacet010, where: ($currentMatch['@class'] INSTANCEOF 'SoftwareFacet')}
.inE('IsIdentifiedBy') { where: ($matched.isidentifiedby01 == $currentMatch)}
.outV('EService') { where: ($matched.eservice0 == $currentMatch)}
.outE('ConsistsOf') { as: consistsof12, where: ($currentMatch['@class'] INSTANCEOF 'ConsistsOf')}
.inV('StateFacet') { as: statefacet20, where: ($currentMatch['@class'] INSTANCEOF 'StateFacet')}
.inE('ConsistsOf') { where: ($matched.consistsof12 == $currentMatch)}
.outV('EService') { where: ($matched.eservice00 == $currentMatch)}
.outE('ConsistsOf') { as: consistsof02, where: ($currentMatch['@class'] INSTANCEOF 'ConsistsOf')}
.inV('StateFacet') { as: statefacet020, where: ($currentMatch['@class'] INSTANCEOF 'StateFacet')}
.inE('ConsistsOf') { where: ($matched.consistsof02 == $currentMatch)}
.outV('EService') { where: ($matched.eservice0 == $currentMatch)}
RETURN
networkingfacet40.hostName AS `Host`,
softwarefacet20.group AS `Group`,
softwarefacet20.name AS `Name`,
softwarefacet20.version AS `Version`,
statefacet20.value AS `Status`,
eservice00.id AS `ID`
networkingfacet00000.hostName AS `Host`,
softwarefacet010.group AS `Group`,
softwarefacet010.name AS `Name`,
softwarefacet010.version AS `Version`,
statefacet020.value AS `Status`,
eservice0.id AS `ID`

View File

@ -24,7 +24,7 @@ MATCH
RETURN
networkingfacet000.hostName AS `HostName`,
statefacet010.value AS `Status`,
((memoryfacet020.size - memoryfacet020.used) + ' ' + memoryfacet020.unit) AS `HD Space Left`,
(memoryfacet030.size + ' ' + memoryfacet030.unit) AS `Mem. Available.`,
((memoryfacet020.size - memoryfacet020.used) + ' ' + memoryfacet020.unit) AS `HD Space Left`,
(memoryfacet030.size + ' ' + memoryfacet030.unit) AS `Mem. Available.`,
hostingnode0.id AS `ID`,
hostingnode0.lastUpdateTime AS `Last Update Time`