diff options
Diffstat (limited to 'rust/src')
| -rw-r--r-- | rust/src/api_server.rs | 56 | ||||
| -rw-r--r-- | rust/src/database_models.rs | 26 | 
2 files changed, 81 insertions, 1 deletions
diff --git a/rust/src/api_server.rs b/rust/src/api_server.rs index aaf3d9a7..efe40165 100644 --- a/rust/src/api_server.rs +++ b/rust/src/api_server.rs @@ -129,6 +129,31 @@ macro_rules! wrap_lookup_handler {      }  } +macro_rules! wrap_history_handler { +    ($get_fn:ident, $get_handler:ident, $get_resp:ident) => { +        fn $get_fn( +            &self, +            id: String, +            limit: Option<i64>, +            _context: &Context, +        ) -> Box<Future<Item = $get_resp, Error = ApiError> + Send> { +            let ret = match self.$get_handler(id.clone(), limit) { +                Ok(history) => +                    $get_resp::FoundEntityHistory(history), +                Err(Error(ErrorKind::Diesel(::diesel::result::Error::NotFound), _)) => +                    $get_resp::NotFound(ErrorResponse { message: format!("No such entity {}: {}", stringify!($model), id) }), +                Err(Error(ErrorKind::Uuid(e), _)) => +                    $get_resp::BadRequest(ErrorResponse { message: e.to_string() }), +                Err(e) => { +                    error!("{}", e); +                    $get_resp::GenericError(ErrorResponse { message: e.to_string() }) +                }, +            }; +            Box::new(futures::done(Ok(ret))) +        } +    } +} +  macro_rules! count_entity {      ($table:ident, $conn:expr) => {{          let count: i64 = $table::table @@ -350,6 +375,32 @@ impl Server {          container_row2entity(Some(ident), rev)      } +    fn get_container_history_handler( +        &self, +        id: String, +        limit: Option<i64>, +    ) -> Result<Vec<EntityHistoryEntry>> { +        let conn = self.db_pool.get().expect("db_pool error"); +        let id = uuid::Uuid::parse_str(&id)?; +        let limit = limit.unwrap_or(50); + +        let rows: Vec<(EditgroupRow, ChangelogRow, ContainerEditRow)> = editgroup::table +            .inner_join(changelog::table) +            .inner_join(container_edit::table) +            .filter(container_edit::ident_id.eq(id)) +            .limit(limit) +            .get_results(&conn)?; + +        let history: Vec<EntityHistoryEntry> = rows.into_iter() +            .map(|(eg_row, cl_row, ce_row)| EntityHistoryEntry { +                edit: ce_row.to_model().expect("edit row to model"), +                editgroup: eg_row.to_model_partial(), +                changelog_entry: cl_row.to_model(), +            }) +            .collect(); +        Ok(history) +    } +      fn get_creator_handler(&self, id: String) -> Result<CreatorEntity> {          let conn = self.db_pool.get().expect("db_pool error");          let id = uuid::Uuid::parse_str(&id)?; @@ -1084,6 +1135,11 @@ impl Api for Server {          doi,          String      ); +    wrap_history_handler!( +        get_container_history, +        get_container_history_handler, +        GetContainerHistoryResponse +    );      // Rename "wrap_lookup_handler"?      wrap_lookup_handler!( diff --git a/rust/src/database_models.rs b/rust/src/database_models.rs index dd84748d..6fa9b7b7 100644 --- a/rust/src/database_models.rs +++ b/rust/src/database_models.rs @@ -1,7 +1,7 @@  use chrono;  use database_schema::*;  use errors::*; -use fatcat_api::models::EntityEdit; +use fatcat_api::models::{ChangelogEntry, Editgroup, EntityEdit};  use serde_json;  use uuid::Uuid; @@ -243,6 +243,20 @@ pub struct EditgroupRow {      pub description: Option<String>,  } +impl EditgroupRow { +    /// Returns an Edigroup API model *without* the entity edits actually populated. Useful for, +    /// eg, entity history queries (where we already have the entity edit we want) +    pub fn to_model_partial(self) -> Editgroup { +        Editgroup { +            id: Some(self.id), +            editor_id: self.editor_id, +            description: self.description, +            extra: self.extra_json, +            edits: None, +        } +    } +} +  #[derive(Debug, Queryable, Identifiable, Associations, AsChangeset)]  #[table_name = "editor"]  pub struct EditorRow { @@ -259,3 +273,13 @@ pub struct ChangelogRow {      pub editgroup_id: i64,      pub timestamp: chrono::NaiveDateTime,  } + +impl ChangelogRow { +    pub fn to_model(self) -> ChangelogEntry { +        ChangelogEntry { +            index: self.id, +            editgroup_id: self.editgroup_id, +            timestamp: chrono::DateTime::from_utc(self.timestamp, chrono::Utc), +        } +    } +}  | 
