Шрифт:
Интервал:
Закладка:
void dbm_close(DBM *database descriptor);
dbm_openЭта функция применяется для открытия имеющихся баз данных и для создания новых баз данных. Аргумент filename — имя файла базы данных без расширения dir или pag.
Остальные параметры такие же, как второй и третий параметры функции open, с которой вы встречались в главе 3. Вы можете использовать те же директивы #define. Второй аргумент управляет возможностью чтения базы данных, записью в нее или обеими операциями. Если создается новая база данных, флаги должны быть двоичными O_READ с O_CREAT, чтобы разрешить создание файлов. Третий аргумент задает начальные права доступа к файлам, которые будут созданы.
Функция dbm_open возвращает указатель на тип DBM. Он применяется во всех последующих обращениях к базе данных. В случае аварийного завершения возвращается (DBM*)0.
dbm_storeЭту функцию применяют для ввода данных в базу данных. Как упоминалось ранее, все данные должны сохраняться с уникальным индексом. Для определения данных, которые вы хотите сохранить, и индекса, используемого для ссылки на них, следует задать два типа datum: один для ссылки на индекс, а другой — на реальные данные. Последний параметр store_mode управляет действиями, совершаемыми при попытке сохранить какие-либо данные с применением ключа, который уже существует. Если установлено значение параметра dbm_insert, сохранение завершается аварийно и функция dbm_store возвращает 1. Если установлено значение параметра dbm_replace, новые данные заменяют существующие и dbm_store возвращает 0. При возникновении других ошибок функция dbm_store возвращает отрицательные числа.
dbm_fetchПодпрограмма dbm_fetch применяется для извлечения данных из базы данных. Она принимает в качестве параметра указатель dbm, возвращенный предшествующим вызовом функции dbm_open и тип datum, который должен быть задан как указатель на ключ. Тип datum возвращается, если данные, относящиеся к используемому ключу, найдены в базе данных, возвращаемая структура datum будет иметь значения dptr и dsize, ссылающиеся на возвращенные данные. Если ключ не найден, dptr будет равен null.
ПримечаниеВажно помнить, что функция dbm_fetch возвращает только параметр типа datum, содержащий указатель на данные. Реальные данные могут находиться в локальной области памяти внутри библиотеки dbm и должны быть скопированы в переменные программы перед дальнейшими вызовами функций dbm.
dbm_closeЭта подпрограмма закрывает базу данных, открытую функцией dbm_open, и должна получить указатель DBM, возвращенный предшествующим вызовом dbm_open.
А теперь выполните упражнение 7.12.
Упражнение 7.12. Простая база данных dbmПознакомившись с основными функциями базы данных dbm, теперь вы знаете, как написать вашу первую программу для работы с dbm (dbm1.c). В этой программе применяется структура, названная test_data.
1. Первыми представлены файлы #include, директивы #define, функция main и объявление структуры test_data:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <ndbm.h>
/* В некоторых системах вам нужно заменить вышестоящую строку строкой #include <gdbm-ndbm.h>*/
#include <string.h>
#define TEST_DB_FILE "/tmp/dbm1_test"
#define ITEMS_USED 3
struct test_data {
char misc_chars[15];
int any_integer;
char more_chars[21];
};
int main() {
2. В функции main задайте элементы структур items_to_store и items_received, строку key и типы datum:
struct test_data items_to_store[ITEMS_USED];
struct test_data item_retrieved;
char key_to_use[20];
int i, result;
datum key_datum;
datum data_datum;
DBM *dbm_ptr;
3. Объявив указатель на структуру типа DBM, откройте вашу тестовую базу данных для чтения и записи, создав ее при необходимости:
dbm_ptr = dbm_open(TEST_DB_FILE, O_RDWR | O_CREAT, 0666);
if (!dbm_ptr) {
fprintf (stderr, "Failed to open databasen");
exit(EXIT_FAILURE);
}
4. Теперь добавьте данные в структуру items_to_store:
memset(items_to_store, ' ', sizeof(items_to_store));
strcpy(items_to_store[0].misc_chars, "First! ");
items_to_store[0].any_integer = 47;
strcpy(items_to_store[0].more_chars, "foo");
strcpy(items_to_store[1].misc_chars, "bar");
items_to_store[1].any_integer = 13;
strcpy(items_to_store[1].more_chars, "unlucky? ");
strcpy(items_to_store[2].misc_chars, "Third");
items_to_store[2].any_integer = 3;
strcpy(items_to_store[2].more_chars, "baz");
5. Для каждого элемента необходимо сформировать ключ для будущих ссылок в виде первой буквы каждой строки и целого числа. Этот ключ затем будет обозначен key_datum, когда data_datum сошлется на элемент items_to_store. Далее вы сохраняете данные в базе данных:
for (i = 0; i < ITEMS_USED; i++) {
sprintf(key_to_use, "%c%c%d",
items_to_store[i].misc_chars[0], items_to_store[i].more_chars[0], items_to_store[i].any_integer);
key_datum.dptr = (void*)key_to_use;
key_datum.dsize = strlen(key to_use);
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 %sn", 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 retrievedn");
memcpy(&item_retrieved, data_datum.dptr, data_datum.dsize);
printf("Retrieved item — %s %d %sn", item_retrieved.misc_chars,
item_retrieved.any_integer, item_retrieved.more_chars);
} else {
printf("No data found for key %sn", key_to_use);
}
dbm_close(dbm_ptr);
exit(EXIT_SUCCESS);
}
Когда вы откомпилируете и выполните программу, вывод будет следующим:
$ gcc -о dbm1 -I/usr/include/gdtm dbm1.с -lgdbm
$ ./dbm1
Data retrieved
Retrieved item — bar 13 unlucky?
Вы получите приведенный вывод, если база данных gdbm установлена в режиме совместимости. Если компиляция не прошла, возможно, вам придется изменить директиву include, как показано в файле, для использования заголовочного файла gdbm-ndbm.h вместо файла ndbm.h и задать в строке компиляции библиотеку совместимости перед основной библиотекой, как показано в следующей строке:
$ gcc -о dbm1 -I/usr/include/gdbm dbm1.с -lgdbm_compat -lgdbm
Как это работает
Сначала вы открываете базу данных, при необходимости создавая ее. Затем вы заполняете три элемента структуры items_to_store, чтобы использовать их как тестовые данные. Для каждого из трех элементов вы создаете индексный ключ. Чтобы он оставался простым, используйте первые символы каждой из двух строк плюс сохраненное целое.
Далее вы задаете две структуры типа 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Функция dbm_delete применяется для удаления элементов из базы данных. Она принимает ключ типа datum точно так же, как функция dbm_fetch, но вместо извлечения данных она удаляет их. В случае успешного завершения функция возвращает 0.
dbm_errorФункция dbm_error просто проверяет базу данных на наличие ошибок, возвращая 0 при их отсутствии.
- Linux - Алексей Стахнов - Программное обеспечение
- Разработка приложений в среде Linux. Второе издание - Майкл Джонсон - Программное обеспечение
- Искусство программирования для Unix - Эрик Реймонд - Программное обеспечение
- Fedora 8 Руководство пользователя - Денис Колисниченко - Программное обеспечение
- Linux Mint и его Cinnamon. Очерки применителя - Алексей Федорчук - Программное обеспечение
- Недокументированные и малоизвестные возможности Windows XP - Роман Клименко - Программное обеспечение
- ELASTIX – общайтесь свободно - Владислав Юров - Программное обеспечение
- Изучаем Windows Vista. Начали! - Дмитрий Донцов - Программное обеспечение
- Windows Vista - Сергей Вавилов - Программное обеспечение
- Операционная система UNIX - Андрей Робачевский - Программное обеспечение