Example #1
0
void MojoDatabase::GetEmailsToDelete(Signal::SlotRef slot)
{
	MojErr err;

	MojDbQuery query;
	err = query.from(PopEmailAdapter::POP_EMAIL_KIND);
	ErrorToException(err);

	err = query.select(PopEmailAdapter::ID);
	ErrorToException(err);

	err = query.select(PopEmailAdapter::SERVER_UID);
	ErrorToException(err);

	err = query.select(EmailSchema::FOLDER_ID);
	ErrorToException(err);

	err = query.where("_del", MojDbQuery::OpEq, true);
	ErrorToException(err);

	query.includeDeleted(true);

	slot.cancel();
	err = m_dbClient.find(slot, query);
	ErrorToException(err);
}
Example #2
0
void MojoDatabase::GetLocalEmailChanges(Signal::SlotRef slot, const MojObject& folderId, const MojInt64& rev, MojDbQuery::Page& page, MojInt32 limit)
{
	MojDbQuery query;

	MojErr err = query.from(PopEmailAdapter::POP_EMAIL_KIND);
	ErrorToException(err);

	err = query.where(EmailSchema::FOLDER_ID, MojDbQuery::OpEq, folderId);
	ErrorToException(err);

	if (rev > 0) {
		err = query.where(PopFolderAdapter::LAST_SYNC_REV, MojDbQuery::OpGreaterThan, rev);
		ErrorToException(err);
	}

	query.includeDeleted(true);
	query.page(page);

	slot.cancel();
	err = m_dbClient.find(slot, query);
	ErrorToException(err);
}
Example #3
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;
}
void ImapActivityFactory::BuildFolderWatch(ActivityBuilder& ab, const MojObject& accountId, const MojObject& folderId, MojInt64 rev)
{
	MojErr err;
	MojDbQuery query;

	ab.SetName( GetFolderWatchName(accountId, folderId) );
	ab.SetDescription("Watches for updates to emails");
	ab.SetExplicit(true);
	ab.SetPersist(true);
	SetNetworkRequirements(ab, true);
	ab.SetImmediate(true, "low");

	// Metadata
	MojObject metadata;
	SetMetadata(metadata, FOLDER_WATCH_NAME, accountId, folderId);
	ab.SetMetadata(metadata);

	// Query
	err = query.from(ImapEmailAdapter::IMAP_EMAIL_KIND);
	ErrorToException(err);
	err = query.where(EmailSchema::FOLDER_ID, MojDbQuery::OpEq, folderId);
	ErrorToException(err);
	err = query.where(ImapEmailAdapter::UPSYNC_REV, MojDbQuery::OpGreaterThan, rev);
	ErrorToException(err);
	err = query.includeDeleted(true);
	ErrorToException(err);

	ab.SetDatabaseWatchTrigger(query);

	// Callback
	MojObject callbackParams;
	err = callbackParams.put("accountId", accountId);
	ErrorToException(err);
	err = callbackParams.put("folderId", folderId);
	ErrorToException(err);

	ab.SetCallback(FOLDER_WATCH_CALLBACK, callbackParams);
}
Example #5
0
void MojoDatabase::GetDeletedEmails(Signal::SlotRef slot, const MojObject& folderId, const MojInt64& rev, MojDbQuery::Page& page, MojInt32 limit)
{
	MojErr err;

	MojDbQuery query;
	err = query.from(PopEmailAdapter::POP_EMAIL_KIND);
	ErrorToException(err);

	// Select relevant fields
	err = query.select(PopEmailAdapter::ID);
	ErrorToException(err);

	err = query.select(PopEmailAdapter::SERVER_UID);
	ErrorToException(err);

	err = query.where(EmailSchema::FOLDER_ID, MojDbQuery::OpEq, folderId);
	ErrorToException(err);

	err = query.where("_del", MojDbQuery::OpEq, true);
	ErrorToException(err);

	// Set limit
	if(limit > 0) {
		query.limit(limit);
	}

	// Make sure deleted objects are returned
	query.includeDeleted(true);

	// Set page
	query.page(page);

	slot.cancel(); // cancel existing slot in case we're in a callback
	err = m_dbClient.find(slot, query);
	ErrorToException(err);
}
Example #6
0
MojErr MojDbWatchTest::eqTest(MojDb& db)
{
    MojDbQuery query;
    MojErr err = query.from(_T("WatchTest:1"));
    MojTestErrCheck(err);
    err = query.where(_T("foo"), MojDbQuery::OpEq, 1);
    MojTestErrCheck(err);
    MojRefCountedPtr<TestWatcher> watcher(new TestWatcher);
    MojTestAssert(watcher.get());
    MojDbCursor cursor;
    err = db.find(query, cursor, watcher->m_slot);
    MojTestErrCheck(err);
    err = cursor.close();
    MojTestErrCheck(err);
    MojTestAssert(watcher->m_count == 0);
    MojRefCountedPtr<TestWatcher> watcher2(new TestWatcher);
    MojTestAssert(watcher2.get());
    bool fired = false;
    err = db.watch(query, cursor, watcher2->m_slot, fired);
    MojTestErrCheck(err);
    err = cursor.close();
    MojTestErrCheck(err);
    MojTestAssert(!fired);
    // puts
    MojObject id;
    err = put(db, 0, 0, id, m_rev);
    MojTestErrCheck(err);
    MojTestAssert(watcher->m_count == 0);
    MojTestAssert(watcher2->m_count == 0);
    err = put(db, 2, 2, id, m_rev);
    MojTestErrCheck(err);
    MojTestAssert(watcher->m_count == 0);
    MojTestAssert(watcher2->m_count == 0);
    err = put(db, 1, 1, id, m_rev);
    MojTestErrCheck(err);
    MojTestAssert(watcher->m_count == 1);
    MojTestAssert(watcher2->m_count == 1);
    err = put(db, 1, 1, id, m_rev);
    MojTestErrCheck(err);
    MojTestAssert(watcher->m_count == 1);
    MojTestAssert(watcher2->m_count == 1);
    // put, changing property not in index
    watcher.reset(new TestWatcher);
    MojTestAssert(watcher.get());
    err = db.find(query, cursor, watcher->m_slot);
    MojTestErrCheck(err);
    err = cursor.close();
    MojTestErrCheck(err);
    err = put(db, 1, 2, id, m_rev);
    MojTestErrCheck(err);
    MojTestAssert(watcher->m_count == 1);
    // dels
    watcher.reset(new TestWatcher);
    MojTestAssert(watcher.get());
    err = db.find(query, cursor, watcher->m_slot);
    MojTestErrCheck(err);
    err = cursor.close();
    MojTestErrCheck(err);
    watcher2.reset(new TestWatcher);
    MojTestAssert(watcher2.get());
    MojDbQuery queryWithRev;
    err = queryWithRev.from(_T("WatchTest:1"));
    MojTestErrCheck(err);
    err = queryWithRev.where(_T("foo"), MojDbQuery::OpEq, 1);
    MojTestErrCheck(err);
    err = queryWithRev.where(_T("_rev"), MojDbQuery::OpGreaterThan, m_rev);
    MojTestErrCheck(err);
    err = queryWithRev.includeDeleted();
    MojTestErrCheck(err);
    fired = false;
    err = db.watch(queryWithRev, cursor, watcher2->m_slot, fired);
    MojTestErrCheck(err);
    err = cursor.close();
    MojTestErrCheck(err);
    MojTestAssert(!fired);
    MojTestAssert(watcher->m_count == 0);
    MojTestAssert(watcher2->m_count == 0);
    bool found;
    err = db.del(id, found);
    MojTestErrCheck(err);
    MojTestAssert(found);
    MojTestAssert(watcher->m_count == 1);
    MojTestAssert(watcher2->m_count == 1);
    // ordering
    watcher.reset(new TestWatcher);
    MojTestAssert(watcher.get());
    err = db.find(query, cursor, watcher->m_slot);
    MojTestErrCheck(err);
    err = put(db, 1, 1, id, m_rev);
    MojTestErrCheck(err);
    MojTestAssert(watcher->m_count == 0);
    err = cursor.close();
    MojTestErrCheck(err);
    MojTestAssert(watcher->m_count == 1);

    return MojErrNone;
}
Example #7
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;
}
Example #8
0
MojErr MojDb::delKind(const MojObject& id, bool& foundOut, MojUInt32 flags, MojDbReqRef req)
{
	MojLogTrace(s_log);
	foundOut = false;

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

	// del kind obj
	MojString idStr;
	err = id.stringValue(idStr);
	MojErrCheck(err);

	MojDbKind *pk = NULL;

	// If Kinds has sub-kinds, we give an error
	err = m_kindEngine.getKind(idStr.data(), pk);
	MojErrCheck(err);

	if (pk->nsubkinds() > 0) {
		MojLogWarning(s_log, _T("delKind_error: %s has %d subkinds \n"), idStr.data(), pk->nsubkinds());
		MojErrThrow(MojErrDbKindHasSubKinds);
	}

	//MojLogInfo(s_log, _T("delKind: %s \n"), idStr.data());
	MojLogWarning(s_log, _T("delKind: %s \n"), idStr.data());

	err = m_kindEngine.checkOwnerPermission(idStr, req);
	MojErrCheck(err);

	MojString dbId;
	err = formatKindId(idStr, dbId);
	MojErrCheck(err);
	MojObject deleted;
	bool found = false;
	MojDbAdminGuard adminGuard(req);
	err = delImpl(dbId, found, deleted, req, flags);
	MojErrCheck(err);

	if (found) {
		// del objects
		MojDbQuery query;
		err = query.from(idStr);
		MojErrCheck(err);
		err = query.includeDeleted(true);
		MojErrCheck(err);
		MojUInt32 count;
		req->fixmode(true); 
		err = delImpl(query, count, req, flags | FlagPurge);
		MojErrCheck(err);

		// del associated permissions
		query.clear();
		err = query.from(MojDbKindEngine::PermissionId);
		MojErrCheck(err);
		err = query.where(MojDbServiceDefs::ObjectKey, MojDbQuery::OpEq, idStr);
		MojErrCheck(err);
		req->fixmode(true);
		err = delImpl(query, count, req, flags);
		MojErrCheck(err);

		// del kind
		MojErr errAcc = m_kindEngine.delKind(idStr, req);
		MojErrAccumulate(err, errAcc);
	}
	err = commitKind(idStr, req, err);
	MojErrCheck(err);
	foundOut = found;

	return MojErrNone;
}
Example #9
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;
}
Example #10
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;
}
Example #11
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;
}