[epiphany] Use an in memory history database for incognito mode



commit 00a63a019221b53e4636d89000b4a9829905dd18
Author: Jan-Michael Brummer <jan brummer tabos org>
Date:   Thu Nov 14 20:16:00 2019 +0100

    Use an in memory history database for incognito mode
    
    Fixes: https://gitlab.gnome.org/GNOME/epiphany/issues/891

 embed/ephy-embed-shell.c                        |  2 +-
 lib/ephy-sqlite-connection.c                    | 29 ++++++++++---
 lib/ephy-sqlite-connection.h                    |  2 +-
 lib/history/ephy-history-service-hosts-table.c  |  3 +-
 lib/history/ephy-history-service-private.h      |  2 +-
 lib/history/ephy-history-service-urls-table.c   |  6 +++
 lib/history/ephy-history-service-visits-table.c |  3 ++
 lib/history/ephy-history-service.c              | 58 +++++++------------------
 src/bookmarks/ephy-bookmarks-import.c           |  2 +-
 tests/ephy-history-test.c                       |  2 +-
 10 files changed, 53 insertions(+), 56 deletions(-)
---
diff --git a/embed/ephy-embed-shell.c b/embed/ephy-embed-shell.c
index 22e20a38b..74e12a80d 100644
--- a/embed/ephy-embed-shell.c
+++ b/embed/ephy-embed-shell.c
@@ -790,7 +790,7 @@ ephy_embed_shell_get_global_history_service (EphyEmbedShell *shell)
     if (priv->mode == EPHY_EMBED_SHELL_MODE_INCOGNITO ||
         priv->mode == EPHY_EMBED_SHELL_MODE_AUTOMATION ||
         priv->mode == EPHY_EMBED_SHELL_MODE_SEARCH_PROVIDER)
-      mode = EPHY_SQLITE_CONNECTION_MODE_READ_ONLY;
+      mode = EPHY_SQLITE_CONNECTION_MODE_MEMORY;
     else
       mode = EPHY_SQLITE_CONNECTION_MODE_READWRITE;
 
diff --git a/lib/ephy-sqlite-connection.c b/lib/ephy-sqlite-connection.c
index bf6c59746..06574936f 100644
--- a/lib/ephy-sqlite-connection.c
+++ b/lib/ephy-sqlite-connection.c
@@ -141,14 +141,35 @@ ephy_sqlite_connection_open (EphySQLiteConnection  *self,
 
   if (sqlite3_open_v2 (self->database_path,
                        &self->database,
-                       self->mode == EPHY_SQLITE_CONNECTION_MODE_READ_ONLY ? SQLITE_OPEN_READONLY
-                                                                           : SQLITE_OPEN_READWRITE | 
SQLITE_OPEN_CREATE,
+                       self->mode == EPHY_SQLITE_CONNECTION_MODE_MEMORY ? SQLITE_OPEN_READWRITE | 
SQLITE_OPEN_CREATE | SQLITE_OPEN_MEMORY
+                                                                        : SQLITE_OPEN_READWRITE | 
SQLITE_OPEN_CREATE,
                        NULL) != SQLITE_OK) {
     ephy_sqlite_connection_get_error (self, error);
     self->database = NULL;
     return FALSE;
   }
 
+  /* Create a local copy of current database for in memory usage */
+  if (self->mode == EPHY_SQLITE_CONNECTION_MODE_MEMORY) {
+    sqlite3 *init_db;
+    int rc;
+
+    rc = sqlite3_open_v2 (self->database_path, &init_db, SQLITE_OPEN_READONLY, 0);
+    if (rc == SQLITE_OK) {
+      sqlite3_backup *backup;
+
+      backup = sqlite3_backup_init (self->database, "main", init_db, "main");
+      rc = sqlite3_backup_step (backup, -1);
+
+      if (rc != SQLITE_DONE)
+        g_warning ("Failed to copy history to in-memory database: %s", sqlite3_errstr (rc));
+
+      sqlite3_backup_finish (backup);
+    }
+
+    sqlite3_close (init_db);
+  }
+
   return TRUE;
 }
 
@@ -250,8 +271,6 @@ gboolean
 ephy_sqlite_connection_begin_transaction (EphySQLiteConnection  *self,
                                           GError               **error)
 {
-  if (self->mode == EPHY_SQLITE_CONNECTION_MODE_READ_ONLY)
-    return TRUE;
   return ephy_sqlite_connection_execute (self, "BEGIN TRANSACTION", error);
 }
 
