fix update api

This commit is contained in:
David Westgate 2024-06-02 18:48:12 -07:00
parent 20dae82345
commit 6d5333b047
2 changed files with 26 additions and 21 deletions

View File

@ -50,14 +50,12 @@ pub async fn read_questions(
let questions_option = store.read().await.fetch_many_questions(start, size).await; let questions_option = store.read().await.fetch_many_questions(start, size).await;
match questions_option { match questions_option {
Some(questions) => { Some(questions) => {
println!("Num question {}", questions.len());
let mut response_vec_dto: Vec<QuestionDTO> = vec![]; let mut response_vec_dto: Vec<QuestionDTO> = vec![];
for question in questions { for question in questions {
//Not ideal - hitting the database serially for the tags of each invidual question. Can be optimized with more complex sql //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; let tags_option = store.read().await.get_tags_for_question(question.id).await;
match tags_option { match tags_option {
Some(tags) => { Some(tags) => {
println!("tags {:?}", tags);
let question_dto: QuestionDTO = QuestionDTO::new(question, tags); let question_dto: QuestionDTO = QuestionDTO::new(question, tags);
response_vec_dto.push(question_dto) response_vec_dto.push(question_dto)
} }
@ -127,12 +125,15 @@ pub async fn update_question(
.await .await
.unwrap(); .unwrap();
// 4: Unassociated all current tags with this question // 4: Unassociated all current tags with this question
if !current_tags.is_empty() {
let _remove_tags = store let _remove_tags = store
.write() .write()
.await .await
.unassociate_tags(updated_question.id, current_tags) .unassociate_tags(updated_question.id, current_tags)
.await .await
.unwrap(); .unwrap();
}
// 5: Associated all of the incoming tags (now newly created if needed) with the question // 5: Associated all of the incoming tags (now newly created if needed) with the question
let _updated_tags = store let _updated_tags = store
.write() .write()

View File

@ -164,7 +164,6 @@ impl Store {
.await; .await;
match result { match result {
Ok(pg_rows) => { Ok(pg_rows) => {
println!("Num rows {}", pg_rows.len());
let question_tags: Vec<QuestionTag> = pg_rows let question_tags: Vec<QuestionTag> = pg_rows
.iter() .iter()
.map(|pg_row| { .map(|pg_row| {
@ -188,17 +187,17 @@ impl Store {
question_id: u8, question_id: u8,
tags: Vec<Tag>, tags: Vec<Tag>,
) -> Result<bool, String> { ) -> Result<bool, String> {
let question_id_tag_id_tuple_string = tags let list = tags
.iter() .iter()
.map(|tag| format!("({},{})", question_id, tag.id)) .map(|tag| format!("({},{})", question_id, tag.id))
.collect::<Vec<String>>() .collect::<Vec<String>>()
.join(","); .join(",");
let query = "DELETE FROM question_tag WHERE (question_id, tag_id) IN ($1)";
match sqlx::query(query) let query = format!(
.bind(question_id_tag_id_tuple_string) "DELETE FROM question_tag WHERE (question_id, tag_id) IN ({})",
.execute(&self.connection) list
.await ); // 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), Ok(_) => Ok(true),
Err(e) => Err(e.to_string()), Err(e) => Err(e.to_string()),
} }
@ -336,7 +335,6 @@ impl Store {
match rows_result { match rows_result {
Ok(pg_rows) => { Ok(pg_rows) => {
println!("num rows {}", pg_rows.len());
let mut result: Vec<Question> = vec![]; let mut result: Vec<Question> = vec![];
for pg_row in pg_rows { for pg_row in pg_rows {
result.push(Question::new( result.push(Question::new(
@ -375,9 +373,15 @@ impl Store {
title: String, title: String,
content: String, content: String,
) -> Result<Question, String> { ) -> Result<Question, String> {
let result = sqlx::query("UPDATE questions SET title = $1 AND SET content = $2 WHERE id = $3 RETURNING id, title, content") let query = "UPDATE questions
.bind(title).bind(content).bind(id.to_string()) SET title = $1, content = $2
.fetch_one(&self.connection).await; 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 { match result {
Ok(pg_row) => Ok(Question::new( Ok(pg_row) => Ok(Question::new(
Store::id_to_u8(&pg_row, "id"), Store::id_to_u8(&pg_row, "id"),