aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBryan Newbold <bnewbold@robocracy.org>2018-12-14 17:36:30 +0800
committerBryan Newbold <bnewbold@robocracy.org>2018-12-14 17:36:30 +0800
commit99e9fe5fa4fa049b988cc8e7d0def5af43b7a323 (patch)
treef822946a06f04f9107e8df8ce6b9af80430a8370
parentf6b7f0afbee988f46ee8f23c8c81224c65407679 (diff)
downloadfatcat-99e9fe5fa4fa049b988cc8e7d0def5af43b7a323.tar.gz
fatcat-99e9fe5fa4fa049b988cc8e7d0def5af43b7a323.zip
lookups impl
-rw-r--r--rust/migrations/2018-05-12-001226_init/up.sql8
-rw-r--r--rust/src/api_server.rs77
-rw-r--r--rust/src/api_wrappers.rs38
-rw-r--r--rust/tests/test_api_server_http.rs152
4 files changed, 240 insertions, 35 deletions
diff --git a/rust/migrations/2018-05-12-001226_init/up.sql b/rust/migrations/2018-05-12-001226_init/up.sql
index b5214078..88614e7b 100644
--- a/rust/migrations/2018-05-12-001226_init/up.sql
+++ b/rust/migrations/2018-05-12-001226_init/up.sql
@@ -425,10 +425,10 @@ INSERT INTO work_edit (ident_id, rev_id, redirect_id, editgroup_id, prev_rev) VA
('00000000-0000-0000-5555-000000000002', '00000000-0000-0000-5555-FFF000000002', null, '00000000-0000-0000-BBBB-000000000004', null),
('00000000-0000-0000-5555-000000000002', '00000000-0000-0000-5555-FFF000000003', null, '00000000-0000-0000-BBBB-000000000005', '00000000-0000-0000-5555-FFF000000002');
-INSERT INTO release_rev (id, work_ident_id, container_ident_id, title, release_type, release_status, release_date, doi, isbn13, core_id, volume, issue, pages, publisher, language) VALUES
- ('00000000-0000-0000-4444-FFF000000001', '00000000-0000-0000-5555-000000000001', null, 'example title', null, null, null, null, null, null, null, null, null, null, null),
- ('00000000-0000-0000-4444-FFF000000002', '00000000-0000-0000-5555-000000000002', '00000000-0000-0000-1111-000000000001', 'bigger example', 'article-journal', null,'2018-01-01', '10.123/abc', '978-3-16-148410-0', '42022773', '12', 'IV', '5-9', 'bogus publishing group', 'cn'),
- ('00000000-0000-0000-4444-FFF000000003', '00000000-0000-0000-5555-000000000003', '00000000-0000-0000-1111-000000000003', 'Why Most Published Research Findings Are False', 'article-journal', 'published', '2005-08-30', '10.1371/journal.pmed.0020124', null, null, '2', '8', 'e124', 'Public Library of Science', 'en');
+INSERT INTO release_rev (id, work_ident_id, container_ident_id, title, release_type, release_status, release_date, doi, wikidata_qid, pmid, pmcid, isbn13, core_id, volume, issue, pages, publisher, language) VALUES
+ ('00000000-0000-0000-4444-FFF000000001', '00000000-0000-0000-5555-000000000001', null, 'example title', null, null, null, null, null, null, null, null, null, null, null, null, null, null),
+ ('00000000-0000-0000-4444-FFF000000002', '00000000-0000-0000-5555-000000000002', '00000000-0000-0000-1111-000000000001', 'bigger example', 'article-journal', null, '2018-01-01', '10.123/abc', 'Q55555', '54321', 'PMC555','978-3-16-148410-0', '42022773', '12', 'IV', '5-9', 'bogus publishing group', 'cn'),
+ ('00000000-0000-0000-4444-FFF000000003', '00000000-0000-0000-5555-000000000003', '00000000-0000-0000-1111-000000000003', 'Why Most Published Research Findings Are False', 'article-journal', 'published', '2005-08-30', '10.1371/journal.pmed.0020124', null, null, null, null, null, '2', '8', 'e124', 'Public Library of Science', 'en');
INSERT INTO release_ident (id, is_live, rev_id, redirect_id) VALUES
('00000000-0000-0000-4444-000000000001', true, '00000000-0000-0000-4444-FFF000000001', null), -- aaaaaaaaaaaaarceaaaaaaaaae
diff --git a/rust/src/api_server.rs b/rust/src/api_server.rs
index 0a415e91..2278f64f 100644
--- a/rust/src/api_server.rs
+++ b/rust/src/api_server.rs
@@ -53,7 +53,7 @@ pub struct Server {
pub db_pool: ConnectionPool,
}
-pub fn get_release_files(id: FatCatId, hide: HideFlags, conn: &DbConn) -> Result<Vec<FileEntity>> {
+pub fn get_release_files(id: FatCatId, hide_flags: HideFlags, conn: &DbConn) -> Result<Vec<FileEntity>> {
let rows: Vec<(FileRevRow, FileIdentRow, FileReleaseRow)> = file_rev::table
.inner_join(file_ident::table)
.inner_join(file_release::table)
@@ -63,7 +63,7 @@ pub fn get_release_files(id: FatCatId, hide: HideFlags, conn: &DbConn) -> Result
.load(conn)?;
rows.into_iter()
- .map(|(rev, ident, _)| FileEntity::db_from_row(conn, rev, Some(ident), hide))
+ .map(|(rev, ident, _)| FileEntity::db_from_row(conn, rev, Some(ident), hide_flags))
.collect()
}
@@ -72,7 +72,8 @@ impl Server {
&self,
issnl: &Option<String>,
wikidata_qid: &Option<String>,
- hide: HideFlags,
+ expand_flags: ExpandFlags,
+ hide_flags: HideFlags,
conn: &DbConn,
) -> Result<ContainerEntity> {
let (ident, rev): (ContainerIdentRow, ContainerRevRow) = match (issnl, wikidata_qid) {
@@ -86,7 +87,7 @@ impl Server {
.first(conn)?
}
(None, Some(wikidata_qid)) => {
- check_issn(wikidata_qid)?;
+ check_wikidata_qid(wikidata_qid)?;
container_ident::table
.inner_join(container_rev::table)
.filter(container_rev::wikidata_qid.eq(&wikidata_qid))
@@ -99,14 +100,17 @@ impl Server {
}
};
- ContainerEntity::db_from_row(conn, rev, Some(ident), hide)
+ let mut entity = ContainerEntity::db_from_row(conn, rev, Some(ident), hide_flags)?;
+ entity.db_expand(&conn, expand_flags)?;
+ Ok(entity)
}
pub fn lookup_creator_handler(
&self,
orcid: &Option<String>,
wikidata_qid: &Option<String>,
- hide: HideFlags,
+ expand_flags: ExpandFlags,
+ hide_flags: HideFlags,
conn: &DbConn,
) -> Result<CreatorEntity> {
let (ident, rev): (CreatorIdentRow, CreatorRevRow) = match (orcid, wikidata_qid) {
@@ -133,13 +137,15 @@ impl Server {
}
};
- CreatorEntity::db_from_row(conn, rev, Some(ident), hide)
+ let mut entity = CreatorEntity::db_from_row(conn, rev, Some(ident), hide_flags)?;
+ entity.db_expand(&conn, expand_flags)?;
+ Ok(entity)
}
pub fn get_creator_releases_handler(
&self,
id: FatCatId,
- hide: HideFlags,
+ hide_flags: HideFlags,
conn: &DbConn,
) -> Result<Vec<ReleaseEntity>> {
// TODO: some kind of unique or group-by?
@@ -153,7 +159,7 @@ impl Server {
// TODO: from_rows, not from_row?
rows.into_iter()
- .map(|(rev, ident, _)| ReleaseEntity::db_from_row(conn, rev, Some(ident), hide))
+ .map(|(rev, ident, _)| ReleaseEntity::db_from_row(conn, rev, Some(ident), hide_flags))
.collect()
}
@@ -162,7 +168,8 @@ impl Server {
md5: &Option<String>,
sha1: &Option<String>,
sha256: &Option<String>,
- hide: HideFlags,
+ expand_flags: ExpandFlags,
+ hide_flags: HideFlags,
conn: &DbConn,
) -> Result<FileEntity> {
let (ident, rev): (FileIdentRow, FileRevRow) = match (md5, sha1, sha256) {
@@ -189,7 +196,9 @@ impl Server {
}
};
- FileEntity::db_from_row(conn, rev, Some(ident), hide)
+ let mut entity = FileEntity::db_from_row(conn, rev, Some(ident), hide_flags)?;
+ entity.db_expand(&conn, expand_flags)?;
+ Ok(entity)
}
pub fn lookup_release_handler(
@@ -199,12 +208,14 @@ impl Server {
isbn13: &Option<String>,
pmid: &Option<String>,
pmcid: &Option<String>,
- hide: HideFlags,
+ core_id: &Option<String>,
+ expand_flags: ExpandFlags,
+ hide_flags: HideFlags,
conn: &DbConn,
) -> Result<ReleaseEntity> {
let (ident, rev): (ReleaseIdentRow, ReleaseRevRow) =
- match (doi, wikidata_qid, isbn13, pmid, pmcid) {
- (Some(doi), None, None, None, None) => {
+ match (doi, wikidata_qid, isbn13, pmid, pmcid, core_id) {
+ (Some(doi), None, None, None, None, None) => {
check_doi(doi)?;
release_ident::table
.inner_join(release_rev::table)
@@ -213,7 +224,7 @@ impl Server {
.filter(release_ident::redirect_id.is_null())
.first(conn)?
}
- (None, Some(wikidata_qid), None, None, None) => {
+ (None, Some(wikidata_qid), None, None, None, None) => {
check_wikidata_qid(wikidata_qid)?;
release_ident::table
.inner_join(release_rev::table)
@@ -222,7 +233,7 @@ impl Server {
.filter(release_ident::redirect_id.is_null())
.first(conn)?
}
- (None, None, Some(isbn13), None, None) => {
+ (None, None, Some(isbn13), None, None, None) => {
// TODO: check_isbn13(isbn13)?;
release_ident::table
.inner_join(release_rev::table)
@@ -231,7 +242,7 @@ impl Server {
.filter(release_ident::redirect_id.is_null())
.first(conn)?
}
- (None, None, None, Some(pmid), None) => {
+ (None, None, None, Some(pmid), None, None) => {
check_pmid(pmid)?;
release_ident::table
.inner_join(release_rev::table)
@@ -240,7 +251,7 @@ impl Server {
.filter(release_ident::redirect_id.is_null())
.first(conn)?
}
- (None, None, None, None, Some(pmcid)) => {
+ (None, None, None, None, Some(pmcid), None) => {
check_pmcid(pmcid)?;
release_ident::table
.inner_join(release_rev::table)
@@ -249,6 +260,15 @@ impl Server {
.filter(release_ident::redirect_id.is_null())
.first(conn)?
}
+ (None, None, None, None, None, Some(core_id)) => {
+ // TODO: check_core_id(core_id)?;
+ release_ident::table
+ .inner_join(release_rev::table)
+ .filter(release_rev::core_id.eq(core_id))
+ .filter(release_ident::is_live.eq(true))
+ .filter(release_ident::redirect_id.is_null())
+ .first(conn)?
+ }
_ => {
return Err(
ErrorKind::MissingOrMultipleExternalId("in lookup".to_string()).into(),
@@ -256,22 +276,24 @@ impl Server {
}
};
- ReleaseEntity::db_from_row(conn, rev, Some(ident), hide)
+ let mut entity = ReleaseEntity::db_from_row(conn, rev, Some(ident), hide_flags)?;
+ entity.db_expand(&conn, expand_flags)?;
+ Ok(entity)
}
pub fn get_release_files_handler(
&self,
id: FatCatId,
- hide: HideFlags,
+ hide_flags: HideFlags,
conn: &DbConn,
) -> Result<Vec<FileEntity>> {
- get_release_files(id, hide, conn)
+ get_release_files(id, hide_flags, conn)
}
pub fn get_work_releases_handler(
&self,
id: FatCatId,
- hide: HideFlags,
+ hide_flags: HideFlags,
conn: &DbConn,
) -> Result<Vec<ReleaseEntity>> {
let rows: Vec<(ReleaseRevRow, ReleaseIdentRow)> = release_rev::table
@@ -282,7 +304,7 @@ impl Server {
.load(conn)?;
rows.into_iter()
- .map(|(rev, ident)| ReleaseEntity::db_from_row(conn, rev, Some(ident), hide))
+ .map(|(rev, ident)| ReleaseEntity::db_from_row(conn, rev, Some(ident), hide_flags))
.collect()
}
@@ -301,7 +323,8 @@ impl Server {
editgroup::editor_id.eq(FatCatId::from_str(&entity.editor_id)?.to_uuid()),
editgroup::description.eq(entity.description),
editgroup::extra_json.eq(entity.extra),
- )).get_result(conn)?;
+ ))
+ .get_result(conn)?;
Ok(Editgroup {
id: Some(uuid2fcid(&row.id)),
@@ -397,7 +420,8 @@ impl Server {
editgroup: Some(eg_row.into_model_partial()),
editgroup_id: uuid2fcid(&cl_row.editgroup_id),
timestamp: chrono::DateTime::from_utc(cl_row.timestamp, chrono::Utc),
- }).collect();
+ })
+ .collect();
Ok(entries)
}
@@ -421,7 +445,8 @@ impl Server {
editgroup: Some(eg_row.into_model_partial()),
editgroup_id: uuid2fcid(&cl_row.editgroup_id),
timestamp: chrono::DateTime::from_utc(cl_row.timestamp, chrono::Utc),
- }).collect();
+ })
+ .collect();
Ok(entries)
}
diff --git a/rust/src/api_wrappers.rs b/rust/src/api_wrappers.rs
index 8c274fb5..cb93ec54 100644
--- a/rust/src/api_wrappers.rs
+++ b/rust/src/api_wrappers.rs
@@ -371,22 +371,29 @@ macro_rules! wrap_lookup_handler {
&self,
$idname: Option<String>,
wikidata_qid: Option<String>,
+ expand: Option<String>,
hide: Option<String>,
_context: &Context,
) -> Box<Future<Item = $get_resp, Error = ApiError> + Send> {
let conn = self.db_pool.get().expect("db_pool error");
+ let expand_flags = match expand {
+ None => ExpandFlags::none(),
+ Some(param) => ExpandFlags::from_str(&param).unwrap(),
+ };
let hide_flags = match hide {
None => HideFlags::none(),
Some(param) => HideFlags::from_str(&param).unwrap(),
};
// No transaction for GET
- let ret = match self.$get_handler(&$idname, &wikidata_qid, hide_flags, &conn) {
+ let ret = match self.$get_handler(&$idname, &wikidata_qid, expand_flags, hide_flags, &conn) {
Ok(entity) =>
$get_resp::FoundEntity(entity),
Err(Error(ErrorKind::Diesel(::diesel::result::Error::NotFound), _)) =>
$get_resp::NotFound(ErrorResponse { message: format!("Not found: {:?} / {:?}", $idname, wikidata_qid) }),
Err(Error(ErrorKind::MalformedExternalId(e), _)) =>
$get_resp::BadRequest(ErrorResponse { message: e.to_string() }),
+ Err(Error(ErrorKind::MissingOrMultipleExternalId(e), _)) => {
+ $get_resp::BadRequest(ErrorResponse { message: e.to_string(), }) },
Err(e) => {
error!("{}", e);
$get_resp::BadRequest(ErrorResponse { message: e.to_string() })
@@ -627,16 +634,21 @@ impl Api for Server {
md5: Option<String>,
sha1: Option<String>,
sha256: Option<String>,
+ expand: Option<String>,
hide: Option<String>,
_context: &Context,
) -> Box<Future<Item = LookupFileResponse, Error = ApiError> + Send> {
let conn = self.db_pool.get().expect("db_pool error");
+ let expand_flags = match expand {
+ None => ExpandFlags::none(),
+ Some(param) => ExpandFlags::from_str(&param).unwrap(),
+ };
let hide_flags = match hide {
None => HideFlags::none(),
Some(param) => HideFlags::from_str(&param).unwrap(),
};
// No transaction for GET
- let ret = match self.lookup_file_handler(&md5, &sha1, &sha256, hide_flags, &conn) {
+ let ret = match self.lookup_file_handler(&md5, &sha1, &sha256, expand_flags, hide_flags, &conn) {
Ok(entity) => LookupFileResponse::FoundEntity(entity),
Err(Error(ErrorKind::Diesel(::diesel::result::Error::NotFound), _)) => {
LookupFileResponse::NotFound(ErrorResponse {
@@ -648,6 +660,11 @@ impl Api for Server {
message: e.to_string(),
})
}
+ Err(Error(ErrorKind::MissingOrMultipleExternalId(e), _)) => {
+ LookupFileResponse::BadRequest(ErrorResponse {
+ message: e.to_string(),
+ })
+ }
Err(e) => {
error!("{}", e);
LookupFileResponse::BadRequest(ErrorResponse {
@@ -665,10 +682,16 @@ impl Api for Server {
isbn13: Option<String>,
pmid: Option<String>,
pmcid: Option<String>,
+ core_id: Option<String>,
+ expand: Option<String>,
hide: Option<String>,
_context: &Context,
) -> Box<Future<Item = LookupReleaseResponse, Error = ApiError> + Send> {
let conn = self.db_pool.get().expect("db_pool error");
+ let expand_flags = match expand {
+ None => ExpandFlags::none(),
+ Some(param) => ExpandFlags::from_str(&param).unwrap(),
+ };
let hide_flags = match hide {
None => HideFlags::none(),
Some(param) => HideFlags::from_str(&param).unwrap(),
@@ -680,6 +703,8 @@ impl Api for Server {
&isbn13,
&pmid,
&pmcid,
+ &core_id,
+ expand_flags,
hide_flags,
&conn,
) {
@@ -687,8 +712,8 @@ impl Api for Server {
Err(Error(ErrorKind::Diesel(::diesel::result::Error::NotFound), _)) => {
LookupReleaseResponse::NotFound(ErrorResponse {
message: format!(
- "Not found: {:?} / {:?} / {:?} / {:?} / {:?}",
- doi, wikidata_qid, isbn13, pmid, pmcid
+ "Not found: {:?} / {:?} / {:?} / {:?} / {:?} / {:?}",
+ doi, wikidata_qid, isbn13, pmid, pmcid, core_id
),
})
}
@@ -697,6 +722,11 @@ impl Api for Server {
message: e.to_string(),
})
}
+ Err(Error(ErrorKind::MissingOrMultipleExternalId(e), _)) => {
+ LookupReleaseResponse::BadRequest(ErrorResponse {
+ message: e.to_string(),
+ })
+ }
Err(e) => {
error!("{}", e);
LookupReleaseResponse::BadRequest(ErrorResponse {
diff --git a/rust/tests/test_api_server_http.rs b/rust/tests/test_api_server_http.rs
index 614e6b65..031a0abf 100644
--- a/rust/tests/test_api_server_http.rs
+++ b/rust/tests/test_api_server_http.rs
@@ -197,6 +197,46 @@ fn test_lookups() {
check_http_response(
request::get(
+ "http://localhost:9411/v0/container/lookup?issnl=1234",
+ headers.clone(),
+ &router,
+ ),
+ status::BadRequest,
+ None,
+ );
+
+ check_http_response(
+ request::get(
+ "http://localhost:9411/v0/container/lookup?wikidata_qid=Q84913959359",
+ headers.clone(),
+ &router,
+ ),
+ status::NotFound,
+ None,
+ );
+
+ check_http_response(
+ request::get(
+ "http://localhost:9411/v0/container/lookup?wikidata_qid=84913959359",
+ headers.clone(),
+ &router,
+ ),
+ status::BadRequest,
+ None,
+ );
+
+ check_http_response(
+ request::get(
+ "http://localhost:9411/v0/container/lookup?wikidata_qid=Q84913959359&issnl=1234-0000",
+ headers.clone(),
+ &router,
+ ),
+ status::BadRequest,
+ None,
+ );
+
+ check_http_response(
+ request::get(
"http://localhost:9411/v0/creator/lookup?orcid=0000-0003-2088-7465",
headers.clone(),
&router,
@@ -207,6 +247,16 @@ fn test_lookups() {
check_http_response(
request::get(
+ "http://localhost:9411/v0/creator/lookup?wikidata_qid=Q5678",
+ headers.clone(),
+ &router,
+ ),
+ status::Ok,
+ Some("John P. A. Ioannidis"),
+ );
+
+ check_http_response(
+ request::get(
"http://localhost:9411/v0/creator/lookup?orcid=0000-0003-2088-0000",
headers.clone(),
&router,
@@ -217,6 +267,24 @@ fn test_lookups() {
check_http_response(
request::get(
+ "http://localhost:9411/v0/file/lookup?md5=7d97e98f8af710c7e7fe703abc8f639e0ee507c4",
+ headers.clone(),
+ &router,
+ ),
+ status::NotFound,
+ None,
+ );
+ check_http_response(
+ request::get(
+ "http://localhost:9411/v0/file/lookup?md5=f4de91152c7ab9fdc2a128f962faebff",
+ headers.clone(),
+ &router,
+ ),
+ status::Ok,
+ Some("0020124&type=printable"),
+ );
+ check_http_response(
+ request::get(
"http://localhost:9411/v0/file/lookup?sha1=7d97e98f8af710c7e7fe703abc8f639e0ee507c4",
headers.clone(),
&router,
@@ -224,6 +292,15 @@ fn test_lookups() {
status::Ok,
Some("robots.txt"),
);
+ check_http_response(
+ request::get(
+ "http://localhost:9411/v0/file/lookup?sha256=ffc1005680cb620eec4c913437dfabbf311b535cfe16cbaeb2faec1f92afc362",
+ headers.clone(),
+ &router,
+ ),
+ status::Ok,
+ Some("0020124&type=printable"),
+ );
check_http_response(
request::get(
@@ -234,6 +311,78 @@ fn test_lookups() {
status::NotFound,
None,
);
+
+ // not URL encoded
+ check_http_response(
+ request::get(
+ "http://localhost:9411/v0/release/lookup?doi=10.123/abc",
+ headers.clone(),
+ &router,
+ ),
+ status::Ok,
+ Some("bigger example"),
+ );
+
+ // URL encoded
+ check_http_response(
+ request::get(
+ "http://localhost:9411/v0/release/lookup?doi=10.123%2Fabc",
+ headers.clone(),
+ &router,
+ ),
+ status::Ok,
+ Some("bigger example"),
+ );
+
+ check_http_response(
+ request::get(
+ "http://localhost:9411/v0/release/lookup?wikidata_qid=Q55555",
+ headers.clone(),
+ &router,
+ ),
+ status::Ok,
+ Some("bigger example"),
+ );
+
+ check_http_response(
+ request::get(
+ "http://localhost:9411/v0/release/lookup?pmid=54321",
+ headers.clone(),
+ &router,
+ ),
+ status::Ok,
+ Some("bigger example"),
+ );
+
+ check_http_response(
+ request::get(
+ "http://localhost:9411/v0/release/lookup?pmcid=PMC555",
+ headers.clone(),
+ &router,
+ ),
+ status::Ok,
+ Some("bigger example"),
+ );
+
+ check_http_response(
+ request::get(
+ "http://localhost:9411/v0/release/lookup?isbn13=978-3-16-148410-0",
+ headers.clone(),
+ &router,
+ ),
+ status::Ok,
+ Some("bigger example"),
+ );
+
+ check_http_response(
+ request::get(
+ "http://localhost:9411/v0/release/lookup?core_id=42022773",
+ headers.clone(),
+ &router,
+ ),
+ status::Ok,
+ Some("bigger example"),
+ );
}
#[test]
@@ -474,7 +623,8 @@ fn test_post_release() {
status::BadRequest,
None,
);
- */}
+ */
+}
#[test]
fn test_post_work() {