提交 8fd3db60 authored 作者: noelgrandin's avatar noelgrandin

Split the LobStorage class into client-side and server-side code.

This is a cleanup targetted at allowing us to fix a deadlock issue.
上级 9ed50ccb
......@@ -25,7 +25,7 @@ import org.h2.store.DataHandler;
import org.h2.store.FileStore;
import org.h2.store.FileStoreInputStream;
import org.h2.store.FileStoreOutputStream;
import org.h2.store.LobStorage;
import org.h2.store.LobStorageBackend;
import org.h2.store.fs.FileUtils;
import org.h2.tools.CompressTool;
import org.h2.util.IOUtils;
......@@ -232,7 +232,7 @@ abstract class ScriptBase extends Prepared implements DataHandler {
return null;
}
public LobStorage getLobStorage() {
public LobStorageBackend getLobStorage() {
return null;
}
......
......@@ -40,7 +40,7 @@ import org.h2.store.DataHandler;
import org.h2.store.FileLock;
import org.h2.store.FileStore;
import org.h2.store.InDoubtTransaction;
import org.h2.store.LobStorage;
import org.h2.store.LobStorageBackend;
import org.h2.store.PageStore;
import org.h2.store.WriterThread;
import org.h2.store.fs.FileUtils;
......@@ -167,7 +167,7 @@ public class Database implements DataHandler {
private SourceCompiler compiler;
private volatile boolean metaTablesInitialized;
private boolean flushOnEachCommit;
private LobStorage lobStorage;
private LobStorageBackend lobStorage;
private final int pageSize;
private int defaultTableType = Table.TYPE_CACHED;
private final DbSettings dbSettings;
......@@ -1102,11 +1102,11 @@ public class Database implements DataHandler {
}
// remove all session variables
if (persistent) {
boolean lobStorageIsUsed = infoSchema.findTableOrView(systemSession, LobStorage.LOB_DATA_TABLE) != null;
boolean lobStorageIsUsed = infoSchema.findTableOrView(systemSession, LobStorageBackend.LOB_DATA_TABLE) != null;
if (lobStorageIsUsed) {
try {
getLobStorage();
lobStorage.removeAllForTable(LobStorage.TABLE_ID_SESSION_VARIABLE);
lobStorage.removeAllForTable(LobStorageBackend.TABLE_ID_SESSION_VARIABLE);
} catch (DbException e) {
trace.error(e, "close");
}
......@@ -2314,9 +2314,9 @@ public class Database implements DataHandler {
return compiler;
}
public LobStorage getLobStorage() {
public LobStorageBackend getLobStorage() {
if (lobStorage == null) {
lobStorage = new LobStorage(this);
lobStorage = new LobStorageBackend(this);
}
return lobStorage;
}
......
......@@ -30,7 +30,7 @@ import org.h2.result.Row;
import org.h2.schema.Schema;
import org.h2.store.DataHandler;
import org.h2.store.InDoubtTransaction;
import org.h2.store.LobStorage;
import org.h2.store.LobStorageBackend;
import org.h2.table.Table;
import org.h2.util.New;
import org.h2.util.SmallLRUCache;
......@@ -145,7 +145,7 @@ public class Session extends SessionWithState {
old = variables.remove(name);
} else {
// link LOB values, to make sure we have our own object
value = value.link(database, LobStorage.TABLE_ID_SESSION_VARIABLE);
value = value.link(database, LobStorageBackend.TABLE_ID_SESSION_VARIABLE);
old = variables.put(name, value);
}
if (old != null) {
......@@ -967,6 +967,10 @@ public class Session extends SessionWithState {
return database;
}
public LobStorageBackend getLobStorageBackend() {
return database.getLobStorage();
}
/**
* Remember that the given LOB value must be un-linked (disconnected from
* the table) at commit.
......
......@@ -22,7 +22,8 @@ import org.h2.message.Trace;
import org.h2.message.TraceSystem;
import org.h2.store.DataHandler;
import org.h2.store.FileStore;
import org.h2.store.LobStorage;
import org.h2.store.LobStorageFrontend;
import org.h2.store.LobStorageInterface;
import org.h2.store.fs.FileUtils;
import org.h2.util.MathUtils;
import org.h2.util.NetUtils;
......@@ -82,7 +83,7 @@ public class SessionRemote extends SessionWithState implements DataHandler {
private int lastReconnect;
private SessionInterface embedded;
private DatabaseEventListener eventListener;
private LobStorage lobStorage;
private LobStorageFrontend lobStorage;
private boolean cluster;
public SessionRemote(ConnectionInfo ci) {
......@@ -681,9 +682,9 @@ public class SessionRemote extends SessionWithState implements DataHandler {
// nothing to do
}
public LobStorage getLobStorage() {
public LobStorageInterface getLobStorage() {
if (lobStorage == null) {
lobStorage = new LobStorage(this);
lobStorage = new LobStorageFrontend(this);
}
return lobStorage;
}
......
......@@ -23,7 +23,8 @@ import org.h2.mvstore.type.DataType;
import org.h2.result.SortOrder;
import org.h2.store.Data;
import org.h2.store.DataHandler;
import org.h2.store.LobStorage;
import org.h2.store.LobStorageBackend;
import org.h2.store.LobStorageInterface;
import org.h2.tools.SimpleResultSet;
import org.h2.util.DateTimeUtils;
import org.h2.value.CompareMode;
......@@ -592,12 +593,12 @@ public class ValueDataType implements DataType {
if (smallLen >= 0) {
byte[] small = DataUtils.newBytes(smallLen);
buff.get(small, 0, smallLen);
return LobStorage.createSmallLob(type, small);
return LobStorageBackend.createSmallLob(type, small);
} else if (smallLen == -3) {
int tableId = readVarInt(buff);
long lobId = readVarLong(buff);
long precision = readVarLong(buff);
LobStorage lobStorage = handler.getLobStorage();
LobStorageInterface lobStorage = handler.getLobStorage();
ValueLobDb lob = ValueLobDb.create(type, lobStorage, tableId, lobId, null, precision);
return lob;
} else {
......
......@@ -30,7 +30,7 @@ import org.h2.jdbc.JdbcSQLException;
import org.h2.message.DbException;
import org.h2.result.ResultColumn;
import org.h2.result.ResultInterface;
import org.h2.store.LobStorage;
import org.h2.store.LobStorageInterface;
import org.h2.util.IOUtils;
import org.h2.util.SmallLRUCache;
import org.h2.util.SmallMap;
......@@ -427,7 +427,7 @@ public class TcpServerThread implements Runnable {
}
long offset = transfer.readLong();
if (in.getPos() != offset) {
LobStorage lobStorage = session.getDataHandler().getLobStorage();
LobStorageInterface lobStorage = session.getDataHandler().getLobStorage();
InputStream lobIn = lobStorage.getInputStream(lobId, hmac, -1);
in = new CachedInputStream(lobIn);
lobs.put(lobId, in);
......
......@@ -787,12 +787,12 @@ public class Data {
if (smallLen >= 0) {
byte[] small = DataUtils.newBytes(smallLen);
read(small, 0, smallLen);
return LobStorage.createSmallLob(type, small);
return LobStorageBackend.createSmallLob(type, small);
} else if (smallLen == -3) {
int tableId = readVarInt();
long lobId = readVarLong();
long precision = readVarLong();
LobStorage lobStorage = handler.getLobStorage();
LobStorageInterface lobStorage = handler.getLobStorage();
ValueLobDb lob = ValueLobDb.create(type, lobStorage, tableId, lobId, null, precision);
return lob;
} else {
......
......@@ -90,7 +90,7 @@ public interface DataHandler {
*
* @return the lob storage mechanism
*/
LobStorage getLobStorage();
LobStorageInterface getLobStorage();
/**
* Get a database connection to be used for LOB access.
......
......@@ -6,7 +6,6 @@
*/
package org.h2.store;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
......@@ -18,7 +17,6 @@ import java.sql.Statement;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import org.h2.constant.ErrorCode;
import org.h2.constant.SysProperties;
import org.h2.engine.Constants;
......@@ -34,8 +32,9 @@ import org.h2.value.ValueLobDb;
/**
* This class stores LOB objects in the database.
* This is the back-end i.e. the server side of the LOB storage.
*/
public class LobStorage {
public class LobStorageBackend implements LobStorageInterface {
/**
* The table id for session variables (LOBs not assigned to a table).
......@@ -75,7 +74,7 @@ public class LobStorage {
private final DataHandler handler;
private boolean init;
public LobStorage(DataHandler handler) {
public LobStorageBackend(DataHandler handler) {
this.handler = handler;
}
......@@ -89,9 +88,6 @@ public class LobStorage {
synchronized (handler) {
conn = handler.getLobConnection();
init = true;
if (conn == null) {
return;
}
try {
Statement stat = conn.createStatement();
// stat.execute("SET UNDO_LOG 0");
......@@ -266,75 +262,6 @@ public class LobStorage {
}
}
/**
* An input stream that reads from a remote LOB.
*/
public static class RemoteInputStream extends InputStream {
/**
* The data handler.
*/
private final DataHandler handler;
/**
* The lob id.
*/
private final long lob;
private final byte[] hmac;
/**
* The position.
*/
private long pos;
/**
* The remaining bytes in the lob.
*/
private long remainingBytes;
public RemoteInputStream(DataHandler handler, long lob, byte[] hmac, long byteCount) {
this.handler = handler;
this.lob = lob;
this.hmac = hmac;
remainingBytes = byteCount;
}
public int read() throws IOException {
byte[] buff = new byte[1];
int len = read(buff, 0, 1);
return len < 0 ? len : (buff[0] & 255);
}
public int read(byte[] buff) throws IOException {
return read(buff, 0, buff.length);
}
public int read(byte[] buff, int off, int length) throws IOException {
if (length == 0) {
return 0;
}
length = (int) Math.min(length, remainingBytes);
if (length == 0) {
return -1;
}
length = handler.readLob(lob, hmac, pos, buff, off, length);
remainingBytes -= length;
if (length == 0) {
return -1;
}
pos += length;
return length;
}
public long skip(long n) {
remainingBytes -= n;
pos += n;
return n;
}
}
/**
* An input stream that reads from a LOB.
*/
......@@ -499,9 +426,6 @@ public class LobStorage {
public void removeLob(long lob) {
try {
synchronized (handler) {
if (conn == null) {
return;
}
String sql = "SELECT BLOCK, HASH FROM " + LOB_MAP + " D WHERE D.LOB = ? " +
"AND NOT EXISTS(SELECT 1 FROM " + LOB_MAP + " O " +
"WHERE O.BLOCK = D.BLOCK AND O.LOB <> ?)";
......@@ -552,12 +476,6 @@ public class LobStorage {
*/
public InputStream getInputStream(long lobId, byte[] hmac, long byteCount) throws IOException {
init();
if (conn == null) {
if (byteCount < 0) {
byteCount = Long.MAX_VALUE;
}
return new BufferedInputStream(new RemoteInputStream(handler, lobId, hmac, byteCount));
}
if (byteCount == -1) {
synchronized (handler) {
try {
......@@ -861,13 +779,6 @@ public class LobStorage {
public Value createBlob(InputStream in, long maxLength) {
if (SysProperties.LOB_IN_DATABASE) {
init();
if (conn == null) {
// remote connections:
// need to use a temp file, because the input stream could come from
// the same database, which would create a weird situation (trying
// to read a block while write something)
return ValueLobDb.createTempBlob(in, maxLength, handler);
}
return addLob(in, maxLength, Value.BLOB);
}
return ValueLob.createBlob(in, maxLength, handler);
......@@ -883,13 +794,6 @@ public class LobStorage {
public Value createClob(Reader reader, long maxLength) {
if (SysProperties.LOB_IN_DATABASE) {
init();
if (conn == null) {
// remote connections:
// need to use a temp file, because the input stream could come from
// the same database, which would create a weird situation (trying
// to read a block while write something)
return ValueLobDb.createTempClob(reader, maxLength, handler);
}
long max = maxLength == -1 ? Long.MAX_VALUE : maxLength;
CountingReaderInputStream in = new CountingReaderInputStream(reader, max);
ValueLobDb lob = addLob(in, Long.MAX_VALUE, Value.CLOB);
......
/*
* Copyright 2004-2013 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.store;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import org.h2.constant.SysProperties;
import org.h2.engine.Constants;
import org.h2.value.Value;
import org.h2.value.ValueLob;
import org.h2.value.ValueLobDb;
/**
* This class stores LOB objects in the database.
* This is the front-end i.e. the client side of the LOB storage.
*/
public class LobStorageFrontend implements LobStorageInterface {
private final DataHandler handler;
public LobStorageFrontend(DataHandler handler) {
this.handler = handler;
}
/**
* Create a LOB object that fits in memory.
*
* @param type the value type
* @param small the byte array
* @return the LOB
*/
public static Value createSmallLob(int type, byte[] small) {
if (SysProperties.LOB_IN_DATABASE) {
int precision;
if (type == Value.CLOB) {
precision = new String(small, Constants.UTF8).length();
} else {
precision = small.length;
}
return ValueLobDb.createSmallLob(type, small, precision);
}
return ValueLob.createSmallLob(type, small);
}
/**
* Delete a LOB from the database.
*
* @param lob the lob id
*/
public void removeLob(long lob) {
// TODO ideally, this should not be called at all, but that's a refactoring for another day
}
/**
* Get the input stream for the given lob.
*
* @param lobId the lob id
* @param hmac the message authentication code (for remote input streams)
* @param byteCount the number of bytes to read, or -1 if not known
* @return the stream
*/
public InputStream getInputStream(long lobId, byte[] hmac, long byteCount) throws IOException {
if (byteCount < 0) {
byteCount = Long.MAX_VALUE;
}
return new BufferedInputStream(new LobStorageRemoteInputStream(handler, lobId, hmac, byteCount));
}
/**
* Copy a lob.
*
* @param type the type
* @param oldLobId the old lob id
* @param tableId the new table id
* @param length the length
* @return the new lob
*/
public ValueLobDb copyLob(int type, long oldLobId, int tableId, long length) {
// TODO ideally, this should not be called at all, but that's a refactoring for another day
// this should never be called
throw new UnsupportedOperationException();
}
/**
* Create a BLOB object.
*
* @param in the input stream
* @param maxLength the maximum length (-1 if not known)
* @return the LOB
*/
public Value createBlob(InputStream in, long maxLength) {
if (SysProperties.LOB_IN_DATABASE) {
// need to use a temp file, because the input stream could come from
// the same database, which would create a weird situation (trying
// to read a block while write something)
return ValueLobDb.createTempBlob(in, maxLength, handler);
}
return ValueLob.createBlob(in, maxLength, handler);
}
/**
* Create a CLOB object.
*
* @param reader the reader
* @param maxLength the maximum length (-1 if not known)
* @return the LOB
*/
public Value createClob(Reader reader, long maxLength) {
if (SysProperties.LOB_IN_DATABASE) {
// need to use a temp file, because the input stream could come from
// the same database, which would create a weird situation (trying
// to read a block while write something)
return ValueLobDb.createTempClob(reader, maxLength, handler);
}
return ValueLob.createClob(reader, maxLength, handler);
}
/**
* Set the table reference of this lob.
*
* @param lobId the lob
* @param table the table
*/
public void setTable(long lobId, int table) {
// TODO ideally, this should not be called at all, but that's a refactoring for another day
// this should never be called
throw new UnsupportedOperationException();
}
}
package org.h2.store;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import org.h2.value.Value;
import org.h2.value.ValueLobDb;
public interface LobStorageInterface {
/**
* Create a CLOB object.
*
* @param reader the reader
* @param maxLength the maximum length (-1 if not known)
* @return the LOB
*/
Value createClob(Reader reader, long maxLength);
/**
* Create a BLOB object.
*
* @param in the input stream
* @param maxLength the maximum length (-1 if not known)
* @return the LOB
*/
Value createBlob(InputStream in, long maxLength);
/**
* Set the table reference of this lob.
*
* @param lobId the lob
* @param table the table
*/
void setTable(long lobId, int table);
/**
* Copy a lob.
*
* @param type the type
* @param oldLobId the old lob id
* @param tableId the new table id
* @param length the length
* @return the new lob
*/
ValueLobDb copyLob(int type, long oldLobId, int tableId, long length);
/**
* Get the input stream for the given lob.
*
* @param lobId the lob id
* @param hmac the message authentication code (for remote input streams)
* @param byteCount the number of bytes to read, or -1 if not known
* @return the stream
*/
InputStream getInputStream(long lobId, byte[] hmac, long byteCount) throws IOException;
/**
* Delete a LOB from the database.
*
* @param lob the lob id
*/
void removeLob(long lob);
}
package org.h2.store;
import java.io.IOException;
import java.io.InputStream;
/**
* An input stream that reads from a remote LOB.
*/
class LobStorageRemoteInputStream extends InputStream {
/**
* The data handler.
*/
private final DataHandler handler;
/**
* The lob id.
*/
private final long lob;
private final byte[] hmac;
/**
* The position.
*/
private long pos;
/**
* The remaining bytes in the lob.
*/
private long remainingBytes;
public LobStorageRemoteInputStream(DataHandler handler, long lob, byte[] hmac, long byteCount) {
this.handler = handler;
this.lob = lob;
this.hmac = hmac;
remainingBytes = byteCount;
}
public int read() throws IOException {
byte[] buff = new byte[1];
int len = read(buff, 0, 1);
return len < 0 ? len : (buff[0] & 255);
}
public int read(byte[] buff) throws IOException {
return read(buff, 0, buff.length);
}
public int read(byte[] buff, int off, int length) throws IOException {
if (length == 0) {
return 0;
}
length = (int) Math.min(length, remainingBytes);
if (length == 0) {
return -1;
}
length = handler.readLob(lob, hmac, pos, buff, off, length);
remainingBytes -= length;
if (length == 0) {
return -1;
}
pos += length;
return length;
}
public long skip(long n) {
remainingBytes -= n;
pos += n;
return n;
}
}
\ No newline at end of file
......@@ -38,7 +38,8 @@ import org.h2.store.DataReader;
import org.h2.store.FileLister;
import org.h2.store.FileStore;
import org.h2.store.FileStoreInputStream;
import org.h2.store.LobStorage;
import org.h2.store.LobStorageBackend;
import org.h2.store.LobStorageInterface;
import org.h2.store.Page;
import org.h2.store.PageFreeList;
import org.h2.store.PageLog;
......@@ -192,8 +193,8 @@ public class Recover extends Tool implements DataHandler {
*/
public static Value.ValueBlob readBlobDb(Connection conn, long lobId, long precision) {
DataHandler h = ((JdbcConnection) conn).getSession().getDataHandler();
LobStorage lobStorage = h.getLobStorage();
return ValueLobDb.create(Value.BLOB, lobStorage, LobStorage.TABLE_TEMP, lobId, null, precision);
LobStorageInterface lobStorage = h.getLobStorage();
return ValueLobDb.create(Value.BLOB, lobStorage, LobStorageBackend.TABLE_TEMP, lobId, null, precision);
}
/**
......@@ -201,8 +202,8 @@ public class Recover extends Tool implements DataHandler {
*/
public static Value.ValueClob readClobDb(Connection conn, long lobId, long precision) {
DataHandler h = ((JdbcConnection) conn).getSession().getDataHandler();
LobStorage lobStorage = h.getLobStorage();
return ValueLobDb.create(Value.CLOB, lobStorage, LobStorage.TABLE_TEMP, lobId, null, precision);
LobStorageInterface lobStorage = h.getLobStorage();
return ValueLobDb.create(Value.CLOB, lobStorage, LobStorageBackend.TABLE_TEMP, lobId, null, precision);
}
private void trace(String message) {
......@@ -1229,7 +1230,7 @@ public class Recover extends Tool implements DataHandler {
writer.println("DELETE FROM " + name + ";");
writer.println("INSERT INTO " + name + " SELECT * FROM " + storageName + ";");
if (name.startsWith("INFORMATION_SCHEMA.LOBS")) {
writer.println("UPDATE " + name + " SET TABLE = " + LobStorage.TABLE_TEMP + ";");
writer.println("UPDATE " + name + " SET TABLE = " + LobStorageBackend.TABLE_TEMP + ";");
deleteLobs = true;
}
}
......@@ -1255,7 +1256,7 @@ public class Recover extends Tool implements DataHandler {
writer.println("DROP ALIAS READ_BLOB_DB;");
writer.println("DROP ALIAS READ_CLOB_DB;");
if (deleteLobs) {
writer.println("DELETE FROM INFORMATION_SCHEMA.LOBS WHERE TABLE = " + LobStorage.TABLE_TEMP + ";");
writer.println("DELETE FROM INFORMATION_SCHEMA.LOBS WHERE TABLE = " + LobStorageBackend.TABLE_TEMP + ";");
}
for (MetaRecord m : schema) {
if (isSchemaObjectTypeDelayed(m)) {
......@@ -1409,7 +1410,7 @@ public class Recover extends Tool implements DataHandler {
/**
* INTERNAL
*/
public LobStorage getLobStorage() {
public LobStorageBackend getLobStorage() {
return null;
}
......
......@@ -31,7 +31,7 @@ import org.h2.jdbc.JdbcBlob;
import org.h2.jdbc.JdbcClob;
import org.h2.jdbc.JdbcConnection;
import org.h2.message.DbException;
import org.h2.store.LobStorage;
import org.h2.store.LobStorageBackend;
import org.h2.tools.SimpleResultSet;
import org.h2.util.New;
import org.h2.util.Utils;
......@@ -540,7 +540,7 @@ public class DataType {
}
case Value.CLOB: {
if (session == null) {
v = LobStorage.createSmallLob(Value.CLOB, rs.getString(columnIndex).getBytes(Constants.UTF8));
v = LobStorageBackend.createSmallLob(Value.CLOB, rs.getString(columnIndex).getBytes(Constants.UTF8));
} else {
Reader in = rs.getCharacterStream(columnIndex);
if (in == null) {
......@@ -553,7 +553,7 @@ public class DataType {
}
case Value.BLOB: {
if (session == null) {
v = LobStorage.createSmallLob(Value.BLOB, rs.getBytes(columnIndex));
v = LobStorageBackend.createSmallLob(Value.BLOB, rs.getBytes(columnIndex));
} else {
InputStream in = rs.getBinaryStream(columnIndex);
v = (in == null) ? (Value) ValueNull.INSTANCE : session.getDataHandler().getLobStorage().createBlob(in, -1);
......
......@@ -25,7 +25,7 @@ import org.h2.constant.SysProperties;
import org.h2.engine.Constants;
import org.h2.message.DbException;
import org.h2.store.DataHandler;
import org.h2.store.LobStorage;
import org.h2.store.LobStorageBackend;
import org.h2.tools.SimpleResultSet;
import org.h2.util.DateTimeUtils;
import org.h2.util.MathUtils;
......@@ -771,7 +771,7 @@ public abstract class Value {
switch(getType()) {
case BYTES:
return LobStorage.createSmallLob(Value.BLOB, getBytesNoCopy());
return LobStorageBackend.createSmallLob(Value.BLOB, getBytesNoCopy());
}
break;
}
......@@ -834,9 +834,9 @@ public abstract class Value {
case FLOAT:
return ValueFloat.get(Float.parseFloat(s.trim()));
case CLOB:
return LobStorage.createSmallLob(CLOB, s.getBytes(Constants.UTF8));
return LobStorageBackend.createSmallLob(CLOB, s.getBytes(Constants.UTF8));
case BLOB:
return LobStorage.createSmallLob(BLOB, StringUtils.convertHexToBytes(s.trim()));
return LobStorageBackend.createSmallLob(BLOB, StringUtils.convertHexToBytes(s.trim()));
case ARRAY:
return ValueArray.get(new Value[]{ValueString.get(s)});
case RESULT_SET: {
......
......@@ -21,7 +21,8 @@ import org.h2.store.DataHandler;
import org.h2.store.FileStore;
import org.h2.store.FileStoreInputStream;
import org.h2.store.FileStoreOutputStream;
import org.h2.store.LobStorage;
import org.h2.store.LobStorageBackend;
import org.h2.store.LobStorageInterface;
import org.h2.store.fs.FileUtils;
import org.h2.util.IOUtils;
import org.h2.util.MathUtils;
......@@ -38,7 +39,7 @@ public class ValueLobDb extends Value implements Value.ValueClob, Value.ValueBlo
private int tableId;
private int hash;
private LobStorage lobStorage;
private LobStorageInterface lobStorage;
private final long lobId;
private final byte[] hmac;
......@@ -48,7 +49,7 @@ public class ValueLobDb extends Value implements Value.ValueClob, Value.ValueBlo
private FileStore tempFile;
private String fileName;
private ValueLobDb(int type, LobStorage lobStorage, int tableId, long lobId, byte[] hmac, long precision) {
private ValueLobDb(int type, LobStorageInterface lobStorage, int tableId, long lobId, byte[] hmac, long precision) {
this.type = type;
this.lobStorage = lobStorage;
this.tableId = tableId;
......@@ -76,7 +77,7 @@ public class ValueLobDb extends Value implements Value.ValueClob, Value.ValueBlo
* @param precision the precision (number of bytes / characters)
* @return the value
*/
public static ValueLobDb create(int type, LobStorage lobStorage,
public static ValueLobDb create(int type, LobStorageInterface lobStorage,
int tableId, long id, byte[] hmac, long precision) {
return new ValueLobDb(type, lobStorage, tableId, id, hmac, precision);
}
......@@ -108,21 +109,21 @@ public class ValueLobDb extends Value implements Value.ValueClob, Value.ValueBlo
Value copy = lobStorage.createClob(getReader(), -1);
return copy;
} else if (small != null) {
return LobStorage.createSmallLob(t, small);
return LobStorageBackend.createSmallLob(t, small);
}
} else if (t == Value.BLOB) {
if (lobStorage != null) {
Value copy = lobStorage.createBlob(getInputStream(), -1);
return copy;
} else if (small != null) {
return LobStorage.createSmallLob(t, small);
return LobStorageBackend.createSmallLob(t, small);
}
}
return super.convertTo(t);
}
public boolean isLinked() {
return tableId != LobStorage.TABLE_ID_SESSION_VARIABLE && small == null;
return tableId != LobStorageBackend.TABLE_ID_SESSION_VARIABLE && small == null;
}
public boolean isStored() {
......@@ -147,22 +148,22 @@ public class ValueLobDb extends Value implements Value.ValueClob, Value.ValueBlo
}
public void unlink() {
if (small == null && tableId != LobStorage.TABLE_ID_SESSION_VARIABLE) {
lobStorage.setTable(lobId, LobStorage.TABLE_ID_SESSION_VARIABLE);
tableId = LobStorage.TABLE_ID_SESSION_VARIABLE;
if (small == null && tableId != LobStorageBackend.TABLE_ID_SESSION_VARIABLE) {
lobStorage.setTable(lobId, LobStorageBackend.TABLE_ID_SESSION_VARIABLE);
tableId = LobStorageBackend.TABLE_ID_SESSION_VARIABLE;
}
}
public Value link(DataHandler h, int tabId) {
if (small == null) {
if (tableId == LobStorage.TABLE_TEMP) {
if (tableId == LobStorageBackend.TABLE_TEMP) {
lobStorage.setTable(lobId, tabId);
this.tableId = tabId;
} else {
return lobStorage.copyLob(type, lobId, tabId, getPrecision());
}
} else if (small.length > h.getMaxLengthInplaceLob()) {
LobStorage s = h.getLobStorage();
LobStorageInterface s = h.getLobStorage();
Value v;
if (type == Value.BLOB) {
v = s.createBlob(getInputStream(), getPrecision());
......
......@@ -15,7 +15,7 @@ import java.sql.Types;
import org.h2.store.Data;
import org.h2.store.DataHandler;
import org.h2.store.FileStore;
import org.h2.store.LobStorage;
import org.h2.store.LobStorageBackend;
import org.h2.test.TestBase;
import org.h2.tools.SimpleResultSet;
import org.h2.util.SmallLRUCache;
......@@ -315,7 +315,7 @@ public class TestDataPage extends TestBase implements DataHandler {
return TempFileDeleter.getInstance();
}
public LobStorage getLobStorage() {
public LobStorageBackend getLobStorage() {
return null;
}
......
......@@ -10,7 +10,7 @@ import java.sql.Connection;
import java.util.Random;
import org.h2.store.DataHandler;
import org.h2.store.FileStore;
import org.h2.store.LobStorage;
import org.h2.store.LobStorageBackend;
import org.h2.store.fs.FileUtils;
import org.h2.test.TestBase;
import org.h2.util.SmallLRUCache;
......@@ -169,7 +169,7 @@ public class TestFile extends TestBase implements DataHandler {
return TempFileDeleter.getInstance();
}
public LobStorage getLobStorage() {
public LobStorageBackend getLobStorage() {
return null;
}
......
......@@ -14,7 +14,7 @@ import java.util.HashMap;
import java.util.Random;
import org.h2.store.DataHandler;
import org.h2.store.FileStore;
import org.h2.store.LobStorage;
import org.h2.store.LobStorageBackend;
import org.h2.test.TestBase;
import org.h2.util.New;
import org.h2.util.SmallLRUCache;
......@@ -145,7 +145,7 @@ public class TestValueHashMap extends TestBase implements DataHandler {
return TempFileDeleter.getInstance();
}
public LobStorage getLobStorage() {
public LobStorageBackend getLobStorage() {
return null;
}
......
......@@ -17,7 +17,8 @@ import java.util.Random;
import org.h2.engine.Constants;
import org.h2.store.DataHandler;
import org.h2.store.FileStore;
import org.h2.store.LobStorage;
import org.h2.store.LobStorageBackend;
import org.h2.store.LobStorageFrontend;
import org.h2.test.TestBase;
import org.h2.test.utils.MemoryFootprint;
import org.h2.tools.SimpleResultSet;
......@@ -54,7 +55,7 @@ public class TestValueMemory extends TestBase implements DataHandler {
private final Random random = new Random(1);
private final SmallLRUCache<String, String[]> lobFileListCache = SmallLRUCache.newInstance(128);
private LobStorage lobStorage;
private LobStorageFrontend lobStorage;
/**
* Run just this test.
......@@ -246,9 +247,9 @@ public class TestValueMemory extends TestBase implements DataHandler {
return TempFileDeleter.getInstance();
}
public LobStorage getLobStorage() {
public LobStorageFrontend getLobStorage() {
if (lobStorage == null) {
lobStorage = new LobStorage(this);
lobStorage = new LobStorageFrontend(this);
}
return lobStorage;
}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论