package AsciiDatabase;
import ModSQL.*;
import java.sql.*;
import java.io.*;
import java.util.Properties;

/* AsciiDatabase/Manager.java
 *
 * Copyright (c) 2004 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>A flexable method of turning flat ascii files into
 * databases.  The config file hard coded here contains pointers
 * to table configuration files and data files.  The table configuration
 * file describes the format of the data in the data file.
 *
 * <p> At the moment, this code also handles the choice of file
 * names for indexes of tables.  This needs to be rethought as
 * ModSQL should handle indices it creates all by itself.
 *
 * @author chris.studholme@utoronto.ca
 */

public class Manager implements DatabaseManager {

  /** Default config file location for AsciiDatabase */
  public static final String defasciiconf = "/etc/asciidb.conf";

  private static final int majorVersion=0;
  private static final int minorVersion=40;

  private RCFile rcfile;


  /**
   * Create new Manager.  Config file location is read from ModSQL.DriverConfig,
   * or default is used.
   *
   * @param rcfilename name of configuration file
   * @exception IOException if an error occurs reading the configuration file
   */
  public Manager() throws IOException {
    // get properities
    Properties props = DriverConfig.getDatabaseProperties("AsciiDatabase");
    String asciiconf = props.getProperty("configfile");
    rcfile = new RCFile(new File(asciiconf!=null?asciiconf:defasciiconf));
  }

  /**
   * Create new Manager with specifed configuration file.
   *
   * @param rcfilename name of configuration file
   * @exception IOException if an error occurs reading the configuration file
   */
  public Manager(String rcfilename) throws IOException {
    rcfile = new RCFile(new File(rcfilename));
  }

  /**
   * Closes the configuration file to free up a file descriptor.
   */
  protected void finalize() {
    rcfile.close();
    rcfile=null;
  }

  /**
   * Returns the major version number of this database.
   *
   * @return major version number
   */
  public int getMajorVersion() {
    return majorVersion;
  }

  /**
   * Returns the minor version number of this database.
   *
   * @return minor version number
   */
  public int getMinorVersion() {
    return minorVersion;
  }

  /**
   * Checks if this database contains the named table.
   *
   * @param name table desired
   * @return true if this database has the desired table, false otherwise
   */
  public boolean hasTable(String name) {
    try {
      String tablercfile = rcfile.ReadCharValue("tabledef",name);
      String datafile = rcfile.ReadCharValue("datafile",name);
      return ((tablercfile!=null)&&(datafile!=null));
    }
    catch (Exception e) {
      return false;
    }
  }

  /**
   * Opens the named table for read only access.
   *
   * @param name desired table
   * @return DatabaseTable requested, or null if the table was not found
   */
  public DatabaseTable openTable(String name) throws DatabaseException {
    return openTable(name,true);
  }

  /**
   * Opens the named table.  Read/write access is not currently supported.
   *
   * @param name desired table
   * @param readonly flag indicating that the table be opened readonly
   * @return DatabaseTable requested, or null if the table was not found
   * @exception DatabaseException if read/write access was requested
   */
  public DatabaseTable openTable(String name, boolean readonly)
    throws DatabaseException {
    try {
      String tablercfile = rcfile.ReadCharValue("tabledef",name);
      String datafile = rcfile.ReadCharValue("datafile",name);
      if ((tablercfile==null)||(datafile==null))
	return null;
      if (readonly==false)
	throw new DatabaseException("table must be opened read-only");
      AsciiTable result = new AsciiTable(name,tablercfile,datafile);
      while ((datafile=rcfile.ReadNextCharValue("datafile"))!=null)
	result.AddDataFile(datafile);
      return result;
    }
    catch (Exception e) {
      System.err.println(e.toString());
      return null;
    }
  }

  /**
   * Create the named table.  
   *
   * @param tablename name of new table
   * @return DatabaseTable object representing the new table
   */
  public DatabaseTable createTable(String tablename, boolean temporary)
    throws DatabaseException {
    if (hasTable(tablename))
      throw new DatabaseException("table '"+tablename+"' exists");
    return null;
  }

  /**
   * Create an index of the specifed column in the specified table.
   *
   * @param name name of table to index
   * @param column name of column to index
   * @return true if the index was successfully created, false otherwise
   */
  public boolean createIndex(String name, String column) {
    return false;
  }

  /**
   * Delete the specified table.
   *
   * @param tablename name of table to drop
   * @exception DatabaseException if the operation failed
   */
  public void dropTable(String name) throws DatabaseException {
    if (!hasTable(name))
      throw new DatabaseException("table '"+name+"' not found");
    throw new DatabaseException("cannot drop table '"+name+"'");
  }

  /**
   * Delete the specified index.
   *
   * @param tablename name of indexed table
   * @param columnname name of indexed column
   */
  public boolean dropIndex(String name, String column)
    throws DatabaseException {
    if (!hasTable(name))
      throw new DatabaseException("table '"+name+"' not found");
    return false;
  }

  public Function getFunction(String function_name) {
    return null;
  }

};

