Commit 00a63a01 authored by Jan-Michael Brummer's avatar Jan-Michael Brummer Committed by Michael Catanzaro

Use an in memory history database for incognito mode

Fixes: #891
parent 4d9199ac
Pipeline #134006 passed with stages
in 9 minutes and 7 seconds
......@@ -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;
......
......@@ -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);
}
......
......@@ -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;
......
......@@ -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);
......
......@@ -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;
};
......
......@@ -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);
......
......@@ -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) "
......
......@@ -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);
......
......@@ -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);
......
......@@ -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 */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment