// 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.Collections;
using System.Collections.Specialized;
using System.Data;
namespace Persist.Sql{
/// <summary>
/// This abstract class is the base class for all the RelationalDatabase objects
/// </summary>
public abstract class RelationalDatabase : IDisposable
{
private static readonly log4net.ILog theLogger = log4net.LogManager.GetLogger(typeof(RelationalDatabase));
private string theName;
private Stack connectionPool = new Stack();
private NameValueCollection theParameters;
/// <summary>
/// Return a new object implementing IDbConnection
/// </summary>
/// <returns>the newly created connection</returns>
protected abstract IDbConnection GetNewConnection();
/// <summary>
/// Return a new object implementing IDbCommand
/// </summary>
/// <returns>the newly created command</returns>
public abstract IDbCommand GetNewCommand();
/// <summary>
/// Return a new object implemnting IDataParameter filled with the specified values
/// </summary>
/// <param name="value">the value of the parameter</param>
/// <param name="dbType">the DbType of the parameter</param>
/// <param name="name">the name of the parameter</param>
/// <returns>the filled IDataParameter</returns>
public abstract IDataParameter GetNewParameter(object value,DbType dbType,string name);
#region IDiposable Implementation
/// <summary>
/// Default Destructor
/// </summary>
~RelationalDatabase()
{
Dispose(false);
}
/// <summary>
/// Dispose the database
/// </summary>
public void Dispose()
{
Dispose(true);
}
/// <summary>
/// Dispose the database object
/// </summary>
/// <param name="disposing">true if the Diposing is explicit</param>
protected virtual void Dispose(bool disposing)
{
if(disposing)
{
IDbConnection conn;
while(connectionPool.Count > 0)
{
conn = (IDbConnection)connectionPool.Pop();
conn.Close();
}
GC.SuppressFinalize(this);
}
}
#endregion
/// <summary>
/// Put the connection in the connection pool
/// </summary>
/// <param name="conn"></param>
public void FreeConnection(IDbConnection conn)
{
lock(connectionPool)
{
System.Diagnostics.Debug.WriteLine("The Thread "+AppDomain.GetCurrentThreadId()+" put the connection("+conn.GetType().ToString()+") in pool");
connectionPool.Push(conn);
}
}
/// <summary>
/// Get a Connection from the connection pool or ask a new one
/// </summary>
/// <returns>a Valid connection</returns>
public IDbConnection GetConnection()
{
IDbConnection conn = null;
lock(connectionPool)
{
while((connectionPool.Count > 0) && conn == null)
{
conn = (IDbConnection)connectionPool.Pop();
if(conn.State != ConnectionState.Open)
{
System.Diagnostics.Debug.WriteLine("The Thread "+AppDomain.GetCurrentThreadId()+" Remove a closed connection from pool");
conn = null;
}
}
}
if(conn == null)
{
System.Diagnostics.Debug.WriteLine("The Thread "+AppDomain.GetCurrentThreadId()+" Ask for a new Connection");
conn = GetNewConnection();
}
else
{
System.Diagnostics.Debug.WriteLine("The Thread "+AppDomain.GetCurrentThreadId()+" found a connection in pool");
}
if(conn.State == ConnectionState.Closed)
{
System.Diagnostics.Debug.WriteLine("The Thread "+AppDomain.GetCurrentThreadId()+" Open the connection");
conn.Open();
}
return conn;
}
/// <summary>
/// the RelationalDatabase Parameters
/// </summary>
public NameValueCollection Parameters
{
get{return theParameters;}
}
/// <summary>
/// Retuirn the RelationalDatabaseName
/// </summary>
public string Name
{
get{return theName;}
set{theName = value;}
}
/// <summary>
/// Initialize the RelationalDatabaseObject
/// </summary>
/// <param name="parameters"></param>
public virtual void Init(NameValueCollection parameters)
{
theParameters = parameters;
}
/// <summary>
/// This is the prefix of the IDataParameters Names
/// <c>
/// Some Provider need a specific prefix for the parameters names,
/// SQLServer need a "@" (default)
/// Oracle need ":"
/// ...
///
/// Thanks ADO.NET :)
/// </c>
/// </summary>
public virtual string ParameterNamePrefix
{
get
{
return "@";
}
}
#region Clauses
/// <summary>
/// Return the AND clause
/// </summary>
public virtual string ClauseStringAnd
{
get
{
return "AND";
}
}
/// <summary>
/// Return the Ascending clause
/// </summary>
public virtual string ClauseStringAscend
{
get
{
return "ASC";
}
}
/// <summary>
/// Return the Descending Clause
/// </summary>
public virtual string ClauseStringDescend
{
get
{
return "DESC";
}
}
/// <summary>
/// Return DISTINCT Clause
/// </summary>
public virtual string ClauseStringDistinct
{
get
{
return "DISTINCT";
}
}
/// <summary>
/// Return the DELETE Clause
/// </summary>
public virtual string ClauseStringDelete
{
get
{
return "DELETE";
}
}
/// <summary>
/// Return =
/// </summary>
public virtual string ClauseStringEqualTo
{
get
{
return "=";
}
}
/// <summary>
/// Reuturn the For update clause
/// SQLServer need to return an empty string here ( to be investigated )
/// </summary>
public virtual string ClauseStringForUpdate
{
get
{
return "FOR UPDATE";
}
}
/// <summary>
/// Return FROM
/// </summary>
public virtual string ClauseStringFrom
{
get
{
return "FROM";
}
}
/// <summary>
/// Return GROUP BY
/// </summary>
public virtual string ClauseStringGroupBy
{
get
{
return "GROUP BY";
}
}
/// <summary>
/// Return COUNT
/// </summary>
public virtual string ClauseStringCount
{
get
{
return "COUNT";
}
}
/// <summary>
/// reutrn HAVING
/// </summary>
public virtual string ClauseStringHaving
{
get
{
return "HAVING";
}
}
/// <summary>
/// Return IN
/// </summary>
public virtual string ClauseStringIn
{
get
{
return "IN";
}
}
/// <summary>
/// Reuturn INSERT INTO
/// </summary>
public virtual string ClauseStringInsert
{
get
{
return "INSERT INTO";
}
}
/// <summary>
/// Reuturn IS ( used with ... WHERE PARAM IS NULL )
/// </summary>
public virtual string ClauseStringIs
{
get
{
return "IS";
}
}
/// <summary>
/// Return the LIKE clause
/// </summary>
public virtual string ClauseStringLike
{
get
{
return "LIKE";
}
}
/// <summary>
///
/// </summary>
public virtual string ClauseStringLimit
{
get
{
return "LIMIT";
}
}
/// <summary>
///
/// </summary>
public virtual string ClauseStringNot
{
get
{
return "NOT";
}
}
/// <summary>
///
/// </summary>
public virtual string ClauseStringOr
{
get
{
return "OR";
}
}
/// <summary>
///
/// </summary>
public virtual string ClauseStringOrderBy
{
get
{
return "ORDER BY";
}
}
/// <summary>
///
/// </summary>
public virtual string ClauseStringSelect
{
get
{
return "SELECT";
}
}
/// <summary>
///
/// </summary>
public virtual string ClauseStringSet
{
get
{
return "SET";
}
}
/// <summary>
///
/// </summary>
public virtual string ClauseStringUpdate
{
get
{
return "UPDATE";
}
}
/// <summary>
///
/// </summary>
public virtual string ClauseStringValues
{
get
{
return "VALUES";
}
}
/// <summary>
///
/// </summary>
public virtual string ClauseStringWhere
{
get
{
return "WHERE";
}
}
/// <summary>
///
/// </summary>
public virtual string StringGroupBy
{
get
{
return "GROUP BY";
}
}
#endregion
}
}
|