1 /* 2 bdb2d is BerkeleyDB for D language 3 It is part of unDE project (http://unde.su) 4 5 Copyright (C) 2009-2014 Nikolay (unDEFER) Krivchenkov <undefer@gmail.com> 6 7 This program is free software: you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation, either version 3 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program. If not, see <http://www.gnu.org/licenses/>. 19 */ 20 21 module berkeleydb.dbexception; 22 23 import berkeleydb.c; 24 import berkeleydb.dbenv; 25 import berkeleydb.dbt; 26 import std.conv; 27 28 /* 29 * This method fully coming from macroses DB_RETOK_* 30 * from db/src/dbinc/db_int.in 31 */ 32 package auto DbRetCodeToException(string Func)(int ret, DbEnv dbenv = null, Dbt *dbt = null, 33 db_lockop_t op = 0, db_lockmode_t mode = 0, const (DB_LOCK) *lock = null, int index = 0) 34 { 35 switch(ret) 36 { 37 case 0: 38 39 static if(Func == "std") 40 { 41 return; 42 } 43 else static if(Func == "Dbc.del" 44 || Func == "Db.del") 45 { 46 case DB_KEYEMPTY: 47 case DB_NOTFOUND: 48 return ret; 49 } 50 else static if(Func == "Dbc.get" 51 || Func == "Db.get" 52 || Func == "exists") 53 { 54 case DB_KEYEMPTY: 55 case DB_NOTFOUND: 56 return ret; 57 } 58 else static if(Func == "Dbc.put") 59 { 60 case DB_KEYEXIST: 61 case DB_NOTFOUND: 62 return ret; 63 } 64 else static if(Func == "Db.put") 65 { 66 case DB_KEYEXIST: 67 return ret; 68 } 69 else static if(Func == "DbLogc.get") 70 { 71 case DB_NOTFOUND: 72 return ret; 73 } 74 else static if(Func == "DbMpoolfile.get") 75 { 76 case DB_PAGE_NOTFOUND: 77 return ret; 78 } 79 else static if(Func == "rep_process_message") 80 { 81 case DB_REP_IGNORE: 82 case DB_REP_ISPERM: 83 case DB_REP_NEWMASTER: 84 case DB_REP_NEWSITE: 85 case DB_REP_NOTPERM: 86 case DB_REP_WOULDROLLBACK: 87 return ret; 88 } 89 else static if(Func == "repmgr_localsite") 90 { 91 case DB_NOTFOUND: 92 return ret; 93 } 94 else static if(Func == "repmgr_start") 95 { 96 case DB_REP_IGNORE: 97 return ret; 98 } 99 else static if(Func == "txn_applied") 100 { 101 case DB_NOTFOUND: 102 case DB_TIMEOUT: 103 case DB_KEYEMPTY: 104 return ret; 105 } 106 else 107 { 108 static assert(0, "Bad func name for DbRetCodeToException"); 109 } 110 111 case DB_LOCK_DEADLOCK: 112 throw new DbDeadlockException("BerkeleyDB error", ret, dbenv); 113 114 case DB_LOCK_NOTGRANTED: 115 throw new DbLockNotGrantedException("BerkeleyDB error", ret, dbenv, 116 op, mode, dbt, lock, index); 117 118 case DB_REP_HANDLE_DEAD: 119 throw new DbRepHandleDeadException("BerkeleyDB error", ret, dbenv); 120 121 case DB_RUNRECOVERY: 122 throw new DbRunRecoveryException("BerkeleyDB error", ret, dbenv); 123 124 static if(Func == "Dbc.get" 125 || Func == "Db.get" 126 || Func == "DbLogc.get") 127 { 128 case DB_BUFFER_SMALL: 129 if (dbt is null) 130 { 131 throw new DbException("BerkeleyDB error", ret, dbenv); 132 } 133 else if (dbt.flags & DB_DBT_USERMEM && dbt.size > dbt.ulen) 134 { 135 throw new DbMemoryException("BerkeleyDB error", ret, dbenv, dbt); 136 } 137 else 138 { 139 return ret; 140 } 141 } 142 143 default: 144 throw new DbException("BerkeleyDB error", ret, dbenv); 145 } 146 } 147 148 package auto DbRetCodeToException()(int ret, DbEnv dbenv = null, Dbt *dbt = null, 149 db_lockop_t op = 0, db_lockmode_t mode = 0, const (DB_LOCK) *lock = null, int index = 0) 150 { 151 DbRetCodeToException!"std"(ret, dbenv, dbt, op, mode, lock, index); 152 } 153 154 class DbException : Exception 155 { 156 int dberrno; 157 DbEnv dbenv; 158 159 package this(string msg_prefix, int errno, DbEnv env, string file = __FILE__, size_t line = __LINE__) 160 { 161 dberrno = errno; 162 dbenv = env; 163 164 char *strerror = db_strerror(dberrno); 165 super(msg_prefix~": "~to!string(strerror), file, line); 166 } 167 } 168 169 class DbWrongUsingException : Exception 170 { 171 package this(string msg, string file = __FILE__, size_t line = __LINE__) 172 { 173 super(msg, file, line); 174 } 175 } 176 177 178 class DbDeadlockException : DbException 179 { 180 package this(string msg_prefix, int errno, DbEnv env, string file = __FILE__, size_t line = __LINE__) 181 { 182 super(msg_prefix, errno, env, file, line); 183 } 184 } 185 186 class DbLockNotGrantedException : DbException 187 { 188 db_lockop_t op; 189 db_lockmode_t mode; 190 const (Dbt) *obj; 191 const (DB_LOCK) *lock; 192 int index; 193 package this(string msg_prefix, int errno, DbEnv env, 194 db_lockop_t _op, db_lockmode_t _mode, const (Dbt) *_obj, const (DB_LOCK) *_lock, int _index, 195 string file = __FILE__, size_t line = __LINE__) 196 { 197 op = _op; 198 mode = _mode; 199 obj = _obj; 200 lock = _lock; 201 index = _index; 202 super(msg_prefix, errno, env, file, line); 203 } 204 } 205 206 class DbMemoryException : DbException 207 { 208 Dbt *dbt; 209 package this(string msg_prefix, int errno, DbEnv env, Dbt *t, string file = __FILE__, size_t line = __LINE__) 210 { 211 dbt = t; 212 super(msg_prefix, errno, env, file, line); 213 } 214 } 215 216 class DbRepHandleDeadException : DbException 217 { 218 package this(string msg_prefix, int errno, DbEnv env, string file = __FILE__, size_t line = __LINE__) 219 { 220 super(msg_prefix, errno, env, file, line); 221 } 222 } 223 224 class DbRunRecoveryException : DbException 225 { 226 package this(string msg_prefix, int errno, DbEnv env, string file = __FILE__, size_t line = __LINE__) 227 { 228 super(msg_prefix, errno, env, file, line); 229 } 230 } 231