All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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(); } }