Extended maintenance of Ruby versions 1.8.7 and 1.9.2 ended on July 31, 2014. Read more

In Files

  • dbm/dbm.c

Class/Module Index [+]

Quicksearch

DBM

Constants

NEWDB
READER

flags for dbm_open()

VERSION
WRCREAT
WRITER

Public Class Methods

new(p1, p2 = v2, p3 = v3) click to toggle source
 
               static VALUE
fdbm_initialize(int argc, VALUE *argv, VALUE obj)
{
    volatile VALUE file;
    VALUE vmode, vflags;
    DBM *dbm;
    struct dbmdata *dbmp;
    int mode, flags = 0;

    if (rb_scan_args(argc, argv, "12", &file, &vmode, &vflags) == 1) {
        mode = 0666;           /* default value */
    }
    else if (NIL_P(vmode)) {
        mode = -1;             /* return nil if DB not exist */
    }
    else {
        mode = NUM2INT(vmode);
    }

    if (!NIL_P(vflags))
        flags = NUM2INT(vflags);

    FilePathValue(file);

    if (flags & RUBY_DBM_RW_BIT) {
        flags &= ~RUBY_DBM_RW_BIT;
        dbm = dbm_open(RSTRING_PTR(file), flags, mode);
    }
    else {
        dbm = 0;
        if (mode >= 0) {
            dbm = dbm_open(RSTRING_PTR(file), O_RDWR|O_CREAT, mode);
        }
        if (!dbm) {
            dbm = dbm_open(RSTRING_PTR(file), O_RDWR, 0);
        }
        if (!dbm) {
            dbm = dbm_open(RSTRING_PTR(file), O_RDONLY, 0);
        }
    }

    if (!dbm) {
        if (mode == -1) return Qnil;
        rb_sys_fail(RSTRING_PTR(file));
    }

    dbmp = ALLOC(struct dbmdata);
    DATA_PTR(obj) = dbmp;
    dbmp->di_dbm = dbm;
    dbmp->di_size = -1;

    return obj;
}
            
open(*args) click to toggle source
 
               static VALUE
fdbm_s_open(int argc, VALUE *argv, VALUE klass)
{
    VALUE obj = Data_Wrap_Struct(klass, 0, free_dbm, 0);

    if (NIL_P(fdbm_initialize(argc, argv, obj))) {
        return Qnil;
    }

    if (rb_block_given_p()) {
        return rb_ensure(rb_yield, obj, fdbm_close, obj);
    }

    return obj;
}
            

Public Instance Methods

[](p1) click to toggle source
 
               static VALUE
fdbm_aref(VALUE obj, VALUE keystr)
{
    return fdbm_fetch(obj, keystr, Qnil);
}
            
[]=(p1, p2) click to toggle source
 
               static VALUE
fdbm_store(VALUE obj, VALUE keystr, VALUE valstr)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;

    fdbm_modify(obj);
    keystr = rb_obj_as_string(keystr);
    valstr = rb_obj_as_string(valstr);

    key.dptr = RSTRING_PTR(keystr);
    key.dsize = RSTRING_LEN(keystr);

    val.dptr = RSTRING_PTR(valstr);
    val.dsize = RSTRING_LEN(valstr);

    GetDBM2(obj, dbmp, dbm);
    dbmp->di_size = -1;
    if (dbm_store(dbm, key, val, DBM_REPLACE)) {
#ifdef HAVE_DBM_CLEARERR
        dbm_clearerr(dbm);
#endif
        if (errno == EPERM) rb_sys_fail(0);
        rb_raise(rb_eDBMError, "dbm_store failed");
    }

    return valstr;
}
            
clear() click to toggle source
 
               static VALUE
fdbm_clear(VALUE obj)
{
    datum key;
    struct dbmdata *dbmp;
    DBM *dbm;

    fdbm_modify(obj);
    GetDBM2(obj, dbmp, dbm);
    dbmp->di_size = -1;
    while (key = dbm_firstkey(dbm), key.dptr) {
        if (dbm_delete(dbm, key)) {
            rb_raise(rb_eDBMError, "dbm_delete failed");
        }
    }
    dbmp->di_size = 0;

    return obj;
}
            
close() click to toggle source
 
               static VALUE
fdbm_close(VALUE obj)
{
    struct dbmdata *dbmp;

    GetDBM(obj, dbmp);
    dbm_close(dbmp->di_dbm);
    dbmp->di_dbm = 0;

    return Qnil;
}
            
closed?() click to toggle source
 
               static VALUE
