From 402cf5ebbd87b4e4de2d5ba83a97e7f9b014dfc9 Mon Sep 17 00:00:00 2001 From: Bryan Newbold Date: Wed, 23 May 2018 22:24:30 -0700 Subject: editgroup accept function --- rust/src/api_helpers.rs | 68 ++++++++++++++++++++++++++++++++++++++++++++++++- rust/src/api_server.rs | 23 ++++++++--------- 2 files changed, 78 insertions(+), 13 deletions(-) diff --git a/rust/src/api_helpers.rs b/rust/src/api_helpers.rs index 200b70a8..247eed88 100644 --- a/rust/src/api_helpers.rs +++ b/rust/src/api_helpers.rs @@ -3,7 +3,7 @@ use errors::*; use diesel; use diesel::prelude::*; use database_models::*; -use database_schema::{editgroup, editor}; +use database_schema::*; pub fn get_or_create_editgroup(editor_id: i64, conn: &PgConnection) -> Result { // check for current active @@ -26,3 +26,69 @@ pub fn get_or_create_editgroup(editor_id: i64, conn: &PgConnection) -> Result Result { + conn.build_transaction().run(|| { + + // check that we haven't accepted already (in changelog) + // NB: could leave this to a UNIQUE constraint + let count: i64 = changelog::table + .filter(changelog::editgroup_id.eq(editgroup_id)) + .count() + .get_result(conn)?; + if count > 0 { + bail!("editgroup {} has already been accepted", editgroup_id); + } + + // for each entity type... + //for entity in (container_edit, creator_edit, file_edit, release_edit, work_edit) { + /* + // This would be the clean and efficient way, but see: + // https://github.com/diesel-rs/diesel/issues/1478 + diesel::update(container_ident::table) + .inner_join(container_edit::table.on( + container_ident::id.eq(container_edit::ident_id) + )) + .filter(container_edit::editgroup_id.eq(editgroup_id)) + .values(( + container_ident::is_live.eq(true), + container_ident::rev_id.eq(container_edit::rev_id), + container_ident::redirect_id.eq(container_edit::redirect_id), + )) + .execute()?; + */ + + // Sketchy... but fast? Only a few queries per accept. + for entity in ["container", "creator", "file", "work", "release"].iter() { + diesel::sql_query( + format!(" + UPDATE {entity}_ident + SET + is_live = true, + rev_id = {entity}_edit.rev_id, + redirect_id = {entity}_edit.redirect_id + FROM {entity}_edit + WHERE + {entity}_ident.id = {entity}_edit.ident_id + AND {entity}_edit.editgroup_id = $1", + entity = entity)) + .bind::(editgroup_id) + .execute(conn)?; + } + + // append log/changelog row + let entry: ChangelogRow = diesel::insert_into(changelog::table) + .values(( + changelog::editgroup_id.eq(editgroup_id), + )) + .get_result(conn)?; + + // update any editor's active editgroup + let no_active: Option = None; + diesel::update(editor::table) + .filter(editor::active_editgroup_id.eq(editgroup_id)) + .set(editor::active_editgroup_id.eq(no_active)) + .execute(conn)?; + Ok(entry) + }) +} diff --git a/rust/src/api_server.rs b/rust/src/api_server.rs index b183f938..9bb7f155 100644 --- a/rust/src/api_server.rs +++ b/rust/src/api_server.rs @@ -4,10 +4,9 @@ use ConnectionPool; use chrono; use api_helpers::*; 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, - file_rev, release_edit, release_ident, release_rev, work_edit, work_ident, - work_rev}; +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}; use diesel::prelude::*; use diesel::{self, insert_into}; use errors::*; @@ -670,15 +669,15 @@ impl Api for Server { fn editgroup_id_accept_post( &self, id: i32, - context: &Context, + _context: &Context, ) -> Box + Send> { - let context = context.clone(); - println!( - "editgroup_id_accept_post({}) - X-Span-ID: {:?}", - id, - context.x_span_id.unwrap_or(String::from("")).clone() - ); - Box::new(futures::failed("Generic failure".into())) + let conn = self.db_pool.get().expect("db_pool error"); + + accept_editgroup(id as i64, &conn).expect("failed to accept editgroup"); + + Box::new(futures::done(Ok(EditgroupIdAcceptPostResponse::MergedSuccessfully( + Success { message: "horray!".to_string() } + )))) } fn editgroup_post( -- cgit v1.2.3