Message::ptr_t MessageManager::receivedMessage(Conversation &conversation, MessageData data) { auto message = make_shared<Message>(*this, data, Message::INCOMING, conversation.getId()); assert(conversation.getIdentity()); assert(conversation.getFirstParticipant()); auto cert = conversation.getFirstParticipant()->getCert(); if (!message->validate(*cert)) { LFLOG_WARN << "Incoming message from " << conversation.getFirstParticipant()->getName() << " to " << conversation.getIdentity()->getName() << " failed validation. Rejecting."; return {}; } // See if we already have received this message if (auto existing = getMessage(data.messageId, conversation.getId())) { return existing; } message->addToDb(); registry_.add(message->getId(), message); touch(message); emit messageAdded(message); return message; }
Message::ptr_t MessageManager::sendMessage(Conversation &conversation, MessageData data) { auto message = make_shared<Message>(*this, data, Message::OUTGOING, conversation.getId()); assert(conversation.getIdentity()); auto cert = conversation.getIdentity()->getCert(); message->sign(*cert); message->addToDb(); registry_.add(message->getId(), message); touch(message); emit messageAdded(message); if (auto contact = conversation.getFirstParticipant()) { contact->queueMessage(message); } return message; }
void ConversationManager::handleDatabaseJobComplete(void* ref, DatabaseResult* result) { CVAsyncContainer* asyncContainer = reinterpret_cast<CVAsyncContainer*>(ref); switch(asyncContainer->mQuery) { case ConvQuery_Conversations: { Conversation* conv; CVAsyncContainer* asCont; uint32 insertId; DataBinding* binding = mDatabase->CreateDataBinding(1); binding->addField(DFT_uint32,offsetof(Conversation,mId),4,0); uint64 count = result->getRowCount(); for(uint32 i = 0; i < count; i++) { conv = new Conversation(); result->GetNextRow(binding,conv); insertId = conv->getId(); mConversations.insert(insertId,conv); asCont = new(mDBAsyncPool.malloc()) CVAsyncContainer(ConvQuery_Pages); asCont->mConversation = conv; mDatabase->ExecuteSqlAsync(this,asCont,"SELECT * FROM conversation_pages WHERE conversation_id=%u ORDER BY page",insertId); } if(result->getRowCount()) gLogger->logMsgLoadSuccess("ConversationManager::loading %u Conversations...",MSG_NORMAL,result->getRowCount()); else gLogger->logMsgLoadFailure("ConversationManager::loading Conversations...",MSG_NORMAL); mDatabase->DestroyDataBinding(binding); } break; case ConvQuery_Pages: { ConversationPage* page; CVAsyncContainer* asCont; uint32 batchId; DataBinding* pageBinding = mDatabase->CreateDataBinding(5); pageBinding->addField(DFT_uint32,offsetof(ConversationPage,mId),4,1); pageBinding->addField(DFT_bstring,offsetof(ConversationPage,mCustomText),512,2); pageBinding->addField(DFT_bstring,offsetof(ConversationPage,mStfFile),255,3); pageBinding->addField(DFT_bstring,offsetof(ConversationPage,mStfVariable),255,4); pageBinding->addField(DFT_uint32,offsetof(ConversationPage,mAnimation),4,6); DataBinding* batchBinding = mDatabase->CreateDataBinding(1); batchBinding->addField(DFT_uint32,0,4,5); uint32 count = static_cast<uint32>(result->getRowCount()); for(uint64 i = 0; i< count; i++) { page = new ConversationPage(); result->GetNextRow(pageBinding,page); page->mCustomText.convert(BSTRType_Unicode16); result->ResetRowIndex(static_cast<int>(i)); result->GetNextRow(batchBinding,&batchId); asyncContainer->mConversation->mPages.push_back(page); // query options asCont = new(mDBAsyncPool.malloc()) CVAsyncContainer(ConvQuery_Page_OptionBatch); asCont->mConversationPage = page; mDatabase->ExecuteSqlAsync(this,asCont,"SELECT conversation_options.id,conversation_options.customText,conversation_options.stf_file," "conversation_options.stf_variable,conversation_options.event,conversation_options.pageLink " "FROM " "conversation_option_batches " "INNER JOIN conversation_options ON (conversation_option_batches.option_id = conversation_options.id) " "WHERE " "(conversation_option_batches.id = %u) ORDER BY conversation_option_batches.option_id",batchId); } mDatabase->DestroyDataBinding(pageBinding); mDatabase->DestroyDataBinding(batchBinding); } break; case ConvQuery_Page_OptionBatch: { ConversationOption* option; DataBinding* binding = mDatabase->CreateDataBinding(6); binding->addField(DFT_uint32,offsetof(ConversationOption,mId),4,0); binding->addField(DFT_bstring,offsetof(ConversationOption,mCustomText),512,1); binding->addField(DFT_bstring,offsetof(ConversationOption,mStfFile),255,2); binding->addField(DFT_bstring,offsetof(ConversationOption,mStfVariable),255,3); binding->addField(DFT_uint32,offsetof(ConversationOption,mEvent),4,4); binding->addField(DFT_uint32,offsetof(ConversationOption,mPageLinkId),4,5); uint64 count = result->getRowCount(); for(uint32 i = 0; i < count; i++) { option = new ConversationOption(); result->GetNextRow(binding,option); option->mCustomText.convert(BSTRType_Unicode16); asyncContainer->mConversationPage->mOptions.push_back(option); } mDatabase->DestroyDataBinding(binding); } break; default: break; } mDBAsyncPool.free(asyncContainer); }