2007-12-18 16:22:21 +00:00
# include <assert.h>
# include <db.h>
# include <errno.h>
2007-12-18 20:39:02 +00:00
# include <db_cxx.h>
2007-12-18 01:31:34 +00:00
2007-12-20 23:47:44 +00:00
# define do_maybe_error(errno)
2007-12-18 16:34:48 +00:00
Db : : Db ( DbEnv * env , u_int32_t flags )
: the_Env ( env )
{
2007-12-18 16:22:21 +00:00
the_db = 0 ;
2007-12-18 16:34:48 +00:00
2007-12-18 20:39:02 +00:00
is_private_env = ( the_Env = = 0 ) ;
2007-12-18 16:22:21 +00:00
DB * tmp_db ;
2007-12-23 01:09:09 +00:00
int ret = db_create ( & tmp_db , the_Env - > get_DB_ENV ( ) , flags & ~ ( DB_CXX_NO_EXCEPTIONS ) ) ;
2007-12-18 16:22:21 +00:00
if ( ret ! = 0 ) {
2007-12-20 23:47:44 +00:00
the_Env - > maybe_throw_error ( ret ) ;
// Otherwise cannot do much
return ;
2007-12-18 16:22:21 +00:00
}
the_db = tmp_db ;
tmp_db - > api_internal = this ;
if ( is_private_env ) {
the_Env = new DbEnv ( tmp_db - > dbenv , flags & DB_CXX_NO_EXCEPTIONS ) ;
}
}
2007-12-18 01:31:34 +00:00
Db : : ~ Db ( ) {
2007-12-21 19:59:31 +00:00
if ( the_db ) {
2007-12-18 01:52:52 +00:00
close ( 0 ) ; // the user should have called close, but we do it here if not done.
2007-12-21 19:59:31 +00:00
assert ( the_db = = 0 ) ;
2007-12-18 01:31:34 +00:00
}
2007-12-29 16:27:50 +00:00
if ( is_private_env & & the_Env ) {
the_Env - > close ( 0 ) ;
delete the_Env ;
}
2007-12-18 01:31:34 +00:00
}
2007-12-30 14:47:13 +00:00
int Db : : set_flags ( u_int32_t flags ) {
int ret = the_db - > set_flags ( the_db , flags ) ;
return the_Env - > maybe_throw_error ( ret ) ;
}
2007-12-18 01:52:52 +00:00
int Db : : close ( u_int32_t flags ) {
2007-12-18 01:31:34 +00:00
if ( ! the_db ) {
2007-12-20 23:47:44 +00:00
return the_Env - > maybe_throw_error ( EINVAL ) ;
2007-12-18 01:31:34 +00:00
}
2007-12-18 16:22:21 +00:00
the_db - > api_internal = 0 ;
2007-12-18 01:52:52 +00:00
2007-12-21 19:59:31 +00:00
2007-12-18 16:22:21 +00:00
int ret = the_db - > close ( the_db , flags ) ;
2007-12-18 01:31:34 +00:00
2007-12-18 01:52:52 +00:00
the_db = 0 ;
2007-12-21 19:59:31 +00:00
int no_exceptions = the_Env - > do_no_exceptions ; // Get this out before possibly deleting the env
if ( is_private_env ) {
// The env was closed by the_db->close, we have to tell the DbEnv that the DB_ENV is gone, and delete it.
the_Env - > the_env = 0 ;
delete the_Env ;
the_Env = 0 ;
}
2007-12-18 01:31:34 +00:00
// Do we need to clean up "private environments"?
2007-12-18 16:22:21 +00:00
// What about cursors? They should be cleaned up already, but who did it?
2007-12-21 19:59:31 +00:00
// This maybe_throw must be the static one because the env is gone.
return DbEnv : : maybe_throw_error ( ret , NULL , no_exceptions ) ;
2007-12-18 16:22:21 +00:00
}
int Db : : open ( DbTxn * txn , const char * filename , const char * subname , DBTYPE typ , u_int32_t flags , int mode ) {
int ret = the_db - > open ( the_db , txn - > get_DB_TXN ( ) , filename , subname , typ , flags , mode ) ;
2007-12-20 23:47:44 +00:00
return the_Env - > maybe_throw_error ( ret ) ;
2007-12-18 16:22:21 +00:00
}
2007-12-18 01:31:34 +00:00
2007-12-23 01:25:54 +00:00
int Db : : del ( DbTxn * txn , Dbt * key , u_int32_t flags ) {
int ret = the_db - > del ( the_db , txn - > get_DB_TXN ( ) , key - > get_DBT ( ) , flags ) ;
return the_Env - > maybe_throw_error ( ret ) ;
}
int Db : : get ( DbTxn * txn , Dbt * key , Dbt * data , u_int32_t flags ) {
int ret = the_db - > get ( the_db , txn - > get_DB_TXN ( ) , key - > get_DBT ( ) , data - > get_DBT ( ) , flags ) ;
return the_Env - > maybe_throw_error ( ret ) ;
}
2007-12-18 16:22:21 +00:00
int Db : : put ( DbTxn * txn , Dbt * key , Dbt * data , u_int32_t flags ) {
int ret = the_db - > put ( the_db , txn - > get_DB_TXN ( ) , key - > get_DBT ( ) , data - > get_DBT ( ) , flags ) ;
2007-12-20 23:47:44 +00:00
return the_Env - > maybe_throw_error ( ret ) ;
2007-12-18 01:31:34 +00:00
}
2007-12-18 16:22:21 +00:00
2007-12-18 18:34:44 +00:00
int Db : : cursor ( DbTxn * txn , Dbc * * cursorp , u_int32_t flags ) {
int ret = the_db - > cursor ( the_db , txn - > get_DB_TXN ( ) , ( DBC * * ) cursorp , flags ) ;
2007-12-20 23:47:44 +00:00
return the_Env - > maybe_throw_error ( ret ) ;
2007-12-18 18:34:44 +00:00
}
2007-12-20 19:00:35 +00:00
2007-12-18 19:37:59 +00:00
int Db : : set_pagesize ( u_int32_t size ) {
int ret = the_db - > set_pagesize ( the_db , size ) ;
2007-12-20 23:47:44 +00:00
return the_Env - > maybe_throw_error ( ret ) ;
2007-12-18 19:37:59 +00:00
}
2007-12-18 18:34:44 +00:00
2007-12-20 19:00:35 +00:00
int Db : : remove ( const char * file , const char * database , u_int32_t flags ) {
int ret = the_db - > remove ( the_db , file , database , flags ) ;
2007-12-21 19:59:31 +00:00
the_db = 0 ;
2007-12-20 23:47:44 +00:00
return the_Env - > maybe_throw_error ( ret ) ;
2007-12-20 19:00:35 +00:00
}
int Db : : set_bt_compare ( bt_compare_fcn_type bt_compare_fcn ) {
int ret = the_db - > set_bt_compare ( the_db , bt_compare_fcn ) ;
2007-12-20 23:47:44 +00:00
return the_Env - > maybe_throw_error ( ret ) ;
2007-12-20 19:00:35 +00:00
}
2007-12-27 22:10:59 +00:00
2007-12-28 17:39:49 +00:00
// Q: How to convert callback types in the most simple way?
// A: (Bradley) I see three ways to do this: The issue is that we have a C++ callback function, and we want to pass it to a C function.
// The fastest way is wrong: You cannot just pass the C++ function pointer since you cannot mix function pointers to C and C++.
// The "right" way is to declare an "extern C" function and do all the conversions. Create a Dbt from a DBT, and then call the C function. For returned data we would have do something too. But it turns out that DBT and Dbt pointers are interchangable so that leads to
// The "fast" way. Declare an "extern C" function, and then use Dbt::get_const_Dbt() to do the conversion quickly.
extern " C " int associate_callback_c ( DB * db_c , const DBT * k , const DBT * d , DBT * result ) {
assert ( db_c ! = 0 ) ;
Db * db_cxx = Db : : get_Db ( db_c ) ;
assert ( db_cxx ) ;
return ( * db_cxx - > associate_callback_cxx ) ( db_cxx , Dbt : : get_const_Dbt ( k ) , Dbt : : get_const_Dbt ( d ) , Dbt : : get_Dbt ( result ) ) ;
2007-12-27 22:30:29 +00:00
}
2007-12-27 22:10:59 +00:00
int Db : : associate ( DbTxn * txnid , Db * secondary , int ( * callback ) ( Db * secondary , const Dbt * key , const Dbt * data , Dbt * result ) , u_int32_t flags ) {
2007-12-27 22:30:29 +00:00
// secondary->set_associate_callback(callback);
2007-12-28 17:39:49 +00:00
secondary - > associate_callback_cxx = callback ;
int ret = the_db - > associate ( the_db , txnid - > get_DB_TXN ( ) , secondary - > get_DB ( ) , associate_callback_c , flags ) ;
2007-12-27 22:10:59 +00:00
return the_Env - > maybe_throw_error ( ret ) ;
}