Return-Path: Delivered-To: apmail-db-derby-commits-archive@www.apache.org Received: (qmail 77406 invoked from network); 15 Apr 2010 16:27:12 -0000 Received: from unknown (HELO mail.apache.org) (140.211.11.3) by 140.211.11.9 with SMTP; 15 Apr 2010 16:27:12 -0000 Received: (qmail 78001 invoked by uid 500); 15 Apr 2010 16:27:12 -0000 Delivered-To: apmail-db-derby-commits-archive@db.apache.org Received: (qmail 77955 invoked by uid 500); 15 Apr 2010 16:27:11 -0000 Mailing-List: contact derby-commits-help@db.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: List-Post: Reply-To: "Derby Development" List-Id: Delivered-To: mailing list derby-commits@db.apache.org Received: (qmail 77948 invoked by uid 99); 15 Apr 2010 16:27:11 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 15 Apr 2010 16:27:11 +0000 X-ASF-Spam-Status: No, hits=-1420.1 required=10.0 tests=ALL_TRUSTED,AWL X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 15 Apr 2010 16:27:09 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 87B15238897A; Thu, 15 Apr 2010 16:26:49 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r934474 - in /db/derby/code/trunk/java: engine/org/apache/derby/impl/jdbc/EmbedCallableStatement.java testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/CallableTest.java Date: Thu, 15 Apr 2010 16:26:49 -0000 To: derby-commits@db.apache.org From: kahatlen@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20100415162649.87B15238897A@eris.apache.org> Author: kahatlen Date: Thu Apr 15 16:26:49 2010 New Revision: 934474 URL: http://svn.apache.org/viewvc?rev=934474&view=rev Log: DERBY-4615: EmbedCallableStatement ignores Calendar in getDate, getTime and getTimestamp Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedCallableStatement.java db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/CallableTest.java Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedCallableStatement.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedCallableStatement.java?rev=934474&r1=934473&r2=934474&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedCallableStatement.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedCallableStatement.java Thu Apr 15 16:26:49 2010 @@ -405,11 +405,12 @@ public abstract class EmbedCallableState * @see CallableStatement#getDate * @exception SQLException NoOutputParameters thrown. */ - public Date getDate(int parameterIndex) throws SQLException + public Date getDate(int parameterIndex, Calendar cal) throws SQLException { checkStatus(); try { - Date v = getParms().getParameterForGet(parameterIndex-1).getDate(getCal()); + Date v = getParms(). + getParameterForGet(parameterIndex-1).getDate(cal); wasNull = (v == null); return v; } catch (StandardException e) @@ -423,11 +424,12 @@ public abstract class EmbedCallableState * @see CallableStatement#getTime * @exception SQLException NoOutputParameters thrown. */ - public Time getTime(int parameterIndex) throws SQLException + public Time getTime(int parameterIndex, Calendar cal) throws SQLException { checkStatus(); try { - Time v = getParms().getParameterForGet(parameterIndex-1).getTime(getCal()); + Time v = getParms(). + getParameterForGet(parameterIndex-1).getTime(cal); wasNull = (v == null); return v; } catch (StandardException e) @@ -441,12 +443,13 @@ public abstract class EmbedCallableState * @see CallableStatement#getTimestamp * @exception SQLException NoOutputParameters thrown. */ - public Timestamp getTimestamp(int parameterIndex) + public Timestamp getTimestamp(int parameterIndex, Calendar cal) throws SQLException { checkStatus(); try { - Timestamp v = getParms().getParameterForGet(parameterIndex-1).getTimestamp(getCal()); + Timestamp v = getParms(). + getParameterForGet(parameterIndex-1).getTimestamp(cal); wasNull = (v == null); return v; } catch (StandardException e) @@ -462,10 +465,10 @@ public abstract class EmbedCallableState * null * @exception SQLException if a database-access error occurs. */ - public java.sql.Date getDate(int parameterIndex, Calendar cal) + public java.sql.Date getDate(int parameterIndex) throws SQLException { - return getDate(parameterIndex); + return getDate(parameterIndex, getCal()); } /** @@ -476,10 +479,10 @@ public abstract class EmbedCallableState * null * @exception SQLException if a database-access error occurs. */ - public java.sql.Time getTime(int parameterIndex, Calendar cal) + public java.sql.Time getTime(int parameterIndex) throws SQLException { - return getTime(parameterIndex); + return getTime(parameterIndex, getCal()); } /** @@ -491,10 +494,10 @@ public abstract class EmbedCallableState * null * @exception SQLException if a database-access error occurs. */ - public java.sql.Timestamp getTimestamp(int parameterIndex, Calendar cal) + public java.sql.Timestamp getTimestamp(int parameterIndex) throws SQLException { - return getTimestamp(parameterIndex); + return getTimestamp(parameterIndex, getCal()); } /** Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/CallableTest.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/CallableTest.java?rev=934474&r1=934473&r2=934474&view=diff ============================================================================== --- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/CallableTest.java (original) +++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/CallableTest.java Thu Apr 15 16:26:49 2010 @@ -26,6 +26,8 @@ import java.sql.Time; import java.sql.Timestamp; import java.util.Arrays; // Used by testUpdateLongBinaryProc +import java.util.Calendar; +import java.util.TimeZone; import java.sql.BatchUpdateException; import java.sql.CallableStatement; @@ -35,10 +37,10 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; +import java.sql.Types; import org.apache.derbyTesting.junit.BaseJDBCTestCase; -import org.apache.derbyTesting.junit.BaseJDBCTestSetup; import org.apache.derbyTesting.junit.CleanDatabaseTestSetup; import org.apache.derbyTesting.junit.JDBC; import org.apache.derbyTesting.junit.TestConfiguration; @@ -384,6 +386,143 @@ public class CallableTest extends BaseJD } /** + * Test that the getters and setters for Date, Time and Timestamp work as + * expected when given a Calendar argument. Test case for DERBY-4615. + */ + public void testTimeAndDateWithCalendar() throws SQLException { + // Create calendars for some time zones to use when testing the + // setter methods. + Calendar[] cal1 = { + Calendar.getInstance(), // local calendar + Calendar.getInstance(TimeZone.getTimeZone("GMT")), + Calendar.getInstance(TimeZone.getTimeZone("Europe/Oslo")), + Calendar.getInstance(TimeZone.getTimeZone("Asia/Hong_Kong")), + }; + + // Use calendars for the same time zones in the getters, but create + // clones so that we don't get interference between the calendars. + Calendar[] cal2 = (Calendar[]) cal1.clone(); + for (int i = 0; i < cal2.length; i++) { + cal2[i] = (Calendar) cal2[i].clone(); + } + + // Now test all the combinations. + for (int i = 0; i < cal1.length; i++) { + for (int j = 0; j < cal2.length; j++) { + testTimeAndDateWithCalendar(cal1[i], cal2[j]); + } + } + } + + /** + * Private helper for {@link #testTimeAndDateWithCalendar()}. This method + * calls a procedure that takes Date, Time and Timestamp arguments and + * returns the exact same values. Call the setters with one calendar and + * the getters with another calendar, and verify that the expected + * conversion between time zones has happened. + * + * @param cal1 the calendar to use for the setter methods + * @param cal2 the calendar to use for the getter methods + */ + private void testTimeAndDateWithCalendar(Calendar cal1, Calendar cal2) + throws SQLException + { + println("Running " + getName() + "() with " + + cal1.getTimeZone().getDisplayName() + " and " + + cal2.getTimeZone().getDisplayName()); + + CallableStatement cs = prepareCall( + "call NON_NUMERIC_TYPES_IN_AND_OUT_PROC(?,?,?,?,?,?,?,?)"); + + Date d = Date.valueOf("2010-04-14"); + Time t = Time.valueOf("12:23:24"); + Timestamp ts = new Timestamp(System.currentTimeMillis()); + ts.setNanos(123456789); + + cs.setDate(1, d, cal1); + cs.setTime(2, t, cal1); + cs.setTimestamp(3, ts, cal1); + cs.setNull(4, Types.VARBINARY); // we don't care about VARBINARY here + + cs.registerOutParameter (5, java.sql.Types.DATE); + cs.registerOutParameter (6, java.sql.Types.TIME); + cs.registerOutParameter (7, java.sql.Types.TIMESTAMP); + cs.registerOutParameter (8, java.sql.Types.VARBINARY); + + cs.execute(); + + assertSameDate(d, cal1, cs.getDate(5, cal2), cal2); + assertSameTime(t, cal1, cs.getTime(6, cal2), cal2); + assertSameTimestamp(ts, cal1, cs.getTimestamp(7, cal2), cal2); + } + + /** + * Assert that two {@code java.util.Date} values have the same + * representation of their date components (year, month and day) in their + * respective time zones. + * + * @param expected the expected date + * @param cal1 a calendar representing the time zone of the expected date + * @param actual the actual date + * @param cal2 a calendar representing the time zone of the actual date + */ + private void assertSameDate(java.util.Date expected, Calendar cal1, + java.util.Date actual, Calendar cal2) { + cal1.clear(); + cal1.setTime(expected); + int expectedYear = cal1.get(Calendar.YEAR); + int expectedMonth = cal1.get(Calendar.MONTH); + int expectedDay = cal1.get(Calendar.DAY_OF_MONTH); + + cal2.clear(); + cal2.setTime(actual); + assertEquals("year", expectedYear, cal2.get(Calendar.YEAR)); + assertEquals("month", expectedMonth, cal2.get(Calendar.MONTH)); + assertEquals("day", expectedDay, cal2.get(Calendar.DAY_OF_MONTH)); + } + + /** + * Assert that two {@code java.util.Date} values have the same + * representation of their time components (hour, minute, second) in their + * respective time zones. + * + * @param expected the expected time + * @param cal1 a calendar representing the time zone of the expected time + * @param actual the actual time + * @param cal2 a calendar representing the time zone of the actual time + */ + private void assertSameTime(java.util.Date expected, Calendar cal1, + java.util.Date actual, Calendar cal2) { + cal1.clear(); + cal1.setTime(expected); + int expectedHour = cal1.get(Calendar.HOUR_OF_DAY); + int expectedMinute = cal1.get(Calendar.MINUTE); + int expectedSecond = cal1.get(Calendar.SECOND); + + cal2.clear(); + cal2.setTime(actual); + assertEquals("hour", expectedHour, cal2.get(Calendar.HOUR_OF_DAY)); + assertEquals("minute", expectedMinute, cal2.get(Calendar.MINUTE)); + assertEquals("second", expectedSecond, cal2.get(Calendar.SECOND)); + } + + /** + * Assert that two Timestamp values have the same representation in their + * respective time zones. + * + * @param expected the expected time + * @param cal1 a calendar representing the time zone of the expected time + * @param actual the actual time + * @param cal2 a calendar representing the time zone of the actual time + */ + private void assertSameTimestamp(Timestamp expected, Calendar cal1, + Timestamp actual, Calendar cal2) { + assertSameDate(expected, cal1, actual, cal2); + assertSameTime(expected, cal1, actual, cal2); + assertEquals("nanos", expected.getNanos(), actual.getNanos()); + } + + /** * Calls a SQL procedure that takes INOUT parameters of various types. * @throws SQLException */