db-torque-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Scott Miller <smil...@vecna.com>
Subject Re: Village Patch (Oracle Clobs)
Date Wed, 09 Apr 2003 22:20:53 GMT
Through some more testing today I found that this method does not work 
for Oracle 8 JDBC drivers.  I am sure a very similar method would work, 
however one of the methods I access via reflection does not exist in the 
v8 drivers.  Here is the new, updated dif.  I added in a check for the 
version of the currently used driver.


Index: com/workingdogs/village/Value.java
===================================================================
RCS file: /home/cvspublic/village/com/workingdogs/village/Value.java,v
retrieving revision 1.18
diff -u -r1.18 Value.java
--- com/workingdogs/village/Value.java  30 Jul 2002 23:20:51 -0000      1.18
+++ com/workingdogs/village/Value.java  9 Apr 2003 22:14:37 -0000
@@ -53,7 +53,18 @@

 package com.workingdogs.village;

+import java.lang.Class;
+import java.lang.ClassNotFoundException;
+import java.lang.IllegalAccessError;
+import java.lang.NoSuchFieldException;
+import java.lang.NoSuchMethodException;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.math.BigDecimal;
+import java.io.IOException;
+import java.io.Writer;
+import java.sql.Clob;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
@@ -67,7 +78,7 @@
 cross between a row and column and contains the information held there.

 @author Jon S. Stevens <A 
