Reference Guide > Custom Procedure Examples > Example 6: Output Cursor
 
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);
}
}