aboutsummaryrefslogtreecommitdiffstats
path: root/rust
diff options
context:
space:
mode:
authorBryan Newbold <bnewbold@robocracy.org>2018-11-26 23:43:56 -0800
committerBryan Newbold <bnewbold@robocracy.org>2018-11-26 23:54:59 -0800
commitd1fd57e7c5dcd9e0062163b4be997808084ef538 (patch)
tree5eacb7bc31292dcf1d17f26d3cc6138daf6f62f7 /rust
parente82f0cf5c4f27c099a8c52eeaec015fb78b7dde3 (diff)
downloadfatcat-d1fd57e7c5dcd9e0062163b4be997808084ef538.tar.gz
fatcat-d1fd57e7c5dcd9e0062163b4be997808084ef538.zip
implement hide flag
Diffstat (limited to 'rust')
-rw-r--r--rust/src/api_entity_crud.rs139
-rw-r--r--rust/src/api_helpers.rs65
-rw-r--r--rust/src/api_server.rs40
-rw-r--r--rust/src/api_wrappers.rs56
-rw-r--r--rust/src/bin/fatcat-export.rs2
5 files changed, 219 insertions, 83 deletions
diff --git a/rust/src/api_entity_crud.rs b/rust/src/api_entity_crud.rs
index 258355f8..cf523547 100644
--- a/rust/src/api_entity_crud.rs
+++ b/rust/src/api_entity_crud.rs
@@ -42,8 +42,8 @@ where
type RevRow;
// Generic Methods
- fn db_get(conn: &DbConn, ident: FatCatId) -> Result<Self>;
- fn db_get_rev(conn: &DbConn, rev_id: Uuid) -> Result<Self>;
+ fn db_get(conn: &DbConn, ident: FatCatId, hide: HideFlags) -> Result<Self>;
+ fn db_get_rev(conn: &DbConn, rev_id: Uuid, hide: HideFlags) -> Result<Self>;
fn db_expand(&mut self, conn: &DbConn, expand: ExpandFlags) -> Result<()>;
fn db_create(&self, conn: &DbConn, edit_context: &EditContext) -> Result<Self::EditRow>;
fn db_create_batch(
@@ -74,6 +74,7 @@ where
conn: &DbConn,
rev_row: Self::RevRow,
ident_row: Option<Self::IdentRow>,
+ hide: HideFlags,
) -> Result<Self>;
fn db_insert_rev(&self, conn: &DbConn) -> Result<Uuid>;
fn db_insert_revs(conn: &DbConn, models: &[&Self]) -> Result<Vec<Uuid>>;
@@ -81,23 +82,23 @@ where
macro_rules! generic_db_get {
($ident_table:ident, $rev_table:ident) => {
- fn db_get(conn: &DbConn, ident: FatCatId) -> Result<Self> {
+ fn db_get(conn: &DbConn, ident: FatCatId, hide: HideFlags) -> Result<Self> {
let (ident, rev): (Self::IdentRow, Self::RevRow) = $ident_table::table
.find(ident.to_uuid())
.inner_join($rev_table::table)
.first(conn)?;
- Self::db_from_row(conn, rev, Some(ident))
+ Self::db_from_row(conn, rev, Some(ident), hide)
}
};
}
macro_rules! generic_db_get_rev {
($rev_table:ident) => {
- fn db_get_rev(conn: &DbConn, rev_id: Uuid) -> Result<Self> {
+ fn db_get_rev(conn: &DbConn, rev_id: Uuid, hide: HideFlags) -> Result<Self> {
let rev = $rev_table::table.find(rev_id).first(conn)?;
- Self::db_from_row(conn, rev, None)
+ Self::db_from_row(conn, rev, None, hide)
}
};
}
@@ -389,6 +390,7 @@ impl EntityCrud for ContainerEntity {
_conn: &DbConn,
rev_row: Self::RevRow,
ident_row: Option<Self::IdentRow>,
+ _hide: HideFlags,
) -> Result<Self> {
let (state, ident_id, redirect_id) = match ident_row {
Some(i) => (
@@ -467,6 +469,7 @@ impl EntityCrud for CreatorEntity {
_conn: &DbConn,
rev_row: Self::RevRow,
ident_row: Option<Self::IdentRow>,
+ _hide: HideFlags,
) -> Result<Self> {
let (state, ident_id, redirect_id) = match ident_row {
Some(i) => (
@@ -542,6 +545,7 @@ impl EntityCrud for FileEntity {
conn: &DbConn,
rev_row: Self::RevRow,
ident_row: Option<Self::IdentRow>,
+ _hide: HideFlags,
) -> Result<Self> {
let (state, ident_id, redirect_id) = match ident_row {
Some(i) => (
@@ -661,8 +665,6 @@ impl EntityCrud for ReleaseEntity {
generic_db_get!(release_ident, release_rev);
generic_db_get_rev!(release_rev);
- //generic_db_create!(release_ident, release_edit);
- //generic_db_create_batch!(release_ident, release_edit);
generic_db_update!(release_ident, release_edit);
generic_db_delete!(release_ident, release_edit);
generic_db_get_history!(release_edit);
@@ -675,11 +677,11 @@ impl EntityCrud for ReleaseEntity {
None => bail!("Can't expand files on a non-concrete entity"),
Some(s) => FatCatId::from_str(&s)?,
};
- self.files = Some(get_release_files(ident, conn)?);
+ self.files = Some(get_release_files(ident, HideFlags::none(), conn)?);
}
if expand.container {
if let Some(ref cid) = self.container_id {
- self.container = Some(ContainerEntity::db_get(conn, FatCatId::from_str(&cid)?)?);
+ self.container = Some(ContainerEntity::db_get(conn, FatCatId::from_str(&cid)?, HideFlags::none())?);
}
}
Ok(())
@@ -769,6 +771,7 @@ impl EntityCrud for ReleaseEntity {
conn: &DbConn,
rev_row: Self::RevRow,
ident_row: Option<Self::IdentRow>,
+ hide: HideFlags,
) -> Result<Self> {
let (state, ident_id, redirect_id) = match ident_row {
Some(i) => (
@@ -779,55 +782,70 @@ impl EntityCrud for ReleaseEntity {
None => (None, None, None),
};
- let refs: Vec<ReleaseRef> = release_ref::table
- .filter(release_ref::release_rev.eq(rev_row.id))
- .order(release_ref::index_val.asc())
- .get_results(conn)?
- .into_iter()
- .map(|r: ReleaseRefRow| ReleaseRef {
- index: r.index_val.map(|v| v as i64),
- key: r.key,
- extra: r.extra_json,
- container_name: r.container_name,
- year: r.year.map(|v| v as i64),
- title: r.title,
- locator: r.locator,
- target_release_id: r
- .target_release_ident_id
- .map(|v| FatCatId::from_uuid(&v).to_string()),
- }).collect();
+ let refs: Option<Vec<ReleaseRef>> = match hide.refs {
+ true => None,
+ false => Some(
+ release_ref::table
+ .filter(release_ref::release_rev.eq(rev_row.id))
+ .order(release_ref::index_val.asc())
+ .get_results(conn)?
+ .into_iter()
+ .map(|r: ReleaseRefRow| ReleaseRef {
+ index: r.index_val.map(|v| v as i64),
+ key: r.key,
+ extra: r.extra_json,
+ container_name: r.container_name,
+ year: r.year.map(|v| v as i64),
+ title: r.title,
+ locator: r.locator,
+ target_release_id: r
+ .target_release_ident_id
+ .map(|v| FatCatId::from_uuid(&v).to_string()),
+ }).collect(),
+ ),
+ };
- let contribs: Vec<ReleaseContrib> = release_contrib::table
- .filter(release_contrib::release_rev.eq(rev_row.id))
- .order((
- release_contrib::role.asc(),
- release_contrib::index_val.asc(),
- )).get_results(conn)?
- .into_iter()
- .map(|c: ReleaseContribRow| ReleaseContrib {
- index: c.index_val.map(|v| v as i64),
- raw_name: c.raw_name,
- role: c.role,
- extra: c.extra_json,
- creator_id: c
- .creator_ident_id
- .map(|v| FatCatId::from_uuid(&v).to_string()),
- creator: None,
- }).collect();
+ let contribs: Option<Vec<ReleaseContrib>> = match hide.contribs {
+ true => None,
+ false => Some(
+ release_contrib::table
+ .filter(release_contrib::release_rev.eq(rev_row.id))
+ .order((
+ release_contrib::role.asc(),
+ release_contrib::index_val.asc(),
+ )).get_results(conn)?
+ .into_iter()
+ .map(|c: ReleaseContribRow| ReleaseContrib {
+ index: c.index_val.map(|v| v as i64),
+ raw_name: c.raw_name,
+ role: c.role,
+ extra: c.extra_json,
+ creator_id: c
+ .creator_ident_id
+ .map(|v| FatCatId::from_uuid(&v).to_string()),
+ creator: None,
+ }).collect(),
+ ),
+ };
- let abstracts: Vec<ReleaseEntityAbstracts> = release_rev_abstract::table
- .inner_join(abstracts::table)
- .filter(release_rev_abstract::release_rev.eq(rev_row.id))
- .get_results(conn)?
- .into_iter()
- .map(
- |r: (ReleaseRevAbstractRow, AbstractsRow)| ReleaseEntityAbstracts {
- sha1: Some(r.0.abstract_sha1),
- mimetype: r.0.mimetype,
- lang: r.0.lang,
- content: Some(r.1.content),
- },
- ).collect();
+ let abstracts: Option<Vec<ReleaseEntityAbstracts>> = match hide.abstracts {
+ true => None,
+ false => Some(
+ release_rev_abstract::table
+ .inner_join(abstracts::table)
+ .filter(release_rev_abstract::release_rev.eq(rev_row.id))
+ .get_results(conn)?
+ .into_iter()
+ .map(
+ |r: (ReleaseRevAbstractRow, AbstractsRow)| ReleaseEntityAbstracts {
+ sha1: Some(r.0.abstract_sha1),
+ mimetype: r.0.mimetype,
+ lang: r.0.lang,
+ content: Some(r.1.content),
+ },
+ ).collect(),
+ ),
+ };
Ok(ReleaseEntity {
title: rev_row.title,
@@ -853,9 +871,9 @@ impl EntityCrud for ReleaseEntity {
publisher: rev_row.publisher,
language: rev_row.language,
work_id: Some(FatCatId::from_uuid(&rev_row.work_ident_id).to_string()),
- refs: Some(refs),
- contribs: Some(contribs),
- abstracts: Some(abstracts),
+ refs: refs,
+ contribs: contribs,
+ abstracts: abstracts,
state: state,
ident: ident_id,
revision: Some(rev_row.id.to_string()),
@@ -1053,6 +1071,7 @@ impl EntityCrud for WorkEntity {
_conn: &DbConn,
rev_row: Self::RevRow,
ident_row: Option<Self::IdentRow>,
+ _hide: HideFlags,
) -> Result<Self> {
let (state, ident_id, redirect_id) = match ident_row {
Some(i) => (
diff --git a/rust/src/api_helpers.rs b/rust/src/api_helpers.rs
index 47c03e58..dea706e7 100644
--- a/rust/src/api_helpers.rs
+++ b/rust/src/api_helpers.rs
@@ -103,7 +103,70 @@ fn test_expand_flags() {
creators: true
}
);
- assert!(all == ExpandFlags::all());
+}
+
+#[derive(Clone, Copy, PartialEq)]
+pub struct HideFlags {
+ pub abstracts: bool,
+ pub refs: bool,
+ pub contribs: bool,
+}
+
+impl FromStr for HideFlags {
+ type Err = Error;
+ fn from_str(param: &str) -> Result<HideFlags> {
+ let list: Vec<&str> = param.split_terminator(",").collect();
+ Ok(HideFlags::from_str_list(&list))
+ }
+}
+
+impl HideFlags {
+ pub fn from_str_list(list: &[&str]) -> HideFlags {
+ HideFlags {
+ abstracts: list.contains(&"abstracts"),
+ refs: list.contains(&"refs"),
+ contribs: list.contains(&"contribs"),
+ }
+ }
+ pub fn none() -> HideFlags {
+ HideFlags {
+ abstracts: false,
+ refs: false,
+ contribs: false,
+ }
+ }
+}
+
+#[test]
+fn test_hide_flags() {
+ assert!(HideFlags::from_str_list(&vec![]).abstracts == false);
+ assert!(HideFlags::from_str_list(&vec!["abstracts"]).abstracts == true);
+ assert!(HideFlags::from_str_list(&vec!["abstract"]).abstracts == false);
+ let all = HideFlags::from_str_list(&vec!["abstracts", "refs", "other_thing", "contribs"]);
+ assert!(
+ all == HideFlags {
+ abstracts: true,
+ refs: true,
+ contribs: true,
+ }
+ );
+ assert!(HideFlags::from_str("").unwrap().abstracts == false);
+ assert!(HideFlags::from_str("abstracts").unwrap().abstracts == true);
+ assert!(
+ HideFlags::from_str("something,,abstracts")
+ .unwrap()
+ .abstracts
+ == true
+ );
+ assert!(HideFlags::from_str("file").unwrap().abstracts == false);
+ let all = HideFlags::from_str("abstracts,refs,other_thing,contribs").unwrap();
+ assert!(
+ all == HideFlags {
+ abstracts: true,
+ refs: true,
+ contribs: true,
+ }
+ );
}
pub fn make_edit_context(
diff --git a/rust/src/api_server.rs b/rust/src/api_server.rs
index 9562a0f2..2bcd4a7f 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, conn: &DbConn) -> Result<Vec<FileEntity>> {
+pub fn get_release_files(id: FatCatId, hide: 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,12 +63,13 @@ pub fn get_release_files(id: FatCatId, conn: &DbConn) -> Result<Vec<FileEntity>>
.load(conn)?;
rows.into_iter()
- .map(|(rev, ident, _)| FileEntity::db_from_row(conn, rev, Some(ident)))
- .collect()
+ .map(
+ |(rev, ident, _)| FileEntity::db_from_row(conn, rev, Some(ident), hide),
+ ).collect()
}
impl Server {
- pub fn lookup_container_handler(&self, issnl: &str, conn: &DbConn) -> Result<ContainerEntity> {
+ pub fn lookup_container_handler(&self, issnl: &str, hide: HideFlags, conn: &DbConn) -> Result<ContainerEntity> {
check_issn(issnl)?;
let (ident, rev): (ContainerIdentRow, ContainerRevRow) = container_ident::table
.inner_join(container_rev::table)
@@ -77,10 +78,10 @@ impl Server {
.filter(container_ident::redirect_id.is_null())
.first(conn)?;
- ContainerEntity::db_from_row(conn, rev, Some(ident))
+ ContainerEntity::db_from_row(conn, rev, Some(ident), hide)
}
- pub fn lookup_creator_handler(&self, orcid: &str, conn: &DbConn) -> Result<CreatorEntity> {
+ pub fn lookup_creator_handler(&self, orcid: &str, hide: HideFlags, conn: &DbConn) -> Result<CreatorEntity> {
check_orcid(orcid)?;
let (ident, rev): (CreatorIdentRow, CreatorRevRow) = creator_ident::table
.inner_join(creator_rev::table)
@@ -89,12 +90,13 @@ impl Server {
.filter(creator_ident::redirect_id.is_null())
.first(conn)?;
- CreatorEntity::db_from_row(conn, rev, Some(ident))
+ CreatorEntity::db_from_row(conn, rev, Some(ident), hide)
}
pub fn get_creator_releases_handler(
&self,
id: FatCatId,
+ hide: HideFlags,
conn: &DbConn,
) -> Result<Vec<ReleaseEntity>> {
// TODO: some kind of unique or group-by?
@@ -108,11 +110,11 @@ impl Server {
// TODO: from_rows, not from_row?
rows.into_iter()
- .map(|(rev, ident, _)| ReleaseEntity::db_from_row(conn, rev, Some(ident)))
+ .map(|(rev, ident, _)| ReleaseEntity::db_from_row(conn, rev, Some(ident), hide))
.collect()
}
- pub fn lookup_file_handler(&self, sha1: &str, conn: &DbConn) -> Result<FileEntity> {
+ pub fn lookup_file_handler(&self, sha1: &str, hide: HideFlags, conn: &DbConn) -> Result<FileEntity> {
let (ident, rev): (FileIdentRow, FileRevRow) = file_ident::table
.inner_join(file_rev::table)
.filter(file_rev::sha1.eq(sha1))
@@ -120,10 +122,15 @@ impl Server {
.filter(file_ident::redirect_id.is_null())
.first(conn)?;
- FileEntity::db_from_row(conn, rev, Some(ident))
+ FileEntity::db_from_row(conn, rev, Some(ident), hide)
}
- pub fn lookup_release_handler(&self, doi: &str, conn: &DbConn) -> Result<ReleaseEntity> {
+ pub fn lookup_release_handler(
+ &self,
+ doi: &str,
+ hide: HideFlags,
+ conn: &DbConn,
+ ) -> Result<ReleaseEntity> {
check_doi(doi)?;
let (ident, rev): (ReleaseIdentRow, ReleaseRevRow) = release_ident::table
.inner_join(release_rev::table)
@@ -132,20 +139,22 @@ impl Server {
.filter(release_ident::redirect_id.is_null())
.first(conn)?;
- ReleaseEntity::db_from_row(conn, rev, Some(ident))
+ ReleaseEntity::db_from_row(conn, rev, Some(ident), hide)
}
pub fn get_release_files_handler(
&self,
id: FatCatId,
+ hide: HideFlags,
conn: &DbConn,
) -> Result<Vec<FileEntity>> {
- get_release_files(id, conn)
+ get_release_files(id, hide, conn)
}
pub fn get_work_releases_handler(
&self,
id: FatCatId,
+ hide: HideFlags,
conn: &DbConn,
) -> Result<Vec<ReleaseEntity>> {
let rows: Vec<(ReleaseRevRow, ReleaseIdentRow)> = release_rev::table
@@ -156,8 +165,9 @@ impl Server {
.load(conn)?;
rows.into_iter()
- .map(|(rev, ident)| ReleaseEntity::db_from_row(conn, rev, Some(ident)))
- .collect()
+ .map(|(rev, ident)| {
+ ReleaseEntity::db_from_row(conn, rev, Some(ident), hide)
+ }).collect()
}
pub fn accept_editgroup_handler(&self, id: FatCatId, conn: &DbConn) -> Result<()> {
diff --git a/rust/src/api_wrappers.rs b/rust/src/api_wrappers.rs
index 0daff73b..50a1665e 100644
--- a/rust/src/api_wrappers.rs
+++ b/rust/src/api_wrappers.rs
@@ -30,17 +30,22 @@ macro_rules! wrap_entity_handlers {
&self,
id: 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");
// No transaction for GET
let ret = match conn.transaction(|| {
let entity_id = FatCatId::from_str(&id)?;
+ let hide_flags = match hide {
+ None => HideFlags::none(),
+ Some(param) => HideFlags::from_str(&param)?,
+ };
match expand {
- None => $model::db_get(&conn, entity_id),
+ None => $model::db_get(&conn, entity_id, hide_flags),
Some(param) => {
let expand_flags = ExpandFlags::from_str(&param)?;
- let mut entity = $model::db_get(&conn, entity_id)?;
+ let mut entity = $model::db_get(&conn, entity_id, hide_flags)?;
entity.db_expand(&conn, expand_flags)?;
Ok(entity)
},
@@ -241,11 +246,16 @@ macro_rules! wrap_lookup_handler {
fn $get_fn(
&self,
$idname: $idtype,
+ hide: Option<String>,
_context: &Context,
) -> Box<Future<Item = $get_resp, Error = ApiError> + Send> {
let conn = self.db_pool.get().expect("db_pool error");
+ 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, &conn) {
+ let ret = match self.$get_handler(&$idname, hide_flags, &conn) {
Ok(entity) =>
$get_resp::FoundEntity(entity),
Err(Error(ErrorKind::Diesel(::diesel::result::Error::NotFound), _)) =>
@@ -291,6 +301,40 @@ macro_rules! wrap_fcid_handler {
}
}
+macro_rules! wrap_fcid_hide_handler {
+ ($get_fn:ident, $get_handler:ident, $get_resp:ident) => {
+ fn $get_fn(
+ &self,
+ id: String,
+ hide: Option<String>,
+ _context: &Context,
+ ) -> Box<Future<Item = $get_resp, Error = ApiError> + Send> {
+ let conn = self.db_pool.get().expect("db_pool error");
+ // No transaction for GET
+ let ret = match (|| {
+ let fcid = FatCatId::from_str(&id)?;
+ let hide_flags = match hide {
+ None => HideFlags::none(),
+ Some(param) => HideFlags::from_str(&param)?,
+ };
+ self.$get_handler(fcid, hide_flags, &conn)
+ })() {
+ Ok(entity) =>
+ $get_resp::Found(entity),
+ Err(Error(ErrorKind::Diesel(::diesel::result::Error::NotFound), _)) =>
+ $get_resp::NotFound(ErrorResponse { message: format!("Not found: {}", id) }),
+ Err(Error(ErrorKind::MalformedExternalId(e), _)) =>
+ $get_resp::BadRequest(ErrorResponse { message: e.to_string() }),
+ Err(e) => {
+ error!("{}", e);
+ $get_resp::BadRequest(ErrorResponse { message: e.to_string() })
+ },
+ };
+ Box::new(futures::done(Ok(ret)))
+ }
+ }
+}
+
impl Api for Server {
wrap_entity_handlers!(
get_container,
@@ -403,17 +447,17 @@ impl Api for Server {
String
);
- wrap_fcid_handler!(
+ wrap_fcid_hide_handler!(
get_release_files,
get_release_files_handler,
GetReleaseFilesResponse
);
- wrap_fcid_handler!(
+ wrap_fcid_hide_handler!(
get_work_releases,
get_work_releases_handler,
GetWorkReleasesResponse
);
- wrap_fcid_handler!(
+ wrap_fcid_hide_handler!(
get_creator_releases,
get_creator_releases_handler,
GetCreatorReleasesResponse
diff --git a/rust/src/bin/fatcat-export.rs b/rust/src/bin/fatcat-export.rs
index 0d6d69b1..9dd5138e 100644
--- a/rust/src/bin/fatcat-export.rs
+++ b/rust/src/bin/fatcat-export.rs
@@ -73,7 +73,7 @@ macro_rules! generic_loop_work {
fn $fn_name(row_receiver: channel::Receiver<IdentRow>, output_sender: channel::Sender<String>, db_conn: &DbConn, expand: Option<ExpandFlags>) {
let result: Result<()> = (|| {
for row in row_receiver {
- let mut entity = $entity_model::db_get_rev(db_conn, row.rev_id.expect("valid, non-deleted row"))
+ let mut entity = $entity_model::db_get_rev(db_conn, row.rev_id.expect("valid, non-deleted row"), HideFlags::none())
.chain_err(|| "reading entity from database")?;
//let mut entity = ReleaseEntity::db_get_rev(db_conn, row.rev_id.expect("valid, non-deleted row"))?;
entity.state = Some("active".to_string()); // XXX