diff --git a/README.md b/README.md index 21c042fd..426bb461 100644 --- a/README.md +++ b/README.md @@ -28,10 +28,13 @@ GTK 4 / Libadwaita client written in Rust * [x] Tabs * [x] Pin * [x] Page + * [ ] Content (cache) + * [x] Meta + * [x] Title * [ ] Navigation * [x] Request * [ ] History - * [ ] Content (cache) + * [ ] User settings ### Protocols diff --git a/src/app/browser/window/tab/item/page.rs b/src/app/browser/window/tab/item/page.rs index cc735fc7..696c36e0 100644 --- a/src/app/browser/window/tab/item/page.rs +++ b/src/app/browser/window/tab/item/page.rs @@ -301,6 +301,7 @@ impl Page { match Database::delete(transaction, &record.id) { Ok(_) => { // Delegate clean action to the item childs + self.meta.clean(transaction, &record.id)?; self.navigation.clean(transaction, &record.id)?; } Err(e) => return Err(e.to_string()), @@ -322,6 +323,7 @@ impl Page { Ok(records) => { for record in records { // Delegate restore action to the item childs + self.meta.restore(transaction, &record.id)?; self.navigation.restore(transaction, &record.id)?; } } @@ -341,6 +343,7 @@ impl Page { let id = Database::last_insert_id(transaction); // Delegate save action to childs + self.meta.save(transaction, &id)?; self.navigation.save(transaction, &id)?; } Err(e) => return Err(e.to_string()), @@ -396,6 +399,7 @@ impl Page { } // Delegate migration to childs + Meta::migrate(tx)?; Navigation::migrate(tx)?; // Success diff --git a/src/app/browser/window/tab/item/page/meta.rs b/src/app/browser/window/tab/item/page/meta.rs index bba62b82..b827795c 100644 --- a/src/app/browser/window/tab/item/page/meta.rs +++ b/src/app/browser/window/tab/item/page/meta.rs @@ -1,7 +1,11 @@ +mod database; mod redirect; + +use database::Database; use redirect::Redirect; use gtk::glib::GString; +use sqlite::Transaction; use std::{cell::RefCell, sync::Arc}; #[derive(Debug, Clone)] @@ -98,4 +102,94 @@ impl Meta { pub fn take_redirect(&self) -> Option { self.redirect.take() } + + // Actions + + pub fn clean( + &self, + transaction: &Transaction, + app_browser_window_tab_page_id: &i64, + ) -> Result<(), String> { + match Database::records(transaction, app_browser_window_tab_page_id) { + Ok(records) => { + for record in records { + match Database::delete(transaction, &record.id) { + Ok(_) => { + // Delegate clean action to the item childs + // nothing yet.. + } + Err(e) => return Err(e.to_string()), + } + } + } + Err(e) => return Err(e.to_string()), + } + + Ok(()) + } + + pub fn restore( + &self, + transaction: &Transaction, + app_browser_window_tab_page_id: &i64, + ) -> Result<(), String> { + match Database::records(transaction, app_browser_window_tab_page_id) { + Ok(records) => { + for record in records { + // Record value can be stored as NULL + if let Some(title) = record.title { + self.set_title(title.as_str()); + } + + // Delegate restore action to the item childs + // nothing yet.. + } + } + Err(e) => return Err(e.to_string()), + } + + Ok(()) + } + + pub fn save( + &self, + transaction: &Transaction, + app_browser_window_tab_page_id: &i64, + ) -> Result<(), String> { + // Keep value in memory until operation complete + let title = self.title(); + + match Database::add( + transaction, + app_browser_window_tab_page_id, + match title.is_empty() { + true => None, + false => Some(title.as_str()), + }, + ) { + Ok(_) => { + // let id = Database::last_insert_id(transaction); + + // Delegate save action to childs + // nothing yet.. + } + Err(e) => return Err(e.to_string()), + } + + Ok(()) + } + + // Tools + pub fn migrate(tx: &Transaction) -> Result<(), String> { + // Migrate self components + if let Err(e) = Database::init(&tx) { + return Err(e.to_string()); + } + + // Delegate migration to childs + // nothing yet.. + + // Success + Ok(()) + } } diff --git a/src/app/browser/window/tab/item/page/meta/database.rs b/src/app/browser/window/tab/item/page/meta/database.rs new file mode 100644 index 00000000..4ce3dc6f --- /dev/null +++ b/src/app/browser/window/tab/item/page/meta/database.rs @@ -0,0 +1,81 @@ +use sqlite::{Error, Transaction}; + +pub struct Table { + pub id: i64, + // pub app_browser_window_tab_item_page_id: i64, not in use + pub title: Option, // can be stored as NULL +} + +pub struct Database { + // nothing yet.. +} + +impl Database { + pub fn init(tx: &Transaction) -> Result { + tx.execute( + "CREATE TABLE IF NOT EXISTS `app_browser_window_tab_item_page_meta` + ( + `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, + `app_browser_window_tab_item_page_id` INTEGER NOT NULL, + `title` VARCHAR(1024) + )", + [], + ) + } + + pub fn add( + tx: &Transaction, + app_browser_window_tab_item_page_id: &i64, + title: Option<&str>, + ) -> Result { + tx.execute( + "INSERT INTO `app_browser_window_tab_item_page_meta` ( + `app_browser_window_tab_item_page_id`, + `title` + ) VALUES (?, ?)", + (app_browser_window_tab_item_page_id, title), + ) + } + + pub fn records( + tx: &Transaction, + app_browser_window_tab_item_page_id: &i64, + ) -> Result, Error> { + let mut stmt = tx.prepare( + "SELECT `id`, + `app_browser_window_tab_item_page_id`, + `title` + FROM `app_browser_window_tab_item_page_meta` + WHERE `app_browser_window_tab_item_page_id` = ?", + )?; + + let result = stmt.query_map([app_browser_window_tab_item_page_id], |row| { + Ok(Table { + id: row.get(0)?, + // app_browser_window_tab_item_page_id: row.get(1)?, not in use + title: row.get(2)?, + }) + })?; + + let mut records = Vec::new(); + + for record in result { + let table = record?; + records.push(table); + } + + Ok(records) + } + + pub fn delete(tx: &Transaction, id: &i64) -> Result { + tx.execute( + "DELETE FROM `app_browser_window_tab_item_page_meta` WHERE `id` = ?", + [id], + ) + } + + /* not in use + pub fn last_insert_id(tx: &Transaction) -> i64 { + tx.last_insert_rowid() + } */ +}