1/*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 1997,2008 Oracle. All rights reserved. 5 * 6 * $Id: cxx_db.cpp,v 12.22 2008/01/08 20:58:09 bostic Exp $ 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_auto/db_auto.h" 18#include "dbinc_auto/crdel_auto.h" 19#include "dbinc/db_dispatch.h" 20#include "dbinc_auto/db_ext.h" 21#include "dbinc_auto/common_ext.h" 22 23// Helper macros for simple methods that pass through to the 24// underlying C method. It may return an error or raise an exception. 25// Note this macro expects that input _argspec is an argument 26// list element (e.g., "char *arg") and that _arglist is the arguments 27// that should be passed through to the C method (e.g., "(db, arg)") 28// 29#define DB_METHOD(_name, _argspec, _arglist, _retok) \ 30int Db::_name _argspec \ 31{ \ 32 int ret; \ 33 DB *db = unwrap(this); \ 34 \ 35 ret = db->_name _arglist; \ 36 if (!_retok(ret)) \ 37 DB_ERROR(dbenv_, "Db::" # _name, ret, error_policy()); \ 38 return (ret); \ 39} 40 41#define DB_DESTRUCTOR(_name, _argspec, _arglist, _retok) \ 42int Db::_name _argspec \ 43{ \ 44 int ret; \ 45 DB *db = unwrap(this); \ 46 \ 47 if (!db) { \ 48 DB_ERROR(dbenv_, "Db::" # _name, EINVAL, error_policy()); \ 49 return (EINVAL); \ 50 } \ 51 ret = db->_name _arglist; \ 52 cleanup(); \ 53 if (!_retok(ret)) \ 54 DB_ERROR(dbenv_, "Db::" # _name, ret, error_policy()); \ 55 return (ret); \ 56} 57 58#define DB_METHOD_QUIET(_name, _argspec, _arglist) \ 59int Db::_name _argspec \ 60{ \ 61 DB *db = unwrap(this); \ 62 \ 63 return (db->_name _arglist); \ 64} 65 66#define DB_METHOD_VOID(_name, _argspec, _arglist) \ 67void Db::_name _argspec \ 68{ \ 69 DB *db = unwrap(this); \ 70 \ 71 db->_name _arglist; \ 72} 73 74// A truism for the Db object is that there is a valid 75// DB handle from the constructor until close(). 76// After the close, the DB handle is invalid and 77// no operations are permitted on the Db (other than 78// destructor). Leaving the Db handle open and not 79// doing a close is generally considered an error. 80// 81// We used to allow Db objects to be closed and reopened. 82// This implied always keeping a valid DB object, and 83// coordinating the open objects between Db/DbEnv turned 84// out to be overly complicated. Now we do not allow this. 85 86Db::Db(DbEnv *dbenv, u_int32_t flags) 87: imp_(0) 88, dbenv_(dbenv) 89, mpf_(0) 90, construct_error_(0) 91, flags_(0) 92, construct_flags_(flags) 93, append_recno_callback_(0) 94, associate_callback_(0) 95, bt_compare_callback_(0) 96, bt_prefix_callback_(0) 97, dup_compare_callback_(0) 98, feedback_callback_(0) 99, h_compare_callback_(0) 100, h_hash_callback_(0) 101{ 102 if (dbenv_ == 0) 103 flags_ |= DB_CXX_PRIVATE_ENV; 104 105 if ((construct_error_ = initialize()) != 0) 106 DB_ERROR(dbenv_, "Db::Db", construct_error_, error_policy()); 107} 108 109// If the DB handle is still open, we close it. This is to make stack 110// allocation of Db objects easier so that they are cleaned up in the error 111// path. If the environment was closed prior to this, it may cause a trap, but 112// an error message is generated during the environment close. Applications 113// should call close explicitly in normal (non-exceptional) cases to check the 114// return value. 115// 116Db::~Db() 117{ 118 DB *db; 119 120 db = unwrap(this); 121 if (db != NULL) { 122 (void)db->close(db, 0); 123 cleanup(); 124 } 125} 126 127// private method to initialize during constructor. 128// initialize must create a backing DB object, 129// and if that creates a new DB_ENV, it must be tied to a new DbEnv. 130// 131int Db::initialize() 132{ 133 DB *db; 134 DB_ENV *cenv = unwrap(dbenv_); 135 int ret; 136 u_int32_t cxx_flags; 137 138 cxx_flags = construct_flags_ & DB_CXX_NO_EXCEPTIONS; 139 140 // Create a new underlying DB object. 141 // We rely on the fact that if a NULL DB_ENV* is given, 142 // one is allocated by DB. 143 // 144 if ((ret = db_create(&db, cenv, 145 construct_flags_ & ~cxx_flags)) != 0) 146 return (ret); 147 148 // Associate the DB with this object 149 imp_ = db; 150 db->api_internal = this; 151 152 // Create a new DbEnv from a DB_ENV* if it was created locally. 153 // It is deleted in Db::close(). 154 // 155 if ((flags_ & DB_CXX_PRIVATE_ENV) != 0) 156 dbenv_ = new DbEnv(db->dbenv, cxx_flags); 157 158 // Create a DbMpoolFile from the DB_MPOOLFILE* in the DB handle. 159 mpf_ = new DbMpoolFile(); 160 mpf_->imp_ = db->mpf; 161 162 return (0); 163} 164 165// private method to cleanup after destructor or during close. 166// If the environment was created by this Db object, we need to delete it. 167// 168void Db::cleanup() 169{ 170 if (imp_ != 0) { 171 imp_ = 0; 172 173 // we must dispose of the DbEnv object if 174 // we created it. This will be the case 175 // if a NULL DbEnv was passed into the constructor. 176 // The underlying DB_ENV object will be inaccessible 177 // after the close, so we must clean it up now. 178 // 179 if ((flags_ & DB_CXX_PRIVATE_ENV) != 0) { 180 dbenv_->cleanup(); 181 delete dbenv_; 182 dbenv_ = 0; 183 } 184 185 delete mpf_; 186 } 187} 188 189// Return a tristate value corresponding to whether we should 190// throw exceptions on errors: 191// ON_ERROR_RETURN 192// ON_ERROR_THROW 193// ON_ERROR_UNKNOWN 194// 195int Db::error_policy() 196{ 197 if (dbenv_ != NULL) 198 return (dbenv_->error_policy()); 199 else { 200 // If the dbenv_ is null, that means that the user 201 // did not attach an environment, so the correct error 202 // policy can be deduced from constructor flags 203 // for this Db. 204 // 205 if ((construct_flags_ & DB_CXX_NO_EXCEPTIONS) != 0) { 206 return (ON_ERROR_RETURN); 207 } 208 else { 209 return (ON_ERROR_THROW); 210 } 211 } 212} 213 214DB_DESTRUCTOR(close, (u_int32_t flags), (db, flags), DB_RETOK_STD) 215DB_METHOD(compact, (DbTxn *txnid, Dbt *start, Dbt *stop, 216 DB_COMPACT *c_data, u_int32_t flags, Dbt *end), 217 (db, unwrap(txnid), start, stop, c_data, flags, end), DB_RETOK_STD) 218 219// The following cast implies that Dbc can be no larger than DBC 220DB_METHOD(cursor, (DbTxn *txnid, Dbc **cursorp, u_int32_t flags), 221 (db, unwrap(txnid), (DBC **)cursorp, flags), 222 DB_RETOK_STD) 223 224DB_METHOD(del, (DbTxn *txnid, Dbt *key, u_int32_t flags), 225 (db, unwrap(txnid), key, flags), 226 DB_RETOK_DBDEL) 227 228void Db::err(int error, const char *format, ...) 229{ 230 DB *db = unwrap(this); 231 232 DB_REAL_ERR(db->dbenv, error, DB_ERROR_SET, 1, format); 233} 234 235void Db::errx(const char *format, ...) 236{ 237 DB *db = unwrap(this); 238 239 DB_REAL_ERR(db->dbenv, 0, DB_ERROR_NOT_SET, 1, format); 240} 241 242DB_METHOD(exists, (DbTxn *txnid, Dbt *key, u_int32_t flags), 243 (db, unwrap(txnid), key, flags), DB_RETOK_EXISTS) 244 245DB_METHOD(fd, (int *fdp), (db, fdp), DB_RETOK_STD) 246 247int Db::get(DbTxn *txnid, Dbt *key, Dbt *value, u_int32_t flags) 248{ 249 DB *db = unwrap(this); 250 int ret; 251 252 ret = db->get(db, unwrap(txnid), key, value, flags); 253 254 if (!DB_RETOK_DBGET(ret)) { 255 if (ret == DB_BUFFER_SMALL) 256 DB_ERROR_DBT(dbenv_, "Db::get", value, error_policy()); 257 else 258 DB_ERROR(dbenv_, "Db::get", ret, error_policy()); 259 } 260 261 return (ret); 262} 263 264int Db::get_byteswapped(int *isswapped) 265{ 266 DB *db = (DB *)unwrapConst(this); 267 return (db->get_byteswapped(db, isswapped)); 268} 269 270DbEnv *Db::get_env() 271{ 272 DB *db = (DB *)unwrapConst(this); 273 DB_ENV *dbenv = db->get_env(db); 274 return (dbenv != NULL ? DbEnv::get_DbEnv(dbenv) : NULL); 275} 276 277DbMpoolFile *Db::get_mpf() 278{ 279 return (mpf_); 280} 281 282DB_METHOD(get_dbname, (const char **filenamep, const char **dbnamep), 283 (db, filenamep, dbnamep), DB_RETOK_STD) 284 285DB_METHOD(get_open_flags, (u_int32_t *flagsp), (db, flagsp), DB_RETOK_STD) 286 287int Db::get_type(DBTYPE *dbtype) 288{ 289 DB *db = (DB *)unwrapConst(this); 290 return (db->get_type(db, dbtype)); 291} 292 293// Dbc is a "compatible" subclass of DBC - that is, no virtual functions 294// or even extra data members, so these casts, although technically 295// non-portable, "should" always be okay. 296DB_METHOD(join, (Dbc **curslist, Dbc **cursorp, u_int32_t flags), 297 (db, (DBC **)curslist, (DBC **)cursorp, flags), DB_RETOK_STD) 298 299DB_METHOD(key_range, 300 (DbTxn *txnid, Dbt *key, DB_KEY_RANGE *results, u_int32_t flags), 301 (db, unwrap(txnid), key, results, flags), DB_RETOK_STD) 302 303// If an error occurred during the constructor, report it now. 304// Otherwise, call the underlying DB->open method. 305// 306int Db::open(DbTxn *txnid, const char *file, const char *database, 307 DBTYPE type, u_int32_t flags, int mode) 308{ 309 int ret; 310 DB *db = unwrap(this); 311 312 if (construct_error_ != 0) 313 ret = construct_error_; 314 else 315 ret = db->open(db, unwrap(txnid), file, database, type, flags, 316 mode); 317 318 if (!DB_RETOK_STD(ret)) 319 DB_ERROR(dbenv_, "Db::open", ret, error_policy()); 320 321 return (ret); 322} 323 324int Db::pget(DbTxn *txnid, Dbt *key, Dbt *pkey, Dbt *value, u_int32_t flags) 325{ 326 DB *db = unwrap(this); 327 int ret; 328 329 ret = db->pget(db, unwrap(txnid), key, pkey, value, flags); 330 331 /* The logic here is identical to Db::get - reuse the macro. */ 332 if (!DB_RETOK_DBGET(ret)) { 333 if (ret == DB_BUFFER_SMALL && DB_OVERFLOWED_DBT(value)) 334 DB_ERROR_DBT(dbenv_, "Db::pget", value, error_policy()); 335 else 336 DB_ERROR(dbenv_, "Db::pget", ret, error_policy()); 337 } 338 339 return (ret); 340} 341 342DB_METHOD(put, (DbTxn *txnid, Dbt *key, Dbt *value, u_int32_t flags), 343 (db, unwrap(txnid), key, value, flags), DB_RETOK_DBPUT) 344 345DB_DESTRUCTOR(rename, 346 (const char *file, const char *database, const char *newname, 347 u_int32_t flags), 348 (db, file, database, newname, flags), DB_RETOK_STD) 349 350DB_DESTRUCTOR(remove, (const char *file, const char *database, u_int32_t flags), 351 (db, file, database, flags), DB_RETOK_STD) 352 353DB_METHOD(truncate, (DbTxn *txnid, u_int32_t *countp, u_int32_t flags), 354 (db, unwrap(txnid), countp, flags), DB_RETOK_STD) 355 356DB_METHOD(stat, (DbTxn *txnid, void *sp, u_int32_t flags), 357 (db, unwrap(txnid), sp, flags), DB_RETOK_STD) 358 359DB_METHOD(stat_print, (u_int32_t flags), (db, flags), DB_RETOK_STD) 360 361DB_METHOD(sync, (u_int32_t flags), (db, flags), DB_RETOK_STD) 362 363DB_METHOD(upgrade, 364 (const char *name, u_int32_t flags), (db, name, flags), DB_RETOK_STD) 365 366//////////////////////////////////////////////////////////////////////// 367// 368// callbacks 369// 370// *_intercept_c are 'glue' functions that must be declared 371// as extern "C" so to be typesafe. Using a C++ method, even 372// a static class method with 'correct' arguments, will not pass 373// the test; some picky compilers do not allow mixing of function 374// pointers to 'C' functions with function pointers to C++ functions. 375// 376// One wart with this scheme is that the *_callback_ method pointer 377// must be declared public to be accessible by the C intercept. 378// It's possible to accomplish the goal without this, and with 379// another public transfer method, but it's just too much overhead. 380// These callbacks are supposed to be *fast*. 381// 382// The DBTs we receive in these callbacks from the C layer may be 383// manufactured there, but we want to treat them as a Dbts. 384// Technically speaking, these DBTs were not constructed as a Dbts, 385// but it should be safe to cast them as such given that Dbt is a 386// *very* thin extension of the DBT. That is, Dbt has no additional 387// data elements, does not use virtual functions, virtual inheritance, 388// multiple inheritance, RTI, or any other language feature that 389// causes the structure to grow or be displaced. Although this may 390// sound risky, a design goal of C++ is complete structure 391// compatibility with C, and has the philosophy 'if you don't use it, 392// you shouldn't incur the overhead'. If the C/C++ compilers you're 393// using on a given machine do not have matching struct layouts, then 394// a lot more things will be broken than just this. 395// 396// The alternative, creating a Dbt here in the callback, and populating 397// it from the DBT, is just too slow and cumbersome to be very useful. 398 399// These macros avoid a lot of boilerplate code for callbacks 400 401#define DB_CALLBACK_C_INTERCEPT(_name, _rettype, _cargspec, \ 402 _return, _cxxargs) \ 403extern "C" _rettype _db_##_name##_intercept_c _cargspec \ 404{ \ 405 Db *cxxthis; \ 406 \ 407 /* We don't have a dbenv handle at this point. */ \ 408 DB_ASSERT(NULL, cthis != NULL); \ 409 cxxthis = Db::get_Db(cthis); \ 410 DB_ASSERT(cthis->dbenv->env, cxxthis != NULL); \ 411 DB_ASSERT(cthis->dbenv->env, cxxthis->_name##_callback_ != 0); \ 412 \ 413 _return (*cxxthis->_name##_callback_) _cxxargs; \ 414} 415 416#define DB_SET_CALLBACK(_cxxname, _name, _cxxargspec, _cb) \ 417int Db::_cxxname _cxxargspec \ 418{ \ 419 DB *cthis = unwrap(this); \ 420 \ 421 _name##_callback_ = _cb; \ 422 return ((*(cthis->_cxxname))(cthis, \ 423 (_cb) ? _db_##_name##_intercept_c : NULL)); \ 424} 425 426/* associate callback - doesn't quite fit the pattern because of the flags */ 427DB_CALLBACK_C_INTERCEPT(associate, 428 int, (DB *cthis, const DBT *key, const DBT *data, DBT *retval), 429 return, (cxxthis, Dbt::get_const_Dbt(key), Dbt::get_const_Dbt(data), 430 Dbt::get_Dbt(retval))) 431 432int Db::associate(DbTxn *txn, Db *secondary, int (*callback)(Db *, const Dbt *, 433 const Dbt *, Dbt *), u_int32_t flags) 434{ 435 DB *cthis = unwrap(this); 436 437 /* Since the secondary Db is used as the first argument 438 * to the callback, we store the C++ callback on it 439 * rather than on 'this'. 440 */ 441 secondary->associate_callback_ = callback; 442 return ((*(cthis->associate))(cthis, unwrap(txn), unwrap(secondary), 443 (callback) ? _db_associate_intercept_c : NULL, flags)); 444} 445 446DB_CALLBACK_C_INTERCEPT(feedback, 447 void, (DB *cthis, int opcode, int pct), 448 /* no return */ (void), (cxxthis, opcode, pct)) 449 450DB_SET_CALLBACK(set_feedback, feedback, 451 (void (*arg)(Db *cxxthis, int opcode, int pct)), arg) 452 453DB_CALLBACK_C_INTERCEPT(append_recno, 454 int, (DB *cthis, DBT *data, db_recno_t recno), 455 return, (cxxthis, Dbt::get_Dbt(data), recno)) 456 457DB_SET_CALLBACK(set_append_recno, append_recno, 458 (int (*arg)(Db *cxxthis, Dbt *data, db_recno_t recno)), arg) 459 460DB_CALLBACK_C_INTERCEPT(bt_compare, 461 int, (DB *cthis, const DBT *data1, const DBT *data2), 462 return, 463 (cxxthis, Dbt::get_const_Dbt(data1), Dbt::get_const_Dbt(data2))) 464 465DB_SET_CALLBACK(set_bt_compare, bt_compare, 466 (int (*arg)(Db *cxxthis, const Dbt *data1, const Dbt *data2)), arg) 467 468DB_CALLBACK_C_INTERCEPT(bt_prefix, 469 size_t, (DB *cthis, const DBT *data1, const DBT *data2), 470 return, 471 (cxxthis, Dbt::get_const_Dbt(data1), Dbt::get_const_Dbt(data2))) 472 473DB_SET_CALLBACK(set_bt_prefix, bt_prefix, 474 (size_t (*arg)(Db *cxxthis, const Dbt *data1, const Dbt *data2)), arg) 475 476DB_CALLBACK_C_INTERCEPT(dup_compare, 477 int, (DB *cthis, const DBT *data1, const DBT *data2), 478 return, 479 (cxxthis, Dbt::get_const_Dbt(data1), Dbt::get_const_Dbt(data2))) 480 481DB_SET_CALLBACK(set_dup_compare, dup_compare, 482 (int (*arg)(Db *cxxthis, const Dbt *data1, const Dbt *data2)), arg) 483 484DB_CALLBACK_C_INTERCEPT(h_compare, 485 int, (DB *cthis, const DBT *data1, const DBT *data2), 486 return, 487 (cxxthis, Dbt::get_const_Dbt(data1), Dbt::get_const_Dbt(data2))) 488 489DB_SET_CALLBACK(set_h_compare, h_compare, 490 (int (*arg)(Db *cxxthis, const Dbt *data1, const Dbt *data2)), arg) 491 492DB_CALLBACK_C_INTERCEPT(h_hash, 493 u_int32_t, (DB *cthis, const void *data, u_int32_t len), 494 return, (cxxthis, data, len)) 495 496DB_SET_CALLBACK(set_h_hash, h_hash, 497 (u_int32_t (*arg)(Db *cxxthis, const void *data, u_int32_t len)), arg) 498 499// This is a 'glue' function declared as extern "C" so it will 500// be compatible with picky compilers that do not allow mixing 501// of function pointers to 'C' functions with function pointers 502// to C++ functions. 503// 504extern "C" 505int _verify_callback_c(void *handle, const void *str_arg) 506{ 507 char *str; 508 __DB_STD(ostream) *out; 509 510 str = (char *)str_arg; 511 out = (__DB_STD(ostream) *)handle; 512 513 (*out) << str; 514 if (out->fail()) 515 return (EIO); 516 517 return (0); 518} 519 520int Db::verify(const char *name, const char *subdb, 521 __DB_STD(ostream) *ostr, u_int32_t flags) 522{ 523 DB *db = unwrap(this); 524 int ret; 525 526 if (!db) 527 ret = EINVAL; 528 else { 529 ret = __db_verify_internal(db, name, subdb, ostr, 530 _verify_callback_c, flags); 531 532 // After a DB->verify (no matter if success or failure), 533 // the underlying DB object must not be accessed. 534 // 535 cleanup(); 536 } 537 538 if (!DB_RETOK_STD(ret)) 539 DB_ERROR(dbenv_, "Db::verify", ret, error_policy()); 540 541 return (ret); 542} 543 544DB_METHOD(set_bt_compare, (bt_compare_fcn_type func), 545 (db, func), DB_RETOK_STD) 546DB_METHOD(get_bt_minkey, (u_int32_t *bt_minkeyp), 547 (db, bt_minkeyp), DB_RETOK_STD) 548DB_METHOD(set_bt_minkey, (u_int32_t bt_minkey), 549 (db, bt_minkey), DB_RETOK_STD) 550DB_METHOD(set_bt_prefix, (bt_prefix_fcn_type func), 551 (db, func), DB_RETOK_STD) 552DB_METHOD(set_dup_compare, (dup_compare_fcn_type func), 553 (db, func), DB_RETOK_STD) 554DB_METHOD(get_encrypt_flags, (u_int32_t *flagsp), 555 (db, flagsp), DB_RETOK_STD) 556DB_METHOD(set_encrypt, (const char *passwd, u_int32_t flags), 557 (db, passwd, flags), DB_RETOK_STD) 558DB_METHOD_VOID(get_errfile, (FILE **errfilep), (db, errfilep)) 559DB_METHOD_VOID(set_errfile, (FILE *errfile), (db, errfile)) 560DB_METHOD_VOID(get_errpfx, (const char **errpfx), (db, errpfx)) 561DB_METHOD_VOID(set_errpfx, (const char *errpfx), (db, errpfx)) 562DB_METHOD(get_flags, (u_int32_t *flagsp), (db, flagsp), 563 DB_RETOK_STD) 564DB_METHOD(set_flags, (u_int32_t flags), (db, flags), 565 DB_RETOK_STD) 566DB_METHOD(set_h_compare, (h_compare_fcn_type func), 567 (db, func), DB_RETOK_STD) 568DB_METHOD(get_h_ffactor, (u_int32_t *h_ffactorp), 569 (db, h_ffactorp), DB_RETOK_STD) 570DB_METHOD(set_h_ffactor, (u_int32_t h_ffactor), 571 (db, h_ffactor), DB_RETOK_STD) 572DB_METHOD(set_h_hash, (h_hash_fcn_type func), 573 (db, func), DB_RETOK_STD) 574DB_METHOD(get_h_nelem, (u_int32_t *h_nelemp), 575 (db, h_nelemp), DB_RETOK_STD) 576DB_METHOD(set_h_nelem, (u_int32_t h_nelem), 577 (db, h_nelem), DB_RETOK_STD) 578DB_METHOD(get_lorder, (int *db_lorderp), (db, db_lorderp), 579 DB_RETOK_STD) 580DB_METHOD(set_lorder, (int db_lorder), (db, db_lorder), 581 DB_RETOK_STD) 582DB_METHOD_VOID(get_msgfile, (FILE **msgfilep), (db, msgfilep)) 583DB_METHOD_VOID(set_msgfile, (FILE *msgfile), (db, msgfile)) 584DB_METHOD_QUIET(get_multiple, (), (db)) 585DB_METHOD(get_pagesize, (u_int32_t *db_pagesizep), 586 (db, db_pagesizep), DB_RETOK_STD) 587DB_METHOD(set_pagesize, (u_int32_t db_pagesize), 588 (db, db_pagesize), DB_RETOK_STD) 589DB_METHOD(get_priority, (DB_CACHE_PRIORITY *priorityp), 590 (db, priorityp), DB_RETOK_STD) 591DB_METHOD(set_priority, (DB_CACHE_PRIORITY priority), 592 (db, priority), DB_RETOK_STD) 593DB_METHOD(get_re_delim, (int *re_delimp), 594 (db, re_delimp), DB_RETOK_STD) 595DB_METHOD(set_re_delim, (int re_delim), 596 (db, re_delim), DB_RETOK_STD) 597DB_METHOD(get_re_len, (u_int32_t *re_lenp), 598 (db, re_lenp), DB_RETOK_STD) 599DB_METHOD(set_re_len, (u_int32_t re_len), 600 (db, re_len), DB_RETOK_STD) 601DB_METHOD(get_re_pad, (int *re_padp), 602 (db, re_padp), DB_RETOK_STD) 603DB_METHOD(set_re_pad, (int re_pad), 604 (db, re_pad), DB_RETOK_STD) 605DB_METHOD(get_re_source, (const char **re_source), 606 (db, re_source), DB_RETOK_STD) 607DB_METHOD(set_re_source, (const char *re_source), 608 (db, re_source), DB_RETOK_STD) 609DB_METHOD(get_q_extentsize, (u_int32_t *extentsizep), 610 (db, extentsizep), DB_RETOK_STD) 611DB_METHOD(set_q_extentsize, (u_int32_t extentsize), 612 (db, extentsize), DB_RETOK_STD) 613 614DB_METHOD_QUIET(set_alloc, (db_malloc_fcn_type malloc_fcn, 615 db_realloc_fcn_type realloc_fcn, db_free_fcn_type free_fcn), 616 (db, malloc_fcn, realloc_fcn, free_fcn)) 617 618void Db::set_errcall(void (*arg)(const DbEnv *, const char *, const char *)) 619{ 620 dbenv_->set_errcall(arg); 621} 622 623void Db::set_msgcall(void (*arg)(const DbEnv *, const char *)) 624{ 625 dbenv_->set_msgcall(arg); 626} 627 628void *Db::get_app_private() const 629{ 630 return unwrapConst(this)->app_private; 631} 632 633void Db::set_app_private(void *value) 634{ 635 unwrap(this)->app_private = value; 636} 637 638DB_METHOD(get_cachesize, (u_int32_t *gbytesp, u_int32_t *bytesp, int *ncachep), 639 (db, gbytesp, bytesp, ncachep), DB_RETOK_STD) 640DB_METHOD(set_cachesize, (u_int32_t gbytes, u_int32_t bytes, int ncache), 641 (db, gbytes, bytes, ncache), DB_RETOK_STD) 642 643int Db::set_paniccall(void (*callback)(DbEnv *, int)) 644{ 645 return (dbenv_->set_paniccall(callback)); 646} 647 648__DB_STD(ostream) *Db::get_error_stream() 649{ 650 return dbenv_->get_error_stream(); 651} 652 653void Db::set_error_stream(__DB_STD(ostream) *error_stream) 654{ 655 dbenv_->set_error_stream(error_stream); 656} 657 658__DB_STD(ostream) *Db::get_message_stream() 659{ 660 return dbenv_->get_message_stream(); 661} 662 663void Db::set_message_stream(__DB_STD(ostream) *message_stream) 664{ 665 dbenv_->set_message_stream(message_stream); 666} 667 668DB_METHOD_QUIET(get_transactional, (), (db)) 669