package org.jcon.df.request;

import org.jcon.df.work.Row;
import org.jcon.util.GenLib;
import java.sql.Statement;
import java.util.Enumeration;

/**
 * A request to add a row to an entity.
 *
 * @author Jack Harich
 */
public class AddOneRow extends DataRequest {

//---------- Private Fields ------------------------------
private Row    row;
private String newMID;
private String entityName;

//---------- Abstract Implementation ---------------------
public boolean isMutator() {
    return true;
}
// prepare() not used since need newMID on server
public Object perform() {
    //print(".perform() entering: " + getState());
    String sql = null;
    try {
        // Preconditions
        if (row == null) {
            throw new IllegalStateException("Failure to" +
            " set row.\nCannot add row without a row.");
        }
        if (entityName == null) {
            throw new IllegalStateException("Failure to" +
            " set entityName.\nCannot add row without an entityName.");
        }
        // Prep - newMID
        newMID = requestServices.createMID(entityName);
        //print(".perform() - newMID = " + newMID);
        if (newMID == null) {
            throw new IllegalStateException("Failure to" +
            " set newMID.\nCannot add row without an MID.");
        }
        addInsertColumn(entityName + ".MID", newMID);
        // Prep - TStamp - DUPECODE with UpdateRow
        if (! requestServices.getTranslator()
            .getTranslatorType().isAutomaticTimeStamp()) {
            // Update TStamp manually
            String timeStamp = GenLib.createCurrentDateTime();
            this.setInsertColumn(entityName + ".TStamp", timeStamp);
        }
        // Translate sql
        sql = requestServices.getTranslator().buildInsertStm(this);
        //print(" - sql = " + sql);
        // Execute
        requestServices.getStatement().executeUpdate(sql);

    } catch(Exception ex) {
        GenLib.exception("AddRow.perform()",
            "Cannot add row using SQL: " + sql, ex);
        this.setFailureText("Cannot add row.");
        this.setFailureSQL(sql);
        this.setFailureException(ex);
    }
    //print(".perform() leaving: " + getState());
    return this;
}
//---------- Properties ----------------------------------
/**
 * Sets the row to be added. This should already be
 * validated by the row's entity. The MID is not yet
 * supplied at this point, so the row is incomplete.
 */
public void setRow(Row newRow) {
    row = newRow;
    // Use row to add insert columns
    Enumeration enum = row.getColumnIDs();
    while (enum.hasMoreElements()) {
        String columnID = (String)enum.nextElement();
        String value = (String)row.getValue(columnID);
        addInsertColumn(columnID, value);
    }
}
/**
 * Specifies the entity the row will be added to.
 */
public void setEntityName(String entityName) {
    if (this.entityName == null) {
        addEntity(entityName);
        this.entityName = entityName;
    } else {
        GenLib.error("AddRow.setEntityName()",
            "EntityName already set to '" + this.entityName + "'.");
    }
}
public String getEntityName() {
    return entityName;
}
/**
 * Called after perform to get the row's MID, which is
 * issued when the row is added to the database.
 * <p>
 * Note that if the row has other columns (due to a join)
 * they need refreshing, which means the row needs refreshing.
 */
public String getNewMID() {
    return newMID;
}
/**
 * For debugging.
 */
public String getState() {
    return "newMID=" + newMID + ", entityName=" + entityName;
}
//---------- Private Methods -----------------------------
//--- Std
private static void print(String text) {
    System.out.println("AddOneRow" + text);
}

} // End class
