bool Table::Get(Transaction* tx, const ByteString &key, ByteString &value) { Dbt dbtKey; Dbt dbtValue; DbTxn* txn = NULL; int ret; if (tx) txn = tx->txn; dbtKey.set_flags(DB_DBT_USERMEM); dbtKey.set_data(key.buffer); dbtKey.set_ulen(key.length); dbtKey.set_size(key.length); dbtValue.set_flags(DB_DBT_USERMEM); dbtValue.set_data(value.buffer); dbtValue.set_ulen(value.size); ret = db->get(txn, &dbtKey, &dbtValue, 0); // DB_PAGE_NOTFOUND can occur with parallel PRUNE and GET operations // probably because we have DB_READ_UNCOMMITED turned on if (ret == DB_KEYEMPTY || ret == DB_NOTFOUND || ret == DB_PAGE_NOTFOUND) return false; if (dbtValue.get_size() > (size_t) value.size) return false; value.length = dbtValue.get_size(); return true; }
RecordData Database::get(const RecordID& id) const { Dbt key(id.data(), id.size()); Dbt data; thread_local static std::vector<char> buffer(256); while (true) { try { data.set_flags(DB_DBT_USERMEM); data.set_data(buffer.data()); data.set_ulen(buffer.size()); const int err = dbMain_.get(/*txnid*/nullptr, &key, &data, /*flags*/0); assert (err == 0); break; } catch(DbException const& ex) { if (ex.get_errno() != DB_BUFFER_SMALL) { throw; } buffer.resize(data.get_size() * 1.5); } } return RecordData(data); }
db_iterator Database::dirs_begin() const { Dbc* pCursor = nullptr; dbDirs_.cursor(NULL, &pCursor, 0); assert(pCursor); RecordID id; Dbt key; Dbt data; key.set_flags(DB_DBT_USERMEM); key.set_data(id.data()); key.set_ulen(id.size()); const int err = pCursor->get(&key, &data, DB_FIRST); if (err) { pCursor->close(); if (err != DB_NOTFOUND) { throw DbException("Failed to obtain first directory record", err); } return dirs_end(); } return db_iterator(pCursor, make_Record(std::move(id), RecordData(data))); }
void JabberBotSession::Status(const std::string *from, MessageStanza::MessageTypes type, const std::string *id) { std::string account_id, resource; split_identifier(from, account_id, resource); char keyValue[account_id.size()+1]; account_id.copy(keyValue, std::string::npos); keyValue[account_id.size()] = '\0'; time_t last = 0; Dbt key(keyValue, account_id.size()+1); Dbt data; data.set_data(&last); data.set_ulen(sizeof(time_t)); int result = m_subscriptionDb.get(NULL, &key, &data, 0); MessageStanza message; message.Type(type); message.To(from); message.Thread(id); if (0 != result) { message.Body("You are not subscribed"); } else { message.Body("You are subscribed"); } m_session->SendMessage(message, false); }
/** * Cursor must be closed before the transaction is aborted/commited. * http://download.oracle.com/docs/cd/E17076_02/html/programmer_reference/transapp_cursor.html */ Bdb::ResponseCode Bdb:: update(const std::string& key, const std::string& value) { if (!inited_) { fprintf(stderr, "insert called on uninitialized database"); return Error; } DbTxn* txn = NULL; Dbc* cursor = NULL; Dbt dbkey, dbdata; dbkey.set_data(const_cast<char*>(key.c_str())); dbkey.set_size(key.size()); dbdata.set_data(const_cast<char*>(value.c_str())); dbdata.set_size(value.size()); Dbt currentData; currentData.set_data(NULL); currentData.set_ulen(0); currentData.set_dlen(0); currentData.set_doff(0); currentData.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL); int rc = 0; for (uint32_t idx = 0; idx < numRetries_; idx++) { env_->txn_begin(NULL, &txn, 0); (*db_).cursor(txn, &cursor, DB_READ_COMMITTED); // move the cursor to the record. rc = cursor->get(&dbkey, ¤tData, DB_SET | DB_RMW); if (rc != 0) { cursor->close(); txn->abort(); if (rc == DB_NOTFOUND) { return KeyNotFound; } else if (rc != DB_LOCK_DEADLOCK) { fprintf(stderr, "Db::get() returned: %s", db_strerror(rc)); return Error; } continue; } // update the record. rc = cursor->put(NULL, &dbdata, DB_CURRENT); cursor->close(); if (rc == 0) { txn->commit(DB_TXN_SYNC); return Success; } else { txn->abort(); if (rc != DB_LOCK_DEADLOCK) { fprintf(stderr, "Db::put() returned: %s", db_strerror(rc)); return Error; } } } fprintf(stderr, "update failed %d times", numRetries_); return Error; }
short CKeyValuePair::GetShort(const std::string &key) { structKey k( Int16, key.size(), key.c_str() ); Dbt v; short value; v.set_flags( DB_DBT_USERMEM ); v.set_ulen( sizeof( short ) ); v.set_size( sizeof( short ) ); v.set_data( &value ); Get( k, &v ); return value; }
double CKeyValuePair::GetDouble(const std::string &key) { structKey k( Double, key.size(), key.c_str() ); Dbt v; double value; v.set_flags( DB_DBT_USERMEM ); v.set_ulen( sizeof( double ) ); v.set_size( sizeof( double ) ); v.set_data( &value ); Get( k, &v ); return value; }
unsigned long CKeyValuePair::GetUnsignedLong(const std::string &key) { structKey k( UInt32, key.size(), key.c_str() ); Dbt v; unsigned long value; v.set_flags( DB_DBT_USERMEM ); v.set_ulen( sizeof( unsigned long ) ); v.set_size( sizeof( unsigned long ) ); v.set_data( &value ); Get( k, &v ); return value; }
float CKeyValuePair::GetFloat(const std::string &key) { structKey k( Float, key.size(), key.c_str() ); Dbt v; float value; v.set_flags( DB_DBT_USERMEM ); v.set_ulen( sizeof( float ) ); v.set_size( sizeof( float ) ); v.set_data( &value ); Get( k, &v ); return value; }
void operator<<(Dbt& dbt, const T& obj) { QByteArray ba; QDataStream ds(&ba, QIODevice::WriteOnly); // Serialize the object ds << obj; dbt.set_ulen(ba.size()); dbt.set_data(ba.data()); }
string read(const char* skey){ Dbt key((void*)skey, ::strlen(skey)); //fetch char* buf = _allocHeap(); //keep as heap mem Dbt data; data.set_data(buf); data.set_ulen(MAX_LEN); data.set_flags(DB_DBT_USERMEM); if( _db->get(nullptr, &key, &data, 0) == DB_NOTFOUND){ return string("F"); }; string res(buf); delete[] buf; return res; };
void test_dbt(void) { u_int32_t size = 3; u_int32_t flags = 5; u_int32_t ulen = 7; void* data = &size; Dbt dbt; dbt.set_size(size); dbt.set_flags(flags); dbt.set_data(data); dbt.set_ulen(ulen); assert(dbt.get_size() == size); assert(dbt.get_flags() == flags); assert(dbt.get_data() == data); assert(dbt.get_ulen() == ulen); }
// Shows a vendor record. Each vendor record is an instance of // a vendor structure. See loadVendorDB() in // example_database_load for how this structure was originally // put into the database. int show_vendor(MyDb &vendorDB, const char *vendor) { Dbt data; VENDOR my_vendor; try { // Set the search key to the vendor's name // vendor is explicitly cast to char * to stop a compiler // complaint. Dbt key((char *)vendor, (u_int32_t)strlen(vendor) + 1); // Make sure we use the memory we set aside for the VENDOR // structure rather than the memory that DB allocates. // Some systems may require structures to be aligned in memory // in a specific way, and DB may not get it right. data.set_data(&my_vendor); data.set_ulen(sizeof(VENDOR)); data.set_flags(DB_DBT_USERMEM); // Get the record vendorDB.getDb().get(NULL, &key, &data, 0); std::cout << " " << my_vendor.street << "\n" << " " << my_vendor.city << ", " << my_vendor.state << "\n" << " " << my_vendor.zipcode << "\n" << " " << my_vendor.phone_number << "\n" << " Contact: " << my_vendor.sales_rep << "\n" << " " << my_vendor.sales_rep_phone << std::endl; } catch (DbException &e) { vendorDB.getDb().err(e.get_errno(), "Error in show_vendor"); throw e; } catch (std::exception &e) { throw e; } return (0); }
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; }
vector<Identity> Freeze::IndexI::untypedFindFirst(const Key& bytes, Int firstN) const { DeactivateController::Guard deactivateGuard(_store->evictor()->deactivateController()); Dbt dbKey; initializeInDbt(bytes, dbKey); #if (DB_VERSION_MAJOR <= 4) || (DB_VERSION_MAJOR == 5 && DB_VERSION_MINOR <= 1) // // When we have a custom-comparison function, Berkeley DB returns // the key on-disk (when it finds one). We disable this behavior: // (ref Oracle SR 5925672.992) // dbKey.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL); #else // // In DB > 5.1 we can not set DB_DBT_PARTIAL in the key Dbt, // when using DB_SET, we must resize the Dbt key param to hold enought // space or Dbc::get fails with DB_BUFFER_SMALL. // dbKey.set_flags(DB_DBT_USERMEM); dbKey.set_ulen(static_cast<u_int32_t>(bytes.size())); #endif Key pkey(1024); Dbt pdbKey; initializeOutDbt(pkey, pdbKey); Dbt dbValue; dbValue.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL); const Ice::CommunicatorPtr& communicator = _store->communicator(); const Ice::EncodingVersion& encoding = _store->encoding(); TransactionIPtr transaction = _store->evictor()->beforeQuery(); DbTxn* tx = transaction == 0 ? 0 : transaction->dbTxn(); vector<Identity> identities; try { for(;;) { Dbc* dbc = 0; identities.clear(); try { // // Move to the first record // _db->cursor(tx, &dbc, 0); u_int32_t flags = DB_SET; bool found; do { for(;;) { try { // // It is critical to set key size to key capacity before the // get, as a resize that increases the size inserts 0 // pkey.resize(pkey.capacity()); found = (dbc->pget(&dbKey, &pdbKey, &dbValue, flags) == 0); if(found) { pkey.resize(pdbKey.get_size()); Ice::Identity ident; ObjectStoreBase::unmarshal(ident, pkey, communicator, encoding); identities.push_back(ident); flags = DB_NEXT_DUP; } break; // for(;;) } catch(const DbDeadlockException&) { throw; } catch(const DbException& dx) { handleDbException(dx, pkey, pdbKey, __FILE__, __LINE__); } } } while((firstN <= 0 || identities.size() < static_cast<size_t>(firstN)) && found); Dbc* toClose = dbc; dbc = 0; toClose->close(); break; // for (;;) } catch(const DbDeadlockException&) { if(dbc != 0) { try { dbc->close(); } catch(const DbDeadlockException&) { if(tx != 0) { throw; } // Else ignored } } if(_store->evictor()->deadlockWarning()) { Warning out(_store->communicator()->getLogger()); out << "Deadlock in Freeze::IndexI::untypedFindFirst while searching \"" << _store->evictor()->filename() + "/" + _dbName << "\"; retrying ..."; } if(tx != 0) { throw; } // Else retry } catch(...) { if(dbc != 0) { try { dbc->close(); } catch(const DbDeadlockException&) { if(tx != 0) { throw; } // Else ignored } } throw; } } } catch(const DbDeadlockException& dx) { throw DeadlockException(__FILE__, __LINE__, dx.what(), transaction); } catch(const DbException& dx) { handleDbException(dx, __FILE__, __LINE__); } return identities; }
Int Freeze::IndexI::untypedCount(const Key& bytes) const { DeactivateController::Guard deactivateGuard(_store->evictor()->deactivateController()); Dbt dbKey; initializeInDbt(bytes, dbKey); #if (DB_VERSION_MAJOR <= 4) || (DB_VERSION_MAJOR == 5 && DB_VERSION_MINOR <= 1) // // When we have a custom-comparison function, Berkeley DB returns // the key on-disk (when it finds one). We disable this behavior: // (ref Oracle SR 5925672.992) // dbKey.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL); #else // // In DB > 5.1 we can not set DB_DBT_PARTIAL in the key Dbt, // when using DB_SET, we must resize the Dbt key param to hold enought // space or Dbc::get fails with DB_BUFFER_SMALL. // dbKey.set_flags(DB_DBT_USERMEM); dbKey.set_ulen(static_cast<u_int32_t>(bytes.size())); #endif Dbt dbValue; dbValue.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL); TransactionIPtr transaction = _store->evictor()->beforeQuery(); DbTxn* tx = transaction == 0 ? 0 : transaction->dbTxn(); Int result = 0; try { for(;;) { Dbc* dbc = 0; try { // // Move to the first record // _db->cursor(tx, &dbc, 0); bool found = (dbc->get(&dbKey, &dbValue, DB_SET) == 0); if(found) { db_recno_t count = 0; dbc->count(&count, 0); result = static_cast<Int>(count); } Dbc* toClose = dbc; dbc = 0; toClose->close(); break; // for (;;) } catch(const DbDeadlockException&) { if(dbc != 0) { try { dbc->close(); } catch(const DbDeadlockException&) { if(tx != 0) { throw; } // Else ignored } } if(_store->evictor()->deadlockWarning()) { Warning out(_store->communicator()->getLogger()); out << "Deadlock in Freeze::IndexI::untypedCount while searching \"" << _store->evictor()->filename() + "/" + _dbName << "\"; retrying ..."; } if(tx != 0) { throw; } // Else retry } catch(...) { if(dbc != 0) { try { dbc->close(); } catch(const DbDeadlockException&) { if(tx != 0) { throw; } // Else ignored } } throw; } } } catch(const DbDeadlockException& dx) { throw DeadlockException(__FILE__, __LINE__, dx.what(), transaction); } catch(const DbException& dx) { DatabaseException ex(__FILE__, __LINE__); ex.message = dx.what(); throw ex; } return result; }
/* Bulk delete from a secondary db. */ void BulkExample::bulkSecondaryDelete( int num, int pair, int *countp, int *iterp, int verbose) { Dbt key; DbTxn *txnp; DbMultipleDataBuilder *ptrd; DbMultipleKeyDataBuilder *ptrkd; u_int32_t flag; int count, i, iter, j, k, rc, ret; char ch; memset(&key, 0, sizeof(Dbt)); txnp = NULL; count = flag = iter = ret = 0; rc = rand() % (STRLEN - 1); /* * The buffer must be at least as large as the page size of the * underlying database and aligned for unsigned integer access. * Its size must be a multiple of 1024 bytes. */ if (klen != (u_int32_t)UPDATES_PER_BULK_PUT * (sizeof(u_int32_t) + DATALEN) * 1024) { klen = (u_int32_t)UPDATES_PER_BULK_PUT * (sizeof(u_int32_t) + DATALEN) * 1024; kbuf = realloc(kbuf, klen); } memset(kbuf, 0, klen); key.set_ulen(klen); key.set_flags(DB_DBT_USERMEM | DB_DBT_BULK); key.set_data(kbuf); /* * Bulk delete all records of a specific set of keys which includes all * characters before the random key in the tstring. The random key is * one of the characters in the tstring. * If DB_MULTIPLE, construct the key Dbt by the DbMultipleDataBuilder * with the specific set of keys. If DB_MULTIPLE_KEY, construct the key * Dbt by the DbMultipleKeyDataBuilder with all key/data pairs of the * specific set of keys. */ flag |= (pair) ? DB_MULTIPLE_KEY : DB_MULTIPLE; if (pair) ptrkd = new DbMultipleKeyDataBuilder(key); else ptrd = new DbMultipleDataBuilder(key); try { for (i = 0; i <= rc; i++) { if (i % UPDATES_PER_BULK_PUT == 0) { if (txnp != NULL) { ret = txnp->commit(0); txnp = NULL; if (ret != 0) throwException(dbenv, NULL, ret, "DB_TXN->commit"); } if ((ret = dbenv->txn_begin(NULL, &txnp, 0)) != 0) throwException(dbenv, NULL, ret, "DB_ENV->txn_begin"); } ch = tstring[i]; if (!pair) { if (ptrd->append(&ch, sizeof(ch)) == false) throwException(dbenv, txnp, EXIT_FAILURE, "DbMultipleDataBuilder->append"); count++; if (verbose) printf("Delete key: %c\n", ch); } else { j = 0; do { k = j * (STRLEN - 1) + i; if (ptrkd->append(&ch, sizeof(ch), &k, sizeof(k)) == false) throwException(dbenv, txnp, EXIT_FAILURE, "DbMultipleKeyDataBuilder->append"); count++; if (verbose) printf( "Delete secondary key: %c, \tdata: %d\n", ch, k); } while (++j < (int)(num / (STRLEN - 1))); } if ((i + 1) % UPDATES_PER_BULK_PUT == 0) { if ((ret = sdbp->del(txnp, &key, flag)) != 0) throwException(dbenv, txnp, ret, "Bulk DB->del"); iter++; if (pair) ptrkd = new DbMultipleKeyDataBuilder(key); else ptrd = new DbMultipleDataBuilder(key); } } if ((rc % UPDATES_PER_BULK_PUT) != 0) { if ((ret = sdbp->del(txnp, &key, flag)) != 0) throwException(dbenv, txnp, ret, "Bulk DB->del"); iter++; } ret = txnp->commit(0); txnp = NULL; if (ret != 0) throwException(dbenv, NULL, ret, "DB_TXN->commit"); *countp = count; *iterp = iter; } catch (DbException &dbe) { cerr << "bulkSecondaryDelete " << dbe.what() << endl; if (txnp != NULL) (void)txnp->abort(); throw dbe; } }
/* Bulk delete from a database. */ void BulkExample::bulkDelete( int num, int dups, int *countp, int *iterp, int verbose) { Dbt key; DbTxn *txnp; DbMultipleDataBuilder *ptrd; DbMultipleKeyDataBuilder *ptrkd; u_int32_t flag; int count, i, j, iter, ret; txnp = NULL; count = flag = iter = ret = 0; memset(&key, 0, sizeof(Dbt)); j = rand() % num; /* * The buffer must be at least as large as the page size of the * underlying database and aligned for unsigned integer access. * Its size must be a multiple of 1024 bytes. */ if (klen != (u_int32_t)UPDATES_PER_BULK_PUT * (sizeof(u_int32_t) + DATALEN) * 1024) { klen = (u_int32_t)UPDATES_PER_BULK_PUT * (sizeof(u_int32_t) + DATALEN) * 1024; kbuf = realloc(kbuf, klen); } memset(kbuf, 0, klen); key.set_ulen(klen); key.set_flags(DB_DBT_USERMEM | DB_DBT_BULK); key.set_data(kbuf); if (data_val == NULL) data_val = (data *)malloc(DATALEN); memset(data_val, 0, DATALEN); /* * Bulk delete all records of a specific set of keys which includes all * non-negative integers smaller than the random key. The random key is * a random non-negative integer smaller than "num". * If DB_MULTIPLE, construct the key Dbt by the DbMultipleDataBuilder * with the specific set of keys. If DB_MULTIPLE_KEY, construct the key * Dbt by the DbMultipleKeyDataBuilder with all key/data pairs of the * specific set of keys. */ flag |= (dups) ? DB_MULTIPLE_KEY : DB_MULTIPLE; if (dups) ptrkd = new DbMultipleKeyDataBuilder(key); else ptrd = new DbMultipleDataBuilder(key); try { for (i = 0; i < j; i++) { if (i % UPDATES_PER_BULK_PUT == 0) { if (txnp != NULL) { ret = txnp->commit(0); txnp = NULL; if (ret != 0) throwException(dbenv, NULL, ret, "DB_TXN->commit"); } if ((ret = dbenv->txn_begin(NULL, &txnp, 0)) != 0) throwException(dbenv, NULL, ret, "DB_ENV->txn_begin"); } if (dups) { data_val->id = 0; get_string(tstring, data_val->str, i); do { if(ptrkd->append(&i,sizeof(i), data_val, DATALEN) == false) throwException(dbenv, txnp, EXIT_FAILURE, "DbMultipleKeyDataBuilder->append"); count++; if (verbose) printf( "Delete key: %d, \tdata: (id %d, str %s)\n", i, data_val->id, data_val->str); } while (data_val->id++ < dups); } else { if(ptrd->append(&i,sizeof(i)) == false) throwException(dbenv, txnp, ret, "DbMultipleDataBuilder->append"); count++; if (verbose) printf("Delete key: %d\n", i); } if ((i + 1) % UPDATES_PER_BULK_PUT == 0) { if ((ret = dbp->del(txnp, &key, flag)) != 0) throwException(dbenv, txnp, ret, "Bulk DB->del"); iter++; if (dups) ptrkd = new DbMultipleKeyDataBuilder(key); else ptrd = new DbMultipleDataBuilder(key); } } if ((j % UPDATES_PER_BULK_PUT) != 0) { if ((ret = dbp->del(txnp, &key, flag)) != 0) throwException(dbenv, txnp, ret, "Bulk DB->del"); iter++; } ret = txnp->commit(0); txnp = NULL; if (ret != 0) throwException(dbenv, NULL, ret, "DB_TXN->commit"); *countp = count; *iterp = iter; } catch (DbException &dbe) { cerr << "bulkDelete " << dbe.what() << endl; if (txnp != NULL) (void)txnp->abort(); throw dbe; } }
int Freeze::MapIndexI::untypedCount(const Key& k, const ConnectionIPtr& connection) const { Dbt dbKey; initializeInDbt(k, dbKey); #if (DB_VERSION_MAJOR <= 4) // // When we have a custom-comparison function, Berkeley DB returns // the key on-disk (when it finds one). We disable this behavior: // (ref Oracle SR 5925672.992) // dbKey.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL); #else // // In DB 5.x we can not set DB_DBT_PARTIAL in the key Dbt, // when using DB_SET, we must resize the Dbt key param to hold enought // space or Dbc::get fails with DB_BUFFER_SMALL. // dbKey.set_flags(DB_DBT_USERMEM); dbKey.set_ulen(static_cast<u_int32_t>(k.size())); #endif Dbt dbValue; dbValue.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL); int result = 0; DbTxn* txn = connection->dbTxn(); try { for(;;) { Dbc* dbc = 0; try { // // Move to the first record // _db->cursor(txn, &dbc, 0); bool found = (dbc->get(&dbKey, &dbValue, DB_SET) == 0); if(found) { db_recno_t count = 0; dbc->count(&count, 0); result = static_cast<int>(count); } Dbc* toClose = dbc; dbc = 0; toClose->close(); break; // for (;;) } catch(const DbDeadlockException&) { if(dbc != 0) { try { dbc->close(); } catch(const DbDeadlockException&) { if(txn != 0) { throw; } else { // // Ignored // } } } if(connection->deadlockWarning()) { Warning out(connection->communicator()->getLogger()); out << "Deadlock in Freeze::MapIndexI::untypedCount while searching \"" << _dbName << "\""; } if(txn != 0) { throw; } // // Otherwise retry // } catch(...) { if(dbc != 0) { try { dbc->close(); } catch(const DbDeadlockException&) { if(txn != 0) { throw; } else { // // Ignored // } } } throw; } } } catch(const DbDeadlockException& dx) { throw DeadlockException(__FILE__, __LINE__, dx.what(), connection->currentTransaction()); } catch(const DbException& dx) { throw DatabaseException(__FILE__, __LINE__, dx.what()); } return result; }
int main(int argc, const char* argv[]) { if (argc !=3) { cout << "usage: "<< argv[0] << " <filename> <db filename>" << endl; return 1; } const char* kDatabaseName = argv[2]; const char* filename = argv[1]; DbEnv env(0); Db* pdb; string line; bool datamode = false; try { env.set_error_stream(&cerr); env.open("./", DB_CREATE | DB_INIT_MPOOL, 0); pdb = new Db(&env, 0); // If you want to support duplicated records and make duplicated // records sorted by data, you need to call: // pdb->set_flags(DB_DUPSORT); // Note that only Btree-typed database supports sorted duplicated // records // If the database does not exist, create it. If it exists, clear // its content after openning. pdb->set_flags( DB_DUP );// | DB_DUPSORT); pdb->open(NULL, kDatabaseName, NULL, DB_BTREE, DB_CREATE | DB_TRUNCATE, 0); ifstream myfile (filename); if (myfile.is_open()) { int count = 0; while ( myfile.good() ) { //if (count++ > 10) { // break; //} getline (myfile,line); if (!datamode) { if ("[DATA]" == line ) { datamode = true; } continue; } //cout << (int)line[8] << endl; int index = 0; while (32 != (char)line[index]) { index++; } string cjkey = line.substr(0, index); while (32 == line[index]) { index++; } string cjdata = line.substr(index, (line.size()-index)); cout << cjkey << "---" << cjdata << endl; Dbt key(const_cast<char*>(cjkey.data()), cjkey.size()); Dbt value(const_cast<char*>(cjdata.data()), cjdata.size()); pdb->put(NULL, &key, &value, 0); } myfile.close(); } else { cout << "Unable to open file"; } // You need to set ulen and flags=DB_DBT_USERMEM to prevent Dbt // from allocate its own memory but use the memory provided by you. string search("aa"); Dbt key(const_cast<char*>(search.c_str()), search.size()); char buffer[1024]; Dbt data; data.set_data(buffer); data.set_ulen(1024); data.set_flags(DB_DBT_USERMEM); if (pdb->get(NULL, &key, &data, 0) == DB_NOTFOUND) { cerr << "Not found" << endl; } else { cout << "Found: " << "PPPPPP" <<buffer << "PPPPPP" << endl; } if (pdb != NULL) { pdb->close(0); delete pdb; // You have to close and delete an exisiting handle, then create // a new one before you can use it to remove a database (file). pdb = new Db(NULL, 0); //pdb->remove("access.db", NULL, 0); delete pdb; } env.close(0); } catch (DbException& e) { cerr << "DbException: " << e.what() << endl; return -1; } catch (std::exception& e) { cerr << e.what() << endl; return -1; } return 0; }
//############################################################################## //############################################################################## std::string BerkeleyDBCXXDb::get_record(record_type type, const std::string& key) const { RANGE_LOG_TIMED_FUNCTION(); std::string fullkey = key_name(type, key); auto txn = current_txn_.lock(); if(txn) { std::string data; if(txn->get_record(type, key, data)) { return data; } } auto lck = boost::dynamic_pointer_cast<BerkeleyDBCXXLock>(this->read_lock(type, key)); DbTxn * dbtxn = BerkeleyDBCXXLockTxnGetter(lck).txn(); Dbt dbkey { (void*) fullkey.c_str(), (uint32_t) fullkey.size() }; size_t bufsize = 131072; std::unique_ptr<char[]> buf { nullptr }; Dbt dbdata; int dbrval = 0; do { if(buf) { LOG(debug0, "resizing_record_buffer") << bufsize; } buf = std::unique_ptr<char[]>(new char[bufsize]); if(!buf) { std::stringstream s; s << "Unable to allocate buffer of size: " << bufsize; THROW_STACK(DatabaseEnvironmentException(s.str())); } dbdata = Dbt(buf.get(), bufsize); dbdata.set_ulen(bufsize); dbdata.set_flags(DB_DBT_USERMEM); bufsize *= 2; int flags = lck->readonly() ? 0 : DB_RMW; try { dbrval = inst_->get(dbtxn, &dbkey, &dbdata, flags); } catch (DbException &e) { if(e.get_errno() == DB_BUFFER_SMALL) { continue; } THROW_STACK(DatabaseEnvironmentException(std::string("Unable to read record") + e.what())); } catch (std::exception &e) { THROW_STACK(DatabaseEnvironmentException(std::string("Unable to read record") + e.what())); } } while(dbrval == DB_BUFFER_SMALL); switch(dbrval) { case 0: break; case DB_NOTFOUND: return std::string(); case DB_BUFFER_SMALL: THROW_STACK(DatabaseEnvironmentException("The requested item could not be returned due to undersized buffer.")); break; case DB_LOCK_DEADLOCK: THROW_STACK(DatabaseEnvironmentException("A transactional database environment operation was selected to resolve a deadlock.")); break; case DB_LOCK_NOTGRANTED: THROW_STACK(DatabaseEnvironmentException("unable to grant a lock in the allowed time.")); break; case DB_REP_HANDLE_DEAD: THROW_STACK(DatabaseEnvironmentException("Dead handle")); break; default: LOG(error, "unknown dbrval") << dbrval; } std::string rval { (char *) dbdata.get_data(), dbdata.get_size() }; return rval; }