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
+118 -23

No files matched your search

+1
View File
@@ -20,6 +20,7 @@ CREATE TABLE IF NOT EXISTS securities
security_type TEXT NOT NULL,
name TEXT NOT NULL UNIQUE,
symbol TEXT NOT NULL UNIQUE,
creation_time DATETIME DEFAULT CURRENT_TIMESTAMP,
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){
}
+14 -7
View File
@@ -1,17 +1,18 @@
use std::path::PathBuf;
use clap::{Arg, ArgAction, ArgMatches, Command, value_parser};
use serde::{Serialize};
use log::{debug, info};
use rusqlite::Connection;
use serde::Serialize;
use simple_logger::SimpleLogger;
use crate::migration::apply_migrations;
use crate::securities::list_securities;
mod migration;
mod users;
mod securities;
mod account;
#[derive(Debug, Serialize)]
struct Output<T> {
@@ -23,7 +24,6 @@ impl<T> Output<T> {
fn success(shit: T) -> Output<T> {
return Output { status: "success".to_string(), result: shit };
}
}
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) {
debug!("Processing list securities command line {:?}.", m);
logic.list_securities(conn);
}
fn process_securities_command_line(conn: &Connection, m: &ArgMatches, logic: &mut dyn CommandLineUserLogic) {
debug!("Processing securities command line {:?}.", m);
match m.subcommand() {
@@ -292,8 +290,17 @@ impl CommandLineUserLogic for ProCommandLineLogic {
}
}
fn list_securities(&mut self, _conn: &Connection) {
todo!()
fn list_securities(&mut self, conn: & Connection) {
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 serde::{Serialize};
use rusqlite::{Connection, Result, ToSql};
use serde::Serialize;
use crate::migration;
#[derive(Debug, Serialize)]
#[derive(Debug, Serialize, PartialEq)]
pub enum SecurityType {
Currency,
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 {
#[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 {
SecurityType::Currency => "currency",
SecurityType::Bond => "bond",
@@ -19,11 +31,10 @@ impl ToSql for SecurityType {
}
}
#[derive(Debug, Serialize)]
#[derive(Debug, Serialize, PartialEq)]
pub struct Security {
id: i32,
security_type: SecurityType,
public_key: String,
symbol: String,
}
@@ -34,22 +45,38 @@ pub struct NewSecurity {
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 q = "INSERT INTO
securities(name, symbol, security_type)
VALUES(?1, ?2, ?3)";
let params = (&sec.name, &sec.symbol, &sec.security_type);
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)]
mod test {
use super::*;
use rusqlite::{Connection, params};
use super::*;
fn setup() -> Connection {
let mut conn = Connection::open_in_memory().unwrap();
@@ -57,6 +84,24 @@ mod test {
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]
fn test_security_types() -> Result<(), rusqlite::Error> {
let conn = setup();
@@ -76,13 +121,39 @@ mod test {
#[test]
fn test_create_security() -> Result<(), rusqlite::Error> {
let mut conn = setup();
let sec = NewSecurity {
security_type: SecurityType::Currency,
public_key: "123".to_string(),
symbol: "P".to_string(),
name: "pisatre".to_string(),
};
let sec = mock_currency_1();
create_security(&mut conn, &sec)?;
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(());
}
}