非常教程

Ruby 2.4参考手册

SDBM

SDBM

Parent:ObjectIncluded modules:Enumerable

SDBM提供了一个简单的基于文件的键值存储,它只能存储String键和值。

请注意,Ruby带有SDBM的源代码,而DBM和GDBM标准库依赖于外部库和头文件。

例子

插入值:

require 'sdbm'

SDBM.open 'my_database' do |db|
  db['apple'] = 'fruit'
  db['pear'] = 'fruit'
  db['carrot'] = 'vegetable'
  db['tomato'] = 'vegetable'
end

批量更新:

require 'sdbm'

SDBM.open 'my_database' do |db|
  db.update('peach' => 'fruit', 'tomato' => 'fruit')
end

检索值:

require 'sdbm'

SDBM.open 'my_database' do |db|
  db.each do |key, value|
    puts "Key: #{key}, Value: #{value}"
  end
end

输出:

Key: apple, Value: fruit
Key: pear, Value: fruit
Key: carrot, Value: vegetable
Key: peach, Value: fruit
Key: tomato, Value: fruit

公共类方法

new(filename, mode = 0666) Show source

通过打开给定的文件名创建一个新的数据库句柄。 SDBM实际上使用两个物理文件,扩展名为“.dir”和“.pag”。 这些扩展名将自动附加到文件名中。

如果该文件不存在,将使用给定模式创建一个新文件,除非模式显式设置为nil。 在后一种情况下,不会创建数据库。

如果文件存在,它将以读/写模式打开。如果失败,它将以只读模式打开。

static VALUE
fsdbm_initialize(int argc, VALUE *argv, VALUE obj)
{
    VALUE file, vmode;
    DBM *dbm;
    struct dbmdata *dbmp;
    int mode;

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

    dbm = 0;
    if (mode >= 0)
        dbm = sdbm_open(RSTRING_PTR(file), O_RDWR|O_CREAT, mode);
    if (!dbm)
        dbm = sdbm_open(RSTRING_PTR(file), O_RDWR, 0);
    if (!dbm)
        dbm = sdbm_open(RSTRING_PTR(file), O_RDONLY, 0);

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

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

    return obj;
}

open(filename, mode = 0666) Show source

open(filename, mode = 0666) { |sdbm| ... }

如果不带块调用,那么这与:: new相同。

如果给出了一个块,新的数据库将被传递给该块,并在块执行后安全关闭。

例:

require 'sdbm'

SDBM.open('my_database') do |db|
  db['hello'] = 'world'
end
static VALUE
fsdbm_s_open(int argc, VALUE *argv, VALUE klass)
{
    VALUE obj = fsdbm_alloc(klass);

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

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

    return obj;
}

公共实例方法

sdbmkey → value or nil Show source

返回与给定键字符串关联的数据库中的值。

如果未找到任何值,则返回nil

static VALUE
fsdbm_aref(VALUE obj, VALUE keystr)
{
    return fsdbm_fetch(obj, keystr, Qnil);
}

sdbmkey = value → value Show source

将给定键作为索引在数据库中存储新值。

如果key已经存在,则会更新与key关联的value。

返回给定的value

static VALUE
fsdbm_store(VALUE obj, VALUE keystr, VALUE valstr)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;

    if (valstr == Qnil) {
        fsdbm_delete(obj, keystr);
        return Qnil;
    }

    fdbm_modify(obj);
    ExportStringValue(keystr);
    ExportStringValue(valstr);

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

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

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

    return valstr;
}

clear → self Show source

从数据库中删除所有数据。

static VALUE
fsdbm_clear(VALUE obj)
{
    datum key;
    struct dbmdata *dbmp;
    DBM *dbm;

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

    return obj;
}

close → nil Show source

关闭数据库文件。

如果数据库已关闭,则引发SDBME错误。

static VALUE
fsdbm_close(VALUE obj)
{
    struct dbmdata *dbmp;

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

    return Qnil;
}

closed? → true or false Show source

如果数据库关闭,则返回true。

static VALUE
fsdbm_closed(VALUE obj)
{
    struct dbmdata *dbmp;

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

    return Qfalse;
}

delete(key) → value or nil Show source

delete(key) { |key, value| ... }

删除与给定键相对应的键值对。 如果键存在,则删除的值将被返回,否则为零。

