From 155e78f014de1a2e259ae5119f4621fbb210a784 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 30 Oct 2002 15:57:05 +0400 Subject: BDB 4.1.24 BitKeeper/deleted/.del-ex_access.wpj~3df6ae8c99bf7c5f: Delete: bdb/build_vxworks/ex_access/ex_access.wpj BitKeeper/deleted/.del-ex_btrec.wpj~a7622f1c6f432dc6: Delete: bdb/build_vxworks/ex_btrec/ex_btrec.wpj BitKeeper/deleted/.del-ex_dbclient.wpj~7345440f3b204cdd: Delete: bdb/build_vxworks/ex_dbclient/ex_dbclient.wpj BitKeeper/deleted/.del-ex_env.wpj~fbe1ab10b04e8b74: Delete: bdb/build_vxworks/ex_env/ex_env.wpj BitKeeper/deleted/.del-ex_mpool.wpj~4479cfd5c45f327d: Delete: bdb/build_vxworks/ex_mpool/ex_mpool.wpj BitKeeper/deleted/.del-ex_tpcb.wpj~f78093006e14bf41: Delete: bdb/build_vxworks/ex_tpcb/ex_tpcb.wpj BitKeeper/deleted/.del-db_buildall.dsp~bd749ff6da11682: Delete: bdb/build_win32/db_buildall.dsp BitKeeper/deleted/.del-cxx_app.cpp~ad8df8e0791011ed: Delete: bdb/cxx/cxx_app.cpp BitKeeper/deleted/.del-cxx_log.cpp~a50ff3118fe06952: Delete: bdb/cxx/cxx_log.cpp BitKeeper/deleted/.del-cxx_table.cpp~ecd751e79b055556: Delete: bdb/cxx/cxx_table.cpp BitKeeper/deleted/.del-namemap.txt~796a3acd3885d8fd: Delete: bdb/cxx/namemap.txt BitKeeper/deleted/.del-Design.fileop~3ca4da68f1727373: Delete: bdb/db/Design.fileop BitKeeper/deleted/.del-db185_int.h~61bee3736e7959ef: Delete: bdb/db185/db185_int.h BitKeeper/deleted/.del-acconfig.h~411e8854d67ad8b5: Delete: bdb/dist/acconfig.h BitKeeper/deleted/.del-mutex.m4~a13383cde18a64e1: Delete: bdb/dist/aclocal/mutex.m4 BitKeeper/deleted/.del-options.m4~b9d0ca637213750a: Delete: bdb/dist/aclocal/options.m4 BitKeeper/deleted/.del-programs.m4~3ce7890b47732b30: Delete: bdb/dist/aclocal/programs.m4 BitKeeper/deleted/.del-tcl.m4~f944e2db93c3b6db: Delete: bdb/dist/aclocal/tcl.m4 BitKeeper/deleted/.del-types.m4~59cae158c9a32cff: Delete: bdb/dist/aclocal/types.m4 BitKeeper/deleted/.del-script~d38f6d3a4f159cb4: Delete: bdb/dist/build/script BitKeeper/deleted/.del-configure.in~ac795a92c8fe049c: Delete: bdb/dist/configure.in BitKeeper/deleted/.del-ltconfig~66bbd007d8024af: Delete: bdb/dist/ltconfig BitKeeper/deleted/.del-rec_ctemp~a28554362534f00a: Delete: bdb/dist/rec_ctemp BitKeeper/deleted/.del-s_tcl~2ffe4326459fcd9f: Delete: bdb/dist/s_tcl BitKeeper/deleted/.del-.IGNORE_ME~d8148b08fa7d5d15: Delete: bdb/dist/template/.IGNORE_ME BitKeeper/deleted/.del-btree.h~179f2aefec1753d: Delete: bdb/include/btree.h BitKeeper/deleted/.del-cxx_int.h~6b649c04766508f8: Delete: bdb/include/cxx_int.h BitKeeper/deleted/.del-db.src~6b433ae615b16a8d: Delete: bdb/include/db.src BitKeeper/deleted/.del-db_185.h~ad8b373d9391d35c: Delete: bdb/include/db_185.h BitKeeper/deleted/.del-db_am.h~a714912b6b75932f: Delete: bdb/include/db_am.h BitKeeper/deleted/.del-db_cxx.h~fcafadf45f5d19e9: Delete: bdb/include/db_cxx.h BitKeeper/deleted/.del-db_dispatch.h~6844f20f7eb46904: Delete: bdb/include/db_dispatch.h BitKeeper/deleted/.del-db_int.src~419a3f48b6a01da7: Delete: bdb/include/db_int.src BitKeeper/deleted/.del-db_join.h~76f9747a42c3399a: Delete: bdb/include/db_join.h BitKeeper/deleted/.del-db_page.h~e302ca3a4db3abdc: Delete: bdb/include/db_page.h BitKeeper/deleted/.del-db_server_int.h~e1d20b6ba3bca1ab: Delete: bdb/include/db_server_int.h BitKeeper/deleted/.del-db_shash.h~5fbf2d696fac90f3: Delete: bdb/include/db_shash.h BitKeeper/deleted/.del-db_swap.h~1e60887550864a59: Delete: bdb/include/db_swap.h BitKeeper/deleted/.del-db_upgrade.h~c644eee73701fc8d: Delete: bdb/include/db_upgrade.h BitKeeper/deleted/.del-db_verify.h~b8d6c297c61f342e: Delete: bdb/include/db_verify.h BitKeeper/deleted/.del-debug.h~dc2b4f2cf27ccebc: Delete: bdb/include/debug.h BitKeeper/deleted/.del-hash.h~2aaa548b28882dfb: Delete: bdb/include/hash.h BitKeeper/deleted/.del-lock.h~a761c1b7de57b77f: Delete: bdb/include/lock.h BitKeeper/deleted/.del-log.h~ff20184238e35e4d: Delete: bdb/include/log.h BitKeeper/deleted/.del-mp.h~7e317597622f3411: Delete: bdb/include/mp.h BitKeeper/deleted/.del-mutex.h~d3ae7a2977a68137: Delete: bdb/include/mutex.h BitKeeper/deleted/.del-os.h~91867cc8757cd0e3: Delete: bdb/include/os.h BitKeeper/deleted/.del-os_jump.h~e1b939fa5151d4be: Delete: bdb/include/os_jump.h BitKeeper/deleted/.del-qam.h~6fad0c1b5723d597: Delete: bdb/include/qam.h BitKeeper/deleted/.del-queue.h~4c72c0826c123d5: Delete: bdb/include/queue.h BitKeeper/deleted/.del-region.h~513fe04d977ca0fc: Delete: bdb/include/region.h BitKeeper/deleted/.del-shqueue.h~525fc3e6c2025c36: Delete: bdb/include/shqueue.h BitKeeper/deleted/.del-tcl_db.h~c536fd61a844f23f: Delete: bdb/include/tcl_db.h BitKeeper/deleted/.del-txn.h~c8d94b221ec147e4: Delete: bdb/include/txn.h BitKeeper/deleted/.del-xa.h~ecc466493aae9d9a: Delete: bdb/include/xa.h BitKeeper/deleted/.del-DbRecoveryInit.java~756b52601a0b9023: Delete: bdb/java/src/com/sleepycat/db/DbRecoveryInit.java BitKeeper/deleted/.del-DbTxnRecover.java~74607cba7ab89d6d: Delete: bdb/java/src/com/sleepycat/db/DbTxnRecover.java BitKeeper/deleted/.del-lock_conflict.c~fc5e0f14cf597a2b: Delete: bdb/lock/lock_conflict.c BitKeeper/deleted/.del-log.src~53ac9e7b5cb023f2: Delete: bdb/log/log.src BitKeeper/deleted/.del-log_findckp.c~24287f008916e81f: Delete: bdb/log/log_findckp.c BitKeeper/deleted/.del-log_rec.c~d51711f2cac09297: Delete: bdb/log/log_rec.c BitKeeper/deleted/.del-log_register.c~b40bb4efac75ca15: Delete: bdb/log/log_register.c BitKeeper/deleted/.del-Design~b3d0f179f2767b: Delete: bdb/mp/Design BitKeeper/deleted/.del-os_finit.c~95dbefc6fe79b26c: Delete: bdb/os/os_finit.c BitKeeper/deleted/.del-os_abs.c~df95d1e7db81924: Delete: bdb/os_vxworks/os_abs.c BitKeeper/deleted/.del-os_finit.c~803b484bdb9d0122: Delete: bdb/os_vxworks/os_finit.c BitKeeper/deleted/.del-os_map.c~3a6d7926398b76d3: Delete: bdb/os_vxworks/os_map.c BitKeeper/deleted/.del-os_finit.c~19a227c6d3c78ad: Delete: bdb/os_win32/os_finit.c BitKeeper/deleted/.del-log-corruption.patch~1cf2ecc7c6408d5d: Delete: bdb/patches/log-corruption.patch BitKeeper/deleted/.del-Btree.pm~af6d0c5eaed4a98e: Delete: bdb/perl.BerkeleyDB/BerkeleyDB/Btree.pm BitKeeper/deleted/.del-BerkeleyDB.pm~7244036d4482643: Delete: bdb/perl.BerkeleyDB/BerkeleyDB.pm BitKeeper/deleted/.del-BerkeleyDB.pod~e7b18fd6132448e3: Delete: bdb/perl.BerkeleyDB/BerkeleyDB.pod BitKeeper/deleted/.del-Hash.pm~10292a26c06a5c95: Delete: bdb/perl.BerkeleyDB/BerkeleyDB/Hash.pm BitKeeper/deleted/.del-BerkeleyDB.pod.P~79f76a1495eda203: Delete: bdb/perl.BerkeleyDB/BerkeleyDB.pod.P BitKeeper/deleted/.del-BerkeleyDB.xs~80c99afbd98e392c: Delete: bdb/perl.BerkeleyDB/BerkeleyDB.xs BitKeeper/deleted/.del-Changes~729c1891efa60de9: Delete: bdb/perl.BerkeleyDB/Changes BitKeeper/deleted/.del-MANIFEST~63a1e34aecf157a0: Delete: bdb/perl.BerkeleyDB/MANIFEST BitKeeper/deleted/.del-Makefile.PL~c68797707d8df87a: Delete: bdb/perl.BerkeleyDB/Makefile.PL BitKeeper/deleted/.del-README~5f2f579b1a241407: Delete: bdb/perl.BerkeleyDB/README BitKeeper/deleted/.del-Todo~dca3c66c193adda9: Delete: bdb/perl.BerkeleyDB/Todo BitKeeper/deleted/.del-config.in~ae81681e450e0999: Delete: bdb/perl.BerkeleyDB/config.in BitKeeper/deleted/.del-dbinfo~28ad67d83be4f68e: Delete: bdb/perl.BerkeleyDB/dbinfo BitKeeper/deleted/.del-mkconsts~543ab60669c7a04e: Delete: bdb/perl.BerkeleyDB/mkconsts BitKeeper/deleted/.del-mkpod~182c0ca54e439afb: Delete: bdb/perl.BerkeleyDB/mkpod BitKeeper/deleted/.del-5.004~e008cb5a48805543: Delete: bdb/perl.BerkeleyDB/patches/5.004 BitKeeper/deleted/.del-irix_6_5.pl~61662bb08afcdec8: Delete: bdb/perl.BerkeleyDB/hints/irix_6_5.pl BitKeeper/deleted/.del-solaris.pl~6771e7182394e152: Delete: bdb/perl.BerkeleyDB/hints/solaris.pl BitKeeper/deleted/.del-typemap~783b8f5295b05f3d: Delete: bdb/perl.BerkeleyDB/typemap BitKeeper/deleted/.del-5.004_01~6081ce2fff7b0bc: Delete: bdb/perl.BerkeleyDB/patches/5.004_01 BitKeeper/deleted/.del-5.004_02~87214eac35ad9e6: Delete: bdb/perl.BerkeleyDB/patches/5.004_02 BitKeeper/deleted/.del-5.004_03~9a672becec7cb40f: Delete: bdb/perl.BerkeleyDB/patches/5.004_03 BitKeeper/deleted/.del-5.004_04~e326cb51af09d154: Delete: bdb/perl.BerkeleyDB/patches/5.004_04 BitKeeper/deleted/.del-5.004_05~7ab457a1e41a92fe: Delete: bdb/perl.BerkeleyDB/patches/5.004_05 BitKeeper/deleted/.del-5.005~f9e2d59b5964cd4b: Delete: bdb/perl.BerkeleyDB/patches/5.005 BitKeeper/deleted/.del-5.005_01~3eb9fb7b5842ea8e: Delete: bdb/perl.BerkeleyDB/patches/5.005_01 BitKeeper/deleted/.del-5.005_02~67477ce0bef717cb: Delete: bdb/perl.BerkeleyDB/patches/5.005_02 BitKeeper/deleted/.del-5.005_03~c4c29a1fb21e290a: Delete: bdb/perl.BerkeleyDB/patches/5.005_03 BitKeeper/deleted/.del-5.6.0~e1fb9897d124ee22: Delete: bdb/perl.BerkeleyDB/patches/5.6.0 BitKeeper/deleted/.del-btree.t~e4a1a3c675ddc406: Delete: bdb/perl.BerkeleyDB/t/btree.t BitKeeper/deleted/.del-db-3.0.t~d2c60991d84558f2: Delete: bdb/perl.BerkeleyDB/t/db-3.0.t BitKeeper/deleted/.del-db-3.1.t~6ee88cd13f55e018: Delete: bdb/perl.BerkeleyDB/t/db-3.1.t BitKeeper/deleted/.del-db-3.2.t~f73b6461f98fd1cf: Delete: bdb/perl.BerkeleyDB/t/db-3.2.t BitKeeper/deleted/.del-destroy.t~cc6a2ae1980a2ecd: Delete: bdb/perl.BerkeleyDB/t/destroy.t BitKeeper/deleted/.del-env.t~a8604a4499c4bd07: Delete: bdb/perl.BerkeleyDB/t/env.t BitKeeper/deleted/.del-examples.t~2571b77c3cc75574: Delete: bdb/perl.BerkeleyDB/t/examples.t BitKeeper/deleted/.del-examples.t.T~8228bdd75ac78b88: Delete: bdb/perl.BerkeleyDB/t/examples.t.T BitKeeper/deleted/.del-examples3.t.T~66a186897a87026d: Delete: bdb/perl.BerkeleyDB/t/examples3.t.T BitKeeper/deleted/.del-examples3.t~fe3822ba2f2d7f83: Delete: bdb/perl.BerkeleyDB/t/examples3.t BitKeeper/deleted/.del-filter.t~f87b045c1b708637: Delete: bdb/perl.BerkeleyDB/t/filter.t BitKeeper/deleted/.del-hash.t~616bfb4d644de3a3: Delete: bdb/perl.BerkeleyDB/t/hash.t BitKeeper/deleted/.del-join.t~29fc39f74a83ca22: Delete: bdb/perl.BerkeleyDB/t/join.t BitKeeper/deleted/.del-mldbm.t~31f5015341eea040: Delete: bdb/perl.BerkeleyDB/t/mldbm.t BitKeeper/deleted/.del-queue.t~8f338034ce44a641: Delete: bdb/perl.BerkeleyDB/t/queue.t BitKeeper/deleted/.del-recno.t~d4ddbd3743add63e: Delete: bdb/perl.BerkeleyDB/t/recno.t BitKeeper/deleted/.del-strict.t~6885cdd2ea71ca2d: Delete: bdb/perl.BerkeleyDB/t/strict.t BitKeeper/deleted/.del-subdb.t~aab62a5d5864c603: Delete: bdb/perl.BerkeleyDB/t/subdb.t BitKeeper/deleted/.del-txn.t~65033b8558ae1216: Delete: bdb/perl.BerkeleyDB/t/txn.t BitKeeper/deleted/.del-unknown.t~f3710458682665e1: Delete: bdb/perl.BerkeleyDB/t/unknown.t BitKeeper/deleted/.del-Changes~436f74a5c414c65b: Delete: bdb/perl.DB_File/Changes BitKeeper/deleted/.del-DB_File.pm~ae0951c6c7665a82: Delete: bdb/perl.DB_File/DB_File.pm BitKeeper/deleted/.del-DB_File.xs~89e49a0b5556f1d8: Delete: bdb/perl.DB_File/DB_File.xs BitKeeper/deleted/.del-DB_File_BS~290fad5dbbb87069: Delete: bdb/perl.DB_File/DB_File_BS BitKeeper/deleted/.del-MANIFEST~90ee581572bdd4ac: Delete: bdb/perl.DB_File/MANIFEST BitKeeper/deleted/.del-Makefile.PL~ac0567bb5a377e38: Delete: bdb/perl.DB_File/Makefile.PL BitKeeper/deleted/.del-README~77e924a5a9bae6b3: Delete: bdb/perl.DB_File/README BitKeeper/deleted/.del-config.in~ab4c2792b86a810b: Delete: bdb/perl.DB_File/config.in BitKeeper/deleted/.del-dbinfo~461c43b30fab2cb: Delete: bdb/perl.DB_File/dbinfo BitKeeper/deleted/.del-dynixptx.pl~50dcddfae25d17e9: Delete: bdb/perl.DB_File/hints/dynixptx.pl BitKeeper/deleted/.del-typemap~55cffb3288a9e587: Delete: bdb/perl.DB_File/typemap BitKeeper/deleted/.del-version.c~a4df0e646f8b3975: Delete: bdb/perl.DB_File/version.c BitKeeper/deleted/.del-5.004_01~d6830d0082702af7: Delete: bdb/perl.DB_File/patches/5.004_01 BitKeeper/deleted/.del-5.004_02~78b082dc80c91031: Delete: bdb/perl.DB_File/patches/5.004_02 BitKeeper/deleted/.del-5.004~4411ec2e3c9e008b: Delete: bdb/perl.DB_File/patches/5.004 BitKeeper/deleted/.del-sco.pl~1e795fe14fe4dcfe: Delete: bdb/perl.DB_File/hints/sco.pl BitKeeper/deleted/.del-5.004_03~33f274648b160d95: Delete: bdb/perl.DB_File/patches/5.004_03 BitKeeper/deleted/.del-5.004_04~8f3d1b3cf18bb20a: Delete: bdb/perl.DB_File/patches/5.004_04 BitKeeper/deleted/.del-5.004_05~9c0f02e7331e142: Delete: bdb/perl.DB_File/patches/5.004_05 BitKeeper/deleted/.del-5.005~c2108cb2e3c8d951: Delete: bdb/perl.DB_File/patches/5.005 BitKeeper/deleted/.del-5.005_01~3b45e9673afc4cfa: Delete: bdb/perl.DB_File/patches/5.005_01 BitKeeper/deleted/.del-5.005_02~9fe5766bb02a4522: Delete: bdb/perl.DB_File/patches/5.005_02 BitKeeper/deleted/.del-5.005_03~ffa1c38c19ae72ea: Delete: bdb/perl.DB_File/patches/5.005_03 BitKeeper/deleted/.del-5.6.0~373be3a5ce47be85: Delete: bdb/perl.DB_File/patches/5.6.0 BitKeeper/deleted/.del-db-btree.t~3231595a1c241eb3: Delete: bdb/perl.DB_File/t/db-btree.t BitKeeper/deleted/.del-db-hash.t~7c4ad0c795c7fad2: Delete: bdb/perl.DB_File/t/db-hash.t BitKeeper/deleted/.del-db-recno.t~6c2d3d80b9ba4a50: Delete: bdb/perl.DB_File/t/db-recno.t BitKeeper/deleted/.del-db_server.sed~cdb00ebcd48a64e2: Delete: bdb/rpc_server/db_server.sed BitKeeper/deleted/.del-db_server_proc.c~d46c8f409c3747f4: Delete: bdb/rpc_server/db_server_proc.c BitKeeper/deleted/.del-db_server_svc.sed~3f5e59f334fa4607: Delete: bdb/rpc_server/db_server_svc.sed BitKeeper/deleted/.del-db_server_util.c~a809f3a4629acda: Delete: bdb/rpc_server/db_server_util.c BitKeeper/deleted/.del-log.tcl~ff1b41f1355b97d7: Delete: bdb/test/log.tcl BitKeeper/deleted/.del-mpool.tcl~b0df4dc1b04db26c: Delete: bdb/test/mpool.tcl BitKeeper/deleted/.del-mutex.tcl~52fd5c73a150565: Delete: bdb/test/mutex.tcl BitKeeper/deleted/.del-txn.tcl~c4ff071550b5446e: Delete: bdb/test/txn.tcl BitKeeper/deleted/.del-README~e800a12a5392010a: Delete: bdb/test/upgrade/README BitKeeper/deleted/.del-pack-2.6.6.pl~89d5076d758d3e98: Delete: bdb/test/upgrade/generate-2.X/pack-2.6.6.pl BitKeeper/deleted/.del-test-2.6.patch~4a52dc83d447547b: Delete: bdb/test/upgrade/generate-2.X/test-2.6.patch --- bdb/cxx/cxx_app.cpp | 671 ---------------------------------------- bdb/cxx/cxx_db.cpp | 605 ++++++++++++++++++++++++++++++++++++ bdb/cxx/cxx_dbc.cpp | 115 +++++++ bdb/cxx/cxx_dbt.cpp | 61 ++++ bdb/cxx/cxx_env.cpp | 802 ++++++++++++++++++++++++++++++++++++++++++++++++ bdb/cxx/cxx_except.cpp | 254 ++++++++++++++-- bdb/cxx/cxx_lock.cpp | 86 +----- bdb/cxx/cxx_log.cpp | 125 -------- bdb/cxx/cxx_logc.cpp | 65 ++++ bdb/cxx/cxx_mpool.cpp | 208 +++++-------- bdb/cxx/cxx_table.cpp | 808 ------------------------------------------------- bdb/cxx/cxx_txn.cpp | 143 +++------ bdb/cxx/namemap.txt | 21 -- 13 files changed, 1990 insertions(+), 1974 deletions(-) delete mode 100644 bdb/cxx/cxx_app.cpp create mode 100644 bdb/cxx/cxx_db.cpp create mode 100644 bdb/cxx/cxx_dbc.cpp create mode 100644 bdb/cxx/cxx_dbt.cpp create mode 100644 bdb/cxx/cxx_env.cpp delete mode 100644 bdb/cxx/cxx_log.cpp create mode 100644 bdb/cxx/cxx_logc.cpp delete mode 100644 bdb/cxx/cxx_table.cpp delete mode 100644 bdb/cxx/namemap.txt (limited to 'bdb/cxx') diff --git a/bdb/cxx/cxx_app.cpp b/bdb/cxx/cxx_app.cpp deleted file mode 100644 index 1fcf04b5c43..00000000000 --- a/bdb/cxx/cxx_app.cpp +++ /dev/null @@ -1,671 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997, 1998, 1999, 2000 - * Sleepycat Software. All rights reserved. - */ - -#include "db_config.h" - -#ifndef lint -static const char revid[] = "$Id: cxx_app.cpp,v 11.38 2000/12/21 20:30:18 dda Exp $"; -#endif /* not lint */ - -#include -#include // needed for set_error_stream -#include - -#include "db_cxx.h" -#include "cxx_int.h" - -#include "db_int.h" -#include "common_ext.h" - -// The reason for a static variable is that some structures -// (like Dbts) have no connection to any Db or DbEnv, so when -// errors occur in their methods, we must have some reasonable -// way to determine whether to throw or return errors. -// -// This variable is taken from flags whenever a DbEnv is constructed. -// Normally there is only one DbEnv per program, and even if not, -// there is typically a single policy of throwing or returning. -// -static int last_known_error_policy = ON_ERROR_UNKNOWN; - -//////////////////////////////////////////////////////////////////////// -// // -// DbEnv // -// // -//////////////////////////////////////////////////////////////////////// - -ostream *DbEnv::error_stream_ = 0; - -// _destroy_check is called when there is a user error in a -// destructor, specifically when close has not been called for an -// object (even if it was never opened). If the DbEnv is being -// destroyed we cannot always use DbEnv::error_stream_, so we'll -// use cerr in that case. -// -void DbEnv::_destroy_check(const char *str, int isDbEnv) -{ - ostream *out; - - out = error_stream_; - if (out == NULL || isDbEnv == 1) - out = &cerr; - - (*out) << "DbEnv::_destroy_check: open " << str << " object destroyed\n"; -} - -// A truism for the DbEnv object is that there is a valid -// DB_ENV handle from the constructor until close(). -// After the close, the DB_ENV handle is invalid and -// no operations are permitted on the DbEnv (other than -// destructor). Leaving the DbEnv handle open and not -// doing a close is generally considered an error. -// -// We used to allow DbEnv objects to be closed and reopened. -// This implied always keeping a valid DB_ENV object, and -// coordinating the open objects between Db/DbEnv turned -// out to be overly complicated. Now we do not allow this. - -DbEnv::DbEnv(u_int32_t flags) -: imp_(0) -, construct_error_(0) -, construct_flags_(flags) -, tx_recover_callback_(0) -, paniccall_callback_(0) -{ - int err; - - COMPQUIET(err, 0); - if ((err = initialize(0)) != 0) - DB_ERROR("DbEnv::DbEnv", err, error_policy()); -} - -DbEnv::DbEnv(DB_ENV *env, u_int32_t flags) -: imp_(0) -, construct_error_(0) -, construct_flags_(flags) -, tx_recover_callback_(0) -, paniccall_callback_(0) -{ - int err; - - COMPQUIET(err, 0); - if ((err = initialize(env)) != 0) - DB_ERROR("DbEnv::DbEnv", err, error_policy()); -} - -// Note: if the user has not closed, we call _destroy_check -// to warn against this non-safe programming practice, -// and call close anyway. -// -DbEnv::~DbEnv() -{ - DB_ENV *env = unwrap(this); - - if (env != NULL) { - _destroy_check("DbEnv", 1); - (void)env->close(env, 0); - - // extra safety - cleanup(); - } -} - -// called by Db destructor when the DbEnv is owned by DB. -void DbEnv::cleanup() -{ - DB_ENV *env = unwrap(this); - - if (env != NULL) { - env->cj_internal = 0; - imp_ = 0; - } -} - -int DbEnv::close(u_int32_t flags) -{ - DB_ENV *env = unwrap(this); - int err, init_err; - - COMPQUIET(init_err, 0); - - // after a close (no matter if success or failure), - // the underlying DB_ENV object must not be accessed, - // so we clean up in advance. - // - cleanup(); - - // It's safe to throw an error after the close, - // since our error mechanism does not peer into - // the DB* structures. - // - if ((err = env->close(env, flags)) != 0) { - DB_ERROR("DbEnv::close", err, error_policy()); - } - return (err); -} - -void DbEnv::err(int error, const char *format, ...) -{ - va_list args; - DB_ENV *env = unwrap(this); - - va_start(args, format); - __db_real_err(env, error, 1, 1, format, args); - va_end(args); -} - -void DbEnv::errx(const char *format, ...) -{ - va_list args; - DB_ENV *env = unwrap(this); - - va_start(args, format); - __db_real_err(env, 0, 0, 1, format, args); - va_end(args); -} - -// used internally during constructor -// to associate an existing DB_ENV with this DbEnv, -// or create a new one. If there is an error, -// construct_error_ is set; this is examined during open. -// -int DbEnv::initialize(DB_ENV *env) -{ - int err; - - last_known_error_policy = error_policy(); - - if (env == 0) { - // Create a new DB_ENV environment. - if ((err = ::db_env_create(&env, - construct_flags_ & ~DB_CXX_NO_EXCEPTIONS)) != 0) { - construct_error_ = err; - return (err); - } - } - imp_ = wrap(env); - env->cj_internal = this; // for DB_ENV* to DbEnv* conversion - return (0); -} - -// Return a tristate value corresponding to whether we should -// throw exceptions on errors: -// ON_ERROR_RETURN -// ON_ERROR_THROW -// ON_ERROR_UNKNOWN -// -int DbEnv::error_policy() -{ - if ((construct_flags_ & DB_CXX_NO_EXCEPTIONS) != 0) { - return (ON_ERROR_RETURN); - } - else { - return (ON_ERROR_THROW); - } -} - -// If an error occurred during the constructor, report it now. -// Otherwise, call the underlying DB->open method. -// -int DbEnv::open(const char *db_home, u_int32_t flags, int mode) -{ - DB_ENV *env = unwrap(this); - int err; - - if ((err = construct_error_) != 0) - DB_ERROR("Db::open", err, error_policy()); - else if ((err = env->open(env, db_home, flags, mode)) != 0) - DB_ERROR("DbEnv::open", err, error_policy()); - - return (err); -} - -int DbEnv::remove(const char *db_home, u_int32_t flags) -{ - DB_ENV *env; - int ret; - - env = unwrap(this); - - // after a remove (no matter if success or failure), - // the underlying DB_ENV object must not be accessed, - // so we clean up in advance. - // - cleanup(); - - if ((ret = env->remove(env, db_home, flags)) != 0) - DB_ERROR("DbEnv::remove", ret, error_policy()); - - return (ret); -} - -// Report an error associated with the DbEnv. -// error_policy is one of: -// ON_ERROR_THROW throw an error -// ON_ERROR_RETURN do nothing here, the caller will return an error -// ON_ERROR_UNKNOWN defer the policy to policy saved in DbEnv::DbEnv -// -void DbEnv::runtime_error(const char *caller, int error, int error_policy) -{ - if (error_policy == ON_ERROR_UNKNOWN) - error_policy = last_known_error_policy; - if (error_policy == ON_ERROR_THROW) { - // Creating and throwing the object in two separate - // statements seems to be necessary for HP compilers. - DbException except(caller, error); - throw except; - } -} - -// static method -char *DbEnv::strerror(int error) -{ - return (db_strerror(error)); -} - -// This is a 'glue' function declared as extern "C" so it will -// be compatible with picky compilers that do not allow mixing -// of function pointers to 'C' functions with function pointers -// to C++ functions. -// -extern "C" -void _stream_error_function_c(const char *prefix, char *message) -{ - DbEnv::_stream_error_function(prefix, message); -} - -void DbEnv::_stream_error_function(const char *prefix, char *message) -{ - // HP compilers need the extra casts, we don't know why. - if (error_stream_) { - if (prefix) { - (*error_stream_) << prefix << (const char *)": "; - } - if (message) { - (*error_stream_) << (const char *)message; - } - (*error_stream_) << (const char *)"\n"; - } -} - -// Note: This actually behaves a bit like a static function, -// since DB_ENV.db_errcall has no information about which -// db_env triggered the call. A user that has multiple DB_ENVs -// will simply not be able to have different streams for each one. -// -void DbEnv::set_error_stream(ostream *stream) -{ - DB_ENV *dbenv = unwrap(this); - - error_stream_ = stream; - dbenv->set_errcall(dbenv, (stream == 0) ? 0 : - _stream_error_function_c); -} - -// static method -char *DbEnv::version(int *major, int *minor, int *patch) -{ - return (db_version(major, minor, patch)); -} - -// This is a variant of the DB_WO_ACCESS macro to define a simple set_ -// method calling the underlying C method, but unlike a simple -// set method, it may return an error or raise an exception. -// Note this macro expects that input _argspec is an argument -// list element (e.g. "char *arg") defined in terms of "arg". -// -#define DB_DBENV_ACCESS(_name, _argspec) \ - \ -int DbEnv::set_##_name(_argspec) \ -{ \ - int ret; \ - DB_ENV *dbenv = unwrap(this); \ - \ - if ((ret = (*(dbenv->set_##_name))(dbenv, arg)) != 0) {\ - DB_ERROR("DbEnv::set_" # _name, ret, error_policy()); \ - } \ - return (ret); \ -} - -#define DB_DBENV_ACCESS_NORET(_name, _argspec) \ - \ -void DbEnv::set_##_name(_argspec) \ -{ \ - DB_ENV *dbenv = unwrap(this); \ - \ - (*(dbenv->set_##_name))(dbenv, arg); \ - return; \ -} - -DB_DBENV_ACCESS_NORET(errfile, FILE *arg) -DB_DBENV_ACCESS_NORET(errpfx, const char *arg) - -// We keep these alphabetical by field name, -// for comparison with Java's list. -// -DB_DBENV_ACCESS(data_dir, const char *arg) -DB_DBENV_ACCESS(lg_bsize, u_int32_t arg) -DB_DBENV_ACCESS(lg_dir, const char *arg) -DB_DBENV_ACCESS(lg_max, u_int32_t arg) -DB_DBENV_ACCESS(lk_detect, u_int32_t arg) -DB_DBENV_ACCESS(lk_max, u_int32_t arg) -DB_DBENV_ACCESS(lk_max_lockers, u_int32_t arg) -DB_DBENV_ACCESS(lk_max_locks, u_int32_t arg) -DB_DBENV_ACCESS(lk_max_objects, u_int32_t arg) -DB_DBENV_ACCESS(mp_mmapsize, size_t arg) -DB_DBENV_ACCESS(mutexlocks, int arg) -DB_DBENV_ACCESS(tmp_dir, const char *arg) -DB_DBENV_ACCESS(tx_max, u_int32_t arg) - -// Here are the set methods that don't fit the above mold. -// -extern "C" { - typedef void (*db_errcall_fcn_type) - (const char *, char *); -}; - -void DbEnv::set_errcall(void (*arg)(const char *, char *)) -{ - DB_ENV *dbenv = unwrap(this); - - // XXX - // We are casting from a function ptr declared with C++ - // linkage to one (same arg types) declared with C - // linkage. It's hard to imagine a pair of C/C++ - // compilers from the same vendor for which this - // won't work. Unfortunately, we can't use a - // intercept function like the others since the - // function does not have a (DbEnv*) as one of - // the args. If this causes trouble, we can pull - // the same trick we use in Java, namely stuffing - // a (DbEnv*) pointer into the prefix. We're - // avoiding this for the moment because it obfuscates. - // - (*(dbenv->set_errcall))(dbenv, (db_errcall_fcn_type)arg); -} - -int DbEnv::set_cachesize(u_int32_t gbytes, u_int32_t bytes, int ncache) -{ - int ret; - DB_ENV *dbenv = unwrap(this); - - if ((ret = - (*(dbenv->set_cachesize))(dbenv, gbytes, bytes, ncache)) != 0) - DB_ERROR("DbEnv::set_cachesize", ret, error_policy()); - - return (ret); -} - -int DbEnv::set_flags(u_int32_t flags, int onoff) -{ - int ret; - DB_ENV *dbenv = unwrap(this); - - if ((ret = (dbenv->set_flags)(dbenv, flags, onoff)) != 0) - DB_ERROR("DbEnv::set_flags", ret, error_policy()); - - return (ret); -} - -int DbEnv::set_lk_conflicts(u_int8_t *lk_conflicts, int lk_max) -{ - int ret; - DB_ENV *dbenv = unwrap(this); - - if ((ret = (*(dbenv->set_lk_conflicts)) - (dbenv, lk_conflicts, lk_max)) != 0) - DB_ERROR("DbEnv::set_lk_conflicts", ret, error_policy()); - - return (ret); -} - -// static method -int DbEnv::set_pageyield(int arg) -{ - int ret; - - if ((ret = db_env_set_pageyield(arg)) != 0) - DB_ERROR("DbEnv::set_pageyield", ret, last_known_error_policy); - - return (ret); -} - -// static method -int DbEnv::set_panicstate(int arg) -{ - int ret; - - if ((ret = db_env_set_panicstate(arg)) != 0) - DB_ERROR("DbEnv::set_panicstate", ret, last_known_error_policy); - - return (ret); -} - -// static method -int DbEnv::set_region_init(int arg) -{ - int ret; - - if ((ret = db_env_set_region_init(arg)) != 0) - DB_ERROR("DbEnv::set_region_init", ret, last_known_error_policy); - - return (ret); -} - -int DbEnv::set_server(char *host, long tsec, long ssec, u_int32_t flags) -{ - int ret; - DB_ENV *dbenv = unwrap(this); - - if ((ret = dbenv->set_server(dbenv, host, tsec, ssec, flags)) != 0) - DB_ERROR("DbEnv::set_server", ret, error_policy()); - - return (ret); -} - -int DbEnv::set_shm_key(long shm_key) -{ - int ret; - DB_ENV *dbenv = unwrap(this); - - if ((ret = dbenv->set_shm_key(dbenv, shm_key)) != 0) - DB_ERROR("DbEnv::set_shm_key", ret, error_policy()); - - return (ret); -} - -// static method -int DbEnv::set_tas_spins(u_int32_t arg) -{ - int ret; - - if ((ret = db_env_set_tas_spins(arg)) != 0) - DB_ERROR("DbEnv::set_tas_spins", ret, last_known_error_policy); - - return (ret); -} - -int DbEnv::set_verbose(u_int32_t which, int onoff) -{ - int ret; - DB_ENV *dbenv = unwrap(this); - - if ((ret = (*(dbenv->set_verbose))(dbenv, which, onoff)) != 0) - DB_ERROR("DbEnv::set_verbose", ret, error_policy()); - - return (ret); -} - -// This is a 'glue' function declared as extern "C" so it will -// be compatible with picky compilers that do not allow mixing -// of function pointers to 'C' functions with function pointers -// to C++ functions. -// -extern "C" -int _tx_recover_intercept_c(DB_ENV *env, DBT *dbt, - DB_LSN *lsn, db_recops op) -{ - return (DbEnv::_tx_recover_intercept(env, dbt, lsn, op)); -} - -int DbEnv::_tx_recover_intercept(DB_ENV *env, DBT *dbt, - DB_LSN *lsn, db_recops op) -{ - if (env == 0) { - DB_ERROR("DbEnv::tx_recover_callback", EINVAL, ON_ERROR_UNKNOWN); - return (EINVAL); - } - DbEnv *cxxenv = (DbEnv *)env->cj_internal; - if (cxxenv == 0) { - DB_ERROR("DbEnv::tx_recover_callback", EINVAL, ON_ERROR_UNKNOWN); - return (EINVAL); - } - if (cxxenv->tx_recover_callback_ == 0) { - DB_ERROR("DbEnv::tx_recover_callback", EINVAL, cxxenv->error_policy()); - return (EINVAL); - } - Dbt *cxxdbt = (Dbt *)dbt; - DbLsn *cxxlsn = (DbLsn *)lsn; - return ((*cxxenv->tx_recover_callback_)(cxxenv, cxxdbt, cxxlsn, op)); -} - -int DbEnv::set_tx_recover - (int (*arg)(DbEnv *, Dbt *, DbLsn *, db_recops)) -{ - int ret; - DB_ENV *dbenv = unwrap(this); - - tx_recover_callback_ = arg; - if ((ret = - (*(dbenv->set_tx_recover))(dbenv, _tx_recover_intercept_c)) != 0) - DB_ERROR("DbEnv::set_tx_recover", ret, error_policy()); - - return (ret); -} - -int DbEnv::set_tx_timestamp(time_t *timestamp) -{ - int ret; - DB_ENV *dbenv = unwrap(this); - - if ((ret = dbenv->set_tx_timestamp(dbenv, timestamp)) != 0) - DB_ERROR("DbEnv::set_tx_timestamp", ret, error_policy()); - - return (ret); -} - -// This is a 'glue' function declared as extern "C" so it will -// be compatible with picky compilers that do not allow mixing -// of function pointers to 'C' functions with function pointers -// to C++ functions. -// -extern "C" -void _paniccall_intercept_c(DB_ENV *env, int errval) -{ - DbEnv::_paniccall_intercept(env, errval); -} - -void DbEnv::_paniccall_intercept(DB_ENV *env, int errval) -{ - if (env == 0) { - DB_ERROR("DbEnv::paniccall_callback", EINVAL, ON_ERROR_UNKNOWN); - } - DbEnv *cxxenv = (DbEnv *)env->cj_internal; - if (cxxenv == 0) { - DB_ERROR("DbEnv::paniccall_callback", EINVAL, ON_ERROR_UNKNOWN); - } - if (cxxenv->paniccall_callback_ == 0) { - DB_ERROR("DbEnv::paniccall_callback", EINVAL, cxxenv->error_policy()); - } - (*cxxenv->paniccall_callback_)(cxxenv, errval); -} - -int DbEnv::set_paniccall(void (*arg)(DbEnv *, int)) -{ - DB_ENV *dbenv = unwrap(this); - - paniccall_callback_ = arg; - - return ((*(dbenv->set_paniccall))(dbenv, _paniccall_intercept_c)); -} - -// This is a 'glue' function declared as extern "C" so it will -// be compatible with picky compilers that do not allow mixing -// of function pointers to 'C' functions with function pointers -// to C++ functions. -// -extern "C" -int _recovery_init_intercept_c(DB_ENV *env) -{ - return (DbEnv::_recovery_init_intercept(env)); -} - -int DbEnv::_recovery_init_intercept(DB_ENV *env) -{ - if (env == 0) { - DB_ERROR("DbEnv::recovery_init_callback", EINVAL, - ON_ERROR_UNKNOWN); - } - DbEnv *cxxenv = (DbEnv *)env->cj_internal; - if (cxxenv == 0) { - DB_ERROR("DbEnv::recovery_init_callback", EINVAL, - ON_ERROR_UNKNOWN); - } - if (cxxenv->recovery_init_callback_ == 0) { - DB_ERROR("DbEnv::recovery_init_callback", EINVAL, - cxxenv->error_policy()); - } - return ((*cxxenv->recovery_init_callback_)(cxxenv)); -} - -int DbEnv::set_recovery_init(int (*arg)(DbEnv *)) -{ - DB_ENV *dbenv = unwrap(this); - - recovery_init_callback_ = arg; - - return ((*(dbenv->set_recovery_init))(dbenv, _recovery_init_intercept_c)); -} - -// This is a 'glue' function declared as extern "C" so it will -// be compatible with picky compilers that do not allow mixing -// of function pointers to 'C' functions with function pointers -// to C++ functions. -// -extern "C" -void _feedback_intercept_c(DB_ENV *env, int opcode, int pct) -{ - DbEnv::_feedback_intercept(env, opcode, pct); -} - -void DbEnv::_feedback_intercept(DB_ENV *env, int opcode, int pct) -{ - if (env == 0) { - DB_ERROR("DbEnv::feedback_callback", EINVAL, ON_ERROR_UNKNOWN); - return; - } - DbEnv *cxxenv = (DbEnv *)env->cj_internal; - if (cxxenv == 0) { - DB_ERROR("DbEnv::feedback_callback", EINVAL, ON_ERROR_UNKNOWN); - return; - } - if (cxxenv->feedback_callback_ == 0) { - DB_ERROR("DbEnv::feedback_callback", EINVAL, - cxxenv->error_policy()); - return; - } - (*cxxenv->feedback_callback_)(cxxenv, opcode, pct); -} - -int DbEnv::set_feedback(void (*arg)(DbEnv *, int, int)) -{ - DB_ENV *dbenv = unwrap(this); - - feedback_callback_ = arg; - - return ((*(dbenv->set_feedback))(dbenv, _feedback_intercept_c)); -} diff --git a/bdb/cxx/cxx_db.cpp b/bdb/cxx/cxx_db.cpp new file mode 100644 index 00000000000..7e50a9b3f27 --- /dev/null +++ b/bdb/cxx/cxx_db.cpp @@ -0,0 +1,605 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1997-2002 + * Sleepycat Software. All rights reserved. + */ + +#include "db_config.h" + +#ifndef lint +static const char revid[] = "$Id: cxx_db.cpp,v 11.71 2002/08/26 22:13:36 mjc Exp $"; +#endif /* not lint */ + +#include +#include + +#include "db_cxx.h" +#include "dbinc/cxx_int.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc_auto/db_auto.h" +#include "dbinc_auto/crdel_auto.h" +#include "dbinc/db_dispatch.h" +#include "dbinc_auto/db_ext.h" +#include "dbinc_auto/common_ext.h" + +// Helper macros for simple methods that pass through to the +// underlying C method. It may return an error or raise an exception. +// Note this macro expects that input _argspec is an argument +// list element (e.g., "char *arg") and that _arglist is the arguments +// that should be passed through to the C method (e.g., "(db, arg)") +// +#define DB_METHOD(_name, _argspec, _arglist, _retok) \ +int Db::_name _argspec \ +{ \ + int ret; \ + DB *db = unwrap(this); \ + \ + ret = db->_name _arglist; \ + if (!_retok(ret)) \ + DB_ERROR("Db::" # _name, ret, error_policy()); \ + return (ret); \ +} + +#define DB_METHOD_CHECKED(_name, _cleanup, _argspec, _arglist, _retok) \ +int Db::_name _argspec \ +{ \ + int ret; \ + DB *db = unwrap(this); \ + \ + if (!db) { \ + DB_ERROR("Db::" # _name, EINVAL, error_policy()); \ + return (EINVAL); \ + } \ + if (_cleanup) \ + cleanup(); \ + ret = db->_name _arglist; \ + if (!_retok(ret)) \ + DB_ERROR("Db::" # _name, ret, error_policy()); \ + return (ret); \ +} + +#define DB_METHOD_QUIET(_name, _argspec, _arglist) \ +int Db::_name _argspec \ +{ \ + DB *db = unwrap(this); \ + \ + return (db->_name _arglist); \ +} + +#define DB_METHOD_VOID(_name, _argspec, _arglist) \ +void Db::_name _argspec \ +{ \ + DB *db = unwrap(this); \ + \ + db->_name _arglist; \ +} + +// A truism for the Db object is that there is a valid +// DB handle from the constructor until close(). +// After the close, the DB handle is invalid and +// no operations are permitted on the Db (other than +// destructor). Leaving the Db handle open and not +// doing a close is generally considered an error. +// +// We used to allow Db objects to be closed and reopened. +// This implied always keeping a valid DB object, and +// coordinating the open objects between Db/DbEnv turned +// out to be overly complicated. Now we do not allow this. + +Db::Db(DbEnv *env, u_int32_t flags) +: imp_(0) +, env_(env) +, construct_error_(0) +, flags_(0) +, construct_flags_(flags) +, append_recno_callback_(0) +, associate_callback_(0) +, bt_compare_callback_(0) +, bt_prefix_callback_(0) +, dup_compare_callback_(0) +, feedback_callback_(0) +, h_hash_callback_(0) +{ + if (env_ == 0) + flags_ |= DB_CXX_PRIVATE_ENV; + + if ((construct_error_ = initialize()) != 0) + DB_ERROR("Db::Db", construct_error_, error_policy()); +} + +// If the DB handle is still open, we close it. This is to make stack +// allocation of Db objects easier so that they are cleaned up in the error +// path. If the environment was closed prior to this, it may cause a trap, but +// an error message is generated during the environment close. Applications +// should call close explicitly in normal (non-exceptional) cases to check the +// return value. +// +Db::~Db() +{ + DB *db; + + db = unwrap(this); + if (db != NULL) { + cleanup(); + (void)db->close(db, 0); + } +} + +// private method to initialize during constructor. +// initialize must create a backing DB object, +// and if that creates a new DB_ENV, it must be tied to a new DbEnv. +// +int Db::initialize() +{ + DB *db; + DB_ENV *cenv = unwrap(env_); + int ret; + u_int32_t cxx_flags; + + cxx_flags = construct_flags_ & DB_CXX_NO_EXCEPTIONS; + + // Create a new underlying DB object. + // We rely on the fact that if a NULL DB_ENV* is given, + // one is allocated by DB. + // + if ((ret = db_create(&db, cenv, + construct_flags_ & ~cxx_flags)) != 0) + return (ret); + + // Associate the DB with this object + imp_ = wrap(db); + db->api_internal = this; + + // Create a new DbEnv from a DB_ENV* if it was created locally. + // It is deleted in Db::close(). + // + if ((flags_ & DB_CXX_PRIVATE_ENV) != 0) + env_ = new DbEnv(db->dbenv, cxx_flags); + + return (0); +} + +// private method to cleanup after destructor or during close. +// If the environment was created by this Db object, we optionally +// delete it, or return it so the caller can delete it after +// last use. +// +void Db::cleanup() +{ + DB *db = unwrap(this); + + if (db != NULL) { + // extra safety + db->api_internal = 0; + imp_ = 0; + + // we must dispose of the DbEnv object if + // we created it. This will be the case + // if a NULL DbEnv was passed into the constructor. + // The underlying DB_ENV object will be inaccessible + // after the close, so we must clean it up now. + // + if ((flags_ & DB_CXX_PRIVATE_ENV) != 0) { + env_->cleanup(); + delete env_; + env_ = 0; + } + } +} + +// Return a tristate value corresponding to whether we should +// throw exceptions on errors: +// ON_ERROR_RETURN +// ON_ERROR_THROW +// ON_ERROR_UNKNOWN +// +int Db::error_policy() +{ + if (env_ != NULL) + return (env_->error_policy()); + else { + // If the env_ is null, that means that the user + // did not attach an environment, so the correct error + // policy can be deduced from constructor flags + // for this Db. + // + if ((construct_flags_ & DB_CXX_NO_EXCEPTIONS) != 0) { + return (ON_ERROR_RETURN); + } + else { + return (ON_ERROR_THROW); + } + } +} + +int Db::close(u_int32_t flags) +{ + DB *db = unwrap(this); + int ret; + + // after a DB->close (no matter if success or failure), + // the underlying DB object must not be accessed, + // so we clean up in advance. + // + cleanup(); + + // It's safe to throw an error after the close, + // since our error mechanism does not peer into + // the DB* structures. + // + if ((ret = db->close(db, flags)) != 0) + DB_ERROR("Db::close", ret, error_policy()); + + return (ret); +} + +// The following cast implies that Dbc can be no larger than DBC +DB_METHOD(cursor, (DbTxn *txnid, Dbc **cursorp, u_int32_t flags), + (db, unwrap(txnid), (DBC **)cursorp, flags), + DB_RETOK_STD) + +DB_METHOD(del, (DbTxn *txnid, Dbt *key, u_int32_t flags), + (db, unwrap(txnid), key, flags), + DB_RETOK_DBDEL) + +void Db::err(int error, const char *format, ...) +{ + DB *db = unwrap(this); + + DB_REAL_ERR(db->dbenv, error, 1, 1, format); +} + +void Db::errx(const char *format, ...) +{ + DB *db = unwrap(this); + + DB_REAL_ERR(db->dbenv, 0, 0, 1, format); +} + +DB_METHOD(fd, (int *fdp), + (db, fdp), + DB_RETOK_STD) + +int Db::get(DbTxn *txnid, Dbt *key, Dbt *value, u_int32_t flags) +{ + DB *db = unwrap(this); + int ret; + + ret = db->get(db, unwrap(txnid), key, value, flags); + + if (!DB_RETOK_DBGET(ret)) { + if (ret == ENOMEM && DB_OVERFLOWED_DBT(value)) + DB_ERROR_DBT("Db::get", value, error_policy()); + else + DB_ERROR("Db::get", ret, error_policy()); + } + + return (ret); +} + +int Db::get_byteswapped(int *isswapped) +{ + DB *db = (DB *)unwrapConst(this); + return (db->get_byteswapped(db, isswapped)); +} + +int Db::get_type(DBTYPE *dbtype) +{ + DB *db = (DB *)unwrapConst(this); + return (db->get_type(db, dbtype)); +} + +// Dbc is a "compatible" subclass of DBC - that is, no virtual functions +// or even extra data members, so these casts, although technically +// non-portable, "should" always be okay. +DB_METHOD(join, (Dbc **curslist, Dbc **cursorp, u_int32_t flags), + (db, (DBC **)curslist, (DBC **)cursorp, flags), + DB_RETOK_STD) + +DB_METHOD(key_range, + (DbTxn *txnid, Dbt *key, DB_KEY_RANGE *results, u_int32_t flags), + (db, unwrap(txnid), key, results, flags), + DB_RETOK_STD) + +// If an error occurred during the constructor, report it now. +// Otherwise, call the underlying DB->open method. +// +int Db::open(DbTxn *txnid, const char *file, const char *database, + DBTYPE type, u_int32_t flags, int mode) +{ + int ret; + DB *db = unwrap(this); + + if (construct_error_ != 0) + ret = construct_error_; + else + ret = db->open(db, unwrap(txnid), file, database, type, flags, + mode); + + if (!DB_RETOK_STD(ret)) + DB_ERROR("Db::open", ret, error_policy()); + + return (ret); +} + +int Db::pget(DbTxn *txnid, Dbt *key, Dbt *pkey, Dbt *value, u_int32_t flags) +{ + DB *db = unwrap(this); + int ret; + + ret = db->pget(db, unwrap(txnid), key, pkey, value, flags); + + /* The logic here is identical to Db::get - reuse the macro. */ + if (!DB_RETOK_DBGET(ret)) { + if (ret == ENOMEM && DB_OVERFLOWED_DBT(value)) + DB_ERROR_DBT("Db::pget", value, error_policy()); + else + DB_ERROR("Db::pget", ret, error_policy()); + } + + return (ret); +} + +DB_METHOD(put, + (DbTxn *txnid, Dbt *key, Dbt *value, u_int32_t flags), + (db, unwrap(txnid), key, value, flags), + DB_RETOK_DBPUT) + +DB_METHOD_CHECKED(rename, 1, + (const char *file, const char *database, const char *newname, + u_int32_t flags), + (db, file, database, newname, flags), DB_RETOK_STD) + +DB_METHOD_CHECKED(remove, 1, + (const char *file, const char *database, u_int32_t flags), + (db, file, database, flags), DB_RETOK_STD) + +DB_METHOD_CHECKED(truncate, 0, + (DbTxn *txnid, u_int32_t *countp, u_int32_t flags), + (db, unwrap(txnid), countp, flags), DB_RETOK_STD) + +DB_METHOD_CHECKED(stat, 0, + (void *sp, u_int32_t flags), (db, sp, flags), DB_RETOK_STD) + +DB_METHOD_CHECKED(sync, 0, + (u_int32_t flags), (db, flags), DB_RETOK_STD) + +DB_METHOD_CHECKED(upgrade, 0, + (const char *name, u_int32_t flags), (db, name, flags), DB_RETOK_STD) + +//////////////////////////////////////////////////////////////////////// +// +// callbacks +// +// *_intercept_c are 'glue' functions that must be declared +// as extern "C" so to be typesafe. Using a C++ method, even +// a static class method with 'correct' arguments, will not pass +// the test; some picky compilers do not allow mixing of function +// pointers to 'C' functions with function pointers to C++ functions. +// +// One wart with this scheme is that the *_callback_ method pointer +// must be declared public to be accessible by the C intercept. +// It's possible to accomplish the goal without this, and with +// another public transfer method, but it's just too much overhead. +// These callbacks are supposed to be *fast*. +// +// The DBTs we receive in these callbacks from the C layer may be +// manufactured there, but we want to treat them as a Dbts. +// Technically speaking, these DBTs were not constructed as a Dbts, +// but it should be safe to cast them as such given that Dbt is a +// *very* thin extension of the DBT. That is, Dbt has no additional +// data elements, does not use virtual functions, virtual inheritance, +// multiple inheritance, RTI, or any other language feature that +// causes the structure to grow or be displaced. Although this may +// sound risky, a design goal of C++ is complete structure +// compatibility with C, and has the philosophy 'if you don't use it, +// you shouldn't incur the overhead'. If the C/C++ compilers you're +// using on a given machine do not have matching struct layouts, then +// a lot more things will be broken than just this. +// +// The alternative, creating a Dbt here in the callback, and populating +// it from the DBT, is just too slow and cumbersome to be very useful. + +// These macros avoid a lot of boilerplate code for callbacks + +#define DB_CALLBACK_C_INTERCEPT(_name, _rettype, _cargspec, \ + _return, _cxxargs) \ +extern "C" _rettype _db_##_name##_intercept_c _cargspec \ +{ \ + Db *cxxthis; \ + \ + DB_ASSERT(cthis != NULL); \ + cxxthis = (Db *)cthis->api_internal; \ + DB_ASSERT(cxxthis != NULL); \ + DB_ASSERT(cxxthis->_name##_callback_ != 0); \ + \ + _return (*cxxthis->_name##_callback_) _cxxargs; \ +} + +#define DB_SET_CALLBACK(_cxxname, _name, _cxxargspec, _cb) \ +int Db::_cxxname _cxxargspec \ +{ \ + DB *cthis = unwrap(this); \ + \ + _name##_callback_ = _cb; \ + return ((*(cthis->_cxxname))(cthis, \ + (_cb) ? _db_##_name##_intercept_c : NULL)); \ +} + +/* associate callback - doesn't quite fit the pattern because of the flags */ +DB_CALLBACK_C_INTERCEPT(associate, + int, (DB *cthis, const DBT *key, const DBT *data, DBT *retval), + return, (cxxthis, Dbt::get_const_Dbt(key), Dbt::get_const_Dbt(data), + Dbt::get_Dbt(retval))) + +int Db::associate(DbTxn *txn, Db *secondary, int (*callback)(Db *, const Dbt *, + const Dbt *, Dbt *), u_int32_t flags) +{ + DB *cthis = unwrap(this); + + /* Since the secondary Db is used as the first argument + * to the callback, we store the C++ callback on it + * rather than on 'this'. + */ + secondary->associate_callback_ = callback; + return ((*(cthis->associate))(cthis, unwrap(txn), unwrap(secondary), + (callback) ? _db_associate_intercept_c : NULL, flags)); +} + +DB_CALLBACK_C_INTERCEPT(feedback, + void, (DB *cthis, int opcode, int pct), + /* no return */ (void), (cxxthis, opcode, pct)) + +DB_SET_CALLBACK(set_feedback, feedback, + (void (*arg)(Db *cxxthis, int opcode, int pct)), arg) + +DB_CALLBACK_C_INTERCEPT(append_recno, + int, (DB *cthis, DBT *data, db_recno_t recno), + return, (cxxthis, Dbt::get_Dbt(data), recno)) + +DB_SET_CALLBACK(set_append_recno, append_recno, + (int (*arg)(Db *cxxthis, Dbt *data, db_recno_t recno)), arg) + +DB_CALLBACK_C_INTERCEPT(bt_compare, + int, (DB *cthis, const DBT *data1, const DBT *data2), + return, + (cxxthis, Dbt::get_const_Dbt(data1), Dbt::get_const_Dbt(data2))) + +DB_SET_CALLBACK(set_bt_compare, bt_compare, + (int (*arg)(Db *cxxthis, const Dbt *data1, const Dbt *data2)), arg) + +DB_CALLBACK_C_INTERCEPT(bt_prefix, + size_t, (DB *cthis, const DBT *data1, const DBT *data2), + return, + (cxxthis, Dbt::get_const_Dbt(data1), Dbt::get_const_Dbt(data2))) + +DB_SET_CALLBACK(set_bt_prefix, bt_prefix, + (size_t (*arg)(Db *cxxthis, const Dbt *data1, const Dbt *data2)), arg) + +DB_CALLBACK_C_INTERCEPT(dup_compare, + int, (DB *cthis, const DBT *data1, const DBT *data2), + return, + (cxxthis, Dbt::get_const_Dbt(data1), Dbt::get_const_Dbt(data2))) + +DB_SET_CALLBACK(set_dup_compare, dup_compare, + (int (*arg)(Db *cxxthis, const Dbt *data1, const Dbt *data2)), arg) + +DB_CALLBACK_C_INTERCEPT(h_hash, + u_int32_t, (DB *cthis, const void *data, u_int32_t len), + return, (cxxthis, data, len)) + +DB_SET_CALLBACK(set_h_hash, h_hash, + (u_int32_t (*arg)(Db *cxxthis, const void *data, u_int32_t len)), arg) + +// This is a 'glue' function declared as extern "C" so it will +// be compatible with picky compilers that do not allow mixing +// of function pointers to 'C' functions with function pointers +// to C++ functions. +// +extern "C" +int _verify_callback_c(void *handle, const void *str_arg) +{ + char *str; + __DB_OSTREAMCLASS *out; + + str = (char *)str_arg; + out = (__DB_OSTREAMCLASS *)handle; + + (*out) << str; + if (out->fail()) + return (EIO); + + return (0); +} + +int Db::verify(const char *name, const char *subdb, + __DB_OSTREAMCLASS *ostr, u_int32_t flags) +{ + DB *db = unwrap(this); + int ret; + + if (!db) + ret = EINVAL; + else + ret = __db_verify_internal(db, name, subdb, ostr, + _verify_callback_c, flags); + + if (!DB_RETOK_STD(ret)) + DB_ERROR("Db::verify", ret, error_policy()); + + return (ret); +} + +DB_METHOD(set_bt_compare, (bt_compare_fcn_type func), + (db, func), DB_RETOK_STD) +DB_METHOD(set_bt_maxkey, (u_int32_t bt_maxkey), + (db, bt_maxkey), DB_RETOK_STD) +DB_METHOD(set_bt_minkey, (u_int32_t bt_minkey), + (db, bt_minkey), DB_RETOK_STD) +DB_METHOD(set_bt_prefix, (bt_prefix_fcn_type func), + (db, func), DB_RETOK_STD) +DB_METHOD(set_dup_compare, (dup_compare_fcn_type func), + (db, func), DB_RETOK_STD) +DB_METHOD(set_encrypt, (const char *passwd, int flags), + (db, passwd, flags), DB_RETOK_STD) +DB_METHOD_VOID(set_errfile, (FILE *errfile), (db, errfile)) +DB_METHOD_VOID(set_errpfx, (const char *errpfx), (db, errpfx)) +DB_METHOD(set_flags, (u_int32_t flags), (db, flags), + DB_RETOK_STD) +DB_METHOD(set_h_ffactor, (u_int32_t h_ffactor), + (db, h_ffactor), DB_RETOK_STD) +DB_METHOD(set_h_hash, (h_hash_fcn_type func), + (db, func), DB_RETOK_STD) +DB_METHOD(set_h_nelem, (u_int32_t h_nelem), + (db, h_nelem), DB_RETOK_STD) +DB_METHOD(set_lorder, (int db_lorder), (db, db_lorder), + DB_RETOK_STD) +DB_METHOD(set_pagesize, (u_int32_t db_pagesize), + (db, db_pagesize), DB_RETOK_STD) +DB_METHOD(set_re_delim, (int re_delim), + (db, re_delim), DB_RETOK_STD) +DB_METHOD(set_re_len, (u_int32_t re_len), + (db, re_len), DB_RETOK_STD) +DB_METHOD(set_re_pad, (int re_pad), + (db, re_pad), DB_RETOK_STD) +DB_METHOD(set_re_source, (char *re_source), + (db, re_source), DB_RETOK_STD) +DB_METHOD(set_q_extentsize, (u_int32_t extentsize), + (db, extentsize), DB_RETOK_STD) + +DB_METHOD_QUIET(set_alloc, (db_malloc_fcn_type malloc_fcn, + db_realloc_fcn_type realloc_fcn, db_free_fcn_type free_fcn), + (db, malloc_fcn, realloc_fcn, free_fcn)) + +void Db::set_errcall(void (*arg)(const char *, char *)) +{ + env_->set_errcall(arg); +} + +void *Db::get_app_private() const +{ + return unwrapConst(this)->app_private; +} + +void Db::set_app_private(void *value) +{ + unwrap(this)->app_private = value; +} + +DB_METHOD(set_cachesize, (u_int32_t gbytes, u_int32_t bytes, int ncache), + (db, gbytes, bytes, ncache), DB_RETOK_STD) +DB_METHOD(set_cache_priority, (DB_CACHE_PRIORITY priority), + (db, priority), DB_RETOK_STD) + +int Db::set_paniccall(void (*callback)(DbEnv *, int)) +{ + return (env_->set_paniccall(callback)); +} + +void Db::set_error_stream(__DB_OSTREAMCLASS *error_stream) +{ + env_->set_error_stream(error_stream); +} diff --git a/bdb/cxx/cxx_dbc.cpp b/bdb/cxx/cxx_dbc.cpp new file mode 100644 index 00000000000..4d5844f922f --- /dev/null +++ b/bdb/cxx/cxx_dbc.cpp @@ -0,0 +1,115 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1997-2002 + * Sleepycat Software. All rights reserved. + */ + +#include "db_config.h" + +#ifndef lint +static const char revid[] = "$Id: cxx_dbc.cpp,v 11.55 2002/07/03 21:03:52 bostic Exp $"; +#endif /* not lint */ + +#include +#include + +#include "db_cxx.h" +#include "dbinc/cxx_int.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc_auto/db_auto.h" +#include "dbinc_auto/crdel_auto.h" +#include "dbinc/db_dispatch.h" +#include "dbinc_auto/db_ext.h" +#include "dbinc_auto/common_ext.h" + +// Helper macro for simple methods that pass through to the +// underlying C method. It may return an error or raise an exception. +// Note this macro expects that input _argspec is an argument +// list element (e.g., "char *arg") and that _arglist is the arguments +// that should be passed through to the C method (e.g., "(db, arg)") +// +#define DBC_METHOD(_name, _argspec, _arglist, _retok) \ +int Dbc::_name _argspec \ +{ \ + int ret; \ + DBC *dbc = this; \ + \ + ret = dbc->c_##_name _arglist; \ + if (!_retok(ret)) \ + DB_ERROR("Dbc::" # _name, ret, ON_ERROR_UNKNOWN); \ + return (ret); \ +} + +// It's private, and should never be called, but VC4.0 needs it resolved +// +Dbc::~Dbc() +{ +} + +DBC_METHOD(close, (void), (dbc), DB_RETOK_STD) +DBC_METHOD(count, (db_recno_t *countp, u_int32_t _flags), + (dbc, countp, _flags), DB_RETOK_STD) +DBC_METHOD(del, (u_int32_t _flags), + (dbc, _flags), DB_RETOK_DBCDEL) + +int Dbc::dup(Dbc** cursorp, u_int32_t _flags) +{ + int ret; + DBC *dbc = this; + DBC *new_cursor = 0; + + ret = dbc->c_dup(dbc, &new_cursor, _flags); + + if (DB_RETOK_STD(ret)) + // The following cast implies that Dbc can be no larger than DBC + *cursorp = (Dbc*)new_cursor; + else + DB_ERROR("Dbc::dup", ret, ON_ERROR_UNKNOWN); + + return (ret); +} + +int Dbc::get(Dbt* key, Dbt *data, u_int32_t _flags) +{ + int ret; + DBC *dbc = this; + + ret = dbc->c_get(dbc, key, data, _flags); + + if (!DB_RETOK_DBCGET(ret)) { + if (ret == ENOMEM && DB_OVERFLOWED_DBT(key)) + DB_ERROR_DBT("Dbc::get", key, ON_ERROR_UNKNOWN); + else if (ret == ENOMEM && DB_OVERFLOWED_DBT(data)) + DB_ERROR_DBT("Dbc::get", data, ON_ERROR_UNKNOWN); + else + DB_ERROR("Dbc::get", ret, ON_ERROR_UNKNOWN); + } + + return (ret); +} + +int Dbc::pget(Dbt* key, Dbt *pkey, Dbt *data, u_int32_t _flags) +{ + int ret; + DBC *dbc = this; + + ret = dbc->c_pget(dbc, key, pkey, data, _flags); + + /* Logic is the same as for Dbc::get - reusing macro. */ + if (!DB_RETOK_DBCGET(ret)) { + if (ret == ENOMEM && DB_OVERFLOWED_DBT(key)) + DB_ERROR_DBT("Dbc::pget", key, ON_ERROR_UNKNOWN); + else if (ret == ENOMEM && DB_OVERFLOWED_DBT(data)) + DB_ERROR_DBT("Dbc::pget", data, ON_ERROR_UNKNOWN); + else + DB_ERROR("Dbc::pget", ret, ON_ERROR_UNKNOWN); + } + + return (ret); +} + +DBC_METHOD(put, (Dbt* key, Dbt *data, u_int32_t _flags), + (dbc, key, data, _flags), DB_RETOK_DBCPUT) diff --git a/bdb/cxx/cxx_dbt.cpp b/bdb/cxx/cxx_dbt.cpp new file mode 100644 index 00000000000..7a4224503ee --- /dev/null +++ b/bdb/cxx/cxx_dbt.cpp @@ -0,0 +1,61 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1997-2002 + * Sleepycat Software. All rights reserved. + */ + +#include "db_config.h" + +#ifndef lint +static const char revid[] = "$Id: cxx_dbt.cpp,v 11.53 2002/03/27 04:31:14 bostic Exp $"; +#endif /* not lint */ + +#include +#include + +#include "db_cxx.h" +#include "dbinc/cxx_int.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc_auto/db_auto.h" +#include "dbinc_auto/crdel_auto.h" +#include "dbinc/db_dispatch.h" +#include "dbinc_auto/db_ext.h" +#include "dbinc_auto/common_ext.h" + +Dbt::Dbt() +{ + DBT *dbt = this; + memset(dbt, 0, sizeof(DBT)); +} + +Dbt::Dbt(void *data_arg, u_int32_t size_arg) +{ + DBT *dbt = this; + memset(dbt, 0, sizeof(DBT)); + set_data(data_arg); + set_size(size_arg); +} + +Dbt::~Dbt() +{ +} + +Dbt::Dbt(const Dbt &that) +{ + const DBT *from = &that; + DBT *to = this; + memcpy(to, from, sizeof(DBT)); +} + +Dbt &Dbt::operator = (const Dbt &that) +{ + if (this != &that) { + const DBT *from = &that; + DBT *to = this; + memcpy(to, from, sizeof(DBT)); + } + return (*this); +} diff --git a/bdb/cxx/cxx_env.cpp b/bdb/cxx/cxx_env.cpp new file mode 100644 index 00000000000..c78c6e9fa47 --- /dev/null +++ b/bdb/cxx/cxx_env.cpp @@ -0,0 +1,802 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1997-2002 + * Sleepycat Software. All rights reserved. + */ + +#include "db_config.h" + +#ifndef lint +static const char revid[] = "$Id: cxx_env.cpp,v 11.88 2002/08/26 22:13:36 mjc Exp $"; +#endif /* not lint */ + +#include +#include // needed for set_error_stream +#include + +#include "db_cxx.h" +#include "dbinc/cxx_int.h" + +#include "db_int.h" +#include "dbinc_auto/common_ext.h" + +#ifdef HAVE_CXX_STDHEADERS +using std::cerr; +#endif + +// Helper macros for simple methods that pass through to the +// underlying C method. They may return an error or raise an exception. +// These macros expect that input _argspec is an argument +// list element (e.g., "char *arg") and that _arglist is the arguments +// that should be passed through to the C method (e.g., "(dbenv, arg)") +// +#define DBENV_METHOD_ERR(_name, _argspec, _arglist, _on_err) \ +int DbEnv::_name _argspec \ +{ \ + DB_ENV *dbenv = unwrap(this); \ + int ret; \ + \ + if ((ret = dbenv->_name _arglist) != 0) { \ + _on_err; \ + } \ + return (ret); \ +} + +#define DBENV_METHOD(_name, _argspec, _arglist) \ + DBENV_METHOD_ERR(_name, _argspec, _arglist, \ + DB_ERROR("DbEnv::" # _name, ret, error_policy())) + +#define DBENV_METHOD_QUIET(_name, _argspec, _arglist) \ +int DbEnv::_name _argspec \ +{ \ + DB_ENV *dbenv = unwrap(this); \ + \ + return (dbenv->_name _arglist); \ +} + +#define DBENV_METHOD_VOID(_name, _argspec, _arglist) \ +void DbEnv::_name _argspec \ +{ \ + DB_ENV *dbenv = unwrap(this); \ + \ + dbenv->_name _arglist; \ +} + +// This datatype is needed for picky compilers. +// +extern "C" { + typedef void (*db_errcall_fcn_type) + (const char *, char *); +}; + +// The reason for a static variable is that some structures +// (like Dbts) have no connection to any Db or DbEnv, so when +// errors occur in their methods, we must have some reasonable +// way to determine whether to throw or return errors. +// +// This variable is taken from flags whenever a DbEnv is constructed. +// Normally there is only one DbEnv per program, and even if not, +// there is typically a single policy of throwing or returning. +// +static int last_known_error_policy = ON_ERROR_UNKNOWN; + +__DB_OSTREAMCLASS *DbEnv::error_stream_ = 0; + +// These 'glue' function are declared as extern "C" so they will +// be compatible with picky compilers that do not allow mixing +// of function pointers to 'C' functions with function pointers +// to C++ functions. +// +extern "C" +void _feedback_intercept_c(DB_ENV *env, int opcode, int pct) +{ + DbEnv::_feedback_intercept(env, opcode, pct); +} + +extern "C" +void _paniccall_intercept_c(DB_ENV *env, int errval) +{ + DbEnv::_paniccall_intercept(env, errval); +} + +extern "C" +void _stream_error_function_c(const char *prefix, char *message) +{ + DbEnv::_stream_error_function(prefix, message); +} + +extern "C" +int _app_dispatch_intercept_c(DB_ENV *env, DBT *dbt, + DB_LSN *lsn, db_recops op) +{ + return (DbEnv::_app_dispatch_intercept(env, dbt, lsn, op)); +} + +extern "C" +int _rep_send_intercept_c(DB_ENV *env, const DBT *cntrl, + const DBT *data, int id, u_int32_t flags) +{ + return (DbEnv::_rep_send_intercept(env, + cntrl, data, id, flags)); +} + +void DbEnv::_feedback_intercept(DB_ENV *env, int opcode, int pct) +{ + if (env == 0) { + DB_ERROR("DbEnv::feedback_callback", EINVAL, ON_ERROR_UNKNOWN); + return; + } + DbEnv *cxxenv = (DbEnv *)env->api1_internal; + if (cxxenv == 0) { + DB_ERROR("DbEnv::feedback_callback", EINVAL, ON_ERROR_UNKNOWN); + return; + } + if (cxxenv->feedback_callback_ == 0) { + DB_ERROR("DbEnv::feedback_callback", EINVAL, + cxxenv->error_policy()); + return; + } + (*cxxenv->feedback_callback_)(cxxenv, opcode, pct); +} + +void DbEnv::_paniccall_intercept(DB_ENV *env, int errval) +{ + if (env == 0) { + DB_ERROR("DbEnv::paniccall_callback", EINVAL, + ON_ERROR_UNKNOWN); + } + DbEnv *cxxenv = (DbEnv *)env->api1_internal; + if (cxxenv == 0) { + DB_ERROR("DbEnv::paniccall_callback", EINVAL, + ON_ERROR_UNKNOWN); + } + if (cxxenv->paniccall_callback_ == 0) { + DB_ERROR("DbEnv::paniccall_callback", EINVAL, + cxxenv->error_policy()); + } + (*cxxenv->paniccall_callback_)(cxxenv, errval); +} + +int DbEnv::_app_dispatch_intercept(DB_ENV *env, DBT *dbt, + DB_LSN *lsn, db_recops op) +{ + if (env == 0) { + DB_ERROR("DbEnv::app_dispatch_callback", + EINVAL, ON_ERROR_UNKNOWN); + return (EINVAL); + } + DbEnv *cxxenv = (DbEnv *)env->api1_internal; + if (cxxenv == 0) { + DB_ERROR("DbEnv::app_dispatch_callback", + EINVAL, ON_ERROR_UNKNOWN); + return (EINVAL); + } + if (cxxenv->app_dispatch_callback_ == 0) { + DB_ERROR("DbEnv::app_dispatch_callback", + EINVAL, cxxenv->error_policy()); + return (EINVAL); + } + Dbt *cxxdbt = (Dbt *)dbt; + DbLsn *cxxlsn = (DbLsn *)lsn; + return ((*cxxenv->app_dispatch_callback_)(cxxenv, cxxdbt, cxxlsn, op)); +} + +int DbEnv::_rep_send_intercept(DB_ENV *env, const DBT *cntrl, + const DBT *data, int id, u_int32_t flags) +{ + + if (env == 0) { + DB_ERROR("DbEnv::rep_send_callback", EINVAL, ON_ERROR_UNKNOWN); + return (EINVAL); + } + DbEnv *cxxenv = (DbEnv *)env->api1_internal; + if (cxxenv == 0) { + DB_ERROR("DbEnv::rep_send_callback", EINVAL, ON_ERROR_UNKNOWN); + return (EINVAL); + } + const Dbt *cxxcntrl = (const Dbt *)cntrl; + Dbt *cxxdata = (Dbt *)data; + return ((*cxxenv->rep_send_callback_)(cxxenv, + cxxcntrl, cxxdata, id, flags)); +} + +// A truism for the DbEnv object is that there is a valid +// DB_ENV handle from the constructor until close(). +// After the close, the DB_ENV handle is invalid and +// no operations are permitted on the DbEnv (other than +// destructor). Leaving the DbEnv handle open and not +// doing a close is generally considered an error. +// +// We used to allow DbEnv objects to be closed and reopened. +// This implied always keeping a valid DB_ENV object, and +// coordinating the open objects between Db/DbEnv turned +// out to be overly complicated. Now we do not allow this. + +DbEnv::DbEnv(u_int32_t flags) +: imp_(0) +, construct_error_(0) +, construct_flags_(flags) +, app_dispatch_callback_(0) +, feedback_callback_(0) +, paniccall_callback_(0) +, pgin_callback_(0) +, pgout_callback_(0) +, rep_send_callback_(0) +{ + if ((construct_error_ = initialize(0)) != 0) + DB_ERROR("DbEnv::DbEnv", construct_error_, error_policy()); +} + +DbEnv::DbEnv(DB_ENV *env, u_int32_t flags) +: imp_(0) +, construct_error_(0) +, construct_flags_(flags) +, app_dispatch_callback_(0) +, feedback_callback_(0) +, paniccall_callback_(0) +, pgin_callback_(0) +, pgout_callback_(0) +, rep_send_callback_(0) +{ + if ((construct_error_ = initialize(env)) != 0) + DB_ERROR("DbEnv::DbEnv", construct_error_, error_policy()); +} + +// If the DB_ENV handle is still open, we close it. This is to make stack +// allocation of DbEnv objects easier so that they are cleaned up in the error +// path. Note that the C layer catches cases where handles are open in the +// environment at close time and reports an error. Applications should call +// close explicitly in normal (non-exceptional) cases to check the return +// value. +// +DbEnv::~DbEnv() +{ + DB_ENV *env = unwrap(this); + + if (env != NULL) { + cleanup(); + (void)env->close(env, 0); + } +} + +// called by destructors before the DB_ENV is destroyed. +void DbEnv::cleanup() +{ + DB_ENV *env = unwrap(this); + + if (env != NULL) { + env->api1_internal = 0; + imp_ = 0; + } +} + +int DbEnv::close(u_int32_t flags) +{ + int ret; + DB_ENV *env = unwrap(this); + + // after a close (no matter if success or failure), + // the underlying DB_ENV object must not be accessed, + // so we clean up in advance. + // + cleanup(); + + // It's safe to throw an error after the close, + // since our error mechanism does not peer into + // the DB* structures. + // + if ((ret = env->close(env, flags)) != 0) + DB_ERROR("DbEnv::close", ret, error_policy()); + + return (ret); +} + +DBENV_METHOD(dbremove, + (DbTxn *txn, const char *name, const char *subdb, u_int32_t flags), + (dbenv, unwrap(txn), name, subdb, flags)) +DBENV_METHOD(dbrename, (DbTxn *txn, const char *name, const char *subdb, + const char *newname, u_int32_t flags), + (dbenv, unwrap(txn), name, subdb, newname, flags)) + +void DbEnv::err(int error, const char *format, ...) +{ + DB_ENV *env = unwrap(this); + + DB_REAL_ERR(env, error, 1, 1, format); +} + +// Return a tristate value corresponding to whether we should +// throw exceptions on errors: +// ON_ERROR_RETURN +// ON_ERROR_THROW +// ON_ERROR_UNKNOWN +// +int DbEnv::error_policy() +{ + if ((construct_flags_ & DB_CXX_NO_EXCEPTIONS) != 0) { + return (ON_ERROR_RETURN); + } + else { + return (ON_ERROR_THROW); + } +} + +void DbEnv::errx(const char *format, ...) +{ + DB_ENV *env = unwrap(this); + + DB_REAL_ERR(env, 0, 0, 1, format); +} + +void *DbEnv::get_app_private() const +{ + return unwrapConst(this)->app_private; +} + +// used internally during constructor +// to associate an existing DB_ENV with this DbEnv, +// or create a new one. +// +int DbEnv::initialize(DB_ENV *env) +{ + int ret; + + last_known_error_policy = error_policy(); + + if (env == 0) { + // Create a new DB_ENV environment. + if ((ret = ::db_env_create(&env, + construct_flags_ & ~DB_CXX_NO_EXCEPTIONS)) != 0) + return (ret); + } + imp_ = wrap(env); + env->api1_internal = this; // for DB_ENV* to DbEnv* conversion + return (0); +} + +// lock methods +DBENV_METHOD(lock_detect, (u_int32_t flags, u_int32_t atype, int *aborted), + (dbenv, flags, atype, aborted)) +DBENV_METHOD_ERR(lock_get, + (u_int32_t locker, u_int32_t flags, const Dbt *obj, + db_lockmode_t lock_mode, DbLock *lock), + (dbenv, locker, flags, obj, lock_mode, &lock->lock_), + DbEnv::runtime_error_lock_get("DbEnv::lock_get", ret, + DB_LOCK_GET, lock_mode, obj, *lock, + -1, error_policy())) +DBENV_METHOD(lock_id, (u_int32_t *idp), (dbenv, idp)) +DBENV_METHOD(lock_id_free, (u_int32_t id), (dbenv, id)) +DBENV_METHOD(lock_put, (DbLock *lock), (dbenv, &lock->lock_)) +DBENV_METHOD(lock_stat, (DB_LOCK_STAT **statp, u_int32_t flags), + (dbenv, statp, flags)) +DBENV_METHOD_ERR(lock_vec, + (u_int32_t locker, u_int32_t flags, DB_LOCKREQ list[], + int nlist, DB_LOCKREQ **elist_returned), + (dbenv, locker, flags, list, nlist, elist_returned), + DbEnv::runtime_error_lock_get("DbEnv::lock_vec", ret, + (*elist_returned)->op, (*elist_returned)->mode, + Dbt::get_Dbt((*elist_returned)->obj), DbLock((*elist_returned)->lock), + (*elist_returned) - list, error_policy())) +// log methods +DBENV_METHOD(log_archive, (char **list[], u_int32_t flags), + (dbenv, list, flags)) + +int DbEnv::log_compare(const DbLsn *lsn0, const DbLsn *lsn1) +{ + return (::log_compare(lsn0, lsn1)); +} + +// The following cast implies that DbLogc can be no larger than DB_LOGC +DBENV_METHOD(log_cursor, (DbLogc **cursorp, u_int32_t flags), + (dbenv, (DB_LOGC **)cursorp, flags)) +DBENV_METHOD(log_file, (DbLsn *lsn, char *namep, size_t len), + (dbenv, lsn, namep, len)) +DBENV_METHOD(log_flush, (const DbLsn *lsn), (dbenv, lsn)) +DBENV_METHOD(log_put, (DbLsn *lsn, const Dbt *data, u_int32_t flags), + (dbenv, lsn, data, flags)) +DBENV_METHOD(log_stat, (DB_LOG_STAT **spp, u_int32_t flags), + (dbenv, spp, flags)) + +int DbEnv::memp_fcreate(DbMpoolFile **dbmfp, u_int32_t flags) +{ + DB_ENV *env = unwrap(this); + int ret; + DB_MPOOLFILE *mpf; + + if (env == NULL) + ret = EINVAL; + else + ret = env->memp_fcreate(env, &mpf, flags); + + if (DB_RETOK_STD(ret)) { + *dbmfp = new DbMpoolFile(); + (*dbmfp)->imp_ = wrap(mpf); + } else + DB_ERROR("DbMpoolFile::f_create", ret, ON_ERROR_UNKNOWN); + + return (ret); +} + +DBENV_METHOD(memp_register, + (int ftype, pgin_fcn_type pgin_fcn, pgout_fcn_type pgout_fcn), + (dbenv, ftype, pgin_fcn, pgout_fcn)) + +// memory pool methods +DBENV_METHOD(memp_stat, + (DB_MPOOL_STAT **gsp, DB_MPOOL_FSTAT ***fsp, u_int32_t flags), + (dbenv, gsp, fsp, flags)) + +DBENV_METHOD(memp_sync, (DbLsn *sn), (dbenv, sn)) + +DBENV_METHOD(memp_trickle, (int pct, int *nwrotep), (dbenv, pct, nwrotep)) + +// If an error occurred during the constructor, report it now. +// Otherwise, call the underlying DB->open method. +// +int DbEnv::open(const char *db_home, u_int32_t flags, int mode) +{ + int ret; + DB_ENV *env = unwrap(this); + + if (construct_error_ != 0) + ret = construct_error_; + else + ret = env->open(env, db_home, flags, mode); + + if (!DB_RETOK_STD(ret)) + DB_ERROR("DbEnv::open", ret, error_policy()); + + return (ret); +} + +int DbEnv::remove(const char *db_home, u_int32_t flags) +{ + int ret; + DB_ENV *env = unwrap(this); + + // after a remove (no matter if success or failure), + // the underlying DB_ENV object must not be accessed, + // so we clean up in advance. + // + cleanup(); + + if ((ret = env->remove(env, db_home, flags)) != 0) + DB_ERROR("DbEnv::remove", ret, error_policy()); + + return (ret); +} + +// Report an error associated with the DbEnv. +// error_policy is one of: +// ON_ERROR_THROW throw an error +// ON_ERROR_RETURN do nothing here, the caller will return an error +// ON_ERROR_UNKNOWN defer the policy to policy saved in DbEnv::DbEnv +// +void DbEnv::runtime_error(const char *caller, int error, int error_policy) +{ + if (error_policy == ON_ERROR_UNKNOWN) + error_policy = last_known_error_policy; + if (error_policy == ON_ERROR_THROW) { + // Creating and throwing the object in two separate + // statements seems to be necessary for HP compilers. + switch (error) { + case DB_LOCK_DEADLOCK: + { + DbDeadlockException dl_except(caller); + throw dl_except; + } + break; + case DB_RUNRECOVERY: + { + DbRunRecoveryException rr_except(caller); + throw rr_except; + } + break; + default: + { + DbException except(caller, error); + throw except; + } + break; + } + } +} + +// Like DbEnv::runtime_error, but issue a DbMemoryException +// based on the fact that this Dbt is not large enough. +void DbEnv::runtime_error_dbt(const char *caller, Dbt *dbt, int error_policy) +{ + if (error_policy == ON_ERROR_UNKNOWN) + error_policy = last_known_error_policy; + if (error_policy == ON_ERROR_THROW) { + // Creating and throwing the object in two separate + // statements seems to be necessary for HP compilers. + DbMemoryException except(caller, dbt); + throw except; + } +} + +// Like DbEnv::runtime_error, but issue a DbLockNotGrantedException, +// or a regular runtime error. +// call regular runtime_error if it +void DbEnv::runtime_error_lock_get(const char *caller, int error, + db_lockop_t op, db_lockmode_t mode, const Dbt *obj, + DbLock lock, int index, int error_policy) +{ + if (error != DB_LOCK_NOTGRANTED) { + runtime_error(caller, error, error_policy); + return; + } + + if (error_policy == ON_ERROR_UNKNOWN) + error_policy = last_known_error_policy; + if (error_policy == ON_ERROR_THROW) { + // Creating and throwing the object in two separate + // statements seems to be necessary for HP compilers. + DbLockNotGrantedException except(caller, op, mode, + obj, lock, index); + throw except; + } +} + +// static method +char *DbEnv::strerror(int error) +{ + return (db_strerror(error)); +} + +void DbEnv::_stream_error_function(const char *prefix, char *message) +{ + // HP compilers need the extra casts, we don't know why. + if (error_stream_) { + if (prefix) { + (*error_stream_) << prefix << (const char *)": "; + } + if (message) { + (*error_stream_) << (const char *)message; + } + (*error_stream_) << (const char *)"\n"; + } +} + +// set methods + +DBENV_METHOD_VOID(set_errfile, (FILE *errfile), (dbenv, errfile)) +DBENV_METHOD_VOID(set_errpfx, (const char *errpfx), (dbenv, errpfx)) + +// We keep these alphabetical by field name, +// for comparison with Java's list. +// +DBENV_METHOD(set_data_dir, (const char *dir), (dbenv, dir)) +DBENV_METHOD(set_encrypt, (const char *passwd, int flags), + (dbenv, passwd, flags)) +DBENV_METHOD(set_lg_bsize, (u_int32_t bsize), (dbenv, bsize)) +DBENV_METHOD(set_lg_dir, (const char *dir), (dbenv, dir)) +DBENV_METHOD(set_lg_max, (u_int32_t max), (dbenv, max)) +DBENV_METHOD(set_lg_regionmax, (u_int32_t regionmax), (dbenv, regionmax)) +DBENV_METHOD(set_lk_detect, (u_int32_t detect), (dbenv, detect)) +DBENV_METHOD(set_lk_max, (u_int32_t max), (dbenv, max)) +DBENV_METHOD(set_lk_max_lockers, (u_int32_t max_lockers), (dbenv, max_lockers)) +DBENV_METHOD(set_lk_max_locks, (u_int32_t max_locks), (dbenv, max_locks)) +DBENV_METHOD(set_lk_max_objects, (u_int32_t max_objects), (dbenv, max_objects)) +DBENV_METHOD(set_mp_mmapsize, (size_t mmapsize), (dbenv, mmapsize)) +DBENV_METHOD(set_tmp_dir, (const char *tmp_dir), (dbenv, tmp_dir)) +DBENV_METHOD(set_tx_max, (u_int32_t tx_max), (dbenv, tx_max)) + +DBENV_METHOD_QUIET(set_alloc, + (db_malloc_fcn_type malloc_fcn, db_realloc_fcn_type realloc_fcn, + db_free_fcn_type free_fcn), + (dbenv, malloc_fcn, realloc_fcn, free_fcn)) + +void DbEnv::set_app_private(void *value) +{ + unwrap(this)->app_private = value; +} + +DBENV_METHOD(set_cachesize, + (u_int32_t gbytes, u_int32_t bytes, int ncache), + (dbenv, gbytes, bytes, ncache)) + +void DbEnv::set_errcall(void (*arg)(const char *, char *)) +{ + DB_ENV *dbenv = unwrap(this); + + // XXX + // We are casting from a function ptr declared with C++ + // linkage to one (same arg types) declared with C + // linkage. It's hard to imagine a pair of C/C++ + // compilers from the same vendor for which this + // won't work. Unfortunately, we can't use a + // intercept function like the others since the + // function does not have a (DbEnv*) as one of + // the args. If this causes trouble, we can pull + // the same trick we use in Java, namely stuffing + // a (DbEnv*) pointer into the prefix. We're + // avoiding this for the moment because it obfuscates. + // + (*(dbenv->set_errcall))(dbenv, (db_errcall_fcn_type)arg); +} + +// Note: This actually behaves a bit like a static function, +// since DB_ENV.db_errcall has no information about which +// db_env triggered the call. A user that has multiple DB_ENVs +// will simply not be able to have different streams for each one. +// +void DbEnv::set_error_stream(__DB_OSTREAMCLASS *stream) +{ + DB_ENV *dbenv = unwrap(this); + + error_stream_ = stream; + dbenv->set_errcall(dbenv, (stream == 0) ? 0 : + _stream_error_function_c); +} + +int DbEnv::set_feedback(void (*arg)(DbEnv *, int, int)) +{ + DB_ENV *dbenv = unwrap(this); + + feedback_callback_ = arg; + + return ((*(dbenv->set_feedback))(dbenv, _feedback_intercept_c)); +} + +DBENV_METHOD(set_flags, (u_int32_t flags, int onoff), (dbenv, flags, onoff)) +DBENV_METHOD(set_lk_conflicts, (u_int8_t *lk_conflicts, int lk_max), + (dbenv, lk_conflicts, lk_max)) + +int DbEnv::set_paniccall(void (*arg)(DbEnv *, int)) +{ + DB_ENV *dbenv = unwrap(this); + + paniccall_callback_ = arg; + + return ((*(dbenv->set_paniccall))(dbenv, _paniccall_intercept_c)); +} + +DBENV_METHOD(set_rpc_server, + (void *cl, char *host, long tsec, long ssec, u_int32_t flags), + (dbenv, cl, host, tsec, ssec, flags)) +DBENV_METHOD(set_shm_key, (long shm_key), (dbenv, shm_key)) +// Note: this changes from last_known_error_policy to error_policy() +DBENV_METHOD(set_tas_spins, (u_int32_t arg), (dbenv, arg)) + +int DbEnv::set_app_dispatch + (int (*arg)(DbEnv *, Dbt *, DbLsn *, db_recops)) +{ + DB_ENV *dbenv = unwrap(this); + int ret; + + app_dispatch_callback_ = arg; + if ((ret = (*(dbenv->set_app_dispatch))(dbenv, + _app_dispatch_intercept_c)) != 0) + DB_ERROR("DbEnv::set_app_dispatch", ret, error_policy()); + + return (ret); +} + +DBENV_METHOD(set_tx_timestamp, (time_t *timestamp), (dbenv, timestamp)) +DBENV_METHOD(set_verbose, (u_int32_t which, int onoff), (dbenv, which, onoff)) + +int DbEnv::txn_begin(DbTxn *pid, DbTxn **tid, u_int32_t flags) +{ + DB_ENV *env = unwrap(this); + DB_TXN *txn; + int ret; + + ret = env->txn_begin(env, unwrap(pid), &txn, flags); + if (DB_RETOK_STD(ret)) + *tid = new DbTxn(txn); + else + DB_ERROR("DbEnv::txn_begin", ret, error_policy()); + + return (ret); +} + +DBENV_METHOD(txn_checkpoint, (u_int32_t kbyte, u_int32_t min, u_int32_t flags), + (dbenv, kbyte, min, flags)) + +int DbEnv::txn_recover(DbPreplist *preplist, long count, + long *retp, u_int32_t flags) +{ + DB_ENV *dbenv = unwrap(this); + DB_PREPLIST *c_preplist; + long i; + int ret; + + /* + * We need to allocate some local storage for the + * returned preplist, and that requires us to do + * our own argument validation. + */ + if (count <= 0) + ret = EINVAL; + else + ret = __os_malloc(dbenv, sizeof(DB_PREPLIST) * count, + &c_preplist); + + if (ret != 0) { + DB_ERROR("DbEnv::txn_recover", ret, error_policy()); + return (ret); + } + + if ((ret = + dbenv->txn_recover(dbenv, c_preplist, count, retp, flags)) != 0) { + __os_free(dbenv, c_preplist); + DB_ERROR("DbEnv::txn_recover", ret, error_policy()); + return (ret); + } + + for (i = 0; i < *retp; i++) { + preplist[i].txn = new DbTxn(); + preplist[i].txn->imp_ = wrap(c_preplist[i].txn); + memcpy(preplist[i].gid, c_preplist[i].gid, + sizeof(preplist[i].gid)); + } + + __os_free(dbenv, c_preplist); + + return (0); +} + +DBENV_METHOD(txn_stat, (DB_TXN_STAT **statp, u_int32_t flags), + (dbenv, statp, flags)) + +int DbEnv::set_rep_transport(u_int32_t myid, + int (*f_send)(DbEnv *, const Dbt *, const Dbt *, int, u_int32_t)) +{ + DB_ENV *dbenv = unwrap(this); + int ret; + + rep_send_callback_ = f_send; + if ((ret = dbenv->set_rep_transport(dbenv, + myid, _rep_send_intercept_c)) != 0) + DB_ERROR("DbEnv::set_rep_transport", ret, error_policy()); + + return (ret); +} + +DBENV_METHOD(rep_elect, + (int nsites, int pri, u_int32_t timeout, int *idp), + (dbenv, nsites, pri, timeout, idp)) + +int DbEnv::rep_process_message(Dbt *control, Dbt *rec, int *idp) +{ + DB_ENV *dbenv = unwrap(this); + int ret; + + ret = dbenv->rep_process_message(dbenv, control, rec, idp); + if (!DB_RETOK_REPPMSG(ret)) + DB_ERROR("DbEnv::rep_process_message", ret, error_policy()); + + return (ret); +} + +DBENV_METHOD(rep_start, + (Dbt *cookie, u_int32_t flags), + (dbenv, (DBT *)cookie, flags)) + +DBENV_METHOD(rep_stat, (DB_REP_STAT **statp, u_int32_t flags), + (dbenv, statp, flags)) + +DBENV_METHOD(set_rep_limit, (u_int32_t gbytes, u_int32_t bytes), + (dbenv, gbytes, bytes)) + +DBENV_METHOD(set_timeout, + (db_timeout_t timeout, u_int32_t flags), + (dbenv, timeout, flags)) + +// static method +char *DbEnv::version(int *major, int *minor, int *patch) +{ + return (db_version(major, minor, patch)); +} + +// static method +DbEnv *DbEnv::wrap_DB_ENV(DB_ENV *dbenv) +{ + DbEnv *wrapped_env = get_DbEnv(dbenv); + if (wrapped_env == NULL) + wrapped_env = new DbEnv(dbenv, 0); + return wrapped_env; +} diff --git a/bdb/cxx/cxx_except.cpp b/bdb/cxx/cxx_except.cpp index a62e21a767d..40fdeae69d6 100644 --- a/bdb/cxx/cxx_except.cpp +++ b/bdb/cxx/cxx_except.cpp @@ -1,20 +1,21 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 1998, 1999, 2000 + * Copyright (c) 1997-2002 * Sleepycat Software. All rights reserved. */ #include "db_config.h" #ifndef lint -static const char revid[] = "$Id: cxx_except.cpp,v 11.7 2000/09/21 15:05:45 dda Exp $"; +static const char revid[] = "$Id: cxx_except.cpp,v 11.17 2002/08/23 01:07:27 mjc Exp $"; #endif /* not lint */ #include +#include #include "db_cxx.h" -#include "cxx_int.h" +#include "dbinc/cxx_int.h" // tmpString is used to create strings on the stack // @@ -25,30 +26,7 @@ public: const char *str2 = 0, const char *str3 = 0, const char *str4 = 0, - const char *str5 = 0) - { - int len = strlen(str1); - if (str2) - len += strlen(str2); - if (str3) - len += strlen(str3); - if (str4) - len += strlen(str4); - if (str5) - len += strlen(str5); - - s_ = new char[len+1]; - - strcpy(s_, str1); - if (str2) - strcat(s_, str2); - if (str3) - strcat(s_, str3); - if (str4) - strcat(s_, str4); - if (str5) - strcat(s_, str5); - } + const char *str5 = 0); ~tmpString() { delete [] s_; } operator const char *() { return (s_); } @@ -56,6 +34,35 @@ private: char *s_; }; +tmpString::tmpString(const char *str1, + const char *str2, + const char *str3, + const char *str4, + const char *str5) +{ + size_t len = strlen(str1); + if (str2) + len += strlen(str2); + if (str3) + len += strlen(str3); + if (str4) + len += strlen(str4); + if (str5) + len += strlen(str5); + + s_ = new char[len+1]; + + strcpy(s_, str1); + if (str2) + strcat(s_, str2); + if (str3) + strcat(s_, str3); + if (str4) + strcat(s_, str4); + if (str5) + strcat(s_, str5); +} + // Note: would not be needed if we can inherit from exception // It does not appear to be possible to inherit from exception // with the current Microsoft library (VC5.0). @@ -100,7 +107,8 @@ DbException::DbException(const char *prefix, int err) DbException::DbException(const char *prefix1, const char *prefix2, int err) : err_(err) { - what_ = dupString(tmpString(prefix1, ": ", prefix2, ": ", db_strerror(err))); + what_ = dupString(tmpString(prefix1, ": ", prefix2, ": ", + db_strerror(err))); } DbException::DbException(const DbException &that) @@ -130,3 +138,193 @@ const char *DbException::what() const { return (what_); } + +//////////////////////////////////////////////////////////////////////// +// // +// DbMemoryException // +// // +//////////////////////////////////////////////////////////////////////// + +static const char *memory_err_desc = "Dbt not large enough for available data"; +DbMemoryException::~DbMemoryException() +{ +} + +DbMemoryException::DbMemoryException(Dbt *dbt) +: DbException(memory_err_desc, ENOMEM) +, dbt_(dbt) +{ +} + +DbMemoryException::DbMemoryException(const char *description) +: DbException(description, ENOMEM) +, dbt_(0) +{ +} + +DbMemoryException::DbMemoryException(const char *prefix, Dbt *dbt) +: DbException(prefix, memory_err_desc, ENOMEM) +, dbt_(dbt) +{ +} + +DbMemoryException::DbMemoryException(const char *prefix1, const char *prefix2, + Dbt *dbt) +: DbException(prefix1, prefix2, ENOMEM) +, dbt_(dbt) +{ +} + +DbMemoryException::DbMemoryException(const DbMemoryException &that) +: DbException(that) +, dbt_(that.dbt_) +{ +} + +DbMemoryException +&DbMemoryException::operator =(const DbMemoryException &that) +{ + if (this != &that) { + DbException::operator=(that); + dbt_ = that.dbt_; + } + return (*this); +} + +Dbt *DbMemoryException::get_dbt() const +{ + return (dbt_); +} + +//////////////////////////////////////////////////////////////////////// +// // +// DbDeadlockException // +// // +//////////////////////////////////////////////////////////////////////// + +DbDeadlockException::~DbDeadlockException() +{ +} + +DbDeadlockException::DbDeadlockException(const char *description) +: DbException(description, DB_LOCK_DEADLOCK) +{ +} + +DbDeadlockException::DbDeadlockException(const DbDeadlockException &that) +: DbException(that) +{ +} + +DbDeadlockException +&DbDeadlockException::operator =(const DbDeadlockException &that) +{ + if (this != &that) + DbException::operator=(that); + return (*this); +} + +//////////////////////////////////////////////////////////////////////// +// // +// DbLockNotGrantedException // +// // +//////////////////////////////////////////////////////////////////////// + +DbLockNotGrantedException::~DbLockNotGrantedException() +{ + delete lock_; +} + +DbLockNotGrantedException::DbLockNotGrantedException(const char *prefix, + db_lockop_t op, db_lockmode_t mode, const Dbt *obj, const DbLock lock, + int index) +: DbException(prefix, DbEnv::strerror(DB_LOCK_NOTGRANTED), + DB_LOCK_NOTGRANTED) +, op_(op) +, mode_(mode) +, obj_(obj) +, index_(index) +{ + lock_ = new DbLock(lock); +} + +DbLockNotGrantedException::DbLockNotGrantedException + (const DbLockNotGrantedException &that) +: DbException(that) +{ + op_ = that.op_; + mode_ = that.mode_; + obj_ = that.obj_; + lock_ = new DbLock(*that.lock_); + index_ = that.index_; +} + +DbLockNotGrantedException +&DbLockNotGrantedException::operator =(const DbLockNotGrantedException &that) +{ + if (this != &that) { + DbException::operator=(that); + op_ = that.op_; + mode_ = that.mode_; + obj_ = that.obj_; + lock_ = new DbLock(*that.lock_); + index_ = that.index_; + } + return (*this); +} + +db_lockop_t DbLockNotGrantedException::get_op() const +{ + return op_; +} + +db_lockmode_t DbLockNotGrantedException::get_mode() const +{ + return mode_; +} + +const Dbt* DbLockNotGrantedException::get_obj() const +{ + return obj_; +} + +DbLock* DbLockNotGrantedException::get_lock() const +{ + return lock_; +} + +int DbLockNotGrantedException::get_index() const +{ + return index_; +} + + + +//////////////////////////////////////////////////////////////////////// +// // +// DbRunRecoveryException // +// // +//////////////////////////////////////////////////////////////////////// + +DbRunRecoveryException::~DbRunRecoveryException() +{ +} + +DbRunRecoveryException::DbRunRecoveryException(const char *description) +: DbException(description, DB_RUNRECOVERY) +{ +} + +DbRunRecoveryException::DbRunRecoveryException + (const DbRunRecoveryException &that) +: DbException(that) +{ +} + +DbRunRecoveryException +&DbRunRecoveryException::operator =(const DbRunRecoveryException &that) +{ + if (this != &that) + DbException::operator=(that); + return (*this); +} diff --git a/bdb/cxx/cxx_lock.cpp b/bdb/cxx/cxx_lock.cpp index e8ce2aa9d30..446eba49e27 100644 --- a/bdb/cxx/cxx_lock.cpp +++ b/bdb/cxx/cxx_lock.cpp @@ -1,86 +1,21 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 1998, 1999, 2000 + * Copyright (c) 1997-2002 * Sleepycat Software. All rights reserved. */ #include "db_config.h" #ifndef lint -static const char revid[] = "$Id: cxx_lock.cpp,v 11.9 2000/09/21 15:05:45 dda Exp $"; +static const char revid[] = "$Id: cxx_lock.cpp,v 11.17 2002/03/27 04:31:16 bostic Exp $"; #endif /* not lint */ #include #include #include "db_cxx.h" -#include "cxx_int.h" - -int DbEnv::lock_detect(u_int32_t flags, u_int32_t atype, int *aborted) -{ - DB_ENV *env = unwrap(this); - int err; - - if ((err = ::lock_detect(env, flags, atype, aborted)) != 0) { - DB_ERROR("DbEnv::lock_detect", err, error_policy()); - return (err); - } - return (err); -} - -int DbEnv::lock_get(u_int32_t locker, u_int32_t flags, const Dbt *obj, - db_lockmode_t lock_mode, DbLock *lock) -{ - DB_ENV *env = unwrap(this); - int err; - - if ((err = ::lock_get(env, locker, flags, obj, - lock_mode, &lock->lock_)) != 0) { - DB_ERROR("DbEnv::lock_get", err, error_policy()); - return (err); - } - return (err); -} - -int DbEnv::lock_id(u_int32_t *idp) -{ - DB_ENV *env = unwrap(this); - int err; - - if ((err = ::lock_id(env, idp)) != 0) { - DB_ERROR("DbEnv::lock_id", err, error_policy()); - } - return (err); -} - -int DbEnv::lock_stat(DB_LOCK_STAT **statp, - db_malloc_fcn_type db_malloc_fcn) -{ - DB_ENV *env = unwrap(this); - int err; - - if ((err = ::lock_stat(env, statp, db_malloc_fcn)) != 0) { - DB_ERROR("DbEnv::lock_stat", err, error_policy()); - return (err); - } - return (0); -} - -int DbEnv::lock_vec(u_int32_t locker, u_int32_t flags, - DB_LOCKREQ list[], - int nlist, DB_LOCKREQ **elist_returned) -{ - DB_ENV *env = unwrap(this); - int err; - - if ((err = ::lock_vec(env, locker, flags, list, - nlist, elist_returned)) != 0) { - DB_ERROR("DbEnv::lock_vec", err, error_policy()); - return (err); - } - return (err); -} +#include "dbinc/cxx_int.h" //////////////////////////////////////////////////////////////////////// // // @@ -108,18 +43,3 @@ DbLock &DbLock::operator = (const DbLock &that) lock_ = that.lock_; return (*this); } - -int DbLock::put(DbEnv *env) -{ - DB_ENV *envp = unwrap(env); - - if (!env) { - return (EINVAL); // handle never assigned - } - - int err; - if ((err = lock_put(envp, &lock_)) != 0) { - DB_ERROR("DbLock::put", err, env->error_policy()); - } - return (err); -} diff --git a/bdb/cxx/cxx_log.cpp b/bdb/cxx/cxx_log.cpp deleted file mode 100644 index 336b9d337f0..00000000000 --- a/bdb/cxx/cxx_log.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997, 1998, 1999, 2000 - * Sleepycat Software. All rights reserved. - */ - -#include "db_config.h" - -#ifndef lint -static const char revid[] = "$Id: cxx_log.cpp,v 11.9 2000/09/21 15:05:45 dda Exp $"; -#endif /* not lint */ - -#include - -#include "db_cxx.h" -#include "cxx_int.h" - -//////////////////////////////////////////////////////////////////////// -// // -// DbLog // -// // -//////////////////////////////////////////////////////////////////////// - -int DbEnv::log_archive(char **list[], u_int32_t flags, - db_malloc_fcn_type db_malloc_fcn) -{ - int err; - DB_ENV *env = unwrap(this); - - if ((err = ::log_archive(env, list, flags, db_malloc_fcn)) != 0) { - DB_ERROR("DbEnv::log_archive", err, error_policy()); - return (err); - } - return (0); -} - -int DbEnv::log_compare(const DbLsn *lsn0, const DbLsn *lsn1) -{ - return (::log_compare(lsn0, lsn1)); -} - -int DbEnv::log_file(DbLsn *lsn, char *namep, size_t len) -{ - int err; - DB_ENV *env = unwrap(this); - - if ((err = ::log_file(env, lsn, namep, len)) != 0) { - DB_ERROR("DbEnv::log_file", err, error_policy()); - return (err); - } - return (0); -} - -int DbEnv::log_flush(const DbLsn *lsn) -{ - int err; - DB_ENV *env = unwrap(this); - - if ((err = ::log_flush(env, lsn)) != 0) { - DB_ERROR("DbEnv::log_flush", err, error_policy()); - return (err); - } - return (0); -} - -int DbEnv::log_get(DbLsn *lsn, Dbt *data, u_int32_t flags) -{ - int err; - DB_ENV *env = unwrap(this); - - if ((err = ::log_get(env, lsn, data, flags)) != 0) { - DB_ERROR("DbEnv::log_get", err, error_policy()); - return (err); - } - return (0); -} - -int DbEnv::log_put(DbLsn *lsn, const Dbt *data, u_int32_t flags) -{ - int err = 0; - DB_ENV *env = unwrap(this); - - if ((err = ::log_put(env, lsn, data, flags)) != 0) { - DB_ERROR("DbEnv::log_put", err, error_policy()); - return (err); - } - return (0); -} - -int DbEnv::log_register(Db *dbp, const char *name) -{ - int err = 0; - DB_ENV *env = unwrap(this); - - if ((err = ::log_register(env, unwrap(dbp), name)) != 0) { - DB_ERROR("DbEnv::log_register", err, error_policy()); - return (err); - } - return (0); -} - -int DbEnv::log_stat(DB_LOG_STAT **spp, db_malloc_fcn_type db_malloc_fcn) -{ - int err = 0; - DB_ENV *env = unwrap(this); - - if ((err = ::log_stat(env, spp, db_malloc_fcn)) != 0) { - DB_ERROR("DbEnv::log_stat", err, error_policy()); - return (err); - } - return (0); -} - -int DbEnv::log_unregister(Db *dbp) -{ - int err; - DB_ENV *env = unwrap(this); - - if ((err = ::log_unregister(env, unwrap(dbp))) != 0) { - DB_ERROR("DbEnv::log_unregister", err, error_policy()); - return (err); - } - return (0); -} diff --git a/bdb/cxx/cxx_logc.cpp b/bdb/cxx/cxx_logc.cpp new file mode 100644 index 00000000000..d1fe83dd58b --- /dev/null +++ b/bdb/cxx/cxx_logc.cpp @@ -0,0 +1,65 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1997-2002 + * Sleepycat Software. All rights reserved. + */ + +#include "db_config.h" + +#ifndef lint +static const char revid[] = "$Id: cxx_logc.cpp,v 11.8 2002/07/03 21:03:53 bostic Exp $"; +#endif /* not lint */ + +#include +#include + +#include "db_cxx.h" +#include "dbinc/cxx_int.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc_auto/db_auto.h" +#include "dbinc_auto/crdel_auto.h" +#include "dbinc/db_dispatch.h" +#include "dbinc_auto/db_ext.h" +#include "dbinc_auto/common_ext.h" + +// It's private, and should never be called, +// but some compilers need it resolved +// +DbLogc::~DbLogc() +{ +} + +// The name _flags prevents a name clash with __db_log_cursor::flags +int DbLogc::close(u_int32_t _flags) +{ + DB_LOGC *logc = this; + int ret; + + ret = logc->close(logc, _flags); + + if (!DB_RETOK_STD(ret)) + DB_ERROR("DbLogc::close", ret, ON_ERROR_UNKNOWN); + + return (ret); +} + +// The name _flags prevents a name clash with __db_log_cursor::flags +int DbLogc::get(DbLsn *lsn, Dbt *data, u_int32_t _flags) +{ + DB_LOGC *logc = this; + int ret; + + ret = logc->get(logc, lsn, data, _flags); + + if (!DB_RETOK_LGGET(ret)) { + if (ret == ENOMEM && DB_OVERFLOWED_DBT(data)) + DB_ERROR_DBT("DbLogc::get", data, ON_ERROR_UNKNOWN); + else + DB_ERROR("DbLogc::get", ret, ON_ERROR_UNKNOWN); + } + + return (ret); +} diff --git a/bdb/cxx/cxx_mpool.cpp b/bdb/cxx/cxx_mpool.cpp index 22f4735e333..3eb78d03ff4 100644 --- a/bdb/cxx/cxx_mpool.cpp +++ b/bdb/cxx/cxx_mpool.cpp @@ -1,20 +1,51 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 1998, 1999, 2000 + * Copyright (c) 1997-2002 * Sleepycat Software. All rights reserved. */ #include "db_config.h" #ifndef lint -static const char revid[] = "$Id: cxx_mpool.cpp,v 11.11 2000/09/21 15:05:45 dda Exp $"; +static const char revid[] = "$Id: cxx_mpool.cpp,v 11.20 2002/07/03 21:03:53 bostic Exp $"; #endif /* not lint */ #include #include "db_cxx.h" -#include "cxx_int.h" +#include "dbinc/cxx_int.h" + +#include "db_int.h" + +// Helper macros for simple methods that pass through to the +// underlying C method. It may return an error or raise an exception. +// Note this macro expects that input _argspec is an argument +// list element (e.g., "char *arg") and that _arglist is the arguments +// that should be passed through to the C method (e.g., "(mpf, arg)") +// +#define DB_MPOOLFILE_METHOD(_name, _argspec, _arglist, _retok) \ +int DbMpoolFile::_name _argspec \ +{ \ + int ret; \ + DB_MPOOLFILE *mpf = unwrap(this); \ + \ + if (mpf == NULL) \ + ret = EINVAL; \ + else \ + ret = mpf->_name _arglist; \ + if (!_retok(ret)) \ + DB_ERROR("DbMpoolFile::"#_name, ret, ON_ERROR_UNKNOWN); \ + return (ret); \ +} + +#define DB_MPOOLFILE_METHOD_VOID(_name, _argspec, _arglist) \ +void DbMpoolFile::_name _argspec \ +{ \ + DB_MPOOLFILE *mpf = unwrap(this); \ + \ + mpf->_name _arglist; \ +} //////////////////////////////////////////////////////////////////////// // // @@ -31,150 +62,49 @@ DbMpoolFile::~DbMpoolFile() { } -int DbMpoolFile::open(DbEnv *envp, const char *file, - u_int32_t flags, int mode, size_t pagesize, - DB_MPOOL_FINFO *finfop, DbMpoolFile **result) -{ - int err; - - DB_MPOOLFILE *mpf; - DB_ENV *env = unwrap(envp); - - if ((err = ::memp_fopen(env, file, flags, mode, pagesize, - finfop, &mpf)) != 0) { - DB_ERROR("DbMpoolFile::open", err, envp->error_policy()); - return (err); - } - *result = new DbMpoolFile(); - (*result)->imp_ = wrap(mpf); - return (0); -} - -int DbMpoolFile::close() +int DbMpoolFile::close(u_int32_t flags) { DB_MPOOLFILE *mpf = unwrap(this); - int err = 0; - if (!mpf) { - err = EINVAL; - } - else if ((err = ::memp_fclose(mpf)) != 0) { - DB_ERROR("DbMpoolFile::close", err, ON_ERROR_UNKNOWN); - return (err); - } + int ret; + + if (mpf == NULL) + ret = EINVAL; + else + ret = mpf->close(mpf, flags); + imp_ = 0; // extra safety // This may seem weird, but is legal as long as we don't access // any data before returning. - // delete this; - return (0); -} - -int DbMpoolFile::get(db_pgno_t *pgnoaddr, u_int32_t flags, void *pagep) -{ - DB_MPOOLFILE *mpf = unwrap(this); - int err = 0; - if (!mpf) { - err = EINVAL; - } - else if ((err = ::memp_fget(mpf, pgnoaddr, flags, pagep)) != 0) { - DB_ERROR("DbMpoolFile::get", err, ON_ERROR_UNKNOWN); - } - return (err); -} - -int DbMpoolFile::put(void *pgaddr, u_int32_t flags) -{ - DB_MPOOLFILE *mpf = unwrap(this); - int err = 0; - if (!mpf) { - err = EINVAL; - } - else if ((err = ::memp_fput(mpf, pgaddr, flags)) != 0) { - DB_ERROR("DbMpoolFile::put", err, ON_ERROR_UNKNOWN); - } - return (err); -} - -int DbMpoolFile::set(void *pgaddr, u_int32_t flags) -{ - DB_MPOOLFILE *mpf = unwrap(this); - int err = 0; - if (!mpf) { - err = EINVAL; - } - else if ((err = ::memp_fset(mpf, pgaddr, flags)) != 0) { - DB_ERROR("DbMpoolFile::set", err, ON_ERROR_UNKNOWN); - } - return (err); -} - -int DbMpoolFile::sync() -{ - DB_MPOOLFILE *mpf = unwrap(this); - int err = 0; - if (!mpf) { - err = EINVAL; - } - else if ((err = ::memp_fsync(mpf)) != 0 && err != DB_INCOMPLETE) { - DB_ERROR("DbMpoolFile::sync", err, ON_ERROR_UNKNOWN); - } - return (err); -} -//////////////////////////////////////////////////////////////////////// -// // -// DbMpool // -// // -//////////////////////////////////////////////////////////////////////// + if (!DB_RETOK_STD(ret)) + DB_ERROR("DbMpoolFile::close", ret, ON_ERROR_UNKNOWN); -int DbEnv::memp_register(int ftype, - pgin_fcn_type pgin_fcn, - pgout_fcn_type pgout_fcn) -{ - DB_ENV *env = unwrap(this); - int err = 0; - - if ((err = ::memp_register(env, ftype, pgin_fcn, pgout_fcn)) != 0) { - DB_ERROR("DbEnv::memp_register", err, error_policy()); - return (err); - } - return (err); + return (ret); } -int DbEnv::memp_stat(DB_MPOOL_STAT **gsp, DB_MPOOL_FSTAT ***fsp, - db_malloc_fcn_type db_malloc_fcn) -{ - DB_ENV *env = unwrap(this); - int err = 0; - - if ((err = ::memp_stat(env, gsp, fsp, db_malloc_fcn)) != 0) { - DB_ERROR("DbEnv::memp_stat", err, error_policy()); - return (err); - } - return (err); -} - -int DbEnv::memp_sync(DbLsn *sn) -{ - DB_ENV *env = unwrap(this); - int err = 0; - - if ((err = ::memp_sync(env, sn)) != 0 && err != DB_INCOMPLETE) { - DB_ERROR("DbEnv::memp_sync", err, error_policy()); - return (err); - } - return (err); -} - -int DbEnv::memp_trickle(int pct, int *nwrotep) -{ - DB_ENV *env = unwrap(this); - int err = 0; - - if ((err = ::memp_trickle(env, pct, nwrotep)) != 0) { - DB_ERROR("DbEnv::memp_trickle", err, error_policy()); - return (err); - } - return (err); -} +DB_MPOOLFILE_METHOD(get, (db_pgno_t *pgnoaddr, u_int32_t flags, void *pagep), + (mpf, pgnoaddr, flags, pagep), DB_RETOK_MPGET) +DB_MPOOLFILE_METHOD_VOID(last_pgno, (db_pgno_t *pgnoaddr), (mpf, pgnoaddr)) +DB_MPOOLFILE_METHOD(open, + (const char *file, u_int32_t flags, int mode, size_t pagesize), + (mpf, file, flags, mode, pagesize), DB_RETOK_STD) +DB_MPOOLFILE_METHOD(put, (void *pgaddr, u_int32_t flags), + (mpf, pgaddr, flags), DB_RETOK_STD) +DB_MPOOLFILE_METHOD_VOID(refcnt, (db_pgno_t *pgnoaddr), (mpf, pgnoaddr)) +DB_MPOOLFILE_METHOD(set, (void *pgaddr, u_int32_t flags), + (mpf, pgaddr, flags), DB_RETOK_STD) +DB_MPOOLFILE_METHOD(set_clear_len, (u_int32_t len), + (mpf, len), DB_RETOK_STD) +DB_MPOOLFILE_METHOD(set_fileid, (u_int8_t *fileid), + (mpf, fileid), DB_RETOK_STD) +DB_MPOOLFILE_METHOD(set_ftype, (int ftype), + (mpf, ftype), DB_RETOK_STD) +DB_MPOOLFILE_METHOD(set_lsn_offset, (int32_t offset), + (mpf, offset), DB_RETOK_STD) +DB_MPOOLFILE_METHOD(set_pgcookie, (DBT *dbt), + (mpf, dbt), DB_RETOK_STD) +DB_MPOOLFILE_METHOD_VOID(set_unlink, (int ul), (mpf, ul)) +DB_MPOOLFILE_METHOD(sync, (), + (mpf), DB_RETOK_STD) diff --git a/bdb/cxx/cxx_table.cpp b/bdb/cxx/cxx_table.cpp deleted file mode 100644 index b7b335d26e9..00000000000 --- a/bdb/cxx/cxx_table.cpp +++ /dev/null @@ -1,808 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997, 1998, 1999, 2000 - * Sleepycat Software. All rights reserved. - */ - -#include "db_config.h" - -#ifndef lint -static const char revid[] = "$Id: cxx_table.cpp,v 11.35 2001/01/11 18:19:49 bostic Exp $"; -#endif /* not lint */ - -#include -#include - -#include "db_cxx.h" -#include "cxx_int.h" - -#include "db_int.h" -#include "db_page.h" -#include "db_ext.h" -#include "common_ext.h" - -//////////////////////////////////////////////////////////////////////// -// // -// Db // -// // -//////////////////////////////////////////////////////////////////////// - -// A truism for the DbEnv object is that there is a valid -// DB_ENV handle from the constructor until close(). -// After the close, the DB handle is invalid and -// no operations are permitted on the Db (other than -// destructor). Leaving the Db handle open and not -// doing a close is generally considered an error. -// -// We used to allow Db objects to be closed and reopened. -// This implied always keeping a valid DB object, and -// coordinating the open objects between Db/DbEnv turned -// out to be overly complicated. Now we do not allow this. - -Db::Db(DbEnv *env, u_int32_t flags) -: imp_(0) -, env_(env) -, construct_error_(0) -, flags_(0) -, construct_flags_(flags) -{ - if (env_ == 0) - flags_ |= DB_CXX_PRIVATE_ENV; - initialize(); -} - -// Note: if the user has not closed, we call _destroy_check -// to warn against this non-safe programming practice. -// We can't close, because the environment may already -// be closed/destroyed. -// -Db::~Db() -{ - DB *db; - - db = unwrap(this); - if (db != NULL) { - DbEnv::_destroy_check("Db", 0); - cleanup(); - } -} - -// private method to initialize during constructor. -// initialize must create a backing DB object, -// and if that creates a new DB_ENV, it must be tied to a new DbEnv. -// If there is an error, construct_error_ is set; this is examined -// during open. -// -int Db::initialize() -{ - u_int32_t cxx_flags; - DB *db; - int err; - DB_ENV *cenv = unwrap(env_); - - cxx_flags = construct_flags_ & DB_CXX_NO_EXCEPTIONS; - - // Create a new underlying DB object. - // We rely on the fact that if a NULL DB_ENV* is given, - // one is allocated by DB. - // - if ((err = db_create(&db, cenv, - construct_flags_ & ~cxx_flags)) != 0) { - construct_error_ = err; - return (err); - } - - // Associate the DB with this object - imp_ = wrap(db); - db->cj_internal = this; - - // Create a new DbEnv from a DB_ENV* if it was created locally. - // It is deleted in Db::close(). - // - if ((flags_ & DB_CXX_PRIVATE_ENV) != 0) - env_ = new DbEnv(db->dbenv, cxx_flags); - - return (0); -} - -// private method to cleanup after destructor or during close. -// If the environment was created by this Db object, we optionally -// delete it, or return it so the caller can delete it after -// last use. -// -void Db::cleanup() -{ - DB *db = unwrap(this); - - if (db != NULL) { - // extra safety - db->cj_internal = 0; - imp_ = 0; - - // we must dispose of the DbEnv object if - // we created it. This will be the case - // if a NULL DbEnv was passed into the constructor. - // The underlying DB_ENV object will be inaccessible - // after the close, so we must clean it up now. - // - if ((flags_ & DB_CXX_PRIVATE_ENV) != 0) { - env_->cleanup(); - delete env_; - env_ = 0; - } - } - construct_error_ = 0; -} - -// Return a tristate value corresponding to whether we should -// throw exceptions on errors: -// ON_ERROR_RETURN -// ON_ERROR_THROW -// ON_ERROR_UNKNOWN -// -int Db::error_policy() -{ - if (env_ != NULL) - return (env_->error_policy()); - else { - // If the env_ is null, that means that the user - // did not attach an environment, so the correct error - // policy can be deduced from constructor flags - // for this Db. - // - if ((construct_flags_ & DB_CXX_NO_EXCEPTIONS) != 0) { - return (ON_ERROR_RETURN); - } - else { - return (ON_ERROR_THROW); - } - } -} - -int Db::close(u_int32_t flags) -{ - DB *db = unwrap(this); - int err; - - // after a DB->close (no matter if success or failure), - // the underlying DB object must not be accessed, - // so we clean up in advance. - // - cleanup(); - - // It's safe to throw an error after the close, - // since our error mechanism does not peer into - // the DB* structures. - // - if ((err = db->close(db, flags)) != 0 && err != DB_INCOMPLETE) - DB_ERROR("Db::close", err, error_policy()); - - return (err); -} - -int Db::cursor(DbTxn *txnid, Dbc **cursorp, u_int32_t flags) -{ - DB *db = unwrap(this); - DBC *dbc = 0; - int err; - - if ((err = db->cursor(db, unwrap(txnid), &dbc, flags)) != 0) { - DB_ERROR("Db::cursor", err, error_policy()); - return (err); - } - - // The following cast implies that Dbc can be no larger than DBC - *cursorp = (Dbc*)dbc; - return (0); -} - -int Db::del(DbTxn *txnid, Dbt *key, u_int32_t flags) -{ - DB *db = unwrap(this); - int err; - - if ((err = db->del(db, unwrap(txnid), key, flags)) != 0) { - // DB_NOTFOUND is a "normal" return, so should not be - // thrown as an error - // - if (err != DB_NOTFOUND) { - DB_ERROR("Db::del", err, error_policy()); - return (err); - } - } - return (err); -} - -void Db::err(int error, const char *format, ...) -{ - va_list args; - DB *db = unwrap(this); - - va_start(args, format); - __db_real_err(db->dbenv, error, 1, 1, format, args); - va_end(args); -} - -void Db::errx(const char *format, ...) -{ - va_list args; - DB *db = unwrap(this); - - va_start(args, format); - __db_real_err(db->dbenv, 0, 0, 1, format, args); - va_end(args); -} - -int Db::fd(int *fdp) -{ - DB *db = unwrap(this); - int err; - - if ((err = db->fd(db, fdp)) != 0) { - DB_ERROR("Db::fd", err, error_policy()); - return (err); - } - return (0); -} - -// This is a 'glue' function declared as extern "C" so it will -// be compatible with picky compilers that do not allow mixing -// of function pointers to 'C' functions with function pointers -// to C++ functions. -// -extern "C" -void _db_feedback_intercept_c(DB *db, int opcode, int pct) -{ - Db::_feedback_intercept(db, opcode, pct); -} - -//static -void Db::_feedback_intercept(DB *db, int opcode, int pct) -{ - if (db == 0) { - DB_ERROR("Db::feedback_callback", EINVAL, ON_ERROR_UNKNOWN); - return; - } - Db *cxxdb = (Db *)db->cj_internal; - if (cxxdb == 0) { - DB_ERROR("Db::feedback_callback", EINVAL, ON_ERROR_UNKNOWN); - return; - } - if (cxxdb->feedback_callback_ == 0) { - DB_ERROR("Db::feedback_callback", EINVAL, cxxdb->error_policy()); - return; - } - (*cxxdb->feedback_callback_)(cxxdb, opcode, pct); -} - -int Db::set_feedback(void (*arg)(Db *, int, int)) -{ - DB *db = unwrap(this); - - feedback_callback_ = arg; - - return ((*(db->set_feedback))(db, _db_feedback_intercept_c)); -} - -// This is a 'glue' function declared as extern "C" so it will -// be compatible with picky compilers that do not allow mixing -// of function pointers to 'C' functions with function pointers -// to C++ functions. -// -extern "C" -int _db_append_recno_intercept_c(DB *db, DBT *data, db_recno_t recno) -{ - return (Db::_append_recno_intercept(db, data, recno)); -} - -//static -int Db::_append_recno_intercept(DB *db, DBT *data, db_recno_t recno) -{ - int err; - - if (db == 0) { - DB_ERROR("Db::append_recno_callback", EINVAL, ON_ERROR_UNKNOWN); - return (EINVAL); - } - Db *cxxdb = (Db *)db->cj_internal; - if (cxxdb == 0) { - DB_ERROR("Db::append_recno_callback", EINVAL, ON_ERROR_UNKNOWN); - return (EINVAL); - } - if (cxxdb->append_recno_callback_ == 0) { - DB_ERROR("Db::append_recno_callback", EINVAL, cxxdb->error_policy()); - return (EINVAL); - } - - // making these copies is slow but portable. - // Another alternative is to cast the DBT* manufactured - // by the C layer to a Dbt*. It 'should be' safe since - // Dbt is a thin shell over DBT, adding no extra data, - // but is nonportable, and could lead to errors if anything - // were added to the Dbt class. - // - Dbt cxxdbt; - memcpy((DBT *)&cxxdbt, data, sizeof(DBT)); - err = (*cxxdb->append_recno_callback_)(cxxdb, &cxxdbt, recno); - memcpy(data, (DBT *)&cxxdbt, sizeof(DBT)); - return (err); -} - -int Db::set_append_recno(int (*arg)(Db *, Dbt *, db_recno_t)) -{ - DB *db = unwrap(this); - - append_recno_callback_ = arg; - - return ((*(db->set_append_recno))(db, _db_append_recno_intercept_c)); -} - -int Db::get(DbTxn *txnid, Dbt *key, Dbt *value, u_int32_t flags) -{ - DB *db = unwrap(this); - int err; - - if ((err = db->get(db, unwrap(txnid), key, value, flags)) != 0) { - // DB_NOTFOUND and DB_KEYEMPTY are "normal" returns, - // so should not be thrown as an error - // - if (err != DB_NOTFOUND && err != DB_KEYEMPTY) { - DB_ERROR("Db::get", err, error_policy()); - return (err); - } - } - return (err); -} - -int Db::get_byteswapped() const -{ - DB *db = (DB *)unwrapConst(this); - return (db->get_byteswapped(db)); -} - -DBTYPE Db::get_type() const -{ - DB *db = (DB *)unwrapConst(this); - return ((DBTYPE)db->get_type(db)); -} - -int Db::join(Dbc **curslist, Dbc **cursorp, u_int32_t flags) -{ - // Dbc is a "compatible" subclass of DBC - - // that is, no virtual functions or even extra data members, - // so this cast, although technically non-portable, - // "should" always be okay. - // - DBC **list = (DBC **)(curslist); - DB *db = unwrap(this); - DBC *dbc = 0; - int err; - - if ((err = db->join(db, list, &dbc, flags)) != 0) { - DB_ERROR("Db::join_cursor", err, error_policy()); - return (err); - } - *cursorp = (Dbc*)dbc; - return (0); -} - -int Db::key_range(DbTxn *txnid, Dbt *key, - DB_KEY_RANGE *results, u_int32_t flags) -{ - DB *db = unwrap(this); - int err; - - if ((err = db->key_range(db, unwrap(txnid), key, - results, flags)) != 0) { - DB_ERROR("Db::key_range", err, error_policy()); - return (err); - } - return (0); -} - -// If an error occurred during the constructor, report it now. -// Otherwise, call the underlying DB->open method. -// -int Db::open(const char *file, const char *database, - DBTYPE type, u_int32_t flags, int mode) -{ - int err; - DB *db = unwrap(this); - - if ((err = construct_error_) != 0) - DB_ERROR("Db::open", construct_error_, error_policy()); - else if ((err = db->open(db, file, database, type, flags, mode)) != 0) - DB_ERROR("Db::open", err, error_policy()); - - return (err); -} - -int Db::put(DbTxn *txnid, Dbt *key, Dbt *value, u_int32_t flags) -{ - int err; - DB *db = unwrap(this); - - if ((err = db->put(db, unwrap(txnid), key, value, flags)) != 0) { - - // DB_KEYEXIST is a "normal" return, so should not be - // thrown as an error - // - if (err != DB_KEYEXIST) { - DB_ERROR("Db::put", err, error_policy()); - return (err); - } - } - return (err); -} - -int Db::rename(const char *file, const char *database, - const char *newname, u_int32_t flags) -{ - int err = 0; - DB *db = unwrap(this); - - if (!db) { - DB_ERROR("Db::rename", EINVAL, error_policy()); - return (EINVAL); - } - - // after a DB->rename (no matter if success or failure), - // the underlying DB object must not be accessed, - // so we clean up in advance. - // - cleanup(); - - if ((err = db->rename(db, file, database, newname, flags)) != 0) { - DB_ERROR("Db::rename", err, error_policy()); - return (err); - } - return (0); -} - -int Db::remove(const char *file, const char *database, u_int32_t flags) -{ - int err = 0; - DB *db = unwrap(this); - - if (!db) { - DB_ERROR("Db::remove", EINVAL, error_policy()); - return (EINVAL); - } - - // after a DB->remove (no matter if success or failure), - // the underlying DB object must not be accessed, - // so we clean up in advance. - // - cleanup(); - - if ((err = db->remove(db, file, database, flags)) != 0) - DB_ERROR("Db::remove", err, error_policy()); - - return (err); -} - -int Db::stat(void *sp, db_malloc_fcn_type db_malloc_fcn, u_int32_t flags) -{ - int err; - DB *db = unwrap(this); - - if (!db) { - DB_ERROR("Db::stat", EINVAL, error_policy()); - return (EINVAL); - } - if ((err = db->stat(db, sp, db_malloc_fcn, flags)) != 0) { - DB_ERROR("Db::stat", err, error_policy()); - return (err); - } - return (0); -} - -int Db::sync(u_int32_t flags) -{ - int err; - DB *db = unwrap(this); - - if (!db) { - DB_ERROR("Db::sync", EINVAL, error_policy()); - return (EINVAL); - } - if ((err = db->sync(db, flags)) != 0 && err != DB_INCOMPLETE) { - DB_ERROR("Db::sync", err, error_policy()); - return (err); - } - return (err); -} - -int Db::upgrade(const char *name, u_int32_t flags) -{ - int err; - DB *db = unwrap(this); - - if (!db) { - DB_ERROR("Db::upgrade", EINVAL, error_policy()); - return (EINVAL); - } - if ((err = db->upgrade(db, name, flags)) != 0) { - DB_ERROR("Db::upgrade", err, error_policy()); - return (err); - } - return (0); -} - -static int _verify_callback_cxx(void *handle, const void *str_arg) -{ - char *str; - ostream *out; - - str = (char *)str_arg; - out = (ostream *)handle; - - (*out) << str; - if (out->fail()) - return (EIO); - - return (0); -} - -// This is a 'glue' function declared as extern "C" so it will -// be compatible with picky compilers that do not allow mixing -// of function pointers to 'C' functions with function pointers -// to C++ functions. -// -extern "C" -int _verify_callback_c(void *handle, const void *str_arg) -{ - return (_verify_callback_cxx(handle, str_arg)); -} - -int Db::verify(const char *name, const char *subdb, - ostream *ostr, u_int32_t flags) -{ - int err; - DB *db = unwrap(this); - - if (!db) { - DB_ERROR("Db::verify", EINVAL, error_policy()); - return (EINVAL); - } - if ((err = __db_verify_internal(db, name, subdb, ostr, - _verify_callback_c, flags)) != 0) { - DB_ERROR("Db::verify", err, error_policy()); - return (err); - } - return (0); -} - -// This is a variant of the DB_WO_ACCESS macro to define a simple set_ -// method calling the underlying C method, but unlike a simple -// set method, it may return an error or raise an exception. -// Note this macro expects that input _argspec is an argument -// list element (e.g. "char *arg") defined in terms of "arg". -// -#define DB_DB_ACCESS(_name, _argspec) \ -\ -int Db::set_##_name(_argspec) \ -{ \ - int ret; \ - DB *db = unwrap(this); \ - \ - if ((ret = (*(db->set_##_name))(db, arg)) != 0) { \ - DB_ERROR("Db::set_" # _name, ret, error_policy()); \ - } \ - return (ret); \ -} - -#define DB_DB_ACCESS_NORET(_name, _argspec) \ - \ -void Db::set_##_name(_argspec) \ -{ \ - DB *db = unwrap(this); \ - \ - (*(db->set_##_name))(db, arg); \ - return; \ -} - -DB_DB_ACCESS(bt_compare, bt_compare_fcn_type arg) -DB_DB_ACCESS(bt_maxkey, u_int32_t arg) -DB_DB_ACCESS(bt_minkey, u_int32_t arg) -DB_DB_ACCESS(bt_prefix, bt_prefix_fcn_type arg) -DB_DB_ACCESS(dup_compare, dup_compare_fcn_type arg) -DB_DB_ACCESS_NORET(errfile, FILE *arg) -DB_DB_ACCESS_NORET(errpfx, const char *arg) -DB_DB_ACCESS(flags, u_int32_t arg) -DB_DB_ACCESS(h_ffactor, u_int32_t arg) -DB_DB_ACCESS(h_hash, h_hash_fcn_type arg) -DB_DB_ACCESS(h_nelem, u_int32_t arg) -DB_DB_ACCESS(lorder, int arg) -DB_DB_ACCESS(malloc, db_malloc_fcn_type arg) -DB_DB_ACCESS(pagesize, u_int32_t arg) -DB_DB_ACCESS(realloc, db_realloc_fcn_type arg) -DB_DB_ACCESS(re_delim, int arg) -DB_DB_ACCESS(re_len, u_int32_t arg) -DB_DB_ACCESS(re_pad, int arg) -DB_DB_ACCESS(re_source, char *arg) -DB_DB_ACCESS(q_extentsize, u_int32_t arg) - -// Here are the set methods that don't fit the above mold. -// - -void Db::set_errcall(void (*arg)(const char *, char *)) -{ - env_->set_errcall(arg); -} - -int Db::set_cachesize(u_int32_t gbytes, u_int32_t bytes, int ncache) -{ - int ret; - DB *db = unwrap(this); - - if ((ret = (*(db->set_cachesize))(db, gbytes, bytes, ncache)) != 0) { - DB_ERROR("Db::set_cachesize", ret, error_policy()); - } - return (ret); -} - -int Db::set_paniccall(void (*callback)(DbEnv *, int)) -{ - return (env_->set_paniccall(callback)); -} - -void Db::set_error_stream(ostream *error_stream) -{ - env_->set_error_stream(error_stream); -} - -//////////////////////////////////////////////////////////////////////// -// // -// Dbc // -// // -//////////////////////////////////////////////////////////////////////// - -// It's private, and should never be called, but VC4.0 needs it resolved -// -Dbc::~Dbc() -{ -} - -int Dbc::close() -{ - DBC *cursor = this; - int err; - - if ((err = cursor->c_close(cursor)) != 0) { - DB_ERROR("Db::close", err, ON_ERROR_UNKNOWN); - return (err); - } - return (0); -} - -int Dbc::count(db_recno_t *countp, u_int32_t flags_arg) -{ - DBC *cursor = this; - int err; - - if ((err = cursor->c_count(cursor, countp, flags_arg)) != 0) { - DB_ERROR("Db::count", err, ON_ERROR_UNKNOWN); - return (err); - } - return (0); -} - -int Dbc::del(u_int32_t flags_arg) -{ - DBC *cursor = this; - int err; - - if ((err = cursor->c_del(cursor, flags_arg)) != 0) { - - // DB_KEYEMPTY is a "normal" return, so should not be - // thrown as an error - // - if (err != DB_KEYEMPTY) { - DB_ERROR("Db::del", err, ON_ERROR_UNKNOWN); - return (err); - } - } - return (err); -} - -int Dbc::dup(Dbc** cursorp, u_int32_t flags_arg) -{ - DBC *cursor = this; - DBC *new_cursor = 0; - int err; - - if ((err = cursor->c_dup(cursor, &new_cursor, flags_arg)) != 0) { - DB_ERROR("Db::dup", err, ON_ERROR_UNKNOWN); - return (err); - } - - // The following cast implies that Dbc can be no larger than DBC - *cursorp = (Dbc*)new_cursor; - return (0); -} - -int Dbc::get(Dbt* key, Dbt *data, u_int32_t flags_arg) -{ - DBC *cursor = this; - int err; - - if ((err = cursor->c_get(cursor, key, data, flags_arg)) != 0) { - - // DB_NOTFOUND and DB_KEYEMPTY are "normal" returns, - // so should not be thrown as an error - // - if (err != DB_NOTFOUND && err != DB_KEYEMPTY) { - DB_ERROR("Db::get", err, ON_ERROR_UNKNOWN); - return (err); - } - } - return (err); -} - -int Dbc::put(Dbt* key, Dbt *data, u_int32_t flags_arg) -{ - DBC *cursor = this; - int err; - - if ((err = cursor->c_put(cursor, key, data, flags_arg)) != 0) { - - // DB_KEYEXIST is a "normal" return, so should not be - // thrown as an error - // - if (err != DB_KEYEXIST) { - DB_ERROR("Db::put", err, ON_ERROR_UNKNOWN); - return (err); - } - } - return (err); -} - -//////////////////////////////////////////////////////////////////////// -// // -// Dbt // -// // -//////////////////////////////////////////////////////////////////////// - -Dbt::Dbt() -{ - DBT *dbt = this; - memset(dbt, 0, sizeof(DBT)); -} - -Dbt::Dbt(void *data_arg, size_t size_arg) -{ - DBT *dbt = this; - memset(dbt, 0, sizeof(DBT)); - set_data(data_arg); - set_size(size_arg); -} - -Dbt::~Dbt() -{ -} - -Dbt::Dbt(const Dbt &that) -{ - const DBT *from = &that; - DBT *to = this; - memcpy(to, from, sizeof(DBT)); -} - -Dbt &Dbt::operator = (const Dbt &that) -{ - if (this != &that) { - const DBT *from = &that; - DBT *to = this; - memcpy(to, from, sizeof(DBT)); - } - return (*this); -} - -DB_RW_ACCESS(Dbt, void *, data, data) -DB_RW_ACCESS(Dbt, u_int32_t, size, size) -DB_RW_ACCESS(Dbt, u_int32_t, ulen, ulen) -DB_RW_ACCESS(Dbt, u_int32_t, dlen, dlen) -DB_RW_ACCESS(Dbt, u_int32_t, doff, doff) -DB_RW_ACCESS(Dbt, u_int32_t, flags, flags) diff --git a/bdb/cxx/cxx_txn.cpp b/bdb/cxx/cxx_txn.cpp index 0abae982644..b04077c0f5b 100644 --- a/bdb/cxx/cxx_txn.cpp +++ b/bdb/cxx/cxx_txn.cpp @@ -1,136 +1,81 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 1998, 1999, 2000 + * Copyright (c) 1997-2002 * Sleepycat Software. All rights reserved. */ #include "db_config.h" #ifndef lint -static const char revid[] = "$Id: cxx_txn.cpp,v 11.13 2000/12/21 16:24:33 dda Exp $"; +static const char revid[] = "$Id: cxx_txn.cpp,v 11.27 2002/07/20 13:50:11 dda Exp $"; #endif /* not lint */ #include #include "db_cxx.h" -#include "cxx_int.h" - -//////////////////////////////////////////////////////////////////////// -// // -// DbTxnMgr // -// // -//////////////////////////////////////////////////////////////////////// - -int DbEnv::txn_begin(DbTxn *pid, DbTxn **tid, u_int32_t flags) -{ - int err; - DB_ENV *env = unwrap(this); - DB_TXN *txn; - - if ((err = ::txn_begin(env, unwrap(pid), &txn, flags)) != 0) { - DB_ERROR("DbEnv::txn_begin", err, error_policy()); - return (err); - } - DbTxn *result = new DbTxn(); - result->imp_ = wrap(txn); - *tid = result; - return (err); -} - -int DbEnv::txn_checkpoint(u_int32_t kbyte, u_int32_t min, u_int32_t flags) -{ - int err; - DB_ENV *env = unwrap(this); - if ((err = ::txn_checkpoint(env, kbyte, min, flags)) != 0 && - err != DB_INCOMPLETE) { - DB_ERROR("DbEnv::txn_checkpoint", err, error_policy()); - return (err); - } - return (err); +#include "dbinc/cxx_int.h" + +#include "db_int.h" + +// Helper macro for simple methods that pass through to the +// underlying C method. It may return an error or raise an exception. +// Note this macro expects that input _argspec is an argument +// list element (e.g., "char *arg") and that _arglist is the arguments +// that should be passed through to the C method (e.g., "(db, arg)") +// +#define DBTXN_METHOD(_name, _delete, _argspec, _arglist) \ +int DbTxn::_name _argspec \ +{ \ + int ret; \ + DB_TXN *txn = unwrap(this); \ + \ + ret = txn->_name _arglist; \ + /* Weird, but safe if we don't access this again. */ \ + if (_delete) \ + delete this; \ + if (!DB_RETOK_STD(ret)) \ + DB_ERROR("DbTxn::" # _name, ret, ON_ERROR_UNKNOWN); \ + return (ret); \ } -int DbEnv::txn_stat(DB_TXN_STAT **statp, db_malloc_fcn_type db_malloc_fcn) -{ - int err; - DB_ENV *env = unwrap(this); - if ((err = ::txn_stat(env, statp, db_malloc_fcn)) != 0) { - DB_ERROR("DbEnv::txn_stat", err, error_policy()); - return (err); - } - return (err); -} - -//////////////////////////////////////////////////////////////////////// -// // -// DbTxn // -// // -//////////////////////////////////////////////////////////////////////// - +// private constructor, never called but needed by some C++ linkers DbTxn::DbTxn() : imp_(0) { } -DbTxn::~DbTxn() +DbTxn::DbTxn(DB_TXN *txn) +: imp_(wrap(txn)) { + txn->api_internal = this; } -int DbTxn::abort() +DbTxn::~DbTxn() { - int err; - DB_TXN *txn; - - txn = unwrap(this); - err = txn_abort(txn); - - // It may seem weird to delete this, but is legal as long - // as we don't access any of its data before returning. - // - delete this; - - if (err != 0) - DB_ERROR("DbTxn::abort", err, ON_ERROR_UNKNOWN); - - return (err); } -int DbTxn::commit(u_int32_t flags) -{ - int err; - DB_TXN *txn; - - txn = unwrap(this); - err = txn_commit(txn, flags); - - // It may seem weird to delete this, but is legal as long - // as we don't access any of its data before returning. - // - delete this; - - if (err != 0) - DB_ERROR("DbTxn::commit", err, ON_ERROR_UNKNOWN); - - return (err); -} +DBTXN_METHOD(abort, 1, (), (txn)) +DBTXN_METHOD(commit, 1, (u_int32_t flags), (txn, flags)) +DBTXN_METHOD(discard, 1, (u_int32_t flags), (txn, flags)) u_int32_t DbTxn::id() { DB_TXN *txn; txn = unwrap(this); - return (txn_id(txn)); // no error + return (txn->id(txn)); // no error } -int DbTxn::prepare() -{ - int err; - DB_TXN *txn; +DBTXN_METHOD(prepare, 0, (u_int8_t *gid), (txn, gid)) +DBTXN_METHOD(set_timeout, 0, (db_timeout_t timeout, u_int32_t flags), + (txn, timeout, flags)) - txn = unwrap(this); - if ((err = txn_prepare(txn)) != 0) { - DB_ERROR("DbTxn::prepare", err, ON_ERROR_UNKNOWN); - return (err); - } - return (0); +// static method +DbTxn *DbTxn::wrap_DB_TXN(DB_TXN *txn) +{ + DbTxn *wrapped_txn = get_DbTxn(txn); + if (wrapped_txn == NULL) + wrapped_txn = new DbTxn(txn); + return wrapped_txn; } diff --git a/bdb/cxx/namemap.txt b/bdb/cxx/namemap.txt deleted file mode 100644 index 75207718577..00000000000 --- a/bdb/cxx/namemap.txt +++ /dev/null @@ -1,21 +0,0 @@ -$Id: namemap.txt,v 10.4 2000/02/19 20:57:54 bostic Exp $ - -The bulk of DB provides for wrapper classes and appropriately named methods -that call into DB. For the most part, there is a straightforward mapping of -names. For the purposes of referencing documentation, this chart shows the -underlying C structure name for each C++ class. In some cases, using the -given C prefix with a C++ method name gives the underlying C function name. -For example, DbMpoolFile::close() is implemented by memp_fclose(). - -C++ C C prefix - -Db DB -DbEnv DB_ENV -Dbc DBC -DbException none -DbInfo DB_INFO -DbLock DB_LOCK lock_ -DbLsn DB_LSN -DbMpoolFile DB_MPOOL_FILE memp_ -Dbt DBT -DbTxn DB_TXN txn_ -- cgit v1.2.1