/*
 * 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.m4;

import edu.udo.cs.miningmart.exception.M4Exception;


import java.util.Collection;

/**
 * @author Timm Euler, Daniel Hakenjos
 * @version $Id: Columnset.java,v 1.6 2006/04/11 14:10:12 euler Exp $
 */
public interface Columnset extends M4Data {

 	/** DB level: String constant used in the DB to indicate that this columnset is a table */
 	public static final String CS_TYPE_TABLE = "T";
 	
 	/** DB level: String constant used in the DB to indicate that this columnset is a view */
 	public static final String CS_TYPE_VIEW = "V";
 	
	//methods from core
	
    /**
     * Set this columnset's concept.
     * 
     * @param c the Concept this ColumnSet belongs to
	 */
	public void setTheConcept(Concept c) throws M4Exception;

    /**
     * @return the Concept this ColumnSet belongs to
     */
    public Concept getTheConcept();

	/**
	 * Set the database schema where the table or view that
	 * this columnset refers to lives.
	 * 
	 * @param s the schema name
	 */
    public void setSchema(String s);

	/**
	 * @return the name of the database schema where the table or view that
	 *         this columnset refers to lives
	 */
    public String getSchema();

    /**
     * @return The name only, or "schema"."name" if the "schema" is known.
     */
    public String getSchemaPlusName();

	/**
	 * Set the type of this columnset (table or view). Use one of the
	 * public constants of this class, either CS_TYPE_TABLE or CS_TYPE_VIEW.
	 * 
	 * @param t A String constant, either Columnset.CS_TYPE_TABLE or Columnset.CS_TYPE_VIEW
	 */
    public void setType(String t) throws M4Exception;

	/**
	 * @return A String constant, either Columnset.CS_TYPE_TABLE or Columnset.CS_TYPE_VIEW
	 */
    public String getType();

	/**
	 * Set the sql definition.
	 * 
	 * @param sqlDefinition the new definition
	 * A value of <code>null</code> indicates that there is no explicit
	 * SQL definition, but that the name of the table or view is its defintion
	 * at the same time. If the sqlDefinition is <code>null</code> then the
	 * method <code>getSQLDefinition()</code> will return
	 * <code>getSchemaPlusName()</code>.
	 */
    public void setSQLDefinition(String sqlDefinition);
	/**
	 * @return the sql definition of this columnset, if not set explicitly
	 * then <code>getSchemaPlusName()</code>. Never returns <code>null</code>.
	 */
    public String getSQLDefinition();

	/**
	 * This method returns a complete SQL query, which can be used to
	 * get the data as represented by this <code>Columnset</code>.
	 * In contrast to the method <code>getSQLDefinition()</code> this
	 * method does also include virtual columns, which are sometimes
	 * <b>not</b> visible at the level of the Columnset's SQL definition.
	 * 
	 * @return an SQL string like
	 * <i>SELECT &lt;SQLDefinition of Column1&gt; &lt;Name of Column1&gt; , ...
	 *           &lt;SQLDefinition of Columnn&gt; &lt;Name of Columnn&gt;
	 *      FROM &lt;SQLDefintion of the Columnset&gt;</i>
	 */
	public String getCompleteSQLQuery() throws M4Exception;

	/**
	 * This method returns a complete SQL query, which can be used to
	 * get the data as represented by this <code>Columnset</code>.
	 * The difference to the same method without the additional parameter
	 * is, that this method allows to specify a target attribute name
	 * for the internal Oracle attribute ROWNUM
	 * 
	 * @see Columnset.getCompleteSQLQuery
	 * @param rowNumName the target attribute name of the ROWNUM attribute
	 * @return an SQL string like
	 * <i>SELECT ROWNUM AS &lt;rowNumName&gt;,
	 *           &lt;SQLDefinition of Column1&gt; &lt;Name of Column1&gt; , ...
	 *           &lt;SQLDefinition of Columnn&gt; &lt;Name of Columnn&gt;
	 *      FROM &lt;SQLDefintion of the Columnset&gt;</i>
	 */
	public String getCompleteSQLQuery(String rowNumName) throws M4Exception;


	/**
	 * Set the information about the multistep branch.
	 * 
	 * @param branchDefinition The new branch information
	 */
	public void setMultiStepBranch(String branchDefinition);

	/**
	 * @return the information about the multistep branch.
	 */
	public String getMultiStepBranch();


	/** 
	 * Adds an attribute-value pair to the MultiStepBranch field if the
	 * attribute isn't already present there.
	 * 
	 * @param oldDef The multistep branch information so far
	 * @param attribute The attribute
	 * @param the value for the attribute
	 */
	public void addMultiStepBranchInfo(String oldDef, String attribute, String value) 
	throws M4Exception;
	
