提交 dfd26da7 authored 作者: Thomas Mueller's avatar Thomas Mueller

Ensure the JDBC client doesn't reference the Database class. Add missing @Override

上级 3fcb3c2a
......@@ -42,6 +42,7 @@ import org.h2.store.FileLock;
import org.h2.store.FileStore;
import org.h2.store.InDoubtTransaction;
import org.h2.store.LobStorageBackend;
import org.h2.store.LobStorageFrontend;
import org.h2.store.PageStore;
import org.h2.store.WriterThread;
import org.h2.store.fs.FileUtils;
......@@ -1121,7 +1122,7 @@ public class Database implements DataHandler {
if (lobStorageIsUsed) {
try {
getLobStorage();
lobStorage.removeAllForTable(LobStorageBackend.TABLE_ID_SESSION_VARIABLE);
lobStorage.removeAllForTable(LobStorageFrontend.TABLE_ID_SESSION_VARIABLE);
} catch (DbException e) {
trace.error(e, "close");
}
......
......@@ -33,6 +33,7 @@ import org.h2.schema.Schema;
import org.h2.store.DataHandler;
import org.h2.store.InDoubtTransaction;
import org.h2.store.LobStorageBackend;
import org.h2.store.LobStorageFrontend;
import org.h2.table.Table;
import org.h2.util.New;
import org.h2.util.SmallLRUCache;
......@@ -148,7 +149,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, LobStorageBackend.TABLE_ID_SESSION_VARIABLE);
value = value.link(database, LobStorageFrontend.TABLE_ID_SESSION_VARIABLE);
old = variables.put(name, value);
}
if (old != null) {
......@@ -578,6 +579,7 @@ public class Session extends SessionWithState {
}
}
@Override
public boolean hasPendingTransaction() {
return undoLog.size() > 0;
}
......
......@@ -123,6 +123,7 @@ public class SessionRemote extends SessionWithState implements DataHandler {
return trans;
}
@Override
public boolean hasPendingTransaction() {
if (clientVersion < Constants.TCP_PROTOCOL_VERSION_10) {
return true;
......
......@@ -15,6 +15,7 @@ import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Time;
import java.sql.Timestamp;
import org.h2.constant.ErrorCode;
import org.h2.constant.SysProperties;
import org.h2.message.DbException;
......@@ -23,7 +24,7 @@ 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.LobStorageBackend;
import org.h2.store.LobStorageFrontend;
import org.h2.store.LobStorageInterface;
import org.h2.tools.SimpleResultSet;
import org.h2.util.DateTimeUtils;
......@@ -597,7 +598,7 @@ public class ValueDataType implements DataType {
if (smallLen >= 0) {
byte[] small = DataUtils.newBytes(smallLen);
buff.get(small, 0, smallLen);
return LobStorageBackend.createSmallLob(type, small);
return LobStorageFrontend.createSmallLob(type, small);
} else if (smallLen == -3) {
int tableId = readVarInt(buff);
long lobId = readVarLong(buff);
......
......@@ -787,7 +787,7 @@ public class Data {
if (smallLen >= 0) {
byte[] small = DataUtils.newBytes(smallLen);
read(small, 0, smallLen);
return LobStorageBackend.createSmallLob(type, small);
return LobStorageFrontend.createSmallLob(type, small);
} else if (smallLen == -3) {
int tableId = readVarInt();
long lobId = readVarLong();
......
......@@ -17,6 +17,7 @@ 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;
......@@ -37,16 +38,6 @@ import org.h2.value.ValueLobDb;
*/
public class LobStorageBackend implements LobStorageInterface {
/**
* The table id for session variables (LOBs not assigned to a table).
*/
public static final int TABLE_ID_SESSION_VARIABLE = -1;
/**
* The table id for temporary objects (not assigned to any object).
*/
public static final int TABLE_TEMP = -2;
/**
* The name of the lob data table. If this table exists, then lob storage is
* used.
......@@ -183,8 +174,8 @@ public class LobStorageBackend implements LobStorageInterface {
} catch (SQLException e) {
throw DbException.convert(e);
}
if (tableId == TABLE_ID_SESSION_VARIABLE) {
removeAllForTable(TABLE_TEMP);
if (tableId == LobStorageFrontend.TABLE_ID_SESSION_VARIABLE) {
removeAllForTable(LobStorageFrontend.TABLE_TEMP);
}
// remove both lobs in the database as well as in the file system
// (compatibility)
......@@ -192,26 +183,6 @@ public class LobStorageBackend implements LobStorageInterface {
ValueLob.removeAllForTable(database, tableId);
}
/**
* 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);
}
/**
* Read a block of data from the given LOB.
*
......@@ -270,144 +241,6 @@ public class LobStorageBackend implements LobStorageInterface {
}
}
/**
* An input stream that reads from a LOB.
*/
public class LobInputStream extends InputStream {
/**
* The size of the lob.
*/
private final long length;
/**
* The remaining bytes in the lob.
*/
private long remainingBytes;
/**
* The temporary buffer.
*/
private byte[] buffer;
/**
* The position within the buffer.
*/
private int pos;
/**
* The lob id.
*/
private final long lob;
/**
* The lob sequence id.
*/
private int seq;
public LobInputStream(long lob, long byteCount) {
this.lob = lob;
remainingBytes = byteCount;
this.length = byteCount;
}
@Override
public int read() throws IOException {
fillBuffer();
if (remainingBytes <= 0) {
return -1;
}
remainingBytes--;
return buffer[pos++] & 255;
}
@Override
public long skip(long n) throws IOException {
long remaining = n;
remaining -= skipSmall(remaining);
if (remaining > BLOCK_LENGTH) {
long toPos = length - remainingBytes + remaining;
try {
long[] seqPos = skipBuffer(lob, toPos);
if (seqPos == null) {
remaining -= super.skip(remaining);
return n - remaining;
}
seq = (int) seqPos[0];
long p = seqPos[1];
remainingBytes = length - p;
remaining = toPos - p;
} catch (SQLException e) {
throw DbException.convertToIOException(e);
}
pos = 0;
buffer = null;
}
fillBuffer();
remaining -= skipSmall(remaining);
remaining -= super.skip(remaining);
return n - remaining;
}
private int skipSmall(long n) {
if (n > 0 && buffer != null && pos < buffer.length) {
int x = MathUtils.convertLongToInt(Math.min(n, buffer.length - pos));
pos += x;
remainingBytes -= x;
return x;
}
return 0;
}
@Override
public int read(byte[] buff) throws IOException {
return readFully(buff, 0, buff.length);
}
@Override
public int read(byte[] buff, int off, int length) throws IOException {
return readFully(buff, off, length);
}
private int readFully(byte[] buff, int off, int length) throws IOException {
if (length == 0) {
return 0;
}
int read = 0;
while (length > 0) {
fillBuffer();
if (remainingBytes <= 0) {
break;
}
int len = (int) Math.min(length, remainingBytes);
len = Math.min(len, buffer.length - pos);
System.arraycopy(buffer, pos, buff, off, len);
pos += len;
read += len;
remainingBytes -= len;
off += len;
length -= len;
}
return read == 0 ? -1 : read;
}
private void fillBuffer() throws IOException {
if (buffer != null && pos < buffer.length) {
return;
}
if (remainingBytes <= 0) {
return;
}
try {
buffer = readBlock(lob, seq++);
pos = 0;
} catch (SQLException e) {
throw DbException.convertToIOException(e);
}
}
}
private PreparedStatement prepare(String sql) throws SQLException {
if (SysProperties.CHECK2) {
if (!Thread.holdsLock(database)) {
......@@ -430,11 +263,6 @@ public class LobStorageBackend implements LobStorageInterface {
prepared.put(sql, prep);
}
/**
* Delete a LOB from the database.
*
* @param lob the lob id
*/
@Override
public void removeLob(long lob) {
try {
......@@ -479,14 +307,6 @@ public class LobStorageBackend implements LobStorageInterface {
}
}
/**
* 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
*/
@Override
public InputStream getInputStream(long lobId, byte[] hmac, long byteCount) throws IOException {
init();
......@@ -557,7 +377,7 @@ public class LobStorageBackend implements LobStorageInterface {
ValueLobDb v = ValueLobDb.createSmallLob(type, small, small.length);
return v;
}
return registerLob(type, lobId, TABLE_TEMP, length);
return registerLob(type, lobId, LobStorageFrontend.TABLE_TEMP, length);
} catch (IOException e) {
if (lobId != -1) {
removeLob(lobId);
......@@ -587,15 +407,6 @@ public class LobStorageBackend implements LobStorageInterface {
}
}
/**
* 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
*/
@Override
public ValueLobDb copyLob(int type, long oldLobId, int tableId, long length) {
synchronized (database) {
......@@ -710,6 +521,183 @@ public class LobStorageBackend implements LobStorageInterface {
}
}
@Override
public Value createBlob(InputStream in, long maxLength) {
if (SysProperties.LOB_IN_DATABASE) {
init();
return addLob(in, maxLength, Value.BLOB);
}
return ValueLob.createBlob(in, maxLength, database);
}
@Override
public Value createClob(Reader reader, long maxLength) {
if (SysProperties.LOB_IN_DATABASE) {
init();
long max = maxLength == -1 ? Long.MAX_VALUE : maxLength;
CountingReaderInputStream in = new CountingReaderInputStream(reader, max);
ValueLobDb lob = addLob(in, Long.MAX_VALUE, Value.CLOB);
lob.setPrecision(in.getLength());
return lob;
}
return ValueLob.createClob(reader, maxLength, database);
}
@Override
public void setTable(long lobId, int table) {
synchronized (database) {
try {
init();
String sql = "UPDATE " + LOBS + " SET TABLE = ? WHERE ID = ?";
PreparedStatement prep = prepare(sql);
prep.setInt(1, table);
prep.setLong(2, lobId);
prep.executeUpdate();
reuse(sql, prep);
} catch (SQLException e) {
throw DbException.convert(e);
}
}
}
/**
* An input stream that reads from a LOB.
*/
public class LobInputStream extends InputStream {
/**
* The size of the lob.
*/
private final long length;
/**
* The remaining bytes in the lob.
*/
private long remainingBytes;
/**
* The temporary buffer.
*/
private byte[] buffer;
/**
* The position within the buffer.
*/
private int pos;
/**
* The lob id.
*/
private final long lob;
/**
* The lob sequence id.
*/
private int seq;
public LobInputStream(long lob, long byteCount) {
this.lob = lob;
remainingBytes = byteCount;
this.length = byteCount;
}
@Override
public int read() throws IOException {
fillBuffer();
if (remainingBytes <= 0) {
return -1;
}
remainingBytes--;
return buffer[pos++] & 255;
}
@Override
public long skip(long n) throws IOException {
long remaining = n;
remaining -= skipSmall(remaining);
if (remaining > BLOCK_LENGTH) {
long toPos = length - remainingBytes + remaining;
try {
long[] seqPos = skipBuffer(lob, toPos);
if (seqPos == null) {
remaining -= super.skip(remaining);
return n - remaining;
}
seq = (int) seqPos[0];
long p = seqPos[1];
remainingBytes = length - p;
remaining = toPos - p;
} catch (SQLException e) {
throw DbException.convertToIOException(e);
}
pos = 0;
buffer = null;
}
fillBuffer();
remaining -= skipSmall(remaining);
remaining -= super.skip(remaining);
return n - remaining;
}
private int skipSmall(long n) {
if (n > 0 && buffer != null && pos < buffer.length) {
int x = MathUtils.convertLongToInt(Math.min(n, buffer.length - pos));
pos += x;
remainingBytes -= x;
return x;
}
return 0;
}
@Override
public int read(byte[] buff) throws IOException {
return readFully(buff, 0, buff.length);
}
@Override
public int read(byte[] buff, int off, int length) throws IOException {
return readFully(buff, off, length);
}
private int readFully(byte[] buff, int off, int length) throws IOException {
if (length == 0) {
return 0;
}
int read = 0;
while (length > 0) {
fillBuffer();
if (remainingBytes <= 0) {
break;
}
int len = (int) Math.min(length, remainingBytes);
len = Math.min(len, buffer.length - pos);
System.arraycopy(buffer, pos, buff, off, len);
pos += len;
read += len;
remainingBytes -= len;
off += len;
length -= len;
}
return read == 0 ? -1 : read;
}
private void fillBuffer() throws IOException {
if (buffer != null && pos < buffer.length) {
return;
}
if (remainingBytes <= 0) {
return;
}
try {
buffer = readBlock(lob, seq++);
pos = 0;
} catch (SQLException e) {
throw DbException.convertToIOException(e);
}
}
}
/**
* An input stream that reads the data from a reader.
*/
......@@ -787,62 +775,4 @@ public class LobStorageBackend implements LobStorageInterface {
}
/**
* Create a BLOB object.
*
* @param in the input stream
* @param maxLength the maximum length (-1 if not known)
* @return the LOB
*/
@Override
public Value createBlob(InputStream in, long maxLength) {
if (SysProperties.LOB_IN_DATABASE) {
init();
return addLob(in, maxLength, Value.BLOB);
}
return ValueLob.createBlob(in, maxLength, database);
}
/**
* Create a CLOB object.
*
* @param reader the reader
* @param maxLength the maximum length (-1 if not known)
* @return the LOB
*/
@Override
public Value createClob(Reader reader, long maxLength) {
if (SysProperties.LOB_IN_DATABASE) {
init();
long max = maxLength == -1 ? Long.MAX_VALUE : maxLength;
CountingReaderInputStream in = new CountingReaderInputStream(reader, max);
ValueLobDb lob = addLob(in, Long.MAX_VALUE, Value.CLOB);
lob.setPrecision(in.getLength());
return lob;
}
return ValueLob.createClob(reader, maxLength, database);
}
/**
* Set the table reference of this lob.
*
* @param lobId the lob
* @param table the table
*/
public void setTable(long lobId, int table) {
synchronized (database) {
try {
init();
String sql = "UPDATE " + LOBS + " SET TABLE = ? WHERE ID = ?";
PreparedStatement prep = prepare(sql);
prep.setInt(1, table);
prep.setLong(2, lobId);
prep.executeUpdate();
reuse(sql, prep);
} catch (SQLException e) {
throw DbException.convert(e);
}
}
}
}
......@@ -11,6 +11,7 @@ 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;
......@@ -20,6 +21,16 @@ import org.h2.value.ValueLobDb;
* This is the front-end i.e. the client side of the LOB storage.
*/
public class LobStorageFrontend implements LobStorageInterface {
/**
* The table id for session variables (LOBs not assigned to a table).
*/
public static final int TABLE_ID_SESSION_VARIABLE = -1;
/**
* The table id for temporary objects (not assigned to any object).
*/
public static final int TABLE_TEMP = -2;
private final DataHandler handler;
......@@ -53,29 +64,16 @@ public class LobStorageFrontend implements LobStorageInterface {
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
*/
@Override
public ValueLobDb copyLob(int type, long oldLobId, int tableId, long length) {
// TODO this should not be called at all, but that's a refactoring for another day
// this should never be called
throw new UnsupportedOperationException();
}
@Override
public void setTable(long lobId, int tableIdSessionVariable) {
throw new UnsupportedOperationException();
}
/**
* Create a BLOB object.
*
* @param in the input stream
* @param maxLength the maximum length (-1 if not known)
* @return the LOB
*/
@Override
public Value createBlob(InputStream in, long maxLength) {
if (SysProperties.LOB_IN_DATABASE) {
......@@ -104,5 +102,26 @@ public class LobStorageFrontend implements LobStorageInterface {
}
return ValueLob.createClob(reader, maxLength, 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);
}
}
......@@ -56,6 +56,14 @@ public interface LobStorageInterface {
*/
InputStream getInputStream(long lobId, byte[] hmac, long byteCount) throws IOException;
/**
* Set the table reference of this lob.
*
* @param lobId the lob
* @param table the table
*/
void setTable(long lobId, int tableIdSessionVariable);
/**
* Delete a LOB from the database.
*
......
......@@ -39,6 +39,7 @@ import org.h2.store.FileLister;
import org.h2.store.FileStore;
import org.h2.store.FileStoreInputStream;
import org.h2.store.LobStorageBackend;
import org.h2.store.LobStorageFrontend;
import org.h2.store.LobStorageInterface;
import org.h2.store.Page;
import org.h2.store.PageFreeList;
......@@ -195,7 +196,7 @@ public class Recover extends Tool implements DataHandler {
public static Value.ValueBlob readBlobDb(Connection conn, long lobId, long precision) {
DataHandler h = ((JdbcConnection) conn).getSession().getDataHandler();
LobStorageInterface lobStorage = h.getLobStorage();
return ValueLobDb.create(Value.BLOB, lobStorage, LobStorageBackend.TABLE_TEMP, lobId, null, precision);
return ValueLobDb.create(Value.BLOB, lobStorage, LobStorageFrontend.TABLE_TEMP, lobId, null, precision);
}
/**
......@@ -204,7 +205,7 @@ public class Recover extends Tool implements DataHandler {
public static Value.ValueClob readClobDb(Connection conn, long lobId, long precision) {
DataHandler h = ((JdbcConnection) conn).getSession().getDataHandler();
LobStorageInterface lobStorage = h.getLobStorage();
return ValueLobDb.create(Value.CLOB, lobStorage, LobStorageBackend.TABLE_TEMP, lobId, null, precision);
return ValueLobDb.create(Value.CLOB, lobStorage, LobStorageFrontend.TABLE_TEMP, lobId, null, precision);
}
private void trace(String message) {
......@@ -1235,7 +1236,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 = " + LobStorageBackend.TABLE_TEMP + ";");
writer.println("UPDATE " + name + " SET TABLE = " + LobStorageFrontend.TABLE_TEMP + ";");
deleteLobs = true;
}
}
......@@ -1261,7 +1262,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 = " + LobStorageBackend.TABLE_TEMP + ";");
writer.println("DELETE FROM INFORMATION_SCHEMA.LOBS WHERE TABLE = " + LobStorageFrontend.TABLE_TEMP + ";");
}
for (MetaRecord m : schema) {
if (isSchemaObjectTypeDelayed(m)) {
......
......@@ -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.LobStorageBackend;
import org.h2.store.LobStorageFrontend;
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 = LobStorageBackend.createSmallLob(Value.CLOB, rs.getString(columnIndex).getBytes(Constants.UTF8));
v = LobStorageFrontend.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 = LobStorageBackend.createSmallLob(Value.BLOB, rs.getBytes(columnIndex));
v = LobStorageFrontend.createSmallLob(Value.BLOB, rs.getBytes(columnIndex));
} else {
InputStream in = rs.getBinaryStream(columnIndex);
v = (in == null) ? (Value) ValueNull.INSTANCE : session.getDataHandler().getLobStorage().createBlob(in, -1);
......
......@@ -22,9 +22,9 @@ import java.sql.Types;
import org.h2.constant.ErrorCode;
import org.h2.constant.SysProperties;
import org.h2.engine.Constants;
import org.h2.engine.Database;
import org.h2.message.DbException;
import org.h2.store.LobStorageBackend;
import org.h2.store.DataHandler;
import org.h2.store.LobStorageFrontend;
import org.h2.tools.SimpleResultSet;
import org.h2.util.DateTimeUtils;
import org.h2.util.MathUtils;
......@@ -771,8 +771,7 @@ public abstract class Value {
case BLOB: {
switch(getType()) {
case BYTES:
return LobStorageBackend.createSmallLob(Value.BLOB, getBytesNoCopy());
return LobStorageFrontend.createSmallLob(Value.BLOB, getBytesNoCopy());
}
break;
}
......@@ -835,9 +834,9 @@ public abstract class Value {
case FLOAT:
return ValueFloat.get(Float.parseFloat(s.trim()));
case CLOB:
return LobStorageBackend.createSmallLob(CLOB, s.getBytes(Constants.UTF8));
return LobStorageFrontend.createSmallLob(CLOB, s.getBytes(Constants.UTF8));
case BLOB:
return LobStorageBackend.createSmallLob(BLOB, StringUtils.convertHexToBytes(s.trim()));
return LobStorageFrontend.createSmallLob(BLOB, StringUtils.convertHexToBytes(s.trim()));
case ARRAY:
return ValueArray.get(new Value[]{ValueString.get(s)});
case RESULT_SET: {
......@@ -969,11 +968,11 @@ public abstract class Value {
* Link a large value to a given table. For values that are kept fully in
* memory this method has no effect.
*
* @param database the database
* @param handler the data handler
* @param tableId the table to link to
* @return the new value or itself
*/
public Value link(Database database, int tableId) {
public Value link(DataHandler handler, int tableId) {
return this;
}
......@@ -990,8 +989,10 @@ public abstract class Value {
/**
* Mark any underlying resource as 'not linked to any table'. For values
* that are kept fully in memory this method has no effect.
*
* @param handler the data handler
*/
public void unlink(Database database) {
public void unlink(DataHandler handler) {
// nothing to do
}
......
......@@ -14,9 +14,9 @@ import java.io.InputStream;
import java.io.Reader;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import org.h2.constant.SysProperties;
import org.h2.engine.Constants;
import org.h2.engine.Database;
import org.h2.message.DbException;
import org.h2.mvstore.DataUtils;
import org.h2.store.DataHandler;
......@@ -237,7 +237,7 @@ public class ValueLob extends Value {
}
}
private static String getFileNamePrefix(String path, int objectId) {
public static String getFileNamePrefix(String path, int objectId) {
String name;
int f = objectId % SysProperties.LOB_FILES_PER_DIRECTORY;
if (f > 0) {
......@@ -498,6 +498,7 @@ public class ValueLob extends Value {
}
}
@Override
public Value link(DataHandler h, int tabId) {
if (fileName == null) {
this.tableId = tabId;
......@@ -741,29 +742,6 @@ public class ValueLob extends Value {
}
}
/**
* Remove all lobs for a given table id.
*
* @param database the database
* @param tableId the table id
*/
public static void removeAllForTable(Database database, int tableId) {
String dir = getFileNamePrefix(database.getDatabasePath(), 0);
removeAllForTable(database, dir, tableId);
}
private static void removeAllForTable(Database database, String dir, int tableId) {
for (String name : FileUtils.newDirectoryStream(dir)) {
if (FileUtils.isDirectory(name)) {
removeAllForTable(database, name, tableId);
} else {
if (name.endsWith(".t" + tableId + Constants.SUFFIX_LOB_FILE)) {
deleteFile(database, name);
}
}
}
}
/**
* Check if this lob value is compressed.
*
......@@ -773,7 +751,7 @@ public class ValueLob extends Value {
return compression;
}
private static synchronized void deleteFile(DataHandler handler, String fileName) {
public static synchronized void deleteFile(DataHandler handler, String fileName) {
// synchronize on the database, to avoid concurrent temp file creation /
// deletion / backup
synchronized (handler.getLobSyncObject()) {
......@@ -805,6 +783,29 @@ public class ValueLob extends Value {
}
return 140;
}
/**
* Remove all lobs for a given table id.
*
* @param handler the data handler
* @param tableId the table id
*/
public static void removeAllForTable(DataHandler handler, int tableId) {
String dir = ValueLob.getFileNamePrefix(handler.getDatabasePath(), 0);
removeAllForTable(handler, dir, tableId);
}
private static void removeAllForTable(DataHandler handler, String dir, int tableId) {
for (String name : FileUtils.newDirectoryStream(dir)) {
if (FileUtils.isDirectory(name)) {
removeAllForTable(handler, name, tableId);
} else {
if (name.endsWith(".t" + tableId + Constants.SUFFIX_LOB_FILE)) {
ValueLob.deleteFile(handler, name);
}
}
}
}
/**
* Create an independent copy of this temporary value.
......
......@@ -13,16 +13,16 @@ import java.io.InputStream;
import java.io.Reader;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import org.h2.constant.SysProperties;
import org.h2.engine.Constants;
import org.h2.engine.Database;
import org.h2.message.DbException;
import org.h2.mvstore.DataUtils;
import org.h2.store.DataHandler;
import org.h2.store.FileStore;
import org.h2.store.FileStoreInputStream;
import org.h2.store.FileStoreOutputStream;
import org.h2.store.LobStorageBackend;
import org.h2.store.LobStorageFrontend;
import org.h2.store.LobStorageInterface;
import org.h2.store.fs.FileUtils;
import org.h2.util.IOUtils;
......@@ -111,14 +111,14 @@ public class ValueLobDb extends Value implements Value.ValueClob, Value.ValueBlo
Value copy = lobStorage.createClob(getReader(), -1);
return copy;
} else if (small != null) {
return LobStorageBackend.createSmallLob(t, small);
return LobStorageFrontend.createSmallLob(t, small);
}
} else if (t == Value.BLOB) {
if (lobStorage != null) {
Value copy = lobStorage.createBlob(getInputStream(), -1);
return copy;
} else if (small != null) {
return LobStorageBackend.createSmallLob(t, small);
return LobStorageFrontend.createSmallLob(t, small);
}
}
return super.convertTo(t);
......@@ -126,7 +126,7 @@ public class ValueLobDb extends Value implements Value.ValueClob, Value.ValueBlo
@Override
public boolean isLinked() {
return tableId != LobStorageBackend.TABLE_ID_SESSION_VARIABLE && small == null;
return tableId != LobStorageFrontend.TABLE_ID_SESSION_VARIABLE && small == null;
}
public boolean isStored() {
......@@ -152,31 +152,31 @@ public class ValueLobDb extends Value implements Value.ValueClob, Value.ValueBlo
}
@Override
public void unlink(Database database) {
if (small == null && tableId != LobStorageBackend.TABLE_ID_SESSION_VARIABLE) {
database.getLobStorage().setTable(lobId, LobStorageBackend.TABLE_ID_SESSION_VARIABLE);
tableId = LobStorageBackend.TABLE_ID_SESSION_VARIABLE;
public void unlink(DataHandler database) {
if (small == null && tableId != LobStorageFrontend.TABLE_ID_SESSION_VARIABLE) {
database.getLobStorage().setTable(lobId, LobStorageFrontend.TABLE_ID_SESSION_VARIABLE);
tableId = LobStorageFrontend.TABLE_ID_SESSION_VARIABLE;
}
}
@Override
public Value link(Database database, int tabId) {
public Value link(DataHandler database, int tabId) {
if (small == null) {
if (tableId == LobStorageBackend.TABLE_TEMP) {
if (tableId == LobStorageFrontend.TABLE_TEMP) {
database.getLobStorage().setTable(lobId, tabId);
this.tableId = tabId;
} else {
return lobStorage.copyLob(type, lobId, tabId, getPrecision());
}
} else if (small.length > database.getMaxLengthInplaceLob()) {
LobStorageInterface s = database.getLobStorage();
} else if (small.length > handler.getMaxLengthInplaceLob()) {
LobStorageInterface s = handler.getLobStorage();
Value v;
if (type == Value.BLOB) {
v = s.createBlob(getInputStream(), getPrecision());
} else {
v = s.createClob(getReader(), getPrecision());
}
return v.link(database, tabId);
return v.link(handler, tabId);
}
return this;
}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论