/* * NOTE: This copyright does *not* cover user programs that use HQ * program services by normal system calls through the application * program interfaces provided as part of the Hyperic Plug-in Development * Kit or the Hyperic Client Development Kit - this is merely considered * normal use of the program, and does *not* fall under the heading of * "derived work". * * Copyright (C) [2004, 2005, 2006], Hyperic, Inc. * This file is part of HQ. * * HQ is free software; you can redistribute it and/or modify * it under the terms version 2 of the GNU General Public License as * published by the Free Software Foundation. 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; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA. */ package org.hyperic.tools.db; import java.io.PrintStream; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.Driver; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import org.hyperic.util.jdbc.JDBC; /** * DBInfo is a tool for printing information about a given JDBC driver and * database * * DBInfo can be run from the command line using the command: * java org.hyperic.tools.db.DBPing * The DBInfo class and your JDBC driver should be in your classpath. * * DBInfo can also be called directly from another class. To do this * instantiate the DBInfo class and then call the DBPing.printInfo() method. */ public class DBInfo { private static final String HELP = "DBInfo database [username] [password] [-driver <driver class>] [-?]\n" + " database The JDBC connect string (e.g., jdbc:cloudscape:test;create=true)\n" + " -driver The JDBC driver class for the database to connect to.\n" + " (e.g., COM.cloudscape.core.JDBCDriver).\n" + " -? Displays help\n" + " -help Displays help\n"; private static final String TRANSACTION_NONE = "TRANSACTION_NONE"; private static final String TRANSACTION_READ_COMMITTED = "TRANSACTION_READ_COMMITTED"; private static final String TRANSACTION_READ_UNCOMMITTED = "TRANSACTION_READ_UNCOMMITTED"; private static final String TRANSACTION_REPEATABLE_READ = "TRANSACTION_REPEATABLE_READ"; private static final String TRANSACTION_SERIALIZABLE = "TRANSACTION_SERIALIZABLE"; private static final String NONE = "NONE"; public static void main(String[] args) { int iArgLen = args.length; boolean bHelp = false; String strDriverClassName = null; ///////////////////////////////////////////////////////////// // Look for the command line options for(int i = 0;i < iArgLen;i++) { if(args[i].equalsIgnoreCase("-driver") == true) { if((i + 1) < iArgLen) { strDriverClassName = args[i + 1]; i++; } else { System.out.println("Error: A JDBC driver class name must be specified after the -driver option.\n"); bHelp = true; break; } } else if(args[i].equals("-?") == true || args[i].equalsIgnoreCase("-help") == true) { bHelp = true; break; } else if(args[i].charAt(0) == '-') { System.out.println("Error: Unknown option \'" + args[i] + '\''); bHelp = true; break; } } ///////////////////////////////////////////////////////////// // Run the ping with the command line arguments if(bHelp == false && iArgLen >= 1) { String strUsername = null; String strPassword = null; if(iArgLen >= 2) strUsername = args[1]; if(iArgLen >= 3) strPassword = args[2]; DBInfo info = new DBInfo(); try { info.printInfo(strDriverClassName, args[0], strUsername, strPassword); } catch(SQLException e) { JDBC.printSQLException(e); } catch(ClassNotFoundException e) { System.out.println("Error: " + e); } } else { bHelp = true; } ////////////////////////////////////////////////////////////////// // Display help if appropriate. Normally either the -? option or // command line arguments. if(bHelp == true) System.out.println(DBInfo.HELP); } /** * Loads the specified JDBC driver and prints informatation about the database. * * @param driver * The Java class name of the JDBC driver (e.g., "COM.cloudscape.core.JDBCDriver"). * @param database * The JDBC driver connect string (e.g., "jdbc:cloudscape:test") * * @return boolean * true if the JDBC driver loaded and connected to the database, false * otherwise. */ public void printInfo(String driver, String database) throws ClassNotFoundException, SQLException { this.printInfo(driver, database, null, null); } /** * Loads the specified JDBC driver and prints information about the database database. * * @param driver * The Java class name of the JDBC driver (e.g., "COM.cloudscape.core.JDBCDriver"). * @param database * The JDBC driver connect string (e.g., "jdbc:cloudscape:test") * @param username * The username to use when connecting to the database. This value can * be null. * @param password * The password to use when connecting to the database. This value can * be null. * * @return boolean * true if the JDBC driver loaded and connected to the database, false * otherwise. */ public void printInfo(String driver, String database, String username, String password) throws ClassNotFoundException, SQLException { int iCnt; Connection conn = null; PrintStream out = System.out; boolean bResult = true; String strTmp; if(driver == null) driver = JDBC.getDriverString(database); database = JDBC.getConnectionString(driver, database); try { Driver dbdriver = (Driver)Class.forName(driver).newInstance(); out.println("Successfully loaded the database driver."); conn = DriverManager.getConnection(database, username, password); out.println("Successfully connected to the database.\n"); DatabaseMetaData data = conn.getMetaData(); out.println("JDBC Driver : " + data.getDriverName()); out.println("Driver Version : " + data.getDriverVersion()); out.println("JDBC Compliant : " + dbdriver.jdbcCompliant()); out.println("URL : " + data.getURL()); out.println(); out.println("Database Product Name : " + data.getDatabaseProductName()); out.println("Database Product Version: " + data.getDatabaseProductVersion()); out.println("Username : " + data.getUserName()); out.println(); out.println("Operations"); out.println(" Data Definition causes Commit : " + data.dataDefinitionCausesTransactionCommit()); out.println(" Data Definition is Ignored : " + data.dataDefinitionIgnoredInTransactions()); out.println(" Catalog Seperator : " + data.getCatalogSeparator()); out.println(" Catalog Term : " + data.getCatalogTerm()); out.println(" Default Transaction Isolation : " + DBInfo.transactionIsolationToString(data.getDefaultTransactionIsolation())); out.println(" Identifier Quote String : " + data.getIdentifierQuoteString()); out.println(" Schema Term : " + data.getSchemaTerm()); out.println(" Search String Escape Char : " + data.getSearchStringEscape()); out.println(" Null Plus Non-Nulls Null : " + data.nullPlusNonNullIsNull()); out.println(" Nulls Sorted at End : " + data.nullsAreSortedAtEnd()); out.println(" Nulls Sorted at Start : " + data.nullsAreSortedAtStart()); out.println(" Nulls Sorted High : " + data.nullsAreSortedHigh()); out.println(" Nulls Sorted Low : " + data.nullsAreSortedLow()); out.println(" Stores Lower-case Identifiers : " + data.storesLowerCaseIdentifiers()); out.println(" Stores Upper-case Identifiers : " + data.storesUpperCaseIdentifiers()); out.println(" Stores Mixed-case Identifiers : " + data.storesMixedCaseIdentifiers()); out.println(" Uses Local File Per Table : " + data.usesLocalFilePerTable()); out.println(" Uses Local Files : " + data.usesLocalFiles()); out.println(); out.println("Limits"); out.println(" Max Binary Literal Length : " + data.getMaxBinaryLiteralLength()); out.println(" Max Catalog Name Length : " + data.getMaxCatalogNameLength()); out.println(" Max Char Literal Length : " + data.getMaxCharLiteralLength()); out.println(" Max Column Name Length : " + data.getMaxColumnNameLength()); out.println(" Max Columns in GROUPBY : " + data.getMaxColumnsInGroupBy()); out.println(" Max Columns in Index : " + data.getMaxColumnsInIndex()); out.println(" Max Columns in ORDERBY : " + data.getMaxColumnsInOrderBy()); out.println(" Max Columns in SELECT : " + data.getMaxColumnsInSelect()); out.println(" Max Columns in Table : " + data.getMaxColumnsInTable()); out.println(" Max Connections : " + data.getMaxConnections()); out.println(" Max Index Length : " + data.getMaxIndexLength()); out.println(" Max Procedure Name Length : " + data.getMaxProcedureNameLength()); out.println(" Max Row Size : " + data.getMaxRowSize()); out.println(" Max Schema Name Length : " + data.getMaxSchemaNameLength()); out.println(" Max Statement Length : " + data.getMaxStatementLength()); out.println(" Max Statements Open : " + data.getMaxStatements()); out.println(" Max Table Name Length : " + data.getMaxTableNameLength()); out.println(" Max Tables in SELECT : " + data.getMaxTablesInSelect()); out.println(" Max Username Length : " + data.getMaxUserNameLength()); out.println(); out.println("Supports"); out.println(" Alter Table with Add Column : " + data.supportsAlterTableWithAddColumn()); out.println(" Alter Table with Drop Column : " + data.supportsAlterTableWithDropColumn()); out.println(" ANSI92 Entry Level SQL : " + data.supportsANSI92EntryLevelSQL()); out.println(" ANSI92 Full SQL : " + data.supportsANSI92FullSQL()); out.println(" ANSI92 Intermediate SQL : " + data.supportsANSI92IntermediateSQL()); out.println(" Catalogs in Data Manipulation : " + data.supportsCatalogsInDataManipulation()); out.println(" Catalogs in Index Definitions : " + data.supportsCatalogsInIndexDefinitions()); out.println(" Catalogs in Privilege Def : " + data.supportsCatalogsInPrivilegeDefinitions()); out.println(" Catalogs in Procedures Calls : " + data.supportsCatalogsInProcedureCalls()); out.println(" Catalogs in Table Definitions : " + data.supportsCatalogsInTableDefinitions()); out.println(" Supports Column Aliasing : " + data.supportsColumnAliasing()); out.println(" Supports Convert : " + data.supportsConvert()); out.println(" ODBC Core SQL Grammer : " + data.supportsCoreSQLGrammar()); out.println(" Correlated Subqueries : " + data.supportsCorrelatedSubqueries()); out.println(" Expressions in ORDERBY : " + data.supportsExpressionsInOrderBy()); out.println(" Extended SQL Grammer : " + data.supportsExtendedSQLGrammar()); out.println(" Full Outer Join : " + data.supportsFullOuterJoins()); out.println(" GROUPBY : " + data.supportsGroupBy()); out.println(" GROUPBY Beyond SELECT : " + data.supportsGroupByBeyondSelect()); out.println(" GROUPBY Unrelated : " + data.supportsGroupByUnrelated()); out.println(" Integrity Enhancement Facility : " + data.supportsIntegrityEnhancementFacility()); out.println(" LIKE Escape Clauses : " + data.supportsLikeEscapeClause()); out.println(" Limited Outer Joins : " + data.supportsLimitedOuterJoins()); out.println(" ODBC Minimum SQL Grammer : " + data.supportsMinimumSQLGrammar()); out.println(" Mixed Case Identifiers : " + data.supportsMixedCaseIdentifiers()); out.println(" Mixed Case Quoted Identifiers : " + data.supportsMixedCaseQuotedIdentifiers()); out.println(" Mulitple Result Sets : " + data.supportsMultipleResultSets()); out.println(" Multiple Transactions : " + data.supportsMultipleTransactions()); out.println(" Non Nullable Columns : " + data.supportsNonNullableColumns()); out.println(" Open Cursors across Commit : " + data.supportsOpenCursorsAcrossCommit()); out.println(" Open Cursors across Rollback : " + data.supportsOpenCursorsAcrossRollback()); out.println(" ORDERBY Unrelated : " + data.supportsOrderByUnrelated()); out.println(" Outer Joins : " + data.supportsOuterJoins()); out.println(" Positioned DELETE : " + data.supportsPositionedDelete()); out.println(" Positioned UPDATE : " + data.supportsPositionedUpdate()); out.println(" Schemas in Data Manipulation : " + data.supportsSchemasInDataManipulation()); out.println(" Schemas in Index Definitions : " + data.supportsSchemasInIndexDefinitions()); out.println(" Schemas in Privilege Def : " + data.supportsSchemasInPrivilegeDefinitions()); out.println(" Schemas in Procedure Calls : " + data.supportsSchemasInProcedureCalls()); out.println(" Schemas in Table Definitions : " + data.supportsSchemasInTableDefinitions()); out.println(" SELECT for UPDATE : " + data.supportsSelectForUpdate()); out.println(" Stored Procedures : " + data.supportsStoredProcedures()); out.println(" Subqueries in Comparisons : " + data.supportsSubqueriesInComparisons()); out.println(" Subqueries in EXISTS : " + data.supportsSubqueriesInExists()); out.println(" Subqueries in IN : " + data.supportsSubqueriesInIns()); out.println(" Subqueries in Quantifieds : " + data.supportsSubqueriesInQuantifieds()); out.println(" Table Correlation Names : " + data.supportsTableCorrelationNames()); out.println(" Transactions : " + data.supportsTransactions()); out.println(" UNION : " + data.supportsUnion()); out.println(" UNION ALL : " + data.supportsUnionAll()); out.println(" Data Manipulation Transactions Only: " + data.supportsDataManipulationTransactionsOnly()); out.println(" Different Table Correlation Names : " + data.supportsDifferentTableCorrelationNames()); out.println(" Data Definition and Data Manipulation Transactions: " + data.supportsDataDefinitionAndDataManipulationTransactions()); out.println(); out.println("Numeric Functions:"); strTmp = data.getNumericFunctions(); if(strTmp.length() == 0) strTmp = DBInfo.NONE; out.println(strTmp + '\n'); out.println("SQL Keywords:"); strTmp = data.getSQLKeywords(); if(strTmp.length() == 0) strTmp = DBInfo.NONE; out.println(strTmp + '\n'); out.println("System Function:"); strTmp = data.getSystemFunctions(); if(strTmp.length() == 0) strTmp = DBInfo.NONE; out.println(strTmp + '\n'); out.println("Date/Time Function:"); strTmp = data.getTimeDateFunctions(); if(strTmp.length() == 0) strTmp = DBInfo.NONE; out.println(strTmp + '\n'); out.println("Table Types:"); ResultSet results = data.getTableTypes(); for(iCnt = 0;results.next() == true;iCnt ++) out.print(results.getString(1) + ", "); if(iCnt == 0) out.println(DBInfo.NONE); out.println('\n'); out.println("Column Types:"); results = data.getTypeInfo(); for(iCnt = 0;results.next() == true;iCnt ++) out.print(results.getString(1) + ", "); if(iCnt == 0) out.println(DBInfo.NONE); out.println('\n'); } catch(SQLException e) { JDBC.printSQLException(e); } catch(InstantiationException e) { // This exception should not occur. The class loader has to be really screwed up. System.out.println("Error: " + e); } catch(IllegalAccessException e) { // This exception should not occur. The class loader has to be really screwed up. System.out.println("Error: " + e); } finally { // Close the Database Connection if(conn != null) { try { conn.close(); } catch(SQLException e) { } } } } private static String transactionIsolationToString(int transactionIsolation) { String strResult; switch(transactionIsolation) { case Connection.TRANSACTION_READ_COMMITTED: strResult = DBInfo.TRANSACTION_READ_COMMITTED; break; case Connection.TRANSACTION_READ_UNCOMMITTED: strResult = DBInfo.TRANSACTION_READ_UNCOMMITTED; break; case Connection.TRANSACTION_REPEATABLE_READ: strResult = DBInfo.TRANSACTION_REPEATABLE_READ; break; case Connection.TRANSACTION_SERIALIZABLE: strResult = DBInfo.TRANSACTION_SERIALIZABLE; break; case Connection.TRANSACTION_NONE: default: strResult = DBInfo.TRANSACTION_NONE; break; } return strResult; } }