Не удается извлечь значения из Berkeley DB на C

#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