diff --git a/src/birthday_store.rs b/src/birthday_store.rs new file mode 100644 index 0000000..56fb05b --- /dev/null +++ b/src/birthday_store.rs @@ -0,0 +1,53 @@ +use anyhow::Result; +use chrono::{NaiveDate, NaiveDateTime}; +use rusqlite::Connection; + +use crate::Birthday; + +pub fn add(name: String, date: String) -> Result<()> { + let db = get_db()?; + let date = NaiveDate::parse_from_str(&date, "%Y-%m-%d")?; + let timestamp = to_timestamp(date); + db.execute( + "INSERT INTO birthdays(name, date_timestamp) VALUES(?1, ?2)", + (name, timestamp), + )?; + Ok(()) +} + +pub fn get_all() -> Result> { + let db = get_db()?; + let mut statement = db.prepare("SELECT id, name, date_timestamp FROM birthdays")?; + let birthday_iter = statement.query_map([], |row| { + let id = row.get(0)?; + let name = row.get(1)?; + let timestamp = row.get(2)?; + let date = from_timestamp(timestamp); + Ok(Birthday { id, name, date }) + })?; + let birthdays: Result, rusqlite::Error> = birthday_iter.collect(); + Ok(birthdays.unwrap()) +} + +fn get_db() -> Result { + let db = Connection::open("test.db")?; + db.execute( + "CREATE TABLE IF NOT EXISTS birthdays ( + id INTEGER PRIMARY KEY, + name TEXT NOT NULL, + date_timestamp INTEGER NOT NULL + ) STRICT", + (), + )?; + Ok(db) +} + +fn to_timestamp(date: NaiveDate) -> i64 { + date.and_hms_opt(0, 0, 0).unwrap().timestamp() +} + +fn from_timestamp(timestamp: i64) -> NaiveDate { + NaiveDateTime::from_timestamp_opt(timestamp, 0) + .unwrap() + .date() +} diff --git a/src/lib.rs b/src/lib.rs index 9c2b594..f8ac85a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,70 +1,30 @@ +mod birthday; +mod birthday_store; use anyhow::{bail, Result}; pub use birthday::Birthday; -use chrono::{Datelike, NaiveDate, NaiveDateTime}; -use rusqlite::Connection; -mod birthday; - -fn get_db() -> Result { - let db = Connection::open("test.db")?; - db.execute( - "CREATE TABLE IF NOT EXISTS birthdays ( - id INTEGER PRIMARY KEY, - name TEXT NOT NULL, - date_timestamp INTEGER NOT NULL - ) STRICT", - (), - )?; - Ok(db) -} - -fn to_timestamp(date: NaiveDate) -> i64 { - date.and_hms_opt(0, 0, 0).unwrap().timestamp() -} - -fn from_timestamp(timestamp: i64) -> NaiveDate { - NaiveDateTime::from_timestamp_opt(timestamp, 0) - .unwrap() - .date() -} +use chrono::{Datelike, NaiveDate}; -pub fn add_birthday(name: String, date: String) -> Result<()> { - let db = get_db()?; - let date = NaiveDate::parse_from_str(&date, "%Y-%m-%d")?; - let timestamp = to_timestamp(date); - db.execute( - "INSERT INTO birthdays(name, date_timestamp) VALUES(?1, ?2)", - (name, timestamp), - )?; - Ok(()) +pub fn add(name: String, date: String) -> Result<()> { + birthday_store::add(name, date) } -pub fn get_all_birthdays() -> Result> { - let db = get_db()?; - let mut statement = db.prepare("SELECT id, name, date_timestamp FROM birthdays")?; - let birthday_iter = statement.query_map([], |row| { - let id = row.get(0)?; - let name = row.get(1)?; - let timestamp = row.get(2)?; - let date = from_timestamp(timestamp); - Ok(Birthday { id, name, date }) - })?; - let birthdays: Result, rusqlite::Error> = birthday_iter.collect(); - Ok(birthdays.unwrap()) +pub fn get_all() -> Result> { + birthday_store::get_all() } -pub fn get_next_birthday(today: NaiveDate) -> Result> { - let mut birthdays = get_all_birthdays()?; +pub fn get_next(today: NaiveDate) -> Result> { + let mut birthdays = birthday_store::get_all()?; birthdays.sort_by_key(|birthday| birthday.next(today)); Ok(birthdays.into_iter().next()) } -pub fn search_birthdays( +pub fn search( name: Option, year: Option, month: Option, day: Option, ) -> Result> { - let mut birthdays = get_all_birthdays()?; + let mut birthdays = birthday_store::get_all()?; if let Some(name) = name { birthdays.retain(|birthday| birthday.name.contains(&name)); diff --git a/src/main.rs b/src/main.rs index ec1c512..809983c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -40,15 +40,15 @@ fn main() -> Result<()> { let cli = Cli::parse(); println!("You ran cli with: {:?}", cli); match cli.command { - Command::Add { name, date } => birthday::add_birthday(name, date), + Command::Add { name, date } => birthday::add(name, date), Command::All {} => { - let birthdays = birthday::get_all_birthdays()?; + let birthdays = birthday::get_all()?; print_birthdays(birthdays); Ok(()) } Command::Next {} => { let today = Utc::now().date_naive(); - let maybe_birthday = birthday::get_next_birthday(today)?; + let maybe_birthday = birthday::get_next(today)?; if let Some(birthday) = maybe_birthday { print_birthdays(vec![birthday]); } @@ -60,13 +60,13 @@ fn main() -> Result<()> { month, day, } => { - let birthdays = birthday::search_birthdays(name, year, month, day)?; + let birthdays = birthday::search(name, year, month, day)?; print_birthdays(birthdays); Ok(()) } Command::Today {} => { let today = Utc::now().date_naive(); - let birthdays = birthday::search_birthdays( + let birthdays = birthday::search( None, Some(today.year()), Some(today.month()),