/**
* This file is part of Waarp Project.
*
* Copyright 2009, Frederic Bregier, and individual contributors by the @author tags. See the
* COPYRIGHT.txt in the distribution for a full listing of individual contributors.
*
* All Waarp Project 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.
*
* Waarp 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 Waarp. If not, see
* <http://www.gnu.org/licenses/>.
*/
package org.waarp.common.database;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import org.waarp.common.database.exception.WaarpDatabaseNoConnectionException;
import org.waarp.common.database.exception.WaarpDatabaseNoDataException;
import org.waarp.common.database.exception.WaarpDatabaseSqlException;
import org.waarp.common.logging.WaarpLogger;
import org.waarp.common.logging.WaarpLoggerFactory;
/**
* Class to handle request
*
* @author Frederic Bregier
*
*/
public class DbRequest {
/**
* Internal Logger
*/
private static final WaarpLogger logger = WaarpLoggerFactory
.getLogger(DbRequest.class);
/**
* Internal Statement
*/
private Statement stmt = null;
/**
* Internal Result Set
*/
private ResultSet rs = null;
/**
* Internal DB Session
*/
private final DbSession ls;
/**
* Create a new request from the DbSession
*
* @param ls
* @throws WaarpDatabaseNoConnectionException
*/
public DbRequest(DbSession ls) throws WaarpDatabaseNoConnectionException {
if (ls.isDisActive()) {
ls.checkConnection();
}
this.ls = ls;
}
/**
* Create a statement with some particular options
*
* @return the new Statement
* @throws WaarpDatabaseNoConnectionException
* @throws WaarpDatabaseSqlException
*/
private Statement createStatement()
throws WaarpDatabaseNoConnectionException,
WaarpDatabaseSqlException {
if (ls == null) {
throw new WaarpDatabaseNoConnectionException("No connection");
}
if (ls.getConn() == null) {
throw new WaarpDatabaseNoConnectionException("No connection");
}
if (ls.isDisActive()) {
ls.checkConnection();
}
try {
return ls.getConn().createStatement();
} catch (SQLException e) {
ls.checkConnection();
try {
return ls.getConn().createStatement();
} catch (SQLException e1) {
throw new WaarpDatabaseSqlException(
"Error while Create Statement", e);
}
}
}
/**
* Execute a SELECT statement and set of Result. The statement must not be an
* update/insert/delete. The previous statement and resultSet are closed.
*
* @param select
* @throws WaarpDatabaseSqlException
* @throws WaarpDatabaseNoConnectionException
*/
public void select(String select)
throws WaarpDatabaseNoConnectionException,
WaarpDatabaseSqlException {
close();
stmt = createStatement();
// rs = stmt.executeQuery(select);
// or alternatively, if you don't know ahead of time that
// the query will be a SELECT...
try {
if (stmt.execute(select)) {
rs = stmt.getResultSet();
}
} catch (SQLException e) {
logger.error("SQL Exception Request:" + select + " " +
e.getMessage());
DbSession.error(e);
ls.checkConnectionNoException();
throw new WaarpDatabaseSqlException("SQL Exception Request:" +
select, e);
}
}
/**
* Execute a SELECT statement and set of Result. The statement must not be an
* update/insert/delete. The previous statement and resultSet are closed.
* The timeout is applied if > 0.
*
* @param select
* @param timeout
* in seconds
* @throws WaarpDatabaseSqlException
* @throws WaarpDatabaseNoConnectionException
*/
public void select(String select, int timeout)
throws WaarpDatabaseNoConnectionException,
WaarpDatabaseSqlException {
close();
stmt = createStatement();
if (timeout > 0) {
try {
stmt.setQueryTimeout(timeout);
} catch (SQLException e1) {
// ignore
}
}
// rs = stmt.executeQuery(select);
// or alternatively, if you don't know ahead of time that
// the query will be a SELECT...
try {
if (stmt.execute(select)) {
rs = stmt.getResultSet();
}
} catch (SQLException e) {
logger.error("SQL Exception Request:" + select + " " +
e.getMessage());
DbSession.error(e);
ls.checkConnectionNoException();
throw new WaarpDatabaseSqlException("SQL Exception Request:" +
select, e);
}
}
/**
* Execute a UPDATE/INSERT/DELETE statement and returns the number of row. The previous
* statement and resultSet are closed.
*
* @param query
* @return the number of row in the query
* @throws WaarpDatabaseSqlException
* @throws WaarpDatabaseNoConnectionException
*/
public int query(String query) throws WaarpDatabaseNoConnectionException,
WaarpDatabaseSqlException {
close();
stmt = createStatement();
try {
int rowcount = stmt.executeUpdate(query);
logger.debug("QUERY(" + rowcount + "): {}", query);
return rowcount;
} catch (SQLException e) {
logger.error("SQL Exception Request:" + query + " " +
e.getMessage());
DbSession.error(e);
ls.checkConnectionNoException();
throw new WaarpDatabaseSqlException("SQL Exception Request:" +
query, e);
}
}
/**
* Finished a Request (ready for a new one)
*/
public void close() {
// it is a good idea to release
// resources in a finally{} block
// in reverse-order of their creation
// if they are no-longer needed
if (rs != null) {
try {
rs.close();
} catch (SQLException sqlEx) {
ls.checkConnectionNoException();
} // ignore
rs = null;
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException sqlEx) {
ls.checkConnectionNoException();
} // ignore
stmt = null;
}
}
/**
* Get the last ID autoincrement from the last request
*
* @return the long Id or DbConstant.ILLEGALVALUE (Long.MIN_VALUE) if an error occurs.
* @throws WaarpDatabaseNoDataException
*/
public long getLastId() throws WaarpDatabaseNoDataException {
ResultSet rstmp;
long result = DbConstant.ILLEGALVALUE;
try {
rstmp = stmt.getGeneratedKeys();
if (rstmp.next()) {
result = rstmp.getLong(1);
}
rstmp.close();
rstmp = null;
} catch (SQLException e) {
DbSession.error(e);
ls.checkConnectionNoException();
throw new WaarpDatabaseNoDataException("No data found", e);
}
return result;
}
/**
* Move the cursor to the next result
*
* @return True if there is a next result, else False
* @throws WaarpDatabaseNoConnectionException
* @throws WaarpDatabaseSqlException
*/
public boolean getNext() throws WaarpDatabaseNoConnectionException,
WaarpDatabaseSqlException {
if (rs == null) {
logger.error("SQL ResultSet is Null into getNext");
throw new WaarpDatabaseNoConnectionException(
"SQL ResultSet is Null into getNext");
}
if (ls.isDisActive()) {
ls.checkConnection();
throw new WaarpDatabaseSqlException(
"Request cannot be executed since connection was recreated between");
}
try {
return rs.next();
} catch (SQLException e) {
logger.warn("SQL Exception to getNextRow" + " " + e.getMessage());
DbSession.error(e);
ls.checkConnectionNoException();
throw new WaarpDatabaseSqlException("SQL Exception to getNextRow",
e);
}
}
/**
*
* @return The resultSet (can be used in conjunction of getNext())
* @throws WaarpDatabaseNoConnectionException
*/
public ResultSet getResultSet() throws WaarpDatabaseNoConnectionException {
if (rs == null) {
throw new WaarpDatabaseNoConnectionException(
"SQL ResultSet is Null into getResultSet");
}
return rs;
}
/**
* Test if value is null and create the string for insert/update
*
* @param value
* @return the string as result
*/
public static String getIsNull(String value) {
return value == null ? " is NULL" : " = '" + value + "'";
}
}