public void convertFromRawBytes(
     byte[] rawBytes, int offset, ConvTable ccsidConverter, boolean ignoreConversionErrors)
     throws SQLException {
   int locatorHandle = BinaryConverter.byteArrayToInt(rawBytes, offset);
   locator_.setHandle(locatorHandle);
   locator_.setColumnIndex(columnIndex_);
   // @J5A reset saved handle after setting new value
   savedObject_ = null;
 }
Beispiel #2
0
  public String getString() throws SQLException {
    if (savedObject_ != null) // @loch
    { // @loch
      // get value from RS.updateX(value)
      doConversion(); // @loch
      truncated_ = 0; // @loch
      return value_; // @loch
    } // @loch

    DBLobData data = locator_.retrieveData(0, locator_.getMaxLength());
    String value =
        converter_.byteArrayToString(data.getRawBytes(), data.getOffset(), data.getLength());
    truncated_ = 0; // @pda make consistent with other SQLData Clob classes
    return value;
  }
  // @pda jdbc40
  public String getNString() throws SQLException {
    truncated_ = 0;
    outOfBounds_ = false;

    if (savedObject_ != null) // @loch
    { // @loch
      // get value from RS.updateX(value)
      doConversion(); // @loch
      truncated_ = 0;
      outOfBounds_ = false; // @loch
      return value_; // @loch
    } // @loch

    DBLobData data = locator_.retrieveData(0, locator_.getMaxLength());
    String value =
        converter_.byteArrayToString(data.getRawBytes(), data.getOffset(), data.getLength());
    return value;
  }
Beispiel #4
0
  // @CRS - This is only called from AS400JDBCPreparedStatement in one place.
  public void convertToRawBytes(byte[] rawBytes, int offset, ConvTable ccsidConverter)
      throws SQLException {
    BinaryConverter.intToByteArray(locator_.getHandle(), rawBytes, offset);

    // Now we write our saved data to the system, because the prepared statement is being executed.
    // We used to write the data to the system on the call to set(), but this messed up
    // batch executes, since the host server only reserves temporary space for locator handles one
    // row at a time.
    // See the toObject() method in this class for more details.
    if (savedObject_ != null) writeToServer();
  }
Beispiel #5
0
  public byte[] getBytes() throws SQLException {
    if (savedObject_ != null) // @loch
    { // @loch
      // get value from RS.updateX(value)
      doConversion(); // @loch
      truncated_ = 0;
      outOfBounds_ = false; // @loch
      return value_; // @loch
    } // @loch

    int locatorLength = (int) locator_.getLength();
    if (locatorLength == 0) return new byte[0];
    DBLobData data = locator_.retrieveData(0, locatorLength);
    int actualLength = data.getLength();
    byte[] bytes = new byte[actualLength];
    System.arraycopy(data.getRawBytes(), data.getOffset(), bytes, 0, actualLength);
    truncated_ = 0;
    outOfBounds_ = false;
    return bytes;
  }
Beispiel #6
0
 public void convertFromRawBytes(byte[] rawBytes, int offset, ConvTable ccsidConverter)
     throws SQLException {
   int locatorHandle = BinaryConverter.byteArrayToInt(rawBytes, offset);
   locator_.setHandle(locatorHandle);
   locator_.setColumnIndex(columnIndex_);
 }
Beispiel #7
0
 // @loch
 public int getHandle() {
   return locator_.getHandle();
 }
Beispiel #8
0
 public void setHandle(int handle) {
   locator_.setHandle(handle);
 }
