public IPentahoResultSet doQuery(
      final SQLConnection sqlConnection, final String query, boolean forwardOnlyResultset)
      throws Exception {
    //
    // At this point, 'connection' and 'sqlConnection' should be pointers to
    // the same object iff the 'connection' is a subclass of pentaho's SQLConnection.
    // It is possible that the sqlConnection will be null, but the connection
    // won't be if someone is using their own implementation of the SQLConnection from
    // the factory.
    //

    IPentahoResultSet resultSet = null;
    if (ComponentBase.debug) {
      dumpQuery(query);
    }

    if (preparedParameters.size() > 0) {
      if (!forwardOnlyResultset) {
        resultSet = connection.prepareAndExecuteQuery(query, preparedParameters);
      } else {
        if (sqlConnection != null) {
          resultSet =
              sqlConnection.prepareAndExecuteQuery(
                  query,
                  preparedParameters,
                  SQLConnection.RESULTSET_FORWARDONLY,
                  SQLConnection.CONCUR_READONLY);
        } else {
          throw new IllegalStateException(
              Messages.getInstance()
                  .getErrorString(
                      "SQLBaseComponent.ERROR_0008_UNSUPPORTED_CURSOR_TYPE")); //$NON-NLS-1$
        }
      }
    } else {
      if (!forwardOnlyResultset) {
        resultSet = connection.executeQuery(query);
      } else {
        if (sqlConnection != null) {
          resultSet =
              sqlConnection.executeQuery(
                  query, SQLConnection.RESULTSET_FORWARDONLY, SQLConnection.CONCUR_READONLY);
        } else {
          throw new IllegalStateException(
              Messages.getInstance()
                  .getErrorString(
                      "SQLBaseComponent.ERROR_0008_UNSUPPORTED_CURSOR_TYPE")); //$NON-NLS-1$
        }
      }
    }
    return resultSet;
  }
  /**
   * executes a prepared method that returns a result set executePrepared looks up any
   * "PREPARELATER" params in the preparedParams map.
   *
   * @param preparedParams a map of possible parameters.
   * @return result set
   */
  public IPentahoResultSet executePrepared(final Map preparedParams) {
    try {
      if (connection == null) {
        error(
            Messages.getInstance()
                .getErrorString("SQLBaseComponent.ERROR_0007_NO_CONNECTION")); // $NON-NLS-1$
        return null;
      }
      if (!connection.initialized()) {
        error(
            Messages.getInstance()
                .getErrorString("SQLBaseComponent.ERROR_0007_NO_CONNECTION")); // $NON-NLS-1$
        return null;
      }

      if (preparedQuery == null) {
        error(
            Messages.getInstance()
                .getErrorString(
                    "SQLBaseComponent.ERROR_0001_QUERY_NOT_SPECIFIED",
                    getActionName())); //$NON-NLS-1$
        return null;
      }

      // copy the preparedParams list, so it can be used multiple times.
      ArrayList copyOfPreparedParameters = new ArrayList(preparedParameters);

      // parse preparedQuery, replacing any {PREPARELATER:NAME} with appropriate values
      String query =
          TemplateUtil.applyTemplate(
              preparedQuery,
              getRuntimeContext(),
              new ParamResolver(copyOfPreparedParameters, preparedParams));

      if (ComponentBase.debug) {
        dumpQuery(query);
      }

      // evaluate
      IPentahoResultSet resultSet = null;
      if (preparedParameters.size() > 0) {
        resultSet = connection.prepareAndExecuteQuery(query, copyOfPreparedParameters);
      } else {
        resultSet = connection.executeQuery(query);
      }

      if (connection instanceof SQLConnection) {
        if (((SQLConnection) connection).isForcedForwardOnly()) {
          warn(
              Messages.getInstance()
                  .getString("SQLBaseComponent.WARN_FALL_BACK_TO_NONSCROLLABLE")); // $NON-NLS-1$
        }
      }

      boolean live = true;
      IActionDefinition actionDefinition = getActionDefinition();
      if (actionDefinition instanceof AbstractRelationalDbAction) {
        AbstractRelationalDbAction relationalDbAction =
            (AbstractRelationalDbAction) actionDefinition;
        live = relationalDbAction.getLive().getBooleanValue(false);
      }

      IPentahoResultSet rs = resultSet;

      // BISERVER-5915, BISERVER-5875 - if the live setting is false, return an in memory resultset.
      if (!live) {
        rs = resultSet.memoryCopy();
      }

      rSet = rs;
      return rs;

    } catch (Exception e) {
      error(
          Messages.getInstance()
              .getErrorString("SQLBaseComponent.ERROR_0006_EXECUTE_FAILED", getActionName()),
          e); //$NON-NLS-1$
    }
    return null;
  }