1/*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 2009 Oracle. All rights reserved. 5 * 6 */ 7using System; 8using System.Collections.Generic; 9using System.Text; 10using BerkeleyDB.Internal; 11 12namespace BerkeleyDB { 13 /// <summary> 14 /// Represents errors that occur during Berkley DB operations. 15 /// </summary> 16 public class DatabaseException : Exception { 17 /// <summary> 18 /// The underlying error code from the Berkeley DB C library. 19 /// </summary> 20 public int ErrorCode; 21 22 /// <summary> 23 /// Throw an exception which corresponds to the specified Berkeley DB 24 /// error code. 25 /// </summary> 26 /// <param name="err">The Berkeley DB error code</param> 27 public static void ThrowException(int err) { 28 switch (err) { 29 case 0: 30 return; 31 case ErrorCodes.DB_NOTFOUND: 32 throw new NotFoundException(); 33 case ErrorCodes.DB_BUFFER_SMALL: 34 throw new MemoryException(); 35 case ErrorCodes.DB_FOREIGN_CONFLICT: 36 throw new ForeignConflictException(); 37 case ErrorCodes.DB_KEYEMPTY: 38 throw new KeyEmptyException(); 39 case ErrorCodes.DB_KEYEXIST: 40 throw new KeyExistException(); 41 case ErrorCodes.DB_LOCK_DEADLOCK: 42 throw new DeadlockException(); 43 case ErrorCodes.DB_LOCK_NOTGRANTED: 44 throw new LockNotGrantedException(); 45 case ErrorCodes.DB_LOG_BUFFER_FULL: 46 throw new FullLogBufferException(); 47 case ErrorCodes.DB_OLD_VERSION: 48 throw new OldVersionException(); 49 case ErrorCodes.DB_PAGE_NOTFOUND: 50 throw new PageNotFoundException(); 51 case ErrorCodes.DB_REP_DUPMASTER: 52 case ErrorCodes.DB_REP_HOLDELECTION: 53 case ErrorCodes.DB_REP_IGNORE: 54 case ErrorCodes.DB_REP_ISPERM: 55 case ErrorCodes.DB_REP_JOIN_FAILURE: 56 case ErrorCodes.DB_REP_NEWSITE: 57 case ErrorCodes.DB_REP_NOTPERM: 58 return; 59 case ErrorCodes.DB_REP_LEASE_EXPIRED: 60 throw new LeaseExpiredException(); 61 case ErrorCodes.DB_RUNRECOVERY: 62 throw new RunRecoveryException(); 63 case ErrorCodes.DB_SECONDARY_BAD: 64 throw new BadSecondaryException(); 65 case ErrorCodes.DB_VERIFY_BAD: 66 throw new VerificationException(); 67 case ErrorCodes.DB_VERSION_MISMATCH: 68 throw new VersionMismatchException(); 69 default: 70 throw new DatabaseException(err); 71 } 72 } 73 74 /// <summary> 75 /// Create a new DatabaseException, encapsulating a specific error code. 76 /// </summary> 77 /// <param name="err">The error code to encapsulate.</param> 78 public DatabaseException(int err) 79 : base(libdb_csharp.db_strerror(err)) { 80 ErrorCode = err; 81 } 82 } 83 84 /// <summary> 85 /// A secondary index has been corrupted. This is likely the result of an 86 /// application operating on related databases without first associating 87 /// them. 88 /// </summary> 89 public class BadSecondaryException : DatabaseException { 90 /// <summary> 91 /// Initialize a new instance of the BadSecondaryException 92 /// </summary> 93 public BadSecondaryException() : base(ErrorCodes.DB_SECONDARY_BAD) { } 94 } 95 96 /// <summary> 97 /// 98 /// </summary> 99 public class ForeignConflictException : DatabaseException { 100 /// <summary> 101 /// Initialize a new instance of the ForeignConflictException 102 /// </summary> 103 public ForeignConflictException() 104 : base(ErrorCodes.DB_FOREIGN_CONFLICT) { } 105 } 106 107 /// <summary> 108 /// In-memory logs are configured and no more log buffer space is available. 109 /// </summary> 110 public class FullLogBufferException : DatabaseException { 111 /// <summary> 112 /// Initialize a new instance of the FullLogBufferException 113 /// </summary> 114 public FullLogBufferException() 115 : base(ErrorCodes.DB_LOG_BUFFER_FULL) { } 116 } 117 118 /// <summary> 119 /// The requested key/data pair logically exists but was never explicitly 120 /// created by the application, or that the requested key/data pair was 121 /// deleted and never re-created. In addition, the Queue access method will 122 /// throw a KeyEmptyException for records that were created as part of a 123 /// transaction that was later aborted and never re-created. 124 /// </summary> 125 /// <remarks> 126 /// The Recno and Queue access methods will automatically create key/data 127 /// pairs under some circumstances. 128 /// </remarks> 129 public class KeyEmptyException : DatabaseException { 130 /// <summary> 131 /// Initialize a new instance of the KeyEmptyException 132 /// </summary> 133 public KeyEmptyException() : base(ErrorCodes.DB_KEYEMPTY) { } 134 } 135 136 /// <summary> 137 /// A key/data pair was inserted into the database using 138 /// <see cref="Database.PutNoOverwrite"/> and the key already 139 /// exists in the database, or using 140 /// <see cref="BTreeDatabase.PutNoDuplicate"/> or 141 /// <see cref="HashDatabase.PutNoDuplicate"/> and the key/data 142 /// pair already exists in the database. 143 /// </summary> 144 public class KeyExistException : DatabaseException { 145 /// <summary> 146 /// Initialize a new instance of the KeyExistException 147 /// </summary> 148 public KeyExistException() : base(ErrorCodes.DB_KEYEXIST) { } 149 } 150 151 /// <summary> 152 /// When multiple threads of control are modifying the database, there is 153 /// normally the potential for deadlock. In Berkeley DB, deadlock is 154 /// signified by a DeadlockException thrown from the Berkeley DB function. 155 /// Whenever a Berkeley DB function throws a DeadlockException, the 156 /// enclosing transaction should be aborted. 157 /// </summary> 158 public class DeadlockException : DatabaseException { 159 /// <summary> 160 /// Initialize a new instance of the DeadlockException 161 /// </summary> 162 public DeadlockException() : base(ErrorCodes.DB_LOCK_DEADLOCK) { } 163 } 164 165 /// <summary> 166 /// The site's replication master lease has expired. 167 /// </summary> 168 public class LeaseExpiredException : DatabaseException { 169 /// <summary> 170 /// Initialize a new instance of the LeaseExpiredException 171 /// </summary> 172 public LeaseExpiredException() 173 : base(ErrorCodes.DB_REP_LEASE_EXPIRED) { } 174 } 175 176 /// <summary> 177 /// If <see cref="DatabaseEnvironmentConfig.TimeNotGranted"/> is true, 178 /// database calls timing out based on lock or transaction timeout values 179 /// will throw a LockNotGrantedException, instead of a DeadlockException. 180 /// </summary> 181 public class LockNotGrantedException : DatabaseException { 182 /// <summary> 183 /// Initialize a new instance of the LockNotGrantedException 184 /// </summary> 185 public LockNotGrantedException() 186 : base(ErrorCodes.DB_LOCK_NOTGRANTED) { } 187 } 188 189 internal class MemoryException : DatabaseException { 190 /// <summary> 191 /// Initialize a new instance of the MemoryException 192 /// </summary> 193 internal MemoryException() : base(ErrorCodes.DB_BUFFER_SMALL) { } 194 } 195 196 /// <summary> 197 /// The requested key/data pair did not exist in the database or that 198 /// start-of- or end-of-file has been reached by a cursor. 199 /// </summary> 200 public class NotFoundException : DatabaseException { 201 /// <summary> 202 /// Initialize a new instance of the NotFoundException 203 /// </summary> 204 public NotFoundException() : base(ErrorCodes.DB_NOTFOUND) { } 205 } 206 207 /// <summary> 208 /// This version of Berkeley DB is unable to upgrade a given database. 209 /// </summary> 210 public class OldVersionException : DatabaseException { 211 /// <summary> 212 /// Initialize a new instance of the OldVersionException 213 /// </summary> 214 public OldVersionException() : base(ErrorCodes.DB_OLD_VERSION) { } 215 } 216 217 /// <summary> 218 /// 219 /// </summary> 220 public class PageNotFoundException : DatabaseException { 221 /// <summary> 222 /// 223 /// </summary> 224 public PageNotFoundException() : base(ErrorCodes.DB_PAGE_NOTFOUND) { } 225 } 226 227 /// <summary> 228 /// Berkeley DB has encountered an error it considers fatal to an entire 229 /// environment. Once a RunRecoveryException has been thrown by any 230 /// interface, it will be returned from all subsequent Berkeley DB calls 231 /// made by any threads of control participating in the environment. 232 /// </summary> 233 /// <remarks> 234 /// An example of this type of fatal error is a corrupted database page. The 235 /// only way to recover from this type of error is to have all threads of 236 /// control exit the Berkeley DB environment, run recovery of the 237 /// environment, and re-enter Berkeley DB. (It is not strictly necessary 238 /// that the processes exit, although that is the only way to recover system 239 /// resources, such as file descriptors and memory, allocated by 240 /// Berkeley DB.) 241 /// </remarks> 242 public class RunRecoveryException : DatabaseException { 243 /// <summary> 244 /// Initialize a new instance of the RunRecoveryException 245 /// </summary> 246 public RunRecoveryException() : base(ErrorCodes.DB_RUNRECOVERY) { } 247 } 248 249 /// <summary> 250 /// Thrown by <see cref="Database.Verify"/> if a database is 251 /// corrupted, and by <see cref="Database.Salvage"/> if all 252 /// key/data pairs in the file may not have been successfully output. 253 /// </summary> 254 public class VerificationException : DatabaseException { 255 /// <summary> 256 /// Initialize a new instance of the VerificationException 257 /// </summary> 258 public VerificationException() : base(ErrorCodes.DB_VERIFY_BAD) { } 259 } 260 261 /// <summary> 262 /// The version of the Berkeley DB library doesn't match the version that 263 /// created the database environment. 264 /// </summary> 265 public class VersionMismatchException : DatabaseException { 266 /// <summary> 267 /// Initialize a new instance of the VersionMismatchException 268 /// </summary> 269 public VersionMismatchException() 270 : base(ErrorCodes.DB_VERSION_MISMATCH) { } 271 } 272} 273