profile.rs
1 mod bookmark; 2 mod database; 3 mod history; 4 mod identity; 5 mod proxy; 6 mod search; 7 mod tofu; 8 9 use anyhow::Result; 10 use bookmark::Bookmark; 11 use database::Database; 12 use gtk::glib::{DateTime, user_config_dir}; 13 use history::History; 14 use identity::Identity; 15 use proxy::Proxy; 16 use r2d2::Pool; 17 use r2d2_sqlite::SqliteConnectionManager; 18 use search::Search; 19 use sqlite::Transaction; 20 use std::{fs::create_dir_all, path::PathBuf}; 21 use tofu::Tofu; 22 23 const VENDOR: &str = "YGGverse"; 24 const APP_ID: &str = "Yoda"; 25 const BRANCH: &str = "master"; 26 27 const DB_NAME: &str = "database.sqlite3"; 28 29 pub struct Profile { 30 pub bookmark: Bookmark, 31 pub config_path: PathBuf, 32 pub database: Database, 33 pub history: History, 34 pub identity: Identity, 35 pub proxy: Proxy, 36 pub search: Search, 37 pub tofu: Tofu, 38 } 39 40 impl Profile { 41 // Constructors 42 43 pub fn init() -> Result<Self> { 44 // Init profile path 45 let mut config_path = user_config_dir(); 46 47 config_path.push(VENDOR); 48 config_path.push(APP_ID); 49 config_path.push(BRANCH); 50 config_path.push(format!( 51 "{}.{}", 52 env!("CARGO_PKG_VERSION_MAJOR"), 53 env!("CARGO_PKG_VERSION_MINOR") 54 )); // @TODO remove after auto-migrate feature implementation 55 56 create_dir_all(&config_path)?; 57 58 // Init database path 59 let mut database_path = config_path.clone(); 60 database_path.push(DB_NAME); 61 62 // Init database connection 63 let database_pool = 64 Pool::new(SqliteConnectionManager::file(database_path.as_path())).unwrap(); 65 66 // Init profile components 67 { 68 // Init writable connection 69 let mut connection = database_pool.get()?; 70 71 // Init new transaction 72 let tx = connection.transaction()?; 73 74 // Begin migration 75 migrate(&tx)?; 76 tx.commit()?; 77 } // unlock database 78 79 // Init model 80 let database = Database::build(&database_pool); 81 82 // Get active profile or create new one 83 let profile_id = match database.active()? { 84 Some(profile) => profile.id, 85 None => database.add(true, DateTime::now_local()?, None)?, 86 }; 87 88 // Init components 89 let bookmark = Bookmark::build(&database_pool, profile_id)?; 90 let history = History::build(&database_pool, profile_id)?; 91 let identity = Identity::build(&database_pool, profile_id)?; 92 let proxy = Proxy::init(&database_pool, profile_id)?; 93 let search = Search::build(&database_pool, profile_id)?; 94 let tofu = Tofu::init(&database_pool, profile_id)?; 95 96 // Result 97 Ok(Self { 98 bookmark, 99 config_path, 100 database, 101 history, 102 identity, 103 proxy, 104 search, 105 tofu, 106 }) 107 } 108 109 // Actions 110 111 pub fn save(&self) -> Result<()> { 112 self.history.save()?; 113 self.proxy.save()?; 114 self.tofu.save()?; 115 Ok(()) 116 } 117 } 118 119 pub fn migrate(tx: &Transaction) -> Result<()> { 120 // Migrate self components 121 database::init(tx)?; 122 123 // Delegate migration to children components 124 bookmark::migrate(tx)?; 125 history::migrate(tx)?; 126 identity::migrate(tx)?; 127 proxy::migrate(tx)?; 128 search::migrate(tx)?; 129 tofu::migrate(tx)?; 130 131 // Success 132 Ok(()) 133 }