#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 IBatisNet.Common; using IBatisNet.Common.Logging; using IBatisNet.DataMapper.Exceptions; #endregion namespace IBatisNet.DataMapper { /// /// Summary description for SqlMapSession. /// [Serializable] public class SqlMapSession : ISqlMapSession { #region Fields private static readonly ILog _logger = LogManager.GetLogger( System.Reflection.MethodBase.GetCurrentMethod().DeclaringType ); private ISqlMapper _sqlMapper = null; private IDataSource _dataSource = null; #endregion #region Constructor (s) / Destructor /// /// /// /// public SqlMapSession(ISqlMapper sqlMapper) { _dataSource = sqlMapper.DataSource; _sqlMapper = sqlMapper; } #endregion #region IDalSession Members #region Fields private bool _isTransactionOpen = false; /// /// Changes the vote to commit (true) or to abort (false) in transsaction /// private bool _consistent = false; /// /// Holds value of connection /// private IDbConnection _connection = null; /// /// Holds value of transaction /// private IDbTransaction _transaction = null; #endregion #region Properties /// /// Gets the SQL mapper. /// /// The SQL mapper. public ISqlMapper SqlMapper { get { return _sqlMapper; } } /// /// The data source use by the session. /// /// public IDataSource DataSource { get { return _dataSource; } } /// /// The Connection use by the session. /// /// public IDbConnection Connection { get { return _connection; } } /// /// The Transaction use by the session. /// /// public IDbTransaction Transaction { get { return _transaction; } } /// /// Indicates if a transaction is open on /// the session. /// public 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 Methods /// /// Complete (commit) a transaction /// /// /// Use in 'using' syntax. /// public void Complete() { this.Consistent = true; } /// /// Open the connection /// public void OpenConnection() { this.OpenConnection(_dataSource.ConnectionString); } /// /// Create the connection /// public void CreateConnection() { CreateConnection(_dataSource.ConnectionString); } /// /// Create the connection /// public void CreateConnection(string connectionString) { _connection = _dataSource.DbProvider.CreateConnection(); _connection.ConnectionString = connectionString; } /// /// Open a connection, on the specified connection string. /// /// The connection string public void OpenConnection(string connectionString) { if (_connection == null) { CreateConnection(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 DataMapperException( 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 DataMapperException(string.Format("Unable to open connection to \"{0}\".", _dataSource.DbProvider.Description), ex ); } } } /// /// Close the connection /// public void CloseConnection() { if ( (_connection != null) && (_connection.State != ConnectionState.Closed) ) { _connection.Close(); if (_logger.IsDebugEnabled) { _logger.Debug(string.Format("Close Connection \"{0}\" to \"{1}\".", _connection.GetHashCode().ToString(), _dataSource.DbProvider.Description)); } _connection.Dispose(); } _connection = null; } /// /// Begins a database transaction. /// public void BeginTransaction() { this.BeginTransaction(_dataSource.ConnectionString); } /// /// Open a connection and begin a transaction on the specified connection string. /// /// The connection string public 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 void BeginTransaction(bool openConnection) { if (openConnection) { this.BeginTransaction(); } else { if (_connection == null || _connection.State != ConnectionState.Open) { this.OpenConnection(); } _transaction = _connection.BeginTransaction(); if (_logger.IsDebugEnabled) { _logger.Debug("Begin Transaction."); } _isTransactionOpen = true; } } /// /// Begins a database transaction with the specified isolation level. /// /// /// The isolation level under which the transaction should run. /// public 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 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 a connection. public 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 void BeginTransaction(string connectionString, bool openConnection, IsolationLevel isolationLevel) { if (openConnection) { this.BeginTransaction( connectionString, isolationLevel ); } else { if (_connection == null || _connection.State != ConnectionState.Open) { throw new DataMapperException("SqlMapSession 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 void CommitTransaction() { if (_logger.IsDebugEnabled) { _logger.Debug("Commit Transaction."); } _transaction.Commit(); _transaction.Dispose(); _transaction = null; _isTransactionOpen = false; if (_connection.State != ConnectionState.Closed) { this.CloseConnection(); } } /// /// Commits the database transaction. /// /// Close the connection public void CommitTransaction(bool closeConnection) { if (closeConnection) { this.CommitTransaction(); } else { if (_logger.IsDebugEnabled) { _logger.Debug("Commit Transaction."); } _transaction.Commit(); _transaction.Dispose(); _transaction = null; _isTransactionOpen = false; } } /// /// Rolls back a transaction from a pending state. /// /// /// Will close the connection. /// public void RollBackTransaction() { if (_logger.IsDebugEnabled) { _logger.Debug("RollBack Transaction."); } _transaction.Rollback(); _transaction.Dispose(); _transaction = null; _isTransactionOpen = false; if (_connection.State != ConnectionState.Closed) { this.CloseConnection(); } } /// /// Rolls back a transaction from a pending state. /// /// Close the connection public void RollBackTransaction(bool closeConnection) { if (closeConnection) { this.RollBackTransaction(); } else { if (_logger.IsDebugEnabled) { _logger.Debug("RollBack Transaction."); } _transaction.Rollback(); _transaction.Dispose(); _transaction = null; _isTransactionOpen = false; } } /// /// Create a command object /// /// /// public IDbCommand CreateCommand(CommandType commandType) { IDbCommand 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) { if (_logger.IsInfoEnabled) { _logger.Info(e.Message); } } } // if (_logger.IsDebugEnabled) // { // command = IDbCommandProxy.NewInstance(command); // } return command; } /// /// Create an IDataParameter /// /// An IDataParameter. public IDbDataParameter CreateDataParameter() { return _dataSource.DbProvider.CreateDataParameter(); } /// /// /// /// public IDbDataAdapter CreateDataAdapter() { return _dataSource.DbProvider.CreateDataAdapter(); } /// /// /// /// /// public IDbDataAdapter CreateDataAdapter(IDbCommand command) { IDbDataAdapter dataAdapter = null; dataAdapter = _dataSource.DbProvider.CreateDataAdapter(); dataAdapter.SelectCommand = command; return dataAdapter; } #endregion #endregion #region IDisposable Members /// /// Releasing, or resetting resources. /// public void Dispose() { if (_logger.IsDebugEnabled) { _logger.Debug("Dispose SqlMapSession"); } if (_isTransactionOpen == false) { if (_connection.State != ConnectionState.Closed) { _sqlMapper.CloseConnection(); } } else { if (_consistent) { _sqlMapper.CommitTransaction(); _isTransactionOpen = false; } else { if (_connection.State != ConnectionState.Closed) { _sqlMapper.RollBackTransaction(); _isTransactionOpen = false; } } } } #endregion } }