Example #1
0
void MojoDatabase::GetAutoDownloadEmails(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.page(page);

	// Sort by timestamp descending
	err = query.order(EmailSchema::TIMESTAMP);
	ErrorToException(err);
	query.desc(true);

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

	slot.cancel();
	err = m_dbClient.find(slot, query);
	ErrorToException(err);
}
Example #2
0
void MojoDatabase::GetSentEmails(Signal::SlotRef slot, const MojObject& outboxFolderId, MojInt32 limit)
{
	MojErr err;

	MojDbQuery query;
	err = query.from(EmailSchema::Kind::EMAIL);
	ErrorToException(err);

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

	MojString sendStatus;
	err = sendStatus.format("%s.%s",EmailSchema::SEND_STATUS, EmailSchema::SendStatus::SENT);
	ErrorToException(err);
	err = query.where(sendStatus.data(), MojDbQuery::OpEq, true);
	ErrorToException(err);

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

	slot.cancel(); // cancel existing slot in case we're in a callback
	err = m_dbClient.find(slot, query);
	ErrorToException(err);
}
Example #3
0
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;
}
MojErr  OnEnabledHandler::getAccountInfoResult(MojObject& payload, MojErr resultErr)
{
	MojLogTrace(IMServiceApp::s_log);
	IMServiceHandler::logMojObjectJsonString(_T("OnEnabledHandler::getAccountInfoResult payload: %s"), payload);

	if (resultErr != MojErrNone) {
		MojLogError(IMServiceApp::s_log, _T("OnEnabledHandler getAccountInfo result error %d"), resultErr);
		return resultErr;
	}

	MojObject result;
	MojErr err = payload.getRequired("result", result);
	if (err != MojErrNone || result.empty()) {
		MojLogError(IMServiceApp::s_log, _T("OnEnabledHandler::getAccountInfoResult result empty or error %d"), err);
		return err;
	}

	err = result.getRequired("_id", m_accountId);
	if (err != MojErrNone || m_accountId.empty()) {
		MojLogError(IMServiceApp::s_log, _T("OnEnabledHandler::getAccountInfoResult accountId empty or error %d"), err);
		return err;
	}

	err = result.getRequired("username", m_username);
	if (err != MojErrNone || m_username.empty()) {
		MojLogError(IMServiceApp::s_log, _T("OnEnabledHandler::getAccountInfoResult username empty or error %d"), err);
		return err;
	}

    {
        MojObject capabilities;
        MojObject messagingObject;
        result.get("capabilityProviders", capabilities);
        getMessagingCapabilityObject(capabilities, messagingObject);
        err = messagingObject.getRequired("serviceName", m_serviceName);
        if (m_serviceName.empty()) {
            MojLogError(IMServiceApp::s_log, _T("OnEnabledHandler::getAccountInfoResult serviceName empty"));
            return err;
        }
    }

    if (m_enable)
    {
        MojDbQuery query;
        query.from("com.palm.config.libpurple:1");
        query.where("accountId", MojDbQuery::OpEq, m_accountId);
        query.limit(1);
        err = m_dbClient.find(m_getAccountConfigSlot, query);
    }
    else
    {
        err = accountDisabled();
    }

	return err;
}
Example #5
0
void MojoDatabase::GetEmails(Signal::SlotRef slot, const MojObject& folderId, MojInt32 limit)
{
	MojDbQuery q;
	MojErr err = q.from(PopEmailAdapter::POP_EMAIL_KIND);
	ErrorToException(err);

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

	err = q.order(EmailSchema::TIMESTAMP);
	ErrorToException(err);

	q.limit(limit);
	q.desc(true);

	err = m_dbClient.find(slot, q);
	ErrorToException(err);
}
Example #6
0
void MojoDatabase::GetEmailSyncList(Signal::SlotRef slot, const MojObject& folderId, const MojInt64& rev, bool desc, MojDbQuery::Page& page, MojInt32 limit)
{
	MojErr err;

	MojDbQuery query;
	err = query.from(PopEmailAdapter::POP_EMAIL_KIND);//EmailSchema::Kind::EMAIL);
	ErrorToException(err);

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

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

	err = query.select(EmailSchema::TIMESTAMP);
	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.page(page);

	// Sort by timestamp descending
	err = query.order(EmailSchema::TIMESTAMP);
	ErrorToException(err);
	query.desc(desc);

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

	slot.cancel(); // cancel existing slot in case we're in a callback

	err = m_dbClient.find(slot, query);
	ErrorToException(err);
}
Example #7
0
MojErr MojDbSearchTest::pageTest(MojDb& db)
{
    MojDbQuery query;
    MojErr err = query.from(_T("SearchTest:2"));
    MojTestErrCheck(err);
    query.limit(3);
    // set page id
    MojString idStr;
    idStr.assign(_T("++IWp1fmlzpdwxKP"));
    MojObject obj(idStr);
    MojDbQuery::Page page;
    err = page.fromObject(obj);
    MojTestErrCheck(err);
    query.page(page);
    err = check(db, query, _T("[\"++IWp1fmlzpdwxKP\",\"++IWp1fmm+O4QrDA\",\"++IWp1fmm0+i9flc\"]"));
    MojTestErrCheck(err);

    return MojErrNone;
}
Example #8
0
MojErr MojDbSearchCursor::init(const MojDbQuery& query)
{
    MojErr err = initImpl(query);
    MojErrCheck(err);

    err = retrieveCollation(query);
    MojErrCheck(err);

    // override limit and sort since we need to retrieve everything
    // and sort before re-imposing limit
    m_limit = query.limit();
    m_distinct = query.distinct();
    if (!m_distinct.empty()) {
        m_orderProp = m_distinct;
    } else {
        m_orderProp = query.order();
    }
    m_query.limit(MaxResults);
    err = m_query.order(_T(""));
    MojErrCheck(err);

    return MojErrNone;
}
Example #9
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 #10
0
MojErr MojDbSearchCursor::init(const MojDbQuery& query)
{
    LOG_TRACE("Entering function %s", __FUNCTION__);
    MojErr err = initImpl(query);
    MojErrCheck(err);

    err = retrieveCollation(query);
    MojErrCheck(err);

    // override limit and sort since we need to retrieve everything
    // and sort before re-imposing limit
    m_limit = query.limit();
    m_distinct = query.distinct();
    if (!m_distinct.empty()) {
        m_orderProp = m_distinct;
    } else {
        m_orderProp = query.order();
    }
    // retrieve page info from query.
    MojDbQuery::Page page;
    page = m_query.page();
    if(!page.empty()) {
        MojObject objOut;
        err = page.toObject(objOut);
        MojErrCheck(err);
        m_page.fromObject(objOut);
    }
    m_query.limit(MaxResults);
    err = m_query.order(_T(""));
    MojErrCheck(err);
    // delete page info from query for query plan
    page.clear();
    m_query.page(page);

    return MojErrNone;
}
Example #11
0
MojErr MojDbPerfUpdateTest::updateObjsViaMerge(MojDb& db, const MojChar* kindId, MojErr (MojDbPerfTest::*createFn) (MojObject&, MojUInt64))
{
	// register all the kinds
	MojTime time;
	MojErr err = putKinds(db, time);
	MojTestErrCheck(err);

	// put objects using createFn
	MojObject objs;
	err = putObjs(db, kindId, numInsertForPut, createFn, objs);
	MojTestErrCheck(err);

	MojObject midObj;
	bool found = objs.at(numInsertForPut/2, midObj);
	MojTestAssert(found);

	MojTime objTime;
	err = mergeObj(db, midObj, objTime);
	MojTestErrCheck(err);
	MojUInt64 mergeTime = objTime.microsecs();
	err = MojPrintF("\n -------------------- \n");
	MojTestErrCheck(err);
	err = MojPrintF("   merging single object - index %llu - of kind %s %llu times took: %llu microsecs\n", numInsertForPut/2, kindId, numMergeIterations, mergeTime);
	MojTestErrCheck(err);
	err = MojPrintF("   time per merge: %llu microsecs", (mergeTime) / (numMergeIterations));
	MojTestErrCheck(err);
	err = MojPrintF("\n\n");
	MojTestErrCheck(err);

	MojString buf;
	err = buf.format("Merge single object - index %llu - %llu times,%s,%llu,%llu,%llu,\n", numInsertForPut/2, numMergeIterations, kindId, mergeTime, mergeTime/numMergeIterations, mergeTime/(1*numMergeIterations));
	MojTestErrCheck(err);
	err = fileWrite(file, buf);
	MojTestErrCheck(err);

	MojTime batchTime;
	MojObject::ArrayIterator beginArr;
	err = objs.arrayBegin(beginArr);
	MojErrCheck(err);
	err = batchMergeObj(db, beginArr, beginArr + (numInsertForPut / 10), batchTime);
	MojTestErrCheck(err);
	mergeTime = batchTime.microsecs();
	err = MojPrintF("   merging batch - %llu objects - of kind %s %llu times took: %llu microsecs\n", numInsertForPut/10, kindId, numBatchMergeIterations, mergeTime);
	MojTestErrCheck(err);
	err = MojPrintF("   time per batch merge: %llu microsecs\n", (mergeTime) / (numBatchMergeIterations));
	MojTestErrCheck(err);
	err = MojPrintF("   time per object: %llu microsecs", (mergeTime) / (numInsertForPut/10 * numBatchMergeIterations));
	MojTestErrCheck(err);
	err = MojPrintF("\n\n");
	MojTestErrCheck(err);

	err = buf.format("Batch merge %llu objects %llu times,%s,%llu,%llu,%llu,\n", numInsertForPut/10, numBatchMergeIterations, kindId, mergeTime, mergeTime/numBatchMergeIterations, mergeTime/(numInsertForPut/10*numBatchMergeIterations));
	MojTestErrCheck(err);
	err = fileWrite(file, buf);
	MojTestErrCheck(err);

	MojTime mergeQueryTime;
	MojTestErrCheck(err);
	MojDbQuery query;
	err = query.from(kindId);
	MojTestErrCheck(err);
	query.limit(numInsertForPut/5);
	query.desc(true);

	MojObject queryObj;
	err = query.toObject(queryObj);
	MojTestErrCheck(err);
	MojString queryStr;
	err = queryObj.stringValue(queryStr);
	MojTestErrCheck(err);

	MojObject props;
	err = props.putString(_T("newKey"), _T("here's a new value"));
	MojTestErrCheck(err);
	MojUInt32 count;
	err = queryMergeObj(db, query, props, count, mergeQueryTime);
	MojTestErrCheck(err);
	mergeTime = mergeQueryTime.microsecs();
	err = MojPrintF("   merging with query - %d objects - of kind %s %llu times took: %llu microsecs\n", count, kindId, numBatchMergeIterations, mergeTime);
	MojTestErrCheck(err);
	err = MojPrintF("   time per merge: %llu microsecs\n", (mergeTime) / (numBatchMergeIterations));
	MojTestErrCheck(err);
	err = MojPrintF("   time per object: %llu microsecs", (mergeTime) / (count * numBatchMergeIterations));
	MojTestErrCheck(err);
	err = MojPrintF("\n\n");
	MojTestErrCheck(err);

	err = buf.format("Merge with query %s,,,,,\nMerge with query - %d objects - %llu times,%s,%llu,%llu,%llu,\n", queryStr.data(), count, numBatchMergeIterations, kindId, mergeTime, mergeTime/numBatchMergeIterations, mergeTime/(count*numBatchMergeIterations));
	MojTestErrCheck(err);
	err = fileWrite(file, buf);
	MojTestErrCheck(err);

	return MojErrNone;
}
Example #12
0
MojErr MojDb::purgeImpl(MojObject& obj, MojUInt32& countOut, MojDbReq& req)
{
	MojLogTrace(s_log);

	MojObject val;
	MojErr err = obj.getRequired(RevNumKey, val);
	MojErrCheck(err);
	MojObject timestamp;
	err = obj.getRequired(TimestampKey, timestamp);
	MojErrCheck(err);

	// purge all objects that were deleted on or prior to this rev num

	// query for objects in two passes - once where backup is true and once where backup is false
	MojDbQuery objQuery;
	err = objQuery.from(MojDbKindEngine::RootKindId);
	MojErrCheck(err);
	err = objQuery.where(DelKey, MojDbQuery::OpEq, true);
	MojErrCheck(err);
	err = objQuery.where(SyncKey, MojDbQuery::OpEq, true);
	MojErrCheck(err);
	err = objQuery.where(RevKey, MojDbQuery::OpLessThanEq, val);
	MojErrCheck(err);

	MojUInt32 backupCount = 0;
	req.autobatch(true);
	req.fixmode(true);
	objQuery.limit(AutoBatchSize);
	err = delImpl(objQuery, backupCount, req, FlagPurge);
	MojErrCheck(err);

	MojDbQuery objQuery2;
	err = objQuery2.from(MojDbKindEngine::RootKindId);
	MojErrCheck(err);
	err = objQuery2.where(DelKey, MojDbQuery::OpEq, true);
	MojErrCheck(err);
	err = objQuery2.where(SyncKey, MojDbQuery::OpEq, false);
	MojErrCheck(err);
	err = objQuery2.where(RevKey, MojDbQuery::OpLessThanEq, val);
	MojErrCheck(err);
	MojUInt32 count = 0;
	MojUInt32 batchRemain = 0;
	if (backupCount <= AutoBatchSize)
		batchRemain = AutoBatchSize - backupCount;
	req.autobatch(true);		// enable auto batch
	req.fixmode(true);		// force deletion of bad entries

	if (batchRemain > 0) {
		objQuery2.limit(batchRemain);
		err = delImpl(objQuery2, count, req, FlagPurge);
		MojErrCheck(err);
	}

	countOut = count + backupCount;

	req.autobatch(false);

	// if we actually deleted objects, store this rev num as the last purge rev
	if (countOut > 0) {
		err = updateState(LastPurgedRevKey, val, req);
		MojErrCheck(err);
	}

	// delete all the RevTimestamp entries prior to this one
	MojDbQuery revTimestampQuery;
	err = revTimestampQuery.from(MojDbKindEngine::RevTimestampId);
	MojErrCheck(err);
	err = revTimestampQuery.where(TimestampKey, MojDbQuery::OpLessThanEq, timestamp);
	MojErrCheck(err);

	count = 0;
	err = delImpl(revTimestampQuery, count, req, FlagPurge);
	MojErrCheck(err);


	return MojErrNone;
}
Example #13
0
MojErr MojDbSearchTest::simpleTest(MojDb& db)
{
	// just foo
	MojErr err = check(db, _T("bogus"), _T("[]"));
	MojTestErrCheck(err);
	err = check(db, _T("f"), _T("[1,2,3,4]"));
	MojTestErrCheck(err);
	err = check(db, _T("F"), _T("[1,2,3,4]"));
	MojTestErrCheck(err);
	err = check(db, _T("fo"), _T("[1,2,3,4]"));
	MojTestErrCheck(err);
	err = check(db, _T("four"), _T("[1,3,4]"));
	MojTestErrCheck(err);
	err = check(db, _T("score"), _T("[1]"));
	MojTestErrCheck(err);
	err = check(db, _T("four years"), _T("[1]"));
	MojTestErrCheck(err);
	err = check(db, _T("Four Years"), _T("[1]"));
	MojTestErrCheck(err);
	err = check(db, _T("four decades"), _T("[]"));
	MojTestErrCheck(err);
	err = check(db, _T("fathers forth"), _T("[2,3]"));
	MojTestErrCheck(err);
	err = check(db, _T("four f"), _T("[1,3,4]"));
	MojTestErrCheck(err);
	err = check(db, _T("four f fo fou"), _T("[1,3,4]"));
	MojTestErrCheck(err);
	// bar and foo
	err = check(db, _T("f"), _T("[3]"), NULL, 2);
	MojTestErrCheck(err);
	// order by bar
	err = check(db, _T("f"), _T("[4,3,2,1]"), _T("bar"));
	MojTestErrCheck(err);
	err = check(db, _T("f"), _T("[1,2,3,4]"), _T("bar"), MojObject::Undefined, true);
	MojTestErrCheck(err);
	err = check(db, _T("f"), _T("[4,3,1,2]"), _T("foo"));
	MojTestErrCheck(err);
	// array value for bar
	MojObject array;
	err = array.push(1);
	MojErrCheck(err);
	err = array.push(2);
	MojErrCheck(err);
	err = check(db, _T("f"), _T("[4,3]"), _T("bar"), array);
	MojTestErrCheck(err);

	// limit
	MojDbQuery query;
	err = initQuery(query, _T("f"));
	MojTestErrCheck(err);
	query.limit(2);
	err = check(db, query, _T("[1,2]"));
	MojTestErrCheck(err);
	err = initQuery(query, _T("f"), _T("bar"));
	MojTestErrCheck(err);
	query.limit(2);
	err = check(db, query, _T("[4,3]"));
	MojTestErrCheck(err);

	// accent insensitivity
	err = check(db, _T("COTE"), _T("[5,6,7,8,9]"));
	MojTestErrCheck(err);

	// case-insensitive ordering
	err = check(db, _T("a"), _T("[12,13,11]"), _T("foo"));
	MojTestErrCheck(err);

	// multi-prop
	query.clear();
	err = query.from(_T("SearchTest:1"));
	MojTestErrCheck(err);
	MojString val;
	err = val.assign(_T("test"));
	MojTestErrCheck(err);
	err = query.where(_T("multiprop"), MojDbQuery::OpSearch, val, MojDbCollationPrimary);
	MojTestErrCheck(err);
	err = check(db, query, _T("[14,15]"));
	MojTestErrCheck(err);

	return MojErrNone;
}
Example #14
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;
}
Example #15
0
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;
}
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;
}
Example #17
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;
}
Example #18
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;
}