From aa30032e3d87f91222dbb425af499f97a76cfd1a Mon Sep 17 00:00:00 2001 From: markpollack Date: Tue, 28 Jul 2009 20:56:50 +0000 Subject: [PATCH] SPRNET-1240 - Add TransientDataAccessException to DAO exception hierarchy --- .../Dao/ConcurrencyFailureException.cs | 34 +- .../Dao/TransientDataAccessException.cs | 83 +++ .../TransientDataAccessResourceException.cs | 82 +++ .../Spring.Data/Data/Common/ErrorCodes.cs | 316 +++++----- .../Spring.Data/Data/Common/dbproviders.xml | 77 ++- .../Support/ErrorCodeExceptionTranslator.cs | 577 +++++++++--------- .../Spring.Data/Spring.Data.2008.csproj | 4 +- 7 files changed, 699 insertions(+), 474 deletions(-) create mode 100644 src/Spring/Spring.Data/Dao/TransientDataAccessException.cs create mode 100644 src/Spring/Spring.Data/Dao/TransientDataAccessResourceException.cs diff --git a/src/Spring/Spring.Data/Dao/ConcurrencyFailureException.cs b/src/Spring/Spring.Data/Dao/ConcurrencyFailureException.cs index e499fc80..2b307f31 100644 --- a/src/Spring/Spring.Data/Dao/ConcurrencyFailureException.cs +++ b/src/Spring/Spring.Data/Dao/ConcurrencyFailureException.cs @@ -26,22 +26,22 @@ using System.Runtime.Serialization; #endregion namespace Spring.Dao -{ - /// - /// Exception thrown on concurrency failure. This exception should be - /// sublassed to indicate the type of failure - optimistic locking, - /// failure to acquire lock, etc. - /// - /// - ///

- /// This exception will be thrown either by O/R mapping tools or by custom DAO - /// implementations. - ///

- ///
- /// Thomas Risberg - /// Griffin Caprio (.NET) +{ + /// + /// Exception thrown on concurrency failure. This exception should be + /// sublassed to indicate the type of failure - optimistic locking, + /// failure to acquire lock, etc. + /// + /// + ///

+ /// This exception will be thrown either by O/R mapping tools or by custom DAO + /// implementations. + ///

