#c #berkeley-db
#c #berkeley-db
Вопрос:
У меня есть два отдельных кода, один для вставки данных, а другой для извлечения данных в Berkeley DB с использованием C. Моя проблема в том, что я могу видеть, что мои данные сохранены, и когда я выполняю команду db-> get сразу после db-> put, я вижу значения. Но когда я пытаюсь выполнить db-> get с помощью отдельного кода, у меня возникают проблемы, я получаю ошибку db-> get: DB_NOTFOUND, когда я не использую какую-либо функцию удаления. Не уверен, в чем ошибка
Вставка кода данных: (Я передаю в него строку из какой-то другой функции)
int db_json(char *json) {
typedef struct {
char data1[500];
} pearson_record;
pearson_record s;
int i =0;
DB *dbp;
DBT key, data;
int ret, t_ret;
int recno;
if ((ret = db_create(amp;dbp, NULL, 0)) != 0) {
fprintf(stderr, "db_create: %sn", db_strerror(ret));
exit (1);
}
if ((ret = dbp->open(dbp, NULL, DATABASE, NULL, DB_BTREE, DB_CREATE, 0664)) != 0) {
dbp->err(dbp, ret, "%s", DATABASE);
goto err;
}
printf("data: %sn",json);
strncpy(s.data1, json, strlen(json) 1);
recno = 1;
memset(amp;key, 0, sizeof(key));
memset(amp;data, 0, sizeof(data));
key.data = amp;recno;
key.size = sizeof(recno);
data.data = amp;s;
data.size = sizeof(s);
if ((ret = dbp->put(dbp, NULL, amp;key,amp;data,0)) == 0)
printf("db: %d: key stored.n", *(int *)key.data);
else
{
dbp->err(dbp, ret, "DB->put");
goto err;
}
err:
if ((t_ret = dbp->close(dbp, 0)) != 0 amp;amp; ret == 0)
ret = t_ret;
return 0;
}
Извлечение кода данных:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <json/json.h>
#include <curl/curl.h>
#include <sys/types.h>
#include <db.h>
#define DATABASE "mydata.db"
int main()
{
typedef struct {
char data1[500];
} pearson_record;
pearson_record s;
int i =0;
DB *dbp;
DBT key, data;
int ret, t_ret;
int recno;
if ((ret = db_create(amp;dbp, NULL, 0)) != 0) {
fprintf(stderr, "db_create: %sn", db_strerror(ret));
exit (1);
}
if ((ret = dbp->open(dbp, NULL, DATABASE, NULL, DB_BTREE, DB_CREATE, 0664)) != 0) {
dbp->err(dbp, ret, "%s", DATABASE);
goto err;
}
memset(amp;key, 0, sizeof(key));
memset(amp;data, 0, sizeof(data));
pearson_record *ppr;
if ((ret = dbp->get(dbp, NULL, amp;key, amp;data, 0)) == 0) {
ppr = (pearson_record *) data.data;
printf("db: %d: key retrieved: data was %s %dn",
*(int *)key.data, ppr->data1, data.size);
}
else {
dbp->err(dbp, ret, "DB->get");
}
goto err;
err:
if ((t_ret = dbp->close(dbp, 0)) != 0 amp;amp; ret == 0)
ret = t_ret;
return 0;
}
Комментарии:
1. Я просто изменил форматирование блоков кода, чтобы вам было легче читать. Однако это действительно неприятный код: почему вы
typedef
вводите одну и ту же структуру дважды (даже в рамках ваших функций) вместо одного файла заголовка, который вы включаете в оба места; и нет необходимости использоватьgoto
в сценарии такого рода.2. Вы проверили, что данные действительно записаны в базу данных? используя инструмент db_dump?
Ответ №1:
Чтобы использовать DB-> get(), вам нужно знать точный ключ записи, которую вы хотите получить. В вашем примере вам пришлось бы установить recno = 1, а затем настроить ключ DBT, чтобы указывать на него, перед вызовом DB-> get().
В вероятном случае, если вы не знаете ключ, вам нужны DB-> cursor() и DBCursor-> get(). Вы можете открыть курсор для базы данных с помощью DB-> cursor(), а затем выполнить цикл вызова DBCursor-> get(курсоры, amp;ключ, amp;данные, DB_NEXT). Это вернет каждую запись в базе данных, начиная с самого начала.
В разделе «Извлечение записей с помощью курсора» в справочнике программиста BDB здесь есть отличный пример:
http://docs.oracle.com/cd/E17076_02/html/programmer_reference/am_cursor.html#am_curget