[epiphany/history-rewrite: 5/11] Add the ability to fetch a series of page visits in a time range.
- From: Xan Lopez <xan src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [epiphany/history-rewrite: 5/11] Add the ability to fetch a series of page visits in a time range.
- Date: Mon, 27 Jun 2011 18:05:30 +0000 (UTC)
commit fd92c010595b98f20dd57fa35e86564c41d08036
Author: Martin Robinson <mrobinson igalia com>
Date: Sat Apr 23 18:55:50 2011 -0700
Add the ability to fetch a series of page visits in a time range.
embed/history/ephy-history-service-private.h | 3 +-
embed/history/ephy-history-service-urls-table.c | 48 +++++++++---
embed/history/ephy-history-service-visits-table.c | 54 +++++++++++++
embed/history/ephy-history-service.c | 85 +++++++++++++++------
embed/history/ephy-history-service.h | 1 +
tests/ephy-history.c | 68 ++++++++++++++--
6 files changed, 212 insertions(+), 47 deletions(-)
---
diff --git a/embed/history/ephy-history-service-private.h b/embed/history/ephy-history-service-private.h
index b6c0667..a940bb0 100644
--- a/embed/history/ephy-history-service-private.h
+++ b/embed/history/ephy-history-service-private.h
@@ -35,11 +35,12 @@ struct _EphyHistoryServicePrivate {
void ephy_history_service_schedule_commit (EphyHistoryService *self);
gboolean ephy_history_service_initialize_urls_table (EphyHistoryService *self);
-EphyHistoryURL * ephy_history_service_get_url_row (EphyHistoryService *self, const char *url);
+EphyHistoryURL * ephy_history_service_get_url_row (EphyHistoryService *self, const char *url_string, EphyHistoryURL *url);
void ephy_history_service_add_url_row (EphyHistoryService *self, EphyHistoryURL *url);
void ephy_history_service_update_url_row (EphyHistoryService *self, EphyHistoryURL *url);
gboolean ephy_history_service_initialize_visits_table (EphyHistoryService *self);
void ephy_history_service_add_visit_row (EphyHistoryService *self, EphyHistoryPageVisit *visit);
+GList * ephy_history_service_find_visit_rows_in_time (EphyHistoryService *self, gint64 from, gint64 to);
#endif /* EPHY_HISTORY_SERVICE_PRIVATE_H */
diff --git a/embed/history/ephy-history-service-urls-table.c b/embed/history/ephy-history-service-urls-table.c
index 018a5c7..68c5a46 100644
--- a/embed/history/ephy-history-service-urls-table.c
+++ b/embed/history/ephy-history-service-urls-table.c
@@ -52,40 +52,62 @@ ephy_history_service_initialize_urls_table (EphyHistoryService *self)
}
EphyHistoryURL *
-ephy_history_service_get_url_row (EphyHistoryService *self, const char *url_string)
+ephy_history_service_get_url_row (EphyHistoryService *self, const char *url_string, EphyHistoryURL *url)
{
EphyHistoryServicePrivate *priv = EPHY_HISTORY_SERVICE (self)->priv;
EphySQLiteStatement *statement = NULL;
- EphyHistoryURL *url = NULL;
GError *error = NULL;
g_assert (priv->history_thread == g_thread_self ());
g_assert (priv->history_database != NULL);
- statement = ephy_sqlite_connection_create_statement (priv->history_database,
- "SELECT id, url, title, visit_count, typed_count, last_visit_time, favicon_id FROM urls "
- "WHERE url=?", &error);
+ if (url_string == NULL && url != NULL) {
+ url_string = url->url;
+ }
+ g_assert (url_string || url->id != -1);
+
+ if (url->id != -1) {
+ statement = ephy_sqlite_connection_create_statement (priv->history_database,
+ "SELECT id, url, title, visit_count, typed_count, last_visit_time FROM urls "
+ "WHERE id=?", &error);
+ } else {
+ statement = ephy_sqlite_connection_create_statement (priv->history_database,
+ "SELECT id, url, title, visit_count, typed_count, last_visit_time FROM urls "
+ "WHERE url=?", &error);
+ }
+
if (NULL != error) {
g_error ("Could not build urls table query statement: %s", error->message);
g_error_free (error);
return NULL;
}
- ephy_sqlite_statement_bind_string (statement, 0, url_string, &error);
+ if (url->id != -1) {
+ ephy_sqlite_statement_bind_int (statement, 0, url->id, &error);
+ } else {
+ ephy_sqlite_statement_bind_string (statement, 0, url_string, &error);
+ }
if (NULL != error) {
g_error ("Could not build urls table query statement: %s", error->message);
g_error_free (error);
+ g_object_unref (statement);
+ return NULL;
+ }
+
+ if (FALSE == ephy_sqlite_statement_step (statement, &error)) {
+ g_object_unref (statement);
return NULL;
}
- if (ephy_sqlite_statement_step (statement, &error)) {
- url = ephy_history_url_new (ephy_sqlite_statement_get_column_as_string (statement, 1),
- ephy_sqlite_statement_get_column_as_string (statement, 2),
- ephy_sqlite_statement_get_column_as_int (statement, 3),
- ephy_sqlite_statement_get_column_as_int (statement, 4),
- ephy_sqlite_statement_get_column_as_int (statement, 5));
- url->id = ephy_sqlite_statement_get_column_as_int (statement, 0);
+ if (url == NULL) {
+ url = ephy_history_url_new (NULL, NULL, 0, 0, 0);
}
+ url->id = ephy_sqlite_statement_get_column_as_int (statement, 0);
+ url->url = g_strdup (ephy_sqlite_statement_get_column_as_string (statement, 1)),
+ url->title = g_strdup (ephy_sqlite_statement_get_column_as_string (statement, 2)),
+ url->visit_count = ephy_sqlite_statement_get_column_as_int (statement, 3),
+ url->typed_count = ephy_sqlite_statement_get_column_as_int (statement, 4),
+ url->last_visit_time = ephy_sqlite_statement_get_column_as_int (statement, 5);
g_object_unref (statement);
return url;
diff --git a/embed/history/ephy-history-service-visits-table.c b/embed/history/ephy-history-service-visits-table.c
index a55fd6b..94fa8c7 100644
--- a/embed/history/ephy-history-service-visits-table.c
+++ b/embed/history/ephy-history-service-visits-table.c
@@ -88,3 +88,57 @@ ephy_history_service_add_visit_row (EphyHistoryService *self, EphyHistoryPageVis
ephy_history_service_schedule_commit (self);
g_object_unref (statement);
}
+
+static EphyHistoryPageVisit *
+create_page_visit_from_statement (EphySQLiteStatement *statement)
+{
+ EphyHistoryPageVisit *visit =
+ ephy_history_page_visit_new (NULL,
+ ephy_sqlite_statement_get_column_as_int (statement, 1),
+ ephy_sqlite_statement_get_column_as_int (statement, 2));
+ visit->url->id = ephy_sqlite_statement_get_column_as_int (statement, 0);
+ return visit;
+}
+
+GList *
+ephy_history_service_find_visit_rows_in_time (EphyHistoryService *self, gint64 from, gint64 to)
+{
+ EphyHistoryServicePrivate *priv = EPHY_HISTORY_SERVICE (self)->priv;
+ EphySQLiteStatement *statement = NULL;
+ GList *visits = NULL;
+ GError *error = NULL;
+
+ g_assert (priv->history_thread == g_thread_self ());
+ g_assert (priv->history_database != NULL);
+
+ statement = ephy_sqlite_connection_create_statement (priv->history_database,
+ "SELECT url, visit_time, visit_type FROM visits WHERE visit_time >= ? and visit_time <= ?", &error);
+ if (NULL != error) {
+ g_error ("Could not build visits table query statement: %s", error->message);
+ g_error_free (error);
+ return NULL;
+ }
+
+ if (FALSE == ephy_sqlite_statement_bind_int (statement, 0, (int) from, &error) ||
+ FALSE == ephy_sqlite_statement_bind_int (statement, 1, (int) to, &error)) {
+ g_error ("Could not build urls table query statement: %s", error->message);
+ g_error_free (error);
+ g_object_unref (statement);
+ return NULL;
+ }
+
+ while (ephy_sqlite_statement_step (statement, &error)) {
+ visits = g_list_append (visits, create_page_visit_from_statement (statement));
+ }
+
+ if (NULL != error) {
+ g_error ("Could not execute urls table query statement: %s", error->message);
+ g_error_free (error);
+ g_object_unref (statement);
+ ephy_history_page_visit_list_free (visits);
+ return NULL;
+ }
+
+ g_object_unref (statement);
+ return visits;
+}
diff --git a/embed/history/ephy-history-service.c b/embed/history/ephy-history-service.c
index 4b85c71..a95101d 100644
--- a/embed/history/ephy-history-service.c
+++ b/embed/history/ephy-history-service.c
@@ -1,5 +1,4 @@
-/*
- * Copyright  2011 Igalia S.L.
+/* * Copyright  2011 Igalia S.L.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,7 +24,7 @@
#include "ephy-history-types.h"
#include "../sqlite/ephy-sqlite-connection.h"
-typedef gpointer (*EphyHistoryJobMethod) (EphyHistoryService *self, gpointer data, gboolean *result);
+typedef gboolean (*EphyHistoryJobMethod) (EphyHistoryService *self, gpointer data, gpointer *result);
static void ephy_history_service_class_init (EphyHistoryServiceClass *klass);
static void ephy_history_service_init (EphyHistoryService *self);
@@ -370,8 +369,8 @@ ephy_history_service_execute_job_on_history_thread (gpointer data)
/* TODO: Here we must check if the history thread is shutting down
in which case we need to free the details and abort */
- details->success = TRUE; /* Successful by default */
- details->result = details->method (details->service, details->method_argument, &details->success);
+ details->result = NULL;
+ details->success = details->method (details->service, details->method_argument, &details->result);
if (details->callback) {
g_idle_add (ephy_history_service_execute_job_callback, details);
@@ -385,9 +384,8 @@ ephy_history_service_execute_job_on_history_thread (gpointer data)
static gboolean
ephy_history_service_execute_add_visit_helper (EphyHistoryService *self, EphyHistoryPageVisit *visit)
{
- EphyHistoryURL *url = ephy_history_service_get_url_row (self, visit->url->url);
-
- if (NULL == url) { /* This URL does not yet exist in the history table */
+ /* A NULL return here means that the URL does not yet exist in the database */
+ if (NULL == ephy_history_service_get_url_row (self, visit->url->url, visit->url)) {
visit->url->last_visit_time = visit->visit_time;
ephy_history_service_add_url_row (self, visit->url);
@@ -397,42 +395,63 @@ ephy_history_service_execute_add_visit_helper (EphyHistoryService *self, EphyHis
}
} else {
- url->visit_count++;
- if (visit->visit_time > url->last_visit_time) {
- url->last_visit_time = visit->visit_time;
+ visit->url->visit_count++;
+ if (visit->visit_time > visit->url->last_visit_time) {
+ visit->url->last_visit_time = visit->visit_time;
}
- ephy_history_service_update_url_row (self, url);
-
- visit->url->id = url->id;
- ephy_history_url_free (url);
+ ephy_history_service_update_url_row (self, visit->url);
}
-
ephy_history_service_add_visit_row (self, visit);
return visit->id != -1;
}
-static gpointer
-ephy_history_service_execute_add_visit (EphyHistoryService *self, EphyHistoryPageVisit *visit, gboolean *success)
+static gboolean
+ephy_history_service_execute_add_visit (EphyHistoryService *self, EphyHistoryPageVisit *visit, gpointer *result)
{
+ gboolean success;
g_assert (self->priv->history_thread == g_thread_self ());
- *success = ephy_history_service_execute_add_visit_helper (self, visit);
+
+ success = ephy_history_service_execute_add_visit_helper (self, visit);
ephy_history_service_schedule_commit (self);
- return NULL;
+ return success;
}
-static gpointer
-ephy_history_service_execute_add_visits (EphyHistoryService *self, GList *visits, gboolean *success)
+static gboolean
+ephy_history_service_execute_add_visits (EphyHistoryService *self, GList *visits, gpointer *result)
{
+ gboolean success = TRUE;
g_assert (self->priv->history_thread == g_thread_self ());
while (visits) {
- *success = success && ephy_history_service_execute_add_visit_helper (self, (EphyHistoryPageVisit *) visits->data);
+ success = success && ephy_history_service_execute_add_visit_helper (self, (EphyHistoryPageVisit *) visits->data);
visits = visits->next;
}
ephy_history_service_schedule_commit (self);
- return NULL;
+ return success;
+}
+
+static gboolean
+ephy_history_service_execute_find_visits_in_time (EphyHistoryService *self, gint64 *times, gpointer *result)
+{
+ GList *visits = ephy_history_service_find_visit_rows_in_time (self, times[0], times[1]);
+ GList *current = visits;
+
+ /* FIXME: We don't have a good way to tell the difference between failures and empty returns */
+ while (current) {
+ EphyHistoryPageVisit *visit = (EphyHistoryPageVisit *) current->data;
+ if (NULL == ephy_history_service_get_url_row (self, NULL, visit->url)) {
+ ephy_history_page_visit_list_free (visits);
+ g_error ("Tried to process an orphaned page visit");
+ return FALSE;
+ }
+
+ current = current->next;
+ }
+
+ *result = visits;
+ return TRUE;
}
void
@@ -463,3 +482,21 @@ ephy_history_service_add_visits (EphyHistoryService *self, GList *visits, EphyHi
details);
}
+
+void
+ephy_history_service_find_visits_in_time (EphyHistoryService *self, gint64 from, gint64 to, EphyHistoryJobCallback callback)
+{
+ EphyHistoryThreadJobDetails *details;
+
+ gint64 *times = g_malloc(2 * sizeof(gint64));
+ times[0] = from;
+ times[1] = to;
+
+ details = ephy_history_thread_job_details_new (self,
+ (EphyHistoryJobMethod) ephy_history_service_execute_find_visits_in_time,
+ times, g_free, callback);
+ ephy_history_service_schedule_idle (self, G_PRIORITY_DEFAULT,
+ ephy_history_service_execute_job_on_history_thread,
+ details);
+
+}
diff --git a/embed/history/ephy-history-service.h b/embed/history/ephy-history-service.h
index d0f4981..ee065f9 100644
--- a/embed/history/ephy-history-service.h
+++ b/embed/history/ephy-history-service.h
@@ -56,6 +56,7 @@ EphyHistoryService * ephy_history_service_new (const cha
void ephy_history_service_add_visit (EphyHistoryService *self, EphyHistoryPageVisit *visit, EphyHistoryJobCallback callback);
void ephy_history_service_add_visits (EphyHistoryService *self, GList *visits, EphyHistoryJobCallback callback);
+void ephy_history_service_find_visits_in_time (EphyHistoryService *self, gint64 from, gint64 to, EphyHistoryJobCallback callback);
G_END_DECLS
diff --git a/tests/ephy-history.c b/tests/ephy-history.c
index 8220538..e20c4ac 100644
--- a/tests/ephy-history.c
+++ b/tests/ephy-history.c
@@ -90,21 +90,71 @@ test_create_history_entry (void)
gtk_main ();
}
+static GList *
+create_test_page_visit_list ()
+{
+ GList *visits = NULL;
+ int i;
+ for (i = 0; i < 100; i++) {
+ visits = g_list_append (visits, ephy_history_page_visit_new ("http://www.gnome.org", 3, EphyPageVisitTypeTyped));
+ visits = g_list_append (visits, ephy_history_page_visit_new ("http://www.gnome.org", 5, EphyPageVisitTypeTyped));
+ visits = g_list_append (visits, ephy_history_page_visit_new ("http://www.cuteoverload.com", 7, EphyPageVisitTypeTyped));
+ visits = g_list_append (visits, ephy_history_page_visit_new ("http://www.cuteoverload.com", 8, EphyPageVisitTypeTyped));
+ }
+ return visits;
+}
+
+static void
+verify_create_history_entry_cb (EphyHistoryService *service, gboolean success, gpointer result)
+{
+ GList *visits = (GList *) result;
+ GList *baseline_visits = create_test_page_visit_list ();
+ GList *current = visits;
+ GList *current_baseline = baseline_visits;
+
+ g_assert (success);
+ g_assert (visits != NULL);
+ g_assert_cmpint (g_list_length (visits), ==, g_list_length (baseline_visits));
+
+ while (current_baseline) {
+ EphyHistoryPageVisit *visit, *baseline_visit;
+
+ g_assert (current);
+ visit = (EphyHistoryPageVisit *) current->data;
+ baseline_visit = (EphyHistoryPageVisit *) current_baseline->data;
+
+ g_assert_cmpstr (visit->url->url, ==, baseline_visit->url->url);
+ g_assert_cmpstr (visit->url->title, ==, baseline_visit->url->title);
+ g_assert_cmpint (visit->visit_time, ==, baseline_visit->visit_time);
+ g_assert_cmpint (visit->visit_type, ==, baseline_visit->visit_type);
+
+ current = current->next;
+ current_baseline = current_baseline->next;
+ }
+
+ ephy_history_page_visit_list_free (visits);
+ ephy_history_page_visit_list_free (baseline_visits);
+
+ g_object_unref (service);
+ gtk_main_quit ();
+}
+
+static void
+verify_create_history_entry (EphyHistoryService *service, gboolean success, gpointer result)
+{
+ g_assert (result == NULL);
+ g_assert (success);
+ ephy_history_service_find_visits_in_time (service, 0, 8, verify_create_history_entry_cb);
+}
+
static void
test_create_history_entries (void)
{
gchar *temporary_file = g_build_filename (g_get_tmp_dir (), "epiphany-history-test.db", NULL);
EphyHistoryService *service = ensure_empty_history(temporary_file);
- GList *visits = NULL;
- visits = g_list_append (visits, ephy_history_page_visit_new ("http://www.gnome.org", 0, EphyPageVisitTypeTyped));
- visits = g_list_append (visits, ephy_history_page_visit_new ("http://www.gnome.org", 3, EphyPageVisitTypeTyped));
- visits = g_list_append (visits, ephy_history_page_visit_new ("http://www.gnome.org", 5, EphyPageVisitTypeTyped));
- visits = g_list_append (visits, ephy_history_page_visit_new ("http://www.cuteoverload.com", 7, EphyPageVisitTypeTyped));
- visits = g_list_append (visits, ephy_history_page_visit_new ("http://www.cuteoverload.com", 8, EphyPageVisitTypeTyped));
-
- ephy_history_service_add_visits (service, visits, page_vist_created);
-
+ GList *visits = create_test_page_visit_list ();
+ ephy_history_service_add_visits (service, visits, verify_create_history_entry);
ephy_history_page_visit_list_free (visits);
gtk_main ();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]