001    package com.sptci.rwt;
002    
003    import java.sql.Connection;
004    import java.sql.DatabaseMetaData;
005    import java.sql.ResultSet;
006    import java.sql.SQLException;
007    
008    import java.util.ArrayList;
009    import java.util.Collection;
010    import java.util.List;
011    
012    import com.sptci.util.CloseJDBCResources;
013    
014    /**
015     * An analyser for analysing metadata about a database.
016     *
017     * <p>&copy; Copyright 2007 <a href='http://sptci.com/' target='_new'>Sans Pareil Technologies, Inc.</a></p>
018     * @author Rakesh Vidyadharan 2007-09-26
019     * @version $Id: DBMSAnalyser.java 4123 2008-05-25 21:49:01Z rakesh $
020     */
021    public class DBMSAnalyser extends Analyser
022    {
023      /**
024       * Create a new instance of the class using the specified connection
025       * manager.
026       *
027       * @param manager The manager for obtaining database connections.
028       */
029      public DBMSAnalyser( final ConnectionManager manager )
030      {
031        super( manager );
032      }
033    
034      /**
035       * Returns a collection of {@link DBMSMetaData} objects that contain the
036       * basic information pertaining to the database.
037       *
038       * <pre>
039       *   ConnectionManager manager = new ConnectionManager( "rwt" );
040       *   Collection<DBMSMetaData> dmd = new DBMSAnalyser( manager ).analyse();
041       * </pre>
042       *
043       * @see Analyser#analyse
044       * @see #analyse()
045       * @see #processTransaction
046       * @see #processJdbcMetaData
047       * @see #processLimits
048       * @param parameters No values needed.
049       * @return Returns a collection with just one entry since there is only
050       *   database about which metadata is retrieved.
051       */
052      @Override
053      public Collection<DBMSMetaData> analyse( final MetaData... parameters )
054        throws SQLException
055      {
056        Collection<DBMSMetaData> collection = new ArrayList<DBMSMetaData>();
057        Connection connection = null;
058        ResultSet resultSet = null;
059    
060        try
061        {
062          connection = manager.open();
063          DatabaseMetaData dmd = connection.getMetaData();
064          DBMSMetaData dbmd = new DBMSMetaData();
065          dbmd.setName( dmd.getDatabaseProductName() );
066          dbmd.setVersion( dmd.getDatabaseProductVersion() );
067          dbmd.setDefaultTransaction(
068              processTransaction( dmd.getDefaultTransactionIsolation() ) );
069          dbmd.setJdbcMetaData( processJdbcMetaData( dmd ) );
070          dbmd.setLimitsMetaData( processLimits( dmd ) );
071          collection.add( dbmd );
072        }
073        finally
074        {
075          CloseJDBCResources.close( resultSet );
076          CloseJDBCResources.close( connection );
077        }
078    
079        return collection;
080      }
081    
082      /**
083       * Return a {@link DBMSMetaData} object that contains the basic
084       * information pertaining to the database connected to.
085       *
086       * @see #analyse( MetaData... )
087       * @return The metadata about the database.
088       * @throws SQLException If errors are encountered while analysing the
089       *   database.
090       */
091      public DBMSMetaData analyse() throws SQLException
092      {
093        return ( (List<DBMSMetaData>) analyse( new MetaData[0] ) ).get( 0 );
094      }
095    
096      /**
097       * Map the constants defined in {@link java.sql.Connection} for
098       * transaction isolation levels to the {@link DBMSMetaData.Transaction}
099       * enumeration.
100       *
101       * @param value The constant value that indicates the transaction level.
102       * @return The enumerated transaction value.
103       */
104      protected DBMSMetaData.Transaction processTransaction( final int value )
105      {
106        DBMSMetaData.Transaction tx = null;
107    
108        switch ( value )
109        {
110          case Connection.TRANSACTION_NONE :
111            tx = DBMSMetaData.Transaction.None;
112            break;
113          case Connection.TRANSACTION_READ_COMMITTED :
114            tx = DBMSMetaData.Transaction.ReadCommitted;
115            break;
116          case Connection.TRANSACTION_READ_UNCOMMITTED :
117            tx = DBMSMetaData.Transaction.ReadUncommitted;
118            break;
119          case Connection.TRANSACTION_REPEATABLE_READ :
120            tx = DBMSMetaData.Transaction.RepeatableRead;
121            break;
122          case Connection.TRANSACTION_SERIALIZABLE :
123            tx = DBMSMetaData.Transaction.Serialisable;
124            break;
125        };
126    
127        return tx;
128      }
129    
130      /**
131       * Fetch the JDBC driver metadata from the specified database meta data.
132       *
133       * @param dmd The database metadata from which the JDBC driver metadata
134       *   is to be retrieved.
135       * @throws SQLException If errors are encountered while fetching the
136       *   information.
137       */
138      protected JDBCMetaData processJdbcMetaData( DatabaseMetaData dmd )
139        throws SQLException
140      {
141        JDBCMetaData md = new JDBCMetaData();
142        md.setName( dmd.getDriverName() );
143        md.setVersion( dmd.getDriverVersion() );
144        return md;
145      }
146    
147      /**
148       * Fetch the limits enforced by the database.
149       *
150       * @param dmd The database metadata from which the database engine
151       *   limits are to be retrieved.
152       * @throws SQLException If errors are encountered while fetching the
153       *   information.
154       */
155      protected LimitsMetaData processLimits( DatabaseMetaData dmd )
156        throws SQLException
157      {
158        LimitsMetaData lmd = new LimitsMetaData();
159        lmd.setCharacterLength( dmd.getMaxCharLiteralLength() );
160        lmd.setColumnNameLength( dmd.getMaxColumnNameLength() );
161        lmd.setColumnsInGroupBy( dmd.getMaxColumnsInGroupBy() );
162        lmd.setColumnsInIndex( dmd.getMaxColumnsInIndex() );
163        lmd.setColumnsInOrderBy( dmd.getMaxColumnsInOrderBy() );
164        lmd.setColumnsInSelect( dmd.getMaxColumnsInSelect() );
165        lmd.setColumnsInTable( dmd.getMaxColumnsInTable() );
166        lmd.setConnections( dmd.getMaxConnections() );
167        lmd.setCursorNameLength( dmd.getMaxCursorNameLength() );
168        lmd.setIndexLength( dmd.getMaxIndexLength() );
169        lmd.setProcedureNameLength( dmd.getMaxProcedureNameLength() );
170        lmd.setRowSize( dmd.getMaxRowSize() );
171        lmd.setSchemaNameLength( dmd.getMaxSchemaNameLength() );
172        lmd.setStatements( dmd.getMaxStatements() );
173        lmd.setTableNameLength( dmd.getMaxTableNameLength() );
174        lmd.setTablesInSelect( dmd.getMaxTablesInSelect() );
175        lmd.setUserNameLength( dmd.getMaxUserNameLength() );
176    
177        return lmd;
178      }
179    }