Example 6: Output Cursor

This custom procedure invokes another procedure, and retrieves output values.

package proc;
import com.compositesw.extension.*;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.sql.Types;
public class OutputCursor
  implements CustomProcedure, java.io.Serializable
{
  private transient ExecutionEnvironment qenv;
  private transient CustomCursor outputCursor;
  private boolean invoked;
  public OutputCursor() { }
  /**
   * This is called once just after constructing the class. The
   * environment contains methods used to interact with the server.
   */
  public void initialize(ExecutionEnvironment qenv)
    throws SQLException
  {
    this.qenv = qenv;
  }
  /**
   * Called during introspection to get the description of the input
   * and output parameters. Should not return null.
   */
  public ParameterInfo[] getParameterInfo() {
    return new ParameterInfo[] {
      new ParameterInfo("result", TYPED_CURSOR, DIRECTION_OUT,
        new ParameterInfo[] {
          new ParameterInfo("IntColumn", Types.INTEGER, DIRECTION_NONE),
          new ParameterInfo("StringColumn", Types.VARCHAR, DIRECTION_NONE),
          new ParameterInfo("TimestampColumn", Types.TIMESTAMP, DIRECTION_NONE),
        })
    };
  }
  /**
   * Called to invoke the stored procedure. Will only be called a
   * single time per instance. Can throw CustomProcedureException or
   * SQLException if there is an error during invoke.
   */
  public void invoke(Object[] inputValues)
    throws CustomProcedureException, SQLException
  {
    invoked = true;
  }
  /**
   * Called to retrieve the number of rows that were inserted,
   * updated, or deleted during the execution of the procedure. A
   * return value of -1 indicates that the number of affected rows is
   * unknown. Can throw CustomProcedureException or SQLException if
   * there is an error when getting the number of affected rows.
   */
  public int getNumAffectedRows() {
    return 0;
  }
  /**
   * Called to retrieve the output values. The returned objects
   * should obey the Java to SQL typing conventions as defined in the
   * table above. Output cursors can be returned as either
   * CustomCursor or java.sql.ResultSet. Can throw
   * CustomProcedureException or SQLException if there is an error
   * when getting the output values. Should not return null.
   */
  public Object[] getOutputValues() {
    outputCursor = createCustomCursor();
    return new Object[] { outputCursor };
  }
  /**
   * Create a custom cursor output.
   */
  private static CustomCursor createCustomCursor() {
    return new CustomCursor() {
      private int counter;
      public ParameterInfo[] getColumnInfo() {
    return null;
      }
      public Object[] next()
        throws CustomProcedureException, SQLException
      {
        if (counter++ >= 10) {
          return null;
        }
        else {
          return new Object[] {
            new Integer(counter),
            Integer.toString(counter),
            new Timestamp(counter),
          };
        }
      }
      public void close()
        throws CustomProcedureException, SQLException
      {
        // do nothing
      }
    };
  }
  /**
   * Called when the procedure reference is no longer needed. Close
   * can be called without retrieving any of the output values (such
   * as cursors) or even invoking, so this needs to do any remaining
   * cleanup. Close can be called concurrently with any other call
   * such as "invoke" or "getOutputValues". In this case, any pending
   * methods should immediately throw a CustomProcedureException.
   */
public void close()
    throws CustomProcedureException, SQLException
  {
    if (outputCursor != null)
      outputCursor.close();
  }
  //
  // Introspection methods
  //
  /**
   * Called during introspection to get the short name of the stored
   * procedure. This name can be overridden during configuration.
   * Should not return null.
   */
  public String getName() {
    return "OutputCursor";
  }
  /**
   * Called during introspection to get the description of the stored
   * procedure. Should not return null.
   */
  public String getDescription() {
    return "Custom procedure that returns cursor data";
  }
  //
  // Transaction methods
  //
  /**
   * Returns true if the custom procedure uses transactions. If this
   * method returns false then commit and rollback will not be called.
   */
  public boolean canCommit() {
    return true;
  }
  /**
   * Commit any open transactions.
   */
  public void commit()
    throws SQLException
  { }
  /**
   * Rollback any open transactions.
   */
  public void rollback()
    throws SQLException
  { }
  /**
   * Returns true if the transaction can be compensated.
   */
  public boolean canCompensate() {
    return true;
  }
  /**
   * Compensate any committed transactions (if supported).
   */
  public void compensate(ExecutionEnvironment qenv)
    throws SQLException
  {
    System.out.println("OutputCursor.compensate(): invoked=" + invoked);
  }
}