Example #1
0
TEST_F(ReqSuite, original)
{
    buildSample();
    mark1();

    // test visibility with update
    {
        MojDbReq req;

        // start transaction
        req.begin(&db, false);
        mark2(req);

        // visible within transaction
        checkMarkWithUpdate(50ul, -2, req);
    }

    // invisible after aborted transaction
    checkMarkWithUpdate(0ul, -2);

    // test visibility with delete
    mark1();
    {
        MojDbReq req;
        // start transaction
        req.begin(&db, false);

        deleteMark(50ul, -1, req);

        // visible within transaction
        {
            MojDbQuery query;
            MojAssertNoErr( query.from(_T("Test:1")) );
            MojAssertNoErr( query.where(_T("bar"), MojDbQuery::OpLessThan, 2) );

            MojObject update;

            MojUInt32 count = 0xbaddcafe;
            MojAssertNoErr( db.merge(query, update, count, MojDb::FlagNone, req) );
            EXPECT_EQ( 33ul, count);
        }
    }

    // invisible after aborted transaction
    {
        MojDbQuery query;
        MojAssertNoErr( query.from(_T("Test:1")) );
        MojAssertNoErr( query.where(_T("bar"), MojDbQuery::OpLessThan, 2) );

        MojObject update;
        // Note: should not set value to something that will introduce double-update

        MojUInt32 count = 0xbaddcafe;
        MojAssertNoErr( db.merge(query, update, count) );

        EXPECT_EQ( 83ul, count);
    }
}
Example #2
0
TEST_F(ReqSuite, deleteUpdateRollback)
{
    buildSample();
    mark1();

    {
        MojDbReq req;
        // start transaction
        req.begin(&db, false);

        checkMarkWithUpdate(50ul, -1, req);
        checkMarkWithUpdate(0ul, -3, req);

        deleteMark(50ul, -1, req);

        checkMarkWithUpdate(0ul, -1, req);
        checkMarkWithUpdate(0ul, -3, req);

        mark3(req);

        checkMarkWithUpdate(0ul, -1, req);
        checkMarkWithUpdate(33ul, -3, req);

    }
    checkMarkWithUpdate(50ul, -1);
    checkMarkWithUpdate(0ul, -3);
}
Example #3
0
TEST_F(ReqSuite, originalEq)
{
    buildSample();
    mark1();

    // test visibility with update
    {
        MojDbReq req;

        // start transaction
        req.begin(&db, false);
        mark2(req);

        // visible within transaction
        checkMarkWithUpdate(50ul, -2, req);
    }

    // invisible after aborted transaction
    checkMarkWithUpdate(0ul, -2);

    // test visibility with delete
    mark1();
    {
        MojDbReq req;
        // start transaction
        req.begin(&db, false);

        deleteMark(50ul, -1, req);
        // visible within transaction
        checkMarkWithUpdate(0ul, -1, req);
    }

    // invisible after aborted transaction
    checkMarkWithUpdate(50ul, -1);

}
Example #4
0
TEST_F(ReqSuite, visibility)
{
    buildSample();
    mark1();

    MojDbReq req;
    // start transaction
    req.begin(&db, false);

    checkMarkWithUpdate(50ul, -1, req);
    checkMarkWithUpdate(0ul, -2, req);

    mark2(req);

    checkMarkWithUpdate(50ul, -2, req);
}
Example #5
0
TEST_F(ReqSuite, updateRollback)
{
    buildSample();
    mark1();

    {
        MojDbReq req;
        // start transaction
        req.begin(&db, false);

        checkMarkWithUpdate(50ul, -1, req);
        checkMarkWithUpdate(0ul, -2, req);

        mark2(req);

        checkMarkWithUpdate(50ul, -2, req);
    }
    checkMarkWithUpdate(50ul, -1);
    checkMarkWithUpdate(0ul, -2);
}
Example #6
0
MojErr MojDb::drop(const MojChar* path)
{
	MojAssert(path);
	MojLogTrace(s_log);

	MojErr err = requireOpen();
	MojErrCheck(err);

	MojDbReq req;
	err = req.begin(this, true);
	MojErrCheck(err);
	err = m_storageEngine->drop(path, req.txn());
	MojErrCheck(err);
	err = req.end();
	MojErrCheck(err);
	err = close();
	MojErrCheck(err);

	return MojErrNone;
}
Example #7
0
MojErr MojDb::open(const MojChar* path, MojDbStorageEngine* engine)
{
	MojAssert(path);
	MojLogTrace(s_log);

	MojErr err = requireNotOpen();
	MojErrCheck(err);

	MojLogInfo(s_log, _T("opening: '%s'..."), path);

	MojAutoCloser<MojDb> closer(this);
	m_isOpen = true;

	// check the database version number and bail if there's a mismatch
	err = checkDbVersion(path);
	MojErrCheck(err);
	// engine
	if (engine == NULL) {
		err = createEngine();
		MojErrCheck(err);
		MojAssert(m_storageEngine.get());
		err = m_storageEngine->configure(m_conf);
		MojErrCheck(err);
		err = m_storageEngine->open(path);
		MojErrCheck(err);
	} else {
		m_storageEngine.reset(engine);
	}

	MojDbReq req;
	err = req.begin(this, true);
	MojErrCheck(err);

	// db
    MojLogInfo(s_log, _T("Open Database: '%s'"), ObjDbName);
	err = m_storageEngine->openDatabase(ObjDbName, req.txn(), m_objDb);
	MojErrCheck(err);
	MojAssert(m_objDb.get());

	// seq
    MojLogInfo(s_log, _T("Open Database: '%s'"), IdSeqName);
	err = m_storageEngine->openSequence(IdSeqName, req.txn(), m_idSeq);
	MojErrCheck(err);
	MojAssert(m_idSeq.get());

	// kinds
    MojLogInfo(s_log, _T("Open Kind Engine"));
	err = m_kindEngine.open(this, req);
    MojLogInfo(s_log, _T("Kind Opened..."));
	MojErrCheck(err);

	// perms
    MojLogInfo(s_log, _T("Open Permissions"));
	err = m_permissionEngine.open(m_conf, this, req);
	MojErrCheck(err);

	// quota
	err = m_quotaEngine.open(m_conf, this, req);
	MojErrCheck(err);
	err = req.end();
	MojErrCheck(err);

	// idgen
	err = m_idGenerator.init();
	MojErrCheck(err);

	closer.release();
	MojLogInfo(s_log, _T("open completed"));

	return MojErrNone;
}
Example #8
0
MojErr MojDbTxnTest::run()
{
	MojErr err;
    MojDb db;

	err = MojDbTestEnv::run(MojDbTestDir);
	MojTestErrCheck(err);

    // open
    err = db.open(MojDbTestDir, env());
    MojTestErrCheck(err);

    // add type
    MojObject obj;
    err = obj.fromJson(MojKindStr);
    MojTestErrCheck(err);
    err = db.putKind(obj);
    MojTestErrCheck(err);

    for (int i = 0; i < 100; ++i) {
        MojObject obj;
        MojErr err = obj.putString(MojDb::KindKey, _T("Test:1"));
        MojTestErrCheck(err);
        err = obj.put(_T("foo"), (i + 25) % 100);
        MojTestErrCheck(err);
        err = obj.put(_T("bar"), i % 3);
        MojTestErrCheck(err);
        err = db.put(obj);
        MojTestErrCheck(err);
    }

    // db: x0 = (25, 0), (26, 1), (27, 2), (28, 0) .. x74 = (99,2), x75 = (0,0) .. x99 = (24,0)

    {
        MojDbQuery query;
        err = query.from(_T("Test:1"));
        MojTestErrCheck(err);
        err = query.where(_T("foo"), MojDbQuery::OpLessThan, 50);
        MojTestErrCheck(err);

        MojObject update;
        err = update.put(_T("bar"), -1);
        MojTestErrCheck(err);
        MojUInt32 count = 0;
        err = db.merge(query, update, count);
        MojTestErrCheck(err);
        MojTestAssert(count == 50);
    }

    // db: x0 = (25, -1) .. x24 = (49,-1), x25 = (50,1)i .. x74 = (99,2), x75 = (0,-1) .. x99 = (24, -1)

    // test visibility with update
    {
        MojDbReq req;
        // start transaction
        req.begin(&db, false);

        MojDbQuery query;
        err = query.from(_T("Test:1"));
        MojTestErrCheck(err);
        err = query.where(_T("bar"), MojDbQuery::OpEq, -1);
        MojTestErrCheck(err);

        MojObject update;
        err = update.put(_T("bar"), -2);
        MojTestErrCheck(err);

        MojUInt32 count = 0;
        err = db.merge(query, update, count, MojDb::FlagNone, req);
        MojTestErrCheck(err);
        MojTestAssert(count == 50);

        // txn: x0 = (25, -2) .. x24 = (49,-2), x25 = (50,1) .. x74 = (99,2), x75 = (0,-2) .. x99 = (24, -2)

        // visible within transaction
        {
            MojDbQuery query;
            err = query.from(_T("Test:1"));
            MojTestErrCheck(err);
            err = query.where(_T("bar"), MojDbQuery::OpEq, -2);
            MojTestErrCheck(err);

            MojObject update;
            err = update.put(_T("bar"), -2);
            MojTestErrCheck(err);

            MojUInt32 count = 0;
            err = db.merge(query, update, count, MojDb::FlagNone, req);
            MojTestErrCheck(err);
            MojTestAssert(count == 50);
        }


        // With BerkeleyDB parallel transaction is locked

        // invisible outside of transaction
        if (engineName().compare(_T("leveldb")) == 0)
        {
            MojDbQuery query;
            err = query.from(_T("Test:1"));
            MojTestErrCheck(err);
            err = query.where(_T("bar"), MojDbQuery::OpEq, -2);
            MojTestErrCheck(err);

            MojObject update;
            err = update.put(_T("bar"), -2);
            MojTestErrCheck(err);

            MojUInt32 count = 0;
            err = db.merge(query, update, count);
            MojTestErrCheck(err);
            MojTestAssert(count == 0);
        }
    }

    // invisible after aborted transaction
    {
        MojDbQuery query;
        err = query.from(_T("Test:1"));
        MojTestErrCheck(err);
        err = query.where(_T("bar"), MojDbQuery::OpEq, -2);
        MojTestErrCheck(err);

        MojObject update;
        err = update.put(_T("bar"), -2);
        MojTestErrCheck(err);

        MojUInt32 count = 0;
        err = db.merge(query, update, count);
        MojTestErrCheck(err);
        MojTestAssert(count == 0);
    }

    // test visibility with delete
    {
        MojDbReq req;
        // start transaction
        req.begin(&db, false);

        MojDbQuery query;
        err = query.from(_T("Test:1"));
        MojTestErrCheck(err);
        err = query.where(_T("bar"), MojDbQuery::OpEq, -1);
        MojTestErrCheck(err);

        MojUInt32 count = 0;
        err = db.del(query, count, MojDb::FlagNone, req);
        MojTestErrCheck(err);
        MojTestAssert(count == 50);

        // txn: x25 = (50,1) .. x74 = (99,2)

        // visible within transaction
        {
            MojDbQuery query;
            err = query.from(_T("Test:1"));
            MojTestErrCheck(err);
            err = query.where(_T("bar"), MojDbQuery::OpLessThan, 2);
            MojTestErrCheck(err);

            MojObject update;
            err = update.put(_T("bar"), -3);
            MojTestErrCheck(err);

            MojUInt32 count = 0;
            err = db.merge(query, update, count, MojDb::FlagNone, req);
            MojTestErrCheck(err);
            MojTestAssert(count == 33);
        }


        // With BerkeleyDB parallel transaction is locked

        // invisible outside of transaction
        if (engineName().compare(_T("leveldb")) == 0)
        {
            MojDbQuery query;
            err = query.from(_T("Test:1"));
            MojTestErrCheck(err);
            err = query.where(_T("bar"), MojDbQuery::OpLessThan, 2);
            MojTestErrCheck(err);

            MojObject update;
            err = update.put(_T("bar"), -3);
            MojTestErrCheck(err);

            MojUInt32 count = 0;
            err = db.merge(query, update, count);
            MojTestErrCheck(err);
            MojTestAssert(count == 83);
        }
    }

    // invisible after aborted transaction
    {
        MojDbQuery query;
        err = query.from(_T("Test:1"));
        MojTestErrCheck(err);
        err = query.where(_T("bar"), MojDbQuery::OpLessThan, 2);
        MojTestErrCheck(err);

        MojObject update;
        // Note that if we change bar=1 here we might get double-update when
        // record we just updated moved into records range ahead of our current
        // cursor position

        MojUInt32 count = 0;
        err = db.merge(query, update, count);
        MojTestErrCheck(err);
        MojTestAssert(count == 83);
    }

    err = db.close();
    MojTestErrCheck(err);

    return MojErrNone;
}