mirror of
https://github.com/AppFlowy-IO/AppFlowy
synced 2026-04-21 23:57:27 +00:00
* chore: compile * chore: bump rust edition * chore: bump rust tool chain version * chore: fix test * chore: fmt * chore: build target * chore: clippy * chore: fmt
216 lines
5.9 KiB
Rust
216 lines
5.9 KiB
Rust
use diesel::sqlite::SqliteConnection;
|
|
use flowy_error::FlowyResult;
|
|
use flowy_sqlite::upsert::excluded;
|
|
use flowy_sqlite::{
|
|
AsChangeset, DBConnection, ExpressionMethods, Identifiable, Insertable, QueryResult, Queryable,
|
|
diesel,
|
|
query_dsl::*,
|
|
schema::{chat_table, chat_table::dsl},
|
|
};
|
|
use lib_infra::util::timestamp;
|
|
use serde::{Deserialize, Serialize};
|
|
use serde_json::Value;
|
|
use uuid::Uuid;
|
|
|
|
#[derive(Clone, Default, Queryable, Insertable, Identifiable)]
|
|
#[diesel(table_name = chat_table)]
|
|
#[diesel(primary_key(chat_id))]
|
|
pub struct ChatTable {
|
|
pub chat_id: String,
|
|
pub created_at: i64,
|
|
pub metadata: String,
|
|
pub rag_ids: Option<String>,
|
|
pub is_sync: bool,
|
|
pub summary: String,
|
|
}
|
|
|
|
impl ChatTable {
|
|
pub fn new(chat_id: String, metadata: Value, rag_ids: Vec<Uuid>, is_sync: bool) -> Self {
|
|
let rag_ids = rag_ids.iter().map(|v| v.to_string()).collect::<Vec<_>>();
|
|
let metadata = serialize_chat_metadata(&metadata);
|
|
let rag_ids = Some(serialize_rag_ids(&rag_ids));
|
|
Self {
|
|
chat_id,
|
|
created_at: timestamp(),
|
|
metadata,
|
|
rag_ids,
|
|
is_sync,
|
|
summary: "".to_string(),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
|
pub struct ChatTableMetadata {
|
|
pub files: Vec<ChatTableFile>,
|
|
}
|
|
|
|
impl ChatTableMetadata {
|
|
pub fn add_file(&mut self, name: String, id: String) {
|
|
if let Some(file) = self.files.iter_mut().find(|f| f.name == name) {
|
|
file.id = id;
|
|
} else {
|
|
self.files.push(ChatTableFile { name, id });
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct ChatTableFile {
|
|
pub name: String,
|
|
pub id: String,
|
|
}
|
|
|
|
#[derive(AsChangeset, Identifiable, Default, Debug)]
|
|
#[diesel(table_name = chat_table)]
|
|
#[diesel(primary_key(chat_id))]
|
|
pub struct ChatTableChangeset {
|
|
pub chat_id: String,
|
|
pub metadata: Option<String>,
|
|
pub rag_ids: Option<String>,
|
|
pub is_sync: Option<bool>,
|
|
pub summary: Option<String>,
|
|
}
|
|
|
|
impl ChatTableChangeset {
|
|
pub fn summary(chat_id: String, summary: String) -> Self {
|
|
Self {
|
|
chat_id,
|
|
metadata: None,
|
|
rag_ids: None,
|
|
is_sync: None,
|
|
summary: Some(summary),
|
|
}
|
|
}
|
|
|
|
pub fn rag_ids(chat_id: String, rag_ids: Vec<String>) -> Self {
|
|
let rag_ids = Some(serialize_rag_ids(&rag_ids));
|
|
Self {
|
|
chat_id,
|
|
metadata: None,
|
|
rag_ids,
|
|
is_sync: None,
|
|
summary: None,
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn serialize_rag_ids(rag_ids: &[String]) -> String {
|
|
serde_json::to_string(rag_ids).unwrap_or_default()
|
|
}
|
|
|
|
pub fn deserialize_rag_ids(rag_ids_str: &Option<String>) -> Vec<String> {
|
|
match rag_ids_str {
|
|
Some(str) => serde_json::from_str(str).unwrap_or_default(),
|
|
None => Vec::new(),
|
|
}
|
|
}
|
|
|
|
pub fn deserialize_chat_metadata<T>(metadata: &str) -> T
|
|
where
|
|
T: serde::de::DeserializeOwned + Default,
|
|
{
|
|
serde_json::from_str(metadata).unwrap_or_default()
|
|
}
|
|
|
|
pub fn serialize_chat_metadata<T>(metadata: &T) -> String
|
|
where
|
|
T: Serialize,
|
|
{
|
|
serde_json::to_string(metadata).unwrap_or_default()
|
|
}
|
|
|
|
pub fn upsert_chat(mut conn: DBConnection, new_chat: &ChatTable) -> QueryResult<usize> {
|
|
diesel::insert_into(chat_table::table)
|
|
.values(new_chat)
|
|
.on_conflict(chat_table::chat_id)
|
|
.do_update()
|
|
.set((
|
|
chat_table::created_at.eq(excluded(chat_table::created_at)),
|
|
chat_table::metadata.eq(excluded(chat_table::metadata)),
|
|
chat_table::rag_ids.eq(excluded(chat_table::rag_ids)),
|
|
chat_table::is_sync.eq(excluded(chat_table::is_sync)),
|
|
))
|
|
.execute(&mut *conn)
|
|
}
|
|
|
|
pub fn update_chat(mut conn: DBConnection, changeset: ChatTableChangeset) -> QueryResult<usize> {
|
|
// Check if the chat exists
|
|
let chat_exists = dsl::chat_table
|
|
.filter(chat_table::chat_id.eq(&changeset.chat_id))
|
|
.first::<ChatTable>(&mut *conn)
|
|
.is_ok();
|
|
|
|
if chat_exists {
|
|
// Update existing chat
|
|
let filter = dsl::chat_table.filter(chat_table::chat_id.eq(changeset.chat_id.clone()));
|
|
diesel::update(filter).set(changeset).execute(&mut *conn)
|
|
} else {
|
|
// Create a new chat row with default values
|
|
let chat = ChatTable {
|
|
chat_id: changeset.chat_id.clone(),
|
|
created_at: timestamp(),
|
|
metadata: changeset.metadata.unwrap_or_else(|| "{}".to_string()),
|
|
rag_ids: changeset.rag_ids,
|
|
is_sync: changeset.is_sync.unwrap_or(false),
|
|
summary: changeset.summary.unwrap_or_default(),
|
|
};
|
|
|
|
// Insert the new row
|
|
diesel::insert_into(chat_table::table)
|
|
.values(&chat)
|
|
.execute(&mut *conn)
|
|
}
|
|
}
|
|
|
|
pub fn update_chat_is_sync(
|
|
mut conn: DBConnection,
|
|
chat_id_val: &str,
|
|
is_sync_val: bool,
|
|
) -> QueryResult<usize> {
|
|
diesel::update(dsl::chat_table.filter(chat_table::chat_id.eq(chat_id_val)))
|
|
.set(chat_table::is_sync.eq(is_sync_val))
|
|
.execute(&mut *conn)
|
|
}
|
|
|
|
pub fn select_chat(mut conn: DBConnection, chat_id_val: &str) -> QueryResult<ChatTable> {
|
|
let row = dsl::chat_table
|
|
.filter(chat_table::chat_id.eq(chat_id_val))
|
|
.first::<ChatTable>(&mut *conn)?;
|
|
Ok(row)
|
|
}
|
|
|
|
pub fn select_chat_summary(conn: &mut DBConnection, chat_id_val: &Uuid) -> QueryResult<String> {
|
|
let summary = dsl::chat_table
|
|
.select(chat_table::summary)
|
|
.filter(chat_table::chat_id.eq(chat_id_val.to_string()))
|
|
.first::<String>(conn)?;
|
|
Ok(summary)
|
|
}
|
|
|
|
pub fn select_chat_rag_ids(
|
|
conn: &mut SqliteConnection,
|
|
chat_id_val: &str,
|
|
) -> FlowyResult<Vec<String>> {
|
|
let chat = dsl::chat_table
|
|
.filter(chat_table::chat_id.eq(chat_id_val))
|
|
.first::<ChatTable>(conn)?;
|
|
|
|
Ok(deserialize_rag_ids(&chat.rag_ids))
|
|
}
|
|
|
|
pub fn select_chat_metadata(
|
|
conn: &mut SqliteConnection,
|
|
chat_id_val: &str,
|
|
) -> FlowyResult<ChatTableMetadata> {
|
|
let metadata_str = dsl::chat_table
|
|
.select(chat_table::metadata)
|
|
.filter(chat_table::chat_id.eq(chat_id_val))
|
|
.first::<String>(&mut *conn)?;
|
|
Ok(deserialize_chat_metadata(&metadata_str))
|
|
}
|
|
|
|
#[allow(dead_code)]
|
|
pub fn delete_chat(mut conn: DBConnection, chat_id_val: &str) -> QueryResult<usize> {
|
|
diesel::delete(dsl::chat_table.filter(chat_table::chat_id.eq(chat_id_val))).execute(&mut *conn)
|
|
}
|