DBBoolean.java
/*
* Copyright 2013 Gregory Graham.
*
* Licensed 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 nz.co.gregs.dbvolution.datatypes;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import nz.co.gregs.dbvolution.DBReport;
import nz.co.gregs.dbvolution.DBRow;
import nz.co.gregs.dbvolution.columns.BooleanColumn;
import nz.co.gregs.dbvolution.databases.definitions.DBDefinition;
import nz.co.gregs.dbvolution.exceptions.IncorrectRowProviderInstanceSuppliedException;
import nz.co.gregs.dbvolution.expressions.BooleanExpression;
import nz.co.gregs.dbvolution.expressions.StringExpression;
import nz.co.gregs.dbvolution.results.BooleanResult;
import nz.co.gregs.dbvolution.operators.DBBooleanPermittedValuesOperator;
import nz.co.gregs.dbvolution.operators.DBPermittedValuesOperator;
import nz.co.gregs.dbvolution.query.RowDefinition;
import nz.co.gregs.dbvolution.utility.comparators.ComparableComparator;
/**
* Encapsulates database values that are Booleans.
*
* <p>
* Use DBBoolean when the column is a {@code bool} or {@code bit(1)} datatype.
*
* <p>
* Generally DBBoolean is declared inside your DBRow sub-class as:
* {@code @DBColumn public DBBoolean myBoolColumn = new DBBoolean();}
*
* <p>
* Yes/No Strings and 0/1 integer columns will need to use {@link DBString} and
* {@link DBInteger} respectively. Depending on your requirements you should try
* sub-classing DBString/DBInteger, extending DBStringEnum/DBIntegerEnum, or
* using a {@link DBTypeAdaptor}.
*
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
*
* @author Gregory Graham
*/
public class DBBoolean extends QueryableDatatype<Boolean> implements BooleanResult {
private static final long serialVersionUID = 1L;
/**
* The default constructor for DBBoolean.
*
* <p>
* Creates an unset undefined DBBoolean object.
*
*/
public DBBoolean() {
}
/**
* Creates a DBBoolean with the value provided.
*
* <p>
* The resulting DBBoolean will be set as having the value provided but will
* not be defined in the database.
*
* @param bool bool
*/
public DBBoolean(Boolean bool) {
super(bool);
}
/**
* Creates a column expression with a boolean result from the expression
* provided.
*
* <p>
* Used in {@link DBReport}, and some {@link DBRow}, sub-classes to derive
* data from the database prior to retrieval.
*
* @param bool bool
*/
public DBBoolean(BooleanExpression bool) {
super(bool);
}
@Override
public int hashCode() {
return super.hashCode();
}
/**
* Implements the standard Java equals method.
*
* @param other other
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
* @return TRUE if this object is the same as the other, otherwise FALSE.
*/
@Override
public boolean equals(Object other) {
if (other instanceof DBBoolean) {
DBBoolean otherDBBoolean = (DBBoolean) other;
return getValue().equals(otherDBBoolean.getValue());
}
return false;
}
@Override
public String getSQLDatatype() {
return "BIT(1)";
}
void setValue(DBBoolean newLiteralValue) {
setValue(newLiteralValue.getValue());
}
/**
* Sets the value of this DBBoolean to the value provided.
*
* @param newLiteralValue newLiteralValue
*/
@Override
public void setValue(Boolean newLiteralValue) {
super.setLiteralValue(newLiteralValue);
}
@Override
public String formatValueForSQLStatement(DBDefinition defn) {
if (getLiteralValue() instanceof Boolean) {
Boolean boolValue = getLiteralValue();
return defn.doBooleanValueTransform(boolValue);
}
return defn.getNull();
}
/**
* Returns the defined or set value of this DBBoolean as an actual Boolean.
*
* <p>
* May return NULL.
*
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
*
* @return the value of this QDT as a boolean.
*/
@SuppressFBWarnings(
value = "NP_BOOLEAN_RETURN_NULL",
justification = "Null is a valid value in databases"
)
public Boolean booleanValue() {
if (this.getLiteralValue() instanceof Boolean) {
return this.getLiteralValue();
} else {
return null;
}
}
@Override
public DBBoolean copy() {
return (DBBoolean) (BooleanResult) super.copy();
}
@Override
public Boolean getValue() {
return booleanValue();
}
@Override
public DBBoolean getQueryableDatatypeForExpressionValue() {
return new DBBoolean();
}
@Override
public boolean isAggregator() {
return false;
}
/**
*
* reduces the rows to only the object, Set, List, Array, or vararg of objects
*
* @param permitted permitted
*/
public void permittedValues(Boolean permitted) {
this.setOperator(new DBBooleanPermittedValuesOperator(permitted));
}
/**
*
* excludes the object, Set, List, Array, or vararg of objects
*
*
* @param excluded excluded
*/
public void excludedValues(Boolean excluded) {
this.setOperator(new DBPermittedValuesOperator<>(excluded));
negateOperator();
}
/**
*
* reduces the rows to only the object, Set, List, Array, or vararg of objects
*
* @param permitted permitted
*/
public void permittedValues(BooleanExpression permitted) {
this.setOperator(new DBPermittedValuesOperator<>(permitted));
}
/**
*
* excludes the object, Set, List, Array, or vararg of objects
*
*
* @param excluded excluded
*/
public void excludedValues(BooleanExpression excluded) {
this.setOperator(new DBPermittedValuesOperator<>(excluded));
negateOperator();
}
/**
* Indicates whether this DBBoolean needs support for returning NULLs.
*
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
*
* @return FALSE.
*/
@Override
public boolean getIncludesNull() {
return false;
}
@Override
protected Boolean getFromResultSet(DBDefinition database, ResultSet resultSet, String fullColumnName) throws SQLException {
Boolean dbValue = resultSet.getBoolean(fullColumnName);
if (resultSet.wasNull()) {
dbValue = null;
}
return dbValue;
}
@Override
public StringExpression stringResult() {
return BooleanExpression.value(this).stringResult();
}
@Override
public boolean isBooleanStatement() {
if (!isDefined() && !isNull()) {
return true;
}
return hasColumnExpression();
}
private final String[] trueValuesArray = new String[]{"YES", "TRUE", "1"};
private final List<String> trueValues = Arrays.asList(trueValuesArray);
@Override
protected void setValueFromStandardStringEncoding(String encodedValue) {
final String upper = encodedValue.toUpperCase();
if (upper.equals("NULL")) {
setValue((Boolean) null);
} else if (trueValues.contains(encodedValue)) {
setValue(true);
} else {
setValue(false);
}
}
@Override
public BooleanColumn getColumn(RowDefinition row) throws IncorrectRowProviderInstanceSuppliedException {
return new BooleanColumn(row, this);
}
public void excludeNotNull() {
this.permittedValues((Boolean) null);
}
public void excludeNull() {
this.excludedValues((Boolean) null);
}
public void permitOnlyNull() {
excludeNotNull();
}
public void permitOnlyNotNull() {
excludeNull();
}
/**
* Set the value to be inserted when no value has been set, using
* {@link #setValue(java.lang.Object) setValue(...)}, for the QDT.
*
* <p>
* The value is only used during the initial insert and does not effect the
* definition of the column within the database.</p>
*
* <p>
* Care should be taken when using this as some "obvious" uses are better
* handled using the
* {@link #setDefaultInsertValue(nz.co.gregs.dbvolution.results.AnyResult) expression version}.
* In particular, setDefaultInsertValue(new Date()) is probably NOT what you
* want, setDefaultInsertValue(DateExpression.currentDate()) will produce a
* correct creation date value.</p>
*
* @param value the value to use during insertion when no particular value has
* been specified.
* @return This QDT
*/
@Override
public synchronized DBBoolean setDefaultInsertValue(Boolean value) {
super.setDefaultInsertValue(value);
return this;
}
/**
* Set the value to be inserted when no value has been set, using
* {@link #setValue(java.lang.Object) setValue(...)}, for the QDT.
*
* <p>
* The value is only used during the initial insert and does not effect the
* definition of the column within the database.</p>
*
* @param value the value to use during insertion when no particular value has
* been specified.
* @return This QDT
*/
public synchronized DBBoolean setDefaultInsertValue(DBBoolean value) {
super.setDefaultInsertValue(value);
return this;
}
/**
* Set the value to be used during an update when no value has been set, using
* {@link #setValue(java.lang.Object) setValue(...)}, for the QDT.
*
* <p>
* The value is only used during updates and does not effect the definition of
* the column within the database nor the initial value of the column.</p>
*
* <p>
* Care should be taken when using this as some "obvious" uses are better
* handled using the
* {@link #setDefaultUpdateValue(nz.co.gregs.dbvolution.results.AnyResult) expression version}.
* In particular, setDefaultUpdateValue(new Date()) is probably NOT what you
* want, setDefaultUpdateValue(DateExpression.currentDate()) will produce a
* correct update time value.</p>
*
* @param value the value to use during update when no particular value has
* been specified.
* @return This QDT
*/
@Override
public synchronized DBBoolean setDefaultUpdateValue(Boolean value) {
super.setDefaultUpdateValue(value);
return this;
}
/**
* Set the value to be used during an update when no value has been set, using
* {@link #setValue(java.lang.Object) setValue(...)}, for the QDT.
*
* <p>
* The value is only used during updates and does not effect the definition of
* the column within the database nor the initial value of the column.</p>
*
* <p>
* Care should be taken when using this as some "obvious" uses are better
* handled using the
* {@link #setDefaultUpdateValue(nz.co.gregs.dbvolution.results.AnyResult) expression version}.
* In particular, setDefaultUpdateValue(new Date()) is probably NOT what you
* want, setDefaultUpdateValue(DateExpression.currentDate()) will produce a
* correct update time value.</p>
*
* @param value the value to use during update when no particular value has
* been specified.
* @return This QDT
*/
public synchronized DBBoolean setDefaultUpdateValue(DBBoolean value) {
super.setDefaultUpdateValue(value);
return this;
}
@Override
public Comparator<Boolean> getComparator() {
return ComparableComparator.forClass(Boolean.class);
}
}