diff --git a/src/app/browser.rs b/src/app/browser.rs index 96faabb4..0a872537 100644 --- a/src/app/browser.rs +++ b/src/app/browser.rs @@ -177,7 +177,7 @@ impl Browser { // Show welcome dialog on profile not selected yet (e.g. first launch) if self.profile.database.selected().is_none() { - // @TODO Welcome::new(self.profile.clone(), self.widget.gobject().clone()).present(); + Welcome::new(self.profile.clone(), self.widget.gobject().clone()).present(); } self diff --git a/src/app/browser/welcome.rs b/src/app/browser/welcome.rs index a28dba83..b41046a3 100644 --- a/src/app/browser/welcome.rs +++ b/src/app/browser/welcome.rs @@ -1,4 +1,5 @@ mod widget; +use gtk::glib::DateTime; use widget::Widget; use crate::profile::Profile; @@ -19,13 +20,19 @@ impl Welcome { let widget = Rc::new(Widget::new(parent)); // Init events - widget.connect_response(|value| { - match value { - Some(id) => { - // Select profile by record ID @TODO - } - None => { - // Create new profile @TODO + widget.connect_response({ + let profile = profile.clone(); + move |value| { + match value { + Some(id) => { + // Select profile by record ID @TODO + } + None => { + // Create and select new profile + let _ = profile + .database + .add(true, &DateTime::now_local().unwrap(), None); + } } } }); diff --git a/src/profile/database.rs b/src/profile/database.rs index bf4be04d..ad50f5b1 100644 --- a/src/profile/database.rs +++ b/src/profile/database.rs @@ -28,7 +28,7 @@ impl Database { pub fn records(&self) -> Vec { let readable = self.connection.read().unwrap(); let tx = readable.unchecked_transaction().unwrap(); - records(&tx).unwrap() + select(&tx).unwrap() } /// Get selected profile record if exist @@ -44,13 +44,31 @@ impl Database { // Setters pub fn add(&self, is_active: bool, time: &DateTime, name: Option<&str>) -> Result { + // Begin new transaction let mut writable = self.connection.write().unwrap(); let tx = writable.transaction().unwrap(); - add(&tx, is_active, time, name).unwrap(); + // New record has active status + if is_active { + // Deactivate other records as only one profile should be active + for record in select(&tx).unwrap() { + let _ = update( + &tx, + record.id, + false, + &record.time, + record.name.as_ref().map(|x| x.as_str()), + ); + } + } + // Create new record + insert(&tx, is_active, time, name).unwrap(); + + // Hold insert ID for result let id = last_insert_id(&tx); + // Done match tx.commit() { Ok(_) => Ok(id), Err(_) => Err(()), // @TODO @@ -73,16 +91,36 @@ pub fn init(tx: &Transaction) -> Result { ) } -pub fn add( +pub fn insert( tx: &Transaction, is_active: bool, time: &DateTime, name: Option<&str>, ) -> Result { - tx.execute("INSERT INTO `profile`", (is_active, time.to_unix(), name)) + tx.execute( + "INSERT INTO `profile` ( + `is_active`, + `time`, + `name` + ) VALUES (?, ?, ?)", + (is_active, time.to_unix(), name), + ) } -pub fn records(tx: &Transaction) -> Result, Error> { +pub fn update( + tx: &Transaction, + id: i64, + is_active: bool, + time: &DateTime, + name: Option<&str>, +) -> Result { + tx.execute( + "UPDATE `profile` SET `is_active` = ?, `time` = ?, `name` = ? WHERE `id` = ? LIMIT 1", + (is_active, time.to_unix(), name, id), + ) +} + +pub fn select(tx: &Transaction) -> Result, Error> { let mut stmt = tx.prepare("SELECT `id`, `is_active`, `time`, `name` FROM `profile`")?; let result = stmt.query_map([], |row| { Ok(Table {