/***************************************************************** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. ****************************************************************/ package org.apache.cayenne.exp; import org.apache.cayenne.exp.parser.ASTAbs; import org.apache.cayenne.exp.parser.ASTAvg; import org.apache.cayenne.exp.parser.ASTConcat; import org.apache.cayenne.exp.parser.ASTCount; import org.apache.cayenne.exp.parser.ASTCurrentDate; import org.apache.cayenne.exp.parser.ASTCurrentTime; import org.apache.cayenne.exp.parser.ASTCurrentTimestamp; import org.apache.cayenne.exp.parser.ASTExtract; import org.apache.cayenne.exp.parser.ASTLength; import org.apache.cayenne.exp.parser.ASTLocate; import org.apache.cayenne.exp.parser.ASTLower; import org.apache.cayenne.exp.parser.ASTMax; import org.apache.cayenne.exp.parser.ASTMin; import org.apache.cayenne.exp.parser.ASTMod; import org.apache.cayenne.exp.parser.ASTObjPath; import org.apache.cayenne.exp.parser.ASTScalar; import org.apache.cayenne.exp.parser.ASTSqrt; import org.apache.cayenne.exp.parser.ASTSubstring; import org.apache.cayenne.exp.parser.ASTSum; import org.apache.cayenne.exp.parser.ASTTrim; import org.apache.cayenne.exp.parser.ASTUpper; /** * Collection of factory methods to create function call expressions. * * @since 4.0 */ public class FunctionExpressionFactory { /** * Call SUBSTRING(string, offset, length) function * * @param exp expression that must evaluate to string * @param offset start offset of substring * @param length length of substring * @return SUBSTRING() call expression */ public static Expression substringExp(Expression exp, int offset, int length) { return substringExp(exp, new ASTScalar((Integer)offset), new ASTScalar((Integer)length)); } /** * Call SUBSTRING(string, offset, length) function * * @param path Object path value * @param offset start offset of substring * @param length length of substring * @return SUBSTRING() call expression */ public static Expression substringExp(String path, int offset, int length) { return substringExp(new ASTObjPath(path), new ASTScalar((Integer)offset), new ASTScalar((Integer)length)); } /** * Call SUBSTRING(string, offset, length) function * * @param exp expression that must evaluate to string * @param offset start offset of substring must evaluate to int * @param length length of substring must evaluate to int * @return SUBSTRING() call expression */ public static Expression substringExp(Expression exp, Expression offset, Expression length) { return new ASTSubstring(exp, offset, length); } /** * @param exp string expression to trim * @return TRIM() call expression */ public static Expression trimExp(Expression exp) { return new ASTTrim(exp); } /** * @param path object path value * @return TRIM() call expression */ public static Expression trimExp(String path) { return new ASTTrim(new ASTObjPath(path)); } /** * @param exp string expression * @return LOWER() call expression */ public static Expression lowerExp(Expression exp) { return new ASTLower(exp); } /** * @param path object path value * @return LOWER() call expression */ public static Expression lowerExp(String path) { return new ASTLower(new ASTObjPath(path)); } /** * @param exp string expression * @return UPPER() call expression */ public static Expression upperExp(Expression exp) { return new ASTUpper(exp); } /** * @param path object path value * @return UPPER() call expression */ public static Expression upperExp(String path) { return new ASTUpper(new ASTObjPath(path)); } /** * @param exp string expression * @return LENGTH() call expression */ public static Expression lengthExp(Expression exp) { return new ASTLength(exp); } /** * @param path object path value * @return LENGTH() call expression */ public static Expression lengthExp(String path) { return new ASTLength(new ASTObjPath(path)); } /** * Call LOCATE(substring, string) function that return position * of substring in string or 0 if it is not found. * * @param substring object path value * @param exp string expression * @return LOCATE() call expression */ public static Expression locateExp(String substring, Expression exp) { return locateExp(new ASTScalar(substring), exp); } /** * Call LOCATE(substring, string) function that return position * of substring in string or 0 if it is not found. * * @param substring object path value * @param path object path * @return LOCATE() call expression */ public static Expression locateExp(String substring, String path) { return locateExp(new ASTScalar(substring), new ASTObjPath(path)); } /** * Call LOCATE(substring, string) function that return position * of substring in string or 0 if it is not found. * * @param substring string expression * @param exp string expression * @return LOCATE() call expression */ public static Expression locateExp(Expression substring, Expression exp) { return new ASTLocate(substring, exp); } /** * @param exp numeric expression * @return ABS() call expression */ public static Expression absExp(Expression exp) { return new ASTAbs(exp); } /** * @param path object path value * @return ABS() call expression */ public static Expression absExp(String path) { return new ASTAbs(new ASTObjPath(path)); } /** * @param exp numeric expression * @return SQRT() call expression */ public static Expression sqrtExp(Expression exp) { return new ASTSqrt(exp); } /** * @param path object path value * @return SQRT() call expression */ public static Expression sqrtExp(String path) { return new ASTSqrt(new ASTObjPath(path)); } /** * @param exp numeric expression * @param number divisor * @return MOD() call expression */ public static Expression modExp(Expression exp, Number number) { return modExp(exp, new ASTScalar(number)); } /** * @param path object path value * @param number divisor * @return MOD() call expression */ public static Expression modExp(String path, Number number) { return modExp(new ASTObjPath(path), new ASTScalar(number)); } /** * @param exp object path value * @param number numeric expression * @return MOD() call expression */ public static Expression modExp(Expression exp, Expression number) { return new ASTMod(exp, number); } /** * <p> * Factory method for expression to call CONCAT(string1, string2, ...) function * </p> * <p> * Can be used like: <pre> * Expression concat = concatExp(SomeClass.POPERTY_1.getPath(), SomeClass.PROPERTY_2.getPath()); * </pre> * </p> * <p> * SQL generation note: * <ul> * <li> if DB supports CONCAT function with vararg then it will be used * <li> if DB supports CONCAT function with two args but also supports concat operator, then operator (eg ||) will be used * <li> if DB supports only CONCAT function with two args then it will be used what can lead to SQL exception if * used with more than two arguments * </ul> * </p> * <p>Currently only known DB with limited concatenation functionality is Openbase.</p> * * @param expressions array of expressions * @return CONCAT() call expression */ public static Expression concatExp(Expression... expressions) { if(expressions == null || expressions.length == 0) { return new ASTConcat(); } return new ASTConcat(expressions); } /** * <p> * Factory method for expression to call CONCAT(string1, string2, ...) function * </p> * <p> * Can be used like:<pre> * Expression concat = concatExp("property1", "property2"); * </pre> * </p> * <p> * SQL generation note: * <ul> * <li> if DB supports CONCAT function with vararg then it will be used * <li> if DB supports CONCAT function with two args but also supports concat operator, then operator (eg ||) will be used * <li> if DB supports only CONCAT function with two args then it will be used what can lead to SQL exception if * used with more than two arguments * </ul> * </p> * <p>Currently only Openbase DB has limited concatenation functionality.</p> * * @param paths array of paths * @return CONCAT() call expression */ public static Expression concatExp(String... paths) { if(paths == null || paths.length == 0) { return new ASTConcat(); } Expression[] expressions = new Expression[paths.length]; for(int i=0; i<paths.length; i++) { expressions[i] = new ASTObjPath(paths[i]); } return new ASTConcat(expressions); } /** * @return Expression COUNT(*) */ public static Expression countExp() { return new ASTCount(); } /** * @return Expression COUNT(exp) */ public static Expression countExp(Expression exp) { return new ASTCount(exp); } /** * @return Expression MIN(exp) */ public static Expression minExp(Expression exp) { return new ASTMin(exp); } /** * @return Expression MAX(exp) */ public static Expression maxExp(Expression exp) { return new ASTMax(exp); } /** * @return Expression AVG(exp) */ public static Expression avgExp(Expression exp) { return new ASTAvg(exp); } /** * @return SUM(exp) expression */ public static Expression sumExp(Expression exp) { return new ASTSum(exp); } /** * @return CURRENT_DATE expression */ public static Expression currentDate() { return new ASTCurrentDate(); } /** * @return CURRENT_TIME expression */ public static Expression currentTime() { return new ASTCurrentTime(); } /** * @return CURRENT_TIMESTAMP expression */ public static Expression currentTimestamp() { return new ASTCurrentTimestamp(); } /** * @param exp date/timestamp expression * @return year(exp) function expression */ public static Expression yearExp(Expression exp) { return extractExp(exp, ASTExtract.DateTimePart.YEAR); } /** * @param path String path * @return year(path) function expression */ public static Expression yearExp(String path) { return extractExp(path, ASTExtract.DateTimePart.YEAR); } /** * @param exp date/timestamp expression * @return month(exp) function expression */ public static Expression monthExp(Expression exp) { return extractExp(exp, ASTExtract.DateTimePart.MONTH); } /** * @param path String path * @return month(path) function expression */ public static Expression monthExp(String path) { return extractExp(path, ASTExtract.DateTimePart.MONTH); } /** * @param exp date/timestamp expression * @return week(exp) function expression */ public static Expression weekExp(Expression exp) { return extractExp(exp, ASTExtract.DateTimePart.WEEK); } /** * @param path String path * @return week(path) function expression */ public static Expression weekExp(String path) { return extractExp(path, ASTExtract.DateTimePart.WEEK); } /** * @param exp date/timestamp expression * @return dayOfYear(exp) function expression */ public static Expression dayOfYearExp(Expression exp) { return extractExp(exp, ASTExtract.DateTimePart.DAY_OF_YEAR); } /** * @param path String path * @return dayOfYear(path) function expression */ public static Expression dayOfYearExp(String path) { return extractExp(path, ASTExtract.DateTimePart.DAY_OF_YEAR); } /** * @param exp date/timestamp expression * @return dayOfMonth(exp) function expression, synonym for day() */ public static Expression dayOfMonthExp(Expression exp) { return extractExp(exp, ASTExtract.DateTimePart.DAY_OF_MONTH); } /** * @param path String path * @return dayOfMonth(path) function expression, synonym for day() */ public static Expression dayOfMonthExp(String path) { return extractExp(path, ASTExtract.DateTimePart.DAY_OF_MONTH); } /** * @param exp date/timestamp expression * @return dayOfWeek(exp) function expression */ public static Expression dayOfWeekExp(Expression exp) { return extractExp(exp, ASTExtract.DateTimePart.DAY_OF_WEEK); } /** * @param path String path * @return dayOfWeek(path) function expression */ public static Expression dayOfWeekExp(String path) { return extractExp(path, ASTExtract.DateTimePart.DAY_OF_WEEK); } /** * @param exp date/timestamp expression * @return hour(exp) function expression */ public static Expression hourExp(Expression exp) { return extractExp(exp, ASTExtract.DateTimePart.HOUR); } /** * @param path String path * @return hour(path) function expression */ public static Expression hourExp(String path) { return extractExp(path, ASTExtract.DateTimePart.HOUR); } /** * @param exp date/timestamp expression * @return minute(exp) function expression */ public static Expression minuteExp(Expression exp) { return extractExp(exp, ASTExtract.DateTimePart.MINUTE); } /** * @param path String path * @return minute(path) function expression */ public static Expression minuteExp(String path) { return extractExp(path, ASTExtract.DateTimePart.MINUTE); } /** * @param exp date/timestamp expression * @return second(exp) function expression */ public static Expression secondExp(Expression exp) { return extractExp(exp, ASTExtract.DateTimePart.SECOND); } /** * @param path String path * @return second(path) function expression */ public static Expression secondExp(String path) { return extractExp(path, ASTExtract.DateTimePart.SECOND); } static Expression extractExp(String path, ASTExtract.DateTimePart part) { return extractExp(ExpressionFactory.pathExp(path), part); } static Expression extractExp(Expression exp, ASTExtract.DateTimePart part) { ASTExtract extract = new ASTExtract(exp); extract.setPart(part); return extract; } }