/soc/2015/igor.gajowiak/chatlog: d77abd768997: Fixes in the sqli...

Igor Gajowiak igor.gajowiak at gmail.com
Fri Jul 17 19:08:57 EDT 2015


Changeset: d77abd768997c34f33eac9fb9fdb035a64a62ddf
Author:	 Igor Gajowiak <igor.gajowiak at gmail.com>
Date:	 2015-07-18 01:08 +0200
Branch:	 default
URL: https://hg.pidgin.im/soc/2015/igor.gajowiak/chatlog/rev/d77abd768997

Description:

Fixes in the sqlite log.

diffstat:

 libpurple/plugins/log/logsqlite.c |  440 ++++++++++++++++++++-----------------
 1 files changed, 235 insertions(+), 205 deletions(-)

diffs (truncated from 583 to 300 lines):

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
@@ -22,51 +22,41 @@
 #include <stdlib.h>
 #include <sqlite3.h>
 
+#include "debug.h"
 #include "purple.h"
 #include "utils.h"
 #include "version.h"
 
-#define DB_ID_NONE -1
-#define DB_EXEC_ERROR -2
+#define SQLITELOG_ID          "genericlog-sqlitelog"
+#define SQLITELOG_NAME        "SQLite log"
+#define SQLITELOG_DESCRIPTION "This plugin logs messages to an SQLite database."
+#define SQLITELOG_AUTHORS \
+	{ "Igor Gajowiak <igor.gajowiak at gmail.com>", NULL }
 
-static sqlite3 *sqlite_log_db = NULL;
+#define SQLITELOG_DB_FILENAME "sqlitelog_db.bin"
 
-static PurplePluginInfo *
-plugin_query (GError ** error)
-{
-	const gchar * const authors[] = {
-		"Igor Gajowiak <igor.gajowiak at gmail.com>",
-		NULL
-	};
+#define SQLITELOG_DB_ID_NONE 0
 
-	return purple_plugin_info_new (
-		"id",           "genericlog-sqlitelog",
-		"name",         "sqlite-log",
-		"version",      DISPLAY_VERSION,
-		"category",     "Genericlog",
-		"summary",      "Sqlite logger",
-		"description",  "log messages into sqlite database",
-		"authors",      authors,
-		"abi-version",  PURPLE_ABI_VERSION,
-		"flags",        PURPLE_PLUGIN_INFO_FLAGS_INTERNAL,
-		NULL
-	);
-}
+#define SQLITELOG_MESSAGE_ID_ATTR "sqlitelog-msg-id"
+
+static sqlite3 *sqlitelog_db_handle = NULL;
 
 static gboolean
-sqlite_log_db_exists(const gchar *db_path)
+sqlitelog_db_file_exists(const gchar *db_path)
 {
 	return g_file_test(db_path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR);
 }
 
 static int
-sqlite_log_create_tables()
+sqlitelog_create_tables(sqlite3 *db_handle)
 {
-	const char *sql_statement =
+	const char *query =
 		"CREATE TABLE Accounts("
 		"Id INTEGER PRIMARY KEY AUTOINCREMENT,"
 		"Username TEXT NOT NULL,"
-		"Protocol TEXT NOT NULL); "
+		"ProtocolId TEXT NOT NULL); "
+
+		"CREATE UNIQUE INDEX AccountsIndex On Accounts(Username, ProtocolId); "
 
 		"CREATE TABLE Messages("
 		"Id INTEGER PRIMARY KEY AUTOINCREMENT,"
@@ -76,230 +66,254 @@ sqlite_log_create_tables()
 		"Contents TEXT NOT NULL,"
 		"MsgTime INTEGER NOT NULL,"
 		"Flags INTEGER NOT NULL,"
+		"Seen BOOLEAN DEFAULT 0,"
 		"AccountId INTEGER NOT NULL,"
-		"Read BOOLEAN DEFAULT 0,"
 		"FOREIGN KEY(AccountId) REFERENCES Accounts(Id)); "
 
-		"CREATE INDEX ReadIndex ON Messages (Read); "
+		"CREATE INDEX SeenIndex ON Messages (Seen); "
 
 		"CREATE TRIGGER AccountDeleted AFTER DELETE ON Accounts "
 		"BEGIN "
 		"DELETE FROM Messages WHERE AccountId = OLD.Id; "
 		"END; ";
 
-	return sqlite3_exec(sqlite_log_db, sql_statement, NULL, NULL, NULL);
+	return sqlite3_exec(db_handle, query, NULL, NULL, NULL);
+}
+
+static void
+sqlitelog_close_db_if_notnull(sqlite3 *db_handle)
+{
+	if (db_handle) sqlite3_close(db_handle);
+}
+
+static gboolean
+sqlitelog_init_db(const gchar *db_path, sqlite3 **db_handle)
+{
+	gboolean create_tables = !sqlitelog_db_file_exists(db_path);
+
+	sqlite3 *handle = NULL;
+
+	if (sqlite3_open_v2(db_path, &handle, SQLITE_OPEN_READWRITE |
+		SQLITE_OPEN_CREATE, NULL) != SQLITE_OK) {
+			sqlitelog_close_db_if_notnull(handle);
+			return FALSE;
+	}
+
+	if (create_tables && sqlitelog_create_tables(handle) != SQLITE_OK) {
+		sqlitelog_close_db_if_notnull(handle);
+		return FALSE;
+	}
+
+	*db_handle = handle;
+	return TRUE;
 }
 
 static int
