View Javadoc

1   package com.explosion.expfmodules.rdbmsconn.dbom;
2   
3   /* =============================================================================
4    *       
5    *     Copyright 2004 Stephen Cowx
6    *
7    *     Licensed under the Apache License, Version 2.0 (the "License");
8    *     you may not use this file except in compliance with the License.
9    *     You may obtain a copy of the License at
10   *
11   *     http://www.apache.org/licenses/LICENSE-2.0
12   *
13   *     Unless required by applicable law or agreed to in writing, software
14   *     distributed under the License is distributed on an "AS IS" BASIS,
15   *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   *     See the License for the specific language governing permissions and
17   *     limitations under the License.
18   * 
19   * =============================================================================
20   */
21  
22  import java.sql.Connection;
23  import java.sql.DatabaseMetaData;
24  import java.sql.ResultSet;
25  import java.sql.SQLException;
26  import java.util.Enumeration;
27  import java.util.Hashtable;
28  import java.util.Vector;
29  
30  import javax.swing.JTree;
31  import javax.swing.table.DefaultTableModel;
32  import javax.swing.table.TableModel;
33  
34  import org.apache.log4j.LogManager;
35  import org.apache.log4j.Logger;
36  
37  import com.explosion.datastream.exql.gui.ExqlTreeNode;
38  import com.explosion.utilities.GeneralUtils;
39  import com.explosion.utilities.exception.ExceptionManagerFactory;
40  
41  public class DBMetaDataManager
42  {
43    private static Logger log = LogManager.getLogger(DBMetaDataManager.class);
44    private JTree tree;
45    private Connection conn;
46    private DatabaseMetaData databaseMetaData;
47  
48    public DBMetaDataManager(Connection conn)
49    {
50      try
51      {
52        this.conn = conn;
53      }
54      catch (Exception e)
55      {
56        ExceptionManagerFactory.getExceptionManager().manageException( e, "Exception caught while constructing Database MetaData Manager");
57      }
58    }
59  
60    /***
61     * This method will return the catalogs for this database.
62     * If there arent any or the getCatalogs() method has not been implemented,
63     * it will return an empty Vector.
64     */
65    private Vector getCatalogs(DatabaseMetaData dbmd)
66    {
67      Vector catalogs = new Vector();
68      ResultSet set = null;
69      try
70      {
71        set = dbmd.getCatalogs();
72        while (set.next())
73          catalogs.addElement(set.getString(1));
74      }
75      catch (SQLException e)
76      {
77  	  ExceptionManagerFactory.getExceptionManager().manageException(e,"Error while retrieving table types.  Resultset MetaData getCatalogs() has possibly not been implemented.");
78      }
79      finally
80      {
81        try
82        {
83          set.close();
84        }
85        catch (Exception e)
86        {
87        }
88      }
89      return catalogs;
90    }
91  
92    /***
93     * This method will return a set of schema names.  If there aren't any or the
94     * driver does not support this method then an empty Vector will be returned.
95     */
96    private Vector getSchemaNames(DatabaseMetaData dbmd)
97    {
98      Vector schemaNames = new Vector();
99      ResultSet set = null;
100     try
101     {
102       set = dbmd.getSchemas();
103       while (set.next())
104         schemaNames.addElement(set.getString(1));
105     }
106     catch (SQLException e)
107     {
108 		ExceptionManagerFactory.getExceptionManager().manageException(e,"Resultset MetaData getSchemas() has possibly not been implemented.");
109     }
110     finally
111     {
112       try
113       {
114         set.close();
115       }
116       catch (Exception e)
117       {
118       }
119     }
120     return schemaNames;
121   }
122 
123   /***
124    * This method will return a set of Table Types.  If there aren't any or the
125    * driver does not support this method then an empty Vector will be returned.
126    */
127   private Vector getTableTypes(DatabaseMetaData dbmd)
128   {
129     Vector tableTypes = new Vector();
130     ResultSet set = null;
131     try
132     {
133       set = dbmd.getTableTypes();
134       while (set.next())
135         tableTypes.addElement(set.getString(1));
136     }
137     catch (SQLException e)
138     {
139 		ExceptionManagerFactory.getExceptionManager().manageException(e,"Resultset MetaData getTableTypes() has possibly not been implemented.");
140     }
141     finally
142     {
143       try
144       {
145         set.close();
146       }
147       catch (Exception e)
148       {
149       }
150     }
151     return tableTypes;
152   }
153 
154   /***
155    * This method will return a set of Standard SQL Types supported by this database.  If there aren't any or the
156    * driver does not support this method then an empty Vector will be returned.
157    */
158   private Vector getTypeInfo(DatabaseMetaData dbmd)
159   {
160     Vector typeInfo = new Vector();
161     ResultSet set = null;
162     try
163     {
164       set = dbmd.getTypeInfo();
165       while (set.next())
166         typeInfo.addElement(set.getString(1));
167     }
168     catch (SQLException e)
169     {
170 		ExceptionManagerFactory.getExceptionManager().manageException(e,"Resultset MetaData getTypeInfo() has possibly not been implemented.");
171     }
172     finally
173     {
174       try
175       {
176         set.close();
177       }
178       catch (Exception e)
179       {
180       }
181     }
182     return typeInfo;
183   }
184 
185   /***
186    * This method will return a list of the tables in this database.  Each row of this list contains table
187    * data in the folowing order: Catalog, Schema, Name, Type, Remarks <br>
188    * If there aren't any tables or the driver does not support this method then an empty Vector will be returned.
189    */
190   private Vector getTables(DatabaseMetaData dbmd, String catalogName, String schemaName, String tableName, String[] types)
191   {
192     Vector tables = new Vector();
193     ResultSet set = null;
194     try
195     {
196       set = dbmd.getTables(catalogName, schemaName, tableName, types);
197       while (set.next())
198       {
199         Vector tableData = new Vector();
200         tableData.addElement(set.getString(1));
201         tableData.addElement(set.getString(2));
202         tableData.addElement(set.getString(3));
203         tableData.addElement(set.getString(4));
204         tableData.addElement(set.getString(5));
205         tables.addElement(tableData);
206       }
207     }
208     catch (SQLException e)
209     {
210 		ExceptionManagerFactory.getExceptionManager().manageException(e,"Resultset MetaData getTables() has possibly not been implemented.");
211     }
212     finally
213     {
214       try
215       {
216         set.close();
217       }
218       catch (Exception e)
219       {
220       }
221     }
222     return tables;
223   }
224 
225   /***
226    * This method will return a list of the columns in this table.  Each row of this list contains Vector
227    * data in the folowing order: TABLE_CAT, TABLE_SCHEM, TABLE_NAME, COLUMN_NAME, DATA_TYPE, TYPE_NAME, COLUMN_SIZE, BUFFER_LENGTH, DECIMAL_DIGITS, NUM_PREC_RADIX, NULLABLE, REMARKS, COLUMN_DEF, SQL_DATETIME_SUB, CHAR_OCTET_LENGTH, ORDINAL_POSITION, IS_NULLABLE <br>
228    * If there aren't any or the driver does not support this method then an empty Vector will be returned.
229    */
230   public Vector getColumns(DBEntity dbed, String columnName) throws Exception
231   {
232     Vector columns = new Vector();
233 
234     /* Need a metadata object for this job */
235     DatabaseMetaData dbmd = getDBMD();
236 
237     /* Get the desired information from the DBEntity Descriptor */
238     String catalog = dbed.getCatalogName();
239     String schema = dbed.getSchemaName();
240     String table = dbed.getEntityName();
241     ResultSet set = null;
242 
243     try
244     {
245       set = dbmd.getColumns(catalog, schema, table, columnName);
246       while (set.next())
247       {
248         Vector columnData = new Vector();
249         columnData.addElement(set.getString(1));
250         columnData.addElement(set.getString(2));
251         columnData.addElement(set.getString(3));
252         columnData.addElement(set.getString(4));
253         columnData.addElement(set.getString(5));
254         columnData.addElement(set.getString(6));
255         columnData.addElement(new Integer(set.getInt(7)));
256         columnData.addElement(new Integer(set.getInt(9)));
257         columnData.addElement(new Integer(set.getInt(10)));
258         columnData.addElement(new Integer(set.getInt(11)));
259         columnData.addElement(set.getString(12));
260         columnData.addElement(set.getString(13));
261         columnData.addElement(new Integer(set.getInt(16)));
262         columnData.addElement(new Integer(set.getInt(17)));
263         columnData.addElement(set.getString(18));
264         columns.addElement(columnData);
265       }
266     }
267     catch (SQLException e)
268     {
269 		ExceptionManagerFactory.getExceptionManager().manageException(e,"Resultset MetaData getColumns() has possibly not been implemented.");
270     }
271     finally
272     {
273       set.close();
274     }
275     return columns;
276   }
277 
278   /***
279    * This method will return a list of primary keys for a specific table.  Each row returned will contain
280    * a vector with it's columns in the following order:
281    * TABLE_CAT, TABLE_SCHEM, TABLE_NAME, COLUMN_NAME, KEY_SEQ, PK_NAME
282    * If there aren't any or the
283    * driver does not support this method then an empty Vector will be returned
284    */
285   private Vector getPrimaryKeys(DatabaseMetaData dbmd, String catalogName, String schemaName, String tableName)
286   {
287     Vector primaryKeys = new Vector();
288     ResultSet set = null;
289     try
290     {
291       set = dbmd.getPrimaryKeys(catalogName, schemaName, tableName);
292       while (set.next())
293       {
294         Vector pkData = new Vector();
295         pkData.addElement(set.getString(1));
296         pkData.addElement(set.getString(2));
297         pkData.addElement(set.getString(3));
298         pkData.addElement(set.getString(4));
299         pkData.addElement(new Short(set.getShort(5)));
300         pkData.addElement(set.getString(6));
301         primaryKeys.addElement(pkData);
302       }
303     }
304     catch (SQLException e)
305     {
306       primaryKeys.addElement("");
307 	  ExceptionManagerFactory.getExceptionManager().manageException(e,"Resultset MetaData getPrimaryKeys() has possibly not been implemented.");
308     }
309     finally
310     {
311       try
312       {
313         set.close();
314       }
315       catch (Exception e)
316       {
317       }
318     }
319     return primaryKeys;
320   }
321 
322 /***
323  * This method adds top level database information to a root node.
324  */
325   public void addTopDBNodes(ExqlTreeNode root) throws Exception
326   {
327     DatabaseMetaData dbmd = getDBMD();
328 
329     /* Get the catalogs for this database */
330     Vector catalogs = getCatalogs(dbmd);
331     for (int i = 0; i < catalogs.size(); i++)
332     {
333       /* Get the catalog and add it to the tree */
334       String catalog = (String) catalogs.elementAt(i);
335       DBEntity catalogDescriptor = new DBEntity(catalog, null, catalog, DBEntity.TYPE_CATALOG);
336       ExqlTreeNode catalogNode = new ExqlTreeNode(catalogDescriptor);
337       root.add(catalogNode);
338     }
339 
340     /* If there are no catalogs  */
341     if (catalogs.size() == 0)
342     {
343       /* Get the schemas for this database */
344       Vector schemas = getSchemaNames(dbmd);
345       if (schemas.size() == 0)
346         buildTableNodes(root, dbmd, null, null);
347       else
348         buildSchemaNodes(schemas, root, dbmd, null);
349     }
350   }
351   
352   public ExqlTreeNode getEntireMetaDataTree() throws Exception
353   {
354     DatabaseMetaData dbmd = getDBMD();
355 
356     /* Create a root node */
357     ExqlTreeNode root = new ExqlTreeNode(dbmd.getDatabaseProductName());
358 
359     /* Get the catalogs for this database */
360     Vector catalogs = getCatalogs(dbmd);
361     for (int i = 0; i < catalogs.size(); i++)
362     {
363       /* Get the catalog and add it to the tree */
364       String catalog = (String) catalogs.elementAt(i);
365       DBEntity catalogDescriptor = new DBEntity(catalog, null, catalog, DBEntity.TYPE_CATALOG);
366       ExqlTreeNode catalogNode = new ExqlTreeNode(catalogDescriptor);
367       root.add(catalogNode);
368 
369       /* Get the schemas for this catalog */
370       Vector schemas = getSchemaNames(dbmd);
371       if (schemas.size() == 0)
372         buildTableNodes(catalogNode, dbmd, catalog, null);
373       else
374         buildSchemaNodes(schemas, catalogNode, dbmd, catalog);
375 
376     }
377 
378     /* If there are no catalogs  */
379     if (catalogs.size() == 0)
380     {
381       /* Get the schemas for this database */
382       Vector schemas = getSchemaNames(dbmd);
383       if (schemas.size() == 0)
384         buildTableNodes(root, dbmd, null, null);
385       else
386         buildSchemaNodes(schemas, root, dbmd, null);
387     }
388 
389     return root;
390   }
391 
392   /***
393    * Retuns general Database information
394    */
395   public DefaultTableModel getGeneralDBMetaData() throws Exception
396   {
397     DatabaseMetaData dbmd = getDBMD();
398 
399     /* Create a default table model */
400     String[][] info = this.getGeneralDBInformation(dbmd);
401     Vector rows = new Vector();
402     for (int i = 0; i < info.length; i++)
403     {
404       Vector values = new Vector();
405       values.addElement(info[i][0]);
406       values.addElement(info[i][1]);
407       rows.addElement(values);
408     }
409 
410     Vector columnNames = new Vector();
411     columnNames.addElement("Property Name");
412     columnNames.addElement("Property Value");
413 
414     return new DefaultTableModel(rows, columnNames);
415   }
416 
417   /***
418    * This method willbuild schema nodes
419    */
420   private void buildSchemaNodes(Vector schemas, ExqlTreeNode parentNode, DatabaseMetaData dbmd, String catalog) throws Exception
421   {
422     ExqlTreeNode schemasNode = new ExqlTreeNode("Schemas");
423     parentNode.add(schemasNode);
424 
425     for (int j = 0; j < schemas.size(); j++)
426     {
427       /* Get the schema and add it to the tree */
428       String schema = (String) schemas.elementAt(j);
429       ExqlTreeNode schemaNode = new ExqlTreeNode(schema);
430       schemasNode.add(schemaNode);
431 
432       /* build the table Nodes */
433       buildTableNodes(schemaNode, dbmd, catalog, schema);
434     }
435   }
436 
437   /***
438    * This method builds table nodes
439    */
440   private void buildTableNodes(ExqlTreeNode parentNode, DatabaseMetaData dbmd, String catalog, String schema) throws Exception
441   {
442     /* Build TableType nodes and add them to the schema nodes */
443     Hashtable nodes = getTableTypeNodes(dbmd);
444 
445     /* Add the tables to the table type nodes */
446     Vector tables = getTables(dbmd, catalog, schema, null, null);
447     for (int k = 0; k < tables.size(); k++)
448     {
449       Vector tableInfo = (Vector) tables.elementAt(k);
450       String tableName = (String) tableInfo.elementAt(2);
451       String tableType = (String) tableInfo.elementAt(3);
452 
453       ExqlTreeNode typeNode = (ExqlTreeNode) nodes.get(getConvertedName(tableType));
454 
455       int tableTypeInt = DBEntity.TYPE_OTHER;
456       if (getConvertedName(tableType).toUpperCase().equals("SYSTEM TABLES"))
457         tableTypeInt = DBEntity.TYPE_SYSTEM_TABLE;
458       else if (getConvertedName(tableType).toUpperCase().equals("VIEWS"))
459         tableTypeInt = DBEntity.TYPE_VIEW;
460       else if (getConvertedName(tableType).toUpperCase().equals("TABLES"))
461         tableTypeInt = DBEntity.TYPE_TABLE;
462       else if (getConvertedName(tableType).toUpperCase().equals("SYNONYMS"))
463         tableTypeInt = DBEntity.TYPE_SYNONYM;
464 
465       DBEntity tableDescriptor = new DBEntity(catalog, schema, tableName, tableTypeInt);
466 	  log.debug("Building entity descriptor for table ==> catalog:" + catalog + " schema:" + schema + " tableName:" + tableName + ".");
467       ExqlTreeNode tableNode = new ExqlTreeNode(tableDescriptor);
468       typeNode.add(tableNode);
469 
470       //buildColumnNodes(tableNode,dbmd,catalog,schema,tableName);
471     }
472 
473     Enumeration en = nodes.keys();
474     while (en.hasMoreElements())
475     {
476       ExqlTreeNode typeNode = (ExqlTreeNode) nodes.get(en.nextElement());
477       if (typeNode.getChildCount() > 0)
478         parentNode.add(typeNode);
479     }
480 
481 
482   }
483 
484   private Hashtable getTableTypeNodes(DatabaseMetaData dbmd) throws Exception
485   {
486     Hashtable nodes = new Hashtable();
487     Vector tableTypes = getTableTypes(dbmd);
488     for (int i = 0; i < tableTypes.size(); i++)
489     {
490       String tableType = (String) tableTypes.elementAt(i);
491       String convertedName = getConvertedName(tableType);
492       ExqlTreeNode tableTypeNode = new ExqlTreeNode(convertedName);
493       nodes.put(convertedName, tableTypeNode);
494     }
495     return nodes;
496   }
497 
498   /***
499    * This method builds table nodes
500    */
501   public TableModel getBasicColumnInformation(DBEntity dbed) throws Exception
502   {
503     /* Add the tables to the table type nodes */
504     Vector columns = this.getColumns(dbed, null);
505 
506     /* Set up the column information */
507     Vector cols = new Vector();
508     cols.addElement("Index");
509     cols.addElement("Name");
510     cols.addElement("Type Name");
511     cols.addElement("IsNullable");
512     cols.addElement("Size");
513     cols.addElement("Default");
514     cols.addElement("Remarks");
515 
516     /* Populate the table with information */
517     Vector rows = new Vector();
518     for (int k = 0; k < columns.size(); k++)
519     {
520       Vector columnInfo = (Vector) columns.elementAt(k);
521       Vector row = new Vector();
522       row.addElement((columnInfo.elementAt(13) == null ? "" : ((Integer) columnInfo.elementAt(13)).toString()));//ORDINAL_POSITION
523       row.addElement((columnInfo.elementAt(3) == null ? "" : (String) columnInfo.elementAt(3)));//COLUMN_NAME
524       row.addElement((columnInfo.elementAt(5) == null ? "" : (String) columnInfo.elementAt(5)));//TYPE_NAME
525       row.addElement((columnInfo.elementAt(14) == null ? "" : (String) columnInfo.elementAt(14)));//IS_NULLABLE
526       row.addElement((columnInfo.elementAt(6) == null ? "" : ((Integer) columnInfo.elementAt(6)).toString()));//COLUMN_SIZE
527       row.addElement((columnInfo.elementAt(11) == null ? "" : (String) columnInfo.elementAt(11)));//COLUMN_DEF
528       row.addElement((columnInfo.elementAt(10) == null ? "" : (String) columnInfo.elementAt(10)));//REMARKS
529       rows.addElement(row);
530     }
531 
532     return new DefaultTableModel(rows, cols);
533 
534   }
535 
536   /***
537    * This method builds table nodes
538    */
539   public TableModel getExtendedColumnInformation(DBEntity dbed) throws Exception
540   {
541     /* Add the tables to the table type nodes */
542     Vector columns = this.getColumns(dbed, null);
543 
544     /* Set up the column information */
545     Vector cols = new Vector();
546     cols.addElement("Name");
547     cols.addElement("Type");
548     cols.addElement("Type Name");
549     cols.addElement("Size");
550     cols.addElement("Decimal digits");
551     cols.addElement("Nullable");
552     cols.addElement("Radix");
553     cols.addElement("Remarks");
554     cols.addElement("Default");
555     cols.addElement("Char bytes");
556     cols.addElement("Index");
557     cols.addElement("IsNullable");
558 
559     /* Populate the table with information */
560     Vector rows = new Vector();
561     for (int k = 0; k < columns.size(); k++)
562     {
563       Vector columnInfo = (Vector) columns.elementAt(k);
564       Vector row = new Vector();
565       row.addElement((columnInfo.elementAt(3) == null ? "" : (String) columnInfo.elementAt(3)));//COLUMN_NAME
566       row.addElement((columnInfo.elementAt(4) == null ? "" : (String) columnInfo.elementAt(4)));//DATA_TYPE
567       row.addElement((columnInfo.elementAt(5) == null ? "" : (String) columnInfo.elementAt(5)));//TYPE_NAME
568       row.addElement((columnInfo.elementAt(6) == null ? "" : ((Integer) columnInfo.elementAt(6)).toString()));//COLUMN_SIZE
569       row.addElement((columnInfo.elementAt(7) == null ? "" : ((Integer) columnInfo.elementAt(7)).toString()));//DECIMAL_DIGITS
570       row.addElement((columnInfo.elementAt(8) == null ? "" : ((Integer) columnInfo.elementAt(8)).toString()));//NUM_PREC_RADIX
571       row.addElement((columnInfo.elementAt(9) == null ? "" : ((Integer) columnInfo.elementAt(9)).toString()));//NULLABLE
572       row.addElement((columnInfo.elementAt(10) == null ? "" : (String) columnInfo.elementAt(10)));//REMARKS
573       row.addElement((columnInfo.elementAt(11) == null ? "" : (String) columnInfo.elementAt(11)));//COLUMN_DEF
574       row.addElement((columnInfo.elementAt(12) == null ? "" : ((Integer) columnInfo.elementAt(12)).toString()));//CHAR_OCTET_LENGTH
575       row.addElement((columnInfo.elementAt(13) == null ? "" : ((Integer) columnInfo.elementAt(13)).toString()));//ORDINAL_POSITION
576       row.addElement((columnInfo.elementAt(14) == null ? "" : (String) columnInfo.elementAt(14)));//IS_NULLABLE
577       rows.addElement(row);
578     }
579 
580     return new DefaultTableModel(rows, cols);
581 
582   }
583 
584 
585   private String[][] getGeneralDBInformation(DatabaseMetaData dbmd) throws Exception
586   {
587     String[][] metaData = new String[110][2];
588 
589     /* Add the desriptions */
590     metaData[0][0] = "DatabaseProductName";
591     metaData[1][0] = "DatabaseProductVersion";
592     metaData[2][0] = "DefaultTransactionIsolation";
593     metaData[3][0] = "DriverMajorVersion";
594     metaData[4][0] = "DriverMinorVersion";
595     metaData[5][0] = "DriverName";
596     metaData[6][0] = "DriverVersion";
597     metaData[7][0] = "ExtraNameCharacters";
598     metaData[8][0] = "IdentifierQuoteString";
599     metaData[9][0] = "MaxBinaryLiteralLength";
600     metaData[10][0] = "MaxCatalogNameLength";
601     metaData[11][0] = "MaxCharLiteralLength";
602     metaData[12][0] = "MaxColumnNameLength";
603     metaData[13][0] = "MaxColumnsInGroupBy";
604     metaData[14][0] = "MaxColumnsInIndex";
605     metaData[15][0] = "MaxColumnsInOrderBy";
606     metaData[16][0] = "MaxColumnsInSelect";
607     metaData[17][0] = "MaxColumnsInTable";
608     metaData[18][0] = "MaxConnections";
609     metaData[19][0] = "MaxCursorNameLength";
610     metaData[20][0] = "MaxIndexLength";
611     metaData[21][0] = "MaxProcedureNameLength";
612     metaData[22][0] = "MaxRowSize";
613     metaData[23][0] = "MaxSchemaNameLength";
614     metaData[24][0] = "MaxStatementLength";
615     metaData[25][0] = "MaxStatements";
616     metaData[26][0] = "MaxTableNameLength";
617     metaData[27][0] = "MaxTablesInSelect";
618     metaData[28][0] = "MaxUserNameLength";
619     metaData[29][0] = "NumericFunctions";
620     metaData[30][0] = "ProcedureTerm";
621     metaData[31][0] = "SchemaTerm";
622     metaData[32][0] = "SearchStringEscape";
623     metaData[33][0] = "SQLKeywords";
624     metaData[34][0] = "StringFunctions";
625     metaData[35][0] = "SystemFunctions";
626     metaData[36][0] = "TimeDateFunctions";
627     metaData[37][0] = "URL";
628     metaData[38][0] = "UserName";
629     metaData[39][0] = "isCatalogAtStart";
630     metaData[40][0] = "isReadOnly";
631     metaData[41][0] = "nullPlusNonNullIsNull";
632     metaData[42][0] = "nullsAreSortedAtEnd";
633     metaData[43][0] = "nullsAreSortedAtStart";
634     metaData[44][0] = "nullsAreSortedHigh";
635     metaData[45][0] = "nullsAreSortedLow";
636     metaData[46][0] = "storesLowerCaseIdentifiers";
637     metaData[47][0] = "storesLowerCaseQuotedIdentifiers";
638     metaData[48][0] = "storesMixedCaseIdentifiers";
639     metaData[49][0] = "storesMixedCaseQuotedIdentifiers";
640     metaData[50][0] = "storesUpperCaseIdentifiers";
641     metaData[51][0] = "storesUpperCaseQuotedIdentifiers";
642     metaData[52][0] = "supportsAlterTableWithAddColumn";
643     metaData[53][0] = "supportsAlterTableWithDropColumn";
644     metaData[54][0] = "supportsANSI92EntryLevelSQL";
645     metaData[55][0] = "supportsANSI92FullSQL";
646     metaData[56][0] = "supportsANSI92IntermediateSQL";
647     metaData[57][0] = "supportsBatchUpdates";
648     metaData[58][0] = "supportsCatalogsInDataManipulation";
649     metaData[59][0] = "supportsCatalogsInIndexDefinitions";
650     metaData[60][0] = "supportsCatalogsInPrivilegeDefinitions";
651     metaData[61][0] = "supportsCatalogsInProcedureCalls";
652     metaData[62][0] = "supportsCatalogsInTableDefinitions";
653     metaData[63][0] = "supportsColumnAliasing";
654     metaData[64][0] = "supportsConvert";
655     metaData[65][0] = "supportsCoreSQLGrammar";
656     metaData[66][0] = "supportsCorrelatedSubqueries";
657     metaData[67][0] = "supportsDataDefinitionAndDataManipulationTransactions";
658     metaData[68][0] = "supportsDataManipulationTransactionsOnly";
659     metaData[69][0] = "supportsDifferentTableCorrelationNames";
660     metaData[70][0] = "supportsExpressionsInOrderBy";
661     metaData[71][0] = "supportsExtendedSQLGrammar";
662     metaData[72][0] = "supportsFullOuterJoins";
663     metaData[73][0] = "supportsGroupBy";
664     metaData[74][0] = "supportsGroupByBeyondSelect";
665     metaData[75][0] = "supportsGroupByUnrelated";
666     metaData[76][0] = "supportsIntegrityEnhancementFacility";
667     metaData[77][0] = "supportsLikeEscapeClause";
668     metaData[78][0] = "supportsLimitedOuterJoins";
669     metaData[79][0] = "supportsMinimumSQLGrammar";
670     metaData[80][0] = "supportsMixedCaseIdentifiers";
671     metaData[81][0] = "supportsMixedCaseQuotedIdentifiers";
672     metaData[82][0] = "supportsMultipleResultSets";
673     metaData[83][0] = "supportsMultipleTransactions";
674     metaData[84][0] = "supportsNonNullableColumns";
675     metaData[85][0] = "supportsOpenCursorsAcrossCommit";
676     metaData[86][0] = "supportsOpenCursorsAcrossRollback";
677     metaData[87][0] = "supportsOpenStatementsAcrossCommit";
678     metaData[88][0] = "supportsOpenStatementsAcrossRollback";
679     metaData[89][0] = "supportsOrderByUnrelated";
680     metaData[90][0] = "supportsOuterJoins";
681     metaData[91][0] = "supportsPositionedDelete";
682     metaData[92][0] = "supportsPositionedUpdate";
683     metaData[93][0] = "supportsSchemasInDataManipulation";
684     metaData[94][0] = "supportsSchemasInIndexDefinitions";
685     metaData[95][0] = "supportsSchemasInPrivilegeDefinitions";
686     metaData[96][0] = "supportsSchemasInProcedureCalls";
687     metaData[97][0] = "supportsSchemasInTableDefinitions";
688     metaData[98][0] = "supportsSelectForUpdate";
689     metaData[99][0] = "supportsStoredProcedures";
690     metaData[100][0] = "supportsSubqueriesInComparisons";
691     metaData[101][0] = "supportsSubqueriesInExists";
692     metaData[102][0] = "supportsSubqueriesInIns";
693     metaData[103][0] = "supportsSubqueriesInQuantifieds";
694     metaData[104][0] = "supportsTableCorrelationNames";
695     metaData[105][0] = "supportsTransactions";
696     metaData[106][0] = "supportsUnion";
697     metaData[107][0] = "supportsUnionAll";
698     metaData[108][0] = "usesLocalFilePerTable";
699     metaData[109][0] = "usesLocalFiles";
700 
701     /* Add the values */
702     metaData[0][1] = dbmd.getDatabaseProductName();
703     metaData[1][1] = dbmd.getDatabaseProductVersion();
704     metaData[2][1] = Integer.toString(dbmd.getDefaultTransactionIsolation());
705     metaData[3][1] = Integer.toString(dbmd.getDriverMajorVersion());
706     metaData[4][1] = Integer.toString(dbmd.getDriverMinorVersion());
707     metaData[5][1] = dbmd.getDriverName();
708     metaData[6][1] = dbmd.getDriverVersion();
709     metaData[7][1] = dbmd.getExtraNameCharacters();
710     metaData[8][1] = dbmd.getIdentifierQuoteString();
711     metaData[9][1] = Integer.toString(dbmd.getMaxBinaryLiteralLength());
712     metaData[10][1] = Integer.toString(dbmd.getMaxCatalogNameLength());
713     metaData[11][1] = Integer.toString(dbmd.getMaxCharLiteralLength());
714     metaData[12][1] = Integer.toString(dbmd.getMaxColumnNameLength());
715     metaData[13][1] = Integer.toString(dbmd.getMaxColumnsInGroupBy());
716     metaData[14][1] = Integer.toString(dbmd.getMaxColumnsInIndex());
717     metaData[15][1] = Integer.toString(dbmd.getMaxColumnsInOrderBy());
718     metaData[16][1] = Integer.toString(dbmd.getMaxColumnsInSelect());
719     metaData[17][1] = Integer.toString(dbmd.getMaxColumnsInTable());
720     metaData[18][1] = Integer.toString(dbmd.getMaxConnections());
721     metaData[19][1] = Integer.toString(dbmd.getMaxCursorNameLength());
722     metaData[20][1] = Integer.toString(dbmd.getMaxIndexLength());
723     metaData[21][1] = Integer.toString(dbmd.getMaxProcedureNameLength());
724     metaData[22][1] = Integer.toString(dbmd.getMaxRowSize());
725     metaData[23][1] = Integer.toString(dbmd.getMaxSchemaNameLength());
726     metaData[24][1] = Integer.toString(dbmd.getMaxStatementLength());
727     metaData[25][1] = Integer.toString(dbmd.getMaxStatements());
728     metaData[26][1] = Integer.toString(dbmd.getMaxTableNameLength());
729     metaData[27][1] = Integer.toString(dbmd.getMaxTablesInSelect());
730     metaData[28][1] = Integer.toString(dbmd.getMaxUserNameLength());
731     metaData[29][1] = dbmd.getNumericFunctions();
732     metaData[30][1] = dbmd.getProcedureTerm();
733     metaData[31][1] = dbmd.getSchemaTerm();
734     metaData[32][1] = dbmd.getSearchStringEscape();
735     metaData[33][1] = dbmd.getSQLKeywords();
736     metaData[34][1] = dbmd.getStringFunctions();
737     metaData[35][1] = dbmd.getSystemFunctions();
738     metaData[36][1] = dbmd.getTimeDateFunctions();
739     metaData[37][1] = dbmd.getURL();
740     metaData[38][1] = dbmd.getUserName();
741     metaData[39][1] = new Boolean(dbmd.isCatalogAtStart()).toString();
742     metaData[40][1] = new Boolean(dbmd.isReadOnly()).toString();
743     metaData[41][1] = new Boolean(dbmd.nullPlusNonNullIsNull()).toString();
744     metaData[42][1] = new Boolean(dbmd.nullsAreSortedAtEnd()).toString();
745     metaData[43][1] = new Boolean(dbmd.nullsAreSortedAtStart()).toString();
746     metaData[44][1] = new Boolean(dbmd.nullsAreSortedHigh()).toString();
747     metaData[45][1] = new Boolean(dbmd.nullsAreSortedLow()).toString();
748     metaData[46][1] = new Boolean(dbmd.storesLowerCaseIdentifiers()).toString();
749     metaData[47][1] = new Boolean(dbmd.storesLowerCaseQuotedIdentifiers()).toString();
750     metaData[48][1] = new Boolean(dbmd.storesMixedCaseIdentifiers()).toString();
751     metaData[49][1] = new Boolean(dbmd.storesMixedCaseQuotedIdentifiers()).toString();
752     metaData[50][1] = new Boolean(dbmd.storesUpperCaseIdentifiers()).toString();
753     metaData[51][1] = new Boolean(dbmd.storesUpperCaseQuotedIdentifiers()).toString();
754     metaData[52][1] = new Boolean(dbmd.supportsAlterTableWithAddColumn()).toString();
755     metaData[53][1] = new Boolean(dbmd.supportsAlterTableWithDropColumn()).toString();
756     metaData[54][1] = new Boolean(dbmd.supportsANSI92EntryLevelSQL()).toString();
757     metaData[55][1] = new Boolean(dbmd.supportsANSI92FullSQL()).toString();
758     metaData[56][1] = new Boolean(dbmd.supportsANSI92IntermediateSQL()).toString();
759 //      metaData[57][1] = new Boolean(dbmd.supportsBatchUpdates()).toString();
760     metaData[58][1] = new Boolean(dbmd.supportsCatalogsInDataManipulation()).toString();
761     metaData[59][1] = new Boolean(dbmd.supportsCatalogsInIndexDefinitions()).toString();
762     metaData[60][1] = new Boolean(dbmd.supportsCatalogsInPrivilegeDefinitions()).toString();
763     metaData[61][1] = new Boolean(dbmd.supportsCatalogsInProcedureCalls()).toString();
764     metaData[62][1] = new Boolean(dbmd.supportsCatalogsInTableDefinitions()).toString();
765     metaData[63][1] = new Boolean(dbmd.supportsColumnAliasing()).toString();
766     metaData[64][1] = new Boolean(dbmd.supportsConvert()).toString();
767     metaData[65][1] = new Boolean(dbmd.supportsCoreSQLGrammar()).toString();
768     metaData[66][1] = new Boolean(dbmd.supportsCorrelatedSubqueries()).toString();
769     metaData[67][1] = new Boolean(dbmd.supportsDataDefinitionAndDataManipulationTransactions()).toString();
770     metaData[68][1] = new Boolean(dbmd.supportsDataManipulationTransactionsOnly()).toString();
771     metaData[69][1] = new Boolean(dbmd.supportsDifferentTableCorrelationNames()).toString();
772     metaData[70][1] = new Boolean(dbmd.supportsExpressionsInOrderBy()).toString();
773     metaData[71][1] = new Boolean(dbmd.supportsExtendedSQLGrammar()).toString();
774     metaData[72][1] = new Boolean(dbmd.supportsFullOuterJoins()).toString();
775     metaData[73][1] = new Boolean(dbmd.supportsGroupBy()).toString();
776     metaData[74][1] = new Boolean(dbmd.supportsGroupByBeyondSelect()).toString();
777     metaData[75][1] = new Boolean(dbmd.supportsGroupByUnrelated()).toString();
778     metaData[76][1] = new Boolean(dbmd.supportsIntegrityEnhancementFacility()).toString();
779     metaData[77][1] = new Boolean(dbmd.supportsLikeEscapeClause()).toString();
780     metaData[78][1] = new Boolean(dbmd.supportsLimitedOuterJoins()).toString();
781     metaData[79][1] = new Boolean(dbmd.supportsMinimumSQLGrammar()).toString();
782     metaData[80][1] = new Boolean(dbmd.supportsMixedCaseIdentifiers()).toString();
783     metaData[81][1] = new Boolean(dbmd.supportsMixedCaseQuotedIdentifiers()).toString();
784     metaData[82][1] = new Boolean(dbmd.supportsMultipleResultSets()).toString();
785     metaData[83][1] = new Boolean(dbmd.supportsMultipleTransactions()).toString();
786     metaData[84][1] = new Boolean(dbmd.supportsNonNullableColumns()).toString();
787     metaData[85][1] = new Boolean(dbmd.supportsOpenCursorsAcrossCommit()).toString();
788     metaData[86][1] = new Boolean(dbmd.supportsOpenCursorsAcrossRollback()).toString();
789     metaData[87][1] = new Boolean(dbmd.supportsOpenStatementsAcrossCommit()).toString();
790     metaData[88][1] = new Boolean(dbmd.supportsOpenStatementsAcrossRollback()).toString();
791     metaData[89][1] = new Boolean(dbmd.supportsOrderByUnrelated()).toString();
792     metaData[90][1] = new Boolean(dbmd.supportsOuterJoins()).toString();
793     metaData[91][1] = new Boolean(dbmd.supportsPositionedDelete()).toString();
794     metaData[92][1] = new Boolean(dbmd.supportsPositionedUpdate()).toString();
795     metaData[93][1] = new Boolean(dbmd.supportsSchemasInDataManipulation()).toString();
796     metaData[94][1] = new Boolean(dbmd.supportsSchemasInIndexDefinitions()).toString();
797     metaData[95][1] = new Boolean(dbmd.supportsSchemasInPrivilegeDefinitions()).toString();
798     metaData[96][1] = new Boolean(dbmd.supportsSchemasInProcedureCalls()).toString();
799     metaData[97][1] = new Boolean(dbmd.supportsSchemasInTableDefinitions()).toString();
800     metaData[98][1] = new Boolean(dbmd.supportsSelectForUpdate()).toString();
801     metaData[99][1] = new Boolean(dbmd.supportsStoredProcedures()).toString();
802     metaData[100][1] = new Boolean(dbmd.supportsSubqueriesInComparisons()).toString();
803     metaData[101][1] = new Boolean(dbmd.supportsSubqueriesInExists()).toString();
804     metaData[102][1] = new Boolean(dbmd.supportsSubqueriesInIns()).toString();
805     metaData[103][1] = new Boolean(dbmd.supportsSubqueriesInQuantifieds()).toString();
806     metaData[104][1] = new Boolean(dbmd.supportsTableCorrelationNames()).toString();
807     metaData[105][1] = new Boolean(dbmd.supportsTransactions()).toString();
808     metaData[106][1] = new Boolean(dbmd.supportsUnion()).toString();
809     metaData[107][1] = new Boolean(dbmd.supportsUnionAll()).toString();
810     metaData[108][1] = new Boolean(dbmd.usesLocalFilePerTable()).toString();
811     metaData[109][1] = new Boolean(dbmd.usesLocalFiles()).toString();
812 
813     return metaData;
814   }
815 
816   /***
817    * This method converts an uppercase string into a sentence case string.ie first letter
818    * capital, all others lowercase.An s is appended too.
819    */
820   private String getConvertedName(String tableType)
821   {
822     return tableType.substring(0, 1).toUpperCase() + tableType.substring(1, tableType.length()).toLowerCase() + "s";
823   }
824 
825   /***
826    * This methnod returns a DatabaseMetaDataObject all references to dbmd must come through
827    * here in case it is neccessary to implement some kind of autoreferesh facility
828    */
829   public DatabaseMetaData getDBMD() throws Exception
830   {
831     if (conn == null)
832       throw new Exception("DBMetaDataManager unable to return meta data as connection is currently null.");
833 
834     if (databaseMetaData == null)
835       databaseMetaData = conn.getMetaData();
836     return databaseMetaData;
837   }
838 
839 
840   public TableModel getBestRowIdentifier(DBEntity dbed) throws Exception
841   {
842     /* Counts the number ofrowa returned */
843     int count = 0;
844 
845     /* Initialise */
846     ResultSet bestIdentifiers = null;
847     Vector cols = new Vector();
848     Vector rows = new Vector();
849 
850     try
851     {
852       /* get a dbmd object */
853       DatabaseMetaData dbmd = getDBMD();
854 
855       /* Get the desired information from the DBEntity Descriptor */
856       String catalog = dbed.getCatalogName();
857       String schema = dbed.getSchemaName();
858       String table = dbed.getEntityName();
859 
860       /* Get the best row identifiers for this table */
861       bestIdentifiers = dbmd.getBestRowIdentifier(catalog, schema, table, DatabaseMetaData.bestRowTransaction, true);
862 
863       /* Set up the column information */
864       cols = new Vector();
865       cols.addElement("Scope");
866       cols.addElement("Column Name");
867       cols.addElement("Data Type");
868       cols.addElement("Type Name");
869       cols.addElement("columnSize");
870       cols.addElement("bufferLength");
871       cols.addElement("decimalDigits");
872       cols.addElement("pseudoColumn");
873 
874       /* Populate the table with information */
875       rows = new Vector();
876       while (bestIdentifiers.next())
877       {
878         count++;
879         Vector row = new Vector();
880         short scope = bestIdentifiers.getShort("SCOPE"); //=> actual scope of result
881         //bestRowTemporary - very temporary, while using row
882         //bestRowTransaction - valid for remainder of current transaction
883         //bestRowSession - valid for remainder of current session
884         String columnName = bestIdentifiers.getString("COLUMN_NAME"); // => column name
885         long dataType = bestIdentifiers.getLong("DATA_TYPE"); //=> SQL data type from java.sql.Types
886         String typeName = bestIdentifiers.getString("TYPE_NAME"); //=> Data source dependent type name, for a UDT the type name is fully qualified
887         int columnSize = bestIdentifiers.getInt("COLUMN_SIZE"); //=> precision
888         int bufferLength = bestIdentifiers.getInt("BUFFER_LENGTH"); //=> not used
889         short decimalDigits = bestIdentifiers.getShort("DECIMAL_DIGITS"); //=> scale
890         short pseduaColumn = bestIdentifiers.getShort("PSEUDO_COLUMN"); //=> is this a pseudo column like an Oracle ROWID bestRowUnknown - may or
891 
892         row.addElement(new Short(scope));
893         row.addElement(columnName);
894         row.addElement(new Long(dataType));
895         row.addElement(typeName);
896         row.addElement(new Integer(columnSize));
897         row.addElement(new Integer(bufferLength));
898         row.addElement(new Short(decimalDigits));
899         row.addElement(new Short(pseduaColumn));
900 
901         rows.addElement(row);
902       }
903     }
904     finally
905     {
906       bestIdentifiers.close();
907     }
908 
909 
910     if (count > 0)
911       return new DefaultTableModel(rows, cols);
912     else
913       return GeneralUtils.getEmptyModel("No information to show.");
914 
915   }
916 
917 }