/*
   * Sets the locator persistence for a request. The persistence is typically
   * set to 1 (Scoped to transaction) but must be set to 0 (scoped to cursor)
   * if Auto commit is off and transaction isolation level isNONE.
   *
   * Should be called whenever autocommit level or isolation level is changed.
   *
   * @ABA
   *
   * This should be followed by a call to persistenceUpdated() after the
   * request returns successfully. This returns true if the request was
   * changed
   */
  private boolean setRequestLocatorPersistence(DBSQLAttributesDS request, int commitMode)
      throws DBDataStreamException {

    // transaction isolation is none, make sure locator persistence is
    // scoped to the cursor
    requestedLocatorPersistence_ = -1;
    if (serverAllowsLocatorPersistenceChange_) {
      if (commitMode == COMMIT_MODE_NONE_) {
        if (currentLocatorPersistence_ != 0) {
          request.setLocatorPersistence(0);
          requestedLocatorPersistence_ = 0;
          return true;
        }
      } else {
        if (currentLocatorPersistence_ != 1) {
          request.setLocatorPersistence(1);
          requestedLocatorPersistence_ = 1;
          return true;
        }
      }
    }
    return false;
  }
  /**
   * Sets whether to enable the local transaction. XA support needs this to be false so that
   * commit(), rollback(), etc. can not be called directly on this object.
   *
   * @param enableLocalTransaction true to enable the local transaction, false otherwise.
   * @exception SQLException If the connection is not open or an error occurs.
   */
  void setLocalTransaction(boolean enableLocalTransaction) throws SQLException {
    localTransaction_ = enableLocalTransaction;

    // Auto commit is disabled while in a distributed transaction.
    if (localTransaction_) {
      autoCommit_ = localAutoCommit_; // prior to XA_START autocommit setting
      if (connection_.newAutoCommitSupport_ == 0)
        setCommitMode(currentCommitMode_); // turn back on auto-commit
      else {
        DBSQLAttributesDS request = null;
        DBReplyRequestedDS reply = null;
        try {
          request =
              DBDSPool.getDBSQLAttributesDS(
                  DBSQLAttributesDS.FUNCTIONID_SET_ATTRIBUTES,
                  id_,
                  DBBaseRequestDS.ORS_BITMAP_RETURN_DATA
                      + DBBaseRequestDS.ORS_BITMAP_SERVER_ATTRIBUTES,
                  0);

          request.setAutoCommit(
              autoCommit_
                  ? 0xE8
                  : 0xD5); // @PDC change autocommit setting to prior setting before XA_START

          boolean changed = false;
          if (connection_.newAutoCommitSupport_ == 1 && autoCommit_ == true) // @PDC
          {
            request.setCommitmentControlLevelParserOption(COMMIT_MODE_NONE_);
            changed = setRequestLocatorPersistence(request, COMMIT_MODE_NONE_); /*@ABA*/

            serverCommitMode_ = COMMIT_MODE_NONE_;
          }

          reply = connection_.sendAndReceive(request);
          int errorClass = reply.getErrorClass();
          int returnCode = reply.getReturnCode();
          if (errorClass != 0 && changed) {
            // Retry request if this fails.
            serverAllowsLocatorPersistenceChange_ = false;
            request.returnToPool();
            request = null;
            reply.returnToPool();
            reply = null;

            request =
                DBDSPool.getDBSQLAttributesDS(
                    DBSQLAttributesDS.FUNCTIONID_SET_ATTRIBUTES,
                    id_,
                    DBBaseRequestDS.ORS_BITMAP_RETURN_DATA
                        + DBBaseRequestDS.ORS_BITMAP_SERVER_ATTRIBUTES,
                    0);

            request.setAutoCommit(
                autoCommit_
                    ? 0xE8
                    : 0xD5); // @PDC change autocommit setting to prior setting before XA_START

            if (connection_.newAutoCommitSupport_ == 1 && autoCommit_ == true) // @PDC
            {
              request.setCommitmentControlLevelParserOption(COMMIT_MODE_NONE_);
              serverCommitMode_ = COMMIT_MODE_NONE_;
            }
            reply = connection_.sendAndReceive(request);
            errorClass = reply.getErrorClass();
            returnCode = reply.getReturnCode();
          }
          if (errorClass != 0) JDError.throwSQLException(connection_, id_, errorClass, returnCode);
          persistenceUpdated();
        } catch (DBDataStreamException e) {
          JDError.throwSQLException(JDError.EXC_INTERNAL, e);
        } finally {
          if (request != null) {
            request.returnToPool();
            request = null;
          }
          if (reply != null) {
            reply.returnToPool();
            reply = null;
          } // Only errorClass used from reply
        }
      }

    } else {
      localAutoCommit_ = autoCommit_;
      autoCommit_ = false;
      if (connection_.newAutoCommitSupport_
          == 0) // @KBA   System is v5r2 or less, do what we always have
      setCommitMode(currentCommitMode_);
      else // @KBA
      {
        DBSQLAttributesDS request = null; // @KBA
        DBReplyRequestedDS reply = null; // @KBA
        try // @KBA
        { // @KBA
          // auto commit is always false when we are in here so we will run under default or
          // specified isolation level
          request =
              DBDSPool.getDBSQLAttributesDS(
                  DBSQLAttributesDS.FUNCTIONID_SET_ATTRIBUTES,
                  id_,
                  DBBaseRequestDS.ORS_BITMAP_RETURN_DATA
                      + DBBaseRequestDS.ORS_BITMAP_SERVER_ATTRIBUTES,
                  0); // @KBA
          request.setAutoCommit(0xD5); // @KBA turn off auto commit
          if (serverCommitMode_ != currentCommitMode_) // @KBA
          request.setCommitmentControlLevelParserOption(getIsolationLevel()); // @KBA
          boolean changed = setRequestLocatorPersistence(request, getIsolationLevel()); /*@ABA*/

          reply = connection_.sendAndReceive(request); // @KBA
          int errorClass = reply.getErrorClass(); // @KBA
          int returnCode = reply.getReturnCode(); // @KBA
          if (errorClass != 0 && changed) {
            // Retry request if this fails.
            serverAllowsLocatorPersistenceChange_ = false;
            request.returnToPool();
            request = null;
            reply.returnToPool();
            reply = null;
            request =
                DBDSPool.getDBSQLAttributesDS(
                    DBSQLAttributesDS.FUNCTIONID_SET_ATTRIBUTES,
                    id_,
                    DBBaseRequestDS.ORS_BITMAP_RETURN_DATA
                        + DBBaseRequestDS.ORS_BITMAP_SERVER_ATTRIBUTES,
                    0); // @KBA
            request.setAutoCommit(0xD5); // @KBA turn off auto commit
            if (serverCommitMode_ != currentCommitMode_) // @KBA
            request.setCommitmentControlLevelParserOption(getIsolationLevel()); // @KBA

            reply = connection_.sendAndReceive(request); // @KBA
            errorClass = reply.getErrorClass(); // @KBA
            returnCode = reply.getReturnCode(); // @KBA
          }
          if (errorClass != 0) // @KBA
          JDError.throwSQLException(connection_, id_, errorClass, returnCode); // @KBA
          persistenceUpdated();
        } // @KBA
        catch (DBDataStreamException e) // @KBA
        { // @KBA
          JDError.throwSQLException(JDError.EXC_INTERNAL, e); // @KBA
        } // @KBA
        finally // @KBA
        { // @KBA
          if (request != null) {
            request.returnToPool();
            request = null;
          } // @KBA
          if (reply != null) {
            reply.returnToPool();
            reply = null;
          } // @KBA
        } // @KBA
        serverCommitMode_ = currentCommitMode_; // @KBA
      }
    }
  }
  /**
   * Change the transaction isolation level using one of the java.sql.Connection.TRANSACTION_*
   * values.
   *
   * @param level One of the java.sql.Connection.TRANSACTION_* values with the exception of
   *     TRANSACTION_NONE.
   * @exception SQLException If an error occurs, an invalid or unsupported level is input, or a
   *     transaction is active.
   */
  void setIsolation(int level) throws SQLException {
    // This is invalid if a transaction is active.
    if (activeLocal_ && connection_.newAutoCommitSupport_ == 0) // @C4C   //@KBC
    JDError.throwSQLException(JDError.EXC_TXN_STATE_INVALID); // @C4C

    // @C7D We do not allow TRANSACTION_NONE at this time.
    // @C7D if (level == Connection.TRANSACTION_NONE)
    // @C7D   JDError.throwSQLException (JDError.EXC_ATTRIBUTE_VALUE_INVALID);

    // Save the isolation level.
    currentCommitMode_ = mapLevelToCommitMode(level);
    currentIsolationLevel_ = level;

    // Set the commit mode on the system.
    if (connection_.newAutoCommitSupport_
        == 0) // @KBA OS/400 V5R2 or earlier do what we always have
    setCommitMode(currentCommitMode_);
    else // @KBA use new auto commit and commit level support
    { // @KBA
      DBSQLAttributesDS request = null; // @KBA
      DBReplyRequestedDS reply = null; // @KBA
      int commitMode = currentCommitMode_;
      try // @KBA
      { // @KBA
        if (autoCommit_ && connection_.newAutoCommitSupport_ == 1) commitMode = COMMIT_MODE_NONE_;
        if (serverCommitMode_ != commitMode) // @KBA
        { // @KBA
          request =
              DBDSPool.getDBSQLAttributesDS(
                  DBSQLAttributesDS.FUNCTIONID_SET_ATTRIBUTES,
                  id_,
                  DBBaseRequestDS.ORS_BITMAP_RETURN_DATA
                      + DBBaseRequestDS.ORS_BITMAP_SERVER_ATTRIBUTES,
                  0); // @KBA
          request.setCommitmentControlLevelParserOption(getIsolationLevel()); // @KBA
          boolean changed = setRequestLocatorPersistence(request, getIsolationLevel()); /*@ABA*/

          reply = connection_.sendAndReceive(request); // @KBA
          int errorClass = reply.getErrorClass(); // @KBA
          int returnCode = reply.getReturnCode(); // @KBA
          if (errorClass != 0 && changed) {
            // Retry request if this fails.
            serverAllowsLocatorPersistenceChange_ = false;
            request.returnToPool();
            request = null;
            reply.returnToPool();
            reply = null;
            request =
                DBDSPool.getDBSQLAttributesDS(
                    DBSQLAttributesDS.FUNCTIONID_SET_ATTRIBUTES,
                    id_,
                    DBBaseRequestDS.ORS_BITMAP_RETURN_DATA
                        + DBBaseRequestDS.ORS_BITMAP_SERVER_ATTRIBUTES,
                    0); // @KBA
            request.setCommitmentControlLevelParserOption(getIsolationLevel()); // @KBA

            reply = connection_.sendAndReceive(request); // @KBA
            errorClass = reply.getErrorClass(); // @KBA
            returnCode = reply.getReturnCode(); // @KBA
          }
          if (errorClass != 0) // @KBA
          JDError.throwSQLException(connection_, id_, errorClass, returnCode); // @KBA
          persistenceUpdated();
        } // @KBA
      } // @KBA
      catch (DBDataStreamException e) // @KBA
      { // @KBA
        JDError.throwSQLException(JDError.EXC_INTERNAL, e); // @KBA
      } // @KBA
      finally // @KBA
      { // @KBA
        if (request != null) {
          request.returnToPool();
          request = null;
        } // @KBA
        if (reply != null) {
          reply.returnToPool();
          reply = null;
        } // @KBA
      } // @KBA
      serverCommitMode_ =
          commitMode; // @KBA    Note:  This may not be what the user set it to, if the user want to
                      // always run auto commit with the *NONE isolation level
    } // @KBA
  }
  /**
   * Set the auto-commit mode.
   *
   * @param autoCommit true to turn on auto-commit mode, false to turn it off.
   * @exception SQLException If an error occurs.
   */
  void setAutoCommit(boolean autoCommit) throws SQLException {
    // If we are in a distributed transaction, then reject a request           @C4A
    // to turn on auto-commit.  If we are supposed to turn it off,             @C4A
    // then just remember for when we are out of the distributed               @C4A
    // transaction, since the database won't let us do any transaction           @C4A
    // stuff during the distributed transaction.                               @C4A
    if (!localTransaction_) { // @C4A
      if (autoCommit == true) // @C4A
      JDError.throwSQLException(JDError.EXC_TXN_STATE_INVALID); // @C4A
      else // @C4A
      localAutoCommit_ = false; // @C4A
    } // @C4A

    // If we are in the local transaction, just go ahead and set it.           @C4A
    else { // @C4A

      // If going from false to true, then commit any outstanding
      // transaction.
      if (!autoCommit_ && autoCommit && activeLocal_) { // @C4C
        commit();
        connection_.postWarning(JDError.getSQLWarning(JDError.WARN_TXN_COMMITTED));
      }

      // Save the auto commit state.
      autoCommit_ = autoCommit;

      // @C5D if (newAutoCommitSupport_) {                                                    //
      // @C5A
      // @C5D     try {                                                                       //
      // @C5A
      // @C5D 		DBSQLAttributesDS request = new DBSQLAttributesDS(                      // @C5A
      // @C5D 		    DBSQLAttributesDS.FUNCTIONID_SET_ATTRIBUTES,                        // @C5A
      // @C5D 		    id_, DBBaseRequestDS.ORS_BITMAP_RETURN_DATA, 0, 0);                 // @C5A
      // @C5D         request.setAutoCommit(autoCommit ? 1 : 0);                              //
      // @C5A
      // @C5D 		DBReplyRequestedDS reply = connection_.sendAndReceive(request);         // @C5A
      // @C5D 		int errorClass = reply.getErrorClass();                                 // @C5A
      // @C5D 		int returnCode = reply.getReturnCode();                                 // @C5A
      // @C5D 		if (errorClass != 0)                                                    // @C5A
      // @C5D 			JDError.throwSQLException(connection_, id_, errorClass, returnCode);// @C5A
      // @C5D 	}                                                                           // @C5A
      // @C5D 	catch (DBDataStreamException e) {                                           // @C5A
      // @C5D 		JDError.throwSQLException (JDError.EXC_INTERNAL, e);                    // @C5A
      // @C5D     }                                                                           //
      // @C5A
      // @C5D }                                                                               //
      // @C5A
      // @C5D else                                                                            //
      // @C5A

      if (connection_.newAutoCommitSupport_
          == 0) // @KBA OS/400 V5R2 or earlier do what we always have
      setCommitMode(currentCommitMode_);
      else // @KBA use new auto commit support
      { // @KBA
        DBSQLAttributesDS request = null; // @KBA
        DBReplyRequestedDS reply = null; // @KBA
        try // @KBA
        { // @KBA
          request =
              DBDSPool.getDBSQLAttributesDS(
                  DBSQLAttributesDS.FUNCTIONID_SET_ATTRIBUTES,
                  id_,
                  DBBaseRequestDS.ORS_BITMAP_RETURN_DATA
                      + DBBaseRequestDS.ORS_BITMAP_SERVER_ATTRIBUTES,
                  0); // @KBA
          request.setAutoCommit(autoCommit ? 0xE8 : 0xD5); // @KBA  Set auto commit to on or off
          request.setCommitmentControlLevelParserOption(
              getIsolationLevel()); // @KBA  Set isolation level
          if (autoCommit_ && connection_.newAutoCommitSupport_ == 1)
            serverCommitMode_ = COMMIT_MODE_NONE_;
          else serverCommitMode_ = currentCommitMode_;

          boolean changed = setRequestLocatorPersistence(request, getIsolationLevel()); /*@ABA*/
          reply = connection_.sendAndReceive(request); // @KBA
          int errorClass = reply.getErrorClass(); // @KBA
          int returnCode = reply.getReturnCode(); // @KBA
          if (errorClass != 0 && changed) {
            // Try again for the case where the server does not support the change
            serverAllowsLocatorPersistenceChange_ = false;
            request.returnToPool();
            request = null;
            reply.returnToPool();
            reply = null;
            request =
                DBDSPool.getDBSQLAttributesDS(
                    DBSQLAttributesDS.FUNCTIONID_SET_ATTRIBUTES,
                    id_,
                    DBBaseRequestDS.ORS_BITMAP_RETURN_DATA
                        + DBBaseRequestDS.ORS_BITMAP_SERVER_ATTRIBUTES,
                    0); // @KBA
            request.setAutoCommit(autoCommit ? 0xE8 : 0xD5); // @KBA  Set auto commit to on or off
            request.setCommitmentControlLevelParserOption(
                getIsolationLevel()); // @KBA  Set isolation level
            if (autoCommit_ && connection_.newAutoCommitSupport_ == 1)
              serverCommitMode_ = COMMIT_MODE_NONE_;
            else serverCommitMode_ = currentCommitMode_;
            reply = connection_.sendAndReceive(request); // @KBA
            errorClass = reply.getErrorClass(); // @KBA
            returnCode = reply.getReturnCode(); // @KBA
          }

          if (errorClass != 0) // @KBA
          JDError.throwSQLException(connection_, id_, errorClass, returnCode); // @KBA
          persistenceUpdated();

        } // @KBA
        catch (DBDataStreamException e) // @KBA
        { // @KBA
          JDError.throwSQLException(JDError.EXC_INTERNAL, e); // @KBA
        } // @KBA
        finally // @KBA
        { // @KBA
          if (request != null) {
            request.returnToPool();
            request = null;
          } // @KBA
          if (reply != null) {
            reply.returnToPool();
            reply = null;
          } // @KBA
        } // @KBA
      } // @KBA
    } // @C4A
  }