trade_product.rs (5750B)
1 use radroots_replica_schema::trade_product::{ 2 ITradeProductCreate, ITradeProductCreateResolve, ITradeProductDelete, 3 ITradeProductDeleteResolve, ITradeProductFieldsFilter, ITradeProductFindMany, 4 ITradeProductFindManyResolve, ITradeProductFindOne, ITradeProductFindOneResolve, 5 ITradeProductUpdate, ITradeProductUpdateResolve, TradeProduct, TradeProductQueryBindValues, 6 }; 7 use radroots_replica_schema::{ReplicaSchemaError, ReplicaSchemaResult, ReplicaSchemaResultList}; 8 use radroots_sql_core::error::SqlError; 9 use radroots_sql_core::{SqlExecutor, utils}; 10 use serde_json::Value; 11 12 const TABLE_NAME: &str = "trade_product"; 13 14 pub fn create( 15 exec: &dyn SqlExecutor, 16 opts: &ITradeProductCreate, 17 ) -> Result<ITradeProductCreateResolve, ReplicaSchemaError<SqlError>> { 18 let field_map = utils::to_object_map(opts).expect("serialize object map"); 19 let id = utils::uuidv4(); 20 let now = utils::time_created_on(); 21 let meta: [(&str, Value); 3] = [ 22 ("id", Value::from(id.clone())), 23 ("created_at", Value::from(now.clone())), 24 ("updated_at", Value::from(now.clone())), 25 ]; 26 let (sql, bind_values) = utils::build_insert_query_with_meta(TABLE_NAME, &meta, &field_map); 27 let params_json = utils::to_params_json(bind_values).expect("serialize bind params"); 28 let _ = exec.exec(&sql, ¶ms_json)?; 29 let on = TradeProductQueryBindValues::Id { id: id.clone() }; 30 let result = find_one_by_on(exec, &on)? 31 .ok_or(ReplicaSchemaError::from(SqlError::NotFound(id.clone())))?; 32 Ok(ReplicaSchemaResult { result }) 33 } 34 35 pub fn find_one( 36 exec: &dyn SqlExecutor, 37 opts: &ITradeProductFindOne, 38 ) -> Result<ITradeProductFindOneResolve, ReplicaSchemaError<SqlError>> { 39 let result = match opts { 40 ITradeProductFindOne::On(args) => find_one_by_on(exec, &args.on)?, 41 }; 42 Ok(ReplicaSchemaResult { result }) 43 } 44 45 pub fn find_many( 46 exec: &dyn SqlExecutor, 47 opts: &ITradeProductFindMany, 48 ) -> Result<ITradeProductFindManyResolve, ReplicaSchemaError<SqlError>> { 49 let results = find_many_filter(exec, &opts.filter)?; 50 Ok(ReplicaSchemaResultList { results }) 51 } 52 53 fn find_many_filter( 54 exec: &dyn SqlExecutor, 55 filter: &Option<ITradeProductFieldsFilter>, 56 ) -> Result<Vec<TradeProduct>, ReplicaSchemaError<SqlError>> { 57 let (sql, bind_values) = utils::build_select_query_with_meta(TABLE_NAME, filter.as_ref()); 58 let params_json = utils::to_params_json(bind_values).expect("serialize bind params"); 59 let json = exec.query_raw(&sql, ¶ms_json)?; 60 let rows: Vec<TradeProduct> = utils::parse_json(&json)?; 61 Ok(rows) 62 } 63 64 fn find_one_by_on( 65 exec: &dyn SqlExecutor, 66 on: &TradeProductQueryBindValues, 67 ) -> Result<Option<TradeProduct>, ReplicaSchemaError<SqlError>> { 68 let (column, value) = on.to_filter_param(); 69 let sql = format!("SELECT * FROM {TABLE_NAME} WHERE {column} = ? LIMIT 1;"); 70 let params_json = utils::to_params_json(vec![value]).expect("serialize bind params"); 71 let json = exec.query_raw(&sql, ¶ms_json)?; 72 let mut rows: Vec<TradeProduct> = utils::parse_json(&json)?; 73 Ok(rows.pop()) 74 } 75 76 fn select_by_id( 77 exec: &dyn SqlExecutor, 78 id: &str, 79 ) -> Result<TradeProduct, ReplicaSchemaError<SqlError>> { 80 let params_json = 81 utils::to_params_json(vec![Value::from(id.to_owned())]).expect("serialize bind params"); 82 let sql = format!("SELECT * FROM {TABLE_NAME} WHERE id = ?;"); 83 let json = exec.query_raw(&sql, ¶ms_json)?; 84 let mut rows: Vec<TradeProduct> = utils::parse_json(&json)?; 85 rows.pop() 86 .ok_or(ReplicaSchemaError::from(SqlError::NotFound(id.to_owned()))) 87 } 88 89 pub fn update( 90 exec: &dyn SqlExecutor, 91 opts: &ITradeProductUpdate, 92 ) -> Result<ITradeProductUpdateResolve, ReplicaSchemaError<SqlError>> { 93 let mut updates = 94 utils::to_partial_object_map(&opts.fields).expect("serialize partial object map"); 95 if updates.is_empty() { 96 return Err(ReplicaSchemaError::from(SqlError::InvalidArgument( 97 String::from("no fields to update"), 98 ))); 99 } 100 updates.insert( 101 String::from("updated_at"), 102 Value::from(utils::time_created_on()), 103 ); 104 let mut set_parts = Vec::with_capacity(updates.len()); 105 let mut bind_values = Vec::with_capacity(updates.len() + 1); 106 for (column, value) in updates { 107 set_parts.push(format!("{column} = ?")); 108 bind_values.push(utils::to_db_bind_value(&value)); 109 } 110 let id_for_lookup = match &opts.on { 111 TradeProductQueryBindValues::Id { id } => id.clone(), 112 }; 113 bind_values.push(Value::from(id_for_lookup.clone())); 114 let sql = format!( 115 "UPDATE {TABLE_NAME} SET {} WHERE id = ?;", 116 set_parts.join(", ") 117 ); 118 let params_json = utils::to_params_json(bind_values).expect("serialize bind params"); 119 let _ = exec.exec(&sql, ¶ms_json)?; 120 let updated = select_by_id(exec, &id_for_lookup)?; 121 Ok(ReplicaSchemaResult { result: updated }) 122 } 123 124 pub fn delete( 125 exec: &dyn SqlExecutor, 126 opts: &ITradeProductDelete, 127 ) -> Result<ITradeProductDeleteResolve, ReplicaSchemaError<SqlError>> { 128 let id_for_lookup = match opts { 129 ITradeProductDelete::On(args) => match &args.on { 130 TradeProductQueryBindValues::Id { id } => id.clone(), 131 }, 132 }; 133 let params_json = utils::to_params_json(vec![Value::from(id_for_lookup.clone())]) 134 .expect("serialize bind params"); 135 let sql = format!("DELETE FROM {TABLE_NAME} WHERE id = ?;"); 136 let outcome = exec.exec(&sql, ¶ms_json)?; 137 if outcome.changes == 0 { 138 return Err(ReplicaSchemaError::from(SqlError::NotFound( 139 id_for_lookup.clone(), 140 ))); 141 } 142 Ok(ReplicaSchemaResult { 143 result: id_for_lookup, 144 }) 145 }