/soc/2015/igor.gajowiak/chatlog: 9d6836494f9f: Implemented getti...
Igor Gajowiak
igor.gajowiak at gmail.com
Sat Jul 25 18:52:53 EDT 2015
Changeset: 9d6836494f9f04ae3708506fbd903f6be5bbd3da
Author: Igor Gajowiak <igor.gajowiak at gmail.com>
Date: 2015-07-26 00:52 +0200
Branch: default
URL: https://hg.pidgin.im/soc/2015/igor.gajowiak/chatlog/rev/9d6836494f9f
Description:
Implemented getting older messages from a log.
diffstat:
libpurple/genericlog.c | 11 ++
libpurple/genericlog.h | 40 +++++++-
libpurple/plugins/log/logsqlite.c | 170 ++++++++++++++++++++++++++++++++++++-
3 files changed, 211 insertions(+), 10 deletions(-)
diffs (truncated from 340 to 300 lines):
diff --git a/libpurple/genericlog.c b/libpurple/genericlog.c
--- a/libpurple/genericlog.c
+++ b/libpurple/genericlog.c
@@ -257,6 +257,16 @@ purple_genericlog_get_all_msgs(PurpleBud
}
gboolean
+purple_genericlog_get_older_msgs(PurpleBuddy *buddy, guint64 timestamp,
+ PurpleMessage *message, GList **result, GError **error)
+{
+ DEFINE_GENERICLOG_FUNC_WITH_RETURN(get_older_msgs,
+ "%s does not support getting older messages",
+ "Getting older messages from %s failed",
+ buddy, timestamp, message, result);
+}
+
+gboolean
purple_genericlog_get_all_buddies(GList** result, GError** error)
{
DEFINE_GENERICLOG_FUNC_WITH_RETURN(get_all_buddies,
@@ -351,6 +361,7 @@ purple_genericlog_class_init(PurpleGener
klass->mark_as_seen = NULL;
klass->get_unseen_msgs = NULL;
klass->get_all_msgs = NULL;
+ klass->get_older_msgs = NULL;
klass->get_all_buddies = NULL;
klass->reserved1 = NULL;
diff --git a/libpurple/genericlog.h b/libpurple/genericlog.h
--- a/libpurple/genericlog.h
+++ b/libpurple/genericlog.h
@@ -64,6 +64,11 @@ struct _PurpleGenericLog
* @get_all_msgs: Gets all messages sent to or received from a buddy.
* Messages are sorted by their timestamp in ascending order.
* Returns %TRUE if operation succeeds, %FALSE otherwise.
+ * @get_older_msgs: Gets all messages sent to or received from a buddy, older
+ * than the message and not older than the timestamp.
+ * If message is %NULL then upper bound check is skipped.
+ * Messages are sorted by their timestamp in descending order.
+ * Returns %TRUE if operation succeeds, %FALSE otherwise.
* @get_all_buddies: Gets a list of all #PurpleBuddy objects with at least one
* message in the log. Returns %TRUE if operation succeeds,
* %FALSE otherwise. The client is responsible for freeing
@@ -90,6 +95,9 @@ struct _PurpleGenericLogClass
gboolean (*get_all_msgs)(PurpleBuddy *buddy, GList **result);
+ gboolean (*get_older_msgs)(PurpleBuddy *buddy, guint64 timestamp,
+ PurpleMessage *message, GList **result);
+
gboolean (*get_all_buddies)(GList **result);
void (*reserved1)(void);
@@ -242,11 +250,11 @@ purple_genericlog_get_unseen_msgs(Purple
/**
* purple_genericlog_get_all_msgs:
- * @buddy: The buddy.
- * @result: Return location for a #GList of #PurpleMessage objects.
- * This will not be set in case of any errors.
- * @error: Return location for a #GError or %NULL. If provided, this
- * will be set to the reason if getting messages fails.
+ * @buddy: The buddy.
+ * @result[out]: Return location for a #GList of #PurpleMessage objects.
+ * This will not be set in case of any errors.
+ * @error: Return location for a #GError or %NULL. If provided, this
+ * will be set to the reason if getting messages fails.
*
* Gets all messages from the active log sent to or received from a buddy.
*
@@ -261,6 +269,28 @@ purple_genericlog_get_all_msgs(PurpleBud
GError **error);
/**
+ * purple_genericlog_get_older_msgs:
+ * @buddy: The buddy.
+ * @timestamp: The lower bound.
+ * @message: The upper bound or %NULL. If not provided then upper bound
+ * check is skipped.
+ * @result[out]: Return location for a #GList of #PurpleMessage objects.
+ * This will not be set in case of any errors.
+ * @error: Return location for a #GError or %NULL. If provided, this
+ * will be set to the reason if getting messages fails.
+ *
+ * Gets messages older than the message and not older than the timestamp
+ * sent to or received from a buddy from the active log.
+ *
+ * Messages are sorted by their timestamp in descending order.
+ *
+ * Returns: %TRUE if succeeds, %FALSE otherwise.
+ */
+gboolean
+purple_genericlog_get_older_msgs(PurpleBuddy *buddy, guint64 timestamp,
+ PurpleMessage *message, GList **result, GError **error);
+
+/**
* purple_genericlog_get_all_buddies:
* @result[out]: Return location for a #GList containing a list of #PurpleBuddy
* objects. This will not be set in case of any errors.
diff --git a/libpurple/plugins/log/logsqlite.c b/libpurple/plugins/log/logsqlite.c
--- a/libpurple/plugins/log/logsqlite.c
+++ b/libpurple/plugins/log/logsqlite.c
@@ -123,6 +123,40 @@ typedef enum
GET_ALL_MSGS_QUERY_PARAM_WHO = 2,
} GetAllMsgsQueryParam;
+static sqlite3_stmt *get_older_msgs_q = NULL;
+
+static const char *get_older_msgs_q_str =
+ "SELECT Id, Author, AuthorAlias, Recipient, Contents, MsgTime, Flags "
+ "FROM Messages "
+ "WHERE AccountId = ?1 AND MsgTime >= ?2 "
+ "AND (Author = ?3 OR Recipient = ?3) "
+ "ORDER BY MsgTime, Id;";
+
+typedef enum
+{
+ GET_OLDER_MSGS_QUERY_PARAM_ACCOUNTID = 1,
+ GET_OLDER_MSGS_QUERY_PARAM_LOWERBOUND = 2,
+ GET_OLDER_MSGS_QUERY_PARAM_WHO = 3
+} GetOlderMsgsQueryParam;
+
+static sqlite3_stmt *get_older_msgs_upper_q = NULL;
+
+static const char *get_older_msgs_upper_q_str =
+ "SELECT Id, Author, AuthorAlias, Recipient, Contents, MsgTime, Flags "
+ "FROM Messages "
+ "WHERE AccountId = ?1 AND MsgTime >= ?2 AND MsgTime <= ?3 AND Id != ?4 "
+ "AND (Author = ?5 OR Recipient = ?5) "
+ "ORDER BY MsgTime, Id;";
+
+typedef enum
+{
+ GET_OLDER_MSGS_UPPER_QUERY_PARAM_ACCOUNTID = 1,
+ GET_OLDER_MSGS_UPPER_QUERY_PARAM_LOWERBOUND = 2,
+ GET_OLDER_MSGS_UPPER_QUERY_PARAM_UPPERBOUND = 3,
+ GET_OLDER_MSGS_UPPER_QUERY_PARAM_EXCEPTID = 4,
+ GET_OLDER_MSGS_UPPER_QUERY_PARAM_WHO = 5
+} GetOlderMsgsUpperQueryParam;
+
typedef enum
{
GET_MSGS_QUERY_COL_ID = 0,
@@ -185,6 +219,8 @@ sqlitelog_finalize_queries()
sqlitelog_finalize_query(&insert_message_q);
sqlitelog_finalize_query(&get_unseen_msgs_q);
sqlitelog_finalize_query(&get_all_msgs_q);
+ sqlitelog_finalize_query(&get_older_msgs_q);
+ sqlitelog_finalize_query(&get_older_msgs_upper_q);
sqlitelog_finalize_query(&mark_as_seen_q);
sqlitelog_finalize_query(&get_all_buddies_q);
}
@@ -219,6 +255,9 @@ sqlitelog_prepare_queries()
!sqlitelog_prepare_query(insert_message_q_str, &insert_message_q) ||
!sqlitelog_prepare_query(get_unseen_msgs_q_str, &get_unseen_msgs_q) ||
!sqlitelog_prepare_query(get_all_msgs_q_str, &get_all_msgs_q) ||
+ !sqlitelog_prepare_query(get_older_msgs_q_str, &get_older_msgs_q) ||
+ !sqlitelog_prepare_query(get_older_msgs_upper_q_str,
+ &get_older_msgs_upper_q) ||
!sqlitelog_prepare_query(mark_as_seen_q_str, &mark_as_seen_q) ||
!sqlitelog_prepare_query(get_all_buddies_q_str, &get_all_buddies_q)) {
@@ -261,6 +300,7 @@ sqlitelog_create_tables(sqlite3 *db_hand
"CREATE INDEX SeenIndex ON Messages (Seen); "
"CREATE INDEX SendIndex ON Messages (Send); "
+ "CREATE INDEX MsgTimeIndex ON Messages (MsgTime); "
"CREATE TRIGGER AccountDeleted AFTER DELETE ON Accounts "
"BEGIN "
@@ -512,23 +552,23 @@ sqlitelog_get_all_msgs_impl(PurpleBuddy
g_assert(get_all_msgs_q);
+ const char *buddy_name = purple_buddy_get_name(buddy);
+ g_return_val_if_fail(buddy_name != NULL, FALSE);
+
PurpleAccount *account = purple_buddy_get_account(buddy);
-
g_return_val_if_fail(account != NULL, FALSE);
unsigned account_id;
if (!sqlitelog_get_account_id(account, &account_id))
return FALSE;
+ // If there are no messages sent or received from account
+ // then return empty list
if (account_id == SQLITELOG_DB_ID_NONE) {
*result = NULL;
return TRUE;
}
- const char *buddy_name = purple_buddy_get_name(buddy);
-
- g_return_val_if_fail(buddy_name != NULL, FALSE);
-
if (sqlite3_bind_int64(get_all_msgs_q,
GET_ALL_MSGS_QUERY_PARAM_ACCOUNTID, account_id) != SQLITE_OK ||
sqlite3_bind_text(get_all_msgs_q,
@@ -541,6 +581,105 @@ sqlitelog_get_all_msgs_impl(PurpleBuddy
}
static gboolean
+sqlitelog_get_older_msgs_impl(PurpleBuddy *buddy, guint64 timestamp,
+ GList **result)
+{
+ g_assert(buddy);
+ g_assert(result);
+
+ g_assert(get_older_msgs_q);
+
+ const char *buddy_name = purple_buddy_get_name(buddy);
+ g_return_val_if_fail(buddy_name != NULL, FALSE);
+
+ PurpleAccount *account = purple_buddy_get_account(buddy);
+ g_return_val_if_fail(account != NULL, FALSE);
+
+ unsigned account_id;
+ if (!sqlitelog_get_account_id(account, &account_id))
+ return FALSE;
+
+ // If there are no messages sent or received from account
+ // then return empty list
+ if (account_id == SQLITELOG_DB_ID_NONE) {
+ *result = NULL;
+ return TRUE;
+ }
+
+ if (sqlite3_bind_int64(get_older_msgs_q,
+ GET_OLDER_MSGS_QUERY_PARAM_ACCOUNTID, account_id) != SQLITE_OK ||
+ sqlite3_bind_int64(get_older_msgs_q,
+ GET_OLDER_MSGS_QUERY_PARAM_LOWERBOUND, timestamp) != SQLITE_OK ||
+ sqlite3_bind_text(get_older_msgs_q,
+ GET_OLDER_MSGS_QUERY_PARAM_WHO, buddy_name, -1, SQLITE_STATIC)
+ != SQLITE_OK) {
+ return FALSE;
+ }
+
+ return sqlitelog_execute_get_msgs_query(get_older_msgs_q, result);
+}
+
+static gboolean
+sqlitelog_get_older_msgs_upper_impl(PurpleBuddy *buddy, guint64 timestamp,
+ PurpleMessage *message, GList **result)
+{
+ g_assert(buddy);
+ g_assert(message);
+ g_assert(result);
+
+ g_assert(get_older_msgs_upper_q);
+
+ const char *buddy_name = purple_buddy_get_name(buddy);
+ g_return_val_if_fail(buddy_name != NULL, FALSE);
+
+ unsigned msg_id = GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(message),
+ SQLITELOG_MESSAGE_ID_ATTR));
+ g_return_val_if_fail(msg_id != SQLITELOG_DB_ID_NONE, FALSE);
+
+ PurpleAccount *account = purple_buddy_get_account(buddy);
+ g_return_val_if_fail(account != NULL, FALSE);
+
+ guint64 upper_bound = purple_message_get_time(message);
+
+ // If the interval is empty then no need to query the database
+ if (timestamp > upper_bound) {
+ *result = NULL;
+ return TRUE;
+ }
+
+ unsigned account_id;
+ if (!sqlitelog_get_account_id(account, &account_id))
+ return FALSE;
+
+ // If there are no messages sent or received from account
+ // then return empty list
+ if (account_id == SQLITELOG_DB_ID_NONE) {
+ *result = NULL;
+ return TRUE;
+ }
+
+ if (sqlite3_bind_int64(get_older_msgs_upper_q,
+ GET_OLDER_MSGS_UPPER_QUERY_PARAM_ACCOUNTID, account_id)
+ != SQLITE_OK ||
+ sqlite3_bind_int64(get_older_msgs_upper_q,
+ GET_OLDER_MSGS_UPPER_QUERY_PARAM_LOWERBOUND, timestamp)
+ != SQLITE_OK ||
+ sqlite3_bind_int64(get_older_msgs_upper_q,
+ GET_OLDER_MSGS_UPPER_QUERY_PARAM_UPPERBOUND, upper_bound)
+ != SQLITE_OK ||
+ sqlite3_bind_int64(get_older_msgs_upper_q,
+ GET_OLDER_MSGS_UPPER_QUERY_PARAM_EXCEPTID, msg_id)
+ != SQLITE_OK ||
+ sqlite3_bind_text(get_older_msgs_upper_q,
+ GET_OLDER_MSGS_UPPER_QUERY_PARAM_WHO, buddy_name, -1, SQLITE_STATIC)
+ != SQLITE_OK) {
+ return FALSE;
+ }
+
+ return sqlitelog_execute_get_msgs_query(get_older_msgs_upper_q, result);
+}
More information about the Commits
mailing list