From 6d5333b047845b29b782c44928f0c6da7e1a9f65 Mon Sep 17 00:00:00 2001 From: David Westgate Date: Sun, 2 Jun 2024 18:48:12 -0700 Subject: [PATCH] fix update api --- src/api.rs | 17 +++++++++-------- src/pg_store.rs | 30 +++++++++++++++++------------- 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/src/api.rs b/src/api.rs index ea5be0e..4dcc912 100644 --- a/src/api.rs +++ b/src/api.rs @@ -50,14 +50,12 @@ pub async fn read_questions( let questions_option = store.read().await.fetch_many_questions(start, size).await; match questions_option { Some(questions) => { - println!("Num question {}", questions.len()); let mut response_vec_dto: Vec = vec![]; for question in questions { //Not ideal - hitting the database serially for the tags of each invidual question. Can be optimized with more complex sql let tags_option = store.read().await.get_tags_for_question(question.id).await; match tags_option { Some(tags) => { - println!("tags {:?}", tags); let question_dto: QuestionDTO = QuestionDTO::new(question, tags); response_vec_dto.push(question_dto) } @@ -127,12 +125,15 @@ pub async fn update_question( .await .unwrap(); // 4: Unassociated all current tags with this question - let _remove_tags = store - .write() - .await - .unassociate_tags(updated_question.id, current_tags) - .await - .unwrap(); + if !current_tags.is_empty() { + let _remove_tags = store + .write() + .await + .unassociate_tags(updated_question.id, current_tags) + .await + .unwrap(); + } + // 5: Associated all of the incoming tags (now newly created if needed) with the question let _updated_tags = store .write() diff --git a/src/pg_store.rs b/src/pg_store.rs index 8991daf..eab1deb 100644 --- a/src/pg_store.rs +++ b/src/pg_store.rs @@ -156,7 +156,7 @@ impl Store { INSERT INTO question_tag (question_id, tag_id) SELECT $1::smallint, UNNEST($2::smallint[]) ON CONFLICT DO NOTHING; - "; + "; let result = sqlx::query(query) .bind(question_id.to_string()) .bind(tag_ids_string) @@ -164,7 +164,6 @@ impl Store { .await; match result { Ok(pg_rows) => { - println!("Num rows {}", pg_rows.len()); let question_tags: Vec = pg_rows .iter() .map(|pg_row| { @@ -188,17 +187,17 @@ impl Store { question_id: u8, tags: Vec, ) -> Result { - let question_id_tag_id_tuple_string = tags + let list = tags .iter() .map(|tag| format!("({},{})", question_id, tag.id)) .collect::>() .join(","); - let query = "DELETE FROM question_tag WHERE (question_id, tag_id) IN ($1)"; - match sqlx::query(query) - .bind(question_id_tag_id_tuple_string) - .execute(&self.connection) - .await - { + + let query = format!( + "DELETE FROM question_tag WHERE (question_id, tag_id) IN ({})", + list + ); // Not bulletproof to injection (still ok), but best we can do with sqlx aside from sequential hits + match sqlx::query(&query).execute(&self.connection).await { Ok(_) => Ok(true), Err(e) => Err(e.to_string()), } @@ -336,7 +335,6 @@ impl Store { match rows_result { Ok(pg_rows) => { - println!("num rows {}", pg_rows.len()); let mut result: Vec = vec![]; for pg_row in pg_rows { result.push(Question::new( @@ -375,9 +373,15 @@ impl Store { title: String, content: String, ) -> Result { - let result = sqlx::query("UPDATE questions SET title = $1 AND SET content = $2 WHERE id = $3 RETURNING id, title, content") - .bind(title).bind(content).bind(id.to_string()) - .fetch_one(&self.connection).await; + let query = "UPDATE questions + SET title = $1, content = $2 + WHERE id = $3 RETURNING id, title, content"; + let result = sqlx::query(query) + .bind(title) + .bind(content) + .bind(i32::from(id)) + .fetch_one(&self.connection) + .await; match result { Ok(pg_row) => Ok(Question::new( Store::id_to_u8(&pg_row, "id"),