非常教程

Ruby 2.4参考手册

GDBM

GDBM

Parent:ObjectIncluded modules:Enumerable

概要

GNU dbm(gdbm)的Ruby扩展 - 一个简单的数据库引擎,用于在磁盘上存储键值对。

描述

GNU dbm是一个简单数据库的库。数据库是存储键值对的文件。Gdbm允许用户通过密钥存储,检索和删除数据。此外,它还允许对所有键值对进行无序遍历。gdbm数据库因此提供了与散列相同的功能。与Hash类的对象一样,可以使用元素访问元素[]。此外,GDBM在Enumerable模块中混合,因此提供了诸如查找,收集,映射等方便的方法。

一个进程可以同时打开几个不同的数据库。一个进程可以打开一个数据库作为“reader”或“writer”。鉴于reader只能读取数据库,writer具有读写访问权限。一个数据库可以被任何数量的reader或者同时只有一个writer访问。

示例

  1. 打开/创建数据库并填入一些条目:require'gdbm'gdbm = GDBM.new(“fruitstore.db”)gdbm“ananas”=“3”gdbm“banana”=“8”gdbm“cranberry”= “4909”gdbm.close

2. 读出数据库:

require 'gdbm' gdbm = GDBM.new("fruitstore.db") gdbm.each_pair do |key, value| print "#{key}: #{value}\n" end gdbm.close

produces

banana: 8 ananas: 3 cranberry: 4909

链接

  • www.gnu.org/software/gdbm/ConsumerFAST标志为新的和开放的。这个标志已经过时,gdbm> = 1.8NEWDB作为一个作者打开数据库;覆盖任何现有的数据库NOLOCK标记,作为新的open openREADER打开数据库的readerSYNC标志。仅适用于gdbm> = 1.8版本的gdbm库WRCREAT以编写者的身份打开数据库;如果数据库不存在,则创建一个新的oneWRITER打开数据库作为writerPublic类方法new(filename,mode = 0666,flags = nil)显示源通过打开名为filename的gdbm文件创建新的GDBM实例。如果该文件不存在,则将创建一个具有文件模式模式的新文件。标志可能是下列之一:
  • READER - 作为reader开放
  • WRITER -作为一个writer开放
  • WRCREAT - 作为writer开放;如果数据库不存在,请创建一个新数据库
  • NEWDB - 作为writer开放;覆盖任何现有的数据库值WRITERWRCREATNEWDB可以按位或按以下值组合:
  • SYNC - 使所有数据库操作与磁盘同步
  • NOLOCK - 不要锁定数据库文件

如果没有指定标志,GDBM对象将尝试以编写器的方式打开数据库文件,如果它尚不存在(cf. flag WRCREAT),将创建它。如果失败(例如,如果另一个进程已经将数据库作为读取器打开),它将尝试以读取器的方式打开数据库文件(cf. flag READER)。

static VALUE
fgdbm_initialize(int argc, VALUE *argv, VALUE obj)
{
    VALUE file, vmode, vflags;
    GDBM_FILE 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 does not exist */
    }
    else {
        mode = NUM2INT(vmode);
    }

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

    SafeStringValue(file);

#ifdef GDBM_CLOEXEC
    /* GDBM_CLOEXEC is available since gdbm 1.10. */
    flags |= GDBM_CLOEXEC;
