lib

Core libraries for Radroots
git clone https://radroots.dev/git/lib.git
Log | Files | Refs | README | LICENSE

log_error.rs (5694B)


      1 use radroots_replica_db_schema::log_error::{
      2     ILogErrorCreate, ILogErrorCreateResolve, ILogErrorDelete, ILogErrorDeleteResolve,
      3     ILogErrorFieldsFilter, ILogErrorFindMany, ILogErrorFindManyResolve, ILogErrorFindOne,
      4     ILogErrorFindOneResolve, ILogErrorUpdate, ILogErrorUpdateResolve, LogError,
      5     LogErrorQueryBindValues,
      6 };
      7 use radroots_sql_core::error::SqlError;
      8 use radroots_sql_core::{SqlExecutor, utils};
      9 use radroots_types::types::{IError, IResult, IResultList};
     10 use serde_json::Value;
     11 
     12 const TABLE_NAME: &str = "log_error";
     13 
     14 pub fn create(
     15     exec: &dyn SqlExecutor,
     16     opts: &ILogErrorCreate,
     17 ) -> Result<ILogErrorCreateResolve, IError<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, &params_json)?;
     29     let on = LogErrorQueryBindValues::Id { id: id.clone() };
     30     let result = find_one_by_on(exec, &on)?.ok_or(IError::from(SqlError::NotFound(id.clone())))?;
     31     Ok(IResult { result })
     32 }
     33 
     34 pub fn find_one(
     35     exec: &dyn SqlExecutor,
     36     opts: &ILogErrorFindOne,
     37 ) -> Result<ILogErrorFindOneResolve, IError<SqlError>> {
     38     let result = match opts {
     39         ILogErrorFindOne::On(args) => find_one_by_on(exec, &args.on)?,
     40     };
     41     Ok(IResult { result })
     42 }
     43 
     44 pub fn find_many(
     45     exec: &dyn SqlExecutor,
     46     opts: &ILogErrorFindMany,
     47 ) -> Result<ILogErrorFindManyResolve, IError<SqlError>> {
     48     let results = find_many_filter(exec, &opts.filter)?;
     49     Ok(IResultList { results })
     50 }
     51 
     52 fn find_many_filter(
     53     exec: &dyn SqlExecutor,
     54     filter: &Option<ILogErrorFieldsFilter>,
     55 ) -> Result<Vec<LogError>, IError<SqlError>> {
     56     let (sql, bind_values) = utils::build_select_query_with_meta(TABLE_NAME, filter.as_ref());
     57     let params_json = utils::to_params_json(bind_values).expect("serialize bind params");
     58     let json = exec.query_raw(&sql, &params_json)?;
     59     let rows: Vec<LogError> = utils::parse_json(&json)?;
     60     Ok(rows)
     61 }
     62 
     63 fn find_one_by_on(
     64     exec: &dyn SqlExecutor,
     65     on: &LogErrorQueryBindValues,
     66 ) -> Result<Option<LogError>, IError<SqlError>> {
     67     let (column, value) = on.to_filter_param();
     68     let sql = format!("SELECT * FROM {TABLE_NAME} WHERE {column} = ? LIMIT 1;");
     69     let params_json = utils::to_params_json(vec![value]).expect("serialize bind params");
     70     let json = exec.query_raw(&sql, &params_json)?;
     71     let mut rows: Vec<LogError> = utils::parse_json(&json)?;
     72     Ok(rows.pop())
     73 }
     74 
     75 fn select_by_id(exec: &dyn SqlExecutor, id: &str) -> Result<LogError, IError<SqlError>> {
     76     let params_json =
     77         utils::to_params_json(vec![Value::from(id.to_owned())]).expect("serialize bind params");
     78     let sql = format!("SELECT * FROM {TABLE_NAME} WHERE id = ?;");
     79     let json = exec.query_raw(&sql, &params_json)?;
     80     let mut rows: Vec<LogError> = utils::parse_json(&json)?;
     81     rows.pop()
     82         .ok_or(IError::from(SqlError::NotFound(id.to_owned())))
     83 }
     84 
     85 pub fn update(
     86     exec: &dyn SqlExecutor,
     87     opts: &ILogErrorUpdate,
     88 ) -> Result<ILogErrorUpdateResolve, IError<SqlError>> {
     89     let mut updates =
     90         utils::to_partial_object_map(&opts.fields).expect("serialize partial object map");
     91     if updates.is_empty() {
     92         return Err(IError::from(SqlError::InvalidArgument(String::from(
     93             "no fields to update",
     94         ))));
     95     }
     96     updates.insert(
     97         String::from("updated_at"),
     98         Value::from(utils::time_created_on()),
     99     );
    100     let mut set_parts = Vec::with_capacity(updates.len());
    101     let mut bind_values = Vec::with_capacity(updates.len() + 1);
    102     for (column, value) in updates {
    103         set_parts.push(format!("{column} = ?"));
    104         bind_values.push(utils::to_db_bind_value(&value));
    105     }
    106     let id_for_lookup = match opts.on.primary_key() {
    107         Some(id) => id,
    108         None => {
    109             let found = find_one_by_on(exec, &opts.on)?;
    110             let model = found.ok_or(IError::from(SqlError::NotFound(opts.on.lookup_key())))?;
    111             model.id
    112         }
    113     };
    114     bind_values.push(Value::from(id_for_lookup.clone()));
    115     let sql = format!(
    116         "UPDATE {TABLE_NAME} SET {} WHERE id = ?;",
    117         set_parts.join(", ")
    118     );
    119     let params_json = utils::to_params_json(bind_values).expect("serialize bind params");
    120     let _ = exec.exec(&sql, &params_json)?;
    121     let updated = select_by_id(exec, &id_for_lookup)?;
    122     Ok(IResult { result: updated })
    123 }
    124 
    125 pub fn delete(
    126     exec: &dyn SqlExecutor,
    127     opts: &ILogErrorDelete,
    128 ) -> Result<ILogErrorDeleteResolve, IError<SqlError>> {
    129     let id_for_lookup = match opts {
    130         ILogErrorDelete::On(args) => match args.on.primary_key() {
    131             Some(id) => id,
    132             None => {
    133                 let found = find_one_by_on(exec, &args.on)?;
    134                 let model = found.ok_or(IError::from(SqlError::NotFound(args.on.lookup_key())))?;
    135                 model.id
    136             }
    137         },
    138     };
    139     let params_json = utils::to_params_json(vec![Value::from(id_for_lookup.clone())])
    140         .expect("serialize bind params");
    141     let sql = format!("DELETE FROM {TABLE_NAME} WHERE id = ?;");
    142     let outcome = exec.exec(&sql, &params_json)?;
    143     if outcome.changes == 0 {
    144         return Err(IError::from(SqlError::NotFound(id_for_lookup.clone())));
    145     }
    146     Ok(IResult {
    147         result: id_for_lookup,
    148     })
    149 }