package net.sourceforge.mayfly.datastore;
import net.sourceforge.mayfly.MayflyException;
import net.sourceforge.mayfly.parser.Location;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.SQLException;
public class DecimalCell extends Cell {
public static BigInteger LONG_MIN = BigInteger.valueOf(Long.MIN_VALUE);
public static BigInteger LONG_MAX = BigInteger.valueOf(Long.MAX_VALUE);
private final BigDecimal value;
public DecimalCell(BigDecimal value) {
this.value = value;
}
public DecimalCell(String string) {
this(new BigDecimal(string));
}
@Override
public byte asByte() throws SQLException {
try {
return longToByte(asLong("a byte"));
}
catch (MayflyException e) {
throw e.asSqlException();
}
}
@Override
public short asShort() throws SQLException {
try {
return longToShort(asLong("a short"));
}
catch (MayflyException e) {
throw e.asSqlException();
}
}
@Override
public int asInt() throws SQLException {
try {
return longToInt(asLong("an int"));
}
catch (MayflyException e) {
throw e.asSqlException();
}
}
@Override
public long asLong() {
/**
* Could call {@link BigDecimal#longValueExact()} if we wanted to
* assume Java 1.5.
*/
return asLong("a long");
}
private long asLong(String intoWhat) {
BigInteger integer = toInteger(intoWhat);
if (integer.compareTo(LONG_MIN) < 0) {
throw doesNotFit(intoWhat);
}
else if (integer.compareTo(LONG_MAX) > 0) {
throw doesNotFit(intoWhat);
}
else {
return integer.longValue();
}
}
private BigInteger toInteger(String intoWhat) {
BigInteger bigInteger = value.toBigInteger();
BigDecimal integerPart = new BigDecimal(bigInteger);
BigDecimal difference = value.subtract(integerPart);
if (difference.signum() != 0) {
throw doesNotFit(intoWhat);
}
return bigInteger;
}
private MayflyException doesNotFit(String intoWhat) {
return new MayflyException(
"Value " + value.toString() + " does not fit in " + intoWhat);
}
@Override
public Object asObject() {
return value;
}
@Override
public String asSql() {
return value.toString();
}
@Override
public BigDecimal asBigDecimal() {
return value;
}
@Override
public double asDouble() {
return value.doubleValue();
}
@Override
public int compareTo(Cell otherCell, Location location) {
if (otherCell instanceof DecimalCell) {
return compareDecimals(value, ((DecimalCell) otherCell).value);
}
else if (otherCell instanceof NullCell) {
return 1;
}
else {
throw cannotCompare(otherCell, location);
}
}
private int compareDecimals(BigDecimal value2, BigDecimal value3) {
return value2.compareTo(value3);
}
@Override
public String displayName() {
return "decimal " + value.toString();
}
}