Skip to content

Commit

Permalink
[misc] implementation of useLegacyDatetimeCode
Browse files Browse the repository at this point in the history
  • Loading branch information
rusher committed Sep 29, 2015
1 parent 77644b6 commit 2619ff5
Show file tree
Hide file tree
Showing 26 changed files with 915 additions and 308 deletions.
2 changes: 0 additions & 2 deletions .travis/before_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,4 @@ then
sleep 20
fi

cat /etc/mysql/my.cnf

sudo mysql -uroot -e "create database IF NOT EXISTS test"
3 changes: 2 additions & 1 deletion build_release.bat
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ call mvn exec:exec package -Dpackage-source
call %BINDIR%\mysqladmin -uroot shutdown

#deploy package
#mvn clean deploy -Dmaven.test.skip=true -Dpackage-source
#mvn clean deploy -Dmaven.test.skip=true -Dpackage-source

Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ public void setDate(final int parameterIndex, final Date date, final Calendar ca
setNull(parameterIndex, Types.DATE);
return;
}
setParameter(parameterIndex, new DateParameter(date));
setParameter(parameterIndex, new DateParameter(date, cal, protocol.getOptions()));
}

/**
Expand All @@ -218,7 +218,7 @@ public void setTime(final int parameterIndex, final Time time, final Calendar ca
setNull(parameterIndex, MySQLType.TIME);
return;
}
setParameter(parameterIndex, new TimeParameter(time, cal, useFractionalSeconds()));
setParameter(parameterIndex, new TimeParameter(time, cal, useFractionalSeconds(), protocol.getOptions()));
}

/**
Expand All @@ -242,7 +242,7 @@ public void setTimestamp(final int parameterIndex, final Timestamp timestamp, fi
setNull(parameterIndex, MySQLType.DATETIME);
return;
}
TimestampParameter t = new TimestampParameter(timestamp, cal, useFractionalSeconds());
TimestampParameter t = new TimestampParameter(timestamp, cal, useFractionalSeconds(), protocol.getOptions());
setParameter(parameterIndex, t);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ protected boolean useFractionalSeconds() {

@Override
protected Calendar cal() {
return connection.cal;
return protocol.getCalendar();
}

/**
Expand Down
18 changes: 1 addition & 17 deletions src/main/java/org/mariadb/jdbc/MySQLConnection.java
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ public final class MySQLConnection implements Connection {
boolean noBackslashEscapes;
boolean nullCatalogMeansCurrent = true;
int autoIncrementIncrement;
Calendar cal;
volatile int lowercaseTableNames = -1;
/**
* save point count - to generate good names for the savepoints.
Expand All @@ -96,26 +95,11 @@ private MySQLConnection(Protocol protocol, ReentrantReadWriteLock lock) throws S
this.lock = lock;
}

static TimeZone getTimeZone(String id) throws SQLException {
TimeZone tz = java.util.TimeZone.getTimeZone(id);

// Validate the timezone ID. JDK maps invalid timezones to GMT
if (tz.getID().equals("GMT") && !id.equals("GMT")) {
throw new SQLException("invalid timezone id '" + id + "'");
}
return tz;
}

public static MySQLConnection newConnection(Protocol protocol, ReentrantReadWriteLock lock) throws SQLException {
MySQLConnection connection = new MySQLConnection(protocol, lock);

Options options = protocol.getOptions();
if (options.serverTimezone != null) {
TimeZone tz = getTimeZone(options.serverTimezone);
connection.cal = Calendar.getInstance(tz);
} else {
connection.cal = new GregorianCalendar();
}

try {
connection.noBackslashEscapes = protocol.noBackslashEscapes();
} catch (QueryException e) {
Expand Down
20 changes: 10 additions & 10 deletions src/main/java/org/mariadb/jdbc/MySQLResultSet.java
Original file line number Diff line number Diff line change
Expand Up @@ -86,19 +86,19 @@ public class MySQLResultSet implements ResultSet {
protected MySQLResultSet() {
}

public MySQLResultSet(QueryResult dqr, MySQLStatement statement, Protocol protocol, Calendar cal) {
public MySQLResultSet(QueryResult dqr, MySQLStatement statement, Protocol protocol) {
this.queryResult = dqr;
this.statement = statement;
this.protocol = protocol;
this.cal = cal;
this.cal = (protocol!=null)?protocol.getCalendar():null;
this.columnNameMap = new ColumnNameMap(dqr.getColumnInformation());
}

private static MySQLResultSet createEmptyResultSet() {
MySQLColumnInformation[] colList = new MySQLColumnInformation[0];
List<ValueObject[]> voList = Collections.emptyList();
QueryResult qr = new CachedSelectResult(colList, voList, (short) 0);
return new MySQLResultSet(qr, null, null, null);
return new MySQLResultSet(qr, null, null);
}

/**
Expand Down Expand Up @@ -140,20 +140,20 @@ static ResultSet createResultSet(String[] columnNames, MySQLType[] columnTypes,
} else {
bytes = rowData[i].getBytes(StandardCharsets.UTF_8);
}
row[i] = new MySQLValueObject(bytes, columns[i]);
row[i] = new MySQLValueObject(bytes, columns[i], protocol.getOptions());
}
rows.add(row);
}
if (findColumnReturnsOne) {
return new MySQLResultSet(new CachedSelectResult(columns, rows, (short) 0),
null, protocol, null) {
null, protocol) {
public int findColumn(String name) {
return 1;
}
};
}
return new MySQLResultSet(new CachedSelectResult(columns, rows, (short) 0),
null, protocol, null);
null, protocol);
}

/**
Expand Down Expand Up @@ -205,20 +205,20 @@ static ResultSet createResultSet(MySQLColumnInformation[] columns, String[][] da
} else {
bytes = rowData[i].getBytes(StandardCharsets.UTF_8);
}
row[i] = new MySQLValueObject(bytes, columns[i]);
row[i] = new MySQLValueObject(bytes, columns[i], protocol.getOptions());
}
rows.add(row);
}
if (findColumnReturnsOne) {
return new MySQLResultSet(new CachedSelectResult(columns, rows, (short) 0),
null, protocol, null) {
null, protocol) {
public int findColumn(String name) {
return 1;
}
};
}
return new MySQLResultSet(new CachedSelectResult(columns, rows, (short) 0),
null, protocol, null);
null, protocol);
}

/**
Expand Down Expand Up @@ -322,7 +322,7 @@ public boolean wasNull() throws SQLException {
}

public String getString(int i) throws SQLException {
return getValueObject(i).getString();
return getValueObject(i).getString(cal);
}

public int getInt(int i) throws SQLException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ protected boolean useFractionalSeconds() {

@Override
protected Calendar cal() {
return connection.cal;
return protocol.getCalendar();
}

protected void setParameter(final int parameterIndex, final ParameterHolder holder) throws SQLException {
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/mariadb/jdbc/MySQLStatement.java
Original file line number Diff line number Diff line change
Expand Up @@ -980,7 +980,7 @@ public ResultSet getResultSet() throws SQLException {
if (queryResult == null || queryResult.getResultSetType() != ResultSetType.SELECT) {
return null; /* Result is an update count, or there are no more results */
}
return new MySQLResultSet(queryResult, this, protocol, connection.cal);
return new MySQLResultSet(queryResult, this, protocol);
}

