#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 } }