diff options
-rw-r--r-- | rust/fatcat-api/README.md | 2 | ||||
-rw-r--r-- | rust/fatcat-api/api.yaml | 6 | ||||
-rw-r--r-- | rust/fatcat-api/api/swagger.yaml | 31 | ||||
-rw-r--r-- | rust/fatcat-api/src/models.rs | 4 | ||||
-rw-r--r-- | rust/fatcat-openapi2.yml | 6 | ||||
-rw-r--r-- | rust/src/api_server.rs | 114 | ||||
-rw-r--r-- | rust/src/database_models.rs | 46 | ||||
-rw-r--r-- | rust/tests/test_api_server.rs | 60 |
8 files changed, 232 insertions, 37 deletions
diff --git a/rust/fatcat-api/README.md b/rust/fatcat-api/README.md index 98eb45fe..e9ba065c 100644 --- a/rust/fatcat-api/README.md +++ b/rust/fatcat-api/README.md @@ -13,7 +13,7 @@ To see how to make this your own, look here: [README](https://github.com/swagger-api/swagger-codegen/blob/master/README.md) - API version: 0.1.0 -- Build date: 2018-05-25T20:55:51.247Z +- Build date: 2018-05-25T21:11:43.744Z This autogenerated project defines an API crate `fatcat` which contains: * An `Api` trait defining the API in Rust. diff --git a/rust/fatcat-api/api.yaml b/rust/fatcat-api/api.yaml index 30e0f44d..827bb8d7 100644 --- a/rust/fatcat-api/api.yaml +++ b/rust/fatcat-api/api.yaml @@ -155,13 +155,11 @@ definitions: contribs: type: array items: - type: string - #$ref: "#/definitions/release_contrib" + $ref: "#/definitions/release_contrib" refs: type: array items: - type: string - #$ref: "#/definitions/release_ref" + $ref: "#/definitions/release_ref" work_entity: type: object properties: diff --git a/rust/fatcat-api/api/swagger.yaml b/rust/fatcat-api/api/swagger.yaml index f173c53d..6e37a5d6 100644 --- a/rust/fatcat-api/api/swagger.yaml +++ b/rust/fatcat-api/api/swagger.yaml @@ -1169,11 +1169,11 @@ definitions: refs: type: "array" items: - type: "string" + $ref: "#/definitions/release_ref" contribs: type: "array" items: - type: "string" + $ref: "#/definitions/release_contrib" issue: type: "string" example: "12" @@ -1226,14 +1226,24 @@ definitions: release_type: "preprint" title: "title" contribs: - - "contribs" - - "contribs" + - creator_stub: "creator_stub" + creator_id: "creator_id" + index: 6 + contrib_type: "contrib_type" + - creator_stub: "creator_stub" + creator_id: "creator_id" + index: 6 + contrib_type: "contrib_type" revision: 42 volume: "volume" pages: "pages" refs: - - "refs" - - "refs" + - target_release_id: "target_release_id" + stub: "stub" + index: 0 + - target_release_id: "target_release_id" + stub: "stub" + index: 0 extra: "{}" editgroup_id: 16 state: "wip" @@ -1409,6 +1419,10 @@ definitions: type: "string" stub: type: "string" + example: + target_release_id: "target_release_id" + stub: "stub" + index: 0 upperCaseName: "RELEASE_REF" release_contrib: type: "object" @@ -1422,6 +1436,11 @@ definitions: type: "string" contrib_type: type: "string" + example: + creator_stub: "creator_stub" + creator_id: "creator_id" + index: 6 + contrib_type: "contrib_type" upperCaseName: "RELEASE_CONTRIB" editgroup_edits: properties: diff --git a/rust/fatcat-api/src/models.rs b/rust/fatcat-api/src/models.rs index 5118872f..350e9698 100644 --- a/rust/fatcat-api/src/models.rs +++ b/rust/fatcat-api/src/models.rs @@ -415,11 +415,11 @@ impl ReleaseContrib { pub struct ReleaseEntity { #[serde(rename = "refs")] #[serde(skip_serializing_if = "Option::is_none")] - pub refs: Option<Vec<String>>, + pub refs: Option<Vec<models::ReleaseRef>>, #[serde(rename = "contribs")] #[serde(skip_serializing_if = "Option::is_none")] - pub contribs: Option<Vec<String>>, + pub contribs: Option<Vec<models::ReleaseContrib>>, #[serde(rename = "issue")] #[serde(skip_serializing_if = "Option::is_none")] diff --git a/rust/fatcat-openapi2.yml b/rust/fatcat-openapi2.yml index 30e0f44d..827bb8d7 100644 --- a/rust/fatcat-openapi2.yml +++ b/rust/fatcat-openapi2.yml @@ -155,13 +155,11 @@ definitions: contribs: type: array items: - type: string - #$ref: "#/definitions/release_contrib" + $ref: "#/definitions/release_contrib" refs: type: array items: - type: string - #$ref: "#/definitions/release_ref" + $ref: "#/definitions/release_ref" work_entity: type: object properties: diff --git a/rust/src/api_server.rs b/rust/src/api_server.rs index a2e133fe..19e33994 100644 --- a/rust/src/api_server.rs +++ b/rust/src/api_server.rs @@ -6,7 +6,7 @@ use chrono; use database_models::*; use database_schema::{changelog, container_ident, container_rev, creator_ident, creator_rev, editgroup, editor, file_ident, file_rev, release_ident, release_rev, - work_ident, work_rev}; + release_contrib, release_ref, work_ident, work_rev}; use diesel::prelude::*; use diesel::{self, insert_into}; use errors::*; @@ -295,18 +295,44 @@ impl Server { Err(e) => return Err(e.into()), }; + let refs: Vec<ReleaseRef> = release_ref::table + .filter(release_ref::release_rev.eq(rev.id)) + .get_results(&conn) + .expect("fetch release refs") + .iter() + .map(|r: &ReleaseRefRow| ReleaseRef { + index: r.index.clone(), + stub: r.stub.clone(), + target_release_id: r.target_release_ident_id.map(|v| v.to_string()) + }) + .collect(); + + let contribs: Vec<ReleaseContrib> = release_contrib::table + .filter(release_contrib::release_rev.eq(rev.id)) + .get_results(&conn) + .expect("fetch release refs") + .iter() + .map(|c: &ReleaseContribRow| ReleaseContrib { + // XXX: index: c.index, + index: None, + contrib_type: c.contrib_type.clone(), + creator_stub: c.stub.clone(), + creator_id: c.creator_ident_id.map(|v| v.to_string()), + }) + .collect(); + let entity = ReleaseEntity { title: rev.title, release_type: rev.release_type, - //date: rev.date, + // XXX: date: rev.date, doi: rev.doi, volume: rev.volume, pages: rev.pages, issue: rev.issue, container_id: rev.container_ident_id.map(|u| u.to_string()), work_id: rev.work_ident_id.to_string(), - refs: None, - contribs: None, + refs: Some(refs), + contribs: Some(contribs), state: Some(ident.state().unwrap().shortname()), ident: Some(ident.id.to_string()), revision: ident.rev_id, @@ -333,18 +359,44 @@ impl Server { Err(e) => return Err(e.into()), }; + let refs: Vec<ReleaseRef> = release_ref::table + .filter(release_ref::release_rev.eq(rev.id)) + .get_results(&conn) + .expect("fetch release refs") + .iter() + .map(|r: &ReleaseRefRow| ReleaseRef { + index: r.index.clone(), + stub: r.stub.clone(), + target_release_id: r.target_release_ident_id.map(|v| v.to_string()) + }) + .collect(); + + let contribs: Vec<ReleaseContrib> = release_contrib::table + .filter(release_contrib::release_rev.eq(rev.id)) + .get_results(&conn) + .expect("fetch release refs") + .iter() + .map(|c: &ReleaseContribRow| ReleaseContrib { + // XXX: index: c.index, + index: None, + contrib_type: c.contrib_type.clone(), + creator_stub: c.stub.clone(), + creator_id: c.creator_ident_id.map(|v| v.to_string()), + }) + .collect(); + let entity = ReleaseEntity { title: rev.title, release_type: rev.release_type, - //date: rev.date, + // XXX: date: rev.date, doi: rev.doi, volume: rev.volume, pages: rev.pages, issue: rev.issue, container_id: rev.container_ident_id.map(|u| u.to_string()), work_id: rev.work_ident_id.to_string(), - refs: None, - contribs: None, + refs: Some(refs), + contribs: Some(contribs), state: Some(ident.state().unwrap().shortname()), ident: Some(ident.id.to_string()), revision: ident.rev_id, @@ -649,6 +701,7 @@ impl Api for Server { None => None, }; + println!("{:?}", container_id); let edit: ReleaseEditRow = diesel::sql_query( "WITH rev AS ( INSERT INTO release_rev (title, release_type, doi, volume, pages, issue, work_ident_id, container_ident_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) @@ -669,10 +722,57 @@ impl Api for Server { .bind::<diesel::sql_types::Uuid, _>(work_id) .bind::<diesel::sql_types::Nullable<diesel::sql_types::Uuid>, _>(container_id) .bind::<diesel::sql_types::BigInt, _>(editgroup_id) + //XXX: extra_json .get_result(&conn) .unwrap(); let edit = &edit; + let _refs: Option<Vec<ReleaseRefRow>> = match body.refs { + None => None, + Some(ref_list) => { + if ref_list.len() == 0 { + Some(vec![]) + } else { + let ref_rows: Vec<ReleaseRefNewRow> = ref_list.iter().map(|r| ReleaseRefNewRow { + release_rev: edit.rev_id.unwrap(), + target_release_ident_id: + r.target_release_id.clone().map(|v| uuid::Uuid::parse_str(&v).expect("valid UUID")), + // XXX: index: r.index, + index: None, + stub: r.stub.clone(), + }).collect(); + let ref_rows: Vec<ReleaseRefRow> = insert_into(release_ref::table) + .values(ref_rows) + .get_results(&conn) + .expect("error inserting release_refs"); + Some(ref_rows) + } + } + }; + + let _contribs: Option<Vec<ReleaseContribRow>> = match body.contribs { + None => None, + Some(contrib_list) => { + if contrib_list.len() == 0 { + Some(vec![]) + } else { + let contrib_rows: Vec<ReleaseContribNewRow> = contrib_list.iter().map(|c| ReleaseContribNewRow { + release_rev: edit.rev_id.unwrap(), + creator_ident_id: + c.creator_id.clone().map(|v| uuid::Uuid::parse_str(&v).expect("valid UUID")), + // XXX: index: r.index, + contrib_type: c.contrib_type.clone(), + stub: c.creator_stub.clone(), + }).collect(); + let contrib_rows: Vec<ReleaseContribRow> = insert_into(release_contrib::table) + .values(contrib_rows) + .get_results(&conn) + .expect("error inserting release_contribs"); + Some(contrib_rows) + } + } + }; + let entity_edit = EntityEdit { editgroup_id: Some(edit.editgroup_id), revision: Some(edit.rev_id.unwrap()), diff --git a/rust/src/database_models.rs b/rust/src/database_models.rs index 5e4e9710..44b57f85 100644 --- a/rust/src/database_models.rs +++ b/rust/src/database_models.rs @@ -150,29 +150,49 @@ 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<Uuid>, - stub: Option<String>, - contrib_type: Option<String>, + pub id: i64, + pub release_rev: i64, + pub creator_ident_id: Option<Uuid>, + pub stub: Option<String>, + // XXX: pub index: Option<i64>, + pub contrib_type: Option<String>, +} + +#[derive(Debug, Insertable)] +#[table_name = "release_contrib"] +pub struct ReleaseContribNewRow { + pub release_rev: i64, + pub creator_ident_id: Option<Uuid>, + pub stub: Option<String>, + // XXX: pub index: Option<i64>, + pub contrib_type: Option<String>, } #[derive(Debug, Queryable, Identifiable, Associations, AsChangeset)] #[table_name = "release_ref"] pub struct ReleaseRefRow { - id: i64, - release_rev: i64, - target_release_ident_id: Option<Uuid>, - index: Option<i64>, - stub: Option<String>, + pub id: i64, + pub release_rev: i64, + pub target_release_ident_id: Option<Uuid>, + pub index: Option<i64>, + pub stub: Option<String>, +} + +#[derive(Debug, Insertable, AsChangeset)] +#[table_name = "release_ref"] +pub struct ReleaseRefNewRow { + pub release_rev: i64, + pub target_release_ident_id: Option<Uuid>, + pub index: Option<i64>, + pub stub: Option<String>, } #[derive(Debug, Queryable, Identifiable, Associations, AsChangeset)] #[table_name = "file_release"] pub struct FileReleaseRow { - id: i64, - file_rev: i64, - target_release_ident_id: Uuid, + pub id: i64, + pub file_rev: i64, + pub target_release_ident_id: Uuid, } #[derive(Debug, Queryable, Identifiable, Associations, AsChangeset)] diff --git a/rust/tests/test_api_server.rs b/rust/tests/test_api_server.rs index 02f88ea4..5d4aaf1d 100644 --- a/rust/tests/test_api_server.rs +++ b/rust/tests/test_api_server.rs @@ -79,6 +79,66 @@ fn test_post_container() { } #[test] +fn test_post_release() { + let server = fatcat::test_server().unwrap(); + let router = fatcat_api::router(server); + let mut headers = Headers::new(); + let mime: Mime = "application/json".parse().unwrap(); + headers.set(ContentType(mime)); + + let response = request::post( + "http://localhost:9411/v0/release", + headers.clone(), + // TODO: target_release_id + r#"{"title": "secret minimal paper", + "release_type": "journal-article", + "work_id": "f1f046a3-45c9-4b99-3333-000000000001" + }"#, + &router, + ).unwrap(); + let status = response.status; + let body = response::extract_body_to_string(response); + println!("{}", body); + assert_eq!(status, Some(status::Created)); + //assert!(body.contains("secret paper")); + // + let response = request::post( + "http://localhost:9411/v0/release", + headers, + // TODO: target_release_id + r#"{"title": "secret paper", + "release_type": "journal-article", + "doi": "10.1234/abcde.781231231239", + "volume": "439", + "pages": "1-399", + "issue": "IV", + "work_id": "f1f046a3-45c9-4b99-3333-000000000002", + "container_id": "f1f046a3-45c9-4b99-cccc-000000000001", + "refs": [{ + "index": 3, + "stub": "just a string" + },{ + "stub": "just a string" + }], + "contribs": [{ + "index": 1, + "creator_stub": "textual description of contributor (aka, name)", + "creator_id": "f1f046a3-45c9-4b99-adce-000000000001", + "contrib_type": "author" + },{ + "creator_stub": "shorter" + }] + }"#, + &router, + ).unwrap(); + let status = response.status; + let body = response::extract_body_to_string(response); + println!("{}", body); + assert_eq!(status, Some(status::Created)); + //assert!(body.contains("secret paper")); +} + +#[test] fn test_accept_editgroup() { let server = fatcat::test_server().unwrap(); let conn = server.db_pool.get().expect("db_pool error"); |