示例#1
0
MojErr MojDbPutHandler::open(const MojObject& conf, MojDb* db, MojDbReq& req)
{
    LOG_TRACE("Entering function %s", __FUNCTION__);
    MojAssertWriteLocked(db->schemaLock());

    m_db = db;
    // configure
    MojErr err = configure(conf, req);
    MojErrCheck(err);
    // load permissions from db
    MojDbQuery query;
    err = query.from(m_kindId);
    MojErrCheck(err);
    MojDbCursor cursor;
    err = db->find(query, cursor, req);
    MojErrCheck(err);
    for (;;) {
        bool found = false;
        MojObject perm;
        err = cursor.get(perm, found);
        MojErrCheck(err);
        if (!found)
            break;
        err = put(perm, req, false);
        MojErrCheck(err);
    }
    return MojErrNone;
}
示例#2
0
文件: MojDb.cpp 项目: KyleMaas/db8
MojErr MojDb::watch(const MojDbQuery& query, MojDbCursor& cursor, WatchSignal::SlotRef watchHandler, bool& firedOut, MojDbReqRef req)
{
	MojLogTrace(s_log);

	firedOut = false;

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

	MojRefCountedPtr<MojDbWatcher> watcher(new MojDbWatcher(watchHandler));
	MojAllocCheck(watcher.get());

	MojDbQuery limitedQuery = query;
	limitedQuery.limit(1);
	err = findImpl(limitedQuery, cursor, watcher.get(), req, OpRead);
	MojErrCheck(err);

	MojDbStorageItem* item = NULL;
	bool found = false;
	cursor.verifymode(false);
	err = cursor.get(item, found);
	MojErrCheck(err);

	if (found) {
       const MojDbKey& key = cursor.storageQuery()->endKey();
       err = watcher->fire(key);
       MojErrCheck(err);
       firedOut = true;
	}

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

	return MojErrNone;
}
示例#3
0
/**
 * verifyRecords
 */
