Ho fuck you car.

This commit is contained in:
didier amyot committed 2022-12-10 17:18:22 -05:00
1 parent 511b2a88f6
commit 20cc644bfb
4 files changed
+124 -29

No files matched your search

+5 -4
View File
@@ -16,10 +16,11 @@ VALUES ('currency'), ('bond');
CREATE TABLE IF NOT EXISTS securities CREATE TABLE IF NOT EXISTS securities
( (
id INTEGER PRIMARY KEY AUTOINCREMENT, id INTEGER PRIMARY KEY AUTOINCREMENT,
security_type TEXT NOT NULL, security_type TEXT NOT NULL,
name TEXT NOT NULL UNIQUE, name TEXT NOT NULL UNIQUE,
symbol TEXT NOT NULL UNIQUE, symbol TEXT NOT NULL UNIQUE,
creation_time DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (security_type) REFERENCES security_types (name) FOREIGN KEY (security_type) REFERENCES security_types (name)
); );
+16
View File
@@ -0,0 +1,16 @@
use rusqlite::Connection;
use crate::securities::Security;
use crate::users::User;
struct Account<'a> {
security: &'a Security,
user: &'a User,
amount: i64,
time_stamp: i64
}
pub fn list_accounts(conn: & Connection){
}
+16 -9
View File
@@ -1,17 +1,18 @@
use std::path::PathBuf; use std::path::PathBuf;
use clap::{Arg, ArgAction, ArgMatches, Command, value_parser}; use clap::{Arg, ArgAction, ArgMatches, Command, value_parser};
use serde::{Serialize};
use log::{debug, info}; use log::{debug, info};
use rusqlite::Connection; use rusqlite::Connection;
use serde::Serialize;
use simple_logger::SimpleLogger; use simple_logger::SimpleLogger;
use crate::migration::apply_migrations; use crate::migration::apply_migrations;
use crate::securities::list_securities;
mod migration; mod migration;
mod users; mod users;
mod securities; mod securities;
mod account;
#[derive(Debug, Serialize)] #[derive(Debug, Serialize)]
struct Output<T> { struct Output<T> {
@@ -21,9 +22,8 @@ struct Output<T> {
impl<T> Output<T> { impl<T> Output<T> {
fn success(shit: T) -> Output<T> { fn success(shit: T) -> Output<T> {
return Output{status: "success".to_string(), result: shit}; return Output { status: "success".to_string(), result: shit };
} }
} }
trait CommandLineUserLogic { trait CommandLineUserLogic {
@@ -128,13 +128,11 @@ fn process_user_command_line(conn: &Connection, m: &ArgMatches, logic: &mut dyn
} }
} }
fn process_list_securities_command_line(conn: &Connection, m: &ArgMatches, logic: &mut dyn CommandLineUserLogic) { fn process_list_securities_command_line(conn: &Connection, m: &ArgMatches, logic: &mut dyn CommandLineUserLogic) {
debug!("Processing list securities command line {:?}.", m); debug!("Processing list securities command line {:?}.", m);
logic.list_securities(conn); logic.list_securities(conn);
} }
fn process_securities_command_line(conn: &Connection, m: &ArgMatches, logic: &mut dyn CommandLineUserLogic) { fn process_securities_command_line(conn: &Connection, m: &ArgMatches, logic: &mut dyn CommandLineUserLogic) {
debug!("Processing securities command line {:?}.", m); debug!("Processing securities command line {:?}.", m);
match m.subcommand() { match m.subcommand() {
@@ -284,7 +282,7 @@ impl CommandLineUserLogic for ProCommandLineLogic {
let out = Output::success(r); let out = Output::success(r);
println!("{}", serde_json::to_string(& out).unwrap()); println!("{}", serde_json::to_string(&out).unwrap());
} }
Err(e) => { Err(e) => {
println!("{:?}", e); println!("{:?}", e);
@@ -292,8 +290,17 @@ impl CommandLineUserLogic for ProCommandLineLogic {
} }
} }
fn list_securities(&mut self, _conn: &Connection) { fn list_securities(&mut self, conn: & Connection) {
todo!() let securities = list_securities(conn);
match securities {
Ok(s) => {
let out = Output::success(s);
println!("{}", serde_json::to_string(&out).unwrap());
},
Err(e) => {
println!("{:?}", e);
}
};
} }
} }
+87 -16
View File
@@ -1,17 +1,29 @@
use rusqlite::{Connection, ToSql}; use rusqlite::{Connection, Result, ToSql};
use serde::{Serialize}; use serde::Serialize;
use crate::migration; use crate::migration;
#[derive(Debug, Serialize, PartialEq)]
#[derive(Debug, Serialize)]
pub enum SecurityType { pub enum SecurityType {
Currency, Currency,
Bond, Bond,
} }
impl SecurityType {
fn from_string(s: String) -> SecurityType {
if s == "currency".to_string() {
return SecurityType::Currency;
}
if s == "bond".to_string() {
return SecurityType::Bond;
}
panic!("Impossible to convert string {} to SecurityType.", s);
}
}
impl ToSql for SecurityType { impl ToSql for SecurityType {
#[inline] #[inline]
fn to_sql(&self) -> rusqlite::Result<rusqlite::types::ToSqlOutput<'_>> { fn to_sql(&self) -> Result<rusqlite::types::ToSqlOutput<'_>> {
Ok(rusqlite::types::ToSqlOutput::from(match self { Ok(rusqlite::types::ToSqlOutput::from(match self {
SecurityType::Currency => "currency", SecurityType::Currency => "currency",
SecurityType::Bond => "bond", SecurityType::Bond => "bond",
@@ -19,11 +31,10 @@ impl ToSql for SecurityType {
} }
} }
#[derive(Debug, Serialize)] #[derive(Debug, Serialize, PartialEq)]
pub struct Security { pub struct Security {
id: i32, id: i32,
security_type: SecurityType, security_type: SecurityType,
public_key: String,
symbol: String, symbol: String,
} }
@@ -34,22 +45,38 @@ pub struct NewSecurity {
name: String, name: String,
} }
pub fn create_security(conn: &mut Connection, sec: &NewSecurity) -> Result<(), rusqlite::Error> { pub fn create_security(conn: &mut Connection, sec: &NewSecurity) -> Result<()> {
let tx = conn.transaction()?; let tx = conn.transaction()?;
let q = "INSERT INTO let q = "INSERT INTO
securities(name, symbol, security_type) securities(name, symbol, security_type)
VALUES(?1, ?2, ?3)"; VALUES(?1, ?2, ?3)";
let params = (&sec.name, &sec.symbol, &sec.security_type); let params = (&sec.name, &sec.symbol, &sec.security_type);
tx.execute(q, params)?; tx.execute(q, params)?;
return Ok(()); return tx.commit();
}
pub fn list_securities(conn: & Connection) -> Result<Vec<Security>> {
let q = "SELECT id, security_type, symbol
FROM securities
ORDER BY creation_time DESC";
let mut stmt = conn.prepare(q)?;
let ret: Vec<Security> = stmt.query_map([], |row| {
Ok(Security {
id: row.get(0)?,
security_type: SecurityType::from_string(row.get(1)?),
symbol: row.get(2)?,
})
}).unwrap().filter(|x| x.is_ok()).map(|x| x.unwrap()).collect();
return Ok(ret);
} }
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use super::*;
use rusqlite::{Connection, params}; use rusqlite::{Connection, params};
use super::*;
fn setup() -> Connection { fn setup() -> Connection {
let mut conn = Connection::open_in_memory().unwrap(); let mut conn = Connection::open_in_memory().unwrap();
@@ -57,6 +84,24 @@ mod test {
return conn; return conn;
} }
fn mock_currency_1() -> NewSecurity {
return NewSecurity {
security_type: SecurityType::Currency,
public_key: "123".to_string(),
symbol: "P".to_string(),
name: "pisatre".to_string(),
};
}
fn mock_currency_2() -> NewSecurity {
return NewSecurity {
security_type: SecurityType::Bond,
public_key: "123".to_string(),
symbol: "B".to_string(),
name: "bong".to_string(),
};
}
#[test] #[test]
fn test_security_types() -> Result<(), rusqlite::Error> { fn test_security_types() -> Result<(), rusqlite::Error> {
let conn = setup(); let conn = setup();
@@ -76,13 +121,39 @@ mod test {
#[test] #[test]
fn test_create_security() -> Result<(), rusqlite::Error> { fn test_create_security() -> Result<(), rusqlite::Error> {
let mut conn = setup(); let mut conn = setup();
let sec = NewSecurity { let sec = mock_currency_1();
security_type: SecurityType::Currency,
public_key: "123".to_string(),
symbol: "P".to_string(),
name: "pisatre".to_string(),
};
create_security(&mut conn, &sec)?; create_security(&mut conn, &sec)?;
return Ok(()); return Ok(());
} }
#[test]
fn test_list_security() -> Result<(), rusqlite::Error> {
let mut conn = setup();
assert_eq!(0, list_securities(& conn)?.len());
let sec = mock_currency_1();
create_security(&mut conn, &sec)?;
let ret = list_securities(& conn)?;
let expt = Security {
id: 1,
security_type: SecurityType::Currency,
symbol: "P".to_string(),
};
assert_eq!(1, ret.len());
assert_eq!(&expt, ret.get(0).unwrap());
let sec = mock_currency_2();
let expt = Security {
id: 2,
security_type: SecurityType::Bond,
symbol: "B".to_string(),
};
create_security(&mut conn, &sec)?;
let ret = list_securities(& conn)?;
assert_eq!(2, ret.len());
assert_eq!(&expt, ret.get(1).unwrap());
return Ok(());
}
} }