Clover coverage report - Ledge Components - SNAPSHOT
Coverage timestamp: Fri Nov 17 2006 05:13:20 CET
file stats: LOC: 306   Methods: 9
NCLOC: 172   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
DatabaseUtils.java 100% 100% 100% 100%
coverage
 1    //
 2    // Copyright (c) 2003, Caltha - Gajda, Krzewski, Mach, Potempski Sp.J.
 3    // All rights reserved.
 4    //
 5    // Redistribution and use in source and binary forms, with or without modification,
 6    // are permitted provided that the following conditions are met:
 7    //
 8    // * Redistributions of source code must retain the above copyright notice,
 9    // this list of conditions and the following disclaimer.
 10    // * Redistributions in binary form must reproduce the above copyright notice,
 11    // this list of conditions and the following disclaimer in the documentation
 12    // and/or other materials provided with the distribution.
 13    // * Neither the name of the Caltha - Gajda, Krzewski, Mach, Potempski Sp.J.
 14    // nor the names of its contributors may be used to endorse or promote products
 15    // derived from this software without specific prior written permission.
 16    //
 17    // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 18    // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 19    // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 20    // IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 21    // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 22    // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 23    // OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 24    // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 25    // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 26    // POSSIBILITY OF SUCH DAMAGE.
 27    //
 28    package org.objectledge.database;
 29   
 30    import java.io.IOException;
 31    import java.io.LineNumberReader;
 32    import java.io.Reader;
 33    import java.sql.Connection;
 34    import java.sql.DatabaseMetaData;
 35    import java.sql.ResultSet;
 36    import java.sql.SQLException;
 37    import java.sql.Statement;
 38   
 39    import javax.sql.DataSource;
 40   
 41    import org.jcontainer.dna.Logger;
 42    import org.jcontainer.dna.impl.Log4JLogger;
 43    import org.objectledge.utils.StringUtils;
 44   
 45    /**
 46    * A set of utility functions for working with JDBC databases.
 47    *
 48    * @author <a href="mailto:rafal@caltha.pl">Rafal Krzewski</a>
 49    * @version $Id: DatabaseUtils.java,v 1.21 2005/03/30 09:20:04 rafal Exp $
 50    */
 51    public class DatabaseUtils
 52    {
 53    /** A logger. Bypasses LogFactory. */
 54    private static Logger log =
 55    new Log4JLogger(org.apache.log4j.Logger.getLogger(DatabaseUtils.class));
 56   
 57    ///CLOVER:OFF
 58    /**
 59    * Private constructor to prevent subclassing and enforce static access.
 60    */
 61    private DatabaseUtils()
 62    {
 63    // static access only
 64    }
 65    ///CLOVER:ON
 66   
 67    // utilities //////////////////////////////////////////////////////////////////////////////
 68   
 69    /**
 70    * Closes the connection.
 71    *
 72    * @param conn the connection.
 73    */
 74  31234 public static void close(Connection conn)
 75    {
 76  31234 try
 77    {
 78  31234 if (conn != null)
 79    {
 80  31188 conn.close();
 81    }
 82    }
 83    ///CLOVER:OFF
 84    catch (SQLException e)
 85    {
 86    log.error("failed to close connection", e);
 87    }
 88    ///CLOVER:ON
 89    }
 90   
 91    /**
 92    * Close the statement.
 93    *
 94    * @param stmt the statement.
 95    */
 96  4324 public static void close(Statement stmt)
 97    {
 98  4324 try
 99    {
 100  4324 if (stmt != null)
 101    {
 102  4278 stmt.close();
 103    }
 104    }
 105    ///CLOVER:OFF
 106    catch (SQLException e)
 107    {
 108    log.error("failed to close statement", e);
 109    }
 110    ///CLOVER:ON
 111    }
 112   
 113   
 114    /**
 115    * Close the result set.
 116    *
 117    * @param rs the result set.
 118    */
 119  10810 public static void close(ResultSet rs)
 120    {
 121  10810 try
 122    {
 123  10810 if (rs != null)
 124    {
 125  10764 rs.close();
 126    }
 127    }
 128    ///CLOVER:OFF
 129    catch (SQLException e)
 130    {
 131    log.error("failed to close result set", e);
 132    }
 133    ///CLOVER:ON
 134    }
 135   
 136    /**
 137    * Close the connection.
 138    *
 139    * @param conn the connection.
 140    * @param stmt the statement.
 141    * @param rs the result set.
 142    */
 143  46 public static void close(Connection conn, Statement stmt, ResultSet rs)
 144    {
 145  46 close(rs);
 146  46 close(stmt);
 147  46 close(conn);
 148    }
 149   
 150    /**
 151    * Unescape the string that comes from query.
 152    *
 153    * @param input the input string.
 154    * @return the result string.
 155    */
 156  31694 public static String unescapeSqlString(String input)
 157    {
 158  31694 return input;
 159    }
 160   
 161    /**
 162    * Escape the \ and ' in string that goes to statement.
 163    *
 164    * @param input the input string.
 165    * @return the result string.
 166    */
 167  11776 public static String escapeSqlString(String input)
 168    {
 169  11776 return StringUtils.backslashEscape(input, "'\\");
 170    }
 171   
 172    /**
 173    * Executes an SQL script.
 174    *
 175    * <p>
 176    * <ul>
 177    * <li>Lines starting with # are ignored</li>
 178    * <li>Statements may span multiple lines, line with a semicolon as the last charcter
 179    * terminates the statement.</li>
 180    * <li>Script execution is aborted when execution of an statement throws an exception.</li>
 181    * </ul>
 182    * </p>
 183    *
 184    * @param dataSource source of connections to the database.
 185    * @param reader the reader to read script from.
 186    * @throws IOException if the script cannot be read.
 187    * @throws SQLException if there is a problem executing the script.
 188    */
 189  4002 public static void runScript(DataSource dataSource, Reader reader)
 190    throws IOException, SQLException
 191    {
 192  4002 Connection conn = dataSource.getConnection();
 193  4002 try
 194    {
 195  4002 runScript(conn, reader);
 196    }
 197    finally
 198    {
 199  4002 close(conn);
 200    }
 201    }
 202   
 203    /**
 204    * Executes an SQL script.
 205    *
 206    * @see #runScript(Connection, Reader)
 207    * @param conn the connections to the database.
 208    * @param reader the reader to read script from.
 209    * @throws IOException if the script cannot be read.
 210    * @throws SQLException if there is a problem executing the script.
 211    */
 212  4002 public static void runScript(Connection conn, Reader reader)
 213    throws IOException, SQLException
 214    {
 215  4002 Statement stmt = conn.createStatement();
 216  4002 try
 217    {
 218  4002 LineNumberReader script = new LineNumberReader(reader);
 219  4002 StringBuilder buff = new StringBuilder();
 220  4002 int start;
 221   
 222  4002 while(script.ready())
 223    {
 224  120106 buff.setLength(0);
 225  120106 String line = script.readLine().trim();
 226  120106 if(line.length() == 0 || line.charAt(0) == '#' || line.startsWith("--"))
 227    {
 228  103914 continue;
 229    }
 230  16192 start = script.getLineNumber();
 231  16192 while(script.ready() && line.charAt(line.length()-1) != ';')
 232    {
 233  5474 buff.append(line).append('\n');
 234  5474 line = script.readLine().trim();
 235  5474 if(line.length() == 0 || line.charAt(0) == '#' || line.startsWith("--"))
 236    {
 237  276 if(script.ready())
 238    {
 239  230 line = script.readLine().trim();
 240  230 continue;
 241    }
 242    else
 243    {
 244  46 break;
 245    }
 246    }
 247    }
 248  16192 if(line.length() == 0 || line.charAt(line.length()-1) != ';')
 249    {
 250  46 throw new SQLException("unterminated statement at line "+start);
 251    }
 252  16146 buff.append(line);
 253  16146 buff.setLength(buff.length()-1); // remove ;
 254  16146 try
 255    {
 256  16146 stmt.execute(buff.toString());
 257    }
 258    catch(SQLException e)
 259    {
 260  46 throw (SQLException)
 261    new SQLException("error executing statement at line "+start).initCause(e);
 262    }
 263    }
 264    }
 265    finally
 266    {
 267  4002 close(stmt);
 268    }
 269    }
 270   
 271   
 272    /**
 273    * Checks if the given database contains a table with the given name.
 274    *
 275    * @param ds DataSource for creating connections to database in question.
 276    * @param table table name, case insensitive.
 277    * @return <code>true</code> if the database contains the table.
 278    * @throws SQLException if there is a problem executing the check.
 279    */
 280  7498 public static boolean hasTable(DataSource ds, String table)
 281    throws SQLException
 282    {
 283  7498 Connection conn = null;
 284  7498 ResultSet tables = null;
 285  7498 try
 286    {
 287  7498 conn = ds.getConnection();
 288  7498 DatabaseMetaData md = conn.getMetaData();
 289  7498 tables = md.getTables(null, null, null, null);
 290  7498 boolean result = false;
 291  7498 while(tables.next())
 292    {
 293  322966 if(tables.getString("TABLE_NAME").equalsIgnoreCase(table))
 294    {
 295  6900 result = true;
 296    }
 297    }
 298  7498 return result;
 299    }
 300    finally
 301    {
 302  7498 close(tables);
 303  7498 close(conn);
 304    }
 305    }
 306    }