public int getUpdateCount() throws SQLException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,21 @@ public enum DefaultOptions {
* setting session read-only.
* default to false
*/
ASSUREREADONLY("assureReadOnly", Boolean.FALSE, "1.3.0");
ASSUREREADONLY("assureReadOnly", Boolean.FALSE, "1.3.0"),


/**
* if true (default) store date/timestamps according to client time zone
* if false, store all date/timestamps in DB according to server time zone, and time information (that is a time difference), doesn't take timezone in account.
*/
USELEGACYDATETIMECODE("useLegacyDatetimeCode", Boolean.TRUE, "1.3.0"),

/**
* maximize Mysql compatibility.
* when using jdbc setDate(), will store date in client timezone, not in server timezone when useLegacyDatetimeCode = false
* default to false.
*/
MAXIMIZEMYSQLCOMPATIBILITY("maximizeMysqlCompatibility", Boolean.FALSE, "1.3.0");

protected final String name;
protected final Object objType;
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/org/mariadb/jdbc/internal/common/Options.java
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ public class Options {
public boolean cachePrepStmts;
public Integer prepStmtCacheSize;
public Integer prepStmtCacheSqlLimit;
public boolean useLegacyDatetimeCode;
public boolean maximizeMysqlCompatibility;


//HA options
public boolean assureReadOnly;
Expand Down Expand Up @@ -147,6 +150,8 @@ public String toString() {
", validConnectionTimeout=" + validConnectionTimeout +
", loadBalanceBlacklistTimeout=" + loadBalanceBlacklistTimeout +
", failoverLoopRetries=" + failoverLoopRetries +
", useLegacyDatetimeCode=" + useLegacyDatetimeCode +
", maximizeMysqlCompatibility=" + maximizeMysqlCompatibility +
'}';
}
}
13 changes: 13 additions & 0 deletions src/main/java/org/mariadb/jdbc/internal/common/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWIS
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.TimeZone;
import java.util.concurrent.locks.ReentrantReadWriteLock;


Expand Down Expand Up @@ -517,4 +518,16 @@ enum LexState {
EOLComment, /* # comment, or // comment, or -- comment */
Backtick /* found backtick */
}

public static TimeZone getTimeZone(String id) throws SQLException {
TimeZone tz = java.util.TimeZone.getTimeZone(id);

// Validate the timezone ID. JDK maps invalid timezones to GMT
if (tz.getID().equals("GMT") && !id.equals("GMT")) {
throw new SQLException("invalid timezone id '" + id + "'");
}
return tz;
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ public interface ValueObject {
public static final int TINYINT1_IS_BIT = 1;
public static final int YEAR_IS_DATE_TYPE = 2;

String getString(Calendar cal);

String getString();

long getLong();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -403,20 +403,19 @@ public PacketOutputStream writeTimestampLength(final Calendar calendar, Timestam
return this;
}

public PacketOutputStream writeDateLength(final Date date) {
public PacketOutputStream writeDateLength(final Calendar calendar) {
assureBufferCapacity(8);
buffer.put((byte) 7);//length
String dt = date.toString(); //"yyyy-mm-dd"
buffer.putShort(Short.parseShort(dt.substring(0, 4)));
buffer.put(Byte.parseByte(dt.substring(5, 7)));
buffer.put(Byte.parseByte(dt.substring(8, 10)));
buffer.putShort((short) calendar.get(Calendar.YEAR));
buffer.put((byte) ((calendar.get(Calendar.MONTH) + 1) & 0xff));
buffer.put((byte) (calendar.get(Calendar.DAY_OF_MONTH) & 0xff));
buffer.put((byte) 0);
buffer.put((byte) 0);
buffer.put((byte) 0);
return this;
}

public PacketOutputStream writeTimeLength(final Calendar calendar, final boolean fractionalSeconds) {
public PacketOutputStream writeTimeLength( final Calendar calendar, final boolean fractionalSeconds) {
if (fractionalSeconds) {
assureBufferCapacity(13);
buffer.put((byte) 12);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWIS

package org.mariadb.jdbc.internal.common.query.parameters;

import org.mariadb.jdbc.internal.common.Options;
import org.mariadb.jdbc.internal.common.packet.PacketOutputStream;
import org.mariadb.jdbc.internal.mysql.MySQLType;

Expand All @@ -63,28 +64,40 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWIS

public class DateParameter extends NotLongDataParameterHolder {
Date date;
Calendar calendar;
Options options;

/**
* Represents a timestamp, constructed with time in millis since epoch
*
* Represents a date, constructed with time in millis since epoch
* @param date the date
* @param cal the calendar to use for timezone
* @param options jdbc options
*/
public DateParameter(Date date) {
public DateParameter(Date date, Calendar cal, Options options) {
this.date = date;
this.calendar = cal;
this.options = options;
}


public void writeTo(OutputStream os) throws IOException {
ParameterWriter.writeDate(os, date);
if (options.useLegacyDatetimeCode || options.maximizeMysqlCompatibility) {
calendar = Calendar.getInstance();
}
calendar.setTimeInMillis(date.getTime());
ParameterWriter.writeDate(os, calendar);
}

/**
* java.sql.Date has no timeZone, but calendar has.
* so Date timemillis must be convert into calendar timeZone (UTC) to have the good date.
* @param writeBuffer
*/
public void writeBinary(PacketOutputStream writeBuffer) {
writeBuffer.writeDateLength(date);
if (options.useLegacyDatetimeCode || options.maximizeMysqlCompatibility) {

}
calendar = Calendar.getInstance();
calendar.setTimeInMillis(date.getTime());
writeBuffer.writeDateLength(calendar);
}

public void writeToLittleEndian(final OutputStream os) throws IOException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,9 +149,11 @@ public static void write(OutputStream out, BigDecimal bd) throws IOException {
out.write(bd.toPlainString().getBytes());
}

public static void writeDate(OutputStream out, java.sql.Date date) throws IOException {
public static void writeDate(OutputStream out, Calendar calendar) throws IOException {
out.write(QUOTE);
out.write(date.toString().getBytes());
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String dateString = sdf.format(calendar.getTime());
out.write(dateString.getBytes());
out.write(QUOTE);
}

Expand Down Expand Up @@ -191,6 +193,7 @@ public static void writeTime(OutputStream out, Time time, Calendar calendar, boo
sdf.setCalendar(calendar);
}
String dateString = sdf.format(time);
if (time.getTime() < 0) dateString="-"+dateString;
out.write(dateString.getBytes());
int microseconds = (int) (time.getTime() % 1000) * 1000;
formatMicroseconds(out, microseconds, writeFractionalSeconds);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWIS
package org.mariadb.jdbc.internal.common.query.parameters;


import org.mariadb.jdbc.internal.common.Options;
import org.mariadb.jdbc.internal.common.packet.PacketOutputStream;
import org.mariadb.jdbc.internal.mysql.MySQLType;

Expand All @@ -64,19 +65,23 @@ public class TimeParameter extends NotLongDataParameterHolder {
Time time;
Calendar calendar;
boolean fractionalSeconds;
Options options;

public TimeParameter(Time time, Calendar cal, boolean fractionalSeconds) {
public TimeParameter(Time time, Calendar cal, boolean fractionalSeconds, Options options) {
this.time = time;
this.calendar = cal;
this.fractionalSeconds = fractionalSeconds;
this.options = options;
}

public void writeTo(final OutputStream os) throws IOException {
ParameterWriter.writeTime(os, time, calendar, fractionalSeconds);
}

public void writeBinary(PacketOutputStream writeBuffer) {
calendar = Calendar.getInstance();
calendar.setTime(time);
calendar.set(Calendar.DAY_OF_MONTH, 1);
writeBuffer.writeTimeLength(calendar, fractionalSeconds);
}

Expand Down
Loading

0 comments on commit 2619ff5

Please sign in to comment.