From 18eae2395863e32e4b7413010adafe1ffc95076e Mon Sep 17 00:00:00 2001 From: Bryan Newbold Date: Fri, 7 Sep 2018 10:49:15 -0700 Subject: major CRUD refactor This is the start of a large refactor to move all entity CRUD (create, read, update, delete) model/database code into it's own file. HACKING has been updated with an overview of what happens in each file. Next steps: - split rev (and sub-table) insertion in to db_rev_insert and make create/update generic - inserts should be batch (vector) by default - move all other entities into this new trait framework - bypass api_server wrappers and call into CRUD from api_wrappers for entity ops (should be a big cleanup) --- rust/src/api_server.rs | 109 +++++++++++-------------------------------------- 1 file changed, 24 insertions(+), 85 deletions(-) (limited to 'rust/src/api_server.rs') diff --git a/rust/src/api_server.rs b/rust/src/api_server.rs index 66c31f61..20f71c7a 100644 --- a/rust/src/api_server.rs +++ b/rust/src/api_server.rs @@ -17,8 +17,8 @@ use fatcat_api::models::*; use sha1::Sha1; use uuid::Uuid; use ConnectionPool; - -type DbConn = diesel::r2d2::PooledConnection>; +use database_entity_crud::{EntityCrud, EditContext}; +use std::str::FromStr; macro_rules! entity_batch_handler { ($post_handler:ident, $post_batch_handler:ident, $model:ident) => { @@ -77,6 +77,19 @@ macro_rules! count_entity { }}; } +fn make_edit_context(conn: &DbConn, editgroup_id: Option) -> Result { + let editor_id = Uuid::parse_str("00000000-0000-0000-AAAA-000000000001")?; // TODO: auth + let editgroup_id = match editgroup_id { + None => FatCatId::from_uuid(&get_or_create_editgroup(editor_id, conn).expect("current editgroup")), + Some(param) => param, + }; + Ok(EditContext { + editor_id: FatCatId::from_uuid(&editor_id), + editgroup_id: editgroup_id, + extra_json: None, + }) +} + #[derive(Clone)] pub struct Server { pub db_pool: ConnectionPool, @@ -281,6 +294,7 @@ fn release_row2entity( }) } +/* XXX: fn work_row2entity(ident: Option, rev: WorkRevRow) -> Result { let (state, ident_id, redirect_id) = match ident { Some(i) => ( @@ -299,6 +313,7 @@ fn work_row2entity(ident: Option, rev: WorkRevRow) -> Result, conn: &DbConn, ) -> Result { - let (ident, rev): (WorkIdentRow, WorkRevRow) = work_ident::table - .find(id) - .inner_join(work_rev::table) - .first(conn)?; - - work_row2entity(Some(ident), rev) + WorkEntity::db_get(conn, FatCatId::from_uuid(id)) } pub fn get_work_releases_handler(&self, id: &str, conn: &DbConn) -> Result> { @@ -886,27 +896,8 @@ impl Server { entity: models::WorkEntity, conn: &DbConn, ) -> Result { - let editor_id = Uuid::parse_str("00000000-0000-0000-AAAA-000000000001")?; // TODO: auth - let editgroup_id = match entity.editgroup_id { - None => get_or_create_editgroup(editor_id, conn).expect("current editgroup"), - Some(param) => fcid2uuid(¶m)?, - }; - - let edit: WorkEditRow = - diesel::sql_query( - "WITH rev AS ( INSERT INTO work_rev (extra_json) - VALUES ($1) - RETURNING id ), - ident AS ( INSERT INTO work_ident (rev_id) - VALUES ((SELECT rev.id FROM rev)) - RETURNING id ) - INSERT INTO work_edit (editgroup_id, ident_id, rev_id) VALUES - ($2, (SELECT ident.id FROM ident), (SELECT rev.id FROM rev)) - RETURNING *", - ).bind::, _>(entity.extra) - .bind::(editgroup_id) - .get_result(conn)?; - + let edit_context = make_edit_context(conn, entity.parse_editgroup_id()?)?; + let edit = entity.db_create(conn, &edit_context)?; edit.into_model() } @@ -916,66 +907,14 @@ impl Server { entity: models::WorkEntity, conn: &DbConn, ) -> Result { - let editor_id = Uuid::parse_str("00000000-0000-0000-AAAA-000000000001")?; // TODO: auth - let editgroup_id = match entity.editgroup_id { - None => get_or_create_editgroup(editor_id, conn).expect("current editgroup"), - Some(param) => fcid2uuid(¶m)?, - }; - - // TODO: refactor this into a check on WorkIdentRow - let current: WorkIdentRow = work_ident::table.find(id).first(conn)?; - if current.is_live != true { - // TODO: what if isn't live? 4xx not 5xx - bail!("can't delete an entity that doesn't exist yet"); - } - if current.rev_id.is_none() { - // TODO: what if it's already deleted? 4xx not 5xx - bail!("entity was already deleted"); - } - - let edit: WorkEditRow = - diesel::sql_query( - "WITH rev AS ( INSERT INTO work_rev (extra_json) - VALUES ($1) - RETURNING id ), - INSERT INTO work_edit (editgroup_id, ident_id, rev_id, prev_rev) VALUES - ($2, $3, (SELECT rev.id FROM rev), $4) - RETURNING *", - ).bind::, _>(entity.extra) - .bind::(editgroup_id) - .bind::(id) - .bind::(current.rev_id.unwrap()) - .get_result(conn)?; - + let edit_context = make_edit_context(conn, entity.parse_editgroup_id()?)?; + let edit = entity.db_update(conn, &edit_context, FatCatId::from_uuid(id))?; edit.into_model() } pub fn delete_work_handler(&self, id: &Uuid, editgroup_id: Option, conn: &DbConn) -> Result { - let editor_id = Uuid::parse_str("00000000-0000-0000-AAAA-000000000001")?; // TODO: auth - let editgroup_id = match editgroup_id { - Some(egid) => egid, - None => get_or_create_editgroup(editor_id, conn)? - }; - - let current: WorkIdentRow = work_ident::table.find(id).first(conn)?; - if current.is_live != true { - // TODO: what if isn't live? 4xx not 5xx - bail!("can't delete an entity that doesn't exist yet"); - } - if current.rev_id.is_none() { - // TODO: what if it's already deleted? 4xx not 5xx - bail!("entity was already deleted"); - } - let edit: WorkEditRow = insert_into(work_edit::table) - .values(( - work_edit::editgroup_id.eq(editgroup_id), - work_edit::ident_id.eq(id), - work_edit::rev_id.eq(None::), - work_edit::redirect_id.eq(None::), - work_edit::prev_rev.eq(current.rev_id), - //work_edit::extra_json.eq(extra), - )) - .get_result(conn)?; + let edit_context = make_edit_context(conn, editgroup_id.map(|u| FatCatId::from_uuid(&u)))?; + let edit = WorkEntity::db_delete(conn, &edit_context, FatCatId::from_uuid(id))?; edit.into_model() } -- cgit v1.2.3