提交 8a43aca5 authored 作者: Thomas Mueller's avatar Thomas Mueller

Server mode: if the client ran with a different timezone setting than the…

Server mode: if the client ran with a different timezone setting than the server, date values got shifted by the difference between the timezones.
上级 cee8afbb
......@@ -9,7 +9,6 @@ package org.h2.command;
import java.io.IOException;
import java.util.ArrayList;
import org.h2.constant.SysProperties;
import org.h2.engine.Constants;
import org.h2.engine.SessionRemote;
import org.h2.expression.ParameterInterface;
import org.h2.expression.ParameterRemote;
......@@ -56,11 +55,10 @@ public class CommandRemote implements CommandInterface {
private void prepare(SessionRemote s, boolean createParams) {
id = s.getNextId();
paramCount = 0;
boolean readParams = s.getClientVersion() >= Constants.TCP_PROTOCOL_VERSION;
for (int i = 0, count = 0; i < transferList.size(); i++) {
try {
Transfer transfer = transferList.get(i);
if (readParams && createParams) {
if (createParams) {
s.traceOperation("SESSION_PREPARE_READ_PARAMS", id);
transfer.writeInt(SessionRemote.SESSION_PREPARE_READ_PARAMS).writeInt(id).writeString(sql);
} else {
......@@ -74,13 +72,9 @@ public class CommandRemote implements CommandInterface {
if (createParams) {
parameters.clear();
for (int j = 0; j < paramCount; j++) {
if (readParams) {
ParameterRemote p = new ParameterRemote(j);
p.readMetaData(transfer);
parameters.add(p);
} else {
parameters.add(new ParameterRemote(j));
}
}
}
} catch (IOException e) {
......
......@@ -39,11 +39,21 @@ public class Constants {
*/
public static final String BUILD_DATE_STABLE = "2010-07-10";
/**
* The TCP protocol version number 6.
*/
public static final int TCP_PROTOCOL_VERSION_6 = 6;
/**
* The TCP protocol version number 7.
*/
public static final int TCP_PROTOCOL_VERSION_7 = 7;
/**
* The TCP protocol version number. This protocol is used by the TCP
* server and remote JDBC client.
*/
public static final int TCP_PROTOCOL_VERSION = 6;
public static final int TCP_PROTOCOL_VERSION = TCP_PROTOCOL_VERSION_7;
/**
* The major version of this database.
......
......@@ -16,12 +16,10 @@ import org.h2.command.CommandRemote;
import org.h2.command.dml.SetTypes;
import org.h2.constant.ErrorCode;
import org.h2.constant.SysProperties;
import org.h2.expression.ParameterInterface;
import org.h2.jdbc.JdbcSQLException;
import org.h2.message.DbException;
import org.h2.message.Trace;
import org.h2.message.TraceSystem;
import org.h2.result.ResultInterface;
import org.h2.store.DataHandler;
import org.h2.store.FileStore;
import org.h2.store.LobStorage;
......@@ -34,8 +32,6 @@ import org.h2.util.StringUtils;
import org.h2.util.TempFileDeleter;
import org.h2.util.Utils;
import org.h2.value.Transfer;
import org.h2.value.Value;
import org.h2.value.ValueString;
/**
* The client side part of a session when using the server mode. This object
......@@ -76,7 +72,7 @@ public class SessionRemote extends SessionWithState implements SessionFactory, D
private byte[] fileEncryptionKey;
private Object lobSyncObject = new Object();
private String sessionId;
private int clientVersion = Constants.TCP_PROTOCOL_VERSION;
private int clientVersion;
private boolean autoReconnect;
private int lastReconnect;
private SessionInterface embedded;
......@@ -98,8 +94,8 @@ public class SessionRemote extends SessionWithState implements SessionFactory, D
trans.setSocket(socket);
trans.setSSL(ci.isSSL());
trans.init();
trans.writeInt(clientVersion);
trans.writeInt(clientVersion);
trans.writeInt(Constants.TCP_PROTOCOL_VERSION_6);
trans.writeInt(Constants.TCP_PROTOCOL_VERSION_7);
trans.writeString(db);
trans.writeString(ci.getOriginalURL());
trans.writeString(ci.getUserName());
......@@ -112,9 +108,8 @@ public class SessionRemote extends SessionWithState implements SessionFactory, D
}
try {
done(trans);
if (clientVersion >= Constants.TCP_PROTOCOL_VERSION) {
clientVersion = trans.readInt();
}
trans.setVersion(clientVersion);
} catch (DbException e) {
trans.close();
throw e;
......@@ -342,45 +337,6 @@ public class SessionRemote extends SessionWithState implements SessionFactory, D
traceSystem.close();
throw e;
}
upgradeClientVersionIfPossible();
}
private void upgradeClientVersionIfPossible() {
try {
// TODO check if a newer client version can be used
// not required when sending TCP_DRIVER_VERSION_6
CommandInterface command = prepareCommand("SELECT VALUE FROM INFORMATION_SCHEMA.SETTINGS WHERE NAME=?", 1);
ParameterInterface param = command.getParameters().get(0);
param.setValue(ValueString.get("info.BUILD_ID"), false);
ResultInterface result = command.executeQuery(1, false);
if (result.next()) {
Value[] v = result.currentRow();
int version = v[0].getInt();
if (version > 71) {
clientVersion = Constants.TCP_PROTOCOL_VERSION;
}
}
result.close();
} catch (DbException e) {
trace.error("Error trying to upgrade client version", e);
// ignore
}
if (clientVersion >= Constants.TCP_PROTOCOL_VERSION) {
sessionId = StringUtils.convertBytesToString(MathUtils.secureRandomBytes(32));
synchronized (this) {
for (Transfer transfer : transferList) {
try {
traceOperation("SESSION_SET_ID", 0);
transfer.writeInt(SessionRemote.SESSION_SET_ID);
transfer.writeString(sessionId);
done(transfer);
} catch (Exception e) {
trace.error("sessionSetId", e);
}
}
}
}
}
private void switchOffCluster() {
......
......@@ -68,12 +68,19 @@ public class TcpServerThread implements Runnable {
if (!server.allow(transfer.getSocket())) {
throw DbException.get(ErrorCode.REMOTE_CONNECTION_NOT_ALLOWED);
}
clientVersion = transfer.readInt();
if (clientVersion < Constants.TCP_PROTOCOL_VERSION) {
throw DbException.get(ErrorCode.DRIVER_VERSION_ERROR_2, "" + clientVersion, "" + Constants.TCP_PROTOCOL_VERSION);
int minClientVersion = transfer.readInt();
if (minClientVersion < 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_7) {
throw DbException.get(ErrorCode.DRIVER_VERSION_ERROR_2, "" + clientVersion, "" + Constants.TCP_PROTOCOL_VERSION_7);
}
int maxClientVersion = transfer.readInt();
if (maxClientVersion >= Constants.TCP_PROTOCOL_VERSION_7) {
clientVersion = Constants.TCP_PROTOCOL_VERSION_7;
} else {
clientVersion = minClientVersion;
}
// max version (currently not used)
transfer.readInt();
transfer.setVersion(clientVersion);
String db = transfer.readString();
String originalURL = transfer.readString();
if (db == null && originalURL == null) {
......@@ -118,10 +125,7 @@ public class TcpServerThread implements Runnable {
session = engine.getSession(ci);
transfer.setSession(session);
transfer.writeInt(SessionRemote.STATUS_OK);
if (clientVersion >= Constants.TCP_PROTOCOL_VERSION) {
// version 6: reply what version to use
transfer.writeInt(Constants.TCP_PROTOCOL_VERSION);
}
transfer.writeInt(clientVersion);
transfer.flush();
server.addConnection(threadId, originalURL, ci.getUserName());
trace("Connected");
......
......@@ -222,8 +222,8 @@ public class FileLock implements Runnable {
Transfer transfer = new Transfer(null);
transfer.setSocket(socket);
transfer.init();
transfer.writeInt(Constants.TCP_PROTOCOL_VERSION);
transfer.writeInt(Constants.TCP_PROTOCOL_VERSION);
transfer.writeInt(Constants.TCP_PROTOCOL_VERSION_6);
transfer.writeInt(Constants.TCP_PROTOCOL_VERSION_7);
transfer.writeString(null);
transfer.writeString(null);
transfer.writeString(id);
......
......@@ -30,6 +30,7 @@ import org.h2.engine.SessionInterface;
import org.h2.message.DbException;
import org.h2.message.TraceSystem;
import org.h2.tools.SimpleResultSet;
import org.h2.util.DateTimeUtils;
import org.h2.util.ExactUTF8InputStreamReader;
import org.h2.util.IOUtils;
import org.h2.util.NetUtils;
......@@ -50,6 +51,7 @@ public class Transfer {
private DataOutputStream out;
private SessionInterface session;
private boolean ssl;
private int version;
/**
* Create a new transfer object for the specified session.
......@@ -322,14 +324,26 @@ public class Transfer {
writeByte(v.getByte());
break;
case Value.TIME:
if (version >= Constants.TCP_PROTOCOL_VERSION_7) {
writeLong(DateTimeUtils.getTimeLocal(v.getTimeNoCopy()));
} else {
writeLong(v.getTimeNoCopy().getTime());
}
break;
case Value.DATE:
if (version >= Constants.TCP_PROTOCOL_VERSION_7) {
writeLong(DateTimeUtils.getTimeLocal(v.getDateNoCopy()));
} else {
writeLong(v.getDateNoCopy().getTime());
}
break;
case Value.TIMESTAMP: {
Timestamp ts = v.getTimestampNoCopy();
if (version >= Constants.TCP_PROTOCOL_VERSION_7) {
writeLong(DateTimeUtils.getTimeLocal(ts));
} else {
writeLong(ts.getTime());
}
writeInt(ts.getNanos());
break;
}
......@@ -455,10 +469,21 @@ public class Transfer {
case Value.BYTE:
return ValueByte.get(readByte());
case Value.DATE:
if (version >= Constants.TCP_PROTOCOL_VERSION_7) {
return ValueDate.getNoCopy(new Date(DateTimeUtils.getTimeGMT(readLong())));
}
return ValueDate.getNoCopy(new Date(readLong()));
case Value.TIME:
if (version >= Constants.TCP_PROTOCOL_VERSION_7) {
return ValueTime.getNoCopy(new Time(DateTimeUtils.getTimeGMT(readLong())));
}
return ValueTime.getNoCopy(new Time(readLong()));
case Value.TIMESTAMP: {
if (version >= Constants.TCP_PROTOCOL_VERSION_7) {
Timestamp ts = new Timestamp(DateTimeUtils.getTimeGMT(readLong()));
ts.setNanos(readInt());
return ValueTimestamp.getNoCopy(ts);
}
Timestamp ts = new Timestamp(readLong());
ts.setNanos(readInt());
return ValueTimestamp.getNoCopy(ts);
......@@ -572,4 +597,9 @@ public class Transfer {
return trans;
}
public void setVersion(int version) {
System.out.println("transfer version " + version);
this.version = version;
}
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论