/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