класс GDBM
Краткое описание
Расширение Ruby для GNU dbm (gdbm) – простой движок базы данных для хранения пар ключ-значение на диске.
Описание
GNU dbm — библиотека для простых баз данных. База данных — это файл, хранящий пары ключ-значение. Gdbm позволяет пользователю хранить, извлекать и удалять данные по ключу. Кроме того, он позволяет выполнить несортированный проход по всем парам ключ-значение. Таким образом, база данных gdbm предоставляет такие же функциональные возможности, как и хэш. Как и объекты класса Hash, к элементам можно обратиться с помощью []. Кроме того, GDBM включает модуль Enumerable, предоставляя удобные методы, такие как find, collect, map и т. д.
Процесс может открыть несколько разных баз данных одновременно. Процесс может открыть базу данных как «читатель» или «писатель». Читатель имеет только доступ для чтения к базе данных, а писатель имеет доступ для чтения и записи. К базе данных могут обращаться любое количество читателей или ровно один писатель одновременно.
Примеры
-
Открытие/создание базы данных и заполнение ее некоторыми записями:
require 'gdbm' gdbm = GDBM.new("fruitstore.db") gdbm["ananas"] = "3" gdbm["banana"] = "8" gdbm["cranberry"] = "4909" gdbm.close -
Чтение базы данных:
require 'gdbm' gdbm = GDBM.new("fruitstore.db") gdbm.each_pair do |key, value| print "#{key}: #{value}\n" end gdbm.closeвыводит
banana: 8 ananas: 3 cranberry: 4909
Ссылки
Константы
- FAST
-
флаг для нового и
open. Этот флаг устарел для gdbm >= 1.8 - NEWDB
-
открытие базы данных как писателя; перезапись существующих баз данных
- NOLOCK
-
флаг для нового и
open - READER
-
открытие базы данных как читателя
- SYNC
-
флаг для нового и
open. Только для gdbm >= 1.8 - VERSION
-
версия библиотеки gdbm
- WRCREAT
-
открытие базы данных как писателя; если база данных не существует, создать новую
- WRITER
-
открытие базы данных как писателя
Публичные методы класса
static VALUE
fgdbm_initialize(int argc, VALUE *argv, VALUE obj)
{
VALUE file, vmode, vflags;
GDBM_FILE dbm;
struct dbmdata *dbmp;
int mode, flags = 0;
TypedData_Get_Struct(obj, struct dbmdata, &dbm_type, dbmp);
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);
FilePathValue(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));
}
if (dbmp->di_dbm)
gdbm_close(dbmp->di_dbm);
dbmp->di_dbm = dbm;
dbmp->di_size = -1;
return obj;
} Создает новый экземпляр GDBM, открывая файл gdbm с именем filename. Если файл не существует, будет создан новый файл с режимом файла mode. flags может быть одним из следующих:
-
READER - открыть как читатель
-
WRITER - открыть как писатель
-
WRCREAT - открыть как писатель; если база данных не существует, создать новую
-
NEWDB - открыть как писатель; перезаписать любые существующие базы данных
Значения WRITER, WRCREAT и NEWDB могут быть объединены с помощью побитового ИЛИ:
-
SYNC - заставить все операции с базой данных синхронизироваться с диском
-
NOLOCK - не блокировать файл базы данных
Если flags не указаны, объект GDBM попытается открыть файл базы данных как писателя и создаст его, если он не существует (см. флаг WRCREAT). Если это не удастся (например, если другой процесс уже открыл базу данных как читатель), он попытается открыть файл базы данных как читатель (см. флаг READER).
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;
} Если вызов без блока, это синоним GDBM::new. Если блок задан, новый экземпляр GDBM будет передан в блок как параметр, а соответствующий файл базы данных будет закрыт после выполнения кода блока.
Пример вызова open с блоком:
require 'gdbm'
GDBM.open("fruitstore.db") do |gdbm|
gdbm.each_pair do |key, value|
print "#{key}: #{value}\n"
end
end
Публичные методы экземпляра
static VALUE
fgdbm_aref(VALUE obj, VALUE keystr)
{
return rb_gdbm_fetch3(obj, keystr);
} Извлекает значение, соответствующее ключу.
static VALUE
fgdbm_store(VALUE obj, VALUE keystr, VALUE valstr)
{
datum key, val;
struct dbmdata *dbmp;
GDBM_FILE dbm;
rb_gdbm_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 (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;
} Связывает значение value с указанным ключом.
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;
} Устанавливает размер внутреннего кэша корзины в size.
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;
} Удаляет все пары ключ-значение из gdbm.
static VALUE
fgdbm_close(VALUE obj)
{
struct dbmdata *dbmp;
GetDBM(obj, dbmp);
gdbm_close(dbmp->di_dbm);
dbmp->di_dbm = 0;
return Qnil;
} Закрывает связанный файл базы данных.
static VALUE
fgdbm_closed(VALUE obj)
{
struct dbmdata *dbmp;
TypedData_Get_Struct(obj, struct dbmdata, &dbm_type, dbmp);
if (dbmp->di_dbm == 0)
return Qtrue;
return Qfalse;
} Возвращает true, если связанный файл базы данных был закрыт.
static VALUE
fgdbm_delete(VALUE obj, VALUE keystr)
{
VALUE valstr;
valstr = fgdbm_fetch(obj, keystr, Qnil);
rb_gdbm_delete(obj, keystr);
return valstr;
} Удаляет пару ключ-значение с указанным ключом из этой базы данных и возвращает соответствующее значение. Возвращает nil, если база данных пуста.
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;
} Удаляет каждую пару ключ-значение из gdbm, для которой блок вычисляет true.
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;
} Выполняет блок для каждого ключа в базе данных, передавая ключ и соответствующее значение в качестве параметра.
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;
} Выполняет блок для каждого ключа в базе данных, передавая ключ в качестве параметра.
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;
} Выполняет блок для каждого ключа в базе данных, передавая ключ и соответствующее значение в качестве параметра.
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;
} Выполняет блок для каждого ключа в базе данных, передавая соответствующее значение в качестве параметра.
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;
} Возвращает true, если база данных пуста.
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;
} Включает или выключает быстрый режим базы данных. Если быстрый режим включен, gdbm не ждет завершения записи на диск перед продолжением.
Этот параметр устарел для gdbm >= 1.8, так как быстрый режим включен по умолчанию. См. также: syncmode=
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;
} Извлекает значение, соответствующее ключу. Если нет значения, связанного с ключом, будет возвращено значение по умолчанию.
static VALUE
fgdbm_has_key(VALUE obj, VALUE keystr)
{
datum key;
struct dbmdata *dbmp;
GDBM_FILE dbm;
long len;
ExportStringValue(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;
} Возвращает true, если данный ключ k существует в базе данных. Возвращает false в противном случае.
static VALUE
fgdbm_has_value(VALUE obj, VALUE valstr)
{
struct dbmdata *dbmp;
GDBM_FILE dbm;
VALUE keystr, valstr2;
ExportStringValue(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;
} Возвращает true, если данное значение v существует в базе данных. Возвращает false в противном случае.
static VALUE
fgdbm_has_key(VALUE obj, VALUE keystr)
{
datum key;
struct dbmdata *dbmp;
GDBM_FILE dbm;
long len;
ExportStringValue(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;
} Возвращает true, если данный ключ k существует в базе данных. Возвращает false в противном случае.
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;
} Возвращает хэш, созданный с использованием значений gdbm в качестве ключей, а ключей - в качестве значений.
static VALUE
fgdbm_key(VALUE obj, VALUE valstr)
{
struct dbmdata *dbmp;
GDBM_FILE dbm;
VALUE keystr, valstr2;
ExportStringValue(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;
} Возвращает ключ для данного значения. Если несколько ключей могут соответствовать одному значению, будет возвращен ключ, который найден первым.
static VALUE
fgdbm_has_key(VALUE obj, VALUE keystr)
{
datum key;
struct dbmdata *dbmp;
GDBM_FILE dbm;
long len;
ExportStringValue(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;
} Возвращает true, если данный ключ k существует в базе данных. Возвращает false в противном случае.
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;
} Возвращает массив всех ключей этой базы данных.
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);
} Возвращает количество пар ключ-значение в этой базе данных.
static VALUE
fgdbm_has_key(VALUE obj, VALUE keystr)
{
datum key;
struct dbmdata *dbmp;
GDBM_FILE dbm;
long len;
ExportStringValue(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;
} Возвращает true, если данный ключ k существует в базе данных. Возвращает false в противном случае.
static VALUE
fgdbm_reject(VALUE obj)
{
return rb_hash_delete_if(fgdbm_to_hash(obj));
} Возвращает копию хэша gdbm, где удалены все пары ключ-значение из gdbm, для которых блок вычисляет true. См. также: delete_if
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;
} Удаляет каждую пару ключ-значение из gdbm, для которой блок вычисляет true.
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;
} Переупорядочивает файл базы данных. Данная операция удаляет зарезервированное пространство элементов, которые уже были удалены. Она полезна только после большого количества удалений в базе данных.
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;
} Заменяет содержимое gdbm на пары ключ-значение из other. other должен иметь метод each_pair.
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;
} Возвращает новый массив всех пар ключ-значение базы данных, для которых block вычисляет значение true.
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);
} Удаляет пару ключ-значение из этой базы данных и возвращает её как массив из двух элементов [ ключ, значение ]. Возвращает nil, если база данных пуста.
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);
} Возвращает количество пар ключ-значение в этой базе данных.
static VALUE
fgdbm_store(VALUE obj, VALUE keystr, VALUE valstr)
{
datum key, val;
struct dbmdata *dbmp;
GDBM_FILE dbm;
rb_gdbm_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 (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;
} Связывает значение value с указанным ключом.
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;
} Если объект gdbm открыт без флага SYNC, нет гарантии, что операции изменения базы данных будут сразу применены к файлу базы данных. Этот метод гарантирует, что все недавние изменения в базе данных будут записаны в файл. Ожидает, пока все операции записи на диск завершатся.
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
} Включает или выключает режим синхронизации базы данных. Если режим синхронизации включен, состояние базы данных в памяти будет синхронизировано с диском после каждой операции изменения базы данных. Если режим синхронизации выключен, GDBM не ожидает, пока записи будут записаны на диск, прежде чем продолжить.
Этот параметр доступен только для gdbm >= 1.8, где режим syncmode выключен по умолчанию. См. также: fastmode=
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;
} Возвращает массив всех пар ключ-значение, содержащихся в базе данных.
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;
} Возвращает хэш всех пар ключ-значение, содержащихся в базе данных.
static VALUE
fgdbm_update(VALUE obj, VALUE other)
{
rb_block_call(other, rb_intern("each_pair"), 0, 0, update_i, obj);
return obj;
} Добавляет пары ключ-значение из other в gdbm, перезаписывая записи с дублирующими ключами теми, что из other. other должен иметь метод each_pair.
static VALUE
fgdbm_has_value(VALUE obj, VALUE valstr)
{
struct dbmdata *dbmp;
GDBM_FILE dbm;
VALUE keystr, valstr2;
ExportStringValue(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;
} Возвращает true, если заданное значение v существует в базе данных. В противном случае возвращает false.
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;
} Возвращает массив всех значений этой базы данных.
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;
} Возвращает массив значений, связанных с каждым указанным ключом.
Ruby Core © 1993–2017 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.