MojErr PopBusDispatcher::AccountCreator::CreatePopAccountResponse(MojObject& response, MojErr err) { MojLogInfo(m_log, "AccountCreator::CreatePopAccountResponse"); MojLogTrace(m_log); if (err) return m_msg->replyError(err); MojString json; err = response.toJson(json); MojLogInfo(m_log, "%s", json.data()); // put the id we have just gotten into the payload we send to smtp account MojObject resultArray; err = response.getRequired("results", resultArray); ErrorToException(err); MojObject result; resultArray.at(0, result); MojObject mailAccountId; err = result.getRequired("id", mailAccountId); ErrorToException(err); err = m_payload.put("mailAccountId", mailAccountId); ErrorToException(err); MojObject accountId; err = m_payload.getRequired("accountId", accountId); ErrorToException(err); ClientPtr client = m_dispatcher.GetOrCreateClient(accountId); client->SendRequest(m_smtpAccountCreatedSlot, "com.palm.smtp", "accountCreated", m_payload); return MojErrNone; }
MojErr PopBusDispatcher::CredentialsChanged(MojServiceMessage* msg, MojObject& payload) { // cancel shut down if it is in shut down state CancelShutdown(); MojLogTrace(s_log); MojString json; MojErr err = payload.toJson(json); ErrorToException(err); MojLogInfo(s_log, "PopBusDispatcher::CredentialsChanged: payload=%s", json.data()); MojObject accountId; err = payload.getRequired("accountId", accountId); ErrorToException(err); try { ClientPtr client = GetOrCreateClient(accountId); // Calling UpdateAccount will force a folder sync. client->UpdateAccount(payload, true); } catch (const std::exception& e) { MojErrThrowMsg(MojErrInternal, "%s", e.what()); } return msg->replySuccess(); }
/* * Save the new incoming IM message to the DB * * @return MojErr if error - caller will log it */ MojErr IncomingIMHandler::saveNewIMMessage(MojRefCountedPtr<IMMessage> IMMessage) { MojErr err; // The message we are handling m_IMMessage = IMMessage; // save it MojObject dbObject; err = m_IMMessage->createDBObject(dbObject); MojErrCheck(err); //add our kind to the object //luna://com.palm.db/put '{"objects":[{"_kind":"com.palm.test:1","foo":1,"bar":1000}]}' err = dbObject.putString(_T("_kind"), PALM_DB_IMMESSAGE_KIND); MojErrCheck(err); // log it - OK to show body in debug log MojString json; err = dbObject.toJson(json); MojErrCheck(err); MojLogDebug(IMServiceApp::s_log, _T("saving message to db: %s"), json.data()); MojLogInfo(IMServiceApp::s_log, _T("saving message to db")); // save it // the save generates a call to the save result handler err = m_dbClient.put(this->m_IMSaveMessageSlot, dbObject); MojErrCheck(err); return MojErrNone; }
/* * Result of query for buddy with given username and serviceName * * If the buddy is found, we can send no matter what. If buddy is not found, we need to check if this service allows sending IM messages * to non buddies (gtalk does not allow this, aol does) */ MojErr SendOneMessageHandler::findBuddyResult(MojObject& result, MojErr findErr) { if (findErr) { MojString error; MojErrToString(findErr, error); MojLogError(IMServiceApp::s_log, _T("findBuddyResult: error %d - %s"), findErr, error.data()); // not much we can do here... failMessage(ERROR_SEND_GENERIC_ERROR); } else { // log the results MojString mojStringJson; result.toJson(mojStringJson); MojLogDebug(IMServiceApp::s_log, _T("findBuddyResult result: %s"), mojStringJson.data()); // "results" in result MojObject results; result.get(_T("results"), results); // check to see if array is empty - there should really always be 0 or 1 item here if (!results.empty()){ // buddy is on the list - send to the transport MojLogInfo(IMServiceApp::s_log, _T("findBuddyResult - user is on buddy list. No need to check account template.")); sendToTransport(); } else { MojLogInfo(IMServiceApp::s_log, _T("findBuddyResult - no buddy found. Need to check account template if this is allowed")); // check palm://com.palm.service.accounts/listAccountTemplates {"capability":"MESSAGING"} to get a list of account templates that support messaging. // If the account template includes "chatWithNonBuddies":false, it should fail to send. MojLogInfo(IMServiceApp::s_log, "Issuing listAccountTemplates request to com.palm.service.accounts"); // parameters: {“capability”:”MESSAGING”} MojObject params; params.putString("capability", "MESSAGING"); // Get a request object from the service MojRefCountedPtr<MojServiceRequest> req; MojErr err = m_service->createRequest(req); if (!err) { err = req->send(m_listAccountSlot, "com.palm.service.accounts", "listAccountTemplates", params); } if (err) { MojString error; MojErrToString(err, error); MojLogError(IMServiceApp::s_log, _T("findBuddyResult failed to send request to accounts: error %d - %s"), err, error.data()); // not much we can do here...don't leave message still pending failMessage(ERROR_SEND_GENERIC_ERROR); } } } return MojErrNone; }
MojoObjectJson::MojoObjectJson(const MojObject& obj) { MojErr err = obj.toJson(m_str); /* Intentially ignore err here. This is for debug output, let's not * make the problem worse... */ (void)err; }
MojErr KindsModel::handleKindsList(MojObject& result, MojErr errCode) { MojString str; result.toJson(str); result.getRequired(_T("results")) return MojErrNone; }
/** * Log the json for a MojObject - useful for debugging */ MojErr IMServiceHandler::logMojObjectJsonString(const MojChar* format, const MojObject mojObject) { if (IMServiceApp::s_log.level() <= MojLogger::LevelInfo) { MojString mojStringJson; mojObject.toJson(mojStringJson); MojLogInfo(IMServiceApp::s_log, format, mojStringJson.data()); } return MojErrNone; }
MojErr MojDbSearchCache::QueryKey::setQuery(const MojDbQuery& query) { MojObject obj; MojErr err = query.toObject(obj); MojErrCheck(err); bool foundOut=false; obj.del(MojDbQuery::PageKey, foundOut); obj.del(MojDbQuery::LimitKey, foundOut); err = obj.toJson(m_query); MojErrCheck(err); setKind(query.from()); return err; }
MojErr echo(MojServiceMessage* msg, const MojObject& payload) { MojString echoStr; MojErr err = payload.toJson(echoStr); MojTestErrCheck(err); MojObject response; err = response.putBool(MojServiceMessage::ReturnValueKey, true); MojTestErrCheck(err); err = response.putString(_T("echo"), echoStr); MojTestErrCheck(err); err = msg->reply(response); MojTestErrCheck(err); return MojErrNone; }
/* * Result of query for loginState entry with given username and serviceName when adding a buddy * * Save buddy in buddyStatus and contact DB */ MojErr SendOneCommandHandler::findAccountIdForAddResult(MojObject& result, MojErr findErr) { if (findErr) { MojString error; MojErrToString(findErr, error); MojLogError(IMServiceApp::s_log, _T("findAccountIdResult failed: error %d - %s"), findErr, error.data()); } else { // parse out the accountId readAccountIdFromResults(result); if (!m_accountId.empty()){ MojObject buddyStatus; buddyStatus.putString("_kind", IM_BUDDYSTATUS_KIND); buddyStatus.put("accountId", m_accountId); buddyStatus.put("username", m_buddyName); buddyStatus.put("serviceName", m_serviceName); // log it MojString json; buddyStatus.toJson(json); MojLogInfo(IMServiceApp::s_log, _T("saving buddy status to db: %s"), json.data()); // save it // the save generates a call to the save result handler MojErr err = m_tempdbClient.put(m_addBuddySlot, buddyStatus); if (err) { MojString error; MojErrToString(err, error); MojLogError(IMServiceApp::s_log, _T("findAccountIdResult: dbClient.put() failed: error %d - %s"), err, error.data()); // tell the outgoing Command handler we are done m_outgoingIMHandler->messageFinished(); } } else { MojLogError(IMServiceApp::s_log, _T("findAccountIdResult: no matching loginState record found for %s %s"), m_username.data(), m_serviceName.data()); // tell the outgoing Command handler we are done m_outgoingIMHandler->messageFinished(); } } return MojErrNone; }
/* * Callback for DB save results * * Status change to "waiting-for-connection" */ MojErr SendOneCommandHandler::imSaveCommandResult(MojObject& result, MojErr saveErr) { MojLogTrace(IMServiceApp::s_log); if (saveErr) { MojString error; MojErrToString(saveErr, error); MojLogError(IMServiceApp::s_log, _T("save imcommand failed. error %d - %s"), saveErr, error.data()); } else { MojString json; result.toJson(json); MojLogInfo(IMServiceApp::s_log, _T("save imcommand %s. response: %s"), this->m_currentCmdDbId.data(), json.data()); } return MojErrNone; }
MojErr SmtpSyncOutboxCommand::ResetErrorResponse(MojObject& response, MojErr err) { try { ResponseToException(response, err); MojString json; response.toJson(json); MojLogInfo(m_log, "SmtpSyncOutboxCommand::ResetErrorResponse got response to updating error status, payload=%s", json.data()); GetOutboxEmails(); } catch (std::exception & e) { HandleException(e, __func__); } catch (...) { HandleException(__func__); } return MojErrNone; }
MojErr PopAccountUpdateCommand::CreateActivityResponse(MojObject& response, MojErr err) { CommandTraceFunction(); try { ErrorToException(err); MojString json; err = response.toJson(json); ErrorToException(err); Sync(); } catch (const std::exception& ex) { Failure(ex); } catch (...) { Failure(MailException("unknown exception", __FILE__, __LINE__)); } return MojErrNone; }
void SmtpAccountDisableCommand::RunImpl() { MojLogInfo(m_log, "SmtpAccountDisable clearing session account"); m_client.GetSession()->ClearAccount(); MojLogInfo(m_log, "SmtpAccountDisable removing watch"); MojObject payload; payload.put("activityName", m_outboxWatchActivityName); MojString json; payload.toJson(json); MojLogInfo(m_log, "SmtpAccountDisable payload %s", json.data()); m_client.SendRequest(m_deleteOutboxWatchResponseSlot, "com.palm.activitymanager", "cancel", payload); }
/* * Parse the account id from the results object for the accountId query * saved in m_accountId member variable * */ MojErr SendOneMessageHandler::readAccountIdFromResults(MojObject& result) { // log the results MojString mojStringJson; result.toJson(mojStringJson); MojLogDebug(IMServiceApp::s_log, _T("readAccountIdFromResults result: %s"), mojStringJson.data()); // "results" in result MojObject results; result.get(_T("results"), results); // check to see if array is empty - there should really always be 1 item here if (!results.empty()){ // get the db id of the buddy MojObject loginState; MojObject::ConstArrayIterator itr = results.arrayBegin(); bool foundOne = false; while (itr != results.arrayEnd()) { if (foundOne) { MojLogError(IMServiceApp::s_log, _T("readAccountIdFromResults: found more than one ImLoginState with same username/serviceName - using the first one")); break; } loginState = *itr; foundOne = true; itr++; } // create the DB object MojErr err = loginState.getRequired("accountId", m_accountId); if (err) { MojLogError(IMServiceApp::s_log, _T("readAccountIdFromResults: missing accountId in loginState entry")); } MojLogInfo(IMServiceApp::s_log, _T("readAccountIdFromResults - accountId: %s. "), m_accountId.data()); } else { MojLogError(IMServiceApp::s_log, _T("readAccountIdFromResults: no matching loginState record found for %s"), m_serviceName.data()); } return MojErrNone; }
MojErr SmtpSyncOutboxCommand::CreateAccountWatchResponse(MojObject& response, MojErr err) { try { ResponseToException(response, err); MojString json; err = response.toJson(json); MojErrCheck(err); MojLogInfo(m_log, "response from activitymanager on updating watch activity: %s", json.data()); CheckErrorCodes(); } catch (std::exception & e) { HandleException(e, __func__); } catch (...) { HandleException(__func__); } return MojErrNone; }
/* * Callback for DB delete results * deleted buddyStatus record */ MojErr SendOneCommandHandler::removeContactResult(MojObject& result, MojErr delErr) { MojLogTrace(IMServiceApp::s_log); if (delErr) { MojString error; MojErrToString(delErr, error); MojLogError(IMServiceApp::s_log, _T("removeContactResult failed. error %d - %s"), delErr, error.data()); } else { MojString json; result.toJson(json); MojLogInfo(IMServiceApp::s_log, _T("removeContactResult response: %s"), json.data()); } // last callback - tell the outgoing Command handler we are finally done m_outgoingIMHandler->messageFinished(); return MojErrNone; }
/* * Callback for DB save results * Status changes */ MojErr SendOneMessageHandler::imSaveMessageResult(MojObject& result, MojErr saveErr) { MojLogTrace(IMServiceApp::s_log); if (saveErr) { MojString error; MojErrToString(saveErr, error); MojLogError(IMServiceApp::s_log, _T("save sent im failed. error %d - %s"), saveErr, error.data()); } else { MojString json; result.toJson(json); MojLogInfo(IMServiceApp::s_log, _T("save sent message %s. response: %s"), this->m_currentMsgdbId.data(), json.data()); } // tell the outgoing message handler we are done m_outgoingIMHandler->messageFinished(); return MojErrNone; }
/*********************************************************************** * setPagePosition * * Move cursor position to page id provided in query. * 1. Find item "_id" which is equal to page id iteratively. * 2. If found, set begin/last position and next page. ***********************************************************************/ MojErr MojDbSearchCursor::setPagePosition() { LOG_TRACE("Entering function %s", __FUNCTION__); MojErr err; MojDbStorageItem* item; m_pos = m_items.begin(); ItemVec::ConstIterator last = m_items.end(); m_limitPos = last; // retrieve page id from query MojObject pageKey; err = m_page.toObject(pageKey); MojErrCheck(err); while (m_pos != last) { // retrieve id from query item = m_pos->get(); const MojObject id = item->id(); // If match, set begin/last position and next page if(pageKey.compare(id) == 0) { if (m_limit >= (last-m_pos)) { m_limitPos = m_items.end(); m_page.clear(); } else { m_limitPos = m_pos + m_limit; // set next page MojDbStorageItem* nextItem = m_limitPos->get(); const MojObject nextId = nextItem->id(); m_page.fromObject(nextId); // print log for nextId MojString strOut; err = nextId.toJson(strOut); MojErrCheck(err); LOG_DEBUG("[db_mojodb] nextId : %s \n", strOut.data()); } break; } ++m_pos; } return MojErrNone; }
/* * Callback for DB delete results * deleted buddyStatus record */ MojErr SendOneCommandHandler::removeBuddyResult(MojObject& result, MojErr delErr) { MojLogTrace(IMServiceApp::s_log); if (delErr) { MojString error; MojErrToString(delErr, error); MojLogError(IMServiceApp::s_log, _T("removeBuddyResult failed. error %d - %s"), delErr, error.data()); } else { MojString json; result.toJson(json); MojLogInfo(IMServiceApp::s_log, _T("removeBuddyResult response: %s"), json.data()); } // now delete from contacts DB //construct our where clause - find by username and servicename MojDbQuery query; MojErr err; err = createContactQuery(query); if (err) { MojString error; MojErrToString(err, error); MojLogError(IMServiceApp::s_log, _T("removeBuddyResult: createContactsQuery failed: error %d - %s"), err, error.data()); } // call del // virtual MojErr del(Signal::SlotRef handler, const MojDbQuery& query, // MojUInt32 flags = MojDb::FlagNone); err = m_dbClient.del(this->m_removeContactSlot, query); if (err) { MojString error; MojErrToString(err, error); MojLogError(IMServiceApp::s_log, _T("removeBuddyResult: dbClient.del() failed: error %d - %s"), err, error.data()); // tell the outgoing Command handler we are done m_outgoingIMHandler->messageFinished(); } return MojErrNone; }
MojErr MojDb::dumpObj(MojFile& file, MojObject obj, MojSize& bytesWrittenOut, MojUInt32 maxBytes) { // remove the rev key before dumping the object bool found = false; MojErr err = obj.del(RevKey, found); MojErrCheck(err); MojString str; err = obj.toJson(str); MojErrCheck(err); err = str.append(_T("\n")); MojErrCheck(err); MojSize len = str.length() * sizeof(MojChar); // if writing this object will put us over the max length, throw an error if (maxBytes && bytesWrittenOut + len > maxBytes) { MojErrThrow(MojErrDbBackupFull); } err = file.writeString(str, bytesWrittenOut); MojErrCheck(err); return MojErrNone; }
/** * Log the json for an incoming IM payload so we can troubleshoot errors in the field in * non debug builds. * * removes "private" data - ie. message body */ MojErr IMServiceHandler::privatelogIMMessage(const MojChar* format, MojObject IMObject, const MojChar* messageTextKey) { MojString mojStringJson; MojString msgText; // replace the message body // not much we can do about errors here... bool found = false; MojErr err = IMObject.del(messageTextKey, found); MojErrCheck(err); if (found) { msgText.assign(_T("***IM Body Removed***")); IMObject.put(messageTextKey, msgText); } // log it (non debug) IMObject.toJson(mojStringJson); MojLogNotice(IMServiceApp::s_log, format, mojStringJson.data()); return MojErrNone; }
MojErr MojDbDistinctTest::check(MojDb& db, const MojDbQuery& query, MojDbCursor& cursor, const MojChar* queryString, const MojChar* expectedIdsJson) { MojErr err = db.find(query, cursor); MojTestErrCheck(err); MojObjectBuilder builder; err = builder.beginArray(); MojTestErrCheck(err); err = cursor.visit(builder); MojTestErrCheck(err); err = cursor.close(); MojTestErrCheck(err); err = builder.endArray(); MojTestErrCheck(err); MojObject results = builder.object(); MojString json; err = results.toJson(json); MojTestErrCheck(err); MojObject expected; err = expected.fromJson(expectedIdsJson); MojTestErrCheck(err); // size check MojTestAssert(expected.size() == results.size()); // value check MojObject::ConstArrayIterator j = results.arrayBegin(); for (MojObject::ConstArrayIterator i = expected.arrayBegin(); i != expected.arrayEnd(); ++i, ++j) { MojObject value; err = j->getRequired(queryString, value); MojTestErrCheck(err); MojTestAssert(*i == value); } return MojErrNone; }
MojErr MojDbSearchTest::check(MojDb& db, const MojDbQuery& query, const MojChar* expectedIdsJson) { MojString str; MojDbSearchCursor cursor(str); MojErr err = db.find(query, cursor); MojTestErrCheck(err); MojObjectBuilder builder; err = builder.beginArray(); MojTestErrCheck(err); err = cursor.visit(builder); MojTestErrCheck(err); err = cursor.close(); MojTestErrCheck(err); err = builder.endArray(); MojTestErrCheck(err); MojObject results = builder.object(); MojString json; err = results.toJson(json); MojTestErrCheck(err); MojObject expected; err = expected.fromJson(expectedIdsJson); MojTestErrCheck(err); MojTestAssert(expected.size() == results.size()); MojObject::ConstArrayIterator j = results.arrayBegin(); for (MojObject::ConstArrayIterator i = expected.arrayBegin(); i != expected.arrayEnd(); ++i, ++j) { MojObject id; err = j->getRequired(MojDb::IdKey, id); MojTestErrCheck(err); MojTestAssert(*i == id); } return MojErrNone; }
MojErr MojService::dispatchRequest(MojServiceMessage* msg) { MojAssert(msg); MojAssertMutexUnlocked(m_mutex); MojLogTrace(s_log); // get payload MojObject payload; MojErr reqErr; MojErr err = reqErr = msg->payload(payload); MojErrCatchAll(err) { return msg->replyError(reqErr); } // get callback Category* category = msg->serviceCategory(); MojAssert(category); MojAssert(category && category->m_service == this); // invoke err = reqErr = category->m_handler->invoke(msg->method(), msg, payload); MojErrCatchAll(err) { MojString payloadStr; (void) payload.toJson(payloadStr); MojString errStr; (void) MojErrToString(reqErr, errStr); MojLogError(s_log, _T("%s (%d) - sender='%s' method='%s' payload='%s'"), errStr.data(), (int) reqErr, msg->senderName(), msg->method(), payloadStr.data()); if (msg->numReplies() == 0) { return msg->replyError(reqErr); } } if (msg->numReplies() == 0 && msg->hasData()) { return msg->reply(); } return MojErrNone; }
MojErr SmtpSendMailCommand::GetEmailResponse(MojObject& response, MojErr err) { try { ResponseToException(response, err); MojString json; response.toJson(json); MojLogInfo(m_log, "got Email response"); MojLogDebug(m_log, "Response: %s", json.data()); // check the database result first ErrorToException(err); MojObject results; err = response.getRequired(_T("results"), results); ErrorToException(err); if(results.size() == 0) { throw MailException("email not found", __FILE__, __LINE__); } // There should only be one email for a given id assert(results.size() == 1); MojObject emailObj; bool hasObject = results.at(0, emailObj); if(!hasObject) { throw MailException("error getting email from results", __FILE__, __LINE__); } EmailAdapter::ParseDatabaseObject(emailObj, m_email); m_toAddress.clear(); if (m_email.GetTo()) { for (EmailAddressList::iterator i = m_email.GetTo()->begin(); i != m_email.GetTo()->end(); i++) m_toAddress.push_back((*i)->GetAddress()); } if (m_email.GetCc()) { for (EmailAddressList::iterator i = m_email.GetCc()->begin(); i != m_email.GetCc()->end(); i++) m_toAddress.push_back((*i)->GetAddress()); } if (m_email.GetBcc()) { for (EmailAddressList::iterator i = m_email.GetBcc()->begin(); i != m_email.GetBcc()->end(); i++) m_toAddress.push_back((*i)->GetAddress()); } m_toIdx = 0; // FIXME: Subscribe to file cache to pin cache contents CalculateEmailSize(); } catch (const std::exception& e) { HandleException(e, __func__, __FILE__, __LINE__); } catch (...) { HandleUnknownException(); } return MojErrNone; }
TEST_F(QuotaTest, usage) { // put quota MojObject obj; MojAssertNoErr( obj.fromJson(_T("{\"owner\":\"com.foo.bar\",\"size\":1000}")) ); MojAssertNoErr( db.putQuotas(&obj, &obj + 1) ); // empty MojInt64 kindUsage = -1; EXPECT_NO_FATAL_FAILURE( getKindUsage(db, _T("Test:1"), kindUsage) ); EXPECT_EQ( 0, kindUsage ) << "Kind without objects should have zero usage"; MojInt64 quotaUsage = -1; EXPECT_NO_FATAL_FAILURE( getQuotaUsage(db, _T("com.foo.bar"), quotaUsage) ); EXPECT_EQ( 0, quotaUsage ) << "Quota without matching objects should have zero usage"; // new obj EXPECT_NO_FATAL_FAILURE( put(db, MojTestKind1Objects[0]) ); MojInt64 kindUsage1 = -1; EXPECT_NO_FATAL_FAILURE( getKindUsage(db, _T("Test:1"), kindUsage1) ); EXPECT_LT( 0, kindUsage1 ) << "Adding new object into kind should increase kind usage"; MojInt64 quotaUsage1 = -1; EXPECT_NO_FATAL_FAILURE( getQuotaUsage(db, _T("com.foo.bar"), quotaUsage1) ); EXPECT_LT( 0, quotaUsage1 ) << "Adding new object matching quota should increase quota usage"; // add prop to existing obj MojAssertNoErr( obj.fromJson(MojTestKind1Objects[0]) ); MojAssertNoErr( obj.put(_T("bar"), 2) ); MojAssertNoErr( db.put(obj, MojDb::FlagForce) ); MojInt64 kindUsage2 = -1; EXPECT_NO_FATAL_FAILURE( getKindUsage(db, _T("Test:1"), kindUsage2) ); EXPECT_LE( 0, kindUsage2 ); EXPECT_LT( kindUsage1, kindUsage2 ) << "Adding property to existing object should increase kind usage"; MojInt64 quotaUsage2 = -1; EXPECT_NO_FATAL_FAILURE( getQuotaUsage(db, _T("com.foo.bar"), quotaUsage2) ); EXPECT_LE( 0, quotaUsage2 ); EXPECT_LT( quotaUsage1, quotaUsage2 ) << "Adding property to existing object that matches quota should increase usage"; // add 2nd obj EXPECT_NO_FATAL_FAILURE( put(db, MojTestKind1Objects[1]) ); MojInt64 kindUsage3 = -1; EXPECT_NO_FATAL_FAILURE( getKindUsage(db, _T("Test:1"), kindUsage3) ); EXPECT_LE( 0, kindUsage3 ); EXPECT_LT( kindUsage2, kindUsage3 ) << "Adding another object should increase kind usage"; MojInt64 quotaUsage3 = -1; EXPECT_NO_FATAL_FAILURE( getQuotaUsage(db, _T("com.foo.bar"), quotaUsage3) ); EXPECT_LE( 0, quotaUsage3 ); EXPECT_LT( quotaUsage2, quotaUsage3 ) << "Adding another object matching to quota should increase usage"; // del first obj bool found = false; MojExpectNoErr( db.del(1, found, MojDb::FlagPurge) ); EXPECT_TRUE( found ) << "Object should be deleted"; MojInt64 kindUsage4 = -1; EXPECT_NO_FATAL_FAILURE( getKindUsage(db, _T("Test:1"), kindUsage4) ); EXPECT_LE( 0, kindUsage4 ); EXPECT_EQ( kindUsage3 - kindUsage2, kindUsage4 ) << "Deletion of object should bring kind usage to expected value"; MojInt64 quotaUsage4 = -1; EXPECT_NO_FATAL_FAILURE( getQuotaUsage(db, _T("com.foo.bar"), quotaUsage4) ); EXPECT_LE( 0, quotaUsage4 ); EXPECT_EQ( quotaUsage3 - quotaUsage2, quotaUsage4 ) << "Deletion of object should bring quota usage to expected value"; // add index MojAssertNoErr( obj.fromJson(MojTestKind1Str2) ); MojExpectNoErr( db.putKind(obj) ); MojInt64 kindUsage5 = -1; EXPECT_NO_FATAL_FAILURE( getKindUsage(db, _T("Test:1"), kindUsage5) ); EXPECT_LE( 0, kindUsage5 ); EXPECT_LT( kindUsage4, kindUsage5 ) << "Adding new index should increase kind usage"; MojInt64 quotaUsage5 = -1; EXPECT_NO_FATAL_FAILURE( getQuotaUsage(db, _T("com.foo.bar"), quotaUsage5) ); EXPECT_LE( 0, quotaUsage5 ); EXPECT_LT( quotaUsage4, quotaUsage5 ) << "Adding new index should increase quota usage"; // update locale MojExpectNoErr( db.updateLocale(_T("FR_fr")) ); MojExpectNoErr( db.updateLocale(_T("EN_us")) ); MojInt64 kindUsage6 = -1; EXPECT_NO_FATAL_FAILURE( getKindUsage(db, _T("Test:1"), kindUsage6) ); EXPECT_LE( 0, kindUsage6 ); EXPECT_EQ( kindUsage5, kindUsage6 ) << "Switching locale forth and back shouldn't affect kind usage"; MojInt64 quotaUsage6 = -1; EXPECT_NO_FATAL_FAILURE( getQuotaUsage(db, _T("com.foo.bar"), quotaUsage6) ); EXPECT_LE( 0, kindUsage6 ); EXPECT_EQ( quotaUsage5, quotaUsage6 ) << "Switching locale forth and back shouldn't affect quota usage"; // drop index MojAssertNoErr( obj.fromJson(MojTestKind1Str1) ); MojExpectNoErr( db.putKind(obj) ); MojInt64 kindUsage7 = -1; EXPECT_NO_FATAL_FAILURE( getKindUsage(db, _T("Test:1"), kindUsage7) ); EXPECT_LE( 0, kindUsage7 ); EXPECT_EQ( kindUsage4, kindUsage7 ) << "Dropping of index should bring kind usage to expected value"; MojInt64 quotaUsage7 = -1; EXPECT_NO_FATAL_FAILURE( getQuotaUsage(db, _T("com.foo.bar"), quotaUsage7) ); EXPECT_LE( 0, quotaUsage7 ); EXPECT_EQ( quotaUsage4, quotaUsage7 ) << "Dropping of index should bring quota usage to expected value"; // drop kind MojString kindStr; MojAssertNoErr( kindStr.assign(_T("Test:1")) ); MojExpectNoErr( db.delKind(kindStr, found) ); EXPECT_TRUE( found ) << "Kind should be deleted"; MojInt64 kindUsage8 = -1; EXPECT_NO_FATAL_FAILURE( getKindUsage(db, _T("Test:1"), kindUsage8) ); EXPECT_EQ( 0, kindUsage8 ) << "Dropping of kind should bring its usage to zero"; MojInt64 quotaUsage8 = -1; EXPECT_NO_FATAL_FAILURE( getQuotaUsage(db, _T("com.foo.bar"), quotaUsage8) ); EXPECT_EQ( 0, quotaUsage8 ) << "Dropping of kind that matches quota should bring quota usage to zero"; MojExpectNoErr( db.quotaStats(obj) ); MojString statStr; MojExpectNoErr( obj.toJson(statStr) ); std::cerr << "quotaStats: " << statStr.data() << std::endl; }
/** * Callback from the save buddy in buddyStatus DB call. * * Now save in contacts db */ MojErr SendOneCommandHandler::addBuddyResult(MojObject& result, MojErr saveErr) { MojLogTrace(IMServiceApp::s_log); if (saveErr) { MojString error; MojErrToString(saveErr, error); MojLogError(IMServiceApp::s_log, _T("addBuddyResult failed. error %d - %s"), saveErr, error.data()); } else { IMServiceHandler::logMojObjectJsonString(_T("addBuddyResult success: %s"), result); } // now add to contacts DB // create the DB object //{ // accountId:<>, // displayName:<>, // photos:[{localFilepath:<>}], // ims:[{value:<>, type:<>}] // } MojObject contact; contact.putString("_kind", IM_CONTACT_KIND); contact.put("accountId", m_accountId); contact.put("remoteId", m_buddyName); // using username as remote ID since we don't have anything else and this should be unique // "ims" array MojObject newImsArray, newImObj; newImObj.put("value", m_buddyName); newImObj.put("type", m_serviceName); // Note we need this twice since some services look for "serviceName" and some look for "type"... Maybe we can evenutally standardize... newImObj.put("serviceName", m_serviceName); newImsArray.push(newImObj); contact.put("ims", newImsArray); // need to add email address too for contacts linker // email:[{value:<>}] MojString emailAddr; bool validEmail = true; emailAddr.assign(m_buddyName.data()); // for AIM, need to add back the "@aol.com" to the email if (MojInvalidIndex == m_buddyName.find('@')) { if (0 == m_serviceName.compare(SERVICENAME_AIM)) emailAddr.append("@aol.com"); else validEmail = false; } if (validEmail) { MojObject newEmailArray, newEmailObj; newEmailObj.put("value", emailAddr); newEmailArray.push(newEmailObj); contact.put("emails", newEmailArray); } // log it MojString json; contact.toJson(json); MojLogInfo(IMServiceApp::s_log, _T("saving contact to db: %s"), json.data()); // save it // the save generates a call to the save result handler MojErr err = m_dbClient.put(this->m_addContactSlot, contact); if (err) { MojString error; MojErrToString(err, error); MojLogError(IMServiceApp::s_log, _T("addBuddyResult: dbClient.put() failed: error %d - %s"), err, error.data()); // tell the outgoing Command handler we are done m_outgoingIMHandler->messageFinished(); } return MojErrNone; }