package net.sourceforge.mayfly.datastore;
import net.sourceforge.mayfly.MayflyException;
import net.sourceforge.mayfly.MayflySqlException;
import net.sourceforge.mayfly.UnimplementedException;
import net.sourceforge.mayfly.parser.Location;
import net.sourceforge.mayfly.util.ValueObject;
import org.joda.time.DateTimeZone;
import java.io.InputStream;
import java.math.BigDecimal;
import java.sql.Blob;
import java.sql.SQLException;
public abstract class Cell extends ValueObject {
/**
@internal
Convert to byte. As byte is an exact type,
should throw an exception if the value cannot be
represented in a byte (likewise for {@link #asShort()},
{@link #asInt()}, and {@link #asLong()}.
*/
public byte asByte() throws SQLException {
throw new MayflyException(
"attempt to read " + displayName() + " as a byte").asSqlException();
}
public short asShort() throws SQLException {
throw new MayflyException(
"attempt to read " + displayName() + " as a short").asSqlException();
}
public int asInt() throws SQLException {
throw new MayflyException(
"attempt to read " + displayName() + " as an int").asSqlException();
}
public long asLong() throws MayflyException {
throw new MayflyException(
"attempt to read " + displayName() + " as a long");
}
public Object asObject() {
throw new UnimplementedException(
"attempt to read " + displayName() + " as an object");
}
public String asString() throws MayflyException {
/** TODO: This method is semantically overloaded; it goes into
various messages, and also implements
{@link java.sql.ResultSet#getString(int)}
Clean this up or else we'll be buggy about things
like UNIQUE constraints on type DECIMAL.
*/
throw new MayflyException(
"attempt to read " + displayName() + " as a string");
}
@Override
public String toString() {
return asBriefString();
}
/**
* @internal
* Must override either this or {@link #asObject()} to avoid infinite loop.
*/
public String asBriefString() {
return asObject().toString();
}
abstract public String asSql();
public BigDecimal asBigDecimal() throws MayflySqlException {
throw new MayflyException(
"attempt to read " + displayName() + " as a decimal")
.asSqlException();
}
public java.sql.Date asDate(DateTimeZone zone) throws SQLException {
throw new MayflyException(
"attempt to read " + displayName() + " as a date")
.asSqlException();
}
public java.sql.Timestamp asTimestamp(DateTimeZone zone) throws SQLException {
throw new MayflyException(
"attempt to read " + displayName() + " as a timestamp")
.asSqlException();
}
/**
@internal
Convert to double. As double is a floating-point (inexact) type,
it is OK to truncate/round.
*/
public double asDouble() throws SQLException {
throw new MayflyException(
"attempt to read " + displayName() + " as a double")
.asSqlException();
}
public InputStream asBinaryStream() throws SQLException {
throw new MayflyException(
"attempt to read " + displayName() + " as binary data")
.asSqlException();
}
public Blob asBlob() throws MayflySqlException {
throw new MayflyException(
"attempt to read " + displayName() + " as binary data")
.asSqlException();
}
public byte[] asBytes() throws SQLException {
throw new MayflyException(
"attempt to read " + displayName() + " as binary data")
.asSqlException();
}
final public int compareTo(Cell otherCell) {
return compareTo(otherCell, Location.UNKNOWN);
}
abstract public int compareTo(Cell otherCell, Location location);
public final boolean sqlEquals(Cell otherCell) {
return sqlEquals(otherCell, Location.UNKNOWN);
}
public boolean sqlEquals(Cell otherCell, Location location) {
return compareTo(otherCell, location) == 0;
}
/**
* @internal
* The kind of equality here is the kind we want for GROUP BY or
* DISTINCT, in which all nulls are equal. That is, it is different
* from {@link #sqlEquals(Cell)}, in which null != null.
*/
public final boolean distinctEquals(Cell otherCell) {
/* (Need to think more about the difference between these
* two implementations and whether equals is the clean
* way to do things or not)
*/
// return compareTo(otherCell, Location.UNKNOWN) == 0;
return equals(otherCell);
}
abstract public String displayName();
protected MayflyException cannotCompare(Cell otherCell, Location location) {
return new MayflyException(
"attempt to compare " + displayName() +
" to " + otherCell.displayName(),
location
);
}
static int longToInt(long localValue) throws SQLException {
if (localValue >= Integer.MIN_VALUE && localValue <= Integer.MAX_VALUE) {
return (int) localValue;
}
else {
throw new SQLException("Value " + localValue + " does not fit in an int");
}
}
static short longToShort(long value) throws SQLException {
if (value >= Short.MIN_VALUE && value <= Short.MAX_VALUE) {
return (short) value;
}
else {
throw new SQLException("Value " + value + " does not fit in a short");
}
}
static byte longToByte(long value) throws SQLException {
if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) {
return (byte) value;
}
else {
throw new SQLException("Value " + value + " does not fit in a byte");
}
}
}