Example #1
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;
}
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;
}
Example #3
0
 ClicCursor(Db& db) {
     db.cursor(0, &cursor, 0);
 }
Example #4
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;
	}
}
Example #5
0
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;
}