@@ -259,8 +278,6 @@ gboolean
 ephy_sqlite_connection_commit_transaction (EphySQLiteConnection  *self,
                                            GError               **error)
 {
-  if (self->mode == EPHY_SQLITE_CONNECTION_MODE_READ_ONLY)
-    return TRUE;
   return ephy_sqlite_connection_execute (self, "COMMIT", error);
 }
 
diff --git a/lib/ephy-sqlite-connection.h b/lib/ephy-sqlite-connection.h
index 868a45a2f..923ec0696 100644
--- a/lib/ephy-sqlite-connection.h
+++ b/lib/ephy-sqlite-connection.h
@@ -32,7 +32,7 @@ G_BEGIN_DECLS
 G_DECLARE_FINAL_TYPE (EphySQLiteConnection, ephy_sqlite_connection, EPHY, SQLITE_CONNECTION, GObject)
 
 typedef enum {
-  EPHY_SQLITE_CONNECTION_MODE_READ_ONLY,
+  EPHY_SQLITE_CONNECTION_MODE_MEMORY,
   EPHY_SQLITE_CONNECTION_MODE_READWRITE
 } EphySQLiteConnectionMode;
 
diff --git a/lib/history/ephy-history-service-hosts-table.c b/lib/history/ephy-history-service-hosts-table.c
index d19f7235d..e4a66ea78 100644
--- a/lib/history/ephy-history-service-hosts-table.c
+++ b/lib/history/ephy-history-service-hosts-table.c
@@ -418,8 +418,7 @@ ephy_history_service_get_host_row_from_url (EphyHistoryService *self,
 
   if (host == NULL) {
     host = ephy_history_host_new (host_locations->data, hostname, 0, 0.0);
-    if (!self->read_only)
-      ephy_history_service_add_host_row (self, host);
+    ephy_history_service_add_host_row (self, host);
   }
 
   g_free (hostname);
diff --git a/lib/history/ephy-history-service-private.h b/lib/history/ephy-history-service-private.h
index 9a9f2146c..b337d0ca2 100644
--- a/lib/history/ephy-history-service-private.h
+++ b/lib/history/ephy-history-service-private.h
@@ -34,7 +34,7 @@ struct _EphyHistoryService {
   GThread *history_thread;
   GAsyncQueue *queue;
   gboolean scheduled_to_quit;
-  gboolean read_only;
+  gboolean in_memory;
   int queue_urls_visited_id;
 };
 
diff --git a/lib/history/ephy-history-service-urls-table.c b/lib/history/ephy-history-service-urls-table.c
index add6fa15f..8047074f7 100644
--- a/lib/history/ephy-history-service-urls-table.c
+++ b/lib/history/ephy-history-service-urls-table.c
@@ -134,6 +134,9 @@ ephy_history_service_add_url_row (EphyHistoryService *self,
   g_assert (self->history_thread == g_thread_self ());
   g_assert (self->history_database != NULL);
 
+  if (self->in_memory)
+    return;
+
   statement = ephy_sqlite_connection_create_statement (self->history_database,
                                                        "INSERT INTO urls (url, title, visit_count, 
typed_count, last_visit_time, host, sync_id) "
                                                        " VALUES (?, ?, ?, ?, ?, ?, ?)", &error);
@@ -177,6 +180,9 @@ ephy_history_service_update_url_row (EphyHistoryService *self,
   g_assert (self->history_thread == g_thread_self ());
   g_assert (self->history_database != NULL);
 
+  if (self->in_memory)
+    return;
+
   statement = ephy_sqlite_connection_create_statement (self->history_database,
                                                        "UPDATE urls SET title=?, visit_count=?, 
typed_count=?, last_visit_time=?, hidden_from_overview=?, sync_id=? "
                                                        "WHERE id=?", &error);
diff --git a/lib/history/ephy-history-service-visits-table.c b/lib/history/ephy-history-service-visits-table.c
index d6fd01b47..53e95a160 100644
--- a/lib/history/ephy-history-service-visits-table.c
+++ b/lib/history/ephy-history-service-visits-table.c
@@ -58,6 +58,9 @@ ephy_history_service_add_visit_row (EphyHistoryService   *self,
   g_assert (self->history_thread == g_thread_self ());
   g_assert (self->history_database != NULL);
 
+  if (self->in_memory)
+    return;
+
   statement = ephy_sqlite_connection_create_statement (
     self->history_database,
     "INSERT INTO visits (url, visit_time, visit_type) "
diff --git a/lib/history/ephy-history-service.c b/lib/history/ephy-history-service.c
index 218217b4e..340618e6f 100644
--- a/lib/history/ephy-history-service.c
+++ b/lib/history/ephy-history-service.c
@@ -95,7 +95,7 @@ static void ephy_history_service_quit (EphyHistoryService    *self,
 enum {
   PROP_0,
   PROP_HISTORY_FILENAME,
-  PROP_READ_ONLY,
+  PROP_MEMORY,
   LAST_PROP
 };
 
@@ -116,8 +116,8 @@ ephy_history_service_set_property (GObject      *object,
       g_free (self->history_filename);
       self->history_filename = g_value_dup_string (value);
       break;
-    case PROP_READ_ONLY:
-      self->read_only = g_value_get_boolean (value);
+    case PROP_MEMORY:
+      self->in_memory = g_value_get_boolean (value);
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (self, property_id, pspec);
@@ -300,10 +300,10 @@ ephy_history_service_class_init (EphyHistoryServiceClass *klass)
                          NULL,
                          G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
 
-  obj_properties[PROP_READ_ONLY] =
-    g_param_spec_boolean ("read-only",
-                          "Read only mode",
-                          "Whether the history service works in read only mode",
+  obj_properties[PROP_MEMORY] =
+    g_param_spec_boolean ("memory",
+                          "In memory mode",
+                          "Whether the history service works in memory mode",
                           FALSE,
                           G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS);
 
@@ -321,7 +321,7 @@ ephy_history_service_new (const char               *history_filename,
 {
   return EPHY_HISTORY_SERVICE (g_object_new (EPHY_TYPE_HISTORY_SERVICE,
                                              "history-filename", history_filename,
-                                             "read-only", mode == EPHY_SQLITE_CONNECTION_MODE_READ_ONLY,
+                                             "memory", mode == EPHY_SQLITE_CONNECTION_MODE_MEMORY,
                                              NULL));
 }
 
@@ -380,8 +380,7 @@ ephy_history_service_open_transaction (EphyHistoryService *self)
   GError *error = NULL;
   g_assert (self->history_thread == g_thread_self ());
 
-  if (self->history_database == NULL ||
-      self->read_only)
+  if (self->history_database == NULL)
     return;
 
   ephy_sqlite_connection_begin_transaction (self->history_database, &error);
@@ -397,8 +396,7 @@ ephy_history_service_commit_transaction (EphyHistoryService *self)
   GError *error = NULL;
   g_assert (self->history_thread == g_thread_self ());
 
-  if (self->history_database == NULL ||
-      self->read_only)
+  if (self->history_database == NULL)
     return;
 
   ephy_sqlite_connection_commit_transaction (self->history_database, &error);
@@ -418,7 +416,7 @@ ephy_history_service_open_database_connections (EphyHistoryService *self)
   if (self->history_database != NULL)
     g_object_unref (self->history_database);
 
-  self->history_database = ephy_sqlite_connection_new (self->read_only ? 
EPHY_SQLITE_CONNECTION_MODE_READ_ONLY
+  self->history_database = ephy_sqlite_connection_new (self->in_memory ? EPHY_SQLITE_CONNECTION_MODE_MEMORY
                                                                        : 
EPHY_SQLITE_CONNECTION_MODE_READWRITE,
                                                        self->history_filename);
   ephy_sqlite_connection_open (self->history_database, &error);
@@ -426,10 +424,7 @@ ephy_history_service_open_database_connections (EphyHistoryService *self)
     g_object_unref (self->history_database);
     self->history_database = NULL;
 
-    /* Opening the database is expected to fail if it's being opened in read-
-     * only mode and does not already exist. Otherwise, this is bad. */
-    if (!self->read_only ||
-        !g_error_matches (error, EPHY_SQLITE_ERROR, SQLITE_CANTOPEN) ||
+    if (!g_error_matches (error, EPHY_SQLITE_ERROR, SQLITE_CANTOPEN) ||
         g_file_test (self->history_filename, G_FILE_TEST_EXISTS)) {
       g_warning ("Could not open history database at %s: %s", self->history_filename, error->message);
     }
@@ -439,8 +434,7 @@ ephy_history_service_open_database_connections (EphyHistoryService *self)
     ephy_sqlite_connection_enable_foreign_keys (self->history_database);
   }
 
-  return self->read_only ||
-         (ephy_history_service_initialize_hosts_table (self) &&
+  return (ephy_history_service_initialize_hosts_table (self) &&
           ephy_history_service_initialize_urls_table (self) &&
           ephy_history_service_initialize_visits_table (self));
 }
@@ -591,7 +585,7 @@ ephy_history_service_execute_add_visit_helper (EphyHistoryService   *self,
 
     ephy_history_service_add_url_row (self, visit->url);
 
-    if (visit->url->id == -1) {
+    if (!self->in_memory && visit->url->id == -1) {
       g_warning ("Adding visit failed after failed URL addition.");
       return FALSE;
     }
@@ -622,9 +616,6 @@ ephy_history_service_execute_add_visit (EphyHistoryService   *self,
   gboolean success;
   g_assert (self->history_thread == g_thread_self ());
 
-  if (self->read_only)
-    return FALSE;
-
   success = ephy_history_service_execute_add_visit_helper (self, visit);
   return success;
 }
@@ -637,9 +628,6 @@ ephy_history_service_execute_add_visits (EphyHistoryService *self,
   gboolean success = TRUE;
   g_assert (self->history_thread == g_thread_self ());
 
-  if (self->read_only)
-    return FALSE;
-
   while (visits) {
     success = success && ephy_history_service_execute_add_visit_helper (self, (EphyHistoryPageVisit 
*)visits->data);
     visits = visits->next;
@@ -854,9 +842,6 @@ ephy_history_service_execute_set_url_title (EphyHistoryService *self,
 {
   char *title = g_strdup (url->title);
 
-  if (self->read_only)
-    return FALSE;
-
   if (ephy_history_service_get_url_row (self, NULL, url) == NULL) {
     /* The URL is not yet in the database, so we can't update it.. */
     g_free (title);
@@ -910,9 +895,6 @@ ephy_history_service_execute_set_url_zoom_level (EphyHistoryService *self,
   double zoom_level;
   EphyHistoryHost *host;
 
-  if (self->read_only)
-    return FALSE;
-
   g_variant_get (variant, "(sd)", &url_string, &zoom_level);
 
   host = ephy_history_service_get_host_row_from_url (self, url_string);
@@ -959,9 +941,6 @@ ephy_history_service_execute_set_url_hidden (EphyHistoryService *self,
 {
   gboolean hidden;
 
-  if (self->read_only)
-    return FALSE;
-
   hidden = url->hidden;
 
   if (ephy_history_service_get_url_row (self, NULL, url) == NULL) {
@@ -1081,9 +1060,6 @@ ephy_history_service_execute_delete_urls (EphyHistoryService *self,
   EphyHistoryURL *url;
   SignalEmissionContext *ctx;
 
-  if (self->read_only)
-    return FALSE;
-
   for (l = urls; l != NULL; l = l->next) {
     url = l->data;
     ephy_history_service_delete_url (self, url);
@@ -1121,9 +1097,6 @@ ephy_history_service_execute_delete_host (EphyHistoryService     *self,
 {
   SignalEmissionContext *ctx;
 
-  if (self->read_only)
-    return FALSE;
-
   ephy_history_service_delete_host_row (self, host);
 
   ctx = signal_emission_context_new (self, g_strdup (host->url),
@@ -1141,8 +1114,7 @@ ephy_history_service_execute_clear (EphyHistoryService *self,
                                     gpointer            pointer,
                                     gpointer           *result)
 {
-  if (self->history_database == NULL ||
-      self->read_only)
+  if (self->history_database == NULL)
     return FALSE;
 
   ephy_history_service_commit_transaction (self);
diff --git a/src/bookmarks/ephy-bookmarks-import.c b/src/bookmarks/ephy-bookmarks-import.c
index 055bbe327..20c884615 100644
--- a/src/bookmarks/ephy-bookmarks-import.c
+++ b/src/bookmarks/ephy-bookmarks-import.c
@@ -235,7 +235,7 @@ ephy_bookmarks_import_from_firefox (EphyBookmarksManager  *manager,
                                FIREFOX_BOOKMARKS_FILE,
                                NULL);
 
-  connection = ephy_sqlite_connection_new (EPHY_SQLITE_CONNECTION_MODE_READ_ONLY, filename);
+  connection = ephy_sqlite_connection_new (EPHY_SQLITE_CONNECTION_MODE_MEMORY, filename);
   ephy_sqlite_connection_open (connection, &my_error);
   if (my_error) {
     g_warning ("Could not open database at %s: %s", filename, my_error->message);
diff --git a/tests/ephy-history-test.c b/tests/ephy-history-test.c
index 70bd2976b..1497e8cd5 100644
--- a/tests/ephy-history-test.c
+++ b/tests/ephy-history-test.c
@@ -102,7 +102,7 @@ static void
 test_readonly_mode (void)
 {
   EphyHistoryService *service = ensure_empty_history (test_db_filename ());
-  EphyHistoryService *readonly_service = ephy_history_service_new (test_db_filename (), 
EPHY_SQLITE_CONNECTION_MODE_READ_ONLY);
+  EphyHistoryService *readonly_service = ephy_history_service_new (test_db_filename (), 
EPHY_SQLITE_CONNECTION_MODE_MEMORY);
 
   /* Having the database open read-only should not break normal connections.
    * https://bugzilla.gnome.org/show_bug.cgi?id=778649 */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]