class BDB::Common

Public Class Methods

[](*args) click to toggle source
static VALUE
bdb_s_create(int argc, VALUE *argv, VALUE obj)
{
    VALUE res;
    int i;

    res = rb_funcall2(obj, rb_intern("new"), 0, 0);
    if (argc == 1 && TYPE(argv[0]) == T_HASH) {
        rb_iterate(rb_each, argv[0], bdb_i_s_create, res);
        return res;
    }
    if (argc % 2 != 0) {
        rb_raise(rb_eArgError, "odd number args for %s", rb_class2name(obj));
    }
    for (i = 0; i < argc; i += 2) {
        bdb_put(2, argv + i, res);
    }
    return res;
}
allocate() click to toggle source
static VALUE
bdb_s_alloc(obj)
    VALUE obj;
{
    VALUE res, cl;
    bdb_DB *dbst;

    res = Data_Make_Struct(obj, bdb_DB, bdb_mark, bdb_free, dbst);
    dbst->options = BDB_NOT_OPEN;
    cl = obj;
    while (cl) {
    if(RTEST(rb_ary_includes(rb_mod_ancestors(cl), bdb_cBtree))) {
            dbst->type = DB_BTREE; 
            break;
        }
        if(RTEST(rb_ary_includes(rb_mod_ancestors(cl), bdb_cRecnum))) {
            dbst->type = DB_RECNO; 
            break;
        }
        else if(RTEST(rb_ary_includes(rb_mod_ancestors(cl), bdb_cHash))) {
            dbst->type = DB_HASH; 
            break;
        }
        else if(RTEST(rb_ary_includes(rb_mod_ancestors(cl), bdb_cRecno))) {
            dbst->type = DB_RECNO;
            break;
    }
#if HAVE_CONST_DB_QUEUE
        else if(RTEST(rb_ary_includes(rb_mod_ancestors(cl), bdb_cQueue))) {
            dbst->type = DB_QUEUE;
            break;
        }
#endif
        else if(RTEST(rb_ary_includes(rb_mod_ancestors(cl), bdb_cUnknown))) {
            dbst->type = DB_UNKNOWN;
            break;
        }
        cl = RCLASS_SUPER(cl);
    }
    if (!cl) {
        rb_raise(bdb_eFatal, "unknown database type");
    }
    dbst->ori_val = res;
    return res;
}
bdb_remove(p1, p2 = v2) click to toggle source
static VALUE
bdb_s_remove(int argc, VALUE *argv, VALUE obj)
{
    bdb_DB *dbst;
    VALUE a, b, c;
    char *name, *subname;

    rb_secure(2);
    c = bdb_i_create(obj);
    GetDB(c, dbst);
    name = subname = NULL;
    a = b = Qnil;
    if (rb_scan_args(argc, argv, "11", &a, &b) == 2) {
        if (!NIL_P(b)) {
            SafeStringValue(b);
            subname = StringValuePtr(b);
        }
    }
    SafeStringValue(a);
    name = StringValuePtr(a);
    bdb_test_error(dbst->dbp->remove(dbst->dbp, name, subname, 0));
    return Qtrue;
}
bdb_rename(p1, p2, p3) click to toggle source
static VALUE
bdb_s_rename(int argc, VALUE *argv, VALUE obj)
{
    bdb_DB *dbst;
    VALUE a, b, c;
    char *name, *subname, *newname;

    rb_secure(2);
    c = bdb_i_create(obj);
    GetDB(c, dbst);
    name = subname = NULL;
    a = b = c = Qnil;
    rb_scan_args(argc, argv, "30", &a, &b, &c);
    if (!NIL_P(b)) {
        SafeStringValue(b);
        subname = StringValuePtr(b);
    }
    SafeStringValue(a);
    SafeStringValue(c);
    name = StringValuePtr(a);
    newname = StringValuePtr(c);
    bdb_test_error(dbst->dbp->rename(dbst->dbp, name, subname, newname, 0));
    return Qtrue;
}
bdb_upgrade(p1, p2 = v2) click to toggle source
static VALUE
bdb_s_upgrade(int argc, VALUE *argv, VALUE obj)
{
#if HAVE_ST_DB_UPGRADE
    bdb_DB *dbst;
    VALUE a, b;
    int flags;
    VALUE val;

    rb_secure(4);
    flags = 0;
    if (rb_scan_args(argc, argv, "11", &a, &b) == 2) {
        flags = NUM2INT(b);
    }
    SafeStringValue(a);
    val = bdb_i_create(obj);
    GetDB(val, dbst);
    bdb_test_error(dbst->dbp->upgrade(dbst->dbp, StringValuePtr(a), flags));
    return val;
#else
    rb_raise(bdb_eFatal, "You can't upgrade a database with this version of DB");
#endif
}
create(*args) click to toggle source
static VALUE
bdb_s_new(int argc, VALUE *argv, VALUE obj)
{
    VALUE res;
    bdb_TXN *txnst = NULL;
    bdb_ENV *envst = NULL;
    bdb_DB *dbst;
    DB_ENV *envp = 0;

#ifdef HAVE_RB_DEFINE_ALLOC_FUNC
    res = rb_obj_alloc(obj);
#else
    res = rb_funcall2(obj, rb_intern("allocate"), 0, 0);
#endif
    Data_Get_Struct(res, bdb_DB, dbst);
    if (argc && TYPE(argv[argc - 1]) == T_HASH) {
        VALUE v, f = argv[argc - 1];

        if ((v = rb_hash_aref(f, rb_str_new2("txn"))) != RHASH(f)->ifnone) {
            if (!rb_obj_is_kind_of(v, bdb_cTxn)) {
                rb_raise(bdb_eFatal, "argument of txn must be a transaction");
            }
            Data_Get_Struct(v, bdb_TXN, txnst);
            dbst->txn = v;
            dbst->env = txnst->env;
        dbst->env_ptr = envst;
            Data_Get_Struct(txnst->env, bdb_ENV, envst);
            envp = envst->envp;
            dbst->options |= envst->options & BDB_NO_THREAD;
            dbst->marshal = txnst->marshal;
        }
        else if ((v = rb_hash_aref(f, rb_str_new2("env"))) != RHASH(f)->ifnone) {
            if (!rb_obj_is_kind_of(v, bdb_cEnv)) {
                rb_raise(bdb_eFatal, "argument of env must be an environnement");
            }
            Data_Get_Struct(v, bdb_ENV, envst);
            dbst->env = v;
        dbst->env_ptr = envst;
            envp = envst->envp;
            dbst->options |= envst->options & BDB_NO_THREAD;
            dbst->marshal = envst->marshal;
        }
#if HAVE_CONST_DB_ENCRYPT 
        if (envst && (envst->options & BDB_ENV_ENCRYPT)) {
            VALUE tmp = rb_str_new2("set_flags");
            if ((v = rb_hash_aref(f, rb_intern("set_flags"))) != RHASH(f)->ifnone) {
                rb_hash_aset(f, rb_intern("set_flags"), 
                             INT2NUM(NUM2INT(v) | DB_ENCRYPT));
            }
            else if ((v = rb_hash_aref(f, tmp)) != RHASH(f)->ifnone) {
                rb_hash_aset(f, tmp, INT2NUM(NUM2INT(v) | DB_ENCRYPT));
            }
            else {
                rb_hash_aset(f, tmp, INT2NUM(DB_ENCRYPT));
            }
        }
#endif
    }
#if HAVE_ST_DB_SET_ERRCALL
    bdb_test_error(db_create(&(dbst->dbp), envp, 0));
    dbst->dbp->set_errpfx(dbst->dbp, "BDB::");
    dbst->dbp->set_errcall(dbst->dbp, bdb_env_errcall);
#endif
    if (bdb_respond_to(obj, bdb_id_load) == Qtrue &&
        bdb_respond_to(obj, bdb_id_dump) == Qtrue) {
        dbst->marshal = obj;
        dbst->options |= BDB_MARSHAL;
    }
    if (rb_method_boundp(obj, rb_intern("bdb_store_key"), 0) == 1) {
        dbst->filter[FILTER_KEY] = INT2FIX(rb_intern("bdb_store_key"));
    }
    if (rb_method_boundp(obj, rb_intern("bdb_fetch_key"), 0) == 1) {
        dbst->filter[2 + FILTER_KEY] = INT2FIX(rb_intern("bdb_fetch_key"));
    }
    if (rb_method_boundp(obj, rb_intern("bdb_store_value"), 0) == 1) {
        dbst->filter[FILTER_VALUE] = INT2FIX(rb_intern("bdb_store_value"));
    }
    if (rb_method_boundp(obj, rb_intern("bdb_fetch_value"), 0) == 1) {
        dbst->filter[2 + FILTER_VALUE] = INT2FIX(rb_intern("bdb_fetch_value"));
    }
    rb_obj_call_init(res, argc, argv);
    if (txnst) {
        bdb_ary_push(&txnst->db_ary, res);
    bdb_ary_push(&txnst->db_objassoc_ary, (VALUE)create_assoc(res, dbst, BDB_OBJ_DB));
    }
    else if (envst) {
        bdb_ary_push(&envst->db_ary, res);
    bdb_ary_push(&envst->db_objassoc_ary, (VALUE)create_assoc(res, dbst, BDB_OBJ_DB));
    }
    return res;
}
new(p1 = v1, p2 = v2, p3 = v3, p4 = v4) click to toggle source
VALUE
bdb_init(int argc, VALUE *argv, VALUE obj)
{
    bdb_DB *dbst;
    DB *dbp;
    int flags, mode, ret, nb;
    char *name, *subname;
    VALUE a, b, d, e;
    VALUE hash_arg = Qnil;
#if HAVE_TYPE_DB_INFO
    DB_INFO dbinfo;

    MEMZERO(&dbinfo, DB_INFO, 1);
#endif
    Data_Get_Struct(obj, bdb_DB, dbst);
    dbp = dbst->dbp;
#if HAVE_TYPE_DB_INFO
    dbst->dbinfo = &dbinfo;
#endif
#if HAVE_ST_DB_SET_ENCRYPT
    if (rb_const_defined(CLASS_OF(obj), rb_intern("BDB_ENCRYPT"))) {
        char *passwd;
        int flags = DB_ENCRYPT_AES;
        VALUE value = rb_const_get(CLASS_OF(obj), rb_intern("BDB_ENCRYPT"));
        if (TYPE(value) == T_ARRAY) {
            if (RARRAY_LEN(value) != 2) {
                rb_raise(bdb_eFatal, "Expected an Array with 2 values");
            }
            passwd = StringValuePtr(RARRAY_PTR(value)[0]);
            flags = NUM2INT(RARRAY_PTR(value)[1]);
        }
        else {
            passwd = StringValuePtr(value);
        }
        bdb_test_error(dbp->set_encrypt(dbp, passwd, flags));
    }
#endif
    if (argc && TYPE(argv[argc - 1]) == T_HASH) {
        hash_arg = argv[argc - 1];
        rb_iterate(rb_each, argv[argc - 1], bdb_i_options, obj);
        argc--;
    }
    mode = flags = 0;
    if (argc) {
        flags = DB_RDONLY;
    }
    a = b = d = e = Qnil;
    switch(nb = rb_scan_args(argc, argv, "04", &a, &b, &d, &e)) {
    case 4:
        mode = NUM2INT(e);
    case 3:
        if (TYPE(d) == T_STRING) {
            if (strcmp(StringValuePtr(d), "r") == 0)
                flags = DB_RDONLY;
            else if (strcmp(StringValuePtr(d), "r+") == 0)
                flags = 0;
            else if (strcmp(StringValuePtr(d), "w") == 0 ||
                     strcmp(StringValuePtr(d), "w+") == 0)
                flags = DB_CREATE | DB_TRUNCATE;
            else if (strcmp(StringValuePtr(d), "a") == 0 ||
                     strcmp(StringValuePtr(d), "a+") == 0)
                flags = DB_CREATE;
            else {
                rb_raise(bdb_eFatal, "flags must be r, r+, w, w+, a or a+");
            }
        }
        else if (d == Qnil)
            flags = DB_RDONLY;
        else
            flags = NUM2INT(d);
    }
    name = subname = NULL;
    if (!NIL_P(a)) {
        SafeStringValue(a);
        name = StringValuePtr(a);
    }
    if (!NIL_P(b)) {
        SafeStringValue(b);
        subname = StringValuePtr(b);
    }
    if (dbst->bt_compare == 0 && rb_respond_to(obj, id_bt_compare) == Qtrue) {
        dbst->options |= BDB_BT_COMPARE;
#if HAVE_TYPE_DB_INFO
        dbst->dbinfo->bt_compare = bdb_bt_compare;
#else
        bdb_test_error(dbp->set_bt_compare(dbp, bdb_bt_compare));
#endif
    }
    if (dbst->bt_prefix == 0 && rb_respond_to(obj, id_bt_prefix) == Qtrue) {
        dbst->options |= BDB_BT_PREFIX;
#if HAVE_TYPE_DB_INFO
        dbst->dbinfo->bt_prefix = bdb_bt_prefix;
#else
        bdb_test_error(dbp->set_bt_prefix(dbp, bdb_bt_prefix));
#endif
    }
#if HAVE_CONST_DB_DUPSORT
    if (dbst->dup_compare == 0 && rb_respond_to(obj, id_dup_compare) == Qtrue) {
        dbst->options |= BDB_DUP_COMPARE;
#if HAVE_TYPE_DB_INFO
        dbst->dbinfo->dup_compare = bdb_dup_compare;
#else
        bdb_test_error(dbp->set_dup_compare(dbp, bdb_dup_compare));
#endif
    }
#endif
    if (dbst->h_hash == 0 && rb_respond_to(obj, id_h_hash) == Qtrue) {
        dbst->options |= BDB_H_HASH;
#if HAVE_TYPE_DB_INFO
        dbst->dbinfo->h_hash = bdb_h_hash;
#else
        bdb_test_error(dbp->set_h_hash(dbp, bdb_h_hash));
#endif
    }
#if HAVE_ST_DB_SET_H_COMPARE
    if (dbst->h_compare == 0 && rb_respond_to(obj, id_h_compare) == Qtrue) {
        dbst->options |= BDB_H_COMPARE;
        bdb_test_error(dbp->set_h_compare(dbp, bdb_h_compare));
    }
#endif
#if HAVE_ST_DB_SET_APPEND_RECNO
    if (dbst->append_recno == 0 && rb_respond_to(obj, id_append_recno) == Qtrue) {
        dbst->options |= BDB_APPEND_RECNO;
        bdb_test_error(dbp->set_append_recno(dbp, bdb_append_recno));
    }
#endif
#if HAVE_ST_DB_SET_FEEDBACK
    if (dbst->feedback == 0 && rb_respond_to(obj, id_feedback) == Qtrue) {
        dbp->set_feedback(dbp, bdb_feedback);
        dbst->options |= BDB_FEEDBACK;
    }
#endif
    if (flags & DB_TRUNCATE) {
        rb_secure(2);
    }
    if (flags & DB_CREATE) {
        rb_secure(4);
    }
    if (rb_safe_level() >= 4) {
        flags |= DB_RDONLY;
    }
#if HAVE_CONST_DB_DUPSORT
    if (dbst->options & BDB_DUP_COMPARE) {
#if HAVE_TYPE_DB_INFO
        dbst->dbinfo->flags = DB_DUP | DB_DUPSORT;
#else
        bdb_test_error(dbp->set_flags(dbp, DB_DUP | DB_DUPSORT));
#endif
    }
#endif
#ifndef BDB_NO_THREAD_COMPILE
    if (!(dbst->options & (BDB_RE_SOURCE | BDB_NO_THREAD))) {
        flags |= DB_THREAD;
    }
#endif
    if (dbst->options & BDB_NEED_CURRENT) {
        rb_thread_local_aset(rb_thread_current(), bdb_id_current_db, obj);
    }

#if ! HAVE_ST_DB_OPEN
    {
        bdb_ENV *envst;
        DB_ENV *envp = NULL;
        if (dbst->env) {
            Data_Get_Struct(dbst->env, bdb_ENV, envst);
            envp = envst->envp;
        }

        if (name == NULL && (flags & DB_RDONLY)) {
            flags &= ~DB_RDONLY;
        }
            
        if ((ret = db_open(name, dbst->type, flags, mode, envp,
                           dbst->dbinfo, &dbp)) != 0) {
            if (bdb_errcall) {
                bdb_errcall = 0;
                rb_raise(bdb_eFatal, "%s -- %s", StringValuePtr(bdb_errstr), db_strerror(ret));
            }
            else
                rb_raise(bdb_eFatal, "%s", db_strerror(ret));
        }
        dbst->dbp = dbp;
    }
#else
    {
#if HAVE_DB_OPEN_7
        DB_TXN *txnid = NULL;
#endif

        if (name == NULL && subname == NULL) {
            if (flags & DB_RDONLY) {
                flags &= ~DB_RDONLY;
            }
#if HAVE_DB_OPEN_7 
#if HAVE_DB_OPEN_7_DB_CREATE
            flags |= DB_CREATE;
#endif
#endif
        }
#if HAVE_DB_OPEN_7
        if (RTEST(dbst->txn)) {
            bdb_TXN *txnst;

            GetTxnDB(dbst->txn, txnst);
            txnid = txnst->txnid;
        }
        else if (RTEST(dbst->env)) {
            bdb_ENV *envst;

            GetEnvDB(dbst->env, envst);
#if HAVE_CONST_DB_AUTO_COMMIT
            if (envst->options & BDB_AUTO_COMMIT) {
                flags |= DB_AUTO_COMMIT;
                dbst->options |= BDB_AUTO_COMMIT;
            }
        }
#endif
        ret = dbp->open(dbp, txnid, name, subname, dbst->type, flags, mode);
#else
        ret = dbp->open(dbp, name, subname, dbst->type, flags, mode);
#endif
        if (ret != 0) {
            dbp->close(dbp, 0);
            if (bdb_errcall) {
                bdb_errcall = 0;
                rb_raise(bdb_eFatal, "%s -- %s", StringValuePtr(bdb_errstr), db_strerror(ret));
            }
            else {
                rb_raise(bdb_eFatal, "%s", db_strerror(ret));
            }
        }
    }
#endif
    dbst->options &= ~BDB_NOT_OPEN;
    if (dbst->env) {
        bdb_ENV *envst;
        Data_Get_Struct(dbst->env, bdb_ENV, envst);
        dbst->options |= envst->options & BDB_INIT_LOCK;
    }
    dbst->filename = dbst->database = Qnil;
    if (name) {
        dbst->filename = rb_tainted_str_new2(name);
        OBJ_FREEZE(dbst->filename);
    }
#if HAVE_ST_DB_OPEN
    if (subname) {
        dbst->database = rb_tainted_str_new2(subname);
        OBJ_FREEZE(dbst->database);
    }
#endif
    dbst->len = -2;
    if (dbst->type == DB_UNKNOWN) {
#if ! HAVE_ST_DB_GET_TYPE
        dbst->type = dbst->dbp->type;
#else
#if HAVE_TYPE_DBTYPE
        {
            DBTYPE new_type;
#if HAVE_DB_GET_TYPE_2
            bdb_test_error(dbst->dbp->get_type(dbst->dbp, &new_type));
#else
            new_type = dbst->dbp->get_type(dbst->dbp);
#endif
            dbst->type = (int)new_type;
        }
#else
        dbst->type = dbst->dbp->get_type(dbst->dbp);
#endif
#endif
        switch(dbst->type) {
        case DB_BTREE:
            rb_obj_reveal(obj, bdb_cBtree);
            break;
        case DB_HASH:
            rb_obj_reveal(obj, bdb_cHash);
            break;
        case DB_RECNO:
        {
            long count;

            rb_warning("It's hard to distinguish Recnum with Recno for all versions of Berkeley DB");
            if ((count = bdb_is_recnum(dbst->dbp)) != -1) {
                rb_obj_reveal(obj, bdb_cRecnum);
                dbst->len = count;
            }
            else {
                rb_obj_reveal(obj, bdb_cRecno);
            }
            break;
        }
#if HAVE_CONST_DB_QUEUE
        case DB_QUEUE:
            rb_obj_reveal(obj, bdb_cQueue);
            break;
#endif
        default:
            dbst->dbp->close(dbst->dbp, 0);
            dbst->dbp = NULL;
            rb_raise(bdb_eFatal, "Unknown DB type");
        }
    }
    if (dbst->len == -2 && rb_obj_is_kind_of(obj, bdb_cRecnum)) {
        long count;

        if ((count = bdb_is_recnum(dbst->dbp)) != -1) {
            VALUE len = bdb_recno_length(obj);
            dbst->len = NUM2LONG(len);
        }
        else {
            if (flags & DB_TRUNCATE) {
                dbst->len = 0;
            }
            else {
                dbst->dbp->close(dbst->dbp, 0);
                dbst->dbp = NULL;
                rb_raise(bdb_eFatal, "database is not a Recnum");
            }
        }
    }
#if HAVE_ST_DB_APP_PRIVATE
    dbst->dbp->app_private = (void *)obj;
#endif
    return obj;
}
open(*args) click to toggle source
static VALUE
bdb_s_open(int argc, VALUE *argv, VALUE obj)
{
    VALUE res = rb_funcall2(obj, rb_intern("new"), argc, argv);
    if (rb_block_given_p()) {
        return rb_ensure(rb_yield, res, bdb_protect_close, res);
    }
    return res;
}
remove(p1, p2 = v2) click to toggle source
static VALUE
bdb_s_remove(int argc, VALUE *argv, VALUE obj)
{
    bdb_DB *dbst;
    VALUE a, b, c;
    char *name, *subname;

    rb_secure(2);
    c = bdb_i_create(obj);
    GetDB(c, dbst);
    name = subname = NULL;
    a = b = Qnil;
    if (rb_scan_args(argc, argv, "11", &a, &b) == 2) {
        if (!NIL_P(b)) {
            SafeStringValue(b);
            subname = StringValuePtr(b);
        }
    }
    SafeStringValue(a);
    name = StringValuePtr(a);
    bdb_test_error(dbst->dbp->remove(dbst->dbp, name, subname, 0));
    return Qtrue;
}
rename(p1, p2, p3) click to toggle source
static VALUE
bdb_s_rename(int argc, VALUE *argv, VALUE obj)
{
    bdb_DB *dbst;
    VALUE a, b, c;
    char *name, *subname, *newname;

    rb_secure(2);
    c = bdb_i_create(obj);
    GetDB(c, dbst);
    name = subname = NULL;
    a = b = c = Qnil;
    rb_scan_args(argc, argv, "30", &a, &b, &c);
    if (!NIL_P(b)) {
        SafeStringValue(b);
        subname = StringValuePtr(b);
    }
    SafeStringValue(a);
    SafeStringValue(c);
    name = StringValuePtr(a);
    newname = StringValuePtr(c);
    bdb_test_error(dbst->dbp->rename(dbst->dbp, name, subname, newname, 0));
    return Qtrue;
}
upgrade(p1, p2 = v2) click to toggle source
static VALUE
bdb_s_upgrade(int argc, VALUE *argv, VALUE obj)
{
#if HAVE_ST_DB_UPGRADE
    bdb_DB *dbst;
    VALUE a, b;
    int flags;
    VALUE val;

    rb_secure(4);
    flags = 0;
    if (rb_scan_args(argc, argv, "11", &a, &b) == 2) {
        flags = NUM2INT(b);
    }
    SafeStringValue(a);
    val = bdb_i_create(obj);
    GetDB(val, dbst);
    bdb_test_error(dbst->dbp->upgrade(dbst->dbp, StringValuePtr(a), flags));
    return val;
#else
    rb_raise(bdb_eFatal, "You can't upgrade a database with this version of DB");
#endif
}

