use crate::Result;
use async_sqlite::rusqlite::{Connection, Error as SqlError, Row};
use sos_core::UtcDateTime;
use sos_system_messages::SysMessage;
use sql_query_builder as sql;
use std::ops::Deref;
use urn::Urn;
#[doc(hidden)]
#[derive(Debug, Default)]
pub struct SystemMessageRow {
pub row_id: i64,
created_at: String,
modified_at: String,
key: String,
json_data: String,
}
impl<'a> TryFrom<&Row<'a>> for SystemMessageRow {
type Error = SqlError;
fn try_from(row: &Row<'a>) -> std::result::Result<Self, Self::Error> {
Ok(SystemMessageRow {
row_id: row.get(0)?,
created_at: row.get(1)?,
modified_at: row.get(2)?,
key: row.get(3)?,
json_data: row.get(4)?,
})
}
}
impl TryFrom<SystemMessageRow> for (Urn, SysMessage) {
type Error = crate::Error;
fn try_from(
row: SystemMessageRow,
) -> std::result::Result<Self, Self::Error> {
Ok((row.key.parse()?, serde_json::from_str(&row.json_data)?))
}
}
impl TryFrom<(Urn, SysMessage)> for SystemMessageRow {
type Error = crate::Error;
fn try_from(
value: (Urn, SysMessage),
) -> std::result::Result<Self, Self::Error> {
Ok(Self {
created_at: UtcDateTime::default().to_rfc3339()?,
modified_at: UtcDateTime::default().to_rfc3339()?,
key: value.0.to_string(),
json_data: serde_json::to_string(&value.1)?,
..Default::default()
})
}
}
pub struct SystemMessageEntity<'conn, C>
where
C: Deref<Target = Connection>,
{
conn: &'conn C,
}
impl<'conn, C> SystemMessageEntity<'conn, C>
where
C: Deref<Target = Connection>,
{
pub fn new(conn: &'conn C) -> Self {
Self { conn }
}
pub fn load_system_messages(
&self,
account_id: i64,
) -> Result<Vec<SystemMessageRow>> {
let query = sql::Select::new()
.select(
r#"
system_message_id,
created_at,
modified_at,
key,
json_data
"#,
)
.from("system_messages")
.where_clause("account_id = ?1");
let mut stmt = self.conn.prepare_cached(&query.as_string())?;
fn convert_row(row: &Row<'_>) -> Result<SystemMessageRow> {
Ok(row.try_into()?)
}
let rows = stmt.query_and_then([account_id], convert_row)?;
let mut messages = Vec::new();
for row in rows {
messages.push(row?);
}
Ok(messages)
}
pub fn mark_system_message(
&self,
account_id: i64,
key: &str,
is_read: bool,
) -> Result<()> {
let modified_at = UtcDateTime::default().to_rfc3339()?;
let query = sql::Update::new()
.update("system_messages")
.set(
"
modified_at = ?1,
json_data = json_replace (json_data, '$.isRead', json(?2))
",
)
.where_clause("account_id = ?3")
.where_and("key = ?4");
let mut stmt = self.conn.prepare_cached(&query.as_string())?;
stmt.execute((modified_at, is_read, account_id, key))?;
Ok(())
}
pub fn delete_system_message(
&self,
account_id: i64,
key: &str,
) -> std::result::Result<(), SqlError> {
let query = sql::Delete::new()
.delete_from("system_messages")
.where_clause("account_id = ?1")
.where_and("key = ?2");
let mut stmt = self.conn.prepare_cached(&query.as_string())?;
stmt.execute((account_id, key))?;
Ok(())
}
pub fn delete_system_messages(
&self,
account_id: i64,
) -> std::result::Result<(), SqlError> {
let query = sql::Delete::new()
.delete_from("system_messages")
.where_clause("account_id = ?1");
let mut stmt = self.conn.prepare_cached(&query.as_string())?;
stmt.execute([account_id])?;
Ok(())
}
pub fn insert_system_message(
&self,
account_id: i64,
row: &SystemMessageRow,
) -> std::result::Result<(), SqlError> {
let query = sql::Insert::new()
.insert_into(
r#"
system_messages
(
account_id,
created_at,
modified_at,
key,
json_data
)
"#,
)
.values("(?1, ?2, ?3, ?4, ?5)");
let mut stmt = self.conn.prepare_cached(&query.as_string())?;
stmt.execute((
account_id,
&row.created_at,
&row.modified_at,
&row.key,
&row.json_data,
))?;
Ok(())
}
pub fn insert_system_messages(
&self,
account_id: i64,
system_messages: &[SystemMessageRow],
) -> std::result::Result<(), SqlError> {
for row in system_messages {
self.insert_system_message(account_id, row)?;
}
Ok(())
}
}