package ModSQL;
import java.sql.*;
 
/* $Id: Operator_Not.java,v 1.7 2003/07/09 06:54:49 cvs Exp $
 *
 * Copyright (c) 2003 Chris Studholme <chris.studholme@utoronto.ca>
 *
 * May be copied or modified under the terms of the GNU General Public
 * License.  See COPYING for more information.
 */

/**
 * <p>SQL operator NOT.
 *
 * @author chris.studholme@utoronto.ca
 */
final class Operator_Not extends Operator {

  /**
   * Default constructor.
   */
  public Operator_Not() {
  }

  /**
   * Constructor with parameter.
   *
   * @param parameter first (and only) parameter
   * @throws SQLException if there is an error with the parameter
   */
  public Operator_Not(Function parameter) throws SQLException {
    addParameter(parameter);
  }
  

  /**
   * <p>Prepare the function for use.  
   *
   * @throws SQLException if the parameter is invalid
   */
  public void optimize() throws SQLException {
    super.optimize();
    if (parameters.length!=1) 
      throw new SQLException("NOT operator requires exactly one parameter");
    switch (parameters[0].getSQLType()) {
    case Types.NULL:
    case Types.BIT:
      break;
    default:
      throw new SQLException("invalid parameter type in NOT operator");
    }
    evaluateConstantParameters();
  }

  /**
   * Returns "#NOT".
   *
   * @return name of function 
   */
  public String functionName() {
    return "#NOT";
  }


  /****************  result meta-data  ****************/
  

  /**
   * Returns Types.BIT.
   *
   * @return SQL type of data to be returned
   */
  public int getSQLType() {
    return Types.BIT;
  }

  /**
   * Returns -1 as this operator will never return a String object.
   *
   * @return maximum size of String returned or -1 if unknown
   */
  public int getMaxResultSize() {
    return -1;
  }


  /****************  evaluation methods  ****************/


  /**
   * Evaluate parameter and invert.
   *
   * @param aggregate passed to parameter
   * @return result object
   * @throws SQLException if a database-access error occurs
   * @throws EndOfTable if thrown by a parameter
   */
  public Object evaluate(boolean aggregate) throws SQLException, EndOfTable {
    if (!parameter_constant[0])
      parameter_value[0] = parameters[0].evaluate(aggregate);
    if (parameter_value[0]==null)
      return null;
    return new Boolean(!((Boolean)parameter_value[0]).booleanValue());
  }

  /**
   * Evaluate parameter and invert.
   *
   * @param match_op how the value should be matched
   * @param match_value desired value
   * @return result object
   * @throws SQLException if a database-access error occurs
   * @throws EndOfTable if thrown by a parameter
   */
  public Object evaluate(int match_op, Object match_value)
    throws SQLException, EndOfTable {
    if (!parameter_constant[0]) {
      if (match_value==null)
	parameter_value[0] = parameters[0].evaluate(match_op,null);
      else {
	Object mv = new Boolean(!((Boolean)match_value).booleanValue());
	parameter_value[0] = parameters[0].evaluate(match_op,mv);
      }
    }
    return parameter_value[0]==null ? null :
      new Boolean(!((Boolean)parameter_value[0]).booleanValue());
  }

};
