summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiften/History')
-rw-r--r--Swiften/History/HistoryMessage.h100
-rw-r--r--Swiften/History/HistoryStorage.h28
-rw-r--r--Swiften/History/SQLiteHistoryStorage.cpp616
-rw-r--r--Swiften/History/SQLiteHistoryStorage.h48
-rw-r--r--Swiften/History/UnitTest/SQLiteHistoryManagerTest.cpp194
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);