Changeset: b98a0fee73f3 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=b98a0fee73f3
Modified Files:
        java/src/nl/cwi/monetdb/jdbc/MonetConnection.java
Branch: default
Log Message:

Merge with Apr2011 branch.


diffs (truncated from 701 to 300 lines):

diff --git a/java/ChangeLog.Apr2011 b/java/ChangeLog.Apr2011
--- a/java/ChangeLog.Apr2011
+++ b/java/ChangeLog.Apr2011
@@ -1,3 +1,8 @@
 # ChangeLog file for java
 # This file is updated with Maddlog
 
+* Wed May 11 2011 Fabian Groffen <fab...@cwi.nl>
+- Insertion via PreparedStatement and retrieval via ResultSet of timestamp
+  and time fields with and without timezones was improved to better
+  respect timezones, as partly indicated in bug #2781.
+
diff --git a/java/Makefile.ag b/java/Makefile.ag
--- a/java/Makefile.ag
+++ b/java/Makefile.ag
@@ -27,7 +27,7 @@
 ant_distjdbc = {
        COND = HAVE_JAVAJDBC
        DIR = datadir/monetdb/lib
-       FILES = monetdb-1.6-mcl.jar monetdb-1.19-jdbc.jar jdbcclient.jar
+       FILES = monetdb-1.6-mcl.jar monetdb-1.20-jdbc.jar jdbcclient.jar
 }
 
 ant_distmerocontrol = {
diff --git a/java/build.properties b/java/build.properties
--- a/java/build.properties
+++ b/java/build.properties
@@ -19,7 +19,7 @@
 # major release number
 JDBC_MAJOR=1
 # minor release number
-JDBC_MINOR=19
+JDBC_MINOR=20
 # an additional identifying string
 JDBC_VER_SUFFIX=Magnistipula
 # the default port to connect on, if no port given when using SQL
diff --git a/java/release.txt b/java/release.txt
--- a/java/release.txt
+++ b/java/release.txt
@@ -1,8 +1,8 @@
 RELEASE NOTES
-MonetDB JDBC driver version 1.19 (Magnistipula/MCL-1.6)
+MonetDB JDBC driver version 1.20 (Magnistipula/MCL-1.6)
 Fabian Groffen <fabian.grof...@cwi.nl>
 
-Release date: 2011-04-05
+Release date: 2011-05-11
 
 
 This JDBC driver is designed for use with MonetDB, a main-memory
diff --git a/java/src/nl/cwi/monetdb/jdbc/MonetConnection.java 
b/java/src/nl/cwi/monetdb/jdbc/MonetConnection.java
--- a/java/src/nl/cwi/monetdb/jdbc/MonetConnection.java
+++ b/java/src/nl/cwi/monetdb/jdbc/MonetConnection.java
@@ -252,7 +252,8 @@
                        setAutoCommit(true);
                        // set our time zone on the server
                        Calendar cal = Calendar.getInstance();
-                       int offset = (cal.get(Calendar.ZONE_OFFSET) + 
cal.get(Calendar.DST_OFFSET)) / (60 * 1000);
+                       int offset = cal.get(Calendar.ZONE_OFFSET) + 
cal.get(Calendar.DST_OFFSET);
+                       offset /= (60 * 1000); // milliseconds to minutes
                        String tz = offset < 0 ? "-" : "+";
                        tz += (Math.abs(offset) / 60 < 10 ? "0" : "") + 
(Math.abs(offset) / 60) + ":";
                        offset -= (offset / 60) * 60;
diff --git a/java/src/nl/cwi/monetdb/jdbc/MonetPreparedStatement.java 
b/java/src/nl/cwi/monetdb/jdbc/MonetPreparedStatement.java
--- a/java/src/nl/cwi/monetdb/jdbc/MonetPreparedStatement.java
+++ b/java/src/nl/cwi/monetdb/jdbc/MonetPreparedStatement.java
@@ -69,10 +69,16 @@
        /** Format of a timestamp with RFC822 time zone */
        final SimpleDateFormat mTimestampZ =
                new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSZ");
+       /** Format of a timestamp */
+       final SimpleDateFormat mTimestamp =
+               new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
        /** Format of a time with RFC822 time zone */
        final SimpleDateFormat mTimeZ =
                new SimpleDateFormat("HH:mm:ss.SSSZ");
-       /** Format of a date used by Mserver */
+       /** Format of a time */
+       final SimpleDateFormat mTime =
+               new SimpleDateFormat("HH:mm:ss.SSS");
+       /** Format of a date used by mserver */
        final SimpleDateFormat mDate =
                new SimpleDateFormat("yyyy-MM-dd");
 
@@ -652,7 +658,7 @@
        public void setDate(int parameterIndex, java.sql.Date x)
                throws SQLException
        {
-               setValue(parameterIndex, "date '" + x.toString() + "'");
+               setDate(parameterIndex, x, null);
        }
 
        /**
@@ -672,8 +678,12 @@
        public void setDate(int parameterIndex, java.sql.Date x, Calendar cal)
                throws SQLException
        {
-               mDate.setTimeZone(cal.getTimeZone());
-               setValue(parameterIndex, "date '" + mDate.format(x) + "'");
+               if (cal == null) {
+                       setValue(parameterIndex, "date '" + x.toString() + "'");
+               } else {
+                       mDate.setTimeZone(cal.getTimeZone());
+                       setValue(parameterIndex, "date '" + mDate.format(x) + 
"'");
+               }
        }
 
        /**
@@ -1208,10 +1218,7 @@
         * @throws SQLException if a database access error occurs
         */
        public void setTime(int index, Time x) throws SQLException {
-               if (index < 1 || index > size)
-                       throw new SQLException("No such parameter with index: " 
+ index);
-
-               setValue(index, monetdbType[index - 1] + " '" + x.toString() + 
"'");
+               setTime(index, x, null);
        }
 
        /**
@@ -1235,11 +1242,25 @@
                if (index < 1 || index > size)
                        throw new SQLException("No such parameter with index: " 
+ index);
 
-               mTimeZ.setTimeZone(cal.getTimeZone());
-
-               String RFC822 = mTimeZ.format(x);
-               setValue(index, monetdbType[index - 1] + " '" +
-                               RFC822.substring(0, 15) + ":" + 
RFC822.substring(15) + "'");
+               boolean hasTimeZone = monetdbType[index - 1].endsWith("tz");
+               if (hasTimeZone) {
+                       // timezone shouldn't matter, since the server is 
timezone
+                       // aware in this case
+                       String RFC822 = mTimeZ.format(x);
+                       setValue(index, "timetz '" +
+                                       RFC822.substring(0, 15) + ":" + 
RFC822.substring(15) + "'");
+               } else {
+                       // server is not timezone aware for this field, and no
+                       // calendar given, since we told the server our 
timezone at
+                       // connection creation, we can just write a plain 
timestamp
+                       // here
+                       if (cal == null) {
+                               setValue(index, "time '" + x.toString() + "'");
+                       } else {
+                               mTime.setTimeZone(cal.getTimeZone());
+                               setValue(index, "time '" + mTime.format(x) + 
"'");
+                       }
+               }
        }
 
        /**
@@ -1254,10 +1275,7 @@
        public void setTimestamp(int index, Timestamp x)
                throws SQLException
        {
-               if (index < 1 || index > size)
-                       throw new SQLException("No such parameter with index: " 
+ index);
-
-               setValue(index, monetdbType[index - 1] + " '" + x.toString() + 
"'");
+               setTimestamp(index, x, null);
        }
 
     /**
@@ -1282,11 +1300,25 @@
                if (index < 1 || index > size)
                        throw new SQLException("No such parameter with index: " 
+ index);
 
-               if (cal == null) cal = Calendar.getInstance();
-               mTimestampZ.setTimeZone(cal.getTimeZone());
-               String RFC822 = mTimestampZ.format(x);
-               setValue(index, monetdbType[index - 1] + " '" +
-                               RFC822.substring(0, 26) + ":" + 
RFC822.substring(26) + "'");
+               boolean hasTimeZone = monetdbType[index - 1].endsWith("tz");
+               if (hasTimeZone) {
+                       // timezone shouldn't matter, since the server is 
timezone
+                       // aware in this case
+                       String RFC822 = mTimestampZ.format(x);
+                       setValue(index, "timestamptz '" +
+                                       RFC822.substring(0, 26) + ":" + 
RFC822.substring(26) + "'");
+               } else {
+                       // server is not timezone aware for this field, and no
+                       // calendar given, since we told the server our 
timezone at
+                       // connection creation, we can just write a plain 
timestamp
+                       // here
+                       if (cal == null) {
+                               setValue(index, "timestamp '" + x.toString() + 
"'");
+                       } else {
+                               mTimestamp.setTimeZone(cal.getTimeZone());
+                               setValue(index, "timestamp '" + 
mTimestamp.format(x) + "'");
+                       }
+               }
        }
 
        /**
diff --git a/java/src/nl/cwi/monetdb/jdbc/MonetResultSet.java 
b/java/src/nl/cwi/monetdb/jdbc/MonetResultSet.java
--- a/java/src/nl/cwi/monetdb/jdbc/MonetResultSet.java
+++ b/java/src/nl/cwi/monetdb/jdbc/MonetResultSet.java
@@ -24,6 +24,7 @@
 import java.util.*;
 import java.math.*;
 import java.net.*;
+import java.text.*;
 import nl.cwi.monetdb.mcl.parser.*;
 
 /**
@@ -1587,6 +1588,12 @@
        }
 
        // This behaviour is according table B-6 of Sun JDBC Specification 3.0
+       private static SimpleDateFormat ts =
+               new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+       private static SimpleDateFormat t =
+               new SimpleDateFormat("HH:mm:ss");
+       private static SimpleDateFormat d =
+               new SimpleDateFormat("yyyy-MM-dd");
        /**
         * Helper method which parses the date/time value for columns of type
         * TIME, DATE and TIMESTAMP.  For the types CHAR, VARCHAR and
@@ -1612,12 +1619,12 @@
                if (col <= 0) throw
                        new IllegalArgumentException("No valid column number 
given!");
 
-               String monetDate;
-               if ((monetDate = getString(col)) == null) return(-1);
-               char[] monDate = monetDate.toCharArray();
-               int pos = 0;
-               int tmp;
+               String monetDate = getString(col);
+               if (monetDate == null)
+                       return(-1);
+
                int nanos = 0;
+               TimeZone ptz = cal.getTimeZone();
 
                // If we got a string type, set the datatype to the given
                // type so we attempt to parse it as the caller thinks it is.
@@ -1629,118 +1636,90 @@
                        dataType = type;
                }
 
-               // we want to start from scratch
-               cal.clear();
+               // we know whether we have a time with or without
+               // time zone if the monet type ends with "tz"
+               boolean hasTimeZone = types[col - 1].endsWith("tz");
 
-               try {
-                       switch(dataType) {
-                               default:
-                                       throw new 
MCLParseException("unsupported data type", 0);
+               // it is important to parse the time in the given timezone in
+               // order to get a correct (UTC) time value, hence we need to
+               // parse it first
+               if (hasTimeZone) {
+                       // MonetDB/SQL99:  Sign TwoDigitHours : Minutes
+                       ptz = TimeZone.getTimeZone("GMT" +
+                                       monetDate.substring(
+                                               monetDate.length() - 6,
+                                               monetDate.length()));
+               }
+               ts.setTimeZone(ptz);
+               t.setTimeZone(ptz);
+               d.setTimeZone(ptz);
 
-                               case Types.DATE:
-                               case Types.TIMESTAMP:
-                                       // parse the date YYYY-MM-DD if we have 
enough chars
-                                       if (monDate.length - pos < 10) break;
-                                       // year
-                                       tmp = 0;
-                                       tmp += getIntrinsicValue(monDate[pos], 
pos++) * 1000;
-                                       tmp += getIntrinsicValue(monDate[pos], 
pos++) * 100;
-                                       tmp += getIntrinsicValue(monDate[pos], 
pos++) * 10;
-                                       tmp += getIntrinsicValue(monDate[pos], 
pos++);
-                                       cal.set(Calendar.YEAR, tmp);
-                                       if (monDate[pos++] != '-') throw
-                                               new MCLParseException("expected 
'-'", pos - 1);
-                                       // month
-                                       tmp = 0;
-                                       tmp += getIntrinsicValue(monDate[pos], 
pos++) * 10;
-                                       tmp += getIntrinsicValue(monDate[pos], 
pos++);
-                                       cal.set(Calendar.MONTH, tmp - 1);
-                                       if (monDate[pos++] != '-') throw
-                                               new MCLParseException("expected 
'-'", pos - 1);
-                                       // day of month
-                                       tmp = 0;
-                                       tmp += getIntrinsicValue(monDate[pos], 
pos++) * 10;
-                                       tmp += getIntrinsicValue(monDate[pos], 
pos++);
-                                       cal.set(Calendar.DAY_OF_MONTH, tmp);
-
-                                       if (dataType == Types.DATE || pos++ == 
monDate.length)
-                                               break;
-                               case Types.TIME:
-                                       // parse the time HH:mm:ss.SSSSSSSS if 
we have enough chars
-                                       if (monDate.length - pos < 8) break;
-                                       // hour of day
-                                       tmp = 0;
-                                       tmp += getIntrinsicValue(monDate[pos], 
pos++) * 10;
-                                       tmp += getIntrinsicValue(monDate[pos], 
pos++);
-                                       cal.set(Calendar.HOUR_OF_DAY, tmp);
_______________________________________________
Checkin-list mailing list
Checkin-list@monetdb.org
http://mail.monetdb.org/mailman/listinfo/checkin-list

Reply via email to