static gboolean ephy_history_service_execute_find_visits (EphyHistoryService *self, EphyHistoryQuery *query, gpointer *result) { GList *visits = ephy_history_service_find_visit_rows (self, query); 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; }
GList * ephy_history_service_find_visit_rows (EphyHistoryService *self, EphyHistoryQuery *query) { EphySQLiteStatement *statement = NULL; GList *substring; GString *statement_str; GList *visits = NULL; GError *error = NULL; const char *base_statement = "" "SELECT " "visits.url, " "visits.visit_time, " "visits.visit_type "; const char *from_join_statement = "" "FROM " "visits JOIN urls ON visits.url = urls.id "; const char *from_visits_statement = "" "FROM " "visits "; int i = 0; g_assert (self->history_thread == g_thread_self ()); g_assert (self->history_database != NULL); statement_str = g_string_new (base_statement); if (query->substring_list) statement_str = g_string_append (statement_str, from_join_statement); else statement_str = g_string_append (statement_str, from_visits_statement); statement_str = g_string_append (statement_str, "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 "); if (query->host > 0) statement_str = g_string_append (statement_str, "urls.host = ? AND "); for (substring = query->substring_list; substring != NULL; substring = substring->next) { statement_str = g_string_append (statement_str, "(urls.url LIKE ? OR urls.title LIKE ?) AND "); } statement_str = g_string_append (statement_str, "1"); statement = ephy_sqlite_connection_create_statement (self->history_database, statement_str->str, &error); g_string_free (statement_str, TRUE); if (error) { g_warning ("Could not build visits table query statement: %s", error->message); g_error_free (error); return NULL; } if (query->from >= 0) { if (ephy_sqlite_statement_bind_int64 (statement, i++, query->from, &error) == FALSE) { g_warning ("Could not build urls 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_int64 (statement, i++, query->to, &error) == FALSE) { g_warning ("Could not build urls table query statement: %s", error->message); g_error_free (error); g_object_unref (statement); return NULL; } } if (query->host > 0) { if (ephy_sqlite_statement_bind_int (statement, i++, (int)query->host, &error) == FALSE) { g_warning ("Could not build urls 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) { char *string = ephy_sqlite_create_match_pattern (substring->data); if (ephy_sqlite_statement_bind_string (statement, i++, string, &error) == FALSE) { g_warning ("Could not build urls table query statement: %s", error->message); g_error_free (error); g_object_unref (statement); g_free (string); return NULL; } if (ephy_sqlite_statement_bind_string (statement, i++, string + 2, &error) == FALSE) { g_warning ("Could not build urls 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)) visits = g_list_prepend (visits, create_page_visit_from_statement (statement)); visits = g_list_reverse (visits); if (error) { g_warning ("Could not execute visits 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; }
static void migrate_history () { GFileInputStream *input; GMarkupParseContext *context; GError *error = NULL; GFile *file; char *filename; char buffer[1024]; HistoryParseData parse_data; gchar *temporary_file = g_build_filename (ephy_dot_dir (), "ephy-history.db", NULL); /* Do nothing if the history file already exists. Safer than wiping * it out. */ if (g_file_test (temporary_file, G_FILE_TEST_EXISTS)) { g_warning ("Did not migrate Epiphany's history, the ephy-history.db file already exists"); g_free (temporary_file); return; } history_service = ephy_history_service_new (temporary_file); g_free (temporary_file); memset (&parse_data, 0, sizeof (HistoryParseData)); parse_data.location = NULL; parse_data.title = NULL; parse_data.visits = NULL; filename = g_build_filename (ephy_dot_dir (), "ephy-history.xml", NULL); file = g_file_new_for_path (filename); g_free (filename); input = g_file_read (file, NULL, &error); g_object_unref (file); if (error) { if (error->code != G_IO_ERROR_NOT_FOUND) g_warning ("Could not load Epiphany history data, migration aborted: %s", error->message); g_error_free (error); return; } context = g_markup_parse_context_new (&history_parse_funcs, 0, &parse_data, NULL); while (TRUE) { gssize count = g_input_stream_read (G_INPUT_STREAM (input), buffer, sizeof (buffer), NULL, &error); if (count <= 0) break; if (!g_markup_parse_context_parse (context, buffer, count, &error)) break; } g_markup_parse_context_free (context); g_input_stream_close (G_INPUT_STREAM (input), NULL, NULL); g_object_unref (input); if (parse_data.visits) { ephy_history_service_add_visits (history_service, parse_data.visits, NULL, (EphyHistoryJobCallback)visit_cb, NULL); ephy_history_page_visit_list_free (parse_data.visits); while (!all_done) g_main_context_iteration (NULL, FALSE); } g_object_unref (history_service); }