fdbm_closed(VALUE obj)
{
    struct dbmdata *dbmp;

    Data_Get_Struct(obj, struct dbmdata, dbmp);
    if (dbmp == 0)
        return Qtrue;
    if (dbmp->di_dbm == 0)
        return Qtrue;

    return Qfalse;
}
            
delete(p1) click to toggle source
 
               static VALUE
fdbm_delete(VALUE obj, VALUE keystr)
{
    datum key, value;
    struct dbmdata *dbmp;
    DBM *dbm;
    VALUE valstr;

    fdbm_modify(obj);
    ExportStringValue(keystr);
    key.dptr = RSTRING_PTR(keystr);
    key.dsize = RSTRING_LEN(keystr);

    GetDBM2(obj, dbmp, dbm);

    value = dbm_fetch(dbm, key);
    if (value.dptr == 0) {
        if (rb_block_given_p()) return rb_yield(keystr);
        return Qnil;
    }

    /* need to save value before dbm_delete() */
    valstr = rb_tainted_str_new(value.dptr, value.dsize);

    if (dbm_delete(dbm, key)) {
        dbmp->di_size = -1;
        rb_raise(rb_eDBMError, "dbm_delete failed");
    }
    else if (dbmp->di_size >= 0) {
        dbmp->di_size--;
    }
    return valstr;
}
            
delete_if() click to toggle source
 
               static VALUE
fdbm_delete_if(VALUE obj)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;
    VALUE keystr, valstr;
    VALUE ret, ary = rb_ary_new();
    int i, status = 0, n;

    fdbm_modify(obj);
    GetDBM2(obj, dbmp, dbm);
    n = dbmp->di_size;
    dbmp->di_size = -1;

    for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
        val = dbm_fetch(dbm, key);
        keystr = rb_tainted_str_new(key.dptr, key.dsize);
        valstr = rb_tainted_str_new(val.dptr, val.dsize);
        ret = rb_protect(rb_yield, rb_assoc_new(rb_str_dup(keystr), valstr), &status);
        if (status != 0) break;
        if (RTEST(ret)) rb_ary_push(ary, keystr);
        GetDBM2(obj, dbmp, dbm);
    }

    for (i = 0; i < RARRAY_LEN(ary); i++) {
        keystr = RARRAY_PTR(ary)[i];
        ExportStringValue(keystr);
        key.dptr = RSTRING_PTR(keystr);
        key.dsize = RSTRING_LEN(keystr);
        if (dbm_delete(dbm, key)) {
            rb_raise(rb_eDBMError, "dbm_delete failed");
        }
    }
    if (status) rb_jump_tag(status);
    if (n > 0) dbmp->di_size = n - RARRAY_LEN(ary);

    return obj;
}
            
each() click to toggle source
 
               static VALUE
fdbm_each_pair(VALUE obj)
{
    datum key, val;
    DBM *dbm;
    struct dbmdata *dbmp;
    VALUE keystr, valstr;

    RETURN_ENUMERATOR(obj, 0, 0);

    GetDBM2(obj, dbmp, dbm);

    for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
        val = dbm_fetch(dbm, key);
        keystr = rb_tainted_str_new(key.dptr, key.dsize);
        valstr = rb_tainted_str_new(val.dptr, val.dsize);
        rb_yield(rb_assoc_new(keystr, valstr));
        GetDBM2(obj, dbmp, dbm);
    }

    return obj;
}
            
each_key() click to toggle source
 
               static VALUE
fdbm_each_key(VALUE obj)
{
    datum key;
    struct dbmdata *dbmp;
    DBM *dbm;

    RETURN_ENUMERATOR(obj, 0, 0);

    GetDBM2(obj, dbmp, dbm);
    for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
        rb_yield(rb_tainted_str_new(key.dptr, key.dsize));
        GetDBM2(obj, dbmp, dbm);
    }
    return obj;
}
            
each_pair() click to toggle source
 
               static VALUE
fdbm_each_pair(VALUE obj)
{
    datum key, val;
    DBM *dbm;
    struct dbmdata *dbmp;
    VALUE keystr, valstr;

    RETURN_ENUMERATOR(obj, 0, 0);

    GetDBM2(obj, dbmp, dbm);

    for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
        val = dbm_fetch(dbm, key);
        keystr = rb_tainted_str_new(key.dptr, key.dsize);
        valstr = rb_tainted_str_new(val.dptr, val.dsize);
        rb_yield(rb_assoc_new(keystr, valstr));
        GetDBM2(obj, dbmp, dbm);
    }

    return obj;
}
            
