#region Apache Notice
/*****************************************************************************
* $Header: $
* $Revision: $
* $Date: $
*
* iBATIS.NET Data Mapper
* Copyright (C) 2004 - 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.Collections;
using IBatisNet.Common;
using IBatisNet.DataMapper.Commands;
using IBatisNet.DataMapper.Configuration.Cache;
using IBatisNet.DataMapper.Configuration.Statements;
using IBatisNet.DataMapper.Scope;
using IBatisNet.DataMapper.MappedStatements;
#endregion
namespace IBatisNet.DataMapper.MappedStatements
{
///
/// Summary description for CachingStatement.
///
public class CachingStatement : IMappedStatement
{
private MappedStatement _mappedStatement =null;
///
/// Event launch on exceute query
///
public event ExecuteEventHandler Execute;
///
/// Constructor
///
///
public CachingStatement(MappedStatement statement)
{
_mappedStatement = statement;
}
///
/// Gets a percentage of successful cache hits achieved
///
/// The percentage of hits (0-1), or -1 if cache is disabled.
public double GetDataCacheHitRatio()
{
if (_mappedStatement.Statement.CacheModel != null)
{
return _mappedStatement.Statement.CacheModel.HitRatio;
}
else
{
return -1;
}
}
#region IMappedStatement Members
///
/// The IPreparedCommand to use
///
public IPreparedCommand PreparedCommand
{
get { return _mappedStatement.PreparedCommand; }
}
///
/// Name used to identify the MappedStatement amongst the others.
/// This the name of the SQL statment by default.
///
public string Name
{
get { return _mappedStatement.Name; }
}
///
/// The SQL statment used by this MappedStatement
///
public IStatement Statement
{
get { return _mappedStatement.Statement; }
}
///
/// The SqlMap used by this MappedStatement
///
public SqlMapper SqlMap
{
get {return _mappedStatement.SqlMap; }
}
///
/// Executes the SQL and retuns all rows selected in a map that is keyed on the property named
/// in the keyProperty parameter. The value at each key will be the value of the property specified
/// in the valueProperty parameter. If valueProperty is null, the entire result object will be entered.
///
/// The session used to execute the statement
/// The object used to set the parameters in the SQL.
/// The property of the result object to be used as the key.
/// The property of the result object to be used as the value (or null)
/// A hashtable of object containing the rows keyed by keyProperty.
///If a transaction is not in progress, or the database throws an exception.
public IDictionary ExecuteQueryForMap(IDalSession session, object parameterObject, string keyProperty, string valueProperty)
{
IDictionary map = new Hashtable();
RequestScope request = this.Statement.Sql.GetRequestScope(parameterObject, session);;
CacheKey key = null;
if (this.Statement.ParameterMap != null)
{
key = new CacheKey(this.SqlMap.TypeHandlerFactory, this.Name,
request.PreparedStatement.PreparedSql,
parameterObject,
request.ParameterMap.GetPropertyNameArray(),
MappedStatement.NO_SKIPPED_RESULTS,
MappedStatement.NO_MAXIMUM_RESULTS,
CacheKeyType.Map);
}
else
{
key = new CacheKey(this.SqlMap.TypeHandlerFactory, this.Name,
request.PreparedStatement.PreparedSql,
parameterObject,
new string[0],
MappedStatement.NO_SKIPPED_RESULTS,
MappedStatement.NO_MAXIMUM_RESULTS,
CacheKeyType.Map);
}
map = (IDictionary)this.Statement.CacheModel[key];
if (map == null)
{
map = _mappedStatement.RunQueryForMap( request, session, parameterObject, keyProperty, valueProperty, null );
this.Statement.CacheModel[key] = map;
}
return map;
}
///
/// Execute an update statement. Also used for delete statement.
/// Return the number of row effected.
///
/// The session used to execute the statement.
/// The object used to set the parameters in the SQL.
/// The number of row effected.
public int ExecuteUpdate(IDalSession session, object parameterObject)
{
return _mappedStatement.ExecuteUpdate(session, parameterObject);
}
///
/// Execute an insert statement. Fill the parameter object with
/// the ouput parameters if any, also could return the insert generated key
///
/// The session
/// The parameter object used to fill the statement.
/// Can return the insert generated key.
public object ExecuteInsert(IDalSession session, object parameterObject)
{
return _mappedStatement.ExecuteInsert(session, parameterObject);
}
///
/// Executes the SQL and and fill a strongly typed collection.
///
/// The session used to execute the statement.
/// The object used to set the parameters in the SQL.
/// A strongly typed collection of result objects.
public void ExecuteQueryForList(IDalSession session, object parameterObject, IList resultObject)
{
_mappedStatement.ExecuteQueryForList(session, parameterObject, resultObject);
}
///
/// Executes the SQL and retuns a subset of the rows selected.
///
/// The session used to execute the statement.
/// The object used to set the parameters in the SQL.
/// The number of rows to skip over.
/// The maximum number of rows to return.
/// A List of result objects.
public IList ExecuteQueryForList(IDalSession session, object parameterObject, int skipResults, int maxResults)
{
IList list = null;
RequestScope request = this.Statement.Sql.GetRequestScope(parameterObject, session);;
CacheKey key = null;
if (this.Statement.ParameterMap != null)
{
key = new CacheKey(this.SqlMap.TypeHandlerFactory, this.Name,
request.PreparedStatement.PreparedSql,
parameterObject,
request.ParameterMap.GetPropertyNameArray(),
skipResults,
maxResults,
CacheKeyType.List);
}
else
{
key = new CacheKey(this.SqlMap.TypeHandlerFactory, this.Name,
request.PreparedStatement.PreparedSql,
parameterObject,
new string[0],
skipResults,
maxResults,
CacheKeyType.List);
}
list = (IList)this.Statement.CacheModel[key];
if (list == null)
{
list = _mappedStatement.RunQueryForList(request, session, parameterObject, skipResults, maxResults, null);
this.Statement.CacheModel[key] = list;
}
return list;
}
///
/// Executes the SQL and retuns all rows selected. This is exactly the same as
/// calling ExecuteQueryForList(session, parameterObject, NO_SKIPPED_RESULTS, NO_MAXIMUM_RESULTS).
///
/// The session used to execute the statement.
/// The object used to set the parameters in the SQL.
/// A List of result objects.
public IList ExecuteQueryForList(IDalSession session, object parameterObject)
{
return this.ExecuteQueryForList( session, parameterObject, MappedStatement.NO_SKIPPED_RESULTS, MappedStatement.NO_MAXIMUM_RESULTS);
}
///
/// Executes an SQL statement that returns a single row as an Object.
///
/// The session used to execute the statement.
/// The object used to set the parameters in the SQL.
/// The object
public object ExecuteQueryForObject(IDalSession session, object parameterObject)
{
return this.ExecuteQueryForObject(session, parameterObject, null);
}
///
/// Executes an SQL statement that returns a single row as an Object of the type of
/// the resultObject passed in as a parameter.
///
/// The session used to execute the statement.
/// The object used to set the parameters in the SQL.
/// The result object.
/// The object
public object ExecuteQueryForObject(IDalSession session, object parameterObject, object resultObject)
{
object obj = null;
RequestScope request = this.Statement.Sql.GetRequestScope(parameterObject, session);;
CacheKey key = null;
if (this.Statement.ParameterMap != null)
{
key = new CacheKey(this.SqlMap.TypeHandlerFactory, this.Name,
request.PreparedStatement.PreparedSql,
parameterObject,
request.ParameterMap.GetPropertyNameArray(),
MappedStatement.NO_SKIPPED_RESULTS,
MappedStatement.NO_MAXIMUM_RESULTS,
CacheKeyType.Object);
}
else
{
key = new CacheKey(this.SqlMap.TypeHandlerFactory, this.Name,
request.PreparedStatement.PreparedSql,
parameterObject,
new string[0],
MappedStatement.NO_SKIPPED_RESULTS,
MappedStatement.NO_MAXIMUM_RESULTS,
CacheKeyType.Object);
}
obj = this.Statement.CacheModel[key];
// check if this query has alreay been run
if (obj == CacheModel.NULL_OBJECT)
{
// convert the marker object back into a null value
obj = null;
}
else if (obj == null)
{
obj = _mappedStatement.RunQueryForObject(request, session, parameterObject, resultObject);
this.Statement.CacheModel[key] = obj;
}
return obj;
}
///
/// Runs a query with a custom object that gets a chance
/// to deal with each row as it is processed.
///
/// The session used to execute the statement.
/// The object used to set the parameters in the SQL.
///
public IList ExecuteQueryForRowDelegate(IDalSession session, object parameterObject, SqlMapper.RowDelegate rowDelegate)
{
return _mappedStatement.ExecuteQueryForRowDelegate(session, parameterObject, rowDelegate);
}
///
/// Runs a query with a custom object that gets a chance
/// to deal with each row as it is processed.
///
/// The session used to execute the statement
/// The object used to set the parameters in the SQL.
/// The property of the result object to be used as the key.
/// The property of the result object to be used as the value (or null)
///
/// A hashtable of object containing the rows keyed by keyProperty.
/// If a transaction is not in progress, or the database throws an exception.
public IDictionary ExecuteQueryForMapWithRowDelegate(IDalSession session, object parameterObject, string keyProperty, string valueProperty, SqlMapper.DictionaryRowDelegate rowDelegate)
{
return _mappedStatement.ExecuteQueryForMapWithRowDelegate(session, parameterObject, keyProperty, valueProperty, rowDelegate);
}
#endregion
}
}