зеркало из https://github.com/mozilla/gecko-dev.git
257 строки
6.8 KiB
C++
257 строки
6.8 KiB
C++
/*-
|
|
* See the file LICENSE for redistribution information.
|
|
*
|
|
* Copyright (c) 1997, 1998
|
|
* Sleepycat Software. All rights reserved.
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#ifndef lint
|
|
static const char sccsid[] = "@(#)cxx_app.cpp 10.14 (Sleepycat) 4/10/98";
|
|
#endif /* not lint */
|
|
|
|
#include "db_cxx.h"
|
|
#include "cxx_int.h"
|
|
|
|
#include <string.h>
|
|
#include <iostream.h>
|
|
#include <fstream.h>
|
|
#include <stdio.h> // needed for setErrorStream
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
// //
|
|
// DbEnv //
|
|
// //
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
static DbEnv *currentApp = 0;
|
|
|
|
ostream *DbEnv::error_stream_ = 0;
|
|
|
|
DbEnv::DbEnv(const char *homeDir, char *const *db_config, u_int32_t flags_arg)
|
|
: error_model_(Exception)
|
|
{
|
|
DB_ENV *env = this;
|
|
memset(env, 0, sizeof(DB_ENV));
|
|
|
|
int err;
|
|
|
|
if ((err = db_appinit(homeDir, db_config, env, flags_arg)) != 0) {
|
|
DB_ERROR("DbEnv::DbEnv", err);
|
|
}
|
|
currentApp = this;
|
|
}
|
|
|
|
DbEnv::DbEnv()
|
|
: error_model_(Exception)
|
|
{
|
|
DB_ENV *env = this;
|
|
memset(env, 0, sizeof(DB_ENV));
|
|
}
|
|
|
|
DbEnv::~DbEnv()
|
|
{
|
|
if (currentApp == this)
|
|
currentApp = 0;
|
|
DB_ENV *env = this;
|
|
|
|
// having a zeroed environment is a signal that
|
|
// appexit() has already been done.
|
|
//
|
|
DB_ENV zeroed;
|
|
memset(&zeroed, 0, sizeof(DB_ENV));
|
|
if (memcmp(&zeroed, env, sizeof(DB_ENV)) != 0) {
|
|
(void)appexit(); // ignore error return
|
|
}
|
|
}
|
|
|
|
int DbEnv::appinit(const char *homeDir, char *const *db_config, u_int32_t flags_arg)
|
|
{
|
|
DB_ENV *env = this;
|
|
|
|
int err;
|
|
|
|
if ((err = db_appinit(homeDir, db_config, env, flags_arg)) != 0) {
|
|
DB_ERROR("DbEnv::appinit", err);
|
|
}
|
|
currentApp = this;
|
|
return err;
|
|
}
|
|
|
|
int DbEnv::appexit()
|
|
{
|
|
DB_ENV *env = this;
|
|
|
|
int err;
|
|
|
|
if ((err = db_appexit(env)) != 0) {
|
|
DB_ERROR("DbEnv::appexit", err);
|
|
}
|
|
memset(env, 0, sizeof(DB_ENV));
|
|
currentApp = 0;
|
|
return err;
|
|
}
|
|
|
|
void DbEnv::set_error_model(ErrorModel model)
|
|
{
|
|
error_model_ = model;
|
|
}
|
|
|
|
int DbEnv::runtime_error(const char *caller, int err, int in_destructor)
|
|
{
|
|
int throwit = (!currentApp ||
|
|
(currentApp && currentApp->error_model_ == Exception));
|
|
|
|
if (throwit && !in_destructor) {
|
|
throw DbException(caller, err);
|
|
}
|
|
return err;
|
|
}
|
|
|
|
// 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(class ostream *stream)
|
|
{
|
|
error_stream_ = stream;
|
|
|
|
db_errcall = stream_error_function;
|
|
}
|
|
|
|
ostream *DbEnv::get_error_stream() const
|
|
{
|
|
return error_stream_;
|
|
}
|
|
|
|
void DbEnv::stream_error_function(const char *prefix, char *message)
|
|
{
|
|
if (error_stream_) {
|
|
if (prefix) {
|
|
(*error_stream_) << prefix << ": ";
|
|
}
|
|
if (message) {
|
|
(*error_stream_) << message;
|
|
}
|
|
(*error_stream_) << "\n";
|
|
}
|
|
}
|
|
|
|
DB_RW_ACCESS(DbEnv, int, lorder, db_lorder)
|
|
DB_RW_ACCESS(DbEnv, DbEnv::db_errcall_fcn, errcall, db_errcall)
|
|
DB_RW_ACCESS(DbEnv, FILE *, errfile, db_errfile)
|
|
DB_RW_ACCESS(DbEnv, const char *, errpfx, db_errpfx)
|
|
DB_RW_ACCESS(DbEnv, int, verbose, db_verbose)
|
|
DB_RW_ACCESS(DbEnv, char *, home, db_home)
|
|
DB_RW_ACCESS(DbEnv, char *, log_dir, db_log_dir)
|
|
DB_RW_ACCESS(DbEnv, char *, tmp_dir, db_tmp_dir)
|
|
DB_RW_ACCESS(DbEnv, char **, data_dir, db_data_dir)
|
|
DB_RW_ACCESS(DbEnv, int, data_cnt, data_cnt)
|
|
DB_RW_ACCESS(DbEnv, int, data_next, data_next)
|
|
DB_RW_ACCESS(DbEnv, u_int8_t *, lk_conflicts, lk_conflicts)
|
|
DB_RW_ACCESS(DbEnv, int, lk_modes, lk_modes)
|
|
DB_RW_ACCESS(DbEnv, unsigned int, lk_max, lk_max)
|
|
DB_RW_ACCESS(DbEnv, u_int32_t, lk_detect, lk_detect)
|
|
DB_RW_ACCESS(DbEnv, u_int32_t, lg_max, lg_max)
|
|
DB_RW_ACCESS(DbEnv, size_t, mp_mmapsize, mp_mmapsize)
|
|
DB_RW_ACCESS(DbEnv, size_t, mp_size, mp_size)
|
|
DB_RW_ACCESS(DbEnv, unsigned int, tx_max, tx_max)
|
|
DB_RW_ACCESS(DbEnv, DbEnv::tx_recover_fcn, tx_recover, tx_recover)
|
|
DB_RW_ACCESS(DbEnv, u_int32_t, flags, flags)
|
|
|
|
// These access methods require construction of
|
|
// wrapper options DB_FOO* to DbFoo* .
|
|
//
|
|
|
|
DbLockTab *DbEnv::get_lk_info() const
|
|
{
|
|
if (!lk_info)
|
|
return 0;
|
|
DbLockTab *result = new DbLockTab();
|
|
result->imp_ = wrap(lk_info);
|
|
return result;
|
|
}
|
|
|
|
DbLog *DbEnv::get_lg_info() const
|
|
{
|
|
if (!lg_info)
|
|
return 0;
|
|
DbLog *result = new DbLog();
|
|
result->imp_ = wrap(lg_info);
|
|
return result;
|
|
}
|
|
|
|
DbMpool *DbEnv::get_mp_info() const
|
|
{
|
|
if (!mp_info)
|
|
return 0;
|
|
DbMpool *result = new DbMpool();
|
|
result->imp_ = wrap(mp_info);
|
|
return result;
|
|
}
|
|
|
|
DbTxnMgr *DbEnv::get_tx_info() const
|
|
{
|
|
if (!tx_info)
|
|
return 0;
|
|
DbTxnMgr *result = new DbTxnMgr();
|
|
result->imp_ = wrap(tx_info);
|
|
return result;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
// //
|
|
// DbInfo //
|
|
// //
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
// Note: in theory, the db_home and db_*_dir fields will always be zero
|
|
// when managed by DbInfo. That's because they are set by
|
|
// db_appinit, not by the user, and we make a copy of the db_env used by
|
|
// the application.
|
|
//
|
|
|
|
DbInfo::DbInfo()
|
|
{
|
|
DB_INFO *info = this;
|
|
memset(info, 0, sizeof(DB_INFO));
|
|
}
|
|
|
|
DbInfo::~DbInfo()
|
|
{
|
|
}
|
|
|
|
DbInfo::DbInfo(const DbInfo &that)
|
|
{
|
|
DB_INFO *to = this;
|
|
const DB_INFO *from = &that;
|
|
memcpy(to, from, sizeof(DB_INFO));
|
|
}
|
|
|
|
DbInfo &DbInfo::operator = (const DbInfo &that)
|
|
{
|
|
DB_INFO *to = this;
|
|
const DB_INFO *from = &that;
|
|
memcpy(to, from, sizeof(DB_INFO));
|
|
return *this;
|
|
}
|
|
|
|
DB_RW_ACCESS(DbInfo, int, lorder, db_lorder)
|
|
DB_RW_ACCESS(DbInfo, size_t, cachesize, db_cachesize)
|
|
DB_RW_ACCESS(DbInfo, size_t, pagesize, db_pagesize)
|
|
DB_RW_ACCESS(DbInfo, DbInfo::db_malloc_fcn, malloc, db_malloc)
|
|
DB_RW_ACCESS(DbInfo, int, bt_maxkey, bt_maxkey)
|
|
DB_RW_ACCESS(DbInfo, int, bt_minkey, bt_minkey)
|
|
DB_RW_ACCESS(DbInfo, DbInfo::bt_compare_fcn, bt_compare, bt_compare)
|
|
DB_RW_ACCESS(DbInfo, DbInfo::bt_prefix_fcn, bt_prefix, bt_prefix)
|
|
DB_RW_ACCESS(DbInfo, unsigned int, h_ffactor, h_ffactor)
|
|
DB_RW_ACCESS(DbInfo, unsigned int, h_nelem, h_nelem)
|
|
DB_RW_ACCESS(DbInfo, DbInfo::h_hash_fcn, h_hash, h_hash)
|
|
DB_RW_ACCESS(DbInfo, int, re_pad, re_pad)
|
|
DB_RW_ACCESS(DbInfo, int, re_delim, re_delim)
|
|
DB_RW_ACCESS(DbInfo, u_int32_t, re_len, re_len)
|
|
DB_RW_ACCESS(DbInfo, char *, re_source, re_source)
|
|
DB_RW_ACCESS(DbInfo, u_int32_t, flags, flags)
|