#endif

    if (flags & RUBY_GDBM_RW_BIT) {
        flags &= ~RUBY_GDBM_RW_BIT;
        dbm = gdbm_open(RSTRING_PTR(file), MY_BLOCK_SIZE,
                        flags, mode, MY_FATAL_FUNC);
    }
    else {
        dbm = 0;
        if (mode >= 0)
            dbm = gdbm_open(RSTRING_PTR(file), MY_BLOCK_SIZE,
                            GDBM_WRCREAT|flags, mode, MY_FATAL_FUNC);
        if (!dbm)
            dbm = gdbm_open(RSTRING_PTR(file), MY_BLOCK_SIZE,
                            GDBM_WRITER|flags, 0, MY_FATAL_FUNC);
        if (!dbm)
            dbm = gdbm_open(RSTRING_PTR(file), MY_BLOCK_SIZE,
                            GDBM_READER|flags, 0, MY_FATAL_FUNC);
    }

    if (dbm) {
        rb_fd_fix_cloexec(gdbm_fdesc(dbm));
    }

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

        if (gdbm_errno == GDBM_FILE_OPEN_ERROR ||
            gdbm_errno == GDBM_CANT_BE_READER ||
            gdbm_errno == GDBM_CANT_BE_WRITER)
            rb_sys_fail_str(file);
        else
            rb_raise(rb_eGDBMError, "%s", gdbm_strerror(gdbm_errno));
    }

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

    return obj;
}

open(filename, mode = 0666, flags = nil) Show source

open(filename, mode = 0666, flags = nil) { |gdbm| ... }

如果没有一个块被调用,这是::new的同义词。如果给出了一个块,新的GDBM实例将作为参数传递给该块,并且在块代码执行完成后关闭相应的数据库文件。

带块的公开调用示例:

require 'gdbm'
GDBM.open("fruitstore.db") do |gdbm|
  gdbm.each_pair do |key, value|
    print "#{key}: #{value}\n"
  end
end
static VALUE
fgdbm_s_open(int argc, VALUE *argv, VALUE klass)
{
    VALUE obj = fgdbm_s_alloc(klass);

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

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

    return obj;
}

Public Instance Methods

gdbmkey → value Show source

检索与对应的

static VALUE
fgdbm_aref(VALUE obj, VALUE keystr)
{
    return rb_gdbm_fetch3(obj, keystr);
}

gdbmkey= value → value Show source

将值的与指定的键相关联

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

    rb_gdbm_modify(obj);
    StringValue(keystr);
    StringValue(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 (gdbm_store(dbm, key, val, GDBM_REPLACE)) {
        if (errno == EPERM) rb_sys_fail(0);
        rb_raise(rb_eGDBMError, "%s", gdbm_strerror(gdbm_errno));
    }

    return valstr;
}

cachesize = size → size Show source

将内部存储区高速缓存的大小设置为大小

static VALUE
fgdbm_set_cachesize(VALUE obj, VALUE val)
{
    struct dbmdata *dbmp;
    GDBM_FILE dbm;
    int optval;

    GetDBM2(obj, dbmp, dbm);
    optval = FIX2INT(val);
    if (gdbm_setopt(dbm, GDBM_CACHESIZE, &optval, sizeof(optval)) == -1) {
        rb_raise(rb_eGDBMError, "%s", gdbm_strerror(gdbm_errno));
    }
    return val;
}

clear → gdbm Show source

删除内的所有键值对GDBM

static VALUE
fgdbm_clear(VALUE obj)
{
    datum key, nextkey;
    struct dbmdata *dbmp;
    GDBM_FILE dbm;

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

#if 0
    while (key = gdbm_firstkey(dbm), key.dptr) {
        if (gdbm_delete(dbm, key)) {
            free(key.dptr);
            rb_raise(rb_eGDBMError, "%s", gdbm_strerror(gdbm_errno));
        }
        free(key.dptr);
    }
#else
    while (key = gdbm_firstkey(dbm), key.dptr) {
        for (; key.dptr; key = nextkey) {
            nextkey = gdbm_nextkey(dbm, key);
            if (gdbm_delete(dbm, key)) {
                free(key.dptr);
                if (nextkey.dptr) free(nextkey.dptr);
                rb_raise(rb_eGDBMError, "%s", gdbm_strerror(gdbm_errno));
            }
            free(key.dptr);
        }
    }
#endif
    dbmp->di_size = 0;

    return obj;
}

close → nil Show source

关闭关联的数据库文件。

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

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

    return Qnil;
}

closed? → true or false Show source

如果关联的数据库文件已关闭,则返回true。

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

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

    return Qfalse;
}

