Changeset: 2d6f35cb428f for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=2d6f35cb428f
Added Files:
        java/src/nl/cwi/monetdb/jdbc/types/INET.java
        java/src/nl/cwi/monetdb/jdbc/types/URL.java
        java/tests/Test_PSsqldata.java
        java/tests/Test_Rsqldata.java
Modified Files:
        java/ChangeLog.Oct2012
        java/src/nl/cwi/monetdb/jdbc/MonetConnection.java
        java/src/nl/cwi/monetdb/jdbc/MonetPreparedStatement.java
        java/src/nl/cwi/monetdb/jdbc/MonetResultSet.java
        java/tests/build.xml
Branch: Oct2012
Log Message:

JDBC: implemented Connection's type map support

Custom mapping between server types and Java classes can now be made,
using the SQLData interface for UDTs.  Two tests to deal with INET and
URL types have been added.


diffs (truncated from 881 to 300 lines):

diff --git a/java/ChangeLog.Oct2012 b/java/ChangeLog.Oct2012
--- a/java/ChangeLog.Oct2012
+++ b/java/ChangeLog.Oct2012
@@ -1,6 +1,13 @@
 # ChangeLog file for java
 # This file is updated with Maddlog
 
+* Fri Nov 23 2012 Fabian Groffen <fab...@monetdb.org>
+- Implemented type map support of Connection to allow custom mapping
+  of UDTs to Java classes.  By default the INET and URL UDTs are
+  now mapped to nl.cwi.monetdb.jdbc.types.{INET,URL}.  Most notably,
+  ResultSet.getObject() and PreparedStatement.setObject() deal with the
+  type map.
+
 * Thu Nov 22 2012 Fabian Groffen <fab...@monetdb.org>
 - Fixed a problem in PreparedStatement where the prepared statement's
   ResultSetMetaData (on its columns to be produced) incorrectly threw
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
@@ -52,6 +52,8 @@ import java.util.concurrent.locks.Condit
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
 
+import nl.cwi.monetdb.jdbc.types.INET;
+import nl.cwi.monetdb.jdbc.types.URL;
 import nl.cwi.monetdb.mcl.MCLException;
 import nl.cwi.monetdb.mcl.io.BufferedMCLReader;
 import nl.cwi.monetdb.mcl.io.BufferedMCLWriter;
@@ -114,8 +116,11 @@ public class MonetConnection extends Mon
        /** The stack of warnings for this Connection object */
        private SQLWarning warnings = null;
        /** The Connection specific mapping of user defined types to Java
-        * types (not used) */
-       private Map<String,Class<?>> typeMap = new HashMap<String,Class<?>>();
+        * types */
+       private Map<String,Class<?>> typeMap = new HashMap<String,Class<?>>() {{
+                       put("inet", INET.class);
+                       put("url",  URL.class);
+       }};
 
        // See javadoc for documentation about WeakHashMap if you don't know 
what
        // it does !!!NOW!!! (only when you deal with it of course)
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
@@ -833,7 +833,16 @@ public class MonetPreparedStatement
                         * @throws SQLException if a database access error 
occurs
                         */
                        public String getParameterClassName(int param) throws 
