Skip to content
Permalink
Browse files

[CONJ-719] LocalTime fractional second implementation

  • Loading branch information...
rusher committed Jul 24, 2019
1 parent 384ea70 commit ca1076c4146492a22d629dfa4967ff121209e0ed
@@ -84,6 +84,7 @@
import java.util.Calendar;
import java.util.TimeZone;
import org.mariadb.jdbc.internal.ColumnType;
import org.mariadb.jdbc.internal.com.send.parameters.LocalTimeParameter;
import org.mariadb.jdbc.internal.com.send.parameters.BigDecimalParameter;
import org.mariadb.jdbc.internal.com.send.parameters.ByteArrayParameter;
import org.mariadb.jdbc.internal.com.send.parameters.ByteParameter;
@@ -1052,7 +1053,7 @@ public void setObject(final int parameterIndex, final Object obj) throws SQLExce
useFractionalSeconds,
options));
} else if (obj instanceof LocalTime) {
setTime(parameterIndex, Time.valueOf((LocalTime) obj));
setParameter(parameterIndex, new LocalTimeParameter((LocalTime) obj, useFractionalSeconds));
} else {
//fallback to sending serialized object
setParameter(parameterIndex, new SerializableParameter(obj, noBackslashEscapes));
@@ -1274,7 +1275,7 @@ private void setInternalObject(final int parameterIndex, final Object obj,
useFractionalSeconds,
options));
} else if (obj instanceof LocalTime) {
setTime(parameterIndex, Time.valueOf((LocalTime) obj));
setParameter(parameterIndex, new LocalTimeParameter((LocalTime) obj, useFractionalSeconds));
} else {
throw ExceptionMapper.getSqlException(
"Could not set parameter in setObject, could not convert: " + obj.getClass() + " to "
@@ -0,0 +1,125 @@
/*
*
* MariaDB Client for Java
*
* Copyright (c) 2012-2014 Monty Program Ab.
* Copyright (c) 2015-2018 MariaDB Ab.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with this library; if not, write to Monty Program Ab info@montyprogram.com.
*
*
*/


package org.mariadb.jdbc.internal.com.send.parameters;

import org.mariadb.jdbc.internal.ColumnType;
import org.mariadb.jdbc.internal.io.output.PacketOutputStream;

import java.io.IOException;
import java.time.LocalTime;

public class LocalTimeParameter implements Cloneable, ParameterHolder {

private final LocalTime time;
private final boolean fractionalSeconds;

/**
* Constructor.
*
* @param time time to write
* @param fractionalSeconds must fractional seconds be send.
*/
public LocalTimeParameter(LocalTime time, boolean fractionalSeconds) {
this.time = time;
this.fractionalSeconds = fractionalSeconds;
}

/**
* Write Time parameter to outputStream.
*
* @param pos the stream to write to
*/
public void writeTo(final PacketOutputStream pos) throws IOException {
StringBuilder dateString = new StringBuilder(15);
dateString
.append(time.getHour() < 10 ? "0" : "")
.append(time.getHour())
.append(time.getMinute() < 10 ? ":0" : ":")
.append(time.getMinute())
.append(time.getSecond() < 10 ? ":0" : ":")
.append(time.getSecond());
int microseconds = time.getNano() / 1000;
if (microseconds > 0 && fractionalSeconds) {
dateString.append(".");
if (microseconds % 1000 == 0) {
dateString.append(Integer.toString(microseconds / 1000 + 1000).substring(1));
} else {
dateString.append(Integer.toString(microseconds + 1000000).substring(1));
}
}

pos.write(QUOTE);
pos.write(dateString.toString().getBytes());
pos.write(QUOTE);
}

public long getApproximateTextProtocolLength() {
return 15;
}

/**
* Write data to socket in binary format.
*
* @param pos socket output stream
* @throws IOException if socket error occur
*/

public void writeBinary(final PacketOutputStream pos) throws IOException {
int nano = time.getNano();
if (fractionalSeconds && nano > 0) {
pos.write((byte) 12);
pos.write((byte) 0);
pos.writeInt(0);
pos.write((byte) time.getHour());
pos.write((byte) time.getMinute());
pos.write((byte) time.getSecond());
pos.writeInt(nano / 1000);
} else {
pos.write((byte) 8);//length
pos.write((byte) 0);
pos.writeInt(0);
pos.write((byte) time.getHour());
pos.write((byte) time.getMinute());
pos.write((byte) time.getSecond());
}
}

public ColumnType getColumnType() {
return ColumnType.TIME;
}

@Override
public String toString() {
return time.toString();
}

public boolean isNullData() {
return false;
}

public boolean isLongData() {
return false;
}
}
@@ -0,0 +1,180 @@
package org.mariadb.jdbc;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import org.junit.Test;

import java.sql.*;
import java.time.*;

public class LocalTimeTest extends BaseTest {

@Test
public void LocalTimeTest() throws SQLException {
Statement stmt = sharedConnection.createStatement();
stmt.execute("CREATE TEMPORARY TABLE LocalTimeTest(val TIME(6), val2 TIME)");
try (PreparedStatement prep = sharedConnection.prepareStatement("INSERT INTO LocalTimeTest value (?, ?)")) {
prep.setObject(1, LocalTime.of(1, 2, 3, 123456789));
prep.setObject(2, LocalTime.of(2, 3, 4, 120000000));
prep.execute();

prep.setObject(1, LocalTime.of(15, 14, 13, 12340000));
prep.setObject(2, LocalTime.of(16, 15, 14, 12340000));
prep.execute();

prep.setObject(1, LocalTime.of(5, 4, 3, 0));
prep.setObject(2, LocalTime.of(6, 5, 4, 0));
prep.execute();
}
ResultSet rs = stmt.executeQuery("SELECT * FROM LocalTimeTest");
assertTrue(rs.next());

assertEquals("01:02:03.123456", rs.getString(1));
assertEquals(LocalTime.of(1, 2, 3, 123456000), rs.getObject(1, LocalTime.class));
assertEquals("01:02:03", rs.getTime(1).toString());
assertEquals(Time.valueOf("01:02:03").getTime() + 123 , rs.getTime(1).getTime());

assertEquals("02:03:04", rs.getString(2));
assertEquals(LocalTime.of(2, 3, 4, 0), rs.getObject(2, LocalTime.class));
assertEquals(Time.valueOf("02:03:04"), rs.getTime(2));
assertEquals(Time.valueOf("02:03:04").getTime() , rs.getTime(2).getTime());

assertTrue(rs.next());

assertEquals("15:14:13.012340", rs.getString(1));
assertEquals(LocalTime.of(15, 14, 13, 12340000), rs.getObject(1, LocalTime.class));
assertEquals(Time.valueOf("15:14:13").toString(), rs.getTime(1).toString());
assertEquals(Time.valueOf("15:14:13").getTime() + 12, rs.getTime(1).getTime());

assertEquals("16:15:14", rs.getString(2));
assertEquals(LocalTime.of(16, 15, 14, 0), rs.getObject(2, LocalTime.class));
assertEquals(Time.valueOf("16:15:14").toString(), rs.getTime(2).toString());
assertEquals(Time.valueOf("16:15:14").getTime(), rs.getTime(2).getTime());

assertTrue(rs.next());

assertEquals("05:04:03.000000", rs.getString(1));
assertEquals(LocalTime.of(5, 4, 3, 0), rs.getObject(1, LocalTime.class));
assertEquals(Time.valueOf("05:04:03").toString(), rs.getTime(1).toString());
assertEquals(Time.valueOf("05:04:03").getTime(), rs.getTime(1).getTime());

assertEquals("06:05:04", rs.getString(2));
assertEquals(LocalTime.of(6, 5, 4, 0), rs.getObject(2, LocalTime.class));
assertEquals(Time.valueOf("06:05:04").toString(), rs.getTime(2).toString());
assertEquals(Time.valueOf("06:05:04").getTime(), rs.getTime(2).getTime());

assertFalse(rs.next());
}


@Test
public void LocalDateTest() throws SQLException {
Statement stmt = sharedConnection.createStatement();
stmt.execute("CREATE TEMPORARY TABLE LocalDateTest(val DATE)");
try (PreparedStatement prep = sharedConnection.prepareStatement("INSERT INTO LocalDateTest value (?)")) {
prep.setObject(1, LocalDate.of(2000, 12, 31));
prep.execute();
prep.setObject(1, LocalDate.of(1000, 1, 1));
prep.execute();
prep.setObject(1, LocalDate.of(9999, 1, 31));
prep.execute();
}
ResultSet rs = stmt.executeQuery("SELECT * FROM LocalDateTest");
assertTrue(rs.next());

assertEquals("2000-12-31", rs.getString(1));
assertEquals(LocalDate.of(2000, 12, 31), rs.getObject(1, LocalDate.class));

assertTrue(rs.next());
assertEquals("1000-01-01", rs.getString(1));
assertEquals(LocalDate.of(1000, 1, 1), rs.getObject(1, LocalDate.class));

assertTrue(rs.next());
assertEquals("9999-01-31", rs.getString(1));
assertEquals(LocalDate.of(9999, 1, 31), rs.getObject(1, LocalDate.class));
assertFalse(rs.next());
}

@Test
public void LocalDateTimeTest() throws SQLException {
Statement stmt = sharedConnection.createStatement();
stmt.execute("CREATE TEMPORARY TABLE LocalDateTimeTest(val DATETIME(6), val2 DATETIME)");
try (PreparedStatement prep = sharedConnection.prepareStatement("INSERT INTO LocalDateTimeTest value (?, ?)")) {
prep.setObject(1, LocalDateTime.of(2000, 12, 31,1, 2, 3, 123456789));
prep.setObject(2, LocalDateTime.of(2000, 12, 31,2, 3, 4, 120000000));
prep.execute();

prep.setObject(1, LocalDateTime.of(1000, 1, 1,15, 14, 13, 12340000));
prep.setObject(2, LocalDateTime.of(1000, 1, 1,16, 15, 14, 12340000));
prep.execute();

prep.setObject(1, LocalDateTime.of(9999, 12, 31,5, 4, 3, 0));
prep.setObject(2, LocalDateTime.of(9999, 12, 31,6, 5, 4, 0));
prep.execute();
}
ResultSet rs = stmt.executeQuery("SELECT * FROM LocalDateTimeTest");
assertTrue(rs.next());

assertEquals("2000-12-31 01:02:03.123456", rs.getString(1));
assertEquals(LocalDateTime.of(2000, 12, 31,1, 2, 3, 123456000), rs.getObject(1, LocalDateTime.class));
assertEquals("2000-12-31 01:02:03.123456", rs.getTimestamp(1).toString());
assertEquals(Timestamp.valueOf("2000-12-31 01:02:03").getTime() + 123 , rs.getTimestamp(1).getTime());
assertEquals(LocalTime.of(1, 2, 3, 123456000), rs.getObject(1, LocalTime.class));
assertEquals("01:02:03", rs.getTime(1).toString());
assertEquals(Timestamp.valueOf("2000-12-31 01:02:03").getTime() + 123 , rs.getTime(1).getTime());
assertEquals(LocalDate.of(2000, 12, 31), rs.getObject(1, LocalDate.class));

assertEquals("2000-12-31 02:03:04.0", rs.getString(2));
assertEquals(LocalDateTime.of(2000, 12, 31,2, 3, 4, 0), rs.getObject(2, LocalDateTime.class));
assertEquals(Timestamp.valueOf("2000-12-31 02:03:04"), rs.getTimestamp(2));
assertEquals(Timestamp.valueOf("2000-12-31 02:03:04").getTime() , rs.getTimestamp(2).getTime());
assertEquals(LocalTime.of(2, 3, 4, 0), rs.getObject(2, LocalTime.class));
assertEquals(Time.valueOf("02:03:04").toString(), rs.getTime(2).toString());
assertEquals(Timestamp.valueOf("2000-12-31 02:03:04").getTime() , rs.getTime(2).getTime());
assertEquals(LocalDate.of(2000, 12, 31), rs.getObject(2, LocalDate.class));

assertTrue(rs.next());

assertEquals("1000-01-01 15:14:13.01234", rs.getString(1));
assertEquals(LocalDateTime.of(1000, 1, 1,15, 14, 13, 12340000), rs.getObject(1, LocalDateTime.class));
assertEquals(Timestamp.valueOf("1000-01-01 15:14:13.01234").toString(), rs.getTimestamp(1).toString());
assertEquals(Timestamp.valueOf("1000-01-01 15:14:13").getTime() + 12, rs.getTimestamp(1).getTime());
assertEquals(LocalTime.of(15, 14, 13, 12340000), rs.getObject(1, LocalTime.class));
assertEquals(Time.valueOf("15:14:13").toString(), rs.getTime(1).toString());
assertEquals(Timestamp.valueOf("1000-01-01 15:14:13.01234").getTime(), rs.getTime(1).getTime());
assertEquals(LocalDate.of(1000, 1, 1), rs.getObject(1, LocalDate.class));

assertEquals("1000-01-01 16:15:14.0", rs.getString(2));
assertEquals(LocalDateTime.of(1000, 1, 1,16, 15, 14, 0), rs.getObject(2, LocalDateTime.class));
assertEquals(Timestamp.valueOf("1000-01-01 16:15:14").toString(), rs.getTimestamp(2).toString());
assertEquals(Timestamp.valueOf("1000-01-01 16:15:14").getTime(), rs.getTimestamp(2).getTime());
assertEquals(LocalTime.of(16, 15, 14, 0), rs.getObject(2, LocalTime.class));
assertEquals(Time.valueOf("16:15:14").toString(), rs.getTime(2).toString());
assertEquals(Timestamp.valueOf("1000-01-01 16:15:14").getTime(), rs.getTime(2).getTime());
assertEquals(LocalDate.of(1000, 1, 1), rs.getObject(2, LocalDate.class));

assertTrue(rs.next());

assertEquals("9999-12-31 05:04:03.0", rs.getString(1));
assertEquals(LocalDateTime.of(9999, 12, 31, 5, 4, 3, 0), rs.getObject(1, LocalDateTime.class));
assertEquals(Timestamp.valueOf("9999-12-31 05:04:03").toString(), rs.getTimestamp(1).toString());
assertEquals(Timestamp.valueOf("9999-12-31 05:04:03").getTime(), rs.getTimestamp(1).getTime());
assertEquals(LocalTime.of(5, 4, 3, 0), rs.getObject(1, LocalTime.class));
assertEquals(Time.valueOf("05:04:03").toString(), rs.getTime(1).toString());
assertEquals(Timestamp.valueOf("9999-12-31 05:04:03").getTime(), rs.getTime(1).getTime());
assertEquals(LocalDate.of(9999, 12, 31), rs.getObject(1, LocalDate.class));

assertEquals("9999-12-31 06:05:04.0", rs.getString(2));
assertEquals(LocalDateTime.of(9999, 12, 31, 6, 5, 4, 0), rs.getObject(2, LocalDateTime.class));
assertEquals(Timestamp.valueOf("9999-12-31 06:05:04").toString(), rs.getTimestamp(2).toString());
assertEquals(Timestamp.valueOf("9999-12-31 06:05:04").getTime(), rs.getTimestamp(2).getTime());
assertEquals(LocalTime.of(6, 5, 4, 0), rs.getObject(2, LocalTime.class));
assertEquals(Time.valueOf("06:05:04").toString(), rs.getTime(2).toString());
assertEquals(Timestamp.valueOf("9999-12-31 06:05:04").getTime(), rs.getTime(2).getTime());
assertEquals(LocalDate.of(9999, 12, 31), rs.getObject(1, LocalDate.class));

assertFalse(rs.next());
}
}

0 comments on commit ca1076c

Please sign in to comment.
You can’t perform that action at this time.