delete(key) → value or nil Show source

从此数据库中删除具有指定键的键值对并返回相应的。如果数据库为空,则返回nil。

static VALUE
fgdbm_delete(VALUE obj, VALUE keystr)
{
    VALUE valstr;

    valstr = fgdbm_fetch(obj, keystr, Qnil);
    rb_gdbm_delete(obj, keystr);
    return valstr;
}

delete_if { |key, value| block } → gdbm Show source

删除从每一个键-值对GDBM为哪些评估为真。

static VALUE
fgdbm_delete_if(VALUE obj)
{
    struct dbmdata *dbmp;
    GDBM_FILE dbm;
    VALUE keystr, valstr;
    VALUE ret, ary = rb_ary_tmp_new(0);
    long i;
    int status = 0, n;

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

    for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
         keystr = rb_gdbm_nextkey(dbm, keystr)) {

        OBJ_FREEZE(keystr);
        valstr = rb_gdbm_fetch2(dbm, keystr);
        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++)
        rb_gdbm_delete(obj, RARRAY_AREF(ary, i));
    if (status) rb_jump_tag(status);
    if (n > 0) dbmp->di_size = n - (int)RARRAY_LEN(ary);
    rb_ary_clear(ary);

    return obj;
}

each_pair { |key, value| block } → gdbm Show source

为数据库中的每个键执行,将和相应的作为参数传递。

static VALUE
fgdbm_each_pair(VALUE obj)
{
    GDBM_FILE dbm;
    struct dbmdata *dbmp;
    VALUE keystr;

    RETURN_ENUMERATOR(obj, 0, 0);

    GetDBM2(obj, dbmp, dbm);
    for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
         keystr = rb_gdbm_nextkey(dbm, keystr)) {

        rb_yield(rb_assoc_new(keystr, rb_gdbm_fetch2(dbm, keystr)));
        GetDBM2(obj, dbmp, dbm);
    }

    return obj;
}

each_key { |key| block } → gdbm Show source

为数据库中的每个密钥执行,将密钥作为参数传递。

static VALUE
fgdbm_each_key(VALUE obj)
{
    struct dbmdata *dbmp;
    GDBM_FILE dbm;
    VALUE keystr;

    RETURN_ENUMERATOR(obj, 0, 0);

    GetDBM2(obj, dbmp, dbm);
    for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
         keystr = rb_gdbm_nextkey(dbm, keystr)) {

        rb_yield(keystr);
        GetDBM2(obj, dbmp, dbm);
    }
    return obj;
}

each_pair { |key, value| block } → gdbm Show source

为数据库中的每个键执行,将和相应的作为参数传递。

static VALUE
fgdbm_each_pair(VALUE obj)
{
    GDBM_FILE dbm;
    struct dbmdata *dbmp;
    VALUE keystr;

    RETURN_ENUMERATOR(obj, 0, 0);

    GetDBM2(obj, dbmp, dbm);
    for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
         keystr = rb_gdbm_nextkey(dbm, keystr)) {

        rb_yield(rb_assoc_new(keystr, rb_gdbm_fetch2(dbm, keystr)));
        GetDBM2(obj, dbmp, dbm);
    }

    return obj;
}

each_value { |value| block } → gdbm Show source

为数据库中的每个键执行,将相应的作为参数传递。

static VALUE
fgdbm_each_value(VALUE obj)
{
    struct dbmdata *dbmp;
    GDBM_FILE dbm;
    VALUE keystr;

    RETURN_ENUMERATOR(obj, 0, 0);

    GetDBM2(obj, dbmp, dbm);
    for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
         keystr = rb_gdbm_nextkey(dbm, keystr)) {

        rb_yield(rb_gdbm_fetch2(dbm, keystr));
        GetDBM2(obj, dbmp, dbm);
    }
    return obj;
}

empty? → true or false Show source

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

