lib

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

nostr_event_head.rs (5916B)


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