Beispiel #9
0
  private void writeToServer() throws SQLException {
    try {
      Object object = savedObject_;
      if (object instanceof String) {
        String string = (String) object;
        int bidiStringType = settings_.getBidiStringType();
        if (bidiStringType == -1) bidiStringType = converter_.bidiStringType_;

        BidiConversionProperties bidiConversionProperties =
            new BidiConversionProperties(bidiStringType); // @KBA
        bidiConversionProperties.setBidiImplicitReordering(
            settings_.getBidiImplicitReordering()); // @KBA
        bidiConversionProperties.setBidiNumericOrderingRoundTrip(
            settings_.getBidiNumericOrdering()); // @KBA

        byte[] bytes =
            converter_.stringToByteArray(
                string,
                bidiConversionProperties); // @KBC changed to use bidiConversionProperties instead
                                           // of bidiStringType
        locator_.writeData(0L, bytes, true); // @K1C
      } else if (object instanceof Reader) {
        int length = scale_; // hack to get the length into the set method
        // Need to write even if there are 0 bytes in case we are batching and
        // the host server reuses the same handle for the previous locator; otherwise,
        // we'll have data in the current row from the previous row.
        if (length == 0) {
          locator_.writeData(0, new byte[0], 0, 0, true); // @K1C
        } else if (length > 0) {
          try {
            int blockSize =
                length < AS400JDBCPreparedStatement.LOB_BLOCK_SIZE
                    ? length
                    : AS400JDBCPreparedStatement.LOB_BLOCK_SIZE;
            int bidiStringType = settings_.getBidiStringType();
            if (bidiStringType == -1) bidiStringType = converter_.bidiStringType_;

            BidiConversionProperties bidiConversionProperties =
                new BidiConversionProperties(bidiStringType); // @KBA
            bidiConversionProperties.setBidiImplicitReordering(
                settings_.getBidiImplicitReordering()); // @KBA
            bidiConversionProperties.setBidiNumericOrderingRoundTrip(
                settings_.getBidiNumericOrdering()); // @KBA

            ReaderInputStream stream =
                new ReaderInputStream(
                    (Reader) savedObject_,
                    converter_.getCcsid(),
                    bidiConversionProperties,
                    blockSize); // @KBC changed to use bidiConversionProperties instead of
                                // bidiStringType
            byte[] byteBuffer = new byte[blockSize];
            int totalBytesRead = 0;
            int bytesRead = stream.read(byteBuffer, 0, blockSize);
            while (bytesRead > -1 && totalBytesRead < length) {
              locator_.writeData(
                  (long) totalBytesRead,
                  byteBuffer,
                  0,
                  bytesRead,
                  true); // totalBytesRead is our offset.  @K1C
              totalBytesRead += bytesRead;
              int bytesRemaining = length - totalBytesRead;
              if (bytesRemaining < blockSize) {
                blockSize = bytesRemaining;
                if (stream.available() == 0 && blockSize != 0) {
                  stream.close(); // @scan1
                  stream =
                      new ReaderInputStream(
                          (Reader) savedObject_,
                          converter_.getCcsid(),
                          bidiConversionProperties,
                          blockSize); // do this so we don't read more chars out of the Reader than
                                      // we have to. //@KBC changed to use bidiConversionProperties
                                      // instead of bidiStringType
                }
              }
              bytesRead = stream.read(byteBuffer, 0, blockSize);
            }
            stream.close(); // @scan1

            if (totalBytesRead < length) {
              // a length longer than the stream was specified
              JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH);
            }

          } catch (IOException ie) {
            JDError.throwSQLException(this, JDError.EXC_INTERNAL, ie);
          }
        } else if (length == -2) // @readerlen new else-if block (read all data)
        {
          try {
            // String readerStr = JDUtilities.readerToString((Reader)savedObject_);
            int blockSize = AS400JDBCPreparedStatement.LOB_BLOCK_SIZE;
            int bidiStringType = settings_.getBidiStringType();
            if (bidiStringType == -1) bidiStringType = converter_.bidiStringType_;

            BidiConversionProperties bidiConversionProperties =
                new BidiConversionProperties(bidiStringType); // @KBA
            bidiConversionProperties.setBidiImplicitReordering(
                settings_.getBidiImplicitReordering()); // @KBA
            bidiConversionProperties.setBidiNumericOrderingRoundTrip(
                settings_.getBidiNumericOrdering()); // @KBA

            ReaderInputStream stream =
                new ReaderInputStream(
                    (Reader) savedObject_,
                    converter_.getCcsid(),
                    bidiConversionProperties,
                    blockSize); // @KBC changed to use bidiConversionProperties instead of
                                // bidiStringType
            byte[] byteBuffer = new byte[blockSize];
            int totalBytesRead = 0;
            int bytesRead = stream.read(byteBuffer, 0, blockSize);
            while (bytesRead > -1) {
              locator_.writeData(
                  (long) totalBytesRead,
                  byteBuffer,
                  0,
                  bytesRead,
                  true); // totalBytesRead is our offset.  @K1C
              totalBytesRead += bytesRead;
              bytesRead = stream.read(byteBuffer, 0, blockSize);
            }
            stream.close(); // @scan1

          } catch (IOException ie) {
            JDError.throwSQLException(this, JDError.EXC_INTERNAL, ie);
          }
        } else {
          JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH);
        }
      } else if (object instanceof InputStream) {
        int length = scale_; // hack to get the length into the set method
        // Need to write even if there are 0 bytes in case we are batching and
        // the host server reuses the same handle for the previous locator; otherwise,
        // we'll have data in the current row from the previous row.
        if (length == 0) {
          locator_.writeData(0, new byte[0], 0, 0, true); // @K1C
        } else if (length > 0) {
          InputStream stream = (InputStream) savedObject_;
          int blockSize =
              length < AS400JDBCPreparedStatement.LOB_BLOCK_SIZE
                  ? length
                  : AS400JDBCPreparedStatement.LOB_BLOCK_SIZE;
          byte[] byteBuffer = new byte[blockSize];
          try {
            int totalBytesRead = 0;
            int bytesRead = stream.read(byteBuffer, 0, blockSize);
            while (bytesRead > -1 && totalBytesRead < length) {
              locator_.writeData(
                  (long) totalBytesRead,
                  byteBuffer,
                  0,
                  bytesRead,
                  true); // totalBytesRead is our offset.  @K1C
              totalBytesRead += bytesRead;
              int bytesRemaining = length - totalBytesRead;
              if (bytesRemaining < blockSize) {
                blockSize = bytesRemaining;
              }
              bytesRead = stream.read(byteBuffer, 0, blockSize);
            }

            if (totalBytesRead < length) {
              // a length longer than the stream was specified
              JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH);
            }

          } catch (IOException ie) {
            JDError.throwSQLException(this, JDError.EXC_INTERNAL, ie);
          }
        } else if (length == -2) // @readerlen new else-if block (read all data)
        {
          InputStream stream = (InputStream) savedObject_;
          int blockSize = AS400JDBCPreparedStatement.LOB_BLOCK_SIZE;
          byte[] byteBuffer = new byte[blockSize];
          try {
            int totalBytesRead = 0;
            int bytesRead = stream.read(byteBuffer, 0, blockSize);
            while (bytesRead > -1) {
              locator_.writeData(
                  (long) totalBytesRead,
                  byteBuffer,
                  0,
                  bytesRead,
                  true); // totalBytesRead is our offset.  @K1C
              totalBytesRead += bytesRead;

              bytesRead = stream.read(byteBuffer, 0, blockSize);
            }
          } catch (IOException ie) {
            JDError.throwSQLException(this, JDError.EXC_INTERNAL, ie);
          }
        } else {
          JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH);
        }
      } else if (JDUtilities.JDBCLevel_ >= 20
          && object instanceof Clob) // @H0A check for jdbc level to know if lobs exist
      {
        // @G5A Start new code for updateable locator case
        boolean set = false;
        if (object instanceof AS400JDBCClobLocator) {
          AS400JDBCClobLocator clob = (AS400JDBCClobLocator) object;

          // Synchronize on a lock so that the user can't keep making updates
          // to the clob while we are taking updates off the vectors.
          synchronized (clob) {
            // See if we saved off our real object from earlier.
            if (clob.savedObject_ != null) {
              savedObject_ = clob.savedObject_;
              scale_ = clob.savedScale_;
              clob.savedObject_ = null;
              writeToServer();
              return;
            }
          }
        }

        // @G5A If the code for updateable lob locators did not run, then run old code.
        if (!set) {
          Clob clob = (Clob) object;
          int length = (int) clob.length();
          String substring = clob.getSubString(1, length);
          locator_.writeData(0L, converter_.stringToByteArray(substring), 0, length, true); // @K1C
          set = true;
        } else {
          JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH);
        }
      }
      /*ifdef JDBC40
      else if( object instanceof SQLXML ) //@PDA jdbc40
      {
          SQLXML xml = (SQLXML)object;

          String stringVal = xml.getString();
          locator_.writeData(0L, converter_.stringToByteArray(stringVal), 0, stringVal.length(), true);
      }
      endif */
      else {
        JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH);
      }
    } finally {
      savedObject_ = null;
    }
    scale_ = (int) locator_.getLength();
  }