如果提供了块,则删除key并将value作为参数传递给块。如果数据库中不存在key,则值将为nil

static VALUE
fsdbm_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_LENINT(keystr);

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

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

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

    if (sdbm_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 { |key, value| ... } → self Show source

遍历数据库中的键值对,删除块返回true的那些键值对。

static VALUE
fsdbm_delete_if(VALUE obj)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;
    VALUE keystr, valstr;
    VALUE ret, ary = rb_ary_new();
    long i;
    int status = 0, n;

    fdbm_modify(obj);
    GetDBM2(obj, dbmp, dbm);
    n = dbmp->di_size;
    dbmp->di_size = -1;
    for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
        val = sdbm_fetch(dbm, key);
        keystr = rb_external_str_new(key.dptr, key.dsize);
        valstr = rb_external_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_AREF(ary, i);
        ExportStringValue(keystr);
        key.dptr = RSTRING_PTR(keystr);
        key.dsize = RSTRING_LENINT(keystr);
        if (sdbm_delete(dbm, key)) {
            rb_raise(rb_eDBMError, "sdbm_delete failed");
        }
    }
    if (status) rb_jump_tag(status);
    if (n > 0) dbmp->di_size = n - RARRAY_LENINT(ary);

    return obj;
}

每个显示源

each { |key, value| ... }

each_pair

each_pair { |key, value| ... }

迭代数据库中的每个键值对。

如果没有给出块,则返回一个枚举器。

static VALUE
fsdbm_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 = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
        val = sdbm_fetch(dbm, key);
        keystr = rb_external_str_new(key.dptr, key.dsize);
        valstr = rb_external_str_new(val.dptr, val.dsize);
        rb_yield(rb_assoc_new(keystr, valstr));
        GetDBM2(obj, dbmp, dbm);
    }

    return obj;
}

each_key Show source

each_key { |key| ... }

迭代数据库中的每个键。

如果没有给出块,则返回一个枚举器。

static VALUE
fsdbm_each_key(VALUE obj)
{
    datum key;
    struct dbmdata *dbmp;
    DBM *dbm;

    RETURN_ENUMERATOR(obj, 0, 0);

    GetDBM2(obj, dbmp, dbm);
    for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
        rb_yield(rb_external_str_new(key.dptr, key.dsize));
        GetDBM2(obj, dbmp, dbm);
    }
    return obj;
}

each_pair Show source

each_pair { |key, value| ... }

迭代数据库中的每个键值对。

如果没有给出块,则返回一个枚举器。

static VALUE
fsdbm_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 = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
        val = sdbm_fetch(dbm, key);
        keystr = rb_external_str_new(key.dptr, key.dsize);
        valstr = rb_external_str_new(val.dptr, val.dsize);
        rb_yield(rb_assoc_new(keystr, valstr));
        GetDBM2(obj, dbmp, dbm);
    }

    return obj;
}

each_value Show source

each_value { |value| ... }

迭代数据库中的每个值。

如果没有给出块,则返回一个枚举器。

static VALUE
fsdbm_each_value(VALUE obj)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;

    RETURN_ENUMERATOR(obj, 0, 0);

    GetDBM2(obj, dbmp, dbm);
    for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
        val = sdbm_fetch(dbm, key);
        rb_yield(rb_external_str_new(val.dptr, val.dsize));
        GetDBM2(obj, dbmp, dbm);
    }
    return obj;
}

empty? → true or false Show source

如果数据库为空,则返回true。

static VALUE
fsdbm_empty_p(VALUE obj)
{
    datum key;
    struct dbmdata *dbmp;
    DBM *dbm;

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

        for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
            return Qfalse;
        }
    }
    else {
        if (dbmp->di_size)
            return Qfalse;
    }
    return Qtrue;
}

fetch(key) → value or nil Show source

fetch(key) { |key| ... }

返回与给定键字符串关联的数据库中的值。

如果提供了一个块,当没有与给定键相关的值时,块将被调用。 该键将作为参数传递给该块。

如果没有提供块并且没有值与给定关联键,则会引发IndexError。

