/*
 * MiningMart Version 1.0
 * 
 * Copyright (C) 2006 Martin Scholz, Timm Euler, 
 *                    Daniel Hakenjos, Katharina Morik
 *
 * Contact: miningmart@ls8.cs.uni-dortmund.de
 *
 * A list of contributing developers (other than the copyright 
 * holders) can be found at
 * http://mmart.cs.uni-dortmund.de/downloads/download.html
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program, see the file MM_HOME/LICENSE; if not, write
 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
 * Floor, Boston, MA 02110-1301, USA.
 */
package edu.udo.cs.miningmart.storedProcedures;

/** 
 * A class to store the necessary information of a DB attribute and
 * to convert the database datatype to the internal datatype and vice
 * versa. 
 *@author Martin Scholz
 *@version $Id: Attribute.java,v 1.4 2006/04/11 14:10:16 euler Exp $ 
 */
class Attribute {

    private final String name;
    private final String dataType;
    private final String internalType;

    /**
     * @param name the name of the attribute in the database
     * @param dataType the relational datatype of the attribute in the database
     * @param internalType the datatype the operator expects the data to have
     */
    public Attribute(String name, String dataType, String internalType) {
		this.name = name;
		this.dataType = dataType;
		this.internalType = internalType;
    }

    public String getName() {
		return name;
    }

    public String getDataTypeName() {
		return dataType;
    }
//
//    public String getDataTypeName() {
//		return (DataType.getNameFor(this.dataType));
//    }

    public boolean isConvertable() {
		return (getConvertedInput() != null && getConvertedOutput("") != null);
    }

    /**
     * This method adds some conversion functions around the attribute
     * name, in order to receive the internal datatype, if it is
     * different from the attribute type in the database.
     *
     * @return a string to be used in SQL statements instead of the
     * attribute name. If conversion is not supported, then
     * <i>null</i> is returned!
     */
    public String getConvertedInput() {
		if (this.getDataTypeName().equalsIgnoreCase(this.internalType)) {
		    if (this.isDate(this.getDataTypeName())) {
				return("to_char(" + this.getName() + ", 'DD.MM.YYYY HH24:MI:SS')");
		    }
		    else {
		    	return this.getName();
		    }
		}

		if (this.isDate(this.getDataTypeName()) &&
		    this.isNumeric(this.internalType) )
		{
		    return ("m4_date_to_timestamp(" + this.getName() + ")");
		}

		if (this.isNumeric(this.getDataTypeName()) &&
		    this.isDate(this.internalType) )
		{
		    return ("to_char(m4_timestamp_to_date(" + this.getName() + "), 'DD.MM.YYYY HH24:MI:SS')");
		}

		return null;
    }

    /**
     * This method adds some conversion functions around a value to be
     * inserted into the database.  It converts the internal datatype
     * into the datatype of the attribute in the database.
     *
     * @param value a value to be inserted into the
     *        database. <i>null</i> represents the DB value 'NULL'.
     * @return a string which should be used in a SQL <i>INSERT</i>
     * statement instead of the value as such. If conversion fails,
     * then <i>null</i> is returned!
     */
    public String getConvertedOutput(String value) {
		if (value == null) {
		    return "NULL";
		}
	
		if (this.getDataTypeName().equalsIgnoreCase(this.internalType)) {
		    if (this.isDate(this.getDataTypeName())) {
				return("to_date('" + value + "', 'DD.MM.YYYY HH24:MI:SS')");
		    }
		    else {
		    	return value;
		    }
		}

		if (this.isNumeric(this.internalType) &&
		    this.isDate(this.getDataTypeName()))
		{
	    	return ("m4_timestamp_to_date(" + value + ")");
		}

		if (this.isDate(this.internalType) &&
		    this.isNumeric(this.getDataTypeName()))
		{
		    return ("m4_date_to_timestamp(to_date('" + value + "', 'DD.MM.YYYY HH24:MI:SS'))");
		}

		return null;
    }

    public String getConvertedOutput(double value) {
		return(this.getConvertedOutput(Double.toString(value)));
    }

    public String getConvertedOutput(int value) {
		return(this.getConvertedOutput(Integer.toString(value)));
    }

    public String getConvertedOutput(long value) {
		return(this.getConvertedOutput(Long.toString(value)));
    }

    public String getConvertedOutput(Object obj) {
		if (obj == null) {
		    return "NULL";
		}
		
		if (obj instanceof String) {
		    return(this.getConvertedOutput((String) obj));
		}

		if (obj instanceof Double) {
		    Double d = (Double) obj;
		    return(this.getConvertedOutput(d.doubleValue()));
		}

		if (obj instanceof Integer) {
		    Integer i = (Integer) obj;
	    	return(this.getConvertedOutput(i.intValue()));
		}

		if (obj instanceof Long) {
		    Long l = (Long) obj;
	    	return(this.getConvertedOutput(l.longValue()));
		}
	
		return null;
    }
    
    private boolean isNumeric(String datatype) {
    	return datatype.startsWith("NUM");
    }
    
    private boolean isDate(String datatype) {
    	return datatype.equals("DATE");
    }
}
/*
 *$Log: Attribute.java,v $
 *Revision 1.4  2006/04/11 14:10:16  euler
 *Updated license text.
 *
 *Revision 1.3  2006/04/06 16:31:16  euler
 *Prepended license remark.
 *
 *Revision 1.2  2006/03/30 16:07:15  scholz
 *fixed author tags for release
 *
 *Revision 1.1  2006/01/03 09:54:23  hakenjos
 *Initial version!
 * 
 */
