Beispiel #1
0
  /**
   * Converts a LOB to the equivalent Java type, i.e. <code>Clob</code> to <code>String</code> and
   * <code>Blob</code> to <code>byte[]</code>. If the value passed is not a LOB object, it is left
   * unchanged and no exception is thrown; the idea is to transparently convert only LOBs.
   *
   * @param value an object that may be a LOB
   * @return if the value was a LOB, the equivalent Java object, otherwise the original value
   * @throws SQLException if an error occurs while reading the LOB contents
   */
  public static Object convertLOB(Object value) throws SQLException {
    if (value instanceof Clob) {
      Clob c = (Clob) value;
      return c.getSubString(1, (int) c.length());
    }

    if (value instanceof Blob) {
      Blob b = (Blob) value;
      return b.getBytes(1, (int) b.length());
    }

    return value;
  }
  /**
   * {@collect.stats} Constructs a <code>SerialBlob</code> object that is a serialized version of
   * the given <code>Blob</code> object.
   *
   * <p>The new <code>SerialBlob</code> object is initialized with the data from the <code>Blob
   * </code> object; therefore, the <code>Blob</code> object should have previously brought the SQL
   * <code>BLOB</code> value's data over to the client from the database. Otherwise, the new <code>
   * SerialBlob</code> object will contain no data.
   *
   * @param blob the <code>Blob</code> object from which this <code>SerialBlob</code> object is to
   *     be constructed; cannot be null.
   * @throws SerialException if an error occurs during serialization
   * @throws SQLException if the <code>Blob</code> passed to this to this constructor is a <code>
   *     null</code>.
   * @see java.sql.Blob
   */
  public SerialBlob(Blob blob) throws SerialException, SQLException {

    if (blob == null) {
      throw new SQLException("Cannot instantiate a SerialBlob " + "object with a null Blob object");
    }

    len = blob.length();
    buf = blob.getBytes(1, (int) len);
    this.blob = blob;

    // if ( len < 10240000)
    // len = 10240000;
    origLen = len;
  }
 /**
  * {@collect.stats} Returns the position in this <code>SerialBlob</code> object where the given
  * <code>Blob</code> object begins, starting the search at the specified position.
  *
  * @param pattern the <code>Blob</code> object for which to search;
  * @param start the position of the byte in this <code>SerialBlob</code> object from which to
  *     begin the search; the first position is <code>1</code>; must not be less than <code>1
  *     </code> nor greater than the length of this <code>SerialBlob</code> object
  * @return the position in this <code>SerialBlob</code> object where the given <code>Blob</code>
  *     object begins, starting at the specified position; <code>-1</code> if the pattern is not
  *     found or the given starting position is out of bounds; position numbering for the return
  *     value starts at <code>1</code>
  * @throws SerialException if an error occurs when serializing the blob
  * @throws SQLException if there is an error accessing the <code>BLOB</code> value from the
  *     database
  */
 public long position(Blob pattern, long start) throws SerialException, SQLException {
   return position(pattern.getBytes(1, (int) (pattern.length())), start);
 }
