// Persist library : Persistence layer
// Copyright (C) 2003 Vincent Daron
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
using System;
using System.Data;
using System.Collections;
using Persist.Sql;
using Persist.Tools;
namespace Persist{
/// <summary>
/// This object is stored in the Thread Data
/// So THIS IS NOT THREAD SAFE :-)
/// </summary>
internal class ConnectionManager
{
private bool isTransactionActive = false;
private Hashtable connections = new Hashtable();
private Hashtable transactions = new Hashtable();
public ConnectionManager()
{
}
public void BeginTransaction()
{
isTransactionActive = true;
}
public void Commit()
{
if(isTransactionActive)
{
try
{
foreach(IDbTransaction transaction in transactions.Values)
{
transaction.Commit();
}
transactions.Clear();
foreach(RelationalDatabase database in this.connections.Keys)
{
database.FreeConnection((IDbConnection)connections[database]);
}
connections.Clear();
}
finally
{
isTransactionActive = false;
}
}
}
public void Rollback()
{
if(isTransactionActive)
{
try
{
foreach(IDbTransaction transaction in transactions.Values)
{
transaction.Rollback();
}
transactions.Clear();
foreach(RelationalDatabase database in this.connections.Keys)
{
database.FreeConnection((IDbConnection)connections[database]);
}
connections.Clear();
}
finally
{
isTransactionActive = false;
}
}
}
public IDbConnection GetConnection(RelationalDatabase database)
{
lock(this)
{
IDbConnection conn = null;
if(isTransactionActive)
{
conn = (IDbConnection)connections[database];
if(conn != null)
{
// Check Connection State
if(conn.State != System.Data.ConnectionState.Open)
{
isTransactionActive = false;
database.FreeConnection(conn);
throw new Exception("Connection has been closed ...");
}
}
else
{
// Obtain connection from the database and put it
// to the internal cache
conn = database.GetConnection();
connections.Add(database, conn);
transactions.Add(conn,conn.BeginTransaction());
}
}
else
{
conn = database.GetConnection();
}
return conn;
}
}
public void FreeConnection(RelationalDatabase database, IDbConnection conn)
{
if(!isTransactionActive)
{
database.FreeConnection(conn);
}
}
public IDataReader ExecuteStatementQuery(SqlStatement statement,IDbConnection connection)
{
IDataReader aDataReader;
if(isTransactionActive)
{
aDataReader = ConnectionUtils.ProcessQuery(statement, connection,(IDbTransaction)transactions[connection]);
}
else
{
aDataReader = ConnectionUtils.ProcessQuery(statement, connection,null);
}
return aDataReader;
}
public int ExecuteStatementNonQuery(SqlStatement statement,IDbConnection connection)
{
int result = 0;
if(isTransactionActive)
{
result = ConnectionUtils.ProcessNonQuery(statement, connection,(IDbTransaction)transactions[connection]);
}
else
{
result = ConnectionUtils.ProcessNonQuery(statement, connection,null);
}
return result;
}
}
}
|