static VALUE
fsdbm_fetch_m(int argc, VALUE *argv, VALUE obj)
{
    VALUE keystr, valstr, ifnone;

    rb_scan_args(argc, argv, "11", &keystr, &ifnone);
    valstr = fsdbm_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?(key) → true or false Show source

如果数据库包含给定的键,则返回true。

static VALUE
fsdbm_has_key(VALUE obj, VALUE keystr)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;

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

    GetDBM2(obj, dbmp, dbm);
    val = sdbm_fetch(dbm, key);
    if (val.dptr) return Qtrue;
    return Qfalse;
}

has_value?(key) → true or false Show source

如果数据库包含给定值,则返回true。

static VALUE
fsdbm_has_value(VALUE obj, VALUE valstr)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;

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

    GetDBM2(obj, dbmp, dbm);
    for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
        val = sdbm_fetch(dbm, key);
        if (val.dsize == RSTRING_LENINT(valstr) &&
            memcmp(val.dptr, RSTRING_PTR(valstr), val.dsize) == 0)
            return Qtrue;
    }
    return Qfalse;
}

include?(key) → true or false Show source

如果数据库包含给定的键,则返回true。

static VALUE
fsdbm_has_key(VALUE obj, VALUE keystr)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;

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

    GetDBM2(obj, dbmp, dbm);
    val = sdbm_fetch(dbm, key);
    if (val.dptr) return Qtrue;
    return Qfalse;
}

invert → Hash Show source

返回键值对已颠倒的哈希。

例:

require 'sdbm'

SDBM.open 'my_database' do |db|
  db.update('apple' => 'fruit', 'spinach' => 'vegetable')

  db.invert  #=> {"fruit" => "apple", "vegetable" => "spinach"}
end
static VALUE
fsdbm_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 = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
        val = sdbm_fetch(dbm, key);
        keystr = rb_external_str_new(key.dptr, key.dsize);
        valstr = rb_external_str_new(val.dptr, val.dsize);
        rb_hash_aset(hash, valstr, keystr);
    }
    return hash;
}

key(value) → key Show source

返回与给定值关联的键。 如果多于一个键对应于给定值,则将返回要找到的第一个键。 如果找不到键,则会返回零。

static VALUE
fsdbm_key(VALUE obj, VALUE valstr)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;

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

    GetDBM2(obj, dbmp, dbm);
    for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
        val = sdbm_fetch(dbm, key);
        if (val.dsize == RSTRING_LEN(valstr) &&
            memcmp(val.dptr, RSTRING_PTR(valstr), val.dsize) == 0)
            return rb_external_str_new(key.dptr, key.dsize);
    }
    return Qnil;
}

key?(key) → true or false Show source

如果数据库包含给定的键,则返回true。

static VALUE
fsdbm_has_key(VALUE obj, VALUE keystr)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;

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

    GetDBM2(obj, dbmp, dbm);
    val = sdbm_fetch(dbm, key);
    if (val.dptr) return Qtrue;
    return Qfalse;
}

keys → Array Show source

返回包含数据库中的键的新数组。

static VALUE
fsdbm_keys(VALUE obj)
{
    datum key;
    struct dbmdata *dbmp;
    DBM *dbm;
    VALUE ary;

    GetDBM2(obj, dbmp, dbm);
    ary = rb_ary_new();
    for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
        rb_ary_push(ary, rb_external_str_new(key.dptr, key.dsize));
    }

    return ary;
}

length → integer Show source

返回数据库中的键的数量。

static VALUE
fsdbm_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 = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
        i++;
    }
    dbmp->di_size = i;

    return INT2FIX(i);
}

member?(key) → true or false Show source

如果数据库包含给定的键,则返回true。

static VALUE
fsdbm_has_key(VALUE obj, VALUE keystr)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;

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

    GetDBM2(obj, dbmp, dbm);
    val = sdbm_fetch(dbm, key);
    if (val.dptr) return Qtrue;
    return Qfalse;
}

reject { |key, value| ... } → Hash Show source

使用数据库中的键值对创建一个新的Hash,然后使用给定的块调用Hash#reject,这会返回一个散列值,只有块返回false的键值对。

static VALUE
fsdbm_reject(VALUE obj)
{
    return rb_hash_delete_if(fsdbm_to_hash(obj));
}

reject! { |key, value| ... } → self Show source

遍历数据库中的键值对,删除块返回true的那些键值对。

