/**
* 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.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.waarp.common.database.exception.WaarpDatabaseNoConnectionException;
import org.waarp.common.database.exception.WaarpDatabaseSqlException;
import org.waarp.common.logging.WaarpLogger;
import org.waarp.common.logging.WaarpLoggerFactory;
/**
* Class to handle PrepareStatement
*
* @author Frederic Bregier
*
*/
public class DbPreparedStatement {
/**
* Internal Logger
*/
private static final WaarpLogger logger = WaarpLoggerFactory
.getLogger(DbPreparedStatement.class);
/**
* Internal PreparedStatement
*/
private PreparedStatement preparedStatement = null;
/**
* The Associated request
*/
private String request = null;
/**
* Is this PreparedStatement ready
*/
private boolean isReady = false;
/**
* The associated resultSet
*/
private ResultSet rs = null;
/**
* The associated DB session
*/
private final DbSession ls;
/**
* Create a DbPreparedStatement from DbSession object
*
* @param ls
* @throws WaarpDatabaseNoConnectionException
*/
public DbPreparedStatement(DbSession ls)
throws WaarpDatabaseNoConnectionException {
if (ls == null) {
logger.error("SQL Exception PreparedStatement no session");
throw new WaarpDatabaseNoConnectionException(
"PreparedStatement no session");
}
if (ls.isDisActive()) {
logger.debug("DisActive: "+ls.getAdmin().getServer());
ls.checkConnection();
}
this.ls = ls;
rs = null;
preparedStatement = null;
setReady(false);
}
/**
* Create a DbPreparedStatement from DbSession object and a request
*
* @param ls
* @param request
* @throws WaarpDatabaseNoConnectionException
* @throws WaarpDatabaseSqlException
*/
public DbPreparedStatement(DbSession ls, String request)
throws WaarpDatabaseNoConnectionException,
WaarpDatabaseSqlException {
if (ls == null) {
logger.error("SQL Exception PreparedStatement no session");
throw new WaarpDatabaseNoConnectionException(
"PreparedStatement no session");
}
if (ls.isDisActive()) {
ls.checkConnection();
}
this.ls = ls;
rs = null;
setReady(false);
preparedStatement = null;
if (request == null) {
logger.error("SQL Exception PreparedStatement no request");
throw new WaarpDatabaseNoConnectionException(
"PreparedStatement no request");
}
try {
preparedStatement = this.ls.getConn().prepareStatement(request);
this.request = request;
setReady(true);
} catch (SQLException e) {
ls.checkConnection();
try {
preparedStatement = this.ls.getConn().prepareStatement(request);
this.request = request;
setReady(true);
} catch (SQLException e1) {
logger.error("SQL Exception PreparedStatement: " + request +
" " + e.getMessage());
DbSession.error(e);
preparedStatement = null;
setReady(false);
throw new WaarpDatabaseSqlException(
"SQL Exception PreparedStatement", e);
}
}
}
/**
* Create a DbPreparedStatement from DbSession object and a request
*
* @param ls
* @param request
* @param nbFetch
* the number of pre fetch rows
* @throws WaarpDatabaseNoConnectionException
* @throws WaarpDatabaseSqlException
*/
public DbPreparedStatement(DbSession ls, String request, int nbFetch)
throws WaarpDatabaseNoConnectionException,
WaarpDatabaseSqlException {
if (ls == null) {
logger.error("SQL Exception PreparedStatement no session");
throw new WaarpDatabaseNoConnectionException(
"PreparedStatement no session");
}
if (ls.isDisActive()) {
ls.checkConnection();
}
this.ls = ls;
rs = null;
setReady(false);
preparedStatement = null;
if (request == null) {
logger.error("SQL Exception PreparedStatement no request");
throw new WaarpDatabaseNoConnectionException(
"PreparedStatement no request");
}
try {
preparedStatement = this.ls.getConn().prepareStatement(request);
this.request = request;
this.preparedStatement.setFetchSize(nbFetch);
setReady(true);
} catch (SQLException e) {
ls.checkConnection();
try {
preparedStatement = this.ls.getConn().prepareStatement(request);
this.request = request;
this.preparedStatement.setFetchSize(nbFetch);
setReady(true);
} catch (SQLException e1) {
logger.error("SQL Exception PreparedStatement: " + request +
" " + e.getMessage());
DbSession.error(e);
preparedStatement = null;
setReady(false);
throw new WaarpDatabaseSqlException(
"SQL Exception PreparedStatement", e);
}
}
}
/**
* Create a preparedStatement from request
*
* @param requestarg
* @throws WaarpDatabaseNoConnectionException
* @throws WaarpDatabaseSqlException
*/
public void createPrepareStatement(String requestarg)
throws WaarpDatabaseNoConnectionException,
WaarpDatabaseSqlException {
if (requestarg == null) {
logger.error("createPreparedStatement no request");
throw new WaarpDatabaseNoConnectionException(
"PreparedStatement no request");
}
if (preparedStatement != null) {
realClose();
}
if (rs != null) {
close();
}
if (ls.isDisActive()) {
logger.debug("DisActive: "+ls.getAdmin().getServer());
ls.checkConnection();
}
try {
preparedStatement = ls.getConn().prepareStatement(requestarg);
request = requestarg;
setReady(true);
} catch (SQLException e) {
ls.checkConnection();
try {
preparedStatement = ls.getConn().prepareStatement(requestarg);
request = requestarg;
setReady(true);
} catch (SQLException e1) {
logger.error("SQL Exception createPreparedStatement from {}:" +
requestarg + " " + e.getMessage(), ls.getAdmin().getServer());
DbSession.error(e);
realClose();
preparedStatement = null;
setReady(false);
throw new WaarpDatabaseSqlException(
"SQL Exception createPreparedStatement: " + requestarg,
e);
}
}
}
/**
* In case of closing database connection, it is possible to reopen a long term
* preparedStatement as it was at creation.
*
* @throws WaarpDatabaseSqlException
* @throws WaarpDatabaseNoConnectionException
*/
public void recreatePreparedStatement()
throws WaarpDatabaseNoConnectionException,
WaarpDatabaseSqlException {
this.createPrepareStatement(request);
}
/**
* Execute a Select preparedStatement
*
* @throws WaarpDatabaseNoConnectionException
* @throws WaarpDatabaseSqlException
*
*/
public void executeQuery() throws WaarpDatabaseNoConnectionException,
WaarpDatabaseSqlException {
if (preparedStatement == null) {
logger.error("executeQuery no request");
throw new WaarpDatabaseNoConnectionException(
"executeQuery no request");
}
if (rs != null) {
close();
}
if (ls.isDisActive()) {
ls.checkConnection();
throw new WaarpDatabaseSqlException(
"Request cannot be executed since connection was recreated between: " +
request);
}
try {
rs = preparedStatement.executeQuery();
} catch (SQLException e) {
logger.error("SQL Exception executeQuery:" + request + " " +
e.getMessage());
DbSession.error(e);
close();
rs = null;
ls.checkConnectionNoException();
throw new WaarpDatabaseSqlException(
"SQL Exception executeQuery: " + request, e);
}
}
/**
* Execute the Update/Insert/Delete preparedStatement
*
* @return the number of row
* @throws WaarpDatabaseNoConnectionException
* @throws WaarpDatabaseSqlException
*/
public int executeUpdate() throws WaarpDatabaseNoConnectionException,
WaarpDatabaseSqlException {
if (preparedStatement == null) {
logger.error("executeUpdate no request");
throw new WaarpDatabaseNoConnectionException(
"executeUpdate no request");
}
if (rs != null) {
close();
}
if (ls.isDisActive()) {
ls.checkConnection();
throw new WaarpDatabaseSqlException(
"Request cannot be executed since connection was recreated between:" +
request);
}
int retour = -1;
try {
retour = preparedStatement.executeUpdate();
} catch (SQLException e) {
logger.error("SQL Exception executeUpdate:" + request + " " +
e.getMessage());
logger.debug("SQL Exception full stack trace", e);
DbSession.error(e);
ls.checkConnectionNoException();
throw new WaarpDatabaseSqlException(
"SQL Exception executeUpdate: " + request, e);
}
return retour;
}
/**
* Close the resultSet if any
*
*/
public void close() {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
}
rs = null;
}
}
/**
* Really close the preparedStatement and the resultSet if any
*
*/
public void realClose() {
close();
if (preparedStatement != null) {
if (ls.isDisActive()) {
ls.checkConnectionNoException();
}
try {
preparedStatement.close();
} catch (SQLException e) {
ls.checkConnectionNoException();
}
preparedStatement = null;
}
setReady(false);
}
/**
* 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.error("SQL Exception to getNextRow" + (request != null ? " [" + request + "]" : "") + " "
+ e.getMessage());
DbSession.error(e);
ls.checkConnectionNoException();
throw new WaarpDatabaseSqlException(
"SQL Exception to getNextRow: " + request, 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;
}
/**
*
* @return The preparedStatement (should be used in conjunction of createPreparedStatement)
* @throws WaarpDatabaseNoConnectionException
*/
public PreparedStatement getPreparedStatement()
throws WaarpDatabaseNoConnectionException {
if (preparedStatement == null) {
throw new WaarpDatabaseNoConnectionException(
"SQL PreparedStatement is Null into getPreparedStatement");
}
return preparedStatement;
}
/**
* @return the dbSession
*/
public DbSession getDbSession() {
return ls;
}
/**
* @return the isReady
*/
public boolean isReady() {
return isReady;
}
/**
* @param isReady the isReady to set
*/
private void setReady(boolean isReady) {
this.isReady = isReady;
}
}