From e6b678fd1abc162e682b4c4c3ed65feb31e617dc Mon Sep 17 00:00:00 2001 From: Bryan Newbold Date: Wed, 16 May 2018 22:15:34 -0700 Subject: progress --- rust/src/api_server.rs | 258 ++++++++++++++++++++++---------------------- rust/src/bin/fatcatd.rs | 6 +- rust/src/database_models.rs | 20 ++-- 3 files changed, 142 insertions(+), 142 deletions(-) diff --git a/rust/src/api_server.rs b/rust/src/api_server.rs index b081ded9..be553aff 100644 --- a/rust/src/api_server.rs +++ b/rust/src/api_server.rs @@ -1,6 +1,7 @@ //! API endpoint handlers use ConnectionPool; +use chrono; use database_models::*; use database_schema::{changelog, container_edit, container_ident, container_rev, creator_edit, creator_ident, creator_rev, editgroup, editor, file_edit, file_ident, @@ -21,6 +22,31 @@ use fatcat_api::{Api, ApiError, ContainerIdGetResponse, ContainerLookupGetRespon use futures::{self, Future}; use uuid; +// Helper for calling through to handlers +macro_rules! wrap_get_id_handler { + ($get_fn:ident, $handler:ident, $resp:ident, $idtype:ident) => { + fn $get_fn( + &self, + id: $idtype, + _context: &Context, + ) -> Box + Send> { + match self.$handler(id) { + Ok(Some(entity)) => + Box::new(futures::done(Ok($resp::FoundEntity(entity)))), + Ok(None) => + Box::new(futures::done(Ok($resp::NotFound( + ErrorResponse { message: "No such entity".to_string() }), + ))), + Err(e) => + // TODO: dig in to error type here + Box::new(futures::done(Ok($resp::BadRequest( + ErrorResponse { message: e.to_string() }, + )))), + } + } + } +} + #[derive(Clone)] pub struct Server { pub db_pool: ConnectionPool, @@ -170,28 +196,84 @@ impl Server { }; Ok(Some(entity)) } + + fn editgroup_id_get_handler(&self, id: i32) -> Result> { + let conn = self.db_pool.get().expect("db_pool error"); + + let row: EditgroupRow = editgroup::table.find(id as i64).first(&conn)?; + + let eg = Editgroup { + id: Some(row.id as isize), + editor_id: row.editor_id as isize, + description: row.description, + }; + Ok(Some(eg)) + } + + fn editor_get_handler(&self, username: String) -> Result> { + let conn = self.db_pool.get().expect("db_pool error"); + + let row: EditorRow = editor::table + .filter(editor::username.eq(&username)) + .first(&conn)?; + + let ed = Editor { + username: row.username, + }; + Ok(Some(ed)) + } + + fn editor_changelog_get_handler(&self, username: String) -> Result> { + let conn = self.db_pool.get().expect("db_pool error"); + + // TODO: single query + let editor: EditorRow = editor::table + .filter(editor::username.eq(username)) + .first(&conn)?; + let changes: Vec<(ChangelogRow, EditgroupRow)> = changelog::table + .inner_join(editgroup::table) + .filter(editgroup::editor_id.eq(editor.id)) + .load(&conn)?; + + let entries = changes + .iter() + .map(|(row, _)| ChangelogentriesInner { + index: row.id as isize, + editgroup_id: row.editgroup_id as isize, + timestamp: chrono::DateTime::from_utc(row.timestamp, chrono::Utc), + }) + .collect(); + Ok(Some(entries)) + } } impl Api for Server { - fn container_id_get( - &self, - id: String, - _context: &Context, - ) -> Box + Send> { - match self.container_id_get_handler(id) { - Ok(Some(entity)) => - Box::new(futures::done(Ok(ContainerIdGetResponse::FoundEntity(entity)))), - Ok(None) => - Box::new(futures::done(Ok(ContainerIdGetResponse::NotFound( - ErrorResponse { message: "No such entity".to_string() }), - ))), - Err(e) => - // TODO: dig in to error type here - Box::new(futures::done(Ok(ContainerIdGetResponse::BadRequest( - ErrorResponse { message: e.to_string() }, - )))), - } - } + wrap_get_id_handler!( + container_id_get, + container_id_get_handler, + ContainerIdGetResponse, + String + ); + wrap_get_id_handler!( + creator_id_get, + creator_id_get_handler, + CreatorIdGetResponse, + String + ); + wrap_get_id_handler!(file_id_get, file_id_get_handler, FileIdGetResponse, String); + wrap_get_id_handler!(work_id_get, work_id_get_handler, WorkIdGetResponse, String); + wrap_get_id_handler!( + release_id_get, + release_id_get_handler, + ReleaseIdGetResponse, + String + ); + wrap_get_id_handler!( + editgroup_id_get, + editgroup_id_get_handler, + EditgroupIdGetResponse, + i32 + ); fn container_lookup_get( &self, @@ -271,26 +353,6 @@ impl Api for Server { )))) } - fn creator_id_get( - &self, - id: String, - _context: &Context, - ) -> Box + Send> { - match self.creator_id_get_handler(id) { - Ok(Some(entity)) => - Box::new(futures::done(Ok(CreatorIdGetResponse::FoundEntity(entity)))), - Ok(None) => - Box::new(futures::done(Ok(CreatorIdGetResponse::NotFound( - ErrorResponse { message: "No such entity".to_string() }), - ))), - Err(e) => - // TODO: dig in to error type here - Box::new(futures::done(Ok(CreatorIdGetResponse::BadRequest( - ErrorResponse { message: e.to_string() }, - )))), - } - } - fn creator_lookup_get( &self, orcid: String, @@ -319,26 +381,6 @@ impl Api for Server { Box::new(futures::failed("Generic failure".into())) } - fn file_id_get( - &self, - id: String, - _context: &Context, - ) -> Box + Send> { - match self.file_id_get_handler(id) { - Ok(Some(entity)) => - Box::new(futures::done(Ok(FileIdGetResponse::FoundEntity(entity)))), - Ok(None) => - Box::new(futures::done(Ok(FileIdGetResponse::NotFound( - ErrorResponse { message: "No such entity".to_string() }), - ))), - Err(e) => - // TODO: dig in to error type here - Box::new(futures::done(Ok(FileIdGetResponse::BadRequest( - ErrorResponse { message: e.to_string() }, - )))), - } - } - fn file_lookup_get( &self, sha1: String, @@ -367,26 +409,6 @@ impl Api for Server { Box::new(futures::failed("Generic failure".into())) } - fn work_id_get( - &self, - id: String, - _context: &Context, - ) -> Box + Send> { - match self.work_id_get_handler(id) { - Ok(Some(entity)) => - Box::new(futures::done(Ok(WorkIdGetResponse::FoundEntity(entity)))), - Ok(None) => - Box::new(futures::done(Ok(WorkIdGetResponse::NotFound( - ErrorResponse { message: "No such entity".to_string() }), - ))), - Err(e) => - // TODO: dig in to error type here - Box::new(futures::done(Ok(WorkIdGetResponse::BadRequest( - ErrorResponse { message: e.to_string() }, - )))), - } - } - fn work_post( &self, body: models::WorkEntity, @@ -401,26 +423,6 @@ impl Api for Server { Box::new(futures::failed("Generic failure".into())) } - fn release_id_get( - &self, - id: String, - _context: &Context, - ) -> Box + Send> { - match self.release_id_get_handler(id) { - Ok(Some(entity)) => - Box::new(futures::done(Ok(ReleaseIdGetResponse::FoundEntity(entity)))), - Ok(None) => - Box::new(futures::done(Ok(ReleaseIdGetResponse::NotFound( - ErrorResponse { message: "No such entity".to_string() }), - ))), - Err(e) => - // TODO: dig in to error type here - Box::new(futures::done(Ok(ReleaseIdGetResponse::BadRequest( - ErrorResponse { message: e.to_string() }, - )))), - } - } - fn release_lookup_get( &self, doi: String, @@ -463,20 +465,6 @@ impl Api for Server { Box::new(futures::failed("Generic failure".into())) } - fn editgroup_id_get( - &self, - id: i32, - context: &Context, - ) -> Box + Send> { - let context = context.clone(); - println!( - "editgroup_id_get({}) - X-Span-ID: {:?}", - id, - context.x_span_id.unwrap_or(String::from("")).clone() - ); - Box::new(futures::failed("Generic failure".into())) - } - fn editgroup_post( &self, context: &Context, @@ -492,28 +480,40 @@ impl Api for Server { fn editor_username_changelog_get( &self, username: String, - context: &Context, + _context: &Context, ) -> Box + Send> { - let context = context.clone(); - println!( - "editor_username_changelog_get(\"{}\") - X-Span-ID: {:?}", - username, - context.x_span_id.unwrap_or(String::from("")).clone() - ); - Box::new(futures::failed("Generic failure".into())) + match self.editor_changelog_get_handler(username) { + Ok(Some(entries)) => + Box::new(futures::done(Ok(EditorUsernameChangelogGetResponse::FoundMergedChanges(entries)))), + Ok(None) => + Box::new(futures::done(Ok(EditorUsernameChangelogGetResponse::NotFound( + ErrorResponse { message: "No such entity".to_string() }), + ))), + Err(e) => + // TODO: dig in to error type here + Box::new(futures::done(Ok(EditorUsernameChangelogGetResponse::GenericError( + ErrorResponse { message: e.to_string() }, + )))), + } } fn editor_username_get( &self, username: String, - context: &Context, + _context: &Context, ) -> Box + Send> { - let context = context.clone(); - println!( - "editor_username_get(\"{}\") - X-Span-ID: {:?}", - username, - context.x_span_id.unwrap_or(String::from("")).clone() - ); - Box::new(futures::failed("Generic failure".into())) + match self.editor_get_handler(username) { + Ok(Some(entity)) => + Box::new(futures::done(Ok(EditorUsernameGetResponse::FoundEditor(entity)))), + Ok(None) => + Box::new(futures::done(Ok(EditorUsernameGetResponse::NotFound( + ErrorResponse { message: "No such entity".to_string() }), + ))), + Err(e) => + // TODO: dig in to error type here + Box::new(futures::done(Ok(EditorUsernameGetResponse::GenericError( + ErrorResponse { message: e.to_string() }, + )))), + } } } diff --git a/rust/src/bin/fatcatd.rs b/rust/src/bin/fatcatd.rs index 05a8e1a5..f33c3763 100644 --- a/rust/src/bin/fatcatd.rs +++ b/rust/src/bin/fatcatd.rs @@ -3,7 +3,7 @@ extern crate chrono; extern crate clap; extern crate diesel; -extern crate dotenv; +//extern crate dotenv; extern crate fatcat; extern crate fatcat_api; extern crate futures; @@ -17,11 +17,11 @@ extern crate slog_async; extern crate slog_term; use clap::{App, Arg}; -use dotenv::dotenv; use iron::{Chain, Iron}; use iron_slog::{DefaultLogFormatter, LoggerMiddleware}; use slog::{Drain, Logger}; -use std::env; +//use dotenv::dotenv; +//use std::env; //use swagger::auth::AllowAllMiddleware; /// Create custom server, wire it to the autogenerated router, diff --git a/rust/src/database_models.rs b/rust/src/database_models.rs index a1f7fc04..9aebb0f9 100644 --- a/rust/src/database_models.rs +++ b/rust/src/database_models.rs @@ -143,25 +143,25 @@ pub struct FileReleaseRow { #[derive(Debug, Queryable, Identifiable, Associations, AsChangeset)] #[table_name = "editgroup"] pub struct EditgroupRow { - id: i64, + pub id: i64, //extra_json: Option, - editor_id: i64, - description: Option, + pub editor_id: i64, + pub description: Option, } #[derive(Debug, Queryable, Identifiable, Associations, AsChangeset)] #[table_name = "editor"] pub struct EditorRow { - id: i64, - username: String, - is_admin: bool, - active_editgroup_id: Option, + 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 { - id: i64, - editgroup_id: i64, - timestamp: chrono::NaiveDateTime, + pub id: i64, + pub editgroup_id: i64, + pub timestamp: chrono::NaiveDateTime, } -- cgit v1.2.3