static VALUE
fsdbm_delete_if(VALUE obj)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;
    VALUE keystr, valstr;
    VALUE ret, ary = rb_ary_new();
    long i;
    int status = 0, n;

    fdbm_modify(obj);
    GetDBM2(obj, dbmp, dbm);
    n = dbmp->di_size;
    dbmp->di_size = -1;
    for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
        val = sdbm_fetch(dbm, key);
        keystr = rb_external_str_new(key.dptr, key.dsize);
        valstr = rb_external_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_AREF(ary, i);
        ExportStringValue(keystr);
        key.dptr = RSTRING_PTR(keystr);
        key.dsize = RSTRING_LENINT(keystr);
        if (sdbm_delete(dbm, key)) {
            rb_raise(rb_eDBMError, "sdbm_delete failed");
        }
    }
    if (status) rb_jump_tag(status);
    if (n > 0) dbmp->di_size = n - RARRAY_LENINT(ary);

    return obj;
}

replace(pairs) → self Show source

清空数据库,然后插入给定的键值对。

这个方法可以处理任何实现#each_pair方法的对象,比如Hash。

static VALUE
fsdbm_replace(VALUE obj, VALUE other)
{
    fsdbm_clear(obj);
    rb_block_call(other, rb_intern("each_pair"), 0, 0, update_i, obj);
    return obj;
}

select { |key, value| ... } → Array Show source

返回块返回true的新的键值对的数组。

例:

require 'sdbm'

SDBM.open 'my_database' do |db|
  db['apple'] = 'fruit'
  db['pear'] = 'fruit'
  db['spinach'] = 'vegetable'

  veggies = db.select do |key, value|
    value == 'vegetable'
  end #=> [["apple", "fruit"], ["pear", "fruit"]]
end
static VALUE
fsdbm_select(VALUE obj)
{
    VALUE new = rb_ary_new();
    datum key, val;
    DBM *dbm;
    struct dbmdata *dbmp;

    GetDBM2(obj, dbmp, dbm);
    for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
        VALUE assoc, v;
        val = sdbm_fetch(dbm, key);
        assoc = rb_assoc_new(rb_external_str_new(key.dptr, key.dsize),
                             rb_external_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 → Array or nil Show source

从数据库中删除一个键值对并将它们作为一个数组返回。 如果数据库为空,则返回nil。

static VALUE
fsdbm_shift(VALUE obj)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;
    VALUE keystr, valstr;

    fdbm_modify(obj);
    GetDBM2(obj, dbmp, dbm);
    key = sdbm_firstkey(dbm);
    if (!key.dptr) return Qnil;
    val = sdbm_fetch(dbm, key);
    keystr = rb_external_str_new(key.dptr, key.dsize);
    valstr = rb_external_str_new(val.dptr, val.dsize);
    sdbm_delete(dbm, key);
    if (dbmp->di_size >= 0) {
        dbmp->di_size--;
    }

    return rb_assoc_new(keystr, valstr);
}

size → integer Show source

返回数据库中的键的数量。

static VALUE
fsdbm_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 = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
        i++;
    }
    dbmp->di_size = i;

    return INT2FIX(i);
}

store(key, value) → value Show source

将给定键作为索引在数据库中存储新值。

如果键已经存在,则会更新与键关联的值。

返回给定的value

static VALUE
fsdbm_store(VALUE obj, VALUE keystr, VALUE valstr)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;

    if (valstr == Qnil) {
        fsdbm_delete(obj, keystr);
        return Qnil;
    }

    fdbm_modify(obj);
    ExportStringValue(keystr);
    ExportStringValue(valstr);

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

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

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

    return valstr;
}

to_a → Array Show source

返回包含数据库中每个键值对的新Array。

例:

require 'sdbm'

SDBM.open 'my_database' do |db|
  db.update('apple' => 'fruit', 'spinach' => 'vegetable')

  db.to_a  #=> [["apple", "fruit"], ["spinach", "vegetable"]]
end
static VALUE
fsdbm_to_a(VALUE obj)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;
    VALUE ary;

    GetDBM2(obj, dbmp, dbm);
    ary = rb_ary_new();
    for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
        val = sdbm_fetch(dbm, key);
        rb_ary_push(ary, rb_assoc_new(rb_external_str_new(key.dptr, key.dsize),
                                      rb_external_str_new(val.dptr, val.dsize)));
    }

    return ary;
}

to_hash → Hash Show source

返回包含数据库中每个键值对的新Hash。

