diff options
| -rw-r--r-- | rust/src/database_models.rs | 92 | ||||
| -rw-r--r-- | rust/src/entity_crud.rs | 9 | 
2 files changed, 87 insertions, 14 deletions
| diff --git a/rust/src/database_models.rs b/rust/src/database_models.rs index 47fd062d..b76b469a 100644 --- a/rust/src/database_models.rs +++ b/rust/src/database_models.rs @@ -4,7 +4,7 @@ use crate::database_schema::*;  use crate::errors::*;  use crate::identifiers::uuid2fcid;  use chrono; -use fatcat_api_spec::models::{ChangelogEntry, Editgroup, EditgroupAnnotation, Editor, EntityEdit}; +use fatcat_api_spec::models::{ChangelogEntry, Editgroup, EditgroupAnnotation, Editor, EntityEdit, ReleaseRef};  use serde_json;  use uuid::Uuid; @@ -501,15 +501,6 @@ pub struct ReleaseRefRow {      pub target_release_ident_id: Uuid,  } -/* These fields now interned in JSON blob -    pub key: Option<String>, -    pub extra_json: Option<serde_json::Value>, -    pub container_name: Option<String>, -    pub year: Option<i32>, -    pub title: Option<String>, -    pub locator: Option<String>, -*/ -  #[derive(Debug, Queryable, Insertable, Associations, AsChangeset)]  #[table_name = "refs_blob"]  pub struct RefsBlobRow { @@ -517,6 +508,87 @@ pub struct RefsBlobRow {      pub refs_json: serde_json::Value,  } +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +/// This model is a stable representation of what goes in a RefsBlobRow `refs_json` field (an array +/// of this model). We could rely on the `ReleaseRef` API spec model directly, but that would lock +/// the database contents to the API spec rigidly; by defining this struct independently, we can +/// migrate the schemas. To start, this is a direct copy of the `ReleaseRef` model. +pub struct RefsBlobJson { +    #[serde(rename = "index")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub index: Option<i64>, + +    /// base32-encoded unique identifier +    #[serde(rename = "target_release_id")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub target_release_id: Option<String>, + +    #[serde(rename = "extra")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub extra: Option<serde_json::Value>, + +    #[serde(rename = "key")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub key: Option<String>, + +    #[serde(rename = "year")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub year: Option<i64>, + +    #[serde(rename = "container_name")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub container_name: Option<String>, + +    #[serde(rename = "title")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub title: Option<String>, + +    #[serde(rename = "locator")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub locator: Option<String>, +} + +impl RefsBlobJson { +    pub fn into_model(self) -> ReleaseRef { +        ReleaseRef { +            index: self.index, +            target_release_id: self.target_release_id, +            extra: self.extra, +            key: self.key, +            year: self.year, +            container_name: self.container_name, +            title: self.title, +            locator: self.locator, +        } +    } + +    pub fn to_model(&self) -> ReleaseRef { +        ReleaseRef { +            index: self.index, +            target_release_id: self.target_release_id.clone(), +            extra: self.extra.clone(), +            key: self.key.clone(), +            year: self.year, +            container_name: self.container_name.clone(), +            title: self.title.clone(), +            locator: self.locator.clone(), +        } +    } + +    pub fn from_model(model: &ReleaseRef) -> RefsBlobJson { +        RefsBlobJson { +            index: model.index, +            target_release_id: model.target_release_id.clone(), +            extra: model.extra.clone(), +            key: model.key.clone(), +            year: model.year, +            container_name: model.container_name.clone(), +            title: model.title.clone(), +            locator: model.locator.clone(), +        } +    } +} +  #[derive(Debug, Queryable, Insertable, Associations, AsChangeset)]  #[table_name = "file_rev_release"]  pub struct FileRevReleaseRow { diff --git a/rust/src/entity_crud.rs b/rust/src/entity_crud.rs index 1147e117..09ce9542 100644 --- a/rust/src/entity_crud.rs +++ b/rust/src/entity_crud.rs @@ -1819,7 +1819,8 @@ impl EntityCrud for ReleaseEntity {                  let refs_blob: RefsBlobRow = refs_blob::table                      .find(sha1) // checked in match                      .get_result(conn)?; -                let mut refs: Vec<ReleaseRef> = serde_json::from_value(refs_blob.refs_json)?; +                let refs: Vec<RefsBlobJson> = serde_json::from_value(refs_blob.refs_json)?; +                let mut refs: Vec<ReleaseRef> = refs.into_iter().map(|j| j.into_model()).collect();                  let ref_rows: Vec<ReleaseRefRow> = release_ref::table                      .filter(release_ref::release_rev.eq(rev_row.id))                      .order(release_ref::index_val.asc()) @@ -1967,10 +1968,10 @@ impl EntityCrud for ReleaseEntity {                      }                      // Have to strip out target refs and indexes, or hashing won't work well when                      // these change -                    let ref_list: Vec<ReleaseRef> = ref_list +                    let ref_list: Vec<RefsBlobJson> = ref_list                          .iter() -                        .map(|r| { -                            let mut r = r.clone(); +                        .map(|r: &ReleaseRef| { +                            let mut r = RefsBlobJson::from_model(r);                              r.target_release_id = None;                              r.index = None;                              r | 