static VALUE
fgdbm_empty_p(VALUE obj)
{
    datum key;
    struct dbmdata *dbmp;
    GDBM_FILE dbm;

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

        key = gdbm_firstkey(dbm);
        if (key.dptr) {
            free(key.dptr);
            return Qfalse;
        }
        return Qtrue;
    }

    if (dbmp->di_size == 0) return Qtrue;
    return Qfalse;
}

fastmode = boolean → boolean Show source

打开或关闭数据库的快速模式。如果打开快速模式,gdbm不会等待写入被刷新到磁盘,然后再继续。

由于默认打开快速模式,因此此选项已过时,因此gdbm> = 1.8。另请参阅:syncmode =

static VALUE
fgdbm_set_fastmode(VALUE obj, VALUE val)
{
    struct dbmdata *dbmp;
    GDBM_FILE dbm;
    int optval;

    GetDBM2(obj, dbmp, dbm);
    optval = 0;
    if (RTEST(val))
        optval = 1;

    if (gdbm_setopt(dbm, GDBM_FASTMODE, &optval, sizeof(optval)) == -1) {
        rb_raise(rb_eGDBMError, "%s", gdbm_strerror(gdbm_errno));
    }
    return val;
}

fetch(key , default) → value Show source

检索与对应的。如果没有与关联的值,则会返回默认值

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

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

如果给定键k存在于数据库中,则返回true 。否则返回false。

static VALUE
fgdbm_has_key(VALUE obj, VALUE keystr)
{
    datum key;
    struct dbmdata *dbmp;
    GDBM_FILE dbm;
    long len;

    StringValue(keystr);
    len = RSTRING_LENINT(keystr);
    if (TOO_LONG(len)) return Qfalse;
    key.dptr = RSTRING_PTR(keystr);
    key.dsize = (int)len;

    GetDBM2(obj, dbmp, dbm);
    if (gdbm_exists(dbm, key))
        return Qtrue;
    return Qfalse;
}

has_value?(v) → true or false Show source

如果给定值v存在于数据库中,则返回true 。否则返回false。

static VALUE
fgdbm_has_value(VALUE obj, VALUE valstr)
{
    struct dbmdata *dbmp;
    GDBM_FILE dbm;
    VALUE keystr, valstr2;

    StringValue(valstr);
    GetDBM2(obj, dbmp, dbm);
    for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
         keystr = rb_gdbm_nextkey(dbm, keystr)) {

        valstr2 = rb_gdbm_fetch2(dbm, keystr);

        if (!NIL_P(valstr2) &&
            (int)RSTRING_LEN(valstr) == (int)RSTRING_LEN(valstr2) &&
            memcmp(RSTRING_PTR(valstr), RSTRING_PTR(valstr2),
                   (int)RSTRING_LEN(valstr)) == 0) {
            return Qtrue;
        }
    }
    return Qfalse;
}

include?(k) → true or false Show source

如果给定键k存在于数据库中,则返回true 。否则返回false。

static VALUE
fgdbm_has_key(VALUE obj, VALUE keystr)
{
    datum key;
    struct dbmdata *dbmp;
    GDBM_FILE dbm;
    long len;

    StringValue(keystr);
    len = RSTRING_LENINT(keystr);
    if (TOO_LONG(len)) return Qfalse;
    key.dptr = RSTRING_PTR(keystr);
    key.dsize = (int)len;

    GetDBM2(obj, dbmp, dbm);
    if (gdbm_exists(dbm, key))
        return Qtrue;
    return Qfalse;
}

invert → hash Show source

返回通过使用gdbm的值作为键创建的散列,并将键作为值创建。

static VALUE
fgdbm_invert(VALUE obj)
{
    struct dbmdata *dbmp;
    GDBM_FILE dbm;
    VALUE keystr, valstr;
    VALUE hash = rb_hash_new();

    GetDBM2(obj, dbmp, dbm);
    for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
         keystr = rb_gdbm_nextkey(dbm, keystr)) {
        valstr = rb_gdbm_fetch2(dbm, keystr);

        rb_hash_aset(hash, valstr, keystr);
    }
    return hash;
}

