trash.rs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. use crate::{
  2. entities::workspace::{TrashTable, TRASH_TABLE},
  3. service::{
  4. user::LoggedUser,
  5. view::{delete_view, read_view_table},
  6. },
  7. sqlx_ext::{map_sqlx_error, DBTransaction, SqlBuilder},
  8. };
  9. use ::protobuf::ProtobufEnum;
  10. use flowy_net::errors::ServerError;
  11. use flowy_workspace::protobuf::{RepeatedTrash, Trash, TrashType};
  12. use sqlx::{postgres::PgArguments, Postgres};
  13. use uuid::Uuid;
  14. pub(crate) async fn create_trash(
  15. transaction: &mut DBTransaction<'_>,
  16. records: Vec<(Uuid, i32)>,
  17. user: LoggedUser,
  18. ) -> Result<(), ServerError> {
  19. for (trash_id, ty) in records {
  20. let (sql, args) = SqlBuilder::create(TRASH_TABLE)
  21. .add_arg("id", trash_id)
  22. .add_arg("user_id", &user.user_id)
  23. .add_arg("ty", ty)
  24. .build()?;
  25. let _ = sqlx::query_with(&sql, args)
  26. .execute(transaction as &mut DBTransaction<'_>)
  27. .await
  28. .map_err(map_sqlx_error)?;
  29. }
  30. Ok(())
  31. }
  32. pub(crate) async fn delete_all_trash(
  33. transaction: &mut DBTransaction<'_>,
  34. user: &LoggedUser,
  35. ) -> Result<(), ServerError> {
  36. let (sql, args) = SqlBuilder::delete(TRASH_TABLE)
  37. .and_where_eq("user_id", &user.user_id)
  38. .build()?;
  39. let result = sqlx::query_with(&sql, args)
  40. .execute(transaction as &mut DBTransaction<'_>)
  41. .await
  42. .map_err(map_sqlx_error)?;
  43. tracing::Span::current().record("affected_row", &result.rows_affected());
  44. Ok(())
  45. }
  46. pub(crate) async fn delete_trash(
  47. transaction: &mut DBTransaction<'_>,
  48. records: Vec<(Uuid, i32)>,
  49. _user: &LoggedUser,
  50. ) -> Result<(), ServerError> {
  51. for (trash_id, _) in records {
  52. // Read the trash_table and delete the original table according to the TrashType
  53. let (sql, args) = SqlBuilder::select(TRASH_TABLE)
  54. .add_field("*")
  55. .and_where_eq("id", trash_id)
  56. .build()?;
  57. let trash_table = sqlx::query_as_with::<Postgres, TrashTable, PgArguments>(&sql, args)
  58. .fetch_one(transaction as &mut DBTransaction<'_>)
  59. .await
  60. .map_err(map_sqlx_error)?;
  61. match TrashType::from_i32(trash_table.ty) {
  62. None => log::error!("Parser trash type with value: {} failed", trash_table.ty),
  63. Some(ty) => match ty {
  64. TrashType::Unknown => {},
  65. TrashType::View => {
  66. let _ = delete_view(transaction as &mut DBTransaction<'_>, vec![trash_table.id]).await;
  67. },
  68. },
  69. }
  70. // Delete the trash table
  71. let (sql, args) = SqlBuilder::delete(TRASH_TABLE).and_where_eq("id", &trash_id).build()?;
  72. let _ = sqlx::query_with(&sql, args)
  73. .execute(transaction as &mut DBTransaction<'_>)
  74. .await
  75. .map_err(map_sqlx_error)?;
  76. }
  77. Ok(())
  78. }
  79. pub(crate) async fn read_trash_ids(
  80. user: &LoggedUser,
  81. transaction: &mut DBTransaction<'_>,
  82. ) -> Result<Vec<String>, ServerError> {
  83. let repeated_trash = read_trash(transaction, user).await?.take_items().into_vec();
  84. let ids = repeated_trash
  85. .into_iter()
  86. .map(|trash| trash.id)
  87. .collect::<Vec<String>>();
  88. Ok(ids)
  89. }
  90. pub(crate) async fn read_trash(
  91. transaction: &mut DBTransaction<'_>,
  92. user: &LoggedUser,
  93. ) -> Result<RepeatedTrash, ServerError> {
  94. let (sql, args) = SqlBuilder::select(TRASH_TABLE)
  95. .add_field("*")
  96. .and_where_eq("user_id", &user.user_id)
  97. .build()?;
  98. let tables = sqlx::query_as_with::<Postgres, TrashTable, PgArguments>(&sql, args)
  99. .fetch_all(transaction as &mut DBTransaction<'_>)
  100. .await
  101. .map_err(map_sqlx_error)?;
  102. let mut trash: Vec<Trash> = vec![];
  103. for table in tables {
  104. match TrashType::from_i32(table.ty) {
  105. None => log::error!("Parser trash type with value: {} failed", table.ty),
  106. Some(ty) => match ty {
  107. TrashType::Unknown => {},
  108. TrashType::View => {
  109. trash.push(read_view_table(table.id, transaction).await?.into());
  110. },
  111. },
  112. }
  113. }
  114. let mut repeated_trash = RepeatedTrash::default();
  115. repeated_trash.set_items(trash.into());
  116. Ok(repeated_trash)
  117. }