static void ephy_history_service_finalize (GObject *self) { EphyHistoryServicePrivate *priv = EPHY_HISTORY_SERVICE (self)->priv; ephy_history_service_quit (EPHY_HISTORY_SERVICE (self), NULL, NULL); if (priv->history_thread) g_thread_join (priv->history_thread); g_free (priv->history_filename); G_OBJECT_CLASS (ephy_history_service_parent_class)->finalize (self); }
EphyHistoryService * ephy_history_service_new (const char *history_filename) { return EPHY_HISTORY_SERVICE (g_object_new (EPHY_TYPE_HISTORY_SERVICE, "history-filename", history_filename, NULL)); }
gboolean ephy_history_service_initialize_hosts_table (EphyHistoryService *self) { EphyHistoryServicePrivate *priv = EPHY_HISTORY_SERVICE (self)->priv; GError *error = NULL; if (ephy_sqlite_connection_table_exists (priv->history_database, "hosts")) { return TRUE; } ephy_sqlite_connection_execute (priv->history_database, "CREATE TABLE hosts (" "id INTEGER PRIMARY KEY," "url LONGVARCAR," "title LONGVARCAR," "visit_count INTEGER DEFAULT 0 NOT NULL," "zoom_level REAL DEFAULT 1.0)", &error); if (error) { g_error("Could not create hosts table: %s", error->message); g_error_free (error); return FALSE; } ephy_history_service_schedule_commit (self); return TRUE; }
GList* ephy_history_service_get_all_hosts (EphyHistoryService *self) { EphyHistoryServicePrivate *priv = EPHY_HISTORY_SERVICE (self)->priv; EphySQLiteStatement *statement = NULL; GList *hosts = 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, zoom_level FROM hosts", &error); if (error) { g_error ("Could not build hosts query statement: %s", error->message); g_error_free (error); return NULL; } while (ephy_sqlite_statement_step (statement, &error)) hosts = g_list_prepend (hosts, create_host_from_statement (statement)); hosts = g_list_reverse (hosts); if (error) { g_error ("Could not execute hosts table query statement: %s", error->message); g_error_free (error); } g_object_unref (statement); return hosts; }
static gboolean ephy_history_service_open_database_connections (EphyHistoryService *self) { EphyHistoryServicePrivate *priv = EPHY_HISTORY_SERVICE (self)->priv; GError *error = NULL; g_assert (priv->history_thread == g_thread_self ()); priv->history_database = ephy_sqlite_connection_new (); ephy_sqlite_connection_open (priv->history_database, priv->history_filename, &error); if (error) { g_object_unref (priv->history_database); priv->history_database = NULL; g_error ("Could not open history database: %s", error->message); g_error_free (error); return FALSE; } ephy_history_service_enable_foreign_keys (self); ephy_sqlite_connection_begin_transaction (priv->history_database, &error); if (error) { g_error ("Could not begin long running transaction in history database: %s", error->message); g_error_free (error); return FALSE; } if ((ephy_history_service_initialize_hosts_table (self) == FALSE) || (ephy_history_service_initialize_urls_table (self) == FALSE) || (ephy_history_service_initialize_visits_table (self) == FALSE)) return FALSE; return TRUE; }
static void test_ephy_completion_model_create (void) { EphyCompletionModel *model; model = ephy_completion_model_new (EPHY_HISTORY_SERVICE (ephy_embed_shell_get_global_history_service (ephy_embed_shell_get_default ())), ephy_shell_get_bookmarks (ephy_shell_get_default ()), TRUE); g_assert (model); g_object_unref (model); }
static void ephy_history_service_close_database_connections (EphyHistoryService *self) { EphyHistoryServicePrivate *priv = EPHY_HISTORY_SERVICE (self)->priv; g_assert (priv->history_thread == g_thread_self ()); ephy_sqlite_connection_close (priv->history_database); g_object_unref (priv->history_database); priv->history_database = NULL; }
static void ephy_history_service_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { EphyHistoryService *self = EPHY_HISTORY_SERVICE (object); switch (property_id) { case PROP_HISTORY_FILENAME: g_value_set_string (value, self->priv->history_filename); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } }
static void ephy_completion_model_init (EphyCompletionModel *model) { EphyCompletionModelPrivate *priv; EphyBookmarks *bookmarks_service; model->priv = priv = EPHY_COMPLETION_MODEL_GET_PRIVATE (model); priv->history_service = EPHY_HISTORY_SERVICE (ephy_embed_shell_get_global_history_service (ephy_embed_shell_get_default ())); bookmarks_service = ephy_shell_get_bookmarks (ephy_shell_get_default ()); priv->bookmarks = ephy_bookmarks_get_bookmarks (bookmarks_service); }
void ephy_history_service_delete_host_row (EphyHistoryService *self, EphyHistoryHost *host) { EphyHistoryServicePrivate *priv = EPHY_HISTORY_SERVICE (self)->priv; EphySQLiteStatement *statement = NULL; gchar *sql_statement; GError *error = NULL; g_assert (priv->history_thread == g_thread_self ()); g_assert (priv->history_database != NULL); g_assert (host->id != -1 || host->url); if (host->id != -1) sql_statement = g_strdup ("DELETE FROM hosts WHERE id=?"); else sql_statement = g_strdup ("DELETE FROM hosts WHERE url=?"); statement = ephy_sqlite_connection_create_statement (priv->history_database, sql_statement, &error); g_free (sql_statement); if (error) { g_error ("Could not build urls table query statement: %s", error->message); g_error_free (error); g_object_unref (statement); return; } if (host->id != -1) ephy_sqlite_statement_bind_int (statement, 0, host->id, &error); else ephy_sqlite_statement_bind_string (statement, 0, host->url, &error); if (error) { g_error ("Could not build hosts table query statement: %s", error->message); g_error_free (error); g_object_unref (statement); return; } ephy_sqlite_statement_step (statement, &error); if (error) { g_error ("Could not modify host in hosts table: %s", error->message); g_error_free (error); } g_object_unref (statement); }
static gboolean ephy_history_service_execute_quit (EphyHistoryService *self, gpointer data, gpointer *result) { EphyHistoryServicePrivate *priv = EPHY_HISTORY_SERVICE (self)->priv; g_assert (priv->history_thread == g_thread_self ()); if (ephy_history_service_is_scheduled_to_commit (self)) ephy_history_service_commit (self); g_async_queue_unref (priv->queue); self->priv->scheduled_to_quit = TRUE; return FALSE; }
static void ephy_history_service_clear_all (EphyHistoryService *self) { EphyHistoryServicePrivate *priv = EPHY_HISTORY_SERVICE (self)->priv; GError *error = NULL; if (NULL == priv->history_database) return; ephy_sqlite_connection_execute (priv->history_database, "DELETE FROM hosts;", &error); if (error) { g_error ("Couldn't clear history database: %s", error->message); g_error_free(error); } }
static void ephy_history_service_enable_foreign_keys (EphyHistoryService *self) { EphyHistoryServicePrivate *priv = EPHY_HISTORY_SERVICE (self)->priv; GError *error = NULL; if (NULL == priv->history_database) return; ephy_sqlite_connection_execute (priv->history_database, "PRAGMA foreign_keys = ON", &error); if (error) { g_error ("Could not enable foreign keys pragma: %s", error->message); g_error_free (error); } }
static void test_ephy_completion_model_update_empty (void) { EphyCompletionModel *model; GMainLoop *loop = NULL; model = ephy_completion_model_new (EPHY_HISTORY_SERVICE (ephy_embed_shell_get_global_history_service (ephy_embed_shell_get_default ())), ephy_shell_get_bookmarks (ephy_shell_get_default ()), TRUE); g_assert (model); loop = g_main_loop_new (NULL, FALSE); ephy_completion_model_update_for_string (model, "hello", (EphyHistoryJobCallback)update_empty_cb, loop); g_main_loop_run (loop); g_object_unref (model); g_main_loop_unref (loop); }
void ephy_history_service_add_host_row (EphyHistoryService *self, EphyHistoryHost *host) { EphyHistoryServicePrivate *priv = EPHY_HISTORY_SERVICE (self)->priv; EphySQLiteStatement *statement = 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, "INSERT INTO hosts (url, title, visit_count, zoom_level) " "VALUES (?, ?, ?, ?)", &error); if (error) { g_error ("Could not build hosts table addition statement: %s", error->message); g_error_free (error); return; } if (ephy_sqlite_statement_bind_string (statement, 0, host->url, &error) == FALSE || ephy_sqlite_statement_bind_string (statement, 1, host->title, &error) == FALSE || ephy_sqlite_statement_bind_int (statement, 2, host->visit_count, &error) == FALSE || ephy_sqlite_statement_bind_double (statement, 3, host->zoom_level, &error) == FALSE) { g_error ("Could not insert host into hosts table: %s", error->message); g_error_free (error); return; } ephy_sqlite_statement_step (statement, &error); if (error) { g_error ("Could not insert host into hosts table: %s", error->message); g_error_free (error); return; } else { host->id = ephy_sqlite_connection_get_last_insert_id (priv->history_database); } g_object_unref (statement); }
void ephy_history_service_update_host_row (EphyHistoryService *self, EphyHistoryHost *host) { EphyHistoryServicePrivate *priv = EPHY_HISTORY_SERVICE (self)->priv; EphySQLiteStatement *statement; 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, "UPDATE hosts SET url=?, title=?, visit_count=?, zoom_level=?" "WHERE id=?", &error); if (error) { g_error ("Could not build hosts table modification statement: %s", error->message); g_error_free (error); return; } if (ephy_sqlite_statement_bind_string (statement, 0, host->url, &error) == FALSE || ephy_sqlite_statement_bind_string (statement, 1, host->title, &error) == FALSE || ephy_sqlite_statement_bind_int (statement, 2, host->visit_count, &error) == FALSE || ephy_sqlite_statement_bind_double (statement, 3, host->zoom_level, &error) == FALSE || ephy_sqlite_statement_bind_int (statement, 4, host->id, &error) == FALSE) { g_error ("Could not modify host in hosts table: %s", error->message); g_error_free (error); return; } ephy_sqlite_statement_step (statement, &error); if (error) { g_error ("Could not modify URL in urls table: %s", error->message); g_error_free (error); } g_object_unref (statement); }
void ephy_history_service_delete_orphan_hosts (EphyHistoryService *self) { EphyHistoryServicePrivate *priv = EPHY_HISTORY_SERVICE (self)->priv; GError *error = NULL; g_assert (priv->history_thread == g_thread_self ()); g_assert (priv->history_database != NULL); /* Where a JOIN would give us all hosts with urls associated, a LEFT JOIN also gives us those hosts for which there are no urls. By means of urls.host == NULL we filter out anything else and retrieve only the ids of the hosts without associated urls. Then, we delete all these rows from the hosts table. */ ephy_sqlite_connection_execute (priv->history_database, "DELETE FROM hosts WHERE hosts.id IN " " (SELECT hosts.id FROM hosts LEFT JOIN urls " " ON hosts.id = urls.host WHERE urls.host is NULL);", &error); if (error) { g_error ("Couldn't remove orphan hosts from database: %s", error->message); g_error_free (error); } }
EphyHistoryHost* ephy_history_service_get_host_row (EphyHistoryService *self, const gchar *host_string, EphyHistoryHost *host) { EphyHistoryServicePrivate *priv = EPHY_HISTORY_SERVICE (self)->priv; EphySQLiteStatement *statement = NULL; GError *error = NULL; g_assert (priv->history_thread == g_thread_self ()); g_assert (priv->history_database != NULL); if (host_string == NULL && host != NULL) host_string = host->url; g_assert (host_string || host->id !=-1); if (host != NULL && host->id != -1) { statement = ephy_sqlite_connection_create_statement (priv->history_database, "SELECT id, url, title, visit_count, zoom_level FROM hosts " "WHERE id=?", &error); } else { statement = ephy_sqlite_connection_create_statement (priv->history_database, "SELECT id, url, title, visit_count, zoom_level FROM hosts " "WHERE url=?", &error); } if (error) { g_error ("Could not build hosts query statement: %s", error->message); g_error_free (error); return NULL; } if (host != NULL && host->id != -1) ephy_sqlite_statement_bind_int (statement, 0, host->id, &error); else ephy_sqlite_statement_bind_string (statement, 0, host_string, &error); if (error) { g_error ("Could not build hosts table query statement: %s", error->message); g_error_free (error); g_object_unref (statement); return NULL; } if (ephy_sqlite_statement_step (statement, &error) == FALSE) { g_object_unref (statement); return NULL; } if (host == NULL) { host = ephy_history_host_new (NULL, NULL, 0, 1.0); } else { if (host->url) g_free (host->url); if (host->title) g_free (host->title); } host->id = ephy_sqlite_statement_get_column_as_int (statement, 0); host->url = g_strdup (ephy_sqlite_statement_get_column_as_string (statement, 1)); host->title = g_strdup (ephy_sqlite_statement_get_column_as_string (statement, 2)); host->visit_count = ephy_sqlite_statement_get_column_as_int (statement, 3); host->zoom_level = ephy_sqlite_statement_get_column_as_double (statement, 4); g_object_unref (statement); return host; }
GList* ephy_history_service_find_host_rows (EphyHistoryService *self, EphyHistoryQuery *query) { EphyHistoryServicePrivate *priv = EPHY_HISTORY_SERVICE (self)->priv; EphySQLiteStatement *statement = NULL; GList *substring; GString *statement_str; GList *hosts = NULL; GError *error = NULL; const char *base_statement = "" "SELECT " "DISTINCT hosts.id, " "hosts.url, " "hosts.title, " "hosts.visit_count, " "hosts.zoom_level " "FROM " "hosts "; int i = 0; g_assert (priv->history_thread == g_thread_self ()); g_assert (priv->history_database != NULL); statement_str = g_string_new (base_statement); /* In either of these cases we need to at least join with the urls table. */ if (query->substring_list || query->from > 0 || query->to > 0) statement_str = g_string_append (statement_str, "JOIN urls on hosts.id = urls.host "); /* In these cases, we additionally need to join with the visits table. */ if (query->from > 0 || query->to > 0) { statement_str = g_string_append (statement_str, "JOIN visits on urls.id = visits.url WHERE "); if (query->from > 0) statement_str = g_string_append (statement_str, "visits.visit_time >= ? AND "); if (query->to > 0) statement_str = g_string_append (statement_str, "visits.visit_time <= ? AND "); } else { statement_str = g_string_append (statement_str, "WHERE "); } for (substring = query->substring_list; substring != NULL; substring = substring->next) statement_str = g_string_append (statement_str, "(hosts.url LIKE ? OR hosts.title LIKE ? OR " "urls.url LIKE ? OR urls.title LIKE ?) AND "); statement_str = g_string_append (statement_str, "1 "); statement = ephy_sqlite_connection_create_statement (priv->history_database, statement_str->str, &error); g_string_free (statement_str, TRUE); if (error) { g_error ("Could not build hosts table query statement: %s", error->message); g_error_free (error); g_object_unref (statement); return NULL; } if (query->from > 0) { if (ephy_sqlite_statement_bind_int (statement, i++, (int)query->from, &error) == FALSE) { g_error ("Could not build hosts table query statement: %s", error->message); g_error_free (error); g_object_unref (statement); return NULL; } } if (query->to > 0) { if (ephy_sqlite_statement_bind_int (statement, i++, (int)query->to, &error) == FALSE) { g_error ("Could not build hosts table query statement: %s", error->message); g_error_free (error); g_object_unref (statement); return NULL; } } for (substring = query->substring_list; substring != NULL; substring = substring->next) { int j = 4; char *string = ephy_sqlite_create_match_pattern (substring->data); while (j--) if (ephy_sqlite_statement_bind_string (statement, i++, string, &error) == FALSE) { g_error ("Could not build hosts table query statement: %s", error->message); g_error_free (error); g_object_unref (statement); g_free (string); return NULL; } g_free (string); } while (ephy_sqlite_statement_step (statement, &error)) hosts = g_list_prepend (hosts, create_host_from_statement (statement)); hosts = g_list_reverse (hosts); if (error) { g_error ("Could not execute hosts table query statement: %s", error->message); g_error_free (error); } g_object_unref (statement); return hosts; }