Beispiel #4
0
  /**
   * Embed the data object as a string literal in the buffer supplied.
   *
   * @param buf The buffer in which the data will be embedded.
   * @param value The data object.
   * @param isUnicode Set to <code>true</code> if Unicode strings should be used, else <code>false
   *     </code>.
   * @param connection The {@link ConnectionJDBC2} object.
   */
  static void embedData(
      StringBuffer buf, Object value, boolean isUnicode, ConnectionJDBC2 connection)
      throws SQLException {
    buf.append(' ');
    if (value == null) {
      buf.append("NULL ");
      return;
    }

    if (value instanceof Blob) {
      Blob blob = (Blob) value;

      value = blob.getBytes(1, (int) blob.length());
    } else if (value instanceof Clob) {
      Clob clob = (Clob) value;

      value = clob.getSubString(1, (int) clob.length());
    }

    if (value instanceof DateTime) {
      buf.append('\'');
      buf.append(value);
      buf.append('\'');
    } else if (value instanceof byte[]) {
      byte[] bytes = (byte[]) value;

      int len = bytes.length;

      if (len >= 0) {
        buf.append('0').append('x');
        if (len == 0 && connection.getTdsVersion() < Driver.TDS70) {
          // Zero length binary values are not allowed
          buf.append('0').append('0');
        } else {
          for (int i = 0; i < len; i++) {
            int b1 = bytes[i] & 0xFF;

            buf.append(hex[b1 >> 4]);
            buf.append(hex[b1 & 0x0F]);
          }
        }
      }
    } else if (value instanceof String) {
      String tmp = (String) value;
      int len = tmp.length();

      if (isUnicode) {
        buf.append('N');
      }
      buf.append('\'');

      for (int i = 0; i < len; i++) {
        char c = tmp.charAt(i);

        if (c == '\'') {
          buf.append('\'');
        }

        buf.append(c);
      }

      buf.append('\'');
    } else if (value instanceof java.sql.Date) {
      DateTime dt = new DateTime((java.sql.Date) value);
      buf.append('\'');
      buf.append(dt);
      buf.append('\'');
    } else if (value instanceof java.sql.Time) {
      DateTime dt = new DateTime((java.sql.Time) value);
      buf.append('\'');
      buf.append(dt);
      buf.append('\'');
    } else if (value instanceof java.sql.Timestamp) {
      DateTime dt = new DateTime((java.sql.Timestamp) value);
      buf.append('\'');
      buf.append(dt);
      buf.append('\'');
    } else if (value instanceof Boolean) {
      buf.append(((Boolean) value).booleanValue() ? '1' : '0');
    } else if (value instanceof BigDecimal) {
      //
      // Ensure large decimal number does not overflow the
      // maximum precision of the server.
      // Main problem is with small numbers e.g. BigDecimal(1.0).toString() =
      // 0.1000000000000000055511151231....
      //
      String tmp = value.toString();
      int maxlen = connection.getMaxPrecision();
      if (tmp.charAt(0) == '-') {
        maxlen++;
      }
      if (tmp.indexOf('.') >= 0) {
        maxlen++;
      }
      if (tmp.length() > maxlen) {
        buf.append(tmp.substring(0, maxlen));
      } else {
        buf.append(tmp);
      }
    } else {
      buf.append(value.toString());
    }
    buf.append(' ');
  }
