#region Apache Notice
/*****************************************************************************
* $Revision: 575902 $
* $LastChangedDate$
* $LastChangedBy$
*
* iBATIS.NET Data Mapper
* Copyright (C) 2008/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.Collections;
using System.Collections.Generic;
using System.Data;
using Apache.Ibatis.Common.Utilities.Objects;
using Apache.Ibatis.DataMapper.Data;
using Apache.Ibatis.DataMapper.Model;
using Apache.Ibatis.DataMapper.Model.Events;
using Apache.Ibatis.DataMapper.Model.ParameterMapping;
using Apache.Ibatis.DataMapper.Model.Statements;
using Apache.Ibatis.DataMapper.MappedStatements.ResultStrategy;
using Apache.Ibatis.DataMapper.Scope;
using Apache.Ibatis.DataMapper.MappedStatements.PostSelectStrategy;
using Apache.Ibatis.DataMapper.Exceptions;
using Apache.Ibatis.DataMapper.TypeHandlers;
using Apache.Ibatis.DataMapper.Session;
using System.Diagnostics;
#endregion
namespace Apache.Ibatis.DataMapper.MappedStatements
{
///
/// Base implementation of .
///
[DebuggerDisplay("MappedStatement: {Id}")]
public partial class MappedStatement : MappedStatementEventSupport, IMappedStatement
{
///
/// Event launch on execute query
///
public event EventHandler Executed = delegate { };
#region Fields
private readonly IStatement statement = null;
private readonly IModelStore modelStore = null;
private readonly IPreparedCommand preparedCommand = null;
private readonly IResultStrategy resultStrategy = null;
#endregion
///
/// Initializes a new instance of the class.
///
/// The model store.
/// The statement.
public MappedStatement(IModelStore modelStore, IStatement statement)
{
this.modelStore = modelStore;
this.statement = statement;
preparedCommand = new DefaultPreparedCommand();
resultStrategy = ResultStrategyFactory.Get(this.statement);
}
#region properties
///
/// The IPreparedCommand to use
///
public IPreparedCommand PreparedCommand
{
get { return preparedCommand; }
}
///
/// Name used to identify the MappedStatement amongst the others.
/// This the name of the SQL statement by default.
///
public string Id
{
get { return statement.Id; }
}
///
/// The SQL statment used by this MappedStatement
///
public IStatement Statement
{
get { return statement; }
}
///
/// The used by this MappedStatement
///
/// The model store.
public IModelStore ModelStore
{
get { return modelStore; }
}
#endregion
///
/// Retrieve the output parameter and map them on the result object.
/// This routine is only use is you specified a ParameterMap and some output attribute
/// or if you use a store procedure with output parameter...
///
///
/// The current session.
/// The result object.
/// The command sql.
private static void RetrieveOutputParameters(RequestScope request, ISession session, IDbCommand command, object result)
{
if (request.ParameterMap != null && request.ParameterMap.HasOutputParameter)
{
int count = request.ParameterMap.PropertiesList.Count;
for (int i = 0; i < count; i++)
{
ParameterProperty mapping = request.ParameterMap.GetProperty(i);
if (mapping.Direction == ParameterDirection.Output ||
mapping.Direction == ParameterDirection.InputOutput)
{
string parameterName = string.Empty;
if (session.SessionFactory.DataSource.DbProvider.UseParameterPrefixInParameter == false)
{
parameterName = mapping.ColumnName;
}
else
{
parameterName = session.SessionFactory.DataSource.DbProvider.ParameterPrefix +
mapping.ColumnName;
}
if (mapping.TypeHandler == null) // Find the TypeHandler
{
lock (mapping)
{
if (mapping.TypeHandler == null)
{
Type propertyType = ObjectProbe.GetMemberTypeForGetter(result, mapping.PropertyName);
mapping.TypeHandler = request.DataExchangeFactory.TypeHandlerFactory.GetTypeHandler(propertyType);
}
}
}
// Fix IBATISNET-239
//"Normalize" System.DBNull parameters
IDataParameter dataParameter = (IDataParameter)command.Parameters[parameterName];
object dbValue = dataParameter.Value;
object value = null;
bool wasNull = (dbValue == DBNull.Value);
if (wasNull)
{
if (mapping.HasNullValue)
{
value = mapping.TypeHandler.ValueOf(mapping.GetAccessor.MemberType, mapping.NullValue);
}
else
{
value = mapping.TypeHandler.NullValue;
}
}
else
{
value = mapping.TypeHandler.GetDataBaseValue(dataParameter.Value, result.GetType());
}
request.IsRowDataFound = request.IsRowDataFound || (value != null);
request.ParameterMap.SetOutputParameter(ref result, mapping, value);
}
}
}
}
///
/// Executes the .
///
/// The current .
private static void ExecuteDelayedLoad(RequestScope request)
{
while (request.DelayedLoad.Count > 0)
{
PostBindind postSelect = request.DelayedLoad.Dequeue();
PostSelectStrategyFactory.Get(postSelect.Method).Execute(postSelect, request);
}
}
///
/// Raise an event ExecuteEventArgs
/// (Used when a query is executed)
///
private void RaiseExecuteEvent()
{
ExecuteEventArgs e = new ExecuteEventArgs();
e.StatementName = statement.Id;
Executed(this, e);
}
///
/// Ensures all the related Execute methods are run in a consistent manner with pre and post events.
///
///
protected virtual T Execute(object preEvent, object postEvent, ISession session, object parameterObject, Func requestRunner)
{
object paramPreEvent = RaisePreEvent(preEvent, parameterObject);
RequestScope request = statement.Sql.GetRequestScope(this, paramPreEvent, session);
preparedCommand.Create(request, session, Statement, paramPreEvent);
T result = requestRunner(request, paramPreEvent);
RaiseExecuteEvent();
return RaisePostEvent(postEvent, paramPreEvent, result, false);
}
}
}