Set up basic RPC for managing channels
Co-authored-by: Mikayla <mikayla@zed.dev>
This commit is contained in:
parent
758e1f6e57
commit
4b94bfa045
12 changed files with 541 additions and 150 deletions
|
@ -3032,11 +3032,16 @@ impl Database {
|
|||
|
||||
// channels
|
||||
|
||||
pub async fn create_root_channel(&self, name: &str) -> Result<ChannelId> {
|
||||
self.create_channel(name, None).await
|
||||
pub async fn create_root_channel(&self, name: &str, creator_id: UserId) -> Result<ChannelId> {
|
||||
self.create_channel(name, None, creator_id).await
|
||||
}
|
||||
|
||||
pub async fn create_channel(&self, name: &str, parent: Option<ChannelId>) -> Result<ChannelId> {
|
||||
pub async fn create_channel(
|
||||
&self,
|
||||
name: &str,
|
||||
parent: Option<ChannelId>,
|
||||
creator_id: UserId,
|
||||
) -> Result<ChannelId> {
|
||||
self.transaction(move |tx| async move {
|
||||
let tx = tx;
|
||||
|
||||
|
@ -3056,19 +3061,50 @@ impl Database {
|
|||
.await?;
|
||||
}
|
||||
|
||||
channel_member::ActiveModel {
|
||||
channel_id: ActiveValue::Set(channel.id),
|
||||
user_id: ActiveValue::Set(creator_id),
|
||||
accepted: ActiveValue::Set(true),
|
||||
admin: ActiveValue::Set(true),
|
||||
..Default::default()
|
||||
}
|
||||
.insert(&*tx)
|
||||
.await?;
|
||||
|
||||
Ok(channel.id)
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
// Property: Members are only
|
||||
pub async fn add_channel_member(&self, channel_id: ChannelId, user_id: UserId) -> Result<()> {
|
||||
pub async fn invite_channel_member(
|
||||
&self,
|
||||
channel_id: ChannelId,
|
||||
invitee_id: UserId,
|
||||
inviter_id: UserId,
|
||||
is_admin: bool,
|
||||
) -> Result<()> {
|
||||
self.transaction(move |tx| async move {
|
||||
let tx = tx;
|
||||
|
||||
// Check if inviter is a member
|
||||
channel_member::Entity::find()
|
||||
.filter(
|
||||
channel_member::Column::ChannelId
|
||||
.eq(channel_id)
|
||||
.and(channel_member::Column::UserId.eq(inviter_id))
|
||||
.and(channel_member::Column::Admin.eq(true)),
|
||||
)
|
||||
.one(&*tx)
|
||||
.await?
|
||||
.ok_or_else(|| {
|
||||
anyhow!("Inviter does not have permissions to invite the invitee")
|
||||
})?;
|
||||
|
||||
let channel_membership = channel_member::ActiveModel {
|
||||
channel_id: ActiveValue::Set(channel_id),
|
||||
user_id: ActiveValue::Set(user_id),
|
||||
user_id: ActiveValue::Set(invitee_id),
|
||||
accepted: ActiveValue::Set(false),
|
||||
admin: ActiveValue::Set(is_admin),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
|
@ -3079,6 +3115,50 @@ impl Database {
|
|||
.await
|
||||
}
|
||||
|
||||
pub async fn respond_to_channel_invite(
|
||||
&self,
|
||||
channel_id: ChannelId,
|
||||
user_id: UserId,
|
||||
accept: bool,
|
||||
) -> Result<()> {
|
||||
self.transaction(move |tx| async move {
|
||||
let tx = tx;
|
||||
|
||||
let rows_affected = if accept {
|
||||
channel_member::Entity::update_many()
|
||||
.set(channel_member::ActiveModel {
|
||||
accepted: ActiveValue::Set(accept),
|
||||
..Default::default()
|
||||
})
|
||||
.filter(
|
||||
channel_member::Column::ChannelId
|
||||
.eq(channel_id)
|
||||
.and(channel_member::Column::UserId.eq(user_id))
|
||||
.and(channel_member::Column::Accepted.eq(false)),
|
||||
)
|
||||
.exec(&*tx)
|
||||
.await?
|
||||
.rows_affected
|
||||
} else {
|
||||
channel_member::ActiveModel {
|
||||
channel_id: ActiveValue::Unchanged(channel_id),
|
||||
user_id: ActiveValue::Unchanged(user_id),
|
||||
..Default::default()
|
||||
}
|
||||
.delete(&*tx)
|
||||
.await?
|
||||
.rows_affected
|
||||
};
|
||||
|
||||
if rows_affected == 0 {
|
||||
Err(anyhow!("no such invitation"))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn get_channels(&self, user_id: UserId) -> Result<Vec<Channel>> {
|
||||
self.transaction(|tx| async move {
|
||||
let tx = tx;
|
||||
|
@ -3087,7 +3167,7 @@ impl Database {
|
|||
WITH RECURSIVE channel_tree(child_id, parent_id, depth) AS (
|
||||
SELECT channel_id as child_id, CAST(NULL as INTEGER) as parent_id, 0
|
||||
FROM channel_members
|
||||
WHERE user_id = $1
|
||||
WHERE user_id = $1 AND accepted
|
||||
UNION
|
||||
SELECT channel_parents.child_id, channel_parents.parent_id, channel_tree.depth + 1
|
||||
FROM channel_parents, channel_tree
|
||||
|
@ -3114,6 +3194,22 @@ impl Database {
|
|||
.await
|
||||
}
|
||||
|
||||
pub async fn get_channel(&self, channel_id: ChannelId) -> Result<Channel> {
|
||||
self.transaction(|tx| async move {
|
||||
let tx = tx;
|
||||
let channel = channel::Entity::find_by_id(channel_id)
|
||||
.one(&*tx)
|
||||
.await?
|
||||
.ok_or_else(|| anyhow!("no such channel"))?;
|
||||
Ok(Channel {
|
||||
id: channel.id,
|
||||
name: channel.name,
|
||||
parent_id: None,
|
||||
})
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
async fn transaction<F, Fut, T>(&self, f: F) -> Result<T>
|
||||
where
|
||||
F: Send + Fn(TransactionHandle) -> Fut,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue