Чтение онлайн

ЖАНРЫ

Разработка приложений в среде Linux. Второе издание

Троан Эрик В.

Шрифт:

13: printf("ошибка: %s\n", dperrmsg(dpecode));

14: return 1;

15: }

16:

17: dpclose(dp);

18:

19: return 0;

20: }

25.2.3. Получение файлового дескриптора

Помимо возможности использования автоматической блокировки, которую предлагает

qdbm
, в некоторых программах потребуется изменять их собственную схему блокировки. Для этой цели
qdbm
обеспечивает доступ к файловому дескриптору, который ссылается на базу данных.

int dpfdesc(DEPOT * depot);

Эта функция возвращает файловый дескриптор базы данных

depqt
[179] .

25.2.4.

Синхронизация базы данных

qdbm
кэширует данные в оперативной памяти для ускорения доступа к базе данных, а ядро Linux кэширует записи на диске, чтобы свести к минимуму задержку между вызовами функции
write
. Чтобы база данных, хранящаяся на диске, оставалась согласованной с буферизированными структурами, приложение может осуществлять ее синхронизацию. В процессе синхронизации базы данных qdbm очищает все ее внутренние буферы и вызывает функцию
fsync
для файлового дескриптора.

179

Несмотря на то что

qdbm
обеспечивает доступ к файловому дескриптору, использовать его следует осторожно. Дело в том, что все операции по чтению и записи в файл должны производиться через библиотеку
qdbm
; операции, не связанные с изменением данных в файле, например, блокировка или установка флага для закрытия после выполнения, допускаются.

int dpsync(DEPOT * depot);

25.3. Чтение записей

Прочитать записи в базе данных можно двумя способами: посредством поиска записи по ее ключу и путем чтения последовательных пар "ключ-значение".

25.3.1. Чтение определенной записи

Функции

dpget
и
dpgetwb
производят поиск записей в базе данных по ключу.

int dpget(DEPOT * depot, const char * key, int keySize, int start,

 int max, int * dataSize);

key
является элементом (ключом), с помощью которого производится поиск по базе данных, a
keySize
определяет длину ключа (или значение
– 1
, при котором
Depot
использует функцию
strlen(key)
для определения длины ключа). С помощью следующих двух параметров,
start
и
max
, можно производить частичное чтение записей; параметр
start
задает смещение в данных, с которого начнется операция чтения, а
max
— максимальное количество байтов для чтения. Например, если область данных представляла бы собой массив из четырехбайтовых целочисленных значений
int
, то в результате присвоения параметру
start
значения
12
и параметру
max
значения
8
производилось бы чтение четвертого и пятого элементов массива. Если для чтения доступно менее
start
байтов, функция
dpget
вернет
NULL
. Чтобы прочитать все байты из данных, параметру
max
следует присвоить значение
– 1
.

Если последний параметр,

dataSize
, не будет равен
NULL
, то целое число, на которое он указывает, будет соответствовать количеству прочитанных байтов.

В случае сбоя эта функция возвращает

NULL
, а в случае успешного завершения она возвращает указатель на прочитанные данные. В случае сбоя
dpcode
сообщает о том, что стало причиной сбоя. В частности, если элемент не существует или имеет менее
start
байтов данных,
dpcode
будет присвоено
DP_ENOITEM
.

Когда функция

dpget
возвращает данные, к ним добавляется байт
0
, позволяя работать с ними как со строкой. Размещение указателя производится с помощью функции
malloc
, и приложение отвечает за освобождение памяти после завершения своей работы. Если приложениям необходимо поместить данные в буфер, вместо того чтобы
Depot
размещала его с помощью функции
malloc
, то они должны использовать функцию
dpgetwb
.

int dpgetwb(DEPOT * depot, const char * key, int keySize, int start,

int max, const char * data);

Функции

dpgetwb
и
dpget
отличаются друг от друга только двумя параметрами:
max
(который интерпретируется по-разному) и
data
(который заменяет параметр
dataSize
из функции
dpgetwb
). Параметр
data
должен указывать на буфер из
max
байтов, в который функция
dpgetwb
будет помещать данные, прочитанные из базы данных. В функции
dpgetwb
параметр
max
не должен иметь значение
– 1
, и буфер не будет иметь байт
0
, автоматически добавляемый в него этой функцией. Функция
dpgetwb
возвращает количество байтов, хранящихся в
data
, и
– 1
, если запись не была найдена, если данных оказалось меньше
start
байтов или если возникла ошибка.

25.3.2. Последовательное чтение записей

С помощью функций

dpiterinit
и
dpiternext
приложения могут производить итерации по всем ключам в базе данных. Ключи не возвращаются в каком-то определенном порядке [180] , а базу данных не нужно модифицировать во время итераций, производимых приложением.

int dpiterinit(DEPOT * depot);

char * dpiternext(DEPOT * depot, int * keySize);

180

Вернее, они возвращаются в том порядке, в котором производятся ссылки на элементы из хеш-области. Хотя это и есть порядок, он является совершенно бесполезным.

В результате вызова функции

dpiterinit qdbm
вернет первый ключ в базе данных во время следующего вызова функции
dpiternext
.

Функция

dpiternext
возвращает указатель либо на первый ключ в базе данных (если только что была вызвана функция
dpiterinit
), либо ключ в базе данных, который следует за ключом, возвращенным в последний раз. Если же в базе данных больше не окажется ключей, будет возвращено
NULL
. Если
keySize
не равен
NULL
, то целочисленное значение, на которое указывает этот параметр, будет задано в качестве размера возвращаемого ключа.

Функция

dpiternext
буфера возвращает указатель на размещение, выполненное функцией
malloc
; после того как приложение завершит работу с ключом, указатель необходимо освободить функцией
free
. Буфер также завершается
NULL
, поэтому при необходимости его можно трактовать как строку.

25.4. Модификация базы данных

Предусмотрены две операции, которые модифицируют базу данных

qdbm
: добавление записей и удаление записей. Обновление записей производится с помощью той же функции, что и добавления записей.

25.4.1. Добавление записей

Новые и обновленные записи заносятся в базу данных с использованием функции

dpput
.

int dpput(DEPOT * dfepot, const char * key, int keySize, const char * data,

 int dataSize, int dmode);

key
представляет собой значение индекса, который впоследствии может использоваться для получения информации, на которую указывает
data
. Параметры
keySize
и
dataSize
могут иметь значение
– 1
, при котором функция
dpput
будет использовать функцию
strlen
для получения размера данного поля. Проверка параметра
dmode
производится только в том случае, если параметр
key
в базе данных уже связан с элементом данных. Параметр
dmode
может иметь одно из перечисленных ниже значений.

Поделиться с друзьями: