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 |