//*****************************************************************************
/*
** FILE:   da_DatabaseSchemaElement.java
**
** (c) 1998 Steve Withall.
**
** HISTORY:
**    23May98  stevew  Created.
*/
package da;

import xg.xg_Element;
import xg.xg_VerificationException;

import eh.eh_Debug;

import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;

import java.lang.StringBuffer;

//*****************************************************************************
/** An XML element to represent the structure of a database.
 */
public class da_DatabaseSchemaElement extends xg_Element
{
    /** The element type name normally used in XML for this sort of element. */
    public final static String RegisteredName = "DatabaseSchema";

    /** The name of the attribute which holds the name of the driver class. */
    public final static String ClassAttName   = "Class";

    //*****************************************************************************
    /** Construct a database schema element with no name.
     */
    public da_DatabaseSchemaElement()
    {
        super(RegisteredName);
    }

    //*****************************************************************************
    /** Construct a database schema element with a name.
     *
     *  @param  InputNodeName  The name of the element
     */
    public da_DatabaseSchemaElement(String InputNodeName)
    {
        super(InputNodeName);
    }

    //*****************************************************************************
    /** <p>Verify that this node is correct (ie. internally correct and/or consistent
     *  with other nodes - such as its parent). The node is OK if it possesses a
     *  'Class' attribute which names a valid database driver class.</p>
     *
     *  @exception  xg_VerificationException  Description of verification problem
     */
    public void verify() throws xg_VerificationException
    {
        eh_Debug.add(2, "da_DatabaseSchemaElement.verify: Verify '" + toString() + "'");

        // Obtain the menu item's ID from the "Class" attribute.
        String  DriverClassName = getAttributeValue(ClassAttName);
//        String  DriverClassName = getAttributeValueVerified(ClassAttName);

        if (DriverClassName != null)
        {
            try
            {
                // Load the named driver class.
//                    Class.forName(DriverClassName);
                Class  DriverClass = Class.forName(DriverClassName);
                eh_Debug.add(2, "da_DatabaseSchemaElement.verify: Loaded driver '" + DriverClassName + "'");
            }
            catch (Exception InputException)
            {
                throw new xg_VerificationException("Error loading database driver '"
                                                      + DriverClassName + "': "
                                                      + InputException);
            }
        }
    }

    //*****************************************************************************
    /** Analyse the database, and put the details into the document model.
     *
     *  @param  InputMetaData  The metadata describing the database
     */
    public void analyseDatabase(DatabaseMetaData  InputMetaData)
    {
	    eh_Debug.add(6, "da_DatabaseSchemaElement.analyseDatabase:");
        analyseCatalogs(InputMetaData);
        analyseSchemas(InputMetaData);
        analyseTableTypes(InputMetaData);
        analyseTables(InputMetaData);
        analyseViews(InputMetaData);
    }

    //*****************************************************************************
    /** Find out about the catalogs in this database.
     *
     *  @param  InputMetaData  The metadata describing the database
     */
    public void analyseCatalogs(DatabaseMetaData  InputMetaData)
    {
	    eh_Debug.add(6, "da_DatabaseSchemaElement.analyseCatalogs:");

        try
        {
	        // Get a list of all the catalogs in the database.
	        ResultSet  CatalogResultSet = InputMetaData.getCatalogs();
	        while (CatalogResultSet.next() )
    	    {
	            eh_Debug.add(6, "  Catalog '" + CatalogResultSet.getString(1) + "'");
	        }
        }
        catch (SQLException InputException)
        {
	        eh_Debug.add(2, "Unable to retrieve list of catalogs: " + InputException);
        }
    }

