Unverified 提交 11b7e7cd authored 作者: Noel Grandin's avatar Noel Grandin 提交者: GitHub

Merge pull request #1233 from grandinj/simplify_old_lob

Simplify old lob ValueLob class
......@@ -584,7 +584,6 @@ public class Data {
writeByte((byte) type);
if (v instanceof ValueLob) {
ValueLob lob = (ValueLob) v;
lob.convertToFileIfRequired(handler);
byte[] small = lob.getSmall();
if (small == null) {
int t = -1;
......@@ -1013,7 +1012,6 @@ public class Data {
int len = 1;
if (v instanceof ValueLob) {
ValueLob lob = (ValueLob) v;
lob.convertToFileIfRequired(handler);
byte[] small = lob.getSmall();
if (small == null) {
int t = -1;
......
......@@ -214,7 +214,7 @@ public class Recover extends Tool implements DataHandler {
/**
* INTERNAL
*/
public static Value.ValueBlob readBlobDb(Connection conn, long lobId,
public static ValueLobDb readBlobDb(Connection conn, long lobId,
long precision) {
DataHandler h = ((JdbcConnection) conn).getSession().getDataHandler();
verifyPageStore(h);
......@@ -235,7 +235,7 @@ public class Recover extends Tool implements DataHandler {
/**
* INTERNAL
*/
public static Value.ValueClob readClobDb(Connection conn, long lobId,
public static ValueLobDb readClobDb(Connection conn, long lobId,
long precision) {
DataHandler h = ((JdbcConnection) conn).getSession().getDataHandler();
verifyPageStore(h);
......
......@@ -995,10 +995,11 @@ public class DataType {
return Value.DECIMAL;
} else if (ResultSet.class.isAssignableFrom(x)) {
return Value.RESULT_SET;
} else if (Value.ValueBlob.class.isAssignableFrom(x)) {
} else if (ValueLobDb.class.isAssignableFrom(x)) {
return Value.BLOB;
} else if (Value.ValueClob.class.isAssignableFrom(x)) {
return Value.CLOB;
// FIXME no way to distinguish between these 2 types
// } else if (ValueLobDb.class.isAssignableFrom(x)) {
// return Value.CLOB;
} else if (Date.class.isAssignableFrom(x)) {
return Value.DATE;
} else if (Time.class.isAssignableFrom(x)) {
......
......@@ -1395,18 +1395,4 @@ public abstract class Value {
return null;
}
/**
* A "binary large object".
*/
public interface ValueClob {
// this is a marker interface
}
/**
* A "character large object".
*/
public interface ValueBlob {
// this is a marker interface
}
}
......@@ -6,15 +6,12 @@
package org.h2.value;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.nio.charset.StandardCharsets;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import org.h2.engine.Constants;
import org.h2.engine.Mode;
import org.h2.engine.SysProperties;
......@@ -22,7 +19,6 @@ import org.h2.message.DbException;
import org.h2.store.DataHandler;
import org.h2.store.FileStore;
import org.h2.store.FileStoreInputStream;
import org.h2.store.FileStoreOutputStream;
import org.h2.store.RangeInputStream;
import org.h2.store.RangeReader;
import org.h2.store.fs.FileUtils;
......@@ -34,19 +30,8 @@ import org.h2.util.StringUtils;
import org.h2.util.Utils;
/**
* Implementation of the BLOB and CLOB data types. Small objects are kept in
* memory and stored in the record.
*
* Large objects are stored in their own files. When large objects are set in a
* prepared statement, they are first stored as 'temporary' files. Later, when
* they are used in a record, and when the record is stored, the lob files are
* linked: the file is renamed using the file format (tableId).(objectId). There
* is one exception: large variables are stored in the file (-1).(objectId).
*
* When lobs are deleted, they are first renamed to a temp file, and if the
* delete operation is committed the file is deleted.
*
* Data compression is supported.
* This is the legacy implementation of LOBs for PageStore databases where the
* LOB was stored in an external file.
*/
public class ValueLob extends Value {
......@@ -109,22 +94,23 @@ public class ValueLob extends Value {
*/
private static int dirCounter;
private final int type;
private long precision;
private DataHandler handler;
/**
* either Value.BLOB or Value.CLOB
*/
private final int valueType;
private final long precision;
private final DataHandler handler;
private int tableId;
private int objectId;
private final int objectId;
private String fileName;
private boolean linked;
private byte[] small;
private int hash;
private boolean compressed;
private FileStore tempFile;
private final boolean compressed;
private ValueLob(int type, DataHandler handler, String fileName,
int tableId, int objectId, boolean linked, long precision,
boolean compressed) {
this.type = type;
this.valueType = type;
this.handler = handler;
this.fileName = fileName;
this.tableId = tableId;
......@@ -134,37 +120,6 @@ public class ValueLob extends Value {
this.compressed = compressed;
}
private ValueLob(int type, byte[] small) {
this.type = type;
this.small = small;
if (small != null) {
if (type == Value.BLOB) {
this.precision = small.length;
} else {
this.precision = getString().length();
}
}
}
private static ValueLob copy(ValueLob lob) {
ValueLob copy = new ValueLob(lob.type, lob.handler, lob.fileName,
lob.tableId, lob.objectId, lob.linked, lob.precision, lob.compressed);
copy.small = lob.small;
copy.hash = lob.hash;
return copy;
}
/**
* Create a small lob using the given byte array.
*
* @param type the type (Value.BLOB or CLOB)
* @param small the byte array
* @return the lob value
*/
private static ValueLob createSmallLob(int type, byte[] small) {
return new ValueLob(type, small);
}
private static String getFileName(DataHandler handler, int tableId,
int objectId) {
if (SysProperties.CHECK && tableId == 0 && objectId == 0) {
......@@ -178,7 +133,7 @@ public class ValueLob extends Value {
/**
* Create a LOB value with the given parameters.
*
* @param type the data type
* @param type the data type, either Value.BLOB or Value.CLOB
* @param handler the file handler
* @param tableId the table object id
* @param objectId the object id
......@@ -196,7 +151,7 @@ public class ValueLob extends Value {
/**
* Create a LOB value with the given parameters.
*
* @param type the data type
* @param type the data type, either Value.BLOB or Value.CLOB
* @param handler the file handler
* @param tableId the table object id
* @param objectId the object id
......@@ -212,92 +167,6 @@ public class ValueLob extends Value {
false/* linked */, precision, compression);
}
/**
* Create a CLOB value from a stream.
*
* @param in the reader
* @param length the number of characters to read, or -1 for no limit
* @param handler the data handler
* @return the lob value
*/
private static ValueLob createClob(Reader in, long length,
DataHandler handler) {
try {
if (handler == null) {
String s = IOUtils.readStringAndClose(in, (int) length);
return createSmallLob(Value.CLOB, s.getBytes(StandardCharsets.UTF_8));
}
boolean compress = handler.getLobCompressionAlgorithm(Value.CLOB) != null;
long remaining = Long.MAX_VALUE;
if (length >= 0 && length < remaining) {
remaining = length;
}
int len = getBufferSize(handler, compress, remaining);
char[] buff;
if (len >= Integer.MAX_VALUE) {
String data = IOUtils.readStringAndClose(in, -1);
buff = data.toCharArray();
len = buff.length;
} else {
buff = new char[len];
len = IOUtils.readFully(in, buff, len);
}
if (len <= handler.getMaxLengthInplaceLob()) {
byte[] small = new String(buff, 0, len).getBytes(StandardCharsets.UTF_8);
return ValueLob.createSmallLob(Value.CLOB, small);
}
ValueLob lob = new ValueLob(Value.CLOB, null);
lob.createFromReader(buff, len, in, remaining, handler);
return lob;
} catch (IOException e) {
throw DbException.convertIOException(e, null);
}
}
private static int getBufferSize(DataHandler handler, boolean compress,
long remaining) {
if (remaining < 0 || remaining > Integer.MAX_VALUE) {
remaining = Integer.MAX_VALUE;
}
int inplace = handler.getMaxLengthInplaceLob();
long m = compress ?
Constants.IO_BUFFER_SIZE_COMPRESS : Constants.IO_BUFFER_SIZE;
if (m < remaining && m <= inplace) {
// using "1L" to force long arithmetic
m = Math.min(remaining, inplace + 1L);
// the buffer size must be bigger than the inplace lob, otherwise we
// can't know if it must be stored in-place or not
m = MathUtils.roundUpLong(m, Constants.IO_BUFFER_SIZE);
}
m = Math.min(remaining, m);
m = MathUtils.convertLongToInt(m);
if (m < 0) {
m = Integer.MAX_VALUE;
}
return (int) m;
}
private void createFromReader(char[] buff, int len, Reader in,
long remaining, DataHandler h) throws IOException {
try (FileStoreOutputStream out = initLarge(h)) {
boolean compress = h.getLobCompressionAlgorithm(Value.CLOB) != null;
while (true) {
precision += len;
byte[] b = new String(buff, 0, len).getBytes(StandardCharsets.UTF_8);
out.write(b, 0, b.length);
remaining -= len;
if (remaining <= 0) {
break;
}
len = getBufferSize(h, compress, remaining);
len = IOUtils.readFully(in, buff, len);
if (len == 0) {
break;
}
}
}
}
private static String getFileNamePrefix(String path, int objectId) {
String name;
int f = objectId % SysProperties.LOB_FILES_PER_DIRECTORY;
......@@ -406,91 +275,6 @@ public class ValueLob extends Value {
return list;
}
/**
* Create a BLOB value from a stream.
*
* @param in the input stream
* @param length the number of characters to read, or -1 for no limit
* @param handler the data handler
* @return the lob value
*/
private static ValueLob createBlob(InputStream in, long length,
DataHandler handler) {
try {
if (handler == null) {
byte[] data = IOUtils.readBytesAndClose(in, (int) length);
return createSmallLob(Value.BLOB, data);
}
long remaining = Long.MAX_VALUE;
boolean compress = handler.getLobCompressionAlgorithm(Value.BLOB) != null;
if (length >= 0 && length < remaining) {
remaining = length;
}
int len = getBufferSize(handler, compress, remaining);
byte[] buff;
if (len >= Integer.MAX_VALUE) {
buff = IOUtils.readBytesAndClose(in, -1);
len = buff.length;
} else {
buff = Utils.newBytes(len);
len = IOUtils.readFully(in, buff, len);
}
if (len <= handler.getMaxLengthInplaceLob()) {
byte[] small = Utils.copyBytes(buff, len);
return ValueLob.createSmallLob(Value.BLOB, small);
}
ValueLob lob = new ValueLob(Value.BLOB, null);
lob.createFromStream(buff, len, in, remaining, handler);
return lob;
} catch (IOException e) {
throw DbException.convertIOException(e, null);
}
}
private FileStoreOutputStream initLarge(DataHandler h) {
this.handler = h;
this.tableId = 0;
this.linked = false;
this.precision = 0;
this.small = null;
this.hash = 0;
String compressionAlgorithm = h.getLobCompressionAlgorithm(type);
this.compressed = compressionAlgorithm != null;
synchronized (h) {
String path = h.getDatabasePath();
if ((path != null) && (path.length() == 0)) {
path = new File(Utils.getProperty("java.io.tmpdir", "."),
SysProperties.PREFIX_TEMP_FILE).getAbsolutePath();
}
objectId = getNewObjectId(h);
fileName = getFileNamePrefix(path, objectId) + Constants.SUFFIX_TEMP_FILE;
tempFile = h.openFile(fileName, "rw", false);
tempFile.autoDelete();
}
return new FileStoreOutputStream(tempFile, h,
compressionAlgorithm);
}
private void createFromStream(byte[] buff, int len, InputStream in,
long remaining, DataHandler h) throws IOException {
try (FileStoreOutputStream out = initLarge(h)) {
boolean compress = h.getLobCompressionAlgorithm(Value.BLOB) != null;
while (true) {
precision += len;
out.write(buff, 0, len);
remaining -= len;
if (remaining <= 0) {
break;
}
len = getBufferSize(h, compress, remaining);
len = IOUtils.readFully(in, buff, len);
if (len <= 0) {
break;
}
}
}
}
/**
* Convert a lob to another data type. The data is fully read in memory
* except when converting to BLOB or CLOB.
......@@ -507,12 +291,12 @@ public class ValueLob extends Value {
*/
@Override
public Value convertTo(int t, int precision, Mode mode, Object column, String[] enumerators) {
if (t == type) {
if (t == valueType) {
return this;
} else if (t == Value.CLOB) {
return ValueLob.createClob(getReader(), -1, handler);
return ValueLobDb.createTempClob(getReader(), -1, handler);
} else if (t == Value.BLOB) {
return ValueLob.createBlob(getInputStream(), -1, handler);
return ValueLobDb.createTempBlob(getInputStream(), -1, handler);
}
return super.convertTo(t, precision, mode, column, null);
}
......@@ -533,24 +317,15 @@ public class ValueLob extends Value {
@Override
public void remove() {
if (fileName != null) {
if (tempFile != null) {
tempFile.stopAutoDelete();
tempFile = null;
}
deleteFile(handler, fileName);
}
deleteFile(handler, fileName);
}
@Override
public Value copy(DataHandler h, int tabId) {
if (fileName == null) {
this.tableId = tabId;
return this;
}
if (linked) {
ValueLob copy = ValueLob.copy(this);
copy.objectId = getNewObjectId(h);
ValueLob copy = new ValueLob(this.valueType, this.handler, this.fileName,
this.tableId, getNewObjectId(h), this.linked, this.precision, this.compressed);
copy.hash = this.hash;
copy.tableId = tabId;
String live = getFileName(h, copy.tableId, copy.objectId);
copyFileTo(h, fileName, live);
......@@ -561,10 +336,6 @@ public class ValueLob extends Value {
if (!linked) {
this.tableId = tabId;
String live = getFileName(h, tableId, objectId);
if (tempFile != null) {
tempFile.stopAutoDelete();
tempFile = null;
}
renameFile(h, fileName, live);
fileName = live;
linked = true;
......@@ -593,7 +364,7 @@ public class ValueLob extends Value {
@Override
public int getType() {
return type;
return valueType;
}
@Override
......@@ -606,18 +377,10 @@ public class ValueLob extends Value {
int len = precision > Integer.MAX_VALUE || precision == 0 ?
Integer.MAX_VALUE : (int) precision;
try {
if (type == Value.CLOB) {
if (small != null) {
return new String(small, StandardCharsets.UTF_8);
}
if (valueType == Value.CLOB) {
return IOUtils.readStringAndClose(getReader(), len);
}
byte[] buff;
if (small != null) {
buff = small;
} else {
buff = IOUtils.readBytesAndClose(getInputStream(), len);
}
byte[] buff = IOUtils.readBytesAndClose(getInputStream(), len);
return StringUtils.convertBytesToHex(buff);
} catch (IOException e) {
throw DbException.convertIOException(e, fileName);
......@@ -626,7 +389,7 @@ public class ValueLob extends Value {
@Override
public byte[] getBytes() {
if (type == CLOB) {
if (valueType == CLOB) {
// convert hex to string
return super.getBytes();
}
......@@ -636,13 +399,10 @@ public class ValueLob extends Value {
@Override
public byte[] getBytesNoCopy() {
if (type == CLOB) {
if (valueType == CLOB) {
// convert hex to string
return super.getBytesNoCopy();
}
if (small != null) {
return small;
}
try {
return IOUtils.readBytesAndClose(
getInputStream(), Integer.MAX_VALUE);
......@@ -659,7 +419,7 @@ public class ValueLob extends Value {
// it in the database file
return (int) (precision ^ (precision >>> 32));
}
if (type == CLOB) {
if (valueType == CLOB) {
hash = getString().hashCode();
} else {
hash = Utils.getByteArrayHash(getBytes());
......@@ -670,7 +430,7 @@ public class ValueLob extends Value {
@Override
protected int compareSecure(Value v, CompareMode mode) {
if (type == Value.CLOB) {
if (valueType == Value.CLOB) {
return Integer.signum(getString().compareTo(v.getString()));
}
byte[] v2 = v.getBytesNoCopy();
......@@ -679,7 +439,7 @@ public class ValueLob extends Value {
@Override
public Object getObject() {
if (type == Value.CLOB) {
if (valueType == Value.CLOB) {
return getReader();
}
return getInputStream();
......@@ -692,14 +452,11 @@ public class ValueLob extends Value {
@Override
public Reader getReader(long oneBasedOffset, long length) {
return rangeReader(getReader(), oneBasedOffset, length, type == Value.CLOB ? precision : -1);
return rangeReader(getReader(), oneBasedOffset, length, valueType == Value.CLOB ? precision : -1);
}
@Override
public InputStream getInputStream() {
if (fileName == null) {
return new ByteArrayInputStream(small);
}
FileStore store = handler.openFile(fileName, "r", true);
boolean alwaysClose = SysProperties.lobCloseBetweenReads;
return new BufferedInputStream(
......@@ -709,9 +466,6 @@ public class ValueLob extends Value {
@Override
public InputStream getInputStream(long oneBasedOffset, long length) {
if (fileName == null) {
return super.getInputStream(oneBasedOffset, length);
}
FileStore store = handler.openFile(fileName, "r", true);
boolean alwaysClose = SysProperties.lobCloseBetweenReads;
InputStream inputStream = new BufferedInputStream(
......@@ -727,7 +481,7 @@ public class ValueLob extends Value {
if (p > Integer.MAX_VALUE || p <= 0) {
p = -1;
}
if (type == Value.BLOB) {
if (valueType == Value.BLOB) {
prep.setBinaryStream(parameterIndex, getInputStream(), (int) p);
} else {
prep.setCharacterStream(parameterIndex, getReader(), (int) p);
......@@ -737,7 +491,7 @@ public class ValueLob extends Value {
@Override
public String getSQL() {
String s;
if (type == Value.CLOB) {
if (valueType == Value.CLOB) {
s = getString();
return StringUtils.quoteStringSQL(s);
}
......@@ -748,11 +502,8 @@ public class ValueLob extends Value {
@Override
public String getTraceSQL() {
if (small != null && getPrecision() <= SysProperties.MAX_TRACE_DATA_LENGTH) {
return getSQL();
}
StringBuilder buff = new StringBuilder();
if (type == Value.CLOB) {
if (valueType == Value.CLOB) {
buff.append("SPACE(").append(getPrecision());
} else {
buff.append("CAST(REPEAT('00', ").append(getPrecision()).append(") AS BINARY");
......@@ -768,7 +519,7 @@ public class ValueLob extends Value {
*/
@Override
public byte[] getSmall() {
return small;
return null;
}
@Override
......@@ -781,35 +532,6 @@ public class ValueLob extends Value {
return other instanceof ValueLob && compareSecure((Value) other, null) == 0;
}
/**
* Store the lob data to a file if the size of the buffer is larger than the
* maximum size for an in-place lob.
*
* @param h the data handler
*/
public void convertToFileIfRequired(DataHandler h) {
try {
if (small != null && small.length > h.getMaxLengthInplaceLob()) {
boolean compress = h.getLobCompressionAlgorithm(type) != null;
int len = getBufferSize(h, compress, Long.MAX_VALUE);
int tabId = tableId;
if (type == Value.BLOB) {
createFromStream(
Utils.newBytes(len), 0, getInputStream(), Long.MAX_VALUE, h);
} else {
createFromReader(
new char[len], 0, getReader(), Long.MAX_VALUE, h);
}
Value v2 = copy(h, tabId);
if (SysProperties.CHECK && v2 != this) {
DbException.throwInternalError(v2.toString());
}
}
} catch (IOException e) {
throw DbException.convertIOException(e, null);
}
}
/**
* Check if this lob value is compressed.
*
......@@ -848,9 +570,6 @@ public class ValueLob extends Value {
@Override
public int getMemory() {
if (small != null) {
return small.length + 104;
}
return 140;
}
......@@ -861,12 +580,12 @@ public class ValueLob extends Value {
* @return the value
*/
@Override
public ValueLob copyToTemp() {
ValueLob lob;
if (type == CLOB) {
lob = ValueLob.createClob(getReader(), precision, handler);
public ValueLobDb copyToTemp() {
ValueLobDb lob;
if (valueType == CLOB) {
lob = ValueLobDb.createTempClob(getReader(), precision, handler);
} else {
lob = ValueLob.createBlob(getInputStream(), precision, handler);
lob = ValueLobDb.createTempBlob(getInputStream(), precision, handler);
}
return lob;
}
......@@ -876,11 +595,11 @@ public class ValueLob extends Value {
if (this.precision <= precision) {
return this;
}
ValueLob lob;
if (type == CLOB) {
lob = ValueLob.createClob(getReader(), precision, handler);
ValueLobDb lob;
if (valueType == CLOB) {
lob = ValueLobDb.createTempClob(getReader(), precision, handler);
} else {
lob = ValueLob.createBlob(getInputStream(), precision, handler);
lob = ValueLobDb.createTempBlob(getInputStream(), precision, handler);
}
return lob;
}
......
......@@ -39,10 +39,12 @@ import org.h2.util.Utils;
* Small objects are kept in memory and stored in the record.
* Large objects are either stored in the database, or in temporary files.
*/
public class ValueLobDb extends Value implements Value.ValueClob,
Value.ValueBlob {
public class ValueLobDb extends Value {
private final int type;
/**
* the value type (Value.BLOB or CLOB)
*/
private final int valueType;
private final long lobId;
private final byte[] hmac;
private final byte[] small;
......@@ -66,7 +68,7 @@ public class ValueLobDb extends Value implements Value.ValueClob,
private ValueLobDb(int type, DataHandler handler, int tableId, long lobId,
byte[] hmac, long precision) {
this.type = type;
this.valueType = type;
this.handler = handler;
this.tableId = tableId;
this.lobId = lobId;
......@@ -78,7 +80,7 @@ public class ValueLobDb extends Value implements Value.ValueClob,
}
private ValueLobDb(int type, byte[] small, long precision) {
this.type = type;
this.valueType = type;
this.small = small;
this.precision = precision;
this.lobId = 0;
......@@ -94,7 +96,7 @@ public class ValueLobDb extends Value implements Value.ValueClob,
*/
private ValueLobDb(DataHandler handler, Reader in, long remaining)
throws IOException {
this.type = Value.CLOB;
this.valueType = Value.CLOB;
this.handler = handler;
this.small = null;
this.lobId = 0;
......@@ -126,7 +128,7 @@ public class ValueLobDb extends Value implements Value.ValueClob,
*/
private ValueLobDb(DataHandler handler, byte[] buff, int len, InputStream in,
long remaining) throws IOException {
this.type = Value.BLOB;
this.valueType = Value.BLOB;
this.handler = handler;
this.small = null;
this.lobId = 0;
......@@ -167,7 +169,7 @@ public class ValueLobDb extends Value implements Value.ValueClob,
/**
* Create a LOB value.
*
* @param type the type
* @param type the type (Value.BLOB or CLOB)
* @param handler the data handler
* @param tableId the table id
* @param id the lob id
......@@ -194,7 +196,7 @@ public class ValueLobDb extends Value implements Value.ValueClob,
*/
@Override
public Value convertTo(int t, int precision, Mode mode, Object column, String[] enumerators) {
if (t == type) {
if (t == valueType) {
return this;
} else if (t == Value.CLOB) {
if (handler != null) {
......@@ -248,7 +250,7 @@ public class ValueLobDb extends Value implements Value.ValueClob,
} else if (small.length > database.getMaxLengthInplaceLob()) {
LobStorageInterface s = database.getLobStorage();
Value v;
if (type == Value.BLOB) {
if (valueType == Value.BLOB) {
v = s.createBlob(getInputStream(), getPrecision());
} else {
v = s.createClob(getReader(), getPrecision());
......@@ -272,7 +274,7 @@ public class ValueLobDb extends Value implements Value.ValueClob,
@Override
public int getType() {
return type;
return valueType;
}
@Override
......@@ -285,7 +287,7 @@ public class ValueLobDb extends Value implements Value.ValueClob,
int len = precision > Integer.MAX_VALUE || precision == 0 ?
Integer.MAX_VALUE : (int) precision;
try {
if (type == Value.CLOB) {
if (valueType == Value.CLOB) {
if (small != null) {
return new String(small, StandardCharsets.UTF_8);
}
......@@ -305,7 +307,7 @@ public class ValueLobDb extends Value implements Value.ValueClob,
@Override
public byte[] getBytes() {
if (type == CLOB) {
if (valueType == CLOB) {
// convert hex to string
return super.getBytes();
}
......@@ -315,7 +317,7 @@ public class ValueLobDb extends Value implements Value.ValueClob,
@Override
public byte[] getBytesNoCopy() {
if (type == CLOB) {
if (valueType == CLOB) {
// convert hex to string
return super.getBytesNoCopy();
}
......@@ -337,7 +339,7 @@ public class ValueLobDb extends Value implements Value.ValueClob,
// it in the database file
return (int) (precision ^ (precision >>> 32));
}
if (type == CLOB) {
if (valueType == CLOB) {
hash = getString().hashCode();
} else {
hash = Utils.getByteArrayHash(getBytes());
......@@ -357,7 +359,7 @@ public class ValueLobDb extends Value implements Value.ValueClob,
return 0;
}
}
if (type == Value.CLOB) {
if (valueType == Value.CLOB) {
return Integer.signum(getString().compareTo(v.getString()));
}
byte[] v2 = v.getBytesNoCopy();
......@@ -366,7 +368,7 @@ public class ValueLobDb extends Value implements Value.ValueClob,
@Override
public Object getObject() {
if (type == Value.CLOB) {
if (valueType == Value.CLOB) {
return getReader();
}
return getInputStream();
......@@ -379,7 +381,7 @@ public class ValueLobDb extends Value implements Value.ValueClob,
@Override
public Reader getReader(long oneBasedOffset, long length) {
return ValueLob.rangeReader(getReader(), oneBasedOffset, length, type == Value.CLOB ? precision : -1);
return ValueLob.rangeReader(getReader(), oneBasedOffset, length, valueType == Value.CLOB ? precision : -1);
}
@Override
......@@ -392,7 +394,7 @@ public class ValueLobDb extends Value implements Value.ValueClob,
return new BufferedInputStream(new FileStoreInputStream(store,
handler, false, alwaysClose), Constants.IO_BUFFER_SIZE);
}
long byteCount = (type == Value.BLOB) ? precision : -1;
long byteCount = (valueType == Value.BLOB) ? precision : -1;
try {
return handler.getLobStorage().getInputStream(this, hmac, byteCount);
} catch (IOException e) {
......@@ -413,7 +415,7 @@ public class ValueLobDb extends Value implements Value.ValueClob,
inputStream = new BufferedInputStream(new FileStoreInputStream(store,
handler, false, alwaysClose), Constants.IO_BUFFER_SIZE);
} else {
byteCount = (type == Value.BLOB) ? precision : -1;
byteCount = (valueType == Value.BLOB) ? precision : -1;
try {
inputStream = handler.getLobStorage().getInputStream(this, hmac, byteCount);
} catch (IOException e) {
......@@ -430,7 +432,7 @@ public class ValueLobDb extends Value implements Value.ValueClob,
if (p > Integer.MAX_VALUE || p <= 0) {
p = -1;
}
if (type == Value.BLOB) {
if (valueType == Value.BLOB) {
prep.setBinaryStream(parameterIndex, getInputStream(), (int) p);
} else {
prep.setCharacterStream(parameterIndex, getReader(), (int) p);
......@@ -440,7 +442,7 @@ public class ValueLobDb extends Value implements Value.ValueClob,
@Override
public String getSQL() {
String s;
if (type == Value.CLOB) {
if (valueType == Value.CLOB) {
s = getString();
return StringUtils.quoteStringSQL(s);
}
......@@ -455,7 +457,7 @@ public class ValueLobDb extends Value implements Value.ValueClob,
return getSQL();
}
StringBuilder buff = new StringBuilder();
if (type == Value.CLOB) {
if (valueType == Value.CLOB) {
buff.append("SPACE(").append(getPrecision());
} else {
buff.append("CAST(REPEAT('00', ").append(getPrecision()).append(") AS BINARY");
......@@ -650,13 +652,13 @@ public class ValueLobDb extends Value implements Value.ValueClob,
return this;
}
ValueLobDb lob;
if (type == CLOB) {
if (valueType == CLOB) {
if (handler == null) {
try {
int p = MathUtils.convertLongToInt(precision);
String s = IOUtils.readStringAndClose(getReader(), p);
byte[] data = s.getBytes(StandardCharsets.UTF_8);
lob = ValueLobDb.createSmallLob(type, data, s.length());
lob = ValueLobDb.createSmallLob(valueType, data, s.length());
} catch (IOException e) {
throw DbException.convertIOException(e, null);
}
......@@ -668,7 +670,7 @@ public class ValueLobDb extends Value implements Value.ValueClob,
try {
int p = MathUtils.convertLongToInt(precision);
byte[] data = IOUtils.readBytesAndClose(getInputStream(), p);
lob = ValueLobDb.createSmallLob(type, data, data.length);
lob = ValueLobDb.createSmallLob(valueType, data, data.length);
} catch (IOException e) {
throw DbException.convertIOException(e, null);
}
......
......@@ -265,8 +265,9 @@ public class TestValue extends TestDb {
testDataType(Value.NULL, Void.class);
testDataType(Value.DECIMAL, BigDecimal.class);
testDataType(Value.RESULT_SET, ResultSet.class);
testDataType(Value.BLOB, Value.ValueBlob.class);
testDataType(Value.CLOB, Value.ValueClob.class);
testDataType(Value.BLOB, ValueLobDb.class);
// see FIXME in DataType.getTypeFromClass
//testDataType(Value.CLOB, Value.ValueClob.class);
testDataType(Value.DATE, Date.class);
testDataType(Value.TIME, Time.class);
testDataType(Value.TIMESTAMP, Timestamp.class);
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论