WepsResultSet.java [src/usda/weru/weps/reports/query] Revision: default  Date:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package usda.weru.weps.reports.query;

import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author joelevin
 */
public abstract class WepsResultSet /*extends SimpleResultSet*/{
    
    public abstract void fill();
    
    public abstract String getName();
    
    ////////////////////////////////////////////////////////////////////////////
    // New member variables.

    // Arrays to hold column info.
    protected ArrayList<String>  m_Columns;
    protected ArrayList<Integer>  m_SqlTypes;
    
    // Fake database connection.
    WepsConnection m_con;
    
    ////////////////////////////////////////////////////////////////////////////
    // Member functions which were previously inherited from SimpleResultSet.
    
    WepsResultSet(WepsConnection con) {
        m_Columns  = new ArrayList<String>();
        m_SqlTypes = new ArrayList<Integer>();
        //
        m_con = con;
    }
    
    /**
     * Create a new column in the data model of the given type.
     * @param name - null is replaced with C1, C2,...
     * @param sqlType - the value returned in getColumnType(..) (ignored internally)
     *                  These are constants defined in class java.sql.Types.
     * @param precision - the precision
     * @param scale - the scale
     * @note This function was inherited from SimpleResultSet.
     */
    public void addColumn(String name, int sqlType, int precision, int scale) {
        // Add info for this column. Discard the "precision" and "scale" arguments.
        m_Columns.add(name);
        m_SqlTypes.add(sqlType);
        
        // Add an empty map entry for an array of this type in the "connection"?
        // We need to restore the connection parameter to do this.
        // This allows all parameters to live in a single object.
        ArrayList<Object> list = new ArrayList<Object> ();
        m_con.m_ParamValues.put(name, list);        
    }

    /**
     * Returns the column count.
     * @return the column count
     */
    public int getColumnCount() {
        int nCount = m_Columns.size();
        assert(m_Columns.size() == m_SqlTypes.size()): "error: sizes of m_Columns and m_SqlTypes disagree.\n";
        return nCount;
    }
    
    /**
     * Add a new row to the result set. Do not use this method when using a RowSource.
     * @param row - the row as an array of objects
     */
    public void addRow(Object[] row) {
        int rowLength = row.length;
        assert(rowLength == m_Columns.size()): "assert: attempt to add different number of columns.";
        // Iterate through the columns in this row.
        for (int i=0; i<rowLength; i++) {
            // Get the name of the column.
            String sColumn = m_Columns.get(i);
           
            // Get the type of the column.
            int nType = m_SqlTypes.get(i);
            
            // Note: the row holds Objects directly, so there is no need to do data conversion.
            
            // @todo check the type of the data value against the value of nType.

            ArrayList<Object> list = m_con.m_ParamValues.get(sColumn); // This list having a null in it is where they are coming from.
            if (list != null) {
                // Append the value to the array.
                Object data = row[i];
                list.add(data);
                m_con.m_ParamValues.put(sColumn, list);
            }
        }
    }
    
    /**
     * Searches for a specific column in the result set.
     *
     * @param columnLabel the column name to search for. It should have already
     * been added by addColumn().
     * @return the 1-based index of the column. Returns -1 on error.
     */
    int findColumn(String columnLabel) {
        // Find the column index from its name.
        for (int i = 0; i < m_Columns.size(); i++) {
            String sColumn = m_Columns.get(i);
            if (sColumn.equals(columnLabel)) {
                return i+1;
            }
        }

        return -1;
    }
    
    ////////////////////////////////////////////////////////////////////////////
    
    /**
     * Creates a new Object array the size of the resultset getColumnCount().       
     * @param add If true, the row will be added to the resultset
     * @return an empty object array.
     */
    protected Object[] createNewRow(boolean add){ // if true this adds an empty value from the empty array it is passing back.
        Object[] row = new Object[getColumnCount()];
        if (add){
            addRow(row);
        }
        return row;
    }
    
    /**
     * Convenience method for adding values based on their column names.  Slight 
     * performance hit is to be expected, but helps prevent programming errors
     * due to future column reordering.
     * @param row 
     * @param columnName column label to be resolved to the 0 based index.
     * @param value Object to store
     */
    protected void setRowValue(Object[] row, String columnName, Object value){
        int index = findColumn(columnName) - 1;
        row[index] = value;
    }

    protected <T> T getRowValue(Object[] row, String columnName){
        int index = findColumn(columnName) - 1;
        return (T) row[index];
    }
    
}