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