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); }
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); }
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); }
MojErr MojDbSearchTest::initQuery(MojDbQuery& query, const MojChar* queryStr, const MojChar* orderBy, const MojObject& barVal, bool desc) { query.clear(); MojErr err = query.from(_T("SearchTest:1")); MojTestErrCheck(err); MojString val; err = val.assign(queryStr); MojTestErrCheck(err); err = query.where(_T("foo"), MojDbQuery::OpSearch, val, MojDbCollationPrimary); MojTestErrCheck(err); query.desc(desc); if (!barVal.undefined()) { err = query.where(_T("bar"), MojDbQuery::OpEq, barVal); MojTestErrCheck(err); } if (orderBy) { err = query.order(orderBy); MojTestErrCheck(err); } return MojErrNone; }
MojErr MojDbQueryPlan::init(const MojDbQuery& query, const MojDbIndex& index) { m_query = query; m_locale = index.locale(); m_idPropIndex = index.idIndex(); m_ranges.clear(); MojErr err = MojErrNone; if (index.includeDeleted() && !m_query.where().contains(MojDb::DelKey)) { err = m_query.where(MojDb::DelKey, MojDbQuery::OpEq, false); MojErrCheck(err); } // build ranges from where clauses err = buildRanges(index); MojErrCheck(err); if (query.desc()) { // reverse ranges if descending err = m_ranges.reverse(); MojErrCheck(err); } return MojErrNone; }
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; }
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; }
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; }