Skip to content

Commit

Permalink
[misc] binary data Time correction
Browse files Browse the repository at this point in the history
  • Loading branch information
rusher committed Feb 20, 2016
1 parent 1036abb commit da00357
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 63 deletions.
22 changes: 6 additions & 16 deletions src/main/java/org/mariadb/jdbc/MariaDbConnection.java
Expand Up @@ -62,7 +62,6 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWIS
import java.util.Properties;
import java.util.concurrent.Executor;
import java.util.concurrent.locks.ReentrantLock;
import java.util.regex.Pattern;


public final class MariaDbConnection implements Connection {
Expand All @@ -71,7 +70,6 @@ public final class MariaDbConnection implements Connection {
* the protocol to communicate with.
*/
private final Protocol protocol;
public Pattern requestWithoutComments = Pattern.compile("((?<![\\\\])['\"])((?:.(?!(?<![\\\\])\\1))*.?)\\1", Pattern.CASE_INSENSITIVE);
public MariaDbPooledConnection pooledConnection;
boolean noBackslashEscapes;
boolean nullCatalogMeansCurrent = true;
Expand Down Expand Up @@ -393,21 +391,13 @@ private boolean checkIfPreparable(String sql) {
if (sql == null) {
return true;
}
if (sql.indexOf("?") == -1) {
return false;
}

String cleanSql = sql.toUpperCase().trim();
if (cleanSql.startsWith("SELECT")
|| cleanSql.startsWith("UPDATE")
|| cleanSql.startsWith("INSERT")
|| cleanSql.startsWith("DELETE")) {

//delete comment to avoid find ? in comment
cleanSql = requestWithoutComments.matcher(cleanSql).replaceAll("");
if (cleanSql.indexOf("?") > 0) {
return true;
}
return false;
if (cleanSql.contains("SELECT")
|| cleanSql.contains("UPDATE")
|| cleanSql.contains("INSERT")
|| cleanSql.contains("DELETE")) {
return true;
}
return false;

Expand Down
Expand Up @@ -101,9 +101,7 @@ private void prepare(String sql) throws SQLException {
connection.lock.unlock();
}
parameterCount = prepareResult.parameters.length;
if (parameterCount > 0) {
currentParameterHolder = new ParameterHolder[prepareResult.parameters.length];
}
currentParameterHolder = new ParameterHolder[prepareResult.parameters.length];
returnTableAlias = protocol.getOptions().useOldAliasMetadataBehavior;
metadata = new MariaDbResultSetMetaData(prepareResult.columns,
protocol.getDataTypeMappingFlags(), returnTableAlias);
Expand Down
Expand Up @@ -258,7 +258,7 @@ private String getTimeString() {
microsecondString = "0" + microsecondString;
}
boolean negative = (rawBytes[0] == 0x01);
return (negative ? "-" : "") + (hourString + ":" + minuteString + ":" + secondString);
return (negative ? "-" : "") + (hourString + ":" + minuteString + ":" + secondString + "." + microsecondString);
}


Expand Down Expand Up @@ -1055,18 +1055,26 @@ private Time binaryTime(Calendar cal) throws ParseException {
default:
Calendar calendar = Calendar.getInstance();
calendar.clear();
if (options.useLegacyDatetimeCode) {
calendar.setLenient(false);
}
int day = 0;
int hour = 0;
int minutes = 0;
int seconds = 0;
boolean negate = false;
if (rawBytes.length > 0) {
negate = (rawBytes[0] & 0xff) == 0x01;
}
if (rawBytes.length > 4) {
day = ((rawBytes[1] & 0xff)
| (rawBytes[2] & 0xff) << 8
| (rawBytes[3] & 0xff) << 16
| (rawBytes[4] & 0xff) << 24);
}
if (rawBytes.length > 7) {
hour = rawBytes[5];
minutes = rawBytes[6];
seconds = rawBytes[7];
}
calendar.set(1970, 0, 1, hour, minutes, seconds);
calendar.set(1970, 0, ((negate ? -1 : 1) * day) + 1, (negate ? -1 : 1) * hour, minutes, seconds);

int nanoseconds = 0;
if (rawBytes.length > 8) {
Expand All @@ -1089,14 +1097,43 @@ private Timestamp binaryTimestamp(Calendar cal) throws ParseException {
}
int year;
int month;
int day;
int day = 0;
int hour = 0;
int minutes = 0;
int seconds = 0;
int microseconds = 0;

if (dataType == MariaDbType.TIME) {
return new Timestamp(getTime(cal).getTime());
Calendar calendar = Calendar.getInstance();
calendar.clear();

boolean negate = false;
if (rawBytes.length > 0) {
negate = (rawBytes[0] & 0xff) == 0x01;
}
if (rawBytes.length > 4) {
day = ((rawBytes[1] & 0xff)
| (rawBytes[2] & 0xff) << 8
| (rawBytes[3] & 0xff) << 16
| (rawBytes[4] & 0xff) << 24);
}
if (rawBytes.length > 7) {
hour = rawBytes[5];
minutes = rawBytes[6];
seconds = rawBytes[7];
}

if (rawBytes.length > 8) {
microseconds = ((rawBytes[8] & 0xff)
| (rawBytes[9] & 0xff) << 8
| (rawBytes[10] & 0xff) << 16
| (rawBytes[11] & 0xff) << 24);
}

calendar.set(1970, 0, ((negate ? -1 : 1) * day) + 1, (negate ? -1 : 1) * hour, minutes, seconds);
Timestamp tt = new Timestamp(calendar.getTimeInMillis());
tt.setNanos(microseconds * 1000);
return tt;
} else {
year = ((rawBytes[0] & 0xff) | (rawBytes[1] & 0xff) << 8);
month = rawBytes[2];
Expand Down
4 changes: 2 additions & 2 deletions src/test/java/org/mariadb/jdbc/CancelTest.java
Expand Up @@ -46,9 +46,9 @@ public void timeoutSleep() throws Exception {
Connection tmpConnection = null;
try {
tmpConnection = openNewConnection(connUri, new Properties());
PreparedStatement stmt = tmpConnection.prepareStatement("select sleep(100)");
Statement stmt = tmpConnection.createStatement();
stmt.setQueryTimeout(1);
stmt.execute();
stmt.execute("select sleep(100)");
} finally {
tmpConnection.close();
}
Expand Down
66 changes: 41 additions & 25 deletions src/test/java/org/mariadb/jdbc/DateTest.java
Expand Up @@ -166,22 +166,20 @@ public void timeTestLegacy() throws SQLException {
setSessionTimeZone(connection, "+05:00");
connection.createStatement().execute("insert into timetest values (null), ('-838:59:59'), ('00:00:00'), "
+ "('838:59:59')");
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery("select * from timetest");
Time[] data = new Time[]{null, Time.valueOf("-838:59:59"), Time.valueOf("00:00:00"),
Time.valueOf("838:59:59")};
int count = 0;
while (rs.next()) {
Time t1 = data[count];
Time t2 = (Time) rs.getObject(1);
assertEquals(t1, t2);
count++;
}
rs.close();
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery("select * from timetest");
testTime(rs, data);

PreparedStatement pstmt = connection.prepareStatement("select * from timetest");
testTime(pstmt.executeQuery(), data);

rs = stmt.executeQuery("select '11:11:11'");
rs.next();
Calendar cal = Calendar.getInstance();
assertEquals(rs.getTime(1, cal).toString(), "11:11:11");
testTime11(rs);

PreparedStatement pstmt2 = connection.prepareStatement("select TIME('11:11:11') ");
testTime11(pstmt2.executeQuery());
} finally {
connection.close();
}
Expand All @@ -194,28 +192,46 @@ public void timeTest() throws SQLException {
connection = setConnection("&useLegacyDatetimeCode=false&serverTimezone=+5:00");
setSessionTimeZone(connection, "+5:00");
connection.createStatement().execute("insert into timetest2 values (null), ('00:00:00'), ('23:59:59')");
Time[] data = new Time[]{null, Time.valueOf("00:00:00"), Time.valueOf("23:59:59")};

Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery("select * from timetest2");
Time[] data = new Time[]{null, Time.valueOf("00:00:00"), Time.valueOf("23:59:59")};
int count = 0;
while (rs.next()) {
Time t1 = data[count];
Time t2 = (Time) rs.getObject(1);
assertEquals(t1, t2);
count++;
}
rs.close();
testTime(rs, data);

PreparedStatement pstmt = connection.prepareStatement("select * from timetest2");
testTime(pstmt.executeQuery(), data);

rs = stmt.executeQuery("select '11:11:11'");
rs.next();
Calendar cal = Calendar.getInstance();
assertEquals(rs.getTime(1, cal).toString(), "11:11:11");
testTime11(rs);

PreparedStatement pstmt2 = connection.prepareStatement("select TIME('11:11:11') ");
testTime11(pstmt2.executeQuery());

} finally {
if (connection != null) {
connection.close();
}
}
}

private void testTime(ResultSet rs, Time[] data) throws SQLException {
int count = 0;
while (rs.next()) {
Time t1 = data[count];
Time t2 = (Time) rs.getObject(1);
assertEquals(t1, t2);
count++;
}
rs.close();
}

private void testTime11(ResultSet rs) throws SQLException {
rs.next();
Calendar cal = Calendar.getInstance();
assertEquals("11:11:11", rs.getTime(1, cal).toString());
rs.close();
}

@Test
public void timestampZeroTest() throws SQLException {
Assume.assumeTrue(isMariadbServer());
Expand Down
21 changes: 11 additions & 10 deletions src/test/java/org/mariadb/jdbc/TimezoneDaylightSavingTimeTest.java
Expand Up @@ -221,7 +221,7 @@ public void testDifferentTime() throws SQLException {
st.executeQuery();
ResultSet rs = st.getResultSet();
rs.next();
assertEquals(rs.getString(1), "90:00:00.123456");
assertEquals("90:00:00.123456", rs.getString(1));
Time tit = rs.getTime(1);
Time tt2 = Time.valueOf("90:00:00");
tt2.setTime(tt2.getTime() + 123);
Expand Down Expand Up @@ -358,15 +358,16 @@ public void testDifferentTimeZoneServer() throws SQLException {

@Test
public void testTimeStampOffsetNowUseServer() throws SQLException {
setConnection("&serverTimezone=Europe/Paris");
//timestamp timezone to parisTimeZone like server
Timestamp currentTimeParis = new Timestamp(System.currentTimeMillis());
PreparedStatement st = sharedConnection.prepareStatement("SELECT NOW()");
ResultSet rs = st.executeQuery();
rs.next();
int offset = parisTimeZone.getOffset(System.currentTimeMillis());
long timeDifference = currentTimeParis.getTime() - offset - rs.getTimestamp(1).getTime();
assertTrue(timeDifference < 1000); // must have less than one second difference
try (Connection connection = setConnection("&serverTimezone=Europe/Paris")) {
//timestamp timezone to parisTimeZone like server
Timestamp currentTimeParis = new Timestamp(System.currentTimeMillis());
PreparedStatement st = connection.prepareStatement("SELECT NOW()");
ResultSet rs = st.executeQuery();
rs.next();
int offset = parisTimeZone.getOffset(System.currentTimeMillis());
long timeDifference = currentTimeParis.getTime() - offset - rs.getTimestamp(1).getTime();
assertTrue(timeDifference < 1000); // must have less than one second difference
}
}

@Test
Expand Down

0 comments on commit da00357

Please sign in to comment.