key(value) → key Show source

返回给定。如果几个键可能映射到相同的值,则返回首先找到的键。

static VALUE
fgdbm_key(VALUE obj, VALUE valstr)
{
    struct dbmdata *dbmp;
    GDBM_FILE dbm;
    VALUE keystr, valstr2;

    StringValue(valstr);
    GetDBM2(obj, dbmp, dbm);
    for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
         keystr = rb_gdbm_nextkey(dbm, keystr)) {

        valstr2 = rb_gdbm_fetch2(dbm, keystr);
        if (!NIL_P(valstr2) &&
            (int)RSTRING_LEN(valstr) == (int)RSTRING_LEN(valstr2) &&
            memcmp(RSTRING_PTR(valstr), RSTRING_PTR(valstr2),
                   (int)RSTRING_LEN(valstr)) == 0) {
            return keystr;
        }
    }
    return Qnil;
}

key?(k) → true or false Show source

如果给定键k存在于数据库中,则返回true 。否则返回false。

static VALUE
fgdbm_has_key(VALUE obj, VALUE keystr)
{
    datum key;
    struct dbmdata *dbmp;
    GDBM_FILE dbm;
    long len;

    StringValue(keystr);
    len = RSTRING_LENINT(keystr);
    if (TOO_LONG(len)) return Qfalse;
    key.dptr = RSTRING_PTR(keystr);
    key.dsize = (int)len;

    GetDBM2(obj, dbmp, dbm);
    if (gdbm_exists(dbm, key))
        return Qtrue;
    return Qfalse;
}

keys → array Show source

返回此数据库所有键的数组。

static VALUE
fgdbm_keys(VALUE obj)
{
    struct dbmdata *dbmp;
    GDBM_FILE dbm;
    VALUE keystr, ary;

    GetDBM2(obj, dbmp, dbm);
    ary = rb_ary_new();
    for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
         keystr = rb_gdbm_nextkey(dbm, keystr)) {

        rb_ary_push(ary, keystr);
    }

    return ary;
}

length → fixnum Show source

返回此数据库中键值对的数量。

static VALUE
fgdbm_length(VALUE obj)
{
    datum key, nextkey;
    struct dbmdata *dbmp;
    GDBM_FILE dbm;
    int i = 0;

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

    for (key = gdbm_firstkey(dbm); key.dptr; key = nextkey) {
        nextkey = gdbm_nextkey(dbm, key);
        free(key.dptr);
        i++;
    }
    dbmp->di_size = i;

    return INT2FIX(i);
}

member?(k) → true or false Show source

如果给定键k存在于数据库中,则返回true 。否则返回false。

static VALUE
fgdbm_has_key(VALUE obj, VALUE keystr)
{
    datum key;
    struct dbmdata *dbmp;
    GDBM_FILE dbm;
    long len;

    StringValue(keystr);
    len = RSTRING_LENINT(keystr);
    if (TOO_LONG(len)) return Qfalse;
    key.dptr = RSTRING_PTR(keystr);
    key.dsize = (int)len;

    GetDBM2(obj, dbmp, dbm);
    if (gdbm_exists(dbm, key))
        return Qtrue;
    return Qfalse;
}

reject { |key, value| block } → hash Show source

返回gdbm的散列副本,其中删除了gdbm中哪些评估为true的所有键值对。另见:delete_if

static VALUE
fgdbm_reject(VALUE obj)
{
    return rb_hash_delete_if(fgdbm_to_hash(obj));
}

reject! { |key, value| block } → gdbm Show source

删除从每一个键-值对GDBM为哪些评估为真。

