#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 } }