DbProvider.cs :  » Persistence-Frameworks » iBATIS.NET » IBatisNet » Common » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » Persistence Frameworks » iBATIS.NET 
iBATIS.NET » IBatisNet » Common » DbProvider.cs

#region Apache Notice
/*****************************************************************************
 * $Revision: 408099 $
 * $LastChangedDate: 2006-05-20 23:56:36 +0200 (sam., 20 mai 2006) $
 * $LastChangedBy: gbayon $
 * 
 * iBATIS.NET Data Mapper
 * Copyright (C) 2006/2005 - The Apache Software Foundation
 *  
 * 
 * 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 Using

using System;
using System.Data;
using System.Reflection;
using System.Xml.Serialization;
using IBatisNet.Common.Exceptions;
using IBatisNet.Common.Utilities;

#endregion

namespace IBatisNet.Common{
  /// <summary>
  /// Information about a data provider.
  /// </summary>
  [Serializable]
  [XmlRoot("provider", Namespace="http://ibatis.apache.org/providers")]
  public class DbProvider : IDbProvider
  {
        private const string SQLPARAMETER = "?";

    #region Fields
    [NonSerialized]
    private string _assemblyName = string.Empty;
    [NonSerialized]
    private string _connectionClass = string.Empty;
    [NonSerialized]
    private string _commandClass = string.Empty;

    [NonSerialized]
    private string _parameterDbTypeClass = string.Empty;
    [NonSerialized]
    private Type _parameterDbType = null;

    [NonSerialized]
    private string _parameterDbTypeProperty = string.Empty;
    [NonSerialized]
    private string _dataAdapterClass = string.Empty;
    [NonSerialized]
    private string _commandBuilderClass = string.Empty;

    [NonSerialized]
    private string _name = string.Empty;
    [NonSerialized]
    private string _description = string.Empty;
    [NonSerialized]
    private bool _isDefault = false;
    [NonSerialized]
    private bool _isEnabled = true;
    [NonSerialized]
    private IDbConnection _templateConnection = null;
    [NonSerialized]
    private IDbDataAdapter _templateDataAdapter= null;
    [NonSerialized]
    private Type _commandBuilderType = null;
    [NonSerialized]
    private string _parameterPrefix = string.Empty;
    [NonSerialized]
    private bool _useParameterPrefixInSql = true;
    [NonSerialized]
    private bool _useParameterPrefixInParameter = true;
    [NonSerialized]
    private bool _usePositionalParameters = false;
    [NonSerialized]
    private bool _templateConnectionIsICloneable = false;
    [NonSerialized]
    private bool _templateDataAdapterIsICloneable = false;
    [NonSerialized]
    private bool _setDbParameterSize = true;
    [NonSerialized]
    private bool _setDbParameterPrecision = true;
    [NonSerialized]
    private bool _setDbParameterScale = true;
    [NonSerialized]
    private bool _useDeriveParameters = true;
    [NonSerialized]
    private bool _allowMARS = false;

    
//    private static readonly ILog _connectionLogger = LogManager.GetLogger("System.Data.IDbConnection");

    #endregion
    
    #region Properties


    /// <summary>
    /// The name of the assembly which conatins the definition of the provider.
    /// </summary>
    /// <example>Examples : "System.Data", "Microsoft.Data.Odbc"</example>
    [XmlAttribute("assemblyName")]
    public string AssemblyName
    {
      get { return _assemblyName; }
      set
      {
        CheckPropertyString("AssemblyName", value);
        _assemblyName = value;
      }
    }


    /// <summary>
    /// Tell us if it is the default data source.
    /// Default false.
    /// </summary>
    [XmlAttribute("default")]
    public bool IsDefault
    {             
      get { return _isDefault; }
      set {_isDefault = value;}
    }
    

    /// <summary>
    /// Tell us if this provider is enabled.
    /// Default true.
    /// </summary>
    [XmlAttribute("enabled")]
    public bool IsEnabled
    {             
      get { return _isEnabled; }
      set {_isEnabled = value;}
    }

    /// <summary>
    /// Tell us if this provider allows having multiple open <see cref="IDataReader"/> with
    /// the same <see cref="IDbConnection"/>.
    /// </summary>
    /// <remarks>
    /// It's a new feature in ADO.NET 2.0 and Sql Server 2005 that allows for multiple forward only read only result sets (MARS).
    /// Some databases have supported this functionality for a long time :
    /// Not Supported : DB2, MySql.Data, OLE DB provider [except Sql Server 2005 when using MDAC 9], SQLite, Obdc 
    /// Supported :  Sql Server 2005, Npgsql
    /// </remarks>
    [XmlAttribute("allowMARS")]
    public bool AllowMARS
    {             
      get { return _allowMARS; }
      set {_allowMARS = value;}
    }
  
    /// <summary>
    /// The connection class name to use.
    /// </summary>
    /// <example>
    /// "System.Data.OleDb.OleDbConnection", 
    /// "System.Data.SqlClient.SqlConnection", 
    /// "Microsoft.Data.Odbc.OdbcConnection"
    /// </example>
    [XmlAttribute("connectionClass")]
    public string DbConnectionClass
    {             
      get { return _connectionClass; }
      set
      {
        CheckPropertyString("DbConnectionClass", value);
        _connectionClass = value;
      }
    }

    /// <summary>
    /// Does this ConnectionProvider require the use of a Named Prefix in the SQL 
    /// statement. 
    /// </summary>
    /// <remarks>
    /// The OLE DB/ODBC .NET Provider does not support named parameters for 
    /// passing parameters to an SQL Statement or a stored procedure called 
    /// by an IDbCommand when CommandType is set to Text.
    /// 
    /// For example, SqlClient requires select * from simple where simple_id = @simple_id
    /// If this is false, like with the OleDb or Obdc provider, then it is assumed that 
    /// the ? can be a placeholder for the parameter in the SQL statement when CommandType 
    /// is set to Text.    
    /// </remarks>
    [XmlAttribute("useParameterPrefixInSql")]
    public bool UseParameterPrefixInSql 
    {
      get { return _useParameterPrefixInSql; }
      set { _useParameterPrefixInSql = value;}
    }
    
    /// <summary>
    /// Does this ConnectionProvider require the use of the Named Prefix when trying
    /// to reference the Parameter in the Command's Parameter collection. 
    /// </summary>
    /// <remarks>
    /// This is really only useful when the UseParameterPrefixInSql = true. 
    /// When this is true the code will look like IDbParameter param = cmd.Parameters["@paramName"], 
    /// if this is false the code will be IDbParameter param = cmd.Parameters["paramName"] - ie - Oracle.
    /// </remarks>
    [XmlAttribute("useParameterPrefixInParameter")]
    public bool UseParameterPrefixInParameter  
    {
      get { return _useParameterPrefixInParameter; }
      set { _useParameterPrefixInParameter = value; }    
    }

    /// <summary>
    /// The OLE DB/OBDC .NET Provider uses positional parameters that are marked with a 
    /// question mark (?) instead of named parameters.
    /// </summary>
    [XmlAttribute("usePositionalParameters")]
    public bool UsePositionalParameters  
    {
      get { return _usePositionalParameters; }
      set { _usePositionalParameters = value; }    
    }

    /// <summary>
    /// Used to indicate whether or not the provider 
    /// supports parameter size.
    /// </summary>
    /// <remarks>
    /// See JIRA-49 about SQLite.Net provider not supporting parameter size.
    /// </remarks>
    [XmlAttribute("setDbParameterSize")]
    public bool SetDbParameterSize
    {
      get { return _setDbParameterSize; }
      set { _setDbParameterSize = value; }    
    }

    /// <summary>
    /// Used to indicate whether or not the provider 
    /// supports parameter precision.
    /// </summary>
    /// <remarks>
    /// See JIRA-49 about SQLite.Net provider not supporting parameter precision.
    /// </remarks>
    [XmlAttribute("setDbParameterPrecision")]
    public bool SetDbParameterPrecision
    {
      get { return _setDbParameterPrecision; }
      set { _setDbParameterPrecision = value; }    
    }

    /// <summary>
    /// Used to indicate whether or not the provider 
    /// supports a parameter scale.
    /// </summary>
    /// <remarks>
    /// See JIRA-49 about SQLite.Net provider not supporting parameter scale.
    /// </remarks>
    [XmlAttribute("setDbParameterScale")]
    public bool SetDbParameterScale
    {
      get { return _setDbParameterScale; }
      set { _setDbParameterScale = value; }    
    }

    /// <summary>
    /// Used to indicate whether or not the provider 
    /// supports DeriveParameters method for procedure.
    /// </summary>
    [XmlAttribute("useDeriveParameters")]
    public bool UseDeriveParameters
    {
      get { return _useDeriveParameters; }
      set { _useDeriveParameters = value; }    
    }

    /// <summary>
    /// The command class name to use.
    /// </summary>
    /// <example>
    /// "System.Data.SqlClient.SqlCommand"
    /// </example>
    [XmlAttribute("commandClass")]
    public string DbCommandClass
    {             
      get { return _commandClass; }
      set
      {
        CheckPropertyString("DbCommandClass", value);
        _commandClass = value;
      }
    }

  
    /// <summary>
    /// The ParameterDbType class name to use.
    /// </summary>      
    /// <example>
    /// "System.Data.SqlDbType"
    /// </example>
    [XmlAttribute("parameterDbTypeClass")]
    public string ParameterDbTypeClass
    {             
      get { return _parameterDbTypeClass; }
      set
      {
        CheckPropertyString("ParameterDbTypeClass", value);
        _parameterDbTypeClass = value;
      }
    }


    /// <summary>
    /// The ParameterDbTypeProperty class name to use.
    /// </summary>
    /// <example >
    /// SqlDbType in SqlParamater.SqlDbType, 
    /// OracleType in OracleParameter.OracleType.
    /// </example>
    [XmlAttribute("parameterDbTypeProperty")]
    public string ParameterDbTypeProperty
    {             
      get { return _parameterDbTypeProperty; }
      set
      {
        CheckPropertyString("ParameterDbTypeProperty", value);
        _parameterDbTypeProperty = value;
      }
    }

    /// <summary>
    /// The dataAdapter class name to use.
    /// </summary>
    /// <example >
    /// "System.Data.SqlDbType"
    /// </example>
    [XmlAttribute("dataAdapterClass")]
    public string DataAdapterClass
    {             
      get { return _dataAdapterClass; }
      set
      {
        CheckPropertyString("DataAdapterClass", value);
        _dataAdapterClass = value;
      }
    }

    /// <summary>
    /// The commandBuilder class name to use.
    /// </summary>
    /// <example >
    /// "System.Data.OleDb.OleDbCommandBuilder", 
    /// "System.Data.SqlClient.SqlCommandBuilder", 
    /// "Microsoft.Data.Odbc.OdbcCommandBuilder"
    /// </example>
    [XmlAttribute("commandBuilderClass")]
    public string CommandBuilderClass
    {             
      get { return _commandBuilderClass; }
      set
      {
        CheckPropertyString("CommandBuilderClass", value);
        _commandBuilderClass = value;
      }
    }


    /// <summary>
    /// Name used to identify the provider amongst the others.
    /// </summary>
    [XmlAttribute("name")]
    public string Name
    {
      get { return _name; }
      set 
      { 
        CheckPropertyString("Name", value);
        _name = value;       
      }
    }

    /// <summary>
    /// Description.
    /// </summary>
    [XmlAttribute("description")]
    public string Description
    {
      get { return _description; }
      set { _description = value;}
    }
    
    /// <summary>
    /// Parameter prefix use in store procedure.
    /// </summary>
    /// <example> @ for Sql Server.</example>
    [XmlAttribute("parameterPrefix")]
    public string ParameterPrefix
    {
      get { return _parameterPrefix; }
      set 
      { 
        if ((value == null) || (value.Length < 1))
        {
          _parameterPrefix = ""; 
        }
        else
        {
          _parameterPrefix = value; 
        }
      }
    }

    /// <summary>
    /// Check if this provider is Odbc ?
    /// </summary>
    [XmlIgnore]
    public bool IsObdc
    {
      get { return (_connectionClass.IndexOf(".Odbc.")>0); }
    }

    /// <summary>
    /// Get the CommandBuilder Type for this provider.
    /// </summary>
    /// <returns>An object.</returns>
    public Type CommandBuilderType
    {
      get {return _commandBuilderType;}
    }

    /// <summary>
    /// Get the ParameterDb Type for this provider.
    /// </summary>
    /// <returns>An object.</returns>
    [XmlIgnore]
    public Type ParameterDbType
    {
      get { return _parameterDbType; }
    }
    #endregion

    #region Constructor (s) / Destructor
    /// <summary>
    /// Do not use direclty, only for serialization.
    /// </summary>
    public DbProvider()
    {
    }
    #endregion

    #region Methods
    /// <summary>
    /// Init the provider.
    /// </summary>
    public void Initialize()
    {
      Assembly assembly = null;
      Type type = null;

      try
      {
        assembly = Assembly.Load(_assemblyName);

        // Build the DataAdapter template 
        type = assembly.GetType(_dataAdapterClass, true);
        CheckPropertyType("DataAdapterClass", typeof(IDbDataAdapter), type);
        _templateDataAdapter = (IDbDataAdapter)type.GetConstructor(Type.EmptyTypes).Invoke(null);
        
        // Build the connection template 
        type = assembly.GetType(_connectionClass, true);
        CheckPropertyType("DbConnectionClass", typeof(IDbConnection), type);
        _templateConnection = (IDbConnection)type.GetConstructor(Type.EmptyTypes).Invoke(null);

        // Get the CommandBuilder Type
        _commandBuilderType = assembly.GetType(_commandBuilderClass, true);
        if (_parameterDbTypeClass.IndexOf(',')>0)
        {
                    _parameterDbType = TypeUtils.ResolveType(_parameterDbTypeClass);
        }
        else
        {
          _parameterDbType = assembly.GetType(_parameterDbTypeClass, true);
        }

        _templateConnectionIsICloneable = _templateConnection is ICloneable;
        _templateDataAdapterIsICloneable = _templateDataAdapter is ICloneable;
      }
      catch(Exception e)
      {
        throw new ConfigurationException(
          string.Format("Could not configure providers. Unable to load provider named \"{0}\" not found, failed. Cause: {1}", _name, e.Message), e
          );
      }
    }


    /// <summary>
    /// Create a connection object for this provider.
    /// </summary>
    /// <returns>An 'IDbConnection' object.</returns>
    public virtual IDbConnection CreateConnection()
    {
      // Cannot do that because on 
      // IDbCommand.Connection = cmdConnection
      // .NET cast the cmdConnection to the real type (as SqlConnection)
      // and we pass a proxy --> exception invalid cast !
//      if (_connectionLogger.IsDebugEnabled)
//      {
//        connection = (IDbConnection)IDbConnectionProxy.NewInstance(connection, this);
//      }
      if (_templateConnectionIsICloneable)
      {
        return (IDbConnection) ((ICloneable)_templateConnection).Clone();
      }
      else
      {
        return (IDbConnection) Activator.CreateInstance(_templateConnection.GetType());
      }
    }

    
    /// <summary>
    /// Create a command object for this provider.
    /// </summary>
    /// <returns>An 'IDbCommand' object.</returns>
    public virtual IDbCommand CreateCommand()
    {
            return _templateConnection.CreateCommand();
    }

    /// <summary>
    /// Create a dataAdapter object for this provider.
    /// </summary>
    /// <returns>An 'IDbDataAdapter' object.</returns>
    public virtual IDbDataAdapter CreateDataAdapter()
    {
      if (_templateDataAdapterIsICloneable)
      {
        return (IDbDataAdapter) ((ICloneable)_templateDataAdapter).Clone();
      }
      else
      {
        return (IDbDataAdapter) Activator.CreateInstance(_templateDataAdapter.GetType());
      }
    }


    /// <summary>
    /// Create a IDbDataParameter object for this provider.
    /// </summary>
    /// <returns>An 'IDbDataParameter' object.</returns>
    public virtual IDbDataParameter CreateDataParameter()
    {
            return _templateConnection.CreateCommand().CreateParameter();
    }

        /// <summary>
        /// Change the parameterName into the correct format IDbCommand.CommandText
        /// for the ConnectionProvider
        /// </summary>
        /// <param name="parameterName">The unformatted name of the parameter</param>
        /// <returns>A parameter formatted for an IDbCommand.CommandText</returns>
        public virtual string FormatNameForSql(string parameterName)
        {
            return _useParameterPrefixInSql ? (_parameterPrefix + parameterName) : SQLPARAMETER;
        }

        /// <summary>
        /// Changes the parameterName into the correct format for an IDbParameter
        /// for the Driver.
        /// </summary>
        /// <remarks>
        /// For SqlServerConnectionProvider it will change <c>id</c> to <c>@id</c>
        /// </remarks>
        /// <param name="parameterName">The unformatted name of the parameter</param>
        /// <returns>A parameter formatted for an IDbParameter.</returns>
        public virtual string FormatNameForParameter(string parameterName)
        {
            return _useParameterPrefixInParameter ? (_parameterPrefix + parameterName) : parameterName;
        }
        
        /// <summary>
    /// Equals implemantation.
    /// </summary>
    /// <param name="obj">The test object.</param>
    /// <returns>A boolean.</returns>
    public override bool Equals(object obj)
    {
      if ((obj != null) && (obj is IDbProvider))
      {
        IDbProvider that = (IDbProvider) obj;
        return ((this._name == that.Name) && 
          (this._assemblyName == that.AssemblyName) &&
          (this._connectionClass == that.DbConnectionClass));
      }
      return false;
    }

    /// <summary>
    /// A hashcode for the provider.
    /// </summary>
    /// <returns>An integer.</returns>
    public override int GetHashCode()
    {
      return (_name.GetHashCode() ^ _assemblyName.GetHashCode() ^ _connectionClass.GetHashCode());
    }

    /// <summary>
    /// ToString implementation.
    /// </summary>
    /// <returns>A string that describes the provider.</returns>
    public override string ToString()
    {
      return "Provider " + _name;
    }

    private void CheckPropertyString(string propertyName, string value)
    {
      if (value == null || value.Trim().Length == 0)
      {
        throw new ArgumentException(
          "The "+propertyName+" property cannot be " +
          "set to a null or empty string value.", propertyName);
      }
    }

    private void CheckPropertyType(string propertyName,Type expectedType, Type value)
    {
      if (value == null)
      {
        throw new ArgumentNullException(
          propertyName, "The "+propertyName+" property cannot be null.");
      }
      if (!expectedType.IsAssignableFrom(value))
      {
        throw new ArgumentException(
          "The Type passed to the "+propertyName+" property must be an "+expectedType.Name+" implementation.");
      }
    }
    #endregion

  }
}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.