diff options
author | Catalin Badea <catalin.badea392@gmail.com> | 2012-07-20 12:22:40 (GMT) |
---|---|---|
committer | Catalin Badea <catalin.badea392@gmail.com> | 2012-07-20 12:22:40 (GMT) |
commit | 9ccedec3844df80241c65dc6fb24d97efc2f41fc (patch) | |
tree | b7dd0ffacb6817a383c8d86e42eb0917dd5bd240 /Swiften | |
parent | 32672b49d8ec454a3ffc94031bb973c6cfa7f862 (diff) | |
download | swift-contrib-9ccedec3844df80241c65dc6fb24d97efc2f41fc.zip swift-contrib-9ccedec3844df80241c65dc6fb24d97efc2f41fc.tar.bz2 |
continous scroll between dates.
Diffstat (limited to 'Swiften')
-rw-r--r-- | Swiften/Base/foreach.h | 1 | ||||
-rw-r--r-- | Swiften/History/HistoryManager.h | 4 | ||||
-rw-r--r-- | Swiften/History/SQLiteHistoryManager.cpp | 72 | ||||
-rw-r--r-- | Swiften/History/SQLiteHistoryManager.h | 5 |
4 files changed, 78 insertions, 4 deletions
diff --git a/Swiften/Base/foreach.h b/Swiften/Base/foreach.h index 87f6147..3ad506d 100644 --- a/Swiften/Base/foreach.h +++ b/Swiften/Base/foreach.h @@ -10,3 +10,4 @@ #undef foreach #define foreach BOOST_FOREACH +#define reverse_foreach BOOST_REVERSE_FOREACH diff --git a/Swiften/History/HistoryManager.h b/Swiften/History/HistoryManager.h index 908d35c..6b32206 100644 --- a/Swiften/History/HistoryManager.h +++ b/Swiften/History/HistoryManager.h @@ -22,7 +22,9 @@ namespace Swift { virtual void addMessage(const HistoryMessage& message) = 0; - virtual std::vector<HistoryMessage> getMessages(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const = 0; + virtual std::vector<HistoryMessage> getMessagesFromDate(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const = 0; + virtual std::vector<HistoryMessage> getMessagesFromNextDate(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const = 0; + virtual std::vector<HistoryMessage> getMessagesFromPreviousDate(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const = 0; virtual ContactsMap getContacts(const JID& selfJID, HistoryMessage::Type type, const std::string& keyword) const = 0; }; } diff --git a/Swiften/History/SQLiteHistoryManager.cpp b/Swiften/History/SQLiteHistoryManager.cpp index 7cddf43..57fce2f 100644 --- a/Swiften/History/SQLiteHistoryManager.cpp +++ b/Swiften/History/SQLiteHistoryManager.cpp @@ -9,7 +9,7 @@ #include <sqlite3.h> #include <Swiften/History/SQLiteHistoryManager.h> -#include <boost/date_time/gregorian/gregorian_types.hpp> +#include <boost/date_time/gregorian/gregorian.hpp> inline std::string getEscapedString(const std::string& s) { std::string result(s); @@ -67,7 +67,7 @@ void SQLiteHistoryManager::addMessage(const HistoryMessage& message) { } } -std::vector<HistoryMessage> SQLiteHistoryManager::getMessages(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const { +std::vector<HistoryMessage> SQLiteHistoryManager::getMessagesFromDate(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const { sqlite3_stmt* selectStatement; boost::optional<int> selfID = getIDFromJID(selfJID.toBare()); @@ -267,4 +267,72 @@ ContactsMap SQLiteHistoryManager::getContacts(const JID& selfJID, HistoryMessage return result; } +boost::gregorian::date SQLiteHistoryManager::getNextDateWithLogs(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date, bool reverseOrder) const { + sqlite3_stmt* selectStatement; + boost::optional<int> selfID = getIDFromJID(selfJID.toBare()); + boost::optional<int> contactID = getIDFromJID(contactJID.toBare()); + + if (!selfID || !contactID) { + // JIDs missing from the database + return boost::gregorian::date(boost::gregorian::not_a_date_time); + } + + std::string selectQuery = "SELECT time FROM messages WHERE (type=" + boost::lexical_cast<std::string>(type); + if (contactJID.isBare()) { + // match only bare jid + selectQuery += " AND ((fromBare=" + boost::lexical_cast<std::string>(*selfID) + " AND toBare=" + + boost::lexical_cast<std::string>(*contactID) + ") OR (fromBare=" + + boost::lexical_cast<std::string>(*contactID) + " AND toBare=" + boost::lexical_cast<std::string>(*selfID) + ")))"; + } + else { + // match resource too + selectQuery += " AND ((fromBare=" + boost::lexical_cast<std::string>(*selfID) + " AND (toBare=" + + boost::lexical_cast<std::string>(*contactID) +" AND toResource='" + + getEscapedString(contactJID.getResource()) + "')) OR ((fromBare=" + + boost::lexical_cast<std::string>(*contactID) + " AND fromResource='" + + getEscapedString(contactJID.getResource()) + "') AND toBare=" + + boost::lexical_cast<std::string>(*selfID) + ")))"; + } + + int timeStamp = (boost::posix_time::ptime(date) - boost::posix_time::ptime(boost::gregorian::date(1970, 1, 1))).total_seconds() + (reverseOrder ? 0 : 86400); + + selectQuery += " AND time" + (reverseOrder ? std::string("<") : std::string(">")) + boost::lexical_cast<std::string>(timeStamp); + selectQuery += " ORDER BY time " + (reverseOrder ? std::string("DESC") : std::string("ASC")) + " LIMIT 1"; + + int r = sqlite3_prepare(db_, selectQuery.c_str(), selectQuery.size(), &selectStatement, NULL); + if (r != SQLITE_OK) { + std::cout << "Error: " << sqlite3_errmsg(db_) << std::endl; + } + + r = sqlite3_step(selectStatement); + if (r == SQLITE_ROW) { + int secondsSinceEpoch(sqlite3_column_int(selectStatement, 0)); + boost::posix_time::ptime time(boost::gregorian::date(1970, 1, 1), boost::posix_time::seconds(secondsSinceEpoch)); + std::cout << "next day is: " << time.date() << "\n"; + return time.date(); + } + + return boost::gregorian::date(boost::gregorian::not_a_date_time); +} + +std::vector<HistoryMessage> SQLiteHistoryManager::getMessagesFromNextDate(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const { + boost::gregorian::date nextDate = getNextDateWithLogs(selfJID, contactJID, type, date, false); + + if (nextDate.is_not_a_date()) { + return std::vector<HistoryMessage>(); + } + + return getMessagesFromDate(selfJID, contactJID, type, nextDate); +} + +std::vector<HistoryMessage> SQLiteHistoryManager::getMessagesFromPreviousDate(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const { + boost::gregorian::date previousDate = getNextDateWithLogs(selfJID, contactJID, type, date, true); + + if (previousDate.is_not_a_date()) { + return std::vector<HistoryMessage>(); + } + + return getMessagesFromDate(selfJID, contactJID, type, previousDate); +} + } diff --git a/Swiften/History/SQLiteHistoryManager.h b/Swiften/History/SQLiteHistoryManager.h index 638d73f..8b08e6b 100644 --- a/Swiften/History/SQLiteHistoryManager.h +++ b/Swiften/History/SQLiteHistoryManager.h @@ -20,9 +20,12 @@ namespace Swift { void addMessage(const HistoryMessage& message); ContactsMap getContacts(const JID& selfJID, HistoryMessage::Type type, const std::string& keyword) const; - std::vector<HistoryMessage> getMessages(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const; + std::vector<HistoryMessage> getMessagesFromDate(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const; + std::vector<HistoryMessage> getMessagesFromNextDate(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const; + std::vector<HistoryMessage> getMessagesFromPreviousDate(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const; private: + boost::gregorian::date getNextDateWithLogs(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date, bool reverseOrder) const; int getIDForJID(const JID&); int addJID(const JID&); |