diff --git a/migrations/create_tables_001.sql b/migrations/create_tables_001.sql index 2e856a3..0a3d16d 100644 --- a/migrations/create_tables_001.sql +++ b/migrations/create_tables_001.sql @@ -9,7 +9,7 @@ CREATE TABLE IF NOT EXISTS users CREATE TABLE IF NOT EXISTS security_types ( name TEXT PRIMARY KEY -); +) STRICT ; INSERT INTO security_types(name) VALUES ('currency'), ('bond'); @@ -40,4 +40,4 @@ CREATE TABLE IF NOT EXISTS accounts CREATE TABLE IF NOT EXISTS account_values ( id INTEGER PRIMARY KEY AUTOINCREMENT -); +) STRICT; diff --git a/src/db/account.rs b/src/db/_accounts.rs similarity index 56% rename from src/db/account.rs rename to src/db/_accounts.rs index 4dbb2e2..e0bea59 100644 --- a/src/db/account.rs +++ b/src/db/_accounts.rs @@ -1,29 +1,40 @@ use rusqlite::{Connection, params, Result, Row, Transaction}; -use crate::db::securities::Security; -use crate::db::users::User; +use crate::db::_securities::Security; +use crate::db::_users::User; pub struct Account { - id: i64, - amount: i64, - timestamp: i64, + pub id: i64, + pub amount: i64, + pub timestamp: i64, + pub security: Security, } -fn _account_from_row(row: &Row) -> Result { - return Ok(Account{ - id: row.get(0)?, - amount: row.get(1)?, - timestamp: row.get(2)?, - }); +impl Account { + pub fn from_row(row: &Row) -> Result{ + return Ok(Account{ + id: row.get("acc_id")?, + amount: row.get("acc_amount")?, + timestamp: row.get("acc_timestamp")?, + security: Security::from_row(row)?, + }); + } } pub fn list_accounts<'a>(conn: &Connection) -> Result> { - let q = "SELECT id, amount, UNIXEPOCH(timestamp) - FROM accounts - ORDER BY id ASC"; + let q = "SELECT acc.id AS acc_id, + acc.amount AS acc_amount, + UNIXEPOCH(acc.timestamp) AS acc_timestamp, + + sec.id AS sec_id, + sec.symbol AS sec_symbol, + sec.security_type AS sec_security_type + FROM accounts acc + JOIN securities sec ON acc.security = sec.id + ORDER BY acc.id ASC"; let mut stmt = conn.prepare(q)?; let ret: Vec = stmt - .query_map([], &_account_from_row)? + .query_map([], &Account::from_row)? .filter(Result::is_ok) .map(Result::unwrap) .collect(); @@ -31,8 +42,17 @@ pub fn list_accounts<'a>(conn: &Connection) -> Result> { } pub fn get_account_by_id(tx: &Transaction, id: u32) -> Result{ - let q = "SELECT id, amount, UNIXEPOCH(timestamp) FROM accounts WHERE id = ?1"; - return tx.query_row(q, params![id], _account_from_row); + let q = "SELECT acc.id AS acc_id, + acc.amount AS acc_amount, + UNIXEPOCH(acc.timestamp) AS acc_timestamp, + + sec.id AS sec_id, + sec.symbol AS sec_symbol, + sec.security_type AS sec_security_type + FROM accounts acc + JOIN securities sec ON acc.security = sec.id + WHERE acc.id = ?1"; + return tx.query_row(q, params![id], Account::from_row); } pub fn create_account(tx: &Transaction, sec: &Security, user: &User) -> Result{ @@ -45,21 +65,21 @@ pub fn create_account(tx: &Transaction, sec: &Security, user: &User) -> Result Result> { - let user_1 = users::create_user(tx, &"bernard".to_string(), &"123".to_string())?; - let user_2 = users::create_user(tx, &"sam".to_string(), &"abc".to_string())?; + let user_1 = _users::create_user(tx, &"bernard".to_string(), &"123".to_string())?; + let user_2 = _users::create_user(tx, &"sam".to_string(), &"abc".to_string())?; return Ok(vec![user_1, user_2]); } fn setup_securities(tx: &Transaction) -> Result> { - let sec_1 = securities::create_security(tx, &securities::test_util::mock_currency_1())?; - let sec_2 = securities::create_security(tx, &securities::test_util::mock_currency_2())?; + let sec_1 = _securities::create_security(tx, &_securities::test_util::mock_currency_1())?; + let sec_2 = _securities::create_security(tx, &_securities::test_util::mock_currency_2())?; return Ok(vec![sec_1, sec_2]); } diff --git a/src/db/securities.rs b/src/db/_securities.rs similarity index 89% rename from src/db/securities.rs rename to src/db/_securities.rs index d82d10c..08ec95a 100644 --- a/src/db/securities.rs +++ b/src/db/_securities.rs @@ -37,6 +37,16 @@ pub struct Security { symbol: String, } +impl Security { + pub fn from_row(row: &Row) -> Result { + Ok(Security { + id: row.get("sec_id")?, + security_type: SecurityType::from_string(row.get("sec_security_type")?), + symbol: row.get("sec_symbol")?, + }) + } +} + pub struct NewSecurity { security_type: SecurityType, symbol: String, @@ -52,29 +62,21 @@ pub fn create_security(tx: &Transaction, sec: &NewSecurity) -> Result return get_security_by_id(tx, tx.last_insert_rowid() as i32); } -fn _security_from_row(row: &Row) -> Result { - Ok(Security { - id: row.get(0)?, - security_type: SecurityType::from_string(row.get(1)?), - symbol: row.get(2)?, - }) -} - pub fn get_security_by_id(tx: &Transaction, id: i32) -> Result { - let q = "SELECT id, security_type, symbol + let q = "SELECT id AS sec_id, security_type AS sec_security_type, symbol AS sec_symbol FROM securities WHERE id = ?1"; - tx.query_row(q, params![id], _security_from_row) + tx.query_row(q, params![id], Security::from_row) } pub fn list_securities(conn: &Connection) -> Result> { - let q = "SELECT id, security_type, symbol + let q = "SELECT id AS sec_id, security_type AS sec_security_type, symbol AS sec_symbol FROM securities ORDER BY id ASC"; let mut stmt = conn.prepare(q)?; let ret: Vec = stmt - .query_map([], &_security_from_row)? + .query_map([], Security::from_row)? .filter(Result::is_ok) .map(Result::unwrap) .collect(); diff --git a/src/db/users.rs b/src/db/_users.rs similarity index 100% rename from src/db/users.rs rename to src/db/_users.rs diff --git a/src/db/mod.rs b/src/db/mod.rs index a9e3cf4..675d720 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -1,6 +1,16 @@ -mod users; -mod securities; -mod account; +mod _users; +mod _securities; +mod _accounts; -pub use securities::{list_securities, Security}; -pub use users::{create_user, list_users, User}; \ No newline at end of file +pub mod securities{ + pub use super::_securities::{list_securities, get_security_by_id, Security}; + +} + +pub mod users{ + pub use super::_users::{create_user, list_users, User}; +} + +pub mod accounts { + pub use super::_accounts::{get_account_by_id, list_accounts, create_account, Account}; +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 3a330f2..df9045b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,11 +7,12 @@ use serde::Serialize; use simple_logger::SimpleLogger; use crate::migration::apply_migrations; -use db::list_securities; -use crate::db::{create_user, list_users}; +use db::securities::list_securities; +use crate::db::users::{create_user, list_users}; mod migration; mod db; +mod services; #[derive(Debug, Serialize)] struct Output { @@ -268,7 +269,7 @@ impl ProCommandLineLogic { impl CommandLineUserLogic for ProCommandLineLogic { fn create_user(&mut self, conn: &mut Connection, name: &String, public_key: &String) { let tx = conn.transaction().unwrap(); - create_user(& tx, name, public_key); + create_user(& tx, name, public_key).unwrap(); tx.commit().unwrap(); } diff --git a/src/services/_transactions.rs b/src/services/_transactions.rs new file mode 100644 index 0000000..9980f18 --- /dev/null +++ b/src/services/_transactions.rs @@ -0,0 +1,9 @@ +use rusqlite::{Transaction, Result}; +use crate::db::accounts::get_account_by_id; +use crate::db::securities::get_security_by_id; + +fn update_account(tx: & Transaction, account_id: u32) -> Result<()>{ + let account = get_account_by_id(tx, account_id)?; + // let sec = get_security_by_id(tx, account.) + return Ok(()) +} \ No newline at end of file diff --git a/src/services/mod.rs b/src/services/mod.rs new file mode 100644 index 0000000..490f567 --- /dev/null +++ b/src/services/mod.rs @@ -0,0 +1 @@ +mod _transactions; \ No newline at end of file