From 94d0d0031dce3362f2038a0b074588fdfeda09b6 Mon Sep 17 00:00:00 2001 From: grabdoc Date: Sun, 11 Feb 2024 13:23:30 -0600 Subject: [PATCH] #266 - working on where clause --- .../db2rest/rest/read/dto/ReadContextV2.java | 4 + .../db2rest/rest/read/model/DbWhere.java | 7 ++ .../processor/pre/RootWhereProcessor.java | 32 +++++--- .../rsql/operator/CustomRSQLOperators.java | 21 +++++ .../handler/EndWithOperatorHandler.java | 14 ++++ .../handler/EqualToOperatorHandler.java | 19 +++++ .../GreaterThanEqualToOperatorHandler.java | 14 ++++ .../handler/GreaterThanOperatorHandler.java | 14 ++++ .../operator/handler/InOperatorHandler.java | 22 ++++++ .../LessThanEqualToOperatorHandler.java | 14 ++++ .../handler/LessThanOperatorHandler.java | 14 ++++ .../operator/handler/LikeOperatorHandler.java | 14 ++++ .../handler/NotEqualToOperatorHandler.java | 14 ++++ .../handler/NotInOperatorHandler.java | 23 ++++++ .../operator/handler/OperatorHandler.java | 31 ++++++++ .../handler/RSQLOperatorHandlers.java | 32 ++++++++ .../handler/StartWithOperatorHandler.java | 14 ++++ .../rsql/parser/RSQLParserBuilder.java | 13 +++ .../rsql/visitor/BaseRSQLVisitor.java | 79 +++++++++++++++++++ 19 files changed, 386 insertions(+), 9 deletions(-) create mode 100644 src/main/java/com/homihq/db2rest/rest/read/model/DbWhere.java create mode 100644 src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/CustomRSQLOperators.java create mode 100644 src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/handler/EndWithOperatorHandler.java create mode 100644 src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/handler/EqualToOperatorHandler.java create mode 100644 src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/handler/GreaterThanEqualToOperatorHandler.java create mode 100644 src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/handler/GreaterThanOperatorHandler.java create mode 100644 src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/handler/InOperatorHandler.java create mode 100644 src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/handler/LessThanEqualToOperatorHandler.java create mode 100644 src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/handler/LessThanOperatorHandler.java create mode 100644 src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/handler/LikeOperatorHandler.java create mode 100644 src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/handler/NotEqualToOperatorHandler.java create mode 100644 src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/handler/NotInOperatorHandler.java create mode 100644 src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/handler/OperatorHandler.java create mode 100644 src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/handler/RSQLOperatorHandlers.java create mode 100644 src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/handler/StartWithOperatorHandler.java create mode 100644 src/main/java/com/homihq/db2rest/rest/read/processor/rsql/parser/RSQLParserBuilder.java create mode 100644 src/main/java/com/homihq/db2rest/rest/read/processor/rsql/visitor/BaseRSQLVisitor.java diff --git a/src/main/java/com/homihq/db2rest/rest/read/dto/ReadContextV2.java b/src/main/java/com/homihq/db2rest/rest/read/dto/ReadContextV2.java index ff201cd3..385cde64 100644 --- a/src/main/java/com/homihq/db2rest/rest/read/dto/ReadContextV2.java +++ b/src/main/java/com/homihq/db2rest/rest/read/dto/ReadContextV2.java @@ -41,10 +41,14 @@ public class ReadContextV2 { DbTable root; List cols; + + public void addWhereCondition(SqlCriterion whereCondition) { this.whereCondition = whereCondition; } + + public void addColumns(List columnList) { this.columns.addAll(columnList); } diff --git a/src/main/java/com/homihq/db2rest/rest/read/model/DbWhere.java b/src/main/java/com/homihq/db2rest/rest/read/model/DbWhere.java new file mode 100644 index 00000000..daac28f7 --- /dev/null +++ b/src/main/java/com/homihq/db2rest/rest/read/model/DbWhere.java @@ -0,0 +1,7 @@ +package com.homihq.db2rest.rest.read.model; + + +import java.util.List; +import java.util.Map; + +public record DbWhere(String tableName, DbTable table, List columns, Map paramMap) { } diff --git a/src/main/java/com/homihq/db2rest/rest/read/processor/pre/RootWhereProcessor.java b/src/main/java/com/homihq/db2rest/rest/read/processor/pre/RootWhereProcessor.java index 1d4e7521..60d002f0 100644 --- a/src/main/java/com/homihq/db2rest/rest/read/processor/pre/RootWhereProcessor.java +++ b/src/main/java/com/homihq/db2rest/rest/read/processor/pre/RootWhereProcessor.java @@ -1,17 +1,21 @@ package com.homihq.db2rest.rest.read.processor.pre; import com.homihq.db2rest.rest.read.dto.ReadContextV2; -import com.homihq.db2rest.rsql.v1.operators.SimpleRSQLOperators; -import com.homihq.db2rest.rsql.v1.parser.WhereFilterVisitor; -import cz.jirutka.rsql.parser.RSQLParser; + + +import com.homihq.db2rest.rest.read.model.DbWhere; +import com.homihq.db2rest.rest.read.processor.rsql.parser.RSQLParserBuilder; +import com.homihq.db2rest.rest.read.processor.rsql.visitor.BaseRSQLVisitor; import cz.jirutka.rsql.parser.ast.Node; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; -import org.mybatis.dynamic.sql.SqlCriterion; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; -//@Component +import java.util.HashMap; +import java.util.Map; + +@Component @Slf4j @Order(6) public class RootWhereProcessor implements ReadPreProcessor { @@ -19,15 +23,25 @@ public class RootWhereProcessor implements ReadPreProcessor { public void process(ReadContextV2 readContextV2) { if(StringUtils.isNotBlank(readContextV2.getFilter())) { + Map paramMap = new HashMap<>(); + + DbWhere dbWhere = new DbWhere( + readContextV2.getTableName(), + readContextV2.getRoot(),readContextV2.getCols(),paramMap); + log.info("-Creating root where condition -"); - Node rootNode = new RSQLParser(SimpleRSQLOperators.customOperators()).parse(readContextV2.getFilter()); + Node rootNode = RSQLParserBuilder.newRSQLParser().parse(readContextV2.getFilter()); + + String where = rootNode + .accept(new BaseRSQLVisitor( + dbWhere)); - SqlCriterion condition = rootNode - .accept(new WhereFilterVisitor(readContextV2.getRootTable())); + log.info("Where - {}", where); + log.info("param map - {}", paramMap); - readContextV2.addWhereCondition(condition); + //readContextV2.addWhereCondition(condition); } } diff --git a/src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/CustomRSQLOperators.java b/src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/CustomRSQLOperators.java new file mode 100644 index 00000000..e24d8355 --- /dev/null +++ b/src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/CustomRSQLOperators.java @@ -0,0 +1,21 @@ +package com.homihq.db2rest.rest.read.processor.rsql.operator; + +import cz.jirutka.rsql.parser.ast.ComparisonOperator; +import cz.jirutka.rsql.parser.ast.RSQLOperators; + +import java.util.Arrays; +import java.util.Set; + +public class CustomRSQLOperators extends RSQLOperators { + + public static final ComparisonOperator LIKE = new ComparisonOperator("=like=", false); + public static final ComparisonOperator START_WITH = new ComparisonOperator("=startWith=", false); + public static final ComparisonOperator END_WITH = new ComparisonOperator("=endWith=", false); + + public static Set customOperators() { + Set comparisonOperators = defaultOperators(); + comparisonOperators.addAll(Arrays.asList(LIKE, START_WITH, END_WITH)); + return comparisonOperators; + } + +} diff --git a/src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/handler/EndWithOperatorHandler.java b/src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/handler/EndWithOperatorHandler.java new file mode 100644 index 00000000..b4ce4138 --- /dev/null +++ b/src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/handler/EndWithOperatorHandler.java @@ -0,0 +1,14 @@ +package com.homihq.db2rest.rest.read.processor.rsql.operator.handler; + +import java.util.Map; + +public class EndWithOperatorHandler implements OperatorHandler { + + private static final String OPERATOR = " like "; + + @Override + public String handle(String columnName, String value, Class type, Map paramMap) { + return columnName + OPERATOR + "'%" + value + "'"; + } + +} diff --git a/src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/handler/EqualToOperatorHandler.java b/src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/handler/EqualToOperatorHandler.java new file mode 100644 index 00000000..f23d770f --- /dev/null +++ b/src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/handler/EqualToOperatorHandler.java @@ -0,0 +1,19 @@ +package com.homihq.db2rest.rest.read.processor.rsql.operator.handler; + +import java.util.Map; + +public class EqualToOperatorHandler implements OperatorHandler { + + private static final String OPERATOR = " = "; + + @Override + public String handle(String columnName, String value, Class type, Map paramMap) { + + Object vo = parseValue(value, type); + + paramMap.put(columnName, vo); + + return columnName + OPERATOR + PREFIX + columnName; + } + +} diff --git a/src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/handler/GreaterThanEqualToOperatorHandler.java b/src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/handler/GreaterThanEqualToOperatorHandler.java new file mode 100644 index 00000000..80b60c06 --- /dev/null +++ b/src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/handler/GreaterThanEqualToOperatorHandler.java @@ -0,0 +1,14 @@ +package com.homihq.db2rest.rest.read.processor.rsql.operator.handler; + +import java.util.Map; + +public class GreaterThanEqualToOperatorHandler implements OperatorHandler { + + private static final String OPERATOR = " >= "; + + @Override + public String handle(String columnName, String value, Class type, Map paramMap) { + return columnName + OPERATOR + parseValue(value, type); + } + +} diff --git a/src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/handler/GreaterThanOperatorHandler.java b/src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/handler/GreaterThanOperatorHandler.java new file mode 100644 index 00000000..7091d34d --- /dev/null +++ b/src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/handler/GreaterThanOperatorHandler.java @@ -0,0 +1,14 @@ +package com.homihq.db2rest.rest.read.processor.rsql.operator.handler; + +import java.util.Map; + +public class GreaterThanOperatorHandler implements OperatorHandler { + + private static final String OPERATOR = " > "; + + @Override + public String handle(String columnName, String value, Class type, Map paramMap) { + return columnName + OPERATOR + parseValue(value, type); + } + +} diff --git a/src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/handler/InOperatorHandler.java b/src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/handler/InOperatorHandler.java new file mode 100644 index 00000000..8d839086 --- /dev/null +++ b/src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/handler/InOperatorHandler.java @@ -0,0 +1,22 @@ +package com.homihq.db2rest.rest.read.processor.rsql.operator.handler; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public class InOperatorHandler implements OperatorHandler { + + private static final String OPERATOR = " in "; + + @Override + public String handle(String columnName, String value, Class type, Map paramMap) { + return handle(columnName, Arrays.asList(value), type, paramMap); + } + + @Override + public String handle(String columnName, List values, Class type, Map paramMap) { + return columnName + " in (" + + values.stream().map(value -> parseValue(value, type)).collect(Collectors.joining(",")) + ")"; + } +} diff --git a/src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/handler/LessThanEqualToOperatorHandler.java b/src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/handler/LessThanEqualToOperatorHandler.java new file mode 100644 index 00000000..923910e5 --- /dev/null +++ b/src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/handler/LessThanEqualToOperatorHandler.java @@ -0,0 +1,14 @@ +package com.homihq.db2rest.rest.read.processor.rsql.operator.handler; + +import java.util.Map; + +public class LessThanEqualToOperatorHandler implements OperatorHandler { + + private static final String OPERATOR = " <= "; + + @Override + public String handle(String columnName, String value, Class type, Map paramMap) { + return columnName + OPERATOR + parseValue(value, type); + } + +} diff --git a/src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/handler/LessThanOperatorHandler.java b/src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/handler/LessThanOperatorHandler.java new file mode 100644 index 00000000..f05f3f72 --- /dev/null +++ b/src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/handler/LessThanOperatorHandler.java @@ -0,0 +1,14 @@ +package com.homihq.db2rest.rest.read.processor.rsql.operator.handler; + +import java.util.Map; + +public class LessThanOperatorHandler implements OperatorHandler { + + private static final String OPERATOR = " < "; + + @Override + public String handle(String columnName, String value, Class type, Map paramMap) { + return columnName + OPERATOR + parseValue(value, type); + } + +} diff --git a/src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/handler/LikeOperatorHandler.java b/src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/handler/LikeOperatorHandler.java new file mode 100644 index 00000000..98c4e5a8 --- /dev/null +++ b/src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/handler/LikeOperatorHandler.java @@ -0,0 +1,14 @@ +package com.homihq.db2rest.rest.read.processor.rsql.operator.handler; + +import java.util.Map; + +public class LikeOperatorHandler implements OperatorHandler { + + private static final String OPERATOR = " like "; + + @Override + public String handle(String columnName, String value, Class type, Map paramMap) { + return columnName + OPERATOR + "'%" + value + "%'"; + } + +} diff --git a/src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/handler/NotEqualToOperatorHandler.java b/src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/handler/NotEqualToOperatorHandler.java new file mode 100644 index 00000000..1cc9dcda --- /dev/null +++ b/src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/handler/NotEqualToOperatorHandler.java @@ -0,0 +1,14 @@ +package com.homihq.db2rest.rest.read.processor.rsql.operator.handler; + +import java.util.Map; + +public class NotEqualToOperatorHandler implements OperatorHandler { + + private static final String OPERATOR = " != "; + + @Override + public String handle(String columnName, String value, Class type, Map paramMap) { + return columnName + OPERATOR + parseValue(value, type); + } + +} diff --git a/src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/handler/NotInOperatorHandler.java b/src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/handler/NotInOperatorHandler.java new file mode 100644 index 00000000..a50ea964 --- /dev/null +++ b/src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/handler/NotInOperatorHandler.java @@ -0,0 +1,23 @@ +package com.homihq.db2rest.rest.read.processor.rsql.operator.handler; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public class NotInOperatorHandler implements OperatorHandler { + + private static final String OPERATOR = " not in "; + + @Override + public String handle(String columnName, String value, Class type, Map paramMap) { + return handle(columnName, Arrays.asList(value), type, paramMap); + } + + @Override + public String handle(String columnName, List values, Class type, Map paramMap) { + return columnName + " not in (" + + values.stream().map(value -> parseValue(value, type)).collect(Collectors.joining(",")) + ")"; + } + +} diff --git a/src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/handler/OperatorHandler.java b/src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/handler/OperatorHandler.java new file mode 100644 index 00000000..52ee242e --- /dev/null +++ b/src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/handler/OperatorHandler.java @@ -0,0 +1,31 @@ +package com.homihq.db2rest.rest.read.processor.rsql.operator.handler; + +import java.util.List; +import java.util.Map; + +public interface OperatorHandler { + + String PREFIX = ":"; + + String handle(String columnName, String value, Class type, Map paramMap); + + default String handle(String columnName, List value, Class type, Map paramMap) { + return handle(columnName, value.get(0), type, paramMap); + } + + default String parseValue(String value, Class type) { + + if (String.class == type) { + return "'" + value + "'"; + } + else if (Boolean.class == type || boolean.class == type) { + Boolean aBoolean = Boolean.valueOf(value); + return aBoolean ? "1" : "0"; + } + else { + return value; + } + + } + +} diff --git a/src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/handler/RSQLOperatorHandlers.java b/src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/handler/RSQLOperatorHandlers.java new file mode 100644 index 00000000..6a7704ed --- /dev/null +++ b/src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/handler/RSQLOperatorHandlers.java @@ -0,0 +1,32 @@ +package com.homihq.db2rest.rest.read.processor.rsql.operator.handler; + + +import static com.homihq.db2rest.rest.read.processor.rsql.operator.CustomRSQLOperators.*; +import static cz.jirutka.rsql.parser.ast.RSQLOperators.*; + +import java.util.HashMap; +import java.util.Map; + +public class RSQLOperatorHandlers { + + private static final Map OPERATOR_HANDLER_MAP = new HashMap<>(); + + static { + OPERATOR_HANDLER_MAP.put(EQUAL.getSymbol(), new EqualToOperatorHandler()); + OPERATOR_HANDLER_MAP.put(NOT_EQUAL.getSymbol(), new NotEqualToOperatorHandler()); + OPERATOR_HANDLER_MAP.put(IN.getSymbol(), new InOperatorHandler()); + OPERATOR_HANDLER_MAP.put(NOT_IN.getSymbol(), new NotInOperatorHandler()); + OPERATOR_HANDLER_MAP.put(GREATER_THAN.getSymbol(), new GreaterThanOperatorHandler()); + OPERATOR_HANDLER_MAP.put(GREATER_THAN_OR_EQUAL.getSymbol(), new GreaterThanEqualToOperatorHandler()); + OPERATOR_HANDLER_MAP.put(LESS_THAN.getSymbol(), new LessThanOperatorHandler()); + OPERATOR_HANDLER_MAP.put(LESS_THAN_OR_EQUAL.getSymbol(), new LessThanEqualToOperatorHandler()); + OPERATOR_HANDLER_MAP.put(LIKE.getSymbol(), new LikeOperatorHandler()); + OPERATOR_HANDLER_MAP.put(START_WITH.getSymbol(), new StartWithOperatorHandler()); + OPERATOR_HANDLER_MAP.put(END_WITH.getSymbol(), new EndWithOperatorHandler()); + + } + + public static OperatorHandler getOperatorHandler(String symbol) { + return OPERATOR_HANDLER_MAP.get(symbol); + } +} diff --git a/src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/handler/StartWithOperatorHandler.java b/src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/handler/StartWithOperatorHandler.java new file mode 100644 index 00000000..d1ed083d --- /dev/null +++ b/src/main/java/com/homihq/db2rest/rest/read/processor/rsql/operator/handler/StartWithOperatorHandler.java @@ -0,0 +1,14 @@ +package com.homihq.db2rest.rest.read.processor.rsql.operator.handler; + +import java.util.Map; + +public class StartWithOperatorHandler implements OperatorHandler { + + private static final String OPERATOR = " like "; + + @Override + public String handle(String columnName, String value, Class type, Map paramMap) { + return columnName + OPERATOR + "'" + value + "%'"; + } + +} diff --git a/src/main/java/com/homihq/db2rest/rest/read/processor/rsql/parser/RSQLParserBuilder.java b/src/main/java/com/homihq/db2rest/rest/read/processor/rsql/parser/RSQLParserBuilder.java new file mode 100644 index 00000000..10de18d8 --- /dev/null +++ b/src/main/java/com/homihq/db2rest/rest/read/processor/rsql/parser/RSQLParserBuilder.java @@ -0,0 +1,13 @@ +package com.homihq.db2rest.rest.read.processor.rsql.parser; + +import com.homihq.db2rest.rest.read.processor.rsql.operator.CustomRSQLOperators; + +import cz.jirutka.rsql.parser.RSQLParser; + +public class RSQLParserBuilder { + + public static RSQLParser newRSQLParser(){ + return new RSQLParser(CustomRSQLOperators.customOperators()); + } + +} diff --git a/src/main/java/com/homihq/db2rest/rest/read/processor/rsql/visitor/BaseRSQLVisitor.java b/src/main/java/com/homihq/db2rest/rest/read/processor/rsql/visitor/BaseRSQLVisitor.java new file mode 100644 index 00000000..07ee9cad --- /dev/null +++ b/src/main/java/com/homihq/db2rest/rest/read/processor/rsql/visitor/BaseRSQLVisitor.java @@ -0,0 +1,79 @@ +package com.homihq.db2rest.rest.read.processor.rsql.visitor; + +import com.homihq.db2rest.exception.InvalidColumnException; +import com.homihq.db2rest.rest.read.model.DbColumn; +import com.homihq.db2rest.rest.read.model.DbWhere; +import com.homihq.db2rest.rest.read.processor.rsql.operator.handler.OperatorHandler; +import com.homihq.db2rest.rest.read.processor.rsql.operator.handler.RSQLOperatorHandlers; +import cz.jirutka.rsql.parser.ast.AndNode; +import cz.jirutka.rsql.parser.ast.ComparisonNode; +import cz.jirutka.rsql.parser.ast.ComparisonOperator; +import cz.jirutka.rsql.parser.ast.OrNode; +import cz.jirutka.rsql.parser.ast.RSQLVisitor; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; + +import java.util.stream.Collectors; + +@RequiredArgsConstructor +@Slf4j +public class BaseRSQLVisitor implements RSQLVisitor { + + private final DbWhere dbWhere; + + @Override + public String visit(AndNode andNode, Object o) { + return "( " + andNode.getChildren().stream().map(node -> node.accept(this)) + .collect(Collectors.joining(" AND ")) + " ) "; + } + + @Override + public String visit(OrNode orNode, Object o) { + return "( " + + orNode.getChildren().stream().map(node -> node.accept(this)).collect(Collectors.joining(" OR ")) + + " ) "; + } + + @Override + public String visit(ComparisonNode node, Object o) { + ComparisonOperator op = node.getOperator(); + + DbColumn sqlColumn = getColumn(node.getSelector()); + + if (sqlColumn == null) { + throw new IllegalArgumentException(String.format("Field '%s' is invalid", node.getSelector())); + } + + Class type = sqlColumn.column().getType().getTypeMappedClass(); + + String queryColumnName = sqlColumn.name(); + + OperatorHandler operatorHandler = RSQLOperatorHandlers.getOperatorHandler(op.getSymbol()); + if (operatorHandler == null) { + throw new IllegalArgumentException(String.format("Operator '%s' is invalid", op.getSymbol())); + } + + if (op.isMultiValue()) { + return operatorHandler.handle(queryColumnName, node.getArguments(), type, this.dbWhere.paramMap()); + } + else { + return operatorHandler.handle(queryColumnName, node.getArguments().get(0), type, this.dbWhere.paramMap()); + } + + } + + + public DbColumn getColumn(String col) { + return + this.dbWhere.columns() + .stream() + .filter(dbColumn -> + StringUtils.equalsIgnoreCase(this.dbWhere.tableName(), dbColumn.tableName()) + && + StringUtils.equalsIgnoreCase(dbColumn.name(), col) + ).findFirst() + .orElseThrow(() -> new InvalidColumnException(this.dbWhere.tableName(), col)); + } + +}