Exemplo n.º 1
0
  public Clob getClob() 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 new AS400JDBCClob(value_, maxLength_); // @loch
    } // @loch

    AS400JDBCClobLocator locatorReturn =
        new AS400JDBCClobLocator(new JDLobLocator(locator_), converter_, savedObject_, scale_);
    if (ConvTable.isMixedCCSID(converter_.ccsid_)) {
      // Since this is a mixed CCSID, the locator APIs with length, etc.. do not work correctly
      // @J5A We read the whole thing and convert to a local clob.
      savedObject_ = locatorReturn.getSubString((long) 1, (int) locatorReturn.length());
      return new AS400JDBCClob((String) savedObject_, maxLength_); // @loch
    }

    return locatorReturn;
  }
Exemplo n.º 2
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();
  }