From 309bf1b58734f0a2ecf310108081f2be34540832 Mon Sep 17 00:00:00 2001 From: yggverse Date: Wed, 11 Sep 2024 01:39:39 +0300 Subject: [PATCH] implement navigation request session save --- src/app/browser/main/tab.cpp | 20 +-- src/app/browser/main/tab/page.cpp | 16 ++- src/app/browser/main/tab/page/navigation.cpp | 125 ++++++++++++++++- src/app/browser/main/tab/page/navigation.hpp | 63 +++++++-- .../main/tab/page/navigation/request.cpp | 128 +++++++++++++++++- .../main/tab/page/navigation/request.hpp | 84 +++++++++--- 6 files changed, 392 insertions(+), 44 deletions(-) diff --git a/src/app/browser/main/tab.cpp b/src/app/browser/main/tab.cpp index 0c0a1cac..ea8dc76d 100644 --- a/src/app/browser/main/tab.cpp +++ b/src/app/browser/main/tab.cpp @@ -35,8 +35,7 @@ Tab::Tab( signal_realize().connect( [this] { - // Restore session from DB - restore(); + restore(); // last session from DB } ); @@ -82,6 +81,8 @@ int Tab::restore() DB::APP_BROWSER_MAIN_TAB__SESSION::IS_CURRENT ) == 1 ); + + // @TODO restore child widget sessions } } @@ -382,7 +383,7 @@ int Tab::DB::APP_BROWSER_MAIN_TAB__SESSION::clean( ); // Delete record - sqlite3_exec( + const int EXEC_STATUS = sqlite3_exec( db, Glib::ustring::sprintf( R"SQL( @@ -395,11 +396,14 @@ int Tab::DB::APP_BROWSER_MAIN_TAB__SESSION::clean( &error ); - // Delegate cleanup childs - tab::Page::DB::APP_BROWSER_MAIN_TAB_PAGE__SESSION::clean( - db, - APP_BROWSER_MAIN_TAB__SESSION_ID - ); + // Delegate children dependencies cleanup + if (EXEC_STATUS == SQLITE_OK) + { + tab::Page::DB::APP_BROWSER_MAIN_TAB_PAGE__SESSION::clean( + db, + APP_BROWSER_MAIN_TAB__SESSION_ID + ); + } } } diff --git a/src/app/browser/main/tab/page.cpp b/src/app/browser/main/tab/page.cpp index b0afda3d..8915ee7e 100644 --- a/src/app/browser/main/tab/page.cpp +++ b/src/app/browser/main/tab/page.cpp @@ -30,6 +30,7 @@ Page::Page( // Init components pageNavigation = Gtk::make_managed( + this->db, ACTION__REFRESH, ACTION__PAGE_NAVIGATION_HISTORY_BACK, ACTION__PAGE_NAVIGATION_HISTORY_FORWARD, @@ -74,7 +75,7 @@ int Page::save( ) { // Delegate save action to child components return pageNavigation->save( - Page::DB::APP_BROWSER_MAIN_TAB_PAGE__SESSION::add( + DB::APP_BROWSER_MAIN_TAB_PAGE__SESSION::add( db, DB__APP_BROWSER_MAIN_TAB__SESSION_ID, mime, @@ -417,10 +418,8 @@ int Page::DB::APP_BROWSER_MAIN_TAB_PAGE__SESSION::clean( DB::APP_BROWSER_MAIN_TAB_PAGE__SESSION::ID ); - // @TODO Delegate cleanup to the child components - // Delete record - sqlite3_exec( + const int EXEC_STATUS = sqlite3_exec( db, Glib::ustring::sprintf( R"SQL( @@ -432,6 +431,15 @@ int Page::DB::APP_BROWSER_MAIN_TAB_PAGE__SESSION::clean( nullptr, &error ); + + // Delegate children dependencies cleanup + if (EXEC_STATUS == SQLITE_OK) + { + page::Navigation::DB::APP_BROWSER_MAIN_TAB_PAGE_NAVIGATION__SESSION::clean( + db, + APP_BROWSER_MAIN_TAB_PAGE__SESSION_ID + ); + } } } diff --git a/src/app/browser/main/tab/page/navigation.cpp b/src/app/browser/main/tab/page/navigation.cpp index 853259c5..66187c04 100644 --- a/src/app/browser/main/tab/page/navigation.cpp +++ b/src/app/browser/main/tab/page/navigation.cpp @@ -8,11 +8,17 @@ using namespace app::browser::main::tab::page; Navigation::Navigation( + sqlite3 * db, const Glib::RefPtr & ACTION__REFRESH, const Glib::RefPtr & ACTION__NAVIGATION_HISTORY_BACK, const Glib::RefPtr & ACTION__NAVIGATION_HISTORY_FORWARD, const Glib::RefPtr & ACTION__NAVIGATION_UPDATE ) { + // Init database + DB::APP_BROWSER_MAIN_TAB_PAGE_NAVIGATION__SESSION::init( + this->db = db + ); + // Init container set_orientation( Gtk::Orientation::HORIZONTAL @@ -63,6 +69,7 @@ Navigation::Navigation( ); navigationRequest = Gtk::make_managed( + db, ACTION__REFRESH, ACTION__NAVIGATION_UPDATE ); @@ -104,9 +111,12 @@ void Navigation::refresh( int Navigation::save( const sqlite3_int64 & DB__APP_BROWSER_MAIN_TAB_PAGE__SESSION_ID ) { - navigationRequest->save(); - - return 1; // @TODO SQL + return navigationRequest->save( + DB::APP_BROWSER_MAIN_TAB_PAGE_NAVIGATION__SESSION::add( + db, + DB__APP_BROWSER_MAIN_TAB_PAGE__SESSION_ID + ) + ); } void Navigation::history_add( @@ -190,4 +200,113 @@ void Navigation::set_request_text( navigationRequest->set_text( VALUE ); +} + +// Database model +int Navigation::DB::APP_BROWSER_MAIN_TAB_PAGE_NAVIGATION__SESSION::init( + sqlite3 * db +) { + char * error; + + return sqlite3_exec( + db, + R"SQL( + CREATE TABLE IF NOT EXISTS `app_browser_main_tab_page_navigation__session` + ( + `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `app_browser_main_tab_page__session_id` INTEGER NOT NULL, + `time` INTEGER NOT NULL DEFAULT CURRENT_TIMESTAMP + ) + )SQL", + nullptr, + nullptr, + &error + ); +} + +int Navigation::DB::APP_BROWSER_MAIN_TAB_PAGE_NAVIGATION__SESSION::clean( + sqlite3 * db, + const int & DB__APP_BROWSER_MAIN_TAB_PAGE__SESSION_ID +) { + char * error; // @TODO + sqlite3_stmt * statement; + + const int PREPARE_STATUS = sqlite3_prepare_v3( + db, + Glib::ustring::sprintf( + R"SQL( + SELECT * FROM `app_browser_main_tab_page_navigation__session` WHERE `app_browser_main_tab_page__session_id` = %d + )SQL", + DB__APP_BROWSER_MAIN_TAB_PAGE__SESSION_ID + ).c_str(), + -1, + SQLITE_PREPARE_NORMALIZE, + &statement, + nullptr + ); + + if (PREPARE_STATUS == SQLITE_OK) + { + while (::sqlite3_step(statement) == SQLITE_ROW) + { + const int APP_BROWSER_MAIN_TAB_PAGE_NAVIGATION__SESSION_ID = sqlite3_column_int( + statement, + DB::APP_BROWSER_MAIN_TAB_PAGE_NAVIGATION__SESSION::ID + ); + + // Delete record + const int EXEC_STATUS = sqlite3_exec( + db, + Glib::ustring::sprintf( + R"SQL( + DELETE FROM `app_browser_main_tab_page_navigation__session` WHERE `id` = %d + )SQL", + APP_BROWSER_MAIN_TAB_PAGE_NAVIGATION__SESSION_ID + ).c_str(), + nullptr, + nullptr, + &error + ); + + // Delegate children dependencies cleanup + if (EXEC_STATUS == SQLITE_OK) + { + navigation::Request::DB::APP_BROWSER_MAIN_TAB_PAGE_NAVIGATION_REQUEST__SESSION::clean( + db, + APP_BROWSER_MAIN_TAB_PAGE_NAVIGATION__SESSION_ID + ); + } + } + } + + return sqlite3_finalize( + statement + ); +} + +sqlite3_int64 Navigation::DB::APP_BROWSER_MAIN_TAB_PAGE_NAVIGATION__SESSION::add( + sqlite3 * db, + const sqlite3_int64 & DB__APP_BROWSER_MAIN_TAB_PAGE__SESSION_ID +) { + char * error; // @TODO + + sqlite3_exec( + db, + Glib::ustring::sprintf( + R"SQL( + INSERT INTO `app_browser_main_tab_page_navigation__session` ( + `app_browser_main_tab_page__session_id` + ) VALUES ( + '%d' + ) + )SQL", + DB__APP_BROWSER_MAIN_TAB_PAGE__SESSION_ID + ).c_str(), + nullptr, + nullptr, + &error + ); + + return sqlite3_last_insert_rowid( + db + ); } \ No newline at end of file diff --git a/src/app/browser/main/tab/page/navigation.hpp b/src/app/browser/main/tab/page/navigation.hpp index 5833c22f..233add5d 100644 --- a/src/app/browser/main/tab/page/navigation.hpp +++ b/src/app/browser/main/tab/page/navigation.hpp @@ -21,20 +21,65 @@ namespace app::browser::main::tab::page class Navigation : public Gtk::Box { - // Components - navigation::Base * navigationBase; - navigation::Bookmark * navigationBookmark; - navigation::History * navigationHistory; - navigation::Request * navigationRequest; - navigation::Update * navigationUpdate; + public: + + /* + * Class database + * + * Allowed parental access to enums and relationship methods + */ + struct DB + { + struct APP_BROWSER_MAIN_TAB_PAGE_NAVIGATION__SESSION + { + enum + { + ID, + TIME + }; // table fields index + + static int init( + sqlite3 * db + ); // return sqlite3_exec status code + + static int clean( + sqlite3 * db, + const int & DB__APP_BROWSER_MAIN_TAB_PAGE__SESSION_ID + ); // return sqlite3_finalize status code + + static sqlite3_int64 add( + sqlite3 * db, + const sqlite3_int64 & DB__APP_BROWSER_MAIN_TAB_PAGE__SESSION_ID + ); // return sqlite3_last_insert_rowid + }; + }; + + /* + * Internal members + */ + private: + + // Database + sqlite3 * db; + + // Components + navigation::Base * navigationBase; + navigation::Bookmark * navigationBookmark; + navigation::History * navigationHistory; + navigation::Request * navigationRequest; + navigation::Update * navigationUpdate; - // Defaults - const int SPACING = 8; - const int MARGIN = 8; + // Defaults + const int SPACING = 8; + const int MARGIN = 8; + /* + * Class API + */ public: Navigation( + sqlite3 * db, const Glib::RefPtr & ACTION__REFRESH, const Glib::RefPtr & ACTION__NAVIGATION_HISTORY_BACK, const Glib::RefPtr & ACTION__NAVIGATION_HISTORY_FORWARD, diff --git a/src/app/browser/main/tab/page/navigation/request.cpp b/src/app/browser/main/tab/page/navigation/request.cpp index 138028f3..dd416b99 100644 --- a/src/app/browser/main/tab/page/navigation/request.cpp +++ b/src/app/browser/main/tab/page/navigation/request.cpp @@ -4,9 +4,15 @@ using namespace app::browser::main::tab::page::navigation; // Construct Request::Request( + sqlite3 * db, const Glib::RefPtr & ACTION__REFRESH, const Glib::RefPtr & ACTION__UPDATE ) { + // Init database + DB::APP_BROWSER_MAIN_TAB_PAGE_NAVIGATION_REQUEST__SESSION::init( + this->db = db + ); + // Init actions action__refresh = ACTION__REFRESH; action__update = ACTION__UPDATE; @@ -78,9 +84,14 @@ void Request::refresh( ); } -int Request::save() -{ - return 1; // @TODO SQL +int Request::save( + const sqlite3_int64 & DB__APP_BROWSER_MAIN_TAB_PAGE_NAVIGATION__SESSION_ID +) { + return DB::APP_BROWSER_MAIN_TAB_PAGE_NAVIGATION_REQUEST__SESSION::add( + db, + DB__APP_BROWSER_MAIN_TAB_PAGE_NAVIGATION__SESSION_ID, + get_text() + ); } void Request::parse() @@ -137,4 +148,115 @@ Glib::ustring Request::get_path() Glib::ustring Request::get_query() { return path; +} + +// Database model +int Request::DB::APP_BROWSER_MAIN_TAB_PAGE_NAVIGATION_REQUEST__SESSION::init( + sqlite3 * db +) { + char * error; + + return sqlite3_exec( + db, + R"SQL( + CREATE TABLE IF NOT EXISTS `app_browser_main_tab_page_navigation_request__session` + ( + `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `app_browser_main_tab_page_navigation__session_id` INTEGER NOT NULL, + `time` INTEGER NOT NULL DEFAULT CURRENT_TIMESTAMP, + `text` VARCHAR (1024) NOT NULL + ) + )SQL", + nullptr, + nullptr, + &error + ); +} + +int Request::DB::APP_BROWSER_MAIN_TAB_PAGE_NAVIGATION_REQUEST__SESSION::clean( + sqlite3 * db, + const int & DB__APP_BROWSER_MAIN_TAB_PAGE_NAVIGATION__SESSION_ID +) { + char * error; // @TODO + sqlite3_stmt * statement; + + const int PREPARE_STATUS = sqlite3_prepare_v3( + db, + Glib::ustring::sprintf( + R"SQL( + SELECT * FROM `app_browser_main_tab_page_navigation_request__session` WHERE `app_browser_main_tab_page_navigation__session_id` = %d + )SQL", + DB__APP_BROWSER_MAIN_TAB_PAGE_NAVIGATION__SESSION_ID + ).c_str(), + -1, + SQLITE_PREPARE_NORMALIZE, + &statement, + nullptr + ); + + if (PREPARE_STATUS == SQLITE_OK) + { + while (::sqlite3_step(statement) == SQLITE_ROW) + { + const int APP_BROWSER_MAIN_TAB_PAGE_NAVIGATION_REQUEST__SESSION_ID = sqlite3_column_int( + statement, + DB::APP_BROWSER_MAIN_TAB_PAGE_NAVIGATION_REQUEST__SESSION::ID + ); + + // Delete record + const int EXEC_STATUS = sqlite3_exec( + db, + Glib::ustring::sprintf( + R"SQL( + DELETE FROM `app_browser_main_tab_page_navigation_request__session` WHERE `id` = %d + )SQL", + APP_BROWSER_MAIN_TAB_PAGE_NAVIGATION_REQUEST__SESSION_ID + ).c_str(), + nullptr, + nullptr, + &error + ); + + // Delegate children dependencies cleanup + if (EXEC_STATUS == SQLITE_OK) + { + // nothing here. + } + } + } + + return sqlite3_finalize( + statement + ); +} + +sqlite3_int64 Request::DB::APP_BROWSER_MAIN_TAB_PAGE_NAVIGATION_REQUEST__SESSION::add( + sqlite3 * db, + const sqlite3_int64 & DB__APP_BROWSER_MAIN_TAB_PAGE_NAVIGATION__SESSION_ID, + const Glib::ustring & TEXT +) { + char * error; // @TODO + + sqlite3_exec( + db, + Glib::ustring::sprintf( + R"SQL( + INSERT INTO `app_browser_main_tab_page_navigation_request__session` ( + `app_browser_main_tab_page_navigation__session_id`, + `text` + ) VALUES ( + '%d', + '%s' + ) + )SQL", + DB__APP_BROWSER_MAIN_TAB_PAGE_NAVIGATION__SESSION_ID, + TEXT + ).c_str(), + nullptr, + nullptr, + &error + ); + + return sqlite3_last_insert_rowid( + db + ); } \ No newline at end of file diff --git a/src/app/browser/main/tab/page/navigation/request.hpp b/src/app/browser/main/tab/page/navigation/request.hpp index 54322c70..1b42e46b 100644 --- a/src/app/browser/main/tab/page/navigation/request.hpp +++ b/src/app/browser/main/tab/page/navigation/request.hpp @@ -8,35 +8,83 @@ #include #include #include +#include namespace app::browser::main::tab::page::navigation { class Request : public Gtk::Entry { - // Actions - Glib::RefPtr action__refresh, - action__update; + public: + + /* + * Class database + * + * Allowed parental access to enums and relationship methods + */ + struct DB + { + struct APP_BROWSER_MAIN_TAB_PAGE_NAVIGATION_REQUEST__SESSION + { + enum + { + ID, + TIME, + TEXT + }; // table fields index + + static int init( + sqlite3 * db + ); // return sqlite3_exec status code + + static int clean( + sqlite3 * db, + const int & DB__APP_BROWSER_MAIN_TAB_PAGE_NAVIGATION__SESSION_ID + ); // return sqlite3_finalize status code + + static sqlite3_int64 add( + sqlite3 * db, + const sqlite3_int64 & DB__APP_BROWSER_MAIN_TAB_PAGE_NAVIGATION__SESSION_ID, + const Glib::ustring & TEXT + ); // return sqlite3_last_insert_rowid + }; + }; - // Extras - double progress_fraction; + /* + * Internal members + */ + private: - Glib::ustring scheme, - host, - port, - path, - query; + // Database + sqlite3 * db; - // Defaults - const bool HEXPAND = true; - const double PROGRESS_PULSE_STEP = .1; - const int PROGRESS_ANIMATION_TIME = 10; + // Actions + Glib::RefPtr action__refresh, + action__update; + + // Extras + double progress_fraction; + + Glib::ustring scheme, + host, + port, + path, + query; - // Private helpers - void parse(); + // Defaults + const bool HEXPAND = true; + const double PROGRESS_PULSE_STEP = .1; + const int PROGRESS_ANIMATION_TIME = 10; + // Private helpers + void parse(); + + /* + * Class API + */ public: Request( + sqlite3 * db, const Glib::RefPtr & ACTION__REFRESH, const Glib::RefPtr & ACTION__UPDATE ); @@ -46,7 +94,9 @@ namespace app::browser::main::tab::page::navigation const double & PROGRESS_FRACTION ); - int save(); + int save( + const sqlite3_int64 & DB__APP_BROWSER_MAIN_TAB_PAGE_NAVIGATION__SESSION_ID + ); // Getters Glib::ustring get_scheme();