#region Apache Notice
/*****************************************************************************
* $Header: $
* $Revision: $
* $Date: $
*
* iBATIS.NET Data Mapper
* Copyright (C) 2005 - Gilles Bayon
*
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
********************************************************************************/
#endregion
#region Using
using System.Data;
using System.Collections;
using System.Text;
using IBatisNet.Common.Logging;
using IBatisNet.Common;
using IBatisNet.Common.Utilities.Objects;
using IBatisNet.DataMapper.Configuration.Statements;
using IBatisNet.DataMapper.Configuration.ParameterMapping;
using IBatisNet.DataMapper.Exceptions;
using IBatisNet.DataMapper.Scope;
#endregion
namespace IBatisNet.DataMapper.Commands
{
///
/// Summary description for DefaultPreparedCommand.
///
internal class DefaultPreparedCommand : IPreparedCommand
{
#region Fields
private static readonly ILog _logger = LogManager.GetLogger( System.Reflection.MethodBase.GetCurrentMethod().DeclaringType );
#endregion
#region IPreparedCommand Members
///
/// Create an IDbCommand for the IDalSession and the current SQL Statement
/// and fill IDbCommand IDataParameter's with the parameterObject.
///
///
/// The IDalSession
/// The IStatement
///
/// The parameter object that will fill the sql parameter
///
/// An IDbCommand with all the IDataParameter filled.
public IDbCommand Create(RequestScope request, IDalSession session, IStatement statement, object parameterObject )
{
// the IDbConnection & the IDbTransaction are assign in the CreateCommand
IDbCommand command = session.CreateCommand(statement.CommandType);
command.CommandText = request.PreparedStatement.PreparedSql;
if (_logger.IsDebugEnabled)
{
_logger.Debug("Statement Id: [" + statement.Id + "] PreparedStatement : [" + command.CommandText + "]");
}
ApplyParameterMap( session, command, request, statement, parameterObject );
return command;
}
///
///
///
///
///
///
///
///
protected virtual void ApplyParameterMap
( IDalSession session, IDbCommand command,
RequestScope request, IStatement statement, object parameterObject )
{
ArrayList properties = request.PreparedStatement.DbParametersName;
ArrayList parameters = request.PreparedStatement.DbParameters;
StringBuilder paramLogList = new StringBuilder(); // Log info
StringBuilder typeLogList = new StringBuilder(); // Log info
for ( int i = 0; i < properties.Count; ++i )
{
IDataParameter sqlParameter = (IDataParameter)parameters[i];
IDataParameter parameterCopy = command.CreateParameter();
ParameterProperty property = request.ParameterMap.GetProperty(i);
#region Logging
if (_logger.IsDebugEnabled)
{
paramLogList.Append(sqlParameter.ParameterName);
paramLogList.Append("=[");
typeLogList.Append(sqlParameter.ParameterName);
typeLogList.Append("=[");
}
#endregion
if (command.CommandType == CommandType.StoredProcedure)
{
#region store procedure command
// A store procedure must always use a ParameterMap
// to indicate the mapping order of the properties to the columns
if (request.ParameterMap == null) // Inline Parameters
{
throw new DataMapperException("A procedure statement tag must alway have a parameterMap attribute, which is not the case for the procedure '"+statement.Id+"'.");
}
else // Parameters via ParameterMap
{
if (property.DirectionAttribute.Length == 0)
{
property.Direction = sqlParameter.Direction;
}
// DbDataParameter dataParameter = (IDbDataParameter)parameters[i];
// property.Precision = dataParameter.Precision;
// property.Scale = dataParameter.Scale;
// property.Size = dataParameter.Size;
sqlParameter.Direction = property.Direction;
}
#endregion
}
#region Logging
if (_logger.IsDebugEnabled)
{
paramLogList.Append( property.PropertyName );
paramLogList.Append( "," );
}
#endregion
request.ParameterMap.SetParameter(property, parameterCopy, parameterObject );
parameterCopy.Direction = sqlParameter.Direction;
// With a ParameterMap, we could specify the ParameterDbTypeProperty
if (request.ParameterMap != null)
{
if (request.ParameterMap.GetProperty(i).DbType != null &&
request.ParameterMap.GetProperty(i).DbType.Length >0)
{
string dbTypePropertyName = session.DataSource.Provider.ParameterDbTypeProperty;
ObjectProbe.SetPropertyValue(parameterCopy, dbTypePropertyName, ObjectProbe.GetPropertyValue(sqlParameter, dbTypePropertyName));
}
else
{
//parameterCopy.DbType = sqlParameter.DbType;
}
}
else
{
//parameterCopy.DbType = sqlParameter.DbType;
}
#region Logging
if (_logger.IsDebugEnabled)
{
if (parameterCopy.Value == System.DBNull.Value)
{
paramLogList.Append("null");
paramLogList.Append( "], " );
typeLogList.Append("System.DBNull, null");
typeLogList.Append( "], " );
}
else
{
paramLogList.Append( parameterCopy.Value.ToString() );
paramLogList.Append( "], " );
// sqlParameter.DbType could be null (as with Npgsql)
// if PreparedStatementFactory did not find a dbType for the parameter in:
// line 225: "if (property.DbType.Length >0)"
// Use parameterCopy.DbType
//typeLogList.Append( sqlParameter.DbType.ToString() );
typeLogList.Append( parameterCopy.DbType.ToString() );
typeLogList.Append( ", " );
typeLogList.Append( parameterCopy.Value.GetType().ToString() );
typeLogList.Append( "], " );
}
}
#endregion
// JIRA-49 Fixes (size, precision, and scale)
if (session.DataSource.Provider.SetDbParameterSize)
{
if (((IDbDataParameter)sqlParameter).Size > 0)
{
((IDbDataParameter)parameterCopy).Size = ((IDbDataParameter)sqlParameter).Size;
}
}
if (session.DataSource.Provider.SetDbParameterPrecision)
{
((IDbDataParameter)parameterCopy).Precision = ((IDbDataParameter)sqlParameter).Precision;
}
if (session.DataSource.Provider.SetDbParameterScale)
{
((IDbDataParameter)parameterCopy).Scale = ((IDbDataParameter)sqlParameter).Scale;
}
parameterCopy.ParameterName = sqlParameter.ParameterName;
command.Parameters.Add( parameterCopy );
}
#region Logging
if (_logger.IsDebugEnabled && properties.Count>0)
{
_logger.Debug("Statement Id: [" + statement.Id + "] Parameters: [" + paramLogList.ToString(0, paramLogList.Length - 2) + "]");
_logger.Debug("Statement Id: [" + statement.Id + "] Types: [" + typeLogList.ToString(0, typeLogList.Length - 2) + "]");
}
#endregion
}
#endregion
}
}