# 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_IFNONE(f)) {
                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_IFNONE(f)) {
                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_IFNONE(f)) {
                    rb_hash_aset(f, rb_intern("set_flags"),
                                 INT2NUM(NUM2INT(v) | DB_ENCRYPT));
                }
                else if ((v = rb_hash_aref(f, tmp)) != RHASH_IFNONE(f)) {
                    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;
    }

unlink(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;
    }

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_IFNONE(f) ||
                (g = rb_hash_aref(f, rb_str_new2("flags"))) != RHASH_IFNONE(f)) {
                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_IFNONE(f) ||
                (g = rb_hash_aref(f, rb_str_new2("flags"))) != RHASH_IFNONE(f)) {
                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_IFNONE(f) ||
                (g = rb_hash_aref(f, rb_str_new2("flags"))) != RHASH_IFNONE(f)) {
                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;
    }