diff options
author | Tobias Markmann <tm@ayena.de> | 2016-03-31 14:57:35 (GMT) |
---|---|---|
committer | Tobias Markmann <tm@ayena.de> | 2016-03-31 14:57:35 (GMT) |
commit | cfbdb43d2cadd40aa87338d41548e4bf89e146e6 (patch) | |
tree | 18d94153a302445196fc0c18586abf44a1ce4a38 /Swiften/History | |
parent | 1d545a4a7fb877f021508094b88c1f17b30d8b4e (diff) | |
download | swift-cfbdb43d2cadd40aa87338d41548e4bf89e146e6.zip swift-cfbdb43d2cadd40aa87338d41548e4bf89e146e6.tar.bz2 |
Convert tabs to 4 spaces for all source files
Removed trailing spaces and whitespace on empty lines
in the process.
Changed CheckTabs.py tool to disallow hard tabs in source
files.
Test-Information:
Manually checked 30 random files that the conversion worked
as expected.
Change-Id: I874f99d617bd3d2bb55f02d58f22f58f9b094480
Diffstat (limited to 'Swiften/History')
-rw-r--r-- | Swiften/History/HistoryMessage.h | 100 | ||||
-rw-r--r-- | Swiften/History/HistoryStorage.h | 28 | ||||
-rw-r--r-- | Swiften/History/SQLiteHistoryStorage.cpp | 616 | ||||
-rw-r--r-- | Swiften/History/SQLiteHistoryStorage.h | 48 | ||||
-rw-r--r-- | Swiften/History/UnitTest/SQLiteHistoryManagerTest.cpp | 194 |
5 files changed, 493 insertions, 493 deletions
diff --git a/Swiften/History/HistoryMessage.h b/Swiften/History/HistoryMessage.h index e07ef60..e910899 100644 --- a/Swiften/History/HistoryMessage.h +++ b/Swiften/History/HistoryMessage.h @@ -12,63 +12,63 @@ #include <Swiften/JID/JID.h> namespace Swift { - class SWIFTEN_API HistoryMessage { - public: - enum Type { - Chat = 0, - Groupchat = 1, - PrivateMessage = 2 - }; + class SWIFTEN_API HistoryMessage { + public: + enum Type { + Chat = 0, + Groupchat = 1, + PrivateMessage = 2 + }; - HistoryMessage( - const std::string& message, - const JID& fromJID, - const JID& toJID, - Type type, - const boost::posix_time::ptime& time, - int utcOffset = 0) : - message_(message), - fromJID_(fromJID), - toJID_(toJID), - type_(type), - time_(time), - utcOffset_(utcOffset) { - } + HistoryMessage( + const std::string& message, + const JID& fromJID, + const JID& toJID, + Type type, + const boost::posix_time::ptime& time, + int utcOffset = 0) : + message_(message), + fromJID_(fromJID), + toJID_(toJID), + type_(type), + time_(time), + utcOffset_(utcOffset) { + } - const std::string& getMessage() const { - return message_; - } + const std::string& getMessage() const { + return message_; + } - const JID& getFromJID() const { - return fromJID_; - } + const JID& getFromJID() const { + return fromJID_; + } - const JID& getToJID() const { - return toJID_; - } + const JID& getToJID() const { + return toJID_; + } - Type getType() const { - return type_; - } + Type getType() const { + return type_; + } - boost::posix_time::ptime getTime() const { - return time_; - } + boost::posix_time::ptime getTime() const { + return time_; + } - int getOffset() const { - return utcOffset_; - } + int getOffset() const { + return utcOffset_; + } - bool operator==(const HistoryMessage& o) const { - return message_ == o.message_ && fromJID_ == o.fromJID_ && toJID_ == o.toJID_ && type_ == o.type_ && time_ == o.time_; - } + bool operator==(const HistoryMessage& o) const { + return message_ == o.message_ && fromJID_ == o.fromJID_ && toJID_ == o.toJID_ && type_ == o.type_ && time_ == o.time_; + } - private: - std::string message_; - JID fromJID_; - JID toJID_; - Type type_; - boost::posix_time::ptime time_; - int utcOffset_; - }; + private: + std::string message_; + JID fromJID_; + JID toJID_; + Type type_; + boost::posix_time::ptime time_; + int utcOffset_; + }; } diff --git a/Swiften/History/HistoryStorage.h b/Swiften/History/HistoryStorage.h index ee8f15b..10b6bb0 100644 --- a/Swiften/History/HistoryStorage.h +++ b/Swiften/History/HistoryStorage.h @@ -17,20 +17,20 @@ #include <Swiften/JID/JID.h> namespace Swift { - typedef std::map<JID, std::set<boost::gregorian::date> > ContactsMap; + typedef std::map<JID, std::set<boost::gregorian::date> > ContactsMap; - class SWIFTEN_API HistoryStorage { - /** - * Messages are stored using localtime timestamps. - */ - public: - virtual ~HistoryStorage() {} + class SWIFTEN_API HistoryStorage { + /** + * Messages are stored using localtime timestamps. + */ + public: + virtual ~HistoryStorage() {} - virtual void addMessage(const HistoryMessage& message) = 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; - virtual boost::posix_time::ptime getLastTimeStampFromMUC(const JID& selfJID, const JID& mucJID) const = 0; - }; + virtual void addMessage(const HistoryMessage& message) = 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; + virtual boost::posix_time::ptime getLastTimeStampFromMUC(const JID& selfJID, const JID& mucJID) const = 0; + }; } diff --git a/Swiften/History/SQLiteHistoryStorage.cpp b/Swiften/History/SQLiteHistoryStorage.cpp index 8306803..beb7ba1 100644 --- a/Swiften/History/SQLiteHistoryStorage.cpp +++ b/Swiften/History/SQLiteHistoryStorage.cpp @@ -17,366 +17,366 @@ #include <Swiften/Base/Path.h> inline std::string getEscapedString(const std::string& s) { - std::string result(s); - - size_t pos = result.find('\''); - while (pos != std::string::npos) { - result.insert(pos, "'"); - pos = result.find('\'', pos + 2); - } - return result; + std::string result(s); + + size_t pos = result.find('\''); + while (pos != std::string::npos) { + result.insert(pos, "'"); + pos = result.find('\'', pos + 2); + } + return result; } namespace Swift { SQLiteHistoryStorage::SQLiteHistoryStorage(const boost::filesystem::path& file) : db_(0) { - thread_ = new boost::thread(boost::bind(&SQLiteHistoryStorage::run, this)); - - sqlite3_open(pathToString(file).c_str(), &db_); - if (!db_) { - std::cerr << "Error opening database " << pathToString(file) << std::endl; - } - - char* errorMessage; - int result = sqlite3_exec(db_, "CREATE TABLE IF NOT EXISTS messages('message' STRING, 'fromBare' INTEGER, 'fromResource' STRING, 'toBare' INTEGER, 'toResource' STRING, 'type' INTEGER, 'time' INTEGER, 'offset' INTEGER)", 0, 0, &errorMessage); - if (result != SQLITE_OK) { - std::cerr << "SQL Error: " << errorMessage << std::endl; - sqlite3_free(errorMessage); - } - - result = sqlite3_exec(db_, "CREATE TABLE IF NOT EXISTS jids('id' INTEGER PRIMARY KEY ASC AUTOINCREMENT, 'jid' STRING UNIQUE NOT NULL)", 0, 0, &errorMessage); - if (result != SQLITE_OK) { - std::cerr << "SQL Error: " << errorMessage << std::endl; - sqlite3_free(errorMessage); - } + thread_ = new boost::thread(boost::bind(&SQLiteHistoryStorage::run, this)); + + sqlite3_open(pathToString(file).c_str(), &db_); + if (!db_) { + std::cerr << "Error opening database " << pathToString(file) << std::endl; + } + + char* errorMessage; + int result = sqlite3_exec(db_, "CREATE TABLE IF NOT EXISTS messages('message' STRING, 'fromBare' INTEGER, 'fromResource' STRING, 'toBare' INTEGER, 'toResource' STRING, 'type' INTEGER, 'time' INTEGER, 'offset' INTEGER)", 0, 0, &errorMessage); + if (result != SQLITE_OK) { + std::cerr << "SQL Error: " << errorMessage << std::endl; + sqlite3_free(errorMessage); + } + + result = sqlite3_exec(db_, "CREATE TABLE IF NOT EXISTS jids('id' INTEGER PRIMARY KEY ASC AUTOINCREMENT, 'jid' STRING UNIQUE NOT NULL)", 0, 0, &errorMessage); + if (result != SQLITE_OK) { + std::cerr << "SQL Error: " << errorMessage << std::endl; + sqlite3_free(errorMessage); + } } SQLiteHistoryStorage::~SQLiteHistoryStorage() { - sqlite3_close(db_); - delete thread_; + sqlite3_close(db_); + delete thread_; } void SQLiteHistoryStorage::addMessage(const HistoryMessage& message) { - int secondsSinceEpoch = (message.getTime() - boost::posix_time::ptime(boost::gregorian::date(1970, 1, 1))).total_seconds(); - - std::string statement = std::string("INSERT INTO messages('message', 'fromBare', 'fromResource', 'toBare', 'toResource', 'type', 'time', 'offset') VALUES(") + - "'" + getEscapedString(message.getMessage()) + "', " + - boost::lexical_cast<std::string>(getIDForJID(message.getFromJID().toBare())) + ", '" + - getEscapedString(message.getFromJID().getResource()) + "', " + - boost::lexical_cast<std::string>(getIDForJID(message.getToJID().toBare())) + ", '" + - getEscapedString(message.getToJID().getResource()) + "', " + - boost::lexical_cast<std::string>(message.getType()) + ", " + - boost::lexical_cast<std::string>(secondsSinceEpoch) + ", " + - boost::lexical_cast<std::string>(message.getOffset()) + ")"; - char* errorMessage; - int result = sqlite3_exec(db_, statement.c_str(), 0, 0, &errorMessage); - if (result != SQLITE_OK) { - std::cerr << "SQL Error: " << errorMessage << std::endl; - sqlite3_free(errorMessage); - } + int secondsSinceEpoch = (message.getTime() - boost::posix_time::ptime(boost::gregorian::date(1970, 1, 1))).total_seconds(); + + std::string statement = std::string("INSERT INTO messages('message', 'fromBare', 'fromResource', 'toBare', 'toResource', 'type', 'time', 'offset') VALUES(") + + "'" + getEscapedString(message.getMessage()) + "', " + + boost::lexical_cast<std::string>(getIDForJID(message.getFromJID().toBare())) + ", '" + + getEscapedString(message.getFromJID().getResource()) + "', " + + boost::lexical_cast<std::string>(getIDForJID(message.getToJID().toBare())) + ", '" + + getEscapedString(message.getToJID().getResource()) + "', " + + boost::lexical_cast<std::string>(message.getType()) + ", " + + boost::lexical_cast<std::string>(secondsSinceEpoch) + ", " + + boost::lexical_cast<std::string>(message.getOffset()) + ")"; + char* errorMessage; + int result = sqlite3_exec(db_, statement.c_str(), 0, 0, &errorMessage); + if (result != SQLITE_OK) { + std::cerr << "SQL Error: " << errorMessage << std::endl; + sqlite3_free(errorMessage); + } } std::vector<HistoryMessage> SQLiteHistoryStorage::getMessagesFromDate(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const { - sqlite3_stmt* selectStatement; - - boost::optional<long long> selfID = getIDFromJID(selfJID.toBare()); - boost::optional<long long> contactID = getIDFromJID(contactJID.toBare()); - - if (!selfID || !contactID) { - // JIDs missing from the database - return std::vector<HistoryMessage>(); - } - - std::string selectQuery = "SELECT * 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) + ")))"; - } - - if (!date.is_not_a_date()) { - int lowerBound = (boost::posix_time::ptime(date) - boost::posix_time::ptime(boost::gregorian::date(1970, 1, 1))).total_seconds(); - int upperBound = lowerBound + 86400; - - selectQuery += " AND (time>=" + boost::lexical_cast<std::string>(lowerBound) + - " AND time<" + boost::lexical_cast<std::string>(upperBound) + ")"; - } - - int r = sqlite3_prepare(db_, selectQuery.c_str(), boost::numeric_cast<int>(selectQuery.size()), &selectStatement, NULL); - if (r != SQLITE_OK) { - std::cout << "Error: " << sqlite3_errmsg(db_) << std::endl; - } - r = sqlite3_step(selectStatement); - - // Retrieve result - std::vector<HistoryMessage> result; - while (r == SQLITE_ROW) { - std::string message(reinterpret_cast<const char*>(sqlite3_column_text(selectStatement, 0))); - - // fromJID - boost::optional<JID> fromJID(getJIDFromID(sqlite3_column_int(selectStatement, 1))); - std::string fromResource(reinterpret_cast<const char*>(sqlite3_column_text(selectStatement, 2))); - if (fromJID) { - fromJID = boost::optional<JID>(JID(fromJID->getNode(), fromJID->getDomain(), fromResource)); - } - - // toJID - boost::optional<JID> toJID(getJIDFromID(sqlite3_column_int(selectStatement, 3))); - std::string toResource(reinterpret_cast<const char*>(sqlite3_column_text(selectStatement, 4))); - if (toJID) { - toJID = boost::optional<JID>(JID(toJID->getNode(), toJID->getDomain(), toResource)); - } - - // message type - HistoryMessage::Type type = static_cast<HistoryMessage::Type>(sqlite3_column_int(selectStatement, 5)); - - // timestamp - int secondsSinceEpoch(sqlite3_column_int(selectStatement, 6)); - boost::posix_time::ptime time(boost::gregorian::date(1970, 1, 1), boost::posix_time::seconds(secondsSinceEpoch)); - - // offset from utc - int offset = sqlite3_column_int(selectStatement, 7); - - result.push_back(HistoryMessage(message, (fromJID ? *fromJID : JID()), (toJID ? *toJID : JID()), type, time, offset)); - r = sqlite3_step(selectStatement); - } - if (r != SQLITE_DONE) { - std::cout << "Error: " << sqlite3_errmsg(db_) << std::endl; - } - sqlite3_finalize(selectStatement); - - return result; + sqlite3_stmt* selectStatement; + + boost::optional<long long> selfID = getIDFromJID(selfJID.toBare()); + boost::optional<long long> contactID = getIDFromJID(contactJID.toBare()); + + if (!selfID || !contactID) { + // JIDs missing from the database + return std::vector<HistoryMessage>(); + } + + std::string selectQuery = "SELECT * 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) + ")))"; + } + + if (!date.is_not_a_date()) { + int lowerBound = (boost::posix_time::ptime(date) - boost::posix_time::ptime(boost::gregorian::date(1970, 1, 1))).total_seconds(); + int upperBound = lowerBound + 86400; + + selectQuery += " AND (time>=" + boost::lexical_cast<std::string>(lowerBound) + + " AND time<" + boost::lexical_cast<std::string>(upperBound) + ")"; + } + + int r = sqlite3_prepare(db_, selectQuery.c_str(), boost::numeric_cast<int>(selectQuery.size()), &selectStatement, NULL); + if (r != SQLITE_OK) { + std::cout << "Error: " << sqlite3_errmsg(db_) << std::endl; + } + r = sqlite3_step(selectStatement); + + // Retrieve result + std::vector<HistoryMessage> result; + while (r == SQLITE_ROW) { + std::string message(reinterpret_cast<const char*>(sqlite3_column_text(selectStatement, 0))); + + // fromJID + boost::optional<JID> fromJID(getJIDFromID(sqlite3_column_int(selectStatement, 1))); + std::string fromResource(reinterpret_cast<const char*>(sqlite3_column_text(selectStatement, 2))); + if (fromJID) { + fromJID = boost::optional<JID>(JID(fromJID->getNode(), fromJID->getDomain(), fromResource)); + } + + // toJID + boost::optional<JID> toJID(getJIDFromID(sqlite3_column_int(selectStatement, 3))); + std::string toResource(reinterpret_cast<const char*>(sqlite3_column_text(selectStatement, 4))); + if (toJID) { + toJID = boost::optional<JID>(JID(toJID->getNode(), toJID->getDomain(), toResource)); + } + + // message type + HistoryMessage::Type type = static_cast<HistoryMessage::Type>(sqlite3_column_int(selectStatement, 5)); + + // timestamp + int secondsSinceEpoch(sqlite3_column_int(selectStatement, 6)); + boost::posix_time::ptime time(boost::gregorian::date(1970, 1, 1), boost::posix_time::seconds(secondsSinceEpoch)); + + // offset from utc + int offset = sqlite3_column_int(selectStatement, 7); + + result.push_back(HistoryMessage(message, (fromJID ? *fromJID : JID()), (toJID ? *toJID : JID()), type, time, offset)); + r = sqlite3_step(selectStatement); + } + if (r != SQLITE_DONE) { + std::cout << "Error: " << sqlite3_errmsg(db_) << std::endl; + } + sqlite3_finalize(selectStatement); + + return result; } long long SQLiteHistoryStorage::getIDForJID(const JID& jid) { - boost::optional<long long> id = getIDFromJID(jid); - if (id) { - return *id; - } - else { - return addJID(jid); - } + boost::optional<long long> id = getIDFromJID(jid); + if (id) { + return *id; + } + else { + return addJID(jid); + } } long long SQLiteHistoryStorage::addJID(const JID& jid) { - std::string statement = std::string("INSERT INTO jids('jid') VALUES('") + getEscapedString(jid.toString()) + "')"; - char* errorMessage; - int result = sqlite3_exec(db_, statement.c_str(), 0, 0, &errorMessage); - if (result != SQLITE_OK) { - std::cerr << "SQL Error: " << errorMessage << std::endl; - sqlite3_free(errorMessage); - } - return sqlite3_last_insert_rowid(db_); + std::string statement = std::string("INSERT INTO jids('jid') VALUES('") + getEscapedString(jid.toString()) + "')"; + char* errorMessage; + int result = sqlite3_exec(db_, statement.c_str(), 0, 0, &errorMessage); + if (result != SQLITE_OK) { + std::cerr << "SQL Error: " << errorMessage << std::endl; + sqlite3_free(errorMessage); + } + return sqlite3_last_insert_rowid(db_); } boost::optional<JID> SQLiteHistoryStorage::getJIDFromID(long long id) const { - boost::optional<JID> result; - sqlite3_stmt* selectStatement; - std::string selectQuery("SELECT jid FROM jids WHERE id=" + boost::lexical_cast<std::string>(id)); - int r = sqlite3_prepare(db_, selectQuery.c_str(), boost::numeric_cast<int>(selectQuery.size()), &selectStatement, NULL); - if (r != SQLITE_OK) { - std::cout << "Error: " << sqlite3_errmsg(db_) << std::endl; - } - r = sqlite3_step(selectStatement); - if (r == SQLITE_ROW) { - result = boost::optional<JID>(reinterpret_cast<const char*>(sqlite3_column_text(selectStatement, 0))); - } - sqlite3_finalize(selectStatement); - return result; + boost::optional<JID> result; + sqlite3_stmt* selectStatement; + std::string selectQuery("SELECT jid FROM jids WHERE id=" + boost::lexical_cast<std::string>(id)); + int r = sqlite3_prepare(db_, selectQuery.c_str(), boost::numeric_cast<int>(selectQuery.size()), &selectStatement, NULL); + if (r != SQLITE_OK) { + std::cout << "Error: " << sqlite3_errmsg(db_) << std::endl; + } + r = sqlite3_step(selectStatement); + if (r == SQLITE_ROW) { + result = boost::optional<JID>(reinterpret_cast<const char*>(sqlite3_column_text(selectStatement, 0))); + } + sqlite3_finalize(selectStatement); + return result; } boost::optional<long long> SQLiteHistoryStorage::getIDFromJID(const JID& jid) const { - boost::optional<long long> result; - sqlite3_stmt* selectStatement; - std::string selectQuery("SELECT id FROM jids WHERE jid='" + jid.toString() + "'"); - long long r = sqlite3_prepare(db_, selectQuery.c_str(), boost::numeric_cast<int>(selectQuery.size()), &selectStatement, NULL); - if (r != SQLITE_OK) { - std::cout << "Error: " << sqlite3_errmsg(db_) << std::endl; - } - r = sqlite3_step(selectStatement); - if (r == SQLITE_ROW) { - result = boost::optional<long long>(sqlite3_column_int(selectStatement, 0)); - } - sqlite3_finalize(selectStatement); - return result; + boost::optional<long long> result; + sqlite3_stmt* selectStatement; + std::string selectQuery("SELECT id FROM jids WHERE jid='" + jid.toString() + "'"); + long long r = sqlite3_prepare(db_, selectQuery.c_str(), boost::numeric_cast<int>(selectQuery.size()), &selectStatement, NULL); + if (r != SQLITE_OK) { + std::cout << "Error: " << sqlite3_errmsg(db_) << std::endl; + } + r = sqlite3_step(selectStatement); + if (r == SQLITE_ROW) { + result = boost::optional<long long>(sqlite3_column_int(selectStatement, 0)); + } + sqlite3_finalize(selectStatement); + return result; } ContactsMap SQLiteHistoryStorage::getContacts(const JID& selfJID, HistoryMessage::Type type, const std::string& keyword) const { - ContactsMap result; - sqlite3_stmt* selectStatement; - - // get id - boost::optional<long long> id = getIDFromJID(selfJID); - if (!id) { - return result; - } - - // get contacts - std::string query = "SELECT DISTINCT messages.'fromBare', messages.'fromResource', messages.'toBare', messages.'toResource', messages.'time' " - "FROM messages WHERE (type=" - + boost::lexical_cast<std::string>(type) + " AND (toBare=" - + boost::lexical_cast<std::string>(*id) + " OR fromBare=" + boost::lexical_cast<std::string>(*id) + "))"; - - // match keyword - if (getEscapedString(keyword).length()) { - query += " AND message LIKE '%" + getEscapedString(keyword) + "%'"; - } - - int r = sqlite3_prepare(db_, query.c_str(), boost::numeric_cast<int>(query.size()), &selectStatement, NULL); - if (r != SQLITE_OK) { - std::cout << "Error: " << sqlite3_errmsg(db_) << std::endl; - } - - r = sqlite3_step(selectStatement); - while (r == SQLITE_ROW) { - int fromBareID = sqlite3_column_int(selectStatement, 0); - std::string fromResource(reinterpret_cast<const char*>(sqlite3_column_text(selectStatement, 1))); - int toBareID = sqlite3_column_int(selectStatement, 2); - std::string toResource(reinterpret_cast<const char*>(sqlite3_column_text(selectStatement, 3))); - std::string resource; - - int secondsSinceEpoch(sqlite3_column_int(selectStatement, 4)); - boost::posix_time::ptime time(boost::gregorian::date(1970, 1, 1), boost::posix_time::seconds(secondsSinceEpoch)); - - boost::optional<JID> contactJID; - - if (fromBareID == *id) { - contactJID = getJIDFromID(toBareID); - resource = toResource; - } - else { - contactJID = getJIDFromID(fromBareID); - resource = fromResource; - } - - // check if it is a MUC contact (from a private conversation) - if (type == HistoryMessage::PrivateMessage) { - contactJID = boost::optional<JID>(JID(contactJID->getNode(), contactJID->getDomain(), resource)); - } - - if (contactJID) { - result[*contactJID].insert(time.date()); - } - - r = sqlite3_step(selectStatement); - } - - if (r != SQLITE_DONE) { - std::cout << "Error: " << sqlite3_errmsg(db_) << std::endl; - } - sqlite3_finalize(selectStatement); - - return result; + ContactsMap result; + sqlite3_stmt* selectStatement; + + // get id + boost::optional<long long> id = getIDFromJID(selfJID); + if (!id) { + return result; + } + + // get contacts + std::string query = "SELECT DISTINCT messages.'fromBare', messages.'fromResource', messages.'toBare', messages.'toResource', messages.'time' " + "FROM messages WHERE (type=" + + boost::lexical_cast<std::string>(type) + " AND (toBare=" + + boost::lexical_cast<std::string>(*id) + " OR fromBare=" + boost::lexical_cast<std::string>(*id) + "))"; + + // match keyword + if (getEscapedString(keyword).length()) { + query += " AND message LIKE '%" + getEscapedString(keyword) + "%'"; + } + + int r = sqlite3_prepare(db_, query.c_str(), boost::numeric_cast<int>(query.size()), &selectStatement, NULL); + if (r != SQLITE_OK) { + std::cout << "Error: " << sqlite3_errmsg(db_) << std::endl; + } + + r = sqlite3_step(selectStatement); + while (r == SQLITE_ROW) { + int fromBareID = sqlite3_column_int(selectStatement, 0); + std::string fromResource(reinterpret_cast<const char*>(sqlite3_column_text(selectStatement, 1))); + int toBareID = sqlite3_column_int(selectStatement, 2); + std::string toResource(reinterpret_cast<const char*>(sqlite3_column_text(selectStatement, 3))); + std::string resource; + + int secondsSinceEpoch(sqlite3_column_int(selectStatement, 4)); + boost::posix_time::ptime time(boost::gregorian::date(1970, 1, 1), boost::posix_time::seconds(secondsSinceEpoch)); + + boost::optional<JID> contactJID; + + if (fromBareID == *id) { + contactJID = getJIDFromID(toBareID); + resource = toResource; + } + else { + contactJID = getJIDFromID(fromBareID); + resource = fromResource; + } + + // check if it is a MUC contact (from a private conversation) + if (type == HistoryMessage::PrivateMessage) { + contactJID = boost::optional<JID>(JID(contactJID->getNode(), contactJID->getDomain(), resource)); + } + + if (contactJID) { + result[*contactJID].insert(time.date()); + } + + r = sqlite3_step(selectStatement); + } + + if (r != SQLITE_DONE) { + std::cout << "Error: " << sqlite3_errmsg(db_) << std::endl; + } + sqlite3_finalize(selectStatement); + + return result; } boost::gregorian::date SQLiteHistoryStorage::getNextDateWithLogs(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date, bool reverseOrder) const { - sqlite3_stmt* selectStatement; - boost::optional<long long> selfID = getIDFromJID(selfJID.toBare()); - boost::optional<long long> 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(), boost::numeric_cast<int>(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); + sqlite3_stmt* selectStatement; + boost::optional<long long> selfID = getIDFromJID(selfJID.toBare()); + boost::optional<long long> 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(), boost::numeric_cast<int>(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> SQLiteHistoryStorage::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); + boost::gregorian::date nextDate = getNextDateWithLogs(selfJID, contactJID, type, date, false); - if (nextDate.is_not_a_date()) { - return std::vector<HistoryMessage>(); - } + if (nextDate.is_not_a_date()) { + return std::vector<HistoryMessage>(); + } - return getMessagesFromDate(selfJID, contactJID, type, nextDate); + return getMessagesFromDate(selfJID, contactJID, type, nextDate); } std::vector<HistoryMessage> SQLiteHistoryStorage::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); + boost::gregorian::date previousDate = getNextDateWithLogs(selfJID, contactJID, type, date, true); - if (previousDate.is_not_a_date()) { - return std::vector<HistoryMessage>(); - } + if (previousDate.is_not_a_date()) { + return std::vector<HistoryMessage>(); + } - return getMessagesFromDate(selfJID, contactJID, type, previousDate); + return getMessagesFromDate(selfJID, contactJID, type, previousDate); } boost::posix_time::ptime SQLiteHistoryStorage::getLastTimeStampFromMUC(const JID& selfJID, const JID& mucJID) const { - boost::optional<long long> selfID = getIDFromJID(selfJID.toBare()); - boost::optional<long long> mucID = getIDFromJID(mucJID.toBare()); + boost::optional<long long> selfID = getIDFromJID(selfJID.toBare()); + boost::optional<long long> mucID = getIDFromJID(mucJID.toBare()); - if (!selfID || !mucID) { - // JIDs missing from the database - return boost::posix_time::ptime(boost::posix_time::not_a_date_time); - } + if (!selfID || !mucID) { + // JIDs missing from the database + return boost::posix_time::ptime(boost::posix_time::not_a_date_time); + } - sqlite3_stmt* selectStatement; - std::string selectQuery = "SELECT messages.'time', messages.'offset' from messages WHERE type=1 AND (toBare=" + - boost::lexical_cast<std::string>(*selfID) + " AND fromBare=" + - boost::lexical_cast<std::string>(*mucID) + ") ORDER BY time DESC LIMIT 1"; + sqlite3_stmt* selectStatement; + std::string selectQuery = "SELECT messages.'time', messages.'offset' from messages WHERE type=1 AND (toBare=" + + boost::lexical_cast<std::string>(*selfID) + " AND fromBare=" + + boost::lexical_cast<std::string>(*mucID) + ") ORDER BY time DESC LIMIT 1"; - int r = sqlite3_prepare(db_, selectQuery.c_str(), boost::numeric_cast<int>(selectQuery.size()), &selectStatement, NULL); - if (r != SQLITE_OK) { - std::cout << "Error: " << sqlite3_errmsg(db_) << std::endl; - } + int r = sqlite3_prepare(db_, selectQuery.c_str(), boost::numeric_cast<int>(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)); - int offset = sqlite3_column_int(selectStatement, 1); + 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)); + int offset = sqlite3_column_int(selectStatement, 1); - return time - boost::posix_time::hours(offset); - } + return time - boost::posix_time::hours(offset); + } - return boost::posix_time::ptime(boost::posix_time::not_a_date_time); + return boost::posix_time::ptime(boost::posix_time::not_a_date_time); } void SQLiteHistoryStorage::run() { diff --git a/Swiften/History/SQLiteHistoryStorage.h b/Swiften/History/SQLiteHistoryStorage.h index 95b13b9..b0223f5 100644 --- a/Swiften/History/SQLiteHistoryStorage.h +++ b/Swiften/History/SQLiteHistoryStorage.h @@ -16,28 +16,28 @@ struct sqlite3; namespace Swift { - class SWIFTEN_API SQLiteHistoryStorage : public HistoryStorage { - public: - SQLiteHistoryStorage(const boost::filesystem::path& file); - ~SQLiteHistoryStorage(); - - void addMessage(const HistoryMessage& message); - ContactsMap getContacts(const JID& selfJID, HistoryMessage::Type type, const std::string& keyword) 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; - boost::posix_time::ptime getLastTimeStampFromMUC(const JID& selfJID, const JID& mucJID) const; - - private: - void run(); - boost::gregorian::date getNextDateWithLogs(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date, bool reverseOrder) const; - long long getIDForJID(const JID&); - long long addJID(const JID&); - - boost::optional<JID> getJIDFromID(long long id) const; - boost::optional<long long> getIDFromJID(const JID& jid) const; - - sqlite3* db_; - boost::thread* thread_; - }; + class SWIFTEN_API SQLiteHistoryStorage : public HistoryStorage { + public: + SQLiteHistoryStorage(const boost::filesystem::path& file); + ~SQLiteHistoryStorage(); + + void addMessage(const HistoryMessage& message); + ContactsMap getContacts(const JID& selfJID, HistoryMessage::Type type, const std::string& keyword) 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; + boost::posix_time::ptime getLastTimeStampFromMUC(const JID& selfJID, const JID& mucJID) const; + + private: + void run(); + boost::gregorian::date getNextDateWithLogs(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date, bool reverseOrder) const; + long long getIDForJID(const JID&); + long long addJID(const JID&); + + boost::optional<JID> getJIDFromID(long long id) const; + boost::optional<long long> getIDFromJID(const JID& jid) const; + + sqlite3* db_; + boost::thread* thread_; + }; } diff --git a/Swiften/History/UnitTest/SQLiteHistoryManagerTest.cpp b/Swiften/History/UnitTest/SQLiteHistoryManagerTest.cpp index 560c992..5968d7e 100644 --- a/Swiften/History/UnitTest/SQLiteHistoryManagerTest.cpp +++ b/Swiften/History/UnitTest/SQLiteHistoryManagerTest.cpp @@ -14,103 +14,103 @@ using namespace Swift; class SQLiteHistoryManagerTest : public CppUnit::TestFixture { - CPPUNIT_TEST_SUITE(SQLiteHistoryManagerTest); - //CPPUNIT_TEST(testAddMessage); - //CPPUNIT_TEST(testAddMessage_TwoMessages); - //CPPUNIT_TEST(testGetIDForJID_SameJID); - //CPPUNIT_TEST(testGetIDForJID_DifferentJIDs); - //CPPUNIT_TEST(getJIDFromID); - //CPPUNIT_TEST(getJIDFromID_UnexistingID); - //CPPUNIT_TEST(getIDFromJID); - //CPPUNIT_TEST(getIDFromJID_UnexistingJID); - //CPPUNIT_TEST_SUITE_END(); - - public: - SQLiteHistoryManagerTest() {} - - void setUp() { - } - - void tearDown() { - } - - void testAddMessage() { - boost::shared_ptr<SQLiteHistoryManager> testling(createHistoryManager()); - HistoryMessage testMessage("Test", JID("foo@bar.com"), JID("fum@baz.org"), boost::posix_time::time_from_string("1980-01-21 22:03")); - testling->addMessage(testMessage); - - std::vector<HistoryMessage> messages = testling->getMessages(); - CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(messages.size())); - CPPUNIT_ASSERT(testMessage == messages[0]); - } - - void testAddMessage_TwoMessages() { - boost::shared_ptr<SQLiteHistoryManager> testling(createHistoryManager()); - HistoryMessage testMessage1("Test1", JID("foo@bar.com"), JID("fum@baz.org"), boost::posix_time::time_from_string("1980-01-21 22:03")); - testling->addMessage(testMessage1); - HistoryMessage testMessage2("Test2", JID("fum@baz.org"), JID("foo@bar.com"), boost::posix_time::time_from_string("1975-03-09 22:04")); - testling->addMessage(testMessage2); - - std::vector<HistoryMessage> messages = testling->getMessages(); - CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(messages.size())); - CPPUNIT_ASSERT(testMessage1 == messages[0]); - CPPUNIT_ASSERT(testMessage2 == messages[1]); - } - - void testGetIDForJID_SameJID() { - boost::shared_ptr<SQLiteHistoryManager> testling(createHistoryManager()); - int id1 = testling->getIDForJID(JID("foo@bar.com")); - int id2 = testling->getIDForJID(JID("foo@bar.com")); - - CPPUNIT_ASSERT_EQUAL(id1, id2); - } - - void testGetIDForJID_DifferentJIDs() { - boost::shared_ptr<SQLiteHistoryManager> testling(createHistoryManager()); - int id1 = testling->getIDForJID(JID("foo@bar.com")); - int id2 = testling->getIDForJID(JID("foo@baz.com")); - - CPPUNIT_ASSERT(id1 != id2); - } - - void getJIDFromID() { - boost::shared_ptr<SQLiteHistoryManager> testling(createHistoryManager()); - int id = testling->addJID(JID("foo@bar.com")); - - boost::optional<JID> result(testling->getJIDFromID(id)); - CPPUNIT_ASSERT(result); - CPPUNIT_ASSERT_EQUAL(JID("foo@bar.com"), *result); - } - - void getJIDFromID_UnexistingID() { - boost::shared_ptr<SQLiteHistoryManager> testling(createHistoryManager()); - - boost::optional<JID> result(testling->getJIDFromID(1)); - - CPPUNIT_ASSERT(!result); - } - - void getIDFromJID() { - boost::shared_ptr<SQLiteHistoryManager> testling(createHistoryManager()); - int id = testling->addJID(JID("foo@bar.com")); - - boost::optional<int> result(testling->getIDFromJID(JID("foo@bar.com"))); - CPPUNIT_ASSERT(result); - CPPUNIT_ASSERT_EQUAL(id, *result); - } - - void getIDFromJID_UnexistingJID() { - boost::shared_ptr<SQLiteHistoryManager> testling(createHistoryManager()); - - boost::optional<int> result(testling->getIDFromJID(JID("foo@bar.com"))); - - CPPUNIT_ASSERT(!result); - } - - private: - SQLiteHistoryManager* createHistoryManager() { - return new SQLiteHistoryManager(":memory:"); - } + CPPUNIT_TEST_SUITE(SQLiteHistoryManagerTest); + //CPPUNIT_TEST(testAddMessage); + //CPPUNIT_TEST(testAddMessage_TwoMessages); + //CPPUNIT_TEST(testGetIDForJID_SameJID); + //CPPUNIT_TEST(testGetIDForJID_DifferentJIDs); + //CPPUNIT_TEST(getJIDFromID); + //CPPUNIT_TEST(getJIDFromID_UnexistingID); + //CPPUNIT_TEST(getIDFromJID); + //CPPUNIT_TEST(getIDFromJID_UnexistingJID); + //CPPUNIT_TEST_SUITE_END(); + + public: + SQLiteHistoryManagerTest() {} + + void setUp() { + } + + void tearDown() { + } + + void testAddMessage() { + boost::shared_ptr<SQLiteHistoryManager> testling(createHistoryManager()); + HistoryMessage testMessage("Test", JID("foo@bar.com"), JID("fum@baz.org"), boost::posix_time::time_from_string("1980-01-21 22:03")); + testling->addMessage(testMessage); + + std::vector<HistoryMessage> messages = testling->getMessages(); + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(messages.size())); + CPPUNIT_ASSERT(testMessage == messages[0]); + } + + void testAddMessage_TwoMessages() { + boost::shared_ptr<SQLiteHistoryManager> testling(createHistoryManager()); + HistoryMessage testMessage1("Test1", JID("foo@bar.com"), JID("fum@baz.org"), boost::posix_time::time_from_string("1980-01-21 22:03")); + testling->addMessage(testMessage1); + HistoryMessage testMessage2("Test2", JID("fum@baz.org"), JID("foo@bar.com"), boost::posix_time::time_from_string("1975-03-09 22:04")); + testling->addMessage(testMessage2); + + std::vector<HistoryMessage> messages = testling->getMessages(); + CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(messages.size())); + CPPUNIT_ASSERT(testMessage1 == messages[0]); + CPPUNIT_ASSERT(testMessage2 == messages[1]); + } + + void testGetIDForJID_SameJID() { + boost::shared_ptr<SQLiteHistoryManager> testling(createHistoryManager()); + int id1 = testling->getIDForJID(JID("foo@bar.com")); + int id2 = testling->getIDForJID(JID("foo@bar.com")); + + CPPUNIT_ASSERT_EQUAL(id1, id2); + } + + void testGetIDForJID_DifferentJIDs() { + boost::shared_ptr<SQLiteHistoryManager> testling(createHistoryManager()); + int id1 = testling->getIDForJID(JID("foo@bar.com")); + int id2 = testling->getIDForJID(JID("foo@baz.com")); + + CPPUNIT_ASSERT(id1 != id2); + } + + void getJIDFromID() { + boost::shared_ptr<SQLiteHistoryManager> testling(createHistoryManager()); + int id = testling->addJID(JID("foo@bar.com")); + + boost::optional<JID> result(testling->getJIDFromID(id)); + CPPUNIT_ASSERT(result); + CPPUNIT_ASSERT_EQUAL(JID("foo@bar.com"), *result); + } + + void getJIDFromID_UnexistingID() { + boost::shared_ptr<SQLiteHistoryManager> testling(createHistoryManager()); + + boost::optional<JID> result(testling->getJIDFromID(1)); + + CPPUNIT_ASSERT(!result); + } + + void getIDFromJID() { + boost::shared_ptr<SQLiteHistoryManager> testling(createHistoryManager()); + int id = testling->addJID(JID("foo@bar.com")); + + boost::optional<int> result(testling->getIDFromJID(JID("foo@bar.com"))); + CPPUNIT_ASSERT(result); + CPPUNIT_ASSERT_EQUAL(id, *result); + } + + void getIDFromJID_UnexistingJID() { + boost::shared_ptr<SQLiteHistoryManager> testling(createHistoryManager()); + + boost::optional<int> result(testling->getIDFromJID(JID("foo@bar.com"))); + + CPPUNIT_ASSERT(!result); + } + + private: + SQLiteHistoryManager* createHistoryManager() { + return new SQLiteHistoryManager(":memory:"); + } }; CPPUNIT_TEST_SUITE_REGISTRATION(SQLiteHistoryManagerTest); |