Exemple #1
0
MojErr MojDbPurgeTest::checkObjectsPurged(MojDb& db, const MojUInt32& count, const MojSize& expectedCount,
		const MojSize& expectedNumObjects, const MojSize& expectedNumRevTimestampObjects, const MojObject& expectedLastPurgeRevNum)
{
	//check number of objects purged
	MojTestAssert(count == expectedCount);

	//there should still be expectedNumObjects test objects
	MojDbQuery query;
	MojErr err = query.from(_T("PurgeTest:1"));
	MojTestErrCheck(err);

	MojDbCursor cursor;
	err = db.find(query, cursor);
	MojTestErrCheck(err);

	MojUInt32 objCount;
	err = cursor.count(objCount);
	MojTestErrCheck(err);
	err = cursor.close();
	MojTestErrCheck(err);

	MojTestAssert(objCount == expectedNumObjects);

	//there should be expectedNumRevTimestampObjects RevTimestamp objects
	MojDbQuery revQuery;
	err = revQuery.from(MojDbKindEngine::RevTimestampId);
	MojTestErrCheck(err);

	MojDbCursor revCursor;
	err = db.find(revQuery, revCursor);
	MojTestErrCheck(err);

	MojUInt32 revTimestampObjCount;
	err = revCursor.count(revTimestampObjCount);
	MojTestErrCheck(err);
	err = revCursor.close();
	MojTestErrCheck(err);

	MojTestAssert(revTimestampObjCount == expectedNumRevTimestampObjects);

	//lastPurgedRevNum should be equal to the expectedLastPurgeRevNum
	MojObject revNum;
	err = db.purgeStatus(revNum);
	MojTestErrCheck(err);

	MojTestAssert(revNum == expectedLastPurgeRevNum);

	return MojErrNone;
}
Exemple #2
0
    void checkCount()
    {
        MojDbQuery query;
        MojAssertNoErr( query.from(_T("LoadTest:1")) );

        MojDbCursor cursor;
        MojAssertNoErr( db.find(query, cursor) );

        MojUInt32 count = 0;
        MojAssertNoErr( cursor.count(count) );

        EXPECT_EQ( 10LL, count );
    }