	/** @param branch A complete field <code>CS_MSBRANCH</code> as found in table
	 * <i>COLUMNSET_T</i>. It is added to the <code>CS_MSBRANCH</code> of <code>this</code>
	 * object via <code>addMultiStepBranchInfo</code>.
	 * */
	public void addMultiStepBranch(String branch) throws M4Exception;
	
	/**
	 * Set all columns of this columnset.
	 * 
	 * @param theColumns Collection of the new set of column objects
	 */
    public void setColumns(Collection theColumns) throws M4Exception;
    
	/**
	 * @param col a <code>Column</code>
	 * @return <code>true</code> if a column with the same ID is already linked to this
	 * <code>Columnset</code>
	 * */
	public boolean hasColumn(Column col) throws M4Exception;

	/**
	 * @return all columns of this columnset in an array
	 */
    public Collection getColumns() throws M4Exception;

    /**
     * Set a specific column. This method is to be used with care!
     * At several occasions it is assumed, that each Column is entered just
     * once in a Collection and entering <code>null</code> values might also be
     * problematic!
     * 
     * @param index number of the Column
     * @param c Column to be set
     */
    public void setColumn(int index, Column c) throws M4Exception;
    
    /**
     * Get a specific column.
     * 
     * @param index number of the Column
     * @return Column at this index
     */
    public Column getColumn(int index) throws M4Exception;

	/**
	 * Active getter for the <code>Key</code> objects referencing to this
	 * <code>Columnset</code> as their forein key.
	 * 
	 * @return a <code>Collection</code> of <code>Key</code> objects
	 */
	public Collection getForeignKeysWhereThisIsFkCs() throws M4Exception;

	/**
	 * Active getter for the <code>ColumnsetStatistics</code> of this <code>Columnset</code>.
	 * @return a <code>Collection</code> of <code>ColumnsetStatistics</code> objects, never
	 * <code>null</code>.
	 */
	public Collection getStatistics() throws M4Exception;

	/**
	 * Setter method.
	 */
	public void setStatistics(Collection theStats) throws M4Exception;
	
	/**
	 * Setter method.
	 * 
	 * @param sa the new value
	 */
    public void setStatisticsAll(int sa) throws M4Exception;

	/**
	 * Getter method.
	 * 
	 * @return the value
	 */
    public int getStatisticsAll() throws M4Exception;

	/**
	 * Setter method.
	 * 
	 * @param sn the new value
	 */
    public void setStatisticsNominal(int sn) throws M4Exception;

	/**
	 * Getter method.
	 * 
	 * @return the value
	 */
    public int getStatisticsNominal() throws M4Exception;

	/**
	 * Setter method.
	 * 
	 * @param so the new value
	 */
    public void setStatisticsOrdinal(int so) throws M4Exception;
    
	/**
	 * Getter method.
	 * 
	 * @return the value
	 */
    public int getStatisticsOrdinal() throws M4Exception;

	/**
	 * Setter method.
	 * 
	 * @param st the new value
	 */
    public void setStatisticsTime(int st) throws M4Exception;

	/**
	 * Getter method.
	 * 
	 * @return the value
	 */
    public int getStatisticsTime() throws M4Exception;

	/**
	 * Add a column to this columnset's columns.
	 * 
	 * @param c the additional column
	 */
    public void addColumn(Column c) throws M4Exception;
    
	/**
	 * Remove a column from this Columnsets's columns.
	 * 
	 * @param c The new column.
	 * @return <code>true</code> if removing succeeded
	 */
	public boolean removeColumn(Column column) throws M4Exception;
	
	public void removeAllColumns() throws M4Exception;
	
	/** 
	 * Scans the MultiStepBranch information of the <code>Columnset</code>
	 * for <i>attributeName=Value;</i> and returns the corresponding value,
	 * <code>null</code> otherwise. The attribute name is compared in a case
	 * insensitive way and it is assumed that exactly the format above is
	 * used. Each attribute value pair needs to be terminated by a ';',
	 * no whitespaces in between! If this assumption does not hold parsing
	 * might throw an exception.
	 * 
	 * @param attributeName The name of the <code>BaseAttribute</code> or
	 * pseudo-attribute (e.g. <i>(Random)</i>) for which the value should
	 * be read from the <code>CS_MSBRANCH</code> field.
	 * @return the value, if found, <code>null</code> otherwise. 
	 */
    public String getMSBranchSelectionValue(String attributeName) throws M4Exception;

	/**
	 * @param attributename The name of a <code>BaseAttribute</code> or a pseudoattribute
	 *    which potentially occurs in the MultiStepBranch information attached to the
	 *    <code>Columnset</code>.
	 * 
	 * @return the MultiStepBranch-<code>String</code> omitting the equation for the
	 * given attribute. If the attribute does not occur, the complete <code>String</code>
	 * is returned. Note that an attribute is expected to occur at most once in the
	 * MultiStepBranch-<code>String</code>, because multiple occurences are redundant or
	 * result in an empty <code>Columnset</code>.
	 * 
	 * @throws M4Exception, if the <i>attributeName</i> occurs in the
	 * <code>String</code>, but the substring is not properly ended by the character ';'.
	 */
	public String getMsbInfoWithoutAttrib(String attributeName) throws M4Exception;
	