static VALUE
fgdbm_delete_if(VALUE obj)
{
    struct dbmdata *dbmp;
    GDBM_FILE dbm;
    VALUE keystr, valstr;
    VALUE ret, ary = rb_ary_tmp_new(0);
    long i;
    int status = 0, n;

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

    for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
         keystr = rb_gdbm_nextkey(dbm, keystr)) {

        OBJ_FREEZE(keystr);
        valstr = rb_gdbm_fetch2(dbm, keystr);
        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++)
        rb_gdbm_delete(obj, RARRAY_AREF(ary, i));
    if (status) rb_jump_tag(status);
    if (n > 0) dbmp->di_size = n - (int)RARRAY_LEN(ary);
    rb_ary_clear(ary);

    return obj;
}

reorganize → gdbm Show source

重新组织数据库文件。该操作删除已被删除的元素的保留空间。它仅在数据库中大量删除后才有用。

static VALUE
fgdbm_reorganize(VALUE obj)
{
    struct dbmdata *dbmp;
    GDBM_FILE dbm;

    rb_gdbm_modify(obj);
    GetDBM2(obj, dbmp, dbm);
    gdbm_reorganize(dbm);
    rb_fd_fix_cloexec(gdbm_fdesc(dbm));
    return obj;
}

replace(other) → gdbm Show source

替换的内容GDBM用的键值对其他必须有#each_pair方法。

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

select { |key, value| block } → array Show source

返回块的计算结果为true 的数据库的所有键值对的新数组。

static VALUE
fgdbm_select(VALUE obj)
{
    VALUE new = rb_ary_new();
    GDBM_FILE dbm;
    struct dbmdata *dbmp;
    VALUE keystr;

    GetDBM2(obj, dbmp, dbm);
    for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
         keystr = rb_gdbm_nextkey(dbm, keystr)) {
        VALUE assoc = rb_assoc_new(keystr, rb_gdbm_fetch2(dbm, keystr));
        VALUE v = rb_yield(assoc);

        if (RTEST(v)) {
            rb_ary_push(new, assoc);
        }
        GetDBM2(obj, dbmp, dbm);
    }

    return new;
}

shift → (key, value) or nil Show source

从该数据库中除去一个键值对,并将其作为两项数组 值返回。如果数据库为空,则返回nil。

static VALUE
fgdbm_shift(VALUE obj)
{
    struct dbmdata *dbmp;
    GDBM_FILE dbm;
    VALUE keystr, valstr;

    rb_gdbm_modify(obj);
    GetDBM2(obj, dbmp, dbm);
    keystr = rb_gdbm_firstkey(dbm);
    if (NIL_P(keystr)) return Qnil;
    valstr = rb_gdbm_fetch2(dbm, keystr);
    rb_gdbm_delete(obj, keystr);

    return rb_assoc_new(keystr, valstr);
}

size → fixnum Show source

返回此数据库中键值对的数量。

static VALUE
fgdbm_length(VALUE obj)
{
    datum key, nextkey;
    struct dbmdata *dbmp;
    GDBM_FILE dbm;
    int i = 0;

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

    for (key = gdbm_firstkey(dbm); key.dptr; key = nextkey) {
        nextkey = gdbm_nextkey(dbm, key);
        free(key.dptr);
        i++;
    }
    dbmp->di_size = i;

    return INT2FIX(i);
}

store(key, value) → value Show source

将值的与指定的键相关联

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

    rb_gdbm_modify(obj);
    StringValue(keystr);
    StringValue(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 (gdbm_store(dbm, key, val, GDBM_REPLACE)) {
        if (errno == EPERM) rb_sys_fail(0);
        rb_raise(rb_eGDBMError, "%s", gdbm_strerror(gdbm_errno));
    }

    return valstr;
}

sync → gdbm Show source

除非使用SYNC标志打开gdbm对象,否则不能保证数据库修改操作立即应用于数据库文件。此方法可确保将最近对数据库的所有修改写入文件。阻塞,直到完成对磁盘的所有写入操作。

static VALUE
fgdbm_sync(VALUE obj)
{
    struct dbmdata *dbmp;
    GDBM_FILE dbm;

    rb_gdbm_modify(obj);
    GetDBM2(obj, dbmp, dbm);
    gdbm_sync(dbm);
    return obj;
}

