void BtRecExample::run() { db_recno_t recno; int ret; char buf[1024]; // Acquire a cursor for the database. dbp->cursor(NULL, &dbcp, 0); // // Prompt the user for a record number, then retrieve and display // that record. // for (;;) { // Get a record number. cout << "recno #> "; cout.flush(); if (fgets(buf, sizeof(buf), stdin) == NULL) break; recno = atoi(buf); // // Start with a fresh key each time, // the dbp->get() routine returns // the key and data pair, not just the key! // Dbt key(&recno, sizeof(recno)); Dbt data; if ((ret = dbcp->get(&key, &data, DB_SET_RECNO)) != 0) { dbp->err(ret, "DBcursor->get"); throw DbException(ret); } // Display the key and data. show("k/d\t", &key, &data); // Move the cursor a record forward. if ((ret = dbcp->get(&key, &data, DB_NEXT)) != 0) { dbp->err(ret, "DBcursor->get"); throw DbException(ret); } // Display the key and data. show("next\t", &key, &data); // // Retrieve the record number for the following record into // local memory. // data.set_data(&recno); data.set_size(sizeof(recno)); data.set_ulen(sizeof(recno)); data.set_flags(data.get_flags() | DB_DBT_USERMEM); if ((ret = dbcp->get(&key, &data, DB_GET_RECNO)) != 0) { if (ret != DB_NOTFOUND && ret != DB_KEYEMPTY) { dbp->err(ret, "DBcursor->get"); throw DbException(ret); } } else { cout << "retrieved recno: " << (u_long)recno << "\n"; } } dbcp->close(); dbcp = NULL; }
int main() { u_int32_t env_flags = DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN; const char* home = "envHome"; u_int32_t db_flags = DB_CREATE | DB_AUTO_COMMIT; const char* fileName = "envtest.db"; Db* dbp = NULL; DbEnv myEnv(0); try{ myEnv.open(home,env_flags,0); myEnv.set_flags(DB_MULTIVERSION,1); dbp = new Db(&myEnv,0); dbp->open( NULL, //Txn pointer fileName, //File name NULL, //Logic db name DB_BTREE, //Database type db_flags, //Open flags 0 //file mode ); }catch(DbException &e){ std::cerr<<"Error when opening database and Environment:" <<fileName<<","<<home<<std::endl; std::cerr<<e.what()<<std::endl; } //put data normally char *key1 = "luffy"; char *data1 = "op"; char *key2= "usopp"; char *data2 = "brave"; Dbt pkey1(key1,strlen(key1)+1); Dbt pdata1(data1,strlen(data1)+1); Dbt pkey2(key2,strlen(key2)+1); Dbt pdata2(data2,strlen(data2)+1); dbp->put(NULL,&pkey1,&pdata1,0); dbp->put(NULL,&pkey2,&pdata2,0); //using txn cursor to read and another cursor to modify before commit try{ DbTxn *txn1 = NULL; myEnv.txn_begin(NULL,&txn1,DB_TXN_SNAPSHOT); Dbc *cursorp = NULL; dbp->cursor(txn1,&cursorp,0); Dbt tempData1,tempKey2,tempData2; tempData2.set_flags(DB_DBT_MALLOC); cursorp->get(&pkey1,&tempData1,DB_SET); cursorp->get(&tempKey2,&tempData2,DB_NEXT); //cout just to see if it is right std::cout<<(char*)pkey1.get_data()<<" : "<<(char*)tempData1.get_data()<<std::endl <<(char*)tempKey2.get_data()<<" : "<<(char*)tempData2.get_data()<<std::endl; //we can ignore the lock when operation in //the same transaction dbp->put(NULL,&pkey1,&pdata2,0); dbp->put(NULL,&pkey2,&pdata1,0); //will not block even cursor still on this page //close cursor cursorp->close(); //commit the txn txn1->commit(0); }catch(DbException &e){ std::cerr<<"Error when use a txn"<<std::endl; } try{ dbp->close(0); //dbp should close before environment myEnv.close(0); }catch(DbException &e){ std::cerr<<"Error when closing database and environment:" <<fileName<<","<<home<<std::endl; std::cerr<<e.what()<<std::endl; } return 0; }
ClicCursor(Db& db) { db.cursor(0, &cursor, 0); }
/* Loop get batches of records. */ void BulkExample::bulkRead( int num, int dups, int iter, int *countp, int verbose) { Dbc *dbcp; Dbt data, dp, key, kp; DbTxn *txnp; DbMultipleDataIterator *ptrd; DbMultipleKeyDataIterator *ptrkd; u_int32_t flags; int count, i, j, ret; count = klen = ret = 0; dbcp = NULL; txnp = NULL; /* Initialize key Dbt and data Dbt, malloc bulk buffer. */ memset(&key, 0, sizeof(key)); memset(&data, 0, sizeof(data)); key.set_size(sizeof(j)); if (dlen != DATALEN * 16 * 1024) { dlen = DATALEN * 16 * 1024; dbuf = realloc(dbuf, dlen); } memset(dbuf, 0, dlen); data.set_flags(DB_DBT_USERMEM); data.set_data(dbuf); data.set_ulen(dlen); data.set_size(dlen); flags = DB_SET; flags |= (dups) ? DB_MULTIPLE: DB_MULTIPLE_KEY; try { for (i = 0; i < iter; i++) { if ((ret = dbenv->txn_begin(NULL, &txnp, 0)) != 0) throwException(dbenv, NULL, ret, "DB_ENV->txn_begin"); if ((ret = dbp->cursor(txnp, &dbcp, 0)) != 0) throwException(dbenv, txnp, ret, "DB->cursor"); /* * Bulk retrieve by a random key which is a random * non-negative integer smaller than "num". * If there are duplicates in the database, retrieve * with DB_MULTIPLE and use the DbMultipleDataIterator * to iterate the data of the random key in the data * Dbt. Otherwise retrieve with DB_MULTIPLE_KEY and use * the DbMultipleKeyDataIterator to iterate the * key/data pairs of the specific set of keys which * includes all integers >= the random key and < "num". */ j = rand() % num; key.set_data(&j); if ((ret = dbcp->get(&key, &data, flags)) != 0) throwException(dbenv, NULL, ret, "DBC->get"); if (dups) { ptrd = new DbMultipleDataIterator(data); while (ptrd->next(dp) == true) { count++; if (verbose) printf( "Retrieve key: %d, \tdata: (id %d, str %s)\n", j, ((struct data *)( dp.get_data()))->id, (char *)((struct data *)( dp.get_data()))->str); } } else { ptrkd = new DbMultipleKeyDataIterator(data); while (ptrkd->next(kp, dp) == true) { count++; if (verbose) printf( "Retrieve key: %d, \tdata: (id %d, str %s)\n", *((int *)kp.get_data()), ((struct data *)( dp.get_data()))->id, (char *)((struct data *)( dp.get_data()))->str); } } ret = dbcp->close(); dbcp = NULL; if (ret != 0) throwException(dbenv, txnp, ret, "DBC->close"); ret = txnp->commit(0); txnp = NULL; if (ret != 0) throwException(dbenv, NULL, ret, "DB_TXN->commit"); } *countp = count; } catch (DbException &dbe) { cerr << "bulkRead " << dbe.what() << endl; if (dbcp != NULL) (void)dbcp->close(); if (txnp != NULL) (void)txnp->abort(); throw dbe; } }
int main() { u_int32_t env_flags = DB_CREATE | // If the environment does not exist, create it. DB_INIT_MPOOL; // Initialize the in-memory cache. //std::string envHome("./"); std::string envHome("/home/kirill"); u_int32_t db_flags = DB_RDONLY; // only read std::string dbName("X-po2s.db"); //std::string dbName("X-so2p.db"); //std::string dbName("X-sp2o.db"); DbEnv myEnv(0); Db *myDb; // Instantiate the Db object Dbc *cursorp; // cursor try { cout << "X-po2s.db output:" << endl; myEnv.open(envHome.c_str(), env_flags, 0); myDb = new Db(&myEnv, 0); myDb->open(NULL, dbName.c_str(), NULL, DB_BTREE, db_flags, 0); // Get a cursor myDb->cursor(NULL, &cursorp, 0); Dbt key, data; // Position the cursor to the first record in the database whose // key and data begin with the correct strings. int ret = cursorp->get(&key, &data, DB_NEXT); while (ret != DB_NOTFOUND) { cout << "..." << endl; std::cout << "key: " << (char *)key.get_data() << "data: " << (char *)data.get_data()<< std::endl; ret = cursorp->get(&key, &data, DB_NEXT); } // Cursors must be closed if (cursorp != NULL) cursorp->close(); if (myDb != NULL) { myDb->close(0); } myEnv.close(0); cout << "Closing ..." << endl; } // Must catch both DbException and std::exception catch(DbException &e) { myDb->err(e.get_errno(), "Database open failed %s", dbName.c_str()); throw e; } catch(std::exception &e) { // No DB error number available, so use errx myDb->errx("Error opening database: %s", e.what()); throw e; } return 0; }