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.dbenv;
22 
23 import berkeleydb.c;
24 import berkeleydb.dbexception;
25 import berkeleydb.dbtxn;
26 import berkeleydb.dbt;
27 import berkeleydb.dblogc;
28 import berkeleydb.dblogverifyconfig;
29 import berkeleydb.dbmpoolfile;
30 import berkeleydb.dbchannel;
31 import berkeleydb.dbsite;
32 
33 import core.stdc.config;
34 import std.stdint;
35 import std.stdio;
36 import std.string;
37 import std.conv;
38 import std.array;
39 import std.format;
40 import core.sys.posix.pthread;
41 
42 version(Windows)
43 {
44 alias long bdb_time_t;
45 }
46 else
47 {
48 alias time_t bdb_time_t;
49 }
50 
51 alias DB_MEM_CONFIG DbMemConfig;
52 alias DB_LOCK DbLock;
53 alias DB_LOCK_STAT DbLockStat;
54 alias DB_LOCKREQ DbLockreq;
55 alias DB_LSN DbLsn;
56 alias DB_BACKUP_CONFIG DbBackupConfig;
57 alias DB_LOG_STAT DbLogStat;
58 alias DB_MPOOL_STAT DbMpoolStat;
59 alias DB_MPOOL_FSTAT DbMpoolFstat;
60 alias DB_TXN_STAT DbTxnStat;
61 alias DB_MUTEX_STAT DbMutexStat;
62 alias DB_REPMGR_SITE DbRepmgrSite;
63 alias DB_REPMGR_STAT DbRepmgrStat;
64 alias DB_REP_STAT DbRepStat;
65 alias DB_TXN_TOKEN DbTxnToken;
66 
67 class DbEnv
68 {
69 private:
70 	DB_ENV *dbenv = null;
71     int opened = 0;
72     int rep_transport = 0;
73     int rep_started = 0;
74     int repmgr_started = 0;
75     static DbEnv[DB_ENV *] dbenv_map;
76 
77     static DbEnv from_DB_ENV(const DB_ENV *_dbenv)
78     {
79         return dbenv_map[_dbenv];
80     }
81 
82 package:
83     @property DB_ENV *_DB_ENV() {return dbenv;}
84     @property int _opened() {return opened;}
85 
86 public:
87 	this(uint32_t flags = 0)
88 	{
89 		auto ret = db_env_create(&dbenv, flags);
90 		DbRetCodeToException(ret, this);
91         dbenv_map[dbenv] = this;
92         assert(ret == 0);
93 	}
94 
95 	~this()
96 	{
97 		if (opened >= 0) close();
98         dbenv_map.remove(dbenv);
99 	}
100 
101 	static ~this()
102 	{
103         dbenv_map = null;
104     }
105 
106     void open(string db_home, uint32_t flags, int mode)
107     {
108 		if (opened > 0) {
109 			throw new DbWrongUsingException("Opening opened DbEnv");
110 		}
111 		if (opened < 0) {
112 			throw new DbWrongUsingException("Opening closed DbEnv");
113 		}
114 		auto ret = dbenv.open(dbenv, db_home.toStringz(), flags, mode);
115 		DbRetCodeToException(ret, this);
116         assert(ret == 0);
117         opened++;
118     }
119 
120 	void close(uint32_t flags = 0)
121 	{
122 		if (opened < 0) {
123 			throw new DbWrongUsingException("Closing closed DbEnv");
124 		}
125 		auto ret = dbenv.close(dbenv, flags);
126         opened = -1;
127 		DbRetCodeToException(ret, this);
128         assert(ret == 0);
129 	}
130 
131     void backup(string target, uint32_t flags = 0)
132     {
133 		if (opened <= 0) {
134 			throw new DbWrongUsingException("Operation on closed or not opened DbEnv");
135 		}
136         auto ret = dbenv.backup(dbenv, target.toStringz(), flags);
137         DbRetCodeToException(ret, this);
138         assert(ret == 0);
139     }
140 
141     void dbbackup(string dbfile, string target, uint32_t flags = 0)
142     {
143 		if (opened <= 0) {
144 			throw new DbWrongUsingException("Operation on closed or not opened DbEnv");
145 		}
146         auto ret = dbenv.dbbackup(dbenv, dbfile.toStringz(), target.toStringz(), flags);
147         DbRetCodeToException(ret, this);
148         assert(ret == 0);
149     }
150 
151     void dbremove(DbTxn txnid, string file, string database, uint32_t flags = 0)
152     {
153 		if (opened < 0) {
154 			throw new DbWrongUsingException("Operation on closed DbEnv");
155 		}
156 		if (txnid && !txnid._DB_TXN) {
157 			throw new DbWrongUsingException("Operation on closed DbTxn");
158 		}
159         auto ret = dbenv.dbremove(dbenv, txnid?txnid._DB_TXN:null, file.toStringz(), database?database.toStringz():null, flags);
160         DbRetCodeToException(ret, this);
161         assert(ret == 0);
162     }
163 
164     void dbrename(DbTxn txnid, string file, string database, string newname, uint32_t flags = 0)
165     {
166 		if (opened < 0) {
167 			throw new DbWrongUsingException("Operation on closed DbEnv");
168 		}
169 		if (txnid && !txnid._DB_TXN) {
170 			throw new DbWrongUsingException("Operation on closed DbTxn");
171 		}
172         auto ret = dbenv.dbrename(dbenv, txnid?txnid._DB_TXN:null, file.toStringz(), database?database.toStringz():null, newname.toStringz(), flags);
173         DbRetCodeToException(ret, this);
174         assert(ret == 0);
175     }
176 
177     void err(T...)(int error, string fmt, T args)
178     {
179 		if (opened < 0) {
180 			throw new DbWrongUsingException("Operation on closed DbEnv");
181 		}
182         auto app = appender!string();
183         formattedWrite(app, fmt, args);
184         dbenv.err(dbenv, error, "%s".toStringz(), app.data.toStringz());
185     }
186 
187     void errx(T...)(string fmt, T args)
188     {
189 		if (opened < 0) {
190 			throw new DbWrongUsingException("Operation on closed DbEnv");
191 		}
192         auto app = appender!string();
193         formattedWrite(app, fmt, args);
194         dbenv.errx(dbenv, "%s".toStringz(), app.data.toStringz());
195     }
196 
197     void failchk(uint32_t flags = 0)
198     {
199 		if (opened <= 0) {
200 			throw new DbWrongUsingException("Operation on closed or not opened DbEnv");
201 		}
202         auto ret = dbenv.failchk(dbenv, flags);
203         DbRetCodeToException(ret, this);
204         assert(ret == 0);
205     }
206 
207     void fileid_reset(string file, uint32_t flags = 0)
208     {
209 		if (opened < 0) {
210 			throw new DbWrongUsingException("Operation on closed DbEnv");
211 		}
212         auto ret = dbenv.fileid_reset(dbenv, file.toStringz(), flags);
213         DbRetCodeToException(ret, this);
214         assert(ret == 0);
215     }
216 
217     static string db_full_version(int *family, int *release, int *major, int *minor, int *patch)
218     {
219         char *res = .db_full_version(family, release, major, minor, patch);
220         return to!string(res);
221     }
222 
223     static string db_full_version(out int family, out int release, out int major, out int minor, out int patch)
224     {
225         char *res = .db_full_version(&family, &release, &major, &minor, &patch);
226         return to!string(res);
227     }
228 
229     string get_home()
230     {
231 		if (opened < 0) {
232 			throw new DbWrongUsingException("Operation on closed DbEnv");
233 		}
234         const (char) *res;
235         auto ret = dbenv.get_home(dbenv, &res);
236         DbRetCodeToException(ret, this);
237         assert(ret == 0);
238         return to!string(res);
239     }
240 
241     uint32_t get_open_flags()
242     {
243 		if (opened <= 0) {
244 			throw new DbWrongUsingException("Operation on closed or not opened DbEnv");
245 		}
246         uint32_t res;
247         auto ret = dbenv.get_open_flags(dbenv, &res);
248         DbRetCodeToException(ret, this);
249         assert(ret == 0);
250         return res;
251     }
252 
253     void log_verify(ref const DbLogVerifyConfig config)
254     {
255 		if (opened < 0) {
256 			throw new DbWrongUsingException("Operation on closed DbEnv");
257 		}
258         auto ret = dbenv.log_verify(dbenv, &config);
259         DbRetCodeToException(ret, this);
260         assert(ret == 0);
261     }
262 
263     void lsn_reset(string file, uint32_t flags = 0)
264     {
265 		if (opened < 0) {
266 			throw new DbWrongUsingException("Operation on closed DbEnv");
267 		}
268         auto ret = dbenv.lsn_reset(dbenv, file.toStringz(), flags);
269         DbRetCodeToException(ret, this);
270         assert(ret == 0);
271     }
272 
273     void remove(string db_home, uint32_t flags = 0)
274     {
275 		if (opened < 0) {
276 			throw new DbWrongUsingException("Operation on closed DbEnv");
277 		}
278 		if (opened > 0) {
279 			throw new DbWrongUsingException("Removing opened DbEnv");
280 		}
281         auto ret = dbenv.remove(dbenv, db_home.toStringz(), flags);
282         opened = -1;
283         DbRetCodeToException(ret, this);
284         assert(ret == 0);
285     }
286 
287     void stat_print(uint32_t flags = 0)
288     {
289 		if (opened <= 0) {
290 			throw new DbWrongUsingException("Operation on closed or not opened DbEnv");
291 		}
292         auto ret = dbenv.stat_print(dbenv, flags);
293         DbRetCodeToException(ret, this);
294         assert(ret == 0);
295     }
296 
297     static string db_version(int *major, int *minor, int *patch)
298     {
299         char *res = .db_version(major, minor, patch);
300         return to!string(res);
301     }
302 
303     static string db_version(out int major, out int minor, out int patch)
304     {
305         char *res = .db_version(&major, &minor, &patch);
306         return to!string(res);
307     }
308 
309     /* Environment Configuration */
310 
311     void add_data_dir(string dir)
312     {
313 		if (opened < 0) {
314 			throw new DbWrongUsingException("Configuration on closed DbEnv");
315 		}
316 		if (opened > 0) {
317 			throw new DbWrongUsingException("Configuration of opened DbEnv");
318 		}
319         auto ret = dbenv.add_data_dir(dbenv, dir.toStringz());
320         DbRetCodeToException(ret, this);
321         assert(ret == 0);
322     }
323 
324     extern (C) void set_alloc(void *function(size_t) app_malloc,
325         void *function(void *, size_t) app_realloc, 
326         void function(void *) app_free)
327     {
328         if (opened < 0) {
329             throw new DbWrongUsingException("Configuration on closed DbEnv");
330         }
331         if (opened > 0) {
332             throw new DbWrongUsingException("Configuration of opened DbEnv");
333         }
334         auto ret = dbenv.set_alloc(dbenv, app_malloc, app_realloc, app_free);
335         DbRetCodeToException(ret, this);
336         assert(ret == 0);
337     }
338 
339     private
340     {
341         int function(DbEnv dbenv, Dbt *log_rec, DbLsn *lsn, db_recops op)
342             tx_recover_callback_refer;
343 
344         extern (C) static int tx_recover_callback(DB_ENV *_dbenv,
345                 DBT *_log_rec, DB_LSN *lsn, db_recops op)
346         {
347             DbEnv dbenv = from_DB_ENV(_dbenv);
348             Dbt *log_rec = cast(Dbt *) _log_rec;
349             return dbenv.tx_recover_callback_refer(dbenv, log_rec, lsn, op);
350         }
351     }
352 
353     void set_app_dispatch(int function(DbEnv dbenv,
354             Dbt *log_rec, DbLsn *lsn, db_recops op) tx_recover)
355     {
356         if (opened < 0) {
357             throw new DbWrongUsingException("Configuration on closed DbEnv");
358         }
359         if (opened > 0) {
360             throw new DbWrongUsingException("Configuration of opened DbEnv");
361         }
362         tx_recover_callback_refer = tx_recover;
363         auto ret = dbenv.set_app_dispatch(dbenv, tx_recover?&tx_recover_callback:null);
364         DbRetCodeToException(ret, this);
365         assert(ret == 0);
366     }
367 
368     private
369     {
370         int function(DbEnv, string dbname, string target, void **handle) open_callback_refer;
371 
372         extern (C) static int open_callback(DB_ENV *_dbenv, const (char) *_dbname, 
373                 const (char) *_target, void **handle)
374         {
375             DbEnv dbenv = from_DB_ENV(_dbenv);
376             string dbname = to!string(_dbname);
377             string target = to!string(_target);
378             return dbenv.open_callback_refer(dbenv, dbname, target, handle);
379         }
380 
381         int function(DbEnv, uint64_t offset, uint32_t size, 
382                 uint8_t *buf, void *handle) write_callback_refer;
383 
384         extern (C) static int write_callback(
385                 DB_ENV *_dbenv, uint32_t offset_gbytes, 
386                 uint32_t offset_bytes, uint32_t size, 
387                 uint8_t *buf, void *handle)
388         {
389             DbEnv dbenv = from_DB_ENV(_dbenv);
390             return dbenv.write_callback_refer(dbenv, 
391                     (1024UL*1024*1024)*offset_gbytes + offset_bytes, 
392                     size, buf, handle);
393         }
394 
395         int function(DbEnv, string dbname, void *handle) close_callback_refer;
396 
397         extern (C) static int close_callback(DB_ENV *_dbenv, const (char) *_dbname, void *handle)
398         {
399             DbEnv dbenv = from_DB_ENV(_dbenv);
400             string dbname = to!string(_dbname);
401             return dbenv.close_callback_refer(dbenv, dbname, handle);
402         }
403     }
404 
405     void set_backup_callbacks(int function(DbEnv, string dbname, 
406             string target, void **handle) open_func,
407         int function(DbEnv, uint64_t offset, uint32_t size, 
408             uint8_t *buf, void *handle) write_func,
409         int function(DbEnv, string dbname, void *handle) close_func)
410     {
411         if (opened < 0) {
412             throw new DbWrongUsingException("Configuration on closed DbEnv");
413         }
414         open_callback_refer = open_func;
415         write_callback_refer = write_func;
416         close_callback_refer = close_func;
417         auto ret = dbenv.set_backup_callbacks(dbenv, 
418                 open_func?&open_callback:null, 
419                 write_func?&write_callback:null, 
420                 close_func?&close_callback:null);
421         DbRetCodeToException(ret, this);
422         assert(ret == 0);
423     }
424 
425     /*FIXME: What we must return when callback references is null??? O_o*/
426     void get_backup_callbacks(ref int function(DbEnv, string dbname, 
427             string target, void **handle) open_func,
428         ref int function(DbEnv, uint64_t offset, uint32_t size, 
429             uint8_t *buf, void *handle) write_func,
430         ref int function(DbEnv, string dbname, void *handle) close_func)
431     {
432         if (opened < 0) {
433             throw new DbWrongUsingException("Get configuration on closed DbEnv");
434         }
435         open_func = open_callback_refer;
436         write_func = write_callback_refer;
437         close_func = close_callback_refer;
438     }
439 
440     void set_backup_config(DbBackupConfig option, uint32_t value)
441     {
442         if (opened < 0) {
443             throw new DbWrongUsingException("Configuration on closed DbEnv");
444         }
445 
446         auto ret = dbenv.set_backup_config(dbenv, option, value);
447         DbRetCodeToException(ret, this);
448         assert(ret == 0);
449     }
450 
451     uint32_t get_backup_config(DbBackupConfig option)
452     {
453         if (opened < 0) {
454             throw new DbWrongUsingException("Get configuration on closed DbEnv");
455         }
456 
457         uint32_t res;
458         auto ret = dbenv.get_backup_config(dbenv, option, &res);
459         DbRetCodeToException(ret, this);
460         assert(ret == 0);
461         return res;
462     }
463 
464     void set_data_dir(string dir)
465     {
466         if (opened < 0) {
467             throw new DbWrongUsingException("Configuration on closed DbEnv");
468         }
469         if (opened > 0) {
470             throw new DbWrongUsingException("Configuration of opened DbEnv");
471         }
472 
473         auto ret = dbenv.set_data_dir(dbenv, dir.toStringz());
474         DbRetCodeToException(ret, this);
475         assert(ret == 0);
476     }
477 
478     string[] get_data_dirs(const (char) ***dirpp)
479     {
480         if (opened < 0) {
481             throw new DbWrongUsingException("Get configuration on closed DbEnv");
482         }
483 
484         const(char) **_res;
485         auto ret = dbenv.get_data_dirs(dbenv, &_res);
486         DbRetCodeToException(ret, this);
487         assert(ret == 0);
488         string[] res = [];
489         for (const(char) **p=_res; *p; p++)
490             res ~= to!string(*p);
491 
492         return res;
493     }
494 
495     void set_create_dir(string dir)
496     {
497         if (opened < 0) {
498             throw new DbWrongUsingException("Configuration on closed DbEnv");
499         }
500 
501         auto ret = dbenv.set_create_dir(dbenv, dir.toStringz());
502         DbRetCodeToException(ret, this);
503         assert(ret == 0);
504     }
505 
506     string get_create_dir()
507     {
508         if (opened < 0) {
509             throw new DbWrongUsingException("Get configuration on closed DbEnv");
510         }
511 
512         const (char) *_res;
513         auto ret = dbenv.get_create_dir(dbenv, &_res);
514         DbRetCodeToException(ret, this);
515         assert(ret == 0);
516         return to!string(_res);
517     }
518 
519     void set_encrypt(string passwd, uint32_t flags = 0)
520     {
521         if (opened < 0) {
522             throw new DbWrongUsingException("Configuration on closed DbEnv");
523         }
524         if (opened > 0) {
525             throw new DbWrongUsingException("Configuration of opened DbEnv");
526         }
527 
528         auto ret = dbenv.set_encrypt(dbenv, passwd.toStringz(), flags);
529         DbRetCodeToException(ret, this);
530         assert(ret == 0);
531     }
532 
533     uint32_t get_encrypt_flags()
534     {
535         if (opened < 0) {
536             throw new DbWrongUsingException("Get configuration on closed DbEnv");
537         }
538         uint32_t res;
539         auto ret = dbenv.get_encrypt_flags(dbenv, &res);
540         DbRetCodeToException(ret, this);
541         assert(ret == 0);
542         return res;
543     }
544 
545     private
546     {
547         void function(DbEnv dbenv, uint32_t event, void *event_info) db_event_callback_refer;
548 
549         extern (C) static void db_event_callback(DB_ENV *_dbenv, uint32_t event, void *event_info)
550         {
551             DbEnv dbenv = from_DB_ENV(_dbenv);
552             dbenv.db_event_callback_refer(dbenv, event, event_info);
553         }
554     }
555 
556     void set_event_notify(void function(DbEnv dbenv, uint32_t event, 
557                 void *event_info) db_event_fcn)
558     {
559         if (opened < 0) {
560             throw new DbWrongUsingException("Configuration on closed DbEnv");
561         }
562         db_event_callback_refer = db_event_fcn;
563         auto ret = dbenv.set_event_notify(dbenv, db_event_fcn?&db_event_callback:null);
564         DbRetCodeToException(ret, this);
565         assert(ret == 0);
566     }
567 
568     private
569     {
570         void function (const DbEnv dbenv, string errpfx, string msg) db_err_callback_refer;
571 
572         extern (C) static void db_err_callback (const (DB_ENV) *_dbenv, const (char) *_errpfx, const (char) *_msg)
573         {
574             DbEnv dbenv = from_DB_ENV(_dbenv);
575             string errpfx = to!string(_errpfx);
576             string msg = to!string(_msg);
577             dbenv.db_err_callback_refer(dbenv, errpfx, msg);
578         }
579     }
580 
581     void set_errcall(void function (const DbEnv dbenv, string errpfx, string msg) db_errcall_fcn)
582     {
583         if (opened < 0) {
584             throw new DbWrongUsingException("Configuration on closed DbEnv");
585         }
586         db_err_callback_refer = db_errcall_fcn;
587         dbenv.set_errcall(dbenv, db_errcall_fcn?&db_err_callback:null);
588     }
589 
590     private File _errfile;
591 
592     void set_errfile(File errfile)
593     {
594         if (opened < 0) {
595             throw new DbWrongUsingException("Configuration on closed DbEnv");
596         }
597         _errfile = errfile;
598         dbenv.set_errfile(dbenv, errfile.getFP());
599     }
600 
601     File get_errfile()
602     {
603         if (opened < 0) {
604             throw new DbWrongUsingException("Get configuration on closed DbEnv");
605         }
606         return _errfile;
607     }
608 
609     void set_errpfx(string errpfx)
610     {
611         if (opened < 0) {
612             throw new DbWrongUsingException("Configuration on closed DbEnv");
613         }
614         dbenv.set_errpfx(dbenv, errpfx.toStringz());
615     }
616 
617     string get_errpfx()
618     {
619         if (opened < 0) {
620             throw new DbWrongUsingException("Get configuration on closed DbEnv");
621         }
622         const (char) *res;
623         dbenv.get_errpfx(dbenv, &res);
624         return to!string(res);
625     }
626 
627     private
628     {
629         void function(DbEnv dbenv, int opcode, int percent) db_feedback_callback_refer;
630 
631         extern (C) static void db_feedback_callback(DB_ENV *_dbenv, int opcode, int percent)
632         {
633             DbEnv dbenv = from_DB_ENV(_dbenv);
634             dbenv.db_feedback_callback_refer(dbenv, opcode, percent);
635         }
636     }
637     
638     void set_feedback(void function(DbEnv dbenv, int opcode, int percent) db_feedback_fcn)
639     {
640         if (opened < 0) {
641             throw new DbWrongUsingException("Configuration on closed DbEnv");
642         }
643         db_feedback_callback_refer = db_feedback_fcn;
644         auto ret = dbenv.set_feedback(dbenv, db_feedback_fcn?&db_feedback_callback:null);
645         DbRetCodeToException(ret, this);
646         assert(ret == 0);
647     }
648 
649     void set_flags(uint32_t flags, int onoff)
650     {
651         if (opened < 0) {
652             throw new DbWrongUsingException("Configuration on closed DbEnv");
653         }
654         auto ret = dbenv.set_flags(dbenv, flags, onoff);
655         DbRetCodeToException(ret, this);
656         assert(ret == 0);
657     }
658 
659     uint32_t get_flags()
660     {
661         if (opened < 0) {
662             throw new DbWrongUsingException("Get configuration on closed DbEnv");
663         }
664         uint32_t res;
665         auto ret = dbenv.get_flags(dbenv, &res);
666         DbRetCodeToException(ret, this);
667         assert(ret == 0);
668         return res;
669     }
670 
671     void set_intermediate_dir_mode(string mode)
672     {
673         if (opened < 0) {
674             throw new DbWrongUsingException("Configuration on closed DbEnv");
675         }
676         if (opened > 0) {
677             throw new DbWrongUsingException("Configuration of opened DbEnv");
678         }
679 
680         auto ret = dbenv.set_intermediate_dir_mode(dbenv, mode.toStringz());
681         DbRetCodeToException(ret, this);
682         assert(ret == 0);
683     }
684 
685     string get_intermediate_dir_mode()
686     {
687         if (opened < 0) {
688             throw new DbWrongUsingException("Get configuration on closed DbEnv");
689         }
690         const (char) *res;
691         auto ret = dbenv.get_intermediate_dir_mode(dbenv, &res);
692         DbRetCodeToException(ret, this);
693         assert(ret == 0);
694         return to!string(res);
695     }
696 
697     private
698     {
699         int function(DbEnv dbenv, 
700                 pid_t pid, db_threadid_t tid, uint32_t flags = 0) is_alive_callback_refer;
701 
702         extern (C) static int is_alive_callback(DB_ENV *_dbenv, 
703                 pid_t pid, db_threadid_t tid, uint32_t flags = 0)
704         {
705             DbEnv dbenv = from_DB_ENV(_dbenv);
706             return dbenv.is_alive_callback_refer(dbenv, pid, tid, flags);
707         }
708     }
709 
710     void set_isalive(int function(DbEnv dbenv, 
711                 pid_t pid, db_threadid_t tid, uint32_t flags = 0) is_alive)
712     {
713         if (opened < 0) {
714             throw new DbWrongUsingException("Configuration on closed DbEnv");
715         }
716         is_alive_callback_refer = is_alive;
717         auto ret = dbenv.set_isalive(dbenv, is_alive?&is_alive_callback:null);
718         DbRetCodeToException(ret, this);
719         assert(ret == 0);
720     }
721 
722     void set_memory_init(DbMemConfig type, uint32_t count)
723     {
724         if (opened < 0) {
725             throw new DbWrongUsingException("Configuration on closed DbEnv");
726         }
727         if (opened > 0) {
728             throw new DbWrongUsingException("Configuration of opened DbEnv");
729         }
730 
731         auto ret = dbenv.set_memory_init(dbenv, type, count);
732         DbRetCodeToException(ret, this);
733         assert(ret == 0);
734     }
735 
736     uint32_t get_memory_init(DbMemConfig type)
737     {
738         if (opened < 0) {
739             throw new DbWrongUsingException("Get configuration on closed DbEnv");
740         }
741         uint32_t res;
742         auto ret = dbenv.get_memory_init(dbenv, type, &res);
743         DbRetCodeToException(ret, this);
744         assert(ret == 0);
745         return res;
746     }
747 
748     void set_memory_max(uint32_t gbytes, uint32_t bytes)
749     {
750         if (opened < 0) {
751             throw new DbWrongUsingException("Configuration on closed DbEnv");
752         }
753         if (opened > 0) {
754             throw new DbWrongUsingException("Configuration of opened DbEnv");
755         }
756 
757         auto ret = dbenv.set_memory_max(dbenv, gbytes, bytes);
758         DbRetCodeToException(ret, this);
759         assert(ret == 0);
760     }
761 
762     void set_memory_max(uint64_t bytes)
763     {
764         uint32_t _gbytes = cast(uint32_t) bytes/(1024*1024*1024);
765         uint32_t _bytes = bytes%(1024*1024*1024);
766         set_memory_max(_gbytes, _bytes);
767     }
768 
769     void get_memory_max(ref uint32_t gbytes, ref uint32_t bytes)
770     {
771         if (opened < 0) {
772             throw new DbWrongUsingException("Get configuration on closed DbEnv");
773         }
774         auto ret = dbenv.get_memory_max(dbenv, &gbytes, &bytes);
775         DbRetCodeToException(ret, this);
776         assert(ret == 0);
777     }
778 
779     uint64_t get_memory_max()
780     {
781         uint32_t gbytes;
782         uint32_t bytes;
783         get_memory_max(gbytes, bytes);
784         return (1024UL*1024*1024)*gbytes + bytes;
785     }
786 
787     void set_metadata_dir(string dir)
788     {
789         if (opened < 0) {
790             throw new DbWrongUsingException("Configuration on closed DbEnv");
791         }
792         if (opened > 0) {
793             throw new DbWrongUsingException("Configuration of opened DbEnv");
794         }
795 
796         auto ret = dbenv.set_metadata_dir(dbenv, dir.toStringz());
797         DbRetCodeToException(ret, this);
798         assert(ret == 0);
799     }
800 
801     string get_metadata_dir()
802     {
803         if (opened < 0) {
804             throw new DbWrongUsingException("Get configuration on closed DbEnv");
805         }
806         const (char) *res;
807         auto ret = dbenv.get_metadata_dir(dbenv, &res);
808         DbRetCodeToException(ret, this);
809         assert(ret == 0);
810         return to!string(res);
811     }
812 
813     private
814     {
815         void function(const DbEnv dbenv, string msg) db_msg_callback_refer;
816 
817         extern (C) static void db_msg_callback(const (DB_ENV) *_dbenv, const (char) *_msg)
818         {
819             DbEnv dbenv = from_DB_ENV(_dbenv);
820             string msg = to!string(_msg);
821             return dbenv.db_msg_callback_refer(dbenv, msg);
822         }
823     }
824 
825     void set_msgcall(void function(const DbEnv dbenv, string msg) db_msgcall_fcn)
826     {
827         if (opened < 0) {
828             throw new DbWrongUsingException("Configuration on closed DbEnv");
829         }
830         db_msg_callback_refer = db_msgcall_fcn;
831         dbenv.set_msgcall(dbenv, db_msgcall_fcn?&db_msg_callback:null);
832     }
833 
834     private File _msgfile;
835 
836     void set_msgfile(File msgfile)
837     {
838         if (opened < 0) {
839             throw new DbWrongUsingException("Configuration on closed DbEnv");
840         }
841         _msgfile = msgfile;
842         dbenv.set_msgfile(dbenv, msgfile.getFP());
843     }
844 
845     File get_msgfile()
846     {
847         if (opened < 0) {
848             throw new DbWrongUsingException("Get configuration on closed DbEnv");
849         }
850         return _msgfile;
851     }
852 
853     void set_shm_key(c_long shm_key)
854     {
855         if (opened < 0) {
856             throw new DbWrongUsingException("Configuration on closed DbEnv");
857         }
858         if (opened > 0) {
859             throw new DbWrongUsingException("Configuration of opened DbEnv");
860         }
861 
862         auto ret = dbenv.set_shm_key(dbenv, shm_key);
863         DbRetCodeToException(ret, this);
864         assert(ret == 0);
865     }
866 
867     c_long get_shm_key()
868     {
869         if (opened < 0) {
870             throw new DbWrongUsingException("Get configuration on closed DbEnv");
871         }
872         c_long res;
873         auto ret = dbenv.get_shm_key(dbenv, &res);
874         DbRetCodeToException(ret, this);
875         assert(ret == 0);
876         return res;
877     }
878 
879     void set_thread_count(uint32_t count)
880     {
881         if (opened < 0) {
882             throw new DbWrongUsingException("Configuration on closed DbEnv");
883         }
884         if (opened > 0) {
885             throw new DbWrongUsingException("Configuration of opened DbEnv");
886         }
887 
888         auto ret = dbenv.set_thread_count(dbenv, count);
889         DbRetCodeToException(ret, this);
890         assert(ret == 0);
891     }
892 
893     uint32_t get_thread_count()
894     {
895         if (opened < 0) {
896             throw new DbWrongUsingException("Get configuration on closed DbEnv");
897         }
898         uint32_t res;
899         auto ret = dbenv.get_thread_count(dbenv, &res);
900         DbRetCodeToException(ret, this);
901         assert(ret == 0);
902         return res;
903     }
904 
905     private
906     {
907         void function(DbEnv dbenv, pid_t *pid, db_threadid_t *tid) thread_id_callback_refer;
908 
909         extern (C) static void thread_id_callback(DB_ENV *_dbenv, pid_t *pid, db_threadid_t *tid)
910         {
911             DbEnv dbenv = from_DB_ENV(_dbenv);
912             return dbenv.thread_id_callback_refer(dbenv, pid, tid);
913         }
914     }
915 
916     void set_thread_id(void function(DbEnv dbenv, pid_t *pid, db_threadid_t *tid) thread_id)
917     {
918         if (opened < 0) {
919             throw new DbWrongUsingException("Configuration on closed DbEnv");
920         }
921         thread_id_callback_refer = thread_id;
922         auto ret = dbenv.set_thread_id(dbenv, thread_id?&thread_id_callback:null);
923         DbRetCodeToException(ret, this);
924         assert(ret == 0);
925     }
926 
927     private
928     {
929         char *function(DbEnv dbenv,
930                 pid_t pid, db_threadid_t tid, char *buf) thread_id_string_callback_refer;
931 
932         extern (C) static char *thread_id_string_callback(DB_ENV *_dbenv,
933                 pid_t pid, db_threadid_t tid, char *buf)
934         {
935             DbEnv dbenv = from_DB_ENV(_dbenv);
936             return dbenv.thread_id_string_callback_refer(dbenv, pid, tid, buf);
937         }
938     }
939 
940     void set_thread_id_string(char *function(DbEnv dbenv,
941                 pid_t pid, db_threadid_t tid, char *buf) thread_id_string)
942     {
943         if (opened < 0) {
944             throw new DbWrongUsingException("Configuration on closed DbEnv");
945         }
946         thread_id_string_callback_refer = thread_id_string;
947         auto ret = dbenv.set_thread_id_string(dbenv, thread_id_string?&thread_id_string_callback:null);
948         DbRetCodeToException(ret, this);
949         assert(ret == 0);
950     }
951 
952     void set_timeout(db_timeout_t timeout, uint32_t flags = 0)
953     {
954         if (opened < 0) {
955             throw new DbWrongUsingException("Configuration on closed DbEnv");
956         }
957         auto ret = dbenv.set_timeout(dbenv, timeout, flags);
958         DbRetCodeToException(ret, this);
959         assert(ret == 0);
960     }
961 
962     db_timeout_t get_timeout(uint32_t flag)
963     {
964         if (opened < 0) {
965             throw new DbWrongUsingException("Get configuration on closed DbEnv");
966         }
967         db_timeout_t res;
968         auto ret = dbenv.get_timeout(dbenv, &res, flag);
969         DbRetCodeToException(ret, this);
970         assert(ret == 0);
971         return res;
972     }
973 
974     void set_tmp_dir(string dir)
975     {
976         if (opened < 0) {
977             throw new DbWrongUsingException("Configuration on closed DbEnv");
978         }
979         auto ret = dbenv.set_tmp_dir(dbenv, dir.toStringz());
980         DbRetCodeToException(ret, this);
981         assert(ret == 0);
982     }
983 
984     string get_tmp_dir()
985     {
986         if (opened < 0) {
987             throw new DbWrongUsingException("Get configuration on closed DbEnv");
988         }
989         const (char) *res;
990         auto ret = dbenv.get_tmp_dir(dbenv, &res);
991         DbRetCodeToException(ret, this);
992         assert(ret == 0);
993         return to!string(res);
994     }
995 
996     void set_verbose(uint32_t which, int onoff)
997     {
998         if (opened < 0) {
999             throw new DbWrongUsingException("Configuration on closed DbEnv");
1000         }
1001         auto ret = dbenv.set_verbose(dbenv, which, onoff);
1002         DbRetCodeToException(ret, this);
1003         assert(ret == 0);
1004     }
1005 
1006     int get_verbose(uint32_t which)
1007     {
1008         if (opened < 0) {
1009             throw new DbWrongUsingException("Get configuration on closed DbEnv");
1010         }
1011         int res;
1012         auto ret = dbenv.get_verbose(dbenv, which, &res);
1013         DbRetCodeToException(ret, this);
1014         assert(ret == 0);
1015         return res;
1016     }
1017 
1018     void set_cachesize(uint32_t gbytes, uint32_t bytes, int ncache)
1019     {
1020         if (opened < 0) {
1021             throw new DbWrongUsingException("Configuration on closed DbEnv");
1022         }
1023         auto ret = dbenv.set_cachesize(dbenv, gbytes, bytes, ncache);
1024         DbRetCodeToException(ret, this);
1025         assert(ret == 0);
1026     }
1027 
1028     void set_cachesize(uint64_t bytes, int ncache)
1029     {
1030         uint32_t _gbytes = cast(uint32_t) bytes/(1024*1024*1024);
1031         uint32_t _bytes = bytes%(1024*1024*1024);
1032         set_cachesize(_gbytes, _bytes, ncache);
1033     }
1034 
1035     void get_cachesize(ref uint32_t gbytes, ref uint32_t bytes, ref int ncache)
1036     {
1037         if (opened < 0) {
1038             throw new DbWrongUsingException("Get configuration on closed DbEnv");
1039         }
1040         auto ret = dbenv.get_cachesize(dbenv, &gbytes, &bytes, &ncache);
1041         DbRetCodeToException(ret, this);
1042         assert(ret == 0);
1043     }
1044 
1045     uint64_t get_memory_max(ref int ncache)
1046     {
1047         uint32_t gbytes;
1048         uint32_t bytes;
1049         get_cachesize(gbytes, bytes, ncache);
1050         return (1024UL*1024*1024)*gbytes + bytes;
1051     }
1052 
1053     void get_memory_max(ref uint64_t _bytes, ref int ncache)
1054     {
1055         uint32_t gbytes;
1056         uint32_t bytes;
1057         get_cachesize(gbytes, bytes, ncache);
1058         _bytes = (1024UL*1024*1024)*gbytes + bytes;
1059     }
1060 
1061     /* Locking Subsystem and Related Methods */
1062     void lock_detect(uint32_t flags, uint32_t atype, int *rejected)
1063     {
1064         if (opened < 0) {
1065             throw new DbWrongUsingException("Lock operation on closed DbEnv");
1066         }
1067         auto ret = dbenv.lock_detect(dbenv, flags, atype, rejected);
1068         DbRetCodeToException(ret, this);
1069         assert(ret == 0);
1070     }
1071 
1072     void lock_get(uint32_t locker, uint32_t flags, Dbt *object,
1073         db_lockmode_t lock_mode, DbLock *lock)
1074     {
1075         if (opened < 0) {
1076             throw new DbWrongUsingException("Lock operation on closed DbEnv");
1077         }
1078         auto ret = dbenv.lock_get(dbenv, locker, flags, &object.dbt,
1079                 lock_mode, lock);
1080         DbRetCodeToException(ret, this, object, DB_LOCK_GET, lock_mode, lock, -1);
1081         assert(ret == 0);
1082     }
1083 
1084     DbLock lock_get(uint32_t locker, uint32_t flags, Dbt *object,
1085         db_lockmode_t lock_mode)
1086     {
1087         DbLock res;
1088         lock_get(locker, flags, object, lock_mode, &res);
1089         return res;
1090     }
1091 
1092     uint32_t lock_id()
1093     {
1094         if (opened < 0) {
1095             throw new DbWrongUsingException("Lock operation on closed DbEnv");
1096         }
1097         uint32_t res;
1098         auto ret = dbenv.lock_id(dbenv, &res);
1099         DbRetCodeToException(ret, this);
1100         assert(ret == 0);
1101         return res;
1102     }
1103 
1104     void lock_id_free(uint32_t id)
1105     {
1106         if (opened < 0) {
1107             throw new DbWrongUsingException("Lock operation on closed DbEnv");
1108         }
1109         auto ret = dbenv.lock_id_free(dbenv, id);
1110         DbRetCodeToException(ret, this);
1111         assert(ret == 0);
1112     }
1113     
1114     void lock_put(ref DbLock lock)
1115     {
1116         if (opened < 0) {
1117             throw new DbWrongUsingException("Lock operation on closed DbEnv");
1118         }
1119         auto ret = dbenv.lock_put(dbenv, &lock);
1120         DbRetCodeToException(ret, this);
1121         assert(ret == 0);
1122     }
1123 
1124     DbLockStat *lock_stat(uint32_t flags = 0)
1125     {
1126         if (opened <= 0) {
1127             throw new DbWrongUsingException("Lock operation on closed or not opened DbEnv");
1128         }
1129         DbLockStat *res;
1130         auto ret = dbenv.lock_stat(dbenv, &res, flags);
1131         DbRetCodeToException(ret, this);
1132         assert(ret == 0);
1133         return res;
1134     }
1135 
1136     void lock_stat_print(uint32_t flags = 0)
1137     {
1138         if (opened <= 0) {
1139             throw new DbWrongUsingException("Lock operation on closed or not opened DbEnv");
1140         }
1141         auto ret = dbenv.lock_stat_print(dbenv, flags);
1142         DbRetCodeToException(ret, this);
1143         assert(ret == 0);
1144     }
1145 
1146     void lock_vec(uint32_t locker, uint32_t flags, DbLockreq[] list)
1147     {
1148         if (opened < 0) {
1149             throw new DbWrongUsingException("Lock operation on closed DbEnv");
1150         }
1151         DbLockreq *elist;
1152         auto ret = dbenv.lock_vec(dbenv, locker, flags, list.ptr, cast(uint)list.length, &elist);
1153         if (ret && elist) DbRetCodeToException(ret, this, 
1154                 cast(Dbt*)elist.obj, elist.op, elist.mode, &elist.lock, cast(int)(elist-list.ptr));
1155         else DbRetCodeToException(ret, this);
1156         assert(ret == 0);
1157     }
1158 
1159     DbTxn cdsgroup_begin()
1160     {
1161         if (opened < 0) {
1162             throw new DbWrongUsingException("Lock operation on closed DbEnv");
1163         }
1164         DB_TXN *_tid;
1165         auto ret = dbenv.cdsgroup_begin(dbenv, &_tid);
1166         DbRetCodeToException(ret, this);
1167         assert(ret == 0);
1168         return new DbTxn(_tid, this);
1169     }
1170 
1171     /* Locking Subsystem Configuration */
1172 
1173     void set_lk_conflicts(uint8_t[] conflicts, int nmodes)
1174     {
1175         if (opened < 0) {
1176             throw new DbWrongUsingException("Lock configuration on closed DbEnv");
1177         }
1178         if (opened > 0) {
1179             throw new DbWrongUsingException("Lock configuration of opened DbEnv");
1180         }
1181         if (conflicts.length != nmodes*nmodes)
1182         {
1183             throw new DbWrongUsingException("conflicts must have nmodes x nmodes size");
1184         }
1185         auto ret = dbenv.set_lk_conflicts(dbenv, conflicts.ptr, nmodes);
1186         DbRetCodeToException(ret, this);
1187         assert(ret == 0);
1188     }
1189 
1190     void get_lk_conflicts(ref const (uint8_t)[] lk_conflicts, ref int lk_modes)
1191     {
1192         if (opened < 0) {
1193             throw new DbWrongUsingException("Lock configuration on closed DbEnv");
1194         }
1195         const(uint8_t) *conflicts;
1196         auto ret = dbenv.get_lk_conflicts(dbenv, &conflicts, &lk_modes);
1197         DbRetCodeToException(ret, this);
1198         assert(ret == 0);
1199         lk_conflicts = conflicts[0..lk_modes*lk_modes];
1200     }
1201 
1202     void set_lk_detect(uint32_t detect)
1203     {
1204         if (opened < 0) {
1205             throw new DbWrongUsingException("Lock configuration on closed DbEnv");
1206         }
1207         auto ret = dbenv.set_lk_detect(dbenv, detect);
1208         DbRetCodeToException(ret, this);
1209         assert(ret == 0);
1210     }
1211 
1212     uint32_t get_lk_detect()
1213     {
1214         if (opened < 0) {
1215             throw new DbWrongUsingException("Lock configuration on closed DbEnv");
1216         }
1217         uint32_t res;
1218         auto ret = dbenv.get_lk_detect(dbenv, &res);
1219         DbRetCodeToException(ret, this);
1220         assert(ret == 0);
1221         return res;
1222     }
1223 
1224     void set_lk_max_lockers(uint32_t max)
1225     {
1226         if (opened < 0) {
1227             throw new DbWrongUsingException("Lock configuration on closed DbEnv");
1228         }
1229         if (opened > 0) {
1230             throw new DbWrongUsingException("Lock configuration of opened DbEnv");
1231         }
1232         auto ret = dbenv.set_lk_max_lockers(dbenv, max);
1233         DbRetCodeToException(ret, this);
1234         assert(ret == 0);
1235     }
1236 
1237     uint32_t get_lk_max_lockers()
1238     {
1239         if (opened < 0) {
1240             throw new DbWrongUsingException("Lock configuration on closed DbEnv");
1241         }
1242         uint32_t res;
1243         auto ret = dbenv.get_lk_max_lockers(dbenv, &res);
1244         DbRetCodeToException(ret, this);
1245         assert(ret == 0);
1246         return res;
1247     }
1248 
1249     void set_lk_max_locks(uint32_t max)
1250     {
1251         if (opened < 0) {
1252             throw new DbWrongUsingException("Lock configuration on closed DbEnv");
1253         }
1254         if (opened > 0) {
1255             throw new DbWrongUsingException("Lock configuration of opened DbEnv");
1256         }
1257         auto ret = dbenv.set_lk_max_locks(dbenv, max);
1258         DbRetCodeToException(ret, this);
1259         assert(ret == 0);
1260     }
1261 
1262     uint32_t get_lk_max_locks()
1263     {
1264         if (opened < 0) {
1265             throw new DbWrongUsingException("Lock configuration on closed DbEnv");
1266         }
1267         uint32_t res;
1268         auto ret = dbenv.get_lk_max_locks(dbenv, &res);
1269         DbRetCodeToException(ret, this);
1270         assert(ret == 0);
1271         return res;
1272     }
1273 
1274     void set_lk_max_objects(uint32_t max)
1275     {
1276         if (opened < 0) {
1277             throw new DbWrongUsingException("Lock configuration on closed DbEnv");
1278         }
1279         if (opened > 0) {
1280             throw new DbWrongUsingException("Lock configuration of opened DbEnv");
1281         }
1282         auto ret = dbenv.set_lk_max_objects(dbenv, max);
1283         DbRetCodeToException(ret, this);
1284         assert(ret == 0);
1285     }
1286 
1287     uint32_t get_lk_max_objects()
1288     {
1289         if (opened < 0) {
1290             throw new DbWrongUsingException("Lock configuration on closed DbEnv");
1291         }
1292         uint32_t res;
1293         auto ret = dbenv.get_lk_max_objects(dbenv, &res);
1294         DbRetCodeToException(ret, this);
1295         assert(ret == 0);
1296         return res;
1297     }
1298 
1299     void set_lk_partitions(uint32_t partitions)
1300     {
1301         if (opened < 0) {
1302             throw new DbWrongUsingException("Lock configuration on closed DbEnv");
1303         }
1304         if (opened > 0) {
1305             throw new DbWrongUsingException("Lock configuration of opened DbEnv");
1306         }
1307         auto ret = dbenv.set_lk_partitions(dbenv, partitions);
1308         DbRetCodeToException(ret, this);
1309         assert(ret == 0);
1310     }
1311 
1312     uint32_t get_lk_partitions()
1313     {
1314         if (opened < 0) {
1315             throw new DbWrongUsingException("Lock configuration on closed DbEnv");
1316         }
1317         uint32_t res;
1318         auto ret = dbenv.get_lk_partitions(dbenv, &res);
1319         DbRetCodeToException(ret, this);
1320         assert(ret == 0);
1321         return res;
1322     }
1323 
1324     void set_lk_priority(uint32_t lockerid, uint32_t priority)
1325     {
1326         if (opened < 0) {
1327             throw new DbWrongUsingException("Lock configuration on closed DbEnv");
1328         }
1329         auto ret = dbenv.set_lk_priority(dbenv, lockerid, priority);
1330         DbRetCodeToException(ret, this);
1331         assert(ret == 0);
1332     }
1333 
1334     uint32_t get_lk_priority(uint32_t lockerid)
1335     {
1336         if (opened < 0) {
1337             throw new DbWrongUsingException("Lock configuration on closed DbEnv");
1338         }
1339         uint32_t res;
1340         auto ret = dbenv.get_lk_priority(dbenv, lockerid, &res);
1341         DbRetCodeToException(ret, this);
1342         assert(ret == 0);
1343         return res;
1344     }
1345 
1346     void set_lk_tablesize(uint32_t tablesize)
1347     {
1348         if (opened < 0) {
1349             throw new DbWrongUsingException("Lock configuration on closed DbEnv");
1350         }
1351         if (opened > 0) {
1352             throw new DbWrongUsingException("Lock configuration of opened DbEnv");
1353         }
1354         auto ret = dbenv.set_lk_tablesize(dbenv, tablesize);
1355         DbRetCodeToException(ret, this);
1356         assert(ret == 0);
1357     }
1358 
1359     uint32_t get_lk_tablesize()
1360     {
1361         if (opened < 0) {
1362             throw new DbWrongUsingException("Lock configuration on closed DbEnv");
1363         }
1364         uint32_t res;
1365         auto ret = dbenv.get_lk_tablesize(dbenv, &res);
1366         DbRetCodeToException(ret, this);
1367         assert(ret == 0);
1368         return res;
1369     }
1370 
1371     /* Logging Subsystem and Related Methods */
1372     string[] log_archive(uint32_t flags = 0)
1373     {
1374         if (opened < 0) {
1375             throw new DbWrongUsingException("Log operation on closed DbEnv");
1376         }
1377         string[] list;
1378         char **_list;
1379         auto ret = dbenv.log_archive(dbenv, &_list, flags);
1380         DbRetCodeToException(ret, this);
1381         assert(ret == 0);
1382 
1383         if (!_list)
1384         {
1385             list = null;
1386         }
1387         else
1388         {
1389             list = [];
1390             char **ptr;
1391             for (ptr = _list; *ptr; ptr++)
1392             {
1393                 list ~= to!string(*ptr);
1394             }
1395         }
1396         return list;
1397     }
1398 
1399     string log_file(const (DbLsn) *lsn)
1400     {
1401         if (opened < 0) {
1402             throw new DbWrongUsingException("Log operation on closed DbEnv");
1403         }
1404         /* According documentation "Log filenames are always 14 characters long" */
1405         char[16] name;
1406         auto ret = dbenv.log_file(dbenv, lsn, name.ptr, name.length);
1407         DbRetCodeToException(ret, this);
1408         assert(ret == 0);
1409         return to!string(name.ptr);
1410     }
1411 
1412     void log_flush(const (DbLsn) *lsn)
1413     {
1414         if (opened < 0) {
1415             throw new DbWrongUsingException("Log operation on closed DbEnv");
1416         }
1417         auto ret = dbenv.log_flush(dbenv, lsn);
1418         DbRetCodeToException(ret, this);
1419         assert(ret == 0);
1420     }
1421 
1422     void log_printf(T...)(DbTxn *txnid, string fmt, T args)
1423     {
1424         if (opened < 0) {
1425             throw new DbWrongUsingException("Log operation on closed DbEnv");
1426         }
1427         auto app = appender!string();
1428         formattedWrite(app, fmt, args);
1429         auto ret = dbenv.log_printf(dbenv, txnid?txnid._DB_TXN:null, "%s".toStringz(), app.data.toStringz());
1430         DbRetCodeToException(ret, this);
1431         assert(ret == 0);
1432     }
1433 
1434     void log_put(DbLsn *lsn, const (Dbt) *data, uint32_t flags = 0)
1435     {
1436         if (opened < 0) {
1437             throw new DbWrongUsingException("Log operation on closed DbEnv");
1438         }
1439         auto ret = dbenv.log_put(dbenv, lsn, &data.dbt, flags);
1440         DbRetCodeToException(ret, this);
1441         assert(ret == 0);
1442     }
1443 
1444     DbLogStat *log_stat(uint32_t flags = 0)
1445     {
1446         if (opened < 0) {
1447             throw new DbWrongUsingException("Log operation on closed DbEnv");
1448         }
1449         DbLogStat *res;
1450         auto ret = dbenv.log_stat(dbenv, &res, flags);
1451         DbRetCodeToException(ret, this);
1452         assert(ret == 0);
1453         return res;
1454     }
1455 
1456     void log_stat_print(uint32_t flags = 0)
1457     {
1458         if (opened < 0) {
1459             throw new DbWrongUsingException("Log operation on closed DbEnv");
1460         }
1461         auto ret = dbenv.log_stat_print(dbenv, flags);
1462         DbRetCodeToException(ret, this);
1463         assert(ret == 0);
1464     }
1465 
1466     /* Logging Subsystem Cursors */
1467     DbLogc log_cursor(uint32_t flags = 0)
1468     {
1469         if (opened < 0) {
1470             throw new DbWrongUsingException("Log operation on closed DbEnv");
1471         }
1472         DB_LOGC *res;
1473         auto ret = dbenv.log_cursor(dbenv, &res, flags);
1474         DbRetCodeToException(ret, this);
1475         assert(ret == 0);
1476         return new DbLogc(res, this);
1477     }
1478 
1479     /* Logging Subsystem Configuration */
1480     void log_set_config(uint32_t flags, int onoff)
1481     {
1482         if (opened < 0) {
1483             throw new DbWrongUsingException("Log configuration on closed DbEnv");
1484         }
1485         auto ret = dbenv.log_set_config(dbenv, flags, onoff);
1486         DbRetCodeToException(ret, this);
1487         assert(ret == 0);
1488     }
1489 
1490     int log_get_config(uint32_t which)
1491     {
1492         if (opened < 0) {
1493             throw new DbWrongUsingException("Log configuration on closed DbEnv");
1494         }
1495         int res;
1496         auto ret = dbenv.log_get_config(dbenv, which, &res);
1497         DbRetCodeToException(ret, this);
1498         assert(ret == 0);
1499         return res;
1500     }
1501 
1502     void set_lg_bsize(uint32_t lg_bsize)
1503     {
1504         if (opened < 0) {
1505             throw new DbWrongUsingException("Log configuration on closed DbEnv");
1506         }
1507         if (opened > 0) {
1508             throw new DbWrongUsingException("Log configuration of opened DbEnv");
1509         }
1510         auto ret = dbenv.set_lg_bsize(dbenv, lg_bsize);
1511         DbRetCodeToException(ret, this);
1512         assert(ret == 0);
1513     }
1514 
1515     uint32_t get_lg_bsize()
1516     {
1517         if (opened < 0) {
1518             throw new DbWrongUsingException("Log configuration on closed DbEnv");
1519         }
1520         uint32_t res;
1521         auto ret = dbenv.get_lg_bsize(dbenv, &res);
1522         DbRetCodeToException(ret, this);
1523         assert(ret == 0);
1524         return res;
1525     }
1526 
1527     void set_lg_dir(string dir)
1528     {
1529         if (opened < 0) {
1530             throw new DbWrongUsingException("Log configuration on closed DbEnv");
1531         }
1532         if (opened > 0) {
1533             throw new DbWrongUsingException("Log configuration of opened DbEnv");
1534         }
1535         auto ret = dbenv.set_lg_dir(dbenv, dir.toStringz());
1536         DbRetCodeToException(ret, this);
1537         assert(ret == 0);
1538     }
1539 
1540     string get_lg_dir()
1541     {
1542         if (opened < 0) {
1543             throw new DbWrongUsingException("Log configuration on closed DbEnv");
1544         }
1545         const (char) *res;
1546         auto ret = dbenv.get_lg_dir(dbenv, &res);
1547         DbRetCodeToException(ret, this);
1548         assert(ret == 0);
1549         return to!string(res);
1550     }
1551 
1552     void set_lg_filemode(int lg_filemode)
1553     {
1554         if (opened < 0) {
1555             throw new DbWrongUsingException("Log configuration on closed DbEnv");
1556         }
1557         auto ret = dbenv.set_lg_filemode(dbenv, lg_filemode);
1558         DbRetCodeToException(ret, this);
1559         assert(ret == 0);
1560     }
1561 
1562     int get_lg_filemode()
1563     {
1564         if (opened < 0) {
1565             throw new DbWrongUsingException("Log configuration on closed DbEnv");
1566         }
1567         int res;
1568         auto ret = dbenv.get_lg_filemode(dbenv, &res);
1569         DbRetCodeToException(ret, this);
1570         assert(ret == 0);
1571         return res;
1572     }
1573 
1574     void set_lg_max(uint32_t lg_max)
1575     {
1576         if (opened < 0) {
1577             throw new DbWrongUsingException("Log configuration on closed DbEnv");
1578         }
1579         auto ret = dbenv.set_lg_max(dbenv, lg_max);
1580         DbRetCodeToException(ret, this);
1581         assert(ret == 0);
1582     }
1583 
1584     uint32_t get_lg_max()
1585     {
1586         if (opened < 0) {
1587             throw new DbWrongUsingException("Log configuration on closed DbEnv");
1588         }
1589         uint32_t res;
1590         auto ret = dbenv.get_lg_max(dbenv, &res);
1591         DbRetCodeToException(ret, this);
1592         assert(ret == 0);
1593         return res;
1594     }
1595 
1596     void set_lg_regionmax(uint32_t lg_regionmax)
1597     {
1598         if (opened < 0) {
1599             throw new DbWrongUsingException("Log configuration on closed DbEnv");
1600         }
1601         if (opened > 0) {
1602             throw new DbWrongUsingException("Log configuration of opened DbEnv");
1603         }
1604         auto ret = dbenv.set_lg_regionmax(dbenv, lg_regionmax);
1605         DbRetCodeToException(ret, this);
1606         assert(ret == 0);
1607     }
1608 
1609     uint32_t get_lg_regionmax()
1610     {
1611         if (opened < 0) {
1612             throw new DbWrongUsingException("Log configuration on closed DbEnv");
1613         }
1614         uint32_t res;
1615         auto ret = dbenv.get_lg_regionmax(dbenv, &res);
1616         DbRetCodeToException(ret, this);
1617         assert(ret == 0);
1618         return res;
1619     }
1620 
1621     /* Memory Pools and Related Methods */
1622     void memp_stat(ref DbMpoolStat *gs, ref DbMpoolFstat*[] fs, uint32_t flags = 0)
1623     {
1624         if (opened <= 0) {
1625             throw new DbWrongUsingException("Memory pool operation on closed or not opened DbEnv");
1626         }
1627         DbMpoolFstat **fsp;
1628         auto ret = dbenv.memp_stat(dbenv, &gs, &fsp, flags);
1629         DbRetCodeToException(ret, this);
1630         assert(ret == 0);
1631 
1632         if (fsp == null) fs = null;
1633         else
1634         {
1635             DbMpoolFstat **ptr;
1636             for (ptr = fsp; *ptr; ptr++)
1637                 fs ~= *ptr;
1638         }
1639     }
1640 
1641     void memp_stat_print(uint32_t flags = 0)
1642     {
1643         if (opened <= 0) {
1644             throw new DbWrongUsingException("Memory pool operation on closed or not opened DbEnv");
1645         }
1646         auto ret = dbenv.memp_stat_print(dbenv, flags);
1647         DbRetCodeToException(ret, this);
1648         assert(ret == 0);
1649     }
1650 
1651     void memp_sync(DbLsn *lsn)
1652     {
1653         if (opened < 0) {
1654             throw new DbWrongUsingException("Memory pool operation on closed DbEnv");
1655         }
1656         auto ret = dbenv.memp_sync(dbenv, lsn);
1657         DbRetCodeToException(ret, this);
1658         assert(ret == 0);
1659     }
1660 
1661     int memp_trickle(int percent)
1662     {
1663         if (opened < 0) {
1664             throw new DbWrongUsingException("Memory pool operation on closed DbEnv");
1665         }
1666         int nwrote;
1667         auto ret = dbenv.memp_trickle(dbenv, percent, &nwrote);
1668         DbRetCodeToException(ret, this);
1669         assert(ret == 0);
1670         return nwrote;
1671     }
1672 
1673     /* Memory Pool Configuration */
1674     private
1675     {
1676         int function(DbEnv env, db_pgno_t pgno, void *pgaddr, 
1677                 Dbt *pgcookie) pgin_callback_refer;
1678 
1679         extern (C) static int pgin_callback(DB_ENV *_env, db_pgno_t pgno, void *pgaddr, 
1680                 DBT *_pgcookie)
1681         {
1682             DbEnv dbenv = from_DB_ENV(_env);
1683             Dbt *pgcookie = cast(Dbt*)_pgcookie;
1684             return dbenv.pgin_callback_refer(dbenv, pgno, pgaddr, pgcookie);
1685         }
1686 
1687         int function(DbEnv env, db_pgno_t pgno, 
1688                 void *pgaddr, Dbt *pgcookie) pgout_callback_refer;
1689 
1690         extern (C) static int pgout_callback(DB_ENV *_env, db_pgno_t pgno, 
1691                 void *pgaddr, DBT *_pgcookie)
1692         {
1693             DbEnv dbenv = from_DB_ENV(_env);
1694             Dbt *pgcookie = cast(Dbt*)_pgcookie;
1695             return dbenv.pgout_callback_refer(dbenv, pgno, pgaddr, pgcookie);
1696         }
1697     }
1698     
1699     void memp_register(int ftype,
1700         int function(DbEnv env, db_pgno_t pgno, void *pgaddr, 
1701         Dbt *pgcookie) pgin_fcn, int function(DbEnv env, db_pgno_t pgno, 
1702         void *pgaddr, Dbt *pgcookie) pgout_fcn)
1703     {
1704         if (opened < 0) {
1705             throw new DbWrongUsingException("Memory Pool configuration on closed DbEnv");
1706         }
1707         pgin_callback_refer = pgin_fcn;
1708         pgout_callback_refer = pgout_fcn;
1709         auto ret = dbenv.memp_register(dbenv, ftype, 
1710                 pgin_fcn?&pgin_callback:null,
1711                 pgout_fcn?&pgout_callback:null);
1712         DbRetCodeToException(ret, this);
1713         assert(ret == 0);
1714     }
1715 
1716     void set_cache_max(uint32_t gbytes, uint32_t bytes)
1717     {
1718         if (opened < 0) {
1719             throw new DbWrongUsingException("Memory Pool configuration on closed DbEnv");
1720         }
1721         if (opened > 0) {
1722             throw new DbWrongUsingException("Memory Pool configuration of opened DbEnv");
1723         }
1724         auto ret = dbenv.set_cache_max(dbenv, gbytes, bytes);
1725         DbRetCodeToException(ret, this);
1726         assert(ret == 0);
1727     }
1728 
1729     void set_cache_max(uint64_t bytes)
1730     {
1731         uint32_t _gbytes = cast(uint32_t) bytes/(1024*1024*1024);
1732         uint32_t _bytes = bytes%(1024*1024*1024);
1733         set_cache_max(_gbytes, _bytes);
1734     }
1735 
1736     void get_cache_max(ref uint32_t gbytes, uint32_t bytes)
1737     {
1738         if (opened < 0) {
1739             throw new DbWrongUsingException("Memory Pool configuration on closed DbEnv");
1740         }
1741         auto ret = dbenv.get_cache_max(dbenv, &gbytes, &bytes);
1742         DbRetCodeToException(ret, this);
1743         assert(ret == 0);
1744     }
1745 
1746     uint64_t get_cache_max()
1747     {
1748         uint32_t gbytes;
1749         uint32_t bytes;
1750         get_cache_max(gbytes, bytes);
1751         return (1024UL*1024*1024)*gbytes + bytes;
1752     }
1753 
1754     void set_mp_max_openfd(int maxopenfd)
1755     {
1756         if (opened < 0) {
1757             throw new DbWrongUsingException("Memory Pool configuration on closed DbEnv");
1758         }
1759         auto ret = dbenv.set_mp_max_openfd(dbenv, maxopenfd);
1760         DbRetCodeToException(ret, this);
1761         assert(ret == 0);
1762     }
1763 
1764     int get_mp_max_openfd()
1765     {
1766         if (opened < 0) {
1767             throw new DbWrongUsingException("Memory Pool configuration on closed DbEnv");
1768         }
1769         int res;
1770         auto ret = dbenv.get_mp_max_openfd(dbenv, &res);
1771         DbRetCodeToException(ret, this);
1772         assert(ret == 0);
1773         return res;
1774     }
1775 
1776     void set_mp_max_write(int maxwrite, db_timeout_t maxwrite_sleep)
1777     {
1778         if (opened < 0) {
1779             throw new DbWrongUsingException("Memory Pool configuration on closed DbEnv");
1780         }
1781         auto ret = dbenv.set_mp_max_write(dbenv, maxwrite, maxwrite_sleep);
1782         DbRetCodeToException(ret, this);
1783         assert(ret == 0);
1784     }
1785 
1786     void get_mp_max_write(ref int maxwrite, 
1787                          ref db_timeout_t maxwrite_sleep)
1788     {
1789         if (opened < 0) {
1790             throw new DbWrongUsingException("Memory Pool configuration on closed DbEnv");
1791         }
1792         auto ret = dbenv.get_mp_max_write(dbenv, &maxwrite, &maxwrite_sleep);
1793         DbRetCodeToException(ret, this);
1794         assert(ret == 0);
1795     }
1796 
1797     void set_mp_mmapsize(size_t mp_mmapsize)
1798     {
1799         if (opened < 0) {
1800             throw new DbWrongUsingException("Memory Pool configuration on closed DbEnv");
1801         }
1802         auto ret = dbenv.set_mp_mmapsize(dbenv, mp_mmapsize);
1803         DbRetCodeToException(ret, this);
1804         assert(ret == 0);
1805     }
1806 
1807     size_t get_mp_mmapsize(DB_ENV *dbenv)
1808     {
1809         if (opened < 0) {
1810             throw new DbWrongUsingException("Memory Pool configuration on closed DbEnv");
1811         }
1812         size_t res;
1813         auto ret = dbenv.get_mp_mmapsize(dbenv, &res);
1814         DbRetCodeToException(ret, this);
1815         assert(ret == 0);
1816         return res;
1817     }
1818 
1819     void set_mp_mtxcount(uint32_t mtxcount)
1820     {
1821         if (opened < 0) {
1822             throw new DbWrongUsingException("Memory Pool configuration on closed DbEnv");
1823         }
1824         if (opened > 0) {
1825             throw new DbWrongUsingException("Memory Pool configuration of opened DbEnv");
1826         }
1827         auto ret = dbenv.set_mp_mtxcount(dbenv, mtxcount);
1828         DbRetCodeToException(ret, this);
1829         assert(ret == 0);
1830     }
1831 
1832     uint32_t get_mp_mtxcount()
1833     {
1834         if (opened < 0) {
1835             throw new DbWrongUsingException("Memory Pool configuration on closed DbEnv");
1836         }
1837         uint32_t res;
1838         auto ret = dbenv.get_mp_mtxcount(dbenv, &res);
1839         DbRetCodeToException(ret, this);
1840         assert(ret == 0);
1841         return res;
1842     }
1843 
1844     void set_mp_pagesize(uint32_t pagesize)
1845     {
1846         if (opened < 0) {
1847             throw new DbWrongUsingException("Memory Pool configuration on closed DbEnv");
1848         }
1849         if (opened > 0) {
1850             throw new DbWrongUsingException("Memory Pool configuration of opened DbEnv");
1851         }
1852         auto ret = dbenv.set_mp_pagesize(dbenv, pagesize);
1853         DbRetCodeToException(ret, this);
1854         assert(ret == 0);
1855     }
1856 
1857     uint32_t get_mp_pagesize()
1858     {
1859         if (opened < 0) {
1860             throw new DbWrongUsingException("Memory Pool configuration on closed DbEnv");
1861         }
1862         uint32_t res;
1863         auto ret = dbenv.get_mp_pagesize(dbenv, &res);
1864         DbRetCodeToException(ret, this);
1865         assert(ret == 0);
1866         return res;
1867     }
1868 
1869     void set_mp_tablesize(uint32_t tablesize)
1870     {
1871         if (opened < 0) {
1872             throw new DbWrongUsingException("Memory Pool configuration on closed DbEnv");
1873         }
1874         if (opened > 0) {
1875             throw new DbWrongUsingException("Memory Pool configuration of opened DbEnv");
1876         }
1877         auto ret = dbenv.set_mp_tablesize(dbenv, tablesize);
1878         DbRetCodeToException(ret, this);
1879         assert(ret == 0);
1880     }
1881 
1882     uint32_t get_mp_tablesize()
1883     {
1884         if (opened < 0) {
1885             throw new DbWrongUsingException("Memory Pool configuration on closed DbEnv");
1886         }
1887         uint32_t res;
1888         auto ret = dbenv.get_mp_tablesize(dbenv, &res);
1889         DbRetCodeToException(ret, this);
1890         assert(ret == 0);
1891         return res;
1892     }
1893 
1894     /* Memory Pool Files */
1895     DbMpoolfile memp_fcreate(uint32_t flags = 0)
1896     {
1897         if (opened < 0) {
1898             throw new DbWrongUsingException("Memory Pool operation on closed DbEnv");
1899         }
1900         DB_MPOOLFILE *dbmf;
1901         auto ret = dbenv.memp_fcreate(dbenv, &dbmf, flags);
1902         DbRetCodeToException(ret, this);
1903         assert(ret == 0);
1904         return new DbMpoolfile(dbmf, this);
1905     }
1906 
1907     /* Transaction Subsystem and Related Methods */
1908     c_long txn_recover(DB_PREPLIST[] preplist, uint32_t flags = 0)
1909     {
1910         if (opened < 0) {
1911             throw new DbWrongUsingException("Transaction configuration on closed DbEnv");
1912         }
1913         c_long res;
1914         auto ret = dbenv.txn_recover(dbenv, preplist.ptr, cast(int)preplist.count, &res, flags);
1915         DbRetCodeToException(ret, this);
1916         assert(ret == 0);
1917         return res;
1918     }
1919 
1920     void txn_checkpoint(uint32_t kbyte, uint32_t min, uint32_t flags = 0)
1921     {
1922         if (opened < 0) {
1923             throw new DbWrongUsingException("Transaction configuration on closed DbEnv");
1924         }
1925         auto ret = dbenv.txn_checkpoint(dbenv, kbyte, min, flags);
1926         DbRetCodeToException(ret, this);
1927         assert(ret == 0);
1928     }
1929 
1930     DbTxnStat *txn_stat(uint32_t flags = 0)
1931     {
1932         if (opened <= 0) {
1933             throw new DbWrongUsingException("Transaction configuration on closed or not opened DbEnv");
1934         }
1935         DbTxnStat *res;
1936         auto ret = dbenv.txn_stat(dbenv, &res, flags);
1937         DbRetCodeToException(ret, this);
1938         assert(ret == 0);
1939         return res;
1940     }
1941 
1942     void txn_stat_print(uint32_t flags = 0)
1943     {
1944         if (opened <= 0) {
1945             throw new DbWrongUsingException("Transaction configuration on closed or not opened DbEnv");
1946         }
1947         auto ret = dbenv.txn_stat_print(dbenv, flags);
1948         DbRetCodeToException(ret, this);
1949         assert(ret == 0);
1950     }
1951 
1952     /* Transaction Subsystem Configuration */
1953     void set_tx_max(uint32_t max)
1954     {
1955         if (opened < 0) {
1956             throw new DbWrongUsingException("Transaction configuration on closed DbEnv");
1957         }
1958         if (opened > 0) {
1959             throw new DbWrongUsingException("Transaction configuration of opened DbEnv");
1960         }
1961         auto ret = dbenv.set_tx_max(dbenv, max);
1962         DbRetCodeToException(ret, this);
1963         assert(ret == 0);
1964     }
1965 
1966     uint32_t get_tx_max()
1967     {
1968         if (opened < 0) {
1969             throw new DbWrongUsingException("Transaction configuration on closed DbEnv");
1970         }
1971         uint32_t res;
1972         auto ret = dbenv.get_tx_max(dbenv, &res);
1973         DbRetCodeToException(ret, this);
1974         assert(ret == 0);
1975         return res;
1976     }
1977 
1978     void set_tx_timestamp(ref bdb_time_t timestamp)
1979     {
1980         if (opened < 0) {
1981             throw new DbWrongUsingException("Transaction configuration on closed DbEnv");
1982         }
1983         if (opened > 0) {
1984             throw new DbWrongUsingException("Transaction configuration of opened DbEnv");
1985         }
1986         auto ret = dbenv.set_tx_timestamp(dbenv, &timestamp);
1987         DbRetCodeToException(ret, this);
1988         assert(ret == 0);
1989     }
1990 
1991     bdb_time_t get_tx_timestamp()
1992     {
1993         if (opened < 0) {
1994             throw new DbWrongUsingException("Transaction configuration on closed DbEnv");
1995         }
1996         bdb_time_t res;
1997         auto ret = dbenv.get_tx_timestamp(dbenv, &res);
1998         DbRetCodeToException(ret, this);
1999         assert(ret == 0);
2000         return res;
2001     }
2002 
2003     /* Transaction Operations */
2004     DbTxn txn_begin(DbTxn parent, uint32_t flags = 0)
2005     {
2006         if (opened < 0) {
2007             throw new DbWrongUsingException("Transaction configuration on closed DbEnv");
2008         }
2009         DB_TXN *res;
2010         auto ret = dbenv.txn_begin(dbenv, parent?parent._DB_TXN:null, &res, flags);
2011         DbRetCodeToException(ret, this);
2012         assert(ret == 0);
2013         return new DbTxn(res, this);
2014     }
2015     
2016     /* BLOB Configuration */
2017 version(VERSION_6)
2018 {
2019     void set_blob_dir(string dir)
2020     {
2021         if (opened < 0) {
2022             throw new DbWrongUsingException("BLOB configuration on closed DbEnv");
2023         }
2024         if (opened > 0) {
2025             throw new DbWrongUsingException("BLOB configuration of opened DbEnv");
2026         }
2027         auto ret = dbenv.set_blob_dir(dbenv, dir.toStringz());
2028         DbRetCodeToException(ret, this);
2029         assert(ret == 0);
2030     }
2031 
2032     string get_blob_dir()
2033     {
2034         if (opened < 0) {
2035             throw new DbWrongUsingException("BLOB configuration on closed DbEnv");
2036         }
2037         const (char) *res;
2038         auto ret = dbenv.get_blob_dir(dbenv, &res);
2039         DbRetCodeToException(ret, this);
2040         assert(ret == 0);
2041         return to!string(res);
2042     }
2043 
2044     void set_blob_threshold(uint32_t bytes, uint32_t flags = 0)
2045     {
2046         if (opened < 0) {
2047             throw new DbWrongUsingException("Transaction configuration on closed DbEnv");
2048         }
2049         auto ret = dbenv.set_blob_threshold(dbenv, bytes, flags);
2050         DbRetCodeToException(ret, this);
2051         assert(ret == 0);
2052     }
2053 
2054     uint32_t get_blob_threshold()
2055     {
2056         if (opened < 0) {
2057             throw new DbWrongUsingException("Transaction configuration on closed DbEnv");
2058         }
2059         uint32_t res;
2060         auto ret = dbenv.get_blob_threshold(dbenv, &res);
2061         DbRetCodeToException(ret, this);
2062         assert(ret == 0);
2063         return res;
2064     }
2065 }
2066     /* Mutex Methods */
2067     void mutex_alloc(uint32_t flags, ref db_mutex_t mutex)
2068     {
2069         if (opened <= 0) {
2070             throw new DbWrongUsingException("Mutex operation on closed or not opened DbEnv");
2071         }
2072         auto ret = dbenv.mutex_alloc(dbenv, flags, &mutex);
2073         DbRetCodeToException(ret, this);
2074         assert(ret == 0);
2075     }
2076 
2077     void mutex_free(db_mutex_t mutex)
2078     {
2079         if (opened <= 0) {
2080             throw new DbWrongUsingException("Mutex operation on closed or not opened DbEnv");
2081         }
2082         auto ret = dbenv.mutex_free(dbenv, mutex);
2083         DbRetCodeToException(ret, this);
2084         assert(ret == 0);
2085     }
2086 
2087     void mutex_lock(db_mutex_t mutex)
2088     {
2089         if (opened <= 0) {
2090             throw new DbWrongUsingException("Mutex operation on closed or not opened DbEnv");
2091         }
2092         auto ret = dbenv.mutex_lock(dbenv, mutex);
2093         DbRetCodeToException(ret, this);
2094         assert(ret == 0);
2095     }
2096 
2097     DbMutexStat *mutex_stat(uint32_t flags = 0)
2098     {
2099         if (opened <= 0) {
2100             throw new DbWrongUsingException("Mutex operation on closed or not opened DbEnv");
2101         }
2102         DbMutexStat *res;
2103         auto ret = dbenv.mutex_stat(dbenv, &res, flags);
2104         DbRetCodeToException(ret, this);
2105         assert(ret == 0);
2106         return res;
2107     }
2108 
2109     void mutex_stat_print(uint32_t flags = 0)
2110     {
2111         if (opened <= 0) {
2112             throw new DbWrongUsingException("Mutex operation on closed or not opened DbEnv");
2113         }
2114         auto ret = dbenv.mutex_stat_print(dbenv, flags);
2115         DbRetCodeToException(ret, this);
2116         assert(ret == 0);
2117     }
2118 
2119     void mutex_unlock(db_mutex_t mutex)
2120     {
2121         if (opened <= 0) {
2122             throw new DbWrongUsingException("Mutex operation on closed or not opened DbEnv");
2123         }
2124         auto ret = dbenv.mutex_unlock(dbenv, mutex);
2125         DbRetCodeToException(ret, this);
2126         assert(ret == 0);
2127     }
2128 
2129     /* Mutex Configuration */
2130     void mutex_set_align(uint32_t alignment)
2131     {
2132         if (opened < 0) {
2133             throw new DbWrongUsingException("Mutex configuration on closed DbEnv");
2134         }
2135         if (opened > 0) {
2136             throw new DbWrongUsingException("Mutex configuration on opened DbEnv");
2137         }
2138         auto ret = dbenv.mutex_set_align(dbenv, alignment);
2139         DbRetCodeToException(ret, this);
2140         assert(ret == 0);
2141     }
2142 
2143     uint32_t mutex_get_align()
2144     {
2145         if (opened < 0) {
2146             throw new DbWrongUsingException("Mutex configuration on closed DbEnv");
2147         }
2148         uint32_t res;
2149         auto ret = dbenv.mutex_get_align(dbenv, &res);
2150         DbRetCodeToException(ret, this);
2151         assert(ret == 0);
2152         return res;
2153     }
2154 
2155     void mutex_set_increment(uint32_t increment)
2156     {
2157         if (opened < 0) {
2158             throw new DbWrongUsingException("Mutex configuration on closed DbEnv");
2159         }
2160         if (opened > 0) {
2161             throw new DbWrongUsingException("Mutex configuration on opened DbEnv");
2162         }
2163         auto ret = dbenv.mutex_set_increment(dbenv, increment);
2164         DbRetCodeToException(ret, this);
2165         assert(ret == 0);
2166     }
2167 
2168     uint32_t mutex_get_increment()
2169     {
2170         if (opened < 0) {
2171             throw new DbWrongUsingException("Mutex configuration on closed DbEnv");
2172         }
2173         uint32_t res;
2174         auto ret = dbenv.mutex_get_increment(dbenv, &res);
2175         DbRetCodeToException(ret, this);
2176         assert(ret == 0);
2177         return res;
2178     }
2179 
2180     void mutex_set_init(uint32_t init)
2181     {
2182         if (opened < 0) {
2183             throw new DbWrongUsingException("Mutex configuration on closed DbEnv");
2184         }
2185         if (opened > 0) {
2186             throw new DbWrongUsingException("Mutex configuration on opened DbEnv");
2187         }
2188         auto ret = dbenv.mutex_set_init(dbenv, init);
2189         DbRetCodeToException(ret, this);
2190         assert(ret == 0);
2191     }
2192 
2193     uint32_t mutex_get_init()
2194     {
2195         if (opened < 0) {
2196             throw new DbWrongUsingException("Mutex configuration on closed DbEnv");
2197         }
2198         uint32_t res;
2199         auto ret = dbenv.mutex_get_init(dbenv, &res);
2200         DbRetCodeToException(ret, this);
2201         assert(ret == 0);
2202         return res;
2203     }
2204 
2205     void mutex_set_max(uint32_t max)
2206     {
2207         if (opened < 0) {
2208             throw new DbWrongUsingException("Mutex configuration on closed DbEnv");
2209         }
2210         if (opened > 0) {
2211             throw new DbWrongUsingException("Mutex configuration on opened DbEnv");
2212         }
2213         auto ret = dbenv.mutex_set_max(dbenv, max);
2214         DbRetCodeToException(ret, this);
2215         assert(ret == 0);
2216     }
2217 
2218     uint32_t mutex_get_max()
2219     {
2220         if (opened < 0) {
2221             throw new DbWrongUsingException("Mutex configuration on closed DbEnv");
2222         }
2223         uint32_t res;
2224         auto ret = dbenv.mutex_get_max(dbenv, &res);
2225         DbRetCodeToException(ret, this);
2226         assert(ret == 0);
2227         return res;
2228     }
2229 
2230     void mutex_set_tas_spins(uint32_t tas_spins)
2231     {
2232         if (opened < 0) {
2233             throw new DbWrongUsingException("Mutex configuration on closed DbEnv");
2234         }
2235         auto ret = dbenv.mutex_set_tas_spins(dbenv, tas_spins);
2236         DbRetCodeToException(ret, this);
2237         assert(ret == 0);
2238     }
2239 
2240     uint32_t mutex_get_tas_spins()
2241     {
2242         if (opened < 0) {
2243             throw new DbWrongUsingException("Mutex configuration on closed DbEnv");
2244         }
2245         uint32_t res;
2246         auto ret = dbenv.mutex_get_tas_spins(dbenv, &res);
2247         DbRetCodeToException(ret, this);
2248         assert(ret == 0);
2249         return res;
2250     }
2251 
2252     /* Replication and Related Methods */
2253     DbChannel repmgr_channel(int eid, uint32_t flags = 0)
2254     {
2255         if (opened < 0) {
2256             throw new DbWrongUsingException("Replication operation on closed DbEnv");
2257         }
2258         if (repmgr_started <= 0) {
2259             throw new DbWrongUsingException("Replication operation before repmgr_start() on DbEnv");
2260         }
2261         DB_CHANNEL *res;
2262         auto ret = dbenv.repmgr_channel(dbenv, eid, &res, flags);
2263         DbRetCodeToException(ret, this);
2264         assert(ret == 0);
2265         return new DbChannel(res, this);
2266     }
2267 
2268     /* This version throws DB_NOTFOUND as exception */
2269     DbSite repmgr_local_site()
2270     {
2271         if (opened < 0) {
2272             throw new DbWrongUsingException("Replication operation on closed DbEnv");
2273         }
2274         DB_SITE *res;
2275         auto ret = dbenv.repmgr_local_site(dbenv, &res);
2276         DbRetCodeToException(ret, this);
2277         assert(ret == 0);
2278         return new DbSite(res, this);
2279     }
2280 
2281     int repmgr_local_site(ref DbSite dbsite)
2282     {
2283         if (opened < 0) {
2284             throw new DbWrongUsingException("Replication operation on closed DbEnv");
2285         }
2286         DB_SITE *res;
2287         auto ret = dbenv.repmgr_local_site(dbenv, &res);
2288         dbsite = new DbSite(res, this);
2289         return DbRetCodeToException!"repmgr_localsite"(ret, this);
2290     }
2291 
2292     private
2293     {
2294         void function (DbEnv env, DbChannel channel, 
2295                 Dbt[] request, uint32_t cb_flags) msg_dispatch_callback_refer;
2296 
2297         extern (C) static void msg_dispatch_callback (DB_ENV *_env, DB_CHANNEL *_channel, 
2298                 DBT *_request, uint32_t nrequest,
2299                 uint32_t cb_flags)
2300         {
2301             DbEnv env = from_DB_ENV(_env);
2302             DbChannel channel = DbChannel.from_DB_CHANNEL(_channel);
2303             Dbt[] request = (cast(Dbt *)_request)[0..nrequest];
2304             return env.msg_dispatch_callback_refer(env, channel, request, cb_flags);
2305         }
2306     }
2307 
2308     void repmgr_msg_dispatch(void function (DbEnv env, DbChannel channel, 
2309                 Dbt[] request, uint32_t cb_flags) msg_dispatch_fcn, uint32_t flags = 0)
2310     {
2311         if (opened < 0) {
2312             throw new DbWrongUsingException("Replication configuration on closed DbEnv");
2313         }
2314         if (repmgr_started > 0) {
2315             throw new DbWrongUsingException("Replication configuration after repmgr_start() on DbEnv");
2316         }
2317         msg_dispatch_callback_refer = msg_dispatch_fcn;
2318         auto ret = dbenv.repmgr_msg_dispatch(dbenv, msg_dispatch_fcn?&msg_dispatch_callback:null, flags);
2319         DbRetCodeToException(ret, this);
2320         assert(ret == 0);
2321     }
2322 
2323     void repmgr_set_ack_policy(int ack_policy)
2324     {
2325         if (opened < 0) {
2326             throw new DbWrongUsingException("Replication configuration on closed DbEnv");
2327         }
2328         auto ret = dbenv.repmgr_set_ack_policy(dbenv, ack_policy);
2329         DbRetCodeToException(ret, this);
2330         assert(ret == 0);
2331     }
2332 
2333     int repmgr_get_ack_policy()
2334     {
2335         if (opened < 0) {
2336             throw new DbWrongUsingException("Replication configuration on closed DbEnv");
2337         }
2338         int res;
2339         auto ret = dbenv.repmgr_get_ack_policy(dbenv, &res);
2340         DbRetCodeToException(ret, this);
2341         assert(ret == 0);
2342         return res;
2343     }
2344 
2345     DbSite repmgr_site(string host, uint port, uint32_t flags = 0)
2346     {
2347         if (opened < 0) {
2348             throw new DbWrongUsingException("Replication operation on closed DbEnv");
2349         }
2350         DB_SITE *res;
2351         auto ret = dbenv.repmgr_site(dbenv, host.toStringz(), port, &res, flags);
2352         DbRetCodeToException(ret, this);
2353         assert(ret == 0);
2354         return new DbSite(res, this);
2355     }
2356 
2357     DbSite repmgr_site_by_eid(int eid)
2358     {
2359         if (opened < 0) {
2360             throw new DbWrongUsingException("Replication operation on closed DbEnv");
2361         }
2362         DB_SITE *res;
2363         auto ret = dbenv.repmgr_site_by_eid(dbenv, eid, &res);
2364         DbRetCodeToException(ret, this);
2365         assert(ret == 0);
2366         return new DbSite(res, this);
2367     }
2368 
2369     DbRepmgrSite[] repmgr_site_list()
2370     {
2371         if (opened < 0) {
2372             throw new DbWrongUsingException("Replication configuration on closed DbEnv");
2373         }
2374         if (repmgr_started <= 0) {
2375             throw new DbWrongUsingException("Replication configuration before repmgr_start() on DbEnv");
2376         }
2377         DbRepmgrSite *list;
2378         uint count;
2379         auto ret = dbenv.repmgr_site_list(dbenv, &count, &list);
2380         DbRetCodeToException(ret, this);
2381         assert(ret == 0);
2382         return list[0..count];
2383     }
2384 
2385     int repmgr_start(int nthreads, uint32_t flags = 0)
2386     {
2387         if (opened <= 0) {
2388             throw new DbWrongUsingException("Replication operation on closed or not opened DbEnv");
2389         }
2390         auto ret = dbenv.repmgr_start(dbenv, nthreads, flags);
2391         int res = DbRetCodeToException!"repmgr_start"(ret, this);
2392         if (res == 0) repmgr_started = 1;
2393         return res;
2394     }
2395 
2396     DbRepmgrStat *repmgr_stat(uint32_t flags = 0)
2397     {
2398         if (opened <= 0) {
2399             throw new DbWrongUsingException("Replication configuration on closed or not opened DbEnv");
2400         }
2401         DbRepmgrStat *res;
2402         auto ret = dbenv.repmgr_stat(dbenv, &res, flags);
2403         DbRetCodeToException(ret, this);
2404         assert(ret == 0);
2405         return res;
2406     }
2407 
2408     void repmgr_stat_print(uint32_t flags = 0)
2409     {
2410         if (opened <= 0) {
2411             throw new DbWrongUsingException("Replication configuration on closed or not opened DbEnv");
2412         }
2413         auto ret = dbenv.repmgr_stat_print(dbenv, flags);
2414         DbRetCodeToException(ret, this);
2415         assert(ret == 0);
2416     }
2417 
2418     /* Base Replication API Methods */
2419     void rep_elect(uint32_t nsites, uint32_t nvotes, uint32_t flags = 0)
2420     {
2421         if (opened <= 0) {
2422             throw new DbWrongUsingException("Replication operation on closed or not opened DbEnv");
2423         }
2424         if (rep_transport <= 0) {
2425             throw new DbWrongUsingException("Replication operation before rep_set_transport() on DbEnv");
2426         }
2427         if (rep_started <= 0) {
2428             throw new DbWrongUsingException("Replication operation before rep_start() on DbEnv");
2429         }
2430         auto ret = dbenv.rep_elect(dbenv, nsites, nvotes, flags);
2431         DbRetCodeToException(ret, this);
2432         assert(ret == 0);
2433     }
2434 
2435     int rep_process_message(Dbt *control, Dbt *rec, int envid, DbLsn *ret_lsn)
2436     {
2437         if (opened < 0) {
2438             throw new DbWrongUsingException("Replication operation on closed DbEnv");
2439         }
2440         if (rep_transport <= 0) {
2441             throw new DbWrongUsingException("Replication operation before rep_set_transport() on DbEnv");
2442         }
2443         auto ret = dbenv.rep_process_message(dbenv, 
2444                 &control.dbt, &rec.dbt, envid, ret_lsn);
2445         return DbRetCodeToException!"rep_process_message"(ret, this);
2446     }
2447 
2448     private
2449     {
2450         int function(DbEnv dbenv,
2451                 const (Dbt) *control, const (Dbt) *rec, const (DbLsn) *lsnp,
2452                 int envid, uint32_t flags = 0) send_callback_refer;
2453 
2454         extern (C) static int send_callback(DB_ENV *_dbenv,
2455                 const (DBT) *_control, const (DBT) *_rec, const (DB_LSN) *lsnp,
2456                 int envid, uint32_t flags = 0)
2457         {
2458             DbEnv dbenv = from_DB_ENV(_dbenv);
2459             const (Dbt) *control = cast(const (Dbt)*) _control;
2460             const (Dbt) *rec = cast(const (Dbt)*) _rec;
2461             return dbenv.send_callback_refer(dbenv, control, rec, lsnp,
2462                     envid, flags);
2463         }
2464     }
2465 
2466     void rep_set_transport(int envid,
2467             int function(DbEnv dbenv,
2468                 const (Dbt) *control, const (Dbt) *rec, const (DbLsn) *lsnp,
2469                 int envid, uint32_t flags = 0) send)
2470     {
2471         if (opened < 0) {
2472             throw new DbWrongUsingException("Replication operation on closed DbEnv");
2473         }
2474         send_callback_refer = send;
2475         auto ret = dbenv.rep_set_transport(dbenv, envid, send?&send_callback:null);
2476         DbRetCodeToException(ret, this);
2477         assert(ret == 0);
2478         rep_transport = 1;
2479     }
2480 
2481     void rep_start(Dbt *cdata, uint32_t flags = 0)
2482     {
2483         if (opened <= 0) {
2484             throw new DbWrongUsingException("Replication operation on closed or not opened DbEnv");
2485         }
2486         if (rep_transport <= 0) {
2487             throw new DbWrongUsingException("Replication operation before rep_set_transport() on DbEnv");
2488         }
2489         auto ret = dbenv.rep_start(dbenv, &cdata.dbt, flags);
2490         DbRetCodeToException(ret, this);
2491         assert(ret == 0);
2492         rep_started = 1;
2493     }
2494 
2495     /* Additional Replication Methods */
2496     DbRepStat *rep_stat(uint32_t flags = 0)
2497     {
2498         if (opened <= 0) {
2499             throw new DbWrongUsingException("Replication operation on closed or not opened DbEnv");
2500         }
2501         DbRepStat *res;
2502         auto ret = dbenv.rep_stat(dbenv, &res, flags);
2503         DbRetCodeToException(ret, this);
2504         assert(ret == 0);
2505         return res;
2506     }
2507 
2508     void rep_stat_print(uint32_t flags = 0)
2509     {
2510         if (opened <= 0) {
2511             throw new DbWrongUsingException("Replication operation on closed or not opened DbEnv");
2512         }
2513         auto ret = dbenv.rep_stat_print(dbenv, flags);
2514         DbRetCodeToException(ret, this);
2515         assert(ret == 0);
2516     }
2517 
2518     void rep_sync(uint32_t flags = 0)
2519     {
2520         if (opened <= 0) {
2521             throw new DbWrongUsingException("Replication operation on closed or not opened DbEnv");
2522         }
2523         if (rep_transport <= 0) {
2524             throw new DbWrongUsingException("Replication operation before rep_set_transport() on DbEnv");
2525         }
2526         auto ret = dbenv.rep_sync(dbenv, flags);
2527         DbRetCodeToException(ret, this);
2528         assert(ret == 0);
2529     }
2530 
2531     /* Replication Configuration */
2532     void rep_set_clockskew(uint32_t fast_clock, uint32_t slow_clock)
2533     {
2534         if (opened < 0) {
2535             throw new DbWrongUsingException("Replication configuration on closed DbEnv");
2536         }
2537         if (rep_started > 0 || repmgr_started > 0) {
2538             throw new DbWrongUsingException("Replication operation after rep_start()/repmgr_start() on DbEnv");
2539         }
2540         auto ret = dbenv.rep_set_clockskew(dbenv, fast_clock, slow_clock);
2541         DbRetCodeToException(ret, this);
2542         assert(ret == 0);
2543     }
2544     
2545     void rep_get_clockskew(ref uint32_t fast_clock, ref uint32_t slow_clock)
2546     {
2547         if (opened < 0) {
2548             throw new DbWrongUsingException("Replication configuration on closed DbEnv");
2549         }
2550         auto ret = dbenv.rep_get_clockskew(dbenv, &fast_clock, &slow_clock);
2551         DbRetCodeToException(ret, this);
2552         assert(ret == 0);
2553     }
2554 
2555     void rep_set_config(uint32_t which, int onoff)
2556     {
2557         if (opened < 0) {
2558             throw new DbWrongUsingException("Replication configuration on closed DbEnv");
2559         }
2560         auto ret = dbenv.rep_set_config(dbenv, which, onoff);
2561         DbRetCodeToException(ret, this);
2562         assert(ret == 0);
2563     }
2564 
2565     int rep_get_config(uint32_t which)
2566     {
2567         if (opened < 0) {
2568             throw new DbWrongUsingException("Replication configuration on closed DbEnv");
2569         }
2570         int res;
2571         auto ret = dbenv.rep_get_config(dbenv, which, &res);
2572         DbRetCodeToException(ret, this);
2573         assert(ret == 0);
2574         return res;
2575     }
2576 
2577     void rep_set_limit(uint32_t gbytes, uint32_t bytes)
2578     {
2579         if (opened < 0) {
2580             throw new DbWrongUsingException("Replication configuration on closed DbEnv");
2581         }
2582         auto ret = dbenv.rep_set_limit(dbenv, gbytes, bytes);
2583         DbRetCodeToException(ret, this);
2584         assert(ret == 0);
2585     }
2586 
2587     void rep_set_limit(uint64_t bytes)
2588     {
2589         uint32_t _gbytes = cast(uint32_t) bytes/(1024*1024*1024);
2590         uint32_t _bytes = bytes%(1024*1024*1024);
2591         rep_set_limit(_gbytes, _bytes);
2592     }
2593 
2594     int rep_get_limit(ref uint32_t gbytes, ref uint32_t bytes)
2595     {
2596         if (opened < 0) {
2597             throw new DbWrongUsingException("Replication configuration on closed DbEnv");
2598         }
2599         int res;
2600         auto ret = dbenv.rep_get_limit(dbenv, &gbytes, &bytes);
2601         DbRetCodeToException(ret, this);
2602         assert(ret == 0);
2603         return res;
2604     }
2605 
2606     uint64_t rep_get_limit()
2607     {
2608         uint32_t gbytes;
2609         uint32_t bytes;
2610         rep_get_limit(gbytes, bytes);
2611         return (1024UL*1024*1024)*gbytes + bytes;
2612     }
2613 
2614     void rep_set_nsites(uint32_t nsites)
2615     {
2616         if (opened < 0) {
2617             throw new DbWrongUsingException("Replication configuration on closed DbEnv");
2618         }
2619         auto ret = dbenv.rep_set_nsites(dbenv, nsites);
2620         DbRetCodeToException(ret, this);
2621         assert(ret == 0);
2622     }
2623 
2624     uint32_t rep_get_nsites()
2625     {
2626         if (opened < 0) {
2627             throw new DbWrongUsingException("Replication configuration on closed DbEnv");
2628         }
2629         uint32_t res;
2630         auto ret = dbenv.rep_get_nsites(dbenv, &res);
2631         DbRetCodeToException(ret, this);
2632         assert(ret == 0);
2633         return res;
2634     }
2635 
2636     void rep_set_priority(uint32_t priority)
2637     {
2638         if (opened < 0) {
2639             throw new DbWrongUsingException("Replication configuration on closed DbEnv");
2640         }
2641         auto ret = dbenv.rep_set_priority(dbenv, priority);
2642         DbRetCodeToException(ret, this);
2643         assert(ret == 0);
2644     }
2645 
2646     uint32_t rep_get_priority()
2647     {
2648         if (opened < 0) {
2649             throw new DbWrongUsingException("Replication configuration on closed DbEnv");
2650         }
2651         uint32_t res;
2652         auto ret = dbenv.rep_get_priority(dbenv, &res);
2653         DbRetCodeToException(ret, this);
2654         assert(ret == 0);
2655         return res;
2656     } 
2657 
2658     void rep_set_request(uint32_t min, uint32_t max)
2659     {
2660         if (opened < 0) {
2661             throw new DbWrongUsingException("Replication configuration on closed DbEnv");
2662         }
2663         auto ret = dbenv.rep_set_request(dbenv, min, max);
2664         DbRetCodeToException(ret, this);
2665         assert(ret == 0);
2666     }
2667 
2668     void rep_get_request(ref uint32_t min, ref uint32_t max)
2669     {
2670         if (opened < 0) {
2671             throw new DbWrongUsingException("Replication configuration on closed DbEnv");
2672         }
2673         auto ret = dbenv.rep_get_request(dbenv, &min, &max);
2674         DbRetCodeToException(ret, this);
2675         assert(ret == 0);
2676     }
2677 
2678     void rep_set_timeout(int which, uint32_t timeout)
2679     {
2680         if (opened < 0) {
2681             throw new DbWrongUsingException("Replication configuration on closed DbEnv");
2682         }
2683         auto ret = dbenv.rep_set_timeout(dbenv, which, timeout);
2684         DbRetCodeToException(ret, this);
2685         assert(ret == 0);
2686     }
2687 
2688     uint32_t rep_get_timeout(int which)
2689     {
2690         if (opened < 0) {
2691             throw new DbWrongUsingException("Replication configuration on closed DbEnv");
2692         }
2693         uint32_t res;
2694         auto ret = dbenv.rep_get_timeout(dbenv, which, &res);
2695         DbRetCodeToException(ret, this);
2696         assert(ret == 0);
2697         return res;
2698     }
2699 
2700     private
2701     {
2702         int function(DbEnv dbenv, string name, 
2703                 ref int result, uint32_t flags = 0) partial_callback_refer;
2704 
2705         extern (C) static int partial_callback(DB_ENV *_dbenv,
2706                 const (char) *_name, int *result, uint32_t flags = 0)
2707         {
2708             DbEnv dbenv = from_DB_ENV(_dbenv);
2709             string name = to!string(_name);
2710             return dbenv.partial_callback_refer(dbenv, name, *result, flags);
2711         }
2712     }
2713 
2714 version(VERSION_6)
2715 {
2716     void rep_set_view(int function(DbEnv dbenv,
2717                 string name, ref int result, uint32_t flags = 0) partial_func)
2718     {
2719         if (opened < 0) {
2720             throw new DbWrongUsingException("Configuration on closed DbEnv");
2721         }
2722         if (opened > 0) {
2723             throw new DbWrongUsingException("Configuration on opened DbEnv");
2724         }
2725         partial_callback_refer = partial_func;
2726         auto ret = dbenv.rep_set_view(dbenv, partial_func?&partial_callback:null);
2727         DbRetCodeToException(ret, this);
2728         assert(ret == 0);
2729     }
2730 }
2731 
2732     /* Transaction Operations */
2733     int txn_applied(DbTxnToken *token, db_timeout_t timeout, uint32_t flags = 0)
2734     {
2735         if (opened <= 0) {
2736             throw new DbWrongUsingException("Replication configuration on closed or not opened DbEnv");
2737         }
2738         auto ret = dbenv.txn_applied(dbenv, token, timeout, flags);
2739         return DbRetCodeToException!"txn_applied"(ret, this);
2740     }
2741 }
2742 
2743 /* This function used as is from berkeleydb.c module:
2744    int log_compare(const (DbLsn) *lsn0, const (DbLsn) *lsn1); */