void LoginDB::change(string user, string pass) { openDb(); Dbc *cursorp; Dbt key(const_cast<char*> (user.data()), user.size()); Dbt data; // Get a cursor db->cursor(NULL, &cursorp, 0); // Position the cursor int ret = cursorp->get(&key, &data, DB_SET); if (ret == 0) { data.set_data(const_cast<char*>(pass.data())); data.set_size(pass.size()); cursorp->put(&key, &data, DB_CURRENT); } if (cursorp != NULL) cursorp->close(); closeDb(); }
void AvailableGroups::slotDeleteServer(quint16 serverId) { Dbt key, data; memset(&key, 0, sizeof(key)); memset(&data, 0, sizeof(data)); Dbc *cursor = 0; int ret; groupDb->cursor(0, &cursor, DB_WRITECURSOR); while ((ret=cursor->get(&key, &data, DB_NEXT)) != DB_NOTFOUND) { g=new AvailableGroup((char*)data.get_data()); g->removeServerPresence(serverId); //resave the group... const char *p=g->data(); memset(&data, 0, sizeof(data)); data.set_data((void*)p); data.set_size(g->size()); if (g->noServerPresence()) { ret=cursor->del(0); if (ret != 0) quban->getLogAlertList()->logMessage(LogAlertList::Error, tr("Cannot delete server ") + servers->value(serverId)->getHostName() + tr(" group record")); } else if ((ret=cursor->put(&key, &data, DB_CURRENT)) != 0) quban->getLogAlertList()->logMessage(LogAlertList::Error, tr("Cannot update group record. Error: ") + dbEnv->strerror(ret)); Q_DELETE(p); } cursor->close(); reloadData(); }
/** * 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; }
// // XXX Figure out the appropriate way to pick out IDs. // int TpcbExample::txn(Db *adb, Db *bdb, Db *tdb, Db *hdb, int accounts, int branches, int tellers) { Dbc *acurs = NULL; Dbc *bcurs = NULL; Dbc *tcurs = NULL; DbTxn *t = NULL; db_recno_t key; Defrec rec; Histrec hrec; int account, branch, teller, ret; Dbt d_dbt; Dbt d_histdbt; Dbt k_dbt; Dbt k_histdbt(&key, sizeof(key)); // !!! // This is sample code -- we could move a lot of this into the driver // to make it faster. // account = random_id(ACCOUNT, accounts, branches, tellers); branch = random_id(BRANCH, accounts, branches, tellers); teller = random_id(TELLER, accounts, branches, tellers); k_dbt.set_size(sizeof(int)); d_dbt.set_flags(DB_DBT_USERMEM); d_dbt.set_data(&rec); d_dbt.set_ulen(sizeof(rec)); hrec.aid = account; hrec.bid = branch; hrec.tid = teller; hrec.amount = 10; // Request 0 bytes since we're just positioning. d_histdbt.set_flags(DB_DBT_PARTIAL); // START PER-TRANSACTION TIMING. // // Technically, TPCB requires a limit on response time, you only get // to count transactions that complete within 2 seconds. That's not // an issue for this sample application -- regardless, here's where // the transaction begins. if (txn_begin(NULL, &t, 0) != 0) goto err; if (adb->cursor(t, &acurs, 0) != 0 || bdb->cursor(t, &bcurs, 0) != 0 || tdb->cursor(t, &tcurs, 0) != 0) goto err; try { // Account record k_dbt.set_data(&account); if (acurs->get(&k_dbt, &d_dbt, DB_SET) != 0) goto err; rec.balance += 10; if (acurs->put(&k_dbt, &d_dbt, DB_CURRENT) != 0) goto err; // Branch record k_dbt.set_data(&branch); if (bcurs->get(&k_dbt, &d_dbt, DB_SET) != 0) goto err; rec.balance += 10; if (bcurs->put(&k_dbt, &d_dbt, DB_CURRENT) != 0) goto err; // Teller record k_dbt.set_data(&teller); if (tcurs->get(&k_dbt, &d_dbt, DB_SET) != 0) goto err; rec.balance += 10; if (tcurs->put(&k_dbt, &d_dbt, DB_CURRENT) != 0) goto err; // History record d_histdbt.set_flags(0); d_histdbt.set_data(&hrec); d_histdbt.set_ulen(sizeof(hrec)); if (hdb->put(t, &k_histdbt, &d_histdbt, DB_APPEND) != 0) goto err; } catch (DbDeadlockException e) { goto err; } if (acurs->close() != 0 || bcurs->close() != 0 || tcurs->close() != 0) goto err; ret = t->commit(0); t = NULL; if (ret != 0) goto err; // END PER-TRANSACTION TIMING. return (0); err: if (acurs != NULL) (void)acurs->close(); if (bcurs != NULL) (void)bcurs->close(); if (tcurs != NULL) (void)tcurs->close(); if (t != NULL) (void)t->abort(); if (verbose) cout << "Transaction A=" << (long)account << " B=" << (long)branch << " T=" << (long)teller << " failed\n"; return (-1); }
// // XXX Figure out the appropriate way to pick out IDs. // int TpcbExample::txn(Db *adb, Db *bdb, Db *tdb, Db *hdb, int accounts, int branches, int tellers) { Dbc *acurs = NULL; Dbc *bcurs = NULL; Dbc *tcurs = NULL; DbTxn *t = NULL; db_recno_t key; Defrec rec; Histrec hrec; int account, branch, teller; Dbt d_dbt; Dbt d_histdbt; Dbt k_dbt; Dbt k_histdbt(&key, sizeof(key)); // // XXX We could move a lot of this into the driver to make this // faster. // account = random_id(ACCOUNT, accounts, branches, tellers); branch = random_id(BRANCH, accounts, branches, tellers); teller = random_id(TELLER, accounts, branches, tellers); k_dbt.set_size(sizeof(int)); d_dbt.set_flags(DB_DBT_USERMEM); d_dbt.set_data(&rec); d_dbt.set_ulen(sizeof(rec)); hrec.aid = account; hrec.bid = branch; hrec.tid = teller; hrec.amount = 10; // Request 0 bytes since we're just positioning. d_histdbt.set_flags(DB_DBT_PARTIAL); // START TIMING if (txn_begin(NULL, &t, 0) != 0) goto err; if (adb->cursor(t, &acurs, 0) != 0 || bdb->cursor(t, &bcurs, 0) != 0 || tdb->cursor(t, &tcurs, 0) != 0) goto err; // Account record k_dbt.set_data(&account); if (acurs->get(&k_dbt, &d_dbt, DB_SET) != 0) goto err; rec.balance += 10; if (acurs->put(&k_dbt, &d_dbt, DB_CURRENT) != 0) goto err; // Branch record k_dbt.set_data(&branch); if (bcurs->get(&k_dbt, &d_dbt, DB_SET) != 0) goto err; rec.balance += 10; if (bcurs->put(&k_dbt, &d_dbt, DB_CURRENT) != 0) goto err; // Teller record k_dbt.set_data(&teller); if (tcurs->get(&k_dbt, &d_dbt, DB_SET) != 0) goto err; rec.balance += 10; if (tcurs->put(&k_dbt, &d_dbt, DB_CURRENT) != 0) goto err; // History record d_histdbt.set_flags(0); d_histdbt.set_data(&hrec); d_histdbt.set_ulen(sizeof(hrec)); if (hdb->put(t, &k_histdbt, &d_histdbt, DB_APPEND) != 0) goto err; if (acurs->close() != 0 || bcurs->close() != 0 || tcurs->close() != 0) goto err; if (t->commit(0) != 0) goto err; // END TIMING return (0); err: if (acurs != NULL) (void)acurs->close(); if (bcurs != NULL) (void)bcurs->close(); if (tcurs != NULL) (void)tcurs->close(); if (t != NULL) (void)t->abort(); if (verbose) cout << "Transaction A=" << (long)account << " B=" << (long)branch << " T=" << (long)teller << " failed\n"; return (-1); }
// Modify or create a part based on the following information MultiPartHeader::Add_Code MultiPartHeader::modifyPart(Db* pdb, quint16 partNo, RawHeader *rh, quint16 hostId) { //qDebug() << "Entering modifyPart"; Add_Code retCode = New_Part; int ret = 0; bool createPart = false; Header* h = 0; char *phead = 0; Dbc *cursorp = 0; Dbt key; Dbt data; //qDebug() << "Creating part for key " << multiPartKey; key.set_data(&multiPartKey); key.set_size(sizeof(quint64)); data.set_data(&partNo); data.set_size(sizeof(quint16)); // Get a cursor pdb->cursor(NULL, &cursorp, DB_WRITECURSOR); //qDebug("1"); // Position the cursor to the first record in the database whose // key matches the search key and whose data begins with the search // data. ret = cursorp->get(&key, &data, DB_GET_BOTH); if (ret == 0) { //qDebug("2"); // update the data h = new Header((char*)data.get_data(), (char*)key.get_data()); //qDebug("3"); if (h->isHeldByServer(hostId)) { retCode = Duplicate_Part; } else retCode = Updated_Part; // qDebug() << "Found an update for part " << partNo << ", existing part " << h->getPartNo() << ", existing msgid " << h->getMessageId() << ", new msgid " << rh->m_mid; // Always update the article number h->setServerPartNum(hostId, rh->m_num); //qDebug("4"); phead=h->data(); data.set_data(phead); data.set_size(h->getRecordSize()); //qDebug("5"); cursorp->put(&key, &data, DB_CURRENT); //qDebug("6"); Q_DELETE_ARRAY(phead); } else if (ret == DB_NOTFOUND) // create the part { //qDebug("7"); createPart = true; } else // encountered an error { qDebug() << "Unable to find part " << partNo << " for key " << multiPartKey << ", result = " << ret; retCode = Error_Part; } // Close the cursor if (cursorp != NULL) cursorp->close(); if (createPart == true) { //qDebug("8"); quint32 partSize = rh->m_bytes.toULong(); h = new Header(multiPartKey, partNo, partSize); //qDebug("9"); h->setMessageId(rh->m_mid); h->setServerPartNum(hostId, rh->m_num); //save in the parts db phead=h->data(); data.set_data(phead); data.set_size(h->getRecordSize()); //qDebug("10"); ret = pdb->put(0, &key, &data, 0); if (ret) { qDebug() << "Unable to create part " << partNo << " for key " << multiPartKey << ", result = " << ret; retCode = Error_Part; } else retCode = New_Part; //qDebug("11"); Q_DELETE_ARRAY(phead); } Q_DELETE(h); //qDebug("12\n"); //qDebug() << "Exiting modifyPart"; return retCode; }