MojErr MojDbShardManagerTest::verifyRecords (const MojChar* strKind, MojDb& db, const MojDbShardInfo&, MojUInt32& count)
{
    MojDbQuery query;
    MojDbCursor cursor;
    count = 0;

    MojErr err = query.from(strKind);
    MojErrCheck(err);

    err = db.find(query, cursor);
    MojErrCheck(err);

    while (true)
    {
        bool found;
        MojObject dbObj;

        err = cursor.get(dbObj, found);
        MojErrCheck(err);
        if (!found)
            break;

        ++count;
    }

    return MojErrNone;
}
示例#4
0
文件: MojDb.cpp 项目: KyleMaas/db8
MojErr MojDb::merge(const MojDbQuery& query, const MojObject& props, MojUInt32& countOut, MojUInt32 flags, MojDbReqRef req)
{
	MojLogTrace(s_log);

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

	MojDbCursor cursor;
	err = findImpl(query, cursor, NULL, req, OpUpdate);
	MojErrCheck(err);
	MojAssert(cursor.txn());

	MojUInt32 count = 0;
	MojUInt32 warns = 0;
	bool found = false;
	MojObject prev;
	for (;;) {
		// get prev rev from cursor
		MojDbStorageItem* prevItem = NULL;
		err = cursor.get(prevItem, found);
		if (err == MojErrInternalIndexOnFind) {
			warns++;
			continue;
		}
		MojErrCheck(err);
		if (!found)
			break;
		err = prevItem->toObject(prev, m_kindEngine);
		MojErrCheck(err);
		// merge obj into prev
		MojObject merged;
		err = mergeInto(merged, props, prev);
		MojErrCheck(err);
		// and update the db
		const MojObject& id = prevItem->id();
		err = putObj(id, merged, &prev, prevItem, req, OpUpdate);
		MojErrCheck(err);
		++count;
	}
	if (warns > 0)
		MojLogWarning(s_log, _T("Merge index_warnings: %s; count: %d\n"), query.from().data(), warns);
	err = cursor.close();
	MojErrCheck(err);
	err = req->end();
	MojErrCheck(err);

	countOut = count;

	return MojErrNone;
}
示例#5
0
MojErr MojDbIndex::build(MojDbStorageTxn* txn)
{
    LOG_TRACE("Entering function %s", __FUNCTION__);
	MojAssert(isOpen());
	MojAssert(m_kind && m_kindEngine);
	MojAssert(m_props.size() > 1);

	// query for all existing objects of this type and add them to the index.
	MojDbQuery query;
	MojErr err = query.from(m_kind->id());
	MojErrCheck(err);
	if (m_includeDeleted) {
		err = query.includeDeleted();
		MojErrCheck(err);
	}

	MojDbCursor cursor;
	MojDbReq adminRequest(true);
	adminRequest.txn(txn);
	err = m_kindEngine->find(query, cursor, NULL, adminRequest, OpRead);
	MojErrCheck(err);

	for (;;) {
		MojObject obj;
		bool found = false;
		err = cursor.get(obj, found);
		MojErrCheck(err);
		if (!found)
			break;
		// add this object to the index
		err = update(&obj, NULL, txn, false);
		MojErrCheck(err);
	}
	err = cursor.close();
	MojErrCheck(err);

	return MojErrNone;
}
示例#6
0
MojErr MojDbKindEngine::loadKinds(MojDbReq& req)
{
	MojAssert(isOpen());
	MojAssertWriteLocked(m_db->m_schemaLock);
	MojLogTrace(s_log);

	MojDbQuery query;
	MojErr err = query.from(KindKindId);
	MojErrCheck(err);
	MojDbCursor cursor;
	err = m_db->find(query, cursor, req);
	MojErrCheck(err);

	for (;;) {
		MojObject obj;
		bool found = false;
		err = cursor.get(obj, found);
		MojErrCheck(err);
		if (!found)
			break;
		// load kind
		MojErr loadErr = err = putKind(obj, req);
		MojErrCatchAll(err) {
			MojString id;
			bool found = false;
			MojErr err = obj.get(MojDbServiceDefs::IdKey, id, found);
			MojErrCheck(err);
			MojString errStr;
			MojErrToString(loadErr, errStr);
			MojLogError(s_log, _T("error loading kind '%s' - %s"), id.data(), errStr.data());
		}
	}
	err = cursor.close();
	MojErrCheck(err);

	return MojErrNone;
}
示例#7
0
MojErr MojDbWatchTest::pageTest(MojDb& db)
{
    MojObject id;
    MojObject idFirst;
    MojObject idFourth;
    MojObject idLast;
    MojInt64 rev;
    for (int i = 100; i < 150; ++i) {
        MojErr err = put(db, 100, i, id, rev);
        MojTestErrCheck(err);
        if (i == 100) {
            idFirst = id;
        } else if (i == 103) {
            idFourth = id;
        } else if (i == 149) {
            idLast = id;
        }
    }
    MojDbQuery query;
    MojErr err = query.from(_T("WatchTest:1"));
    MojTestErrCheck(err);
    err = query.where(_T("foo"), MojDbQuery::OpGreaterThanEq, 100);
    MojTestErrCheck(err);
    query.limit(3);
    MojRefCountedPtr<TestWatcher> watcher(new TestWatcher);
    MojTestAssert(watcher.get());
    MojDbCursor cursor;
    err = db.find(query, cursor, watcher->m_slot);
    MojTestErrCheck(err);
    bool found = false;
    MojUInt32 count = 0;
    do {
        MojObject obj;
        err = cursor.get(obj, found);
        MojTestErrCheck(err);
        if (found)
            ++count;
    } while (found);
    MojTestAssert(count == 3);
    MojDbQuery::Page page;
    err = cursor.nextPage(page);
    MojTestErrCheck(err);
    err = cursor.close();
    MojTestErrCheck(err);

    err = merge(db, idFourth, 53);
    MojTestErrCheck(err);
    MojTestAssert(watcher->m_count == 0);

    query.page(page);
    MojRefCountedPtr<TestWatcher> watcher2(new TestWatcher);
    MojTestAssert(watcher2.get());
    err = db.find(query, cursor, watcher2->m_slot);
    MojTestErrCheck(err);
    found = false;
    count = 0;
    do {
        MojObject obj;
        err = cursor.get(obj, found);
        MojTestErrCheck(err);
        if (found)
            ++count;
    } while (found);
    MojTestAssert(count == 3);
    err = cursor.close();
    MojTestErrCheck(err);
    err = db.del(idFirst, found);
    MojTestErrCheck(err);
    MojTestAssert(found);
    MojTestAssert(watcher->m_count == 1);
    MojTestAssert(watcher2->m_count == 0);
    err = db.del(idFourth, found);
    MojTestErrCheck(err);
    MojTestAssert(found);
    MojTestAssert(watcher->m_count == 1);
    MojTestAssert(watcher2->m_count == 1);

    // desc order
    query.page(MojDbQuery::Page());
    query.desc(true);
    MojRefCountedPtr<TestWatcher> watcher3(new TestWatcher);
    MojTestAssert(watcher3.get());
    err = db.find(query, cursor, watcher3->m_slot);
    MojTestErrCheck(err);

    found = false;
    count = 0;
    do {
        MojObject obj;
        err = cursor.get(obj, found);
        MojTestErrCheck(err);
        if (found)
            ++count;
    } while (found);
    MojTestAssert(count == 3);
    err = cursor.close();
    MojTestErrCheck(err);

    err = merge(db, idLast, 53);
    MojTestErrCheck(err);
    MojTestAssert(watcher3->m_count == 1);

    MojRefCountedPtr<TestWatcher> watcher4(new TestWatcher);
    MojTestAssert(watcher4.get());
    err = db.find(query, cursor, watcher4->m_slot);
    MojTestErrCheck(err);

    found = false;
    count = 0;
    do {
        MojObject obj;
        err = cursor.get(obj, found);
        MojTestErrCheck(err);
        if (found)
            ++count;
    } while (found);
    MojTestAssert(count == 3);

    err = cursor.close();
    MojTestErrCheck(err);
    err = merge(db, idLast, 54);
    MojTestErrCheck(err);
    MojTestAssert(watcher4->m_count == 1);

    return MojErrNone;
}
示例#8
0
MojErr MojDbPurgeTest::run()
{
	MojDb db;
	MojErr err = db.open(MojDbTestDir);
	MojTestErrCheck(err);

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

	MojObject revNums[10];
	MojObject ids[10];
	//put 10 objects in the db
	for(int i = 0; i < 10; i++) {
		err = obj.fromJson(MojTestObjStr1);
		MojTestErrCheck(err);
		err = db.put(obj);
		MojTestErrCheck(err);
		// get _rev and id
		MojObject rev;
		err = obj.getRequired(MojDb::RevKey, rev);
		MojTestErrCheck(err);
		revNums[i] = rev;
		MojObject id;
		err = obj.getRequired(MojDb::IdKey, id);
		MojTestErrCheck(err);
		ids[i] = id;
	}

	//purge now, there are no RevTimestamp entries
	MojUInt32 count = 0;
	err = db.purge(count, 30);
	MojTestErrCheck(err);

	err = checkObjectsPurged(db, count, 0, 10, 1, -1);
	MojTestErrCheck(err);

	//create a RevTimestamp entry - that's not more than PurgeNumDays days ago
	MojTime time;
	err = MojGetCurrentTime(time);
	MojTestErrCheck(err);
	err = createRevTimestamp(db, revNums[0], time.microsecs());
	MojTestErrCheck(err);

	//purge now, there are no RevTimestamp entries that are more than
	//PurgeNumDays ago, so nothing should be purged
	count = 0;
	err = db.purge(count, 30);
	MojTestErrCheck(err);

	err = checkObjectsPurged(db, count, 0, 10, 3, -1);
	MojTestErrCheck(err);

	//create a RevTimestamp entry for more than PurgeNumDays days ago
	err = MojGetCurrentTime(time);
	MojTestErrCheck(err);
	err = createRevTimestamp(db, revNums[9], time.microsecs() - (((MojInt64)40) * MojTime::UnitsPerDay));
	MojTestErrCheck(err);

	//purge now, since nothing has been deleted, nothing should be purged,
	//but the RevTimestamp object should be deleted
	count = 0;
	err = db.purge(count, 30);
	MojTestErrCheck(err);

	err = checkObjectsPurged(db, count, 0, 10, 4, -1);
	MojTestErrCheck(err);

	//delete something - this will set its revision number higher
	bool found;
	err = db.del(ids[0], found);
	MojTestErrCheck(err);
	MojTestAssert(found == true);

	//purge now, since nothing has been deleted prior to the revision
	//number, nothing should be purged
	count = 0;
	err = db.purge(count, 30);
	MojTestErrCheck(err);

	err = checkObjectsPurged(db, count, 0, 9, 5, -1);
	MojTestErrCheck(err);

	//delete another object
	err = db.del(ids[1], found);
	MojTestErrCheck(err);
	MojTestAssert(found == true);

	//create a RevTimestamp entry for more than PurgeNumDays days ago,
	//with the rev number of the 1st obj we deleted
	MojDbQuery query;
	err = query.from(_T("PurgeTest:1"));
	MojTestErrCheck(err);
	err = query.where(MojDb::IdKey, MojDbQuery::OpEq, ids[0]);
	MojTestErrCheck(err);
	err = query.includeDeleted();
	MojTestErrCheck(err);

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

	MojObject objFromDb;
	err = cursor.get(objFromDb, found);
	MojTestErrCheck(err);
	err = cursor.close();
	MojTestErrCheck(err);
	MojTestAssert(found == true);

	MojObject revFromDb;
	err = objFromDb.getRequired(MojDb::RevKey, revFromDb);
	MojTestErrCheck(err);

	err = MojGetCurrentTime(time);
	MojTestErrCheck(err);
	err = createRevTimestamp(db, revFromDb, time.microsecs() - (((MojInt64)35) * MojTime::UnitsPerDay));
	MojTestErrCheck(err);

	//now purge, only id[0] should be purged
	count = 0;
	err = db.purge(count, 30);
	MojTestErrCheck(err);

	err = checkObjectsPurged(db, count, 1, 8, 6, revFromDb);
	MojTestErrCheck(err);

	//TODO 2.12.10 - this test does not pass yet, we need to fix calling delKind after a purge
	//err = delKindTest(db);
	//MojTestErrCheck(err);

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

	return MojErrNone;
}
示例#9
0
文件: MojDb.cpp 项目: KyleMaas/db8
MojErr MojDb::delImpl(const MojDbQuery& quer, MojUInt32& countOut, MojDbReq& req, MojUInt32 flags)
{
	MojLogTrace(s_log);

	countOut = 0;
	MojInt32 warns = 0;
    MojDbQuery newQuery = quer;
    MojUInt32 queryLimit = newQuery.limit();

    if(newQuery.limit() == MojDbQuery::LimitDefault)
        newQuery.limit(AutoBatchSize);

    while(queryLimit > 0)
    {
        MojDbCursor cursor;
        MojErr err = findImpl(newQuery, cursor, NULL, req, OpDelete);

        MojErrCheck(err);
        MojAssert(cursor.txn());

        MojUInt32 count = 0;
        MojUInt32 numberInBatch = 0;

        bool found = false;

        MojObject obj;
        for (;;) {
            MojDbStorageItem* item = NULL;
            err = cursor.get(item, found);
            // We simply skip ghost keys and continue; A warning is already written to the system log earlier
            if (err == MojErrInternalIndexOnFind) {
                warns++;
                numberInBatch++;
                continue;
            }
            MojErrCheck(err);
            if (!found)
                break;
            err = item->toObject(obj, m_kindEngine);
            MojErrCheck(err);
            const MojObject& id = item->id();
            MojObject deleted;
            err = delObj(id, obj, item, deleted, req, flags);
            MojErrCheck(err);
            ++count;
            numberInBatch++;
        }

        if (warns > 0)
            MojLogInfo(s_log, _T("delquery index_warnings: %s, count: %d\n"), newQuery.from().data(), warns);
        countOut += count;

        err = cursor.close();
        MojErrCheck(err);

        if(numberInBatch >= AutoBatchSize) // sing > - just in case something messed up
        {
            err = commitBatch(req);
            MojErrCheck(err);
        }

        if(count == 0)
            break;

        queryLimit -= newQuery.limit();
        if(queryLimit > AutoBatchSize)
            newQuery.limit(AutoBatchSize);
        else
            newQuery.limit(queryLimit);
    }

    return MojErrNone;
}
示例#10
0
MojErr MojDbKind::stats(MojObject& objOut, MojSize& usageOut, MojDbReq& req, bool verify)
{
	MojLogTrace(s_log);

#if defined(TESTDBKIND)
	MojLogInfo(s_log, _T("Subkinds for - %s ; count = %d\n"), m_id.data(), m_subs.size());
	int n = 0;
	for (KindVec::ConstIterator i = m_subs.begin(); i != m_subs.end(); ++i) {
		MojLogInfo(s_log, _T("SubKind %d: %s"), n++, (*i)->id().data());
	}
	MojLogInfo(s_log, _T("Supers for - %s ; count = %d\n"), m_id.data(), m_supers.size());
	n = 0;
	for (KindVec::ConstIterator i = m_supers.begin(); i != m_supers.end(); ++i) {
		MojLogInfo(s_log, _T("Super %d: %s"), n++, (*i)->id().data());
	}
#endif 
	// analyze objects
	MojDbQuery query;
	MojErr err = query.from(m_id);
	MojErrCheck(err);
	err = query.includeDeleted(true);
	MojErrCheck(err);
	MojDbCursor cursor;
	err = m_kindEngine->find(query, cursor, NULL, req, OpRead);
	MojLogInfo(s_log, _T("KindStats start: %s ; Indexes = %zu; Using Index: %s; \n"), 
				m_id.data(), m_indexes.size(), cursor.m_dbIndex->name().data());

	MojErrCheck(err);
	MojSize count = 0;
	MojSize size = 0;
	MojSize delCount = 0;
	MojSize delSize = 0;
	MojSize warnings = 0;
	for (;;) {
		MojDbStorageItem* item = NULL;
		bool found = false;
		cursor.verifymode(true);
		err = cursor.get(item, found);
		if (err == MojErrInternalIndexOnFind) {
			warnings++;
			continue;
		}
		if (err != MojErrNone)		// for all other errors break and dump current stats 
			break;	
		if (!found)
			break;
		MojObject obj;
		err = item->toObject(obj, *m_kindEngine, true);
		if (err != MojErrNone)
			break;
		bool deleted = false;
		if (obj.get(MojDb::DelKey, deleted) && deleted) {
			delSize += item->size();
			delCount++;
		} else {
			size += item->size();
			count++;
		}
	}

	MojLogInfo(s_log, _T("KindStats Summary: %s : Count: %zu; delCount: %zu; warnings: %zu \n"), m_id.data(), count, delCount, warnings);
	
	usageOut += size + delSize;
	MojObject info;
	err = info.put(SizeKey, (MojInt64) size);
	MojErrCheck(err);
	err = info.put(CountKey, (MojInt64) count);
	MojErrCheck(err);
	if (delCount > 0) {
		err = info.put(DelSizeKey, (MojInt64) delSize);
		MojErrCheck(err);
		err = info.put(DelCountKey, (MojInt64) delCount);
		MojErrCheck(err);
	}
	if (warnings > 0) {
		err = info.put(WarnKey, (MojInt64) warnings);
		MojErrCheck(err);
	}
	err = objOut.put(ObjectsKey, info);
	MojErrCheck(err);

	// and indexes
	MojObject indexes;
	
	for (IndexVec::ConstIterator i = m_indexes.begin(); i != m_indexes.end(); ++i) {
		MojObject indexInfo;
		err = (*i)->stats(indexInfo, usageOut, req);
		MojErrCheck(err);

		if (verify) {
			MojDbIndex *pi = i->get();
			MojErr err2 = verifyIndex(pi, indexInfo, req);
			MojErrCheck(err2);
		}

		err = indexes.put((*i)->name(), indexInfo);
		MojErrCheck(err);
	}
	err = objOut.put(IndexesKey, indexes);
	MojErrCheck(err);

	return MojErrNone;
}
示例#11
0
MojErr MojDbKind::updateSupers(const KindMap& map, const StringVec& superIds, bool updating, MojDbReq& req)
{
	MojLogTrace(s_log);
	MojInt32 indexes = 0;
	if (updating) {
		KindVec addedSupers;
		MojErr err = diffSupers(map, superIds, m_superIds, addedSupers);
		MojErrCheck(err);
		KindVec removedSupers;
		err = diffSupers(map, m_superIds, superIds, removedSupers);
		MojErrCheck(err);

		// remove/add our objects from new/removed supers
		if (!addedSupers.empty() || !removedSupers.empty()) {
			MojDbQuery query;
			err = query.from(m_id);
			MojErrCheck(err);
			err = query.includeDeleted(true);
			MojErrCheck(err);
			MojDbCursor cursor;
			cursor.kindEngine(m_kindEngine);
			err = find(cursor, NULL, req, OpKindUpdate);
			MojErrCheck(err);
			for (;;) {
				MojObject obj;
				bool found = false;
				err = cursor.get(obj, found);
				MojErrCheck(err);
				if (!found)
					break;

				for (KindVec::ConstIterator i = addedSupers.begin(); i != addedSupers.end(); ++i) {
					err = (*i)->updateOwnIndexes(&obj, NULL, req, indexes);
					MojErrCheck(err);
				}
				for (KindVec::ConstIterator i = removedSupers.begin(); i != removedSupers.end(); ++i) {
					err = (*i)->updateOwnIndexes(NULL, &obj, req, indexes);
					MojErrCheck(err);
				}
			}
		}
	}

	// remove old supers
	m_superIds = superIds;
	MojErr err = clearSupers();
	MojErrCheck(err);
	// look for new supers
	for (StringVec::ConstIterator i = m_superIds.begin(); i != m_superIds.end(); ++i) {
		KindMap::ConstIterator mapIter = map.find(*i);
		if (mapIter != map.end()) {
			err = addSuper(mapIter->get());
			MojErrCheck(err);
		}
	}
	// look for kinds that extend us
	for (KindMap::ConstIterator i = map.begin(); i != map.end(); ++i) {
		if ((*i)->m_superIds.find(m_id) != MojInvalidIndex) {
			err = (*i)->addSuper(this);
			MojErrCheck(err);
		}
	}
	// add root kind if we have no supers
	if (m_supers.empty()) {
		KindMap::ConstIterator mapIter = map.find(MojDbKindEngine::RootKindId);
		if (mapIter != map.end()) {
			err = addSuper(mapIter->get());
			MojErrCheck(err);
		}
	}
	return MojErrNone;
}
示例#12
0
MojErr MojDbKind::verifyIndex(MojDbIndex *pIndex, MojObject &iinfo, MojDbReq& req)
{
	// Goes throudh each index entry and verifies that it points to a valid object
	// For debugging purposes as stats for indexes does not access the target objects
	// Index->stats function does not have enough context to find the object
	// db/stats usage '{"verify":true,"kind":"xyz"}' - each optional
	
	MojDbQuery query;
	MojErr err = query.from(m_id);
	MojErrCheck(err);
	err = query.includeDeleted(true);
	MojErrCheck(err);
	MojDbCursor cursor;
	query.m_forceIndex = pIndex;		// Important: Otherwise, it will pick the default index
	cursor.verifymode(true);		// to get the errors
	err = m_kindEngine->find(query, cursor, NULL, req, OpRead);
	MojLogInfo(s_log, _T("Kind_verifyIndex: Kind: %s; Index: %s; idIndex: %zX; size: %zu; CursorIndex: %s \n"), m_name.data(), 
					pIndex->name().data(), pIndex->idIndex(), pIndex->size(), cursor.m_dbIndex->name().data());
	MojErrCheck(err);
	MojSize count = 0;
	MojSize delCount = 0;
	MojSize warnCount = 0;
	char s[1024];
	for (;;) {
		MojDbStorageItem* item = NULL;
		bool found = false;
		err = cursor.get(item, found);
		if (err == MojErrInternalIndexOnFind) {
			warnCount++;
			MojDbIsamQuery *iquery = (MojDbIsamQuery *)cursor.m_storageQuery.get();
			MojErr err2 =  MojByteArrayToHex(iquery->m_keyData, iquery->m_keySize, s); 
			MojErrCheck(err2);
			MojChar *ids = (iquery->m_keySize > 18) ? (MojChar *)(iquery->m_keyData + iquery->m_keySize - 17) : NULL; 
			MojLogInfo(s_log, _T("VerifyIndex Warning: %s; KeySize: %zu; %s ;id: %s \n"), 
					cursor.m_dbIndex->name().data(), iquery->m_keySize, s, ids);
			continue;
		}
		MojErrCheck(err);
		if (!found)
			break;
		MojObject obj;
		err = item->toObject(obj, *m_kindEngine, true);
		MojErrCheck(err);
		bool deleted = false;
		if (obj.get(MojDb::DelKey, deleted) && deleted) {
			delCount++;
		} else {
			count++;
		}
	}

	MojLogInfo(s_log, _T("Kind_verifyIndex Counts: Kind: %s; Index: %s; count: %zu; delcount: %zu; warnings: %zu \n"), m_name.data(), 
					pIndex->name().data(), count, delCount, warnCount);
	
	err = iinfo.put(VerifyCountKey, (MojInt64)count);
	MojErrCheck(err);
	err = iinfo.put(VerifyWarnCountKey, (MojInt64) warnCount);
	MojErrCheck(err);
	err = iinfo.put(VerifyDelCountKey, (MojInt64) delCount);
	MojErrCheck(err);

	return MojErrNone;
}
示例#13
0
MojErr MojDb::dumpImpl(MojFile& file, bool backup, bool incDel, const MojObject& revParam, const MojObject& delRevParam, bool skipKinds, MojUInt32& countOut, MojDbReq& req,
		MojObject* response, const MojChar* keyName, MojSize& bytesWritten, MojSize& warns, MojUInt32 maxBytes)
{
	// query for objects, adding the backup key and rev key if necessary
	MojDbQuery query;
	MojErr err = query.from(MojDbKindEngine::RootKindId);
	MojErrCheck(err);
	err = query.where(MojDb::DelKey, MojDbQuery::OpEq, incDel);
	MojErrCheck(err);
	if (backup) {
		err = query.where(MojDb::SyncKey, MojDbQuery::OpEq, true);
		MojErrCheck(err);
		if (incDel) {
			err = query.where(MojDb::RevKey, MojDbQuery::OpGreaterThan, delRevParam);
			MojErrCheck(err);
		} else {
			err = query.where(MojDb::RevKey, MojDbQuery::OpGreaterThan, revParam);
			MojErrCheck(err);
		}
	}

	MojDbCursor cursor;
	err = findImpl(query, cursor, NULL, req, OpRead);
	MojErrCheck(err);
	warns = 0;

	MojObject curRev;
	for(;;) {
		bool found = false;
		MojObject obj;
		err = cursor.get(obj, found);
		// So that we can get as much data as possible from a corrupt database
		// We simply skip ghost keys and continue
		if (err == MojErrInternalIndexOnFind) {
			warns++;
			continue;
		}
		MojErrCheck(err);
		if (!found)
			break;

		if (skipKinds) {
			MojString kind;
			err = obj.getRequired(KindKey, kind);
			MojErrCheck(err);
			if (kind == MojDbKindEngine::KindKindId) {
				continue;
			}
		}

		// write out each object, if the backup is full, insert the appropriate incremental key
		err = dumpObj(file, obj, bytesWritten, maxBytes);
		MojErrCatch(err, MojErrDbBackupFull) {
			if (response) {
				MojErr errBackup = MojErrNone;
				if (!curRev.undefined()) {
					errBackup = insertIncrementalKey(*response, keyName, curRev);
					MojErrCheck(errBackup);
				} else {
					errBackup = insertIncrementalKey(*response, keyName, incDel ? delRevParam: revParam);
					MojErrCheck(errBackup);
				}
				errBackup = handleBackupFull(revParam, delRevParam, *response, keyName);
				MojErrCheck(errBackup);
			}
			return MojErrNone;
		}
		MojErrCheck(err);
		err = obj.getRequired(MojDb::RevKey, curRev);
		MojErrCheck(err);
		countOut++;
	}
	err = cursor.close();
	MojErrCheck(err);

    if (warns > 0) {
        MojLogWarning(s_log, _T("Finished Backup with %d warnings \n"), (int)warns);
    } else {
        MojLogDebug(s_log, _T("Finished Backup with no warnings \n"));
    }

	// construct the next incremental key
	if (response && !curRev.undefined()) {
		err = insertIncrementalKey(*response, keyName, curRev);
		MojErrCheck(err);
	}
	return MojErrNone;
}
示例#14
0
MojErr MojDb::purge(MojUInt32& countOut, MojInt64 numDays, MojDbReqRef req)
{
	MojLogTrace(s_log);

	countOut = 0;
	if (numDays <= -1) {
		numDays = m_purgeWindow;
	}

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

	MojLogDebug(s_log, _T("purging objects deleted more than %lld days ago..."), numDays);

	MojTime time;
	err = MojGetCurrentTime(time);
	MojErrCheck(err);

	// store the revision number to current timestamp mapping
	MojObject revTimeMapping;
	MojInt64 rev;
	err = nextId(rev);
	MojErrCheck(err);
	err = revTimeMapping.put(RevNumKey, rev);
	MojErrCheck(err);
	err = revTimeMapping.put(TimestampKey, time.microsecs());
	MojErrCheck(err);
	err = revTimeMapping.putString(KindKey, MojDbKindEngine::RevTimestampId);
	MojErrCheck(err);

	err = putImpl(revTimeMapping, MojDb::FlagNone, req);
	MojErrCheck(err);

	// find the revision number for numDays prior to now
	MojInt64 purgeTime = time.microsecs() - (MojTime::UnitsPerDay * numDays);
	MojDbQuery query;
	err = query.from(MojDbKindEngine::RevTimestampId);
	MojErrCheck(err);
	query.limit(1);
	err = query.where(TimestampKey, MojDbQuery::OpLessThanEq, purgeTime);
	MojErrCheck(err);
	err = query.order(TimestampKey);
	MojErrCheck(err);
	query.desc(true);

	MojDbCursor cursor;
	err = findImpl(query, cursor, NULL, req, OpDelete);
	MojErrCheck(err);
	bool found = false;
	MojObject obj;
	err = cursor.get(obj, found);
	MojErrCheck(err);
	err = cursor.close();
	MojErrCheck(err);

	MojUInt32 batchCount = 0;
	MojUInt32 totalCount = 0;

	while ((found))
	{
		// Do it in AutoBatchSize batches
		batchCount = 0;
		req->fixmode(true);		// purge even if index mis-matches
		err = purgeImpl(obj, batchCount, req);
		MojLogDebug(s_log, _T("purge batch processed: batch: %d; total: %d; err = %d\n"),
					batchCount, (totalCount + batchCount), err);
		MojErrCheck(err);
		totalCount += batchCount;
		countOut = totalCount;
		if (batchCount < AutoBatchSize)	// last batch
			break;
		err = commitBatch(req);
		MojErrCheck(err);
		continue;
	}

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

	MojLogDebug(s_log, _T("purged %d objects"), countOut);


	return MojErrNone;
}