Move leave_project from Store to db module

This commit is contained in:
Nathan Sobo 2022-11-16 14:24:26 -07:00
parent bdb521cb6b
commit e5f05c9f3b
4 changed files with 82 additions and 48 deletions

View File

@ -1209,6 +1209,7 @@ where
id: collaborator.project_id,
host_user_id: Default::default(),
connection_ids: Default::default(),
host_connection_id: Default::default(),
});
let collaborator_connection_id =
@ -1219,6 +1220,8 @@ where
if collaborator.is_host {
left_project.host_user_id = collaborator.user_id;
left_project.host_connection_id =
ConnectionId(collaborator.connection_id as u32);
}
}
}
@ -1474,7 +1477,8 @@ where
.bind(user_id)
.bind(connection_id.0 as i32)
.fetch_one(&mut tx)
.await?;
.await
.unwrap();
if !worktrees.is_empty() {
let mut params = "(?, ?, ?, ?, ?, ?, ?),".repeat(worktrees.len());
@ -1505,7 +1509,7 @@ where
.bind(0)
.bind(false);
}
query.execute(&mut tx).await?;
query.execute(&mut tx).await.unwrap();
}
sqlx::query(
@ -1526,7 +1530,8 @@ where
.bind(0)
.bind(true)
.execute(&mut tx)
.await?;
.await
.unwrap();
let room = self.commit_room_transaction(room_id, tx).await?;
Ok((project_id, room))
@ -2086,6 +2091,64 @@ where
.await
}
pub async fn leave_project(
&self,
project_id: ProjectId,
connection_id: ConnectionId,
) -> Result<LeftProject> {
self.transact(|mut tx| async move {
let result = sqlx::query(
"
DELETE FROM project_collaborators
WHERE project_id = $1 AND connection_id = $2
",
)
.bind(project_id)
.bind(connection_id.0 as i32)
.execute(&mut tx)
.await?;
if result.rows_affected() != 1 {
Err(anyhow!("not a collaborator on this project"))?;
}
let connection_ids = sqlx::query_scalar::<_, i32>(
"
SELECT connection_id
FROM project_collaborators
WHERE project_id = $1
",
)
.bind(project_id)
.fetch_all(&mut tx)
.await?
.into_iter()
.map(|id| ConnectionId(id as u32))
.collect();
let (host_user_id, host_connection_id) = sqlx::query_as::<_, (i32, i32)>(
"
SELECT host_user_id, host_connection_id
FROM projects
WHERE id = $1
",
)
.bind(project_id)
.fetch_one(&mut tx)
.await?;
tx.commit().await?;
Ok(LeftProject {
id: project_id,
host_user_id: UserId(host_user_id),
host_connection_id: ConnectionId(host_connection_id as u32),
connection_ids,
})
})
.await
}
pub async fn project_collaborators(
&self,
project_id: ProjectId,
@ -2645,6 +2708,7 @@ struct LanguageServer {
pub struct LeftProject {
pub id: ProjectId,
pub host_user_id: UserId,
pub host_connection_id: ConnectionId,
pub connection_ids: Vec<ConnectionId>,
}

View File

@ -1041,8 +1041,11 @@ impl Server {
let project_id = ProjectId::from_proto(request.payload.project_id);
let project;
{
let mut store = self.store().await;
project = store.leave_project(project_id, sender_id)?;
project = self
.app_state
.db
.leave_project(project_id, sender_id)
.await?;
tracing::info!(
%project_id,
host_user_id = %project.host_user_id,
@ -1050,17 +1053,15 @@ impl Server {
"leave project"
);
if project.remove_collaborator {
broadcast(sender_id, project.connection_ids, |conn_id| {
self.peer.send(
conn_id,
proto::RemoveProjectCollaborator {
project_id: project_id.to_proto(),
peer_id: sender_id.0,
},
)
});
}
broadcast(sender_id, project.connection_ids, |conn_id| {
self.peer.send(
conn_id,
proto::RemoveProjectCollaborator {
project_id: project_id.to_proto(),
peer_id: sender_id.0,
},
)
});
}
Ok(())

View File

@ -251,37 +251,6 @@ impl Store {
}
}
pub fn leave_project(
&mut self,
project_id: ProjectId,
connection_id: ConnectionId,
) -> Result<LeftProject> {
let project = self
.projects
.get_mut(&project_id)
.ok_or_else(|| anyhow!("no such project"))?;
// If the connection leaving the project is a collaborator, remove it.
let remove_collaborator = if let Some(guest) = project.guests.remove(&connection_id) {
project.active_replica_ids.remove(&guest.replica_id);
true
} else {
false
};
if let Some(connection) = self.connections.get_mut(&connection_id) {
connection.projects.remove(&project_id);
}
Ok(LeftProject {
id: project.id,
host_connection_id: project.host_connection_id,
host_user_id: project.host.user_id,
connection_ids: project.connection_ids(),
remove_collaborator,
})
}
#[cfg(test)]
pub fn check_invariants(&self) {
for (connection_id, connection) in &self.connections {

View File

@ -24,7 +24,7 @@ use std::{
};
use tracing::instrument;
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Serialize)]
#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Serialize)]
pub struct ConnectionId(pub u32);
impl fmt::Display for ConnectionId {