You are viewing a plain text version of this content. The canonical link for it is here.
Posted to ojb-dev@db.apache.org by ar...@apache.org on 2004/06/24 11:38:34 UTC

cvs commit: db-ojb/src/java/org/apache/ojb/broker/util JdbcTypesHelper.java

arminw      2004/06/24 02:38:34

  Modified:    src/java/org/apache/ojb/broker/util JdbcTypesHelper.java
  Log:
  OJB271
  fix by martin kalen, oracle9i needs special handling of LONGVARCHAR
  
  Instead of ResultSet.getBytes one must use streaming  from ResultSet.getBinaryStream to safely read all data using Oracle. Current behaviour is non-deterministic (probably timing dependent) silent truncation of data when reading from the ResultSet using Oracle THIN driver.
  
  Revision  Changes    Path
  1.11      +74 -16    db-ojb/src/java/org/apache/ojb/broker/util/JdbcTypesHelper.java
  
  Index: JdbcTypesHelper.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/util/JdbcTypesHelper.java,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- JdbcTypesHelper.java	4 Apr 2004 23:53:37 -0000	1.10
  +++ JdbcTypesHelper.java	24 Jun 2004 09:38:34 -0000	1.11
  @@ -1,5 +1,8 @@
   package org.apache.ojb.broker.util;
   
  +import java.io.ByteArrayOutputStream;
  +import java.io.IOException;
  +import java.io.InputStream;
   import java.lang.reflect.Field;
   import java.math.BigDecimal;
   import java.net.URL;
  @@ -36,6 +39,7 @@
    * See the License for the specific language governing permissions and
    * limitations under the License.
    */
  +
   public final class JdbcTypesHelper
   {
       private static Map jdbcObjectTypesFromType = new HashMap();
  @@ -122,7 +126,7 @@
       {
           JdbcType result = null;
           result = (JdbcType) jdbcObjectTypesFromName.get(typeName.toLowerCase());
  -        if(result == null)
  +        if (result == null)
           {
               throw new OJBRuntimeException("The type " + typeName + " can not be handled by OJB." +
                       " Please specify only types as defined by java.sql.Types.");
  @@ -180,14 +184,12 @@
               result = getJdbcTypeByName("datalink");
   //#endif
           else
  -            throw new OJBRuntimeException(
  -                    "The type " + fieldType + " can not be handled by OJB automatically."
  +            throw new OJBRuntimeException("The type " + fieldType + " can not be handled by OJB automatically."
                       + " Please specify a type as defined by java.sql.Types in your field-descriptor");
           return result;
       }
   
   
  -
       /**
        * Returns an java object read from the specified ResultSet column.
        */
  @@ -223,7 +225,7 @@
               {
                   Field field = fields[i];
                   int temp = field.getInt(null);
  -                if(temp == jdbcType)
  +                if (temp == jdbcType)
                   {
                       return field.getName();
                   }
  @@ -244,7 +246,9 @@
       public abstract static class BaseType implements JdbcType
       {
           abstract Object readValueFromResultSet(ResultSet rs, String columnName) throws SQLException;
  +
           abstract Object readValueFromResultSet(ResultSet rs, int columnIndex) throws SQLException;
  +
           abstract Object readValueFromStatement(CallableStatement stmt, int columnIndex) throws SQLException;
           /*
           only supported by jdk >= 1.4x, maybe useful in further versions
  @@ -253,11 +257,11 @@
   
           public boolean equals(Object obj)
           {
  -            if(this == obj) return true;
  +            if (this == obj) return true;
               boolean result = false;
  -            if(obj instanceof JdbcType)
  +            if (obj instanceof JdbcType)
               {
  -                result = this.getType() == ((JdbcType)obj).getType();
  +                result = this.getType() == ((JdbcType) obj).getType();
               }
               return result;
           }
  @@ -266,7 +270,7 @@
           {
               return getType();
           }
  -        
  +
           public Object getObjectFromColumn(CallableStatement stmt, int columnId) throws SQLException
           {
               return getObjectFromColumn(null, stmt, null, columnId);
  @@ -284,7 +288,7 @@
               {
   //                return columnIndex == MIN_INT
   //                        ? readValueFromStatement(stmt, columnName) : readValueFromStatement(stmt, columnIndex);
  -                if(columnIndex == MIN_INT)
  +                if (columnIndex == MIN_INT)
                   {
                       throw new UnsupportedOperationException("Not implemented yet");
                   }
  @@ -319,7 +323,6 @@
       }
   
   
  -
       public static final class T_Char extends BaseType
       {
           public Object sequenceKeyConversion(Long identifier) throws SequenceManagerException
  @@ -888,6 +891,55 @@
   
       public static final class T_LongVarBinary extends BaseType
       {
  +        protected static final int BUFSZ = 2048;
  +
  +        /**
  +         * Retrieve LONGVARBINARY InputStream data and pack into a byte array.
  +         *
  +         * @param is the input stream to be retrieved
  +         * @return a string containing the clob data
  +         * @throws SQLException if conversion fails or the clob cannot be read
  +         */
  +        protected static byte[] retrieveStreamDataFromRs(InputStream is) throws SQLException
  +        {
  +            if (is == null)
  +            {
  +                return null;
  +            }
  +            byte[] bytes = null;
  +            ByteArrayOutputStream bos = null;
  +            try
  +            {
  +                bos = new ByteArrayOutputStream();
  +                int numRead;
  +                byte[] buf = new byte[BUFSZ];
  +                while ((numRead = is.read(buf, 0, buf.length)) > 0)
  +                {
  +                    bos.write(buf, 0, numRead);
  +                }
  +                bytes = bos.toByteArray();
  +            }
  +            catch (IOException e)
  +            {
  +                throw new SQLException("I/O exception retrieving LONGVARBINARY: " + e.getLocalizedMessage());
  +            }
  +            finally
  +            {
  +                if (bos != null)
  +                {
  +                    try
  +                    {
  +                        bos.close();
  +                    }
  +                    catch (Exception ignored)
  +                    {
  +                        //ignore
  +                    }
  +                }
  +            }
  +            return bytes;
  +        }
  +
           public Object sequenceKeyConversion(Long identifier) throws SequenceManagerException
           {
               return identifier.toString().getBytes();
  @@ -905,12 +957,12 @@
   
           Object readValueFromResultSet(ResultSet rs, String columnName) throws SQLException
           {
  -            return rs.getBytes(columnName);
  +            return retrieveStreamDataFromRs(rs.getBinaryStream(columnName));
           }
   
           Object readValueFromResultSet(ResultSet rs, int columnIndex) throws SQLException
           {
  -            return rs.getBytes(columnIndex);
  +            return retrieveStreamDataFromRs(rs.getBinaryStream(columnIndex));
           }
   
           public int getType()
  @@ -1021,13 +1073,16 @@
       public static final class T_Clob extends BaseType
       {
           protected static final int BUFSZ = 32768;
  +
           /**
            * Convert CLOB to String. Safe for very large objects.
  +         *
            * @param aClob clob with character data
            * @return a string containing the clob data
            * @throws SQLException if conversion fails or the clob cannot be read
            */
  -        protected static String safeClobToString(Clob aClob) throws SQLException {
  +        protected static String safeClobToString(Clob aClob) throws SQLException
  +        {
               long length = aClob.length();
               if (length == 0)
               {
  @@ -1036,14 +1091,17 @@
               StringBuffer sb = new StringBuffer();
               char[] buf = new char[BUFSZ];
               java.io.Reader stream = aClob.getCharacterStream();
  -            try {
  +            try
  +            {
                   int numRead;
                   while ((numRead = stream.read(buf)) != -1)
                   {
                       sb.append(buf, 0, numRead);
                   }
                   stream.close();
  -            } catch (java.io.IOException e) {
  +            }
  +            catch (java.io.IOException e)
  +            {
                   throw new SQLException(e.getLocalizedMessage());
               }
               return sb.toString();
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org