HREF="mailto:jon@latchkey.com">jon@latchkey.com</A>
-@version $Revision: 1.18 $
+@version $Revision:   1.0  $
 */
 public class Value
 {
@@ -77,6 +88,10 @@
     private int columnNumber;
     /** what sql type of object is this? */
     private int type;
+    /** Name of the oracle driver -- used to support Oracle clobs as a 
special case */
+    private static final String ORACLE_DRIVER_NAME = "Oracle JDBC driver";
+    /** Version of the oracle driver being supported with cloba */
+    private static final int ORACLE_DRIVER_VERSION = 9;

     /**
      * Creates a new Value object based on the ResultSet, columnNumber 
and type
@@ -152,7 +167,42 @@
             case Types.BLOB:
                 valueObject = rs.getBytes (columnNumber);
                 break;
-
+
+            case Types.CLOB:
+               // read any CLOBs as strings
+               Clob clob = rs.getClob(columnNumber);
+               if( clob == null )
+               {
+                       valueObject = null;
+               }
+               else
+               {
+                       long remainingLength = clob.length();
+                       long currentPosition = 1;
+
+                       String valueString = "";
+                       while( remainingLength > 0 )
+                       {
+                               int readLength = 0;
+                               if( remainingLength > Integer.MAX_VALUE )
+                               {
+                                       // there will be more iterations
+                                       readLength = Integer.MAX_VALUE;
+                               }
+                               else
+                               {
+                                       // this is the last iteration
+                                       readLength = (int)remainingLength;
+                               }
+
+                               valueString += clob.getSubString( 
currentPosition, readLength );
+                               currentPosition += readLength;
+                               remainingLength -= readLength;
+                       }
+                       valueObject = valueString;
+               }
+               break;
+
             case Types.LONGVARCHAR:
             case Types.CHAR:
             case Types.VARCHAR:
@@ -267,6 +317,105 @@
                 stmt.setBytes (stmtNumber, this.asBytes());
                 break;

+                       case Types.CLOB:
+                               if( ORACLE_DRIVER_NAME.equals( 
stmt.getConnection().getMetaData().getDriverName() ) &&
+                                       
stmt.getConnection().getMetaData().getDriverMajorVersion() >= 
ORACLE_DRIVER_VERSION  )
+                               {
+                                       try
+                                       {
+                                               // support oracle clobs 
without requiring oracle libraries
+                                               // at compile time
+                                               // Note this assumes 
that if you are using the Oracle Driver.
+                                               // then you have access 
to the oracle.sql.CLOB class
+
+                                               // First get the oracle 
clob class
+                                               Class oracleClobClass = 
Class.forName("oracle.sql.CLOB");
+
+                                               // now get the static 
factory method
+                                               Class partypes[] = new 
Class[3];
+                                               partypes[0] = 
Class.forName("java.sql.Connection");
+                                               partypes[1] = Boolean.TYPE;
+                                               partypes[2] = Integer.TYPE;
+                                               Method 
createTemporaryMethod = oracleClobClass.getDeclaredMethod( 
"createTemporary", partypes );
+
+                                               // now get ready to call 
the factory method
+                                               Field 
durationSessionField = oracleClobClass.getField( "DURATION_SESSION" );
+                                               Object arglist[] = new 
Object[3];
+                                               arglist[0] = 
stmt.getConnection();
+                                               arglist[1] = Boolean.TRUE;
+                                               arglist[2] = 
durationSessionField.get(null); //null is valid because of static field
+
+                                               // Create our CLOB
+                                               Object tempClob = 
createTemporaryMethod.invoke( null, arglist ); //null is valid because 
of static method
+
+                                               // get the open method
+                                               partypes = new Class[1];
+                                               partypes[0] = Integer.TYPE;
+                                               Method openMethod = 
oracleClobClass.getDeclaredMethod( "open", partypes );
+
+                                               // prepare to call the 
method
+                                               Field modeReadWriteField 
= oracleClobClass.getField( "MODE_READWRITE" );
+                                               arglist = new Object[1];
+                                               arglist[0] = 
modeReadWriteField.get(null); //null is valid because of static field
+
+                                               // call 
open(CLOB.MODE_READWRITE);
+                                               openMethod.invoke( 
tempClob, arglist );
+
+                                               // get the 
getCharacterOutputStream method
+                                               Method 
getCharacterOutputStreamMethod = oracleClobClass.getDeclaredMethod( 
"getCharacterOutputStream", null );
+
+                                               // call the 
getCharacterOutpitStream method
+                                               Writer tempClobWriter = 
(Writer) getCharacterOutputStreamMethod.invoke( tempClob, null );
+
+                                               // write the string to 
the clob
+                                               
tempClobWriter.write(this.asString());
+                                               tempClobWriter.flush();
+                                               tempClobWriter.close();
+
+                                               // get the close method
+                                               Method closeMethod = 
oracleClobClass.getDeclaredMethod( "close", null );
+
+                                               // call the close method
+                                               closeMethod.invoke( 
tempClob, null );
+
+                                               // add the clob to the 
statement
+                                               stmt.setClob( 
stmtNumber, (Clob)tempClob );
+                                       }
+                                       catch( ClassNotFoundException e )
+                                       {
+                                               // could not find the 
class with reflection
+                                               throw new 
DataSetException("Unable to find a required class.\n" + e.getMessage());
+                                       }
+                                       catch( NoSuchMethodException e )
+                                       {
+                                               // could not find the 
metho with reflection
+                                               throw new 
DataSetException("Unable to find a required method.\n" + e.getMessage());
+                                       }
+                                       catch( NoSuchFieldException e )
+                                       {
+                                               // could not find the 
field with reflection
+                                               throw new 
DataSetException("Unable to find a required field.\n" + e.getMessage());
+                                       }
+                                       catch( IllegalAccessException e )
+                                       {
+                                               throw new 
DataSetException("Unable to access a required method or field.\n" + 
e.getMessage());
+                                       }
+                                       catch( InvocationTargetException e )
+                                       {
+                                               throw new 
DataSetException(e.getMessage());
+                                       }
+                                       catch( IOException e )
+                                       {
+                                               throw new 
DataSetException(e.getMessage());
+                                       }
+                               }
+                               else
+                               {
+                                       stmt.setString( stmtNumber, 
this.asString() );
+                               }
+
+                               break;
+
             case Types.LONGVARCHAR:
             case Types.CHAR:
             case Types.VARCHAR:
cvs server: Diffing docs


-Scott


Mime
View raw message