mod normal;
use diesel::{ExpressionMethods, OptionalExtension, QueryDsl, RunQueryDsl, SqliteConnection};
use futures_loco_protocol::session::LocoSession;
use talk_loco_client::talk::{
channel::ChannelType,
session::{channel::info::ChannelInfoType, TalkSession},
};
use crate::{
database::{
model::channel::{meta::ChannelMetaRow, ChannelListRow},
schema::{channel_list, channel_meta, chat, user_profile},
DatabasePool, PoolTaskError,
},
ClientResult,
};
use self::normal::NormalChannelUpdater;
#[derive(Debug)]
pub struct ChannelUpdater {
id: i64,
}
impl ChannelUpdater {
pub fn new(id: i64) -> Self {
Self { id }
}
pub async fn initialize(
self,
session: &LocoSession,
pool: &DatabasePool,
) -> ClientResult<Option<()>> {
let res = TalkSession(session).channel(self.id).info().await?;
let meta_rows = res
.channel_metas
.into_iter()
.map(|meta| ChannelMetaRow::from_meta(self.id, meta))
.collect::<Vec<_>>();
match res.channel_type {
ChannelInfoType::DirectChat(normal)
| ChannelInfoType::MultiChat(normal)
| ChannelInfoType::MemoChat(normal) => {
NormalChannelUpdater::new(self.id)
.initialize(session, pool, normal, move |conn| {
diesel::replace_into(channel_meta::table)
.values(meta_rows)
.execute(conn)?;
Ok(())
})
.await?;
}
_ => return Ok(None),
}
Ok(Some(()))
}
pub fn remove(self, conn: &mut SqliteConnection) -> Result<Option<()>, PoolTaskError> {
let row: ChannelListRow = if let Some(row) = {
channel_list::table
.select(channel_list::all_columns)
.filter(channel_list::id.eq(self.id))
.first::<ChannelListRow>(conn)
.optional()?
} {
row
} else {
return Ok(None);
};
let ty = ChannelType::from(row.channel_type.as_str());
match ty {
ChannelType::DirectChat | ChannelType::MultiChat | ChannelType::MemoChat => {
NormalChannelUpdater::new(self.id).remove(conn)?;
}
_ => return Ok(None),
}
diesel::delete(chat::table.filter(chat::channel_id.eq(self.id))).execute(conn)?;
diesel::delete(channel_meta::table.filter(channel_meta::channel_id.eq(self.id)))
.execute(conn)?;
diesel::delete(user_profile::table.filter(user_profile::channel_id.eq(self.id)))
.execute(conn)?;
diesel::delete(channel_list::table.filter(channel_list::id.eq(self.id))).execute(conn)?;
Ok(Some(()))
}
}