nz.co.gregs.dbvolution.expressions.AnyExpression Maven / Gradle / Ivy
/*
* Copyright 2018 gregorygraham.
*
* This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
* To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/4.0/
* or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.
*
* You are free to:
* Share - copy and redistribute the material in any medium or format
* Adapt - remix, transform, and build upon the material
*
* The licensor cannot revoke these freedoms as long as you follow the license terms.
* Under the following terms:
*
* Attribution -
* You must give appropriate credit, provide a link to the license, and indicate if changes were made.
* You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use.
* NonCommercial -
* You may not use the material for commercial purposes.
* ShareAlike -
* If you remix, transform, or build upon the material,
* you must distribute your contributions under the same license as the original.
* No additional restrictions -
* You may not apply legal terms or technological measures that legally restrict others from doing anything the
* license permits.
*
* Check the Creative Commons website for any details, legalese, and updates.
*/
package nz.co.gregs.dbvolution.expressions;
import com.vividsolutions.jts.geom.LineSegment;
import com.vividsolutions.jts.geom.LineString;
import com.vividsolutions.jts.geom.MultiPoint;
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.geom.Polygon;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import nz.co.gregs.dbvolution.DBRow;
import nz.co.gregs.dbvolution.databases.DBDatabase;
import nz.co.gregs.dbvolution.databases.definitions.DBDefinition;
import nz.co.gregs.dbvolution.results.AnyResult;
import nz.co.gregs.dbvolution.datatypes.QueryableDatatype;
import nz.co.gregs.dbvolution.results.BooleanResult;
import nz.co.gregs.dbvolution.results.DateRepeatResult;
import nz.co.gregs.dbvolution.results.DateResult;
import nz.co.gregs.dbvolution.results.IntegerResult;
import nz.co.gregs.dbvolution.results.NumberResult;
import nz.co.gregs.dbvolution.results.StringResult;
import org.joda.time.Period;
/**
*
* @author gregorygraham
* @param
* @param
* @param
*/
public abstract class AnyExpression, D extends QueryableDatatype> implements ExpressionColumn, AnyResult {
private final AnyResult> innerResult;
private final boolean nullProtectionRequired;
/**
* Returns an expression that will evaluate to NULL in SQL.
*
* @return an untyped expression that returns NULL
*/
public AnyExpression, ?, ?> nullExpression() {
return new StringExpression() {
@Override
public String toSQLString(DBDefinition db) {
return db.getNull();
}
};
}
abstract public R expression(B value);
abstract public R expression(R value);
abstract public R expression(D value);
@Override
public String createSQLForFromClause(DBDatabase database) {
return getInnerResult().createSQLForFromClause(database);
}
@Override
public Set getTablesInvolved() {
final AnyResult> inner = getInnerResult();
if (inner == null) {
return new HashSet<>(0);
} else {
return inner.getTablesInvolved();
}
}
@Override
public boolean isAggregator() {
final AnyResult> inner = getInnerResult();
return inner == null ? false : inner.isAggregator();
}
@Override
public String toSQLString(DBDefinition db) {
return (getInnerResult() == null) ? db.getNull() : getInnerResult().toSQLString(db);
}
/**
* A complex expression requires more than just a function call in the select
* clause.
*
* @return FALSE, unless you need a subtable to work out your expressions's
* value
*/
@Override
public boolean isComplexExpression() {
AnyResult> inner = getInnerResult();
if (inner == null) {
return false;
} else {
return inner.isComplexExpression();
}
}
@Override
public boolean isPurelyFunctional() {
if (getInnerResult() == null) {
return true;
} else {
return getInnerResult().isPurelyFunctional();
}
}
/**
* Does nothing
*
*/
public AnyExpression() {
innerResult = null;
/* This creates a terminator expression for null-safety chains */
nullProtectionRequired = false;
}
/**
*
* @param only
*/
public AnyExpression(AnyResult> only) {
innerResult = only;
nullProtectionRequired = only == null ? true : innerResult.getIncludesNull();
}
protected boolean isNullSafetyTerminator() {
return getInnerResult() == null && (getIncludesNull() == false);
}
public AnyResult> getInnerResult() {
return innerResult;
}
@Override
public boolean getIncludesNull() {
AnyResult> inner = getInnerResult();
return nullProtectionRequired||(inner==null?false:inner.getIncludesNull());
}
/**
* Create An Appropriate Expression Object For This Object
*
*
* The expression framework requires a *Expression to work with. The easiest
* way to get that is the {@code DBRow.column()} method.
*
*
* However if you wish your expression to start with a literal value it is a
* little trickier.
*
*
* This method provides the easy route to a *Expression from a literal value.
* Just call, for instance, {@code StringExpression.value("STARTING STRING")}
* to get a StringExpression and start the expression chain.
*
*
* - Only object classes that are appropriate need to be handle by the
* DBExpression subclass.
-
*
- The implementation should be {@code static}
*
*
* @param value a literal value to use in the expression
* Support DBvolution at
* Patreon
* @return a DBExpression instance that is appropriate to the subclass and the
* value supplied.
*/
public final static BooleanExpression value(Boolean value) {
return new BooleanExpression(value);
}
/**
* Create An Appropriate Expression Object For This Object
*
*
* The expression framework requires a *Expression to work with. The easiest
* way to get that is the {@code DBRow.column()} method.
*
*
* However if you wish your expression to start with a literal value it is a
* little trickier.
*
*
* This method provides the easy route to a *Expression from a literal value.
* Just call, for instance, {@code StringExpression.value("STARTING STRING")}
* to get a StringExpression and start the expression chain.
*
*
* - Only object classes that are appropriate need to be handle by the
* DBExpression subclass.
-
*
- The implementation should be {@code static}
*
*
* @param integer a literal value to use in the expression
* Support DBvolution at
* Patreon
* @return a DBExpression instance that is appropriate to the subclass and the
* value supplied.
*/
public final static IntegerExpression value(Integer integer) {
return new IntegerExpression(integer);
}
/**
* Create An Appropriate Expression Object For This Object
*
*
* The expression framework requires a *Expression to work with. The easiest
* way to get that is the {@code DBRow.column()} method.
*
*
* However if you wish your expression to start with a literal value it is a
* little trickier.
*
*
* This method provides the easy route to a *Expression from a literal value.
* Just call, for instance, {@code StringExpression.value("STARTING STRING")}
* to get a StringExpression and start the expression chain.
*
*
* - Only object classes that are appropriate need to be handle by the
* DBExpression subclass.
-
*
- The implementation should be {@code static}
*
*
* @param integer a literal value to use in the expression
* Support DBvolution at
* Patreon
* @return a DBExpression instance that is appropriate to the subclass and the
* value supplied.
*/
public final static IntegerExpression value(Long integer) {
return new IntegerExpression(integer);
}
/**
* Create An Appropriate Expression Object For This Object
*
*
* The expression framework requires a *Expression to work with. The easiest
* way to get that is the {@code DBRow.column()} method.
*
*
* However if you wish your expression to start with a literal value it is a
* little trickier.
*
*
* This method provides the easy route to a *Expression from a literal value.
* Just call, for instance, {@code StringExpression.value("STARTING STRING")}
* to get a StringExpression and start the expression chain.
*
*
* - Only object classes that are appropriate need to be handle by the
* DBExpression subclass.
-
*
- The implementation should be {@code static}
*
*
* @param integer a literal value to use in the expression
* Support DBvolution at
* Patreon
* @return a DBExpression instance that is appropriate to the subclass and the
* value supplied.
*/
public final static IntegerExpression value(int integer) {
return new IntegerExpression(integer);
}
/**
* Create An Appropriate Expression Object For This Object
*
*
* The expression framework requires a *Expression to work with. The easiest
* way to get that is the {@code DBRow.column()} method.
*
*
* However if you wish your expression to start with a literal value it is a
* little trickier.
*
*
* This method provides the easy route to a *Expression from a literal value.
* Just call, for instance, {@code StringExpression.value("STARTING STRING")}
* to get a StringExpression and start the expression chain.
*
*
* - Only object classes that are appropriate need to be handle by the
* DBExpression subclass.
-
*
- The implementation should be {@code static}
*
*
* @param integer a literal value to use in the expression
* Support DBvolution at
* Patreon
* @return a DBExpression instance that is appropriate to the subclass and the
* value supplied.
*/
public final static IntegerExpression value(long integer) {
return new IntegerExpression(integer);
}
/**
* Create An Appropriate Expression Object For This Object
*
*
* The expression framework requires a *Expression to work with. The easiest
* way to get that is the {@code DBRow.column()} method.
*
*
* However if you wish your expression to start with a literal value it is a
* little trickier.
*
*
* This method provides the easy route to a *Expression from a literal value.
* Just call, for instance, {@code StringExpression.value("STARTING STRING")}
* to get a StringExpression and start the expression chain.
*
*
* - Only object classes that are appropriate need to be handle by the
* DBExpression subclass.
-
*
- The implementation should be {@code static}
*
*
* @param number a literal value to use in the expression
* Support DBvolution at
* Patreon
* @return a DBExpression instance that is appropriate to the subclass and the
* value supplied.
*/
public final static NumberExpression value(Number number) {
return new NumberExpression(number);
}
/**
* Create An Appropriate Expression Object For This Object
*
*
* The expression framework requires a *Expression to work with. The easiest
* way to get that is the {@code DBRow.column()} method.
*
*
* However if you wish your expression to start with a literal value it is a
* little trickier.
*
*
* This method provides the easy route to a *Expression from a literal value.
* Just call, for instance, {@code StringExpression.value("STARTING STRING")}
* to get a StringExpression and start the expression chain.
*
*
* - Only object classes that are appropriate need to be handle by the
* DBExpression subclass.
-
*
- The implementation should be {@code static}
*
*
* @param string a literal value to use in the expression
* Support DBvolution at
* Patreon
* @return a DBExpression instance that is appropriate to the subclass and the
* value supplied.
*/
public final static StringExpression value(String string) {
return new StringExpression(string);
}
/**
* Create An Appropriate Expression Object For This Object
*
*
* The expression framework requires a *Expression to work with. The easiest
* way to get that is the {@code DBRow.column()} method.
*
*
* However if you wish your expression to start with a literal value it is a
* little trickier.
*
*
* This method provides the easy route to a *Expression from a literal value.
* Just call, for instance, {@code StringExpression.value("STARTING STRING")}
* to get a StringExpression and start the expression chain.
*
*
* - Only object classes that are appropriate need to be handle by the
* DBExpression subclass.
-
*
- The implementation should be {@code static}
*
*
* @param date a literal value to use in the expression
* Support DBvolution at
* Patreon
* @return a DBExpression instance that is appropriate to the subclass and the
* value supplied.
*/
public final static DateExpression value(Date date) {
return new DateExpression(date);
}
/**
* Create An Appropriate Expression Object For This Object
*
*
* The expression framework requires a *Expression to work with. The easiest
* way to get that is the {@code DBRow.column()} method.
*
*
* However if you wish your expression to start with a literal value it is a
* little trickier.
*
*
* This method provides the easy route to a *Expression from a literal value.
* Just call, for instance, {@code StringExpression.value("STARTING STRING")}
* to get a StringExpression and start the expression chain.
*
*
* - Only object classes that are appropriate need to be handle by the
* DBExpression subclass.
-
*
- The implementation should be {@code static}
*
*
* @param period a literal value to use in the expression
* Support DBvolution at
* Patreon
* @return a DBExpression instance that is appropriate to the subclass and the
* value supplied.
*/
public final static DateRepeatExpression value(Period period) {
return new DateRepeatExpression(period);
}
/**
* Create An Appropriate Expression Object For This Object
*
*
* The expression framework requires a *Expression to work with. The easiest
* way to get that is the {@code DBRow.column()} method.
*
*
* However if you wish your expression to start with a literal value it is a
* little trickier.
*
*
* This method provides the easy route to a *Expression from a literal value.
* Just call, for instance, {@code StringExpression.value("STARTING STRING")}
* to get a StringExpression and start the expression chain.
*
*
* - Only object classes that are appropriate need to be handle by the
* DBExpression subclass.
-
*
- The implementation should be {@code static}
*
*
* @param value a literal value to use in the expression
* Support DBvolution at
* Patreon
* @return a DBExpression instance that is appropriate to the subclass and the
* value supplied.
*/
public final static BooleanExpression value(BooleanResult value) {
return new BooleanExpression(value);
}
/**
* Create An Appropriate Expression Object For This Object
*
*
* The expression framework requires a *Expression to work with. The easiest
* way to get that is the {@code DBRow.column()} method.
*
*
* However if you wish your expression to start with a literal value it is a
* little trickier.
*
*
* This method provides the easy route to a *Expression from a literal value.
* Just call, for instance, {@code StringExpression.value("STARTING STRING")}
* to get a StringExpression and start the expression chain.
*
*
* - Only object classes that are appropriate need to be handle by the
* DBExpression subclass.
-
*
- The implementation should be {@code static}
*
*
* @param integer a literal value to use in the expression
* Support DBvolution at
* Patreon
* @return a DBExpression instance that is appropriate to the subclass and the
* value supplied.
*/
public final static IntegerExpression value(IntegerResult integer) {
return new IntegerExpression(integer);
}
/**
* Create An Appropriate Expression Object For This Object
*
*
* The expression framework requires a *Expression to work with. The easiest
* way to get that is the {@code DBRow.column()} method.
*
*
* However if you wish your expression to start with a literal value it is a
* little trickier.
*
*
* This method provides the easy route to a *Expression from a literal value.
* Just call, for instance, {@code StringExpression.value("STARTING STRING")}
* to get a StringExpression and start the expression chain.
*
*
* - Only object classes that are appropriate need to be handle by the
* DBExpression subclass.
-
*
- The implementation should be {@code static}
*
*
* @param number a literal value to use in the expression
* Support DBvolution at
* Patreon
* @return a DBExpression instance that is appropriate to the subclass and the
* value supplied.
*/
public final static NumberExpression value(NumberResult number) {
return new NumberExpression(number);
}
/**
* Create An Appropriate Expression Object For This Object
*
*
* The expression framework requires a *Expression to work with. The easiest
* way to get that is the {@code DBRow.column()} method.
*
*
* However if you wish your expression to start with a literal value it is a
* little trickier.
*
*
* This method provides the easy route to a *Expression from a literal value.
* Just call, for instance, {@code StringExpression.value("STARTING STRING")}
* to get a StringExpression and start the expression chain.
*
*
* - Only object classes that are appropriate need to be handle by the
* DBExpression subclass.
-
*
- The implementation should be {@code static}
*
*
* @param string a literal value to use in the expression
* Support DBvolution at
* Patreon
* @return a DBExpression instance that is appropriate to the subclass and the
* value supplied.
*/
public final static StringExpression value(StringResult string) {
return new StringExpression(string);
}
/**
* Create An Appropriate Expression Object For This Object
*
*
* The expression framework requires a *Expression to work with. The easiest
* way to get that is the {@code DBRow.column()} method.
*
*
* However if you wish your expression to start with a literal value it is a
* little trickier.
*
*
* This method provides the easy route to a *Expression from a literal value.
* Just call, for instance, {@code StringExpression.value("STARTING STRING")}
* to get a StringExpression and start the expression chain.
*
*
* - Only object classes that are appropriate need to be handle by the
* DBExpression subclass.
-
*
- The implementation should be {@code static}
*
*
* @param date a literal value to use in the expression
* Support DBvolution at
* Patreon
* @return a DBExpression instance that is appropriate to the subclass and the
* value supplied.
*/
public final static DateExpression value(DateResult date) {
return new DateExpression(date);
}
/**
* Create An Appropriate Expression Object For This Object
*
*
* The expression framework requires a *Expression to work with. The easiest
* way to get that is the {@code DBRow.column()} method.
*
*
* However if you wish your expression to start with a literal value it is a
* little trickier.
*
*
* This method provides the easy route to a *Expression from a literal value.
* Just call, for instance, {@code StringExpression.value("STARTING STRING")}
* to get a StringExpression and start the expression chain.
*
*
* - Only object classes that are appropriate need to be handle by the
* DBExpression subclass.
-
*
- The implementation should be {@code static}
*
*
* @param period a literal value to use in the expression
* Support DBvolution at
* Patreon
* @return a DBExpression instance that is appropriate to the subclass and the
* value supplied.
*/
public final static DateRepeatExpression value(DateRepeatResult period) {
return new DateRepeatExpression(period);
}
public final static Point2DExpression value(Point point) {
return new Point2DExpression(point);
}
public final static MultiPoint2DExpression value(MultiPoint mpoint) {
return new MultiPoint2DExpression(mpoint);
}
public final static Line2DExpression value(LineString line) {
return new Line2DExpression(line);
}
public final static LineSegment2DExpression value(LineSegment linesegment) {
return new LineSegment2DExpression(linesegment);
}
public final static Polygon2DExpression value(Polygon polygon) {
return new Polygon2DExpression(polygon);
}
public final static BooleanExpression nullBoolean() {
return new BooleanExpression().nullExpression();
}
public final static IntegerExpression nullInteger() {
return new IntegerExpression().nullExpression();
}
public final static NumberExpression nullNumber() {
return new NumberExpression().nullExpression();
}
public final static StringExpression nullString() {
return new StringExpression().nullExpression();
}
public final static DateExpression nullDate() {
return new DateExpression().nullExpression();
}
public final static DateRepeatExpression nullDateRepeat() {
return new DateRepeatExpression().nullExpression();
}
public final static Point2DExpression nullPoint2D() {
return new Point2DExpression().nullExpression();
}
public final static MultiPoint2DExpression nullMultiPoint2D() {
return new MultiPoint2DExpression().nullExpression();
}
public final static Line2DExpression nullLine2D() {
return new Line2DExpression().nullExpression();
}
public final static LineSegment2DExpression nullLineSegment2D() {
return new LineSegment2DExpression().nullExpression();
}
public final static Polygon2DExpression nullPolygon2D() {
return new Polygon2DExpression().nullExpression();
}
}