use chrono; use database_schema::*; use errors::*; use serde_json; use uuid::Uuid; // Ugh. I thought the whole point was to *not* do this, but: // https://github.com/diesel-rs/diesel/issues/1589 pub enum EntityState { WorkInProgress, Active(i64), Redirect(Uuid, i64), Deleted, } impl EntityState { pub fn shortname(&self) -> String { match self { EntityState::WorkInProgress => "wip", EntityState::Active(_) => "active", EntityState::Redirect(_, _) => "redirect", EntityState::Deleted => "deleted", }.to_string() } } pub trait EntityIdentRow { fn state(&self) -> Result; } // Helper for constructing tables macro_rules! entity_structs { ($edit_table:expr, $edit_struct:ident, $ident_table:expr, $ident_struct:ident) => { #[derive(Debug, Queryable, Identifiable, Associations, AsChangeset, QueryableByName)] #[table_name = $edit_table] pub struct $edit_struct { pub id: i64, pub ident_id: Uuid, pub rev_id: Option, pub redirect_id: Option, pub editgroup_id: i64, pub extra_json: Option, } #[derive(Debug, Queryable, Identifiable, Associations, AsChangeset)] #[table_name = $ident_table] pub struct $ident_struct { pub id: Uuid, pub is_live: bool, pub rev_id: Option, pub redirect_id: Option, } impl EntityIdentRow for $ident_struct { fn state(&self) -> Result { if !self.is_live { return Ok(EntityState::WorkInProgress); } match (self.redirect_id, self.rev_id) { (None, None) => Ok(EntityState::Deleted), (Some(redir), Some(rev)) => Ok(EntityState::Redirect(redir, rev)), (None, Some(rev)) => Ok(EntityState::Active(rev)), _ => bail!("Invalid EntityIdentRow state"), } } } }; } #[derive(Debug, Queryable, Identifiable, Associations, AsChangeset)] #[table_name = "container_rev"] pub struct ContainerRevRow { pub id: i64, pub extra_json: Option, pub name: String, pub publisher: Option, pub issn: Option, } entity_structs!( "container_edit", ContainerEditRow, "container_ident", ContainerIdentRow ); #[derive(Debug, Queryable, Identifiable, Associations, AsChangeset)] #[table_name = "creator_rev"] pub struct CreatorRevRow { pub id: i64, pub extra_json: Option, pub name: String, pub orcid: Option, } entity_structs!( "creator_edit", CreatorEditRow, "creator_ident", CreatorIdentRow ); #[derive(Debug, Queryable, Identifiable, Associations, AsChangeset)] #[table_name = "file_rev"] pub struct FileRevRow { pub id: i64, pub extra_json: Option, pub size: Option, pub sha1: Option, pub url: Option, } entity_structs!("file_edit", FileEditRow, "file_ident", FileIdentRow); #[derive(Debug, Queryable, Identifiable, Associations, AsChangeset)] #[table_name = "release_rev"] pub struct ReleaseRevRow { pub id: i64, pub extra_json: Option, pub work_ident_id: Uuid, pub container_ident_id: Option, pub title: String, pub release_type: Option, pub date: Option, pub doi: Option, pub volume: Option, pub pages: Option, pub issue: Option, } entity_structs!( "release_edit", ReleaseEditRow, "release_ident", ReleaseIdentRow ); #[derive(Debug, Queryable, Identifiable, Associations, AsChangeset)] #[table_name = "work_rev"] pub struct WorkRevRow { pub id: i64, pub extra_json: Option, pub work_type: Option, pub primary_release_id: Option, } entity_structs!("work_edit", WorkEditRow, "work_ident", WorkIdentRow); #[derive(Debug, Queryable, Identifiable, Associations, AsChangeset)] #[table_name = "release_contrib"] pub struct ReleaseContribRow { id: i64, release_rev: i64, creator_ident_id: Option, stub: Option, contrib_type: Option, } #[derive(Debug, Queryable, Identifiable, Associations, AsChangeset)] #[table_name = "release_ref"] pub struct ReleaseRefRow { id: i64, release_rev: i64, target_release_ident_id: Option, index: Option, stub: Option, } #[derive(Debug, Queryable, Identifiable, Associations, AsChangeset)] #[table_name = "file_release"] pub struct FileReleaseRow { id: i64, file_rev: i64, target_release_ident_id: Uuid, } #[derive(Debug, Queryable, Identifiable, Associations, AsChangeset)] #[table_name = "editgroup"] pub struct EditgroupRow { pub id: i64, pub extra_json: Option, pub editor_id: i64, pub description: Option, } #[derive(Debug, Queryable, Identifiable, Associations, AsChangeset)] #[table_name = "editor"] pub struct EditorRow { pub id: i64, pub username: String, pub is_admin: bool, pub active_editgroup_id: Option, } #[derive(Debug, Queryable, Identifiable, Associations, AsChangeset)] #[table_name = "changelog"] pub struct ChangelogRow { pub id: i64, pub editgroup_id: i64, pub timestamp: chrono::NaiveDateTime, }