blob: e80b683a4e7852b1b6682ba0cd641373cd9db62a [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.empire.db.context;
import java.sql.Connection;
import java.sql.SQLException;
import org.apache.empire.db.DBCommand;
import org.apache.empire.db.DBContext;
import org.apache.empire.db.DBObject;
import org.apache.empire.db.DBTable;
import org.apache.empire.db.DBUtils;
import org.apache.empire.db.context.DBRollbackManager.ReleaseAction;
import org.apache.empire.db.exceptions.EmpireSQLException;
import org.apache.empire.exceptions.InvalidArgumentException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* DBContextBase
* Basic implementation of the DBContext interface which can be used as a base class for own implmentations
* @author rainer
*/
public abstract class DBContextBase implements DBContext
{
// Logger
private static final Logger log = LoggerFactory.getLogger(DBContextBase.class);
private DBUtils utils = null;
private boolean noRollbackManagerWarnOnce = true;
/**
* Factory function for Utils creation
* @return the utils implementation
*/
protected DBUtils createUtils()
{
return new DBUtils(this);
}
@Override
public DBUtils getUtils()
{
if (utils==null)
utils = createUtils();
return utils;
}
protected abstract Connection getConnection(boolean required);
protected abstract DBRollbackManager getRollbackManager(boolean required);
@Override
public Connection getConnection()
{
return getConnection(true);
}
/**
* returns whether DBCommmand should automatically create a prepared statement with command params (?)
* Event if this is false, is still possible to manually add command params using cmd.addCmdParam();
* @return true if automatic prepared Statements are enabled or false if not
*/
public abstract boolean isPreparedStatementsEnabled();
/**
* Creates a new Command object for the given database
*
* @return the command object.
*/
@Override
public final DBCommand createCommand()
{
return getDbms().createCommand(isPreparedStatementsEnabled());
}
/**
* Executes an SQLStatment
* @param sqlCmd the SQL-Command
* @param sqlParams a list of objects to replace sql parameters
*/
@Override
public final int executeSQL(String sqlCmd, Object[] sqlParams)
{
if (utils==null) getUtils();
return utils.executeSQL(sqlCmd, sqlParams, null);
}
/**
* Executes an Insert statement from a command object
* @param cmd the command object containing the insert command
* @return the number of records that have been inserted with the supplied statement
*/
@Override
public final int executeInsert(DBCommand cmd)
{
if (utils==null) getUtils();
return utils.executeSQL(cmd.getInsert(), cmd.getParamValues(), null);
}
/**
* Executes an InsertInfo statement from a command object
* @param table the table into which to insert the selected data
* @param cmd the command object containing the selection command
* @return the number of records that have been inserted with the supplied statement
*/
@Override
public final int executeInsertInto(DBTable table, DBCommand cmd)
{
if (utils==null) getUtils();
return utils.executeSQL(cmd.getInsertInto(table), cmd.getParamValues(), null);
}
/**
* Executes an Update statement from a command object
* @param cmd the command object containing the update command
* @return the number of records that have been updated with the supplied statement
*/
@Override
public final int executeUpdate(DBCommand cmd)
{
if (utils==null) getUtils();
return utils.executeSQL(cmd.getUpdate(), cmd.getParamValues(), null);
}
/**
* Executes a Delete statement from a command object
* @param from the database table from which to delete records
* @param cmd the command object containing the delete constraints
* @return the number of records that have been deleted with the supplied statement
*/
@Override
public final int executeDelete(DBTable from, DBCommand cmd)
{
if (utils==null) getUtils();
return utils.executeSQL(cmd.getDelete(from), cmd.getParamValues(), null);
}
@Override
public void commit()
{
try
{ // Check argument
Connection conn = getConnection(false);
if (conn==null)
{ log.info("No Connection to commmit changes");
return; // Nothing to do
}
// Perform Discard before commit
DBRollbackManager dbrm = (isRollbackHandlingEnabled() ? getRollbackManager(false) : null);
if (dbrm!=null)
dbrm.releaseConnection(conn, ReleaseAction.Discard);
// Commit
if (conn.getAutoCommit()==false)
conn.commit();
// Done
return;
} catch (SQLException sqle) {
// Commit failed!
throw new EmpireSQLException(getDbms(), sqle);
}
}
/**
* Discards all changes made since the previous commit/rollback
* and releases any database locks currently held by this
* Connection.
* <P>
* @param conn a valid database connection
*/
@Override
public void rollback()
{
try
{ // Check argument
Connection conn = getConnection(false);
if (conn==null)
{ log.info("No Connection to rollback changes");
return; // Nothing to do
}
// rollback
log.info("Database rollback issued!");
conn.rollback();
// Perform Rollback
DBRollbackManager dbrm = (isRollbackHandlingEnabled() ? getRollbackManager(false) : null);
if (dbrm!=null)
dbrm.releaseConnection(conn, ReleaseAction.Rollback);
// Done
return;
} catch (SQLException sqle) {
// Commit failed!
throw new EmpireSQLException(getDbms(), sqle);
}
}
@Override
public void appendRollbackHandler(DBRollbackHandler handler)
{
if (handler==null || handler.getObject()==null)
throw new InvalidArgumentException("handler", handler);
// Check enabled
if (!isRollbackHandlingEnabled())
{ log.warn("*** Rollback handling is disabled for this context. AppendRollbackHandler must not be called! ***");
return;
}
// Add handler
DBRollbackManager dbrm = getRollbackManager(true);
if (dbrm!=null)
dbrm.appendHandler(getConnection(true), handler);
else if (noRollbackManagerWarnOnce)
{ log.warn("*** No DBRollbackManager provided! Rollbacks will be disabled. ***");
noRollbackManagerWarnOnce = false;
}
}
@Override
public void removeRollbackHandler(DBObject object)
{
if (object==null)
throw new InvalidArgumentException("object", object);
// Check enabled
if (!isRollbackHandlingEnabled())
{ log.warn("*** Rollback handling is disabled for this context. RemoveRollbackHandler should not be called! ***");
return;
}
// Remove handler
DBRollbackManager dbrm = getRollbackManager(false);
if (dbrm!=null)
dbrm.removeHandler(getConnection(false), object);
}
/**
* Discard connection releated ressources
* WARING: No gurarantee it will be called
*/
@Override
public void discard()
{
/* don't close connection! */
}
/**
* helper to close a connection on discard
*/
protected void closeConnection()
{ try
{ // close connection
Connection conn = getConnection();
conn.close();
} catch (SQLException sqle) {
// Commit failed!
throw new EmpireSQLException(getDbms(), sqle);
}
}
}