Beispiel #5
0
  /**
   * Convert an existing data object to the specified JDBC type.
   *
   * @param callerReference an object reference to the caller of this method; must be a <code>
   *     Connection</code>, <code>Statement</code> or <code>ResultSet</code>
   * @param x the data object to convert
   * @param jdbcType the required type constant from <code>java.sql.Types</code>
   * @return the converted data object
   * @throws SQLException if the conversion is not supported or fails
   */
  static Object convert(Object callerReference, Object x, int jdbcType, String charSet)
      throws SQLException {
    // handle null value
    if (x == null) {
      switch (jdbcType) {
        case java.sql.Types.BIT:
        case JtdsStatement.BOOLEAN:
          return Boolean.FALSE;

        case java.sql.Types.TINYINT:
        case java.sql.Types.SMALLINT:
        case java.sql.Types.INTEGER:
          return INTEGER_ZERO;

        case java.sql.Types.BIGINT:
          return LONG_ZERO;

        case java.sql.Types.REAL:
          return FLOAT_ZERO;

        case java.sql.Types.FLOAT:
        case java.sql.Types.DOUBLE:
          return DOUBLE_ZERO;

        default:
          return null;
      }
    }

    try {
      switch (jdbcType) {
        case java.sql.Types.TINYINT:
          if (x instanceof Boolean) {
            return ((Boolean) x).booleanValue() ? INTEGER_ONE : INTEGER_ZERO;
          } else if (x instanceof Byte) {
            return new Integer(((Byte) x).byteValue() & 0xFF);
          } else {
            long val;
            if (x instanceof Number) {
              val = ((Number) x).longValue();
            } else if (x instanceof String) {
              val = new Long(((String) x).trim()).longValue();
            } else {
              break;
            }
            if (val < Byte.MIN_VALUE || val > Byte.MAX_VALUE) {
              throw new SQLException(
                  Messages.get("error.convert.numericoverflow", x, getJdbcTypeName(jdbcType)),
                  "22003");
            } else {
              return new Integer(new Long(val).intValue());
            }
          }

        case java.sql.Types.SMALLINT:
          if (x instanceof Boolean) {
            return ((Boolean) x).booleanValue() ? INTEGER_ONE : INTEGER_ZERO;
          } else if (x instanceof Short) {
            return new Integer(((Short) x).shortValue());
          } else if (x instanceof Byte) {
            return new Integer(((Byte) x).byteValue() & 0xFF);
          } else {
            long val;
            if (x instanceof Number) {
              val = ((Number) x).longValue();
            } else if (x instanceof String) {
              val = new Long(((String) x).trim()).longValue();
            } else {
              break;
            }
            if (val < Short.MIN_VALUE || val > Short.MAX_VALUE) {
              throw new SQLException(
                  Messages.get("error.convert.numericoverflow", x, getJdbcTypeName(jdbcType)),
                  "22003");
            } else {
              return new Integer(new Long(val).intValue());
            }
          }

        case java.sql.Types.INTEGER:
          if (x instanceof Integer) {
            return x;
          } else if (x instanceof Boolean) {
            return ((Boolean) x).booleanValue() ? INTEGER_ONE : INTEGER_ZERO;
          } else if (x instanceof Short) {
            return new Integer(((Short) x).shortValue());
          } else if (x instanceof Byte) {
            return new Integer(((Byte) x).byteValue() & 0xFF);
          } else {
            long val;
            if (x instanceof Number) {
              val = ((Number) x).longValue();
            } else if (x instanceof String) {
              val = new Long(((String) x).trim()).longValue();
            } else {
              break;
            }
            if (val < Integer.MIN_VALUE || val > Integer.MAX_VALUE) {
              throw new SQLException(
                  Messages.get("error.convert.numericoverflow", x, getJdbcTypeName(jdbcType)),
                  "22003");
            } else {
              return new Integer(new Long(val).intValue());
            }
          }

        case java.sql.Types.BIGINT:
          if (x instanceof BigDecimal) {
            BigDecimal val = (BigDecimal) x;
            if (val.compareTo(MIN_VALUE_LONG_BD) < 0 || val.compareTo(MAX_VALUE_LONG_BD) > 0) {
              throw new SQLException(
                  Messages.get("error.convert.numericoverflow", x, getJdbcTypeName(jdbcType)),
                  "22003");
            } else {
              return new Long(val.longValue());
            }
          } else if (x instanceof Long) {
            return x;
          } else if (x instanceof Boolean) {
            return ((Boolean) x).booleanValue() ? LONG_ONE : LONG_ZERO;
          } else if (x instanceof Byte) {
            return new Long(((Byte) x).byteValue() & 0xFF);
          } else if (x instanceof BigInteger) {
            BigInteger val = (BigInteger) x;
            if (val.compareTo(MIN_VALUE_LONG_BI) < 0 || val.compareTo(MAX_VALUE_LONG_BI) > 0) {
              throw new SQLException(
                  Messages.get("error.convert.numericoverflow", x, getJdbcTypeName(jdbcType)),
                  "22003");
            } else {
              return new Long(val.longValue());
            }
          } else if (x instanceof Number) {
            return new Long(((Number) x).longValue());
          } else if (x instanceof String) {
            return new Long(((String) x).trim());
          } else {
            break;
          }

        case java.sql.Types.REAL:
          if (x instanceof Float) {
            return x;
          } else if (x instanceof Byte) {
            return new Float(((Byte) x).byteValue() & 0xFF);
          } else if (x instanceof Number) {
            return new Float(((Number) x).floatValue());
          } else if (x instanceof String) {
            return new Float(((String) x).trim());
          } else if (x instanceof Boolean) {
            return ((Boolean) x).booleanValue() ? FLOAT_ONE : FLOAT_ZERO;
          }

          break;

        case java.sql.Types.FLOAT:
        case java.sql.Types.DOUBLE:
          if (x instanceof Double) {
            return x;
          } else if (x instanceof Byte) {
            return new Double(((Byte) x).byteValue() & 0xFF);
          } else if (x instanceof Number) {
            return new Double(((Number) x).doubleValue());
          } else if (x instanceof String) {
            return new Double(((String) x).trim());
          } else if (x instanceof Boolean) {
            return ((Boolean) x).booleanValue() ? DOUBLE_ONE : DOUBLE_ZERO;
          }

          break;

        case java.sql.Types.NUMERIC:
        case java.sql.Types.DECIMAL:
          if (x instanceof BigDecimal) {
            return x;
          } else if (x instanceof Number) {
            return new BigDecimal(x.toString());
          } else if (x instanceof String) {
            return new BigDecimal((String) x);
          } else if (x instanceof Boolean) {
            return ((Boolean) x).booleanValue() ? BIG_DECIMAL_ONE : BIG_DECIMAL_ZERO;
          }

          break;

        case java.sql.Types.VARCHAR:
        case java.sql.Types.CHAR:
          if (x instanceof String) {
            return x;
          } else if (x instanceof Number) {
            return x.toString();
          } else if (x instanceof Boolean) {
            return ((Boolean) x).booleanValue() ? "1" : "0";
          } else if (x instanceof Clob) {
            Clob clob = (Clob) x;
            long length = clob.length();

            if (length > Integer.MAX_VALUE) {
              throw new SQLException(Messages.get("error.normalize.lobtoobig"), "22000");
            }

            return clob.getSubString(1, (int) length);
          } else if (x instanceof Blob) {
            Blob blob = (Blob) x;
            long length = blob.length();

            if (length > Integer.MAX_VALUE) {
              throw new SQLException(Messages.get("error.normalize.lobtoobig"), "22000");
            }

            x = blob.getBytes(1, (int) length);
          }

          if (x instanceof byte[]) {
            return toHex((byte[]) x);
          }

          return x.toString(); // Last hope!

        case java.sql.Types.BIT:
        case JtdsStatement.BOOLEAN:
          if (x instanceof Boolean) {
            return x;
          } else if (x instanceof Number) {
            return (((Number) x).intValue() == 0) ? Boolean.FALSE : Boolean.TRUE;
          } else if (x instanceof String) {
            String tmp = ((String) x).trim();

            return ("1".equals(tmp) || "true".equalsIgnoreCase(tmp)) ? Boolean.TRUE : Boolean.FALSE;
          }

          break;

        case java.sql.Types.VARBINARY:
        case java.sql.Types.BINARY:
          if (x instanceof byte[]) {
            return x;
          } else if (x instanceof Blob) {
            Blob blob = (Blob) x;

            return blob.getBytes(1, (int) blob.length());
          } else if (x instanceof Clob) {
            Clob clob = (Clob) x;
            long length = clob.length();

            if (length > Integer.MAX_VALUE) {
              throw new SQLException(Messages.get("error.normalize.lobtoobig"), "22000");
            }

            x = clob.getSubString(1, (int) length);
          }

          if (x instanceof String) {
            //
            // Strictly speaking this conversion is not required by
            // the JDBC standard but jTDS has always supported it.
            //
            if (charSet == null) {
              charSet = "ISO-8859-1";
            }

            try {
              return ((String) x).getBytes(charSet);
            } catch (UnsupportedEncodingException e) {
              return ((String) x).getBytes();
            }
          } else if (x instanceof UniqueIdentifier) {
            return ((UniqueIdentifier) x).getBytes();
          }

          break;

        case java.sql.Types.TIMESTAMP:
          if (x instanceof DateTime) {
            return ((DateTime) x).toTimestamp();
          } else if (x instanceof java.sql.Timestamp) {
            return x;
          } else if (x instanceof java.sql.Date) {
            return new java.sql.Timestamp(((java.sql.Date) x).getTime());
          } else if (x instanceof java.sql.Time) {
            return new java.sql.Timestamp(((java.sql.Time) x).getTime());
          } else if (x instanceof java.lang.String) {
            return java.sql.Timestamp.valueOf(((String) x).trim());
          }

          break;

        case java.sql.Types.DATE:
          if (x instanceof DateTime) {
            return ((DateTime) x).toDate();
          } else if (x instanceof java.sql.Date) {
            return x;
          } else if (x instanceof java.sql.Time) {
            return DATE_ZERO;
          } else if (x instanceof java.sql.Timestamp) {
            GregorianCalendar cal = (GregorianCalendar) calendar.get();
            cal.setTime((java.util.Date) x);
            cal.set(Calendar.HOUR_OF_DAY, 0);
            cal.set(Calendar.MINUTE, 0);
            cal.set(Calendar.SECOND, 0);
            cal.set(Calendar.MILLISECOND, 0);
            // VM1.4+ only              return new java.sql.Date(cal.getTimeInMillis());
            return new java.sql.Date(cal.getTime().getTime());
          } else if (x instanceof java.lang.String) {
            return java.sql.Date.valueOf(((String) x).trim());
          }

          break;

        case java.sql.Types.TIME:
          if (x instanceof DateTime) {
            return ((DateTime) x).toTime();
          } else if (x instanceof java.sql.Time) {
            return x;
          } else if (x instanceof java.sql.Date) {
            return TIME_ZERO;
          } else if (x instanceof java.sql.Timestamp) {
            GregorianCalendar cal = (GregorianCalendar) calendar.get();
            // VM 1.4+ only             cal.setTimeInMillis(((java.sql.Timestamp)x).getTime());
            cal.setTime((java.util.Date) x);
            cal.set(Calendar.YEAR, 1970);
            cal.set(Calendar.MONTH, 0);
            cal.set(Calendar.DAY_OF_MONTH, 1);
            // VM 1.4+ only             return new java.sql.Time(cal.getTimeInMillis());*/
            return new java.sql.Time(cal.getTime().getTime());
          } else if (x instanceof java.lang.String) {
            return java.sql.Time.valueOf(((String) x).trim());
          }

          break;

        case java.sql.Types.OTHER:
          return x;

        case java.sql.Types.JAVA_OBJECT:
          throw new SQLException(
              Messages.get(
                  "error.convert.badtypes", x.getClass().getName(), getJdbcTypeName(jdbcType)),
              "22005");

        case java.sql.Types.LONGVARBINARY:
        case java.sql.Types.BLOB:
          if (x instanceof Blob) {
            return x;
          } else if (x instanceof byte[]) {
            return new BlobImpl(getConnection(callerReference), (byte[]) x);
          } else if (x instanceof Clob) {
            //
            // Convert CLOB to BLOB. Not required by the standard but we will
            // do it anyway.
            //
            Clob clob = (Clob) x;
            try {
              if (charSet == null) {
                charSet = "ISO-8859-1";
              }
              Reader rdr = clob.getCharacterStream();
              BlobImpl blob = new BlobImpl(getConnection(callerReference));
              BufferedWriter out =
                  new BufferedWriter(new OutputStreamWriter(blob.setBinaryStream(1), charSet));
              // TODO Use a buffer to improve performance
              int c;
              while ((c = rdr.read()) >= 0) {
                out.write(c);
              }
              out.close();
              rdr.close();
              return blob;
            } catch (UnsupportedEncodingException e) {
              // Unlikely to happen but fall back on in memory copy
              x = clob.getSubString(1, (int) clob.length());
            } catch (IOException e) {
              throw new SQLException(
                  Messages.get("error.generic.ioerror", e.getMessage()), "HY000");
            }
          }

          if (x instanceof String) {
            //
            // Strictly speaking this conversion is also not required by
            // the JDBC standard but jTDS has always supported it.
            //
            BlobImpl blob = new BlobImpl(getConnection(callerReference));
            String data = (String) x;

            if (charSet == null) {
              charSet = "ISO-8859-1";
            }

            try {
              blob.setBytes(1, data.getBytes(charSet));
            } catch (UnsupportedEncodingException e) {
              blob.setBytes(1, data.getBytes());
            }

            return blob;
          }

          break;

        case java.sql.Types.LONGVARCHAR:
        case java.sql.Types.CLOB:
          if (x instanceof Clob) {
            return x;
          } else if (x instanceof Blob) {
            //
            // Convert BLOB to CLOB
            //
            Blob blob = (Blob) x;
            try {
              InputStream is = blob.getBinaryStream();
              ClobImpl clob = new ClobImpl(getConnection(callerReference));
              Writer out = clob.setCharacterStream(1);
              // TODO Use a buffer to improve performance
              int b;
              // These reads/writes are buffered by the underlying blob buffers
              while ((b = is.read()) >= 0) {
                out.write(hex[b >> 4]);
                out.write(hex[b & 0x0F]);
              }
              out.close();
              is.close();
              return clob;
            } catch (IOException e) {
              throw new SQLException(
                  Messages.get("error.generic.ioerror", e.getMessage()), "HY000");
            }
          } else if (x instanceof Boolean) {
            x = ((Boolean) x).booleanValue() ? "1" : "0";
          } else if (!(x instanceof byte[])) {
            x = x.toString();
          }

          if (x instanceof byte[]) {
            ClobImpl clob = new ClobImpl(getConnection(callerReference));
            clob.setString(1, toHex((byte[]) x));

            return clob;
          } else if (x instanceof String) {
            return new ClobImpl(getConnection(callerReference), (String) x);
          }

          break;

        default:
          throw new SQLException(
              Messages.get("error.convert.badtypeconst", getJdbcTypeName(jdbcType)), "HY004");
      }

      throw new SQLException(
          Messages.get("error.convert.badtypes", x.getClass().getName(), getJdbcTypeName(jdbcType)),
          "22005");
    } catch (NumberFormatException nfe) {
      throw new SQLException(
          Messages.get("error.convert.badnumber", getJdbcTypeName(jdbcType)), "22000");
    }
  }