提交 99fe80ea authored 作者: noelgrandin's avatar noelgrandin

Use HMAC for authenticating remote LOB id's, removing the need for maintaining a…

Use HMAC for authenticating remote LOB id's, removing the need for maintaining a cache, and removing the limit on the number of LOBs per result set.
上级 a680461e
...@@ -23,6 +23,8 @@ Change Log ...@@ -23,6 +23,8 @@ Change Log
</li><li>Apache Tomcat 7.x will now longer log a warning when unloading the web application, if using a connection pool. </li><li>Apache Tomcat 7.x will now longer log a warning when unloading the web application, if using a connection pool.
</li><li>H2 Console: support the Midori browser (for Debian / Raspberry Pi) </li><li>H2 Console: support the Midori browser (for Debian / Raspberry Pi)
</li><li>When opening a remote session, don't open a temporary file if the trace level is set to zero </li><li>When opening a remote session, don't open a temporary file if the trace level is set to zero
</li><li>Use HMAC for authenticating remote LOB id's, removing the need for maintaining a cache, and removing the limit
on the number of LOBs per result set.
</li></ul> </li></ul>
<h2>Version 1.3.167 (2012-05-23)</h2> <h2>Version 1.3.167 (2012-05-23)</h2>
......
...@@ -235,7 +235,7 @@ abstract class ScriptBase extends Prepared implements DataHandler { ...@@ -235,7 +235,7 @@ abstract class ScriptBase extends Prepared implements DataHandler {
return null; return null;
} }
public int readLob(long lobId, long offset, byte[] buff, int off, int length) { public int readLob(long lobId, byte[] hmac, long offset, byte[] buff, int off, int length) {
throw DbException.throwInternalError(); throw DbException.throwInternalError();
} }
......
...@@ -71,6 +71,11 @@ public class Constants { ...@@ -71,6 +71,11 @@ public class Constants {
*/ */
public static final int TCP_PROTOCOL_VERSION_11 = 11; public static final int TCP_PROTOCOL_VERSION_11 = 11;
/**
* The TCP protocol version number 11.
*/
public static final int TCP_PROTOCOL_VERSION_12 = 12;
/** /**
* The major version of this database. * The major version of this database.
*/ */
......
...@@ -2401,7 +2401,7 @@ public class Database implements DataHandler { ...@@ -2401,7 +2401,7 @@ public class Database implements DataHandler {
return false; return false;
} }
public int readLob(long lobId, long offset, byte[] buff, int off, int length) { public int readLob(long lobId, byte[] hmac, long offset, byte[] buff, int off, int length) {
throw DbException.throwInternalError(); throw DbException.throwInternalError();
} }
......
...@@ -96,7 +96,7 @@ public class SessionRemote extends SessionWithState implements DataHandler { ...@@ -96,7 +96,7 @@ public class SessionRemote extends SessionWithState implements DataHandler {
trans.setSSL(ci.isSSL()); trans.setSSL(ci.isSSL());
trans.init(); trans.init();
trans.writeInt(Constants.TCP_PROTOCOL_VERSION_6); trans.writeInt(Constants.TCP_PROTOCOL_VERSION_6);
trans.writeInt(Constants.TCP_PROTOCOL_VERSION_11); trans.writeInt(Constants.TCP_PROTOCOL_VERSION_12);
trans.writeString(db); trans.writeString(db);
trans.writeString(ci.getOriginalURL()); trans.writeString(ci.getOriginalURL());
trans.writeString(ci.getUserName()); trans.writeString(ci.getUserName());
...@@ -691,13 +691,14 @@ public class SessionRemote extends SessionWithState implements DataHandler { ...@@ -691,13 +691,14 @@ public class SessionRemote extends SessionWithState implements DataHandler {
return null; return null;
} }
public synchronized int readLob(long lobId, long offset, byte[] buff, int off, int length) { public synchronized int readLob(long lobId, byte[] hmac, long offset, byte[] buff, int off, int length) {
for (int i = 0, count = 0; i < transferList.size(); i++) { for (int i = 0, count = 0; i < transferList.size(); i++) {
Transfer transfer = transferList.get(i); Transfer transfer = transferList.get(i);
try { try {
traceOperation("LOB_READ", (int) lobId); traceOperation("LOB_READ", (int) lobId);
transfer.writeInt(SessionRemote.LOB_READ); transfer.writeInt(SessionRemote.LOB_READ);
transfer.writeLong(lobId); transfer.writeLong(lobId);
transfer.writeBytes(hmac);
transfer.writeLong(offset); transfer.writeLong(offset);
transfer.writeInt(length); transfer.writeInt(length);
done(transfer); done(transfer);
......
...@@ -37,7 +37,6 @@ import org.h2.util.SmallMap; ...@@ -37,7 +37,6 @@ import org.h2.util.SmallMap;
import org.h2.util.StringUtils; import org.h2.util.StringUtils;
import org.h2.value.Transfer; import org.h2.value.Transfer;
import org.h2.value.Value; import org.h2.value.Value;
import org.h2.value.ValueLobDb;
/** /**
* One server thread is opened per client connection. * One server thread is opened per client connection.
...@@ -51,10 +50,7 @@ public class TcpServerThread implements Runnable { ...@@ -51,10 +50,7 @@ public class TcpServerThread implements Runnable {
private Thread thread; private Thread thread;
private Command commit; private Command commit;
private SmallMap cache = new SmallMap(SysProperties.SERVER_CACHED_OBJECTS); private SmallMap cache = new SmallMap(SysProperties.SERVER_CACHED_OBJECTS);
private SmallLRUCache<Long, CachedInputStream> lobs = private SmallLRUCache<Long, CachedInputStream> lobs = SmallLRUCache.newInstance(SysProperties.SERVER_CACHED_OBJECTS);
SmallLRUCache.newInstance(Math.max(
SysProperties.SERVER_CACHED_OBJECTS,
SysProperties.SERVER_RESULT_SET_FETCH_SIZE * 5));
private int threadId; private int threadId;
private int clientVersion; private int clientVersion;
private String sessionId; private String sessionId;
...@@ -83,12 +79,12 @@ public class TcpServerThread implements Runnable { ...@@ -83,12 +79,12 @@ public class TcpServerThread implements Runnable {
int minClientVersion = transfer.readInt(); int minClientVersion = transfer.readInt();
if (minClientVersion < Constants.TCP_PROTOCOL_VERSION_6) { if (minClientVersion < Constants.TCP_PROTOCOL_VERSION_6) {
throw DbException.get(ErrorCode.DRIVER_VERSION_ERROR_2, "" + clientVersion, "" + Constants.TCP_PROTOCOL_VERSION_6); throw DbException.get(ErrorCode.DRIVER_VERSION_ERROR_2, "" + clientVersion, "" + Constants.TCP_PROTOCOL_VERSION_6);
} else if (minClientVersion > Constants.TCP_PROTOCOL_VERSION_11) { } else if (minClientVersion > Constants.TCP_PROTOCOL_VERSION_12) {
throw DbException.get(ErrorCode.DRIVER_VERSION_ERROR_2, "" + clientVersion, "" + Constants.TCP_PROTOCOL_VERSION_11); throw DbException.get(ErrorCode.DRIVER_VERSION_ERROR_2, "" + clientVersion, "" + Constants.TCP_PROTOCOL_VERSION_12);
} }
int maxClientVersion = transfer.readInt(); int maxClientVersion = transfer.readInt();
if (maxClientVersion >= Constants.TCP_PROTOCOL_VERSION_11) { if (maxClientVersion >= Constants.TCP_PROTOCOL_VERSION_12) {
clientVersion = Constants.TCP_PROTOCOL_VERSION_11; clientVersion = Constants.TCP_PROTOCOL_VERSION_12;
} else { } else {
clientVersion = minClientVersion; clientVersion = minClientVersion;
} }
...@@ -396,15 +392,18 @@ public class TcpServerThread implements Runnable { ...@@ -396,15 +392,18 @@ public class TcpServerThread implements Runnable {
break; break;
} }
case SessionRemote.LOB_READ: { case SessionRemote.LOB_READ: {
byte[] hmac = transfer.readBytes();
long lobId = transfer.readLong(); long lobId = transfer.readLong();
transfer.verifyLobMac(hmac, lobId);
CachedInputStream in = lobs.get(lobId); CachedInputStream in = lobs.get(lobId);
if (in == null) { if (in == null) {
throw DbException.get(ErrorCode.OBJECT_CLOSED); in = new CachedInputStream(null);
lobs.put(lobId, in);
} }
long offset = transfer.readLong(); long offset = transfer.readLong();
if (in.getPos() != offset) { if (in.getPos() != offset) {
LobStorage lobStorage = session.getDataHandler().getLobStorage(); LobStorage lobStorage = session.getDataHandler().getLobStorage();
InputStream lobIn = lobStorage.getInputStream(lobId, -1); InputStream lobIn = lobStorage.getInputStream(lobId, hmac, -1);
in = new CachedInputStream(lobIn); in = new CachedInputStream(lobIn);
lobs.put(lobId, in); lobs.put(lobId, in);
lobIn.skip(offset); lobIn.skip(offset);
...@@ -426,7 +425,7 @@ public class TcpServerThread implements Runnable { ...@@ -426,7 +425,7 @@ public class TcpServerThread implements Runnable {
close(); close();
} }
} }
private int getState(int oldModificationId) { private int getState(int oldModificationId) {
if (session.getModificationId() == oldModificationId) { if (session.getModificationId() == oldModificationId) {
return SessionRemote.STATUS_OK; return SessionRemote.STATUS_OK;
...@@ -439,26 +438,13 @@ public class TcpServerThread implements Runnable { ...@@ -439,26 +438,13 @@ public class TcpServerThread implements Runnable {
transfer.writeBoolean(true); transfer.writeBoolean(true);
Value[] v = result.currentRow(); Value[] v = result.currentRow();
for (int i = 0; i < result.getVisibleColumnCount(); i++) { for (int i = 0; i < result.getVisibleColumnCount(); i++) {
writeValue(v[i]); transfer.writeValue(v[i]);
} }
} else { } else {
transfer.writeBoolean(false); transfer.writeBoolean(false);
} }
} }
private void writeValue(Value v) throws IOException {
if (v.getType() == Value.CLOB || v.getType() == Value.BLOB) {
if (v instanceof ValueLobDb) {
ValueLobDb lob = (ValueLobDb) v;
if (lob.isStored()) {
long id = lob.getLobId();
lobs.put(id, new CachedInputStream(null));
}
}
}
transfer.writeValue(v);
}
void setThread(Thread thread) { void setThread(Thread thread) {
this.thread = thread; this.thread = thread;
} }
......
...@@ -793,7 +793,7 @@ public class Data { ...@@ -793,7 +793,7 @@ public class Data {
long lobId = readVarLong(); long lobId = readVarLong();
long precision = readVarLong(); long precision = readVarLong();
LobStorage lobStorage = handler.getLobStorage(); LobStorage lobStorage = handler.getLobStorage();
ValueLobDb lob = ValueLobDb.create(type, lobStorage, tableId, lobId, precision); ValueLobDb lob = ValueLobDb.create(type, lobStorage, tableId, lobId, null, precision);
return lob; return lob;
} else { } else {
int tableId = readVarInt(); int tableId = readVarInt();
......
...@@ -109,6 +109,6 @@ public interface DataHandler { ...@@ -109,6 +109,6 @@ public interface DataHandler {
* @param length the number of bytes to read * @param length the number of bytes to read
* @return the number of bytes read * @return the number of bytes read
*/ */
int readLob(long lobId, long offset, byte[] buff, int off, int length); int readLob(long lobId, byte[] hmac, long offset, byte[] buff, int off, int length);
} }
...@@ -225,7 +225,7 @@ public class FileLock implements Runnable { ...@@ -225,7 +225,7 @@ public class FileLock implements Runnable {
transfer.setSocket(socket); transfer.setSocket(socket);
transfer.init(); transfer.init();
transfer.writeInt(Constants.TCP_PROTOCOL_VERSION_6); transfer.writeInt(Constants.TCP_PROTOCOL_VERSION_6);
transfer.writeInt(Constants.TCP_PROTOCOL_VERSION_11); transfer.writeInt(Constants.TCP_PROTOCOL_VERSION_12);
transfer.writeString(null); transfer.writeString(null);
transfer.writeString(null); transfer.writeString(null);
transfer.writeString(id); transfer.writeString(id);
......
...@@ -281,6 +281,8 @@ public class LobStorage { ...@@ -281,6 +281,8 @@ public class LobStorage {
*/ */
private final long lob; private final long lob;
private final byte[] hmac;
/** /**
* The position. * The position.
*/ */
...@@ -291,9 +293,10 @@ public class LobStorage { ...@@ -291,9 +293,10 @@ public class LobStorage {
*/ */
private long remainingBytes; private long remainingBytes;
public RemoteInputStream(DataHandler handler, long lob, long byteCount) { public RemoteInputStream(DataHandler handler, long lob, byte[] hmac, long byteCount) {
this.handler = handler; this.handler = handler;
this.lob = lob; this.lob = lob;
this.hmac = hmac;
remainingBytes = byteCount; remainingBytes = byteCount;
} }
...@@ -315,7 +318,7 @@ public class LobStorage { ...@@ -315,7 +318,7 @@ public class LobStorage {
if (length == 0) { if (length == 0) {
return -1; return -1;
} }
length = handler.readLob(lob, pos, buff, off, length); length = handler.readLob(lob, hmac, pos, buff, off, length);
remainingBytes -= length; remainingBytes -= length;
if (length == 0) { if (length == 0) {
return -1; return -1;
...@@ -547,13 +550,13 @@ public class LobStorage { ...@@ -547,13 +550,13 @@ public class LobStorage {
* @param byteCount the number of bytes to read, or -1 if not known * @param byteCount the number of bytes to read, or -1 if not known
* @return the stream * @return the stream
*/ */
public InputStream getInputStream(long lobId, long byteCount) throws IOException { public InputStream getInputStream(long lobId, byte[] hmac, long byteCount) throws IOException {
init(); init();
if (conn == null) { if (conn == null) {
if (byteCount < 0) { if (byteCount < 0) {
byteCount = Long.MAX_VALUE; byteCount = Long.MAX_VALUE;
} }
return new BufferedInputStream(new RemoteInputStream(handler, lobId, byteCount)); return new BufferedInputStream(new RemoteInputStream(handler, lobId, hmac, byteCount));
} }
if (byteCount == -1) { if (byteCount == -1) {
synchronized (handler) { synchronized (handler) {
...@@ -644,7 +647,7 @@ public class LobStorage { ...@@ -644,7 +647,7 @@ public class LobStorage {
prep.setInt(3, tableId); prep.setInt(3, tableId);
prep.execute(); prep.execute();
reuse(sql, prep); reuse(sql, prep);
ValueLobDb v = ValueLobDb.create(type, this, tableId, lobId, byteCount); ValueLobDb v = ValueLobDb.create(type, this, tableId, lobId, null, byteCount);
return v; return v;
} catch (SQLException e) { } catch (SQLException e) {
throw DbException.convert(e); throw DbException.convert(e);
...@@ -683,7 +686,7 @@ public class LobStorage { ...@@ -683,7 +686,7 @@ public class LobStorage {
prep.executeUpdate(); prep.executeUpdate();
reuse(sql, prep); reuse(sql, prep);
ValueLobDb v = ValueLobDb.create(type, this, tableId, lobId, length); ValueLobDb v = ValueLobDb.create(type, this, tableId, lobId, null, length);
return v; return v;
} catch (SQLException e) { } catch (SQLException e) {
throw DbException.convert(e); throw DbException.convert(e);
......
...@@ -193,7 +193,7 @@ public class Recover extends Tool implements DataHandler { ...@@ -193,7 +193,7 @@ public class Recover extends Tool implements DataHandler {
public static Value.ValueBlob readBlobDb(Connection conn, long lobId, long precision) { public static Value.ValueBlob readBlobDb(Connection conn, long lobId, long precision) {
DataHandler h = ((JdbcConnection) conn).getSession().getDataHandler(); DataHandler h = ((JdbcConnection) conn).getSession().getDataHandler();
LobStorage lobStorage = h.getLobStorage(); LobStorage lobStorage = h.getLobStorage();
return ValueLobDb.create(Value.BLOB, lobStorage, LobStorage.TABLE_TEMP, lobId, precision); return ValueLobDb.create(Value.BLOB, lobStorage, LobStorage.TABLE_TEMP, lobId, null, precision);
} }
/** /**
...@@ -202,7 +202,7 @@ public class Recover extends Tool implements DataHandler { ...@@ -202,7 +202,7 @@ public class Recover extends Tool implements DataHandler {
public static Value.ValueClob readClobDb(Connection conn, long lobId, long precision) { public static Value.ValueClob readClobDb(Connection conn, long lobId, long precision) {
DataHandler h = ((JdbcConnection) conn).getSession().getDataHandler(); DataHandler h = ((JdbcConnection) conn).getSession().getDataHandler();
LobStorage lobStorage = h.getLobStorage(); LobStorage lobStorage = h.getLobStorage();
return ValueLobDb.create(Value.CLOB, lobStorage, LobStorage.TABLE_TEMP, lobId, precision); return ValueLobDb.create(Value.CLOB, lobStorage, LobStorage.TABLE_TEMP, lobId, null, precision);
} }
private void trace(String message) { private void trace(String message) {
...@@ -1415,7 +1415,7 @@ public class Recover extends Tool implements DataHandler { ...@@ -1415,7 +1415,7 @@ public class Recover extends Tool implements DataHandler {
/** /**
* INTERNAL * INTERNAL
*/ */
public int readLob(long lobId, long offset, byte[] buff, int off, int length) { public int readLob(long lobId, byte[] hmac, long offset, byte[] buff, int off, int length) {
throw DbException.throwInternalError(); throw DbException.throwInternalError();
} }
......
...@@ -26,11 +26,13 @@ import org.h2.engine.Constants; ...@@ -26,11 +26,13 @@ import org.h2.engine.Constants;
import org.h2.engine.SessionInterface; import org.h2.engine.SessionInterface;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.message.TraceSystem; import org.h2.message.TraceSystem;
import org.h2.security.SHA256;
import org.h2.store.Data; import org.h2.store.Data;
import org.h2.store.DataReader; import org.h2.store.DataReader;
import org.h2.tools.SimpleResultSet; import org.h2.tools.SimpleResultSet;
import org.h2.util.DateTimeUtils; import org.h2.util.DateTimeUtils;
import org.h2.util.IOUtils; import org.h2.util.IOUtils;
import org.h2.util.MathUtils;
import org.h2.util.NetUtils; import org.h2.util.NetUtils;
import org.h2.util.StringUtils; import org.h2.util.StringUtils;
import org.h2.util.Utils; import org.h2.util.Utils;
...@@ -43,13 +45,15 @@ public class Transfer { ...@@ -43,13 +45,15 @@ public class Transfer {
private static final int BUFFER_SIZE = 16 * 1024; private static final int BUFFER_SIZE = 16 * 1024;
private static final int LOB_MAGIC = 0x1234; private static final int LOB_MAGIC = 0x1234;
private static final int LOB_MAC_SALT_LENGTH = 16;
private Socket socket; private Socket socket;
private DataInputStream in; private DataInputStream in;
private DataOutputStream out; private DataOutputStream out;
private SessionInterface session; private SessionInterface session;
private boolean ssl; private boolean ssl;
private int version; private int version;
private byte[] lobMacSalt;
/** /**
* Create a new transfer object for the specified session. * Create a new transfer object for the specified session.
...@@ -405,13 +409,14 @@ public class Transfer { ...@@ -405,13 +409,14 @@ public class Transfer {
writeString(v.getString()); writeString(v.getString());
break; break;
case Value.BLOB: { case Value.BLOB: {
if (version >= Constants.TCP_PROTOCOL_VERSION_11) { if (version >= Constants.TCP_PROTOCOL_VERSION_12) {
if (v instanceof ValueLobDb) { if (v instanceof ValueLobDb) {
ValueLobDb lob = (ValueLobDb) v; ValueLobDb lob = (ValueLobDb) v;
if (lob.isStored()) { if (lob.isStored()) {
writeLong(-1); writeLong(-1);
writeInt(lob.getTableId()); writeInt(lob.getTableId());
writeLong(lob.getLobId()); writeLong(lob.getLobId());
writeBytes(calculateLobMac(lob.getLobId()));
writeLong(lob.getPrecision()); writeLong(lob.getPrecision());
break; break;
} }
...@@ -430,12 +435,13 @@ public class Transfer { ...@@ -430,12 +435,13 @@ public class Transfer {
break; break;
} }
case Value.CLOB: { case Value.CLOB: {
if (version >= Constants.TCP_PROTOCOL_VERSION_11) { if (version >= Constants.TCP_PROTOCOL_VERSION_12) {
if (v instanceof ValueLobDb) { if (v instanceof ValueLobDb) {
ValueLobDb lob = (ValueLobDb) v; ValueLobDb lob = (ValueLobDb) v;
if (lob.isStored()) { if (lob.isStored()) {
writeLong(-1); writeLong(-1);
writeInt(lob.getTableId()); writeInt(lob.getTableId());
writeBytes(calculateLobMac(lob.getLobId()));
writeLong(lob.getLobId()); writeLong(lob.getLobId());
writeLong(lob.getPrecision()); writeLong(lob.getPrecision());
break; break;
...@@ -567,12 +573,13 @@ public class Transfer { ...@@ -567,12 +573,13 @@ public class Transfer {
return ValueStringFixed.get(readString()); return ValueStringFixed.get(readString());
case Value.BLOB: { case Value.BLOB: {
long length = readLong(); long length = readLong();
if (version >= Constants.TCP_PROTOCOL_VERSION_11) { if (version >= Constants.TCP_PROTOCOL_VERSION_12) {
if (length == -1) { if (length == -1) {
int tableId = readInt(); int tableId = readInt();
long id = readLong(); long id = readLong();
byte[] hmac = readBytes();
long precision = readLong(); long precision = readLong();
return ValueLobDb.create(Value.BLOB, session.getDataHandler().getLobStorage(), tableId, id, precision); return ValueLobDb.create(Value.BLOB, session.getDataHandler().getLobStorage(), tableId, id, hmac, precision);
} }
int len = (int) length; int len = (int) length;
byte[] small = new byte[len]; byte[] small = new byte[len];
...@@ -592,12 +599,13 @@ public class Transfer { ...@@ -592,12 +599,13 @@ public class Transfer {
} }
case Value.CLOB: { case Value.CLOB: {
long length = readLong(); long length = readLong();
if (version >= Constants.TCP_PROTOCOL_VERSION_11) { if (version >= Constants.TCP_PROTOCOL_VERSION_12) {
if (length == -1) { if (length == -1) {
int tableId = readInt(); int tableId = readInt();
long id = readLong(); long id = readLong();
byte[] hmac = readBytes();
long precision = readLong(); long precision = readLong();
return ValueLobDb.create(Value.CLOB, session.getDataHandler().getLobStorage(), tableId, id, precision); return ValueLobDb.create(Value.CLOB, session.getDataHandler().getLobStorage(), tableId, id, hmac, precision);
} }
DataReader reader = new DataReader(in); DataReader reader = new DataReader(in);
int len = (int) length; int len = (int) length;
...@@ -703,4 +711,37 @@ public class Transfer { ...@@ -703,4 +711,37 @@ public class Transfer {
return socket == null || socket.isClosed(); return socket == null || socket.isClosed();
} }
/**
* @throws DbException if the HMAC does not verify
*/
public void verifyLobMac(byte[] hmacData, long lobId) {
byte[] result = calculateLobMac(lobId);
if (!result.equals(hmacData)) {
throw DbException.get(ErrorCode.REMOTE_CONNECTION_NOT_ALLOWED);
}
}
private byte[] calculateLobMac(long lobId) {
if (lobMacSalt == null) {
lobMacSalt = MathUtils.secureRandomBytes(LOB_MAC_SALT_LENGTH);
}
byte[] hmacData = SHA256.getHashWithSalt(longToBytes(lobId), lobMacSalt);
return hmacData;
}
private static byte[] longToBytes(long src) {
byte[] data = new byte[8];
data[0] = (byte) (src >> 56);
data[1] = (byte) (src >> 48);
data[2] = (byte) (src >> 40);
data[3] = (byte) (src >> 32);
data[4] = (byte) (src >> 24);
data[5] = (byte) (src >> 16);
data[6] = (byte) (src >> 8);
data[7] = (byte) src;
return data;
}
} }
...@@ -39,6 +39,7 @@ public class ValueLobDb extends Value implements Value.ValueClob, Value.ValueBlo ...@@ -39,6 +39,7 @@ public class ValueLobDb extends Value implements Value.ValueClob, Value.ValueBlo
private LobStorage lobStorage; private LobStorage lobStorage;
private long lobId; private long lobId;
private byte[] hmac;
private byte[] small; private byte[] small;
...@@ -46,11 +47,12 @@ public class ValueLobDb extends Value implements Value.ValueClob, Value.ValueBlo ...@@ -46,11 +47,12 @@ public class ValueLobDb extends Value implements Value.ValueClob, Value.ValueBlo
private FileStore tempFile; private FileStore tempFile;
private String fileName; private String fileName;
private ValueLobDb(int type, LobStorage lobStorage, int tableId, long lobId, long precision) { private ValueLobDb(int type, LobStorage lobStorage, int tableId, long lobId, byte[] hmac, long precision) {
this.type = type; this.type = type;
this.lobStorage = lobStorage; this.lobStorage = lobStorage;
this.tableId = tableId; this.tableId = tableId;
this.lobId = lobId; this.lobId = lobId;
this.hmac = hmac;
this.precision = precision; this.precision = precision;
} }
...@@ -71,8 +73,8 @@ public class ValueLobDb extends Value implements Value.ValueClob, Value.ValueBlo ...@@ -71,8 +73,8 @@ public class ValueLobDb extends Value implements Value.ValueClob, Value.ValueBlo
* @return the value * @return the value
*/ */
public static ValueLobDb create(int type, LobStorage lobStorage, public static ValueLobDb create(int type, LobStorage lobStorage,
int tableId, long id, long precision) { int tableId, long id, byte[] hmac, long precision) {
return new ValueLobDb(type, lobStorage, tableId, id, precision); return new ValueLobDb(type, lobStorage, tableId, id, hmac, precision);
} }
/** /**
...@@ -285,7 +287,7 @@ public class ValueLobDb extends Value implements Value.ValueClob, Value.ValueBlo ...@@ -285,7 +287,7 @@ public class ValueLobDb extends Value implements Value.ValueClob, Value.ValueBlo
} }
long byteCount = (type == Value.BLOB) ? precision : -1; long byteCount = (type == Value.BLOB) ? precision : -1;
try { try {
return lobStorage.getInputStream(lobId, byteCount); return lobStorage.getInputStream(lobId, hmac, byteCount);
} catch (IOException e) { } catch (IOException e) {
throw DbException.convertIOException(e, toString()); throw DbException.convertIOException(e, toString());
} }
......
...@@ -323,7 +323,7 @@ public class TestDataPage extends TestBase implements DataHandler { ...@@ -323,7 +323,7 @@ public class TestDataPage extends TestBase implements DataHandler {
return null; return null;
} }
public int readLob(long lobId, long offset, byte[] buff, int off, int length) { public int readLob(long lobId, byte[] hmac, long offset, byte[] buff, int off, int length) {
return -1; return -1;
} }
......
...@@ -175,7 +175,7 @@ public class TestFile extends TestBase implements DataHandler { ...@@ -175,7 +175,7 @@ public class TestFile extends TestBase implements DataHandler {
return null; return null;
} }
public int readLob(long lobId, long offset, byte[] buff, int off, int length) { public int readLob(long lobId, byte[] hmac, long offset, byte[] buff, int off, int length) {
return -1; return -1;
} }
......
...@@ -153,7 +153,7 @@ public class TestValueHashMap extends TestBase implements DataHandler { ...@@ -153,7 +153,7 @@ public class TestValueHashMap extends TestBase implements DataHandler {
return null; return null;
} }
public int readLob(long lobId, long offset, byte[] buff, int off, int length) { public int readLob(long lobId, byte[] hmac, long offset, byte[] buff, int off, int length) {
return -1; return -1;
} }
......
...@@ -257,7 +257,7 @@ public class TestValueMemory extends TestBase implements DataHandler { ...@@ -257,7 +257,7 @@ public class TestValueMemory extends TestBase implements DataHandler {
return null; return null;
} }
public int readLob(long lobId, long offset, byte[] buff, int off, int length) { public int readLob(long lobId, byte[] hmac, long offset, byte[] buff, int off, int length) {
return -1; return -1;
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论