/* * DatabaseConnection * * Copyright (C) 2010 Jaroslav Merxbauer * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * */ package notwa.dal; import notwa.common.ConnectionInfo; import java.sql.Connection; import java.sql.DriverManager; import java.sql.Statement; import java.sql.ResultSet; import java.sql.SQLException; import org.apache.log4j.Logger; /** * <code>DatabaseConnection</code> encapsulates the jdbc conneciton retrived * by the {@link DriverManager}. It provides a unified way to construct and * open the connection and to execte queries on it. * * @author eTeR * @version %I% %G% */ public class DatabaseConnection { private Connection con; private ConnectionInfo ci; private Logger log; /** * The sole constructor accepting the <code>ConnectionInfo</code> describing * the actual database and credentials to which we are trying to connect. * * @param ci The <code>ConnectionInfo</code> keeping the database server connection * information and credetials. */ public DatabaseConnection(ConnectionInfo ci) { this.log = Logger.getLogger(this.getClass()); this.ci = ci; } /** * Executes the given SQL Query and returns the result kept by the <code>ResultSet</code>. * The caller is responsible to know what type every column should be and call the * appropriate strongly typed method. * * @param query The SQL Query that should be executed againts the server. * @return The actual <code>ResultSet</code> filled by the executed query. * @throws SQLException If there is a problem with the database connection or * whenever there is a problem with retrieving data from * the database or accessing the ResultSet. */ public ResultSet executeQuery(String query) throws SQLException { log.trace(query); /* Make sure that you are connected, otherwise try to reconnect */ if (!isConnected()) { connect(); } Statement s = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE); ResultSet rs = s.executeQuery(query); return rs; } /** * Executes the given SQL Query and returns a single scalar value. * The caller is responsible specify the output type of this method. * * @param <TOutput> The output type the caller is expecting to receive. * @param query The SQL Query that should be executed againts the server. * Please make sure that this query result to one row with a * single column to acquire the correct data. * @return <code>Object</code> value from the first column of the first row which is * suposed to be the only returned variable. * <code>null</code> if there is no row. * @throws SQLException If there is a problem with the database connection or * whenever there is a problem with retrieving data from * the database or accessing the ResultSet. */ public <TOutput> TOutput executeScalar(String query) throws SQLException { log.trace(query); /* Make sure that you are connected, otherwise try to reconnect */ if (!isConnected()) { connect(); } Statement s = con.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); ResultSet rs = s.executeQuery(query); if (rs.next()) { return (TOutput) rs.getObject(1); } else { return null; } } /** * Verifies whether the connection wasn't already closed either manually by the * <code>close</code> method or due to some network problem. * If the connection haven't been even already got, it is consider at not connected. * @return <code>true</code> if there is a connection ongoing between the application * and the database server. * <code>false</code> otherwise. */ public boolean isConnected() { try { if (con != null) { return !this.con.isClosed(); } else { return false; } } catch (SQLException sex) { log.error("Error occured while asking isClosed on connection!", sex); return false; } } /** * Attempts to close the opened connection. */ public void close() { if (isConnected()) { try { con.close(); } catch (Exception ex) { log.error("Error occured while closing the connection!", ex); } } } /** * Attempts to connect to the database server provided by the <code>ConnectionInfo</code>. * * @throws SQLException When a critical issue occured during the connection process. */ private void connect() throws SQLException { try { con = DriverManager.getConnection(ci.compileConnectionString(), ci.getUser(), ci.getPassword()); } catch (SQLException ex) { log.error("Exception occured while connecting to the MySql database!", ex); throw ex; } } }