Beispiel #10
0
  // @loch method to temporary convert from object input to output before even going to host
  // (writeToServer() does the conversion needed before writing to host)
  // This will only be used when resultSet.updateX(obj1) is called followed by a obj2 =
  // resultSet.getX()
  // Purpose is to do a local type conversion from obj1 to obj2 like other non-locator lob types
  private void doConversion() throws SQLException {
    int length_ = scale_;

    if (length_ == -1) {
      try {
        // try to get length from locator
        length_ = (int) locator_.getLength();
      } catch (Exception e) {
      }
    }

    try {
      Object object = savedObject_;
      if (savedObject_ instanceof String) {
        value_ = (String) object;
      } else if (object instanceof Reader) {
        if (length_ >= 0) {
          try {
            int blockSize =
                length_ < AS400JDBCPreparedStatement.LOB_BLOCK_SIZE
                    ? length_
                    : AS400JDBCPreparedStatement.LOB_BLOCK_SIZE;
            Reader stream = (Reader) object;
            StringBuffer buf = new StringBuffer();
            char[] charBuffer = new char[blockSize];
            int totalCharsRead = 0;
            int charsRead = stream.read(charBuffer, 0, blockSize);
            while (charsRead > -1 && totalCharsRead < length_) {
              buf.append(charBuffer, 0, charsRead);
              totalCharsRead += charsRead;
              int charsRemaining = length_ - totalCharsRead;
              if (charsRemaining < blockSize) {
                blockSize = charsRemaining;
              }
              charsRead = stream.read(charBuffer, 0, blockSize);
            }
            value_ = buf.toString();

            if (value_.length() < length_) {
              // a length longer than the stream was specified
              JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH);
            }
          } catch (IOException ie) {
            JDError.throwSQLException(this, JDError.EXC_INTERNAL, ie);
          }
        } else if (length_ == -2) // @readerlen new else-if block (read all data)
        {
          try {
            int blockSize = AS400JDBCPreparedStatement.LOB_BLOCK_SIZE;
            Reader stream = (Reader) object;
            StringBuffer buf = new StringBuffer();
            char[] charBuffer = new char[blockSize];
            int totalCharsRead = 0;
            int charsRead = stream.read(charBuffer, 0, blockSize);
            while (charsRead > -1) {
              buf.append(charBuffer, 0, charsRead);
              totalCharsRead += charsRead;
              charsRead = stream.read(charBuffer, 0, blockSize);
            }
            value_ = buf.toString();

          } catch (IOException ie) {
            JDError.throwSQLException(this, JDError.EXC_INTERNAL, ie);
          }
        } else {
          JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH);
        }
      } else if (object instanceof Clob) {
        Clob clob = (Clob) object;
        value_ = clob.getSubString(1, (int) clob.length());
      }
      /* ifdef JDBC40
       else if( object instanceof SQLXML )
       {
           SQLXML xml = (SQLXML)object;
           value_ = xml.getString();
       }
      endif */
      else {
        JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH);
      }

      // Truncate if necessary.
      int valueLength = value_.length();
      if (valueLength > maxLength_) {
        value_ = value_.substring(0, maxLength_);
      }
    } finally {
      // nothing
    }
  }