SQLException {
-                               return 
MonetResultSet.getClassForType(javaType[getParamIdx(param)]).getName();
+                               Map map = getConnection().getTypeMap();
+                               Class c;
+                               if 
(map.containsKey(monetdbType[getParamIdx(param)])) {
+                                       c = 
(Class)map.get(monetdbType[getParamIdx(param)]);
+                               } else {
+                                       c = MonetResultSet.getClassForType(
+                                                       
javaType[getParamIdx(param)]
+                                       );
+                               }
+                               return c.getName();
                        }
 
                        /**
@@ -1911,10 +1920,126 @@ public class MonetPreparedStatement
                } else if (x instanceof SQLXML) {
                        throw new SQLFeatureNotSupportedException("Operation 
setObject() with object of type SQLXML currently not supported!", "0A000");
                } else if (x instanceof SQLData) { // not in JDBC4.1???
-                       // do something with:
-                       // ((SQLData)x).writeSQL( [java.sql.SQLOutput] );
-                       // needs an SQLOutput stream... bit too far away from 
reality
-                       throw new SQLFeatureNotSupportedException("Operation 
setObject() with object of type SQLData currently not supported!", "0A000");
+                       SQLData sx = (SQLData)x;
+                       final int paramnr = parameterIndex;
+                       final String sqltype = sx.getSQLTypeName();
+                       SQLOutput out = new SQLOutput() {
+                               public void writeString(String x) throws 
SQLException {
+                                       // special situation, this is when a 
string
+                                       // representation is given, but we need 
to prefix it
+                                       // with the actual sqltype the server 
expects, or we
+                                       // will get an error back
+                                       setValue(
+                                                       paramnr,
+                                                       sqltype + " '" + 
x.replaceAll("\\\\", "\\\\\\\\").replaceAll("'", "\\\\'") + "'"
+                                       );
+                               }
+
+                               public void writeBoolean(boolean x) throws 
SQLException {
+                                       setBoolean(paramnr, x);
+                               }
+
+                               public void writeByte(byte x) throws 
SQLException {
+                                       setByte(paramnr, x);
+                               }
+
+                               public void writeShort(short x) throws 
SQLException {
+                                       setShort(paramnr, x);
+                               }
+
+                               public void writeInt(int x) throws SQLException 
{
+                                       setInt(paramnr, x);
+                               }
+
+                               public void writeLong(long x) throws 
SQLException {
+                                       setLong(paramnr, x);
+                               }
+                               
+                               public void writeFloat(float x) throws 
SQLException {
+                                       setFloat(paramnr, x);
+                               }
+
+                               public void writeDouble(double x) throws 
SQLException {
+                                       setDouble(paramnr, x);
+                               }
+
+                               public void writeBigDecimal(BigDecimal x) 
throws SQLException {
+                                       setBigDecimal(paramnr, x);
+                               }
+
+                               public void writeBytes(byte[] x) throws 
SQLException {
+                                       setBytes(paramnr, x);
+                               }
+
+                               public void writeDate(java.sql.Date x) throws 
SQLException {
+                                       setDate(paramnr, x);
+                               }
+
+                               public void writeTime(java.sql.Time x) throws 
SQLException {
+                                       setTime(paramnr, x);
+                               }
+
+                               public void writeTimestamp(Timestamp x) throws 
SQLException {
+                                       setTimestamp(paramnr, x);
+                               }
+
+                               public void writeCharacterStream(Reader x) 
throws SQLException {
+                                       setCharacterStream(paramnr, x);
+                               }
+
+                               public void writeAsciiStream(InputStream x) 
throws SQLException {
+                                       setAsciiStream(paramnr, x);
+                               }
+
+                               public void writeBinaryStream(InputStream x) 
throws SQLException {
+                                       setBinaryStream(paramnr, x);
+                               }
+
+                               public void writeObject(SQLData x) throws 
SQLException {
+                                       setObject(paramnr, x);
+                               }
+
+                               public void writeRef(Ref x) throws SQLException 
{
+                                       setRef(paramnr, x);
+                               }
+
+                               public void writeBlob(Blob x) throws 
SQLException {
+                                       setBlob(paramnr, x);
+                               }
+
+                               public void writeClob(Clob x) throws 
SQLException {
+                                       setClob(paramnr, x);
+                               }
+
+                               public void writeStruct(Struct x) throws 
SQLException {
+                                       setObject(paramnr, x);
+                               }
+
+                               public void writeArray(Array x) throws 
SQLException {
+                                       setArray(paramnr, x);
+                               }
+
+                               public void writeURL(URL x) throws SQLException 
{
+                                       setURL(paramnr, x);
+                               }
+
+                               public void writeNString(String x) throws 
SQLException {
+                                       setNString(paramnr, x);
+                               }
+
+                               public void writeNClob(NClob x) throws 
SQLException {
+                                       setNClob(paramnr, x);
+                               }
+
+                               public void writeRowId(RowId x) throws 
SQLException {
+                                       setRowId(paramnr, x);
+                               }
+
+                               public void writeSQLXML(SQLXML x) throws 
SQLException {
+                                       setSQLXML(paramnr, x);
+                               }
+                       };
+                       sx.writeSQL(out);
                } else {        // java Class
                        throw new SQLFeatureNotSupportedException("Operation 
setObject() with object of type Class currently not supported!", "0A000");
                }
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
@@ -25,6 +25,8 @@ import java.util.*;
 import java.math.*;
 import java.net.*;
 import java.text.*;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
 import nl.cwi.monetdb.mcl.parser.*;
 
 /**
@@ -1293,9 +1295,17 @@ public class MonetResultSet extends Mone
                         */
                        public String getColumnClassName(int column) throws 
