unwrap() purge

This commit is contained in:
thatscringebro
2026-04-06 13:32:42 -04:00
parent ba1b5349db
commit 1c65375044
7 changed files with 159 additions and 172 deletions

View File

@@ -33,8 +33,15 @@ impl App {
}
};
let mut error = String::new();
data_layer::setup(&con);
let tr_types = data_layer::get_transaction_types(&con);
let tr_types = match data_layer::get_transaction_types(&con) {
Ok(tt) => tt,
Err(e) => {
error = e.to_string();
Vec::new()
}
};
return App {
current_screen: CurrentScreen::Main,
@@ -55,7 +62,11 @@ impl App {
"Chart 3".to_string(),
]
.to_vec(),
error: String::new(),
error: if error.is_empty() {
String::new()
} else {
error
},
error_showing: false,
selected_tr_type_chart: 1,
selected_tr_type_chart_desc: tr_types
@@ -86,10 +97,16 @@ impl App {
}
pub fn get_list_trx(&mut self) -> Vec<Transaction> {
let accounts = self
return match self
.trx_table
.get_trx(self.acc_list.get_selected_id(), &self.connection);
return accounts.to_vec();
.get_trx(self.acc_list.get_selected_id(), &self.connection)
{
Ok(t) => t,
Err(e) => {
self.error = e.to_string();
Vec::new()
}
};
}
pub fn next_tr(&mut self) {
@@ -120,7 +137,14 @@ impl App {
pub fn save_new_tr(&mut self) {
let new = self.new_transaction.get_id() == 0;
self.next_tr_input();
let tr = data_layer::upsert_transaction(&self.connection, self.new_transaction.clone());
let tr =
match data_layer::upsert_transaction(&self.connection, self.new_transaction.clone()) {
Ok(tr) => tr,
Err(e) => {
self.error = e.to_string();
return;
}
};
if new {
self.trx_table.add_tr(tr);
}
@@ -305,19 +329,31 @@ impl App {
}
}
pub fn get_cumulative_total(&self) -> Vec<(f64, f64)> {
return data_layer::get_cumulative_account_sum(
pub fn get_cumulative_total(&mut self) -> Vec<(f64, f64)> {
return match data_layer::get_cumulative_account_sum(
&self.connection,
self.acc_list.get_selected_id(),
);
) {
Ok(d) => d,
Err(e) => {
self.error = e.to_string();
Vec::new()
}
};
}
pub fn get_trtype_data(&self) -> Vec<(f64, f64)> {
return data_layer::get_tr_type_price_over_time(
pub fn get_trtype_data(&mut self) -> Vec<(f64, f64)> {
return match data_layer::get_tr_type_price_over_time(
&self.connection,
self.acc_list.get_selected_id(),
self.selected_tr_type_chart,
);
) {
Ok(d) => d,
Err(e) => {
self.error = e.to_string();
Vec::new()
}
};
}
pub fn select_tr_type_chart(&mut self, id: i64) {

View File

@@ -1,3 +1,5 @@
use std::error::Error;
use crate::entities::*;
use chrono::DateTime;
use sqlite::{Connection, State};
@@ -82,28 +84,7 @@ pub fn upsert_account(
));
}
// pub fn get_account(con: &Connection, id: i64) -> Account {
// let query = "SELECT * FROM Accounts WHERE id = ?";
// let mut statement = con.prepare(query).unwrap();
// statement.bind((1, id)).unwrap();
// if let Ok(State::Row) = statement.next() {
// return Account::new(
// statement.read::<i64, _>("id").unwrap(),
// statement.read::<String, _>("name").unwrap(),
// statement.read::<f64, _>("asset_price").unwrap(),
// statement
// .read::<i64, _>("type")
// .unwrap()
// .try_into()
// .unwrap(),
// );
// } else {
// return Account::new(0, "".to_string(), 0.0, AccountType::Cash);
// }
// }
pub fn get_account_total(id: i64, con: &Connection) -> f64 {
pub fn get_account_total(id: i64, con: &Connection) -> Result<f64, Box<dyn Error>> {
let mut query = "
SELECT
SUM(
@@ -119,16 +100,16 @@ JOIN Accounts a ON t.account_id = a.id"
query.push_str(" WHERE account_id = :id")
}
let mut statement = con.prepare(query).unwrap();
let mut statement = con.prepare(query)?;
if id != 0 {
statement.bind((":id", id)).unwrap();
statement.bind((":id", id))?;
}
if let Ok(State::Row) = statement.next() {
return statement.read::<f64, _>("total").unwrap();
return Ok(statement.read::<f64, _>("total")?);
} else {
return 0.0;
return Ok(0.0);
}
}
@@ -156,62 +137,40 @@ pub fn get_accounts(con: &Connection) -> Result<Vec<Account>, Box<dyn std::error
return Ok(vec);
}
// pub fn upsert_transaction_type(con: &Connection, tt: TransactionType) -> TransactionType {
// let query;
// if tt.get_id() == 0 {
// query = "INSERT INTO TransactionTypes (description) VALUES (?) RETURNING id;";
// } else {
// query = "UPDATE TransactionTypes SET description = ? WHERE id = ? RETURNING id;";
// }
// let mut statement = con.prepare(query).unwrap();
// statement.bind((1, &tt.get_description() as &str)).unwrap();
// if tt.get_id() != 0 {
// statement.bind((2, tt.get_id())).unwrap();
// }
// let id;
// if let Ok(State::Row) = statement.next() {
// id = statement.read::<i64, _>("id").unwrap();
// } else {
// id = 0;
// }
// return TransactionType::new(id, tt.get_description());
// }
pub fn get_transaction_type(con: &Connection, id: i64) -> TransactionType {
pub fn get_transaction_type(con: &Connection, id: i64) -> Result<TransactionType, Box<dyn Error>> {
let query = "SELECT * FROM TransactionTypes WHERE id = ?";
let mut statement = con.prepare(query).unwrap();
statement.bind((1, id)).unwrap();
let mut statement = con.prepare(query)?;
statement.bind((1, id))?;
if let Ok(State::Row) = statement.next() {
return TransactionType::new(
statement.read::<i64, _>("id").unwrap(),
statement.read::<String, _>("description").unwrap(),
);
return Ok(TransactionType::new(
statement.read::<i64, _>("id")?,
statement.read::<String, _>("description")?,
));
} else {
return TransactionType::new(0, "".to_string());
return Ok(TransactionType::new(0, "".to_string()));
}
}
pub fn get_transaction_types(con: &Connection) -> Vec<TransactionType> {
pub fn get_transaction_types(con: &Connection) -> Result<Vec<TransactionType>, Box<dyn Error>> {
let query = "SELECT * FROM TransactionTypes";
let mut statement = con.prepare(query).unwrap();
let mut statement = con.prepare(query)?;
let mut vec = Vec::<TransactionType>::new();
while let Ok(State::Row) = statement.next() {
vec.push(TransactionType::new(
statement.read::<i64, _>("id").unwrap(),
statement.read::<String, _>("description").unwrap(),
statement.read::<i64, _>("id")?,
statement.read::<String, _>("description")?,
));
}
return vec;
return Ok(vec);
}
pub fn upsert_transaction(con: &Connection, tr: Transaction) -> Transaction {
pub fn upsert_transaction(
con: &Connection,
tr: Transaction,
) -> Result<Transaction, Box<dyn Error>> {
let query;
if tr.get_id() == 0 {
query = "INSERT INTO Transactions
@@ -224,32 +183,26 @@ pub fn upsert_transaction(con: &Connection, tr: Transaction) -> Transaction {
WHERE id = :id RETURNING id;";
}
let mut statement = con.prepare(query).unwrap();
statement.bind((":ac_id", tr.get_account_id())).unwrap();
statement
.bind((":type_id", tr.get_type().get_id()))
.unwrap();
statement.bind((":amnt", tr.get_amount())).unwrap();
statement
.bind((":date", tr.get_date().timestamp()))
.unwrap();
statement.bind((":desc", &tr.get_desc() as &str)).unwrap();
statement
.bind((":asset_amnt", tr.get_asset_amnt()))
.unwrap();
let mut statement = con.prepare(query)?;
statement.bind((":ac_id", tr.get_account_id()))?;
statement.bind((":type_id", tr.get_type().get_id()))?;
statement.bind((":amnt", tr.get_amount()))?;
statement.bind((":date", tr.get_date().timestamp()))?;
statement.bind((":desc", &tr.get_desc() as &str))?;
statement.bind((":asset_amnt", tr.get_asset_amnt()))?;
if tr.get_id() != 0 {
statement.bind((":id", tr.get_id())).unwrap();
statement.bind((":id", tr.get_id()))?;
}
let id;
if let Ok(State::Row) = statement.next() {
id = statement.read::<i64, _>("id").unwrap();
id = statement.read::<i64, _>("id")?;
} else {
id = 0;
}
return Transaction::new(
return Ok(Transaction::new(
id,
tr.get_account_id(),
tr.get_amount(),
@@ -258,82 +211,64 @@ pub fn upsert_transaction(con: &Connection, tr: Transaction) -> Transaction {
tr.get_type().get_id(),
tr.get_asset_amnt(),
con,
);
));
}
// pub fn get_transaction(con: &Connection, id: i64) -> Transaction {
// let query = "SELECT * FROM Transactions WHERE id = :id";
// let mut statement = con.prepare(query).unwrap();
// statement.bind((":id", id)).unwrap();
// if let Ok(State::Row) = statement.next() {
// return Transaction::new(
// statement.read::<i64, _>("id").unwrap(),
// statement.read::<i64, _>("account_id").unwrap(),
// statement.read::<f64, _>("amount").unwrap(),
// DateTime::from_timestamp(statement.read::<i64, _>("date").unwrap(), 0).unwrap(),
// statement.read::<String, _>("description").unwrap(),
// statement.read::<i64, _>("type_id").unwrap(),
// statement.read::<f64, _>("asset_amount").unwrap(),
// con,
// );
// } else {
// return Transaction::new_empty();
// }
// }
pub fn get_account_transactions(con: &Connection, ac_id: i64) -> Vec<Transaction> {
pub fn get_account_transactions(
con: &Connection,
ac_id: i64,
) -> Result<Vec<Transaction>, Box<dyn Error>> {
if ac_id == 0 {
return get_transactions(con);
}
let query = "SELECT * FROM Transactions WHERE account_id = :id ORDER BY Date DESC";
let mut statement = con.prepare(query).unwrap();
statement.bind((":id", ac_id)).unwrap();
let mut statement = con.prepare(query)?;
statement.bind((":id", ac_id))?;
let mut vec = Vec::<Transaction>::new();
while let Ok(State::Row) = statement.next() {
vec.push(Transaction::new(
statement.read::<i64, _>("id").unwrap(),
statement.read::<i64, _>("account_id").unwrap(),
statement.read::<f64, _>("amount").unwrap(),
DateTime::from_timestamp(statement.read::<i64, _>("date").unwrap(), 0).unwrap(),
statement.read::<String, _>("description").unwrap(),
statement.read::<i64, _>("type_id").unwrap(),
statement.read::<f64, _>("asset_amount").unwrap(),
statement.read::<i64, _>("id")?,
statement.read::<i64, _>("account_id")?,
statement.read::<f64, _>("amount")?,
DateTime::from_timestamp(statement.read::<i64, _>("date")?, 0).unwrap_or_default(),
statement.read::<String, _>("description")?,
statement.read::<i64, _>("type_id")?,
statement.read::<f64, _>("asset_amount")?,
con,
));
}
return vec;
return Ok(vec);
}
pub fn get_transactions(con: &Connection) -> Vec<Transaction> {
pub fn get_transactions(con: &Connection) -> Result<Vec<Transaction>, Box<dyn Error>> {
let query = "SELECT * FROM Transactions ORDER BY Date DESC";
let mut statement = con.prepare(query).unwrap();
let mut statement = con.prepare(query)?;
let mut vec = Vec::<Transaction>::new();
while let Ok(State::Row) = statement.next() {
vec.push(Transaction::new(
statement.read::<i64, _>("id").unwrap(),
statement.read::<i64, _>("account_id").unwrap(),
statement.read::<f64, _>("amount").unwrap(),
DateTime::from_timestamp(statement.read::<i64, _>("date").unwrap(), 0).unwrap(),
statement.read::<String, _>("description").unwrap(),
statement.read::<i64, _>("type_id").unwrap(),
statement.read::<f64, _>("asset_amount").unwrap(),
statement.read::<i64, _>("id")?,
statement.read::<i64, _>("account_id")?,
statement.read::<f64, _>("amount")?,
DateTime::from_timestamp(statement.read::<i64, _>("date")?, 0).unwrap_or_default(),
statement.read::<String, _>("description")?,
statement.read::<i64, _>("type_id")?,
statement.read::<f64, _>("asset_amount")?,
con,
));
}
return vec;
return Ok(vec);
}
pub fn get_tr_type_price_over_time(
con: &Connection,
ac_id: i64,
tr_type_id: i64,
) -> Vec<(f64, f64)> {
) -> Result<Vec<(f64, f64)>, Box<dyn Error>> {
let mut query = "
SELECT strftime('%Y%m', datetime(date, 'unixepoch')) as z, SUM(amount) as y
FROM Transactions
@@ -345,24 +280,27 @@ WHERE type_id = :tr_type
}
query.push_str(" GROUP BY z;");
let mut statement = con.prepare(query).unwrap();
statement.bind((":tr_type", tr_type_id)).unwrap();
let mut statement = con.prepare(query)?;
statement.bind((":tr_type", tr_type_id))?;
if ac_id != 0 {
statement.bind((":ac_id", ac_id)).unwrap();
statement.bind((":ac_id", ac_id))?;
}
let mut data = Vec::<(f64, f64)>::new();
let mut x = 0.0;
while let Ok(State::Row) = statement.next() {
let y = statement.read::<f64, _>("y").unwrap() * -1.0; // Pour passer de dépense dans le négatif à un graphique qui monte
let y = statement.read::<f64, _>("y")? * -1.0; // Pour passer de dépense dans le négatif à un graphique qui monte
data.push((x, y));
x += 1.0;
}
return data;
return Ok(data);
}
pub fn get_cumulative_account_sum(con: &Connection, ac_id: i64) -> Vec<(f64, f64)> {
pub fn get_cumulative_account_sum(
con: &Connection,
ac_id: i64,
) -> Result<Vec<(f64, f64)>, Box<dyn Error>> {
let mut query = "
SELECT
SUM(amount) OVER (
@@ -375,18 +313,18 @@ FROM
query.push_str(" WHERE account_id = :ac_id");
}
let mut statement = con.prepare(query).unwrap();
let mut statement = con.prepare(query)?;
if ac_id != 0 {
statement.bind((":ac_id", ac_id)).unwrap();
statement.bind((":ac_id", ac_id))?;
}
let mut data = Vec::<(f64, f64)>::new();
let mut x = 0.0;
while let Ok(State::Row) = statement.next() {
let y = statement.read::<f64, _>("y").unwrap();
let y = statement.read::<f64, _>("y")?;
data.push((x, y));
x += 1.0;
}
return data;
return Ok(data);
}

View File

@@ -1,4 +1,4 @@
use std::convert::TryFrom;
use std::{convert::TryFrom, error::Error};
use sqlite::Connection;
@@ -53,7 +53,7 @@ impl Account {
pub fn set_type(&mut self, ac_type: AccountType) {
self.ac_type = ac_type;
}
pub fn get_total(&self, con: &Connection) -> f64 {
pub fn get_total(&self, con: &Connection) -> Result<f64, Box<dyn Error>> {
return data_layer::get_account_total(self.id, con);
}
}

View File

@@ -33,7 +33,10 @@ impl Transaction {
date: date,
description: desc,
type_id: type_id,
tr_type: data_layer::get_transaction_type(con, type_id),
tr_type: data_layer::get_transaction_type(con, type_id).unwrap_or(TransactionType {
id: 0,
description: String::new(),
}),
asset_amount: asset_amount,
}
}
@@ -91,7 +94,10 @@ impl Transaction {
}
pub fn set_type(&mut self, tr_id: i64, con: &Connection) {
self.type_id = tr_id;
self.tr_type = data_layer::get_transaction_type(con, tr_id);
self.tr_type = data_layer::get_transaction_type(con, tr_id).unwrap_or(TransactionType {
id: 0,
description: String::new(),
});
}
pub fn get_asset_amnt(&self) -> f64 {

View File

@@ -1,3 +1,5 @@
use std::error::Error;
use ratatui::widgets::TableState;
use sqlite::Connection;
@@ -19,15 +21,19 @@ impl TrxTable {
};
}
pub fn get_trx(&mut self, ac_id: i64, con: &Connection) -> Vec<Transaction> {
pub fn get_trx(
&mut self,
ac_id: i64,
con: &Connection,
) -> Result<Vec<Transaction>, Box<dyn Error>> {
if ac_id == -1 {
return Vec::new();
return Ok(Vec::new());
}
if self.trx.iter().count() == 0 || self.ac_id != ac_id {
self.ac_id = ac_id;
self.trx = data_layer::get_account_transactions(con, ac_id);
self.trx = data_layer::get_account_transactions(con, ac_id)?;
}
return self.trx.clone();
return Ok(self.trx.clone());
}
pub fn selected_tr(&self) -> Transaction {

View File

@@ -5,7 +5,7 @@ mod enums;
mod ui;
use crate::{app::App, enums::*, ui::ui};
use chrono::Local;
use entities::{Account, AccountType, Transaction};
use entities::{Account, Transaction};
use ratatui::{
Terminal,
crossterm::{

View File

@@ -63,6 +63,7 @@ pub fn ui(frame: &mut Frame, app: &mut App) {
"Total: {}",
app.get_list_accounts()[i]
.get_total(&app.connection)
.unwrap_or_default()
.to_string()
)
} else {
@@ -116,14 +117,14 @@ pub fn ui(frame: &mut Frame, app: &mut App) {
let min_x = slice
.into_iter()
.map(|&(x, _)| x)
.min_by(|a, b| a.partial_cmp(b).unwrap())
.unwrap()
.min_by(|a, b| a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Less))
.unwrap_or_default()
.round();
let max_x = slice
.into_iter()
.map(|&(x, _)| x)
.max_by(|a, b| a.partial_cmp(b).unwrap())
.unwrap()
.max_by(|a, b| a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Greater))
.unwrap_or_default()
.round()
+ 1.0;
let x_axis = Axis::default()
@@ -134,15 +135,15 @@ pub fn ui(frame: &mut Frame, app: &mut App) {
let min_y = slice
.into_iter()
.map(|&(_, y)| y)
.min_by(|a, b| a.partial_cmp(b).unwrap())
.unwrap()
.min_by(|a, b| a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Less))
.unwrap_or_default()
.round()
- 1.0;
let max_y = slice
.into_iter()
.map(|&(_, y)| y)
.max_by(|a, b| a.partial_cmp(b).unwrap())
.unwrap()
.max_by(|a, b| a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Greater))
.unwrap_or_default()
.round()
+ 1.0;
let y_axis = Axis::default()
@@ -190,14 +191,14 @@ pub fn ui(frame: &mut Frame, app: &mut App) {
let min_x = slice
.into_iter()
.map(|&(x, _)| x)
.min_by(|a, b| a.partial_cmp(b).unwrap())
.unwrap()
.min_by(|a, b| a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Less))
.unwrap_or_default()
.round();
let max_x = slice
.into_iter()
.map(|&(x, _)| x)
.max_by(|a, b| a.partial_cmp(b).unwrap())
.unwrap()
.max_by(|a, b| a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Greater))
.unwrap_or_default()
.round()
+ 1.0;
let x_axis = Axis::default()
@@ -208,15 +209,15 @@ pub fn ui(frame: &mut Frame, app: &mut App) {
let min_y = slice
.into_iter()
.map(|&(_, y)| y)
.min_by(|a, b| a.partial_cmp(b).unwrap())
.unwrap()
.min_by(|a, b| a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Less))
.unwrap_or_default()
.round()
- 1.0;
let max_y = slice
.into_iter()
.map(|&(_, y)| y)
.max_by(|a, b| a.partial_cmp(b).unwrap())
.unwrap()
.max_by(|a, b| a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Greater))
.unwrap_or_default()
.round()
+ 1.0;
let y_axis = Axis::default()