syncmode = boolean → boolean Show source

打开或关闭数据库的同步模式。如果同步模式打开,则在每次数据库修改操作后,数据库的内存中状态都将同步到磁盘。如果关闭同步模式,则GDBM在继续之前不会等待写入刷新到磁盘。

此选项仅适用于gdbm> = 1.8,默认关闭syncmode。另请参阅:fastmode =

static VALUE
fgdbm_set_syncmode(VALUE obj, VALUE val)
{
#if !defined(GDBM_SYNCMODE)
    fgdbm_set_fastmode(obj, RTEST(val) ? Qfalse : Qtrue);
    return val;
#else
    struct dbmdata *dbmp;
    GDBM_FILE dbm;
    int optval;

    GetDBM2(obj, dbmp, dbm);
    optval = 0;
    if (RTEST(val))
        optval = 1;

    if (gdbm_setopt(dbm, GDBM_FASTMODE, &optval, sizeof(optval)) == -1) {
        rb_raise(rb_eGDBMError, "%s", gdbm_strerror(gdbm_errno));
    }
    return val;
#endif
}

to_a → array Show source

返回数据库中包含的所有键值对的数组。

static VALUE
fgdbm_to_a(VALUE obj)
{
    struct dbmdata *dbmp;
    GDBM_FILE dbm;
    VALUE keystr, ary;

    GetDBM2(obj, dbmp, dbm);
    ary = rb_ary_new();
    for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
         keystr = rb_gdbm_nextkey(dbm, keystr)) {

        rb_ary_push(ary, rb_assoc_new(keystr, rb_gdbm_fetch2(dbm, keystr)));
    }

    return ary;
}

to_hash → hash Show source

返回数据库中包含的所有键值对的散列。

static VALUE
fgdbm_to_hash(VALUE obj)
{
    struct dbmdata *dbmp;
    GDBM_FILE dbm;
    VALUE keystr, hash;

    GetDBM2(obj, dbmp, dbm);
    hash = rb_hash_new();
    for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
         keystr = rb_gdbm_nextkey(dbm, keystr)) {

        rb_hash_aset(hash, keystr, rb_gdbm_fetch2(dbm, keystr));
    }

    return hash;
}

update(other) → gdbm Show source

添加的键值对其他GDBM,覆盖与那些重复的键条目其他必须有#each_pair方法。

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

value?(v) → true or false Show source

如果给定值v存在于数据库中,则返回true 。否则返回false。

static VALUE
fgdbm_has_value(VALUE obj, VALUE valstr)
{
    struct dbmdata *dbmp;
    GDBM_FILE dbm;
    VALUE keystr, valstr2;

    StringValue(valstr);
    GetDBM2(obj, dbmp, dbm);
    for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
         keystr = rb_gdbm_nextkey(dbm, keystr)) {

        valstr2 = rb_gdbm_fetch2(dbm, keystr);

        if (!NIL_P(valstr2) &&
            (int)RSTRING_LEN(valstr) == (int)RSTRING_LEN(valstr2) &&
            memcmp(RSTRING_PTR(valstr), RSTRING_PTR(valstr2),
                   (int)RSTRING_LEN(valstr)) == 0) {
            return Qtrue;
        }
    }
    return Qfalse;
}

values → array Show source

返回此数据库所有值的数组。

static VALUE
fgdbm_values(VALUE obj)
{
    datum key, nextkey;
    struct dbmdata *dbmp;
    GDBM_FILE dbm;
    VALUE valstr, ary;

    GetDBM2(obj, dbmp, dbm);
    ary = rb_ary_new();
    for (key = gdbm_firstkey(dbm); key.dptr; key = nextkey) {
        nextkey = gdbm_nextkey(dbm, key);
        valstr = rb_gdbm_fetch(dbm, key);
        free(key.dptr);
        rb_ary_push(ary, valstr);
    }

    return ary;
}

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

返回与每个指定相关联的值的数组。

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

    return new;
}
GDBM
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