each_value() click to toggle source
 
               static VALUE
fdbm_each_value(VALUE obj)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;

    RETURN_ENUMERATOR(obj, 0, 0);

    GetDBM2(obj, dbmp, dbm);
    for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
        val = dbm_fetch(dbm, key);
        rb_yield(rb_tainted_str_new(val.dptr, val.dsize));
        GetDBM2(obj, dbmp, dbm);
    }
    return obj;
}
            
empty?() click to toggle source
 
               static VALUE
fdbm_empty_p(VALUE obj)
{
    datum key;
    struct dbmdata *dbmp;
    DBM *dbm;
    int i = 0;

    GetDBM2(obj, dbmp, dbm);
    if (dbmp->di_size < 0) {
        dbm = dbmp->di_dbm;

        for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
            i++;
        }
    }
    else {
        i = dbmp->di_size;
    }
    if (i == 0) return Qtrue;
    return Qfalse;
}
            
fetch(p1, p2 = v2) click to toggle source
 
               static VALUE
fdbm_fetch_m(int argc, VALUE *argv, VALUE obj)
{
    VALUE keystr, valstr, ifnone;

    rb_scan_args(argc, argv, "11", &keystr, &ifnone);
    valstr = fdbm_fetch(obj, keystr, ifnone);
    if (argc == 1 && !rb_block_given_p() && NIL_P(valstr))
        rb_raise(rb_eIndexError, "key not found");

    return valstr;
}
            
has_key?(p1) click to toggle source
 
               static VALUE
fdbm_has_key(VALUE obj, VALUE keystr)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;

    ExportStringValue(keystr);
    key.dptr = RSTRING_PTR(keystr);
    key.dsize = RSTRING_LEN(keystr);

    GetDBM2(obj, dbmp, dbm);
    val = dbm_fetch(dbm, key);
    if (val.dptr) return Qtrue;
    return Qfalse;
}
            
has_value?(p1) click to toggle source
 
               static VALUE
fdbm_has_value(VALUE obj, VALUE valstr)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;

    ExportStringValue(valstr);
    val.dptr = RSTRING_PTR(valstr);
    val.dsize = RSTRING_LEN(valstr);

    GetDBM2(obj, dbmp, dbm);
    for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
        val = dbm_fetch(dbm, key);
        if (val.dsize == RSTRING_LEN(valstr) &&
            memcmp(val.dptr, RSTRING_PTR(valstr), val.dsize) == 0)
            return Qtrue;
    }
    return Qfalse;
}
            
include?(p1) click to toggle source
 
               static VALUE
fdbm_has_key(VALUE obj, VALUE keystr)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;

    ExportStringValue(keystr);
    key.dptr = RSTRING_PTR(keystr);
    key.dsize = RSTRING_LEN(keystr);

    GetDBM2(obj, dbmp, dbm);
    val = dbm_fetch(dbm, key);
    if (val.dptr) return Qtrue;
    return Qfalse;
}
            
index(p1) click to toggle source
 
               static VALUE
fdbm_index(VALUE hash, VALUE value)
{
    rb_warn("DBM#index is deprecated; use DBM#key");
    return fdbm_key(hash, value);
}
            
invert() click to toggle source
 
               static VALUE
fdbm_invert(VALUE obj)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;
    VALUE keystr, valstr;
    VALUE hash = rb_hash_new();

    GetDBM2(obj, dbmp, dbm);
    for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
        val = dbm_fetch(dbm, key);
        keystr = rb_tainted_str_new(key.dptr, key.dsize);
        valstr = rb_tainted_str_new(val.dptr, val.dsize);
        rb_hash_aset(hash, valstr, keystr);
    }
    return hash;
}
            
key(p1) click to toggle source
 
               static VALUE
fdbm_key(VALUE obj, VALUE valstr)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;

    ExportStringValue(valstr);
    val.dptr = RSTRING_PTR(valstr);
    val.dsize = RSTRING_LEN(valstr);

    GetDBM2(obj, dbmp, dbm);
    for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
        val = dbm_fetch(dbm, key);
        if (val.dsize == RSTRING_LEN(valstr) &&
            memcmp(val.dptr, RSTRING_PTR(valstr), val.dsize) == 0) {
            return rb_tainted_str_new(key.dptr, key.dsize);
        }
    }
    return Qnil;
}
            
key?(p1) click to toggle source
 
               static VALUE
