📄 value.java
字号:
/*
* Copyright 2004-2008 H2 Group. Licensed under the H2 License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.value;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.Reader;
import java.lang.ref.SoftReference;
import java.math.BigDecimal;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Time;
import java.sql.Timestamp;
import java.sql.Types;
import org.h2.constant.ErrorCode;
import org.h2.constant.SysProperties;
import org.h2.engine.Constants;
import org.h2.message.Message;
import org.h2.store.DataHandler;
import org.h2.tools.SimpleResultSet;
import org.h2.util.ByteUtils;
import org.h2.util.IOUtils;
import org.h2.util.MathUtils;
import org.h2.util.StringUtils;
/**
* This is the base class for all value classes.
* It provides conversion and comparison methods.
*/
public abstract class Value {
/**
* The data type is unknown at this time.
*/
public static final int UNKNOWN = -1;
public static final int NULL = 0, BOOLEAN = 1, BYTE = 2, SHORT = 3, INT = 4, LONG = 5, DECIMAL = 6;
public static final int DOUBLE = 7, FLOAT = 8, TIME = 9, DATE = 10, TIMESTAMP = 11, BYTES = 12;
public static final int STRING = 13, STRING_IGNORECASE = 14, BLOB = 15, CLOB = 16;
public static final int ARRAY = 17, RESULT_SET = 18, JAVA_OBJECT = 19, UUID = 20, STRING_FIXED = 21;
public static final int TYPE_COUNT = STRING_FIXED + 1;
private static SoftReference softCache = new SoftReference(null);
private static final BigDecimal MAX_LONG_DECIMAL = new BigDecimal("" + Long.MAX_VALUE);
private static final BigDecimal MIN_LONG_DECIMAL = new BigDecimal("" + Long.MIN_VALUE);
/**
* Get the SQL expression for this value.
*
* @return the SQL expression
*/
public abstract String getSQL();
/**
* Get the value type.
*
* @return the type
*/
public abstract int getType();
/**
* Get the precision.
*
* @return the precision
*/
public abstract long getPrecision();
/**
* Get the display size in characters.
*
* @return the display size
*/
public abstract int getDisplaySize();
/**
* Get the memory used by this object.
*
* @return the memory used in bytes
*/
public int getMemory() {
return DataType.getDataType(getType()).memory * 4;
}
/**
* Get the value as a string.
*
* @return the string
*/
public abstract String getString();
/**
* Get the value as an object.
*
* @return the object
*/
public abstract Object getObject();
/**
* Set the value as a parameter in a prepared statement.
*
* @param prep the prepared statement
* @param parameterIndex the parameter index
*/
public abstract void set(PreparedStatement prep, int parameterIndex) throws SQLException;
/**
* Compare the value with another value of the same type.
*
* @param v the other value
* @param mode the compare mode
* @return 0 if both values are equal, -1 if the other value is smaller, and
* 1 otherwise
*/
protected abstract int compareSecure(Value v, CompareMode mode) throws SQLException;
public abstract int hashCode();
/**
* Check if the two values are equal.
* No data conversion is made; this method returns false
* if the other object is not of the same class.
*
* @param other the other value
* @return true if they are equal
*/
public abstract boolean equals(Object other);
public static int getOrder(int type) {
switch(type) {
case UNKNOWN:
return 1;
case NULL:
return 2;
case STRING:
return 10;
case CLOB:
return 11;
case STRING_FIXED:
return 12;
case STRING_IGNORECASE:
return 13;
case BOOLEAN:
return 20;
case BYTE:
return 21;
case SHORT:
return 22;
case INT:
return 23;
case LONG:
return 24;
case DECIMAL:
return 25;
case FLOAT:
return 26;
case DOUBLE:
return 27;
case TIME:
return 30;
case DATE:
return 31;
case TIMESTAMP:
return 32;
case BYTES:
return 40;
case BLOB:
return 41;
case UUID:
return 42;
case JAVA_OBJECT:
return 43;
case ARRAY:
return 50;
case RESULT_SET:
return 51;
default:
throw Message.getInternalError("type:"+type);
}
}
public static int getHigherOrder(int t1, int t2) throws SQLException {
if (t1 == t2) {
if (t1 == Value.UNKNOWN) {
throw Message.getSQLException(ErrorCode.UNKNOWN_DATA_TYPE_1, "?, ?");
}
return t1;
}
int o1 = getOrder(t1);
int o2 = getOrder(t2);
return o1 > o2 ? t1 : t2;
}
static Value cache(Value v) {
if (SysProperties.OBJECT_CACHE) {
Value[] cache = (Value[]) softCache.get();
int hash = v.hashCode();
if (cache == null) {
cache = new Value[SysProperties.OBJECT_CACHE_SIZE];
softCache = new SoftReference(cache);
}
int index = hash & (SysProperties.OBJECT_CACHE_SIZE - 1);
Value cached = cache[index];
if (cached != null) {
if (cached.getType() == v.getType() && v.equals(cached)) {
// cacheHit++;
return cached;
}
}
// cacheMiss++;
// cache[cacheCleaner] = null;
// cacheCleaner = (cacheCleaner + 1) & (Constants.OBJECT_CACHE_SIZE - 1);
cache[index] = v;
}
return v;
}
public Boolean getBoolean() throws SQLException {
return ((ValueBoolean) convertTo(Value.BOOLEAN)).getBoolean();
}
public Date getDate() throws SQLException {
return ((ValueDate) convertTo(Value.DATE)).getDate();
}
public Date getDateNoCopy() throws SQLException {
return ((ValueDate) convertTo(Value.DATE)).getDateNoCopy();
}
public Time getTime() throws SQLException {
return ((ValueTime) convertTo(Value.TIME)).getTime();
}
public Time getTimeNoCopy() throws SQLException {
return ((ValueTime) convertTo(Value.TIME)).getTimeNoCopy();
}
public Timestamp getTimestamp() throws SQLException {
return ((ValueTimestamp) convertTo(Value.TIMESTAMP)).getTimestamp();
}
public Timestamp getTimestampNoCopy() throws SQLException {
return ((ValueTimestamp) convertTo(Value.TIMESTAMP)).getTimestampNoCopy();
}
public byte[] getBytes() throws SQLException {
return ((ValueBytes) convertTo(Value.BYTES)).getBytes();
}
public byte[] getBytesNoCopy() throws SQLException {
return ((ValueBytes) convertTo(Value.BYTES)).getBytesNoCopy();
}
public byte getByte() throws SQLException {
return ((ValueByte) convertTo(Value.BYTE)).getByte();
}
public short getShort() throws SQLException {
return ((ValueShort) convertTo(Value.SHORT)).getShort();
}
public BigDecimal getBigDecimal() throws SQLException {
return ((ValueDecimal) convertTo(Value.DECIMAL)).getBigDecimal();
}
public double getDouble() throws SQLException {
return ((ValueDouble) convertTo(Value.DOUBLE)).getDouble();
}
public float getFloat() throws SQLException {
return ((ValueFloat) convertTo(Value.FLOAT)).getFloat();
}
public int getInt() throws SQLException {
return ((ValueInt) convertTo(Value.INT)).getInt();
}
public long getLong() throws SQLException {
return ((ValueLong) convertTo(Value.LONG)).getLong();
}
public InputStream getInputStream() throws SQLException {
return new ByteArrayInputStream(getBytesNoCopy());
}
public Reader getReader() throws SQLException {
return IOUtils.getReader(getString());
}
public Value add(Value v) throws SQLException {
throw Message.getUnsupportedException();
}
public int getSignum() throws SQLException {
throw Message.getUnsupportedException();
}
public Value negate() throws SQLException {
throw Message.getUnsupportedException();
}
public Value subtract(Value v) throws SQLException {
throw Message.getUnsupportedException();
}
public Value divide(Value v) throws SQLException {
throw Message.getUnsupportedException();
}
public Value multiply(Value v) throws SQLException {
throw Message.getUnsupportedException();
}
public Value convertTo(int type) throws SQLException {
// converting NULL done in ValueNull
// converting BLOB to CLOB and vice versa is done in ValueLob
if (getType() == type) {
return this;
}
// decimal conversion
switch (type) {
case BOOLEAN: {
switch (getType()) {
case BYTE:
case SHORT:
case INT:
case LONG:
case DECIMAL:
case DOUBLE:
case FLOAT:
return ValueBoolean.get(getSignum() != 0);
case TIME:
case DATE:
case TIMESTAMP:
case BYTES:
case JAVA_OBJECT:
case UUID:
throw Message.getSQLException(ErrorCode.DATA_CONVERSION_ERROR_1, getString());
}
break;
}
case BYTE: {
switch (getType()) {
case BOOLEAN:
return ValueByte.get(getBoolean().booleanValue() ? (byte) 1 : (byte) 0);
case SHORT:
return ValueByte.get(convertToByte(getShort()));
case INT:
return ValueByte.get(convertToByte(getInt()));
case LONG:
return ValueByte.get(convertToByte(getLong()));
case DECIMAL:
return ValueByte.get(convertToByte(convertToLong(getBigDecimal())));
case DOUBLE:
return ValueByte.get(convertToByte(convertToLong(getDouble())));
case FLOAT:
return ValueByte.get(convertToByte(convertToLong(getFloat())));
}
break;
}
case SHORT: {
switch (getType()) {
case BOOLEAN:
return ValueShort.get(getBoolean().booleanValue() ? (short) 1 : (short) 0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -