package org.jcon.df.request;

//import org.jcon.df.Entity;
import org.jcon.df.Schema;
import org.jcon.df.work.Row;
import org.jcon.util.DataLib;
import org.jcon.param.Param;
import org.jcon.test.TestJDBC;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Enumeration;
import java.util.Vector;

/**
 * A request to read a row set from the database.
 * Currently Param driven via setParam();
 * If the filter is null all rows are included.
 * The client does not need to call prepare().
 *
 * @author Jack Harich
 */
public class ReadRowSet extends DataRequest {

//---------- Private Fields ------------------------------
// *** Currently we use a Vector rather than a remote
// object, which would handle larger result sets
//private ResultRowSet resultRowSet; // Remote, later
// Since this is performed locally, it doesn't matter
private Vector rows = new Vector();
private int    index;

//---------- Initialization ------------------------------
public static void main(String args[]) {
    new ReadRowSet().runUnitTest();
}
//---------- Abstract Implementation ---------------------
public boolean isMutator() {
    return false;
}
public Object perform() {
    String text = ".";
    String sql = null;
    try {
        // Prepare reader  - set properties, execute
        ResultSetReader reader = new ResultSetReader();
        reader.setSchema(requestServices.getSchema());
        String[] colIDs = DataLib.convertVectorToStringArray(getColumnIDs());
        reader.setColumnIDs(colIDs);
        reader.setStatement(requestServices.getStatement());
        // Get sql and execute
        sql = requestServices.getTranslator().buildSelectStm(this);
        //print(".perform() - translator built: " + sql + "\n");
        reader.setSQL(sql);
        text = " in ResultSetReader.";
            reader.execute(); // throws SQLException
        text = ".";
        // Prepare rows
        rows.removeAllElements();
        index = 0;
        // Use reader
        Row row = reader.nextRow();
        while (row != null) {
            //print(" reading: " + row);
            rows.addElement(row);
            row = reader.nextRow();
        }
    } catch(Exception ex) {
        //ex.printStackTrace();
        this.setFailureText("Cannot read row set" + text);
        this.setFailureSQL(sql);
        this.setFailureException(ex);
    }
    return this;
}
//---------- Properties ----------------------------------
/**
 * This is an alternative to setting properties, allowing
 * a parameter driven ReadRowSet. It overrides all properties.
 */
public void setParam(Param param, Schema schema) {
    clear();
    // columnIDs
    Vector lines = param.getVector("ColumnIDs");
    for (int i = 0; i < lines.size(); i++) {
        String line = (String)lines.elementAt(i);
        //print(".setParam() - columnID line: '" + line + "'");
        if (line.endsWith(".*")) {
            addAllColumnIDs(line, schema);
        } else {
            addColumnID(line);
        }
    }
    // entityNames
    addEntities(param.getString("Entities"));
    // sortBy
    setSortBy(param.getString("SortBy")); // null if none
    // joins
    if (param.hasProperty("Joins")) {
        Vector joinLines = param.getVector("Joins");
        for (int i = 0; i < joinLines.size(); i++) {
            addJoin((String)joinLines.elementAt(i));
        }
    }
    // filter
    if (param.hasProperty("FilterLine")) {
        //print(".setParam() - setting filter: " + param.getString("FilterLine"));
        setFilterLine(param.getString("FilterLine"));
    }
}
/**     SAMPLE PARAM
    DataRequest has:
        ColumnIDs hasLines:
            SysUser.*
            End: ColumnIDs
        Entities is: SysUser
        SortBy is: LastName, FirstName DESC
        FilterLine is: (A = 1 OR B = 2) AND C LIKE D*
        End: DataRequest
    End: SysUserSource
*/
//---------- Public Methods ------------------------------
//----- Result set reader methods
public boolean hasMoreRows() {
    return (index < rows.size() ? true : false);
}
public Row nextRow() {
    return (Row)rows.elementAt(index++);
}
public void close() {
    rows.removeAllElements();
}
//----- Other
public void runUnitTest() {
    TestJDBC tester = new TestJDBC();

    // Prepare reader
    ReadRowSet reader = new ReadRowSet();
    reader.addColumnID("SysUser.MID");
    reader.addColumnID("SysUser.FirstName");
    reader.addColumnID("SysUser.LastLogon");
    reader.addEntity("SysUser");
    // No need to set Translator properties
    reader.perform();
    // Use reader
    while (reader.hasMoreRows()) {
        Row row = reader.nextRow();
        print("Rowx = " + row);
    }
    // Done
    reader.close();
    tester.close();
}
//---------- Properties ----------------------------------

//---------- Private Methods -----------------------------
//--- Std
private static void print(String text) {
    System.out.println("ReadRowSet" + text);
}

} // End class