SQLException {
                                try {
-                                       return getClassForType(
-                                                       
getJavaType(types[column - 1])
-                                               ).getName();
+                                       Class type;
+                                       Map map = 
getStatement().getConnection().getTypeMap();
+                                       if (map.containsKey(types[column - 1])) 
{
+                                               type = 
(Class)map.get(types[column - 1]);
+                                       } else {
+                                               type = 
getClassForType(getJavaType(types[column - 1]));
+                                       }
+                                       if (type != null)
+                                               return type.getName();
+                                       throw new SQLException("column type 
mapping null: " +
+                                                       types[column - 1], 
"M0M03");
                                } catch (IndexOutOfBoundsException e) {
                                        throw new SQLException("No such column 
" + column, "M1M05");
                                }
@@ -1419,6 +1429,15 @@ public class MonetResultSet extends Mone
                return getObject(columnIndex, 
this.getStatement().getConnection().getTypeMap());
        }
 
+       private boolean classImplementsSQLData(Class cl) {
+               Class[] cls = cl.getInterfaces();
+               for (int i = 0; i < cls.length; i++) {
+                       if (cls[i] == SQLData.class)
+                               return true;
+               }
+               return false;
+       }
+
        /**
         * Retrieves the value of the designated column in the current row of 
this
         * ResultSet object as an Object in the Java programming language. If 
the
@@ -1475,6 +1494,136 @@ public class MonetResultSet extends Mone
                        return getClob(i);
                } else if (type == Blob.class) {
                        return getBlob(i);
+               } else if (classImplementsSQLData(type)) {
+                       SQLData x;
+                       try {
+                               Constructor<? extends SQLData> ctor =
+                                       ((Class)type).getConstructor();
+                               x = ctor.newInstance();
+                       } catch (NoSuchMethodException nsme) {
+                               throw new SQLException(nsme.getMessage(), 
"M0M27");
+                       } catch (InstantiationException ie) {
+                               throw new SQLException(ie.getMessage(), 
"M0M27");
+                       } catch (IllegalAccessException iae) {
+                               throw new SQLException(iae.getMessage(), 
"M0M27");
+                       } catch (IllegalArgumentException ige) {
+                               throw new SQLException(ige.getMessage(), 
"M0M27");
+                       } catch (InvocationTargetException ite) {
+                               throw new SQLException(ite.getMessage(), 
"M0M27");
+                       }
+                       final int colnum = i;
+                       final boolean valwasnull = wasNull();
+                       SQLInput input = new SQLInput() {
+                               public String readString() throws SQLException {
+                                       return getString(colnum);
+                               }
+
+                               public boolean readBoolean() throws 
SQLException {
+                                       return getBoolean(colnum);
+                               }
+
+                               public byte readByte() throws SQLException {
+                                       return getByte(colnum);
+                               }
+
+                               public short readShort() throws SQLException {
+                                       return getShort(colnum);
+                               }
+
+                               public int readInt() throws SQLException {
+                                       return getInt(colnum);
+                               }
+
+                               public long readLong() throws SQLException {
+                                       return getLong(colnum);
+                               }
+
+                               public float readFloat() throws SQLException {
+                                       return getFloat(colnum);
+                               }
+
+                               public double readDouble() throws SQLException {
+                                       return getDouble(colnum);
+                               }
+
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
http://mail.monetdb.org/mailman/listinfo/checkin-list

Reply via email to