Files
RSSuper/linux/src/database/search-history-store.vala
Michael Freno c2e1622bd8
Some checks failed
CI - Multi-Platform Native / Build iOS (RSSuper) (push) Has been cancelled
CI - Multi-Platform Native / Build macOS (push) Has been cancelled
CI - Multi-Platform Native / Build Android (push) Has been cancelled
CI - Multi-Platform Native / Build Linux (push) Has been cancelled
CI - Multi-Platform Native / Build Summary (push) Has been cancelled
restructure
2026-03-30 16:39:18 -04:00

172 lines
4.8 KiB
Vala

/*
* SearchHistoryStore.vala
*
* CRUD operations for search history.
*/
/**
* SearchHistoryStore - Manages search history persistence
*/
public class RSSuper.SearchHistoryStore : Object {
private Database db;
/**
* Maximum number of history entries to keep
*/
public int max_entries { get; set; default = 100; }
/**
* Signal emitted when a search is recorded
*/
public signal void search_recorded(SearchQuery query, int result_count);
/**
* Signal emitted when history is cleared
*/
public signal void history_cleared();
/**
* Create a new search history store
*/
public SearchHistoryStore(Database db) {
this.db = db;
}
/**
* Record a search query
*/
public int record_search(SearchQuery query, int result_count = 0) throws Error {
var stmt = db.prepare(
"INSERT INTO search_history (query, filters_json, sort_option, page, page_size, result_count) " +
"VALUES (?, ?, ?, ?, ?, ?);"
);
stmt.bind_text(1, query.query, -1, null);
stmt.bind_text(2, query.filters_json ?? "", -1, null);
stmt.bind_text(3, SearchFilters.sort_option_to_string(query.sort), -1, null);
stmt.bind_int(4, query.page);
stmt.bind_int(5, query.page_size);
stmt.bind_int(6, result_count);
stmt.step();
debug("Search recorded: %s (%d results)", query.query, result_count);
search_recorded(query, result_count);
// Clean up old entries if needed
cleanup_old_entries();
return 0; // Returns the last inserted row ID in SQLite
}
/**
* Get search history
*/
public SearchQuery[] get_history(int limit = 50) throws Error {
var queries = new GLib.List<SearchQuery?>();
var stmt = db.prepare(
"SELECT query, filters_json, sort_option, page, page_size, result_count, created_at " +
"FROM search_history " +
"ORDER BY created_at DESC " +
"LIMIT ?;"
);
stmt.bind_int(1, limit);
while (stmt.step() == Sqlite.ROW) {
var query = row_to_query(stmt);
queries.append(query);
}
return queries_to_array(queries);
}
/**
* Get recent searches (last 24 hours)
*/
public SearchQuery[] get_recent() throws Error {
var queries = new GLib.List<SearchQuery?>();
var now = new DateTime.now_local();
var yesterday = now.add_days(-1);
var threshold = yesterday.format("%Y-%m-%dT%H:%M:%S");
var stmt = db.prepare(
"SELECT query, filters_json, sort_option, page, page_size, result_count, created_at " +
"FROM search_history " +
"WHERE created_at >= ? " +
"ORDER BY created_at DESC " +
"LIMIT 20;"
);
stmt.bind_text(1, threshold, -1, null);
while (stmt.step() == Sqlite.ROW) {
var query = row_to_query(stmt);
queries.append(query);
}
return queries_to_array(queries);
}
/**
* Delete a search history entry by ID
*/
public void delete(int id) throws Error {
var stmt = db.prepare("DELETE FROM search_history WHERE id = ?;");
stmt.bind_int(1, id);
stmt.step();
debug("Search history entry deleted: %d", id);
}
/**
* Clear all search history
*/
public void clear() throws Error {
var stmt = db.prepare("DELETE FROM search_history;");
stmt.step();
debug("Search history cleared");
history_cleared();
}
/**
* Clear old search history entries
*/
private void cleanup_old_entries() throws Error {
var stmt = db.prepare(
"DELETE FROM search_history WHERE id NOT IN (" +
"SELECT id FROM search_history ORDER BY created_at DESC LIMIT ?" +
");"
);
stmt.bind_int(1, max_entries);
stmt.step();
}
/**
* Convert a database row to a SearchQuery
*/
private SearchQuery row_to_query(Sqlite.Statement stmt) {
string query_str = stmt.column_text(0);
string? filters_json = stmt.column_text(1);
string sort_str = stmt.column_text(2);
int page = stmt.column_int(3);
int page_size = stmt.column_int(4);
return SearchQuery(query_str, page, page_size, filters_json,
SearchFilters.sort_option_from_string(sort_str));
}
private SearchQuery[] queries_to_array(GLib.List<SearchQuery?> list) {
SearchQuery[] arr = {};
for (unowned var node = list; node != null; node = node.next) {
arr += node.data;
}
return arr;
}
}