Public Instance Methods

[](*args) click to toggle source
static VALUE
bdb_get_dyna(int argc, VALUE *argv, VALUE obj)
{
    return bdb_get_internal(argc, argv, obj, Qnil, 1);
}
[]=(p1, p2) click to toggle source
static VALUE
bdb_aset(obj, a, b)
    VALUE obj, a, b;
{
    VALUE tmp[2];
    tmp[0] = a;
    tmp[1] = b;
    bdb_put(2, tmp, obj);
    return b;
}
associate(p1, p2 = v2) click to toggle source
static VALUE
bdb_associate(int argc, VALUE *argv, VALUE obj)
{
    bdb_DB *dbst, *secondst;
    VALUE second, flag;
    int flags = 0;

    if (!rb_block_given_p()) {
        rb_raise(bdb_eFatal, "call out of an iterator");
    }
    if (rb_scan_args(argc, argv, "11", &second, &flag) == 2) {
        flags = NUM2INT(flag);
    }
    if (!rb_obj_is_kind_of(second, bdb_cCommon)) {
        rb_raise(bdb_eFatal, "associate expect a BDB object");
    }
    GetDB(second, secondst);
    if (RTEST(secondst->secondary)) {
        rb_raise(bdb_eFatal, "associate with a primary index");
    }
    GetDB(obj, dbst);

    dbst->options |= BDB_NEED_CURRENT;
    if (!dbst->secondary) {
        dbst->secondary = rb_ary_new();
    }
    rb_thread_local_aset(rb_thread_current(), bdb_id_current_db, obj);
#if HAVE_RB_BLOCK_PROC
    rb_ary_push(dbst->secondary, rb_assoc_new(second, rb_block_proc()));
#else
    rb_ary_push(dbst->secondary, rb_assoc_new(second, rb_f_lambda()));
#endif
    secondst->secondary = Qnil;

#if HAVE_DB_ASSOCIATE_TXN
    {
        DB_TXN *txnid = NULL;
        if (RTEST(dbst->txn)) {
            bdb_TXN *txnst;

            GetTxnDB(dbst->txn, txnst);
            txnid = txnst->txnid;
        }
#if HAVE_CONST_DB_AUTO_COMMIT
        else if (dbst->options & BDB_AUTO_COMMIT) {
          flags |= DB_AUTO_COMMIT;
        }
#endif
        bdb_test_error(dbst->dbp->associate(dbst->dbp, txnid, secondst->dbp, 
                                            bdb_call_secondary, flags));
    }
#else
    bdb_test_error(dbst->dbp->associate(dbst->dbp, secondst->dbp, 
                                        bdb_call_secondary, flags));
#endif
    return obj;
}
both?(p1, p2) click to toggle source
static VALUE
bdb_has_both(obj, a, b)
    VALUE obj, a, b;
{
#if ! HAVE_CONST_DB_GET_BOTH
    return bdb_has_both_internal(obj, a, b, Qfalse);
#else
    bdb_DB *dbst;
    DB_TXN *txnid;
    DBT key, data;
    int ret, flags;
    db_recno_t recno;
    volatile VALUE c = Qnil;
    volatile VALUE d = Qnil;
    void *tmp_key, *tmp_data;

    INIT_TXN(txnid, obj, dbst);
#if CANT_DB_CURSOR_GET_BOTH
    if (RECNUM_TYPE(dbst)) {
        return bdb_has_both_internal(obj, a, b, Qfalse);
    }
#endif
    MEMZERO(&key, DBT, 1);
    MEMZERO(&data, DBT, 1);
    c = bdb_test_recno(obj, &key, &recno, a);
    d = bdb_test_dump(obj, &data, b, FILTER_VALUE);
    data.flags |= DB_DBT_MALLOC;
    SET_PARTIAL(dbst, data);
    flags = DB_GET_BOTH | TEST_INIT_LOCK(dbst);
    tmp_key = key.data;
    tmp_data = data.data;
#if HAVE_ST_DB_OPEN
#if HAVE_DB_KEY_DBT_MALLOC
    key.flags |= DB_DBT_MALLOC;
#endif
#endif
    ret = bdb_test_error(dbst->dbp->get(dbst->dbp, txnid, &key, &data, flags));
    if (ret == DB_NOTFOUND || ret == DB_KEYEMPTY)
        return Qfalse;
    if (tmp_data != data.data) {
        free(data.data);
    }
    if ((key.flags & DB_DBT_MALLOC) && tmp_key != key.data) {
        free(key.data);
    }
    return Qtrue;
#endif
}
byteswapped?() click to toggle source
static VALUE
bdb_byteswapp(obj)
    VALUE obj;
{
    bdb_DB *dbst;
    int byteswap = 0;

    GetDB(obj, dbst);
#if HAVE_ST_DB_BYTESWAPPED
    return dbst->dbp->byteswapped?Qtrue:Qfalse;
#elif HAVE_DB_GET_BYTESWAPPED_2
    dbst->dbp->get_byteswapped(dbst->dbp, &byteswap);
    return byteswap?Qtrue:Qfalse;
#else
    return dbst->dbp->get_byteswapped(dbst->dbp)?Qtrue:Qfalse;
#endif
}
cache_priority() click to toggle source
static VALUE
bdb_cache_priority_get(VALUE obj)
{
    bdb_DB *dbst;
    GetDB(obj, dbst);
    return INT2FIX(dbst->priority);
}
cache_priority=(p1) click to toggle source
static VALUE
bdb_cache_priority_set(VALUE obj, VALUE a)
{
    int priority;
    bdb_DB *dbst;
    GetDB(obj, dbst);
    priority = dbst->priority;
    bdb_test_error(dbst->dbp->set_cache_priority(dbst->dbp, NUM2INT(a)));
    dbst->priority = NUM2INT(a);
    return INT2FIX(priority);
}
clear(*args) click to toggle source
VALUE
bdb_clear(int argc, VALUE *argv, VALUE obj)
{
#if HAVE_ST_DB_TRUNCATE
    bdb_DB *dbst;
    DB_TXN *txnid;
    unsigned int count = 0;
#endif
    int flags = 0;

    rb_secure(4);
#if HAVE_ST_DB_TRUNCATE
    INIT_TXN(txnid, obj, dbst);
#if HAVE_CONST_DB_AUTO_COMMIT
    if (txnid == NULL && (dbst->options & BDB_AUTO_COMMIT)) {
      flags |= DB_AUTO_COMMIT;
    }
#endif
    bdb_test_error(dbst->dbp->truncate(dbst->dbp, txnid, &count, flags));
    return INT2NUM(count);
#else
    flags = 0;
    if (argc && TYPE(argv[argc - 1]) == T_HASH) {
        VALUE g, f = argv[argc - 1];
        if ((g = rb_hash_aref(f, rb_intern("flags"))) != RHASH(f)->ifnone ||
            (g = rb_hash_aref(f, rb_str_new2("flags"))) != RHASH(f)->ifnone) {
            flags = NUM2INT(g);
        }
        argc--;
    }
    if (argc) {
        flags = NUM2INT(argv[0]);
    }
    return bdb_lgth_intern(obj, Qtrue, flags);
#endif
}
clear_partial() click to toggle source
static VALUE
bdb_clear_partial(obj)
    VALUE obj;
{
    bdb_DB *dbst;
    VALUE ret;

    GetDB(obj, dbst);
    if (dbst->marshal) {
        rb_raise(bdb_eFatal, "set_partial is not implemented with Marshal");
    }
    ret = rb_ary_new2(3);
    rb_ary_push(ret, (dbst->partial == DB_DBT_PARTIAL)?Qtrue:Qfalse);
    rb_ary_push(ret, INT2NUM(dbst->doff));
    rb_ary_push(ret, INT2NUM(dbst->dlen));
    dbst->doff = dbst->dlen = dbst->partial = 0;
    return ret;
}
close(p1 = v1) click to toggle source
static VALUE
bdb_close(int argc, VALUE *argv, VALUE obj)
{
    VALUE opt;
    bdb_DB *dbst;
    int flags = 0;

    if (!OBJ_TAINTED(obj) && rb_safe_level() >= 4) {
        rb_raise(rb_eSecurityError, "Insecure: can't close the database");
    }
    Data_Get_Struct(obj, bdb_DB, dbst);
    if (dbst->dbp != NULL) {
        if (rb_scan_args(argc, argv, "01", &opt)) {
            flags = NUM2INT(opt);
        }
        bdb_i_close(dbst, flags);
    }
    if (RDATA(obj)->dfree != free) {
        dbst->options |= BDB_NOT_OPEN;
        bdb_final_aref(dbst);
        RDATA(obj)->dfree = free;
    }
    return Qnil;
}
conf(*args) click to toggle source
static VALUE
bdb_conf(int argc, VALUE *argv, VALUE obj)
{
    int i, state;
    VALUE res, val;
    struct optst opt;

    if (argc > 1) {
        rb_raise(rb_eArgError, "invalid number of arguments (%d for 1)", argc);
    }
    if (argc == 1) {
        return bdb_i_conf(obj, argv[0]);
    }
    res = rb_hash_new();
    opt.obj = obj;
    for (i = 0; options[i] != NULL; i++) {
        opt.str = rb_str_new2(options[i]);
        val = rb_protect(bdb_intern_conf, (VALUE)&opt, &state);
        if (state == 0) {
            rb_hash_aset(res, opt.str, val);
        }
    }
    return res;
}
configuration(*args) click to toggle source
static VALUE
bdb_conf(int argc, VALUE *argv, VALUE obj)
{
    int i, state;
    VALUE res, val;
    struct optst opt;

    if (argc > 1) {
        rb_raise(rb_eArgError, "invalid number of arguments (%d for 1)", argc);
    }
    if (argc == 1) {
        return bdb_i_conf(obj, argv[0]);
    }
    res = rb_hash_new();
    opt.obj = obj;
    for (i = 0; options[i] != NULL; i++) {
        opt.str = rb_str_new2(options[i]);
        val = rb_protect(bdb_intern_conf, (VALUE)&opt, &state);
        if (state == 0) {
            rb_hash_aset(res, opt.str, val);
        }
    }
    return res;
}
count(p1) click to toggle source
static VALUE
bdb_count(obj, a)
    VALUE obj, a;
{
    bdb_DB *dbst;
    DB_TXN *txnid;
    DBC *dbcp;
    DBT key, data;
    int ret, flags27;
    db_recno_t recno;
    db_recno_t count;
    volatile VALUE b = Qnil;

    INIT_TXN(txnid, obj, dbst);
    MEMZERO(&key, DBT, 1);
    b = bdb_test_recno(obj, &key, &recno, a);
    MEMZERO(&data, DBT, 1);
    data.flags |= DB_DBT_MALLOC;
    SET_PARTIAL(dbst, data);
#if HAVE_DB_CURSOR_4
    bdb_test_error(dbst->dbp->cursor(dbst->dbp, txnid, &dbcp, 0));
#else
    bdb_test_error(dbst->dbp->cursor(dbst->dbp, txnid, &dbcp));
#endif
    flags27 = TEST_INIT_LOCK(dbst);
    bdb_cache_error(dbcp->c_get(dbcp, &key, &data, DB_SET | flags27),
                    dbcp->c_close(dbcp), ret);
    if (ret == DB_NOTFOUND) {
        dbcp->c_close(dbcp);
        return INT2NUM(0);
    }
#if HAVE_ST_DBC_C_COUNT
    bdb_cache_error(dbcp->c_count(dbcp, &count, 0), dbcp->c_close(dbcp), ret);
    dbcp->c_close(dbcp);
    return INT2NUM(count);
#else
    count = 1;
    while (1) {
        MEMZERO(&data, DBT, 1);
        data.flags |= DB_DBT_MALLOC;
        SET_PARTIAL(dbst, data);
        bdb_cache_error(dbcp->c_get(dbcp, &key, &data, DB_NEXT_DUP | flags27),
                        dbcp->c_close(dbcp), ret);
        if (ret == DB_NOTFOUND) {
            dbcp->c_close(dbcp);
            return INT2NUM(count);
        }
        if (ret == DB_KEYEMPTY) continue;
        FREE_KEY(dbst, key);
        if (data.flags & DB_DBT_MALLOC) {
            free(data.data);
            data.data = 0;
        }
        count++;
    }
    return INT2NUM(-1);
#endif
}
database() click to toggle source
static VALUE
bdb_database(obj)
    VALUE obj;
{
    bdb_DB *dbst;
    GetDB(obj, dbst);
    return dbst->database;
}
db_close(p1 = v1) click to toggle source
static VALUE
bdb_close(int argc, VALUE *argv, VALUE obj)
{
    VALUE opt;
    bdb_DB *dbst;
    int flags = 0;

    if (!OBJ_TAINTED(obj) && rb_safe_level() >= 4) {
        rb_raise(rb_eSecurityError, "Insecure: can't close the database");
    }
    Data_Get_Struct(obj, bdb_DB, dbst);
    if (dbst->dbp != NULL) {
        if (rb_scan_args(argc, argv, "01", &opt)) {
            flags = NUM2INT(opt);
        }
        bdb_i_close(dbst, flags);
    }
    if (RDATA(obj)->dfree != free) {
        dbst->options |= BDB_NOT_OPEN;
        bdb_final_aref(dbst);
        RDATA(obj)->dfree = free;
    }
    return Qnil;
}
db_del(p1) click to toggle source
VALUE
bdb_del(obj, a)
    VALUE a, obj;
{
    bdb_DB *dbst;
    DB_TXN *txnid;
    int flag = 0;
    DBT key;
    int ret;
    db_recno_t recno;
    volatile VALUE b = Qnil;

    rb_secure(4);
    INIT_TXN(txnid, obj, dbst);
#if HAVE_CONST_DB_AUTO_COMMIT
    if (txnid == NULL && (dbst->options & BDB_AUTO_COMMIT)) {
        flag |= DB_AUTO_COMMIT;
    }
#endif
    MEMZERO(&key, DBT, 1);
    b = bdb_test_recno(obj, &key, &recno, a);
    ret = bdb_test_error(dbst->dbp->del(dbst->dbp, txnid, &key, flag));
    if (ret == DB_NOTFOUND || ret == DB_KEYEMPTY)
        return Qnil;
    else
        return obj;
}
db_get(*args) click to toggle source
static VALUE
bdb_get_dyna(int argc, VALUE *argv, VALUE obj)
{
    return bdb_get_internal(argc, argv, obj, Qnil, 1);
}
db_pget(p1, p2 = v2, p3 = v3) click to toggle source
static VALUE
bdb_pget(int argc, VALUE *argv, VALUE obj)
{
    VALUE a = Qnil;
    VALUE b = Qnil;
    VALUE c;
    bdb_DB *dbst;
    DB_TXN *txnid;
    DBT pkey, data, skey;
    int flagss;
    int ret, flags;
    db_recno_t srecno;
    void *tmp_data = 0;

    INIT_TXN(txnid, obj, dbst);
    flagss = flags = 0;
    MEMZERO(&skey, DBT, 1);
    MEMZERO(&pkey, DBT, 1);
    MEMZERO(&data, DBT, 1);
    data.flags |= DB_DBT_MALLOC;
    pkey.flags |= DB_DBT_MALLOC;
    switch(rb_scan_args(argc, argv, "12", &a, &b, &c)) {
    case 3:
        flags = NUM2INT(c);
        if ((flags & ~DB_RMW) == DB_GET_BOTH) {
            b = bdb_test_dump(obj, &data, b, FILTER_VALUE);
            data.flags |= DB_DBT_MALLOC;
            tmp_data = data.data;
        }
        break;
    case 2:
        flagss = flags = NUM2INT(b);
        break;
    }
    a = bdb_test_recno(obj, &skey, &srecno, a);
    SET_PARTIAL(dbst, data);
    flags |= TEST_INIT_LOCK(dbst);
    ret = bdb_test_error(dbst->dbp->pget(dbst->dbp, txnid, &skey, &pkey, &data, flags));
    if (ret == DB_NOTFOUND || ret == DB_KEYEMPTY)
        return Qnil;
    if (((flags & ~DB_RMW) == DB_GET_BOTH) ||
        ((flags & ~DB_RMW) == DB_SET_RECNO)) {
        if ((data.flags & DB_DBT_MALLOC) && tmp_data == data.data) {
            data.flags &= ~DB_DBT_MALLOC;
        }
        return bdb_assoc2(obj, &skey, &pkey, &data);
    }
    return bdb_assoc(obj, &pkey, &data);
}
db_put(p1, p2, p3 = v3) click to toggle source
VALUE
bdb_put(int argc, VALUE *argv, VALUE obj)
{
    volatile VALUE a0 = Qnil;
    volatile VALUE b0 = Qnil;
    VALUE a, b, c;
    bdb_DB *dbst;
    DB_TXN *txnid;
    DBT key, data;
    int ret, flags;
    db_recno_t recno;

    rb_secure(4);
    INIT_TXN(txnid, obj, dbst);
    flags = 0;
    a = b = c = Qnil;
    MEMZERO(&key, DBT, 1);
    MEMZERO(&data, DBT, 1);
    if (rb_scan_args(argc, argv, "21", &a, &b, &c) == 3) {
        flags = NUM2INT(c);
    }
    a0 = bdb_test_recno(obj, &key, &recno, a);
    b0 = bdb_test_dump(obj, &data, b, FILTER_VALUE);
    SET_PARTIAL(dbst, data);
#if HAVE_CONST_DB_QUEUE
    if (dbst->type == DB_QUEUE && dbst->re_len < data.size) {
        rb_raise(bdb_eFatal, "size > re_len for Queue");
    }
#endif
#if HAVE_CONST_DB_AUTO_COMMIT
    if (txnid == NULL && (dbst->options & BDB_AUTO_COMMIT)) {
      flags |= DB_AUTO_COMMIT;
    }
#endif
    ret = bdb_test_error(dbst->dbp->put(dbst->dbp, txnid, &key, &data, flags));
    if (ret == DB_KEYEXIST)
        return Qfalse;
    else {
        if (dbst->partial) {
            if (flags & DB_APPEND) {
                a = INT2NUM((long)key.data);
            }
            return bdb_get(1, &a, obj);
        }
        else {
            return bdb_test_ret(obj, b0, b, FILTER_VALUE);
        }
    }
}
db_sync() click to toggle source
static VALUE
bdb_sync(obj)
    VALUE obj;
{
    bdb_DB *dbst;

    if (!OBJ_TAINTED(obj) && rb_safe_level() >= 4)
        rb_raise(rb_eSecurityError, "Insecure: can't sync the database");
    GetDB(obj, dbst);
    bdb_test_error(dbst->dbp->sync(dbst->dbp, 0));
    return Qtrue;
}
del(p1) click to toggle source
VALUE
bdb_del(obj, a)
    VALUE a, obj;
{
    bdb_DB *dbst;
    DB_TXN *txnid;
    int flag = 0;
    DBT key;
    int ret;
    db_recno_t recno;
    volatile VALUE b = Qnil;

    rb_secure(4);
    INIT_TXN(txnid, obj, dbst);
#if HAVE_CONST_DB_AUTO_COMMIT
    if (txnid == NULL && (dbst->options & BDB_AUTO_COMMIT)) {
        flag |= DB_AUTO_COMMIT;
    }
#endif
    MEMZERO(&key, DBT, 1);
    b = bdb_test_recno(obj, &key, &recno, a);
    ret = bdb_test_error(dbst->dbp->del(dbst->dbp, txnid, &key, flag));
    if (ret == DB_NOTFOUND || ret == DB_KEYEMPTY)
        return Qnil;
    else
        return obj;
}
delete(p1) click to toggle source
VALUE
bdb_del(obj, a)
    VALUE a, obj;
{
    bdb_DB *dbst;
    DB_TXN *txnid;
    int flag = 0;
    DBT key;
    int ret;
    db_recno_t recno;
    volatile VALUE b = Qnil;

    rb_secure(4);
    INIT_TXN(txnid, obj, dbst);
#if HAVE_CONST_DB_AUTO_COMMIT
    if (txnid == NULL && (dbst->options & BDB_AUTO_COMMIT)) {
        flag |= DB_AUTO_COMMIT;
    }
#endif
    MEMZERO(&key, DBT, 1);
    b = bdb_test_recno(obj, &key, &recno, a);
    ret = bdb_test_error(dbst->dbp->del(dbst->dbp, txnid, &key, flag));
    if (ret == DB_NOTFOUND || ret == DB_KEYEMPTY)
        return Qnil;
    else
        return obj;
}
delete_if(*args) click to toggle source
static VALUE
bdb_delete_if(int argc, VALUE *argv, VALUE obj)
{
    return bdb_each_kvc(argc, argv, obj, DB_NEXT, Qfalse, BDB_ST_DELETE | BDB_ST_ONE);
}
dup_count(p1) click to toggle source
static VALUE
bdb_count(obj, a)
    VALUE obj, a;
{
    bdb_DB *dbst;
    DB_TXN *txnid;
    DBC *dbcp;
    DBT key, data;
    int ret, flags27;
    db_recno_t recno;
    db_recno_t count;
    volatile VALUE b = Qnil;

    INIT_TXN(txnid, obj, dbst);
    MEMZERO(&key, DBT, 1);
    b = bdb_test_recno(obj, &key, &recno, a);
    MEMZERO(&data, DBT, 1);
    data.flags |= DB_DBT_MALLOC;
    SET_PARTIAL(dbst, data);
#if HAVE_DB_CURSOR_4
    bdb_test_error(dbst->dbp->cursor(dbst->dbp, txnid, &dbcp, 0));
#else
    bdb_test_error(dbst->dbp->cursor(dbst->dbp, txnid, &dbcp));
#endif
    flags27 = TEST_INIT_LOCK(dbst);
    bdb_cache_error(dbcp->c_get(dbcp, &key, &data, DB_SET | flags27),
                    dbcp->c_close(dbcp), ret);
    if (ret == DB_NOTFOUND) {
        dbcp->c_close(dbcp);
        return INT2NUM(0);
    }
#if HAVE_ST_DBC_C_COUNT
    bdb_cache_error(dbcp->c_count(dbcp, &count, 0), dbcp->c_close(dbcp), ret);
    dbcp->c_close(dbcp);
    return INT2NUM(count);
#else
    count = 1;
    while (1) {
        MEMZERO(&data, DBT, 1);
        data.flags |= DB_DBT_MALLOC;
        SET_PARTIAL(dbst, data);
        bdb_cache_error(dbcp->c_get(dbcp, &key, &data, DB_NEXT_DUP | flags27),
                        dbcp->c_close(dbcp), ret);
        if (ret == DB_NOTFOUND) {
            dbcp->c_close(dbcp);
            return INT2NUM(count);
        }
        if (ret == DB_KEYEMPTY) continue;
        FREE_KEY(dbst, key);
        if (data.flags & DB_DBT_MALLOC) {
            free(data.data);
            data.data = 0;
        }
        count++;
    }
    return INT2NUM(-1);
#endif
}
duplicates(*args) click to toggle source
static VALUE
bdb_common_dups(int argc, VALUE *argv, VALUE obj)
{
    int flags = BDB_ST_DUPKV;
    VALUE result = rb_ary_new();
    if (argc > 1) {
        if (RTEST(argv[argc - 1])) {
            flags = BDB_ST_DUPKV;
        }
        else {
            flags = BDB_ST_DUPVAL;
        }
        argc--;
    }
    return bdb_each_kvc(argc, argv, obj, DB_NEXT_DUP, result, flags);
}
dups(*args) click to toggle source
static VALUE
bdb_common_dups(int argc, VALUE *argv, VALUE obj)
{
    int flags = BDB_ST_DUPKV;
    VALUE result = rb_ary_new();
    if (argc > 1) {
        if (RTEST(argv[argc - 1])) {
            flags = BDB_ST_DUPKV;
        }
        else {
            flags = BDB_ST_DUPVAL;
        }
        argc--;
    }
    return bdb_each_kvc(argc, argv, obj, DB_NEXT_DUP, result, flags);
}
each(*args) click to toggle source
static VALUE
bdb_each_pair(int argc, VALUE *argv, VALUE obj) 
{
    return bdb_each_kvc(argc, argv, obj, DB_NEXT, Qfalse, BDB_ST_KV);
}
each_dup(*args) click to toggle source
static VALUE
bdb_common_each_dup(int argc, VALUE *argv, VALUE obj)
{
    if (!rb_block_given_p()) {
        rb_raise(bdb_eFatal, "each_dup called out of an iterator");
    }
    return bdb_each_kvc(argc, argv, obj, DB_NEXT_DUP, Qfalse, BDB_ST_DUPKV);
}
each_dup_value(*args) click to toggle source
static VALUE
bdb_common_each_dup_val(int argc, VALUE *argv, VALUE obj)
{
    if (!rb_block_given_p()) {
        rb_raise(bdb_eFatal, "each_dup called out of an iterator");
    }
    return bdb_each_kvc(argc, argv, obj, DB_NEXT_DUP, Qfalse, BDB_ST_DUPVAL);
}
each_key(*args) click to toggle source
VALUE
bdb_each_key(int argc, VALUE *argv, VALUE obj)
{ 
    return bdb_each_kvc(argc, argv, obj, DB_NEXT, Qfalse, BDB_ST_KEY); 
}
each_pair(*args) click to toggle source
static VALUE
bdb_each_pair(int argc, VALUE *argv, VALUE obj) 
{
    return bdb_each_kvc(argc, argv, obj, DB_NEXT, Qfalse, BDB_ST_KV);
}
each_primary(p1 = v1) click to toggle source
static VALUE
bdb_each_pair_prim(int argc, VALUE *argv, VALUE obj) 
{
    VALUE tmp[2] = {Qnil, Qtrue};
    rb_scan_args(argc, argv, "01", tmp);
    return bdb_each_kvc(2, tmp, obj, DB_NEXT, Qfalse, BDB_ST_KV);
}
each_value(*args) click to toggle source
VALUE
bdb_each_value(int argc, VALUE *argv, VALUE obj)
{ 
    return bdb_each_kvc(argc, argv, obj, DB_NEXT, Qfalse, BDB_ST_VALUE);
}
empty?() click to toggle source
static VALUE
bdb_empty(obj)
    VALUE obj;
{
    bdb_DB *dbst;
    DB_TXN *txnid;
    DBC *dbcp;
    DBT key, data;
    int ret, flags;
    db_recno_t recno;

    INIT_TXN(txnid, obj, dbst);
    MEMZERO(&key, DBT, 1);
    INIT_RECNO(dbst, key, recno);
    MEMZERO(&data, DBT, 1);
    data.flags = DB_DBT_MALLOC;
#if HAVE_DB_CURSOR_4
    bdb_test_error(dbst->dbp->cursor(dbst->dbp, txnid, &dbcp, 0));
#else
    bdb_test_error(dbst->dbp->cursor(dbst->dbp, txnid, &dbcp));
#endif
    SET_PARTIAL(dbst, data);
    flags = TEST_INIT_LOCK(dbst);
    bdb_cache_error(dbcp->c_get(dbcp, &key, &data, DB_FIRST | flags),
                    dbcp->c_close(dbcp), ret);
    if (ret == DB_NOTFOUND) {
        dbcp->c_close(dbcp);
        return Qtrue;
    }
    FREE_KEY(dbst, key);
    free(data.data);
    dbcp->c_close(dbcp);
    return Qfalse;
}
env() click to toggle source
static VALUE
bdb_env(VALUE obj)
{
    bdb_DB *dbst;

    GetDB(obj, dbst);
    if (RTEST(dbst->env)) {
        return dbst->env;
    }
    return Qnil;
}
env?() click to toggle source
VALUE
bdb_env_p(VALUE obj)
{
    bdb_DB *dbst;

    GetDB(obj, dbst);
    return (RTEST(dbst->env)?Qtrue:Qfalse);
}
environment() click to toggle source
static VALUE
bdb_env(VALUE obj)
{
    bdb_DB *dbst;

    GetDB(obj, dbst);
    if (RTEST(dbst->env)) {
        return dbst->env;
    }
    return Qnil;
}
environment?() click to toggle source
VALUE
bdb_env_p(VALUE obj)
{
    bdb_DB *dbst;

    GetDB(obj, dbst);
    return (RTEST(dbst->env)?Qtrue:Qfalse);
}
fd() click to toggle source
static VALUE
bdb_fd(VALUE obj)
{
    int fd = 0;
    bdb_DB *dbst;
    VALUE ary[2];

    GetDB(obj, dbst);
    if (dbst->dbp->fd(dbst->dbp, &fd)) {
        rb_raise(rb_eArgError, "invalid database handler");
    }
    ary[0] = INT2FIX(fd);
    ary[1] = rb_str_new2("r");
    return rb_class_new_instance(2, ary, rb_cIO);
}
feedback=(p1) click to toggle source
static VALUE
bdb_feedback_set(VALUE obj, VALUE a)
{
    bdb_DB *dbst;

    GetDB(obj, dbst);
    if (NIL_P(a)) {
        dbst->feedback = a;
    }
    else {
        if (!rb_respond_to(a, bdb_id_call)) {
            rb_raise(bdb_eFatal, "arg must respond to #call");
        }
        dbst->feedback = a;
        if (!(dbst->options & BDB_FEEDBACK)) {
            dbst->options |= BDB_FEEDBACK;
            rb_thread_local_aset(rb_thread_current(), bdb_id_current_db, obj); 
        }
    }
    return a;
}
fetch(p1, p2 = v2) click to toggle source
static VALUE
bdb_fetch(int argc, VALUE *argv, VALUE obj)
{
    VALUE key, if_none;
    VALUE val;

    rb_scan_args(argc, argv, "11", &key, &if_none);
    val = bdb_get_internal(1, argv, obj, Qundef, 1);
    if (val == Qundef) {
        if (rb_block_given_p()) {
            if (argc > 1) {
                rb_raise(rb_eArgError, "wrong # of arguments");
            }
            return rb_yield(key);
        }
        if (argc == 1) {
            rb_raise(rb_eIndexError, "key not found");
        }
        return if_none;
    }
    return val;
}
filename() click to toggle source
static VALUE
bdb_filename(obj)
    VALUE obj;
{
    bdb_DB *dbst;
    GetDB(obj, dbst);
    return dbst->filename;
}
flush() click to toggle source
static VALUE
bdb_sync(obj)
    VALUE obj;
{
    bdb_DB *dbst;

    if (!OBJ_TAINTED(obj) && rb_safe_level() >= 4)
        rb_raise(rb_eSecurityError, "Insecure: can't sync the database");
    GetDB(obj, dbst);
    bdb_test_error(dbst->dbp->sync(dbst->dbp, 0));
    return Qtrue;
}
get(*args) click to toggle source
static VALUE
bdb_get_dyna(int argc, VALUE *argv, VALUE obj)
{
    return bdb_get_internal(argc, argv, obj, Qnil, 1);
}
get_byteswapped() click to toggle source
static VALUE
bdb_byteswapp(obj)
    VALUE obj;
{
    bdb_DB *dbst;
    int byteswap = 0;

    GetDB(obj, dbst);
#if HAVE_ST_DB_BYTESWAPPED
    return dbst->dbp->byteswapped?Qtrue:Qfalse;
#elif HAVE_DB_GET_BYTESWAPPED_2
    dbst->dbp->get_byteswapped(dbst->dbp, &byteswap);
    return byteswap?Qtrue:Qfalse;
#else
    return dbst->dbp->get_byteswapped(dbst->dbp)?Qtrue:Qfalse;
#endif
}
get_dup(*args) click to toggle source
static VALUE
bdb_get_dup(int argc, VALUE *argv, VALUE obj)
{
    VALUE result = Qfalse;
    if (!rb_block_given_p()) {
        result = rb_ary_new();
    }
    return bdb_each_kvc(argc, argv, obj, DB_NEXT_DUP, result, BDB_ST_DUPU);
}
has_both?(p1, p2) click to toggle source
static VALUE
bdb_has_both(obj, a, b)
    VALUE obj, a, b;
{
#if ! HAVE_CONST_DB_GET_BOTH
    return bdb_has_both_internal(obj, a, b, Qfalse);
#else
    bdb_DB *dbst;
    DB_TXN *txnid;
    DBT key, data;
    int ret, flags;
    db_recno_t recno;
    volatile VALUE c = Qnil;
    volatile VALUE d = Qnil;
    void *tmp_key, *tmp_data;

    INIT_TXN(txnid, obj, dbst);
#if CANT_DB_CURSOR_GET_BOTH
    if (RECNUM_TYPE(dbst)) {
        return bdb_has_both_internal(obj, a, b, Qfalse);
    }
#endif
    MEMZERO(&key, DBT, 1);
    MEMZERO(&data, DBT, 1);
    c = bdb_test_recno(obj, &key, &recno, a);
    d = bdb_test_dump(obj, &data, b, FILTER_VALUE);
    data.flags |= DB_DBT_MALLOC;
    SET_PARTIAL(dbst, data);
    flags = DB_GET_BOTH | TEST_INIT_LOCK(dbst);
    tmp_key = key.data;
    tmp_data = data.data;
#if HAVE_ST_DB_OPEN
#if HAVE_DB_KEY_DBT_MALLOC
    key.flags |= DB_DBT_MALLOC;
#endif
#endif
    ret = bdb_test_error(dbst->dbp->get(dbst->dbp, txnid, &key, &data, flags));
    if (ret == DB_NOTFOUND || ret == DB_KEYEMPTY)
        return Qfalse;
    if (tmp_data != data.data) {
        free(data.data);
    }
    if ((key.flags & DB_DBT_MALLOC) && tmp_key != key.data) {
        free(key.data);
    }
    return Qtrue;
#endif
}
has_env?() click to toggle source
VALUE
bdb_env_p(VALUE obj)
{
    bdb_DB *dbst;

    GetDB(obj, dbst);
    return (RTEST(dbst->env)?Qtrue:Qfalse);
}
has_environment?() click to toggle source
VALUE
bdb_env_p(VALUE obj)
{
    bdb_DB *dbst;

    GetDB(obj, dbst);
    return (RTEST(dbst->env)?Qtrue:Qfalse);
}
has_key?(p1) click to toggle source
static VALUE
bdb_has_key(obj, key)
    VALUE obj, key;
{
    return (bdb_get_internal(1, &key, obj, Qundef, 0) == Qundef)?Qfalse:Qtrue;
}
has_value?(p1) click to toggle source
VALUE
bdb_has_value(obj, a)
    VALUE obj, a;
{
    return bdb_internal_value(obj, a, Qfalse, DB_NEXT);
}
in_transaction?() click to toggle source
VALUE
bdb_txn_p(VALUE obj)
{
    bdb_DB *dbst;

    GetDB(obj, dbst);
    return (RTEST(dbst->txn)?Qtrue:Qfalse);
}
in_txn?() click to toggle source
VALUE
bdb_txn_p(VALUE obj)
{
    bdb_DB *dbst;

    GetDB(obj, dbst);
    return (RTEST(dbst->txn)?Qtrue:Qfalse);
}
include?(p1) click to toggle source
static VALUE
bdb_has_key(obj, key)
    VALUE obj, key;
{
    return (bdb_get_internal(1, &key, obj, Qundef, 0) == Qundef)?Qfalse:Qtrue;
}
index(p1) click to toggle source
VALUE
bdb_index(obj, a)
    VALUE obj, a;
{
    return bdb_internal_value(obj, a, Qtrue, DB_NEXT);
}
indexes(*args) click to toggle source
static VALUE
bdb_indexes(int argc, VALUE *argv, VALUE obj)
{
    VALUE indexes;
    int i;

#if HAVE_RB_ARY_VALUES_AT
    rb_warn("Common#%s is deprecated; use Common#values_at",
#if HAVE_RB_FRAME_THIS_FUNC
            rb_id2name(rb_frame_this_func())
#else
            rb_id2name(rb_frame_last_func())
#endif
            );
#endif
    indexes = rb_ary_new2(argc);
    for (i = 0; i < argc; i++) {
        rb_ary_push(indexes, bdb_get(1, &argv[i], obj));
    }
    return indexes;
}
indices(*args) click to toggle source
static VALUE
bdb_indexes(int argc, VALUE *argv, VALUE obj)
{
    VALUE indexes;
    int i;

#if HAVE_RB_ARY_VALUES_AT
    rb_warn("Common#%s is deprecated; use Common#values_at",
#if HAVE_RB_FRAME_THIS_FUNC
            rb_id2name(rb_frame_this_func())
#else
            rb_id2name(rb_frame_last_func())
#endif
            );
#endif
    indexes = rb_ary_new2(argc);
    for (i = 0; i < argc; i++) {
        rb_ary_push(indexes, bdb_get(1, &argv[i], obj));
    }
    return indexes;
}
invert() click to toggle source
static VALUE
bdb_invert(obj)
    VALUE obj;
{
    return bdb_to_type(obj, rb_hash_new(), Qfalse);
}
join(p1, p2 = v2) click to toggle source
static VALUE
bdb_join(int argc, VALUE *argv, VALUE obj)
{
    bdb_DB *dbst;
    bdb_DBC *dbcst;
    DBC *dbc, **dbcarr;
    int flags, i;
    eachst st;
    VALUE a, b, c;

    c = 0;
    flags = 0;
    GetDB(obj, dbst);
    if (rb_scan_args(argc, argv, "11", &a, &b) == 2) {
        flags = NUM2INT(b);
    }
    if (TYPE(a) != T_ARRAY) {
        rb_raise(bdb_eFatal, "first argument must an array of cursors");
    }
    if (RARRAY_LEN(a) == 0) {
        rb_raise(bdb_eFatal, "empty array");
    }
    dbcarr = ALLOCA_N(DBC *, RARRAY_LEN(a) + 1);
    {
        DBC **dbs;
        bdb_DB *tmp;

        for (dbs = dbcarr, i = 0; i < RARRAY_LEN(a); i++, dbs++) {
            if (!rb_obj_is_kind_of(RARRAY_PTR(a)[i], bdb_cCursor)) {
                rb_raise(bdb_eFatal, "element %d is not a cursor", i);
            }
            GetCursorDB(RARRAY_PTR(a)[i], dbcst, tmp);
            *dbs = dbcst->dbc;
        }
        *dbs = 0;
    }
    dbc = 0;
#if HAVE_TYPE_DB_INFO
    bdb_test_error(dbst->dbp->join(dbst->dbp, dbcarr, 0, &dbc));
#else
    bdb_test_error(dbst->dbp->join(dbst->dbp, dbcarr, &dbc, 0));
#endif
    st.db = obj;
    st.dbcp = dbc;
    st.sens = flags | TEST_INIT_LOCK(dbst);
    rb_ensure(bdb_i_join, (VALUE)&st, bdb_i_joinclose, (VALUE)&st);
    return obj;
}
key?(p1) click to toggle source
static VALUE
bdb_has_key(obj, key)
    VALUE obj, key;
{
    return (bdb_get_internal(1, &key, obj, Qundef, 0) == Qundef)?Qfalse:Qtrue;
}
keys() click to toggle source
static VALUE
bdb_keys(obj)
    VALUE obj;
{
    return bdb_kv(obj, BDB_ST_KEY);
}
length() click to toggle source
static VALUE
bdb_length(obj)
    VALUE obj;
{
    return bdb_lgth_intern(obj, Qfalse);
}
Also aliased as: size
member?(p1) click to toggle source
static VALUE
bdb_has_key(obj, key)
    VALUE obj, key;
{
    return (bdb_get_internal(1, &key, obj, Qundef, 0) == Qundef)?Qfalse:Qtrue;
}
partial_clear() click to toggle source
static VALUE
bdb_clear_partial(obj)
    VALUE obj;
{
    bdb_DB *dbst;
    VALUE ret;

    GetDB(obj, dbst);
    if (dbst->marshal) {
        rb_raise(bdb_eFatal, "set_partial is not implemented with Marshal");
    }
    ret = rb_ary_new2(3);
    rb_ary_push(ret, (dbst->partial == DB_DBT_PARTIAL)?Qtrue:Qfalse);
    rb_ary_push(ret, INT2NUM(dbst->doff));
    rb_ary_push(ret, INT2NUM(dbst->dlen));
    dbst->doff = dbst->dlen = dbst->partial = 0;
    return ret;
}
pget(p1, p2 = v2, p3 = v3) click to toggle source
static VALUE
bdb_pget(int argc, VALUE *argv, VALUE obj)
{
    VALUE a = Qnil;
    VALUE b = Qnil;
    VALUE c;
    bdb_DB *dbst;
    DB_TXN *txnid;
    DBT pkey, data, skey;
    int flagss;
    int ret, flags;
    db_recno_t srecno;
    void *tmp_data = 0;

    INIT_TXN(txnid, obj, dbst);
    flagss = flags = 0;
    MEMZERO(&skey, DBT, 1);
    MEMZERO(&pkey, DBT, 1);
    MEMZERO(&data, DBT, 1);
    data.flags |= DB_DBT_MALLOC;
    pkey.flags |= DB_DBT_MALLOC;
    switch(rb_scan_args(argc, argv, "12", &a, &b, &c)) {
    case 3:
        flags = NUM2INT(c);
        if ((flags & ~DB_RMW) == DB_GET_BOTH) {
            b = bdb_test_dump(obj, &data, b, FILTER_VALUE);
            data.flags |= DB_DBT_MALLOC;
            tmp_data = data.data;
        }
        break;
    case 2:
        flagss = flags = NUM2INT(b);
        break;
    }
    a = bdb_test_recno(obj, &skey, &srecno, a);
    SET_PARTIAL(dbst, data);
    flags |= TEST_INIT_LOCK(dbst);
    ret = bdb_test_error(dbst->dbp->pget(dbst->dbp, txnid, &skey, &pkey, &data, flags));
    if (ret == DB_NOTFOUND || ret == DB_KEYEMPTY)
        return Qnil;
    if (((flags & ~DB_RMW) == DB_GET_BOTH) ||
        ((flags & ~DB_RMW) == DB_SET_RECNO)) {
        if ((data.flags & DB_DBT_MALLOC) && tmp_data == data.data) {
            data.flags &= ~DB_DBT_MALLOC;
        }
        return bdb_assoc2(obj, &skey, &pkey, &data);
    }
    return bdb_assoc(obj, &pkey, &data);
}
primary_get(p1, p2 = v2, p3 = v3) click to toggle source
static VALUE
bdb_pget(int argc, VALUE *argv, VALUE obj)
{
    VALUE a = Qnil;
    VALUE b = Qnil;
    VALUE c;
    bdb_DB *dbst;
    DB_TXN *txnid;
    DBT pkey, data, skey;
    int flagss;
    int ret, flags;
    db_recno_t srecno;
    void *tmp_data = 0;

    INIT_TXN(txnid, obj, dbst);
    flagss = flags = 0;
    MEMZERO(&skey, DBT, 1);
    MEMZERO(&pkey, DBT, 1);
    MEMZERO(&data, DBT, 1);
    data.flags |= DB_DBT_MALLOC;
    pkey.flags |= DB_DBT_MALLOC;
    switch(rb_scan_args(argc, argv, "12", &a, &b, &c)) {
    case 3:
        flags = NUM2INT(c);
        if ((flags & ~DB_RMW) == DB_GET_BOTH) {
            b = bdb_test_dump(obj, &data, b, FILTER_VALUE);
            data.flags |= DB_DBT_MALLOC;
            tmp_data = data.data;
        }
        break;
    case 2:
        flagss = flags = NUM2INT(b);
        break;
    }
    a = bdb_test_recno(obj, &skey, &srecno, a);
    SET_PARTIAL(dbst, data);
    flags |= TEST_INIT_LOCK(dbst);
    ret = bdb_test_error(dbst->dbp->pget(dbst->dbp, txnid, &skey, &pkey, &data, flags));
    if (ret == DB_NOTFOUND || ret == DB_KEYEMPTY)
        return Qnil;
    if (((flags & ~DB_RMW) == DB_GET_BOTH) ||
        ((flags & ~DB_RMW) == DB_SET_RECNO)) {
        if ((data.flags & DB_DBT_MALLOC) && tmp_data == data.data) {
            data.flags &= ~DB_DBT_MALLOC;
        }
        return bdb_assoc2(obj, &skey, &pkey, &data);
    }
    return bdb_assoc(obj, &pkey, &data);
}
priority() click to toggle source
static VALUE
bdb_priority(VALUE obj)
{
    bdb_DB *dbst;
    DB_CACHE_PRIORITY prio = 0;

    GetDB(obj, dbst);
    if (dbst->dbp->get_priority(dbst->dbp, &prio)) {
        rb_raise(rb_eArgError, "invalid argument");
    }
    return INT2FIX(prio);
}
priority=(p1) click to toggle source
static VALUE
bdb_set_priority(VALUE obj, VALUE a)
{
    bdb_DB *dbst;

    GetDB(obj, dbst);
    if (dbst->dbp->set_priority(dbst->dbp, NUM2INT(a))) {
        rb_raise(rb_eArgError, "invalid argument");
    }
    return a;
}
put(p1, p2, p3 = v3) click to toggle source
VALUE
bdb_put(int argc, VALUE *argv, VALUE obj)
{
    volatile VALUE a0 = Qnil;
    volatile VALUE b0 = Qnil;
    VALUE a, b, c;
    bdb_DB *dbst;
    DB_TXN *txnid;
    DBT key, data;
    int ret, flags;
    db_recno_t recno;

    rb_secure(4);
    INIT_TXN(txnid, obj, dbst);
    flags = 0;
    a = b = c = Qnil;
    MEMZERO(&key, DBT, 1);
    MEMZERO(&data, DBT, 1);
    if (rb_scan_args(argc, argv, "21", &a, &b, &c) == 3) {
        flags = NUM2INT(c);
    }
    a0 = bdb_test_recno(obj, &key, &recno, a);
    b0 = bdb_test_dump(obj, &data, b, FILTER_VALUE);
    SET_PARTIAL(dbst, data);
#if HAVE_CONST_DB_QUEUE
    if (dbst->type == DB_QUEUE && dbst->re_len < data.size) {
        rb_raise(bdb_eFatal, "size > re_len for Queue");
    }
#endif
#if HAVE_CONST_DB_AUTO_COMMIT
    if (txnid == NULL && (dbst->options & BDB_AUTO_COMMIT)) {
      flags |= DB_AUTO_COMMIT;
    }
#endif
    ret = bdb_test_error(dbst->dbp->put(dbst->dbp, txnid, &key, &data, flags));
    if (ret == DB_KEYEXIST)
        return Qfalse;
    else {
        if (dbst->partial) {
            if (flags & DB_APPEND) {
                a = INT2NUM((long)key.data);
            }
            return bdb_get(1, &a, obj);
        }
        else {
            return bdb_test_ret(obj, b0, b, FILTER_VALUE);
        }
    }
}
reject(*args) click to toggle source
static VALUE
bdb_reject(int argc, VALUE *argv, VALUE obj)
{
    return bdb_each_kvc(argc, argv, obj, DB_NEXT, rb_hash_new(), BDB_ST_REJECT);
}
reject!(*args) click to toggle source
static VALUE
bdb_delete_if(int argc, VALUE *argv, VALUE obj)
{
    return bdb_each_kvc(argc, argv, obj, DB_NEXT, Qfalse, BDB_ST_DELETE | BDB_ST_ONE);
}
replace(*args) click to toggle source
static VALUE
bdb_replace(int argc, VALUE *argv, VALUE obj)
{
    VALUE g;
    int flags;

    if (argc == 0 || argc > 2) {
        rb_raise(rb_eArgError, "invalid number of arguments (0 for 1)");
    }
    flags = 0;
    if (TYPE(argv[argc - 1]) == T_HASH) {
        VALUE f = argv[argc - 1];
        if ((g = rb_hash_aref(f, rb_intern("flags"))) != RHASH(f)->ifnone ||
            (g = rb_hash_aref(f, rb_str_new2("flags"))) != RHASH(f)->ifnone) {
            flags = NUM2INT(g);
        }
        argc--;
    }
    if (argc == 2) {
        flags = NUM2INT(argv[1]);
    }
    g = INT2FIX(flags);
    bdb_clear(1, &g, obj);
    rb_iterate(each_pair, argv[0], bdb_update_i, obj);
    return obj;
}
reverse_each(*args) click to toggle source
static VALUE
bdb_each_riap(int argc, VALUE *argv, VALUE obj) 
{
    return bdb_each_kvc(argc, argv, obj, DB_PREV, Qfalse, BDB_ST_KV | BDB_ST_ONE);
}
reverse_each_key(*args) click to toggle source
static VALUE
bdb_each_yek(int argc, VALUE *argv, VALUE obj) 
{ 
    return bdb_each_kvc(argc, argv, obj, DB_PREV, Qfalse, BDB_ST_KEY | BDB_ST_ONE);
}
reverse_each_pair(*args) click to toggle source
static VALUE
bdb_each_riap(int argc, VALUE *argv, VALUE obj) 
{
    return bdb_each_kvc(argc, argv, obj, DB_PREV, Qfalse, BDB_ST_KV | BDB_ST_ONE);
}
reverse_each_primary(p1 = v1) click to toggle source
static VALUE
bdb_each_riap_prim(int argc, VALUE *argv, VALUE obj) 
{
    VALUE tmp[2] = {Qnil, Qtrue};
    rb_scan_args(argc, argv, "01", tmp);
    return bdb_each_kvc(2, tmp, obj, DB_PREV, Qfalse, BDB_ST_KV);
}
reverse_each_value(*args) click to toggle source
VALUE
bdb_each_eulav(int argc, VALUE *argv, VALUE obj)
{
    return bdb_each_kvc(argc, argv, obj, DB_PREV, Qfalse, BDB_ST_VALUE | BDB_ST_ONE);
}
select(*args) click to toggle source
static VALUE
bdb_select(int argc, VALUE *argv, VALUE obj)
{
    VALUE result = rb_ary_new();

    if (rb_block_given_p()) {
        if (argc > 0) {
            rb_raise(rb_eArgError, "wrong number arguments(%d for 0)", argc);
        }
        return bdb_each_kvc(argc, argv, obj, DB_NEXT, result, BDB_ST_SELECT);
    }
    rb_warn("Common#select(index..) is deprecated; use Common#values_at");
    return bdb_values_at(argc, argv, obj);
}
set_partial(p1, p2) click to toggle source
static VALUE
bdb_set_partial(obj, a, b)
    VALUE obj, a, b;
{
    bdb_DB *dbst;
    VALUE ret;

    GetDB(obj, dbst);
    if (dbst->marshal) {
        rb_raise(bdb_eFatal, "set_partial is not implemented with Marshal");
    }
    ret = rb_ary_new2(3);
    rb_ary_push(ret, (dbst->partial == DB_DBT_PARTIAL)?Qtrue:Qfalse);
    rb_ary_push(ret, INT2NUM(dbst->doff));
    rb_ary_push(ret, INT2NUM(dbst->dlen));
    dbst->doff = NUM2UINT(a);
    dbst->dlen = NUM2UINT(b);
    dbst->partial = DB_DBT_PARTIAL;
    return ret;
}
size()
Alias for: length
store(p1, p2, p3 = v3) click to toggle source
VALUE
bdb_put(int argc, VALUE *argv, VALUE obj)
{
    volatile VALUE a0 = Qnil;
    volatile VALUE b0 = Qnil;
    VALUE a, b, c;
    bdb_DB *dbst;
    DB_TXN *txnid;
    DBT key, data;
    int ret, flags;
    db_recno_t recno;

    rb_secure(4);
    INIT_TXN(txnid, obj, dbst);
    flags = 0;
    a = b = c = Qnil;
    MEMZERO(&key, DBT, 1);
    MEMZERO(&data, DBT, 1);
    if (rb_scan_args(argc, argv, "21", &a, &b, &c) == 3) {
        flags = NUM2INT(c);
    }
    a0 = bdb_test_recno(obj, &key, &recno, a);
    b0 = bdb_test_dump(obj, &data, b, FILTER_VALUE);
    SET_PARTIAL(dbst, data);
#if HAVE_CONST_DB_QUEUE
    if (dbst->type == DB_QUEUE && dbst->re_len < data.size) {
        rb_raise(bdb_eFatal, "size > re_len for Queue");
    }
#endif
#if HAVE_CONST_DB_AUTO_COMMIT
    if (txnid == NULL && (dbst->options & BDB_AUTO_COMMIT)) {
      flags |= DB_AUTO_COMMIT;
    }
#endif
    ret = bdb_test_error(dbst->dbp->put(dbst->dbp, txnid, &key, &data, flags));
    if (ret == DB_KEYEXIST)
        return Qfalse;
    else {
        if (dbst->partial) {
            if (flags & DB_APPEND) {
                a = INT2NUM((long)key.data);
            }
            return bdb_get(1, &a, obj);
        }
        else {
            return bdb_test_ret(obj, b0, b, FILTER_VALUE);
        }
    }
}
subname() click to toggle source
static VALUE
bdb_database(obj)
    VALUE obj;
{
    bdb_DB *dbst;
    GetDB(obj, dbst);
    return dbst->database;
}
sync() click to toggle source
static VALUE
bdb_sync(obj)
    VALUE obj;
{
    bdb_DB *dbst;

    if (!OBJ_TAINTED(obj) && rb_safe_level() >= 4)
        rb_raise(rb_eSecurityError, "Insecure: can't sync the database");
    GetDB(obj, dbst);
    bdb_test_error(dbst->dbp->sync(dbst->dbp, 0));
    return Qtrue;
}
to_a() click to toggle source
static VALUE
bdb_to_a(obj)
    VALUE obj;
{
    return bdb_to_type(obj, rb_ary_new(), Qtrue);
}
to_hash() click to toggle source
static VALUE
bdb_to_hash(obj)
    VALUE obj;
{
    return bdb_to_type(obj, rb_hash_new(), Qtrue);
}
transaction() click to toggle source
static VALUE
bdb_txn(VALUE obj)
{
    bdb_DB *dbst;

    GetDB(obj, dbst);
    if (RTEST(dbst->txn)) {
        return dbst->txn;
    }
    return Qnil;
}
transaction?() click to toggle source
VALUE
bdb_txn_p(VALUE obj)
{
    bdb_DB *dbst;

    GetDB(obj, dbst);
    return (RTEST(dbst->txn)?Qtrue:Qfalse);
}
truncate(*args) click to toggle source
VALUE
bdb_clear(int argc, VALUE *argv, VALUE obj)
{
#if HAVE_ST_DB_TRUNCATE
    bdb_DB *dbst;
    DB_TXN *txnid;
    unsigned int count = 0;
#endif
    int flags = 0;

    rb_secure(4);
#if HAVE_ST_DB_TRUNCATE
    INIT_TXN(txnid, obj, dbst);
#if HAVE_CONST_DB_AUTO_COMMIT
    if (txnid == NULL && (dbst->options & BDB_AUTO_COMMIT)) {
      flags |= DB_AUTO_COMMIT;
    }
#endif
    bdb_test_error(dbst->dbp->truncate(dbst->dbp, txnid, &count, flags));
    return INT2NUM(count);
#else
    flags = 0;
    if (argc && TYPE(argv[argc - 1]) == T_HASH) {
        VALUE g, f = argv[argc - 1];
        if ((g = rb_hash_aref(f, rb_intern("flags"))) != RHASH(f)->ifnone ||
            (g = rb_hash_aref(f, rb_str_new2("flags"))) != RHASH(f)->ifnone) {
            flags = NUM2INT(g);
        }
        argc--;
    }
    if (argc) {
        flags = NUM2INT(argv[0]);
    }
    return bdb_lgth_intern(obj, Qtrue, flags);
#endif
}
txn() click to toggle source
static VALUE
bdb_txn(VALUE obj)
{
    bdb_DB *dbst;

    GetDB(obj, dbst);
    if (RTEST(dbst->txn)) {
        return dbst->txn;
    }
    return Qnil;
}
txn?() click to toggle source
VALUE
bdb_txn_p(VALUE obj)
{
    bdb_DB *dbst;

    GetDB(obj, dbst);
    return (RTEST(dbst->txn)?Qtrue:Qfalse);
}
update(p1) click to toggle source
static VALUE
bdb_update(obj, other)
    VALUE obj, other;
{
    rb_iterate(each_pair, other, bdb_update_i, obj);
    return obj;
}
value?(p1) click to toggle source
VALUE
bdb_has_value(obj, a)
    VALUE obj, a;
{
    return bdb_internal_value(obj, a, Qfalse, DB_NEXT);
}
values() click to toggle source
static VALUE
bdb_values(obj)
    VALUE obj;
{
    return bdb_kv(obj, BDB_ST_VALUE);
}
values_at(*args) click to toggle source
static VALUE
bdb_values_at(int argc, VALUE *argv, VALUE obj)
{
    VALUE result = rb_ary_new2(argc);
    long i;
    for (i = 0; i < argc; i++) {
        rb_ary_push(result, bdb_get(1, &argv[i], obj));
    }
    return result;
}
verify(p1 = v1, p2 = v2) click to toggle source
static VALUE
bdb_verify(int argc, VALUE *argv, VALUE obj)
{
    bdb_DB *dbst;
    char *file, *database;
    VALUE flagv = Qnil, iov = Qnil;
    int flags = 0;
#if HAVE_TYPE_RB_IO_T
    rb_io_t *fptr;
#else
    OpenFile *fptr;
#endif
    FILE *io = NULL;

    rb_secure(4);
    file = database = NULL;
    switch(rb_scan_args(argc, argv, "02", &iov, &flagv)) {
    case 2:
        flags = NUM2INT(flagv);
    case 1:
        if (!NIL_P(iov)) {
            iov = rb_convert_type(iov, T_FILE, "IO", "to_io");
            GetOpenFile(iov, fptr);
            rb_io_check_writable(fptr);
#if HAVE_RB_IO_STDIO_FILE
            io = rb_io_stdio_file(fptr);
#else
            io = GetWriteFile(fptr);
#endif
        }
        break;
    case 0:
        break;
    }
    GetDB(obj, dbst);
    if (!NIL_P(dbst->filename)) {
        file = StringValuePtr(dbst->filename);
    }
    if (!NIL_P(dbst->database)) {
        database = StringValuePtr(dbst->database);
    }
    bdb_test_error(dbst->dbp->verify(dbst->dbp, file, database, io, flags));
    return Qnil;
}