sql implementation for account and ttype

This commit is contained in:
thatscringebro 2025-10-17 15:34:14 -04:00
parent d5e34d1534
commit 8a862a444f
5 changed files with 153 additions and 16 deletions

1
.gitignore vendored
View File

@ -20,3 +20,4 @@ Cargo.lock
# and can be added to the global gitignore or merged into this file. For a more nuclear # and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder. # option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/ #.idea/
*.db

View File

@ -1,5 +1,5 @@
use sqlite::{Connection, State};
use crate::entities::*; use crate::entities::*;
use sqlite::{Connection, State};
pub fn setup(con: &Connection) { pub fn setup(con: &Connection) {
let _ = con.execute( let _ = con.execute(
@ -25,11 +25,56 @@ pub fn setup(con: &Connection) {
FOREIGN KEY(account_id) REFERENCES Accounts(id), FOREIGN KEY(account_id) REFERENCES Accounts(id),
FOREIGN KEY(type_id) REFERENCES TransactionTypes(id) FOREIGN KEY(type_id) REFERENCES TransactionTypes(id)
); );
"); ",
);
} }
//pub fn 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> { pub fn get_accounts(con: &Connection) -> Vec<Account> {
let query = "SELECT * FROM Accounts"; let query = "SELECT * FROM Accounts";
@ -37,7 +82,70 @@ pub fn get_accounts(con: &Connection) -> Vec<Account> {
let mut vec = Vec::<Account>::new(); let mut vec = Vec::<Account>::new();
while let Ok(State::Row) = statement.next() { 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())); 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; return vec;

View File

@ -1,11 +1,11 @@
use std::convert::TryFrom; use std::convert::TryFrom;
pub struct Account { pub struct Account {
id: i64, id: i64,
pub name: String, name: String,
ac_type: AccountType, ac_type: AccountType,
} }
impl Account{ impl Account {
pub fn new(id: i64, name: String, ac_type: AccountType) -> Self { pub fn new(id: i64, name: String, ac_type: AccountType) -> Self {
Account { Account {
id: id, id: id,
@ -13,14 +13,23 @@ impl Account{
ac_type: ac_type, ac_type: ac_type,
} }
} }
pub fn get_id(&self) -> i64 {
return self.id;
}
pub fn get_name(&self) -> String {
return self.name.clone();
}
pub fn get_ac_type(&self) -> AccountType {
return AccountType::try_from(self.ac_type as i64).unwrap();
}
} }
pub enum AccountType{ #[derive(Copy, Clone)]
Cash, pub enum AccountType {
Cash = 1,
Assets, Assets,
} }
impl TryFrom<i64> for AccountType { impl TryFrom<i64> for AccountType {
type Error = (); type Error = ();

View File

@ -1,5 +1,5 @@
use chrono::{DateTime, Utc};
use crate::entities::Account; use crate::entities::Account;
use chrono::{DateTime, Utc};
pub struct Transaction { pub struct Transaction {
id: i32, id: i32,
@ -13,7 +13,22 @@ pub struct Transaction {
tr_type: TransactionType, tr_type: TransactionType,
} }
pub struct TransactionType{ pub struct TransactionType {
id: i32, id: i64,
description: String, description: String,
} }
impl TransactionType {
pub fn new(id: i64, desc: String) -> Self {
TransactionType {
id: id,
description: desc,
}
}
pub fn get_id(&self) -> i64 {
return self.id;
}
pub fn get_description(&self) -> String {
return self.description.clone();
}
}

View File

@ -2,6 +2,8 @@ mod data_layer;
mod entities; mod entities;
use sqlite::Connection; use sqlite::Connection;
use crate::entities::Account;
fn main() { fn main() {
println!("Hello, world!"); println!("Hello, world!");
@ -14,8 +16,10 @@ fn main() {
}; };
data_layer::setup(&connection); data_layer::setup(&connection);
let mut account = Account::new(0, "test".to_string(), entities::AccountType::Cash);
account = data_layer::upsert_account(&connection, account);
let accounts = data_layer::get_accounts(&connection); let accounts = data_layer::get_accounts(&connection);
for ac in accounts.iter() { for ac in accounts.iter() {
println!("name: {}", ac.name) println!("name: {}", ac.get_name())
} }
} }