[server]: delete the trash's target

This commit is contained in:
appflowy 2021-10-28 13:42:39 +08:00
parent efc1adecdf
commit 818aff46d4
8 changed files with 92 additions and 29 deletions

View File

@ -1,6 +1,6 @@
{
"[dart]": {
"editor.formatOnSave": true,
"editor.formatOnSave": false,
"editor.formatOnType": true,
"editor.rulers": [
120

View File

@ -173,7 +173,7 @@ class ScrollbarState extends State<StyledScrollbar> {
),
),
)
]).opacity(showHandle ? 1.0 : 0.0, animate: true);
]).opacity(showHandle ? 1.0 : 0.0, animate: false);
},
);
}

View File

@ -9,7 +9,7 @@ export ROOT = "./scripts/database"
init_postgres:
${ROOT}/init_postgres.sh
init_database:
init_database: init_postgres
${ROOT}/init_database.sh
reset_db:

View File

@ -31,7 +31,7 @@ pub async fn create_handler(
.begin()
.await
.context("Failed to acquire a Postgres connection to create trash")?;
log::error!("😁create handler: {:?}", params);
let _ = create_trash(&mut transaction, make_records(params)?, logged_user).await?;
transaction

View File

@ -9,7 +9,7 @@ use crate::{
use ::protobuf::ProtobufEnum;
use flowy_net::errors::ServerError;
use flowy_workspace::protobuf::{RepeatedTrash, Trash, TrashType};
use sqlx::{postgres::PgArguments, Postgres};
use sqlx::{postgres::PgArguments, Postgres, Row};
use uuid::Uuid;
pub(crate) async fn create_trash(
@ -33,10 +33,25 @@ pub(crate) async fn create_trash(
Ok(())
}
#[tracing::instrument(skip(transaction, user), fields(delete_rows), err)]
pub(crate) async fn delete_all_trash(
transaction: &mut DBTransaction<'_>,
user: &LoggedUser,
) -> Result<(), ServerError> {
let (sql, args) = SqlBuilder::select(TRASH_TABLE)
.and_where_eq("user_id", &user.user_id)
.build()?;
let rows = sqlx::query_with(&sql, args)
.fetch_all(transaction as &mut DBTransaction<'_>)
.await
.map_err(map_sqlx_error)?
.into_iter()
.map(|row| (row.get("id"), row.get("ty")))
.collect::<Vec<(Uuid, i32)>>();
tracing::Span::current().record("delete_rows", &format!("{:?}", rows).as_str());
let affected_row_count = rows.len();
let _ = delete_trash_targets(transaction as &mut DBTransaction<'_>, rows).await?;
let (sql, args) = SqlBuilder::delete(TRASH_TABLE)
.and_where_eq("user_id", &user.user_id)
.build()?;
@ -44,8 +59,9 @@ pub(crate) async fn delete_all_trash(
.execute(transaction as &mut DBTransaction<'_>)
.await
.map_err(map_sqlx_error)?;
tracing::Span::current().record("affected_row", &result.rows_affected());
debug_assert_eq!(affected_row_count as u64, result.rows_affected());
Ok(())
}
@ -76,6 +92,12 @@ pub(crate) async fn delete_trash(
},
}
let _ = delete_trash_targets(
transaction as &mut DBTransaction<'_>,
vec![(trash_table.id.clone(), trash_table.ty)],
)
.await?;
// Delete the trash table
let (sql, args) = SqlBuilder::delete(TRASH_TABLE).and_where_eq("id", &trash_id).build()?;
let _ = sqlx::query_with(&sql, args)
@ -86,6 +108,25 @@ pub(crate) async fn delete_trash(
Ok(())
}
async fn delete_trash_targets(
transaction: &mut DBTransaction<'_>,
targets: Vec<(Uuid, i32)>,
) -> Result<(), ServerError> {
for (id, ty) in targets {
match TrashType::from_i32(ty) {
None => log::error!("Parser trash type with value: {} failed", ty),
Some(ty) => match ty {
TrashType::Unknown => {},
TrashType::View => {
let _ = delete_view(transaction as &mut DBTransaction<'_>, vec![id]).await;
},
},
}
}
Ok(())
}
pub(crate) async fn read_trash_ids(
user: &LoggedUser,
transaction: &mut DBTransaction<'_>,

View File

@ -1,5 +1,6 @@
use crate::impl_def_and_def_mut;
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
use std::fmt::Formatter;
#[derive(PartialEq, Debug, ProtoBuf_Enum, Clone)]
pub enum TrashType {
@ -32,6 +33,15 @@ pub struct TrashIdentifiers {
pub delete_all: bool,
}
impl std::fmt::Display for TrashIdentifiers {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.write_str(&format!(
"{:?}",
&self.items.iter().map(|item| &item.id).collect::<Vec<_>>()
))
}
}
impl TrashIdentifiers {
pub fn all() -> TrashIdentifiers {
TrashIdentifiers {

View File

@ -67,7 +67,16 @@ impl TrashCan {
#[tracing::instrument(level = "debug", skip(self) err)]
pub async fn restore_all(&self) -> WorkspaceResult<()> {
let repeated_trash = self.delete_all_trash_on_local()?;
let repeated_trash = thread::scope(|_s| {
let conn = self.database.db_connection()?;
conn.immediate_transaction::<_, WorkspaceError, _>(|| {
let repeated_trash = TrashTableSql::read_all(&*conn)?;
let _ = TrashTableSql::delete_all(&*conn)?;
Ok(repeated_trash)
})
})
.unwrap()?;
let identifiers: TrashIdentifiers = repeated_trash.items.clone().into();
let (tx, mut rx) = mpsc::channel::<WorkspaceResult<()>>(1);
let _ = self.notify.send(TrashEvent::Putback(identifiers, tx));
@ -78,34 +87,39 @@ impl TrashCan {
Ok(())
}
#[tracing::instrument(level = "debug", skip(self) err)]
#[tracing::instrument(level = "debug", skip(self), err)]
pub async fn delete_all(&self) -> WorkspaceResult<()> {
let repeated_trash = self.delete_all_trash_on_local()?;
let identifiers: TrashIdentifiers = repeated_trash.items.clone().into();
let (tx, mut rx) = mpsc::channel::<WorkspaceResult<()>>(1);
let _ = self.notify.send(TrashEvent::Delete(identifiers, tx));
let _ = rx.recv().await;
let repeated_trash = TrashTableSql::read_all(&*(self.database.db_connection()?))?;
let trash_identifiers: TrashIdentifiers = repeated_trash.items.clone().into();
let _ = self.delete_with_identifiers(trash_identifiers.clone()).await?;
notify_trash_num_changed(RepeatedTrash { items: vec![] });
let _ = self.delete_all_trash_on_server().await?;
Ok(())
}
fn delete_all_trash_on_local(&self) -> WorkspaceResult<RepeatedTrash> {
let conn = self.database.db_connection()?;
conn.immediate_transaction::<_, WorkspaceError, _>(|| {
let repeated_trash = TrashTableSql::read_all(&*conn)?;
let _ = TrashTableSql::delete_all(&*conn)?;
Ok(repeated_trash)
})
#[tracing::instrument(level = "debug", skip(self), err)]
pub async fn delete(&self, trash_identifiers: TrashIdentifiers) -> WorkspaceResult<()> {
let _ = self.delete_with_identifiers(trash_identifiers.clone()).await?;
notify_trash_num_changed(TrashTableSql::read_all(&*(self.database.db_connection()?))?);
let _ = self.delete_trash_on_server(trash_identifiers)?;
Ok(())
}
#[tracing::instrument(level = "debug", skip(self) err)]
pub async fn delete(&self, trash_identifiers: TrashIdentifiers) -> WorkspaceResult<()> {
#[tracing::instrument(level = "debug", skip(self), fields(delete_trash_ids), err)]
pub async fn delete_with_identifiers(&self, trash_identifiers: TrashIdentifiers) -> WorkspaceResult<()> {
let (tx, mut rx) = mpsc::channel::<WorkspaceResult<()>>(1);
tracing::Span::current().record("delete_trash_ids", &format!("{}", trash_identifiers).as_str());
let _ = self.notify.send(TrashEvent::Delete(trash_identifiers.clone(), tx));
let _ = rx.recv().await;
match rx.recv().await {
None => {},
Some(result) => match result {
Ok(_) => {},
Err(e) => log::error!("{}", e),
},
}
let conn = self.database.db_connection()?;
conn.immediate_transaction::<_, WorkspaceError, _>(|| {
@ -114,10 +128,6 @@ impl TrashCan {
}
Ok(())
})?;
notify_trash_num_changed(TrashTableSql::read_all(&conn)?);
let _ = self.delete_trash_on_server(trash_identifiers)?;
Ok(())
}
@ -212,6 +222,7 @@ impl TrashCan {
spawn(async move {
match server.read_trash(&token).await {
Ok(repeated_trash) => {
log::debug!("Remote trash count: {}", repeated_trash.items.len());
match pool.get() {
Ok(conn) => {
let result = conn.immediate_transaction::<_, WorkspaceError, _>(|| {

View File

@ -302,8 +302,9 @@ async fn handle_trash_event(
}
}
#[tracing::instrument(skip(repeated_view), err)]
#[tracing::instrument(skip(repeated_view), fields(view_count), err)]
fn notify_view_num_changed(belong_to_id: &str, repeated_view: RepeatedView) -> WorkspaceResult<()> {
tracing::Span::current().record("view_count", &format!("{}", repeated_view.len()).as_str());
send_dart_notification(&belong_to_id, WorkspaceNotification::AppViewsChanged)
.payload(repeated_view)
.send();