1 /*-
2 * Copyright (c) 1997, 2020 Oracle and/or its affiliates. All rights reserved.
3 *
4 * See the file LICENSE for license information.
5 *
6 * $Id$
7 */
8
9 #include "db_config.h"
10
11 #include "db_int.h"
12
13 #include "db_cxx.h"
14 #include "dbinc/cxx_int.h"
15
16 #include "dbinc/db_page.h"
17 #include "dbinc/db_am.h"
18 #include "dbinc/log.h"
19 #include "dbinc_auto/common_ext.h"
20 #include "dbinc_auto/log_ext.h"
21
22 #ifdef HAVE_CXX_STDHEADERS
23 using std::cerr;
24 #endif
25
26 // Helper macros for simple methods that pass through to the
27 // underlying C method. They may return an error or raise an exception.
28 // These macros expect that input _argspec is an argument
29 // list element (e.g., "char *arg") and that _arglist is the arguments
30 // that should be passed through to the C method (e.g., "(dbenv, arg)")
31 //
32 #define DBENV_METHOD_ERR(_name, _argspec, _arglist, _on_err) \
33 int DbEnv::_name _argspec \
34 { \
35 DB_ENV *dbenv = unwrap(this); \
36 int ret; \
37 \
38 if ((ret = dbenv->_name _arglist) != 0) { \
39 _on_err; \
40 } \
41 return (ret); \
42 }
43
44 #define DBENV_METHOD(_name, _argspec, _arglist) \
45 DBENV_METHOD_ERR(_name, _argspec, _arglist, \
46 DB_ERROR(this, "DbEnv::" # _name, ret, error_policy()))
47
48 #define DBENV_METHOD_QUIET(_name, _argspec, _arglist) \
49 int DbEnv::_name _argspec \
50 { \
51 DB_ENV *dbenv = unwrap(this); \
52 \
53 return (dbenv->_name _arglist); \
54 }
55
56 #define DBENV_METHOD_VOID(_name, _argspec, _arglist) \
57 void DbEnv::_name _argspec \
58 { \
59 DB_ENV *dbenv = unwrap(this); \
60 \
61 dbenv->_name _arglist; \
62 }
63
64 // The reason for a static variable is that some structures
65 // (like Dbts) have no connection to any Db or DbEnv, so when
66 // errors occur in their methods, we must have some reasonable
67 // way to determine whether to throw or return errors.
68 //
69 // This variable is taken from flags whenever a DbEnv is constructed.
70 // Normally there is only one DbEnv per program, and even if not,
71 // there is typically a single policy of throwing or returning.
72 //
73 static int last_known_error_policy = ON_ERROR_UNKNOWN;
74
75 // These 'glue' function are declared as extern "C" so they will
76 // be compatible with picky compilers that do not allow mixing
77 // of function pointers to 'C' functions with function pointers
78 // to C++ functions.
79 //
80 extern "C"
_feedback_intercept_c(DB_ENV * dbenv,int opcode,int pct)81 void _feedback_intercept_c(DB_ENV *dbenv, int opcode, int pct)
82 {
83 DbEnv::_feedback_intercept(dbenv, opcode, pct);
84 }
85
86 extern "C"
_paniccall_intercept_c(DB_ENV * dbenv,int errval)87 void _paniccall_intercept_c(DB_ENV *dbenv, int errval)
88 {
89 DbEnv::_paniccall_intercept(dbenv, errval);
90 }
91
92 extern "C"
_partial_rep_intercept_c(DB_ENV * dbenv,const char * name,int * result,u_int32_t flags)93 int _partial_rep_intercept_c(DB_ENV *dbenv,
94 const char *name, int *result, u_int32_t flags)
95 {
96 return (DbEnv::_partial_rep_intercept(dbenv, name, result, flags));
97 }
98
99 extern "C"
_event_func_intercept_c(DB_ENV * dbenv,u_int32_t event,void * event_info)100 void _event_func_intercept_c(DB_ENV *dbenv, u_int32_t event, void *event_info)
101 {
102 DbEnv::_event_func_intercept(dbenv, event, event_info);
103 }
104
105 extern "C"
_stream_error_function_c(const DB_ENV * dbenv,const char * prefix,const char * message)106 void _stream_error_function_c(const DB_ENV *dbenv,
107 const char *prefix, const char *message)
108 {
109 DbEnv::_stream_error_function(dbenv, prefix, message);
110 }
111
112 extern "C"
_stream_message_function_c(const DB_ENV * dbenv,const char * prefix,const char * message)113 void _stream_message_function_c(const DB_ENV *dbenv,
114 const char *prefix, const char *message)
115 {
116 DbEnv::_stream_message_function(dbenv, prefix, message);
117 }
118
119 extern "C"
_app_dispatch_intercept_c(DB_ENV * dbenv,DBT * dbt,DB_LSN * lsn,db_recops op)120 int _app_dispatch_intercept_c(DB_ENV *dbenv, DBT *dbt, DB_LSN *lsn, db_recops op)
121 {
122 return (DbEnv::_app_dispatch_intercept(dbenv, dbt, lsn, op));
123 }
124
125 extern "C"
_rep_send_intercept_c(DB_ENV * dbenv,const DBT * cntrl,const DBT * data,const DB_LSN * lsn,int id,u_int32_t flags)126 int _rep_send_intercept_c(DB_ENV *dbenv, const DBT *cntrl, const DBT *data,
127 const DB_LSN *lsn, int id, u_int32_t flags)
128 {
129 return (DbEnv::_rep_send_intercept(dbenv,
130 cntrl, data, lsn, id, flags));
131 }
132
133 extern "C"
_repmgr_set_socket_intercept_c(DB_ENV * dbenv,DB_REPMGR_SOCKET socket,int * result,u_int32_t flags)134 int _repmgr_set_socket_intercept_c(DB_ENV *dbenv, DB_REPMGR_SOCKET socket,
135 int *result, u_int32_t flags)
136 {
137 return DbEnv::_repmgr_set_socket_intercept(dbenv, socket, result, flags);
138 }
139
140 extern "C"
_message_dispatch_intercept_c(DB_ENV * dbenv,DB_CHANNEL * channel,DBT * request,u_int32_t nrequest,u_int32_t cb_flags)141 void _message_dispatch_intercept_c(DB_ENV *dbenv, DB_CHANNEL *channel,
142 DBT *request, u_int32_t nrequest, u_int32_t cb_flags)
143 {
144 DbEnv::_message_dispatch_intercept(dbenv, channel, request, nrequest,
145 cb_flags);
146 }
147
148 extern "C"
_isalive_intercept_c(DB_ENV * dbenv,pid_t pid,db_threadid_t thrid,u_int32_t flags)149 int _isalive_intercept_c(
150 DB_ENV *dbenv, pid_t pid, db_threadid_t thrid, u_int32_t flags)
151 {
152 return (DbEnv::_isalive_intercept(dbenv, pid, thrid, flags));
153 }
154
155 extern "C"
_thread_id_intercept_c(DB_ENV * dbenv,pid_t * pidp,db_threadid_t * thridp)156 void _thread_id_intercept_c(DB_ENV *dbenv, pid_t *pidp, db_threadid_t *thridp)
157 {
158 DbEnv::_thread_id_intercept(dbenv, pidp, thridp);
159 }
160
161 extern "C"
_thread_id_string_intercept_c(DB_ENV * dbenv,pid_t pid,db_threadid_t thrid,char * buf)162 char *_thread_id_string_intercept_c(DB_ENV *dbenv, pid_t pid,
163 db_threadid_t thrid, char *buf)
164 {
165 return (DbEnv::_thread_id_string_intercept(dbenv, pid, thrid, buf));
166 }
167
168 extern "C"
_backup_close_intercept_c(DB_ENV * dbenv,const char * dbname,void * handle)169 int _backup_close_intercept_c(DB_ENV *dbenv, const char *dbname, void *handle)
170 {
171 return (DbEnv::_backup_close_intercept(dbenv, dbname, handle));
172 }
173
174 extern "C"
_backup_open_intercept_c(DB_ENV * dbenv,const char * dbname,const char * target,void ** handle)175 int _backup_open_intercept_c(DB_ENV *dbenv,
176 const char *dbname, const char *target, void **handle)
177 {
178 return (DbEnv::_backup_open_intercept(dbenv, dbname, target, handle));
179 }
180
181 extern "C"
_backup_write_intercept_c(DB_ENV * dbenv,u_int32_t off_gbytes,u_int32_t off_bytes,u_int32_t size,u_int8_t * buf,void * handle)182 int _backup_write_intercept_c(DB_ENV *dbenv, u_int32_t off_gbytes,
183 u_int32_t off_bytes, u_int32_t size, u_int8_t *buf, void *handle)
184 {
185 return (DbEnv::_backup_write_intercept(
186 dbenv, off_gbytes, off_bytes, size, buf, handle));
187 }
188
_feedback_intercept(DB_ENV * dbenv,int opcode,int pct)189 void DbEnv::_feedback_intercept(DB_ENV *dbenv, int opcode, int pct)
190 {
191 DbEnv *cxxenv = DbEnv::get_DbEnv(dbenv);
192 if (cxxenv == 0) {
193 DB_ERROR(0,
194 "DbEnv::feedback_callback", EINVAL, ON_ERROR_UNKNOWN);
195 return;
196 }
197 if (cxxenv->feedback_callback_ == 0) {
198 DB_ERROR(DbEnv::get_DbEnv(dbenv),
199 "DbEnv::feedback_callback", EINVAL, cxxenv->error_policy());
200 return;
201 }
202 (*cxxenv->feedback_callback_)(cxxenv, opcode, pct);
203 }
204
_paniccall_intercept(DB_ENV * dbenv,int errval)205 void DbEnv::_paniccall_intercept(DB_ENV *dbenv, int errval)
206 {
207 DbEnv *cxxenv = DbEnv::get_DbEnv(dbenv);
208 if (cxxenv == 0) {
209 DB_ERROR(0,
210 "DbEnv::paniccall_callback", EINVAL, ON_ERROR_UNKNOWN);
211 return;
212 }
213 if (cxxenv->paniccall_callback_ == 0) {
214 DB_ERROR(cxxenv, "DbEnv::paniccall_callback", EINVAL,
215 cxxenv->error_policy());
216 return;
217 }
218 (*cxxenv->paniccall_callback_)(cxxenv, errval);
219 }
220
_partial_rep_intercept(DB_ENV * dbenv,const char * name,int * result,u_int32_t flags)221 int DbEnv::_partial_rep_intercept(DB_ENV *dbenv,
222 const char *name, int *result, u_int32_t flags)
223 {
224 DbEnv *cxxenv = DbEnv::get_DbEnv(dbenv);
225 if (cxxenv == 0) {
226 DB_ERROR(0,
227 "DbEnv::partial_rep_callback", EINVAL, ON_ERROR_UNKNOWN);
228 return (EINVAL);
229 }
230 return ((*cxxenv->partial_rep_callback_)(cxxenv, name, result, flags));
231 }
232
_event_func_intercept(DB_ENV * dbenv,u_int32_t event,void * event_info)233 void DbEnv::_event_func_intercept(
234 DB_ENV *dbenv, u_int32_t event, void *event_info)
235 {
236 DbEnv *cxxenv = DbEnv::get_DbEnv(dbenv);
237 if (cxxenv == 0) {
238 DB_ERROR(0,
239 "DbEnv::event_func_callback", EINVAL, ON_ERROR_UNKNOWN);
240 return;
241 }
242 if (cxxenv->event_func_callback_ == 0) {
243 DB_ERROR(cxxenv, "DbEnv::event_func_callback", EINVAL,
244 cxxenv->error_policy());
245 return;
246 }
247 (*cxxenv->event_func_callback_)(cxxenv, event, event_info);
248 }
249
_app_dispatch_intercept(DB_ENV * dbenv,DBT * dbt,DB_LSN * lsn,db_recops op)250 int DbEnv::_app_dispatch_intercept(DB_ENV *dbenv, DBT *dbt, DB_LSN *lsn,
251 db_recops op)
252 {
253 DbEnv *cxxenv = DbEnv::get_DbEnv(dbenv);
254 if (cxxenv == 0) {
255 DB_ERROR(DbEnv::get_DbEnv(dbenv),
256 "DbEnv::app_dispatch_callback", EINVAL, ON_ERROR_UNKNOWN);
257 return (EINVAL);
258 }
259 if (cxxenv->app_dispatch_callback_ == 0) {
260 DB_ERROR(DbEnv::get_DbEnv(dbenv),
261 "DbEnv::app_dispatch_callback", EINVAL,
262 cxxenv->error_policy());
263 return (EINVAL);
264 }
265 Dbt *cxxdbt = (Dbt *)dbt;
266 DbLsn *cxxlsn = (DbLsn *)lsn;
267 return ((*cxxenv->app_dispatch_callback_)(cxxenv, cxxdbt, cxxlsn, op));
268 }
269
_isalive_intercept(DB_ENV * dbenv,pid_t pid,db_threadid_t thrid,u_int32_t flags)270 int DbEnv::_isalive_intercept(
271 DB_ENV *dbenv, pid_t pid, db_threadid_t thrid, u_int32_t flags)
272 {
273 DbEnv *cxxenv = DbEnv::get_DbEnv(dbenv);
274 if (cxxenv == 0) {
275 DB_ERROR(DbEnv::get_DbEnv(dbenv),
276 "DbEnv::isalive_callback", EINVAL, ON_ERROR_UNKNOWN);
277 return (0);
278 }
279 return ((*cxxenv->isalive_callback_)(cxxenv, pid, thrid, flags));
280 }
281
_repmgr_set_socket_intercept(DB_ENV * dbenv,DB_REPMGR_SOCKET socket,int * result,u_int32_t flags)282 int DbEnv::_repmgr_set_socket_intercept(DB_ENV *dbenv,
283 DB_REPMGR_SOCKET socket, int *result, u_int32_t flags)
284 {
285 DbEnv *cxxenv = DbEnv::get_DbEnv(dbenv);
286 if (cxxenv == 0) {
287 DB_ERROR(DbEnv::get_DbEnv(dbenv),
288 "DbEnv::repmgr_set_socket_callback", EINVAL,
289 ON_ERROR_UNKNOWN);
290 return (EINVAL);
291 } else {
292 return ((*cxxenv->repmgr_set_socket_callback_)(cxxenv,
293 socket, result, flags));
294 }
295 }
296
_message_dispatch_intercept(DB_ENV * dbenv,DB_CHANNEL * dbchannel,DBT * request,u_int32_t nrequest,u_int32_t cb_flags)297 void DbEnv::_message_dispatch_intercept(DB_ENV *dbenv, DB_CHANNEL *dbchannel,
298 DBT *request, u_int32_t nrequest, u_int32_t cb_flags)
299 {
300 DbEnv *cxxenv = DbEnv::get_DbEnv(dbenv);
301 if (cxxenv == 0)
302 DB_ERROR(DbEnv::get_DbEnv(dbenv),
303 "DbEnv::message_dispatch_callback", EINVAL,
304 ON_ERROR_UNKNOWN);
305 else {
306 DbChannel *cxxchannel = (DbChannel *)dbchannel;
307 Dbt *cxxdbt = (Dbt *)request;
308 ((*cxxenv->message_dispatch_callback_)(cxxenv, cxxchannel,
309 cxxdbt, nrequest, cb_flags));
310 }
311 }
312
_rep_send_intercept(DB_ENV * dbenv,const DBT * cntrl,const DBT * data,const DB_LSN * lsn,int id,u_int32_t flags)313 int DbEnv::_rep_send_intercept(DB_ENV *dbenv, const DBT *cntrl, const DBT *data,
314 const DB_LSN *lsn, int id, u_int32_t flags)
315 {
316 DbEnv *cxxenv = DbEnv::get_DbEnv(dbenv);
317 if (cxxenv == 0) {
318 DB_ERROR(DbEnv::get_DbEnv(dbenv),
319 "DbEnv::rep_send_callback", EINVAL, ON_ERROR_UNKNOWN);
320 return (EINVAL);
321 }
322 const Dbt *cxxcntrl = (const Dbt *)cntrl;
323 const DbLsn *cxxlsn = (const DbLsn *)lsn;
324 Dbt *cxxdata = (Dbt *)data;
325 return ((*cxxenv->rep_send_callback_)(cxxenv,
326 cxxcntrl, cxxdata, cxxlsn, id, flags));
327 }
328
_thread_id_intercept(DB_ENV * dbenv,pid_t * pidp,db_threadid_t * thridp)329 void DbEnv::_thread_id_intercept(DB_ENV *dbenv,
330 pid_t *pidp, db_threadid_t *thridp)
331 {
332 DbEnv *cxxenv = DbEnv::get_DbEnv(dbenv);
333 if (cxxenv == 0) {
334 DB_ERROR(DbEnv::get_DbEnv(dbenv),
335 "DbEnv::thread_id_callback", EINVAL, ON_ERROR_UNKNOWN);
336 } else
337 cxxenv->thread_id_callback_(cxxenv, pidp, thridp);
338 }
339
_thread_id_string_intercept(DB_ENV * dbenv,pid_t pid,db_threadid_t thrid,char * buf)340 char *DbEnv::_thread_id_string_intercept(DB_ENV *dbenv,
341 pid_t pid, db_threadid_t thrid, char *buf)
342 {
343 DbEnv *cxxenv = DbEnv::get_DbEnv(dbenv);
344 if (cxxenv == 0) {
345 DB_ERROR(DbEnv::get_DbEnv(dbenv),
346 "DbEnv::thread_id_string_callback", EINVAL,
347 ON_ERROR_UNKNOWN);
348 return (NULL);
349 }
350 return (cxxenv->thread_id_string_callback_(cxxenv, pid, thrid, buf));
351 }
352
_backup_close_intercept(DB_ENV * dbenv,const char * dbname,void * handle)353 int DbEnv::_backup_close_intercept(
354 DB_ENV *dbenv, const char *dbname, void *handle)
355 {
356 DbEnv *cxxenv = DbEnv::get_DbEnv(dbenv);
357 if (cxxenv == 0) {
358 DB_ERROR(DbEnv::get_DbEnv(dbenv),
359 "DbEnv::backup_close_callback", EINVAL, ON_ERROR_UNKNOWN);
360 return (EINVAL);
361 }
362 if (cxxenv->backup_close_callback_ == 0) {
363 DB_ERROR(DbEnv::get_DbEnv(dbenv), "DbEnv::backup_close_callback",
364 EINVAL, cxxenv->error_policy());
365 return (EINVAL);
366 }
367 return (*cxxenv->backup_close_callback_)(cxxenv, dbname, handle);
368 }
369
_backup_open_intercept(DB_ENV * dbenv,const char * dbname,const char * target,void ** handle)370 int DbEnv::_backup_open_intercept(DB_ENV *dbenv,
371 const char *dbname, const char *target, void **handle)
372 {
373 DbEnv *cxxenv = DbEnv::get_DbEnv(dbenv);
374 if (cxxenv == 0) {
375 DB_ERROR(DbEnv::get_DbEnv(dbenv),
376 "DbEnv::backup_open_callback", EINVAL, ON_ERROR_UNKNOWN);
377 return (EINVAL);
378 }
379 if (cxxenv->backup_open_callback_ == 0) {
380 DB_ERROR(DbEnv::get_DbEnv(dbenv), "DbEnv::backup_open_callback",
381 EINVAL, cxxenv->error_policy());
382 return (EINVAL);
383 }
384 return (*cxxenv->backup_open_callback_)(cxxenv, dbname, target, handle);
385 }
386
_backup_write_intercept(DB_ENV * dbenv,u_int32_t off_gbytes,u_int32_t off_bytes,u_int32_t size,u_int8_t * buf,void * handle)387 int DbEnv::_backup_write_intercept(DB_ENV *dbenv, u_int32_t off_gbytes,
388 u_int32_t off_bytes, u_int32_t size, u_int8_t *buf, void *handle)
389 {
390 DbEnv *cxxenv = DbEnv::get_DbEnv(dbenv);
391 if (cxxenv == 0) {
392 DB_ERROR(DbEnv::get_DbEnv(dbenv),
393 "DbEnv::backup_write_callback", EINVAL, ON_ERROR_UNKNOWN);
394 return (EINVAL);
395 }
396 if (cxxenv->backup_write_callback_ == 0) {
397 DB_ERROR(DbEnv::get_DbEnv(dbenv), "DbEnv::backup_write_callback",
398 EINVAL, cxxenv->error_policy());
399 return (EINVAL);
400 }
401 return (*cxxenv->backup_write_callback_)(
402 cxxenv, off_gbytes, off_bytes, size, buf, handle);
403 }
404
405 // A truism for the DbEnv object is that there is a valid
406 // DB_ENV handle from the constructor until close().
407 // After the close, the DB_ENV handle is invalid and
408 // no operations are permitted on the DbEnv (other than
409 // destructor). Leaving the DbEnv handle open and not
410 // doing a close is generally considered an error.
411 //
412 // We used to allow DbEnv objects to be closed and reopened.
413 // This implied always keeping a valid DB_ENV object, and
414 // coordinating the open objects between Db/DbEnv turned
415 // out to be overly complicated. Now we do not allow this.
416
DbEnv(u_int32_t flags)417 DbEnv::DbEnv(u_int32_t flags)
418 : imp_(0)
419 , slices_(0)
420 , construct_error_(0)
421 , construct_flags_(flags)
422 , internally_managed_(false)
423 , error_stream_(0)
424 , message_stream_(0)
425 , app_dispatch_callback_(0)
426 , feedback_callback_(0)
427 , paniccall_callback_(0)
428 , partial_rep_callback_(0)
429 , event_func_callback_(0)
430 , rep_send_callback_(0)
431 , message_dispatch_callback_(0)
432 {
433 if ((construct_error_ = initialize(0)) != 0)
434 DB_ERROR(this, "DbEnv::DbEnv", construct_error_,
435 error_policy());
436 }
437
DbEnv(DB_ENV * dbenv,u_int32_t flags)438 DbEnv::DbEnv(DB_ENV *dbenv, u_int32_t flags)
439 : imp_(0)
440 , slices_(0)
441 , construct_error_(0)
442 , construct_flags_(flags)
443 , internally_managed_(false)
444 , error_stream_(0)
445 , message_stream_(0)
446 , app_dispatch_callback_(0)
447 , feedback_callback_(0)
448 , paniccall_callback_(0)
449 , partial_rep_callback_(0)
450 , event_func_callback_(0)
451 , rep_send_callback_(0)
452 , message_dispatch_callback_(0)
453 {
454 if ((construct_error_ = initialize(dbenv)) != 0)
455 DB_ERROR(this, "DbEnv::DbEnv", construct_error_,
456 error_policy());
457 }
458
DbEnv(DB_ENV * dbenv)459 DbEnv::DbEnv(DB_ENV *dbenv)
460 : imp_(0)
461 , slices_(0)
462 , construct_error_(0)
463 , construct_flags_(0)
464 , internally_managed_(true)
465 , error_stream_(0)
466 , message_stream_(0)
467 , app_dispatch_callback_(0)
468 , feedback_callback_(0)
469 , paniccall_callback_(0)
470 , partial_rep_callback_(0)
471 , event_func_callback_(0)
472 , rep_send_callback_(0)
473 , message_dispatch_callback_(0)
474 {
475 if ((construct_error_ = initialize(dbenv)) != 0)
476 DB_ERROR(this, "DbEnv::DbEnv", construct_error_,
477 error_policy());
478 }
479
480 // If the DB_ENV handle is still open, we close it. This is to make stack
481 // allocation of DbEnv objects easier so that they are cleaned up in the error
482 // path. Note that the C layer catches cases where handles are open in the
483 // environment at close time and reports an error. Applications should call
484 // close explicitly in normal (non-exceptional) cases to check the return
485 // value.
486 //
~DbEnv()487 DbEnv::~DbEnv()
488 {
489 DB_ENV *dbenv = unwrap(this);
490
491 /*
492 * Specify DB_FORCESYNC to make sure databases are sync'ed to disk.
493 * Users can call DbEnv::close with 0 as real parameter to close all
494 * but the last environment object/handle. Doing so can avoid
495 * unnecessary database syncs. The last environment object/handle
496 * must be closed with DB_FORCESYNC parameter, or be closed via this
497 * function.
498 */
499 if (dbenv != NULL) {
500 /*
501 * Do not close environments that are opened and closed
502 * internally, such as slice environments.
503 */
504 if (!internally_managed_)
505 (void)dbenv->close(dbenv, DB_FORCESYNC);
506 cleanup();
507 }
508 }
509
510 // called by destructors before the DB_ENV is destroyed.
cleanup()511 void DbEnv::cleanup()
512 {
513 int i;
514
515 if (slices_ != NULL) {
516 for (i = 0; slices_[i] != NULL; i++) {
517 delete slices_[i];
518 }
519 delete [] slices_;
520 }
521 imp_ = 0;
522 }
523
close(u_int32_t flags)524 int DbEnv::close(u_int32_t flags)
525 {
526 int ret;
527 DB_ENV *dbenv = unwrap(this);
528
529 ret = dbenv->close(dbenv, flags);
530
531 // after a close (no matter if success or failure),
532 // the underlying DB_ENV object must not be accessed.
533 cleanup();
534
535 // It's safe to throw an error after the close,
536 // since our error mechanism does not peer into
537 // the DB* structures.
538 //
539 if (ret != 0)
540 DB_ERROR(this, "DbEnv::close", ret, error_policy());
541
542 return (ret);
543 }
544
545 DBENV_METHOD(dbremove,
546 (DbTxn *txn, const char *name, const char *subdb, u_int32_t flags),
547 (dbenv, unwrap(txn), name, subdb, flags))
548 DBENV_METHOD(dbrename, (DbTxn *txn, const char *name, const char *subdb,
549 const char *newname, u_int32_t flags),
550 (dbenv, unwrap(txn), name, subdb, newname, flags))
551
err(int error,const char * format,...)552 void DbEnv::err(int error, const char *format, ...)
553 {
554 DB_ENV *dbenv = unwrap(this);
555
556 DB_REAL_ERR(dbenv, error, DB_ERROR_SET, 1, format);
557 }
558
559 // Return a tristate value corresponding to whether we should
560 // throw exceptions on errors:
561 // ON_ERROR_RETURN
562 // ON_ERROR_THROW
563 // ON_ERROR_UNKNOWN
564 //
error_policy()565 int DbEnv::error_policy()
566 {
567 if ((construct_flags_ & DB_CXX_NO_EXCEPTIONS) != 0) {
568 return (ON_ERROR_RETURN);
569 }
570 else {
571 return (ON_ERROR_THROW);
572 }
573 }
574
errx(const char * format,...)575 void DbEnv::errx(const char *format, ...)
576 {
577 DB_ENV *dbenv = unwrap(this);
578
579 DB_REAL_ERR(dbenv, 0, DB_ERROR_NOT_SET, 1, format);
580 }
581
get_app_private() const582 void *DbEnv::get_app_private() const
583 {
584 return unwrapConst(this)->app_private;
585 }
586
587 DBENV_METHOD(failchk, (u_int32_t flags), (dbenv, flags))
588 DBENV_METHOD(fileid_reset, (const char *file, u_int32_t flags),
589 (dbenv, file, flags))
590 DBENV_METHOD(get_home, (const char **homep), (dbenv, homep))
591 DBENV_METHOD(get_open_flags, (u_int32_t *flagsp), (dbenv, flagsp))
592 DBENV_METHOD(get_data_dirs, (const char ***dirspp), (dbenv, dirspp))
593
is_bigendian()594 bool DbEnv::is_bigendian()
595 {
596 return unwrap(this)->is_bigendian() ? true : false;
597 }
598
599 DBENV_METHOD(get_thread_count, (u_int32_t *count), (dbenv, count))
600 DBENV_METHOD(set_thread_count, (u_int32_t count), (dbenv, count))
601
602 // used internally during constructor
603 // to associate an existing DB_ENV with this DbEnv,
604 // or create a new one.
605 //
initialize(DB_ENV * dbenv)606 int DbEnv::initialize(DB_ENV *dbenv)
607 {
608 int ret;
609
610 last_known_error_policy = error_policy();
611
612 if (dbenv == 0) {
613 // Create a new DB_ENV environment.
614 if ((ret = ::db_env_create(&dbenv,
615 construct_flags_ & ~DB_CXX_NO_EXCEPTIONS)) != 0)
616 return (ret);
617 }
618 imp_ = dbenv;
619 dbenv->api1_internal = this; // for DB_ENV* to DbEnv* conversion
620 return (0);
621 }
622
623 // lock methods
624 DBENV_METHOD(lock_detect, (u_int32_t flags, u_int32_t atype, int *aborted),
625 (dbenv, flags, atype, aborted))
626 DBENV_METHOD_ERR(lock_get,
627 (u_int32_t locker, u_int32_t flags, Dbt *obj,
628 db_lockmode_t lock_mode, DbLock *lock),
629 (dbenv, locker, flags, obj, lock_mode, &lock->lock_),
630 DbEnv::runtime_error_lock_get(this, "DbEnv::lock_get", ret,
631 DB_LOCK_GET, lock_mode, obj, *lock,
632 -1, error_policy()))
633 DBENV_METHOD(lock_id, (u_int32_t *idp), (dbenv, idp))
634 DBENV_METHOD(lock_id_free, (u_int32_t id), (dbenv, id))
635 DBENV_METHOD(lock_put, (DbLock *lock), (dbenv, &lock->lock_))
636 DBENV_METHOD(lock_stat, (DB_LOCK_STAT **statp, u_int32_t flags),
637 (dbenv, statp, flags))
638 DBENV_METHOD(lock_stat_print, (u_int32_t flags), (dbenv, flags))
639 DBENV_METHOD_ERR(lock_vec,
640 (u_int32_t locker, u_int32_t flags, DB_LOCKREQ list[],
641 int nlist, DB_LOCKREQ **elist_returned),
642 (dbenv, locker, flags, list, nlist, elist_returned),
643 DbEnv::runtime_error_lock_get(this, "DbEnv::lock_vec", ret,
644 (*elist_returned)->op, (*elist_returned)->mode,
645 Dbt::get_Dbt((*elist_returned)->obj), DbLock((*elist_returned)->lock),
646 (int)((*elist_returned) - list), error_policy()))
647 // log methods
648 DBENV_METHOD(log_archive, (char **list[], u_int32_t flags),
649 (dbenv, list, flags))
650
log_compare(const DbLsn * lsn0,const DbLsn * lsn1)651 int DbEnv::log_compare(const DbLsn *lsn0, const DbLsn *lsn1)
652 {
653 return (::log_compare(lsn0, lsn1));
654 }
655
656 // The following cast implies that DbLogc can be no larger than DB_LOGC
657 DBENV_METHOD(log_cursor, (DbLogc **cursorp, u_int32_t flags),
658 (dbenv, (DB_LOGC **)cursorp, flags))
659 DBENV_METHOD(log_file, (DbLsn *lsn, char *namep, size_t len),
660 (dbenv, lsn, namep, len))
661 DBENV_METHOD(log_flush, (const DbLsn *lsn), (dbenv, lsn))
662 DBENV_METHOD(log_get_config, (u_int32_t which, int *onoffp),
663 (dbenv, which, onoffp))
664 DBENV_METHOD(log_put, (DbLsn *lsn, const Dbt *data, u_int32_t flags),
665 (dbenv, lsn, data, flags))
666
log_printf(DbTxn * txn,const char * fmt,...)667 int DbEnv::log_printf(DbTxn *txn, const char *fmt, ...)
668 {
669 DB_ENV *dbenv = unwrap(this);
670 va_list ap;
671 int ret;
672
673 va_start(ap, fmt);
674 ret = __log_printf_pp(dbenv, unwrap(txn), fmt, ap);
675 va_end(ap);
676
677 return (ret);
678 }
679
680 DBENV_METHOD(log_set_config, (u_int32_t which, int onoff),
681 (dbenv, which, onoff))
682 DBENV_METHOD(log_stat, (DB_LOG_STAT **spp, u_int32_t flags),
683 (dbenv, spp, flags))
684 DBENV_METHOD(log_stat_print, (u_int32_t flags), (dbenv, flags))
685
log_verify(DB_LOG_VERIFY_CONFIG * config)686 int DbEnv::log_verify(DB_LOG_VERIFY_CONFIG *config)
687 {
688 DB_ENV *dbenv = unwrap(this);
689
690 // Simply return the error, don't throw exceptions.
691 return dbenv->log_verify(dbenv, config);
692 }
693
694 DBENV_METHOD(lsn_reset, (const char *file, u_int32_t flags),
695 (dbenv, file, flags))
696
memp_fcreate(DbMpoolFile ** dbmfp,u_int32_t flags)697 int DbEnv::memp_fcreate(DbMpoolFile **dbmfp, u_int32_t flags)
698 {
699 DB_ENV *dbenv = unwrap(this);
700 int ret;
701 DB_MPOOLFILE *mpf;
702
703 if (dbenv == NULL)
704 ret = EINVAL;
705 else
706 ret = dbenv->memp_fcreate(dbenv, &mpf, flags);
707
708 if (DB_RETOK_STD(ret)) {
709 *dbmfp = new DbMpoolFile();
710 (*dbmfp)->imp_ = mpf;
711 } else
712 DB_ERROR(this, "DbMpoolFile::f_create", ret, ON_ERROR_UNKNOWN);
713
714 return (ret);
715 }
716
717 DBENV_METHOD(memp_register,
718 (int ftype, pgin_fcn_type pgin_fcn, pgout_fcn_type pgout_fcn),
719 (dbenv, ftype, pgin_fcn, pgout_fcn))
720
721 // memory pool methods
722 DBENV_METHOD(memp_stat,
723 (DB_MPOOL_STAT **gsp, DB_MPOOL_FSTAT ***fsp, u_int32_t flags),
724 (dbenv, gsp, fsp, flags))
725 DBENV_METHOD(memp_stat_print, (u_int32_t flags), (dbenv, flags))
726 DBENV_METHOD(memp_sync, (DbLsn *sn), (dbenv, sn))
727 DBENV_METHOD(memp_trickle, (int pct, int *nwrotep), (dbenv, pct, nwrotep))
728
msg(const char * format,...)729 void DbEnv::msg(const char *format, ...)
730 {
731 DB_ENV *dbenv = unwrap(this);
732
733 DB_REAL_MSG(dbenv, format);
734 }
735
736 // If an error occurred during the constructor, report it now.
737 // Otherwise, call the underlying DB->open method.
738 //
open(const char * db_home,u_int32_t flags,int mode)739 int DbEnv::open(const char *db_home, u_int32_t flags, int mode)
740 {
741 int ret;
742 DB_ENV *dbenv = unwrap(this);
743
744 if (construct_error_ != 0)
745 ret = construct_error_;
746 else
747 ret = dbenv->open(dbenv, db_home, flags, mode);
748
749 if (!DB_RETOK_STD(ret))
750 DB_ERROR(this, "DbEnv::open", ret, error_policy());
751
752 return (ret);
753 }
754
remove(const char * db_home,u_int32_t flags)755 int DbEnv::remove(const char *db_home, u_int32_t flags)
756 {
757 int ret;
758 DB_ENV *dbenv = unwrap(this);
759
760 ret = dbenv->remove(dbenv, db_home, flags);
761
762 // after a remove (no matter if success or failure),
763 // the underlying DB_ENV object must not be accessed,
764 // so we clean up in advance.
765 //
766 cleanup();
767
768 if (ret != 0)
769 DB_ERROR(this, "DbEnv::remove", ret, error_policy());
770
771 return (ret);
772 }
773
774 // Report an error associated with the DbEnv.
775 // error_policy is one of:
776 // ON_ERROR_THROW throw an error
777 // ON_ERROR_RETURN do nothing here, the caller will return an error
778 // ON_ERROR_UNKNOWN defer the policy to policy saved in DbEnv::DbEnv
779 //
runtime_error(DbEnv * dbenv,const char * caller,int error,int error_policy)780 void DbEnv::runtime_error(DbEnv *dbenv,
781 const char *caller, int error, int error_policy)
782 {
783 if (error_policy == ON_ERROR_UNKNOWN)
784 error_policy = last_known_error_policy;
785 if (error_policy == ON_ERROR_THROW) {
786 // Creating and throwing the object in two separate
787 // statements seems to be necessary for HP compilers.
788 switch (error) {
789 case DB_LOCK_DEADLOCK:
790 {
791 DbDeadlockException dl_except(caller);
792 dl_except.set_env(dbenv);
793 throw dl_except;
794 }
795 case DB_LOCK_NOTGRANTED:
796 {
797 DbLockNotGrantedException lng_except(caller);
798 lng_except.set_env(dbenv);
799 throw lng_except;
800 }
801 case DB_REP_HANDLE_DEAD:
802 {
803 DbRepHandleDeadException hd_except(caller);
804 hd_except.set_env(dbenv);
805 throw hd_except;
806 }
807 case DB_RUNRECOVERY:
808 {
809 DbRunRecoveryException rr_except(caller);
810 rr_except.set_env(dbenv);
811 throw rr_except;
812 }
813 default:
814 {
815 DbException except(caller, error);
816 except.set_env(dbenv);
817 throw except;
818 }
819 }
820 }
821 }
822
823 // Like DbEnv::runtime_error, but issue a DbMemoryException
824 // based on the fact that this Dbt is not large enough.
runtime_error_dbt(DbEnv * dbenv,const char * caller,Dbt * dbt,int error_policy)825 void DbEnv::runtime_error_dbt(DbEnv *dbenv,
826 const char *caller, Dbt *dbt, int error_policy)
827 {
828 if (error_policy == ON_ERROR_UNKNOWN)
829 error_policy = last_known_error_policy;
830 if (error_policy == ON_ERROR_THROW) {
831 // Creating and throwing the object in two separate
832 // statements seems to be necessary for HP compilers.
833 DbMemoryException except(caller, dbt);
834 except.set_env(dbenv);
835 throw except;
836 }
837 }
838
839 // Like DbEnv::runtime_error, but issue a DbLockNotGrantedException,
840 // or a regular runtime error.
841 // call regular runtime_error if it
runtime_error_lock_get(DbEnv * dbenv,const char * caller,int error,db_lockop_t op,db_lockmode_t mode,Dbt * obj,DbLock lock,int index,int error_policy)842 void DbEnv::runtime_error_lock_get(DbEnv *dbenv,
843 const char *caller, int error,
844 db_lockop_t op, db_lockmode_t mode, Dbt *obj,
845 DbLock lock, int index, int error_policy)
846 {
847 if (error != DB_LOCK_NOTGRANTED) {
848 runtime_error(dbenv, caller, error, error_policy);
849 return;
850 }
851
852 if (error_policy == ON_ERROR_UNKNOWN)
853 error_policy = last_known_error_policy;
854 if (error_policy == ON_ERROR_THROW) {
855 // Creating and throwing the object in two separate
856 // statements seems to be necessary for HP compilers.
857 DbLockNotGrantedException except(caller, op, mode,
858 obj, lock, index);
859 except.set_env(dbenv);
860 throw except;
861 }
862 }
863
_stream_error_function(const DB_ENV * dbenv,const char * prefix,const char * message)864 void DbEnv::_stream_error_function(
865 const DB_ENV *dbenv, const char *prefix, const char *message)
866 {
867 const DbEnv *cxxenv = DbEnv::get_const_DbEnv(dbenv);
868 if (cxxenv == 0) {
869 DB_ERROR(0,
870 "DbEnv::stream_error", EINVAL, ON_ERROR_UNKNOWN);
871 return;
872 }
873
874 if (cxxenv->error_callback_)
875 cxxenv->error_callback_(cxxenv, prefix, message);
876 else if (cxxenv->error_stream_) {
877 // HP compilers need the extra casts, we don't know why.
878 if (prefix) {
879 (*cxxenv->error_stream_) << prefix;
880 (*cxxenv->error_stream_) << (const char *)": ";
881 }
882 if (message)
883 (*cxxenv->error_stream_) << (const char *)message;
884 (*cxxenv->error_stream_) << (const char *)"\n";
885 }
886 }
887
_stream_message_function(const DB_ENV * dbenv,const char * prefix,const char * message)888 void DbEnv::_stream_message_function(
889 const DB_ENV *dbenv, const char *prefix, const char *message)
890 {
891 const DbEnv *cxxenv = DbEnv::get_const_DbEnv(dbenv);
892 if (cxxenv == 0) {
893 DB_ERROR(0,
894 "DbEnv::stream_message", EINVAL, ON_ERROR_UNKNOWN);
895 return;
896 }
897
898 if (cxxenv->message_callback_)
899 cxxenv->message_callback_(cxxenv, prefix, message);
900 else if (cxxenv->message_stream_) {
901 // HP compilers need the extra casts, we don't know why.
902 if (prefix) {
903 (*cxxenv->message_stream_) << prefix;
904 (*cxxenv->message_stream_) << (const char *)": ";
905 }
906 if (message)
907 (*cxxenv->message_stream_) << (const char *)message;
908 (*cxxenv->message_stream_) << (const char *)"\n";
909 }
910 }
911
912 // static method
strerror(int error)913 char *DbEnv::strerror(int error)
914 {
915 return (db_strerror(error));
916 }
917
918 // We keep these alphabetical by field name,
919 // for comparison with Java's list.
920 //
921 DBENV_METHOD(get_backup_config, (DB_BACKUP_CONFIG type, u_int32_t *valuep), (dbenv, type, valuep))
922 DBENV_METHOD(set_backup_config, (DB_BACKUP_CONFIG type, u_int32_t value), (dbenv, type, value))
923 DBENV_METHOD(get_blob_dir, (const char **dir), (dbenv, dir))
924 DBENV_METHOD(set_blob_dir, (const char *dir), (dbenv, dir))
925 DBENV_METHOD(get_blob_threshold, (u_int32_t *bytes), (dbenv, bytes))
926 DBENV_METHOD(set_blob_threshold, (u_int32_t bytes, u_int32_t flags), (dbenv, bytes, flags))
927 DBENV_METHOD(set_data_dir, (const char *dir), (dbenv, dir))
928 DBENV_METHOD(get_encrypt_flags, (u_int32_t *flagsp),
929 (dbenv, flagsp))
930 DBENV_METHOD(set_encrypt, (const char *passwd, u_int32_t flags),
931 (dbenv, passwd, flags))
932 DBENV_METHOD_VOID(get_errfile, (FILE **errfilep), (dbenv, errfilep))
933 DBENV_METHOD_VOID(set_errfile, (FILE *errfile), (dbenv, errfile))
934 DBENV_METHOD_VOID(get_errpfx, (const char **errpfxp), (dbenv, errpfxp))
935 DBENV_METHOD_VOID(set_errpfx, (const char *errpfx), (dbenv, errpfx))
936 DBENV_METHOD(get_ext_file_dir, (const char **dir), (dbenv, dir))
937 DBENV_METHOD(set_ext_file_dir, (const char *dir), (dbenv, dir))
938 DBENV_METHOD(get_ext_file_threshold, (u_int32_t *bytes), (dbenv, bytes))
939 DBENV_METHOD(set_ext_file_threshold, (u_int32_t bytes, u_int32_t flags), (dbenv, bytes, flags))
940 DBENV_METHOD(get_intermediate_dir_mode, (const char **modep), (dbenv, modep))
941 DBENV_METHOD(set_intermediate_dir_mode, (const char *mode), (dbenv, mode))
942 DBENV_METHOD(get_lg_bsize, (u_int32_t *bsizep), (dbenv, bsizep))
943 DBENV_METHOD(set_lg_bsize, (u_int32_t bsize), (dbenv, bsize))
944 DBENV_METHOD(get_lg_dir, (const char **dirp), (dbenv, dirp))
945 DBENV_METHOD(set_lg_dir, (const char *dir), (dbenv, dir))
946 DBENV_METHOD(get_lg_filemode, (int *modep), (dbenv, modep))
947 DBENV_METHOD(set_lg_filemode, (int mode), (dbenv, mode))
948 DBENV_METHOD(get_lg_max, (u_int32_t *maxp), (dbenv, maxp))
949 DBENV_METHOD(set_lg_max, (u_int32_t max), (dbenv, max))
950 DBENV_METHOD(get_lg_regionmax, (u_int32_t *regionmaxp), (dbenv, regionmaxp))
951 DBENV_METHOD(set_lg_regionmax, (u_int32_t regionmax), (dbenv, regionmax))
952 DBENV_METHOD(get_lk_conflicts, (const u_int8_t **lk_conflictsp, int *lk_maxp),
953 (dbenv, lk_conflictsp, lk_maxp))
954 DBENV_METHOD(set_lk_conflicts, (u_int8_t *lk_conflicts, int lk_max),
955 (dbenv, lk_conflicts, lk_max))
956 DBENV_METHOD(get_lk_detect, (u_int32_t *detectp), (dbenv, detectp))
957 DBENV_METHOD(set_lk_detect, (u_int32_t detect), (dbenv, detect))
958 DBENV_METHOD(get_lk_max_lockers, (u_int32_t *max_lockersp),
959 (dbenv, max_lockersp))
960 DBENV_METHOD(set_lk_max_lockers, (u_int32_t max_lockers), (dbenv, max_lockers))
961 DBENV_METHOD(get_lk_max_locks, (u_int32_t *max_locksp), (dbenv, max_locksp))
962 DBENV_METHOD(set_lk_max_locks, (u_int32_t max_locks), (dbenv, max_locks))
963 DBENV_METHOD(get_lk_max_objects, (u_int32_t *max_objectsp),
964 (dbenv, max_objectsp))
965 DBENV_METHOD(set_lk_max_objects, (u_int32_t max_objects), (dbenv, max_objects))
966 DBENV_METHOD(get_lk_partitions, (u_int32_t *partitionsp), (dbenv, partitionsp))
967 DBENV_METHOD(set_lk_partitions, (u_int32_t partitions), (dbenv, partitions))
968 DBENV_METHOD(get_lk_priority, (u_int32_t lockerid, u_int32_t *priorityp), (dbenv, lockerid, priorityp))
969 DBENV_METHOD(set_lk_priority, (u_int32_t lockerid, u_int32_t priority), (dbenv, lockerid, priority))
970 DBENV_METHOD(get_lk_tablesize, (u_int32_t *tablesize), (dbenv, tablesize))
971 DBENV_METHOD(set_lk_tablesize, (u_int32_t tablesize), (dbenv, tablesize))
972 DBENV_METHOD(get_memory_init, (DB_MEM_CONFIG type, u_int32_t *count), (dbenv, type, count))
973 DBENV_METHOD(set_memory_init, (DB_MEM_CONFIG type, u_int32_t count), (dbenv, type, count))
974 DBENV_METHOD(get_memory_max, (u_int32_t *gbytes, u_int32_t *bytes), (dbenv, gbytes, bytes))
975 DBENV_METHOD(set_memory_max, (u_int32_t gbytes, u_int32_t bytes), (dbenv, gbytes, bytes))
976 DBENV_METHOD(get_metadata_dir, (const char **dirp), (dbenv, dirp))
977 DBENV_METHOD(set_metadata_dir, (const char *dir), (dbenv, dir))
978 DBENV_METHOD(get_mp_max_openfd, (int *maxopenfdp), (dbenv, maxopenfdp))
979 DBENV_METHOD(set_mp_max_openfd, (int maxopenfd), (dbenv, maxopenfd))
980 DBENV_METHOD(get_mp_max_write, (int *maxwritep, db_timeout_t *maxwrite_sleepp),
981 (dbenv, maxwritep, maxwrite_sleepp))
982 DBENV_METHOD(set_mp_max_write, (int maxwrite, db_timeout_t maxwrite_sleep),
983 (dbenv, maxwrite, maxwrite_sleep))
984 DBENV_METHOD(get_mp_mmapsize, (size_t *mmapsizep), (dbenv, mmapsizep))
985 DBENV_METHOD(set_mp_mmapsize, (size_t mmapsize), (dbenv, mmapsize))
986 DBENV_METHOD(get_mp_pagesize, (u_int32_t *pagesizep), (dbenv, pagesizep))
987 DBENV_METHOD(set_mp_pagesize, (u_int32_t pagesize), (dbenv, pagesize))
988 DBENV_METHOD(get_mp_tablesize, (u_int32_t *tablesizep), (dbenv, tablesizep))
989 DBENV_METHOD(set_mp_tablesize, (u_int32_t tablesize), (dbenv, tablesize))
990 DBENV_METHOD_VOID(get_msgfile, (FILE **msgfilep), (dbenv, msgfilep))
991 DBENV_METHOD_VOID(set_msgfile, (FILE *msgfile), (dbenv, msgfile))
992 DBENV_METHOD_VOID(get_msgpfx, (const char **msgpfxp), (dbenv, msgpfxp))
993 DBENV_METHOD_VOID(set_msgpfx, (const char *msgpfx), (dbenv, msgpfx))
994 DBENV_METHOD(get_region_dir, (const char **dirp), (dbenv, dirp))
995 DBENV_METHOD(set_region_dir, (const char *dir), (dbenv, dir))
996 DBENV_METHOD(get_tmp_dir, (const char **tmp_dirp), (dbenv, tmp_dirp))
997 DBENV_METHOD(set_tmp_dir, (const char *tmp_dir), (dbenv, tmp_dir))
998 DBENV_METHOD(get_tx_max, (u_int32_t *tx_maxp), (dbenv, tx_maxp))
999 DBENV_METHOD(set_tx_max, (u_int32_t tx_max), (dbenv, tx_max))
1000
1001 DBENV_METHOD(stat_print, (u_int32_t flags), (dbenv, flags))
1002
1003 DBENV_METHOD_QUIET(get_alloc,
1004 (db_malloc_fcn_type *malloc_fcnp, db_realloc_fcn_type *realloc_fcnp,
1005 db_free_fcn_type *free_fcnp),
1006 (dbenv, malloc_fcnp, realloc_fcnp, free_fcnp))
1007
1008 DBENV_METHOD_QUIET(set_alloc,
1009 (db_malloc_fcn_type malloc_fcn, db_realloc_fcn_type realloc_fcn,
1010 db_free_fcn_type free_fcn),
1011 (dbenv, malloc_fcn, realloc_fcn, free_fcn))
1012
set_app_private(void * value)1013 void DbEnv::set_app_private(void *value)
1014 {
1015 unwrap(this)->app_private = value;
1016 }
1017
1018 DBENV_METHOD(get_cachesize,
1019 (u_int32_t *gbytesp, u_int32_t *bytesp, int *ncachep),
1020 (dbenv, gbytesp, bytesp, ncachep))
1021 DBENV_METHOD(set_cachesize,
1022 (u_int32_t gbytes, u_int32_t bytes, int ncache),
1023 (dbenv, gbytes, bytes, ncache))
1024 DBENV_METHOD(get_cache_max, (u_int32_t *gbytesp, u_int32_t *bytesp),
1025 (dbenv, gbytesp, bytesp))
1026 DBENV_METHOD(set_cache_max, (u_int32_t gbytes, u_int32_t bytes),
1027 (dbenv, gbytes, bytes))
1028 DBENV_METHOD(get_create_dir, (const char **dirp), (dbenv, dirp))
1029 DBENV_METHOD(set_create_dir, (const char *dir), (dbenv, dir))
1030
get_slices(DbEnv *** slices)1031 int DbEnv::get_slices(DbEnv ***slices)
1032 {
1033 DB_ENV **c_slices;
1034 DB_ENV *dbenv;
1035 int i, num_slices, ret;
1036
1037 if (slices_ != NULL) {
1038 *slices = slices_;
1039 return (0);
1040 }
1041
1042 dbenv = unwrap(this);
1043 ret = dbenv->get_slices(dbenv, &c_slices);
1044 if (ret == 0) {
1045 for (num_slices = 0;
1046 c_slices[num_slices] != NULL; num_slices++);
1047 if (num_slices == 0) {
1048 *slices = NULL;
1049 return (0);
1050 }
1051 slices_ = new DbEnv *[num_slices + 1];
1052 for (i = 0; i < num_slices; i++) {
1053 slices_[i] = new DbEnv(c_slices[i]);
1054 }
1055 slices_[i] = NULL;
1056 *slices = slices_;
1057 }
1058 else
1059 *slices = NULL;
1060
1061 if (!DB_RETOK_STD(ret))
1062 DB_ERROR(this, "DbEnv::get_slices", ret, error_policy());
1063 return (ret);
1064 }
1065
get_slice_count()1066 u_int32_t DbEnv::get_slice_count()
1067 {
1068 DB_ENV *dbenv;
1069 u_int32_t count;
1070 int ret;
1071
1072 dbenv = unwrap(this);
1073 count = 0;
1074
1075 ret = dbenv->get_slice_count(dbenv, &count);
1076 if (!DB_RETOK_STD(ret))
1077 DB_ERROR(this, "DbEnv::get_slice_count", ret, error_policy());
1078
1079 return (count);
1080 }
1081
get_errcall(void (** argp)(const DbEnv *,const char *,const char *))1082 void DbEnv::get_errcall(void (**argp)(const DbEnv *, const char *, const char *))
1083 {
1084 if (argp != NULL)
1085 *argp = error_callback_;
1086 return;
1087 }
1088
set_errcall(void (* arg)(const DbEnv *,const char *,const char *))1089 void DbEnv::set_errcall(void (*arg)(const DbEnv *, const char *, const char *))
1090 {
1091 DB_ENV *dbenv = unwrap(this);
1092
1093 error_callback_ = arg;
1094 error_stream_ = 0;
1095
1096 dbenv->set_errcall(dbenv, (arg == 0) ? 0 :
1097 _stream_error_function_c);
1098 }
1099
__DB_STD(ostream)1100 __DB_STD(ostream) *DbEnv::get_error_stream()
1101 {
1102 return (error_stream_);
1103 }
1104
set_error_stream(__DB_STD (ostream)* stream)1105 void DbEnv::set_error_stream(__DB_STD(ostream) *stream)
1106 {
1107 DB_ENV *dbenv = unwrap(this);
1108
1109 error_stream_ = stream;
1110 error_callback_ = 0;
1111
1112 dbenv->set_errcall(dbenv, (stream == 0) ? 0 :
1113 _stream_error_function_c);
1114 }
1115
get_feedback(void (** argp)(DbEnv *,int,int))1116 int DbEnv::get_feedback(void (**argp)(DbEnv *, int, int))
1117 {
1118 if (argp != NULL)
1119 *argp = feedback_callback_;
1120 return 0;
1121 }
1122
set_feedback(void (* arg)(DbEnv *,int,int))1123 int DbEnv::set_feedback(void (*arg)(DbEnv *, int, int))
1124 {
1125 DB_ENV *dbenv = unwrap(this);
1126
1127 feedback_callback_ = arg;
1128
1129 return (dbenv->set_feedback(dbenv,
1130 arg == 0 ? 0 : _feedback_intercept_c));
1131 }
1132
1133 DBENV_METHOD(get_flags, (u_int32_t *flagsp), (dbenv, flagsp))
1134 DBENV_METHOD(set_flags, (u_int32_t flags, int onoff), (dbenv, flags, onoff))
1135
get_msgcall(void (** argp)(const DbEnv *,const char *,const char *))1136 void DbEnv::get_msgcall(void (**argp)(const DbEnv *, const char *, const char *))
1137 {
1138 if (argp != NULL)
1139 *argp = message_callback_;
1140 }
1141
set_msgcall(void (* arg)(const DbEnv *,const char *,const char *))1142 void DbEnv::set_msgcall(void (*arg)(const DbEnv *, const char *, const char *))
1143 {
1144 DB_ENV *dbenv = unwrap(this);
1145
1146 message_callback_ = arg;
1147 message_stream_ = 0;
1148
1149 dbenv->set_msgcall(dbenv, (arg == 0) ? 0 :
1150 _stream_message_function_c);
1151 }
1152
__DB_STD(ostream)1153 __DB_STD(ostream) *DbEnv::get_message_stream()
1154 {
1155 return (message_stream_);
1156 }
1157
set_message_stream(__DB_STD (ostream)* stream)1158 void DbEnv::set_message_stream(__DB_STD(ostream) *stream)
1159 {
1160 DB_ENV *dbenv = unwrap(this);
1161
1162 message_stream_ = stream;
1163 message_callback_ = 0;
1164
1165 dbenv->set_msgcall(dbenv, (stream == 0) ? 0 :
1166 _stream_message_function_c);
1167 }
1168
set_paniccall(void (* arg)(DbEnv *,int))1169 int DbEnv::set_paniccall(void (*arg)(DbEnv *, int))
1170 {
1171 DB_ENV *dbenv = unwrap(this);
1172
1173 paniccall_callback_ = arg;
1174
1175 return (dbenv->set_paniccall(dbenv,
1176 arg == 0 ? 0 : _paniccall_intercept_c));
1177 }
1178
set_event_notify(void (* arg)(DbEnv *,u_int32_t,void *))1179 int DbEnv::set_event_notify(void (*arg)(DbEnv *, u_int32_t, void *))
1180 {
1181 DB_ENV *dbenv = unwrap(this);
1182
1183 event_func_callback_ = arg;
1184
1185 return (dbenv->set_event_notify(dbenv,
1186 arg == 0 ? 0 : _event_func_intercept_c));
1187 }
1188
1189 DBENV_METHOD(get_shm_key, (long *shm_keyp), (dbenv, shm_keyp))
1190 DBENV_METHOD(set_shm_key, (long shm_key), (dbenv, shm_key))
1191
get_app_dispatch(int (** argp)(DbEnv *,Dbt *,DbLsn *,db_recops))1192 int DbEnv::get_app_dispatch
1193 (int (**argp)(DbEnv *, Dbt *, DbLsn *, db_recops))
1194 {
1195 if (argp != NULL)
1196 *argp = app_dispatch_callback_;
1197 return 0;
1198 }
1199
set_app_dispatch(int (* arg)(DbEnv *,Dbt *,DbLsn *,db_recops))1200 int DbEnv::set_app_dispatch
1201 (int (*arg)(DbEnv *, Dbt *, DbLsn *, db_recops))
1202 {
1203 DB_ENV *dbenv = unwrap(this);
1204 int ret;
1205
1206 app_dispatch_callback_ = arg;
1207 if ((ret = dbenv->set_app_dispatch(dbenv,
1208 arg == 0 ? 0 : _app_dispatch_intercept_c)) != 0)
1209 DB_ERROR(this, "DbEnv::set_app_dispatch", ret, error_policy());
1210
1211 return (ret);
1212 }
1213
get_isalive(int (** argp)(DbEnv *,pid_t,db_threadid_t,u_int32_t))1214 int DbEnv::get_isalive
1215 (int (**argp)(DbEnv *, pid_t, db_threadid_t, u_int32_t))
1216 {
1217 if (argp != NULL)
1218 *argp = isalive_callback_;
1219 return 0;
1220 }
1221
set_isalive(int (* arg)(DbEnv *,pid_t,db_threadid_t,u_int32_t))1222 int DbEnv::set_isalive
1223 (int (*arg)(DbEnv *, pid_t, db_threadid_t, u_int32_t))
1224 {
1225 DB_ENV *dbenv = unwrap(this);
1226 int ret;
1227
1228 isalive_callback_ = arg;
1229 if ((ret = dbenv->set_isalive(dbenv,
1230 arg == 0 ? 0 : _isalive_intercept_c)) != 0)
1231 DB_ERROR(this, "DbEnv::set_isalive", ret, error_policy());
1232
1233 return (ret);
1234 }
1235
1236 DBENV_METHOD(get_tx_timestamp, (time_t *timestamp), (dbenv, timestamp))
1237 DBENV_METHOD(set_tx_timestamp, (time_t *timestamp), (dbenv, timestamp))
1238 DBENV_METHOD(get_verbose, (u_int32_t which, int *onoffp),
1239 (dbenv, which, onoffp))
1240 DBENV_METHOD(set_verbose, (u_int32_t which, int onoff), (dbenv, which, onoff))
1241
1242 DBENV_METHOD(mutex_alloc,
1243 (u_int32_t flags, db_mutex_t *mutexp), (dbenv, flags, mutexp))
1244 DBENV_METHOD(mutex_free, (db_mutex_t mutex), (dbenv, mutex))
1245 DBENV_METHOD(mutex_get_align, (u_int32_t *argp), (dbenv, argp))
1246 DBENV_METHOD(mutex_get_increment, (u_int32_t *argp), (dbenv, argp))
1247 DBENV_METHOD(mutex_get_init, (u_int32_t *argp), (dbenv, argp))
1248 DBENV_METHOD(mutex_get_max, (u_int32_t *argp), (dbenv, argp))
1249 DBENV_METHOD(mutex_get_tas_spins, (u_int32_t *argp), (dbenv, argp))
1250 DBENV_METHOD(mutex_lock, (db_mutex_t mutex), (dbenv, mutex))
1251 DBENV_METHOD(mutex_set_align, (u_int32_t arg), (dbenv, arg))
1252 DBENV_METHOD(mutex_set_increment, (u_int32_t arg), (dbenv, arg))
1253 DBENV_METHOD(mutex_set_init, (u_int32_t arg), (dbenv, arg))
1254 DBENV_METHOD(mutex_set_max, (u_int32_t arg), (dbenv, arg))
1255 DBENV_METHOD(mutex_set_tas_spins, (u_int32_t arg), (dbenv, arg))
1256 DBENV_METHOD(mutex_stat,
1257 (DB_MUTEX_STAT **statp, u_int32_t flags), (dbenv, statp, flags))
1258 DBENV_METHOD(mutex_stat_print, (u_int32_t flags), (dbenv, flags))
1259 DBENV_METHOD(mutex_unlock, (db_mutex_t mutex), (dbenv, mutex))
1260
get_thread_id_fn(void (** argp)(DbEnv *,pid_t *,db_threadid_t *))1261 int DbEnv::get_thread_id_fn(void (**argp)(DbEnv *, pid_t *, db_threadid_t *))
1262 {
1263 if (argp != NULL)
1264 *argp = thread_id_callback_;
1265 return 0;
1266 }
1267
set_thread_id(void (* arg)(DbEnv *,pid_t *,db_threadid_t *))1268 int DbEnv::set_thread_id(void (*arg)(DbEnv *, pid_t *, db_threadid_t *))
1269 {
1270 DB_ENV *dbenv = unwrap(this);
1271 int ret;
1272
1273 thread_id_callback_ = arg;
1274 if ((ret = dbenv->set_thread_id(dbenv,
1275 arg == 0 ? 0 : _thread_id_intercept_c)) != 0)
1276 DB_ERROR(this, "DbEnv::set_thread_id", ret, error_policy());
1277
1278 return (ret);
1279 }
1280
get_thread_id_string_fn(char * (** argp)(DbEnv *,pid_t,db_threadid_t,char *))1281 int DbEnv::get_thread_id_string_fn(
1282 char *(**argp)(DbEnv *, pid_t, db_threadid_t, char *))
1283 {
1284 if (argp != NULL)
1285 *argp = thread_id_string_callback_;
1286 return 0;
1287 }
1288
set_thread_id_string(char * (* arg)(DbEnv *,pid_t,db_threadid_t,char *))1289 int DbEnv::set_thread_id_string(
1290 char *(*arg)(DbEnv *, pid_t, db_threadid_t, char *))
1291 {
1292 DB_ENV *dbenv = unwrap(this);
1293 int ret;
1294
1295 thread_id_string_callback_ = arg;
1296 if ((ret = dbenv->set_thread_id_string(dbenv,
1297 arg == 0 ? 0 : _thread_id_string_intercept_c)) != 0)
1298 DB_ERROR(this, "DbEnv::set_thread_id_string", ret,
1299 error_policy());
1300
1301 return (ret);
1302 }
1303
get_backup_callbacks(int (** open_funcp)(DbEnv *,const char *,const char *,void **),int (** write_funcp)(DbEnv *,u_int32_t,u_int32_t,u_int32_t,u_int8_t *,void *),int (** close_funcp)(DbEnv *,const char *,void *))1304 int DbEnv::get_backup_callbacks(
1305 int (**open_funcp)(DbEnv *, const char *, const char *, void **),
1306 int (**write_funcp)(DbEnv *, u_int32_t, u_int32_t, u_int32_t, u_int8_t *, void *),
1307 int (**close_funcp)(DbEnv *, const char *, void *))
1308 {
1309 if (open_funcp != NULL)
1310 *open_funcp = backup_open_callback_;
1311 if (write_funcp != NULL)
1312 *write_funcp = backup_write_callback_;
1313 if (close_funcp != NULL)
1314 *close_funcp = backup_close_callback_;
1315
1316 return 0;
1317 }
1318
set_backup_callbacks(int (* open_func)(DbEnv *,const char *,const char *,void **),int (* write_func)(DbEnv *,u_int32_t,u_int32_t,u_int32_t,u_int8_t *,void *),int (* close_func)(DbEnv *,const char *,void *))1319 int DbEnv::set_backup_callbacks(
1320 int (*open_func)(DbEnv *, const char *, const char *, void **),
1321 int (*write_func)(DbEnv *, u_int32_t, u_int32_t, u_int32_t, u_int8_t *, void *),
1322 int (*close_func)(DbEnv *, const char *, void *))
1323 {
1324 DB_ENV *dbenv = unwrap(this);
1325 int ret;
1326
1327 backup_open_callback_ = open_func;
1328 backup_write_callback_ = write_func;
1329 backup_close_callback_ = close_func;
1330
1331 if ((ret = dbenv->set_backup_callbacks(dbenv,
1332 open_func == 0 ? 0 : _backup_open_intercept_c,
1333 write_func == 0 ? 0 : _backup_write_intercept_c,
1334 close_func == 0 ? 0 : _backup_close_intercept_c)) != 0)
1335 DB_ERROR(this, "DbEnv::set_backup_callbacks", ret,
1336 error_policy());
1337
1338 return (ret);
1339 }
1340
1341 DBENV_METHOD(add_data_dir, (const char *dir), (dbenv, dir))
1342
cdsgroup_begin(DbTxn ** tid)1343 int DbEnv::cdsgroup_begin(DbTxn **tid)
1344 {
1345 DB_ENV *dbenv = unwrap(this);
1346 DB_TXN *txn;
1347 int ret;
1348
1349 ret = dbenv->cdsgroup_begin(dbenv, &txn);
1350 if (DB_RETOK_STD(ret))
1351 *tid = new DbTxn(txn, NULL);
1352 else
1353 DB_ERROR(this, "DbEnv::cdsgroup_begin", ret, error_policy());
1354
1355 return (ret);
1356 }
1357
txn_begin(DbTxn * pid,DbTxn ** tid,u_int32_t flags)1358 int DbEnv::txn_begin(DbTxn *pid, DbTxn **tid, u_int32_t flags)
1359 {
1360 DB_ENV *dbenv = unwrap(this);
1361 DB_TXN *txn;
1362 int ret;
1363
1364 ret = dbenv->txn_begin(dbenv, unwrap(pid), &txn, flags);
1365 if (DB_RETOK_STD(ret))
1366 *tid = new DbTxn(txn, pid);
1367 else
1368 DB_ERROR(this, "DbEnv::txn_begin", ret, error_policy());
1369
1370 return (ret);
1371 }
1372
1373 DBENV_METHOD(txn_checkpoint, (u_int32_t kbyte, u_int32_t min, u_int32_t flags),
1374 (dbenv, kbyte, min, flags))
1375
txn_recover(DbPreplist * preplist,long count,long * retp,u_int32_t flags)1376 int DbEnv::txn_recover(DbPreplist *preplist, long count,
1377 long *retp, u_int32_t flags)
1378 {
1379 DB_ENV *dbenv = unwrap(this);
1380 DB_PREPLIST *c_preplist;
1381 long i;
1382 int ret;
1383
1384 /*
1385 * We need to allocate some local storage for the
1386 * returned preplist, and that requires us to do
1387 * our own argument validation.
1388 */
1389 if (count <= 0)
1390 ret = EINVAL;
1391 else
1392 ret = __os_malloc(dbenv->env, sizeof(DB_PREPLIST) * count,
1393 &c_preplist);
1394
1395 if (ret != 0) {
1396 DB_ERROR(this, "DbEnv::txn_recover", ret, error_policy());
1397 return (ret);
1398 }
1399
1400 if ((ret =
1401 dbenv->txn_recover(dbenv, c_preplist, count, retp, flags)) != 0) {
1402 __os_free(dbenv->env, c_preplist);
1403 DB_ERROR(this, "DbEnv::txn_recover", ret, error_policy());
1404 return (ret);
1405 }
1406
1407 for (i = 0; i < *retp; i++) {
1408 preplist[i].txn = new DbTxn(NULL);
1409 preplist[i].txn->imp_ = c_preplist[i].txn;
1410 memcpy(preplist[i].gid, c_preplist[i].gid,
1411 sizeof(preplist[i].gid));
1412 }
1413
1414 __os_free(dbenv->env, c_preplist);
1415
1416 return (0);
1417 }
1418
1419 DBENV_METHOD(txn_stat, (DB_TXN_STAT **statp, u_int32_t flags),
1420 (dbenv, statp, flags))
1421 DBENV_METHOD(txn_stat_print, (u_int32_t flags), (dbenv, flags))
1422
rep_set_transport(int myid,int (* arg)(DbEnv *,const Dbt *,const Dbt *,const DbLsn *,int,u_int32_t))1423 int DbEnv::rep_set_transport(int myid, int (*arg)(DbEnv *,
1424 const Dbt *, const Dbt *, const DbLsn *, int, u_int32_t))
1425 {
1426 DB_ENV *dbenv = unwrap(this);
1427 int ret;
1428
1429 rep_send_callback_ = arg;
1430 if ((ret = dbenv->rep_set_transport(dbenv, myid,
1431 arg == 0 ? 0 : _rep_send_intercept_c)) != 0)
1432 DB_ERROR(this, "DbEnv::rep_set_transport", ret, error_policy());
1433
1434 return (ret);
1435 }
1436
1437 DBENV_METHOD(rep_elect, (u_int32_t nsites, u_int32_t nvotes, u_int32_t flags),
1438 (dbenv, nsites, nvotes, flags))
1439 DBENV_METHOD(rep_flush, (), (dbenv))
1440 DBENV_METHOD(rep_get_config, (u_int32_t which, int *onoffp),
1441 (dbenv, which, onoffp))
1442 DBENV_METHOD(rep_get_request, (u_int32_t *min, u_int32_t *max),
1443 (dbenv, min, max))
1444 DBENV_METHOD(rep_set_request, (u_int32_t min, u_int32_t max), (dbenv, min, max))
1445
rep_process_message(Dbt * control,Dbt * rec,int id,DbLsn * ret_lsnp)1446 int DbEnv::rep_process_message(Dbt *control,
1447 Dbt *rec, int id, DbLsn *ret_lsnp)
1448 {
1449 DB_ENV *dbenv = unwrap(this);
1450 int ret;
1451
1452 ret = dbenv->rep_process_message(dbenv, control, rec, id, ret_lsnp);
1453 if (!DB_RETOK_REPPMSG(ret))
1454 DB_ERROR(this, "DbEnv::rep_process_message", ret,
1455 error_policy());
1456
1457 return (ret);
1458 }
1459
1460 DBENV_METHOD(rep_set_config,
1461 (u_int32_t which, int onoff), (dbenv, which, onoff))
1462 DBENV_METHOD(rep_start,
1463 (Dbt *cookie, u_int32_t flags),
1464 (dbenv, (DBT *)cookie, flags))
1465
1466 DBENV_METHOD(rep_stat, (DB_REP_STAT **statp, u_int32_t flags),
1467 (dbenv, statp, flags))
1468 DBENV_METHOD(rep_stat_print, (u_int32_t flags), (dbenv, flags))
1469 DBENV_METHOD(rep_sync, (u_int32_t flags), (dbenv, flags))
1470
1471 DBENV_METHOD(rep_get_clockskew, (u_int32_t *fast_clockp, u_int32_t *slow_clockp),
1472 (dbenv, fast_clockp, slow_clockp))
1473 DBENV_METHOD(rep_set_clockskew, (u_int32_t fast_clock, u_int32_t slow_clock),
1474 (dbenv, fast_clock, slow_clock))
1475 DBENV_METHOD(rep_get_limit, (u_int32_t *gbytesp, u_int32_t *bytesp),
1476 (dbenv, gbytesp, bytesp))
1477 DBENV_METHOD(rep_set_limit, (u_int32_t gbytes, u_int32_t bytes),
1478 (dbenv, gbytes, bytes))
1479
1480 //
1481 // Begin advanced replication API method implementations
1482 DBENV_METHOD(rep_get_nsites, (u_int32_t *n), (dbenv, n))
1483 DBENV_METHOD(rep_set_nsites, (u_int32_t n), (dbenv, n))
1484 DBENV_METHOD(rep_get_priority, (u_int32_t *priority),
1485 (dbenv, priority))
1486 DBENV_METHOD(rep_set_priority, (u_int32_t priority),
1487 (dbenv, priority))
1488 DBENV_METHOD(rep_get_timeout, (int which, db_timeout_t * timeout),
1489 (dbenv, which, timeout))
1490 DBENV_METHOD(rep_set_timeout, (int which, db_timeout_t timeout),
1491 (dbenv, which, timeout))
1492
rep_set_view(int (* arg)(DbEnv *,const char *,int *,u_int32_t))1493 int DbEnv::rep_set_view(int (*arg)(DbEnv *, const char *, int *, u_int32_t))
1494 {
1495 DB_ENV *dbenv = unwrap(this);
1496
1497 partial_rep_callback_ = arg;
1498
1499 return (dbenv->rep_set_view(dbenv,
1500 arg == 0 ? 0 : _partial_rep_intercept_c));
1501 }
1502
1503 DBENV_METHOD(repmgr_get_ack_policy, (int *policy), (dbenv, policy))
1504 DBENV_METHOD(repmgr_set_ack_policy, (int policy), (dbenv, policy))
1505 DBENV_METHOD(repmgr_get_incoming_queue_max,
1506 (u_int32_t *gbytesp, u_int32_t *bytesp), (dbenv, gbytesp, bytesp));
1507 DBENV_METHOD(repmgr_set_incoming_queue_max,
1508 (u_int32_t gbytes, u_int32_t bytes), (dbenv, gbytes, bytes));
1509
repmgr_set_socket(int (* approval_func)(DbEnv *,DB_REPMGR_SOCKET,int *,u_int32_t))1510 int DbEnv::repmgr_set_socket(int (*approval_func)(DbEnv *,
1511 DB_REPMGR_SOCKET, int *, u_int32_t))
1512 {
1513 DB_ENV *dbenv = unwrap(this);
1514 int ret;
1515
1516 repmgr_set_socket_callback_ = approval_func;
1517 if ((ret = dbenv->repmgr_set_socket(dbenv,
1518 approval_func == 0 ? 0 : _repmgr_set_socket_intercept_c)) != 0)
1519 DB_ERROR(this, "DbEnv::repmgr_set_socket", ret, error_policy());
1520
1521 return (ret);
1522 }
1523
1524 DBENV_METHOD(repmgr_set_ssl_config,
1525 (int which, char *value), (dbenv, which, value))
1526
repmgr_channel(int eid,DbChannel ** dbchannel,u_int32_t flags)1527 int DbEnv::repmgr_channel(int eid, DbChannel **dbchannel, u_int32_t flags)
1528 {
1529 DB_ENV *dbenv = unwrap(this);
1530 DB_CHANNEL *channel;
1531 int ret;
1532
1533 ret = dbenv->repmgr_channel(dbenv, eid, &channel, flags);
1534 if (DB_RETOK_STD(ret)) {
1535 *dbchannel = new DbChannel();
1536 (*dbchannel)->imp_ = channel;
1537 (*dbchannel)->dbenv_ = this;
1538 } else
1539 DB_ERROR(this, "DbEnv::repmgr_channel", ret, error_policy());
1540
1541 return (ret);
1542 }
1543
repmgr_msg_dispatch(void (* arg)(DbEnv *,DbChannel *,Dbt *,u_int32_t,u_int32_t),u_int32_t flags)1544 int DbEnv::repmgr_msg_dispatch(
1545 void (*arg)(DbEnv *, DbChannel *, Dbt *, u_int32_t, u_int32_t),
1546 u_int32_t flags)
1547 {
1548 DB_ENV *dbenv = unwrap(this);
1549 int ret;
1550
1551 message_dispatch_callback_ = arg;
1552 if ((ret = dbenv->repmgr_msg_dispatch(dbenv,
1553 arg == 0 ? 0 : _message_dispatch_intercept_c, flags)) != 0)
1554 DB_ERROR(this, "DbEnv::repmgr_msg_dispatch", ret, error_policy());
1555
1556 return (ret);
1557 }
1558
repmgr_local_site(DbSite ** dbsite)1559 int DbEnv::repmgr_local_site(DbSite **dbsite)
1560 {
1561 DB_ENV *dbenv = unwrap(this);
1562 DB_SITE *site;
1563 int ret;
1564
1565 ret = dbenv->repmgr_local_site(dbenv, &site);
1566 if (DB_RETOK_REPMGR_LOCALSITE(ret)) {
1567 if (ret == 0) {
1568 *dbsite = new DbSite();
1569 (*dbsite)->imp_ = site;
1570 }
1571 } else
1572 DB_ERROR(this, "DbEnv::repmgr_local_site", ret, error_policy());
1573
1574 return (ret);
1575 }
1576
repmgr_site(const char * host,u_int port,DbSite ** dbsite,u_int32_t flags)1577 int DbEnv::repmgr_site(const char *host, u_int port, DbSite **dbsite,
1578 u_int32_t flags)
1579 {
1580 DB_ENV *dbenv = unwrap(this);
1581 DB_SITE *site;
1582 int ret;
1583
1584 ret = dbenv->repmgr_site(dbenv, host, port, &site, flags);
1585 if (DB_RETOK_STD(ret)) {
1586 *dbsite = new DbSite();
1587 (*dbsite)->imp_ = site;
1588 } else
1589 DB_ERROR(this, "DbEnv::repmgr_site", ret, error_policy());
1590
1591 return (ret);
1592 }
1593
repmgr_site_by_eid(int eid,DbSite ** dbsite)1594 int DbEnv::repmgr_site_by_eid(int eid, DbSite **dbsite)
1595 {
1596 DB_ENV *dbenv = unwrap(this);
1597 DB_SITE *site;
1598 int ret;
1599
1600 ret = dbenv->repmgr_site_by_eid(dbenv, eid, &site);
1601 if (DB_RETOK_STD(ret)) {
1602 *dbsite = new DbSite();
1603 (*dbsite)->imp_ = site;
1604 } else
1605 DB_ERROR(this, "DbEnv::repmgr_site_by_eid", ret,
1606 error_policy());
1607
1608 return (ret);
1609 }
1610
1611 DBENV_METHOD(repmgr_site_list, (u_int *countp, DB_REPMGR_SITE **listp),
1612 (dbenv, countp, listp))
1613
repmgr_start(int nthreads,u_int32_t flags)1614 int DbEnv::repmgr_start(int nthreads, u_int32_t flags)
1615 {
1616 DB_ENV *dbenv = unwrap(this);
1617 int ret;
1618
1619 ret = dbenv->repmgr_start(dbenv, nthreads, flags);
1620 if (!DB_RETOK_REPMGR_START(ret))
1621 DB_ERROR(this, "DbEnv::repmgr_start", ret,
1622 error_policy());
1623
1624 return (ret);
1625 }
1626
1627 DBENV_METHOD(repmgr_stat, (DB_REPMGR_STAT **statp, u_int32_t flags),
1628 (dbenv, statp, flags))
1629 DBENV_METHOD(repmgr_stat_print, (u_int32_t flags), (dbenv, flags))
1630
1631 // End advanced replication API method implementations.
1632
1633 DBENV_METHOD(get_timeout,
1634 (db_timeout_t *timeoutp, u_int32_t flags),
1635 (dbenv, timeoutp, flags))
1636 DBENV_METHOD(set_timeout,
1637 (db_timeout_t timeout, u_int32_t flags),
1638 (dbenv, timeout, flags))
1639
1640 DBENV_METHOD(backup,
1641 (const char *target, u_int32_t flags), (dbenv, target, flags))
1642 DBENV_METHOD(dbbackup,
1643 (const char *dbfile, const char *target, u_int32_t flags),
1644 (dbenv, dbfile, target, flags))
1645
1646 // static method
version(int * major,int * minor,int * patch)1647 char *DbEnv::version(int *major, int *minor, int *patch)
1648 {
1649 return (db_version(major, minor, patch));
1650 }
1651
1652 // static method
full_version(int * family,int * release,int * major,int * minor,int * patch)1653 char *DbEnv::full_version(int *family, int *release,
1654 int *major, int *minor, int *patch)
1655 {
1656 return (db_full_version(family, release, major, minor, patch));
1657 }
1658
1659 // static method
wrap_DB_ENV(DB_ENV * dbenv)1660 DbEnv *DbEnv::wrap_DB_ENV(DB_ENV *dbenv)
1661 {
1662 DbEnv *wrapped_env = get_DbEnv(dbenv);
1663 return (wrapped_env != NULL) ? wrapped_env : new DbEnv(dbenv, 0);
1664 }
1665
1666 //static method used for testing
slices_enabled()1667 bool DbEnv::slices_enabled()
1668 {
1669 DB_ENV *dbenv;
1670 u_int32_t count;
1671
1672 if (db_env_create(&dbenv, 0) != 0)
1673 return (false);
1674 dbenv->set_errfile(dbenv, NULL);
1675 dbenv->set_errcall(dbenv, NULL);
1676
1677 if (dbenv->get_slice_count(dbenv, &count) == DB_OPNOTSUP)
1678 return (false);
1679
1680 (void)dbenv->close(dbenv, 0);
1681
1682 return (true);
1683 }
1684