static VALUE
fsdbm_to_hash(VALUE obj)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;
    VALUE hash;

    GetDBM2(obj, dbmp, dbm);
    hash = rb_hash_new();
    for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
        val = sdbm_fetch(dbm, key);
        rb_hash_aset(hash, rb_external_str_new(key.dptr, key.dsize),
                           rb_external_str_new(val.dptr, val.dsize));
    }

    return hash;
}

update(pairs) → self Show source

插入或更新键值对。

这个方法可以处理任何实现#each_pair方法的对象,比如Hash。

static VALUE
fsdbm_update(VALUE obj, VALUE other)
{
    rb_block_call(other, rb_intern("each_pair"), 0, 0, update_i, obj);
    return obj;
}

value?(key) → true or false Show source

如果数据库包含给定值,则返回true。

static VALUE
fsdbm_has_value(VALUE obj, VALUE valstr)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;

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

    GetDBM2(obj, dbmp, dbm);
    for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
        val = sdbm_fetch(dbm, key);
        if (val.dsize == RSTRING_LENINT(valstr) &&
            memcmp(val.dptr, RSTRING_PTR(valstr), val.dsize) == 0)
            return Qtrue;
    }
    return Qfalse;
}

values → Array Show source

返回包含数据库中值的新数组。

static VALUE
fsdbm_values(VALUE obj)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;
    VALUE ary;

    GetDBM2(obj, dbmp, dbm);
    ary = rb_ary_new();
    for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
        val = sdbm_fetch(dbm, key);
        rb_ary_push(ary, rb_external_str_new(val.dptr, val.dsize));
    }

    return ary;
}

values_at(key, ...) → Array Show source

返回与给定键相对应的值数组。

static VALUE
fsdbm_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, fsdbm_fetch(obj, argv[i], Qnil));
    }

    return new;
}
SDBM
Ruby 2.4

Ruby 是一种面向对象、命令式、函数式、动态的通用编程语言,是世界上最优美而巧妙的语言。

主页 https://www.ruby-lang.org/
源码 https://github.com/ruby/ruby
版本 2.4
发布版本 2.4.1

Ruby 2.4目录

1.缩略 | Abbrev
2.ARGF
3.数组 | Array
4.Base64
5.基本对象 | BasicObject
6.基准测试 | Benchmark
7.BigDecimal
8.绑定 | Binding
9.CGI
10.类 | Class
11.比较 | Comparable
12.负责 | Complex
13.计算续体 | Continuation
14.覆盖 | Coverage
15.CSV
16.日期 | Date
17.日期时间 | DateTime
18.DBM
19.代理 | Delegator
20.摘要 | Digest
21.Dir
22.DRb
23.编码 | Encoding
24.枚举 | Enumerable
25.枚举 | Enumerator
26.ENV
27.ERB
28.错误 | Errors
29.Etc
30.期望值 | Exception
31.错误类 | FalseClass
32.Fiber
33.Fiddle
34.文件 | File
35.文件实用程序 | FileUtils
36.查找 | Find
37.浮点 | Float
38.Forwardable
39.GC
40.GDBM
41.GetoptLong
42.Hash
43.Integer
44.IO
45.IPAddr
46.JSON
47.Kernel
48.语言 | 3Language
49.记录 | Logger
50.编排 | Marshal
51.MatchData
52.数学 | Math
53.矩阵 | Matrix
54.方法 | Method
55.模型 | Module
56.监控 | Monitor
57. 互斥 | Mutex
58.Net
59.Net::FTP
60.Net::HTTP
61.Net::IMAP
62.Net::SMTP
63.NilClass
64.数字 | Numeric
65.对象 | Object
66.ObjectSpace
67.Observable
68.Open3
69.OpenSSL
70.OpenStruct
71.OpenURI
72.OptionParser
73.路径名 | Pathname
74.完整输出 | PrettyPrint
75.Prime
76.Proc
77.过程 | Process
78.PStore
79.PTY
80.队列 | Queue
81.随机 | Random
82.范围 | Range
83.合理的 | Rational
84.Readline
85.Regexp
86.Resolv
87.Ripper
88.RubyVM
89.Scanf
90.SDBM
91.SecureRandom
92.Set
93.Shell
94.信号 | Signal
95.Singleton
96.套接字 | Socket
97.字符串 | String
98.StringIO
99.StringScanner
100.结构 | Struct