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