use actix_web::web::Data; use chrono::{Datelike, DateTime, Timelike, Utc}; use futures::executor::block_on; use sqlx::{Arguments, Pool, Row, Sqlite}; use sqlx::sqlite::{SqliteArguments, SqliteRow}; use common::models::production::Production; use common::models::used::Used; use crate::traits::database::{Database, DatabaseSub}; use crate::traits::query::QuerySub; use crate::traits::standard::{Standard, StandardSub}; impl Standard for Production { fn table_name() -> String { "production".to_string() } } impl StandardSub for Production { fn parent_table() -> String { "produced_entry_id".to_string() } } impl QuerySub for Production { fn from_sqlite_row(row: SqliteRow, _parent_id: i64, pool: &Data>) -> Production { let production_id: i64 = row.get(0); let uses = Used::get_by_parent_id(production_id, pool); Production { id: production_id, date_created: row.get(1), date_produced: row.get(2), mhd: row.get(3), uses } } fn from_sqlite_row_small(row: SqliteRow, _parent_id: i64, _pool: &Data>) -> Production { Production { id: row.get(0), date_created: row.get(1), date_produced: row.get(2), mhd: row.get(3), uses: vec![] } } } impl DatabaseSub for Production { } impl Database for Production { fn insert(&self, pool: &Data>) -> i64 { // TODO: First check if there is enough from ingredient to produce let statement = format!( "INSERT INTO {} (date_created) VALUES ($1)", Production::table_name(), ); let mut date_time: DateTime = Utc::now(); date_time = date_time.with_day(21).unwrap(); date_time = date_time.with_month(09).unwrap(); //date_time = date_time.with_hour(10).unwrap(); let mut args = SqliteArguments::default(); args.add(date_time); let mut conn = block_on(pool.acquire()).unwrap(); let temp = block_on( sqlx::query_with( statement.as_str(), args) .execute(&mut *conn) ); println!("Produced result:\n {:#?}", temp); // TODO: Check if problematic with more users when more productions are created in a very very short timespan. let production_id = temp.unwrap().last_insert_rowid(); for entry in &self.uses { let mut entry = entry.clone(); entry.production_id = Some(production_id); entry.order_pos_id = None; entry.insert(pool); } production_id } fn update(&self, pool: &Data>) { let production = Production::get_by_id(self.id, pool).first().unwrap().clone(); let mut date_produced: Option> = self.date_produced; let mut mhd: Option> = self.mhd; if production.date_produced.is_some() { date_produced = production.date_produced; } if production.mhd.is_some() { mhd = production.mhd; } let statement = format!( "UPDATE {} SET date_produced = $2, mhd = $3 WHERE id = $1", Production::table_name(), ); let mut args = SqliteArguments::default(); args.add(&self.id); args.add(date_produced); args.add(mhd); println!("Production"); let mut conn = block_on(pool.acquire()).unwrap(); let temp = block_on( sqlx::query_with( statement.as_str(), args) .execute(&mut *conn) ); println!("Result:\n {:#?}", temp); } fn delete(&self, _pool: &Data>) { println!("Not allowed to delete!") } fn get_all(pool: &Data>) -> Vec { let mut conn = block_on(pool.acquire()).unwrap(); let res = block_on( sqlx::query(format!("SELECT * FROM {}", Production::table_name()).as_str()) .fetch_all(&mut *conn) ); conn.detach(); let mut productions: Vec = Vec::new(); match res { Ok(records) => { for record in records { productions.push( // TODO: Load parent_id //Production::from_sqlite_row(record, -1, pool) Production::from_sqlite_row_small(record, -1, pool) ); } } Err(err) => { println!("Error while loading all production entries:"); println!("{:#?}", err); } } productions } fn get_by_id(id: i64, pool: &Data>) -> Vec { let statement = format!( "SELECT * FROM {} WHERE id = $1", Production::table_name(), ); let mut args = SqliteArguments::default(); args.add(id); let mut conn = block_on(pool.acquire()).unwrap(); let res = block_on( sqlx::query_with( statement.as_str(), args) .fetch_all(&mut *conn) ); conn.detach(); let mut productions: Vec = Vec::new(); match res { Ok(records) => { for record in records { productions.push( // TODO: Load parent_id Production::from_sqlite_row(record, -1, pool) //Production::from_sqlite_row_small(record, -1, pool) ); } } Err(err) => { println!("Error while loading production with id: {}:", id); println!("{:#?}", err); } } productions } fn get_by_search(search_term: String, pool: &Data>) -> Vec { let statement = format!( "SELECT * FROM {} WHERE description like \"%{}%\"", Production::table_name(), search_term, ); let mut conn = block_on(pool.acquire()).unwrap(); let res = block_on( sqlx::query( statement.as_str()) .fetch_all(&mut *conn) ); conn.detach(); let mut productions: Vec = Vec::new(); match res { Ok(records) => { for record in records { productions.push( // TODO: Load parent_id //Production::from_sqlite_row(record, -1, pool) Production::from_sqlite_row_small(record, -1, pool) ); } } Err(err) => { println!("Error while loading variants with search term: {}:", search_term); println!("{:#?}", err); } } productions } }