diff options
author | Bryan Newbold <bnewbold@robocracy.org> | 2018-07-25 21:58:17 -0700 |
---|---|---|
committer | Bryan Newbold <bnewbold@robocracy.org> | 2018-07-25 21:58:17 -0700 |
commit | 5b8d98192972ccbc776024dc4041e4519557a03b (patch) | |
tree | 12ff5d45717b378fd00175dca8a309c58c732336 /rust/src/api_helpers.rs | |
parent | be936450ac981c48b44d4d599402d4b7853129cd (diff) | |
download | fatcat-5b8d98192972ccbc776024dc4041e4519557a03b.tar.gz fatcat-5b8d98192972ccbc776024dc4041e4519557a03b.zip |
big transaction/conn refactor
Diffstat (limited to 'rust/src/api_helpers.rs')
-rw-r--r-- | rust/src/api_helpers.rs | 140 |
1 files changed, 69 insertions, 71 deletions
diff --git a/rust/src/api_helpers.rs b/rust/src/api_helpers.rs index 91c6200d..489631b3 100644 --- a/rust/src/api_helpers.rs +++ b/rust/src/api_helpers.rs @@ -7,6 +7,7 @@ use errors::*; use regex::Regex; use uuid::Uuid; +/// This function should always be run within a transaction pub fn get_or_create_editgroup(editor_id: Uuid, conn: &PgConnection) -> Result<Uuid> { // check for current active let ed_row: EditorRow = editor::table.find(editor_id).first(conn)?; @@ -15,81 +16,78 @@ pub fn get_or_create_editgroup(editor_id: Uuid, conn: &PgConnection) -> Result<U } // need to insert and update - conn.build_transaction().run(|| { - let eg_row: EditgroupRow = diesel::insert_into(editgroup::table) - .values((editgroup::editor_id.eq(ed_row.id),)) - .get_result(conn)?; - diesel::update(editor::table.find(ed_row.id)) - .set(editor::active_editgroup_id.eq(eg_row.id)) - .execute(conn)?; - Ok(eg_row.id) - }) + let eg_row: EditgroupRow = diesel::insert_into(editgroup::table) + .values((editgroup::editor_id.eq(ed_row.id),)) + .get_result(conn)?; + diesel::update(editor::table.find(ed_row.id)) + .set(editor::active_editgroup_id.eq(eg_row.id)) + .execute(conn)?; + Ok(eg_row.id) } +/// This function should always be run within a transaction pub fn accept_editgroup(editgroup_id: Uuid, conn: &PgConnection) -> Result<ChangelogRow> { - 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.to_string() - ); - } - - // 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"] { - 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::<diesel::sql_types::Uuid, _>(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<Uuid> = None; - diesel::update(editor::table) - .filter(editor::active_editgroup_id.eq(editgroup_id)) - .set(editor::active_editgroup_id.eq(no_active)) + // 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.to_string() + ); + } + + // 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"] { + 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::<diesel::sql_types::Uuid, _>(editgroup_id) .execute(conn)?; - Ok(entry) - }) + } + + // 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<Uuid> = 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) } /// Convert fatcat IDs (base32 strings) to UUID |