Question

* ---Edit - now the whole sourse*

When I debug it on the end, "get" and "value" have different values! Probably, I convert to void* and back to User the wrong way?

#include <db_cxx.h>
#include <stdio.h>

struct User{
User(){}
int name;
int town;
User(int a){};
inline int get_index(int a){
    return town;
} //for another stuff
};
int main(){ 
try {
DbEnv* env = new DbEnv(NULL);
env->open("./", 
    DB_CREATE | DB_INIT_MPOOL | DB_THREAD | 
DB_INIT_LOCK | DB_INIT_TXN | DB_RECOVER | DB_INIT_LOG, 0);
Db* datab = new Db(env, 0);
datab->open(NULL, "db.dbf", NULL, DB_BTREE, DB_CREATE | DB_AUTO_COMMIT, 0);

Dbt key, value, get;
char a[10] = "bbaaccd";
User u;
u.name = 1;
u.town = 34;
key.set_data(a);
key.set_size(strlen(a) + 1 );
value.set_data((void*)&u);
value.set_size(sizeof(u));
get.set_flags(DB_DBT_MALLOC);

DbTxn* txn;
env->txn_begin(NULL, &txn, 0);
datab->put(txn, &key, &value, 0);
datab->get(txn, &key, &get, 0);
txn->commit(0);
User g;
g = *((User*)&get);
printf("%d", g.town);
getchar();
return 0;
}catch (DbException &e){
    printf("%s", e.what());
    getchar();
}

solution

create a kind of "serializator" what would convert all POD's into void* and then will unite these pieces

PS Or I'd rewrite User into POD type and everything will be all right, I hope.

Add

It's strange, but... I cast a defenetly non-pod object to void* and back (it has std::string inside) and it's all right (without sending it to the db and back). How could it be? And after I cast and send 'trough' db defenetly pod object (no extra methods, all members are pod, it's a simple struct {int a; int b; ...}) I get back dirted one. What's wrong with my approach?

Add about week after first 'add'

Damn... I've compiled it ones, just for have a look at which kind of dirt it returnes, and oh! it's okay!... I can't ! ... AAh!.. Lord... A reasonable question (in 99.999 percent of situations right answer is 'my', but... here...) - whos is this fault? My or VSs?

Was it helpful?

Solution

Unless User is a POD this is undefined in C++.

Edit:

Looking at db_cxx.h, aren't you supposed to do call get_doff(), get_dlen(), and get_data() or something on Dbt instead of just casting (and assigning) it to the user type?

OTHER TIPS

Since there is no check of the return value of put(), it could well be there is an error which prevented updating. The documentation indicates quite a few error condtions:

You are almost definitely NOT supposed to cast 'get' directly to a User. Instead, extract the data you stored and then cast that. We can't know for sure unless you share with us the definition of Dbt. Making a guess, based on what we can see:

datab->get(txn, &key, &get, 0);
void* data = get.get_data();
User g = *((User*)data);

Tell us more about Dbt and we can probably help you out more.

I would do something like this:

User               user;
std::stringstream  dbStotrStream;

dbStoreStream << user;  // Serialize user
std::string        dbStore(bdStoreStream.str());
value.set_data(dbStore.c_str());  
value.set_size(dbStore.lenght());

////  Put in DB

Then extracting it would look like this:

//// Get from DB

std::string        dbStore(get.get_data(),get.get_date() + get.get_size());
std::stringstream  dbStoreStream(dbStore);
User              outUser;

 dbStoreStream >> outUSer;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top