Coverage Report - org.apache.ojb.broker.ant.DBUtility
 
Classes in this File Line Coverage Branch Coverage Complexity
DBUtility
N/A
N/A
8.333
 
 1  
 package org.apache.ojb.broker.ant;
 2  
 
 3  
 /* Copyright 2002-2005 The Apache Software Foundation
 4  
  *
 5  
  * Licensed under the Apache License, Version 2.0 (the "License");
 6  
  * you may not use this file except in compliance with the License.
 7  
  * You may obtain a copy of the License at
 8  
  *
 9  
  *     http://www.apache.org/licenses/LICENSE-2.0
 10  
  *
 11  
  * Unless required by applicable law or agreed to in writing, software
 12  
  * distributed under the License is distributed on an "AS IS" BASIS,
 13  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  
  * See the License for the specific language governing permissions and
 15  
  * limitations under the License.
 16  
  */
 17  
 
 18  
 import java.sql.*;
 19  
 import java.util.Hashtable;
 20  
 
 21  
 /**
 22  
  * DBUtility is a utility class for verifying that various Database objects
 23  
  * exist in a specified database.  This utility does not use the jdbc 
 24  
  * DatabaseMetaData object because not all jdbc drivers fully implement
 25  
  * it (like org.hsqldb.jdbcDriver - suckers).
 26  
  * 
 27  
  * @author <a href="mailto:daren@softwarearena.com">Daren Drummond</a>
 28  
  * @version $Id: DBUtility.java,v 1.1 2007-08-24 22:17:41 ewestfal Exp $
 29  
  */
 30  
 public class DBUtility 
 31  
 {
 32  
         private Connection m_connection = null;
 33  
         
 34  
         private String m_url = null;
 35  
         private String m_user = null;
 36  
         private String m_pwd = null;
 37  
         private static String m_ORA_EXCEPTION_1000 = "ORA-01000";
 38  
         private static String m_ORA_EXCEPTION_604 = "ORA-00604";
 39  
 
 40  
         /**
 41  
          * DBUtility connects to the database in this constructor.
 42  
          * 
 43  
          * @param url                        String representing the jdbc connection url.  For example, "jdbc:hsqldb:target/test/OJB".
 44  
          * @param user                        The database user account to use for logging on.
 45  
          * @param pwd                        The password for the user
 46  
          * 
 47  
          * @throws SQLException                        Throws SQLException if there are problems connecting to the database.
 48  
          * @throws ClassNotFoundException        Throws ClassNotFoundException if the jdbc driver class can not be found.
 49  
          */
 50  
         public DBUtility(String url, String user, String pwd) 
 51  
         throws SQLException
 52  
         {
 53  
                 m_url = url;
 54  
                 m_user = user;
 55  
                 m_pwd = pwd;
 56  
                 m_connection = connect(url, user, pwd);                
 57  
         }
 58  
         
 59  
         public void release() throws SQLException
 60  
         {
 61  
                 if(m_connection != null)
 62  
                 {
 63  
                         m_connection.close();        
 64  
                 }
 65  
         }
 66  
         
 67  
         private void resetConnection()
 68  
         {
 69  
                 try
 70  
                 {
 71  
                         release();
 72  
                         connect(m_url, m_user, m_pwd);
 73  
                 }
 74  
                 catch(Exception e)
 75  
                 {
 76  
                         System.out.println("Could not reconnect to database!!!! " + e.getMessage());
 77  
                 }
 78  
         }
 79  
 
 80  
         private Connection connect(String url, String user, String pwd) throws SQLException
 81  
         {
 82  
                 m_connection = DriverManager.getConnection(url, user, pwd);                        
 83  
                 return m_connection;
 84  
         }
 85  
         
 86  
         
 87  
         /**
 88  
          *         Checks the database for the existence of this table.  Returns true if it
 89  
          *  exists, false if it doesn't exist, and throws a SQLException if the 
 90  
          *  connection is not established.  NOTE: If a schema is required for your
 91  
          *  database, then it should have been provided in the connection url.
 92  
          * 
 93  
          * @param         tableName        String name of the table that you want check for existence.
 94  
          * @return boolean                true if the table exists, false if it doesn't exist.
 95  
          */
 96  
         public boolean exists(String tableName)
 97  
         {
 98  
                 boolean bReturn = false;
 99  
 
 100  
                 if (tableName == null) return bReturn;
 101  
                 PreparedStatement checkTable = null;
 102  
                 try
 103  
                 {
 104  
                         //System.out.println("DBUtility: looking up table: " + tableName);
 105  
                         //System.out.println("Select * from " + tableName + " where 1=0");
 106  
                         checkTable = m_connection.prepareStatement("Select * from " + tableName + " where 1=0");
 107  
                         checkTable.executeQuery();
 108  
                         bReturn = true;
 109  
                 }
 110  
                 catch(Exception e)
 111  
                 {
 112  
                         if (e.getMessage().startsWith(m_ORA_EXCEPTION_1000) || e.getMessage().startsWith(m_ORA_EXCEPTION_604))
 113  
                         {
 114  
                                 System.out.println("Exceeded available Oracle cursors.  Resetting connection and trying the SQL statement again...");
 115  
                                 resetConnection();
 116  
                                 return exists(tableName);
 117  
                         }
 118  
                         else
 119  
                         {
 120  
                                 //System.out.println("DD - " + e.getMessage());
 121  
                                 bReturn = false;        
 122  
                         }
 123  
                 }
 124  
         
 125  
                 return bReturn;
 126  
         }
 127  
         
 128  
         private Hashtable m_columnCache = new Hashtable(79);
 129  
         
 130  
         private ResultSet getColumns(String tableName)
 131  
         {
 132  
                 return (ResultSet)m_columnCache.get(tableName);
 133  
         }
 134  
         private void putColumns(String tableName, ResultSet columns)
 135  
         {
 136  
                 m_columnCache.put(tableName, columns);
 137  
         }
 138  
         
 139  
         /**
 140  
          *         Checks the database for the existence of this table.column of the specified
 141  
          *  jdbc type.  Returns true if it exists, false if it doesn't exist, and throws 
 142  
          *  a SQLException if the connection is not established.  NOTE: If a schema is 
 143  
          *  required for your database, then it should have been provided in the 
 144  
          *         connection url.
 145  
          * 
 146  
          * @param        tableName                String name of the table to check.
 147  
          * @param        columnName                String name of the table column to check.
 148  
          * @param        jdbcType                Case insensitive String representation of 
 149  
          *                                                         the jdbc type of the column.  Valid values 
 150  
          *                                                         are string representations of the types listed
 151  
          *                                                         in java.sql.Types.  For example, "bit", "float",
 152  
          *                                                         "varchar", "clob", etc.
 153  
          * @param        ignoreCase                boolean flag that determines if the utility should
 154  
          *                                                         consider the column name case when searching for 
 155  
          *                                                         the database table.column.
 156  
          * 
 157  
          * @throws SQLException if the Table doesn't exist, if the column doesn't exist, if the column type doesn't match the specified jdbcType.
 158  
          */        
 159  
         public void exists(String tableName, String columnName, String jdbcType, boolean ignoreCase) throws SQLException
 160  
         {
 161  
                 if (tableName == null) throw new SQLException("TableName was null.  You must specify a valid table name.");
 162  
                 if (columnName == null) throw new SQLException("Column name was null.  You must specify a valid column name.");
 163  
 
 164  
                 ResultSet columns = getColumns(tableName);
 165  
 
 166  
                 if(columns == null)
 167  
                 {
 168  
                         //columns not in the cache, look them up and cache
 169  
                         PreparedStatement checkTable = null;
 170  
                         try
 171  
                         {
 172  
                                 //System.out.println("DBUtility: looking up table: " + tableName);
 173  
                                 //System.out.println("Select * from " + tableName + " where 1=0");
 174  
                                 checkTable = m_connection.prepareStatement("Select * from " + tableName + " where 1=0");
 175  
                                 columns = checkTable.executeQuery();
 176  
                                 putColumns(tableName, columns);
 177  
                         }
 178  
                         catch(SQLException sqle)
 179  
                         {
 180  
                                 if (sqle.getMessage().startsWith(m_ORA_EXCEPTION_1000) || sqle.getMessage().startsWith(m_ORA_EXCEPTION_604))
 181  
                                 {
 182  
                                         System.out.println("Exceeded available Oracle cursors.  Resetting connection and trying the SQL statement again...");
 183  
                                         resetConnection();
 184  
                                         exists(tableName, columnName, jdbcType, ignoreCase);
 185  
                                 }
 186  
                                 else
 187  
                                 {
 188  
                                         //System.out.println(sqle.getMessage());
 189  
                                         throw sqle;
 190  
                                 }
 191  
                         }        
 192  
                 }
 193  
                 
 194  
                 ResultSetMetaData rsMeta = columns.getMetaData();
 195  
                 int iColumns = rsMeta.getColumnCount();
 196  
                 int jdbcTypeConst = this.getJdbcType(jdbcType);
 197  
                 for(int i = 1; i <= iColumns; i++)
 198  
                 {
 199  
                         if(ignoreCase)
 200  
                         {
 201  
                                 //ignore case while testing
 202  
                                 if(columnName.equalsIgnoreCase(rsMeta.getColumnName(i)))
 203  
                                 {
 204  
                                         //The column exists, does the type match?
 205  
                                         if(jdbcTypeConst != rsMeta.getColumnType(i))
 206  
                                         {
 207  
                                                 throw new SQLException("The column '" + tableName + "." + columnName + "' is of type '" + rsMeta.getColumnTypeName(i) + "' and cannot be mapped to the jdbc type '" + jdbcType + "'.");
 208  
                                         }
 209  
                                         else
 210  
                                         {
 211  
                                                 return;        
 212  
                                         }
 213  
                                 }
 214  
                         }
 215  
                         else
 216  
                         {
 217  
                                 //enforce case-sensitive compare
 218  
                                 if(columnName.equals(rsMeta.getColumnName(i)))
 219  
                                 {
 220  
                                         //The column exists, does the type match?
 221  
                                         if(jdbcTypeConst != rsMeta.getColumnType(i))
 222  
                                         {
 223  
                                                 throw new SQLException("The column '" + tableName + "." + columnName + "' is of type '" + rsMeta.getColumnTypeName(i) + "' and cannot be mapped to the jdbc type '" + jdbcType + "'.");
 224  
                                         }
 225  
                                         else
 226  
                                         {
 227  
                                                 return;        
 228  
                                         }
 229  
                                 }                                
 230  
                                 
 231  
                         }
 232  
                         
 233  
                         //System.out.println("Found column: " + rsMeta.getColumnName(i));
 234  
                 }
 235  
 
 236  
                 throw new SQLException("The column '" + columnName + "' was not found in table '" + tableName + "'.");
 237  
 
 238  
         }        
 239  
         
 240  
         /**
 241  
          *         Checks the database for the existence of this table.column of the specified
 242  
          *  jdbc type.  Throws a SQLException if if the Table.Column can not be found, and
 243  
          *         throws a SQLWarning if the column type does not match the passed JDBC type.
 244  
          *  NOTE: If a schema is required for your database, then it should have been 
 245  
          *         provided in the connection url.
 246  
          * 
 247  
          * @param        tableName                String name of the table to check.
 248  
          * @param        columnName                String name of the table column to check.
 249  
          * @param        jdbcType                Case insensitive String representation of 
 250  
          *                                                         the jdbc type of the column.  Valid values 
 251  
          *                                                         are string representations of the types listed
 252  
          *                                                         in java.sql.Types.  For example, "bit", "float",
 253  
          *                                                         "varchar", "clob", etc.
 254  
          * @param        ignoreCase                boolean flag that determines if the utility should
 255  
          *                                                         consider the column name case when searching for 
 256  
          *                                                         the database table.column.
 257  
          * 
 258  
          * @throws SQLException if the Table doesn't exist, if the column doesn't exist.
 259  
          * @throws SQLWarning if the column type doesn't match the specified jdbcType.
 260  
          */        
 261  
         public void existsUseWarnings(String tableName, String columnName, String jdbcType, boolean ignoreCase) throws SQLException, SQLWarning
 262  
         {
 263  
                 if (tableName == null) throw new SQLException("TableName was null.  You must specify a valid table name.");
 264  
                 if (columnName == null) throw new SQLException("Column name was null.  You must specify a valid column name.");
 265  
 
 266  
                 ResultSet columns = getColumns(tableName);
 267  
                 
 268  
                 if(columns == null)
 269  
                 {
 270  
                         //columns not in the cache, look them up and cache
 271  
                         try
 272  
                         {
 273  
                                 //System.out.println("DBUtility: looking up table: " + tableName);
 274  
                                 //System.out.println("Select * from " + tableName + " where 1=0");
 275  
                                 PreparedStatement checkTable = m_connection.prepareStatement("Select * from " + tableName + " where 1=0");
 276  
                                 columns = checkTable.executeQuery();
 277  
                                 putColumns(tableName, columns);
 278  
                         }
 279  
                         catch(SQLException sqle)
 280  
                         {
 281  
                                 if (sqle.getMessage().startsWith(m_ORA_EXCEPTION_1000) || sqle.getMessage().startsWith(m_ORA_EXCEPTION_604))
 282  
                                 {
 283  
                                         System.out.println("Exceeded available Oracle cursors.  Resetting connection and trying the SQL statement again...");
 284  
                                         resetConnection();
 285  
                                         existsUseWarnings(tableName, columnName, jdbcType, ignoreCase); 
 286  
                                 }
 287  
                                 else
 288  
                                 {
 289  
                                         //System.out.println(sqle.getMessage());
 290  
                                         throw sqle;
 291  
                                 }
 292  
                         }
 293  
                 }
 294  
                 
 295  
                 ResultSetMetaData rsMeta = columns.getMetaData();
 296  
                 int iColumns = rsMeta.getColumnCount();
 297  
                 int jdbcTypeConst = this.getJdbcType(jdbcType);
 298  
                 for(int i = 1; i <= iColumns; i++)
 299  
                 {
 300  
                         if(ignoreCase)
 301  
                         {
 302  
                                 //ignore case while testing
 303  
                                 if(columnName.equalsIgnoreCase(rsMeta.getColumnName(i)))
 304  
                                 {
 305  
                                         //The column exists, does the type match?
 306  
                                         if(jdbcTypeConst != rsMeta.getColumnType(i))
 307  
                                         {
 308  
                                                 throw new SQLWarning("The column '" + tableName + "." + columnName + "' is of type '" + rsMeta.getColumnTypeName(i) + "' and cannot be mapped to the jdbc type '" + jdbcType + "'.");
 309  
                                         }
 310  
                                         else
 311  
                                         {
 312  
                                                 return;        
 313  
                                         }
 314  
                                 }
 315  
                         }
 316  
                         else
 317  
                         {
 318  
                                 //enforce case-sensitive compare
 319  
                                 if(columnName.equals(rsMeta.getColumnName(i)))
 320  
                                 {
 321  
                                         //The column exists, does the type match?
 322  
                                         if(jdbcTypeConst != rsMeta.getColumnType(i))
 323  
                                         {
 324  
                                                 throw new SQLWarning("The column '" + tableName + "." + columnName + "' is of type '" + rsMeta.getColumnTypeName(i) + "' and cannot be mapped to the jdbc type '" + jdbcType + "'.");
 325  
                                         }
 326  
                                         else
 327  
                                         {
 328  
                                                 return;        
 329  
                                         }
 330  
                                 }                                
 331  
                                 
 332  
                         }
 333  
                         
 334  
                         //System.out.println("Found column: " + rsMeta.getColumnName(i));
 335  
                 }
 336  
 
 337  
                 throw new SQLException("The column '" + columnName + "' was not found in table '" + tableName + "'.");
 338  
 
 339  
         }                
 340  
         
 341  
         
 342  
         /**
 343  
          *         Checks the database for the existence of this table.column.  
 344  
          *         Throws a SQLException if if the Table.Column can not be found.
 345  
          *  NOTE: If a schema is required for your
 346  
          *  database, then it should have been provided in the connection url.
 347  
          * 
 348  
          * @param        tableName                String name of the table to check.
 349  
          * @param        columnName                String name of the table column to check.
 350  
          * @param        ignoreCase                boolean flag that determines if the utility should
 351  
          *                                                         consider the column name case when searching for 
 352  
          *                                                         the database table.column.
 353  
          * 
 354  
          * @throws SQLException if the Table doesn't exist, if the column doesn't exist.
 355  
          */        
 356  
         
 357  
         public void exists(String tableName, String columnName, boolean ignoreCase) throws SQLException
 358  
         {
 359  
                 if (tableName == null) throw new SQLException("TableName was null.  You must specify a valid table name.");
 360  
                 if (columnName == null) throw new SQLException("Column name was null.  You must specify a valid column name.");
 361  
 
 362  
                 ResultSet columns = getColumns(tableName);
 363  
                 
 364  
                 if(columns == null)
 365  
                 {
 366  
                         //columns not in the cache, look them up and cache
 367  
                         try
 368  
                         {
 369  
                                 //System.out.println("DBUtility: looking up table: " + tableName);
 370  
                                 //System.out.println("Select * from " + tableName + " where 1=0");
 371  
                                 PreparedStatement checkTable = m_connection.prepareStatement("Select * from " + tableName + " where 1=0");
 372  
                                 columns = checkTable.executeQuery();
 373  
                                 putColumns(tableName, columns);
 374  
                         }
 375  
                         catch(SQLException sqle)
 376  
                         {
 377  
                                 if (sqle.getMessage().startsWith(m_ORA_EXCEPTION_1000) || sqle.getMessage().startsWith(m_ORA_EXCEPTION_604))
 378  
                                 {
 379  
                                         System.out.println("Exceeded available Oracle cursors.  Resetting connection and trying the SQL statement again...");
 380  
                                         resetConnection();
 381  
                                         exists(tableName, columnName, ignoreCase);
 382  
                                 }
 383  
                                 else
 384  
                                 {
 385  
                                         System.out.println(sqle.getMessage());
 386  
                                         throw sqle;
 387  
                                 }
 388  
                         }
 389  
                 }
 390  
                 
 391  
                 ResultSetMetaData rsMeta = columns.getMetaData();
 392  
                 int iColumns = rsMeta.getColumnCount();
 393  
                 for(int i = 1; i <= iColumns; i++)
 394  
                 {
 395  
                         if(ignoreCase)
 396  
                         {
 397  
                                 //ignore case while testing
 398  
                                 if(columnName.equalsIgnoreCase(rsMeta.getColumnName(i)))
 399  
                                 {
 400  
                                         return;
 401  
                                 }
 402  
                         }
 403  
                         else
 404  
                         {
 405  
                                 //enforce case-sensitive compare
 406  
                                 if(columnName.equals(rsMeta.getColumnName(i)))
 407  
                                 {
 408  
                                         return;
 409  
                                 }                                
 410  
                                 
 411  
                         }
 412  
                         
 413  
                         //System.out.println("Found column: " + rsMeta.getColumnName(i));
 414  
                 }
 415  
 
 416  
                 throw new SQLException("The column '" + columnName + "' was not found in table '" + tableName + "'.");
 417  
 
 418  
         }        
 419  
                 
 420  
         
 421  
           /**
 422  
      * Determines the java.sql.Types constant value from an OJB 
 423  
      * FIELDDESCRIPTOR value.
 424  
      * 
 425  
      * @param type The FIELDDESCRIPTOR which JDBC type is to be determined.
 426  
      * 
 427  
      * @return int the int value representing the Type according to
 428  
      * 
 429  
      * @throws SQLException if the type is not a valid jdbc type.
 430  
      * java.sql.Types
 431  
      */
 432  
     public int getJdbcType(String ojbType) throws SQLException
 433  
     {
 434  
         int result;
 435  
         if(ojbType == null) ojbType = "";
 436  
                 ojbType = ojbType.toLowerCase();
 437  
         if (ojbType.equals("bit"))
 438  
             result = Types.BIT;
 439  
         else if (ojbType.equals("tinyint"))
 440  
             result = Types.TINYINT;
 441  
         else if (ojbType.equals("smallint"))
 442  
             result = Types.SMALLINT;
 443  
         else if (ojbType.equals("integer"))
 444  
             result = Types.INTEGER;
 445  
         else if (ojbType.equals("bigint"))
 446  
             result = Types.BIGINT;
 447  
 
 448  
         else if (ojbType.equals("float"))
 449  
             result = Types.FLOAT;
 450  
         else if (ojbType.equals("real"))
 451  
             result = Types.REAL;
 452  
         else if (ojbType.equals("double"))
 453  
             result = Types.DOUBLE;
 454  
 
 455  
         else if (ojbType.equals("numeric"))
 456  
             result = Types.NUMERIC;
 457  
         else if (ojbType.equals("decimal"))
 458  
             result = Types.DECIMAL;
 459  
 
 460  
         else if (ojbType.equals("char"))
 461  
             result = Types.CHAR;
 462  
         else if (ojbType.equals("varchar"))
 463  
             result = Types.VARCHAR;
 464  
         else if (ojbType.equals("longvarchar"))
 465  
             result = Types.LONGVARCHAR;
 466  
 
 467  
         else if (ojbType.equals("date"))
 468  
             result = Types.DATE;
 469  
         else if (ojbType.equals("time"))
 470  
             result = Types.TIME;
 471  
         else if (ojbType.equals("timestamp"))
 472  
             result = Types.TIMESTAMP;
 473  
 
 474  
         else if (ojbType.equals("binary"))
 475  
             result = Types.BINARY;
 476  
         else if (ojbType.equals("varbinary"))
 477  
             result = Types.VARBINARY;
 478  
         else if (ojbType.equals("longvarbinary"))
 479  
             result = Types.LONGVARBINARY;
 480  
 
 481  
                 else if (ojbType.equals("clob"))
 482  
                      result = Types.CLOB;
 483  
                 else if (ojbType.equals("blob"))
 484  
                         result = Types.BLOB;
 485  
         else
 486  
             throw new SQLException(
 487  
                 "The type '"+ ojbType + "' is not a valid jdbc type.");
 488  
         return result;
 489  
     }        
 490  
 
 491  
         protected void finalize()
 492  
         {
 493  
                 try
 494  
                 {
 495  
                         release();
 496  
                 }
 497  
                 catch(Exception e)
 498  
                 {
 499  
                         e.printStackTrace();        
 500  
                 }
 501  
         }
 502  
 }