ft_rs/src/data_layer.rs
2025-10-17 15:34:14 -04:00

153 lines
4.6 KiB
Rust

use crate::entities::*;
use sqlite::{Connection, State};
pub fn setup(con: &Connection) {
let _ = con.execute(
"
CREATE TABLE IF NOT EXISTS Accounts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
type INTEGER NOT NULL
);
CREATE TABLE IF NOT EXISTS TransactionTypes (
id INTEGER PRIMARY KEY AUTOINCREMENT,
description TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS Transactions (
id INTEGER PRIMARY KEY AUTOINCREMENT,
account_id INTEGER NOT NULL,
type_id INTEGER NOT NULL,
amount FLOAT NOT NULL,
date DATE NOT NULL,
description TEXT,
FOREIGN KEY(account_id) REFERENCES Accounts(id),
FOREIGN KEY(type_id) REFERENCES TransactionTypes(id)
);
",
);
}
pub fn upsert_account(con: &Connection, ac: Account) -> Account {
let query;
let ac_type = ac.get_ac_type() as i64;
if ac.get_id() == 0 {
query = "INSERT INTO Accounts (name, type) VALUES (?, ?) RETURNING id;";
} else {
query = "UPDATE Accounts SET name = ?, type = ? WHERE id = ? RETURNING id;";
}
let mut statement = con.prepare(query).unwrap();
statement.bind((1, &ac.get_name() as &str)).unwrap();
statement.bind((2, ac_type)).unwrap();
if ac.get_id() != 0 {
statement.bind((3, ac.get_id())).unwrap();
}
let id;
if let Ok(State::Row) = statement.next() {
id = statement.read::<i64, _>("id").unwrap();
} else {
id = 0;
}
return Account::new(id, ac.get_name(), ac_type.try_into().unwrap());
}
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::<i64, _>("type")
.unwrap()
.try_into()
.unwrap(),
);
} else {
return Account::new(0, "".to_string(), AccountType::Cash);
}
}
pub fn get_accounts(con: &Connection) -> Vec<Account> {
let query = "SELECT * FROM Accounts";
let mut statement = con.prepare(query).unwrap();
let mut vec = Vec::<Account>::new();
while let Ok(State::Row) = statement.next() {
vec.push(Account::new(
statement.read::<i64, _>("id").unwrap(),
statement.read::<String, _>("name").unwrap(),
statement
.read::<i64, _>("type")
.unwrap()
.try_into()
.unwrap(),
));
}
return 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 {
let query = "SELECT * FROM TransactionTypes WHERE id = ?";
let mut statement = con.prepare(query).unwrap();
statement.bind((1, id)).unwrap();
if let Ok(State::Row) = statement.next() {
return TransactionType::new(
statement.read::<i64, _>("id").unwrap(),
statement.read::<String, _>("description").unwrap(),
);
} else {
return TransactionType::new(0, "".to_string());
}
}
pub fn get_transaction_types(con: &Connection) -> Vec<TransactionType> {
let query = "SELECT * FROM TransactionTypes";
let mut statement = con.prepare(query).unwrap();
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(),
));
}
return vec;
}