Going somewhere.
This commit is contained in:
1 parent
4a86c4250a
commit
511b2a88f6
6 files changed
+123
-14
No files matched your search
Generated
+7
@@ -146,6 +146,7 @@ dependencies = [
|
||||
"clap-verbosity-flag",
|
||||
"home",
|
||||
"log",
|
||||
"resource",
|
||||
"rusqlite",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -335,6 +336,12 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "resource"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "11a7f6703c396037a02da99195e49138c37f3cc5146cb95f2f7d26debc0c5622"
|
||||
|
||||
[[package]]
|
||||
name = "rusqlite"
|
||||
version = "0.28.0"
|
||||
|
||||
@@ -15,3 +15,4 @@ log = "0.4.17"
|
||||
home = "0.5.4"
|
||||
sha2 = "0.10.6"
|
||||
serde_json = "1.0"
|
||||
resource = "0.5.0"
|
||||
@@ -2,23 +2,25 @@ CREATE TABLE IF NOT EXISTS users
|
||||
(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT NOT NULL,
|
||||
public_key TEXT NOT NULL
|
||||
public_key TEXT NOT NULL,
|
||||
foo INTEGER
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS security_types
|
||||
(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT NOT NULL UNIQUE
|
||||
name TEXT PRIMARY KEY
|
||||
);
|
||||
|
||||
INSERT INTO security_types(name)
|
||||
VALUES ('currency'), ('bond');
|
||||
|
||||
CREATE TABLE IF NOT EXISTS securities
|
||||
(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
security_type INTEGER NOT NULL,
|
||||
security_type TEXT NOT NULL,
|
||||
name TEXT NOT NULL UNIQUE,
|
||||
symbol TEXT NOT NULL UNIQUE,
|
||||
|
||||
FOREIGN KEY (security_type) REFERENCES security_types (id)
|
||||
FOREIGN KEY (security_type) REFERENCES security_types (name)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS account
|
||||
+6
-5
@@ -7,7 +7,7 @@ use log::{debug, info};
|
||||
use rusqlite::Connection;
|
||||
use simple_logger::SimpleLogger;
|
||||
|
||||
use crate::migration::migrate;
|
||||
use crate::migration::apply_migrations;
|
||||
|
||||
mod migration;
|
||||
mod users;
|
||||
@@ -68,8 +68,8 @@ fn new_user_command_line_parser() -> Command {
|
||||
return Command::new("new")
|
||||
.long_flag("new")
|
||||
.about("Create new user.")
|
||||
.arg(Arg::new("name").long("name").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("name").long("name").required(true).help("name of new user.").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 {
|
||||
@@ -308,14 +308,15 @@ fn set_logger(m: &ArgMatches) {
|
||||
SimpleLogger::new().with_level(get_verbosity(&m)).init().unwrap();
|
||||
}
|
||||
|
||||
|
||||
fn main() {
|
||||
let command = command_line_parser();
|
||||
let m = command.get_matches();
|
||||
|
||||
set_logger(&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();
|
||||
process_command_line(&conn, &m, &mut logic);
|
||||
}
|
||||
+15
-3
@@ -1,6 +1,7 @@
|
||||
use std::time::Instant;
|
||||
use rusqlite::{Connection, Transaction};
|
||||
use sha2::{Digest, Sha256};
|
||||
use resource::{resource_str};
|
||||
|
||||
#[derive(Debug)]
|
||||
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> {
|
||||
let hash = compute_migration_sha256(migration);
|
||||
|
||||
|
||||
let q = "INSERT INTO shitty_migrations(id, sha256) VALUES (?1, ?2)";
|
||||
tx.execute(q, (&id, &hash)).map_err(|e| Error::Sql(e))?;
|
||||
// let migration_id = tx.last_insert_rowid();
|
||||
|
||||
|
||||
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 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(());
|
||||
}
|
||||
|
||||
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)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
@@ -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(());
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user