#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;
using System.Collections;
using System.Collections.Specialized;
using System.Data;
using System.Text;
using System.Threading;
using System.Xml;
using IBatisNet.Common;
using IBatisNet.Common.Utilities;
using IBatisNet.DataMapper.Configuration;
using IBatisNet.DataMapper.Configuration.Cache;
using IBatisNet.DataMapper.Configuration.ParameterMapping;
using IBatisNet.DataMapper.Configuration.ResultMapping;
using IBatisNet.DataMapper.Exceptions;
using IBatisNet.DataMapper.MappedStatements;
using IBatisNet.DataMapper.TypeHandlers;
#endregion
namespace IBatisNet.DataMapper
{
///
/// Summary description for SqlMap.
///
public class SqlMapper
{
///
/// A delegate called once per row in the QueryWithRowDelegate method
///
/// The object currently being processed.
/// The optional parameter object passed into the QueryWithRowDelegate method.
/// The IList that will be returned to the caller.
public delegate void RowDelegate(object obj, object parameterObject, IList list);
///
/// A delegate called once per row in the QueryForMapWithRowDelegate method
///
///
///
/// The optional parameter object passed into the QueryForMapWithRowDelegate method.
/// The IDictionary that will be returned to the caller.
public delegate void DictionaryRowDelegate(object key, object value, object parameterObject, IDictionary dictionary);
#region Fields
//(MappedStatement Name, MappedStatement)
private HybridDictionary _mappedStatements = new HybridDictionary();
//(ResultMap name, ResultMap)
private HybridDictionary _resultMaps = new HybridDictionary();
//(ParameterMap name, ParameterMap)
private HybridDictionary _parameterMaps = new HybridDictionary();
// DataSource
private DataSource _dataSource = null;
//(CacheModel name, cache))
private HybridDictionary _cacheMaps = new HybridDictionary();
private TypeHandlerFactory _typeHandlerFactory = null;
private bool _cacheModelsEnabled = false;
private bool _useEmbedStatementParams = false;
// An identifiant
private string _id = string.Empty;
///
/// Container session unique for each thread.
///
private SessionHolder _sessionHolder = null;
#endregion
#region Properties
///
/// Returns the DalSession instance
/// currently being used by the SqlMap.
///
public IDalSession LocalSession
{
get { return _sessionHolder.LocalSession; }
}
///
/// Tell if the session is started.
///
///
public bool IsSessionStarted
{
get { return (_sessionHolder.LocalSession != null); }
}
///
/// A flag that determines whether cache models were enabled
/// when this SqlMap was built.
///
public bool IsCacheModelsEnabled
{
get { return _cacheModelsEnabled; }
}
///
/// A flag that determines whether statements use
/// embedded parameters.
///
public bool UseEmbedStatementParams
{
get { return _useEmbedStatementParams; }
}
///
/// The TypeHandlerFactory
///
internal TypeHandlerFactory TypeHandlerFactory
{
get { return _typeHandlerFactory; }
}
#endregion
#region Constructor (s) / Destructor
///
/// Create a new SqlMap
///
internal SqlMapper(TypeHandlerFactory typeHandlerFactory)
{
_typeHandlerFactory = typeHandlerFactory;
_id = HashCodeProvider.GetIdentityHashCode(this).ToString();
_sessionHolder = new SessionHolder(_id);
}
#endregion
#region Methods
///
/// Set the falg to tell us if cache models were enabled
/// or not.
///
internal void SetCacheModelsEnabled(bool value)
{
_cacheModelsEnabled = value;
}
///
/// Sets the flag indicating if statements should used embedded
/// parameters
///
internal void SetUseEmbedStatementParams(bool value)
{
_useEmbedStatementParams = value;
}
#region Configure
///
/// Configure an SqlMap.
///
/// An xml sql map configuration document.
/// the SqlMap
[Obsolete("This method will be remove in next version, use DomSqlMapBuilder.Configure.", false)]
static public SqlMapper Configure( XmlDocument document )
{
return new DomSqlMapBuilder().Build( document, false );
}
///
/// Configure an SqlMap from default resource file named SqlMap.config.
///
/// An SqlMap
/// The file path is relative to the application root.
[Obsolete("This method will be remove in future version, use DomSqlMapBuilder.Configure.", false)]
static public SqlMapper Configure()
{
return Configure( Resources.GetConfigAsXmlDocument(DomSqlMapBuilder.DEFAULT_FILE_CONFIG_NAME) );
}
///
/// Configure an SqlMap from via a relative ressource path.
///
///
/// A relative ressource path from your Application root
/// or an absolue file path file:\\c:\dir\a.config
///
/// An SqlMap
[Obsolete("This method will be remove in future version, use DomSqlMapBuilder.Configure.", false)]
public static SqlMapper Configure(string resource)
{
XmlDocument document = null;
if (resource.StartsWith("file://"))
{
document = Resources.GetUrlAsXmlDocument( resource.Remove(0, 7) );
}
else
{
document = Resources.GetResourceAsXmlDocument( resource );
}
return new DomSqlMapBuilder().Build( document, false);
}
///
/// Configure and monitor the default configuration file for modifications
/// and automatically reconfigure SqlMap.
///
/// An SqlMap
[Obsolete("This method will be remove in future version, use DomSqlMapBuilder.Configure.", false)]
public static SqlMapper ConfigureAndWatch(ConfigureHandler configureDelegate)
{
return ConfigureAndWatch( DomSqlMapBuilder.DEFAULT_FILE_CONFIG_NAME, configureDelegate ) ;
}
///
/// Configure and monitor the configuration file for modifications
/// and automatically reconfigure SqlMap.
///
///
/// A relative ressource path from your Application root
/// or a absolue file path file:\\c:\dir\a.config
///
///
/// Delegate called when the file has changed, to rebuild the dal.
///
/// An SqlMap
[Obsolete("This method will be remove in future version, use DomSqlMapBuilder.Configure.", false)]
public static SqlMapper ConfigureAndWatch( string resource, ConfigureHandler configureDelegate )
{
XmlDocument document = null;
if (resource.StartsWith("file://"))
{
document = Resources.GetUrlAsXmlDocument( resource.Remove(0, 7) );
}
else
{
document = Resources.GetResourceAsXmlDocument( resource );
}
ConfigWatcherHandler.ClearFilesMonitored();
ConfigWatcherHandler.AddFileToWatch( Resources.GetFileInfo( resource ) );
TimerCallback callBakDelegate = new TimerCallback( DomSqlMapBuilder.OnConfigFileChange );
StateConfig state = new StateConfig();
state.FileName = resource;
state.ConfigureHandler = configureDelegate;
new ConfigWatcherHandler( callBakDelegate, state );
return new DomSqlMapBuilder().Build( document, true );
}
#endregion
#region Manage Connection, Transaction
///
/// Open a connection
///
///
public IDalSession OpenConnection()
{
if (_sessionHolder.LocalSession != null)
{
throw new DataMapperException("SqlMap could not invoke OpenConnection(). A connection is already started. Call CloseConnection first.");
}
SqlMapSession session = new SqlMapSession(this);
_sessionHolder.Store(session);
session.OpenConnection();
return session;
}
///
/// Open a connection, on the specified connection string.
///
/// The connection string
public IDalSession OpenConnection(string connectionString)
{
if (_sessionHolder.LocalSession != null)
{
throw new DataMapperException("SqlMap could not invoke OpenConnection(). A connection is already started. Call CloseConnection first.");
}
SqlMapSession session = new SqlMapSession(this);
_sessionHolder.Store(session);
session.OpenConnection(connectionString);
return session;
}
///
/// Open a connection
///
public void CloseConnection()
{
if (_sessionHolder.LocalSession == null)
{
throw new DataMapperException("SqlMap could not invoke CloseConnection(). No connection was started. Call OpenConnection() first.");
}
try
{
IDalSession session = _sessionHolder.LocalSession;
session.CloseConnection();
}
catch(Exception ex)
{
throw new DataMapperException("SqlMapper could not CloseConnection(). Cause :"+ex.Message, ex);
}
finally
{
_sessionHolder.Dispose();
}
}
///
/// Begins a database transaction.
///
public IDalSession BeginTransaction()
{
if (_sessionHolder.LocalSession != null)
{
throw new DataMapperException("SqlMap could not invoke BeginTransaction(). A Transaction is already started. Call CommitTransaction() or RollbackTransaction first.");
}
SqlMapSession session = new SqlMapSession(this);
_sessionHolder.Store(session);
session.BeginTransaction();
return session ;
}
///
/// Open a connection and begin a transaction on the specified connection string.
///
/// The connection string
public IDalSession BeginTransaction(string connectionString)
{
if (_sessionHolder.LocalSession != null)
{
throw new DataMapperException("SqlMap could not invoke BeginTransaction(). A Transaction is already started. Call CommitTransaction() or RollbackTransaction first.");
}
SqlMapSession session = new SqlMapSession(this);
_sessionHolder.Store(session);
session.BeginTransaction( connectionString );
return session ;
}
///
/// Begins a database transaction on the currect session
///
/// Open a connection.
public IDalSession BeginTransaction(bool openConnection)
{
IDalSession session = null;
if (openConnection)
{
session = this.BeginTransaction();
}
else
{
session = _sessionHolder.LocalSession;
if (session == null)
{
throw new DataMapperException("SqlMap could not invoke BeginTransaction(). A session must be Open. Call OpenConnection() first.");
}
session.BeginTransaction(openConnection);
}
return session;
}
///
/// Begins a database transaction with the specified isolation level.
///
///
/// The isolation level under which the transaction should run.
///
public IDalSession BeginTransaction(IsolationLevel isolationLevel)
{
if (_sessionHolder.LocalSession != null)
{
throw new DataMapperException("SqlMap could not invoke BeginTransaction(). A Transaction is already started. Call CommitTransaction() or RollbackTransaction first.");
}
SqlMapSession session = new SqlMapSession(this);
_sessionHolder.Store(session);
session.BeginTransaction(isolationLevel);
return session;
}
///
/// Open a connection and begin a transaction on the specified connection string.
///
/// The connection string
/// The transaction isolation level for this connection.
public IDalSession BeginTransaction(string connectionString, IsolationLevel isolationLevel)
{
if (_sessionHolder.LocalSession != null)
{
throw new DataMapperException("SqlMap could not invoke BeginTransaction(). A Transaction is already started. Call CommitTransaction() or RollbackTransaction first.");
}
SqlMapSession session = new SqlMapSession(this);
_sessionHolder.Store(session);
session.BeginTransaction( connectionString, isolationLevel);
return session;
}
///
/// Start a database transaction on the current session
/// with the specified isolation level.
///
/// Open a connection.
///
/// The isolation level under which the transaction should run.
///
public IDalSession BeginTransaction(bool openConnection, IsolationLevel isolationLevel)
{
IDalSession session = null;
if (openConnection)
{
session = this.BeginTransaction(isolationLevel);
}
else
{
session = _sessionHolder.LocalSession;
if (session == null)
{
throw new DataMapperException("SqlMap could not invoke BeginTransaction(). A session must be Open. Call OpenConnection() first.");
}
session.BeginTransaction(openConnection, isolationLevel);
}
return session;
}
///
/// Begins a transaction on the current connection
/// with the specified IsolationLevel value.
///
/// The transaction isolation level for this connection.
/// The connection string
/// Open a connection.
public IDalSession BeginTransaction(string connectionString, bool openConnection, IsolationLevel isolationLevel)
{
IDalSession session = null;
if (openConnection)
{
session = this.BeginTransaction(connectionString, isolationLevel);
}
else
{
session = _sessionHolder.LocalSession;
if (session == null)
{
throw new DataMapperException("SqlMap could not invoke BeginTransaction(). A session must be Open. Call OpenConnection() first.");
}
session.BeginTransaction(connectionString, openConnection, isolationLevel);
}
return session;
}
///
/// Commits the database transaction.
///
///
/// Will close the connection.
///
public void CommitTransaction()
{
if (_sessionHolder.LocalSession == null)
{
throw new DataMapperException("SqlMap could not invoke CommitTransaction(). No Transaction was started. Call BeginTransaction() first.");
}
try
{
IDalSession session = _sessionHolder.LocalSession;
session.CommitTransaction();
}
finally
{
_sessionHolder.Dispose();
}
}
///
/// Commits the database transaction.
///
/// Close the connection
public void CommitTransaction(bool closeConnection)
{
if (_sessionHolder.LocalSession == null)
{
throw new DataMapperException("SqlMap could not invoke CommitTransaction(). No Transaction was started. Call BeginTransaction() first.");
}
try
{
IDalSession session = _sessionHolder.LocalSession;
session.CommitTransaction(closeConnection);
}
finally
{
if (closeConnection)
{
_sessionHolder.Dispose();
}
}
}
///
/// Rolls back a transaction from a pending state.
///
///
/// Will close the connection.
///
public void RollBackTransaction()
{
if (_sessionHolder.LocalSession == null)
{
throw new DataMapperException("SqlMap could not invoke RollBackTransaction(). No Transaction was started. Call BeginTransaction() first.");
}
try
{
IDalSession session = _sessionHolder.LocalSession;
session.RollBackTransaction();
}
finally
{
_sessionHolder.Dispose();
}
}
///
/// Rolls back a transaction from a pending state.
///
/// Close the connection
public void RollBackTransaction(bool closeConnection)
{
if (_sessionHolder.LocalSession == null)
{
throw new DataMapperException("SqlMap could not invoke RollBackTransaction(). No Transaction was started. Call BeginTransaction() first.");
}
try
{
IDalSession session = _sessionHolder.LocalSession;
session.RollBackTransaction(closeConnection);
}
finally
{
if (closeConnection)
{
_sessionHolder.Dispose();
}
}
}
#endregion
#region QueryForObject
///
/// Executes a Sql SELECT statement that returns that returns data
/// to populate a single object instance.
///
/// The parameter object is generally used to supply the input
/// data for the WHERE clause parameter(s) of the SELECT statement.
///
/// The name of the sql statement to execute.
/// The object used to set the parameters in the SQL.
/// The single result object populated with the result set data.
public object QueryForObject(string statementName, object parameterObject)
{
bool isSessionLocal = false;
IDalSession session = _sessionHolder.LocalSession;
object result;
if (session == null)
{
session = new SqlMapSession(this.DataSource);
session.OpenConnection();
isSessionLocal = true;
}
IMappedStatement statement = GetMappedStatement(statementName);
try
{
result = statement.ExecuteQueryForObject(session, parameterObject);
}
catch
{
throw;
}
finally
{
if ( isSessionLocal )
{
session.CloseConnection();
}
}
return result;
}
///
/// Executes a Sql SELECT statement that returns a single object of the type of the
/// resultObject parameter.
///
/// The name of the sql statement to execute.
/// The object used to set the parameters in the SQL.
/// An object of the type to be returned.
/// The single result object populated with the result set data.
public object QueryForObject(string statementName, object parameterObject, object resultObject)
{
bool isSessionLocal = false;
IDalSession session = _sessionHolder.LocalSession;
object result = null;
if (session == null)
{
session = new SqlMapSession(this.DataSource);
session.OpenConnection();
isSessionLocal = true;
}
IMappedStatement statement = GetMappedStatement(statementName);
try
{
result = statement.ExecuteQueryForObject(session, parameterObject, resultObject);
}
catch
{
throw;
}
finally
{
if ( isSessionLocal )
{
session.CloseConnection();
}
}
return result;
}
#endregion
#region QueryForMap, QueryForDictionary
///
/// Alias to QueryForMap, .NET spirit.
/// Feature idea by Ted Husted.
///
/// The name of the sql statement to execute.
/// The object used to set the parameters in the SQL.
/// The property of the result object to be used as the key.
/// A IDictionary (Hashtable) of object containing the rows keyed by keyProperty.
public IDictionary QueryForDictionary(string statementName, object parameterObject, string keyProperty)
{
return QueryForMap( statementName, parameterObject, keyProperty);
}
///
/// Alias to QueryForMap, .NET spirit.
/// Feature idea by Ted Husted.
///
/// The name of the sql statement to execute.
/// 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 IDictionary (Hashtable) of object containing the rows keyed by keyProperty.
///If a transaction is not in progress, or the database throws an exception.
public IDictionary QueryForDictionary(string statementName, object parameterObject, string keyProperty, string valueProperty)
{
return QueryForMap( statementName, parameterObject, keyProperty, valueProperty);
}
///
/// 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 entire result object.
///
/// The name of the sql statement to execute.
/// The object used to set the parameters in the SQL.
/// The property of the result object to be used as the key.
/// A IDictionary (Hashtable) of object containing the rows keyed by keyProperty.
public IDictionary QueryForMap(string statementName, object parameterObject, string keyProperty)
{
return QueryForMap(statementName, parameterObject, keyProperty, null);
}
///
/// 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 name of the sql statement to execute.
/// 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 IDictionary (Hashtable) of object containing the rows keyed by keyProperty.
///If a transaction is not in progress, or the database throws an exception.
public IDictionary QueryForMap(string statementName, object parameterObject, string keyProperty, string valueProperty)
{
bool isSessionLocal = false;
IDalSession session = _sessionHolder.LocalSession;
IDictionary map = null;
if (session == null)
{
session = new SqlMapSession(this.DataSource);
session.OpenConnection();
isSessionLocal = true;
}
IMappedStatement statement = GetMappedStatement(statementName);
try
{
map = statement.ExecuteQueryForMap(session, parameterObject, keyProperty, valueProperty);
}
catch
{
throw;
}
finally
{
if ( isSessionLocal )
{
session.CloseConnection();
}
}
return map;
}
#endregion
#region QueryForList
///
/// Executes a Sql SELECT statement that returns data to populate
/// a number of result objects.
///
/// The parameter object is generally used to supply the input
/// data for the WHERE clause parameter(s) of the SELECT statement.
///
/// The name of the sql statement to execute.
/// The object used to set the parameters in the SQL.
/// A List of result objects.
public IList QueryForList(string statementName, object parameterObject)
{
bool isSessionLocal = false;
IDalSession session = _sessionHolder.LocalSession;
IList list;
if (session == null)
{
session = new SqlMapSession(this.DataSource);
session.OpenConnection();
isSessionLocal = true;
}
IMappedStatement statement = GetMappedStatement(statementName);
try
{
list = statement.ExecuteQueryForList(session, parameterObject);
}
catch
{
throw;
}
finally
{
if ( isSessionLocal )
{
session.CloseConnection();
}
}
return list;
}
///
/// Executes the SQL and retuns all rows selected.
///
/// The parameter object is generally used to supply the input
/// data for the WHERE clause parameter(s) of the SELECT statement.
///
/// The name of the sql statement to execute.
/// 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 QueryForList(string statementName, object parameterObject, int skipResults, int maxResults)
{
bool isSessionLocal = false;
IDalSession session = _sessionHolder.LocalSession;
IList list;
if (session == null)
{
session = new SqlMapSession(this.DataSource);
session.OpenConnection();
isSessionLocal = true;
}
IMappedStatement statement = GetMappedStatement(statementName);
try
{
list = statement.ExecuteQueryForList(session, parameterObject, skipResults, maxResults);
}
catch
{
throw;
}
finally
{
if ( isSessionLocal )
{
session.CloseConnection();
}
}
return list;
}
///
/// Executes a Sql SELECT statement that returns data to populate
/// a number of result objects.
///
/// The parameter object is generally used to supply the input
/// data for the WHERE clause parameter(s) of the SELECT statement.
///
/// The name of the sql statement to execute.
/// The object used to set the parameters in the SQL.
/// An Ilist object used to hold the objects.
/// A List of result objects.
public void QueryForList(string statementName, object parameterObject, IList resultObject)
{
bool isSessionLocal = false;
IDalSession session = _sessionHolder.LocalSession;
if (resultObject == null)
{
throw new DataMapperException("resultObject parameter must be instantiated before being passed to SqlMapper.QueryForList");
}
if (session == null)
{
session = new SqlMapSession(this.DataSource);
session.OpenConnection();
isSessionLocal = true;
}
IMappedStatement statement = GetMappedStatement(statementName);
try
{
statement.ExecuteQueryForList(session, parameterObject, resultObject);
}
catch
{
throw;
}
finally
{
if ( isSessionLocal )
{
session.CloseConnection();
}
}
}
#endregion
#region QueryForPaginatedList
///
/// Executes the SQL and retuns a subset of the results in a dynamic PaginatedList that can be used to
/// automatically scroll through results from a database table.
///
/// The name of the sql statement to execute.
/// The object used to set the parameters in the SQL
/// The maximum number of objects to store in each page
/// A PaginatedList of beans containing the rows
public PaginatedList QueryForPaginatedList(String statementName, object parameterObject, int pageSize)
{
IMappedStatement statement = GetMappedStatement(statementName);
return new PaginatedList(statement, parameterObject, pageSize);
}
#endregion
#region QueryWithRowDelegate
///
/// Runs a query for list with a custom object that gets a chance to deal
/// with each row as it is processed.
///
/// The parameter object is generally used to supply the input
/// data for the WHERE clause parameter(s) of the SELECT statement.
///
/// The name of the sql statement to execute.
/// The object used to set the parameters in the SQL.
///
/// A List of result objects.
public IList QueryWithRowDelegate(string statementName, object parameterObject, RowDelegate rowDelegate)
{
bool isSessionLocal = false;
IDalSession session = _sessionHolder.LocalSession;
IList list = null;
if (session == null)
{
session = new SqlMapSession(this.DataSource);
session.OpenConnection();
isSessionLocal = true;
}
IMappedStatement statement = GetMappedStatement(statementName);
try
{
list = statement.ExecuteQueryForRowDelegate(session, parameterObject, rowDelegate);
}
catch
{
throw;
}
finally
{
if ( isSessionLocal )
{
session.CloseConnection();
}
}
return list;
}
///
/// Runs a query with a custom object that gets a chance to deal
/// with each row as it is processed.
///
/// The parameter object is generally used to supply the input
/// data for the WHERE clause parameter(s) of the SELECT statement.
///
/// The name of the sql statement to execute.
/// 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 IDictionary (Hashtable) of object containing the rows keyed by keyProperty.
///If a transaction is not in progress, or the database throws an exception.
public IDictionary QueryForMapWithRowDelegate(string statementName, object parameterObject, string keyProperty, string valueProperty, DictionaryRowDelegate rowDelegate)
{
bool isSessionLocal = false;
IDalSession session = _sessionHolder.LocalSession;
IDictionary map = null;
if (session == null)
{
session = new SqlMapSession(this.DataSource);
session.OpenConnection();
isSessionLocal = true;
}
IMappedStatement statement = GetMappedStatement(statementName);
try
{
map = statement.ExecuteQueryForMapWithRowDelegate(session, parameterObject, keyProperty, valueProperty, rowDelegate);
}
catch
{
throw;
}
finally
{
if ( isSessionLocal )
{
session.CloseConnection();
}
}
return map;
}
#endregion
#region Query Insert, Update, Delete
///
/// Executes a Sql INSERT statement.
/// Insert is a bit different from other update methods, as it
/// provides facilities for returning the primary key of the
/// newly inserted row (rather than the effected rows). This
/// functionality is of course optional.
///
/// The parameter object is generally used to supply the input
/// data for the INSERT values.
///
/// The name of the statement to execute.
/// The parameter object.
/// The primary key of the newly inserted row.
/// This might be automatically generated by the RDBMS,
/// or selected from a sequence table or other source.
///
public object Insert(string statementName, object parameterObject)
{
bool isSessionLocal = false;
IDalSession session = _sessionHolder.LocalSession;
object generatedKey = null;
if (session == null)
{
session = new SqlMapSession(this.DataSource);
session.OpenConnection();
isSessionLocal = true;
}
IMappedStatement statement = GetMappedStatement(statementName);
try
{
generatedKey = statement.ExecuteInsert(session, parameterObject);
}
catch
{
throw;
}
finally
{
if ( isSessionLocal )
{
session.CloseConnection();
}
}
return generatedKey;
}
///
/// Executes a Sql UPDATE statement.
/// Update can also be used for any other update statement type,
/// such as inserts and deletes. Update returns the number of
/// rows effected.
///
/// The parameter object is generally used to supply the input
/// data for the UPDATE values as well as the WHERE clause parameter(s).
///
/// The name of the statement to execute.
/// The parameter object.
/// The number of rows effected.
// ///
// /// If no rows are effected throw this exception.
// ///
public int Update(string statementName, object parameterObject)
{
bool isSessionLocal = false;
IDalSession session = _sessionHolder.LocalSession;
int rows = 0; // the number of rows affected
if (session == null)
{
session = new SqlMapSession(this.DataSource);
session.OpenConnection();
isSessionLocal = true;
}
IMappedStatement statement = GetMappedStatement(statementName);
try
{
rows = statement.ExecuteUpdate(session, parameterObject);
}
catch
{
throw;
}
finally
{
if ( isSessionLocal )
{
session.CloseConnection();
}
}
// // check that statement affected a row
// if( rows == 0 )
// {
// // throw concurrency error if no record was affected
// throw new ConcurrentException();
// }
return rows;
}
///
/// Executes a Sql DELETE statement.
/// Delete returns the number of rows effected.
///
/// The name of the statement to execute.
/// The parameter object.
/// The number of rows effected.
public int Delete(string statementName, object parameterObject)
{
bool isSessionLocal = false;
IDalSession session = _sessionHolder.LocalSession;
int rows = 0; // the number of rows affected
if (session == null)
{
session = new SqlMapSession(this.DataSource);
session.OpenConnection();
isSessionLocal = true;
}
IMappedStatement statement = GetMappedStatement(statementName);
try
{
rows = statement.ExecuteUpdate(session, parameterObject);
}
catch
{
throw;
}
finally
{
if ( isSessionLocal )
{
session.CloseConnection();
}
}
return rows;
}
#endregion
#region Get/Add ParemeterMap, ResultMap, MappedStatement, TypeAlias, DataSource, CacheModel
///
/// Gets a MappedStatement by name
///
/// The name of the statement
/// The MappedStatement
public IMappedStatement GetMappedStatement(string name)
{
if (_mappedStatements.Contains(name) == false)
{
throw new DataMapperException("This SQL map does not contain a MappedStatement named " + name);
}
return (IMappedStatement) _mappedStatements[name];
}
///
/// Adds a (named) MappedStatement.
///
/// The key name
/// The statement to add
internal void AddMappedStatement(string key, IMappedStatement mappedStatement)
{
if (_mappedStatements.Contains(key) == true)
{
throw new DataMapperException("This SQL map already contains a MappedStatement named " + mappedStatement.Id);
}
_mappedStatements.Add(key, mappedStatement);
}
///
/// The MappedStatements collection
///
internal HybridDictionary MappedStatements
{
get { return _mappedStatements; }
}
///
/// Get a ParameterMap by name
///
/// The name of the ParameterMap
/// The ParameterMap
internal ParameterMap GetParameterMap(string name)
{
if (!_parameterMaps.Contains(name))
{
throw new DataMapperException("This SQL map does not contain an ParameterMap named " + name + ". ");
}
return (ParameterMap) _parameterMaps[name];
}
///
/// Adds a (named) ParameterMap.
///
/// the ParameterMap to add
internal void AddParameterMap(ParameterMap parameterMap)
{
if (_parameterMaps.Contains(parameterMap.Id) == true)
{
throw new DataMapperException("This SQL map already contains an ParameterMap named " + parameterMap.Id);
}
_parameterMaps.Add(parameterMap.Id, parameterMap);
}
///
/// Gets a ResultMap by name
///
/// The name of the result map
/// The ResultMap
internal ResultMap GetResultMap(string name)
{
if (_resultMaps.Contains(name) == false)
{
throw new DataMapperException("This SQL map does not contain an ResultMap named " + name);
}
return (ResultMap) _resultMaps[name];
}
///
/// Adds a (named) ResultMap
///
/// The ResultMap to add
internal void AddResultMap(ResultMap resultMap)
{
if (_resultMaps.Contains(resultMap.Id) == true)
{
throw new DataMapperException("This SQL map already contains an ResultMap named " + resultMap.Id);
}
_resultMaps.Add(resultMap.Id, resultMap);
}
///
/// The ParameterMap collection
///
internal HybridDictionary ParameterMaps
{
get { return _parameterMaps; }
}
///
/// The ResultMap collection
///
internal HybridDictionary ResultMaps
{
get { return _resultMaps; }
}
///
/// The DataSource
///
public DataSource DataSource
{
get { return _dataSource; }
set { _dataSource = value; }
}
///
/// Flushes all cached objects that belong to this SqlMap
///
public void FlushCaches()
{
IDictionaryEnumerator enumerator = _cacheMaps.GetEnumerator();
while (enumerator.MoveNext())
{
((CacheModel)enumerator.Value).Flush();
}
}
///
/// Adds a (named) cache.
///
/// The cache to add
internal void AddCache(CacheModel cache)
{
if (_cacheMaps.Contains(cache.Id))
{
throw new DataMapperException("This SQL map already contains an Cache named " + cache.Id);
}
_cacheMaps.Add(cache.Id, cache);
}
///
/// Gets a cache by name
///
/// The name of the cache to get
/// The cache object
internal CacheModel GetCache(string name)
{
if (!_cacheMaps.Contains(name))
{
throw new DataMapperException("This SQL map does not contain an Cache named " + name);
}
return (CacheModel) _cacheMaps[name];
}
///
///
///
///
public string GetDataCacheStats()
{
StringBuilder buffer = new StringBuilder();
buffer.Append(Environment.NewLine);
buffer.Append("Cache Data Statistics");
buffer.Append(Environment.NewLine);
buffer.Append("=====================");
buffer.Append(Environment.NewLine);
IDictionaryEnumerator enumerator = _mappedStatements.GetEnumerator();
while (enumerator.MoveNext())
{
IMappedStatement mappedStatement = (IMappedStatement)enumerator.Value;
buffer.Append(mappedStatement.Id);
buffer.Append(": ");
if (mappedStatement is CachingStatement)
{
double hitRatio = ((CachingStatement)mappedStatement).GetDataCacheHitRatio();
if (hitRatio != -1)
{
buffer.Append(Math.Round(hitRatio * 100));
buffer.Append("%");
}
else
{
// this statement has a cache but it hasn't been accessed yet
// buffer.Append("Cache has not been accessed."); ???
buffer.Append("No Cache.");
}
}
else
{
buffer.Append("No Cache.");
}
buffer.Append(Environment.NewLine);
}
return buffer.ToString();
}
#endregion
#endregion
}
}