summaryrefslogtreecommitdiff
path: root/bdb/cxx
diff options
context:
space:
mode:
authorunknown <ram@mysql.r18.ru>2002-10-30 15:57:05 +0400
committerunknown <ram@mysql.r18.ru>2002-10-30 15:57:05 +0400
commit155e78f014de1a2e259ae5119f4621fbb210a784 (patch)
tree6881a3cca88bea0bb9eeffd5aae34be437152786 /bdb/cxx
parentb8798d25ab71436bf690ee8ae48285a655c5487e (diff)
downloadmariadb-git-155e78f014de1a2e259ae5119f4621fbb210a784.tar.gz
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
Diffstat (limited to 'bdb/cxx')
-rw-r--r--bdb/cxx/cxx_app.cpp671
-rw-r--r--bdb/cxx/cxx_db.cpp605
-rw-r--r--bdb/cxx/cxx_dbc.cpp115
-rw-r--r--bdb/cxx/cxx_dbt.cpp61
-rw-r--r--bdb/cxx/cxx_env.cpp802
-rw-r--r--bdb/cxx/cxx_except.cpp254
-rw-r--r--bdb/cxx/cxx_lock.cpp86
-rw-r--r--bdb/cxx/cxx_log.cpp125
-rw-r--r--bdb/cxx/cxx_logc.cpp65
-rw-r--r--bdb/cxx/cxx_mpool.cpp208
-rw-r--r--bdb/cxx/cxx_table.cpp808
-rw-r--r--bdb/cxx/cxx_txn.cpp143
-rw-r--r--bdb/cxx/namemap.txt21
13 files changed, 1990 insertions, 1974 deletions
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 <errno.h>
-#include <stdio.h> // needed for set_error_stream
-#include <string.h>
-
-#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 <errno.h>
+#include <string.h>
+
+#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 <errno.h>
+#include <string.h>
+
+#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 <errno.h>
+#include <string.h>
+
+#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 <errno.h>
+#include <stdio.h> // needed for set_error_stream
+#include <string.h>
+
+#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 <string.h>
+#include <errno.h>
#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 <errno.h>
#include <string.h>
#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 <errno.h>
-
-#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 <errno.h>
+#include <string.h>
+
+#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 <errno.h>
#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 <errno.h>
-#include <string.h>
-
-#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 <errno.h>
#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_