diff --git a/src/Spring/Spring.Data/Data/Common/MultiDelegatingDbProvider.cs b/src/Spring/Spring.Data/Data/Common/MultiDelegatingDbProvider.cs
index 83620328..7221d873 100644
--- a/src/Spring/Spring.Data/Data/Common/MultiDelegatingDbProvider.cs
+++ b/src/Spring/Spring.Data/Data/Common/MultiDelegatingDbProvider.cs
@@ -1,268 +1,283 @@
-#region Licence
-
-/*
- * Copyright © 2002-2007 the original author or authors.
- *
- * 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
-
-using System;
-using System.Collections;
-using System.Data;
-using Spring.Collections;
-using Spring.Dao;
-using Spring.Data.Common;
-using Spring.Objects.Factory;
-using Spring.Threading;
-
-
-namespace Spring.Data
-{
- ///
- /// A wrapper implementation for IDbProvider such that multiple DbProvider instances can be
- /// selected at runtime, say based on web request criteria.
- ///
- ///
- /// The name of which DbProvider to use, as provided to the IDictionary property TargetDbProviders
+#region Licence
+
+/*
+ * Copyright © 2002-2007 the original author or authors.
+ *
+ * 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
+
+using System;
+using System.Collections;
+using System.Data;
+using Spring.Collections;
+using Spring.Dao;
+using Spring.Data.Common;
+using Spring.Objects.Factory;
+using Spring.Threading;
+
+
+namespace Spring.Data
+{
+ ///
+ /// A wrapper implementation for IDbProvider such that multiple DbProvider instances can be
+ /// selected at runtime, say based on web request criteria.
+ ///
+ ///
+ /// The name of which DbProvider to use, as provided to the IDictionary property TargetDbProviders
/// is "dbProviderName". Once the target dbprovider name is known, set the name via a call to
- /// LogicalThreadContext.SetData(MultiDelegatingDbProvider.CURRENT_DBPROVIDER_SLOTNAME, "database1ProviderName"). The value
- /// "database1ProviderName" must match a key in the provided TargetDbProviders dictionary.
- ///
- /// Mark Pollack
- public class MultiDelegatingDbProvider : IDbProvider, IInitializingObject
+ /// LogicalThreadContext.SetData(MultiDelegatingDbProvider.CURRENT_DBPROVIDER_SLOTNAME, "database1ProviderName"). The value
+ /// "database1ProviderName" must match a key in the provided TargetDbProviders dictionary.
+ ///
+ /// Mark Pollack
+ public class MultiDelegatingDbProvider : IDbProvider, IInitializingObject
{
- private static readonly string CURRENT_DBPROVIDER_SLOTNAME = Spring.Util.UniqueKey.GetTypeScopedString(typeof(MultiDelegatingDbProvider), "Current");
-
- private IDictionary targetDbProviders = new SynchronizedHashtable();
-
- #region Constructors
- ///
- /// Initializes a new instance of the class.
- ///
- public MultiDelegatingDbProvider()
- {
-
- }
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The target db providers.
- public MultiDelegatingDbProvider(IDictionary targetDbProviders)
- {
- this.targetDbProviders = targetDbProviders;
- }
-
- #endregion
-
- ///
- /// Sets the target db providers.
- ///
- /// The target db providers.
- public IDictionary TargetDbProviders
- {
- set { targetDbProviders = value; }
- }
-
- ///
- /// Ensures that the there are values in the TargetDbProviders dictionary and that the
- /// key is of the type string and value is of the type IDbProvider.
- ///
- /// If the above conditions are not met.
- public void AfterPropertiesSet()
- {
- if (targetDbProviders.Count == 0)
- {
- throw new ArgumentException("Target DbProvider collection required.");
- }
- foreach (DictionaryEntry entry in targetDbProviders)
- {
- if (! entry.Key.GetType().Equals(typeof(string)))
- {
- throw new ArgumentException("Key identifying target IDbProvider in TargetDbProviders dictionary property is required to be of type string. Key = " + entry.Key);
- }
- IDbProvider targetProvider = entry.Value as IDbProvider;
- if (targetProvider == null)
- {
- throw new ArgumentException("Value in TargetDbProviders dictionary is not of type IDbProvider.");
- }
- }
- }
-
- #region IDbProvider methods
-
-
- ///
- /// Returns a new command object for executing SQL statments/Stored Procedures
- /// against the database.
- ///
- /// An new
- public IDbCommand CreateCommand()
- {
- return GetTargetProvider().CreateCommand();
- }
-
- ///
- /// Returns a new connection object to communicate with the database.
- ///
- /// A new
- public IDbConnection CreateConnection()
- {
- return GetTargetProvider().CreateConnection();
- }
-
- ///
- /// Returns a new parameter object for binding values to parameter
- /// placeholders in SQL statements or Stored Procedure variables.
- ///
- /// A new
- public IDbDataParameter CreateParameter()
- {
- return GetTargetProvider().CreateParameter();
- }
-
- ///
- /// Returns a new adapter objects for use with offline DataSets.
- ///
- /// A new
- public IDbDataAdapter CreateDataAdapter()
- {
- return GetTargetProvider().CreateDataAdapter();
- }
-
- ///
- /// Returns a new instance of the providers CommandBuilder class.
- ///
- /// A new Command Builder
- /// In .NET 1.1 there was no common base class or interface
- /// for command builders, hence the return signature is object to
- /// be portable (but more loosely typed) across .NET 1.1/2.0
- public object CreateCommandBuilder()
- {
- return GetTargetProvider().CreateDataAdapter();
- }
-
- ///
- /// Creates the name of the parameter in the format appropriate to use inside IDbCommand.CommandText.
- ///
- /// The unformatted name of the parameter.
- ///
- /// The parameter name formatted foran IDbCommand.CommandText.
- ///
- /// In most cases this adds the parameter prefix to the name passed into this method.
- public string CreateParameterName(string name)
- {
- return GetTargetProvider().CreateParameterName(name);
- }
-
-
- ///
- /// Creates the name ofthe parameter in the format appropriate for an IDataParameter, i.e. to be
- /// part of a IDataParameterCollection.
- ///
- /// The unformatted name of the parameter.
- ///
- /// The parameter name formatted for an IDataParameter
- ///
- public string CreateParameterNameForCollection(string name)
- {
- return GetTargetProvider().CreateParameterNameForCollection(name);
- }
-
- ///
- /// Return metadata information about the database provider
- ///
- ///
- public IDbMetadata DbMetadata
- {
- get { return GetTargetProvider().DbMetadata; }
- }
-
- ///
- /// Connection string used to create connections.
- ///
- ///
- public string ConnectionString
- {
- get { return GetTargetProvider().ConnectionString; }
- set { GetTargetProvider().ConnectionString = value; }
- }
-
- ///
- /// Extracts the provider specific error code as a string.
- ///
- /// The data access exception.
- /// The provider specific error code
- public string ExtractError(Exception e)
- {
- return GetTargetProvider().ExtractError(e);
- }
-
- ///
- /// Determines whether the provided exception is in fact related
- /// to database access. This can be provider dependent in .NET 1.1 since
- /// there isn't a common base class for ADO.NET exceptions.
- ///
- /// The exception thrown when performing data access
- /// operations.
- ///
- /// true if is a valid data access exception for the specified
- /// exception; otherwise, false.
- ///
- public bool IsDataAccessException(Exception e)
- {
-#if NET_2_0
- if (e is System.Data.Common.DbException)
- {
- return true;
- }
- else
- {
- return false;
- }
-#else
- return IsDataAccessExceptionBCL11(e);
-#endif
- }
-
- ///
- /// Determines whether is data access exception in .NET 1.1 for the specified exception.
- ///
- /// The candidate exception.
- ///
- /// true if is data access exception in .NET 1.1 for the specified exception; otherwise, false.
- ///
- public bool IsDataAccessExceptionBCL11(Exception e)
- {
- return false;
- }
- #endregion
-
- ///
- /// Gets the target provider based on the thread local name "dbProviderName"
- ///
- /// The corresonding IDbProvider.
- protected virtual IDbProvider GetTargetProvider()
+ private static readonly string CURRENT_DBPROVIDER_SLOTNAME = Spring.Util.UniqueKey.GetTypeScopedString(typeof(MultiDelegatingDbProvider), "Current");
+
+ private IDbProvider defaultDbProvider;
+
+ private IDictionary targetDbProviders = new SynchronizedHashtable();
+
+ #region Constructors
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public MultiDelegatingDbProvider()
{
- string dbProviderName = (string)LogicalThreadContext.GetData(CURRENT_DBPROVIDER_SLOTNAME);
- if (targetDbProviders.Contains(dbProviderName))
- {
- return (IDbProvider)targetDbProviders[dbProviderName];
- }
- throw new InvalidDataAccessApiUsageException("'" + dbProviderName + "'"
- + "was not under the thread local key 'dbProviderName'");
+
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The target db providers.
+ public MultiDelegatingDbProvider(IDictionary targetDbProviders)
+ {
+ this.targetDbProviders = targetDbProviders;
+ }
+
+ #endregion
+
+ ///
+ /// Sets the default IDbProvider. This will be returned if no DbProvider is found in thread local storage.
+ ///
+ /// The default db provider.
+ public IDbProvider DefaultDbProvider
+ {
+ set { defaultDbProvider = value; }
+ }
+
+ ///
+ /// Sets the target db providers.
+ ///
+ /// The target db providers.
+ public IDictionary TargetDbProviders
+ {
+ set { targetDbProviders = value; }
+ }
+
+ ///
+ /// Ensures that the there are values in the TargetDbProviders dictionary and that the
+ /// key is of the type string and value is of the type IDbProvider.
+ ///
+ /// If the above conditions are not met.
+ public void AfterPropertiesSet()
+ {
+ if (targetDbProviders.Count == 0)
+ {
+ throw new ArgumentException("Target DbProvider collection required.");
+ }
+ foreach (DictionaryEntry entry in targetDbProviders)
+ {
+ if (! entry.Key.GetType().Equals(typeof(string)))
+ {
+ throw new ArgumentException("Key identifying target IDbProvider in TargetDbProviders dictionary property is required to be of type string. Key = " + entry.Key);
+ }
+ IDbProvider targetProvider = entry.Value as IDbProvider;
+ if (targetProvider == null)
+ {
+ throw new ArgumentException("Value in TargetDbProviders dictionary is not of type IDbProvider.");
+ }
+ }
+ }
+
+ #region IDbProvider methods
+
+
+ ///
+ /// Returns a new command object for executing SQL statments/Stored Procedures
+ /// against the database.
+ ///
+ /// An new
+ public IDbCommand CreateCommand()
+ {
+ return GetTargetProvider().CreateCommand();
+ }
+
+ ///
+ /// Returns a new connection object to communicate with the database.
+ ///
+ /// A new
+ public IDbConnection CreateConnection()
+ {
+ return GetTargetProvider().CreateConnection();
+ }
+
+ ///
+ /// Returns a new parameter object for binding values to parameter
+ /// placeholders in SQL statements or Stored Procedure variables.
+ ///
+ /// A new
+ public IDbDataParameter CreateParameter()
+ {
+ return GetTargetProvider().CreateParameter();
+ }
+
+ ///
+ /// Returns a new adapter objects for use with offline DataSets.
+ ///
+ /// A new
+ public IDbDataAdapter CreateDataAdapter()
+ {
+ return GetTargetProvider().CreateDataAdapter();
+ }
+
+ ///
+ /// Returns a new instance of the providers CommandBuilder class.
+ ///
+ /// A new Command Builder
+ /// In .NET 1.1 there was no common base class or interface
+ /// for command builders, hence the return signature is object to
+ /// be portable (but more loosely typed) across .NET 1.1/2.0
+ public object CreateCommandBuilder()
+ {
+ return GetTargetProvider().CreateDataAdapter();
+ }
+
+ ///
+ /// Creates the name of the parameter in the format appropriate to use inside IDbCommand.CommandText.
+ ///
+ /// The unformatted name of the parameter.
+ ///
+ /// The parameter name formatted foran IDbCommand.CommandText.
+ ///
+ /// In most cases this adds the parameter prefix to the name passed into this method.
+ public string CreateParameterName(string name)
+ {
+ return GetTargetProvider().CreateParameterName(name);
+ }
+
+
+ ///
+ /// Creates the name ofthe parameter in the format appropriate for an IDataParameter, i.e. to be
+ /// part of a IDataParameterCollection.
+ ///
+ /// The unformatted name of the parameter.
+ ///
+ /// The parameter name formatted for an IDataParameter
+ ///
+ public string CreateParameterNameForCollection(string name)
+ {
+ return GetTargetProvider().CreateParameterNameForCollection(name);
+ }
+
+ ///
+ /// Return metadata information about the database provider
+ ///
+ ///
+ public IDbMetadata DbMetadata
+ {
+ get { return GetTargetProvider().DbMetadata; }
+ }
+
+ ///
+ /// Connection string used to create connections.
+ ///
+ ///
+ public string ConnectionString
+ {
+ get { return GetTargetProvider().ConnectionString; }
+ set { GetTargetProvider().ConnectionString = value; }
+ }
+
+ ///
+ /// Extracts the provider specific error code as a string.
+ ///
+ /// The data access exception.
+ /// The provider specific error code
+ public string ExtractError(Exception e)
+ {
+ return GetTargetProvider().ExtractError(e);
+ }
+
+ ///
+ /// Determines whether the provided exception is in fact related
+ /// to database access. This can be provider dependent in .NET 1.1 since
+ /// there isn't a common base class for ADO.NET exceptions.
+ ///
+ /// The exception thrown when performing data access
+ /// operations.
+ ///
+ /// true if is a valid data access exception for the specified
+ /// exception; otherwise, false.
+ ///
+ public bool IsDataAccessException(Exception e)
+ {
+#if NET_2_0
+ if (e is System.Data.Common.DbException)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+#else
+ return IsDataAccessExceptionBCL11(e);
+#endif
+ }
+
+ ///
+ /// Determines whether is data access exception in .NET 1.1 for the specified exception.
+ ///
+ /// The candidate exception.
+ ///
+ /// true if is data access exception in .NET 1.1 for the specified exception; otherwise, false.
+ ///
+ public bool IsDataAccessExceptionBCL11(Exception e)
+ {
+ return false;
+ }
+ #endregion
+
+ ///
+ /// Gets the target provider based on the thread local name "dbProviderName"
+ ///
+ /// The corresonding IDbProvider.
+ protected virtual IDbProvider GetTargetProvider()
+ {
+ string dbProviderName = (string)LogicalThreadContext.GetData(CURRENT_DBPROVIDER_SLOTNAME);
+ if (targetDbProviders.Contains(dbProviderName))
+ {
+ return (IDbProvider)targetDbProviders[dbProviderName];
+ }
+ if (defaultDbProvider != null)
+ {
+ return defaultDbProvider;
+ }
+ throw new InvalidDataAccessApiUsageException("'" + dbProviderName + "'"
+ + "was not under the thread local key 'dbProviderName'");
}
///
@@ -270,12 +285,12 @@ namespace Spring.Data
/// the current thread's procesing.
///
/// The name of the DbProvider to use for the current threads processing.
- public static string CurrentDbProviderName
+ public static string CurrentDbProviderName
{
set
{
LogicalThreadContext.SetData(CURRENT_DBPROVIDER_SLOTNAME, value);
}
- }
- }
-}
+ }
+ }
+}