Beispiel #11
0
  // This method actually writes the data to the system.
  private void writeToServer() throws SQLException {
    if (savedObject_ instanceof byte[]) {
      byte[] bytes = (byte[]) savedObject_;
      locator_.writeData(0, bytes, true); // @K1A
    } else if (savedObject_ instanceof InputStream) {
      int length = scale_; // hack to get the length into the set method

      // Need to write even if there are 0 bytes in case we are batching and
      // the host server reuses the same handle for the previous locator; otherwise,
      // we'll have data in the current row from the previous row.
      if (length == 0) {
        locator_.writeData(0, new byte[0], 0, 0, true); // @K1A
      } else if (length > 0) {
        InputStream stream = (InputStream) savedObject_;
        int blockSize =
            length < AS400JDBCPreparedStatement.LOB_BLOCK_SIZE
                ? length
                : AS400JDBCPreparedStatement.LOB_BLOCK_SIZE;
        byte[] byteBuffer = new byte[blockSize];
        try {
          int totalBytesRead = 0;
          int bytesRead = stream.read(byteBuffer, 0, blockSize);
          while (bytesRead > -1 && totalBytesRead < length) {
            locator_.writeData(
                totalBytesRead,
                byteBuffer,
                0,
                bytesRead,
                true); // totalBytesRead is our offset.  @K1A
            totalBytesRead += bytesRead;
            int bytesRemaining = length - totalBytesRead;
            if (bytesRemaining < blockSize) {
              blockSize = bytesRemaining;
            }
            bytesRead = stream.read(byteBuffer, 0, blockSize);
          }

          if (totalBytesRead < length) {
            // a length longer than the stream was specified
            JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH);
          }
        } catch (IOException ie) {
          JDError.throwSQLException(this, JDError.EXC_INTERNAL, ie);
        }
      } else if (length == -2) // @readerlen new else-if block (read all data)
      {
        InputStream stream = (InputStream) savedObject_;
        int blockSize = AS400JDBCPreparedStatement.LOB_BLOCK_SIZE;
        byte[] byteBuffer = new byte[blockSize];
        try {
          int totalBytesRead = 0;
          int bytesRead = stream.read(byteBuffer, 0, blockSize);
          while (bytesRead > -1) {
            locator_.writeData(
                totalBytesRead,
                byteBuffer,
                0,
                bytesRead,
                true); // totalBytesRead is our offset.  @K1A
            totalBytesRead += bytesRead;

            bytesRead = stream.read(byteBuffer, 0, blockSize);
          }

        } catch (IOException ie) {
          JDError.throwSQLException(this, JDError.EXC_INTERNAL, ie);
        }
      } else {
        JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH);
      }
    } else if (JDUtilities.JDBCLevel_ >= 20
        && savedObject_ instanceof Blob) // @H0A check for jdbc level to know if lobs exist
    {
      // @A1C
      // @G5A Start new code for updateable locator case to go through the Vectors
      // @G5A and update the blob copy when ResultSet.updateBlob() is called.
      boolean set = false;
      if (savedObject_ instanceof AS400JDBCBlobLocator) {
        AS400JDBCBlobLocator blob = (AS400JDBCBlobLocator) savedObject_;

        // Synchronize on a lock so that the user can't keep making updates
        // to the blob while we are taking updates off the vectors.
        synchronized (blob) {
          // See if we saved off our real object from earlier.
          if (blob.savedObject_ != null) {
            savedObject_ = blob.savedObject_;
            scale_ = blob.savedScale_;
            blob.savedObject_ = null;
            writeToServer();
            return;
          }
        }
      }

      // @G5A If the code for updateable lob locators did not run, then run old code.
      if (!set) {
        Blob blob = (Blob) savedObject_; // @A1C
        int length = (int) blob.length();
        byte[] data = blob.getBytes(1, length);
        locator_.writeData(0, data, 0, length, true); // @K1A
      }
    } else {
      JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH);
    }
  }
 public void setHandle(int handle) {
   locator_.setHandle(handle);
   // @J5A reset savedObject after setting handle
   savedObject_ = null;
 }