package ModSQL;
import java.sql.Types;
import java.sql.SQLException;
import java.io.PrintStream;

/* $Id: Literal.java,v 1.8 2003/05/29 04:58:40 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.
 */

/**
 * Wrapper for literal values.
 *
 * @author chris.studholme@utoronto.ca
 */
final class Literal implements Function {

  /** Literal value. */
  protected Object value;
  /** SQL type of value. */
  protected int type;

  /**
   * Constructor for null value.
   */
  public Literal() {
    value = null;
    type = Types.NULL;
  }
  /**
   * Constructor for java object.
   *
   * @param s object literal
   */
  public Literal(Object s) {
    value = s;
    type = AbstractFunction.getObjectSQLType(value);
  }
  /**
   * Constructor for integer.
   *
   * @param i integer literal
   */
  public Literal(int i) {
    value = new Integer(i);
    type = Types.INTEGER;
  }
  /**
   * Constructor for long.
   *
   * @param l long literal
   */
  public Literal(long l) {
    value = new Long(l);
    type = Types.BIGINT;
  }
  /**
   * Constructor for double.
   *
   * @param d double literal
   */
  public Literal(double d) {
    value = new Double(d);
    type = Types.DOUBLE;
  }
  /**
   * Constructor for boolean.
   *
   * @param b boolean literal
   */
  public Literal(boolean b) {
    value = new Boolean(b);
    type = Types.BIT;
  }

  /**
   * Return human readable version of literal.
   *
   * @return human readable literal
   */
  public String toString() {
    if (value==null)
      return "NULL";
    if (value instanceof Number || value instanceof Boolean)
      return value.toString();
    return '\''+value.toString()+'\'';
  }


  /****************  parameter handling methods  ****************/

  /**
   * Get the number of parameters.  Always returns 0 as parameters are
   * not supported.
   *
   * @return number of parameters
   */
  public int getParameterCount() {
    return 0;
  }
  
  /**
   * Get a particular parameter.  Always throws an exception as parameters
   * are not supported.
   *
   * @param index index of parameter to get
   * @return parameter (function)
   * @throws IndexOutOfBoundsException always
   */
  public Function getParameter(int index) {
    throw new IndexOutOfBoundsException("parameters not supported");
  }

  /**
   * Adds a parameter to the list of parameters.  Always throws an exception
   * as parameters are not supported.
   *
   * @param item function to add
   * @throws SQLException always
   */
  public void addParameter(Function item) throws SQLException {
    throw new SQLException("parameters not supported");
  }

  /**
   * Specify the order in which the parameters should be evaluated.  Always
   * throws an exception as parameters are not supported.
   *
   * @param index index of parameter
   * @param order number indicating order in which parameter is evaluated
   * @throws IndexOutOfBoundsException always
   */
  public void evaluateOrder(int index, int order) {
    throw new IndexOutOfBoundsException("parameters not supported");
  }

  /**
   * Does nothing as a Literal has no parameters.
   *
   * @param o object to register with
   */
  public void registerWith(Object o) {
  }

  /**
   * Does nothing.
   */
  public void optimize() {
  }


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

  /**
   * Determine if this function returns a constant value.  Always returns
   * true for literal values.
   *
   * @return true
   */
  public boolean isConstant() {
    return true;
  }

  /**
   * Determine if this function will return a value that is an aggregate of
   * many database rows.  Always returns false for literal values.
   *
   * @return false
   */
  public boolean isAggregate() {
    return false;
  }

  /**
   * Return the SQL type of the literal value.
   *
   * @return SQL type of data to be returned
   */
  public int getSQLType() {
    return type;
  }

  /**
   * If the literal is a String, this method returns the length of the 
   * String.  Otherwise, -1 is returned.
   *
   * @return length of String or -1 if literal is not a String
   */
  public int getMaxResultSize() {
    return value instanceof String ? ((String)value).length() : -1;
  }


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

  /**
   * Returns the literal value.
   *
   * @param aggregate true to get final aggregate value
   * @return result object
   */
  public Object evaluate(boolean aggregate) {
    return value;
  }

  /**
   * Returns the literal value.
   *
   * @param match_op how the value should be matched
   * @param match_value desired value
   * @return result object
   */
  public Object evaluate(int match_op, Object match_value) {
    return value;
  }

  /**
   * Does nothing.
   */
  public void reset() {
  }

};