fdbm_has_key(VALUE obj, VALUE keystr)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;

    ExportStringValue(keystr);
    key.dptr = RSTRING_PTR(keystr);
    key.dsize = RSTRING_LEN(keystr);

    GetDBM2(obj, dbmp, dbm);
    val = dbm_fetch(dbm, key);
    if (val.dptr) return Qtrue;
    return Qfalse;
}
            
keys() click to toggle source
 
               static VALUE
fdbm_keys(VALUE obj)
{
    datum key;
    struct dbmdata *dbmp;
    DBM *dbm;
    VALUE ary;

    GetDBM2(obj, dbmp, dbm);

    ary = rb_ary_new();
    for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
        rb_ary_push(ary, rb_tainted_str_new(key.dptr, key.dsize));
    }

    return ary;
}
            
length() click to toggle source
 
               static VALUE
fdbm_length(VALUE obj)
{
    datum key;
    struct dbmdata *dbmp;
    DBM *dbm;
    int i = 0;

    GetDBM2(obj, dbmp, dbm);
    if (dbmp->di_size > 0) return INT2FIX(dbmp->di_size);

    for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
        i++;
    }
    dbmp->di_size = i;

    return INT2FIX(i);
}
            
member?(p1) click to toggle source
 
               static VALUE
fdbm_has_key(VALUE obj, VALUE keystr)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;

    ExportStringValue(keystr);
    key.dptr = RSTRING_PTR(keystr);
    key.dsize = RSTRING_LEN(keystr);

    GetDBM2(obj, dbmp, dbm);
    val = dbm_fetch(dbm, key);
    if (val.dptr) return Qtrue;
    return Qfalse;
}
            
reject() click to toggle source
 
               static VALUE
fdbm_reject(VALUE obj)
{
    return rb_hash_delete_if(fdbm_to_hash(obj));
}
            
reject!() click to toggle source
 
               static VALUE
fdbm_delete_if(VALUE obj)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;
    VALUE keystr, valstr;
    VALUE ret, ary = rb_ary_new();
    int i, status = 0, n;

    fdbm_modify(obj);
    GetDBM2(obj, dbmp, dbm);
    n = dbmp->di_size;
    dbmp->di_size = -1;

    for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
        val = dbm_fetch(dbm, key);
        keystr = rb_tainted_str_new(key.dptr, key.dsize);
        valstr = rb_tainted_str_new(val.dptr, val.dsize);
        ret = rb_protect(rb_yield, rb_assoc_new(rb_str_dup(keystr), valstr), &status);
        if (status != 0) break;
        if (RTEST(ret)) rb_ary_push(ary, keystr);
        GetDBM2(obj, dbmp, dbm);
    }

    for (i = 0; i < RARRAY_LEN(ary); i++) {
        keystr = RARRAY_PTR(ary)[i];
        ExportStringValue(keystr);
        key.dptr = RSTRING_PTR(keystr);
        key.dsize = RSTRING_LEN(keystr);
        if (dbm_delete(dbm, key)) {
            rb_raise(rb_eDBMError, "dbm_delete failed");
        }
    }
    if (status) rb_jump_tag(status);
    if (n > 0) dbmp->di_size = n - RARRAY_LEN(ary);

    return obj;
}
            
replace(p1) click to toggle source
 
               static VALUE
fdbm_replace(VALUE obj, VALUE other)
{
    fdbm_clear(obj);
    rb_block_call(other, rb_intern("each_pair"), 0, 0, update_i, obj);
    return obj;
}
            
select() click to toggle source
 
               static VALUE
fdbm_select(VALUE obj)
{
    VALUE new = rb_ary_new();
    datum key, val;
    DBM *dbm;
    struct dbmdata *dbmp;

    GetDBM2(obj, dbmp, dbm);
    for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
        VALUE assoc, v;
        val = dbm_fetch(dbm, key);
        assoc = rb_assoc_new(rb_tainted_str_new(key.dptr, key.dsize),
                             rb_tainted_str_new(val.dptr, val.dsize));
        v = rb_yield(assoc);
        if (RTEST(v)) {
            rb_ary_push(new, assoc);
        }
        GetDBM2(obj, dbmp, dbm);
    }

    return new;
}
            
shift() click to toggle source
 
               static VALUE
fdbm_shift(VALUE obj)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;
    VALUE keystr, valstr;

    fdbm_modify(obj);
    GetDBM2(obj, dbmp, dbm);
    dbmp->di_size = -1;

    key = dbm_firstkey(dbm);
    if (!key.dptr) return Qnil;
    val = dbm_fetch(dbm, key);
    keystr = rb_tainted_str_new(key.dptr, key.dsize);
    valstr = rb_tainted_str_new(val.dptr, val.dsize);
    dbm_delete(dbm, key);

    return rb_assoc_new(keystr, valstr);
}
            
