Основы программирования в Linux
data_datum.dptr = (void*)&items_to_store[i];data_datum.dsize = sizeof(struct.test_data);result = dbm_store(dbm_ptr, key_datum, data_datum, DBM_REPLACE);if (result != 0) {fprintf(stderr, "dbm_store failed on key %s\n", key_to_use);exit(2);}}6. Далее посмотрите, сможете ли вы извлечь эти новые данные, и в заключение следует закрыть базу данных:
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);}dbm_close(dbm_ptr);exit(EXIT_SUCCESS);}Когда вы откомпилируете и выполните программу, вывод будет следующим:
$ <b>gcc -о dbm1 -I/usr/include/gdtm dbm1.с -lgdbm</b>$ <b>./dbm1</b>Data retrievedRetrieved item — bar 13 unlucky?Вы получите приведенный вывод, если база данных gdbm установлена в режиме совместимости. Если компиляция не прошла, возможно, вам придется изменить директиву
, как показано в файле, для использования заголовочного файла gdbm-ndbm.h вместо файла ndbm.h и задать в строке компиляции библиотеку совместимости перед основной библиотекой, как показано в следующей строке:include$ <b>gcc -о dbm1 -I/usr/include/gdbm dbm1.с -lgdbm_compat -lgdbm</b>Как это работает
Сначала вы открываете базу данных, при необходимости создавая ее. Затем вы заполняете три элемента структуры
, чтобы использовать их как тестовые данные. Для каждого из трех элементов вы создаете индексный ключ. Чтобы он оставался простым, используйте первые символы каждой из двух строк плюс сохраненное целое.items_to_storeДалее вы задаете две структуры типа
, одну для ключа и другую для сохраняемых данных. Сохранив три элемента в базе данных, вы конструируете новый ключ и настраиваете структуру типаdatumтак, чтобы она указывала на него. Затем вы применяете данный ключ для извлечения данных из базы данных. Убедитесь в успехе, проверив, чтоdatumв возвращенномdptrне равенdatum. Получив подтверждение, вы можете копировать извлеченные данные (которые могут храниться внутри библиотеки dbm) в вашу собственную структуру, применяя возвращенный размерnull(если этого не сделать, при наличии данных переменного размера вы можете скопировать несуществующие данные). В заключение извлеченные данные выводятся на экран, чтобы продемонстрировать корректность их извлечения.dbm_fetchДополнительные функции dbm
После знакомства с основными функциями библиотеки dbm приведем несколько оставшихся функций, применяемых при работе с базой данных dbm:
<b>int dbm_delete(DBM *database_descriptor, datum key);</b><b>int dbm_error(DBM *database_descriptor);</b><b>int dbm_clearerr(DBM *database_dascriptor);</b><b>datum dbm_firstkey(DBM *database_descriptor);</b><b>datum dbm_nextkey(DBM *database_descriptor);</b>dbm_deleteФункция
применяется для удаления элементов из базы данных. Она принимает ключ типаdbm_deleteточно так же, как функцияdatum, но вместо извлечения данных она удаляет их. В случае успешного завершения функция возвращает 0.dbm_fetchdbm_errorФункция
просто проверяет базу данных на наличие ошибок, возвращая 0 при их отсутствии.dbm_errordbm_clearerrФункция dbm_clearerr очищает любой флаг ошибочной ситуации, который может быть установлен в базе данных.
dbm_firstkey и dbm_nextkeyЭти подпрограммы обычно используются вместе для просмотра ключей всех элементов базы данных. Далее приведена структура требуемого для просмотра цикла:
DBM *db_ptr;datum key;for (key = dbm_firstkey(db_ptr); key.dptr; key = dbm_nextkey(db_ptr));Выполните упражнение 7.13.
Упражнение 7.13. Извлечение и удалениеВ этом примере вы улучшите файл dbm1.с с помощью описанных новых функций и создадите новый файл dbm2.c.
1. Сделайте копию dbm1.с и откройте его для редактирования. Отредактируйте строку
.#define TEST_DB_FILE<i>#unclude <unistd.h></i>#include <stdlib.h>#include <stdio.h>#include <fcntl.h>#include <ndbm.h>#include <string.h><i>#define TEST_DB_FILE "/tmp/dbm2_test"</i>#define ITEMS_USED 32. Теперь вам нужно внести изменения только в секцию извлечения:
/* теперь попытайтесь удалить некоторые данные */sprintf(key_to_use, "bu%d", 13);key_datum.dptr = key_to_use;key_datum.dsize = strlen(key_to_use);<i> if (dbm_delete(dbm_ptr, key_datum) == 0) {</i>