AdoTemplate.cs :  » Inversion-of-Control-Dependency-Injection » Spring.net » Spring » Data » Generic » 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 » Inversion of Control Dependency Injection » Spring.net 
Spring.net » Spring » Data » Generic » AdoTemplate.cs
#region License

/*
 * Copyright  2002-2006 the original author or authors.
 * 
 * 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

#if NET_2_0


using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using Common.Logging;
using Spring.Dao;
using Spring.Dao.Support.Generic;
using Spring.Data.Common;
using Spring.Data.Core;
using Spring.Data.Support;
using Spring.Util;

namespace Spring.Data.Generic{
    /// <summary>
    /// This is the central class in the Spring.Data.Generic namespace.
    /// It simplifies the use of ADO.NET and helps to avoid commons errors.
    /// </summary>
    /// <author>Mark Pollack (.NET)</author>
    public class AdoTemplate : AdoAccessor, IAdoOperations
    {

        #region Logging Definition

        private static readonly ILog LOG = LogManager.GetLogger(typeof(AdoTemplate));

        #endregion

        #region Fields

        private Core.AdoTemplate classicAdoTemplate;
        protected Type dataReaderWrapperType;

        #endregion

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="AdoTemplate"/> class.
        /// </summary>
        public AdoTemplate()
            : base()
        {
            classicAdoTemplate = new Core.AdoTemplate();
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="AdoTemplate"/> class.
        /// </summary>
        /// <param name="provider">The provider.</param>
        public AdoTemplate(IDbProvider provider)
        {
            classicAdoTemplate = new Core.AdoTemplate(provider);
            AfterPropertiesSet();
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="AdoTemplate"/> class.
        /// </summary>
        /// <param name="provider">The database provider.</param>
        /// <param name="lazyInit">if set to <c>false</c>
        /// lazily initialize the ErrorCodeExceptionTranslator.</param>
        public AdoTemplate(IDbProvider provider, bool lazyInit)
        {
            classicAdoTemplate = new Core.AdoTemplate(provider, lazyInit);
            AfterPropertiesSet();
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="AdoTemplate"/> class.
        /// </summary>
        /// <remarks>Useful if you have a subclass of Spring.Data.Core.AdoTemplate.</remarks>
        /// <param name="classicAdoTemplate">The classic ADO template.</param>
        public AdoTemplate(Core.AdoTemplate classicAdoTemplate)
        {
            this.classicAdoTemplate = classicAdoTemplate;
            AfterPropertiesSet();
        }
        #endregion

        #region Properties

        /// <summary>
        /// An instance of a DbProvider implementation.
        /// </summary>
        public override IDbProvider DbProvider
        {
            get { return classicAdoTemplate.DbProvider; }
            set { classicAdoTemplate.DbProvider = value; }
        }

        /// <summary>
        /// Gets or sets a value indicating whether to lazily initialize the 
        /// IAdoExceptionTranslator for this accessor, on first encounter of a 
        /// exception from the data provider.  Default is "true"; can be switched to
        /// "false" for initialization on startup.
        /// </summary>
        /// <value><c>true</c> if to lazy initialize the IAdoExceptionTranslator; 
        /// otherwise, <c>false</c>.</value>
        public override bool LazyInit
        {
            get { return classicAdoTemplate.LazyInit; }
            set { classicAdoTemplate.LazyInit = value; }
        }

        /// <summary>
        /// Gets or sets the exception translator. If no custom translator is provided, a default
        /// <see cref="ErrorCodeExceptionTranslator"/> is used.
        /// </summary>
        /// <value>The exception translator.</value>
        public override IAdoExceptionTranslator ExceptionTranslator
        {
            get { return classicAdoTemplate.ExceptionTranslator; }
            set { classicAdoTemplate.ExceptionTranslator = value; }
        }


        /// <summary>
        /// Gets or set the System.Type to use to create an instance of IDataReaderWrapper 
        /// for the purpose of having defaults values to use in case of DBNull values read 
        /// from IDataReader.
        /// </summary>
        /// <value>The type of the data reader wrapper.</value>
        public override Type DataReaderWrapperType
        {
            get { return classicAdoTemplate.DataReaderWrapperType; }
            set { classicAdoTemplate.DataReaderWrapperType = value; }
        }

        /// <summary>
        /// Gets the 'Classic' AdoTemplate in Spring.Data
        /// </summary>
        /// <remarks>
        /// Useful to access methods that return non-generic collections.
        /// </remarks>
        /// <value>The 'Classic; AdoTemplate in Spring.Data.</value>
        public Core.AdoTemplate ClassicAdoTemplate
        {
            get { return classicAdoTemplate; }
        }

        /// <summary>
        /// Gets or sets the command timeout for IDbCommands that this AdoTemplate executes.  It also
        /// sets the value of the contained 'ClassicAdoTemplate'.
        /// </summary>
        /// <value>The command timeout.</value>
        /// <remarks>Default is 0, indicating to use the database provider's default.
        /// Any timeout specified here will be overridden by the remaining
        /// transaction timeout when executing within a transaction that has a
        /// timeout specified at the transaction level.
        /// </remarks>
        public override int CommandTimeout
        {
            get { return commandTimeout; }
            set
            {
                commandTimeout = value;
                classicAdoTemplate.CommandTimeout = value;
            }
        }

        #endregion

        #region General Execute Callback methods

        /// <summary>
        /// Execute a ADO.NET operation on a command object using a interface based callback.
        /// </summary>
        /// <param name="action">the callback to execute</param>
        /// <returns>object returned from callback</returns>
        public virtual T Execute<T>(ICommandCallback<T> action)
        {
            ConnectionTxPair connectionTxPairToUse = GetConnectionTxPair(DbProvider);

            IDbCommand command = null;
            try
            {
                command = DbProvider.CreateCommand();
                command.Connection = connectionTxPairToUse.Connection;
                command.Transaction = connectionTxPairToUse.Transaction;
                //TODO collect warnings...
                //RegisterEventHandlers(command.Connection);
                ApplyCommandSettings(command);
                //TODO explicit check to cast to base class.
                DbCommand commandToUse = command as DbCommand;
                if (commandToUse != null)
                {
                    T result = action.DoInCommand((DbCommand)command);
                    //SqlWarnings sqlWarnings = GetSqlWarnings()
                    //ThrowExceptionOnWarningIfNotIgnoringWarnings(sqlWarnings);
                    return result;
                }
                else
                {
                    throw new InvalidDataAccessApiUsageException(
                        "Providers implementation of IDbCommand does not inherit from System.Data.Common.DbCommand.  Use the alternative overloaded Execute method that specifies IDbCommandCallback as a parameter.");
                }

            }
            catch (Exception e)
            {
                DisposeCommand(command);
                command = null;
                DisposeConnection(connectionTxPairToUse.Connection, DbProvider);
                connectionTxPairToUse.Connection = null;
                if (DbProvider.IsDataAccessException(e))
                {
                    throw ExceptionTranslator.Translate("CommandCallback", GetCommandText(action), e);
                }
                else
                {
                    throw;
                }


            }
            finally
            {
                DisposeCommand(command);
                DisposeConnection(connectionTxPairToUse.Connection, DbProvider);
            }
        }

        /// <summary>
        /// Execute a ADO.NET operation on a command object using a delegate callback.
        /// </summary>
        /// <remarks>This allows for implementing arbitrary data access operations
        /// on a single command within Spring's managed ADO.NET environment.</remarks>
        /// <param name="del">The delegate called with a command object.</param>
        /// <returns>A result object returned by the action or null</returns>
        public virtual T Execute<T>(CommandDelegate<T> del)
        {
            ConnectionTxPair connectionTxPairToUse = GetConnectionTxPair(DbProvider);

            IDbCommand command = null;
            try
            {
                command = DbProvider.CreateCommand();
                command.Connection = connectionTxPairToUse.Connection;
                command.Transaction = connectionTxPairToUse.Transaction;
                //TODO collect warnings...
                //RegisterEventHandlers(command.Connection);
                ApplyCommandSettings(command);
                DbCommand commandToUse = command as DbCommand;
                if (commandToUse != null)
                {
                    T result = del((DbCommand) command);
                    //SqlWarnings sqlWarnings = GetSqlWarnings()
                    //ThrowExceptionOnWarningIfNotIgnoringWarnings(sqlWarnings);
                    return result;
                }
                else
                {
                    throw new InvalidDataAccessApiUsageException(
                        "Providers implementation of IDbCommand does not inherit from System.Data.Common.DbCommand.  Use the alternative overloaded Execute method that specifies IDbCommandDelegate as a parameter.");
                }            
            }
            catch (Exception e)
            {
                string commandText = command.CommandText;
                DisposeCommand(command);
                command = null;
                DisposeConnection(connectionTxPairToUse.Connection, DbProvider);
                connectionTxPairToUse.Connection = null;
                if (DbProvider.IsDataAccessException(e))
                {
                    throw ExceptionTranslator.Translate("CommandCallback", commandText, e);
                }
                else
                {
                    throw;
                }


            }
            finally
            {
                DisposeCommand(command);
                DisposeConnection(connectionTxPairToUse.Connection, DbProvider);
            }
        }


        /// <summary>
        /// Execute a ADO.NET operation on a command object using a interface based callback.
        /// </summary>
        /// <param name="action">the callback to execute</param>
        /// <returns>object returned from callback</returns>
        public virtual T Execute<T>(IDbCommandCallback<T> action)
        {
            ConnectionTxPair connectionTxPairToUse = GetConnectionTxPair(DbProvider);

            IDbCommand command = null;
            try
            {
                command = DbProvider.CreateCommand();
                command.Connection = connectionTxPairToUse.Connection;
                command.Transaction = connectionTxPairToUse.Transaction;
                //TODO collect warnings...
                //RegisterEventHandlers(command.Connection);
                ApplyCommandSettings(command);
                T result = action.DoInCommand(command);
                //SqlWarnings sqlWarnings = GetSqlWarnings()
                //ThrowExceptionOnWarningIfNotIgnoringWarnings(sqlWarnings);
                return result;
            }
            catch (Exception e)
            {
                DisposeCommand(command);
                command = null;
                DisposeConnection(connectionTxPairToUse.Connection, DbProvider);
                connectionTxPairToUse.Connection = null;
                if (DbProvider.IsDataAccessException(e))
                {
                    throw ExceptionTranslator.Translate("CommandCallback", GetCommandText(action), e);
                }
                else
                {
                    throw;
                }


            }
            finally
            {
                DisposeCommand(command);
                DisposeConnection(connectionTxPairToUse.Connection, DbProvider);
            }
        }

        /// <summary>
        /// Execute a ADO.NET operation on a command object using a delegate callback.
        /// </summary>
        /// <remarks>This allows for implementing arbitrary data access operations
        /// on a single command within Spring's managed ADO.NET environment.</remarks>
        /// <param name="del">The delegate called with a command object.</param>
        /// <returns>A result object returned by the action or null</returns>
        public virtual T Execute<T>(IDbCommandDelegate<T> del)
        {
            ConnectionTxPair connectionTxPairToUse = GetConnectionTxPair(DbProvider);

            IDbCommand command = null;
            try
            {
                command = DbProvider.CreateCommand();
                command.Connection = connectionTxPairToUse.Connection;
                command.Transaction = connectionTxPairToUse.Transaction;
                //TODO collect warnings...
                //RegisterEventHandlers(command.Connection);
                ApplyCommandSettings(command);
                T result = del(command);
                //SqlWarnings sqlWarnings = GetSqlWarnings()
                //ThrowExceptionOnWarningIfNotIgnoringWarnings(sqlWarnings);
                return result;
            }
            catch (Exception e)
            {
                string commandText = command.CommandText;
                DisposeCommand(command);
                command = null;
                DisposeConnection(connectionTxPairToUse.Connection, DbProvider);
                connectionTxPairToUse.Connection = null;
                if (DbProvider.IsDataAccessException(e))
                {
                    throw ExceptionTranslator.Translate("CommandCallback", commandText, e);
                }
                else
                {
                    throw;
                }


            }
            finally
            {
                DisposeCommand(command);
                DisposeConnection(connectionTxPairToUse.Connection, DbProvider);
            }
        }


        /// <summary>
        /// Executes ADO.NET operations on a command object, created by the provided IDbCommandCreator,
        /// using the interface based callback IDbCommandCallback.
        /// </summary>
        /// <typeparam name="T">The type of object returned from the callback.</typeparam>
        /// <param name="commandCreator">The command creator.</param>
        /// <param name="action">The callback to execute based on IDbCommand</param>
        /// <returns>
        /// A result object returned by the action or null
        /// </returns>
        public virtual T Execute<T>(IDbCommandCreator commandCreator, IDbCommandCallback<T> action)
        {
            AssertUtils.ArgumentNotNull(commandCreator, "commandCreator", "IDbCommandCreator must not be null");
            AssertUtils.ArgumentNotNull(action, "action", "Callback object must not be null");
            ConnectionTxPair connectionTxPairToUse = GetConnectionTxPair(DbProvider);

            IDbCommand command = null;
            try
            {
                command = commandCreator.CreateDbCommand(DbProvider);
                command.Connection = connectionTxPairToUse.Connection;
                command.Transaction = connectionTxPairToUse.Transaction;
                //TODO collect warnings...
                //RegisterEventHandlers(command.Connection);
                ApplyCommandSettings(command);
                T result = action.DoInCommand(command);
                //SqlWarnings sqlWarnings = GetSqlWarnings()
                //ThrowExceptionOnWarningIfNotIgnoringWarnings(sqlWarnings);
                return result;
            }
            catch (Exception e)
            {
                DisposeCommand(command);
                command = null;
                DisposeConnection(connectionTxPairToUse.Connection, DbProvider);
                connectionTxPairToUse.Connection = null;
                if (DbProvider.IsDataAccessException(e))
                {
                    throw ExceptionTranslator.Translate("CommandCallback", GetCommandText(action), e);
                }
                else
                {
                    throw;
                }


            }
            finally
            {
                DisposeCommand(command);
                DisposeConnection(connectionTxPairToUse.Connection, DbProvider);
            }

        }

        /// <summary>
        /// Execute ADO.NET operations on a IDbDataAdapter object using an interface based callback.
        /// </summary>
        /// <typeparam name="T">The type of object returned from the callback.</typeparam>
        /// <param name="dataAdapterCallback">The data adapter callback.</param>
        /// <returns>
        /// A result object returned by the callback or null
        /// </returns>
        /// <remarks>This allows for implementing abritrary data access operations
        /// on a single DataAdapter within Spring's managed ADO.NET environment.
        /// </remarks>
        public virtual T Execute<T>(IDataAdapterCallback<T> dataAdapterCallback)
        {
            ConnectionTxPair connectionTxPairToUse = GetConnectionTxPair(DbProvider);
            IDbDataAdapter dataAdapter = null;
            try
            {
                dataAdapter = DbProvider.CreateDataAdapter();
                //TODO row updated event handling...
                dataAdapter.SelectCommand = DbProvider.CreateCommand();
                dataAdapter.SelectCommand.Connection = connectionTxPairToUse.Connection;
                //TODO register for warnings on connection.
                dataAdapter.SelectCommand.Transaction = connectionTxPairToUse.Transaction;
                ApplyCommandSettings(dataAdapter.SelectCommand);
                T result = dataAdapterCallback.DoInDataAdapter(dataAdapter);
                return result;
            }
            catch (Exception)
            {
                DisposeDataAdapterCommands(dataAdapter);
                //TODO set dataAdapter command's = null; ?
                //TODO exception translation? different hierarchy for data set operations.
                DisposeConnection(connectionTxPairToUse.Connection, DbProvider);
                connectionTxPairToUse.Connection = null;
                throw;
            }
            finally
            {
                DisposeDataAdapterCommands(dataAdapter);
                DisposeConnection(connectionTxPairToUse.Connection, DbProvider);
            }


        }

        /// <summary>
        /// Execute ADO.NET operations on a IDbDataAdapter object using an delgate based callback.
        /// </summary>
        /// <remarks>This allows for implementing abritrary data access operations
        /// on a single DataAdapter within Spring's managed ADO.NET environment.
        /// </remarks>        
        /// <typeparam name="T">The type of object returned from the callback.</typeparam>
        /// <param name="dataAdapterCallback">The delegate called with a IDbDataAdapter object.</param>
        /// <returns>A result object returned by the callback or null</returns>
        public virtual T Execute<T>(DataAdapterDelegate<T> dataAdapterCallback)
        {
            ConnectionTxPair connectionTxPairToUse = GetConnectionTxPair(DbProvider);
            IDbDataAdapter dataAdapter = null;
            try
            {
                dataAdapter = DbProvider.CreateDataAdapter();
                //TODO row updated event handling...
                dataAdapter.SelectCommand = DbProvider.CreateCommand();
                dataAdapter.SelectCommand.Connection = connectionTxPairToUse.Connection;
                //TODO register for warnings on connection.
                dataAdapter.SelectCommand.Transaction = connectionTxPairToUse.Transaction;
                ApplyCommandSettings(dataAdapter.SelectCommand);
                T result = dataAdapterCallback(dataAdapter);
                return result;

            }
            catch (Exception)
            {
                DisposeDataAdapterCommands(dataAdapter);
                //TODO set dataAdapter command's = null; ?
                //TODO exception translation? different hierarchy for data set operations.
                DisposeConnection(connectionTxPairToUse.Connection, DbProvider);
                connectionTxPairToUse.Connection = null;
                throw;
            }
            finally
            {
                DisposeDataAdapterCommands(dataAdapter);
                DisposeConnection(connectionTxPairToUse.Connection, DbProvider);
            }
        }

        #endregion

        #region ExecuteNonQuery

        /// <summary>
        /// Executes a non query returning the number of rows affected.
        /// </summary>
        /// <param name="cmdType">The command type.</param>
        /// <param name="cmdText">The command text to execute.</param>
        /// <returns>The number of rows affected.</returns>
        public virtual int ExecuteNonQuery(CommandType cmdType, string cmdText)
        {
            return classicAdoTemplate.ExecuteNonQuery(cmdType, cmdText);
        }


        /// <summary>
        /// Executes a non query returning the number of rows affected.
        /// </summary>
        /// <param name="cmdType">The command type.</param>
        /// <param name="cmdText">The command text to execute.</param>
        /// <param name="parameterName">The name of the parameter to map.</param>
        /// <param name="dbType">One of the database parameter type enumerations.</param>
        /// <param name="size">The length of the parameter. 0 if not applicable to parameter type.</param>
        /// <param name="parameterValue">The parameter value.</param>
        /// <returns>The number of rows affected.</returns>
        public virtual int ExecuteNonQuery(CommandType cmdType, string cmdText,
                                   string parameterName, Enum dbType, int size, object parameterValue)
        {
            return classicAdoTemplate.ExecuteNonQuery(cmdType, cmdText, parameterName, dbType, size, parameterValue);


        }

        /// <summary>
        /// Executes a non query returning the number of rows affected.
        /// </summary>
        /// <param name="cmdType">The command type.</param>
        /// <param name="cmdText">The command text to execute.</param>
        /// <param name="parameters">The parameter collection to map.</param>
        /// <returns>The number of rows affected.</returns>
        public virtual int ExecuteNonQuery(CommandType cmdType, string cmdText,
                                           IDbParameters parameters)
        {
            return classicAdoTemplate.ExecuteNonQuery(cmdType, cmdText, parameters);

        }

        /// <summary>
        /// Executes a non query with parameters set via the
        /// command setter, returning the number of rows affected.
        /// </summary>
        /// <param name="cmdType">The command type.</param>
        /// <param name="cmdText">The command text to execute.</param>
        /// <param name="commandSetter">The command setter.</param>
        /// <returns>The number of rows affected.</returns>
        public virtual int ExecuteNonQuery(CommandType cmdType, string cmdText,
                                           ICommandSetter commandSetter)
        {
            return classicAdoTemplate.ExecuteNonQuery(cmdType, cmdText, commandSetter);
        }

        /// <summary>
        /// Executes a non query with a command created via IDbCommandCreator and
        /// parameters.
        /// </summary>
        /// <remarks>Output parameters can be retrieved via the returned
        /// dictionary.
        /// <para>
        /// More commonly used as a lower level support method within the framework,
        /// for example StoredProcedure/AdoScalar.
        /// </para>
        /// </remarks>
        /// <param name="commandCreator">The callback to create a IDbCommand.</param>
        /// <returns>The number of rows affected.</returns>
        public virtual IDictionary ExecuteNonQuery(IDbCommandCreator commandCreator)
        {
            return classicAdoTemplate.ExecuteNonQuery(commandCreator);
        }

        #endregion

        #region ExecuteScalar

        /// <summary>
        /// Execute the query with the specified command text.
        /// </summary>
        /// <remarks>No parameters are used.  As with 
        /// IDbCommand.ExecuteScalar, it returns the first column of the first row in the result set
        /// returned by the query.  Extra columns or row are ignored.</remarks>
        /// <param name="cmdType">The command type</param>
        /// <param name="cmdText">The command text to execute.</param>
        /// <returns>The first column of the first row in the result set</returns>
        public virtual object ExecuteScalar(CommandType cmdType, string cmdText)
        {
            return classicAdoTemplate.ExecuteScalar(cmdType, cmdText);
        }

        /// <summary>
        /// Execute the query with the specified command text and parameter returning a scalar result
        /// </summary>
        /// <param name="cmdType">The command type</param>
        /// <param name="cmdText">The command text to execute.</param>
        /// <param name="parameterName">The name of the parameter to map.</param>
        /// <param name="dbType">One of the database parameter type enumerations.</param>
        /// <param name="size">The length of the parameter. 0 if not applicable to parameter type.</param>
        /// <param name="parameterValue">The parameter value.</param>
        /// <returns>The first column of the first row in the result set</returns>
        public virtual object ExecuteScalar(CommandType cmdType, string cmdText,
                                            string parameterName, Enum dbType, int size, object parameterValue)
        {
            return classicAdoTemplate.ExecuteScalar(cmdType, cmdText, parameterName, dbType, size, parameterValue);

        }


        /// <summary>
        /// Execute the query with the specified command text and parameters returning a scalar result
        /// </summary>
        /// <param name="cmdType">The command type</param>
        /// <param name="cmdText">The command text to execute.</param>
        /// <param name="parameters">The parameter collection to map.</param>
        /// <returns>The first column of the first row in the result set</returns>
        public virtual object ExecuteScalar(CommandType cmdType, string cmdText,
                                            IDbParameters parameters)
        {
            return classicAdoTemplate.ExecuteScalar(cmdType, cmdText, parameters);
        }

        /// <summary>
        /// Execute the query with the specified command text and parameters set via the
        /// command setter, returning a scalar result
        /// </summary>
        /// <param name="cmdType">The command type</param>
        /// <param name="cmdText">The command text to execute.</param>
        /// <param name="commandSetter">The command setter.</param>
        /// <returns>The first column of the first row in the result set</returns>
        public virtual object ExecuteScalar(CommandType cmdType, string cmdText,
                                            ICommandSetter commandSetter)
        {
            return classicAdoTemplate.ExecuteScalar(cmdType, cmdText, commandSetter);
        }

        /// <summary>
        /// Execute the query with a command created via IDbCommandCreator and 
        /// parameters
        /// </summary>
        /// <remarks>Output parameters can be retrieved via the returned
        /// dictionary.
        /// <para>
        /// More commonly used as a lower level support method within the framework,
        /// for example for StoredProcedure/AdoScalar.
        /// </para></remarks>
        /// <param name="commandCreator">The callback to create a IDbCommand.</param>
        /// <returns>A dictionary containing output parameters, if any</returns>
        public virtual IDictionary ExecuteScalar(IDbCommandCreator commandCreator)
        {
            return classicAdoTemplate.ExecuteScalar(commandCreator);
        }

        #endregion

        #region Queries with RowCallback

        /// <summary>
        /// Execute a query given IDbCommand's type and text by 
        /// passing the created IDbCommand to a ICommandSetter implementation 
        /// that knows how to bind values to the IDbCommand, reading a 
        /// single result set on a per-row basis with a <see cref="IRowCallback"/>.
        /// </summary>
        /// <param name="cmdType">The type of command</param>
        /// <param name="cmdText">The text of the query.</param>
        /// <param name="rowCallback">callback that will extract results
        /// one row at a time.
        /// </param>
        /// <param name="commandSetter">The command setter.</param>
        public virtual void QueryWithRowCallback(CommandType cmdType, string cmdText, IRowCallback rowCallback,
                                                 ICommandSetter commandSetter)
        {
            classicAdoTemplate.QueryWithRowCallback(cmdType, cmdText, rowCallback, commandSetter);
        }
        /// <summary>
        /// Execute a query given IDbCommand's type and text, reading a 
        /// single result set on a per-row basis with a <see cref="IRowCallback"/>.
        /// </summary>
        /// <param name="cmdType">The type of command</param>
        /// <param name="cmdText">The text of the query.</param>
        /// <param name="rowCallback">callback that will extract results
        /// one row at a time.
        /// </param>
        public virtual void QueryWithRowCallback(CommandType cmdType, string cmdText, IRowCallback rowCallback)
        {
            classicAdoTemplate.QueryWithRowCallback(cmdType, cmdText, rowCallback);
        }

        /// <summary>
        /// Execute a query given IDbCommand's type and text and provided parameter
        /// information, reading a 
        /// single result set on a per-row basis with a <see cref="IRowCallback"/>.
        /// </summary>
        /// <param name="cmdType">The type of command</param>
        /// <param name="cmdText">The text of the query.</param>
        /// <param name="rowCallback">callback that will extract results
        /// one row at a time.
        /// </param>
        /// <param name="parameterName">The name of the parameter to map.</param>
        /// <param name="dbType">One of the database parameter type enumerations.</param>
        /// <param name="size">The length of the parameter. 0 if not applicable to parameter type.</param>
        /// <param name="parameterValue">The parameter value.</param>
        public virtual void QueryWithRowCallback(CommandType cmdType, string cmdText, IRowCallback rowCallback,
                                                 string parameterName, Enum dbType, int size, object parameterValue)
        {
            classicAdoTemplate.QueryWithRowCallback(cmdType, cmdText, rowCallback,
                                                    parameterName, dbType, size, parameterValue);
        }

        /// <summary>
        /// Execute a query given IDbCommand's type and text and provided IDbParameters,
        /// reading a single result set on a per-row basis with a <see cref="IRowCallback"/>.
        /// </summary>
        /// <param name="cmdType">Type of the command.</param>
        /// <param name="cmdText">The text of the query.</param>
        /// <param name="rowCallback">callback that will extract results
        /// one row at a time.</param>
        /// <param name="parameter">The parameter collection to map.</param>
        public virtual void QueryWithRowCallback(CommandType cmdType, string cmdText, IRowCallback rowCallback,
                                  IDbParameters parameter)
        {
            classicAdoTemplate.QueryWithRowCallback(cmdType, cmdText, rowCallback,
                                                    parameter);
        }

        #endregion

        #region Queries with RowCallback Delegate

        public virtual void QueryWithRowCallbackDelegate(CommandType cmdType, string sql, RowCallbackDelegate rowCallbackDelegate)
        {
            classicAdoTemplate.QueryWithRowCallbackDelegate(cmdType, sql, rowCallbackDelegate);

        }
        public virtual void QueryWithRowCallbackDelegate(CommandType cmdType, string sql, RowCallbackDelegate rowCallbackDelegate, ICommandSetter commandSetter)
        {
            classicAdoTemplate.QueryWithRowCallbackDelegate(cmdType, sql, rowCallbackDelegate, commandSetter);
        }

        public virtual void QueryWithRowCallbackDelegate(CommandType cmdType, string sql, RowCallbackDelegate rowCallbackDelegate,
                        string parameterName, Enum dbType, int size, object parameterValue)
        {
            classicAdoTemplate.QueryWithRowCallbackDelegate(cmdType, sql, rowCallbackDelegate,
                                                            parameterName, dbType, size, parameterValue);

        }

        public void QueryWithRowCallbackDelegate(CommandType cmdType, string sql, RowCallbackDelegate rowCallbackDelegate, IDbParameters parameters)
        {
            classicAdoTemplate.QueryWithRowCallbackDelegate(cmdType, sql, rowCallbackDelegate, parameters);

        }

        #endregion

        #region Queries with RowMapper<T>

        public IList<T> QueryWithRowMapper<T>(CommandType cmdType, string cmdText, IRowMapper<T> rowMapper)
        {
            return QueryWithResultSetExtractor(cmdType, cmdText, new RowMapperResultSetExtractor<T>(rowMapper));

        }


        public IList<T> QueryWithRowMapper<T>(CommandType cmdType, String cmdText, IRowMapper<T> rowMapper,
                                              ICommandSetter commandSetter)
        {
            return QueryWithResultSetExtractor(cmdType, cmdText, new RowMapperResultSetExtractor<T>(rowMapper), commandSetter);

        }

        public IList<T> QueryWithRowMapper<T>(CommandType cmdType, string cmdText, IRowMapper<T> rowMapper,
                                              string parameterName, Enum dbType, int size, object parameterValue)
        {
            return QueryWithResultSetExtractor(cmdType, cmdText, new RowMapperResultSetExtractor<T>(rowMapper), parameterName, dbType, size, parameterValue);

        }

        public IList<T> QueryWithRowMapper<T>(CommandType cmdType, string cmdText, IRowMapper<T> rowMapper, IDbParameters parameters)
        {
            return QueryWithResultSetExtractor(cmdType, cmdText, new RowMapperResultSetExtractor<T>(rowMapper), parameters);

        }



        #endregion

        #region Queries with RowMapperDelegate<T>

        public IList<T> QueryWithRowMapperDelegate<T>(CommandType cmdType, string cmdText, RowMapperDelegate<T> rowMapperDelegate)
        {
            return QueryWithResultSetExtractor(cmdType, cmdText, new RowMapperResultSetExtractor<T>(rowMapperDelegate));

        }

        public IList<T> QueryWithRowMapperDelegate<T>(CommandType cmdType, string cmdText, RowMapperDelegate<T> rowMapperDelegate,
                                                      ICommandSetter commandSetter)
        {
            return QueryWithResultSetExtractor(cmdType, cmdText, new RowMapperResultSetExtractor<T>(rowMapperDelegate),
                                               commandSetter);
        }

        public IList<T> QueryWithRowMapperDelegate<T>(CommandType cmdType, string cmdText, RowMapperDelegate<T> rowMapperDelegate,
                                                      string parameterName, Enum dbType, int size, object parameterValue)
        {
            return QueryWithResultSetExtractor(cmdType, cmdText, new RowMapperResultSetExtractor<T>(rowMapperDelegate),
                                               parameterName, dbType, size, parameterValue);
        }

        public IList<T> QueryWithRowMapperDelegate<T>(CommandType cmdType, string cmdText, RowMapperDelegate<T> rowMapperDelegate,
                                               IDbParameters parameters)
        {
            return QueryWithResultSetExtractor(cmdType, cmdText, new RowMapperResultSetExtractor<T>(rowMapperDelegate),
                                               parameters);
        }
        #endregion

        #region Queries with ResultSetExtractor<T>

        public T QueryWithResultSetExtractor<T>(CommandType cmdType,
                                                string cmdText,
                                                IResultSetExtractor<T> resultSetExtractor)
        {
            AssertUtils.ArgumentNotNull(cmdText, "cmdText", "CommandText must not be null");
            if (LOG.IsDebugEnabled)
            {
                LOG.Debug("Executing CommandText [" + cmdText + "]");
            }
            return Execute<T>(new QueryCallback<T>(this, cmdType, cmdText, resultSetExtractor, null));
        }

        public T QueryWithResultSetExtractor<T>(CommandType commandType, string cmdText, IResultSetExtractor<T> resultSetExtractor,
                                                string name, Enum dbType, int size, object parameterValue)
        {
            AssertUtils.ArgumentNotNull(resultSetExtractor, "resultSetExtractor", "Result Set Extractor must not be null");
            return Execute<T>(new QueryCallback<T>(this, commandType, cmdText, resultSetExtractor,
                                                   CreateDbParameters(name, dbType, size, parameterValue)));
        }

        public T QueryWithResultSetExtractor<T>(CommandType commandType, string cmdText,
                                                IResultSetExtractor<T> resultSetExtractor,
                                                IDbParameters parameters)
        {
            AssertUtils.ArgumentNotNull(resultSetExtractor, "resultSetExtractor", "Result Set Extractor must not be null");
            return Execute<T>(new QueryCallback<T>(this, commandType, cmdText, resultSetExtractor, parameters));
        }

        public T QueryWithResultSetExtractor<T>(CommandType cmdType, string cmdText,
                                                IResultSetExtractor<T> resultSetExtractor,
                                                ICommandSetter commandSetter)
        {
            AssertUtils.ArgumentNotNull(resultSetExtractor, "resultSetExtractor", "Result Set Extractor must not be null");
            return Execute<T>(new QueryCallbackWithCommandSetter<T>(this, cmdType, cmdText,
                                                                    resultSetExtractor,
                                                                    commandSetter));
        }

        public T QueryWithResultSetExtractor<T>(CommandType cmdType, string cmdText,
                                                IResultSetExtractor<T> resultSetExtractor,
                                                CommandSetterDelegate commandSetterDelegate)
        {
            AssertUtils.ArgumentNotNull(resultSetExtractor, "resultSetExtractor", "Result Set Extractor must not be null");
            return Execute<T>(new QueryCallbackWithCommandSetterDelegate<T>(this, cmdType, cmdText,
                                                                    resultSetExtractor,
                                                                    commandSetterDelegate));
        }

        #endregion


        #region Queries with ResultSetExtractorDelegate<T>

        public T QueryWithResultSetExtractorDelegate<T>(CommandType cmdType,
                                                        string cmdText,
                                                        ResultSetExtractorDelegate<T> resultSetExtractorDelegate)
        {
            AssertUtils.ArgumentNotNull(cmdText, "cmdText", "CommandText must not be null");
            AssertUtils.ArgumentNotNull(resultSetExtractorDelegate, "resultSetExtractorDelegate", "Result set extractor delegate must not be null");
            if (LOG.IsDebugEnabled)
            {
                LOG.Debug("Executing CommandText [" + cmdText + "]");
            }

            return Execute<T>(new QueryCallback<T>(this, cmdType, cmdText, resultSetExtractorDelegate, null));
        }

        public T QueryWithResultSetExtractorDelegate<T>(CommandType commandType, string cmdText, ResultSetExtractorDelegate<T> resultSetExtractorDelegate,
                                                        string paramenterName, Enum dbType, int size, object parameterValue)
        {
            AssertUtils.ArgumentNotNull(cmdText, "cmdText", "CommandText must not be null");
            AssertUtils.ArgumentNotNull(resultSetExtractorDelegate, "resultSetExtractorDelegate", "Result set extractor delegate must not be null");
            return Execute<T>(new QueryCallback<T>(this, commandType, cmdText, resultSetExtractorDelegate,
                                                   CreateDbParameters(paramenterName, dbType, size, parameterValue)));
        }

        public T QueryWithResultSetExtractorDelegate<T>(CommandType commandType, string cmdText, ResultSetExtractorDelegate<T> resultSetExtractorDelegate,
                                                IDbParameters parameters)
        {
            AssertUtils.ArgumentNotNull(cmdText, "cmdText", "CommandText must not be null");
            AssertUtils.ArgumentNotNull(resultSetExtractorDelegate, "resultSetExtractorDelegate", "Result set extractor delegate  must not be null");
            return Execute<T>(new QueryCallback<T>(this, commandType, cmdText, resultSetExtractorDelegate, parameters));
        }

        public T QueryWithResultSetExtractorDelegate<T>(CommandType cmdType, string cmdText, ResultSetExtractorDelegate<T> resultSetExtractorDelegate,
                                                        ICommandSetter commandSetter)
        {
            AssertUtils.ArgumentNotNull(cmdText, "cmdText", "CommandText must not be null");
            AssertUtils.ArgumentNotNull(resultSetExtractorDelegate, "resultSetExtractorDelegate", "Result set extractor delegate must not be null");
            return Execute<T>(new QueryCallbackWithCommandSetter<T>(this, cmdType, cmdText,
                                                                    resultSetExtractorDelegate,
                                                                    commandSetter));
        }

        public T QueryWithResultSetExtractorDelegate<T>(CommandType cmdType, string cmdText, ResultSetExtractorDelegate<T> resultSetExtractorDelegate,
                                                        CommandSetterDelegate commandSetterDelegate)
        {
            AssertUtils.ArgumentNotNull(resultSetExtractorDelegate, "resultSetExtractorDelegate", "Result set extractor delegate must not be null");
            return Execute<T>(new QueryCallbackWithCommandSetterDelegate<T>(this, cmdType, cmdText,
                                                                    resultSetExtractorDelegate,
                                                                    commandSetterDelegate));
        }

        #endregion

        #region Query for Object<T>

        public T QueryForObject<T>(CommandType cmdType, string cmdText, IRowMapper<T> rowMapper)
        {
            IList<T> results = QueryWithRowMapper(cmdType, cmdText, rowMapper);
            return DataAccessUtils.RequiredUniqueResultSet(results);
        }

        public T QueryForObject<T>(CommandType cmdType, string cmdText, IRowMapper<T> rowMapper, ICommandSetter commandSetter)
        {
            IList<T> results = QueryWithRowMapper(cmdType, cmdText, rowMapper, commandSetter);
            return DataAccessUtils.RequiredUniqueResultSet(results);
        }

        public T QueryForObject<T>(CommandType cmdType, string cmdText, IRowMapper<T> rowMapper, IDbParameters parameters)
        {
            IList<T> results = QueryWithRowMapper(cmdType, cmdText, rowMapper, parameters);
            return DataAccessUtils.RequiredUniqueResultSet(results);
        }


        public T QueryForObject<T>(CommandType cmdType, string cmdText, IRowMapper<T> rowMapper,
                                   string parameterName, Enum dbType, int size, object parameterValue)
        {
            IList<T> results = QueryWithRowMapper(cmdType, cmdText, rowMapper, parameterName, dbType, size, parameterValue);
            return DataAccessUtils.RequiredUniqueResultSet(results);
        }
        #endregion

        #region Query for ObjectDelegate<T>

        public T QueryForObjectDelegate<T>(CommandType cmdType, string cmdText, RowMapperDelegate<T> rowMapperDelegate)
        {
            IList<T> results = QueryWithRowMapperDelegate(cmdType, cmdText, rowMapperDelegate);
            return DataAccessUtils.RequiredUniqueResultSet(results);
        }

        public T QueryForObjectDelegate<T>(CommandType cmdType, string cmdText, RowMapperDelegate<T> rowMapperDelegate, ICommandSetter commandSetter)
        {
            IList<T> results = QueryWithRowMapperDelegate(cmdType, cmdText, rowMapperDelegate, commandSetter);
            return DataAccessUtils.RequiredUniqueResultSet(results);
        }

        public T QueryForObjectDelegate<T>(CommandType cmdType, string cmdText, RowMapperDelegate<T> rowMapperDelegate, IDbParameters parameters)
        {
            IList<T> results = QueryWithRowMapperDelegate(cmdType, cmdText, rowMapperDelegate, parameters);
            return DataAccessUtils.RequiredUniqueResultSet(results);
        }


        public T QueryForObjectDelegate<T>(CommandType cmdType, string cmdText, RowMapperDelegate<T> rowMapperDelegate,
                                   string parameterName, Enum dbType, int size, object parameterValue)
        {
            IList<T> results = QueryWithRowMapperDelegate(cmdType, cmdText, rowMapperDelegate, parameterName, dbType, size, parameterValue);
            return DataAccessUtils.RequiredUniqueResultSet(results);
        }
        #endregion


        #region Query with CommandCreator

        public T QueryWithCommandCreator<T>(IDbCommandCreator cc, IResultSetExtractor<T> rse)
        {
            return QueryWithCommandCreator<T>(cc, rse, null);
        }

        public void QueryWithCommandCreator(IDbCommandCreator cc, IRowCallback rowCallback)
        {
            classicAdoTemplate.QueryWithCommandCreator(cc, rowCallback, null);
        }

        public IList<T> QueryWithCommandCreator<T>(IDbCommandCreator cc, IRowMapper<T> rowMapper)
        {
            return QueryWithCommandCreator<T>(cc, rowMapper, null);
        }

        public T QueryWithCommandCreator<T>(IDbCommandCreator cc, IResultSetExtractor<T> rse, IDictionary returnedParameters)
        {
            if (rse == null)
            {
                throw new ArgumentNullException("Result Set Extractor must not be null");
            }

            return Execute(cc, new AdoResultSetExtractorWithOutputParamsCommandCallback<T>(this, rse, returnedParameters));
        }


        public void QueryWithCommandCreator(IDbCommandCreator cc, IRowCallback rowCallback, IDictionary returnedParameters)
        {
            classicAdoTemplate.QueryWithCommandCreator(cc, rowCallback, returnedParameters);
        }


        public IList<T> QueryWithCommandCreator<T>(IDbCommandCreator cc, IRowMapper<T> rowMapper, IDictionary returnedParameters)
        {
            if (rowMapper == null)
            {
                throw new ArgumentNullException("rowMapper must not be null");
            }

            return Execute(cc, new AdoRowMapperQueryCommandCallback<T>(this, rowMapper, returnedParameters));
        }


        public IDictionary QueryWithCommandCreator<T>(IDbCommandCreator cc, IList namedResultSetProcessors)
        {
            return classicAdoTemplate.Execute(cc, new AdoResultProcessorsQueryCommandCallback<T>(this, namedResultSetProcessors)) as IDictionary;
        }
        

        public IDictionary QueryWithCommandCreator<T,U>(IDbCommandCreator cc, IList namedResultSetProcessors)
        {
            return classicAdoTemplate.Execute(cc, new AdoResultProcessorsQueryCommandCallback<T,U>(this, namedResultSetProcessors)) as IDictionary;
        }


        #endregion

        #region General Helper Methods

        /// <summary>
        /// Checks if DbProvider is not null and creates ExceptionTranslator if not LazyInit.
        /// </summary>
        public override void AfterPropertiesSet()
        {
            classicAdoTemplate.AfterPropertiesSet();
            classicAdoTemplate.CommandTimeout = CommandTimeout;
        }

        /// <summary>
        /// Creates the data reader wrapper for use in AdoTemplate callback methods.
        /// </summary>
        /// <param name="readerToWrap">The reader to wrap.</param>
        /// <returns>The data reader used in AdoTemplate callbacks</returns>
        public override IDataReader CreateDataReaderWrapper(IDataReader readerToWrap)
        {
            return classicAdoTemplate.CreateDataReaderWrapper(readerToWrap);
        }

        #endregion

        #region Parameter Creation Helper Methods

        /// <summary>
        /// Derives the parameters of a stored procedure including the return parameter
        /// </summary>
        /// <param name="procedureName">Name of the procedure.</param>
        /// <param name="includeReturnParameter">if set to <c>true</c> to include return parameter.</param>
        /// <returns>The stored procedure parameters</returns>
        public override IDataParameter[] DeriveParameters(string procedureName, bool includeReturnParameter)
        {
            return classicAdoTemplate.DeriveParameters(procedureName, includeReturnParameter);
        }

        #endregion





        #region Internal Helper classes

        internal class QueryCallback<T> : IDbCommandCallback<T>, ICommandTextProvider
        {
            private AdoTemplate adoTemplate;
            private IResultSetExtractor<T> rse;
            private ResultSetExtractorDelegate<T> resultSetExtractorDelegate;
            private CommandType commandType;
            private string commandText;
            private IDbParameters parameters;

            public QueryCallback(AdoTemplate adoTemplate,
                                 CommandType cmdType,
                                 string cmdText,
                                 IResultSetExtractor<T> rse,
                                 IDbParameters dbParameters)
            {
                this.adoTemplate = adoTemplate;
                commandType = cmdType;
                commandText = cmdText;
                this.rse = rse;
                parameters = dbParameters;
            }

            public QueryCallback(AdoTemplate adoTemplate,
                         CommandType cmdType,
                         string cmdText,
                         ResultSetExtractorDelegate<T> resultSetExtractorDelegate,
                         IDbParameters dbParameters)
            {
                this.adoTemplate = adoTemplate;
                commandType = cmdType;
                commandText = cmdText;
                this.resultSetExtractorDelegate = resultSetExtractorDelegate;
                parameters = dbParameters;
            }

            public string CommandText
            {
                get { return commandText; }
            }

            public T DoInCommand(IDbCommand command)
            {
                IDataReader reader = null;
                try
                {
                    command.CommandType = commandType;
                    command.CommandText = commandText;
                    ParameterUtils.CopyParameters(command, parameters);
                    reader = adoTemplate.CreateDataReaderWrapper(command.ExecuteReader());
                    T returnValue = default(T);
                    if (rse != null)
                    {
                        returnValue = rse.ExtractData(reader);
                    }
                    else
                    {
                        returnValue = resultSetExtractorDelegate(reader);
                    }
                    return returnValue;
                }
                finally
                {
                    Support.AdoUtils.CloseReader(reader);
                    ParameterUtils.CopyParameters(parameters, command);
                }
            }


        }

        internal class QueryCallbackWithCommandSetter<T> : IDbCommandCallback<T>, ICommandTextProvider
        {
            private AdoTemplate adoTemplate;
            private IResultSetExtractor<T> rse;
            private ResultSetExtractorDelegate<T> resultSetExtractorDelegate;
            private CommandType commandType;
            private string commandText;
            private ICommandSetter commandSetter;

            public QueryCallbackWithCommandSetter(AdoTemplate adoTemplate,
                                                     CommandType cmdType,
                                                     string cmdText,
                                                     IResultSetExtractor<T> rse,
                                                     ICommandSetter commandSetter)
            {
                this.adoTemplate = adoTemplate;
                commandType = cmdType;
                commandText = cmdText;
                this.rse = rse;
                this.commandSetter = commandSetter;
            }

            public QueryCallbackWithCommandSetter(AdoTemplate adoTemplate,
                                             CommandType cmdType,
                                             string cmdText,
                                             ResultSetExtractorDelegate<T> resultSetExtractorDelegate,
                                             ICommandSetter commandSetter)
            {
                this.adoTemplate = adoTemplate;
                commandType = cmdType;
                commandText = cmdText;
                this.resultSetExtractorDelegate = resultSetExtractorDelegate;
                this.commandSetter = commandSetter;
            }

            public string CommandText
            {
                get { return commandText; }
            }

            public T DoInCommand(IDbCommand command)
            {
                IDataReader reader = null;
                try
                {
                    command.CommandType = commandType;
                    command.CommandText = commandText;
                    if (commandSetter != null)
                    {
                        commandSetter.SetValues(command);
                    }
                    reader = adoTemplate.CreateDataReaderWrapper(command.ExecuteReader());
                    if (rse != null)
                    {
                        return rse.ExtractData(reader);
                    }
                    else
                    {
                        return resultSetExtractorDelegate(reader);
                    }

                }
                finally
                {
                    Support.AdoUtils.CloseReader(reader);
                }
            }


        }

        internal class QueryCallbackWithCommandSetterDelegate<T> : IDbCommandCallback<T>, ICommandTextProvider
        {
            private AdoTemplate adoTemplate;
            private IResultSetExtractor<T> rse;
            private ResultSetExtractorDelegate<T> resultSetExtractorDelegate;
            private CommandType commandType;
            private string commandText;
            private CommandSetterDelegate commandSetterDelegate;

            public QueryCallbackWithCommandSetterDelegate(AdoTemplate adoTemplate,
                                                        CommandType cmdType,
                                                        string cmdText,
                                                        IResultSetExtractor<T> rse,
                                                        CommandSetterDelegate commandSetterDelegate)
            {
                this.adoTemplate = adoTemplate;
                commandType = cmdType;
                commandText = cmdText;
                this.rse = rse;
                this.commandSetterDelegate = commandSetterDelegate;
            }

            public QueryCallbackWithCommandSetterDelegate(AdoTemplate adoTemplate,
                                                CommandType cmdType,
                                                string cmdText,
                                                ResultSetExtractorDelegate<T> resultSetExtractorDelegate,
                                                CommandSetterDelegate commandSetterDelegate)
            {
                this.adoTemplate = adoTemplate;
                commandType = cmdType;
                commandText = cmdText;
                this.resultSetExtractorDelegate = resultSetExtractorDelegate;
                this.commandSetterDelegate = commandSetterDelegate;
            }

            public string CommandText
            {
                get { return commandText; }
            }

            public T DoInCommand(IDbCommand command)
            {
                IDataReader reader = null;
                try
                {
                    command.CommandType = commandType;
                    command.CommandText = commandText;
                    if (commandSetterDelegate != null)
                    {
                        commandSetterDelegate(command);
                    }
                    reader = adoTemplate.CreateDataReaderWrapper(command.ExecuteReader());
                    if (rse != null)
                    {
                        return rse.ExtractData(reader);
                    }
                    else
                    {
                        return resultSetExtractorDelegate(reader);
                    }
                }
                finally
                {
                    Support.AdoUtils.CloseReader(reader);
                }
            }


        }

        internal class AdoRowMapperQueryCommandCallback<T> : IDbCommandCallback<IList<T>>
        {
            private AdoTemplate adoTemplate;
            private IRowMapper<T> rowMapper;
            private IDictionary returnedParameters;

            public AdoRowMapperQueryCommandCallback(AdoTemplate adoTemplate, IRowMapper<T> rowMapper, IDictionary returnedParameters)
            {
                this.adoTemplate = adoTemplate;
                this.rowMapper = rowMapper;
                this.returnedParameters = returnedParameters;
            }

            public IList<T> DoInCommand(IDbCommand command)
            {
                IList<T> objectList;
                //Extract the single returned result set
                IDataReader reader = null;
                try
                {
                    reader = adoTemplate.CreateDataReaderWrapper(command.ExecuteReader());
                    RowMapperResultSetExtractor<T> rse = new RowMapperResultSetExtractor<T>(rowMapper, 1);
                    objectList = rse.ExtractData(reader);
                }
                finally
                {
                    Support.AdoUtils.CloseReader(reader);
                }
                ParameterUtils.ExtractOutputParameters(returnedParameters, command);
                return objectList;
            }
        }

        internal class AdoResultSetExtractorWithOutputParamsCommandCallback<T> : IDbCommandCallback<T>
        {
            private AdoTemplate adoTemplate;
            private IResultSetExtractor<T> rse;
            private IDictionary returnedParameters;

            public AdoResultSetExtractorWithOutputParamsCommandCallback(AdoTemplate adoTemplate, IResultSetExtractor<T> rse, IDictionary returnedParameters)
            {
                this.adoTemplate = adoTemplate;
                this.rse = rse;
                this.returnedParameters = returnedParameters;
            }

            public T DoInCommand(IDbCommand command)
            {
                T returnVal;
                //Extract the single returned result set
                IDataReader reader = null;
                try
                {
                    reader = adoTemplate.CreateDataReaderWrapper(command.ExecuteReader());
                    returnVal = rse.ExtractData(reader);
                }
                finally
                {
                    Support.AdoUtils.CloseReader(reader);
                }
                ParameterUtils.ExtractOutputParameters(returnedParameters, command);
                return returnVal;
            }
        }

        internal class BaseAdoResultProcessorsQueryCommandCallback<T>
        {
            public static void ProcessNonGenericResultSetProcessor(NamedResultSetProcessor otherResultSetProcessor, IDataReader reader, IDictionary returnedResults)
            {
                string parameterName = otherResultSetProcessor.Name;
                if (otherResultSetProcessor.ResultSetProcessor is IResultSetExtractor)
                {
                    IResultSetExtractor rse = (IResultSetExtractor)otherResultSetProcessor.ResultSetProcessor;
                    object result = rse.ExtractData(reader);
                    returnedResults.Add(parameterName, result);
                }
                else if (otherResultSetProcessor.ResultSetProcessor is IRowMapper)
                {
                    IRowMapper rowMapper = (IRowMapper)otherResultSetProcessor.ResultSetProcessor;
                    object result = (new RowMapperResultSetExtractor(rowMapper)).ExtractData(reader);
                    returnedResults.Add(parameterName, result);
                }
                else if (otherResultSetProcessor.ResultSetProcessor is IRowCallback)
                {
                    IRowCallback rowCallback = (IRowCallback)otherResultSetProcessor.ResultSetProcessor;
                    (new RowCallbackResultSetExtractor(rowCallback)).ExtractData(reader);
                    returnedResults.Add(parameterName, "ResultSet returned was processed by an IRowCallback");
                }
            }

            public static void ProcessFirstGenericResultSetProcessor(NamedResultSetProcessor<T> firstResultSetProcessor, IDataReader reader, IDictionary returnedResults)
            {
                string parameterName = firstResultSetProcessor.Name;
                if (firstResultSetProcessor.ResultSetExtractor != null)
                {
                    IResultSetExtractor<T> rse = firstResultSetProcessor.ResultSetExtractor;
                    T result = rse.ExtractData(reader);
                    returnedResults.Add(parameterName, result);
                }
                else if (firstResultSetProcessor.RowMapper != null)
                {
                    IRowMapper<T> rowMapper = firstResultSetProcessor.RowMapper;
                    object result = (new RowMapperResultSetExtractor<T>(rowMapper)).ExtractData(reader);
                    returnedResults.Add(parameterName, result);
                }
                else if (firstResultSetProcessor.RowCallback != null)
                {
                    IRowCallback rowCallback = firstResultSetProcessor.RowCallback;
                    (new RowCallbackResultSetExtractor(rowCallback)).ExtractData(reader);
                    returnedResults.Add(parameterName, "ResultSet returned was processed by an IRowCallback");
                }
            }
        }

        internal class AdoResultProcessorsQueryCommandCallback<T> : BaseAdoResultProcessorsQueryCommandCallback<T>, ICommandCallback
        {
            private AdoTemplate adoTemplate;
            private IList namedResultSetProcessors;

            public AdoResultProcessorsQueryCommandCallback(AdoTemplate adoTemplate, IList namedResultSetProcessors)
            {
                this.adoTemplate = adoTemplate;
                this.namedResultSetProcessors = namedResultSetProcessors;
            }

            public object DoInCommand(IDbCommand command)
            {
                IDictionary returnedResults = new Hashtable();
                int resultSetIndex = 0;
                IDataReader reader = null;
                try
                {
                    reader = adoTemplate.CreateDataReaderWrapper(command.ExecuteReader());

                    //TODO On >= .NET 2.0 platforms make use of DbDataReader.HasRows property to
                    //     see if there is a result set.  now currently assuming matching
                    //     NamedResultSetProcessor/ResultSet pairs.
             
                    do
                    {
                        if (namedResultSetProcessors.Count == 0)
                        {
                            //We could just have output parameters and/or return value, that is, no result sets
                            //If we didn't register a result set processor, it is likely that a result set wasn't expected.
                            break;
                        }
                        NamedResultSetProcessor<T> firstResultSetProcessor = null;
                        NamedResultSetProcessor otherResultSetProcessor = null;
                        try
                        {
                            if (resultSetIndex == 0)
                            {
                                firstResultSetProcessor
                                    = namedResultSetProcessors[resultSetIndex] as NamedResultSetProcessor<T>;
                                //Will have possibility of run-time type error if using QueryWithCommandCreator
                                if (firstResultSetProcessor == null)
                                {
                                    LOG.Error("NamedResultSetProcessor for result set index " + resultSetIndex +
                                              ", is not of expected type NamedResultSetProcessor<T>.  Type = " +
                                              namedResultSetProcessors[resultSetIndex].GetType() +
                                              "; Skipping processing for this result set.");
                                    continue;
                                }
                            }
                            else
                            {
                                otherResultSetProcessor =
                                    namedResultSetProcessors[resultSetIndex] as NamedResultSetProcessor;
                                if (otherResultSetProcessor == null)
                                {

                                    LOG.Error("NamedResultSetProcessor for result set index " + resultSetIndex +
                                              ", is not of expected type NamedResultSetProcessor  Type = " +
                                              namedResultSetProcessors[resultSetIndex].GetType() +
                                              "; Skipping processing for this result set.");
                                    continue;
                                }
                            }
                        }
                        catch (IndexOutOfRangeException e)
                        {
                            LOG.Error("No NamedResultSetProcessor associated with result set index " + resultSetIndex, e);
                            continue;
                        }
                        catch (ArgumentOutOfRangeException e)
                        {
                            LOG.Error("No NamedResultSetProcessor associated with result set index " + resultSetIndex, e);
                            continue;
                        }


                        if (resultSetIndex == 0)
                        {
                            ProcessFirstGenericResultSetProcessor(firstResultSetProcessor, reader, returnedResults);
                        }
                        else
                        {
                            ProcessNonGenericResultSetProcessor(otherResultSetProcessor, reader, returnedResults);
                        }
                        resultSetIndex++;

                    } while (reader.NextResult());
                }
                finally
                {
                    Support.AdoUtils.CloseReader(reader);
                }
                ParameterUtils.ExtractOutputParameters(returnedResults, command);
                return returnedResults;
            }
        }


        internal class AdoResultProcessorsQueryCommandCallback<T, U> : BaseAdoResultProcessorsQueryCommandCallback<T>, ICommandCallback
        {
            private AdoTemplate adoTemplate;
            private IList namedResultSetProcessors;

            public AdoResultProcessorsQueryCommandCallback(AdoTemplate adoTemplate, IList namedResultSetProcessors)
            {
                this.adoTemplate = adoTemplate;
                this.namedResultSetProcessors = namedResultSetProcessors;
            }

            public object DoInCommand(IDbCommand command)
            {
                IDictionary returnedResults = new Hashtable();
                int resultSetIndex = 0;
                IDataReader reader = null;
                try
                {
                    reader = adoTemplate.CreateDataReaderWrapper(command.ExecuteReader());

                    //TODO On >= .NET 2.0 platforms make use of DbDataReader.HasRows property to
                    //     see if there is a result set.  now currently assuming matching
                    //     NamedResultSetProcessor/ResultSet pairs.

                    do
                    {
                        if (namedResultSetProcessors.Count == 0)
                        {
                            //We could just have output parameters and/or return value, that is, no result sets
                            //If we didn't register a result set processor, it is likely that a result set wasn't expected.
                            break;
                        }
                        NamedResultSetProcessor<T> firstResultSetProcessor = null;
                        NamedResultSetProcessor<U> secondResultSetProcessor = null;
                        NamedResultSetProcessor otherResultSetProcessor = null;
                        try
                        {
                            if (resultSetIndex == 0)
                            {
                                firstResultSetProcessor = namedResultSetProcessors[resultSetIndex] as NamedResultSetProcessor<T>;
                                //Will only have possibility of run-time type error if using QueryWithCommandCreator
                                if (firstResultSetProcessor == null)
                                {

                                    LOG.Error("NamedResultSetProcessor for result set index " + resultSetIndex +
                                              ", is not of expected type NamedResultSetProcessor<T>  Type = " +
                                              namedResultSetProcessors[resultSetIndex].GetType() +
                                              "; Skipping processing for this result set.");
                                    continue;                                    
                                }
                            } else if (resultSetIndex == 1)
                            {
                                secondResultSetProcessor
                                    = namedResultSetProcessors[resultSetIndex] as NamedResultSetProcessor<U>;
                                if (secondResultSetProcessor == null)
                                {

                                    LOG.Error("NamedResultSetProcessor for result set index " + resultSetIndex +
                                              ", is not of expected type NamedResultSetProcessor<T>  Type = " +
                                              namedResultSetProcessors[resultSetIndex].GetType() +
                                              "; Skipping processing for this result set.");
                                    continue;
                                }
                            } else
                            {
                                otherResultSetProcessor =
                                    namedResultSetProcessors[resultSetIndex] as NamedResultSetProcessor;
                                if (otherResultSetProcessor == null)
                                {

                                    LOG.Error("NamedResultSetProcessor for result set index " + resultSetIndex +
                                              ", is not of expected type NamedResultSetProcessor  Type = " +
                                              namedResultSetProcessors[resultSetIndex].GetType() +
                                              "; Skipping processing for this result set.");
                                    continue;
                                }
                            }

                        }
                        catch (IndexOutOfRangeException e)
                        {
                            LOG.Error("No NamedResultSetProcessor associated with result set index " + resultSetIndex, e);
                            continue;
                        }
                        catch (ArgumentOutOfRangeException e)
                        {
                            LOG.Error("No NamedResultSetProcessor associated with result set index " + resultSetIndex, e);
                            continue;
                        }

                        if (resultSetIndex == 0)
                        {
                            ProcessFirstGenericResultSetProcessor(firstResultSetProcessor, reader, returnedResults);
                        }
                        else if (resultSetIndex == 1)
                        {
                            string parameterName = secondResultSetProcessor.Name;
                            if (secondResultSetProcessor.ResultSetExtractor != null)
                            {
                                IResultSetExtractor<U> rse = secondResultSetProcessor.ResultSetExtractor;
                                U result = rse.ExtractData(reader);
                                returnedResults.Add(parameterName, result);
                            }
                            else if (secondResultSetProcessor.RowMapper != null)
                            {
                                IRowMapper<U> rowMapper = secondResultSetProcessor.RowMapper;
                                object result = (new RowMapperResultSetExtractor<U>(rowMapper)).ExtractData(reader);
                                returnedResults.Add(parameterName, result);
                            }
                            else if (secondResultSetProcessor.RowCallback != null)
                            {
                                //In this case a dummy type parameter would need to be specified a better alternative would
                                //be to to use the single type parameterization of this callback.
                                IRowCallback rowCallback = secondResultSetProcessor.RowCallback;
                                (new RowCallbackResultSetExtractor(rowCallback)).ExtractData(reader);
                                returnedResults.Add(parameterName, "ResultSet returned was processed by an IRowCallback");
                            }
                        }
                        else
                        {
                            ProcessNonGenericResultSetProcessor(otherResultSetProcessor, reader, returnedResults);
                        }
                        resultSetIndex++;

                    } while (reader.NextResult());
                }
                finally
                {
                    Support.AdoUtils.CloseReader(reader);
                }
                ParameterUtils.ExtractOutputParameters(returnedResults, command);
                return returnedResults;
            }


        }
        #endregion

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