    /**
     * Reads, or computes and inserts into the statistics table, the number
     * of rows of this ColumnSet and returns it as a string.
     * 
     * @return the number of rows in the columnset as a String
     */
    public String readOrComputeCount() throws M4Exception;

    /**
     * Executes several SQL procedure queries to calculate statistical information for
     * the given columnset on demand. The result is written to the table <i>CSSTATIST_T</i>
     * and the JAVA cache is updated.
     * 
     * Statistics already available are not recomputed.
     * 
     * Finally an update for the statistics of all the <code>Column</code>s of this
     * <code>Columnset</code> is performed.
     */
    public void updateStatistics() throws M4Exception;
    
    /**
     * If data changes in the database, e.g. a DB Concept is edited,
     * then this method allows to delete the deprecated statistics objects
     * without running a garbage collection.
     */
    public void clearStatistics() throws M4Exception;
    
	/**
	 * Returns the Relation in which this Columnset realizes the
	 * cross table, if there is such a Relation.
	 * 
	 * @return Relation The Relation or <code>null</code>
	 */
	public Relation getRelation();

	/**
	 * Sets the connection to a Relation. This can be used
	 * if this Columnset realizes the cross table of a Relation.
	 * 
	 * @param newRelation The Relation to set
	 */
	public void setRelation(Relation newRelation) throws M4Exception;
	
	//methods from old interface	

	/* Constants */

	public static final String TYPE_TABLE = "T";
	public static final String TYPE_VIEW = "V";
	public static final String TYPE_SNAPSHOT = "SN";
	public static final String TYPE_MATERIALIZED_VIEW = "MV";


  /* TE: not used
  String getFile();

  void setFile(String file);

  String getUser();

  void setUser(String user);

  String getConnectString();

  void setConnectString(String connectString);
  */

  /* Association methods */

  /**
   * Creates a Column that will be connected to this ColumnSet. The name of the Column must be unique for this ColumnSet.
   * @throws CreateException when an error occurs during creation of the object.
   * @throws NameExistsException when the provided name already exists.
   */
  Column createColumn(String name, String datatype) throws M4Exception;

  /**
   * Creates an M4 Column for every column of the table or view with the
   * given name, and connects it to this Columnset.
   * 
   * @param nameOfTableOrView name of the table or view
   * @throws M4Exception
   */
  void createColumnsFromDbObject(String nameOfTableOrView) throws M4Exception;
	
  Column getColumn(String columnName) throws M4Exception;

  /**
   * Creates a ForeignKey. The name of the Key must be unique within the ColumnSet.
   */
  ForeignKey createForeignKeyWhereThisIsFkCs(String name) throws M4Exception;

  ForeignKey getForeignKeyWhereThisIsFkCs(String keyName) throws M4Exception;

  /**
   * Removes the specified ForeignKey for this ColumnSet. It is also removed from the M4 Schema.
   */
  void removeForeignKeyWhereThisIsFkCs(String name) throws M4Exception;

  /**
   * Removes all ForeignKeys from this ColumnSet. They are removed from the M4 Schema.
   */
  void removeAllForeignKeys() throws M4Exception;

  /**
   * Creates a PrimaryKey. The name of the Key must be unique within the ColumnSet.
   * @throws CreateException when an error occurs during creation of the object.
   * @throws NameExistsException when the provided name already exists.
   */
  PrimaryKey createPrimaryKey(String name) throws M4Exception;

  void setPrimaryKey(PrimaryKey primaryKey) throws M4Exception;

  /**
   * Removes the specified PrimaryKey for this ColumnSet. It is also removed from the M4 Schema.
   */
  void removePrimaryKey() throws M4Exception;

  Columnset copy(Concept newConcept) throws M4Exception;

  PrimaryKey getPrimaryKey() throws M4Exception;
}
/*
 * Historie
 * --------
 * 
 * $Log: Columnset.java,v $
 * Revision 1.6  2006/04/11 14:10:12  euler
 * Updated license text.
 *
 * Revision 1.5  2006/04/06 16:31:12  euler
 * Prepended license remark.
 *
 * Revision 1.4  2006/03/20 16:44:21  euler
 * Bugfixes
 *
 * Revision 1.3  2006/01/13 01:19:46  scholz
 * improved statistics computation
 *
 * Revision 1.2  2006/01/05 14:11:37  euler
 * Bugfixes
 *
 * Revision 1.1  2006/01/03 09:54:24  hakenjos
 * Initial version!
 *
 */