size() click to toggle source
 
               static VALUE
fdbm_length(VALUE obj)
{
    datum key;
    struct dbmdata *dbmp;
    DBM *dbm;
    int i = 0;

    GetDBM2(obj, dbmp, dbm);
    if (dbmp->di_size > 0) return INT2FIX(dbmp->di_size);

    for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
        i++;
    }
    dbmp->di_size = i;

    return INT2FIX(i);
}
            
store(p1, p2) click to toggle source
 
               static VALUE
fdbm_store(VALUE obj, VALUE keystr, VALUE valstr)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;

    fdbm_modify(obj);
    keystr = rb_obj_as_string(keystr);
    valstr = rb_obj_as_string(valstr);

    key.dptr = RSTRING_PTR(keystr);
    key.dsize = RSTRING_LEN(keystr);

    val.dptr = RSTRING_PTR(valstr);
    val.dsize = RSTRING_LEN(valstr);

    GetDBM2(obj, dbmp, dbm);
    dbmp->di_size = -1;
    if (dbm_store(dbm, key, val, DBM_REPLACE)) {
#ifdef HAVE_DBM_CLEARERR
        dbm_clearerr(dbm);
#endif
        if (errno == EPERM) rb_sys_fail(0);
        rb_raise(rb_eDBMError, "dbm_store failed");
    }

    return valstr;
}
            
to_a() click to toggle source
 
               static VALUE
fdbm_to_a(VALUE obj)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;
    VALUE ary;

    GetDBM2(obj, dbmp, dbm);
    ary = rb_ary_new();
    for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
        val = dbm_fetch(dbm, key);
        rb_ary_push(ary, rb_assoc_new(rb_tainted_str_new(key.dptr, key.dsize),
                                      rb_tainted_str_new(val.dptr, val.dsize)));
    }

    return ary;
}
            
to_hash() click to toggle source
 
               static VALUE
fdbm_to_hash(VALUE obj)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;
    VALUE hash;

    GetDBM2(obj, dbmp, dbm);
    hash = rb_hash_new();
    for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
        val = dbm_fetch(dbm, key);
        rb_hash_aset(hash, rb_tainted_str_new(key.dptr, key.dsize),
                           rb_tainted_str_new(val.dptr, val.dsize));
    }

    return hash;
}
            
update(p1) click to toggle source
 
               static VALUE
fdbm_update(VALUE obj, VALUE other)
{
    rb_block_call(other, rb_intern("each_pair"), 0, 0, update_i, obj);
    return obj;
}
            
value?(p1) click to toggle source
 
               static VALUE
fdbm_has_value(VALUE obj, VALUE valstr)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;

    ExportStringValue(valstr);
    val.dptr = RSTRING_PTR(valstr);
    val.dsize = RSTRING_LEN(valstr);

    GetDBM2(obj, dbmp, dbm);
    for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
        val = dbm_fetch(dbm, key);
        if (val.dsize == RSTRING_LEN(valstr) &&
            memcmp(val.dptr, RSTRING_PTR(valstr), val.dsize) == 0)
            return Qtrue;
    }
    return Qfalse;
}
            
values() click to toggle source
 
               static VALUE
fdbm_values(VALUE obj)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;
    VALUE ary;

    GetDBM2(obj, dbmp, dbm);
    ary = rb_ary_new();
    for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
        val = dbm_fetch(dbm, key);
        rb_ary_push(ary, rb_tainted_str_new(val.dptr, val.dsize));
    }

    return ary;
}
            
values_at(*args) click to toggle source
 
               static VALUE
fdbm_values_at(int argc, VALUE *argv, VALUE obj)
{
    VALUE new = rb_ary_new2(argc);
    int i;

    for (i=0; i<argc; i++) {
        rb_ary_push(new, fdbm_fetch(obj, argv[i], Qnil));
    }

    return new;
}
            

Commenting is here to help enhance the documentation. For example, code samples, or clarification of the documentation.

If you have questions about Ruby or the documentation, please post to one of the Ruby mailing lists. You will get better, faster, help that way.

If you wish to post a correction of the docs, please do so, but also file bug report so that it can be corrected for the next release. Thank you.

If you want to help improve the Ruby documentation, please visit Documenting-ruby.org.

blog comments powered by Disqus