Esempio n. 1
0
bool CDB::Rewrite(const string& strFile, const char* pszSkip)
{
    while (true)
    {
        {
            LOCK(bitdb.cs_db);
            if (!bitdb.mapFileUseCount.count(strFile) || bitdb.mapFileUseCount[strFile] == 0)
            {
                // Flush log data to the dat file
                bitdb.CloseDb(strFile);
                bitdb.CheckpointLSN(strFile);
                bitdb.mapFileUseCount.erase(strFile);

                bool fSuccess = true;
                printf("Rewriting %s...\n", strFile.c_str());
                string strFileRes = strFile + ".rewrite";
                { // surround usage of db with extra {}
                    CDB db(strFile.c_str(), "r");
                    Db* pdbCopy = new Db(&bitdb.dbenv, 0);

                    int ret = pdbCopy->open(NULL,                 // Txn pointer
                                            strFileRes.c_str(),   // Filename
                                            "main",    // Logical db name
                                            DB_BTREE,  // Database type
                                            DB_CREATE,    // Flags
                                            0);
                    if (ret > 0)
                    {
                        printf("Cannot create database file %s\n", strFileRes.c_str());
                        fSuccess = false;
                    }

                    Dbc* pcursor = db.GetCursor();
                    if (pcursor)
                        while (fSuccess)
                        {
                            CDataStream ssKey(SER_DISK, CLIENT_VERSION);
                            CDataStream ssValue(SER_DISK, CLIENT_VERSION);
                            int ret = db.ReadAtCursor(pcursor, ssKey, ssValue, DB_NEXT);
                            if (ret == DB_NOTFOUND)
                            {
                                pcursor->close();
                                break;
                            }
                            else if (ret != 0)
                            {
                                pcursor->close();
                                fSuccess = false;
                                break;
                            }
                            if (pszSkip &&
                                strncmp(&ssKey[0], pszSkip, std::min(ssKey.size(), strlen(pszSkip))) == 0)
                                continue;
                            if (strncmp(&ssKey[0], "\x07version", 8) == 0)
                            {
                                // Update version:
                                ssValue.clear();
                                ssValue << CLIENT_VERSION;
                            }
                            Dbt datKey(&ssKey[0], ssKey.size());
                            Dbt datValue(&ssValue[0], ssValue.size());
                            int ret2 = pdbCopy->put(NULL, &datKey, &datValue, DB_NOOVERWRITE);
                            if (ret2 > 0)
                                fSuccess = false;
                        }
                    if (fSuccess)
                    {
                        db.Close();
                        bitdb.CloseDb(strFile);
                        if (pdbCopy->close(0))
                            fSuccess = false;
                        delete pdbCopy;
                    }
                }
                if (fSuccess)
                {
                    Db dbA(&bitdb.dbenv, 0);
                    if (dbA.remove(strFile.c_str(), NULL, 0))
                        fSuccess = false;
                    Db dbB(&bitdb.dbenv, 0);
                    if (dbB.rename(strFileRes.c_str(), NULL, strFile.c_str(), 0))
                        fSuccess = false;
                }
                if (!fSuccess)
                    printf("Rewriting of %s FAILED!\n", strFileRes.c_str());
                return fSuccess;
            }
        }
        MilliSleep(100);
    }
    return false;
}
Esempio n. 2
0
/* Bulk fill a database. */
void BulkExample::bulkUpdate(
    int num, int dups, int *countp, int *iterp, int verbose)
{
	Dbt key, data;
	u_int32_t flag;
	DbTxn *txnp;
	int count, i, iter, ret;
	DbMultipleDataBuilder *ptrd, *ptrk;
	DbMultipleKeyDataBuilder *ptrkd;

	txnp = NULL;
	count = flag = iter = ret = 0;
	ptrk = ptrd = NULL;
	if (data_val == NULL)
		data_val = (struct data *)malloc(DATALEN);
	memset(data_val, 0, DATALEN);
	memset(&key, 0, sizeof(Dbt));
	memset(&data, 0, sizeof(Dbt));

	/* 
	 * 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 (dlen != (u_int32_t) UPDATES_PER_BULK_PUT *
	    (sizeof(u_int32_t) + DATALEN) * 1024) {
		dlen = (u_int32_t) UPDATES_PER_BULK_PUT *
		    (sizeof(u_int32_t) + DATALEN) * 1024;
		dbuf = realloc(dbuf, dlen);
	}
	memset(dbuf, 0, dlen);
	data.set_ulen(dlen);
	data.set_flags(DB_DBT_USERMEM | DB_DBT_BULK);
	data.set_data(dbuf);

	/*
	 * Bulk insert with either DB_MULTIPLE in two buffers or
	 * DB_MULTIPLE_KEY in a single buffer. With DB_MULTIPLE, all keys are
	 * constructed in the key Dbt, and all data is constructed in the data
	 * Dbt. With DB_MULTIPLE_KEY, all key/data pairs are constructed in the
	 * key Dbt. We use DB_MULTIPLE mode when there are duplicate records.
	 */
	flag |= (dups) ? DB_MULTIPLE : DB_MULTIPLE_KEY;
	if (dups) {
		ptrk = new DbMultipleDataBuilder(key);
		ptrd = new DbMultipleDataBuilder(data);
	} else
		ptrkd = new DbMultipleKeyDataBuilder(key);

	try {
		for (i = 0; i < num; 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");
			}
			data_val->id = 0;
			get_string(tstring, data_val->str, i);
			do {
				if (dups) {
					if (ptrk->append(&i,
					    sizeof(i)) == false)
						throwException(dbenv,
						    txnp, EXIT_FAILURE,
"DbMultipleDataBuilder->append");
					if (ptrd->append(data_val,
					    DATALEN) == false)
						throwException(dbenv,
						    txnp, EXIT_FAILURE,
"DbMultipleDataBuilder->append");
				} else {
					if (ptrkd->append(&i, sizeof(i),
					    data_val, DATALEN) == false)
						throwException(dbenv,
						    txnp, EXIT_FAILURE,
"DbMultipleKeyDataBuilder->append");
				}
				if (verbose)
					printf(
"Insert key: %d, \t data: (id %d, str %s)\n",
					    i, data_val->id, data_val->str);
				count++;
			} while (data_val->id++ < dups);
			if ((i + 1) % UPDATES_PER_BULK_PUT == 0) {
				if ((ret = dbp->put(txnp,
					    &key, &data, flag)) != 0)
					throwException(dbenv,
					    txnp, ret, "Bulk DB->put");
				iter++;
				if (dups) {
					ptrk = new DbMultipleDataBuilder(key);
					ptrd = new DbMultipleDataBuilder(data);
				} else
					ptrkd = new
					    DbMultipleKeyDataBuilder(key);
			}
		} 
		if ((num % UPDATES_PER_BULK_PUT) != 0) {
			if ((ret = dbp->put(txnp, &key, &data, flag)) != 0)
				throwException(dbenv,
				    txnp, ret, "Bulk DB->put");
			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 << "bulkUpdate " << dbe.what() << endl;
		if (txnp != NULL)
			(void)txnp->abort();
		throw dbe;
	}
}
Esempio n. 3
0
// A function that performs a series of writes to a
// Berkeley DB database. The information written
// to the database is largely nonsensical, but the
// mechanism of transactional commit/abort and
// deadlock detection is illustrated here.
void *
writerThread(void *args)
{
    int j, thread_num;
    int max_retries = 20;   // Max retry on a deadlock
    const char *key_strings[] = {"key 1", "key 2", "key 3", "key 4",
                           "key 5", "key 6", "key 7", "key 8",
                           "key 9", "key 10"};

    Db *dbp = (Db *)args;
    DbEnv *envp = dbp->get_env();

    // Get the thread number
    (void)mutex_lock(&thread_num_lock);
    global_thread_num++;
    thread_num = global_thread_num;
    (void)mutex_unlock(&thread_num_lock);

    // Initialize the random number generator
    srand(thread_num);

    // Perform 50 transactions
    for (int i=0; i<50; i++) {
        DbTxn *txn;
        bool retry = true;
        int retry_count = 0;
        // while loop is used for deadlock retries
        while (retry) {
            // try block used for deadlock detection and
            // general db exception handling
            try {

                // Begin our transaction. We group multiple writes in
                // this thread under a single transaction so as to
                // (1) show that you can atomically perform multiple
                // writes at a time, and (2) to increase the chances
                // of a deadlock occurring so that we can observe our
                // deadlock detection at work.

                // Normally we would want to avoid the potential for
                // deadlocks, so for this workload the correct thing
                // would be to perform our puts with autocommit. But
                // that would excessively simplify our example, so we
                // do the "wrong" thing here instead.
                txn = NULL;
                envp->txn_begin(NULL, &txn, 0);

                // Perform the database write for this transaction.
                for (j = 0; j < 10; j++) {
                    Dbt key, value;
                    key.set_data((void *)key_strings[j]);
                    key.set_size((u_int32_t)strlen(key_strings[j]) + 1);

                    int payload = rand() + i;
                    value.set_data(&payload);
                    value.set_size(sizeof(int));

                    // Perform the database put
                    dbp->put(txn, &key, &value, 0);
                }

                // countRecords runs a cursor over the entire database.
                // We do this to illustrate issues of deadlocking
                std::cout << thread_num <<  " : Found "
                          <<  countRecords(dbp, NULL)
                          << " records in the database." << std::endl;

                std::cout << thread_num <<  " : committing txn : " << i
                          << std::endl;

                // commit
                try {
                    txn->commit(0);
                    retry = false;
                    txn = NULL;
                } catch (DbException &e) {
                    std::cout << "Error on txn commit: "
                              << e.what() << std::endl;
                }
            } catch (DbDeadlockException &) {
                // First thing that we MUST do is abort the transaction.
                if (txn != NULL)
                    (void)txn->abort();

                // Now we decide if we want to retry the operation.
                // If we have retried less than max_retries,
                // increment the retry count and goto retry.
                if (retry_count < max_retries) {
                    std::cout << "############### Writer " << thread_num
                              << ": Got DB_LOCK_DEADLOCK.\n"
                              << "Retrying write operation."
                              << std::endl;
                    retry_count++;
                    retry = true;
                 } else {
                    // Otherwise, just give up.
                    std::cerr << "Writer " << thread_num
                              << ": Got DeadLockException and out of "
                              << "retries. Giving up." << std::endl;
                    retry = false;
                 }
           } catch (DbException &e) {
                std::cerr << "db put failed" << std::endl;
                std::cerr << e.what() << std::endl;
                if (txn != NULL)
                    txn->abort();
                retry = false;
           } catch (std::exception &ee) {
            std::cerr << "Unknown exception: " << ee.what() << std::endl;
            return (0);
          }
        }
    }
    return (0);
}
Esempio n. 4
0
int RepMgr::doloop()
{
    Db *dbp;
    Dbt key, data;
    char buf[BUFSIZE], *rbuf;
    int ret;

    dbp = NULL;
    memset(&key, 0, sizeof(key));
    memset(&data, 0, sizeof(data));
    ret = 0;

    for (;;) {
        if (dbp == NULL) {
            dbp = new Db(&dbenv, 0);

            try {
                dbp->open(NULL, DATABASE, NULL, DB_BTREE,
                    DB_CREATE | DB_AUTO_COMMIT, 0);
            } catch(DbException dbe) {
                dbenv.err(ret, "DB->open");
                throw dbe;
            }
        }

        cout << "QUOTESERVER" ;
        cout << "> " << flush;

        if (fgets(buf, sizeof(buf), stdin) == NULL)
            break;
        if (strtok(&buf[0], " \t\n") == NULL) {
            switch ((ret = print_stocks(dbp))) {
            case 0:
                continue;
            default:
                dbp->err(ret, "Error traversing data");
                goto err;
            }
        }
        rbuf = strtok(NULL, " \t\n");
        if (rbuf == NULL || rbuf[0] == '\0') {
            if (strncmp(buf, "exit", 4) == 0 ||
                strncmp(buf, "quit", 4) == 0)
                break;
            dbenv.errx("Format: TICKER VALUE");
            continue;
        }

        key.set_data(buf);
        key.set_size((u_int32_t)strlen(buf));

        data.set_data(rbuf);
        data.set_size((u_int32_t)strlen(rbuf));

        if ((ret = dbp->put(NULL, &key, &data, 0)) != 0)
        {
            dbp->err(ret, "DB->put");
            if (ret != DB_KEYEXIST)
                goto err;
        }
    }

err:
    if (dbp != NULL)
        (void)dbp->close(DB_NOSYNC);

    return (ret);
}
Esempio n. 5
0
bool CDB::Rewrite(const string& strFile, BerkerleyDBUpgradeProgress &progress, const char* pszSkip, int previousVer, int currentVer)
{
    while (!fShutdown)
    {
        {
            LOCK(bitdb.cs_db);
            if (!bitdb.mapFileUseCount.count(strFile) || bitdb.mapFileUseCount[strFile] == 0)
            {
                // Flush log data to the dat file
                bitdb.CloseDb(strFile);
                bitdb.CheckpointLSN(strFile);
                bitdb.mapFileUseCount.erase(strFile);

                bool fSuccess = true;
                printf("Rewriting %s...\n", strFile.c_str());
                string strFileRes = strFile + ".rewrite";
                {
                    // surround usage of db with extra {}
                    CDB db(strFile.c_str(), "r");
                    Db* pdbCopy = new Db(&bitdb.dbenv, 0);

                    int ret = pdbCopy->open(NULL,                 // Txn pointer
                                            strFileRes.c_str(),   // Filename
                                            "main",    // Logical db name
                                            DB_BTREE,  // Database type
                                            DB_CREATE,    // Flags
                                            0);
                    if (ret > 0)
                    {
                        printf("Cannot create database file %s\n", strFileRes.c_str());
                        fSuccess = false;
                    }

                    Dbc* pcursor = db.GetCursor();
                    if (pcursor)

                        nTotalBytesCompleted = 0;
                        nProgressPercent = 0;

                        int numRows = 0;

                        CDataStream ssKey(SER_DISK, CLIENT_VERSION);
                        CDataStream ssValue(SER_DISK, CLIENT_VERSION);

                        while (fSuccess)
                        {
                            int ret = db.ReadAtCursor(pcursor, ssKey, ssValue, DB_NEXT);

                            if (ret == DB_NOTFOUND)
                            {
                                pcursor->close();
                                break;
                            }
                            else if (ret != 0)
                            {
                                pcursor->close();
                                fSuccess = false;
                                break;
                            }

                            numRows++;
                        }

                        db.ReadAtCursor(pcursor, ssKey, ssValue, DB_FIRST);
                        nTotalBytes = numRows;
                        // Set up progress calculations and callbacks.
                        callbackTotalOperationProgress = &progress;
                        ExternalBlockFileProgress callbackProgress;
                        callbackProgress.connect(RewriteProgress);
                        (*callbackTotalOperationProgress)(0.0);

                        fSuccess = true;
                        while (fSuccess)
                        {
                            CDataStream ssKey(SER_DISK, CLIENT_VERSION);
                            CDataStream ssValue(SER_DISK, CLIENT_VERSION);
                            int ret = db.ReadAtCursor(pcursor, ssKey, ssValue, DB_NEXT);
                            if (ret == DB_NOTFOUND)
                            {
                                pcursor->close();
                                break;
                            }
                            else if (ret != 0)
                            {
                                pcursor->close();
                                fSuccess = false;
                                break;
                            }

                            /*
                            if (strncmp(&ssKey[0], "\x02tx", 3) != 0)
                            {
                                char* k = &ssKey[0];
                                int xx = 1;
                            }
*/

                            if (pszSkip && strncmp(&ssKey[0], pszSkip, std::min(ssKey.size(), strlen(pszSkip))) == 0)
                                continue;

                            if (strncmp(&ssKey[0], "\x07version", 8) == 0)
                            {
                                // Update version:
                                ssValue.clear();
                                ssValue << currentVer;
                            }

                            // update blockindex to include block hash
                            if (previousVer <= DB_MINVER_INCHASH && strncmp(&ssKey[0], "\nblockindex", 11) == 0)
                            {
                                CDiskBlockIndex diskindex(DB_PREV_VER);
                                ssValue >> diskindex;
                                diskindex.fileVersion = CLIENT_VERSION; // update version

                                /*
                                // Construct block index object
                                CBlockIndex* pindexNew = InsertBlockIndex(blockHash);
                                pindexNew->pprev          = InsertBlockIndex(diskindex.hashPrev);
                                pindexNew->pnext          = InsertBlockIndex(diskindex.hashNext);
                                pindexNew->nFile          = diskindex.nFile;
                                pindexNew->nBlockPos      = diskindex.nBlockPos;
                                pindexNew->nHeight        = diskindex.nHeight;
                                pindexNew->nMint          = diskindex.nMint;
                                pindexNew->nMoneySupply   = diskindex.nMoneySupply;
                                pindexNew->nFlags         = diskindex.nFlags;
                                pindexNew->nStakeModifier = diskindex.nStakeModifier;
                                pindexNew->prevoutStake   = diskindex.prevoutStake;
                                pindexNew->nStakeTime     = diskindex.nStakeTime;
                                pindexNew->hashProofOfStake = diskindex.hashProofOfStake;
                                pindexNew->nVersion       = diskindex.nVersion;
                                pindexNew->hashMerkleRoot = diskindex.hashMerkleRoot;
                                pindexNew->nTime          = diskindex.nTime;
                                pindexNew->nBits          = diskindex.nBits;
                                pindexNew->nNonce         = diskindex.nNonce;
                                */
                                uint256 blockHash = diskindex.GetBlockHash(); // calc hash (force)
                                ssValue << diskindex; // serialize
                            }

                            Dbt datKey(&ssKey[0], ssKey.size());
                            Dbt datValue(&ssValue[0], ssValue.size());
                            (callbackProgress)(1);

                            int ret2 = pdbCopy->put(NULL, &datKey, &datValue, DB_NOOVERWRITE);
                            if (ret2 > 0)
                                fSuccess = false;
                        }
                    if (fSuccess)
                    {
                        db.Close();
                        bitdb.CloseDb(strFile);
                        if (pdbCopy->close(0))
                            fSuccess = false;
                        delete pdbCopy;
                    }
                }
                if (fSuccess)
                {
                    Db dbA(&bitdb.dbenv, 0);
                    if (dbA.remove(strFile.c_str(), NULL, 0))
                        fSuccess = false;
                    Db dbB(&bitdb.dbenv, 0);
                    if (dbB.rename(strFileRes.c_str(), NULL, strFile.c_str(), 0))
                        fSuccess = false;
                }
                if (!fSuccess)
                    printf("Rewriting of %s FAILED!\n", strFileRes.c_str());
                return fSuccess;
            }
        }
Esempio n. 6
0
int main(int argc, char *argv[])
{
	try {
		Db *db = new Db(NULL, 0);
		db->open(NULL, "my.db", NULL, DB_BTREE, DB_CREATE, 0644);

		// populate our massive database.
		// all our strings include null for convenience.
		// Note we have to cast for idiomatic
		// usage, since newer gcc requires it.
		Dbt *keydbt = new Dbt((char*)"key", 4);
		Dbt *datadbt = new Dbt((char*)"data", 5);
		db->put(NULL, keydbt, datadbt, 0);

		// Now, retrieve.  We could use keydbt over again,
		// but that wouldn't be typical in an application.
		Dbt *goodkeydbt = new Dbt((char*)"key", 4);
		Dbt *badkeydbt = new Dbt((char*)"badkey", 7);
		Dbt *resultdbt = new Dbt();
		resultdbt->set_flags(DB_DBT_MALLOC);

		int ret;

		if ((ret = db->get(NULL, goodkeydbt, resultdbt, 0)) != 0) {
			cout << "get: " << DbEnv::strerror(ret) << "\n";
		}
		else {
			char *result = (char *)resultdbt->get_data();
			cout << "got data: " << result << "\n";
		}

		if ((ret = db->get(NULL, badkeydbt, resultdbt, 0)) != 0) {
			// We expect this...
			cout << "get using bad key: "
			     << DbEnv::strerror(ret) << "\n";
		}
		else {
			char *result = (char *)resultdbt->get_data();
			cout << "*** got data using bad key!!: "
			     << result << "\n";
		}

		// Now, truncate and make sure that it's really gone.
		cout << "truncating data...\n";
		u_int32_t nrecords;
		db->truncate(NULL, &nrecords, 0);
		cout << "truncate returns " << nrecords << "\n";
		if ((ret = db->get(NULL, goodkeydbt, resultdbt, 0)) != 0) {
			// We expect this...
			cout << "after truncate get: "
			     << DbEnv::strerror(ret) << "\n";
		}
		else {
			char *result = (char *)resultdbt->get_data();
			cout << "got data: " << result << "\n";
		}

		db->close(0);
		cout << "finished test\n";
	}
	catch (DbException &dbe) {
		cerr << "Db Exception: " << dbe.what();
	}
	return 0;
}
Esempio n. 7
0
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;
}
Esempio n. 8
0
int RepMgrGSG::doloop()
{
    Dbt key, data;
    Db *dbp;
    char buf[BUFSIZE], *rbuf;
    int ret;

    dbp = 0;
    memset(&key, 0, sizeof(key));
    memset(&data, 0, sizeof(data));
    ret = 0;

    for (;;) {
        if (dbp == 0) {
            dbp = new Db(&dbenv, 0);

            try {
                dbp->open(NULL, DATABASE, NULL, DB_BTREE,
                    app_data.is_master ? DB_CREATE | DB_AUTO_COMMIT :
                    DB_AUTO_COMMIT, 0);
            } catch(DbException dbe) {
                // It is expected that this condition will be triggered
                // when client sites start up.  It can take a while for 
                // the master site to be found and synced, and no DB will
                // be available until then.
                if (dbe.get_errno() == ENOENT) {
                    cout << "No stock db available yet - retrying." << endl;
                    try {
                        dbp->close(0);
                    } catch (DbException dbe2) {
                        cout << "Unexpected error closing after failed" <<
                            " open, message: " << dbe2.what() << endl;
                        dbp = NULL;
                        goto err;
                    }
                    dbp = NULL;
                    sleep(SLEEPTIME);
                    continue;
                } else {
                    dbenv.err(ret, "DB->open");
                    throw dbe;
                }
            }
        }

        cout << "QUOTESERVER" ;
        if (!app_data.is_master)
            cout << "(read-only)";
        cout << "> " << flush;

        if (fgets(buf, sizeof(buf), stdin) == NULL)
            break;
        if (strtok(&buf[0], " \t\n") == NULL) {
            switch ((ret = print_stocks(dbp))) {
            case 0:
                continue;
            case DB_REP_HANDLE_DEAD:
                (void)dbp->close(DB_NOSYNC);
                cout << "closing db handle due to rep handle dead" << endl;
                dbp = NULL;
                continue;
            default:
                dbp->err(ret, "Error traversing data");
                goto err;
            }
        }
        rbuf = strtok(NULL, " \t\n");
        if (rbuf == NULL || rbuf[0] == '\0') {
            if (strncmp(buf, "exit", 4) == 0 ||
                strncmp(buf, "quit", 4) == 0)
                break;
            dbenv.errx("Format: TICKER VALUE");
            continue;
        }

        if (!app_data.is_master) {
            dbenv.errx("Can't update at client");
            continue;
        }

        key.set_data(buf);
        key.set_size((u_int32_t)strlen(buf));

        data.set_data(rbuf);
        data.set_size((u_int32_t)strlen(rbuf));

        if ((ret = dbp->put(NULL, &key, &data, 0)) != 0)
        {
            dbp->err(ret, "DB->put");
            if (ret != DB_KEYEXIST)
                goto err;
        }
    }

err:    if (dbp != 0) {
        (void)dbp->close(DB_NOSYNC);
        }

    return (ret);
}
Esempio n. 9
0
 void put(const char* skey, const char* sval){
   Dbt key((void*)skey, strlen(skey));
   Dbt value((void*)sval, ::strlen(sval)+1);
   _db->put(nullptr, &key, &value, 0);
 };
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;

  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()) {
        while ( myfile.good() ) {
            getline (myfile,line);

            // Ignore empty and commented lines
            if ((line.length() == 0) || (startswith(line, std::string("#")))) {
                continue;
            }

            std::vector<std::string> cj = split(line, ' ');

            int freq = atoi(cj[1].c_str());

            Dbt key(const_cast<char*>(cj[0].data()), cj[0].size());
            Dbt value(&freq, sizeof(int));
            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.

    if (pdb != NULL) {
      pdb->close(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;
}