/soc/2015/igor.gajowiak/chatlog: 9d6836494f9f: Implemented getti...

Igor Gajowiak <[email protected]>
Newsgroups gmane.comp.gnome.gaim.cvs
Message-ID <[email protected]>
Changeset: 9d6836494f9f04ae3708506fbd903f6be5bbd3da
Author:	 Igor Gajowiak <[email protected]>
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);
+}

_______________________________________________
Commits mailing list
[email protected]
https://pidgin.im/cgi-bin/mailman/listinfo/commits
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.