Going somewhere.

This commit is contained in:
didier amyot committed 2022-12-08 11:07:35 -05:00
1 parent 4a86c4250a
commit 511b2a88f6
6 files changed
+127 -18

No files matched your search

Generated
+7
View File
@@ -146,6 +146,7 @@ dependencies = [
"clap-verbosity-flag", "clap-verbosity-flag",
"home", "home",
"log", "log",
"resource",
"rusqlite", "rusqlite",
"serde", "serde",
"serde_json", "serde_json",
@@ -335,6 +336,12 @@ dependencies = [
"proc-macro2", "proc-macro2",
] ]
[[package]]
name = "resource"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "11a7f6703c396037a02da99195e49138c37f3cc5146cb95f2f7d26debc0c5622"
[[package]] [[package]]
name = "rusqlite" name = "rusqlite"
version = "0.28.0" version = "0.28.0"
+2 -1
View File
@@ -14,4 +14,5 @@ simple_logger = "4.0.0"
log = "0.4.17" log = "0.4.17"
home = "0.5.4" home = "0.5.4"
sha2 = "0.10.6" sha2 = "0.10.6"
serde_json = "1.0" serde_json = "1.0"
resource = "0.5.0"
@@ -2,23 +2,25 @@ CREATE TABLE IF NOT EXISTS users
( (
id INTEGER PRIMARY KEY AUTOINCREMENT, id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL, name TEXT NOT NULL,
public_key TEXT NOT NULL public_key TEXT NOT NULL,
foo INTEGER
); );
CREATE TABLE IF NOT EXISTS security_types CREATE TABLE IF NOT EXISTS security_types
( (
id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT PRIMARY KEY
name TEXT NOT NULL UNIQUE
); );
INSERT INTO security_types(name)
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 INTEGER 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,
FOREIGN KEY (security_type) REFERENCES security_types (name)
FOREIGN KEY (security_type) REFERENCES security_types (id)
); );
CREATE TABLE IF NOT EXISTS account CREATE TABLE IF NOT EXISTS account
@@ -33,4 +35,4 @@ CREATE TABLE IF NOT EXISTS account
CREATE TABLE IF NOT EXISTS account_values CREATE TABLE IF NOT EXISTS account_values
( (
id INTEGER PRIMARY KEY AUTOINCREMENT id INTEGER PRIMARY KEY AUTOINCREMENT
); );
+6 -5
View File
@@ -7,7 +7,7 @@ use log::{debug, info};
use rusqlite::Connection; use rusqlite::Connection;
use simple_logger::SimpleLogger; use simple_logger::SimpleLogger;
use crate::migration::migrate; use crate::migration::apply_migrations;
mod migration; mod migration;
mod users; mod users;
@@ -68,8 +68,8 @@ fn new_user_command_line_parser() -> Command {
return Command::new("new") return Command::new("new")
.long_flag("new") .long_flag("new")
.about("Create new user.") .about("Create new user.")
.arg(Arg::new("name").long("name").help("name of new user.").action(ArgAction::Set)) .arg(Arg::new("name").long("name").required(true).help("name of new user.").action(ArgAction::Set))
.arg(Arg::new("public_key").long("public-key").help("public key of users.").action(ArgAction::Set)); .arg(Arg::new("public_key").required(true).long("public-key").help("public key of users.").action(ArgAction::Set));
} }
fn ls_user_command_line_parser() -> Command { fn ls_user_command_line_parser() -> Command {
@@ -308,14 +308,15 @@ fn set_logger(m: &ArgMatches) {
SimpleLogger::new().with_level(get_verbosity(&m)).init().unwrap(); SimpleLogger::new().with_level(get_verbosity(&m)).init().unwrap();
} }
fn main() { fn main() {
let command = command_line_parser(); let command = command_line_parser();
let m = command.get_matches(); let m = command.get_matches();
set_logger(&m); set_logger(&m);
let mut conn = get_connection(&m); let mut conn = get_connection(&m);
let migrations: Vec<String> = Vec::new();
migrate(&mut conn, & migrations).unwrap(); apply_migrations(&mut conn).unwrap();
let mut logic = ProCommandLineLogic::new(); let mut logic = ProCommandLineLogic::new();
process_command_line(&conn, &m, &mut logic); process_command_line(&conn, &m, &mut logic);
} }
+15 -3
View File
@@ -1,6 +1,7 @@
use std::time::Instant; use std::time::Instant;
use rusqlite::{Connection, Transaction}; use rusqlite::{Connection, Transaction};
use sha2::{Digest, Sha256}; use sha2::{Digest, Sha256};
use resource::{resource_str};
#[derive(Debug)] #[derive(Debug)]
pub enum IntegrityError { pub enum IntegrityError {
@@ -52,13 +53,12 @@ pub fn migrate(conn: &mut Connection, migrations: &Vec<String>) -> Result<(), Er
fn apply_migration(tx: &Transaction, id: usize, migration: &String) -> Result<(), Error> { fn apply_migration(tx: &Transaction, id: usize, migration: &String) -> Result<(), Error> {
let hash = compute_migration_sha256(migration); let hash = compute_migration_sha256(migration);
let q = "INSERT INTO shitty_migrations(id, sha256) VALUES (?1, ?2)"; let q = "INSERT INTO shitty_migrations(id, sha256) VALUES (?1, ?2)";
tx.execute(q, (&id, &hash)).map_err(|e| Error::Sql(e))?; tx.execute(q, (&id, &hash)).map_err(|e| Error::Sql(e))?;
// let migration_id = tx.last_insert_rowid();
let now = Instant::now(); let now = Instant::now();
tx.execute(migration, ()).map_err(|e| Error::Sql(e))?; tx.execute_batch(migration).map_err(|e| Error::Sql(e))?;
let elapsed_time = now.elapsed(); let elapsed_time = now.elapsed();
let q = "UPDATE shitty_migrations SET duration = ?1 WHERE id = ?2"; let q = "UPDATE shitty_migrations SET duration = ?1 WHERE id = ?2";
@@ -89,6 +89,18 @@ fn check_migration(tx: &Transaction, id: usize, migration: &String) -> Result<()
return Ok(()); return Ok(());
} }
fn get_migrations() -> Vec<String> {
let mut ret = Vec::new();
ret.push(resource_str!("migrations/create_tables_001.sql").as_ref().to_string());
return ret;
}
pub fn apply_migrations(conn: &mut Connection) -> Result<(), Error> {
let migrations = get_migrations();
return migrate(conn, &migrations);
}
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use super::*; use super::*;
+86
View File
@@ -1,2 +1,88 @@
use rusqlite::{Connection, ToSql};
use serde::{Serialize};
use crate::migration;
#[derive(Debug, Serialize)]
pub enum SecurityType {
Currency,
Bond,
}
impl ToSql for SecurityType {
#[inline]
fn to_sql(&self) -> rusqlite::Result<rusqlite::types::ToSqlOutput<'_>> {
Ok(rusqlite::types::ToSqlOutput::from(match self {
SecurityType::Currency => "currency",
SecurityType::Bond => "bond",
}))
}
}
#[derive(Debug, Serialize)]
pub struct Security {
id: i32,
security_type: SecurityType,
public_key: String,
symbol: String,
}
pub struct NewSecurity {
security_type: SecurityType,
public_key: String,
symbol: String,
name: String,
}
pub fn create_security(conn: &mut Connection, sec: &NewSecurity) -> Result<(), rusqlite::Error> {
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(());
}
#[cfg(test)]
mod test {
use super::*;
use rusqlite::{Connection, params};
fn setup() -> Connection {
let mut conn = Connection::open_in_memory().unwrap();
migration::apply_migrations(&mut conn).unwrap();
return conn;
}
#[test]
fn test_security_types() -> Result<(), rusqlite::Error> {
let conn = setup();
let q = "CREATE TABLE test_security_types(
name TEXT,
FOREIGN KEY (name) REFERENCES security_types (name)
)";
conn.execute(q, ())?;
let security_types = vec![SecurityType::Currency, SecurityType::Bond];
for sec in security_types.iter() {
let q = "INSERT INTO test_security_types(name) VALUES (?1)";
conn.execute(q, params![sec])?;
}
return Ok(());
}
#[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(),
};
create_security(&mut conn, &sec)?;
return Ok(());
}
}