MojErr MojDbServiceHandler::findImpl(MojServiceMessage* msg, MojObject& payload, MojDbReq& req, MojDbCursor& cursor, bool doCount)
{
	MojAssert(msg);
	MojLogTrace(s_log);

	MojObject queryObj;
	MojErr err = payload.getRequired(MojDbServiceDefs::QueryKey, queryObj);
	MojErrCheck(err);
	bool doWatch = false;
	payload.get(MojDbServiceDefs::WatchKey, doWatch);

	MojDbQuery query;
	err = query.fromObject(queryObj);
	MojErrCheck(err);
	MojUInt32 limit = query.limit();
	if (limit == MojDbQuery::LimitDefault){
		query.limit(MaxQueryLimit);
	} else if (limit > MaxQueryLimit) {
		MojErrThrowMsg(MojErrDbInvalidQuery, _T("db: limit greater than %d not allowed"), MaxQueryLimit);
	}

	if (doWatch) {
		MojRefCountedPtr<Watcher> watcher(new Watcher(msg));
		MojAllocCheck(watcher.get());
		err = m_db.find(query, cursor, watcher->m_watchSlot, req);
		MojErrCheck(err);
	} else {
		err = m_db.find(query, cursor, req);
		MojErrCheck(err);
	}

	// append results
	MojObjectVisitor& writer = msg->writer();
	err = writer.beginObject();
	MojErrCheck(err);
	err = writer.boolProp(MojServiceMessage::ReturnValueKey, true);
	MojErrCheck(err);
	err = writer.propName(MojDbServiceDefs::ResultsKey);
	MojErrCheck(err);
	err = writer.beginArray();
	MojErrCheck(err);
	err = cursor.visit(writer);
	MojErrCheck(err);
	err = writer.endArray();
	MojErrCheck(err);

	// append next page
	MojDbQuery::Page page;
	err = cursor.nextPage(page);
	MojErrCheck(err);
	if (!page.empty()) {
		MojObject pageObj;
		err = page.toObject(pageObj);
		MojErrCheck(err);
		err = writer.objectProp(MojDbServiceDefs::NextKey, pageObj);
		MojErrCheck(err);
	}

	// append count
	if (doCount) {
		MojUInt32 count = 0;
		err = cursor.count(count);
		MojErrCheck(err);
		err = writer.intProp(MojDbServiceDefs::CountKey, (MojInt64) count);
		MojErrCheck(err);
	}

	err = writer.endObject();
	MojErrCheck(err);

	if (doWatch) {
		// if this is a watched query, it cannot be part of a batch so it's safe to reply here
		err = msg->reply();
		MojErrCheck(err);
	}

	// notifications can fire any time after the cursor is closed,
	// so don't close it until after sending the reply.
	err = cursor.close();
	MojErrCheck(err);

	return MojErrNone;
}
Exemple #4
0
MojErr MojDbPurgeTest::delKindTest(MojDb& db)
{

	// start from scratch - purge everything
	MojUInt32 count = 0;
	MojErr err = db.purge(count, 0);
	MojTestErrCheck(err);
	MojTestAssert(count > 0);

	// purge again, make sure nothing is left
	err = db.purge(count, 0);
	MojTestErrCheck(err);
	MojTestAssert(count == 0);

	// make sure at least 2 objects exist
	MojDbQuery q;
	err = q.from(_T("PurgeTest:1"));
	MojTestErrCheck(err);
	MojDbCursor cursor;
	err = db.find(q, cursor);
	MojTestErrCheck(err);

	MojUInt32 objCount;
	err = cursor.count(objCount);
	MojTestErrCheck(err);
	err = cursor.close();
	MojTestErrCheck(err);

	if (objCount <= 1) {
		for (int i = objCount; i < 2; i++) {
			MojObject obj;
			err = obj.fromJson(MojTestObjStr1);
			MojTestErrCheck(err);
			err = db.put(obj);
			MojTestErrCheck(err);
			objCount++;
		}
	}

	// delete half the objects
	q.limit(objCount / 2);

	MojUInt32 delCount;
	err = db.del(q, delCount);
	MojTestErrCheck(err);

	// delete the kind
	MojString idStr;
	err = idStr.assign(_T("PurgeTest:1"));
	MojTestErrCheck(err);
	MojObject id(idStr);
	bool found;
	err = db.delKind(id, found);
	MojTestErrCheck(err);
	MojTestAssert(found);

	/*MojUInt32 deletedObjCount;
	err = q.where(_T("_del"), MojDbQuery::OpEq, true);
	MojTestErrCheck(err);
	q.includeDeleted(true);
	err = db.find(q, cursor);
	MojTestErrCheck(err);
	err = cursor.count(deletedObjCount);
	MojTestErrCheck(err);
	err = cursor.close();
	MojTestErrCheck(err);

	// now all the objects should be deleted
	MojTestAssert(deletedObjCount == objCount);*/

	// purge now
	err = db.purge(count, 0);
	MojTestErrCheck(err);

	return MojErrNone;
}
Exemple #5
0
MojErr MojDb::dump(const MojChar* path, MojUInt32& countOut, bool incDel, MojDbReqRef req, bool backup,
		MojUInt32 maxBytes, const MojObject* incrementalKey, MojObject* backupResponse)
{
	MojAssert(path);
	MojLogTrace(s_log);

	MojErr err = beginReq(req);
	MojErrCheck(err);

	if (!req->admin()) {
		MojLogError(s_log, _T("access denied: '%s' cannot dump db to path: '%s'"), req->domain().data(), path);
		MojErrThrow(MojErrDbAccessDenied);
	}

	MojFile file;
	err = file.open(path, MOJ_O_WRONLY | MOJ_O_CREAT | MOJ_O_TRUNC, MOJ_S_IRUSR | MOJ_S_IWUSR);
	MojErrCheck(err);

	// write out kinds first, then existing objects, then deleted objects
	MojSize bytesWritten = 0;
	MojSize totalwarns = 0;
	MojSize newwarns = 0;
	MojDbQuery objQuery;
	MojVector<MojObject> kindVec;
	MojObject revParam = -1;
	MojObject delRevParam = -1;

	// if we were given an incremental key, pull out the revs now
	if (incrementalKey) {
		incrementalKey->get(MojDbServiceDefs::RevKey, revParam);
		incrementalKey->get(MojDbServiceDefs::DeletedRevKey, delRevParam);
	}

	err = m_kindEngine.getKinds(kindVec);
	MojErrCheck(err);

	// write kinds - if incremental, only write the kinds that have changed since the respective revs
	MojString countStr;
	for (MojVector<MojObject>::ConstIterator i = kindVec.begin(); i != kindVec.end(); ++i) {
		if (backup) {
			bool backupKind = false;
			i->get(MojDbKind::SyncKey, backupKind);
			if (!backupKind)
				continue;
			MojString id;
			err = i->getRequired(MojDbServiceDefs::IdKey, id);
			MojErrCheck(err);
			MojDbQuery countQuery;
			err = countQuery.from(id);
			MojErrCheck(err);
			MojDbCursor cursor;
			err = find(countQuery, cursor, req);
			MojErrCheck(err);
			MojUInt32 count = 0;
			err = cursor.count(count);
			MojErrCheck(err);
			if (count > 0) {
				if (i != kindVec.begin()) {
					err = countStr.appendFormat(_T(", "));
					MojErrCheck(err);
				}
				err = countStr.appendFormat("%s=%u", id.data(), count);
				MojErrCheck(err);
			}
		}
		bool deleted = false;
		i->get(DelKey, deleted);
		MojObject kindRev;
		err = i->getRequired(RevKey, kindRev);
		MojErrCheck(err);
		if ((deleted && kindRev > delRevParam) || (!deleted && kindRev > revParam)) {
			err = dumpObj(file, (*i), bytesWritten, maxBytes);
			MojErrCheck(err);
			countOut++;
		}
	}

	// dump all the non-deleted objects
	err = dumpImpl(file, backup, false, revParam, delRevParam, true, countOut, req, backupResponse, MojDbServiceDefs::RevKey, bytesWritten, newwarns, maxBytes);
	MojErrCheck(err);
	totalwarns += newwarns;
	// If we're supposed to include deleted objects, dump the deleted objects now.
	// There's a chance that we may have run out of space in our backup.  If that's the case,
	// we don't want to try to dump deleted objects - we can detect this by looking for the HasMoreKey
	if (incDel && backupResponse && !backupResponse->contains(MojDbServiceDefs::HasMoreKey)) {
		err = dumpImpl(file, backup, true, revParam, delRevParam, false, countOut, req, backupResponse, MojDbServiceDefs::DeletedRevKey, bytesWritten, newwarns, maxBytes);
		MojErrCheck(err);
	}
	totalwarns += newwarns;

	// Add the Full and Version keys
	if (backup && backupResponse) {
		bool incremental = (incrementalKey != NULL);
		err = backupResponse->putBool(MojDbServiceDefs::FullKey, !incremental);
		MojErrCheck(err);
		err = backupResponse->put(MojDbServiceDefs::VersionKey, DatabaseVersion);
		MojErrCheck(err);
		err = backupResponse->put(MojDbServiceDefs::WarningsKey, (MojInt32)totalwarns);
		MojErrCheck(err);
		MojString description;
		err = description.format(_T("incremental=%u"), countOut);
		MojErrCheck(err);
		if (!countStr.empty()) {
			err = description.appendFormat(_T(", %s"), countStr.data());
			MojErrCheck(err);
		}
		err = backupResponse->put(_T("description"), description);
		MojErrCheck(err);
	}

	err = req->end();
	MojErrCheck(err);

	return MojErrNone;
}