Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support LocalDateTime and OffsetDateTime in CallableStatement #1393

Merged
merged 9 commits into from Sep 1, 2020
Expand Up @@ -24,6 +24,7 @@
import java.sql.Time;
import java.sql.Timestamp;
import java.text.MessageFormat;
import java.time.LocalDateTime;
import java.util.Calendar;
import java.util.HashMap;
import java.util.TreeMap;
Expand Down Expand Up @@ -740,6 +741,20 @@ public <T> T getObject(int index, Class<T> type) throws SQLException {
returnValue = getTime(index);
} else if (type == java.sql.Timestamp.class) {
returnValue = getTimestamp(index);
} else if (type == java.time.LocalDateTime.class || type == java.time.LocalDate.class
|| type == java.time.LocalTime.class) {
java.time.LocalDateTime ldt = getLocalDateTime(index);
if (null == ldt) {
returnValue = null;
} else {
if (type == java.time.LocalDateTime.class) {
returnValue = ldt;
} else if (type == java.time.LocalDate.class) {
returnValue = ldt.toLocalDate();
} else {
returnValue = ldt.toLocalTime();
}
}
CasualSuperman marked this conversation as resolved.
Show resolved Hide resolved
} else if (type == microsoft.sql.DateTimeOffset.class) {
returnValue = getDateTimeOffset(index);
} else if (type == UUID.class) {
Expand Down Expand Up @@ -893,6 +908,14 @@ public Timestamp getTimestamp(String name, Calendar cal) throws SQLServerExcepti
return value;
}

LocalDateTime getLocalDateTime(int columnIndex) throws SQLServerException {
loggerExternal.entering(getClassNameLogging(), "getLocalDateTime", columnIndex);
checkClosed();
LocalDateTime value = (LocalDateTime) getValue(columnIndex, JDBCType.LOCALDATETIME);
loggerExternal.exiting(getClassNameLogging(), "getLocalDateTime", value);
return value;
}

@Override
public Timestamp getDateTime(int index) throws SQLServerException {
if (loggerExternal.isLoggable(java.util.logging.Level.FINER))
Expand Down
Expand Up @@ -3,13 +3,12 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;
import java.sql.*;
CasualSuperman marked this conversation as resolved.
Show resolved Hide resolved
import java.text.MessageFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.TimeZone;
import java.util.UUID;

import org.junit.jupiter.api.AfterAll;
Expand Down Expand Up @@ -39,6 +38,7 @@ public class CallableStatementTest extends AbstractTest {
private static String outputProcedureNameGUID = RandomUtil.getIdentifier("uniqueidentifier_SP");
private static String setNullProcedureName = RandomUtil.getIdentifier("CallableStatementTest_setNull_SP");
private static String inputParamsProcedureName = RandomUtil.getIdentifier("CallableStatementTest_inputParams_SP");
private static String getObjectLocalDateTimeProcedureName = RandomUtil.getIdentifier("CallableStatementTest_getObjectLocalDateTime_SP");

/**
* Setup before test
Expand All @@ -53,11 +53,13 @@ public static void setupTest() throws SQLException {
TestUtils.dropProcedureIfExists(AbstractSQLGenerator.escapeIdentifier(outputProcedureNameGUID), stmt);
TestUtils.dropProcedureIfExists(AbstractSQLGenerator.escapeIdentifier(setNullProcedureName), stmt);
TestUtils.dropProcedureIfExists(AbstractSQLGenerator.escapeIdentifier(inputParamsProcedureName), stmt);
TestUtils.dropProcedureIfExists(AbstractSQLGenerator.escapeIdentifier(getObjectLocalDateTimeProcedureName), stmt);

createGUIDTable(stmt);
createGUIDStoredProcedure(stmt);
createSetNullProcedure(stmt);
createInputParamsProcedure(stmt);
createGetObjectLocalDateTimeProcedure(stmt);
}
}

Expand Down Expand Up @@ -123,6 +125,45 @@ public void getSetNullWithTypeVarchar() throws SQLException {
}
}


/**
* Tests getObject(n, java.time.LocalDateTime.class).
*
* @throws SQLException
*/
@Test
public void getObjectAsLocalDateTime() throws SQLException {
CasualSuperman marked this conversation as resolved.
Show resolved Hide resolved
String sql = "{CALL " + AbstractSQLGenerator.escapeIdentifier(getObjectLocalDateTimeProcedureName) + " (?)}";
try (Connection con = DriverManager.getConnection(connectionString); CallableStatement cs = con.prepareCall(sql)) {
cs.registerOutParameter(1, Types.TIMESTAMP);
TimeZone prevTimeZone = TimeZone.getDefault();
TimeZone.setDefault(TimeZone.getTimeZone("America/Edmonton"));

// a local date/time that does not actually exist because of Daylight Saving Time
final String testValueDate = "2018-03-11";
final String testValueTime = "02:00:00.1234567";
final String testValueDateTime = testValueDate + "T" + testValueTime;

try {
cs.execute();

LocalDateTime expectedLocalDateTime = LocalDateTime.parse(testValueDateTime);
LocalDateTime actualLocalDateTime = cs.getObject(1, LocalDateTime.class);
assertEquals(expectedLocalDateTime, actualLocalDateTime);

LocalDate expectedLocalDate = LocalDate.parse(testValueDate);
LocalDate actualLocalDate = cs.getObject(1, LocalDate.class);
assertEquals(expectedLocalDate, actualLocalDate);

LocalTime expectedLocalTime = LocalTime.parse(testValueTime);
LocalTime actualLocalTime = cs.getObject(1, LocalTime.class);
assertEquals(expectedLocalTime, actualLocalTime);
} finally {
TimeZone.setDefault(prevTimeZone);
}
}
}

/**
* recognize parameter names with and without leading '@'
*
Expand Down Expand Up @@ -207,4 +248,11 @@ private static void createInputParamsProcedure(Statement stmt) throws SQLExcepti

stmt.execute(sql);
}

private static void createGetObjectLocalDateTimeProcedure(Statement stmt) throws SQLException {
CasualSuperman marked this conversation as resolved.
Show resolved Hide resolved
String sql = "CREATE PROCEDURE " + AbstractSQLGenerator.escapeIdentifier(getObjectLocalDateTimeProcedureName)
+ "(@p1 datetime2(7) OUTPUT) AS "
+ "SELECT @p1 = '2018-03-11T02:00:00.1234567'";
stmt.execute(sql);
}
}