+ ///
+ /// Thomas Risberg + /// Griffin Caprio (.NET) [Serializable] - public class ConcurrencyFailureException : DataAccessException + public class ConcurrencyFailureException : TransientDataAccessException { /// /// Creates a new instance of the @@ -82,8 +82,8 @@ namespace Spring.Dao /// /// The /// that contains contextual information about the source or destination. - /// - protected ConcurrencyFailureException( + /// + protected ConcurrencyFailureException( SerializationInfo info, StreamingContext context ) : base( info, context ) {} } } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Dao/TransientDataAccessException.cs b/src/Spring/Spring.Data/Dao/TransientDataAccessException.cs new file mode 100644 index 00000000..3577a2d7 --- /dev/null +++ b/src/Spring/Spring.Data/Dao/TransientDataAccessException.cs @@ -0,0 +1,83 @@ +#region License + +/* + * Copyright 2002-2004 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 + +#region Imports + +using System; +using System.Runtime.Serialization; + +#endregion + +namespace Spring.Dao +{ + /// + /// Root of the hierarchy of data access exception that are considered transient - + /// where a previously failed operation might be able to succeed when the operation + /// is retried without any intervention by application-level functionality. + /// + /// Thomas Risberg + /// Mark Pollack (.NET) + [Serializable] + public abstract class TransientDataAccessException : DataAccessException + { + /// + /// Creates a new instance of the + /// class. + /// + public TransientDataAccessException() : base("No Exception Message") {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + public TransientDataAccessException( string message ) : base( message ) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception (from the underlying data access API, such as ADO.NET). + /// + public TransientDataAccessException( string message, Exception rootCause) + : base( message , rootCause ) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected TransientDataAccessException( + SerializationInfo info, StreamingContext context ) : base( info, context ) {} + } +} \ No newline at end of file diff --git a/src/Spring/Spring.Data/Dao/TransientDataAccessResourceException.cs b/src/Spring/Spring.Data/Dao/TransientDataAccessResourceException.cs new file mode 100644 index 00000000..e5bea460 --- /dev/null +++ b/src/Spring/Spring.Data/Dao/TransientDataAccessResourceException.cs @@ -0,0 +1,82 @@ +#region License + +/* + * Copyright 2002-2004 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 + +#region Imports + +using System; +using System.Runtime.Serialization; + +#endregion + +namespace Spring.Dao +{ + /// + /// RDta access exception thrown when a resource fails temporarily and the operation can be + /// retried. + /// + /// Thomas Risberg + /// Mark Pollack (.NET) + [Serializable] + public class TransientDataAccessResourceException : TransientDataAccessException + { + /// + /// Creates a new instance of the + /// class. + /// + public TransientDataAccessResourceException() : base("No Exception Message") {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + public TransientDataAccessResourceException( string message ) : base( message ) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception (from the underlying data access API, such as ADO.NET). + /// + public TransientDataAccessResourceException( string message, Exception rootCause) + : base( message , rootCause ) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected TransientDataAccessResourceException( + SerializationInfo info, StreamingContext context ) : base( info, context ) {} + } +} \ No newline at end of file diff --git a/src/Spring/Spring.Data/Data/Common/ErrorCodes.cs b/src/Spring/Spring.Data/Data/Common/ErrorCodes.cs index 29e30c40..455ed2c2 100644 --- a/src/Spring/Spring.Data/Data/Common/ErrorCodes.cs +++ b/src/Spring/Spring.Data/Data/Common/ErrorCodes.cs @@ -1,159 +1,167 @@ -#region Licence - -/* - * Copyright © 2002-2005 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 - -#region Imports - -using System; -using Common.Logging; - -#endregion - -namespace Spring.Data.Common -{ - /// - /// Holds ADO.NET error codes for a particular provider. - /// - /// - /// Used by ErrorCodeExceptionTranslator. The embedded resource - /// "dbProviders.xml" in Spring.Data.Common contains default - /// ErrorCodes instances for various providers. - /// - /// Mark Pollack (.NET) - public class ErrorCodes - { - #region Fields - private string[] databaseProductNames; - - private string[] badSqlGrammarCodes = new String[0]; - - private string[] invalidResultSetAccessCodes = new String[0]; - - private string[] dataAccessResourceFailureCodes = new String[0]; - - private string[] permissionDeniedCodes = new String[0]; - - private string[] dataIntegrityViolationCodes = new String[0]; - - private string[] cannotAcquireLockCodes = new String[0]; - - private string[] deadlockLoserCodes = new String[0]; - - private string[] cannotSerializeTransactionCodes = new String[0]; - - private string[] duplicateKeyCodes = new string[0]; - - // CustomErrorCodesTranslation[] customTranslations; - #endregion - - #region Constants - - /// - /// The shared log instance for this class (and derived classes). - /// - protected static readonly ILog log = - LogManager.GetLogger(typeof (ErrorCodes)); - - #endregion - - #region Constructor (s) - /// - /// Initializes a new instance of the class. - /// - public ErrorCodes() - { - - } - - #endregion - - #region Properties - public string DatabaseProductName - { - get - { - return (databaseProductNames != null && databaseProductNames.Length > 0 ? - databaseProductNames[0] : null); - } - } - - public string[] DatabaseProductNames - { - get { return databaseProductNames; } - set { databaseProductNames = value; } - } - - public string[] BadSqlGrammarCodes - { - get { return badSqlGrammarCodes; } - set { badSqlGrammarCodes = value; } - } - - public string[] InvalidResultSetAccessCodes - { - get { return invalidResultSetAccessCodes; } - set { invalidResultSetAccessCodes = value; } - } - - public string[] DataAccessResourceFailureCodes - { - get { return dataAccessResourceFailureCodes; } - set { dataAccessResourceFailureCodes = value; } - } - - public string[] PermissionDeniedCodes - { - get { return permissionDeniedCodes; } - set { permissionDeniedCodes = value; } - } - - public string[] DataIntegrityViolationCodes - { - get { return dataIntegrityViolationCodes; } - set { dataIntegrityViolationCodes = value; } - } - - public string[] CannotAcquireLockCodes - { - get { return cannotAcquireLockCodes; } - set { cannotAcquireLockCodes = value; } - } - - public string[] DeadlockLoserCodes - { - get { return deadlockLoserCodes; } - set { deadlockLoserCodes = value; } - } - - public string[] CannotSerializeTransactionCodes - { - get { return cannotSerializeTransactionCodes; } - set { cannotSerializeTransactionCodes = value; } - } - +#region Licence + +/* + * Copyright © 2002-2005 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 + +#region Imports + +using System; +using Common.Logging; + +#endregion + +namespace Spring.Data.Common +{ + /// + /// Holds ADO.NET error codes for a particular provider. + /// + /// + /// Used by ErrorCodeExceptionTranslator. The embedded resource + /// "dbProviders.xml" in Spring.Data.Common contains default + /// ErrorCodes instances for various providers. + /// + /// Mark Pollack (.NET) + public class ErrorCodes + { + #region Fields + private string[] databaseProductNames; + + private string[] badSqlGrammarCodes = new String[0]; + + private string[] invalidResultSetAccessCodes = new String[0]; + + private string[] duplicateKeyCodes = new string[0]; + + private string[] dataIntegrityViolationCodes = new String[0]; + + private string[] permissionDeniedCodes = new String[0]; + + private string[] dataAccessResourceFailureCodes = new String[0]; + + private string[] transientAccessResourceFailureCodes = new String[0]; + + private string[] cannotAcquireLockCodes = new String[0]; + + private string[] deadlockLoserCodes = new String[0]; + + private string[] cannotSerializeTransactionCodes = new String[0]; + + // CustomErrorCodesTranslation[] customTranslations; + #endregion + + #region Constants + + /// + /// The shared log instance for this class (and derived classes). + /// + protected static readonly ILog log = + LogManager.GetLogger(typeof (ErrorCodes)); + + #endregion + + #region Constructor (s) + /// + /// Initializes a new instance of the class. + /// + public ErrorCodes() + { + + } + + #endregion + + #region Properties + public string DatabaseProductName + { + get + { + return (databaseProductNames != null && databaseProductNames.Length > 0 ? + databaseProductNames[0] : null); + } + } + + public string[] DatabaseProductNames + { + get { return databaseProductNames; } + set { databaseProductNames = value; } + } + + public string[] BadSqlGrammarCodes + { + get { return badSqlGrammarCodes; } + set { badSqlGrammarCodes = value; } + } + + public string[] InvalidResultSetAccessCodes + { + get { return invalidResultSetAccessCodes; } + set { invalidResultSetAccessCodes = value; } + } + + public string[] DataAccessResourceFailureCodes + { + get { return dataAccessResourceFailureCodes; } + set { dataAccessResourceFailureCodes = value; } + } + + public string[] PermissionDeniedCodes + { + get { return permissionDeniedCodes; } + set { permissionDeniedCodes = value; } + } + + public string[] DataIntegrityViolationCodes + { + get { return dataIntegrityViolationCodes; } + set { dataIntegrityViolationCodes = value; } + } + + public string[] CannotAcquireLockCodes + { + get { return cannotAcquireLockCodes; } + set { cannotAcquireLockCodes = value; } + } + + public string[] TransientAccessResourceFailureCodes + { + get { return transientAccessResourceFailureCodes; } + set { transientAccessResourceFailureCodes = value; } + } + + public string[] DeadlockLoserCodes + { + get { return deadlockLoserCodes; } + set { deadlockLoserCodes = value; } + } + + public string[] CannotSerializeTransactionCodes + { + get { return cannotSerializeTransactionCodes; } + set { cannotSerializeTransactionCodes = value; } + } + public string[] DuplicateKeyCodes { get { return duplicateKeyCodes; } set { duplicateKeyCodes = value; } - } - - #endregion - - } + } + + #endregion + + } } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Data/Common/dbproviders.xml b/src/Spring/Spring.Data/Data/Common/dbproviders.xml index 9d335032..21627714 100644 --- a/src/Spring/Spring.Data/Data/Common/dbproviders.xml +++ b/src/Spring/Spring.Data/Data/Common/dbproviders.xml @@ -837,14 +837,20 @@ - + -007,-029,-097,-104,-109,-115,-128,-199,-204,-206,-301,-408,-441,-491 + + -803 + + + -407,-530,-531,-532,-543,-544,-545,-603,-667,-803 + -904,-971 - - -407,-530,-531,-532,-543,-544,-545,-603,-667,-803 + + -1035,-1218,-30080,-30081 -911,-913 @@ -879,14 +885,20 @@ - + -007,-029,-097,-104,-109,-115,-128,-199,-204,-206,-301,-408,-441,-491 + + -803 + + + -407,-530,-531,-532,-543,-544,-545,-603,-667,-803 + -904,-971 - - -407,-530,-531,-532,-543,-544,-545,-603,-667,-803 + + -1035,-1218,-30080,-30081 -911,-913 @@ -923,14 +935,21 @@ - + + -007,-029,-097,-104,-109,-115,-128,-199,-204,-206,-301,-408,-441,-491 + + -803 + + + -407,-530,-531,-532,-543,-544,-545,-603,-667,-803 + -904,-971 - - -407,-530,-531,-532,-543,-544,-545,-603,-667,-803 + + -1035,-1218,-30080,-30081 -911,-913 @@ -964,15 +983,22 @@ - - + + + -007,-029,-097,-104,-109,-115,-128,-199,-204,-206,-301,-408,-441,-491 + + -803 + + + -407,-530,-531,-532,-543,-544,-545,-603,-667,-803 + -904,-971 - - -407,-530,-531,-532,-543,-544,-545,-603,-667,-803 + + -1035,-1218,-30080,-30081 -911,-913 @@ -1010,14 +1036,21 @@ - + + -007,-029,-097,-104,-109,-115,-128,-199,-204,-206,-301,-408,-441,-491 + + -803 + + + -407,-530,-531,-532,-543,-544,-545,-603,-667,-803 + -904,-971 - - -407,-530,-531,-532,-543,-544,-545,-603,-667,-803 + + -1035,-1218,-30080,-30081 -911,-913 @@ -1241,6 +1274,9 @@ 423,511,515,530,547,2601,2615,2714 + + 921,1105 + 1205 @@ -1276,6 +1312,12 @@ 423,511,515,530,547,2601,2615,2714 + + 921,1105 + + + 921,1105 + 1205 @@ -1313,6 +1355,9 @@ 423,511,515,530,547,2601,2615,2714 + + 921,1105 + 1205 diff --git a/src/Spring/Spring.Data/Data/Support/ErrorCodeExceptionTranslator.cs b/src/Spring/Spring.Data/Data/Support/ErrorCodeExceptionTranslator.cs index f417a87c..65618865 100644 --- a/src/Spring/Spring.Data/Data/Support/ErrorCodeExceptionTranslator.cs +++ b/src/Spring/Spring.Data/Data/Support/ErrorCodeExceptionTranslator.cs @@ -1,158 +1,158 @@ -#region License - -/* - * Copyright © 2002-2006 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 - -#region Imports - -using System; -using Common.Logging; -using Spring.Dao; -using Spring.Data.Common; - -#endregion - -namespace Spring.Data.Support -{ - /// - /// Implementation of IAdoExceptionTranslator that analyzes provider specific - /// error codes and translates into the DAO exception hierarchy. - /// - /// This class loads the obtains error codes from - /// the IDbProvider metadata property ErrorCodes - /// which defines error code mappings for various providers. - /// - /// Mark Pollack (.NET) - public class ErrorCodeExceptionTranslator : IAdoExceptionTranslator - { - #region Fields - - private ErrorCodes errorCodes; - - private IAdoExceptionTranslator fallbackTranslator; - - private IDbProvider dbProvider; - - #endregion - - #region Constants - - /// - /// The shared log instance for this class (and derived classes). - /// - protected static readonly ILog log = - LogManager.GetLogger(typeof (ErrorCodeExceptionTranslator)); - - #endregion - - #region Constructor (s) - - /// - /// Initializes a new instance of the class. - /// - /// The data provider. - public ErrorCodeExceptionTranslator(IDbProvider provider) - { - DbProvider = provider; - } - - - - /// - /// Initializes a new instance of the class. - /// - /// The data provider. - /// The error code collection. - public ErrorCodeExceptionTranslator(IDbProvider provider, ErrorCodes ec) - { - DbProvider = provider; - errorCodes = ec; - } - - - - #endregion - - #region Properties - - /// - /// Sets the db provider. - /// - /// The db provider. - public IDbProvider DbProvider - { - set - { - dbProvider = value; - fallbackTranslator = new FallbackExceptionTranslator(); - errorCodes = dbProvider.DbMetadata.ErrorCodes; - - } - } - - /// - /// Gets the error codes for the provider - /// - /// The error codes. - public ErrorCodes ErrorCodes - { - get - { - return errorCodes; - } - } - - #endregion - - /// - /// Gets or sets the fallback translator to use in case error code based translation - /// fails. - /// - /// The fallback translator. - public IAdoExceptionTranslator FallbackTranslator - { - get - { - return fallbackTranslator; - } - set - { - fallbackTranslator = value; - } - } - - - #region Methods - - #endregion - - - /// - /// Translate the given into a generic data access exception. - /// - /// A readable string describing the task being attempted. - /// The SQL query or update that caused the problem. May be null. - /// - /// The encountered by the ADO.NET implementation. - /// - /// - /// A appropriate for the supplied - /// . +#region License + +/* + * Copyright © 2002-2006 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 + +#region Imports + +using System; +using Common.Logging; +using Spring.Dao; +using Spring.Data.Common; + +#endregion + +namespace Spring.Data.Support +{ + /// + /// Implementation of IAdoExceptionTranslator that analyzes provider specific + /// error codes and translates into the DAO exception hierarchy. + /// + /// This class loads the obtains error codes from + /// the IDbProvider metadata property ErrorCodes + /// which defines error code mappings for various providers. + /// + /// Mark Pollack (.NET) + public class ErrorCodeExceptionTranslator : IAdoExceptionTranslator + { + #region Fields + + private ErrorCodes errorCodes; + + private IAdoExceptionTranslator fallbackTranslator; + + private IDbProvider dbProvider; + + #endregion + + #region Constants + + /// + /// The shared log instance for this class (and derived classes). + /// + protected static readonly ILog log = + LogManager.GetLogger(typeof (ErrorCodeExceptionTranslator)); + + #endregion + + #region Constructor (s) + + /// + /// Initializes a new instance of the class. + /// + /// The data provider. + public ErrorCodeExceptionTranslator(IDbProvider provider) + { + DbProvider = provider; + } + + + + /// + /// Initializes a new instance of the class. + /// + /// The data provider. + /// The error code collection. + public ErrorCodeExceptionTranslator(IDbProvider provider, ErrorCodes ec) + { + DbProvider = provider; + errorCodes = ec; + } + + + + #endregion + + #region Properties + + /// + /// Sets the db provider. + /// + /// The db provider. + public IDbProvider DbProvider + { + set + { + dbProvider = value; + fallbackTranslator = new FallbackExceptionTranslator(); + errorCodes = dbProvider.DbMetadata.ErrorCodes; + + } + } + + /// + /// Gets the error codes for the provider + /// + /// The error codes. + public ErrorCodes ErrorCodes + { + get + { + return errorCodes; + } + } + + #endregion + + /// + /// Gets or sets the fallback translator to use in case error code based translation + /// fails. + /// + /// The fallback translator. + public IAdoExceptionTranslator FallbackTranslator + { + get + { + return fallbackTranslator; + } + set + { + fallbackTranslator = value; + } + } + + + #region Methods + + #endregion + + + /// + /// Translate the given into a generic data access exception. + /// + /// A readable string describing the task being attempted. + /// The SQL query or update that caused the problem. May be null. + /// + /// The encountered by the ADO.NET implementation. + /// + /// + /// A appropriate for the supplied + /// . /// public virtual DataAccessException Translate(string task, string sql, Exception exception) { @@ -206,139 +206,144 @@ namespace Spring.Data.Support /// return null to indicate that no exception match has been found and that /// fallback translation should kick in. /// - protected virtual DataAccessException DoTranslate(string task, string sql, string errorCode, Exception exception) - { - // First, try custom translation from overridden method. - DataAccessException dex = TranslateException(task, sql, errorCode, exception); - if (dex != null) - { - return dex; - } - - - if (errorCodes != null) - { - - if (errorCode != null) - { - if (Array.IndexOf(errorCodes.BadSqlGrammarCodes, errorCode) >= 0) - { - LogTranslation(task, sql, errorCode, exception, false); - return new BadSqlGrammarException(task, sql, exception); - } - else if (Array.IndexOf(errorCodes.InvalidResultSetAccessCodes, errorCode) >= 0) - { - LogTranslation(task, sql, errorCode, exception, false); - return new InvalidResultSetAccessException(task, sql, exception); + protected virtual DataAccessException DoTranslate(string task, string sql, string errorCode, Exception exception) + { + // First, try custom translation from overridden method. + DataAccessException dex = TranslateException(task, sql, errorCode, exception); + if (dex != null) + { + return dex; + } + + + if (errorCodes != null) + { + + if (errorCode != null) + { + if (Array.IndexOf(errorCodes.BadSqlGrammarCodes, errorCode) >= 0) + { + LogTranslation(task, sql, errorCode, exception, false); + return new BadSqlGrammarException(task, sql, exception); + } + else if (Array.IndexOf(errorCodes.InvalidResultSetAccessCodes, errorCode) >= 0) + { + LogTranslation(task, sql, errorCode, exception, false); + return new InvalidResultSetAccessException(task, sql, exception); } else if (Array.IndexOf(errorCodes.DuplicateKeyCodes, errorCode) >= 0) { LogTranslation(task, sql, errorCode, exception, false); return new DuplicateKeyException(task, sql, exception); - } - else if (Array.IndexOf(errorCodes.DataAccessResourceFailureCodes, errorCode) >= 0) - { - LogTranslation(task, sql, errorCode, exception, false); - return new DataAccessResourceFailureException(BuildMessage(task, sql, exception), exception); - } - else if (Array.IndexOf(errorCodes.PermissionDeniedCodes, errorCode) >= 0) - { - LogTranslation(task, sql, errorCode, exception, false); - return new PermissionDeniedDataAccessException(BuildMessage(task, sql, exception), exception); - } - else if (Array.IndexOf(errorCodes.DataIntegrityViolationCodes, errorCode) >= 0) - { - LogTranslation(task, sql, errorCode, exception, false); - return new DataIntegrityViolationException(BuildMessage(task, sql, exception), exception); - } - else if (Array.IndexOf(errorCodes.CannotAcquireLockCodes, errorCode) >= 0) - { - LogTranslation(task, sql, errorCode, exception, false); - return new CannotAcquireLockException(BuildMessage(task, sql, exception), exception); - } - else if (Array.IndexOf(errorCodes.DeadlockLoserCodes, errorCode) >= 0) - { - LogTranslation(task, sql, errorCode, exception, false); - return new DeadlockLoserDataAccessException(BuildMessage(task, sql, exception), exception); - } - else if (Array.IndexOf(errorCodes.CannotSerializeTransactionCodes, errorCode) >= 0) - { - LogTranslation(task, sql, errorCode, exception, false); - return new CannotSerializeTransactionException(BuildMessage(task, sql, exception), exception); - } - } - } - return null; - } - - /// - /// Subclasses can override this method to attempt a custom mapping from a data access Exception - /// to DataAccessException. - /// - /// Readable text describing the task being attempted. - /// SQL query or update that caused the problem. May be null. - /// The error code extracted from the generic data access exception for - /// a particular provider. - /// The exception thrown from a data access operation. - /// - /// null if no custom translation was possible, otherwise a DataAccessException - /// resulting from custom translation. This exception should include the exception parameter - /// as a nested root cause. This implementation always returns null, meaning that - /// the translator always falls back to the default error codes. - /// - protected virtual DataAccessException TranslateException(string task, string sql, string errorCode, Exception exception) - { - return null; - } - - - /// - /// Builds the message. - /// - /// The task. - /// The SQL. - /// The exception. - /// - protected virtual string BuildMessage(string task, string sql, Exception exception) - { - return task + "; SQL [" + sql + "]; " + exception.Message; - } - - /// - /// Determines whether the specified exception is valid data access exception. - /// - /// The exception. - /// - /// true if is valid data access exception; otherwise, false. - /// - public bool IsValidDataAccessException(Exception e) - { - return dbProvider.IsDataAccessException(e); - } - - /// - /// Logs the translation. - /// - /// The task. - /// The SQL. - /// The error code. - /// The exception. - /// if set to true [b]. - private void LogTranslation(string task, string sql, string errorCode, Exception exception, bool b) - { - if (log.IsDebugEnabled) - { - String intro = "Translating"; - log.Debug(intro + " ADO exception with error code '" + errorCode - + "', message [" + exception.Message + - "]; SQL was [" + sql + "] for task [" + task + "]"); - } - } - - private string ExtractErrorCode(Exception exception) - { - // Use provider specific reflection information to extract error code. - return dbProvider.ExtractError(exception); - } - } -} + } + else if (Array.IndexOf(errorCodes.DataAccessResourceFailureCodes, errorCode) >= 0) + { + LogTranslation(task, sql, errorCode, exception, false); + return new DataAccessResourceFailureException(BuildMessage(task, sql, exception), exception); + } + else if (Array.IndexOf(errorCodes.TransientAccessResourceFailureCodes, errorCode) >= 0) + { + LogTranslation(task, sql, errorCode, exception, false); + return new TransientDataAccessResourceException(BuildMessage(task, sql, exception), exception); + } + else if (Array.IndexOf(errorCodes.PermissionDeniedCodes, errorCode) >= 0) + { + LogTranslation(task, sql, errorCode, exception, false); + return new PermissionDeniedDataAccessException(BuildMessage(task, sql, exception), exception); + } + else if (Array.IndexOf(errorCodes.DataIntegrityViolationCodes, errorCode) >= 0) + { + LogTranslation(task, sql, errorCode, exception, false); + return new DataIntegrityViolationException(BuildMessage(task, sql, exception), exception); + } + else if (Array.IndexOf(errorCodes.CannotAcquireLockCodes, errorCode) >= 0) + { + LogTranslation(task, sql, errorCode, exception, false); + return new CannotAcquireLockException(BuildMessage(task, sql, exception), exception); + } + else if (Array.IndexOf(errorCodes.DeadlockLoserCodes, errorCode) >= 0) + { + LogTranslation(task, sql, errorCode, exception, false); + return new DeadlockLoserDataAccessException(BuildMessage(task, sql, exception), exception); + } + else if (Array.IndexOf(errorCodes.CannotSerializeTransactionCodes, errorCode) >= 0) + { + LogTranslation(task, sql, errorCode, exception, false); + return new CannotSerializeTransactionException(BuildMessage(task, sql, exception), exception); + } + } + } + return null; + } + + /// + /// Subclasses can override this method to attempt a custom mapping from a data access Exception + /// to DataAccessException. + /// + /// Readable text describing the task being attempted. + /// SQL query or update that caused the problem. May be null. + /// The error code extracted from the generic data access exception for + /// a particular provider. + /// The exception thrown from a data access operation. + /// + /// null if no custom translation was possible, otherwise a DataAccessException + /// resulting from custom translation. This exception should include the exception parameter + /// as a nested root cause. This implementation always returns null, meaning that + /// the translator always falls back to the default error codes. + /// + protected virtual DataAccessException TranslateException(string task, string sql, string errorCode, Exception exception) + { + return null; + } + + + /// + /// Builds the message. + /// + /// The task. + /// The SQL. + /// The exception. + /// + protected virtual string BuildMessage(string task, string sql, Exception exception) + { + return task + "; SQL [" + sql + "]; " + exception.Message; + } + + /// + /// Determines whether the specified exception is valid data access exception. + /// + /// The exception. + /// + /// true if is valid data access exception; otherwise, false. + /// + public bool IsValidDataAccessException(Exception e) + { + return dbProvider.IsDataAccessException(e); + } + + /// + /// Logs the translation. + /// + /// The task. + /// The SQL. + /// The error code. + /// The exception. + /// if set to true [b]. + private void LogTranslation(string task, string sql, string errorCode, Exception exception, bool b) + { + if (log.IsDebugEnabled) + { + String intro = "Translating"; + log.Debug(intro + " ADO exception with error code '" + errorCode + + "', message [" + exception.Message + + "]; SQL was [" + sql + "] for task [" + task + "]"); + } + } + + private string ExtractErrorCode(Exception exception) + { + // Use provider specific reflection information to extract error code. + return dbProvider.ExtractError(exception); + } + } +} diff --git a/src/Spring/Spring.Data/Spring.Data.2008.csproj b/src/Spring/Spring.Data/Spring.Data.2008.csproj index b753c6a8..ce985839 100644 --- a/src/Spring/Spring.Data/Spring.Data.2008.csproj +++ b/src/Spring/Spring.Data/Spring.Data.2008.csproj @@ -1,7 +1,7 @@  Local - 9.0.30729 + 9.0.21022 2.0 {AE00E5AB-C39A-436F-86D2-33BFE33E2E40} Debug @@ -104,6 +104,8 @@ + +