// // Source File Name: Browser.java 1.3 // // Licensed Materials -- Property of IBM // // (c) Copyright International Business Machines Corporation, 1999. // All Rights Reserved. // // US Government Users Restricted Rights - // Use, duplication or disclosure restricted by // GSA ADP Schedule Contract with IBM Corp. // // PURPOSE : // Prompts for a Schema and table search pattern string. // Display a list of tables that macth the search pattern. // Allows the user to select a varitey of catalog information, // for each of the tables. // For more information about these samples, refer to the README file. // For more information on Programming in Java, refer to the // "Programming in Java" section of the Application Development Guide. // For more information on building and running Java programs for DB2, // refer to the "Building Java Applets and Applications" section of the // Application Building Guide. // For more information on the SQL language, refer to the SQL Reference. import java.io.*; import java.lang.*; import java.sql.*; import java.util.*; class Browser { static { try { // register the driver with DriverManager // The newInstance() call is needed for the sample to work with // JDK 1.1.1 on OS/2, where the Class.forName() method does not // run the static initializer. For other JDKs, the newInstance // call can be omitted. Class.forName("COM.ibm.db2.jdbc.app.DB2Driver").newInstance(); } catch (Exception e) { e.printStackTrace(); } } public static void main (String[] argv) { Connection con = null; try { // connect to server if (argv.length == 3) { // connect using command line arguments con = Tools.DBConnect(argv[0], argv[1], argv[2]); } else { // prompt user for database name, user ID, password con = Tools.DBConnect(); } con.setAutoCommit (false); boolean quit = false; int tableChoice = 0; String action = new String(""); String schema = new String(""); String table = new String(""); Vector tables = new Vector(); tables = listAndStoreTables (con); // main program asks which methods to run and then executes while (!quit) { System.out.println ("\n|Q=Quit C=cols P=Primary Key I=Index M=Imported Key |"); System.out.println ( "|T=Tab Priv O=Col Priv S=Stats X=Exported Key L=List Tables |"); System.out.println ("Enter an action: [Q | C | P | I | F | T | O | L]"); action = Tools.readString(); if (action.equalsIgnoreCase ("q")) { quit = true; } else { // depending on letter provided by user specific methods will perform // note user entries must be perfect or exceptions will be thrown if (action.equalsIgnoreCase ("l")) { tables = listAndStoreTables (con); } else { System.out.println ("Enter a table number:"); tableChoice = Integer.valueOf (Tools.readString()).intValue(); // a vector stores the names of the tables and schemas // vectors were used because of expandability // however, only one vector contains both the schema and table values schema = ((String)tables.elementAt((tableChoice-1)*2)).trim(); table = ((String)tables.elementAt((tableChoice-1)*2+1)).trim(); if (action.equalsIgnoreCase ("c")) { listColumns (con, schema, table); } if (action.equalsIgnoreCase ("p")) { listPrimaryKeys (con, schema, table); } if (action.equalsIgnoreCase ("i")) { listIndices (con, schema, table); } if (action.equalsIgnoreCase ("m")) { listForeignKeys (con, schema, table, true); } if (action.equalsIgnoreCase ("t")) { listTablePriv (con, schema, table); } if (action.equalsIgnoreCase ("o")) { listColPriv (con, schema, table); } if (action.equalsIgnoreCase ("s")) { listStats (con, schema, table); } if (action.equalsIgnoreCase ("x")) { listForeignKeys (con, schema, table, false); } System.out.print ("\n>> Hit Enter to Continue <<"); action = Tools.readString (); } } } // disconnect from connection made System.out.println ("\n>Disconnecting..."); con.commit(); con.close(); } catch (Exception e) { e.printStackTrace(); } } // // listAndStoreTables // - lists tables for user and stores tables and schemas in a vector // public static Vector listAndStoreTables (Connection con) { Vector storedTables = new Vector(); try { System.out.println ("Enter Table Schema Name Search Pattern:"); String tableSchemSearchPat = Tools.readString().toUpperCase(); System.out.println ("Enter Table Name Search Pattern:"); String tableSearchPat = Tools.readString().toUpperCase(); DatabaseMetaData dmd = con.getMetaData(); System.out.println ("# TABLE_SCHEMA TABLE_NAME TABLE_TYPE"); System.out.println (" ----------------------- ----------------------- ----------"); // create a vector to store all table types // this method insures that only as much memory as needed is used // to store the data types ResultSet rs1 = dmd.getTableTypes(); Vector tableTypes = new Vector(); while (rs1.next()) { tableTypes.addElement(rs1.getString (1)); } rs1.close(); // copy vector to an array to be used in getTables String[] tableType = new String[tableTypes.size()]; tableTypes.copyInto (tableType); String tableSchema = new String(""); String table = new String(""); String tType = new String(""); // output tables and types that fit search pattern ResultSet rs2 = dmd.getTables (null, tableSchemSearchPat, tableSearchPat, tableType); int indicator = 0; while (rs2.next()) { // format and read in text for output tableSchema = rs2.getString (2); table = rs2.getString (3); tType = rs2.getString (4); indicator = indicator + 1; System.out.println (Tools.padLength (String.valueOf(indicator), 3) + " " + Tools.padLength(tableSchema, 23) + " " + Tools.padLength(table, 23) + " " + tType); storedTables.addElement (tableSchema); storedTables.addElement (table); } rs2.close(); } catch (Exception e) { e.printStackTrace(); } return storedTables; } // // listColumns // - schemaName and tableName should be exact strings, NOT search patterns // public static void listColumns (Connection con, String schemaName, String tableName) { try { DatabaseMetaData dmd = con.getMetaData(); ResultSet rs = dmd.getColumns (null, schemaName, tableName, "%"); System.out.println ("\nSchema: " + schemaName + "\tTable: " + tableName); // variables to be used in loop through the result set int n = 0; int decLength = 0; int colLength = 0; String nlble = new String(""); String colName = new String(""); String colType = new String(""); String remarks = new String(""); String numOutput = new String(""); while (rs.next()) { colName = rs.getString (4); colType = rs.getString (6); colLength = rs.getInt (7); decLength = rs.getInt (9); // formated output numOutput = "(" + colLength; if (!rs.wasNull()) { numOutput = numOutput + ", " + decLength; } numOutput = numOutput + ")"; // if n = tyepNullable then column values are nullable else not n = rs.getInt (11); if (n == DatabaseMetaData.typeNullable) { nlble = "NULLABLE"; } else { nlble = "NOT NULLABLE"; } remarks = rs.getString (12); // output column characteristics to screen System.out.print (" " + colName + ", " + nlble + ", " + colType + ", " + numOutput); if (!rs.wasNull() && !remarks.equals("")) { System.out.print (", " + remarks); } System.out.print ("\n"); } rs.close(); } catch (Exception e) { e.printStackTrace(); } } // // listPrimaryKeys // - schemaName and tableName should be exact strings, NOT search patterns // public static void listPrimaryKeys (Connection con, String schemaName, String tableName) { try { DatabaseMetaData dmd = con.getMetaData(); ResultSet rs = dmd.getPrimaryKeys (null, schemaName, tableName); System.out.println ("\nPrimary Keys for " + schemaName + "." + tableName); String colName = new String(""); String pkName = new String(""); int num = 1; // retrieve data and output information while (rs.next()) { colName = rs.getString (4); pkName = rs.getString (6); System.out.print (" " + num + " Column: " + Tools.padLength(colName, 18) + " Primary Key Name: "); if (rs.wasNull()) { System.out.print ("NULL\n"); } else { System.out.print (pkName + "\n"); } num = num + 1; } rs.close(); } catch (Exception e) { e.printStackTrace(); } } // // listIndices // - schemaName and tableName should be exact strings, NOT search patterns // public static void listIndices (Connection con, String schemaName, String tableName) { try { DatabaseMetaData dmd = con.getMetaData(); ResultSet rs1 = dmd.getIndexInfo (null, schemaName, tableName, true, true); System.out.println ("\nPrimary Key or Unique Index for " + schemaName + "." + tableName); Vector indexCols = new Vector(); // getIndexInfo will return the names of all index columns // however it will not return the information about those columns // therfore store column names into a vector and perform another query // using getColumns where columnsearchpattern = column name in vector String colName1 = new String(""); while (rs1.next()) { colName1 = rs1.getString (9); if (!rs1.wasNull()) { indexCols.addElement (colName1); } } rs1.close(); String colName2 = new String(""); String type = new String(""); int length = 0; int scale = 0; // for every column name stored in indexColumns query the column // characteristics and output for (int cnt = 0; cnt < indexCols.size(); cnt = cnt + 1) { ResultSet rs2 = dmd.getColumns (null, schemaName, tableName, (String)indexCols.elementAt(cnt)); if (rs2.next()) { colName2 = rs2.getString (4); type = rs2.getString (6); length = rs2.getInt (7); scale = rs2.getInt (9); System.out.print (" " + colName2 + ", " + type + ", (" + length); if (!rs2.wasNull()) { System.out.print (", " + scale + ")\n"); } else { System.out.print (")\n"); } } rs2.close(); } } catch (Exception e) { e.printStackTrace(); } } // // listForeignKeys // - schemaName and tableName should be exact strings, NOT search patterns // public static void listForeignKeys (Connection con, String schemaName, String tableName, boolean importedKey) { try { DatabaseMetaData dmd = con.getMetaData(); ResultSet rs; // since the getImportedKeys and getExportedKeys methods return the same types of // information to the result set use the same method to do both // however we must choose which one through the boolean importedKey String keyType = new String(""); if (importedKey) { rs = dmd.getImportedKeys (null, schemaName, tableName); keyType = "Imported"; } else { rs = dmd.getExportedKeys (null, schemaName, tableName); keyType = "Exported"; } System.out.println ("\nPrimary Key and " + keyType + " Keys for " + schemaName + "." + tableName); String updateRuleType = new String(""); String deleteRuleType = new String(""); String pkColName = new String(""); String fkSchema = new String(""); String fkTable = new String(""); String fkColName = new String(""); String pkName = new String(""); String fkName = new String(""); short updateRule = 0; short deleteRule = 0; while (rs.next()) { // retrieve data and output // if the values for either rule type match values for the defined variables // in the DatabaseMetaData class then the rule type is found updateRule = rs.getShort (10); switch (updateRule) { case DatabaseMetaData.importedKeyCascade: updateRuleType = "CASCADE "; break; // non IBM only case DatabaseMetaData.importedKeyRestrict: updateRuleType = "RESTRICT "; break; // always for IBM DBMs default: updateRuleType = "SET NULL "; break; } deleteRule = rs.getShort (11); switch (deleteRule) { case DatabaseMetaData.importedKeyNoAction: deleteRuleType = "NO ACTION "; break; // most are non-IBM case DatabaseMetaData.importedKeyCascade: deleteRuleType = "CASCADE "; break; case DatabaseMetaData.importedKeyRestrict: deleteRuleType = "RESTRICT "; break; // always for IBM DBMs default: deleteRuleType = "SET NULL "; break; } pkColName = rs.getString (4); fkSchema = rs.getString (6); fkTable = rs.getString (7); fkColName = rs.getString (8); System.out.println (" " + pkColName + " " + fkSchema + "." + fkTable + "." + fkColName); System.out.println (" Update Rule: " + updateRuleType + ", Delete Rule: " + deleteRuleType); pkName = rs.getString (13); fkName = rs.getString (12); if (pkName != null) { System.out.println (" Primary Key Name: " + pkName); } if (fkName != null) { System.out.println (" Foreign Key Name: " + fkName); } } rs.close(); } catch (Exception e) { e.printStackTrace(); } } // // listTablePriv // - schemaName and tableName should be exact strings, NOT search patterns // public static void listTablePriv (Connection con, String schemaName, String tableName) { try { DatabaseMetaData dmd = con.getMetaData(); ResultSet rs = dmd.getTablePrivileges (null, schemaName, tableName); System.out.println ("\nCurrent User's Privileges for: " + schemaName + "." + tableName); System.out.println (" Grantor Grantee Privilege Grantable"); System.out.println (" --------------- ----------------- ---------- ---"); String grantor = new String(""); String grantee = new String(""); String privilege = new String(""); String grantable = new String(""); while (rs.next()) { // retrieve data and output necessary information grantor = rs.getString (4); grantee = rs.getString (5); privilege = rs.getString (6); grantable = rs.getString (7); System.out.println (" " + Tools.padLength(grantor, 16) + Tools.padLength(grantee, 18) + Tools.padLength(privilege, 11) + grantable); } rs.close(); } catch (Exception e) { e.printStackTrace(); } } // // listColPriv // - schemaName and tableName should be exact strings, NOT search patterns // public static void listColPriv (Connection con, String schemaName, String tableName) { try { DatabaseMetaData dmd = con.getMetaData(); System.out.println ("Enter Search Pattern for Column Name:"); String colSearchPat = Tools.readString(); // search using column privileges for all columns under search pattern ResultSet rs = dmd.getColumnPrivileges (null, schemaName, tableName, colSearchPat); String colName = new String(""); String colOld = new String(""); String grantor = new String(""); String grantee = new String(""); String privilege = new String(""); String grantable = new String(""); while (rs.next()) { // retrieve data and display under formated output colName = rs.getString (4); if (!colName.equals(colOld)) { System.out.println ("\n Column: " + colName + "\n"); System.out.println (" Grantor Grantee Privilege Grantable"); System.out.println (" --------------- ----------------- ---------- ---"); colOld = colName; } grantor = rs.getString (5); grantee = rs.getString (6); privilege = rs.getString (7); grantable = rs.getString (8); System.out.println (" " + Tools.padLength(grantor, 16) + Tools.padLength(grantee, 18) + Tools.padLength(privilege, 11) + grantable); } rs.close(); // close statement handle } catch (Exception e) { e.printStackTrace(); } } // // listStats // - schemaName and tableName should be exact strings, NOT search patterns // public static void listStats (Connection con, String schemaName, String tableName) { try { DatabaseMetaData dmd = con.getMetaData(); System.out.println ("\nStatistics for " + schemaName + "." + tableName); ResultSet rs = dmd.getIndexInfo (null, schemaName, tableName, true, true); String colName = new String(""); String indexName = new String(""); int card = 0; int pages = 0; while (rs.next()) { // if the data refers to the table not the columns indicate as such if (rs.getShort(7) == DatabaseMetaData.tableIndexStatistic) { System.out.println (" Table Statistics:"); } // retrieve data and output to screen else { colName = rs.getString (9); indexName = rs.getString (6); System.out.println (" Columns: " + Tools.padLength(colName, 19) + "Index Name: " + indexName); } card = rs.getInt (11); pages = rs.getInt (12); System.out.println (" Cardinality: " + card + "\t\tPages: " + pages); } rs.close(); } catch (Exception e) { e.printStackTrace(); } } }