-sqlite_log_create_and_init_db(const gchar *db_path)
+sqlitelog_get_account_id_cb(void *data, int argc, char **argv, char **col_name)
 {
-	int rc = sqlite3_open_v2(db_path, &sqlite_log_db,
-		SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
+	g_assert(argc == 1);
 
-	if(rc != SQLITE_OK) {
-		purple_debug_error("sqlitelog", "database creation failed");
-		return rc;
-	}
-	return sqlite_log_create_tables();
-}
-
-static int
-sqlite_log_get_id_cb(void *data, int argc, char **argv, char **azColName)
-{
-	int *p_i = (int*) data;
-	*p_i = atoi(argv[0]);
+	*((unsigned*) data) = g_ascii_strtoull(argv[0], NULL, 10);
 	return 0;
 }
 
-static int
-sqlite_log_db_get_account_id(PurpleAccount *account)
+static gboolean
+sqlitelog_get_account_id(const PurpleAccount *account, unsigned *result)
 {
-	char *sql_statement = g_strdup_printf(
-			"SELECT Id FROM Accounts WHERE Username like \'%s\'"
-			"AND Protocol like \'%s\'",
-			purple_account_get_username(account),
-			purple_account_get_protocol_id(account));
-
-	int protocol_id = DB_ID_NONE;
-	int rc = sqlite3_exec(sqlite_log_db, sql_statement,
-		sqlite_log_get_id_cb, (void*)(&protocol_id), NULL);
-	if(rc != SQLITE_OK) {
-		purple_debug_error("sqlitelog", "fetching account id failed");
-		g_free(sql_statement);
-		return DB_EXEC_ERROR;
-	}
-
-	g_free(sql_statement);
-	return protocol_id;
-}
-
-static int
-sqlite_log_insert_account(const PurpleAccount *account)
-{
-	char *sql_statement = g_strdup_printf(
-		"INSERT INTO Accounts (Username, Protocol) "
-		"VALUES(\'%s\', \'%s\');",
+	gchar *query = g_strdup_printf(
+		"SELECT Id FROM Accounts WHERE "
+		"Username = '%s' AND "
+		"ProtocolId = '%s'",
 		purple_account_get_username(account),
 		purple_account_get_protocol_id(account));
 
-	int rc = sqlite3_exec(sqlite_log_db, sql_statement, NULL, NULL, NULL);
-	g_free(sql_statement);
-	return rc;
-}
-
-static int
-sqlite_log_get_max_acc_id()
-{
-	char *sql_statement = "SELECT max(Id) FROM Accounts;";
-	int id = 0;
-	int rc = sqlite3_exec(sqlite_log_db, sql_statement,
-		sqlite_log_get_id_cb, (void*)(&id), NULL);
-
-	if(rc != SQLITE_OK) {
-		purple_debug_error("sqlitelog", "fetching max account id failed");
-		return DB_EXEC_ERROR;
-	}
-	return id;
-}
-
-static gboolean
-sqlite_log_log_im(PurpleAccount *account, PurpleMessage *message)
-{
-	PurpleMessageFlags msg_flags = purple_message_get_flags(message);
-	if((msg_flags & PURPLE_MESSAGE_NO_LOG) ||
-		(msg_flags & PURPLE_MESSAGE_SYSTEM) ||
-		(msg_flags & PURPLE_MESSAGE_NOTIFY))
-		return TRUE;
-
-	char *sql_statement;
-
-	int db_account_id = sqlite_log_db_get_account_id(account);
-	if(db_account_id == DB_EXEC_ERROR)
+	unsigned account_id = SQLITELOG_DB_ID_NONE;
+	if (sqlite3_exec(sqlitelog_db_handle, query, sqlitelog_get_account_id_cb,
+		&account_id, NULL) != SQLITE_OK) {
+		g_free(query);
 		return FALSE;
-
-	if(db_account_id == DB_ID_NONE) {
-		if(sqlite_log_insert_account(account) != SQLITE_OK)
-			return FALSE;
-		if((db_account_id = sqlite_log_get_max_acc_id()) == DB_EXEC_ERROR)
-			return FALSE;
 	}
 
-	sql_statement = g_strdup_printf(
-		"INSERT INTO Messages "
-		"(Author, AuthorAlias, Recipient, Contents, MsgTime, Flags, AccountId, Read) "
-		"VALUES(\'%s\', \'%s\', \'%s\', \'%s\', %lu, %d, %d, %d);",
-		purple_message_get_author(message),
-		purple_message_get_author_alias(message),
-		purple_message_get_recipient(message),
-		purple_message_get_contents(message),
-		purple_message_get_time(message),
-		msg_flags,
-		db_account_id,
-		msg_flags & PURPLE_MESSAGE_SEND ? 1 : 0);
+	g_free(query);
 
-	if(sqlite3_exec(sqlite_log_db, sql_statement, NULL, NULL, NULL) != SQLITE_OK)
-		return FALSE;
-
-	/* here we could have a problem because of conversion from int64 to int(32bit) */
-	sqlite3_int64 db_msg_id = sqlite3_last_insert_rowid(sqlite_log_db);
-	g_object_set_data(G_OBJECT(message), "sqlitelog-msg-id", GINT_TO_POINTER(db_msg_id));
-
-	g_free(sql_statement);
+	*result = account_id;
 	return TRUE;
 }
 
 static gboolean
-sqlite_log_mark_as_seen(PurpleMessage *message)
+sqlitelog_insert_account(const PurpleAccount *account, unsigned *id)
 {
-	gpointer id = g_object_get_data(G_OBJECT(message), "sqlitelog-msg-id");
+	char *query = g_strdup_printf(
+		"INSERT INTO Accounts (Username, ProtocolId) "
+		"VALUES('%s', '%s');",
+		purple_account_get_username(account),
+		purple_account_get_protocol_id(account));
 
-	if(id == NULL)
-		return FALSE;
+	int rc = sqlite3_exec(sqlitelog_db_handle, query, NULL, NULL, NULL);
+	g_free(query);
 
-	char *sql_statement = g_strdup_printf("UPDATE Messages SET Read = 0 "
-										"WHERE Id = %d;", GPOINTER_TO_INT(id));
+	if (rc == SQLITE_OK && id)
+		*id = (unsigned) sqlite3_last_insert_rowid(sqlitelog_db_handle);
 
-	if(sqlite3_exec(sqlite_log_db, sql_statement, NULL, NULL, NULL) != SQLITE_OK) {
-		g_free(sql_statement);
-		return FALSE;
-	}
-	return TRUE;
+	return rc == SQLITE_OK;
+}
+
+static gboolean
+sqlitelog_insert_message(unsigned account_id, const PurpleMessage *msg,
+	unsigned *id)
+{
+	PurpleMessageFlags msg_flags = purple_message_get_flags(msg);
+
+	char *query = g_strdup_printf(
+		"INSERT INTO Messages (Author, AuthorAlias, Recipient, "
+		"Contents, MsgTime, Flags, Seen, AccountId) "
+		"VALUES('%s', '%s', '%s', '%s', %lu, %d, %d, %u);",
+		purple_message_get_author(msg),
+		purple_message_get_author_alias(msg),
+		purple_message_get_recipient(msg),
+		purple_message_get_contents(msg),
+		purple_message_get_time(msg),
+		msg_flags,
+		// TODO: Fix this value



More information about the Commits mailing list