Beispiel #1
0
void MojoDatabase::UpdateAccountFolders(Signal::SlotRef slot, const MojObject& accountId, const MojObject& inboxFolderId,
																						  const MojObject& draftsFolderId,
																						  const MojObject& sentFolderId,
																						  const MojObject& outboxFolderId,
																						  const MojObject& trashFolderId)
{
	MojDbQuery q;
	MojErr err = q.from(PopAccountAdapter::POP_ACCOUNT_KIND);
	ErrorToException(err);

	err = q.where(PopAccountAdapter::ACCOUNT_ID, MojDbQuery::OpEq, accountId);
	ErrorToException(err);

	MojObject props;

	if (!inboxFolderId.undefined()) {
		err = props.put(EmailAccountAdapter::INBOX_FOLDERID, inboxFolderId);
		ErrorToException(err);
	}

	if (!draftsFolderId.undefined()) {
		err = props.put(EmailAccountAdapter::DRAFTS_FOLDERID, draftsFolderId);
		ErrorToException(err);
	}

	if (!sentFolderId.undefined()) {
		err = props.put(EmailAccountAdapter::SENT_FOLDERID, sentFolderId);
		ErrorToException(err);
	}

	if (!outboxFolderId.undefined()) {
		err = props.put(EmailAccountAdapter::OUTBOX_FOLDERID, outboxFolderId);
		ErrorToException(err);
	}

	if (!trashFolderId.undefined()) {
		err = props.put(EmailAccountAdapter::TRASH_FOLDERID, trashFolderId);
		ErrorToException(err);
	}

	err = m_dbClient.merge(slot, q, props);
	ErrorToException(err);
}
Beispiel #2
0
void PopClient::SetAccount(MojObject& accountId)
{
	MojLogTrace(s_log);

	assert(m_state == State_None);
	assert(!accountId.null());
	assert(!accountId.undefined());

	m_accountId = accountId;
	m_builderFactory->SetAccountId(m_accountId);
}
Beispiel #3
0
MojErr MojDb::get(const MojObject& id, MojObject& objOut, bool& foundOut, MojDbReqRef req)
{
	MojLogTrace(s_log);

	objOut.clear();
	foundOut = false;
	MojObjectBuilder builder;

	MojErr err = get(&id, &id + 1, builder, req);
	MojErrCheck(err);

	objOut = builder.object();
	foundOut = !objOut.undefined();

	return MojErrNone;
}
Beispiel #4
0
void MojoDatabase::UpdateEmailParts(Signal::SlotRef slot, const MojObject& emailId, const MojObject& parts, bool autoDownload)
{
	MojObject email;
	MojErr err = email.put(PopEmailAdapter::ID, emailId);
	ErrorToException(err);

	err = email.put(EmailSchema::PARTS, parts);
	ErrorToException(err);

	if ((!parts.undefined() && !parts.null() && parts.size() > 0) || !autoDownload) {
		err = email.put(PopEmailAdapter::DOWNLOADED, true);
		ErrorToException(err);
	}

	MojLogDebug(PopClient::s_log, "Updating email '%s' with parts: '%s'", AsJsonString(emailId).c_str(), AsJsonString(parts).c_str());
	err = m_dbClient.merge(slot, email);
	ErrorToException(err);
}
Beispiel #5
0
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 PopBusDispatcher::DownloadAttachment(MojServiceMessage* msg, MojObject& payload)
{
	// cancel shut down if it is in shut down state
	CancelShutdown();

	MojLogTrace(s_log);

	MojLogInfo(s_log, "Downloading parts from client");
	try {
		MojObject accountId;
		MojErr err = payload.getRequired("accountId", accountId);
		ErrorToException(err);

		ClientPtr client = GetOrCreateClient(accountId, false);

		MojObject folderId;
		err = payload.getRequired("folderId", folderId);
		ErrorToException(err);

		if(folderId.undefined() || folderId.null())
			MojErrThrowMsg(MojErrInternal, "Invalid folder ID");

		MojObject emailId;
		err = payload.getRequired("emailId", emailId);
		ErrorToException(err);

		MojObject partId;
		err = payload.getRequired("partId", partId);
		ErrorToException(err);

		boost::shared_ptr<DownloadListener> listener(new DownloadListener(msg, emailId, partId));
		client->DownloadPart(folderId, emailId, partId, listener);

		return MojErrNone;
	} catch (const std::exception& e) {
		MojErrThrowMsg(MojErrInternal, "exception: %s", e.what());
	}
	return MojErrNone;
}
Beispiel #7
0
void EmailAdapter::ParseDatabaseObject(const MojObject& obj, Email& email)
{
	MojErr err;
	
	MojObject folderId;
	err = obj.getRequired(FOLDER_ID, folderId);
	ErrorToException(err);
	email.SetFolderId(folderId);
	
	MojString subject;
	err = obj.getRequired(SUBJECT, subject);
	ErrorToException(err);
	email.SetSubject( std::string(subject) );
	
	MojObject fromAddress;
	err = obj.getRequired(FROM, fromAddress);
	ErrorToException(err);
	email.SetFrom( ParseAddress(fromAddress) );
	
	// Optional replyTo address
	MojObject replyTo;
	if(obj.get(REPLY_TO, replyTo) && !replyTo.null()) {
		email.SetReplyTo( ParseAddress(replyTo) );
	}

	MojInt64 timestamp;
	err = obj.getRequired(TIMESTAMP, timestamp);
	ErrorToException(err);
	email.SetDateReceived(timestamp);
	
	// Parse recipients
	MojObject recipients;
	err = obj.getRequired(RECIPIENTS, recipients);
	ErrorToException(err);
	ParseRecipients(recipients, email);
	
	// Parse flags
	MojObject flags;
	if (obj.get(FLAGS, flags)) {
		ParseFlags(flags, email);
	}

	// Parse parts
	MojObject parts;
	err = obj.getRequired(PARTS, parts);
	ErrorToException(err);

	EmailPartList partList;
	ParseParts(parts, partList);
	email.SetPartList(partList);

	MojObject originalMsgId;
	if (obj.get(ORIGINAL_MSG_ID, originalMsgId)) {
		email.SetOriginalMsgId(originalMsgId);
	}

	MojString draftType;
	bool hasDraftType = false;
	err = obj.get(DRAFT_TYPE, draftType, hasDraftType);
	ErrorToException(err);
	if (hasDraftType) {
		email.SetDraftType( ParseDraftType(draftType) );
	}

	MojString priority;
	bool hasPriority = false;
	err = obj.get(PRIORITY, priority, hasPriority);
	ErrorToException(err);
	// If no priority exists, this will default to normal
	email.SetPriority(ParsePriority(priority));

	email.SetMessageId( DatabaseAdapter::GetOptionalString(obj, MESSAGE_ID) );
	email.SetInReplyTo( DatabaseAdapter::GetOptionalString(obj, IN_REPLY_TO) );

	// SendStatus
	// NOTE: This is not being serialized back to the database in SerializeToDatabaseObject
	MojObject sendStatus;
	if (obj.get(SEND_STATUS, sendStatus)) {
		bool isSent = false;
		if (sendStatus.get(SendStatus::SENT, isSent)) {
			email.SetSent(isSent);
		}
		bool hasFatalError = false;
		if (sendStatus.get(SendStatus::FATAL_ERROR, hasFatalError)) {
			email.SetHasFatalError(hasFatalError);
		}
		MojInt64 retryCount;
		if (sendStatus.get(SendStatus::RETRY_COUNT, retryCount)) {
			email.SetRetryCount(retryCount);
		}
		MojObject sendError;
		if (sendStatus.get(SendStatus::ERROR, sendError)) {
			MojObject errorCode;
			if (sendError.get(SendStatusError::ERROR_CODE, errorCode) && !errorCode.null() && !errorCode.undefined()) {
				email.SetSendError(static_cast<MailError::ErrorCode>(errorCode.intValue()));
			}
		}
	}
}
Beispiel #8
0
MojErr MojDb::putObj(const MojObject& id, MojObject& obj, const MojObject* oldObj,
					 MojDbStorageItem* oldItem, MojDbReq& req, MojDbOp op, bool checkSchema)
{
	MojLogTrace(s_log);

	// if nothing changed, don't do the update
	if (oldObj != NULL && obj == *oldObj)
		return MojErrNone;

	// update revision
	MojInt64 rev;
	MojErr err = nextId(rev);
	MojErrCheck(err);
	err = obj.put(RevKey, rev);
	MojErrCheck(err);

	// assign id
	MojObject putId = id;
	if (putId.undefined()) {
		err = m_idGenerator.id(putId);
		MojErrCheck(err);
		err = obj.put(IdKey, putId);
		MojErrCheck(err);
	}

	// assign ids to subobjects in arrays - only for regular objects
	MojString kindName;
	bool found = false;
	err = obj.get(MojDb::KindKey, kindName, found);
	MojErrCheck(err);
	if (!found)
		MojErrThrow(MojErrDbKindNotSpecified);
	if (!kindName.startsWith(MojDbKindEngine::KindKindIdPrefix)) {
		err = assignIds(obj);
		MojErrCheck(err);
	}

	// validate, update indexes, etc.
	MojTokenSet tokenSet;
	err = m_kindEngine.update(&obj, oldObj, req, op, tokenSet, checkSchema);
	MojErrCheck(err);

	// serialize object
	MojDbObjectHeader header(putId);
	err = header.extractFrom(obj);
	MojErrCheck(err);
	MojBuffer buf;
	err = header.write(buf, m_kindEngine);
	MojErrCheck(err);
	MojObjectWriter writer(buf, &tokenSet);
	err = obj.visit(writer);
	MojErrCheck(err);

	// store it in the db
	if (oldItem) {
		err = m_objDb->update(putId, buf, oldItem, req.txn());
		MojErrCheck(err);
	} else {
		err = m_objDb->insert(putId, buf, req.txn());
		MojErrCheck(err);
	}

	// put header back in the object for response purposes
	err = header.addTo(obj);
	MojErrCheck(err);

	return MojErrNone;
}
Beispiel #9
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;
}