#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 : IDalSession { #region Fields private static readonly ILog _logger = LogManager.GetLogger( System.Reflection.MethodBase.GetCurrentMethod().DeclaringType ); private SqlMapper _sqlMapper = null; private DataSource _dataSource = null; #endregion #region Constructor (s) / Destructor /// /// /// /// public SqlMapSession(SqlMapper sqlMapper) { _dataSource = sqlMapper.DataSource; _sqlMapper = sqlMapper; } /// /// /// /// public SqlMapSession(DataSource dataSource) { _dataSource = dataSource; } #endregion #region IDalSession Members #region Fields private bool _isOpenTransaction = 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 /// /// /// public DataSource DataSource { get { return _dataSource; } } /// /// /// public IDbConnection Connection { get { return _connection; } } /// /// /// public IDbTransaction Transaction { get { return _transaction; } } /// /// 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); } /// /// Open a connection, on the specified connection string. /// /// The connection string public void OpenConnection(string connectionString) { if (_connection == null) { _connection = _dataSource.Provider.GetConnection(); _connection.ConnectionString = connectionString; try { _connection.Open(); if (_logger.IsDebugEnabled) { _logger.Debug( string.Format("Open Connection \"{0}\" to \"{1}\".", _connection.GetHashCode().ToString(), _dataSource.Provider.Description) ); } } catch(Exception ex) { throw new DataMapperException( string.Format("Unable to open connection to \"{0}\".", _dataSource.Provider.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.Provider.Description) ); } } catch(Exception ex) { throw new DataMapperException(string.Format("Unable to open connection to \"{0}\".", _dataSource.Provider.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.Provider.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."); } _isOpenTransaction = 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) { throw new DataMapperException("SqlMapSession could not invoke BeginTransaction(). A Connection must be started. Call OpenConnection() first."); } _transaction = _connection.BeginTransaction(); if (_logger.IsDebugEnabled) { _logger.Debug("Begin Transaction."); } _isOpenTransaction = 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."); } _isOpenTransaction = 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."); } _isOpenTransaction = true; } } /// /// Commits the database transaction. /// /// /// Will close the connection. /// public void CommitTransaction() { if (_logger.IsDebugEnabled) { _logger.Debug("Commit Transaction."); } _transaction.Commit(); _transaction.Dispose(); if (_connection.State != ConnectionState.Closed) { this.CloseConnection(); } } /// /// Commits the database transaction. /// /// Close the connection public void CommitTransaction(bool closeConnection) { if (closeConnection) { this.CommitTransaction(); } else { _transaction.Commit(); if (_logger.IsDebugEnabled) { _logger.Debug("Commit Transaction."); } _transaction.Dispose(); } } /// /// Rolls back a transaction from a pending state. /// /// /// Will close the connection. /// public void RollBackTransaction() { _transaction.Rollback(); if (_logger.IsDebugEnabled) { _logger.Debug("RollBack Transaction."); } _transaction.Dispose(); _transaction = null; 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; } } /// /// Create a command object /// /// /// public IDbCommand CreateCommand(CommandType commandType) { IDbCommand command = null; command = _dataSource.Provider.GetCommand(); // Assign CommandType command.CommandType = commandType; // Assign connection 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 IDataParameter CreateDataParameter() { IDataParameter dataParameter = null; dataParameter = _dataSource.Provider.GetDataParameter(); return dataParameter; } /// /// /// /// public IDbDataAdapter CreateDataAdapter() { return _dataSource.Provider.GetDataAdapter(); } /// /// /// /// /// public IDbDataAdapter CreateDataAdapter(IDbCommand command) { IDbDataAdapter dataAdapter = null; dataAdapter = _dataSource.Provider.GetDataAdapter(); 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 (_isOpenTransaction == false) { if (_connection.State != ConnectionState.Closed) { _sqlMapper.CloseConnection(); } } else { if (_consistent) { _sqlMapper.CommitTransaction(); } else { if (_connection.State != ConnectionState.Closed) { _sqlMapper.RollBackTransaction(); } } } } #endregion } }