    //*****************************************************************************
    /** Find out about the schemas in this database.
     *
     *  @param  InputMetaData  The metadata describing the database
     */
    public void analyseSchemas(DatabaseMetaData  InputMetaData)
    {
	    eh_Debug.add(6, "da_DatabaseSchemaElement.analyseSchemas:");

        try
        {
	        // Get a list of all the schemas in the database.
	        ResultSet  SchemaResultSet = InputMetaData.getSchemas();
	        while (SchemaResultSet.next() )
    	    {
	            eh_Debug.add(6, "  Schema '" + SchemaResultSet.getString(1) + "'");
	        }
        }
        catch (SQLException InputException)
        {
	        eh_Debug.add(2, "Unable to list schemas: " + InputException);
        }
    }

    //*****************************************************************************
    /** Find out about the types of table supported by this database.
     *
     *  @param  InputMetaData  The metadata describing the database
     */
    public void analyseTableTypes(DatabaseMetaData  InputMetaData)
    {
	    eh_Debug.add(6, "da_DatabaseSchemaElement.analyseTableTypes:");

        try
        {
	        // Get a list of all the table types allowed by this database.
	        ResultSet  TableTypeResultSet = InputMetaData.getTableTypes();
	        while (TableTypeResultSet.next() )
    	    {
	            eh_Debug.add(6, "  Table type '" + TableTypeResultSet.getString(1) + "'");
	        }
        }
        catch (SQLException InputException)
        {
	        eh_Debug.add(2, "Unable to list table types: " + InputException);
        }
    }

    //*****************************************************************************
    /** Find out about the tables in this database.
     *
     *  @param  InputMetaData  The metadata describing the database
     */
    public void analyseTables(DatabaseMetaData  InputMetaData)
    {
	    eh_Debug.add(6, "da_DatabaseSchemaElement.analyseTables:");

        try
        {
	        // Get a list of all the tables in the database.
	        String[]   TableTypeArray = { "TABLE" };
	        ResultSet  TableResultSet = InputMetaData.getTables(null,
	                                                            null,
	                                                            "%",
	                                                            TableTypeArray);
	        while (TableResultSet.next() )
    	    {
    	        da_DatabaseTableElement  NewTableElement = new da_DatabaseTableElement();
                addChild(NewTableElement);
    	        NewTableElement.analyseTable(InputMetaData, TableResultSet);
	        }
        }
        catch (SQLException InputException)
        {
	        eh_Debug.add(2, "Error retrieving list of tables: " + InputException);
        }
    }

    //*****************************************************************************
    /** Find out about the views in this database.
     *
     *  @param  InputMetaData  The metadata describing the database
     */
    public void analyseViews(DatabaseMetaData  InputMetaData)
    {
	    eh_Debug.add(6, "da_DatabaseSchemaElement.analyseViews:");

        try
        {
	        // Get a list of all the views in the database.
	        String[]   TableTypeArray = { "VIEW" };
	        ResultSet  ViewResultSet  = InputMetaData.getTables(null,
	                                                            null,
	                                                            "%",
	                                                            TableTypeArray);
	        while (ViewResultSet.next() )
    	    {
    	        da_DatabaseViewElement  NewViewElement = new da_DatabaseViewElement();
                addChild(NewViewElement);
    	        NewViewElement.analyseView(InputMetaData, ViewResultSet);
//    	        String  ViewNameString = TableResultSet.getString(3);
//    	        StringBuffer  DebugBuffer = new StringBuffer("  View '" + ViewNameString + "'");
//    	        String  TableRemarksString = TableResultSet.getString(5);
//    	        if (TableRemarksString != null)
//    	            DebugBuffer.append(", remarks '" + TableRemarksString + "'");
//	            eh_Debug.add(6, DebugBuffer.toString() );
	        }
        }
        catch (SQLException InputException)
        {
	        eh_Debug.add(2, "Error retrieving list of views: " + InputException);
        }
    }

    //*****************************************************************************
    /** Get a summary descriptive string suitable for display in the tree view or
     *  elsewhere.
     *
     *  @return  A description suitable for display in the tree view
     */
    public String toString()
    {
        return("Database schema element '" + NodeName + "'");
    }
}

//*****************************************************************************
