1406 lines
41 KiB
C
1406 lines
41 KiB
C
#include "bdb.h"
|
|
|
|
static s48_value scheme_DB_VERSION = S48_FALSE;
|
|
static s48_value scheme_DB_VERSION_VERBOSE = S48_FALSE;
|
|
|
|
/* initialise flag constants */
|
|
static s48_value scheme_DB_RPCCLIENT = S48_FALSE;
|
|
static s48_value scheme_DB_INIT_LOCK = S48_FALSE;
|
|
static s48_value scheme_DB_JOINENV = S48_FALSE;
|
|
static s48_value scheme_DB_INIT_MPOOL = S48_FALSE;
|
|
static s48_value scheme_DB_INIT_LOG = S48_FALSE;
|
|
static s48_value scheme_DB_INIT_REP = S48_FALSE;
|
|
static s48_value scheme_DB_INIT_TXN = S48_FALSE;
|
|
static s48_value scheme_DB_RECOVER = S48_FALSE;
|
|
static s48_value scheme_DB_RECOVER_FATAL = S48_FALSE;
|
|
static s48_value scheme_DB_USE_ENVIRON = S48_FALSE;
|
|
static s48_value scheme_DB_USE_ENVIRON_ROOT = S48_FALSE;
|
|
static s48_value scheme_DB_CREATE = S48_FALSE;
|
|
static s48_value scheme_DB_LOCKDOWN = S48_FALSE;
|
|
static s48_value scheme_DB_PRIVATE = S48_FALSE;
|
|
static s48_value scheme_DB_SYSTEM_MEM = S48_FALSE;
|
|
static s48_value scheme_DB_THREAD = S48_FALSE;
|
|
static s48_value scheme_DB_XA_CREATE = S48_FALSE;
|
|
static s48_value scheme_DB_AUTO_COMMIT = S48_FALSE;
|
|
static s48_value scheme_DB_DIRTY_READ = S48_FALSE;
|
|
static s48_value scheme_DB_EXCL = S48_FALSE;
|
|
static s48_value scheme_DB_NOMMAP = S48_FALSE;
|
|
static s48_value scheme_DB_RDONLY = S48_FALSE;
|
|
static s48_value scheme_DB_TRUNCATE = S48_FALSE;
|
|
static s48_value scheme_DB_NOSYNC = S48_FALSE;
|
|
static s48_value scheme_DB_CONSUME = S48_FALSE;
|
|
static s48_value scheme_DB_CONSUME_WAIT = S48_FALSE;
|
|
static s48_value scheme_DB_GET_BOTH = S48_FALSE;
|
|
static s48_value scheme_DB_RMW = S48_FALSE;
|
|
static s48_value scheme_DB_MULTIPLE = S48_FALSE;
|
|
static s48_value scheme_DB_SET_RECNO = S48_FALSE;
|
|
static s48_value scheme_DB_APPEND = S48_FALSE;
|
|
static s48_value scheme_DB_NODUPDATA = S48_FALSE;
|
|
static s48_value scheme_DB_NOOVERWRITE = S48_FALSE;
|
|
static s48_value scheme_DB_CURRENT = S48_FALSE;
|
|
static s48_value scheme_DB_FIRST = S48_FALSE;
|
|
static s48_value scheme_DB_WRITECURSOR = S48_FALSE;
|
|
static s48_value scheme_DB_GET_BOTH_RANGE = S48_FALSE;
|
|
static s48_value scheme_DB_GET_RECNO = S48_FALSE;
|
|
static s48_value scheme_DB_JOIN_ITEM = S48_FALSE;
|
|
static s48_value scheme_DB_LAST = S48_FALSE;
|
|
static s48_value scheme_DB_NEXT = S48_FALSE;
|
|
static s48_value scheme_DB_NEXT_DUP = S48_FALSE;
|
|
static s48_value scheme_DB_NEXT_NODUP = S48_FALSE;
|
|
static s48_value scheme_DB_PREV = S48_FALSE;
|
|
static s48_value scheme_DB_SET = S48_FALSE;
|
|
static s48_value scheme_DB_SET_RANGE = S48_FALSE;
|
|
static s48_value scheme_DB_MULTIPLE_KEY = S48_FALSE;
|
|
static s48_value scheme_DB_TXN_NOSYNC = S48_FALSE;
|
|
static s48_value scheme_DB_TXN_NOWAIT = S48_FALSE;
|
|
static s48_value scheme_DB_TXN_SYNC = S48_FALSE;
|
|
static s48_value scheme_DB_DONOTINDEX = S48_FALSE;
|
|
static s48_value scheme_DB_FILEOPEN = S48_FALSE;
|
|
static s48_value scheme_DB_KEYEMPTY = S48_FALSE;
|
|
static s48_value scheme_DB_KEYEXIST = S48_FALSE;
|
|
static s48_value scheme_DB_LOCK_DEADLOCK = S48_FALSE;
|
|
static s48_value scheme_DB_LOCK_NOTGRANTED = S48_FALSE;
|
|
static s48_value scheme_DB_NOSERVER = S48_FALSE;
|
|
static s48_value scheme_DB_NOSERVER_HOME = S48_FALSE;
|
|
static s48_value scheme_DB_NOSERVER_ID = S48_FALSE;
|
|
static s48_value scheme_DB_NOTFOUND = S48_FALSE;
|
|
static s48_value scheme_DB_OLD_VERSION = S48_FALSE;
|
|
static s48_value scheme_DB_PAGE_NOTFOUND = S48_FALSE;
|
|
static s48_value scheme_DB_REP_DUPMASTER = S48_FALSE;
|
|
static s48_value scheme_DB_REP_HANDLE_DEAD = S48_FALSE;
|
|
static s48_value scheme_DB_REP_HOLDELECTION = S48_FALSE;
|
|
static s48_value scheme_DB_REP_ISPERM = S48_FALSE;
|
|
static s48_value scheme_DB_REP_NEWMASTER = S48_FALSE;
|
|
static s48_value scheme_DB_REP_NEWSITE = S48_FALSE;
|
|
static s48_value scheme_DB_REP_NOTPERM = S48_FALSE;
|
|
static s48_value scheme_DB_REP_OUTDATED = S48_FALSE;
|
|
static s48_value scheme_DB_REP_UNAVAIL = S48_FALSE;
|
|
static s48_value scheme_DB_RUNRECOVERY = S48_FALSE;
|
|
static s48_value scheme_DB_SECONDARY_BAD = S48_FALSE;
|
|
static s48_value scheme_DB_VERIFY_BAD = S48_FALSE;
|
|
static s48_value scheme_DB_LOCK_NOWAIT = S48_FALSE;
|
|
static s48_value scheme_DB_ENCRYPT_AES = S48_FALSE;
|
|
static s48_value scheme_DB_CDB_ALLDB = S48_FALSE;
|
|
static s48_value scheme_DB_DIRECT_DB = S48_FALSE;
|
|
static s48_value scheme_DB_DIRECT_LOG = S48_FALSE;
|
|
static s48_value scheme_DB_LOG_AUTOREMOVE = S48_FALSE;
|
|
static s48_value scheme_DB_NOLOCKING = S48_FALSE;
|
|
static s48_value scheme_DB_NOPANIC = S48_FALSE;
|
|
static s48_value scheme_DB_OVERWRITE = S48_FALSE;
|
|
static s48_value scheme_DB_PANIC_ENVIRONMENT = S48_FALSE;
|
|
static s48_value scheme_DB_REGION_INIT = S48_FALSE;
|
|
static s48_value scheme_DB_TIME_NOTGRANTED = S48_FALSE;
|
|
static s48_value scheme_DB_TXN_NOT_DURABLE = S48_FALSE;
|
|
static s48_value scheme_DB_TXN_WRITE_NOSYNC = S48_FALSE;
|
|
static s48_value scheme_DB_FORCE = S48_FALSE;
|
|
static s48_value scheme_DB_CHKSUM = S48_FALSE;
|
|
static s48_value scheme_DB_ENCRYPT = S48_FALSE;
|
|
static s48_value scheme_DB_DUP = S48_FALSE;
|
|
static s48_value scheme_DB_DUPSORT = S48_FALSE;
|
|
static s48_value scheme_DB_RECNUM = S48_FALSE;
|
|
static s48_value scheme_DB_REVSPLITOFF = S48_FALSE;
|
|
static s48_value scheme_DB_RENUMBER = S48_FALSE;
|
|
static s48_value scheme_DB_SNAPSHOT = S48_FALSE;
|
|
static s48_value scheme_DB_PREV_NODUP = S48_FALSE;
|
|
static s48_value scheme_DB_AFTER = S48_FALSE;
|
|
static s48_value scheme_DB_BEFORE = S48_FALSE;
|
|
static s48_value scheme_DB_KEYFIRST = S48_FALSE;
|
|
static s48_value scheme_DB_KEYLAST = S48_FALSE;
|
|
|
|
|
|
/* initialise DB_TYPES */
|
|
static s48_value scheme_DB_BTREE = S48_FALSE;
|
|
static s48_value scheme_DB_HASH = S48_FALSE;
|
|
static s48_value scheme_DB_QUEUE = S48_FALSE;
|
|
static s48_value scheme_DB_RECNO = S48_FALSE;
|
|
static s48_value scheme_DB_UNKNOWN = S48_FALSE;
|
|
|
|
/* lock types */
|
|
static s48_value scheme_DB_LOCK_READ = S48_FALSE;
|
|
static s48_value scheme_DB_LOCK_WRITE = S48_FALSE;
|
|
static s48_value scheme_DB_LOCK_IWRITE = S48_FALSE;
|
|
static s48_value scheme_DB_LOCK_IREAD = S48_FALSE;
|
|
static s48_value scheme_DB_LOCK_IWR = S48_FALSE;
|
|
|
|
s48_value scsh_enter_db(DB *h)
|
|
{
|
|
s48_value rec = S48_FALSE;
|
|
|
|
S48_DECLARE_GC_PROTECT(1);
|
|
S48_GC_PROTECT_1(rec);
|
|
|
|
rec = s48_make_record(bdb_db_record_type);
|
|
S48_RECORD_SET(rec, 0, s48_enter_integer((long) h));
|
|
|
|
S48_GC_UNPROTECT();
|
|
return rec;
|
|
}
|
|
|
|
s48_value scsh_enter_lock(DB_LOCK *l)
|
|
{
|
|
s48_value rec = S48_FALSE;
|
|
S48_DECLARE_GC_PROTECT(1);
|
|
|
|
S48_GC_PROTECT_1(rec);
|
|
rec = s48_make_record(bdb_lock_record_type);
|
|
S48_RECORD_SET(rec, 0, s48_enter_integer((long) l));
|
|
S48_GC_UNPROTECT();
|
|
return rec;
|
|
}
|
|
|
|
s48_value scsh_enter_txnid(DB_TXN *txnid)
|
|
{
|
|
s48_value rec = S48_FALSE;
|
|
|
|
S48_DECLARE_GC_PROTECT(1);
|
|
S48_GC_PROTECT_1(rec);
|
|
|
|
rec = s48_make_record(bdb_txn_record_type);
|
|
S48_RECORD_SET(rec, 0, s48_enter_integer((long) txnid));
|
|
|
|
S48_GC_UNPROTECT();
|
|
return rec;
|
|
}
|
|
|
|
s48_value scsh_enter_cursor(DBC *dbc)
|
|
{
|
|
s48_value rec = S48_FALSE;
|
|
|
|
S48_DECLARE_GC_PROTECT(1);
|
|
S48_GC_PROTECT_1(rec);
|
|
|
|
rec = s48_make_record(bdb_dbc_record_type);
|
|
S48_RECORD_SET(rec, 0, s48_enter_integer((long) dbc));
|
|
|
|
S48_GC_UNPROTECT();
|
|
return rec;
|
|
}
|
|
|
|
s48_value scsh_enter_dbenv(DB_ENV *h)
|
|
{
|
|
s48_value rec = S48_FALSE;
|
|
|
|
S48_DECLARE_GC_PROTECT(1);
|
|
S48_GC_PROTECT_1(rec);
|
|
|
|
rec = s48_make_record(bdb_env_record_type);
|
|
S48_RECORD_SET(rec, 0, s48_enter_integer((long) h));
|
|
|
|
S48_GC_UNPROTECT();
|
|
return rec;
|
|
}
|
|
|
|
/* convert null-terminated array of strings to a list of Scheme strings */
|
|
s48_value scsh_enter_string_array(const char **array)
|
|
{
|
|
int i;
|
|
s48_value res = S48_NULL;
|
|
S48_DECLARE_GC_PROTECT(1);
|
|
|
|
S48_GC_PROTECT_1(res);
|
|
if (array == NULL) {
|
|
S48_GC_UNPROTECT();
|
|
return S48_NULL;
|
|
}
|
|
for (i = 0; array[i] != NULL; i++)
|
|
res = s48_cons(s48_enter_string(array[i]), res);
|
|
S48_GC_UNPROTECT();
|
|
return res;
|
|
}
|
|
|
|
|
|
/* BDB operations */
|
|
|
|
/* database environment */
|
|
|
|
/* create an environment handle */
|
|
s48_value scsh_bdb_env_create(s48_value sflags)
|
|
{
|
|
|
|
DB_ENV *dbenv;
|
|
int res;
|
|
u_int32_t flags = S48_FALSE;
|
|
|
|
S48_DECLARE_GC_PROTECT(1);
|
|
S48_GC_PROTECT_1(sflags);
|
|
flags = s48_extract_integer(sflags);
|
|
S48_GC_UNPROTECT();
|
|
|
|
res = db_env_create(&dbenv, flags);
|
|
|
|
CHECK_BDB_RESULT_CODE(res);
|
|
return scsh_enter_dbenv(dbenv);
|
|
}
|
|
|
|
/* close an environment */
|
|
s48_value scsh_bdb_env_close(s48_value env)
|
|
{
|
|
int res;
|
|
DB_ENV *dbenv;
|
|
S48_DECLARE_GC_PROTECT(1);
|
|
|
|
S48_GC_PROTECT_1(env);
|
|
|
|
dbenv = scsh_extract_dbenv(env);
|
|
S48_GC_UNPROTECT();
|
|
|
|
res = dbenv->close(dbenv, 0);
|
|
CHECK_BDB_RESULT_CODE(res);
|
|
return S48_FALSE;
|
|
}
|
|
|
|
/* acquire a locker id */
|
|
s48_value scsh_bdb_env_lock_id(s48_value senv_handle)
|
|
{
|
|
DB_ENV *dbenv;
|
|
int res;
|
|
u_int32_t idp = 0;
|
|
|
|
dbenv = scsh_extract_dbenv(senv_handle);
|
|
res = dbenv->lock_id(dbenv, &idp);
|
|
if (res > 0)
|
|
s48_raise_os_error(res);
|
|
return s48_list_2(s48_enter_integer(res),
|
|
(res == 0) ? s48_enter_integer((long) idp) : S48_FALSE);
|
|
}
|
|
|
|
/* release a locker id */
|
|
s48_value scsh_bdb_env_lock_id_free(s48_value senv_handle, s48_value slocker_id)
|
|
{
|
|
DB_ENV *dbenv;
|
|
int res;
|
|
u_int32_t locker_id;
|
|
S48_DECLARE_GC_PROTECT(2);
|
|
|
|
S48_GC_PROTECT_2(senv_handle, slocker_id);
|
|
dbenv = scsh_extract_dbenv(senv_handle);
|
|
locker_id = s48_extract_integer(slocker_id);
|
|
S48_GC_UNPROTECT();
|
|
res = dbenv->lock_id_free(dbenv, locker_id);
|
|
CHECK_BDB_RESULT_CODE(res);
|
|
return S48_FALSE;
|
|
}
|
|
|
|
/* acquire a lock */
|
|
s48_value scsh_bdb_env_lock_get(s48_value senv_handle, s48_value slocker_id,
|
|
s48_value sflags, s48_value sobject,
|
|
s48_value slock_mode)
|
|
{
|
|
DB_ENV *dbenv;
|
|
int res;
|
|
u_int32_t locker_id, flags;
|
|
DBT object;
|
|
DB_LOCK *lock;
|
|
db_lockmode_t lock_mode;
|
|
S48_DECLARE_GC_PROTECT(5);
|
|
|
|
S48_GC_PROTECT_5(senv_handle, slocker_id, sflags, sobject, slock_mode);
|
|
dbenv = scsh_extract_dbenv(senv_handle);
|
|
locker_id = s48_extract_integer(slocker_id);
|
|
flags = s48_extract_integer(sflags);
|
|
memset(&object, 0, sizeof(DBT));
|
|
scsh_extract_bytevector_as_DBT(sobject, &object);
|
|
lock_mode = s48_extract_integer(slock_mode);
|
|
S48_GC_UNPROTECT();
|
|
|
|
if ((lock = (DB_LOCK *) calloc(1, sizeof(DB_LOCK))) == NULL)
|
|
s48_raise_out_of_memory();
|
|
|
|
res = dbenv->lock_get(dbenv, locker_id, flags, &object,
|
|
lock_mode, lock);
|
|
if (res > 0)
|
|
s48_raise_os_error(res);
|
|
return s48_list_2(s48_enter_integer(res),
|
|
(res == 0) ? s48_enter_integer((long) lock) : S48_FALSE);
|
|
}
|
|
|
|
/* release a lock */
|
|
s48_value scsh_bdb_env_lock_put(s48_value senv_handle, s48_value slock)
|
|
{
|
|
DB_ENV *dbenv;
|
|
int res;
|
|
DB_LOCK *lock;
|
|
S48_DECLARE_GC_PROTECT(2);
|
|
|
|
S48_GC_PROTECT_2(senv_handle, slock);
|
|
dbenv = scsh_extract_dbenv(senv_handle);
|
|
lock = scsh_extract_lock(slock);
|
|
S48_GC_UNPROTECT();
|
|
|
|
res = dbenv->lock_put(dbenv, lock);
|
|
CHECK_BDB_RESULT_CODE(res);
|
|
return S48_FALSE;
|
|
}
|
|
|
|
/* remove a database */
|
|
s48_value scsh_bdb_dbremove(s48_value senv_handle, s48_value stxnid,
|
|
s48_value sfile, s48_value sdatabase,
|
|
s48_value sflags)
|
|
{
|
|
DB_ENV *dbenv;
|
|
DB_TXN *txnid;
|
|
char *file, *database;
|
|
u_int32_t flags;
|
|
int res;
|
|
S48_DECLARE_GC_PROTECT(5);
|
|
|
|
S48_GC_PROTECT_5(senv_handle, stxnid, sfile, sdatabase, sflags);
|
|
dbenv = scsh_extract_dbenv(senv_handle);
|
|
txnid = EXTRACT_OPTIONAL_TXNID(stxnid);
|
|
file = s48_extract_string(sfile);
|
|
database = s48_extract_string(sdatabase);
|
|
flags = s48_extract_integer(sflags);
|
|
S48_GC_UNPROTECT();
|
|
|
|
res = dbenv->dbremove(dbenv, txnid, file, database, flags);
|
|
CHECK_BDB_RESULT_CODE(res);
|
|
return S48_FALSE;
|
|
}
|
|
|
|
/* rename a database */
|
|
s48_value scsh_bdb_dbrename(s48_value senv_handle, s48_value stxnid,
|
|
s48_value sfile, s48_value sdatabase,
|
|
s48_value snewname, s48_value sflags)
|
|
{
|
|
DB_ENV *dbenv;
|
|
DB_TXN *txnid;
|
|
char *file, *database, *newname;
|
|
int res;
|
|
u_int32_t flags;
|
|
S48_DECLARE_GC_PROTECT(6);
|
|
|
|
S48_GC_UNPROTECT_6(senv_handle, stxnid, sfile, sdatabase, snewname, sflags);
|
|
dbenv = scsh_extract_dbenv(senv_handle);
|
|
txnid = EXTRACT_OPTIONAL_TXNID(stxnid);
|
|
file = s48_extract_string(sfile);
|
|
database = s48_extract_string(sdatabase);
|
|
newname = s48_extract_string(snewname);
|
|
flags = s48_extract_integer(sflags);
|
|
|
|
res = dbenv->dbrename(dbenv, txnid, file, database, newname, flags);
|
|
CHECK_BDB_RESULT_CODE(res);
|
|
return S48_FALSE;
|
|
}
|
|
|
|
/* open an environment */
|
|
s48_value scsh_bdb_env_open(s48_value env_handle, s48_value sdb_home,
|
|
s48_value sflags, s48_value smode)
|
|
{
|
|
int res, mode;
|
|
char *dbhome;
|
|
DB_ENV *dbenv;
|
|
u_int32_t flags;
|
|
|
|
S48_DECLARE_GC_PROTECT(4);
|
|
S48_GC_PROTECT_4(env_handle, sdb_home, sflags, smode);
|
|
|
|
dbhome = s48_extract_string(sdb_home);
|
|
dbenv = scsh_extract_dbenv(env_handle);
|
|
mode = s48_extract_integer(smode);
|
|
flags = s48_extract_integer(sflags);
|
|
S48_GC_UNPROTECT();
|
|
|
|
res = dbenv->open(dbenv, dbhome, flags, mode);
|
|
CHECK_BDB_RESULT_CODE(res);
|
|
return S48_FALSE;
|
|
}
|
|
|
|
/* set path for method database files */
|
|
s48_value scsh_bdb_env_set_data_dir(s48_value senv_handle, s48_value sdir)
|
|
{
|
|
int res;
|
|
DB_ENV *dbenv;
|
|
char* dir;
|
|
S48_DECLARE_GC_PROTECT(2);
|
|
|
|
S48_GC_PROTECT_2(senv_handle, sdir);
|
|
dir = s48_extract_string(sdir);
|
|
dbenv = scsh_extract_dbenv(senv_handle);
|
|
S48_GC_UNPROTECT();
|
|
|
|
res = dbenv->set_data_dir(dbenv, dir);
|
|
CHECK_BDB_RESULT_CODE(res);
|
|
return S48_FALSE;
|
|
}
|
|
|
|
s48_value scsh_bdb_env_get_data_dirs(s48_value senv_handle)
|
|
{
|
|
int res;
|
|
const char **a;
|
|
s48_value lst;
|
|
DB_ENV *dbenv;
|
|
S48_DECLARE_GC_PROTECT(2);
|
|
|
|
S48_GC_PROTECT_2(senv_handle, lst);
|
|
dbenv = scsh_extract_dbenv(senv_handle);
|
|
res = dbenv->get_data_dirs(dbenv, &a);
|
|
CHECK_BDB_RESULT_CODE(res);
|
|
lst = scsh_enter_string_array(a);
|
|
S48_GC_UNPROTECT();
|
|
return lst;
|
|
}
|
|
|
|
s48_value scsh_bdb_env_set_encrypt(s48_value senv_handle, s48_value spasswd,
|
|
s48_value sflags)
|
|
{
|
|
int res;
|
|
char *passwd;
|
|
DB_ENV *dbenv;
|
|
u_int32_t flags;
|
|
S48_DECLARE_GC_PROTECT(3);
|
|
|
|
S48_GC_PROTECT_3(senv_handle, spasswd, sflags);
|
|
dbenv = scsh_extract_dbenv(senv_handle);
|
|
passwd = s48_extract_string(spasswd);
|
|
flags = s48_extract_integer(sflags);
|
|
|
|
res = dbenv->set_encrypt(dbenv, passwd, flags);
|
|
memset(passwd, 0, S48_STRING_LENGTH(spasswd));
|
|
S48_GC_UNPROTECT();
|
|
CHECK_BDB_RESULT_CODE(res);
|
|
return S48_TRUE;
|
|
}
|
|
|
|
s48_value scsh_bdb_env_get_encrypt_flags(s48_value senv_handle)
|
|
{
|
|
int res;
|
|
int flags = 0;
|
|
DB_ENV *dbenv;
|
|
|
|
dbenv = scsh_extract_dbenv(senv_handle);
|
|
res = dbenv->get_encrypt_flags(dbenv, &flags);
|
|
if (res > 0)
|
|
s48_raise_os_error(res);
|
|
return s48_list_2(s48_enter_integer(res),
|
|
s48_enter_integer(flags));
|
|
}
|
|
|
|
/* set timeout for locks and transactions */
|
|
s48_value scsh_bdb_env_set_timeout(s48_value senv_handle, s48_value stimeout,
|
|
s48_value lockp)
|
|
{
|
|
DB_ENV *dbenv;
|
|
int res;
|
|
db_timeout_t timeout;
|
|
u_int32_t flags;
|
|
S48_DECLARE_GC_PROTECT(3);
|
|
|
|
S48_GC_PROTECT_3(senv_handle, stimeout, lockp);
|
|
dbenv = scsh_extract_dbenv(senv_handle);
|
|
flags = (lockp == S48_FALSE) ? DB_SET_TXN_TIMEOUT : DB_SET_LOCK_TIMEOUT;
|
|
timeout = (db_timeout_t) s48_extract_integer(stimeout);
|
|
S48_GC_UNPROTECT();
|
|
|
|
res = dbenv->set_timeout(dbenv, timeout, flags);
|
|
CHECK_BDB_RESULT_CODE(res);
|
|
return S48_FALSE;
|
|
}
|
|
|
|
/* get timeout for locks and transactions */
|
|
s48_value scsh_bdb_env_get_timeout(s48_value senv_handle, s48_value lockp)
|
|
{
|
|
DB_ENV *dbenv;
|
|
int res;
|
|
db_timeout_t timeout;
|
|
u_int32_t flags;
|
|
S48_DECLARE_GC_PROTECT(2);
|
|
|
|
S48_GC_PROTECT_2(senv_handle, lockp);
|
|
dbenv = scsh_extract_dbenv(senv_handle);
|
|
flags = (lockp == S48_FALSE) ? DB_SET_TXN_TIMEOUT : DB_SET_LOCK_TIMEOUT;
|
|
S48_GC_UNPROTECT();
|
|
res = dbenv->get_timeout(dbenv, &timeout, flags);
|
|
if (res > 0)
|
|
s48_raise_os_error(res);
|
|
return s48_list_2(s48_enter_integer(res),
|
|
(res == 0) ? s48_enter_integer((long) timeout) : S48_FALSE);
|
|
}
|
|
|
|
/* set a maximum number of transactions */
|
|
s48_value scsh_bdb_env_set_tx_max(s48_value senv_handle, s48_value smax)
|
|
{
|
|
DB_ENV *dbenv;
|
|
u_int32_t max;
|
|
int res;
|
|
S48_DECLARE_GC_PROTECT(2);
|
|
|
|
S48_GC_PROTECT_2(senv_handle, smax);
|
|
dbenv = scsh_extract_dbenv(senv_handle);
|
|
max = s48_extract_integer(smax);
|
|
S48_GC_UNPROTECT();
|
|
|
|
res = dbenv->set_tx_max(dbenv, max);
|
|
CHECK_BDB_RESULT_CODE(res);
|
|
return S48_FALSE;
|
|
}
|
|
|
|
/* get the maximum number of transactions */
|
|
s48_value scsh_bdb_env_get_tx_max(s48_value senv_handle)
|
|
{
|
|
DB_ENV *dbenv;
|
|
u_int32_t max = 0;
|
|
int res;
|
|
|
|
dbenv = scsh_extract_dbenv(senv_handle);
|
|
res = dbenv->get_tx_max(dbenv, &max);
|
|
if (res > 0)
|
|
s48_raise_os_error(res);
|
|
return s48_list_2(s48_enter_integer(res),
|
|
(res == 0) ? s48_enter_integer(max) : S48_FALSE);
|
|
}
|
|
|
|
/* set a recovery timestamp */
|
|
s48_value scsh_bdb_env_set_tx_timestamp(s48_value senv_handle, s48_value stimestamp)
|
|
{
|
|
int res;
|
|
DB_ENV *dbenv;
|
|
time_t timestamp;
|
|
S48_DECLARE_GC_PROTECT(2);
|
|
|
|
S48_GC_PROTECT_2(senv_handle, stimestamp);
|
|
dbenv = scsh_extract_dbenv(senv_handle);
|
|
timestamp = (time_t) s48_extract_integer(stimestamp);
|
|
S48_GC_UNPROTECT();
|
|
res = dbenv->set_tx_timestamp(dbenv, ×tamp);
|
|
CHECK_BDB_RESULT_CODE(res);
|
|
return S48_FALSE;
|
|
}
|
|
|
|
/* get a recovery timestamp */
|
|
s48_value scsh_bdb_env_get_tx_timestamp(s48_value senv_handle)
|
|
{
|
|
DB_ENV *dbenv;
|
|
time_t timestamp;
|
|
int res;
|
|
|
|
dbenv = scsh_extract_dbenv(senv_handle);
|
|
res = dbenv->get_tx_timestamp(dbenv, ×tamp);
|
|
if (res > 0)
|
|
s48_raise_os_error(res);
|
|
return s48_list_2(s48_enter_integer(res),
|
|
(res == 0) ? s48_enter_integer(timestamp) : S48_FALSE);
|
|
}
|
|
|
|
/* set tmp dir */
|
|
s48_value scsh_bdb_env_set_tmp_dir(s48_value senv_handle, s48_value sdir)
|
|
{
|
|
DB_ENV *dbenv;
|
|
int res;
|
|
char *dir;
|
|
S48_DECLARE_GC_PROTECT(2);
|
|
|
|
S48_GC_PROTECT_2(senv_handle, sdir);
|
|
dir = s48_extract_string(sdir);
|
|
dbenv = scsh_extract_dbenv(senv_handle);
|
|
S48_GC_UNPROTECT();
|
|
|
|
res = dbenv->set_tmp_dir(dbenv, dir);
|
|
CHECK_BDB_RESULT_CODE(res);
|
|
return S48_FALSE;
|
|
}
|
|
|
|
/* get tmp dir */
|
|
s48_value scsh_bdb_env_get_tmp_dir(s48_value senv_handle)
|
|
{
|
|
DB_ENV *dbenv;
|
|
int res;
|
|
char *tmpdir;
|
|
|
|
dbenv = scsh_extract_dbenv(senv_handle);
|
|
res = dbenv->get_tmp_dir(dbenv, (const char **) &tmpdir);
|
|
if (res > 0)
|
|
s48_raise_os_error(res);
|
|
return s48_list_2(s48_enter_integer(res),
|
|
((res == 0) && (tmpdir != NULL)) ?
|
|
s48_enter_string(tmpdir) : S48_FALSE);
|
|
}
|
|
|
|
/* set flags of DB_ENV */
|
|
s48_value scsh_bdb_env_set_flags(s48_value senv_handle, s48_value sflags,
|
|
s48_value clearp)
|
|
{
|
|
DB_ENV *dbenv;
|
|
u_int32_t flags;
|
|
int res;
|
|
S48_DECLARE_GC_PROTECT(3);
|
|
|
|
S48_GC_PROTECT_3(senv_handle, sflags, clearp);
|
|
dbenv = scsh_extract_dbenv(senv_handle);
|
|
flags = s48_extract_integer(sflags);
|
|
res = dbenv->set_flags(dbenv, flags, (clearp == S48_TRUE) ? 0 : 1);
|
|
S48_GC_UNPROTECT();
|
|
CHECK_BDB_RESULT_CODE(res);
|
|
return S48_FALSE;
|
|
}
|
|
|
|
/* get flags of DB_ENV */
|
|
s48_value scsh_bdb_env_get_flags(s48_value senv_handle)
|
|
{
|
|
DB_ENV *dbenv;
|
|
int res;
|
|
u_int32_t flags;
|
|
|
|
dbenv = scsh_extract_dbenv(senv_handle);
|
|
res = dbenv->get_flags(dbenv, &flags);
|
|
if (res > 0)
|
|
s48_raise_os_error(res);
|
|
return s48_list_2(s48_enter_integer(res),
|
|
(res == 0) ? s48_enter_integer(flags) : S48_FALSE);
|
|
}
|
|
|
|
/* remove an environment */
|
|
s48_value scsh_bdb_env_remove(s48_value db_home, s48_value sflags)
|
|
{
|
|
DB_ENV *dbenv;
|
|
int res;
|
|
char *dbhome;
|
|
u_int32_t flags;
|
|
|
|
S48_DECLARE_GC_PROTECT(2);
|
|
S48_GC_PROTECT_2(db_home, sflags);
|
|
dbhome = s48_extract_string(db_home);
|
|
flags = s48_extract_integer(sflags);
|
|
S48_GC_UNPROTECT();
|
|
|
|
res = dbenv->remove(dbenv, dbhome, flags);
|
|
CHECK_BDB_RESULT_CODE(res);
|
|
return S48_TRUE;
|
|
}
|
|
|
|
/* checkpoint the transaction subsystem */
|
|
s48_value scsh_bdb_env_txn_checkpoint(s48_value senv_handle, s48_value skybte,
|
|
s48_value smin, s48_value sflags)
|
|
{
|
|
DB_ENV *dbenv;
|
|
int res;
|
|
u_int32_t kbyte, min, flags;
|
|
S48_DECLARE_GC_PROTECT(4);
|
|
|
|
S48_GC_PROTECT_4(senv_handle, skybte, smin, sflags);
|
|
dbenv = scsh_extract_dbenv(senv_handle);
|
|
kbyte = s48_extract_integer(skybte);
|
|
min = s48_extract_integer(smin);
|
|
flags = s48_extract_integer(sflags);
|
|
S48_GC_UNPROTECT();
|
|
|
|
res = dbenv->txn_checkpoint(dbenv, kbyte, min, flags);
|
|
CHECK_BDB_RESULT_CODE(res);
|
|
return S48_FALSE;
|
|
}
|
|
|
|
/* create DB - returns dbp handle */
|
|
s48_value scsh_bdb_create(s48_value env, s48_value sflags)
|
|
{
|
|
DB *dbp;
|
|
DB_ENV *dbenv;
|
|
int res;
|
|
u_int32_t flags;
|
|
|
|
S48_DECLARE_GC_PROTECT(2);
|
|
S48_GC_PROTECT_2(env, sflags);
|
|
flags = s48_extract_integer(sflags);
|
|
dbenv = EXTRACT_OPTIONAL_ENV(env);
|
|
S48_GC_UNPROTECT();
|
|
|
|
res = db_create(&dbp, dbenv, flags);
|
|
CHECK_BDB_RESULT_CODE(res);
|
|
return scsh_enter_db(dbp);
|
|
}
|
|
|
|
/* open DB */
|
|
s48_value scsh_bdb_open(s48_value db, s48_value sfile, s48_value sdatabase,
|
|
s48_value stxnid, s48_value stype, s48_value sflags,
|
|
s48_value smode)
|
|
{
|
|
int res, mode;
|
|
char *dbfile;
|
|
char *database;
|
|
DB *dbp;
|
|
DB_TXN *txnid;
|
|
DBTYPE type;
|
|
u_int32_t flags;
|
|
|
|
S48_DECLARE_GC_PROTECT(7);
|
|
S48_GC_PROTECT_7(db, sfile, sdatabase, stxnid, stype, sflags, smode);
|
|
dbfile = s48_extract_string(sfile);
|
|
database = EXTRACT_OPTIONAL_STRING(sdatabase);
|
|
dbp = scsh_extract_db(db);
|
|
txnid = EXTRACT_OPTIONAL_TXNID(stxnid);
|
|
type = s48_extract_integer(stype);
|
|
flags = s48_extract_integer(sflags);
|
|
mode = s48_extract_integer(smode);
|
|
|
|
S48_GC_UNPROTECT();
|
|
|
|
res = dbp->open(dbp, txnid, dbfile, database, type, flags, mode);
|
|
CHECK_BDB_RESULT_CODE(res);
|
|
return S48_FALSE;
|
|
}
|
|
|
|
/* close DB */
|
|
s48_value scsh_bdb_close(s48_value db, s48_value sflags)
|
|
{
|
|
int res;
|
|
DB *dbp;
|
|
u_int32_t flags;
|
|
|
|
S48_DECLARE_GC_PROTECT(2);
|
|
S48_GC_PROTECT_2(db, sflags);
|
|
dbp= scsh_extract_db(db);
|
|
flags = s48_extract_integer(sflags);
|
|
S48_GC_UNPROTECT();
|
|
|
|
res = dbp->close(dbp, flags);
|
|
CHECK_BDB_RESULT_CODE(res);
|
|
return S48_FALSE;
|
|
}
|
|
|
|
s48_value scsh_bdb_truncate(s48_value db, s48_value stxnid, s48_value sflags)
|
|
{
|
|
int res;
|
|
DB *dbp;
|
|
u_int32_t flags;
|
|
u_int32_t *countp;
|
|
DB_TXN *txnid;
|
|
|
|
S48_DECLARE_GC_PROTECT(3);
|
|
S48_GC_PROTECT_3(db, stxnid, sflags);
|
|
dbp= scsh_extract_db(db);
|
|
txnid = EXTRACT_OPTIONAL_TXNID(stxnid);
|
|
flags = s48_extract_integer(sflags);
|
|
S48_GC_UNPROTECT();
|
|
|
|
res = dbp->truncate(dbp, txnid, countp, flags);
|
|
CHECK_BDB_RESULT_CODE(res);
|
|
return S48_FALSE;
|
|
}
|
|
|
|
s48_value scsh_bdb_sync(s48_value db)
|
|
{
|
|
int res;
|
|
DB *dbp;
|
|
|
|
S48_DECLARE_GC_PROTECT(1);
|
|
S48_GC_PROTECT_1(db);
|
|
dbp = scsh_extract_db(db);
|
|
S48_GC_UNPROTECT();
|
|
|
|
res = dbp->sync(dbp, 0);
|
|
CHECK_BDB_RESULT_CODE(res);
|
|
return S48_FALSE;
|
|
}
|
|
|
|
/* DBT as byte vectors */
|
|
s48_value scsh_enter_DBT_as_bytevector(DBT* dt)
|
|
{
|
|
int i;
|
|
s48_value res = S48_FALSE;
|
|
S48_DECLARE_GC_PROTECT(1);
|
|
S48_GC_PROTECT_1(res);
|
|
|
|
res = s48_make_byte_vector(dt->size, 0);
|
|
i = 0;
|
|
|
|
for (i = 0; i < dt->size; i++)
|
|
S48_BYTE_VECTOR_SET(res, i, ((char*)(dt->data))[i]);
|
|
|
|
S48_GC_UNPROTECT();
|
|
return res;
|
|
}
|
|
|
|
void scsh_extract_bytevector_as_DBT(s48_value bytevector, DBT* dt)
|
|
{
|
|
dt->data = s48_extract_byte_vector(bytevector);
|
|
dt->size = S48_BYTE_VECTOR_LENGTH(bytevector);
|
|
}
|
|
|
|
/* DBT operations */
|
|
|
|
/* set the database cryptographic key */
|
|
s48_value scsh_bdb_set_encrypt(s48_value sdatabase, s48_value spasswd,
|
|
s48_value sflags)
|
|
{
|
|
DB *db;
|
|
char *passwd;
|
|
int res;
|
|
u_int32_t flags;
|
|
S48_DECLARE_GC_PROTECT(3);
|
|
|
|
S48_GC_PROTECT_3(sdatabase, spasswd, sflags);
|
|
db = scsh_extract_db(sdatabase);
|
|
flags = s48_extract_integer(sflags);
|
|
passwd = s48_extract_string(spasswd);
|
|
|
|
res = db->set_encrypt(db, passwd, flags);
|
|
memset(&passwd, 0, S48_STRING_LENGTH(spasswd));
|
|
S48_GC_UNPROTECT();
|
|
CHECK_BDB_RESULT_CODE(res);
|
|
return S48_FALSE;
|
|
}
|
|
|
|
/* get the database cryptographic flags */
|
|
s48_value scsh_bdb_get_encrypt_flags(s48_value sdatabase)
|
|
{
|
|
DB *db;
|
|
int res;
|
|
u_int32_t flags = 0;
|
|
|
|
db = scsh_extract_db(sdatabase);
|
|
res = db->get_encrypt_flags(db, &flags);
|
|
if (res > 0)
|
|
s48_raise_os_error(res);
|
|
return s48_list_2(s48_enter_integer(res),
|
|
(res == 0) ? s48_enter_integer(flags) : S48_FALSE);
|
|
}
|
|
|
|
/* general database configuration */
|
|
s48_value scsh_bdb_set_flags(s48_value sdatabase, s48_value sflags)
|
|
{
|
|
DB *db;
|
|
int res;
|
|
u_int32_t flags;
|
|
S48_DECLARE_GC_PROTECT(2);
|
|
|
|
S48_GC_PROTECT_2(sdatabase, sflags);
|
|
db = scsh_extract_db(sdatabase);
|
|
flags = s48_extract_integer(sflags);
|
|
S48_GC_UNPROTECT();
|
|
res = db->set_flags(db, flags);
|
|
CHECK_BDB_RESULT_CODE(res);
|
|
return S48_FALSE;
|
|
}
|
|
|
|
s48_value scsh_bdb_get_flags(s48_value sdatabase)
|
|
{
|
|
DB *db;
|
|
int res;
|
|
u_int32_t flags;
|
|
|
|
db = scsh_extract_db(sdatabase);
|
|
res = db->get_flags(db, &flags);
|
|
if (res > 0)
|
|
s48_raise_os_error(res);
|
|
return s48_list_2(s48_enter_integer(res),
|
|
(res == 0) ? s48_enter_integer(flags) : S48_FALSE);
|
|
}
|
|
|
|
s48_value scsh_bdb_set_lorder(s48_value sdatabase, s48_value sbig_endian_p)
|
|
{
|
|
DB *db;
|
|
int res;
|
|
S48_DECLARE_GC_PROTECT(2);
|
|
|
|
S48_GC_PROTECT_2(sdatabase, sbig_endian_p);
|
|
db = scsh_extract_db(sdatabase);
|
|
res = db->set_lorder(db, (sbig_endian_p == S48_TRUE) ? 4321 : 1234);
|
|
S48_GC_UNPROTECT();
|
|
CHECK_BDB_RESULT_CODE(res);
|
|
return S48_FALSE;
|
|
}
|
|
|
|
s48_value scsh_bdb_get_lorder(s48_value sdatabase)
|
|
{
|
|
DB *db;
|
|
int res, lorder;
|
|
|
|
db = scsh_extract_db(sdatabase);
|
|
res = db->get_lorder(db, &lorder);
|
|
if (res > 0)
|
|
s48_raise_os_error(res);
|
|
return s48_list_2(s48_enter_integer(res),
|
|
(res == 0) ? ((lorder == 4321) ? S48_TRUE : S48_FALSE)
|
|
: S48_UNSPECIFIC);
|
|
}
|
|
|
|
s48_value scsh_bdb_set_pagesize(s48_value sdatabase, s48_value spagesize)
|
|
{
|
|
DB *db;
|
|
u_int32_t pagesize;
|
|
int res;
|
|
S48_DECLARE_GC_PROTECT(2);
|
|
|
|
S48_GC_PROTECT_2(sdatabase, spagesize);
|
|
db = scsh_extract_db(sdatabase);
|
|
pagesize = s48_extract_integer(spagesize);
|
|
S48_GC_UNPROTECT();
|
|
|
|
res = db->set_pagesize(db, pagesize);
|
|
CHECK_BDB_RESULT_CODE(res);
|
|
return S48_FALSE;
|
|
}
|
|
|
|
s48_value scsh_bdb_get_pagesize(s48_value sdatabase)
|
|
{
|
|
DB *db;
|
|
u_int32_t pagesize = 0;
|
|
int res;
|
|
|
|
db = scsh_extract_db(sdatabase);
|
|
res = db->get_pagesize(db, &pagesize);
|
|
if (res > 0)
|
|
s48_raise_os_error(res);
|
|
return s48_list_2(s48_enter_integer(res),
|
|
(res == 0) ? s48_enter_integer(pagesize) : S48_FALSE);
|
|
}
|
|
|
|
/* Put key and data DBT's in DB */
|
|
s48_value scsh_bdb_put(s48_value db, s48_value skey, s48_value sdata,
|
|
s48_value stxnid, s48_value sflags)
|
|
{
|
|
int res = 0;
|
|
DB *dbp;
|
|
DB_TXN *txnid;
|
|
DBT key, data;
|
|
u_int32_t flags;
|
|
S48_DECLARE_GC_PROTECT(5);
|
|
|
|
S48_GC_PROTECT_5(db, skey, sdata, stxnid, sflags);
|
|
|
|
dbp = scsh_extract_db(db);
|
|
txnid = EXTRACT_OPTIONAL_TXNID(stxnid);
|
|
flags = s48_extract_integer(sflags);
|
|
|
|
memset(&key, 0, sizeof(DBT));
|
|
memset(&data, 0, sizeof(DBT));
|
|
scsh_extract_bytevector_as_DBT(skey, &key);
|
|
scsh_extract_bytevector_as_DBT(sdata, &data);
|
|
|
|
res = dbp->put(dbp, txnid, &key, &data, flags);
|
|
S48_GC_UNPROTECT();
|
|
CHECK_BDB_RESULT_CODE(res);
|
|
return S48_FALSE;
|
|
}
|
|
|
|
/* Get DBT to corresponding key */
|
|
s48_value scsh_bdb_get(s48_value handle, s48_value skey,
|
|
s48_value stxnid, s48_value sflags)
|
|
{
|
|
int res;
|
|
DB *dbp;
|
|
u_int32_t flags;
|
|
DB_TXN *txnid;
|
|
DBT key, data;
|
|
|
|
S48_DECLARE_GC_PROTECT(4);
|
|
|
|
S48_GC_PROTECT_4(handle, skey, stxnid, sflags);
|
|
memset(&key, 0, sizeof(DBT));
|
|
memset(&data, 0, sizeof(DBT));
|
|
|
|
dbp = scsh_extract_db(handle);
|
|
flags = s48_extract_integer(sflags);
|
|
txnid = EXTRACT_OPTIONAL_TXNID(stxnid);
|
|
|
|
scsh_extract_bytevector_as_DBT(skey, &key);
|
|
S48_GC_UNPROTECT();
|
|
res = dbp->get(dbp, txnid, &key, &data, flags);
|
|
|
|
if (res > 0)
|
|
s48_raise_os_error(res);
|
|
|
|
switch (res) {
|
|
case DB_NOTFOUND:
|
|
case DB_KEYEMPTY:
|
|
return s48_enter_integer(res);
|
|
break;
|
|
default:
|
|
CHECK_BDB_RESULT_CODE(res);
|
|
return scsh_enter_DBT_as_bytevector(&data);
|
|
}
|
|
}
|
|
|
|
/* Delete DBT to corresponding key */
|
|
s48_value scsh_bdb_del(s48_value handle, s48_value skey,
|
|
s48_value stxnid, s48_value sflags)
|
|
{
|
|
int res;
|
|
DB* dbp;
|
|
DB_TXN *txnid;
|
|
DBT key;
|
|
u_int32_t flags;
|
|
|
|
S48_DECLARE_GC_PROTECT(4);
|
|
S48_GC_PROTECT_4(handle, skey, stxnid, sflags);
|
|
|
|
dbp = scsh_extract_db(handle);
|
|
flags = s48_extract_integer(sflags);
|
|
txnid = EXTRACT_OPTIONAL_TXNID(stxnid);
|
|
memset(&key, 0, sizeof(DBT));
|
|
scsh_extract_bytevector_as_DBT(skey, &key);
|
|
|
|
S48_GC_UNPROTECT();
|
|
res = dbp->del(dbp, txnid, &key, flags);
|
|
CHECK_BDB_RESULT_CODE(res);
|
|
return S48_FALSE;
|
|
}
|
|
|
|
s48_value scsh_bdb_create_cursor(s48_value handle, s48_value stxnid,
|
|
s48_value sflags)
|
|
{
|
|
int res;
|
|
DB* dbp;
|
|
DBC* dbcp;
|
|
DB_TXN *txnid;
|
|
u_int32_t flags;
|
|
s48_value ret = S48_FALSE;
|
|
S48_DECLARE_GC_PROTECT(4);
|
|
|
|
S48_GC_PROTECT_4(handle, stxnid, sflags, ret);
|
|
dbp = scsh_extract_db(handle);
|
|
flags = s48_extract_integer(sflags);
|
|
txnid = EXTRACT_OPTIONAL_TXNID(stxnid);
|
|
|
|
S48_GC_UNPROTECT();
|
|
res = dbp->cursor(dbp,txnid, &dbcp, flags);
|
|
CHECK_BDB_RESULT_CODE(res);
|
|
return scsh_enter_cursor(dbcp);
|
|
}
|
|
|
|
s48_value scsh_bdb_close_cursor(s48_value scursor)
|
|
{
|
|
int res;
|
|
DBC *cursor;
|
|
S48_DECLARE_GC_PROTECT(1);
|
|
|
|
S48_GC_PROTECT_1(scursor);
|
|
cursor = scsh_extract_cursor(scursor);
|
|
S48_GC_UNPROTECT();
|
|
|
|
res = cursor->c_close(cursor);
|
|
CHECK_BDB_RESULT_CODE(res);
|
|
return S48_FALSE;
|
|
}
|
|
|
|
/* retrieve values from cursor */
|
|
s48_value scsh_bdb_cursor_cget(s48_value dbc, s48_value sflags)
|
|
{
|
|
int res;
|
|
DBC* dbcp;
|
|
u_int32_t flags;
|
|
DBT *key, *data;
|
|
S48_DECLARE_GC_PROTECT(2);
|
|
|
|
S48_GC_PROTECT_2(dbc, sflags);
|
|
memset(&key, 0, sizeof(DBT));
|
|
memset(&data, 0, sizeof(DBT));
|
|
dbcp = scsh_extract_cursor(dbc);
|
|
flags = s48_extract_integer(sflags);
|
|
S48_GC_UNPROTECT();
|
|
|
|
res = dbcp->c_get(dbcp, key, data, flags);
|
|
CHECK_BDB_RESULT_CODE(res);
|
|
return scsh_enter_DBT_as_bytevector(data);
|
|
}
|
|
|
|
/* return a count of duplicates */
|
|
s48_value scsh_bdb_cursor_count(s48_value scursor)
|
|
{
|
|
DBC *dbc;
|
|
int res;
|
|
db_recno_t countp;
|
|
|
|
dbc = scsh_extract_cursor(scursor);
|
|
res = dbc->c_count(dbc, &countp, 0);
|
|
if (res > 0)
|
|
s48_raise_os_error(res);
|
|
return s48_list_2(s48_enter_integer(res),
|
|
(res == 0) ? s48_enter_integer((long) countp) : S48_FALSE);
|
|
}
|
|
|
|
/* delete by cursor */
|
|
s48_value scsh_bdb_cursor_del(s48_value scursor)
|
|
{
|
|
DBC *dbc;
|
|
int res;
|
|
|
|
dbc = scsh_extract_cursor(scursor);
|
|
res = dbc->c_del(dbc, 0);
|
|
CHECK_BDB_RESULT_CODE(res);
|
|
return S48_FALSE;
|
|
}
|
|
|
|
/* store by cursor */
|
|
s48_value scsh_bdb_cursor_put(s48_value scursor, s48_value skey,
|
|
s48_value sdata, s48_value sflags)
|
|
{
|
|
DBT key, data;
|
|
DBC *dbc;
|
|
u_int32_t flags;
|
|
int res;
|
|
S48_DECLARE_GC_PROTECT(4);
|
|
|
|
S48_GC_PROTECT_4(scursor, skey, sdata, sflags);
|
|
dbc = scsh_extract_cursor(scursor);
|
|
flags = s48_extract_integer(sflags);
|
|
memset(&key, 0, sizeof(DBT));
|
|
memset(&data, 0, sizeof(DBT));
|
|
scsh_extract_bytevector_as_DBT(skey, &key);
|
|
scsh_extract_bytevector_as_DBT(sdata, &data);
|
|
S48_GC_UNPROTECT();
|
|
|
|
res = dbc->c_put(dbc, &key, &data, flags);
|
|
CHECK_BDB_RESULT_CODE(res);
|
|
return S48_FALSE;
|
|
}
|
|
|
|
s48_value scsh_bdb_txn_begin (s48_value handle, s48_value sparent,
|
|
s48_value sflags)
|
|
{
|
|
int res;
|
|
DB_ENV* env;
|
|
DBC* dbcp;
|
|
DB_TXN* parent, *txnid;
|
|
u_int32_t flags;
|
|
s48_value ret = S48_FALSE;
|
|
//parent = NULL; // only for nested transactions
|
|
|
|
S48_DECLARE_GC_PROTECT(3);
|
|
S48_GC_PROTECT_3(handle, sflags, ret);
|
|
|
|
env = scsh_extract_dbenv(handle);
|
|
flags = s48_extract_integer(sflags);
|
|
S48_GC_UNPROTECT();
|
|
|
|
res = env->txn_begin(env, NULL, &txnid, flags);
|
|
CHECK_BDB_RESULT_CODE(res);
|
|
return scsh_enter_txnid(txnid);
|
|
}
|
|
|
|
s48_value scsh_bdb_txn_abort(s48_value stxnid)
|
|
{
|
|
int res;
|
|
DB_TXN *txnid;
|
|
s48_value ret = S48_FALSE;
|
|
|
|
S48_DECLARE_GC_PROTECT(1);
|
|
S48_GC_PROTECT_1(stxnid);
|
|
|
|
txnid = EXTRACT_OPTIONAL_TXNID(stxnid);
|
|
S48_GC_UNPROTECT();
|
|
|
|
res = txnid->abort(txnid);
|
|
CHECK_BDB_RESULT_CODE(res);
|
|
return S48_TRUE;
|
|
}
|
|
|
|
s48_value scsh_bdb_txn_commit(s48_value stxnid, s48_value sflags)
|
|
{
|
|
int res;
|
|
DB_TXN *txnid;
|
|
s48_value ret = S48_FALSE;
|
|
u_int32_t flags;
|
|
S48_DECLARE_GC_PROTECT(2);
|
|
S48_GC_PROTECT_2(stxnid, sflags);
|
|
flags = s48_extract_integer(sflags);
|
|
txnid = EXTRACT_OPTIONAL_TXNID(stxnid);
|
|
S48_GC_UNPROTECT();
|
|
|
|
res = txnid->commit(txnid, flags);
|
|
CHECK_BDB_RESULT_CODE(res);
|
|
return S48_TRUE;
|
|
}
|
|
|
|
/* initialize bindings */
|
|
void scsh_init_bdb_bindings(void)
|
|
{
|
|
S48_GC_PROTECT_GLOBAL(scheme_DB_VERSION);
|
|
scheme_DB_VERSION = s48_list_3(s48_enter_integer(DB_VERSION_MAJOR),
|
|
s48_enter_integer(DB_VERSION_MINOR),
|
|
s48_enter_integer(DB_VERSION_PATCH));
|
|
s48_define_exported_binding("scheme_DB_VERSION", scheme_DB_VERSION);
|
|
|
|
S48_GC_PROTECT_GLOBAL(scheme_DB_VERSION_VERBOSE);
|
|
scheme_DB_VERSION_VERBOSE = s48_enter_string(DB_VERSION_STRING);
|
|
s48_define_exported_binding("scheme_DB_VERSION_VERBOSE",
|
|
scheme_DB_VERSION_VERBOSE);
|
|
|
|
/* records */
|
|
S48_GC_PROTECT_GLOBAL(bdb_db_record_type);
|
|
bdb_db_record_type = s48_get_imported_binding("bdb-db");
|
|
|
|
S48_GC_PROTECT_GLOBAL(bdb_env_record_type);
|
|
bdb_env_record_type = s48_get_imported_binding("bdb-env");
|
|
|
|
S48_GC_PROTECT_GLOBAL(bdb_lock_record_type);
|
|
bdb_lock_record_type = s48_get_imported_binding("bdb-lock");
|
|
|
|
S48_GC_PROTECT_GLOBAL(bdb_mpoolfile_record_type);
|
|
bdb_mpoolfile_record_type = s48_get_imported_binding("bdb-mpoolfile");
|
|
|
|
S48_GC_PROTECT_GLOBAL(bdb_txn_record_type);
|
|
bdb_txn_record_type = s48_get_imported_binding("bdb-txn");
|
|
|
|
S48_GC_PROTECT_GLOBAL(bdb_dbc_record_type);
|
|
bdb_dbc_record_type = s48_get_imported_binding("bdb-dbc");
|
|
|
|
/* flag constants */
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_RPCCLIENT, DB_RPCCLIENT);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_INIT_LOCK, DB_INIT_LOCK);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_JOINENV, DB_JOINENV);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_INIT_MPOOL, DB_INIT_MPOOL);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_INIT_LOG, DB_INIT_LOG);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_INIT_REP, DB_INIT_REP);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_INIT_TXN, DB_INIT_TXN);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_RECOVER, DB_RECOVER);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_RECOVER_FATAL, DB_RECOVER_FATAL);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_USE_ENVIRON, DB_USE_ENVIRON);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_USE_ENVIRON_ROOT, DB_USE_ENVIRON_ROOT);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_CREATE, DB_CREATE);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_LOCKDOWN, DB_LOCKDOWN);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_PRIVATE, DB_PRIVATE);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_SYSTEM_MEM, DB_SYSTEM_MEM);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_THREAD, DB_THREAD);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_AUTO_COMMIT, DB_AUTO_COMMIT);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_DIRTY_READ, DB_DIRTY_READ);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_EXCL, DB_EXCL);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_NOMMAP, DB_NOMMAP);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_RDONLY, DB_RDONLY);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_SYSTEM_MEM, DB_SYSTEM_MEM);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_TRUNCATE, DB_TRUNCATE);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_NOSYNC, DB_NOSYNC);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_CONSUME, DB_CONSUME);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_CONSUME_WAIT, DB_CONSUME_WAIT);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_GET_BOTH, DB_GET_BOTH);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_RMW, DB_RMW);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_MULTIPLE, DB_MULTIPLE);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_SET_RECNO, DB_SET_RECNO);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_APPEND, DB_APPEND);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_NODUPDATA, DB_NODUPDATA);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_NOOVERWRITE, DB_NOOVERWRITE);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_CURRENT, DB_CURRENT);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_FIRST, DB_FIRST);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_WRITECURSOR, DB_WRITECURSOR);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_GET_BOTH_RANGE, DB_GET_BOTH_RANGE);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_GET_RECNO, DB_GET_RECNO);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_JOIN_ITEM, DB_JOIN_ITEM);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_LAST, DB_LAST);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_NEXT, DB_NEXT);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_NEXT_DUP, DB_NEXT_DUP);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_NEXT_NODUP, DB_NEXT_NODUP);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_PREV, DB_PREV);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_SET, DB_SET);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_SET_RANGE, DB_SET_RANGE);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_MULTIPLE_KEY, DB_MULTIPLE_KEY);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_TXN_NOSYNC, DB_TXN_NOSYNC);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_TXN_NOWAIT, DB_TXN_NOWAIT);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_TXN_SYNC, DB_TXN_SYNC);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_BTREE, DB_BTREE);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_HASH, DB_HASH);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_QUEUE, DB_QUEUE);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_RECNO, DB_RECNO);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_UNKNOWN, DB_UNKNOWN);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_LOCK_NOWAIT, DB_LOCK_NOWAIT);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_ENCRYPT_AES, DB_ENCRYPT_AES);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_CDB_ALLDB, DB_CDB_ALLDB);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_DIRECT_DB, DB_DIRECT_DB);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_DIRECT_LOG, DB_DIRECT_LOG);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_LOG_AUTOREMOVE, DB_LOG_AUTOREMOVE);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_NOLOCKING, DB_NOLOCKING);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_NOPANIC, DB_NOPANIC);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_OVERWRITE, DB_OVERWRITE);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_PANIC_ENVIRONMENT, DB_PANIC_ENVIRONMENT);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_REGION_INIT, DB_REGION_INIT);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_TIME_NOTGRANTED, DB_TIME_NOTGRANTED);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_TXN_NOT_DURABLE, DB_TXN_NOT_DURABLE);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_TXN_WRITE_NOSYNC, DB_TXN_WRITE_NOSYNC);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_FORCE, DB_FORCE);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_CHKSUM, DB_CHKSUM);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_ENCRYPT, DB_ENCRYPT);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_DUP, DB_DUP);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_DUPSORT, DB_DUPSORT);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_RECNUM, DB_RECNUM);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_REVSPLITOFF, DB_REVSPLITOFF);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_RENUMBER, DB_RENUMBER);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_SNAPSHOT, DB_SNAPSHOT);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_PREV_NODUP, DB_PREV_NODUP);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_AFTER, DB_AFTER);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_BEFORE, DB_BEFORE);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_KEYFIRST, DB_KEYFIRST);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_KEYLAST, DB_KEYLAST);
|
|
|
|
/* return codes */
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_DONOTINDEX, DB_DONOTINDEX);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_FILEOPEN, DB_FILEOPEN);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_KEYEMPTY, DB_KEYEMPTY);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_KEYEXIST, DB_KEYEXIST);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_LOCK_DEADLOCK, DB_LOCK_DEADLOCK);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_LOCK_NOTGRANTED, DB_LOCK_NOTGRANTED);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_NOSERVER, DB_NOSERVER);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_NOSERVER_HOME, DB_NOSERVER_HOME);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_NOSERVER_ID, DB_NOSERVER_ID);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_NOTFOUND, DB_NOTFOUND);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_OLD_VERSION, DB_OLD_VERSION);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_PAGE_NOTFOUND, DB_PAGE_NOTFOUND);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_REP_DUPMASTER, DB_REP_DUPMASTER);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_REP_HANDLE_DEAD, DB_REP_HANDLE_DEAD);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_REP_HOLDELECTION, DB_REP_HOLDELECTION);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_REP_ISPERM, DB_REP_ISPERM);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_REP_NEWMASTER, DB_REP_NEWMASTER);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_REP_NEWSITE, DB_REP_NEWSITE);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_REP_NOTPERM, DB_REP_NOTPERM);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_REP_OUTDATED, DB_REP_OUTDATED);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_REP_UNAVAIL, DB_REP_UNAVAIL);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_RUNRECOVERY, DB_RUNRECOVERY);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_SECONDARY_BAD, DB_SECONDARY_BAD);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_VERIFY_BAD, DB_VERIFY_BAD);
|
|
|
|
/* lock modes */
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_LOCK_READ, DB_LOCK_READ);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_LOCK_WRITE, DB_LOCK_WRITE);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_LOCK_IWRITE, DB_LOCK_IWRITE);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_LOCK_IREAD, DB_LOCK_IREAD);
|
|
ENTER_INTEGER_CONSTANT(scheme_DB_LOCK_IWR, DB_LOCK_IWR);
|
|
|
|
/* export functions to scheme */
|
|
S48_EXPORT_FUNCTION(scsh_bdb_create);
|
|
S48_EXPORT_FUNCTION(scsh_bdb_open);
|
|
S48_EXPORT_FUNCTION(scsh_bdb_close);
|
|
S48_EXPORT_FUNCTION(scsh_bdb_put);
|
|
S48_EXPORT_FUNCTION(scsh_bdb_get);
|
|
S48_EXPORT_FUNCTION(scsh_bdb_del);
|
|
S48_EXPORT_FUNCTION(scsh_bdb_env_create);
|
|
S48_EXPORT_FUNCTION(scsh_bdb_dbremove);
|
|
S48_EXPORT_FUNCTION(scsh_bdb_dbrename);
|
|
S48_EXPORT_FUNCTION(scsh_bdb_env_set_data_dir);
|
|
S48_EXPORT_FUNCTION(scsh_bdb_env_get_data_dirs);
|
|
S48_EXPORT_FUNCTION(scsh_bdb_env_set_encrypt);
|
|
S48_EXPORT_FUNCTION(scsh_bdb_env_get_encrypt_flags);
|
|
S48_EXPORT_FUNCTION(scsh_bdb_env_set_timeout);
|
|
S48_EXPORT_FUNCTION(scsh_bdb_env_get_timeout);
|
|
S48_EXPORT_FUNCTION(scsh_bdb_env_set_tmp_dir);
|
|
S48_EXPORT_FUNCTION(scsh_bdb_env_get_tmp_dir);
|
|
S48_EXPORT_FUNCTION(scsh_bdb_env_set_tx_max);
|
|
S48_EXPORT_FUNCTION(scsh_bdb_env_get_tx_max);
|
|
S48_EXPORT_FUNCTION(scsh_bdb_env_set_tx_timestamp);
|
|
S48_EXPORT_FUNCTION(scsh_bdb_env_get_tx_timestamp);
|
|
S48_EXPORT_FUNCTION(scsh_bdb_env_set_flags);
|
|
S48_EXPORT_FUNCTION(scsh_bdb_env_get_flags);
|
|
S48_EXPORT_FUNCTION(scsh_bdb_env_open);
|
|
S48_EXPORT_FUNCTION(scsh_bdb_env_close);
|
|
S48_EXPORT_FUNCTION(scsh_bdb_env_lock_get);
|
|
S48_EXPORT_FUNCTION(scsh_bdb_env_lock_put);
|
|
S48_EXPORT_FUNCTION(scsh_bdb_env_remove);
|
|
S48_EXPORT_FUNCTION(scsh_bdb_env_txn_checkpoint);
|
|
S48_EXPORT_FUNCTION(scsh_bdb_truncate);
|
|
S48_EXPORT_FUNCTION(scsh_bdb_sync);
|
|
S48_EXPORT_FUNCTION(scsh_bdb_create_cursor);
|
|
S48_EXPORT_FUNCTION(scsh_bdb_close_cursor);
|
|
S48_EXPORT_FUNCTION(scsh_bdb_cursor_cget);
|
|
S48_EXPORT_FUNCTION(scsh_bdb_cursor_count);
|
|
S48_EXPORT_FUNCTION(scsh_bdb_cursor_del);
|
|
S48_EXPORT_FUNCTION(scsh_bdb_cursor_put);
|
|
S48_EXPORT_FUNCTION(scsh_bdb_txn_begin);
|
|
S48_EXPORT_FUNCTION(scsh_bdb_txn_abort);
|
|
S48_EXPORT_FUNCTION(scsh_bdb_txn_commit);
|
|
S48_EXPORT_FUNCTION(scsh_bdb_set_encrypt);
|
|
S48_EXPORT_FUNCTION(scsh_bdb_get_encrypt_flags);
|
|
S48_EXPORT_FUNCTION(scsh_bdb_set_flags);
|
|
S48_EXPORT_FUNCTION(scsh_bdb_get_flags);
|
|
S48_EXPORT_FUNCTION(scsh_bdb_set_lorder);
|
|
S48_EXPORT_FUNCTION(scsh_bdb_get_lorder);
|
|
S48_EXPORT_FUNCTION(scsh_bdb_set_pagesize);
|
|
S48_EXPORT_FUNCTION(scsh_bdb_get_pagesize);
|
|
S48_EXPORT_FUNCTION(scsh_bdb_env_lock_id);
|
|
S48_EXPORT_FUNCTION(scsh_bdb_env_lock_id_free);
|
|
}
|