farm.rs (6033B)
1 use radroots_replica_schema::farm::{ 2 Farm, FarmQueryBindValues, IFarmCreate, IFarmCreateResolve, IFarmDelete, IFarmDeleteResolve, 3 IFarmFieldsFilter, IFarmFindMany, IFarmFindManyResolve, IFarmFindOne, IFarmFindOneResolve, 4 IFarmUpdate, IFarmUpdateResolve, 5 }; 6 use radroots_replica_schema::{ReplicaSchemaError, ReplicaSchemaResult, ReplicaSchemaResultList}; 7 use radroots_sql_core::error::SqlError; 8 use radroots_sql_core::{SqlExecutor, utils}; 9 use serde_json::Value; 10 11 const TABLE_NAME: &str = "farm"; 12 13 pub fn create( 14 exec: &dyn SqlExecutor, 15 opts: &IFarmCreate, 16 ) -> Result<IFarmCreateResolve, ReplicaSchemaError<SqlError>> { 17 let field_map = utils::to_object_map(opts).expect("farm create fields serialize"); 18 let id = utils::uuidv4(); 19 let now = utils::time_created_on(); 20 let meta: [(&str, Value); 3] = [ 21 ("id", Value::from(id.clone())), 22 ("created_at", Value::from(now.clone())), 23 ("updated_at", Value::from(now.clone())), 24 ]; 25 let (sql, bind_values) = utils::build_insert_query_with_meta(TABLE_NAME, &meta, &field_map); 26 let params_json = 27 utils::to_params_json(bind_values).expect("farm create bind params serialize"); 28 let _ = exec.exec(&sql, ¶ms_json)?; 29 let on = FarmQueryBindValues::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: &IFarmFindOne, 38 ) -> Result<IFarmFindOneResolve, ReplicaSchemaError<SqlError>> { 39 let result = match opts { 40 IFarmFindOne::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: &IFarmFindMany, 48 ) -> Result<IFarmFindManyResolve, 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<IFarmFieldsFilter>, 56 ) -> Result<Vec<Farm>, ReplicaSchemaError<SqlError>> { 57 let (sql, bind_values) = utils::build_select_query_with_meta(TABLE_NAME, filter.as_ref()); 58 let params_json = 59 utils::to_params_json(bind_values).expect("farm find_many bind params serialize"); 60 let json = exec.query_raw(&sql, ¶ms_json)?; 61 let rows: Vec<Farm> = utils::parse_json(&json)?; 62 Ok(rows) 63 } 64 65 fn find_one_by_on( 66 exec: &dyn SqlExecutor, 67 on: &FarmQueryBindValues, 68 ) -> Result<Option<Farm>, ReplicaSchemaError<SqlError>> { 69 let (column, value) = on.to_filter_param(); 70 let sql = format!("SELECT * FROM {TABLE_NAME} WHERE {column} = ? LIMIT 1;"); 71 let params_json = 72 utils::to_params_json(vec![value]).expect("farm find_one bind params serialize"); 73 let json = exec.query_raw(&sql, ¶ms_json)?; 74 let mut rows: Vec<Farm> = utils::parse_json(&json)?; 75 Ok(rows.pop()) 76 } 77 78 fn select_by_id(exec: &dyn SqlExecutor, id: &str) -> Result<Farm, ReplicaSchemaError<SqlError>> { 79 let params_json = utils::to_params_json(vec![Value::from(id.to_owned())]) 80 .expect("farm select_by_id bind params serialize"); 81 let sql = format!("SELECT * FROM {TABLE_NAME} WHERE id = ?;"); 82 let json = exec.query_raw(&sql, ¶ms_json)?; 83 let mut rows: Vec<Farm> = utils::parse_json(&json)?; 84 rows.pop() 85 .ok_or(ReplicaSchemaError::from(SqlError::NotFound(id.to_owned()))) 86 } 87 88 pub fn update( 89 exec: &dyn SqlExecutor, 90 opts: &IFarmUpdate, 91 ) -> Result<IFarmUpdateResolve, ReplicaSchemaError<SqlError>> { 92 let mut updates = 93 utils::to_partial_object_map(&opts.fields).expect("farm update fields serialize"); 94 if updates.is_empty() { 95 return Err(ReplicaSchemaError::from(SqlError::InvalidArgument( 96 String::from("no fields to update"), 97 ))); 98 } 99 updates.insert( 100 String::from("updated_at"), 101 Value::from(utils::time_created_on()), 102 ); 103 let mut set_parts = Vec::with_capacity(updates.len()); 104 let mut bind_values = Vec::with_capacity(updates.len() + 1); 105 for (column, value) in updates { 106 set_parts.push(format!("{column} = ?")); 107 bind_values.push(utils::to_db_bind_value(&value)); 108 } 109 let id_for_lookup = match opts.on.primary_key() { 110 Some(id) => id, 111 None => { 112 let found = find_one_by_on(exec, &opts.on)?; 113 let model = found.ok_or(ReplicaSchemaError::from(SqlError::NotFound( 114 opts.on.lookup_key(), 115 )))?; 116 model.id 117 } 118 }; 119 bind_values.push(Value::from(id_for_lookup.clone())); 120 let sql = format!( 121 "UPDATE {TABLE_NAME} SET {} WHERE id = ?;", 122 set_parts.join(", ") 123 ); 124 let params_json = 125 utils::to_params_json(bind_values).expect("farm update bind params serialize"); 126 let _ = exec.exec(&sql, ¶ms_json)?; 127 let updated = select_by_id(exec, &id_for_lookup)?; 128 Ok(ReplicaSchemaResult { result: updated }) 129 } 130 131 pub fn delete( 132 exec: &dyn SqlExecutor, 133 opts: &IFarmDelete, 134 ) -> Result<IFarmDeleteResolve, ReplicaSchemaError<SqlError>> { 135 let id_for_lookup = match opts { 136 IFarmDelete::On(args) => match args.on.primary_key() { 137 Some(id) => id, 138 None => { 139 let found = find_one_by_on(exec, &args.on)?; 140 let model = found.ok_or(ReplicaSchemaError::from(SqlError::NotFound( 141 args.on.lookup_key(), 142 )))?; 143 model.id 144 } 145 }, 146 }; 147 let params_json = utils::to_params_json(vec![Value::from(id_for_lookup.clone())]) 148 .expect("farm delete bind params serialize"); 149 let sql = format!("DELETE FROM {TABLE_NAME} WHERE id = ?;"); 150 let outcome = exec.exec(&sql, ¶ms_json)?; 151 if outcome.changes == 0 { 152 return Err(ReplicaSchemaError::from(SqlError::NotFound( 153 id_for_lookup.clone(), 154 ))); 155 } 156 Ok(ReplicaSchemaResult { 157 result: id_for_lookup, 158 }) 159 }