diff --git a/src/content/content-type.cpp b/src/content/content-type.cpp index 00805bfc6..4aeac8869 100644 --- a/src/content/content-type.cpp +++ b/src/content/content-type.cpp @@ -154,16 +154,8 @@ bool ContentType::isValid () const { return !d->type.empty() && !d->subType.empty(); } -bool ContentType::isFile() const { - //TODO Improve - if (*this != ContentType::FileTransfer && *this != ContentType::PlainText && - *this != ContentType::ExternalBody && *this != ContentType::Imdn && - *this != ContentType::ImIsComposing && *this != ContentType::ResourceLists && - *this != ContentType::Sdp && *this != ContentType::Cpim && - *this != ContentType::ConferenceInfo) { - return true; - } - return false; +bool ContentType::isFile () const { + return isFile(*this); } string ContentType::asString () const { @@ -178,4 +170,17 @@ string ContentType::asString () const { return ""; } +bool ContentType::isFile (const ContentType &contentType) { + // TODO Improve. + return contentType != FileTransfer && + contentType != PlainText && + contentType != ExternalBody && + contentType != Imdn && + contentType != ImIsComposing && + contentType != ResourceLists && + contentType != Sdp && + contentType != Cpim && + contentType != ConferenceInfo; +} + LINPHONE_END_NAMESPACE diff --git a/src/content/content-type.h b/src/content/content-type.h index fe5147645..a66955a94 100644 --- a/src/content/content-type.h +++ b/src/content/content-type.h @@ -59,6 +59,8 @@ public: std::string asString () const; + static bool isFile (const ContentType &contentType); + static const ContentType Cpim; static const ContentType ExternalBody; static const ContentType FileTransfer; diff --git a/src/content/content.cpp b/src/content/content.cpp index dd646d198..e94c0ecee 100644 --- a/src/content/content.cpp +++ b/src/content/content.cpp @@ -121,7 +121,7 @@ void Content::setBody (const vector &body) { d->body = body; } -void Content::setBody (std::vector &&body) { +void Content::setBody (vector &&body) { L_D(); d->body = move(body); } diff --git a/src/content/content.h b/src/content/content.h index 0047f6a46..4635898bf 100644 --- a/src/content/content.h +++ b/src/content/content.h @@ -22,9 +22,11 @@ #include +// TODO: Remove me. +#include "linphone/content.h" + #include "object/app-data-container.h" #include "object/clonable-object.h" -#include "linphone/content.h" // ============================================================================= diff --git a/src/db/main-db.cpp b/src/db/main-db.cpp index 89b2a475d..2fe78c568 100644 --- a/src/db/main-db.cpp +++ b/src/db/main-db.cpp @@ -289,37 +289,78 @@ MainDb::MainDb (const shared_ptr &core) : AbstractDb(*new MainDbPrivate), if (!chatRoom) return nullptr; - string localSipAddress; - string remoteSipAddress; - string imdnMessageId; - int state; - int direction; - int isSecured; - - soci::session *session = dbSession.getBackendSession(); - *session << "SELECT local_sip_address.value, remote_sip_address.value, imdn_message_id, state, direction, is_secured" - " FROM event, conference_chat_message_event, sip_address AS local_sip_address," - " sip_address AS remote_sip_address" - " WHERE event_id = :eventId" - " AND event_id = event.id" - " AND local_sip_address_id = local_sip_address.id" - " AND remote_sip_address_id = remote_sip_address.id", soci::into(localSipAddress), soci::into(remoteSipAddress), - soci::into(imdnMessageId), soci::into(state), soci::into(direction), soci::into(isSecured), soci::use(eventId); - - // TODO: Create me. // TODO: Use cache, do not fetch the same message twice. + + // 1 - Fetch chat message. shared_ptr chatMessage = make_shared(chatRoom); + { + string localSipAddress; + string remoteSipAddress; + string imdnMessageId; + int state; + int direction; + int isSecured; - chatMessage->getPrivate()->setState(static_cast(state), true); - chatMessage->getPrivate()->setDirection(static_cast(direction)); - chatMessage->setIsSecured(static_cast(isSecured)); + soci::session *session = dbSession.getBackendSession(); + *session << "SELECT local_sip_address.value, remote_sip_address.value, imdn_message_id, state, direction, is_secured" + " FROM event, conference_chat_message_event, sip_address AS local_sip_address," + " sip_address AS remote_sip_address" + " WHERE event_id = :eventId" + " AND event_id = event.id" + " AND local_sip_address_id = local_sip_address.id" + " AND remote_sip_address_id = remote_sip_address.id", soci::into(localSipAddress), soci::into(remoteSipAddress), + soci::into(imdnMessageId), soci::into(state), soci::into(direction), soci::into(isSecured), soci::use(eventId); - if (direction == static_cast(ChatMessage::Direction::Outgoing)) { - chatMessage->setFromAddress(Address(localSipAddress)); - chatMessage->setToAddress(Address(remoteSipAddress)); - } else { - chatMessage->setFromAddress(Address(remoteSipAddress)); - chatMessage->setToAddress(Address(localSipAddress)); + chatMessage->getPrivate()->setState(static_cast(state), true); + chatMessage->getPrivate()->setDirection(static_cast(direction)); + chatMessage->setIsSecured(static_cast(isSecured)); + + if (direction == static_cast(ChatMessage::Direction::Outgoing)) { + chatMessage->setFromAddress(Address(localSipAddress)); + chatMessage->setToAddress(Address(remoteSipAddress)); + } else { + chatMessage->setFromAddress(Address(remoteSipAddress)); + chatMessage->setToAddress(Address(localSipAddress)); + } + } + + // 2 - Fetch contents. + { + soci::session *session = dbSession.getBackendSession(); + const string query = "SELECT content_type.value, body FROM chat_message_content, content_type" + " WHERE event_id = :eventId AND content_type_id = content_type.id"; + soci::rowset rows = (session->prepare << query, soci::use(eventId)); + for (const auto &row : rows) { + ContentType contentType(row.get(1)); + Content *content; + + if (contentType == ContentType::FileTransfer) + content = new FileTransferContent(); + else if (contentType.isFile()) { + long long contentId = q->getBackend() == AbstractDb::Sqlite3 + ? static_cast(row.get(0)) + : row.get(0); + + string name; + int size; + string path; + + *session << "SELECT name, size, path FROM chat_message_file_content" + " WHERE chat_message_content_id = :contentId", soci::use(contentId); + + FileContent *fileContent = new FileContent(); + fileContent->setFileName(name); + fileContent->setFileSize(static_cast(size)); + fileContent->setFilePath(path); + + content = fileContent; + } else + Content *content = new Content(); + + content->setContentType(contentType); + content->setBody(row.get(2)); + chatMessage.addContent(content); + } } // TODO: Use cache.