diff options
Diffstat (limited to 'src/db/payments.rs')
-rw-r--r-- | src/db/payments.rs | 109 |
1 files changed, 76 insertions, 33 deletions
diff --git a/src/db/payments.rs b/src/db/payments.rs index 540a006..4a6774c 100644 --- a/src/db/payments.rs +++ b/src/db/payments.rs @@ -1,6 +1,8 @@ use std::collections::HashMap; use std::iter::FromIterator; -use tokio_rusqlite::{Connection, Row, params_from_iter, types::ToSql, named_params}; +use tokio_rusqlite::{ + named_params, params_from_iter, types::ToSql, Connection, Row, +}; use crate::db::utils; use crate::model::frequency::Frequency; @@ -30,7 +32,7 @@ fn row_to_table(row: &Row) -> Result<payment::Table, rusqlite::Error> { category_name: row.get(4)?, category_color: row.get(5)?, date: row.get(6)?, - frequency: row.get(7)? + frequency: row.get(7)?, }) } @@ -50,7 +52,7 @@ fn row_to_form(row: &Row) -> Result<payment::Form, rusqlite::Error> { user_id: row.get(3)?, category_id: row.get(4)?, date: row.get(5)?, - frequency: row.get(6)? + frequency: row.get(6)?, }) } @@ -58,7 +60,7 @@ pub async fn count( conn: &Connection, payment_query: &queries::Payments, ) -> Count { - let mut query = format!(r#" + let mut query = r#" SELECT COUNT(*) AS count, SUM(payments.cost) AS total_cost @@ -66,7 +68,8 @@ pub async fn count( INNER JOIN users ON users.id = payments.user_id INNER JOIN categories ON categories.id = payments.category_id WHERE payments.deleted_at IS NULL - "#); + "# + .to_string(); let mut params = Vec::<Box<dyn ToSql + Send>>::new(); complete_search_query(payment_query, &mut query, &mut params); @@ -74,7 +77,8 @@ pub async fn count( let res = conn .call(move |conn| { let mut stmt = conn.prepare(&query)?; - let mut iter = stmt.query_map(params_from_iter(params), row_to_count)?; + let mut iter = + stmt.query_map(params_from_iter(params), row_to_count)?; utils::one(&mut iter) }) .await; @@ -96,7 +100,7 @@ pub async fn list_for_table( payment_query: &queries::Payments, per_page: i64, ) -> Vec<payment::Table> { - let mut query = format!(r#" + let mut query = r#" SELECT payments.id, payments.name, @@ -110,7 +114,8 @@ pub async fn list_for_table( INNER JOIN users ON users.id = payments.user_id INNER JOIN categories ON categories.id = payments.category_id WHERE payments.deleted_at IS NULL - "#); + "# + .to_string(); let mut params = Vec::<Box<dyn ToSql + Send>>::new(); complete_search_query(payment_query, &mut query, &mut params); @@ -141,35 +146,62 @@ pub async fn list_for_table( fn complete_search_query( q: &queries::Payments, query: &mut String, - params: &mut Vec<Box<dyn ToSql + Send>> + params: &mut Vec<Box<dyn ToSql + Send>>, ) { complete_frequency(q.frequency, query, params); complete_name(q.name.clone(), query, params); complete_cost(q.cost.clone(), query, params); complete_user(q.user, query, params); complete_category(q.category, query, params); - complete_date("payments.date >=".to_string(), q.start_date.clone(), query, params); - complete_date("payments.date <=".to_string(), q.end_date.clone(), query, params); + complete_date( + "payments.date >=".to_string(), + q.start_date.clone(), + query, + params, + ); + complete_date( + "payments.date <=".to_string(), + q.end_date.clone(), + query, + params, + ); } -fn complete_frequency(frequency: Option<Frequency>, query: &mut String, params: &mut Vec<Box<dyn ToSql + Send>>) { +fn complete_frequency( + frequency: Option<Frequency>, + query: &mut String, + params: &mut Vec<Box<dyn ToSql + Send>>, +) { query.push_str("AND payments.frequency = ?"); - params.push(Box::new(frequency.unwrap_or(Frequency::Punctual).to_string())); + params.push(Box::new( + frequency.unwrap_or(Frequency::Punctual).to_string(), + )); } -fn complete_name(name: Option<String>, query: &mut String, params: &mut Vec<Box<dyn ToSql + Send>>) { +fn complete_name( + name: Option<String>, + query: &mut String, + params: &mut Vec<Box<dyn ToSql + Send>>, +) { if let Some(name) = name { if !name.is_empty() { - query.push_str(format!( - "AND {} LIKE ?", - utils::format_key_for_search("payments.name") - ).as_str()); + query.push_str( + format!( + "AND {} LIKE ?", + utils::format_key_for_search("payments.name") + ) + .as_str(), + ); params.push(Box::new(name)); } } } -fn complete_cost(cost: Option<String>, query: &mut String, params: &mut Vec<Box<dyn ToSql + Send>>) { +fn complete_cost( + cost: Option<String>, + query: &mut String, + params: &mut Vec<Box<dyn ToSql + Send>>, +) { if let Some(cost) = cost { if !cost.is_empty() { query.push_str("AND payments.cost = ?"); @@ -178,14 +210,22 @@ fn complete_cost(cost: Option<String>, query: &mut String, params: &mut Vec<Box< } } -fn complete_user(user: Option<i64>, query: &mut String, params: &mut Vec<Box<dyn ToSql + Send>>) { +fn complete_user( + user: Option<i64>, + query: &mut String, + params: &mut Vec<Box<dyn ToSql + Send>>, +) { if let Some(user) = user { query.push_str("AND payments.user_id = ?"); params.push(Box::new(user)) } } -fn complete_category(category: Option<i64>, query: &mut String, params: &mut Vec<Box<dyn ToSql + Send>>) { +fn complete_category( + category: Option<i64>, + query: &mut String, + params: &mut Vec<Box<dyn ToSql + Send>>, +) { if let Some(category) = category { query.push_str("AND payments.category_id = ?"); params.push(Box::new(category)); @@ -196,7 +236,7 @@ fn complete_date( name_and_op: String, date: Option<String>, query: &mut String, - params: &mut Vec<Box<dyn ToSql + Send>> + params: &mut Vec<Box<dyn ToSql + Send>>, ) { if let Some(date) = date { if !date.is_empty() { @@ -224,7 +264,7 @@ pub async fn list_for_stats(conn: &Connection) -> Vec<payment::Stat> { let res = conn .call(move |conn| { - let mut stmt = conn.prepare(&query)?; + let mut stmt = conn.prepare(query)?; let payments = stmt .query_map([], row_to_stat)? .collect::<Result<Vec<payment::Stat>, _>>()?; @@ -261,7 +301,7 @@ pub async fn get_row(conn: &Connection, id: i64, frequency: Frequency) -> i64 { let mut stmt = conn.prepare(query)?; let mut iter = stmt.query_map( named_params![":id": id, ":frequency": frequency.to_string()], - |row| row.get(0) + |row| row.get(0), )?; utils::one::<i64, _>(&mut iter) }) @@ -295,7 +335,8 @@ pub async fn get_for_form(conn: &Connection, id: i64) -> Option<payment::Form> { let res = conn .call(move |conn| { let mut stmt = conn.prepare(query)?; - let mut iter = stmt.query_map(named_params![":id": id], row_to_form)?; + let mut iter = + stmt.query_map(named_params![":id": id], row_to_form)?; utils::one(&mut iter) }) .await; @@ -370,7 +411,6 @@ pub async fn update(conn: &Connection, id: i64, p: payment::Update) -> bool { }) .await; - match res { Ok(_) => true, Err(err) => { @@ -400,14 +440,17 @@ pub async fn search_category( conn: &Connection, payment_name: String, ) -> Option<i64> { - let query = format!(r#" + let query = format!( + r#" SELECT category_id FROM payments WHERE deleted_at IS NULL AND {} LIKE :name ORDER BY updated_at, created_at - "#, utils::format_key_for_search("name")); + "#, + utils::format_key_for_search("name") + ); let payment_name_closure = payment_name.clone(); @@ -424,7 +467,9 @@ pub async fn search_category( match res { Ok(category) => Some(category), - Err(tokio_rusqlite::Error::Rusqlite(rusqlite::Error::QueryReturnedNoRows)) => None, + Err(tokio_rusqlite::Error::Rusqlite( + rusqlite::Error::QueryReturnedNoRows, + )) => None, Err(err) => { log::error!( "Error looking for the category of {}: {:?}", @@ -448,7 +493,7 @@ pub async fn is_category_used(conn: &Connection, category_id: i64) -> bool { let res = conn .call(move |conn| { - let mut stmt = conn.prepare(&query)?; + let mut stmt = conn.prepare(query)?; Ok(stmt.exists(named_params![":category_id": category_id])?) }) .await; @@ -520,9 +565,7 @@ pub async fn create_monthly_payments(conn: &Connection) { AND deleted_at IS NULL "#; - let res = conn - .call(move |conn| Ok(conn.execute(query, [])?)) - .await; + let res = conn.call(move |conn| Ok(conn.execute(query, [])?)).await; match res { Ok(_) => (), |