
com.sap.cds.ql.CQL Maven / Gradle / Ivy
The newest version!
/************************************************************************
* © 2020-2024 SAP SE or an SAP affiliate company. All rights reserved. *
************************************************************************/
package com.sap.cds.ql;
import static java.util.Arrays.asList;
import java.time.Instant;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collector;
import com.google.common.annotations.Beta;
import com.sap.cds.ql.cqn.CqnArithmeticExpression;
import com.sap.cds.ql.cqn.CqnBetweenPredicate;
import com.sap.cds.ql.cqn.CqnCaseExpression;
import com.sap.cds.ql.cqn.CqnComparisonPredicate;
import com.sap.cds.ql.cqn.CqnConnectivePredicate;
import com.sap.cds.ql.cqn.CqnConnectivePredicate.Operator;
import com.sap.cds.ql.cqn.CqnContainmentTest;
import com.sap.cds.ql.cqn.CqnContainmentTest.Position;
import com.sap.cds.ql.cqn.CqnElementRef;
import com.sap.cds.ql.cqn.CqnEtagPredicate;
import com.sap.cds.ql.cqn.CqnExpand;
import com.sap.cds.ql.cqn.CqnInPredicate;
import com.sap.cds.ql.cqn.CqnListValue;
import com.sap.cds.ql.cqn.CqnMatchPredicate;
import com.sap.cds.ql.cqn.CqnPredicate;
import com.sap.cds.ql.cqn.CqnReference.Segment;
import com.sap.cds.ql.cqn.CqnSelect;
import com.sap.cds.ql.cqn.CqnSortSpecification;
import com.sap.cds.ql.cqn.CqnSortSpecification.Order;
import com.sap.cds.ql.cqn.CqnStar;
import com.sap.cds.ql.cqn.CqnStatement;
import com.sap.cds.ql.cqn.CqnStructuredTypeRef;
import com.sap.cds.ql.cqn.CqnValue;
import com.sap.cds.ql.cqn.CqnVector;
import com.sap.cds.ql.cqn.Modifier;
public interface CQL {
BooleanValue TRUE = CDS.QL.create.booleanValue(true);
BooleanValue FALSE = CDS.QL.create.booleanValue(false);
NullValue NULL = CDS.QL.create.nullValue();
/**
* Creates a {@link RefBuilder} from the given ref, which allows for in-place
* modification of the ref.
*
* @param ref the ref to be copied
* @return the ref builder
*/
static RefBuilder copy(CqnStructuredTypeRef ref) {
return CDS.QL.builder.copy(ref);
}
/**
* Creates a {@link RefBuilder} from the given ref, which allows for in-place
* modification of the ref.
*
* @param ref the element ref to be copied
* @return the ref builder
*/
static RefBuilder> copy(CqnElementRef ref) {
return CDS.QL.builder.copy(ref);
}
/**
* Creates a copy of the given expand.
*
* @param expand the expand to be copied
* @return the copy
*/
static Expand> copy(CqnExpand expand) {
return CDS.QL.builder.copy(expand);
}
/**
* Creates a copy of the given predicate.
*
* @param pred the predicate to be copied
* @return the copy
*/
static Predicate copy(CqnPredicate pred) {
return CDS.QL.builder.copy(pred);
}
/**
* Creates a modified copy of the given predicate.
*
* @param pred the predicate to be copied
* @param modifier the modifier for altering the copy
* @return the modified copy
*/
static Predicate copy(CqnPredicate pred, Modifier modifier) {
return CDS.QL.builder.copy(pred, modifier);
}
/**
* Creates a copy of the given CQN statement.
*
* @param the type of CqnStatement
* @param statement the CQN statement to be copied
* @return the copy
*/
static S copy(S statement) {
return CDS.QL.builder.copy(statement);
}
/**
* Creates a modified copy of the given CQN statement.
*
* @param the type of CqnStatement
* @param statement the CQN statement to be copied
* @param modifier the modifier for altering the copy
* @return the modified copy
*/
static S copy(S statement, Modifier modifier) {
return CDS.QL.builder.copy(statement, modifier);
}
/**
* Creates a CDS QL function call that is send to the underlying data store.
*
* @param the return type of the function call
* @param name the name of the function to be called
* @param args the arguments of the function
* @return the CDS QL function call
*/
static FunctionCall func(String name, CqnValue... args) {
return func(name, asList(args));
}
/**
* Creates a CDS QL function call that is send to the underlying data store.
*
* @param the return type of the function call
* @param name the name of the function to be called
* @param args the arguments of the function
* @return the CDS QL function call
*/
static FunctionCall func(String name, List extends CqnValue> args) {
return CDS.QL.create.func(name, args);
}
/**
* Creates a CDS QL function call that is send to the underlying data store.
*
* @param name the name of the function to be called
* @param args the arguments of the function
* @return the CDS QL function call
*/
static BooleanFunction booleanFunc(String name, List extends CqnValue> args) {
return CDS.QL.create.booleanFunc(name, args);
}
/**
* Creates a {@link Value} of type {@link T} with a hint that the value should
* be treated as constant.
*
* @param the type of the constant
* @param value the value
* @return the constant
*/
static Literal constant(T value) {
return CDS.QL.create.constant(value);
}
/**
* Creates a {@link Value} of type {@link T}.
*
* @param the type of the non-constant value
* @param value the value of the non-constant value
* @return the value
* @see #param(String)
*/
static Literal val(T value) {
return CDS.QL.create.val(value);
}
/**
* Creates a new {@link CqnVector} which can be used in vector functions such as
* {@link #cosineSimilarity} and {@link #l2Distance}.
*
* @param vector the vector as float[] or in String format
* @return the {@link CqnVector}
*/
@Beta
static CqnVector vector(Object vector) {
return CDS.QL.create.vector(vector);
}
/**
* Negates a given {@link CqnPredicate}.
*
* @param predicate the {@code CqnPredicate} to be negated
* @return the negated predicate
*/
static Predicate not(CqnPredicate predicate) {
return CDS.QL.create.not(predicate);
}
/**
* Creates a conjunction of two given predicates
*
* @param p1 1st operand of the conjunction
* @param p2 2nd operand of the conjunction
* @return the conjunction
*/
static Predicate and(CqnPredicate p1, CqnPredicate p2) {
return and(asList(p1, p2));
}
/**
* Returns a {@link Collector} that connects the input predicates with AND.
*
* If there are none the {@link Collector} returns TRUE.
*
* @return the collector
*/
static Collector withAnd() {
return CDS.QL.create.withAnd();
}
/**
* Creates a disjunction of two given predicates
*
* @param p1 1st operand of the disjunction
* @param p2 2nd operand of the disjunction
* @return the disjunction
*/
static Predicate or(CqnPredicate p1, CqnPredicate p2) {
return or(asList(p1, p2));
}
/**
* Creates a conjunction of given predicates
*
* @param predicates the predicates to connect
* @return the conjunction
*/
static Predicate and(Iterable extends CqnPredicate> predicates) {
return connect(Operator.AND, predicates);
}
/**
* Creates a disjunction of given predicates
*
* @param predicates the predicates to connect
* @return the disjunction
*/
static Predicate or(Iterable extends CqnPredicate> predicates) {
return connect(Operator.OR, predicates);
}
/**
* Returns a {@link Collector} that connects the input predicates with OR.
*
* If there are none the {@link Collector} returns FALSE.
*
* @return the collector
*/
static Collector withOr() {
return CDS.QL.create.withOr();
}
/**
* Creates a logical connection of given predicates {@link CqnPredicate}.
*
* @param operator operator to connect the predicates with
* @param predicates the predicates to connect
* @return the logical connection
*/
static Predicate connect(CqnConnectivePredicate.Operator operator, Iterable extends CqnPredicate> predicates) {
return CDS.QL.create.connect(operator, predicates);
}
/**
* Creates an indexed {@link Parameter} to be used in CQN statements. Can be
* used with positional parameter values.
*
* @param the type of the parameter
* @param index the parameter index. If used with positional parameter values,
* start with 0 for the first parameter
* @return the parameter
*/
static Parameter param(int index) {
return param(String.valueOf(index));
}
/**
* Creates a named {@link Parameter} to be used in queries.
*
* @param the type of the parameter
* @param name the parameter name
* @return the parameter
*/
static Parameter param(String name) {
return CDS.QL.create.param(name);
}
/**
* Creates a CQN plain value, which is directly send to the underlying data
* store.
*
* @param value the value content
* @return the plain value
*/
static Value> plain(String value) {
return CDS.QL.create.plain(value);
}
/**
* Creates a count all function call.
*
* @return the count value
*/
static Value count() {
return func("COUNT");
}
/**
* Creates a count function call on the given element.
*
* @param element the ref to the element to be counted
* @return the count value
*/
static Value count(CqnElementRef element) {
return func("COUNT", element);
}
/**
* Creates a min function call on the given element or expression.
*
* @param the type of the value
* @param value the ref to the element to be counted or an expression
* @return the minimum value
*/
static Value min(CqnValue value) {
return func("min", value);
}
/**
* Creates a max function call on the given element or expression.
*
* @param the type of the value
* @param value the ref to the element to be counted or an expression
* @return the maximum value
*/
static Value max(CqnValue value) {
return func("max", value);
}
/**
* Creates a sum function call on the given element or expression.
*
* @param value the ref to the element to be counted or an expression
* @return the sum value
*/
static Value sum(CqnValue value) {
return func("sum", value);
}
/**
* Creates an average function call on the given element or expression.
*
* @param value the ref to the element to be counted or an expression
* @return the average value
*/
static Value average(CqnValue value) {
return func("avg", value);
}
/**
* Creates an count distinct function call on the given element or expression.
*
* @param value the ref to the element to be counted or an expression
* @return the count of distinct values
*/
static Value countDistinct(CqnValue value) {
return CDS.QL.create.countDistinct(value);
}
/**
* Creates a predicate that tests whether a string value contains a given
* substring
*
* @param value the string value
* @param substring the substring to test for
* @param caseInsensitive whether the test should be case insensitive
* @return the predicate for the containment test
*/
static Predicate contains(CqnValue value, CqnValue substring, boolean caseInsensitive) {
return CDS.QL.create.containment(Position.ANY, value, substring, caseInsensitive);
}
/**
* Creates a predicate that tests whether a string value starts with a given
* prefix
*
* @param value the string value
* @param prefix the prefix to test for
* @param caseInsensitive whether the test should be case insensitive
* @return the predicate for the containment test
*/
static Predicate startsWith(CqnValue value, CqnValue prefix, boolean caseInsensitive) {
return CDS.QL.create.containment(Position.START, value, prefix, caseInsensitive);
}
/**
* Creates a predicate that tests whether a string value ends with a given
* suffix
*
* @param value the string value
* @param suffix the suffix to test for
* @param caseInsensitive whether the test should be case insensitive
* @return the predicate for the containment test
*/
static Predicate endsWith(CqnValue value, CqnValue suffix, boolean caseInsensitive) {
return CDS.QL.create.containment(Position.END, value, suffix, caseInsensitive);
}
/**
* Creates a predicate that tests whether a string value contains a given
* substring at a given position {@link CqnContainmentTest.Position}
*
* @param position the position
* @param value the string value
* @param substring the substring to test for
* @param caseInsensitive whether the test should be case insensitive
* @return the predicate for the containment test
*/
static Predicate containment(CqnContainmentTest.Position position, CqnValue value, CqnValue substring,
boolean caseInsensitive) {
return CDS.QL.create.containment(position, value, substring, caseInsensitive);
}
/**
* Creates a CDS QL expression for converting the given string value to lower
* case using the rules of the underlying data store.
*
* @param val the String value to be converted
* @return the CDS QL expression for lower case conversion
*/
static Value toLower(Value val) {
return CDS.QL.create.toLower(val);
}
/**
* Creates a CDS QL expression for converting the given string value to lower
* case using the rules of the underlying data store.
*
* @param val the String value to be converted
* @return the CDS QL expression for lower case conversion
*/
static Value toLower(String val) {
return CDS.QL.create.toLower(val(val));
}
/**
* Creates a CDS QL expression for converting the given string value to upper
* case using the rules of the underlying data store.
*
* @param val the String value to be converted
* @return the CDS QL expression for upper case conversion
*/
static Value toUpper(Value val) {
return CDS.QL.create.toUpper(val);
}
/**
* Creates a CDS QL expression for converting the given string value to upper
* case using the rules of the underlying data store.
*
* @param val the String value to be converted
* @return the CDS QL expression for upper case conversion
*/
static Value toUpper(String val) {
return CDS.QL.create.toUpper(val(val));
}
/**
* Creates a CDS QL function to compute the cosine similarity of two vectors.
*
* @param vector1 the first vector
* @param vector2 the second vector
* @return the cosine similarity function
*/
static Value cosineSimilarity(CqnValue vector1, CqnValue vector2) {
return CDS.QL.create.cosineSimilarity(vector1, vector2);
}
/**
* Creates a CDS QL function to compute the L2 distance of two
* vectors.
*
* @param vector1 the first vector
* @param vector2 the second vector
* @return the L2 distance function
*/
static Value l2Distance(CqnValue vector1, CqnValue vector2) {
return CDS.QL.create.l2Distance(vector1, vector2);
}
/**
* Creates a {@link StructuredType} representing a CDS entity.
*
* @param qualifiedName the qualified name of the CDS entity
* @return the {@code StructuredType} representing the CDS entity
*/
static StructuredType> entity(String qualifiedName) {
return CDS.QL.create.entity(qualifiedName);
}
/**
* Creates a {@link StructuredType} representing a CDS entity.
*
* @param the type of the entity
* @param type the class of the entity type
* @return the {@code StructuredType} representing the CDS entity
*/
static > T entity(Class type) {
return CDS.QL.create.entity(type);
}
/**
* Creates a {@link StructuredType} representing a path from a CDS entity to
* another entity.
*
* @param path a String of association element names separated by '.'
* @return the {@code StructuredType} representing the path to a CDS entity
*/
static StructuredType> to(String path) {
return CDS.QL.create.to(path);
}
/**
* Creates a {@link StructuredType} representing a path from a CDS entity to
* another entity.
*
* To create a {@link StructuredTypeRef}, use {@link StructuredType#asRef()
* CQL.to(segments).asRef()}.
*
* @param segments the segments of the path
* @return the {@code StructuredType} representing the path to a CDS entity
*/
static StructuredType> to(List extends Segment> segments) {
return CDS.QL.create.to(segments);
}
/**
* Creates an {@link ElementRef} representing a path from a CDS entity to an
* element of this or another entity.
*
* @param the type of the element
* @param path a String of element names separated by '.', where all except the
* last segment represent association elements.
* @return the {@code ElementRef} representing the path to the CDS element
*/
static ElementRef get(String path) {
return CDS.QL.create.get(path);
}
/**
* Creates an {@link ElementRef} representing a path from a CDS entity to an
* element of this or another entity.
*
* @param the type of the element
* @param segments the segments of the path
* @return the {@code ElementRef} representing the path to the CDS element
*/
static ElementRef get(List extends Segment> segments) {
return CDS.QL.create.get(segments);
}
/**
* Creates a segment of a structured type or element reference without filter.
*
* Use {@link #refSegment(String, CqnPredicate)} to create a segment with filter
* condition.
*
* @param id the id of the segment
* @return the segment
*/
static Segment refSegment(String id) {
return CDS.QL.create.refSegment(id);
}
/**
* Creates a segment of a structured type or element reference with a filter
* condition.
*
* @param id the id of the segment
* @param filter the filter of the segment
* @return the segment
*/
static Segment refSegment(String id, CqnPredicate filter) {
return CDS.QL.create.refSegment(id, filter);
}
/**
* Creates a list of reference segments without filter.
*
* @param segmentIds the ids of the segments
* @return the segments
*/
static List refSegments(List segmentIds) {
return CDS.QL.create.refSegments(segmentIds);
}
/**
* Creates an arithmetic expression.
*
* @param left the left-hand side of the expression
* @param op the operator
* @param right the right-hand side of the expression
* @return the arithmetic expression
*/
static Value expression(CqnValue left, CqnArithmeticExpression.Operator op, CqnValue right) {
return CDS.QL.create.expression(left, op, right);
}
/**
* Creates a 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 the comparison predicate
*/
static Predicate comparison(CqnValue lhs, CqnComparisonPredicate.Operator op, CqnValue rhs) {
return CDS.QL.create.comparison(lhs, op, rhs);
}
/**
* Creates an {@link CqnInPredicate in} predicate.
*
* @param value the value to be checked if it's contained in the collection
* @param values the collection of values
* @return the {@code in} predicate
*/
static Predicate in(CqnValue value, Collection extends CqnValue> values) {
return CDS.QL.create.in(value, values);
}
/**
* Creates a {@link CqnBetweenPredicate between} predicate that tests if this
* {@code value} is within a closed interval with given bounds
*
* @param value the value to be checked if it's contained in a closed interval
* between {@code low} and {@code high}
* @param low the lower bound
* @param high the upper bound
* @return the {@code between} predicate
*/
static Predicate between(CqnValue value, CqnValue low, CqnValue high) {
return CDS.QL.create.between(value, low, high);
}
/**
* Creates an {@link CqnInPredicate in} predicate.
*
* @param value the value to be checked if it's contained in the collection
* @param valueSet the value describing a collection of values
* @return the {@code in} predicate
*/
static Predicate in(CqnValue value, CqnValue valueSet) {
return CDS.QL.create.in(value, valueSet);
}
/**
* Creates a predicate that checks if the values of the given elements match any
* of the given value sets.
*
* The value sets to test against are computed from the given value maps by
* extracting the values for the given elements.
*
* @param elements the element names
* @param valueMaps the value maps to match against
*/
static Predicate in(List elements, Collection extends Map> valueMaps) {
return CDS.QL.create.in(elements, valueMaps);
}
/**
* Creates an IN predicate that tests if this value is equal to any value
* returned by the subquery.
*
* @param value the value (n-tuple) to be checked if it's contained in the
* result of the subquery
* @param subquery the subquery that defines the set of expected values
* @return the IN predicate
*/
static Predicate in(CqnValue value, CqnSelect subquery) {
return CDS.QL.create.in(value, subquery);
}
/**
* Creates a {@link CqnEtagPredicate} predicate.
*
* @param values the list of ETag values
* @return the {@code eTag} predicate
*/
@Beta
static Predicate eTag(CqnListValue values) {
return CDS.QL.create.eTag(values);
}
/**
* Creates a {@link CqnEtagPredicate} predicate.
*
* @param value the ETag value
* @return the {@code eTag} predicate
*/
@Beta
static Predicate eTag(Object value) {
return eTag(list(val(value)));
}
/**
* Creates a {@link CqnEtagPredicate} predicate.
*
* @param elementRef the reference to ETag element
* @param value the ETag values
* @return the {@code eTag} predicate
*/
@Beta
static Predicate eTag(CqnElementRef elementRef, Object value) {
return CDS.QL.create.eTag(elementRef, value);
}
/**
* Creates a search predicate.
*
* @param term the search term
* @return the search predicate
*/
static Predicate search(String term) {
return CDS.QL.create.search(term);
}
/**
* Creates an exists predicate that tests if a given subquery returns any row
*
* @param subQuery the subquery that performs the existence test
* @return the exists predicate
*/
static Predicate exists(CqnSelect subQuery) {
return CDS.QL.create.exists(subQuery);
}
/**
* Creates a match predicate that tests if a given ref matches a given filter
*
* @param ref the reference
* @param pred the filter
* @param quantifier all or any
* @return the match predicate
*/
static Predicate match(CqnStructuredTypeRef ref, CqnPredicate pred, CqnMatchPredicate.Quantifier quantifier) {
return CDS.QL.create.match(ref, pred, quantifier);
}
/**
* Creates an {@link ElementRef} to be used in queries to represent $now.
*
* @return the now value
*/
static Value now() {
return CDS.QL.create.now().type(Instant.class);
}
/**
* Creates an {@link ElementRef} on the available $validFrom value.
*
* @return the validFrom value
*/
static Value validFrom() {
return CDS.QL.create.validFrom().type(Instant.class);
}
/**
* Creates an {@link ElementRef} on the available $validTo value.
*
* @return the validTo value
*/
static Value validTo() {
return CDS.QL.create.validTo().type(Instant.class);
}
/**
* Creates an {@link ElementRef} on the available $user.locale value.
*
* @return the locale string value
*/
static Value userLocale() {
return CDS.QL.create.userLocale().type(String.class);
}
/**
* Creates an {@link ElementRef} on the available $user.id value.
*
* @return the user.id value
*/
static Value userId() {
return CDS.QL.create.userId().type(String.class);
}
static CqnStar star() {
return CqnStar.star();
}
/**
* Creates a {@link CqnListValue} composing given values
*
* @param values the components
* @return the list value
*/
static CqnListValue list(List extends CqnValue> values) {
return CDS.QL.create.list(values);
}
/**
* Creates a {@link CqnListValue} composing given values
*
* @param values the items
* @return the list value
*/
static CqnListValue list(CqnValue... values) {
return list(Arrays.asList(values));
}
/**
* Creates a predicate from a map of element names to values or parameters. The
* map entries are transformed into equality predicates and joined via
* and.
*
* @param elementToValueMap the element name to value map defining the condition
* @return the matching predicate
*/
static Predicate matching(Map elementToValueMap) {
return CDS.QL.builder.matching(elementToValueMap);
}
/**
* Creates a {@link CqnSortSpecification} that sorts a value by a given order
*
* @param value the value
* @param order the order
* @return the sort specification
*/
static CqnSortSpecification sort(CqnValue value, Order order) {
return CDS.QL.create.sort(value, order);
}
/**
* Creates a predicate that tests if this value matches a specified regular
* expression
*
* @param value the value that is tested
* @param pattern Regular expression represented as a string value
* @param options Regular expression options represented as a string value
* @return the predicate to match the expression
*/
static Predicate matchesPattern(CqnValue value, CqnValue pattern, CqnValue options) {
return CDS.QL.create.matchesPattern(value, pattern, options);
}
/**
* Creates a predicate that tests if this value matches a specified regular
* expression
*
* @param value the value that is tested
* @param pattern Regular expression represented as a string value
* @return the predicate to match the expression
*/
static Predicate matchesPattern(CqnValue value, CqnValue pattern) {
return CDS.QL.create.matchesPattern(value, pattern);
}
/**
* Creates a predicate that tests if this value matches a specified regular
* expression
*
* @param value the value that is tested
* @param pattern Regular expression represented as a plain string
* @return the predicate to match the expression
*/
static Predicate matchesPattern(CqnValue value, String pattern) {
return CDS.QL.create.matchesPattern(value, CQL.val(pattern));
}
/**
* Creates a predicate that tests if this value matches a specified regular
* expression
*
* @param value the value that is tested
* @param pattern Regular expression represented as a string value
* @param caseInsensitive If true, the test is case-insensitive
* @param multiLineSensitive If true, the test is multi-line sensitive
* @return the predicate to match the expression
*/
static Predicate matchesPattern(CqnValue value, CqnValue pattern, boolean caseInsensitive,
boolean multiLineSensitive) {
return CDS.QL.create.matchesPattern(value, pattern, caseInsensitive, multiLineSensitive);
}
/**
* Starts a chain of when-then expressions.
*
* @param pred the {@link CqnCaseExpression.Case#condition() condition} of the
* first case.
* @return a builder to specify the case's return value
*/
static When when(CqnPredicate pred) {
return CDS.QL.create.when(pred);
}
/**
* Creates a builder for a {@link CqnCaseExpression.Case case}
*
* @return a builder to connect more cases to
*/
static Then cases() {
return CDS.QL.create;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy