Далее вы задаете две структуры типа datum
, одну для ключа и другую для сохраняемых данных. Сохранив три элемента в базе данных, вы конструируете новый ключ и настраиваете структуру типа datum
так, чтобы она указывала на него. Затем вы применяете данный ключ для извлечения данных из базы данных. Убедитесь в успехе, проверив, что dptr
в возвращенном datum
не равен null
. Получив подтверждение, вы можете копировать извлеченные данные (которые могут храниться внутри библиотеки dbm) в вашу собственную структуру, применяя возвращенный размер dbm_fetch
(если этого не сделать, при наличии данных переменного размера вы можете скопировать несуществующие данные). В заключение извлеченные данные выводятся на экран, чтобы продемонстрировать корректность их извлечения.
Дополнительные функции dbm
После знакомства с основными функциями библиотеки dbm приведем несколько оставшихся функций, применяемых при работе с базой данных dbm:
int dbm_delete(DBM *database_descriptor, datum key);
int dbm_error(DBM *database_descriptor);
int dbm_clearerr(DBM *database_dascriptor);
datum dbm_firstkey(DBM *database_descriptor);
datum dbm_nextkey(DBM *database_descriptor);
Функция dbm_delete
применяется для удаления элементов из базы данных. Она принимает ключ типа datum
точно так же, как функция dbm_fetch
, но вместо извлечения данных она удаляет их. В случае успешного завершения функция возвращает 0.
Функция dbm_error
просто проверяет базу данных на наличие ошибок, возвращая 0 при их отсутствии.
Функция dbm_clearerr очищает любой флаг ошибочной ситуации, который может быть установлен в базе данных.
Эти подпрограммы обычно используются вместе для просмотра ключей всех элементов базы данных. Далее приведена структура требуемого для просмотра цикла:
DBM *db_ptr;
datum key;
for (key = dbm_firstkey(db_ptr); key.dptr; key = dbm_nextkey(db_ptr));
Выполните упражнение 7.13.
В этом примере вы улучшите файл dbm1.с с помощью описанных новых функций и создадите новый файл dbm2.c.
1. Сделайте копию dbm1.с и откройте его для редактирования. Отредактируйте строку #define TEST_DB_FILE
.
#include
#include
#include
#include
#include
#define ITEMS_USED 3
2. Теперь вам нужно внести изменения только в секцию извлечения:
/* теперь попытайтесь удалить некоторые данные */
sprintf(key_to_use, "bu%d", 13);
key_datum.dptr = key_to_use;
key_datum.dsize = strlen(key_to_use);
data_datum = dbm_fetch(dbm_ptr, key_datum);
if (data_datum.dptr) {
printf("Data retrieved\n");
memcpy(&item_retrieved, data_datum.dptr, data_datum.dsize);
printf("Retrieved item - %s %d %s\n",
item_retrieved.misc_chars, item_retrieved.any_integer,
item_retrieved.more_chars);
} else {
printf("No data found for key %s\n", key_to_use);
}
}
Далее приведен вывод:
$ ./dbm2
Data with key bu13 deleted
Data retrieved
Retrieved item — Third 3 baz
Data retrieved
Retrieved item - First! 47 foo
Как это работает
Первая часть программы, идентичная предыдущему примеру, просто сохраняет данные в базе данных. Затем вы формируете ключ, соответствующий второму элементу, и удаляете этот элемент из базы данных.