com.sap.cds.ql.cqn.Modifier Maven / Gradle / Ivy
/************************************************************************
* © 2021-2024 SAP SE or an SAP affiliate company. All rights reserved. *
************************************************************************/
package com.sap.cds.ql.cqn;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import com.google.common.annotations.Beta;
import com.sap.cds.ql.BooleanFunction;
import com.sap.cds.ql.CQL;
import com.sap.cds.ql.FilterableStatement;
import com.sap.cds.ql.Predicate;
import com.sap.cds.ql.Select;
import com.sap.cds.ql.StructuredType;
import com.sap.cds.ql.Then;
import com.sap.cds.ql.Value;
import com.sap.cds.ql.cqn.CqnCaseExpression.Case;
/**
* Provider interface for modifying CQN {@link CqnPredicate Predicates},
* {@link CqnValue Values} and {@link CqnStatement Statements} copied with
* {@link CQL#copy(CqnStatement, Modifier) CQL.copy}.
*
* Override the default methods to replace specific parts of the statement /
* predicate.
*/
public interface Modifier {
/**
* Override this method to replace a {@link CqnStructuredTypeRef structured type
* ref}.
*
* @param ref the immutable {@link CqnStructuredTypeRef}
* @return the replacement ref
*
* @see CQL#to(List) CQL.to(segments).asRef() to create a new ref
* @see CQL#copy(CqnStructuredTypeRef) CQL.copy(ref) to create a modifiable copy
* of the ref
*/
default CqnStructuredTypeRef ref(CqnStructuredTypeRef ref) {
return ref;
}
/**
* Override this method to replace an {@link CqnElementRef element} ref with
* another {@link CqnValue}.
*
* @param ref the immutable {@link CqnElementRef}
* @return a {@link CqnValue value} replacing the ref
*
* @see CQL#get(List) CQL.get(segments) to create a new ref
* @see CQL#copy(CqnElementRef) CQL.copy(ref) to create a modifiable copy of the
* ref
*/
default CqnValue ref(CqnElementRef ref) {
return ref;
}
/**
* Override this method to replace a {@link CqnLiteral literal} value with
* another {@link CqnValue}.
*
* @param value the immutable {@link CqnLiteral} value
* @return a {@link CqnValue value} replacing the {@link CqnLiteral}
*
* @see CQL#val
* @see CQL#constant
*/
default CqnValue literal(CqnLiteral> value) {
return value;
}
/**
* Override this method to replace {@link CqnParameter parameters}.
*
* @param param the {@link CqnParameter}
* @return a {@link CqnValue} replacing the {@code parameter}
*/
default CqnValue parameter(CqnParameter param) {
return param;
}
@Beta
default CqnValue plain(CqnPlain plain) {
return plain;
}
/**
* Override this method to replace a {@link CqnListValue list} value with
* another {@link CqnValue}.
*
* @param values the list of {@link CqnValue values}
* @return a {@link CqnValue} replacing the {@link CqnListValue}
*
* @see CQL#list
*/
default CqnValue list(List> values) {
return CQL.list(values);
}
/**
* Override this method to replace an {@link CqnArithmeticExpression arithmetic}
* expression.
*
* @param left the left-hand side of the expression
* @param op the operator
* @param right the right-hand side of the expression
* @param type the return type of the expression
* @return a {@link CqnValue} replacing the arithmetic expression
*
* @see CQL#expression
*/
default CqnValue expression(Value left, CqnArithmeticExpression.Operator op, Value right,
String type) {
return CQL.expression(left, op, right).type(type);
}
/**
* Override this method to replace an {@link CqnCaseExpression case}
* expression.
*
* @param cases the cases
* @param defaultValue the default value
* @param type the return type of the expression
* @return a {@link CqnValue} replacing the case expression
*/
@Beta
default CqnValue caseExpression(List cases, CqnValue defaultValue, String type) {
Then builder = CQL.cases();
for (Case c : cases) {
builder = builder.when(c.condition()).then(c.value());
}
return builder.orElse(defaultValue).type(type);
}
/**
* Override this method to replace a {@link CqnFunc function} call.
*
* @param name the name of the function
* @param args the arguments of the function
* @param type the return type of the function call
* @return a {@link CqnValue} replacing the function call
*
* @see CQL#func
*/
default CqnValue function(String name, List> args, String type) {
return CQL.func(name, args).type(type);
}
/**
* Override this method to replace a predicate {@link BooleanFunction function}
* call.
*
* @param name the name of the function
* @param args the arguments of the function
* @return a {@link CqnPredicate} replacing the Boolean function call
*
* @see CQL#booleanFunc
*/
default CqnPredicate booleanFunction(String name, List> args) {
return CQL.booleanFunc(name, args);
}
/**
* Override this method to replace a {@link CqnComparisonPredicate comparison}
* predicate.
*
* @param lhs the left-hand side of the comparison
* @param op the comparison operator
* @param rhs the right-hand side of the comparison
* @return a {@link CqnPredicate} replacing the comparison
*
* @see CQL#comparison
*/
default CqnPredicate comparison(Value> lhs, CqnComparisonPredicate.Operator op, Value> rhs) {
return CQL.comparison(lhs, op, rhs);
}
/**
* Override this method to replace an {@link CqnInPredicate in} predicate that
* checks if the given {@code value} is equal to any value in the
* {@code valueSet}.
*
* @param value the value to be checked if it's contained in the set
* @param valueSet the {@link CqnInPredicate#valueSet() value set}
* @return a {@link CqnPredicate} replacing the {@link CqnInPredicate}
*
* @see CQL#in
*/
default CqnPredicate in(Value> value, CqnValue valueSet) {
return CQL.in(value, valueSet);
}
/**
* Override this method to replace an {@link CqnInSubquery in subquery}
* predicate that checks if the given {@code value} is equal to any value
* returned by the subquery.
*
* @param inSubquery
* the in subquery predicate
* @return a {@link CqnPredicate} replacing the {@link CqnInSubquery}
*/
@Beta
default CqnPredicate in(CqnInSubquery inSubquery) {
return inSubquery;
}
/**
* Override this method to replace a {@link CqnBetweenPredicate between}
* predicate that that tests if this {@code value} is within a closed interval
* with given bounds of {@code low} and {@code high}.
*
* @param value the value to be checked if it's contained in a closed interval
* @param low the lower bound
* @param high the upper bound
* @return a {@link CqnPredicate} replacing the {@link CqnBetweenPredicate}
*
* @see CQL#between
*/
default CqnPredicate between(CqnValue value, CqnValue low, CqnValue high) {
return CQL.between(value, low, high);
}
/**
* Override this method to replace a {@link CqnPredicate eTag} predicate that
* checks if an ETag matches any value from the given {@code values} list.
*
* @param values the list of values
* @return a {@link CqnPredicate} replacing the {@link CqnEtagPredicate}
*/
@Beta
default CqnPredicate eTag(CqnElementRef ref, CqnListValue values) {
return CQL.eTag(ref, values);
}
/**
* Override this method to replace a logical {@link CqnConnectivePredicate
* connection} predicate, which connects multiple predicates with the given
* {@link CqnConnectivePredicate.Operator operator}.
*
* @param op the connective operator ({@code AND}/{@code OR})
* @param predicates the list of connected predicates
* @return a {@link CqnPredicate} replacing the logical connection
*
* @see CQL#connect
* @see CQL#and
* @see CQL#or
*/
default CqnPredicate connective(CqnConnectivePredicate.Operator op, List predicates) {
return CQL.connect(op, predicates);
}
/**
* Override this method to replace a logical {@link CqnNegation negation}.
*
* @param predicate the {@link CqnNegation#predicate() predicate} of the
* negation
* @return a {@link CqnPredicate} replacing the negation
*
* @see CQL#not
*/
default CqnPredicate negation(Predicate predicate) {
return CQL.not(predicate);
}
/**
* Override this method to replace an {@link CqnExistsSubquery exist} subquery.
*
* @param subQuery the {@link CqnExistsSubquery#subquery() query} of the exists
* predicate
* @return a {@link CqnPredicate} replacing the {@link CqnExistsSubquery}
*
* @see CQL#exists
*/
default CqnPredicate exists(Select> subQuery) {
return CQL.exists(subQuery);
}
/**
* Override this method to replace a {@link CqnMatchPredicate match} predicate.
*
* @param match the {@code match} predicate
* @return a {@link CqnPredicate} replacing the {@link CqnMatchPredicate}
*
* @see CQL#match
*/
default CqnPredicate match(CqnMatchPredicate match) {
return match;
}
/**
* Override this method to replace a {@link CqnContainmentTest containment} test
* predicate.
*
* @param position the {@link CqnContainmentTest#position() position}
* @param value the string {@link CqnContainmentTest#value() value}
* @param term the {@link CqnContainmentTest#term() term} to test for
* @param caseInsensitive whether the test should be
* {@link CqnContainmentTest#caseInsensitive() case
* insensitive}
* @return a {@link CqnPredicate} replacing the {@link CqnContainmentTest}
*
* @see CQL#containment
*/
default CqnPredicate containment(CqnContainmentTest.Position position, CqnValue value, CqnValue term,
boolean caseInsensitive) {
return CQL.containment(position, value, term, caseInsensitive);
}
/**
* Override this method to replace a {@link CqnSearchTermPredicate search}
* predicate.
*
* @param search the search term predicate
* @return a {@link CqnPredicate} replacing the {@link CqnSearchTermPredicate}
*
* @see CQL#search
*/
default CqnPredicate searchTerm(CqnSearchTermPredicate search) {
return search(search.searchTerm());
}
/**
* @deprecated use {@link #searchTerm(CqnSearchTermPredicate)} instead
*/
@Deprecated(since = "3.0", forRemoval = true)
default CqnPredicate search(String term) {
return CQL.search(term);
}
/**
* Override this method to replace a {@link CqnPassThroughSearchPredicate search}
* predicate.
*
* @param search the pass-through search predicate
* @return a {@link CqnPredicate} replacing the {@link CqnPassThroughSearchPredicate}
*/
default CqnPredicate passThroughSearch(CqnPassThroughSearchPredicate search) {
return search;
}
/*
* Select modifier methods.
*/
/**
* Override this method to set the {@link FilterableStatement#where() where}
* clause of {@link FilterableStatement filterable} statements.
*
* @param where the {@code where} clause of the statement, or null
* @return a {@link CqnPredicate} replacing the where clause
*/
default CqnPredicate where(Predicate where) {
return where;
}
/**
* Override this method to set the {@link CqnSelect#search() search} clause of
* {@link CqnSelect Select} statements.
*
* @param search the {@code search} clause of the statement, or null
* @return a {@link CqnPredicate} replacing the search clause
*/
default CqnPredicate search(Predicate search) {
return search;
}
/**
* Override this method to set the
* {@link Select#search(java.util.function.Function, Iterable) searchable}
* elements of {@link CqnSelect Select} statements.
*
* @param searchableElements the searchable elements of the statement
* @return the set of searchable elements
*/
default Set searchableElements(Set searchableElements) {
return searchableElements;
}
/**
* Override this method to replace {@link CqnInline inline} lists.
*
* Use {@link StructuredType#inline(Iterable) CQL.to(segments).inline(items)} to
* create a new {@code inline}.
*
* @param inline the {@link CqnInline}
* @return a {@link CqnSelectListItem} replacing the {@code inline}
*/
default CqnSelectListItem inline(CqnInline inline) {
return inline;
}
/**
* Override this method to replace {@link CqnExpand expand} lists.
*
* To create a new expand, use {@link StructuredType#expand(Iterable)
* CQL.to(segments).expand(items)}. To create a modifiable copy of the expand,
* use {@link CQL#copy(CqnExpand) CQL.copy(expand)}.
*
* @param expand the {@link CqnExpand}
* @return a {@link CqnSelectListItem} replacing the {@code expand}
*/
default CqnSelectListItem expand(CqnExpand expand) {
return expand;
}
/**
* Override this method to replace {@link CqnSelectListValue values} on the
* select list of {@link CqnSelect Select} statements.
*
* @param value the value
* @param alias the alias
* @return a {@link CqnSelectListItem} replacing the {@code value}
*/
@Beta
default CqnSelectListItem selectListValue(Value> value, String alias) {
return value.as(alias);
}
/**
* Override this method to replace {@link CqnStar asterisk} (*) on the select
* list of {@link CqnSelect Select} statements.
*
* @return a {@link CqnSelectListItem} replacing the {@code asterisk}
*/
default List selectAll() {
return new ArrayList<>(0);
}
/**
* Override this method to modify the select list {@link CqnSelect#items()
* items} of {@link CqnSelect Select} statements.
*
* @param items the list of selected {@link CqnSelectListItem items}
* @return the new list of items
*/
default List items(List items) {
return items;
}
/**
* Override this method to modify the {@link CqnSelect#excluding() exclude list}
* of {@link CqnSelect Select} statements.
*
* @param excluding the names of the excluded elements
* @return a set of names to be excluded from the Select result
*/
default Set excluding(Set excluding) {
return excluding;
}
/**
* Override this method to modify the {@link CqnSelect#groupBy() groupBy} clause
* of {@link CqnSelect Select} statements.
*
* @param values the groupBy list of the Select statement
* @return a list of values to group by
*/
default List groupBy(List values) {
return values;
}
/**
* Override this method to modify the {@link CqnSelect#having() having} clause
* of {@link CqnSelect Select} statements.
*
* @param having the having clause of the Select statement
* @return a {@link Predicate} replacing the having clause
*/
@Beta
default CqnPredicate having(Predicate having) {
return having;
}
/**
* Override this method to modify the {@link CqnSelect#orderBy() orderBy} clause
* of {@link CqnSelect Select} statements.
*
* @param sortSpecs the orderBy list of the Select statement
* @return a list of {@link CqnSortSpecification} defining the order of the
* result
*/
default List orderBy(List sortSpecs) {
return sortSpecs;
}
/**
* Override this method to replace specific {@link CqnSortSpecification sort}
* specs in the {@link CqnSelect#orderBy() orderBy} clause of {@link CqnSelect
* Select} statements.
*
* @param value the value of the sort spec
* @param order the sort {@link CqnSortSpecification.Order order}
* @return a sort spec
*
* @see CQL#sort
*/
default CqnSortSpecification sort(Value> value, CqnSortSpecification.Order order) {
return CQL.sort(value, order);
}
/**
* Override this method to set the {@link CqnSelect#isDistinct() distinct} flag
* of {@link CqnSelect Select} statements.
*
* @param distinct the {@code distinct} flag of the Select statement
* @return the new {@code distinct} flag
*/
default boolean distinct(boolean distinct) {
return distinct;
}
/**
* Override this method to set the {@link CqnSelect#hasInlineCount() inline
* count} flag of {@link CqnSelect Select} statements.
*
* @param inlineCount the {@code inline count} flag of the Select statement
* @return the new {@code inline count} flag
*/
default boolean inlineCount(boolean inlineCount) {
return inlineCount;
}
/**
* Override this method to set the {@link Select#limit(long) top} limit of
* {@link CqnSelect Select} statements.
*
* @param top the {@code top} limit of the Select statement
* @return the new maximum number of rows to be selected or -1 for unlimited
*/
default long top(long top) {
return top;
}
/**
* Override this method to set {@link Select#limit(long, long) skip} of
* {@link CqnSelect Select} statements.
*
* @param skip the {@code skip} number of the Select statement
* @return the new number of rows that shall be skipped
*/
default long skip(long skip) {
return skip;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy