#region Apache Notice
/*****************************************************************************
* $Header: $
* $Revision$
* $Date$
*
* iBATIS.NET Data Mapper
* Copyright (C) 2004 - Gilles Bayon
*
*
* Licensed 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.
*
********************************************************************************/
#endregion
#region Imports
using System;
using System.Data;
using System.Reflection;
using IBatisNet.Common;
using IBatisNet.Common.Logging;
using IBatisNet.DataAccess.Exceptions;
#endregion
namespace IBatisNet.DataAccess.DaoSessionHandlers
{
///
/// An ADO.NET implementation of the DataAccess Session .
///
public class SimpleDaoSession : DaoSession
{
#region Fields
private static readonly ILog _logger = LogManager.GetLogger( MethodBase.GetCurrentMethod().DeclaringType );
private IDataSource _dataSource = null;
private bool _isTransactionOpen = false;
private bool _consistent = false;
///
/// Holds value of connection
///
private IDbConnection _connection = null;
///
/// Holds value of transaction
///
private IDbTransaction _transaction = null;
#endregion
#region Properties
///
/// The data source use by the session.
///
///
public override IDataSource DataSource
{
get { return _dataSource; }
}
///
/// The Connection use by the session.
///
///
public override IDbConnection Connection
{
get { return _connection; }
}
///
/// The Transaction use by the session.
///
///
public override IDbTransaction Transaction
{
get { return _transaction; }
}
///
/// Indicates if a transaction is open on
/// the session.
///
///
public override bool IsTransactionStart
{
get { return _isTransactionOpen; }
}
///
/// Changes the vote for transaction to commit (true) or to abort (false).
///
private bool Consistent
{
set { _consistent = value; }
}
#endregion
#region Constructor (s) / Destructor
///
///
///
///
///
public SimpleDaoSession(DaoManager daoManager, DataSource dataSource):base(daoManager)
{
_dataSource = dataSource;
}
#endregion
#region Methods
///
/// Complete (commit) a transaction
///
///
/// Use in 'using' syntax.
///
public override void Complete()
{
this.Consistent = true;
}
///
/// Opens a database connection.
///
public override void OpenConnection()
{
this.OpenConnection(_dataSource.ConnectionString);
}
///
/// Open a connection, on the specified connection string.
///
/// The connection string
public override void OpenConnection(string connectionString)
{
if (_connection == null)
{
_connection = _dataSource.DbProvider.CreateConnection();
_connection.ConnectionString = connectionString;
try
{
_connection.Open();
if (_logger.IsDebugEnabled)
{
_logger.Debug(string.Format("Open Connection \"{0}\" to \"{1}\".", _connection.GetHashCode().ToString(), _dataSource.DbProvider.Description) );
}
}
catch(Exception ex)
{
throw new DataAccessException( string.Format("Unable to open connection to \"{0}\".", _dataSource.DbProvider.Description), ex );
}
}
else if (_connection.State != ConnectionState.Open)
{
try
{
_connection.Open();
if (_logger.IsDebugEnabled)
{
_logger.Debug(string.Format("Open Connection \"{0}\" to \"{1}\".", _connection.GetHashCode().ToString(), _dataSource.DbProvider.Description) );
}
}
catch(Exception ex)
{
throw new DataAccessException(string.Format("Unable to open connection to \"{0}\".", _dataSource.DbProvider.Description), ex );
}
}
}
///
/// Closes the connection
///
public override void CloseConnection()
{
if ( (_connection != null) && (_connection.State == ConnectionState.Open) )
{
_connection.Close();
if (_logger.IsDebugEnabled)
{
_logger.Debug(string.Format("Close Connection \"{0}\" to \"{1}\".", _connection.GetHashCode().ToString(), _dataSource.DbProvider.Description));
}
}
_connection = null;
}
///
/// Begins a transaction.
///
///
/// Oepn a connection.
///
public override void BeginTransaction()
{
this.BeginTransaction( _dataSource.ConnectionString );
}
///
/// Open a connection and begin a transaction on the specified connection string.
///
/// The connection string
public override void BeginTransaction(string connectionString)
{
if (_connection == null || _connection.State != ConnectionState.Open)
{
this.OpenConnection( connectionString );
}
_transaction = _connection.BeginTransaction();
if (_logger.IsDebugEnabled)
{
_logger.Debug("Begin Transaction.");
}
_isTransactionOpen = true;
}
///
/// Begins a database transaction
///
/// Open a connection.
public override void BeginTransaction(bool openConnection)
{
if (openConnection)
{
this.BeginTransaction();
}
else
{
if (_connection == null || _connection.State != ConnectionState.Open)
{
throw new DataAccessException("SimpleDaoSession could not invoke BeginTransaction(). A Connection must be started. Call OpenConnection() first.");
}
_transaction = _connection.BeginTransaction();
if (_logger.IsDebugEnabled)
{
_logger.Debug("Begin Transaction.");
}
_isTransactionOpen = true;
}
}
///
/// Begins a transaction at the data source with the specified IsolationLevel value.
///
/// The transaction isolation level for this connection.
public override void BeginTransaction(IsolationLevel isolationLevel)
{
this.BeginTransaction( _dataSource.ConnectionString, isolationLevel );
}
///
/// Open a connection and begin a transaction on the specified connection string.
///
/// The connection string
/// The transaction isolation level for this connection.
public override void BeginTransaction(string connectionString, IsolationLevel isolationLevel)
{
if (_connection == null || _connection.State != ConnectionState.Open)
{
this.OpenConnection( connectionString );
}
_transaction = _connection.BeginTransaction(isolationLevel);
if (_logger.IsDebugEnabled)
{
_logger.Debug("Begin Transaction.");
}
_isTransactionOpen = true;
}
///
/// Begins a transaction on the current connection
/// with the specified IsolationLevel value.
///
/// The transaction isolation level for this connection.
/// Open the connection ?
public override void BeginTransaction(bool openConnection, IsolationLevel isolationLevel)
{
this.BeginTransaction( _dataSource.ConnectionString, openConnection, isolationLevel );
}
///
/// Begins a transaction on the current connection
/// with the specified IsolationLevel value.
///
/// The transaction isolation level for this connection.
/// The connection string
/// Open a connection.
public override void BeginTransaction(string connectionString, bool openConnection, IsolationLevel isolationLevel)
{
if (openConnection)
{
this.BeginTransaction(connectionString, isolationLevel);
}
else
{
if (_connection == null || _connection.State != ConnectionState.Open)
{
throw new DataAccessException("SimpleDaoSession could not invoke StartTransaction(). A Connection must be started. Call OpenConnection() first.");
}
_transaction = _connection.BeginTransaction(isolationLevel);
if (_logger.IsDebugEnabled)
{
_logger.Debug("Begin Transaction.");
}
_isTransactionOpen = true;
}
}
///
/// Commits the database transaction.
///
///
/// Will close the connection.
///
public override void CommitTransaction()
{
if (_logger.IsDebugEnabled)
{
_logger.Debug("Commit Transaction");
}
_transaction.Commit();
_transaction.Dispose();
_transaction= null;
_isTransactionOpen = false;
if (_connection.State != ConnectionState.Closed)
{
CloseConnection();
}
}
///
/// Commits the database transaction.
///
/// Close the connection
public override void CommitTransaction(bool closeConnection)
{
if (_logger.IsDebugEnabled)
{
_logger.Debug("Commit Transaction");
}
_transaction.Commit();
_transaction.Dispose();
_transaction= null;
_isTransactionOpen = false;
if (closeConnection)
{
if (_connection.State != ConnectionState.Closed)
{
CloseConnection();
}
}
}
///
/// Rolls back a transaction from a pending state.
///
///
/// Will close the connection.
///
public override void RollBackTransaction()
{
if (_logger.IsDebugEnabled)
{
_logger.Debug("RollBack Transaction");
}
_transaction.Rollback();
_transaction.Dispose();
_transaction = null;
_isTransactionOpen = false;
if (_connection.State != ConnectionState.Closed)
{
CloseConnection();
}
}
///
/// Rolls back a transaction from a pending state.
///
/// Close the connection
public override void RollBackTransaction(bool closeConnection)
{
if (_logger.IsDebugEnabled)
{
_logger.Debug("RollBack Transaction");
}
_transaction.Rollback();
_transaction.Dispose();
_transaction = null;
_isTransactionOpen = false;
if (closeConnection)
{
if (_connection.State != ConnectionState.Closed)
{
CloseConnection();
}
}
}
///
///
///
///
///
public override IDbCommand CreateCommand(CommandType commandType)
{
IDbCommand command = null;
command = _dataSource.DbProvider.CreateCommand();
command.CommandType = commandType;
command.Connection = _connection;
// Assign transaction
if (_transaction != null)
{
try
{
command.Transaction = _transaction;
}
catch
{}
}
// Assign connection timeout
if (_connection!= null)
{
try // MySql provider doesn't suppport it !
{
command.CommandTimeout = _connection.ConnectionTimeout;
}
catch(NotSupportedException e)
{
_logger.Info(e.Message);
}
}
return command;
}
///
/// Create an IDataParameter
///
/// An IDataParameter.
public override IDbDataParameter CreateDataParameter()
{
IDbDataParameter dataParameter = _dataSource.DbProvider.CreateDataParameter();
return dataParameter;
}
///
///
///
///
public override IDbDataAdapter CreateDataAdapter()
{
return _dataSource.DbProvider.CreateDataAdapter();
}
///
///
///
///
///
public override IDbDataAdapter CreateDataAdapter(IDbCommand command)
{
IDbDataAdapter dataAdapter = null;
dataAdapter = _dataSource.DbProvider.CreateDataAdapter();
dataAdapter.SelectCommand = command;
return dataAdapter;
}
#endregion
#region IDisposable Members
///
///
///
public override void Dispose()
{
if (_logger.IsDebugEnabled)
{
_logger.Debug("Dispose DaoSession");
}
if (_isTransactionOpen == false)
{
if (_connection.State != ConnectionState.Closed)
{
daoManager.CloseConnection();
}
}
else
{
if (_consistent)
{
daoManager.CommitTransaction();
_isTransactionOpen = false;
}
else
{
if (_connection.State != ConnectionState.Closed)
{
daoManager.RollBackTransaction();
_isTransactionOpen = false;
}
}
}
}
#endregion
}
}