From 6298a0d96d7b6233fdfeaeaf12d793836f96553f Mon Sep 17 00:00:00 2001 From: appflowy Date: Mon, 6 Dec 2021 15:49:21 +0800 Subject: [PATCH] add core --- backend/tests/util/helper.rs | 2 +- .../flowy-core/src/core/flowy_core.rs | 134 ++++++++++++++++++ frontend/rust-lib/flowy-core/src/core/mod.rs | 4 + frontend/rust-lib/flowy-core/src/core/task.rs | 69 +++++++++ .../rust-lib/flowy-core/src/handlers/mod.rs | 9 -- frontend/rust-lib/flowy-core/src/lib.rs | 5 +- frontend/rust-lib/flowy-core/src/module.rs | 63 +++++--- .../{app_controller.rs => app/controller.rs} | 31 ++-- .../app/event_handler.rs} | 4 +- .../flowy-core/src/services/app/mod.rs | 3 + .../app/app_table.rs => services/app/sql.rs} | 85 +++++++++-- .../flowy-core/src/services/database.rs | 1 - .../rust-lib/flowy-core/src/services/mod.rs | 17 ++- .../{trash_can.rs => trash/controller.rs} | 20 ++- .../trash/event_handler.rs} | 14 +- .../flowy-core/src/services/trash/mod.rs | 3 + .../trash_table.rs => services/trash/sql.rs} | 53 ++++++- .../controller.rs} | 22 ++- .../view/event_handler.rs} | 4 +- .../flowy-core/src/services/view/mod.rs | 3 + .../view_table.rs => services/view/sql.rs} | 109 +++++++++++++- .../controller.rs} | 129 +++-------------- .../workspace/event_handler.rs} | 0 .../flowy-core/src/services/workspace/mod.rs | 3 + .../workspace/sql.rs} | 80 ++++++++++- .../flowy-core/src/sql_tables/app/app_sql.rs | 76 ---------- .../flowy-core/src/sql_tables/app/mod.rs | 5 - .../rust-lib/flowy-core/src/sql_tables/mod.rs | 4 - .../flowy-core/src/sql_tables/trash/mod.rs | 5 - .../src/sql_tables/trash/trash_sql.rs | 53 ------- .../flowy-core/src/sql_tables/view/mod.rs | 5 - .../src/sql_tables/view/view_sql.rs | 104 -------------- .../src/sql_tables/workspace/mod.rs | 5 - .../sql_tables/workspace/workspace_table.rs | 71 ---------- frontend/rust-lib/flowy-sdk/src/lib.rs | 48 +++---- frontend/rust-lib/flowy-sdk/src/module.rs | 11 +- 36 files changed, 676 insertions(+), 578 deletions(-) create mode 100644 frontend/rust-lib/flowy-core/src/core/flowy_core.rs create mode 100644 frontend/rust-lib/flowy-core/src/core/mod.rs create mode 100644 frontend/rust-lib/flowy-core/src/core/task.rs delete mode 100644 frontend/rust-lib/flowy-core/src/handlers/mod.rs rename frontend/rust-lib/flowy-core/src/services/{app_controller.rs => app/controller.rs} (95%) rename frontend/rust-lib/flowy-core/src/{handlers/app_handler.rs => services/app/event_handler.rs} (94%) create mode 100644 frontend/rust-lib/flowy-core/src/services/app/mod.rs rename frontend/rust-lib/flowy-core/src/{sql_tables/app/app_table.rs => services/app/sql.rs} (58%) delete mode 100644 frontend/rust-lib/flowy-core/src/services/database.rs rename frontend/rust-lib/flowy-core/src/services/{trash_can.rs => trash/controller.rs} (98%) rename frontend/rust-lib/flowy-core/src/{handlers/trash_handler.rs => services/trash/event_handler.rs} (77%) create mode 100644 frontend/rust-lib/flowy-core/src/services/trash/mod.rs rename frontend/rust-lib/flowy-core/src/{sql_tables/trash/trash_table.rs => services/trash/sql.rs} (58%) rename frontend/rust-lib/flowy-core/src/services/{view_controller.rs => view/controller.rs} (97%) rename frontend/rust-lib/flowy-core/src/{handlers/view_handler.rs => services/view/event_handler.rs} (97%) create mode 100644 frontend/rust-lib/flowy-core/src/services/view/mod.rs rename frontend/rust-lib/flowy-core/src/{sql_tables/view/view_table.rs => services/view/sql.rs} (51%) rename frontend/rust-lib/flowy-core/src/services/{workspace_controller.rs => workspace/controller.rs} (76%) rename frontend/rust-lib/flowy-core/src/{handlers/workspace_handler.rs => services/workspace/event_handler.rs} (100%) create mode 100644 frontend/rust-lib/flowy-core/src/services/workspace/mod.rs rename frontend/rust-lib/flowy-core/src/{sql_tables/workspace/workspace_sql.rs => services/workspace/sql.rs} (50%) delete mode 100644 frontend/rust-lib/flowy-core/src/sql_tables/app/app_sql.rs delete mode 100644 frontend/rust-lib/flowy-core/src/sql_tables/app/mod.rs delete mode 100644 frontend/rust-lib/flowy-core/src/sql_tables/mod.rs delete mode 100644 frontend/rust-lib/flowy-core/src/sql_tables/trash/mod.rs delete mode 100644 frontend/rust-lib/flowy-core/src/sql_tables/trash/trash_sql.rs delete mode 100644 frontend/rust-lib/flowy-core/src/sql_tables/view/mod.rs delete mode 100644 frontend/rust-lib/flowy-core/src/sql_tables/view/view_sql.rs delete mode 100644 frontend/rust-lib/flowy-core/src/sql_tables/workspace/mod.rs delete mode 100644 frontend/rust-lib/flowy-core/src/sql_tables/workspace/workspace_table.rs diff --git a/backend/tests/util/helper.rs b/backend/tests/util/helper.rs index 1b463faa93..93d7d6eb5c 100644 --- a/backend/tests/util/helper.rs +++ b/backend/tests/util/helper.rs @@ -188,7 +188,7 @@ impl std::convert::From for TestUserServer { pg_pool: server.pg_pool, user_token: None, user_id: None, - client_server_config: server.client_server_config.clone(), + client_server_config: server.client_server_config, } } } diff --git a/frontend/rust-lib/flowy-core/src/core/flowy_core.rs b/frontend/rust-lib/flowy-core/src/core/flowy_core.rs new file mode 100644 index 0000000000..03d1f7354f --- /dev/null +++ b/frontend/rust-lib/flowy-core/src/core/flowy_core.rs @@ -0,0 +1,134 @@ +use crate::{ + entities::workspace::RepeatedWorkspace, + errors::{WorkspaceError, WorkspaceResult}, + module::WorkspaceUser, + notify::{send_dart_notification, WorkspaceNotification}, + services::{server::Server, AppController, TrashController, ViewController, WorkspaceController}, +}; +use chrono::Utc; +use flowy_document_infra::{entities::doc::DocDelta, user_default::initial_read_me}; +use flowy_workspace_infra::user_default; +use lazy_static::lazy_static; +use lib_infra::entities::network_state::NetworkType; +use parking_lot::RwLock; +use std::{collections::HashMap, sync::Arc}; + +lazy_static! { + static ref INIT_WORKSPACE: RwLock> = RwLock::new(HashMap::new()); +} + +pub struct FlowyCore { + pub user: Arc, + server: Server, + pub workspace_controller: Arc, + pub(crate) app_controller: Arc, + pub(crate) view_controller: Arc, + pub(crate) trash_controller: Arc, +} + +impl FlowyCore { + pub(crate) fn new( + user: Arc, + server: Server, + workspace_controller: Arc, + app_controller: Arc, + view_controller: Arc, + trash_controller: Arc, + ) -> Self { + if let Ok(token) = user.token() { + INIT_WORKSPACE.write().insert(token, false); + } + + Self { + user, + server, + workspace_controller, + app_controller, + view_controller, + trash_controller, + } + } + + async fn init(&self, token: &str) -> Result<(), WorkspaceError> { + if let Some(is_init) = INIT_WORKSPACE.read().get(token) { + if *is_init { + return Ok(()); + } + } + log::debug!("Start initializing flowy core"); + INIT_WORKSPACE.write().insert(token.to_owned(), true); + let _ = self.server.init(); + let _ = self.workspace_controller.init()?; + let _ = self.app_controller.init()?; + let _ = self.view_controller.init()?; + let _ = self.trash_controller.init()?; + log::debug!("Finish initializing core"); + + Ok(()) + } + + pub fn network_state_changed(&self, new_type: NetworkType) { + match new_type { + NetworkType::UnknownNetworkType => {}, + NetworkType::Wifi => {}, + NetworkType::Cell => {}, + NetworkType::Ethernet => {}, + } + } + + pub async fn user_did_sign_in(&self, token: &str) -> WorkspaceResult<()> { + // TODO: (nathan) do something here + + log::debug!("workspace initialize after sign in"); + let _ = self.init(token).await?; + Ok(()) + } + + pub async fn user_did_logout(&self) { + // TODO: (nathan) do something here + } + + pub async fn user_session_expired(&self) { + // TODO: (nathan) do something here + } + + pub async fn user_did_sign_up(&self, _token: &str) -> WorkspaceResult<()> { + log::debug!("Create user default workspace"); + let time = Utc::now(); + let mut workspace = user_default::create_default_workspace(time); + let apps = workspace.take_apps().into_inner(); + let cloned_workspace = workspace.clone(); + + let _ = self.workspace_controller.create_workspace(workspace).await?; + for mut app in apps { + let views = app.take_belongings().into_inner(); + let _ = self.app_controller.create_app(app).await?; + for (index, view) in views.into_iter().enumerate() { + if index == 0 { + let delta = initial_read_me(); + let doc_delta = DocDelta { + doc_id: view.id.clone(), + data: delta.to_json(), + }; + let _ = self.view_controller.apply_doc_delta(doc_delta).await?; + + self.view_controller.set_latest_view(&view); + } + let _ = self.view_controller.create_view(view).await?; + } + } + + let token = self.user.token()?; + let repeated_workspace = RepeatedWorkspace { + items: vec![cloned_workspace], + }; + + send_dart_notification(&token, WorkspaceNotification::UserCreateWorkspace) + .payload(repeated_workspace) + .send(); + + log::debug!("workspace initialize after sign up"); + let _ = self.init(&token).await?; + Ok(()) + } +} diff --git a/frontend/rust-lib/flowy-core/src/core/mod.rs b/frontend/rust-lib/flowy-core/src/core/mod.rs new file mode 100644 index 0000000000..a21ead744c --- /dev/null +++ b/frontend/rust-lib/flowy-core/src/core/mod.rs @@ -0,0 +1,4 @@ +mod flowy_core; +mod task; + +pub use flowy_core::*; diff --git a/frontend/rust-lib/flowy-core/src/core/task.rs b/frontend/rust-lib/flowy-core/src/core/task.rs new file mode 100644 index 0000000000..01054ee350 --- /dev/null +++ b/frontend/rust-lib/flowy-core/src/core/task.rs @@ -0,0 +1,69 @@ +use crate::{errors::WorkspaceError, services::WorkspaceController}; +use flowy_workspace_infra::entities::workspace::{QueryWorkspaceRequest, RepeatedWorkspace, WorkspaceIdentifier}; +use lib_dispatch::prelude::{data_result, Data, DataResult, Unit}; +use std::{convert::TryInto, sync::Arc}; + +#[tracing::instrument(skip(data, controller), err)] +pub(crate) async fn read_workspaces_handler( + data: Data, + controller: Unit>, +) -> DataResult { + let params: WorkspaceIdentifier = data.into_inner().try_into()?; + let user_id = controller.user.user_id()?; + let workspaces = controller.read_local_workspaces( + params.workspace_id.clone(), + &user_id, + &*controller.database.db_connection()?, + )?; + let _ = controller.read_workspaces_on_server(user_id, params); + + data_result(workspaces) +} + +// #[tracing::instrument(level = "debug", skip(self), err)] +// fn read_workspaces_on_server(&self, user_id: String, params: +// WorkspaceIdentifier) -> Result<(), WorkspaceError> { let (token, server) +// = self.token_with_server()?; let workspace_sql = +// self.workspace_sql.clone(); let app_ctrl = self.app_controller.clone(); +// let view_ctrl = self.view_controller.clone(); +// let conn = self.database.db_connection()?; +// tokio::spawn(async move { +// // Opti: handle the error and retry? +// let workspaces = server.read_workspace(&token, params).await?; +// let _ = (&*conn).immediate_transaction::<_, WorkspaceError, _>(|| { +// tracing::debug!("Save {} workspace", workspaces.len()); +// for workspace in &workspaces.items { +// let m_workspace = workspace.clone(); +// let apps = m_workspace.apps.clone().into_inner(); +// let workspace_table = WorkspaceTable::new(m_workspace, +// &user_id); +// +// let _ = workspace_sql.create_workspace(workspace_table, +// &*conn)?; tracing::debug!("Save {} apps", apps.len()); +// for app in apps { +// let views = app.belongings.clone().into_inner(); +// match app_ctrl.save_app(app, &*conn) { +// Ok(_) => {}, +// Err(e) => log::error!("create app failed: {:?}", e), +// } +// +// tracing::debug!("Save {} views", views.len()); +// for view in views { +// match view_ctrl.save_view(view, &*conn) { +// Ok(_) => {}, +// Err(e) => log::error!("create view failed: {:?}", +// e), } +// } +// } +// } +// Ok(()) +// })?; +// +// send_dart_notification(&token, +// WorkspaceNotification::WorkspaceListUpdated) .payload(workspaces) +// .send(); +// Result::<(), WorkspaceError>::Ok(()) +// }); +// +// Ok(()) +// } diff --git a/frontend/rust-lib/flowy-core/src/handlers/mod.rs b/frontend/rust-lib/flowy-core/src/handlers/mod.rs deleted file mode 100644 index cd1e525370..0000000000 --- a/frontend/rust-lib/flowy-core/src/handlers/mod.rs +++ /dev/null @@ -1,9 +0,0 @@ -mod app_handler; -mod trash_handler; -mod view_handler; -mod workspace_handler; - -pub(crate) use app_handler::*; -pub(crate) use trash_handler::*; -pub(crate) use view_handler::*; -pub(crate) use workspace_handler::*; diff --git a/frontend/rust-lib/flowy-core/src/lib.rs b/frontend/rust-lib/flowy-core/src/lib.rs index e3441b8d9c..f3d3d51b8c 100644 --- a/frontend/rust-lib/flowy-core/src/lib.rs +++ b/frontend/rust-lib/flowy-core/src/lib.rs @@ -10,15 +10,14 @@ mod macros; #[macro_use] extern crate flowy_database; +pub mod core; pub mod errors; -pub mod handlers; mod notify; pub mod protobuf; -mod sql_tables; mod util; pub mod prelude { pub use flowy_workspace_infra::entities::{app::*, trash::*, view::*, workspace::*}; - pub use crate::{errors::*, module::*, services::*}; + pub use crate::{core::*, errors::*, module::*}; } diff --git a/frontend/rust-lib/flowy-core/src/module.rs b/frontend/rust-lib/flowy-core/src/module.rs index 00f5672481..d404d31a25 100644 --- a/frontend/rust-lib/flowy-core/src/module.rs +++ b/frontend/rust-lib/flowy-core/src/module.rs @@ -1,15 +1,27 @@ -use crate::{ - errors::WorkspaceError, - event::WorkspaceEvent, - handlers::*, - services::{server::construct_workspace_server, AppController, TrashCan, ViewController, WorkspaceController}, -}; +use std::sync::Arc; + use backend_service::configuration::ClientServerConfiguration; use flowy_database::DBConnection; use flowy_document::module::FlowyDocument; use lib_dispatch::prelude::*; use lib_sqlite::ConnectionPool; -use std::sync::Arc; + +use crate::{ + core::FlowyCore, + errors::WorkspaceError, + event::WorkspaceEvent, + services::{ + app::event_handler::*, + server::construct_workspace_server, + trash::event_handler::*, + view::event_handler::*, + workspace::event_handler::*, + AppController, + TrashController, + ViewController, + WorkspaceController, + }, +}; pub trait WorkspaceDeps: WorkspaceUser + WorkspaceDatabase {} @@ -28,48 +40,57 @@ pub trait WorkspaceDatabase: Send + Sync { } } -pub fn init_workspace_controller( +pub fn init_core( user: Arc, database: Arc, flowy_document: Arc, server_config: &ClientServerConfiguration, -) -> Arc { +) -> Arc { let server = construct_workspace_server(server_config); - let trash_can = Arc::new(TrashCan::new(database.clone(), server.clone(), user.clone())); + let trash_controller = Arc::new(TrashController::new(database.clone(), server.clone(), user.clone())); let view_controller = Arc::new(ViewController::new( user.clone(), database.clone(), server.clone(), - trash_can.clone(), + trash_controller.clone(), flowy_document, )); let app_controller = Arc::new(AppController::new( user.clone(), database.clone(), - trash_can.clone(), + trash_controller.clone(), server.clone(), )); - Arc::new(WorkspaceController::new( + let workspace_controller = Arc::new(WorkspaceController::new( + user.clone(), + database.clone(), + app_controller.clone(), + view_controller.clone(), + trash_controller.clone(), + server.clone(), + )); + + Arc::new(FlowyCore::new( user, - database, + server, + workspace_controller, app_controller, view_controller, - trash_can, - server, + trash_controller, )) } -pub fn create(workspace: Arc) -> Module { +pub fn create(core: Arc) -> Module { let mut module = Module::new() .name("Flowy-Workspace") - .data(workspace.clone()) - .data(workspace.app_controller.clone()) - .data(workspace.view_controller.clone()) - .data(workspace.trash_can.clone()); + .data(core.workspace_controller.clone()) + .data(core.app_controller.clone()) + .data(core.view_controller.clone()) + .data(core.trash_controller.clone()); module = module .event(WorkspaceEvent::CreateWorkspace, create_workspace_handler) diff --git a/frontend/rust-lib/flowy-core/src/services/app_controller.rs b/frontend/rust-lib/flowy-core/src/services/app/controller.rs similarity index 95% rename from frontend/rust-lib/flowy-core/src/services/app_controller.rs rename to frontend/rust-lib/flowy-core/src/services/app/controller.rs index 3845cd8640..107b87a54c 100644 --- a/frontend/rust-lib/flowy-core/src/services/app_controller.rs +++ b/frontend/rust-lib/flowy-core/src/services/app/controller.rs @@ -1,9 +1,3 @@ -use std::{collections::HashSet, sync::Arc}; - -use futures::{FutureExt, StreamExt}; - -use flowy_database::SqliteConnection; - use crate::{ entities::{ app::{App, CreateAppParams, *}, @@ -12,14 +6,21 @@ use crate::{ errors::*, module::{WorkspaceDatabase, WorkspaceUser}, notify::*, - services::{server::Server, TrashCan, TrashEvent}, - sql_tables::app::{AppTable, AppTableChangeset, AppTableSql}, + services::{ + app::sql::{AppTable, AppTableChangeset, AppTableSql}, + server::Server, + TrashController, + TrashEvent, + }, }; +use flowy_database::SqliteConnection; +use futures::{FutureExt, StreamExt}; +use std::{collections::HashSet, sync::Arc}; pub(crate) struct AppController { user: Arc, database: Arc, - trash_can: Arc, + trash_can: Arc, server: Server, } @@ -27,7 +28,7 @@ impl AppController { pub(crate) fn new( user: Arc, database: Arc, - trash_can: Arc, + trash_can: Arc, server: Server, ) -> Self { Self { @@ -185,7 +186,7 @@ impl AppController { } #[tracing::instrument(level = "trace", skip(database, trash_can))] -async fn handle_trash_event(database: Arc, trash_can: Arc, event: TrashEvent) { +async fn handle_trash_event(database: Arc, trash_can: Arc, event: TrashEvent) { let db_result = database.db_connection(); match event { TrashEvent::NewTrash(identifiers, ret) | TrashEvent::Putback(identifiers, ret) => { @@ -226,7 +227,11 @@ async fn handle_trash_event(database: Arc, trash_can: Arc } #[tracing::instrument(skip(workspace_id, trash_can, conn), err)] -fn notify_apps_changed(workspace_id: &str, trash_can: Arc, conn: &SqliteConnection) -> WorkspaceResult<()> { +fn notify_apps_changed( + workspace_id: &str, + trash_can: Arc, + conn: &SqliteConnection, +) -> WorkspaceResult<()> { let repeated_app = read_local_workspace_apps(workspace_id, trash_can, conn)?; send_dart_notification(workspace_id, WorkspaceNotification::WorkspaceAppsChanged) .payload(repeated_app) @@ -236,7 +241,7 @@ fn notify_apps_changed(workspace_id: &str, trash_can: Arc, conn: &Sqli pub fn read_local_workspace_apps( workspace_id: &str, - trash_can: Arc, + trash_can: Arc, conn: &SqliteConnection, ) -> Result { let mut app_tables = AppTableSql::read_workspace_apps(workspace_id, false, conn)?; diff --git a/frontend/rust-lib/flowy-core/src/handlers/app_handler.rs b/frontend/rust-lib/flowy-core/src/services/app/event_handler.rs similarity index 94% rename from frontend/rust-lib/flowy-core/src/handlers/app_handler.rs rename to frontend/rust-lib/flowy-core/src/services/app/event_handler.rs index 38799288db..011af97ade 100644 --- a/frontend/rust-lib/flowy-core/src/handlers/app_handler.rs +++ b/frontend/rust-lib/flowy-core/src/services/app/event_handler.rs @@ -12,7 +12,7 @@ use crate::{ trash::Trash, }, errors::WorkspaceError, - services::{AppController, TrashCan, ViewController}, + services::{AppController, TrashController, ViewController}, }; use lib_dispatch::prelude::{data_result, Data, DataResult, Unit}; use std::{convert::TryInto, sync::Arc}; @@ -30,7 +30,7 @@ pub(crate) async fn create_app_handler( pub(crate) async fn delete_app_handler( data: Data, controller: Unit>, - trash_can: Unit>, + trash_can: Unit>, ) -> Result<(), WorkspaceError> { let params: AppIdentifier = data.into_inner().try_into()?; let trash = controller diff --git a/frontend/rust-lib/flowy-core/src/services/app/mod.rs b/frontend/rust-lib/flowy-core/src/services/app/mod.rs new file mode 100644 index 0000000000..8bf3cc04ff --- /dev/null +++ b/frontend/rust-lib/flowy-core/src/services/app/mod.rs @@ -0,0 +1,3 @@ +pub mod controller; +pub mod event_handler; +pub(crate) mod sql; diff --git a/frontend/rust-lib/flowy-core/src/sql_tables/app/app_table.rs b/frontend/rust-lib/flowy-core/src/services/app/sql.rs similarity index 58% rename from frontend/rust-lib/flowy-core/src/sql_tables/app/app_table.rs rename to frontend/rust-lib/flowy-core/src/services/app/sql.rs index a236d82d32..12b08d55e9 100644 --- a/frontend/rust-lib/flowy-core/src/sql_tables/app/app_table.rs +++ b/frontend/rust-lib/flowy-core/src/services/app/sql.rs @@ -1,18 +1,87 @@ -use std::convert::TryInto; - -use diesel::sql_types::Binary; -use serde::{Deserialize, Serialize, __private::TryFrom}; - -use flowy_database::schema::app_table; - use crate::{ entities::{ app::{App, ColorStyle, UpdateAppParams}, trash::{Trash, TrashType}, view::RepeatedView, }, - sql_tables::workspace::WorkspaceTable, + services::workspace::sql::WorkspaceTable, }; +use diesel::sql_types::Binary; +use flowy_database::{ + prelude::*, + schema::{app_table, app_table::dsl}, + SqliteConnection, +}; +use serde::{Deserialize, Serialize, __private::TryFrom}; +use std::convert::TryInto; + +use crate::errors::WorkspaceError; + +pub struct AppTableSql {} + +impl AppTableSql { + pub(crate) fn create_app(app_table: AppTable, conn: &SqliteConnection) -> Result<(), WorkspaceError> { + match diesel_record_count!(app_table, &app_table.id, conn) { + 0 => diesel_insert_table!(app_table, &app_table, conn), + _ => { + let changeset = AppTableChangeset::from_table(app_table); + diesel_update_table!(app_table, changeset, conn) + }, + } + Ok(()) + } + + pub(crate) fn update_app(changeset: AppTableChangeset, conn: &SqliteConnection) -> Result<(), WorkspaceError> { + diesel_update_table!(app_table, changeset, conn); + Ok(()) + } + + pub(crate) fn read_app(app_id: &str, conn: &SqliteConnection) -> Result { + let filter = dsl::app_table.filter(app_table::id.eq(app_id)).into_boxed(); + let app_table = filter.first::(conn)?; + Ok(app_table) + } + + pub(crate) fn read_workspace_apps( + workspace_id: &str, + is_trash: bool, + conn: &SqliteConnection, + ) -> Result, WorkspaceError> { + let app_table = dsl::app_table + .filter(app_table::workspace_id.eq(workspace_id)) + .filter(app_table::is_trash.eq(is_trash)) + .order(app_table::create_time.asc()) + .load::(conn)?; + + Ok(app_table) + } + + pub(crate) fn delete_app(app_id: &str, conn: &SqliteConnection) -> Result { + let app_table = dsl::app_table + .filter(app_table::id.eq(app_id)) + .first::(conn)?; + diesel_delete_table!(app_table, app_id, conn); + Ok(app_table) + } + + // pub(crate) fn read_views_belong_to_app( + // &self, + // app_id: &str, + // ) -> Result, WorkspaceError> { + // let conn = self.database.db_connection()?; + // + // let views = conn.immediate_transaction::<_, WorkspaceError, _>(|| { + // let app_table: AppTable = dsl::app_table + // .filter(app_table::id.eq(app_id)) + // .first::(&*(conn))?; + // let views = + // ViewTable::belonging_to(&app_table).load::(&*conn)?; + // Ok(views) + // })?; + // + // Ok(views) + // } +} #[derive(PartialEq, Clone, Debug, Queryable, Identifiable, Insertable, Associations)] #[belongs_to(WorkspaceTable, foreign_key = "workspace_id")] diff --git a/frontend/rust-lib/flowy-core/src/services/database.rs b/frontend/rust-lib/flowy-core/src/services/database.rs deleted file mode 100644 index 8b13789179..0000000000 --- a/frontend/rust-lib/flowy-core/src/services/database.rs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/frontend/rust-lib/flowy-core/src/services/mod.rs b/frontend/rust-lib/flowy-core/src/services/mod.rs index 5678526952..5ce07dd23b 100644 --- a/frontend/rust-lib/flowy-core/src/services/mod.rs +++ b/frontend/rust-lib/flowy-core/src/services/mod.rs @@ -1,11 +1,10 @@ -pub(crate) use app_controller::*; -pub(crate) use trash_can::*; -pub(crate) use view_controller::*; -pub use workspace_controller::*; +pub(crate) use app::controller::*; +pub(crate) use trash::controller::*; +pub(crate) use view::controller::*; +pub(crate) use workspace::controller::*; -mod app_controller; -mod database; +pub(crate) mod app; pub(crate) mod server; -mod trash_can; -mod view_controller; -mod workspace_controller; +pub(crate) mod trash; +pub(crate) mod view; +pub(crate) mod workspace; diff --git a/frontend/rust-lib/flowy-core/src/services/trash_can.rs b/frontend/rust-lib/flowy-core/src/services/trash/controller.rs similarity index 98% rename from frontend/rust-lib/flowy-core/src/services/trash_can.rs rename to frontend/rust-lib/flowy-core/src/services/trash/controller.rs index 716966a0d9..670111860b 100644 --- a/frontend/rust-lib/flowy-core/src/services/trash_can.rs +++ b/frontend/rust-lib/flowy-core/src/services/trash/controller.rs @@ -1,27 +1,23 @@ -use std::{fmt::Formatter, sync::Arc}; - -use crossbeam_utils::thread; -use tokio::sync::{broadcast, mpsc}; - -use flowy_database::SqliteConnection; - use crate::{ entities::trash::{RepeatedTrash, Trash, TrashIdentifier, TrashIdentifiers, TrashType}, errors::{WorkspaceError, WorkspaceResult}, module::{WorkspaceDatabase, WorkspaceUser}, notify::{send_anonymous_dart_notification, WorkspaceNotification}, - services::server::Server, - sql_tables::trash::TrashTableSql, + services::{server::Server, trash::sql::TrashTableSql}, }; +use crossbeam_utils::thread; +use flowy_database::SqliteConnection; +use std::{fmt::Formatter, sync::Arc}; +use tokio::sync::{broadcast, mpsc}; -pub struct TrashCan { +pub struct TrashController { pub database: Arc, notify: broadcast::Sender, server: Server, user: Arc, } -impl TrashCan { +impl TrashController { pub fn new(database: Arc, server: Server, user: Arc) -> Self { let (tx, _) = broadcast::channel(10); @@ -196,7 +192,7 @@ impl TrashCan { } } -impl TrashCan { +impl TrashController { #[tracing::instrument(level = "debug", skip(self, trash), err)] fn create_trash_on_server>(&self, trash: T) -> WorkspaceResult<()> { let token = self.user.token()?; diff --git a/frontend/rust-lib/flowy-core/src/handlers/trash_handler.rs b/frontend/rust-lib/flowy-core/src/services/trash/event_handler.rs similarity index 77% rename from frontend/rust-lib/flowy-core/src/handlers/trash_handler.rs rename to frontend/rust-lib/flowy-core/src/services/trash/event_handler.rs index dff81964e8..3b72f630c0 100644 --- a/frontend/rust-lib/flowy-core/src/handlers/trash_handler.rs +++ b/frontend/rust-lib/flowy-core/src/services/trash/event_handler.rs @@ -1,13 +1,15 @@ use crate::{ entities::trash::{RepeatedTrash, TrashIdentifier, TrashIdentifiers}, errors::WorkspaceError, - services::TrashCan, + services::TrashController, }; use lib_dispatch::prelude::{data_result, Data, DataResult, Unit}; use std::sync::Arc; #[tracing::instrument(skip(controller), err)] -pub(crate) async fn read_trash_handler(controller: Unit>) -> DataResult { +pub(crate) async fn read_trash_handler( + controller: Unit>, +) -> DataResult { let conn = controller.database.db_connection()?; let repeated_trash = controller.read_trash(&conn)?; data_result(repeated_trash) @@ -16,7 +18,7 @@ pub(crate) async fn read_trash_handler(controller: Unit>) -> DataR #[tracing::instrument(skip(identifier, controller), err)] pub(crate) async fn putback_trash_handler( identifier: Data, - controller: Unit>, + controller: Unit>, ) -> Result<(), WorkspaceError> { let _ = controller.putback(&identifier.id).await?; Ok(()) @@ -25,20 +27,20 @@ pub(crate) async fn putback_trash_handler( #[tracing::instrument(skip(identifiers, controller), err)] pub(crate) async fn delete_trash_handler( identifiers: Data, - controller: Unit>, + controller: Unit>, ) -> Result<(), WorkspaceError> { let _ = controller.delete(identifiers.into_inner()).await?; Ok(()) } #[tracing::instrument(skip(controller), err)] -pub(crate) async fn restore_all_handler(controller: Unit>) -> Result<(), WorkspaceError> { +pub(crate) async fn restore_all_handler(controller: Unit>) -> Result<(), WorkspaceError> { let _ = controller.restore_all().await?; Ok(()) } #[tracing::instrument(skip(controller), err)] -pub(crate) async fn delete_all_handler(controller: Unit>) -> Result<(), WorkspaceError> { +pub(crate) async fn delete_all_handler(controller: Unit>) -> Result<(), WorkspaceError> { let _ = controller.delete_all().await?; Ok(()) } diff --git a/frontend/rust-lib/flowy-core/src/services/trash/mod.rs b/frontend/rust-lib/flowy-core/src/services/trash/mod.rs new file mode 100644 index 0000000000..c08fd82307 --- /dev/null +++ b/frontend/rust-lib/flowy-core/src/services/trash/mod.rs @@ -0,0 +1,3 @@ +pub mod controller; +pub mod event_handler; +mod sql; diff --git a/frontend/rust-lib/flowy-core/src/sql_tables/trash/trash_table.rs b/frontend/rust-lib/flowy-core/src/services/trash/sql.rs similarity index 58% rename from frontend/rust-lib/flowy-core/src/sql_tables/trash/trash_table.rs rename to frontend/rust-lib/flowy-core/src/services/trash/sql.rs index b07fc53088..b65b448a96 100644 --- a/frontend/rust-lib/flowy-core/src/sql_tables/trash/trash_table.rs +++ b/frontend/rust-lib/flowy-core/src/services/trash/sql.rs @@ -1,6 +1,55 @@ -use crate::entities::trash::{Trash, TrashType}; +use crate::{ + entities::trash::{RepeatedTrash, Trash, TrashType}, + errors::WorkspaceError, +}; use diesel::sql_types::Integer; -use flowy_database::schema::trash_table; +use flowy_database::{ + prelude::*, + schema::{trash_table, trash_table::dsl}, + SqliteConnection, +}; + +pub struct TrashTableSql {} + +impl TrashTableSql { + pub(crate) fn create_trash(repeated_trash: Vec, conn: &SqliteConnection) -> Result<(), WorkspaceError> { + for trash in repeated_trash { + let trash_table: TrashTable = trash.into(); + match diesel_record_count!(trash_table, &trash_table.id, conn) { + 0 => diesel_insert_table!(trash_table, &trash_table, conn), + _ => { + let changeset = TrashTableChangeset::from(trash_table); + diesel_update_table!(trash_table, changeset, conn) + }, + } + } + + Ok(()) + } + + pub(crate) fn read_all(conn: &SqliteConnection) -> Result { + let trash_tables = dsl::trash_table.load::(conn)?; + let items = trash_tables.into_iter().map(|t| t.into()).collect::>(); + Ok(RepeatedTrash { items }) + } + + pub(crate) fn delete_all(conn: &SqliteConnection) -> Result<(), WorkspaceError> { + let _ = diesel::delete(dsl::trash_table).execute(conn)?; + Ok(()) + } + + pub(crate) fn read(trash_id: &str, conn: &SqliteConnection) -> Result { + let trash_table = dsl::trash_table + .filter(trash_table::id.eq(trash_id)) + .first::(conn)?; + Ok(trash_table) + } + + pub(crate) fn delete_trash(trash_id: &str, conn: &SqliteConnection) -> Result<(), WorkspaceError> { + diesel_delete_table!(trash_table, trash_id, conn); + Ok(()) + } +} #[derive(PartialEq, Clone, Debug, Queryable, Identifiable, Insertable, Associations)] #[table_name = "trash_table"] diff --git a/frontend/rust-lib/flowy-core/src/services/view_controller.rs b/frontend/rust-lib/flowy-core/src/services/view/controller.rs similarity index 97% rename from frontend/rust-lib/flowy-core/src/services/view_controller.rs rename to frontend/rust-lib/flowy-core/src/services/view/controller.rs index d460afe03d..2e98984dd8 100644 --- a/frontend/rust-lib/flowy-core/src/services/view_controller.rs +++ b/frontend/rust-lib/flowy-core/src/services/view/controller.rs @@ -11,8 +11,12 @@ use crate::{ errors::{internal_error, WorkspaceError, WorkspaceResult}, module::{WorkspaceDatabase, WorkspaceUser}, notify::{send_dart_notification, WorkspaceNotification}, - services::{server::Server, TrashCan, TrashEvent}, - sql_tables::view::{ViewTable, ViewTableChangeset, ViewTableSql}, + services::{ + server::Server, + view::sql::{ViewTable, ViewTableChangeset, ViewTableSql}, + TrashController, + TrashEvent, + }, }; use flowy_document::module::FlowyDocument; use flowy_workspace_infra::entities::share::{ExportData, ExportParams}; @@ -24,7 +28,7 @@ pub(crate) struct ViewController { user: Arc, server: Server, database: Arc, - trash_can: Arc, + trash_can: Arc, document: Arc, } @@ -33,7 +37,7 @@ impl ViewController { user: Arc, database: Arc, server: Server, - trash_can: Arc, + trash_can: Arc, document: Arc, ) -> Self { Self { @@ -296,7 +300,7 @@ impl ViewController { async fn handle_trash_event( database: Arc, document: Arc, - trash_can: Arc, + trash_can: Arc, event: TrashEvent, ) { let db_result = database.db_connection(); @@ -372,7 +376,11 @@ fn notify_dart(view_table: ViewTable, notification: WorkspaceNotification) { } #[tracing::instrument(skip(belong_to_id, trash_can, conn), fields(view_count), err)] -fn notify_views_changed(belong_to_id: &str, trash_can: Arc, conn: &SqliteConnection) -> WorkspaceResult<()> { +fn notify_views_changed( + belong_to_id: &str, + trash_can: Arc, + conn: &SqliteConnection, +) -> WorkspaceResult<()> { let repeated_view = read_local_belonging_view(belong_to_id, trash_can.clone(), conn)?; tracing::Span::current().record("view_count", &format!("{}", repeated_view.len()).as_str()); send_dart_notification(&belong_to_id, WorkspaceNotification::AppViewsChanged) @@ -383,7 +391,7 @@ fn notify_views_changed(belong_to_id: &str, trash_can: Arc, conn: &Sql fn read_local_belonging_view( belong_to_id: &str, - trash_can: Arc, + trash_can: Arc, conn: &SqliteConnection, ) -> WorkspaceResult { let mut view_tables = ViewTableSql::read_views(belong_to_id, conn)?; diff --git a/frontend/rust-lib/flowy-core/src/handlers/view_handler.rs b/frontend/rust-lib/flowy-core/src/services/view/event_handler.rs similarity index 97% rename from frontend/rust-lib/flowy-core/src/handlers/view_handler.rs rename to frontend/rust-lib/flowy-core/src/services/view/event_handler.rs index 5212d7cb2a..7a1e11e5aa 100644 --- a/frontend/rust-lib/flowy-core/src/handlers/view_handler.rs +++ b/frontend/rust-lib/flowy-core/src/services/view/event_handler.rs @@ -13,7 +13,7 @@ use crate::{ }, }, errors::WorkspaceError, - services::{TrashCan, ViewController}, + services::{TrashController, ViewController}, }; use flowy_document_infra::entities::doc::DocDelta; use flowy_workspace_infra::entities::share::{ExportData, ExportParams, ExportRequest}; @@ -63,7 +63,7 @@ pub(crate) async fn apply_doc_delta_handler( pub(crate) async fn delete_view_handler( data: Data, controller: Unit>, - trash_can: Unit>, + trash_can: Unit>, ) -> Result<(), WorkspaceError> { let params: ViewIdentifiers = data.into_inner().try_into()?; for view_id in ¶ms.view_ids { diff --git a/frontend/rust-lib/flowy-core/src/services/view/mod.rs b/frontend/rust-lib/flowy-core/src/services/view/mod.rs new file mode 100644 index 0000000000..c08fd82307 --- /dev/null +++ b/frontend/rust-lib/flowy-core/src/services/view/mod.rs @@ -0,0 +1,3 @@ +pub mod controller; +pub mod event_handler; +mod sql; diff --git a/frontend/rust-lib/flowy-core/src/sql_tables/view/view_table.rs b/frontend/rust-lib/flowy-core/src/services/view/sql.rs similarity index 51% rename from frontend/rust-lib/flowy-core/src/sql_tables/view/view_table.rs rename to frontend/rust-lib/flowy-core/src/services/view/sql.rs index 54f9f49c44..fedd6310bb 100644 --- a/frontend/rust-lib/flowy-core/src/sql_tables/view/view_table.rs +++ b/frontend/rust-lib/flowy-core/src/services/view/sql.rs @@ -1,15 +1,112 @@ -use diesel::sql_types::Integer; - -use flowy_database::schema::view_table; -use lib_infra::timestamp; - use crate::{ entities::{ trash::{Trash, TrashType}, view::{RepeatedView, UpdateViewParams, View, ViewType}, }, - sql_tables::app::AppTable, + errors::WorkspaceError, + services::app::sql::AppTable, }; +use diesel::sql_types::Integer; +use flowy_database::{ + prelude::*, + schema::{view_table, view_table::dsl}, + SqliteConnection, +}; +use lib_infra::timestamp; + +pub struct ViewTableSql {} + +impl ViewTableSql { + pub(crate) fn create_view(view_table: ViewTable, conn: &SqliteConnection) -> Result<(), WorkspaceError> { + match diesel_record_count!(view_table, &view_table.id, conn) { + 0 => diesel_insert_table!(view_table, &view_table, conn), + _ => { + let changeset = ViewTableChangeset::from_table(view_table); + diesel_update_table!(view_table, changeset, conn) + }, + } + Ok(()) + } + + pub(crate) fn read_view(view_id: &str, conn: &SqliteConnection) -> Result { + // https://docs.diesel.rs/diesel/query_builder/struct.UpdateStatement.html + // let mut filter = + // dsl::view_table.filter(view_table::id.eq(view_id)).into_boxed(); + // if let Some(is_trash) = is_trash { + // filter = filter.filter(view_table::is_trash.eq(is_trash)); + // } + // let repeated_view = filter.first::(conn)?; + let view_table = dsl::view_table + .filter(view_table::id.eq(view_id)) + .first::(conn)?; + + Ok(view_table) + } + + // belong_to_id will be the app_id or view_id. + pub(crate) fn read_views(belong_to_id: &str, conn: &SqliteConnection) -> Result, WorkspaceError> { + let view_tables = dsl::view_table + .filter(view_table::belong_to_id.eq(belong_to_id)) + .order(view_table::create_time.asc()) + .into_boxed() + .load::(conn)?; + + Ok(view_tables) + } + + pub(crate) fn update_view(changeset: ViewTableChangeset, conn: &SqliteConnection) -> Result<(), WorkspaceError> { + diesel_update_table!(view_table, changeset, conn); + Ok(()) + } + + pub(crate) fn delete_view(view_id: &str, conn: &SqliteConnection) -> Result<(), WorkspaceError> { + diesel_delete_table!(view_table, view_id, conn); + Ok(()) + } +} + +// pub(crate) fn read_views( +// belong_to_id: &str, +// is_trash: Option, +// conn: &SqliteConnection, +// ) -> Result { +// let views = dsl::view_table +// .inner_join(trash_table::dsl::trash_table.on(trash_id.ne(view_table:: +// id))) .filter(view_table::belong_to_id.eq(belong_to_id)) +// .select(( +// view_table::id, +// view_table::belong_to_id, +// view_table::name, +// view_table::desc, +// view_table::modified_time, +// view_table::create_time, +// view_table::thumbnail, +// view_table::view_type, +// view_table::version, +// )) +// .load(conn)? +// .into_iter() +// .map( +// |(id, belong_to_id, name, desc, create_time, modified_time, +// thumbnail, view_type, version)| { ViewTable { +// id, +// belong_to_id, +// name, +// desc, +// modified_time, +// create_time, +// thumbnail, +// view_type, +// version, +// is_trash: false, +// } +// .into() +// }, +// ) +// .collect::>(); +// +// Ok(RepeatedView { items: views }) +// } #[derive(PartialEq, Clone, Debug, Queryable, Identifiable, Insertable, Associations)] #[belongs_to(AppTable, foreign_key = "belong_to_id")] diff --git a/frontend/rust-lib/flowy-core/src/services/workspace_controller.rs b/frontend/rust-lib/flowy-core/src/services/workspace/controller.rs similarity index 76% rename from frontend/rust-lib/flowy-core/src/services/workspace_controller.rs rename to frontend/rust-lib/flowy-core/src/services/workspace/controller.rs index bbace11f5b..ec42ddfadd 100644 --- a/frontend/rust-lib/flowy-core/src/services/workspace_controller.rs +++ b/frontend/rust-lib/flowy-core/src/services/workspace/controller.rs @@ -2,24 +2,19 @@ use crate::{ errors::*, module::{WorkspaceDatabase, WorkspaceUser}, notify::*, - services::{read_local_workspace_apps, server::Server, AppController, TrashCan, ViewController}, - sql_tables::workspace::{WorkspaceTable, WorkspaceTableChangeset, WorkspaceTableSql}, + services::{ + read_local_workspace_apps, + server::Server, + workspace::sql::{WorkspaceTable, WorkspaceTableChangeset, WorkspaceTableSql}, + AppController, + TrashController, + ViewController, + }, }; -use chrono::Utc; use flowy_database::SqliteConnection; -use flowy_document_infra::{entities::doc::DocDelta, user_default::initial_read_me}; -use flowy_workspace_infra::{ - entities::{app::RepeatedApp, view::View, workspace::*}, - user_default, -}; -use lazy_static::lazy_static; -use lib_infra::{entities::network_state::NetworkType, kv::KV}; -use parking_lot::RwLock; -use std::{collections::HashMap, sync::Arc}; - -lazy_static! { - static ref INIT_WORKSPACE: RwLock> = RwLock::new(HashMap::new()); -} +use flowy_workspace_infra::entities::{app::RepeatedApp, view::View, workspace::*}; +use lib_infra::kv::KV; +use std::sync::Arc; pub struct WorkspaceController { pub user: Arc, @@ -27,7 +22,7 @@ pub struct WorkspaceController { pub(crate) view_controller: Arc, pub(crate) database: Arc, pub(crate) app_controller: Arc, - pub(crate) trash_can: Arc, + pub(crate) trash_controller: Arc, server: Server, } @@ -37,13 +32,9 @@ impl WorkspaceController { database: Arc, app_controller: Arc, view_controller: Arc, - trash_can: Arc, + trash_can: Arc, server: Server, ) -> Self { - if let Ok(token) = user.token() { - INIT_WORKSPACE.write().insert(token, false); - } - let workspace_sql = Arc::new(WorkspaceTableSql {}); Self { user, @@ -51,92 +42,12 @@ impl WorkspaceController { view_controller, database, app_controller, - trash_can, + trash_controller: trash_can, server, } } - async fn init(&self, token: &str) -> Result<(), WorkspaceError> { - log::debug!("Start initializing workspace"); - if let Some(is_init) = INIT_WORKSPACE.read().get(token) { - if *is_init { - return Ok(()); - } - } - log::debug!("Finish initializing workspace"); - INIT_WORKSPACE.write().insert(token.to_owned(), true); - let _ = self.server.init(); - let _ = self.trash_can.init()?; - let _ = self.view_controller.init()?; - let _ = self.app_controller.init()?; - - Ok(()) - } - - pub fn network_state_changed(&self, new_type: NetworkType) { - match new_type { - NetworkType::UnknownNetworkType => {}, - NetworkType::Wifi => {}, - NetworkType::Cell => {}, - NetworkType::Ethernet => {}, - } - } - - pub async fn user_did_sign_in(&self, token: &str) -> WorkspaceResult<()> { - // TODO: (nathan) do something here - - log::debug!("workspace initialize after sign in"); - let _ = self.init(token).await?; - Ok(()) - } - - pub async fn user_did_logout(&self) { - // TODO: (nathan) do something here - } - - pub async fn user_session_expired(&self) { - // TODO: (nathan) do something here - } - - pub async fn user_did_sign_up(&self, _token: &str) -> WorkspaceResult<()> { - log::debug!("Create user default workspace"); - let time = Utc::now(); - let mut workspace = user_default::create_default_workspace(time); - let apps = workspace.take_apps().into_inner(); - let cloned_workspace = workspace.clone(); - - let _ = self.create_workspace(workspace).await?; - for mut app in apps { - let views = app.take_belongings().into_inner(); - let _ = self.app_controller.create_app(app).await?; - for (index, view) in views.into_iter().enumerate() { - if index == 0 { - let delta = initial_read_me(); - let doc_delta = DocDelta { - doc_id: view.id.clone(), - data: delta.to_json(), - }; - let _ = self.view_controller.apply_doc_delta(doc_delta).await?; - - self.view_controller.set_latest_view(&view); - } - let _ = self.view_controller.create_view(view).await?; - } - } - - let token = self.user.token()?; - let repeated_workspace = RepeatedWorkspace { - items: vec![cloned_workspace], - }; - - send_dart_notification(&token, WorkspaceNotification::UserCreateWorkspace) - .payload(repeated_workspace) - .send(); - - log::debug!("workspace initialize after sign up"); - let _ = self.init(&token).await?; - Ok(()) - } + pub(crate) fn init(&self) -> Result<(), WorkspaceError> { Ok(()) } pub(crate) async fn create_workspace_from_params( &self, @@ -263,7 +174,7 @@ impl WorkspaceController { } #[tracing::instrument(level = "debug", skip(self, conn), err)] - fn read_local_workspaces( + pub(crate) fn read_local_workspaces( &self, workspace_id: Option, user_id: &str, @@ -301,7 +212,7 @@ impl WorkspaceController { #[tracing::instrument(level = "debug", skip(self, conn), err)] fn read_local_apps(&self, workspace_id: &str, conn: &SqliteConnection) -> Result { - let repeated_app = read_local_workspace_apps(workspace_id, self.trash_can.clone(), conn)?; + let repeated_app = read_local_workspace_apps(workspace_id, self.trash_controller.clone(), conn)?; Ok(repeated_app) } } @@ -354,7 +265,11 @@ impl WorkspaceController { } #[tracing::instrument(level = "debug", skip(self), err)] - fn read_workspaces_on_server(&self, user_id: String, params: WorkspaceIdentifier) -> Result<(), WorkspaceError> { + pub(crate) fn read_workspaces_on_server( + &self, + user_id: String, + params: WorkspaceIdentifier, + ) -> Result<(), WorkspaceError> { let (token, server) = self.token_with_server()?; let workspace_sql = self.workspace_sql.clone(); let app_ctrl = self.app_controller.clone(); diff --git a/frontend/rust-lib/flowy-core/src/handlers/workspace_handler.rs b/frontend/rust-lib/flowy-core/src/services/workspace/event_handler.rs similarity index 100% rename from frontend/rust-lib/flowy-core/src/handlers/workspace_handler.rs rename to frontend/rust-lib/flowy-core/src/services/workspace/event_handler.rs diff --git a/frontend/rust-lib/flowy-core/src/services/workspace/mod.rs b/frontend/rust-lib/flowy-core/src/services/workspace/mod.rs new file mode 100644 index 0000000000..8bf3cc04ff --- /dev/null +++ b/frontend/rust-lib/flowy-core/src/services/workspace/mod.rs @@ -0,0 +1,3 @@ +pub mod controller; +pub mod event_handler; +pub(crate) mod sql; diff --git a/frontend/rust-lib/flowy-core/src/sql_tables/workspace/workspace_sql.rs b/frontend/rust-lib/flowy-core/src/services/workspace/sql.rs similarity index 50% rename from frontend/rust-lib/flowy-core/src/sql_tables/workspace/workspace_sql.rs rename to frontend/rust-lib/flowy-core/src/services/workspace/sql.rs index c6956b05d4..27fd14a7ab 100644 --- a/frontend/rust-lib/flowy-core/src/sql_tables/workspace/workspace_sql.rs +++ b/frontend/rust-lib/flowy-core/src/services/workspace/sql.rs @@ -1,15 +1,15 @@ +use crate::{ + entities::{ + app::RepeatedApp, + workspace::{UpdateWorkspaceParams, Workspace}, + }, + errors::WorkspaceError, +}; use diesel::SqliteConnection; - use flowy_database::{ prelude::*, schema::{workspace_table, workspace_table::dsl}, }; - -use crate::{ - errors::WorkspaceError, - sql_tables::workspace::{WorkspaceTable, WorkspaceTableChangeset}, -}; - pub(crate) struct WorkspaceTableSql {} impl WorkspaceTableSql { @@ -64,3 +64,69 @@ impl WorkspaceTableSql { Ok(()) } } + +#[derive(PartialEq, Clone, Debug, Queryable, Identifiable, Insertable)] +#[table_name = "workspace_table"] +pub struct WorkspaceTable { + pub id: String, + pub name: String, + pub desc: String, + pub modified_time: i64, + pub create_time: i64, + pub user_id: String, + pub version: i64, +} + +impl WorkspaceTable { + #[allow(dead_code)] + pub fn new(workspace: Workspace, user_id: &str) -> Self { + WorkspaceTable { + id: workspace.id, + name: workspace.name, + desc: workspace.desc, + modified_time: workspace.modified_time, + create_time: workspace.create_time, + user_id: user_id.to_owned(), + version: 0, + } + } +} + +impl std::convert::From for Workspace { + fn from(table: WorkspaceTable) -> Self { + Workspace { + id: table.id, + name: table.name, + desc: table.desc, + apps: RepeatedApp::default(), + modified_time: table.modified_time, + create_time: table.create_time, + } + } +} + +#[derive(AsChangeset, Identifiable, Clone, Default, Debug)] +#[table_name = "workspace_table"] +pub struct WorkspaceTableChangeset { + pub id: String, + pub name: Option, + pub desc: Option, +} + +impl WorkspaceTableChangeset { + pub fn new(params: UpdateWorkspaceParams) -> Self { + WorkspaceTableChangeset { + id: params.id, + name: params.name, + desc: params.desc, + } + } + + pub(crate) fn from_table(table: WorkspaceTable) -> Self { + WorkspaceTableChangeset { + id: table.id, + name: Some(table.name), + desc: Some(table.desc), + } + } +} diff --git a/frontend/rust-lib/flowy-core/src/sql_tables/app/app_sql.rs b/frontend/rust-lib/flowy-core/src/sql_tables/app/app_sql.rs deleted file mode 100644 index 8ce92f0662..0000000000 --- a/frontend/rust-lib/flowy-core/src/sql_tables/app/app_sql.rs +++ /dev/null @@ -1,76 +0,0 @@ -use flowy_database::{ - prelude::*, - schema::{app_table, app_table::dsl}, - SqliteConnection, -}; - -use crate::{ - errors::WorkspaceError, - sql_tables::app::{AppTable, AppTableChangeset}, -}; - -pub struct AppTableSql {} - -impl AppTableSql { - pub(crate) fn create_app(app_table: AppTable, conn: &SqliteConnection) -> Result<(), WorkspaceError> { - match diesel_record_count!(app_table, &app_table.id, conn) { - 0 => diesel_insert_table!(app_table, &app_table, conn), - _ => { - let changeset = AppTableChangeset::from_table(app_table); - diesel_update_table!(app_table, changeset, conn) - }, - } - Ok(()) - } - - pub(crate) fn update_app(changeset: AppTableChangeset, conn: &SqliteConnection) -> Result<(), WorkspaceError> { - diesel_update_table!(app_table, changeset, conn); - Ok(()) - } - - pub(crate) fn read_app(app_id: &str, conn: &SqliteConnection) -> Result { - let filter = dsl::app_table.filter(app_table::id.eq(app_id)).into_boxed(); - let app_table = filter.first::(conn)?; - Ok(app_table) - } - - pub(crate) fn read_workspace_apps( - workspace_id: &str, - is_trash: bool, - conn: &SqliteConnection, - ) -> Result, WorkspaceError> { - let app_table = dsl::app_table - .filter(app_table::workspace_id.eq(workspace_id)) - .filter(app_table::is_trash.eq(is_trash)) - .order(app_table::create_time.asc()) - .load::(conn)?; - - Ok(app_table) - } - - pub(crate) fn delete_app(app_id: &str, conn: &SqliteConnection) -> Result { - let app_table = dsl::app_table - .filter(app_table::id.eq(app_id)) - .first::(conn)?; - diesel_delete_table!(app_table, app_id, conn); - Ok(app_table) - } - - // pub(crate) fn read_views_belong_to_app( - // &self, - // app_id: &str, - // ) -> Result, WorkspaceError> { - // let conn = self.database.db_connection()?; - // - // let views = conn.immediate_transaction::<_, WorkspaceError, _>(|| { - // let app_table: AppTable = dsl::app_table - // .filter(app_table::id.eq(app_id)) - // .first::(&*(conn))?; - // let views = - // ViewTable::belonging_to(&app_table).load::(&*conn)?; - // Ok(views) - // })?; - // - // Ok(views) - // } -} diff --git a/frontend/rust-lib/flowy-core/src/sql_tables/app/mod.rs b/frontend/rust-lib/flowy-core/src/sql_tables/app/mod.rs deleted file mode 100644 index 4e2792e3d1..0000000000 --- a/frontend/rust-lib/flowy-core/src/sql_tables/app/mod.rs +++ /dev/null @@ -1,5 +0,0 @@ -mod app_sql; -mod app_table; - -pub(crate) use app_sql::*; -pub(crate) use app_table::*; diff --git a/frontend/rust-lib/flowy-core/src/sql_tables/mod.rs b/frontend/rust-lib/flowy-core/src/sql_tables/mod.rs deleted file mode 100644 index 3ee0f4b591..0000000000 --- a/frontend/rust-lib/flowy-core/src/sql_tables/mod.rs +++ /dev/null @@ -1,4 +0,0 @@ -pub mod app; -pub mod trash; -pub mod view; -pub mod workspace; diff --git a/frontend/rust-lib/flowy-core/src/sql_tables/trash/mod.rs b/frontend/rust-lib/flowy-core/src/sql_tables/trash/mod.rs deleted file mode 100644 index c8af3d5dc0..0000000000 --- a/frontend/rust-lib/flowy-core/src/sql_tables/trash/mod.rs +++ /dev/null @@ -1,5 +0,0 @@ -mod trash_sql; -mod trash_table; - -pub(crate) use trash_sql::*; -pub(crate) use trash_table::*; diff --git a/frontend/rust-lib/flowy-core/src/sql_tables/trash/trash_sql.rs b/frontend/rust-lib/flowy-core/src/sql_tables/trash/trash_sql.rs deleted file mode 100644 index 2b489e7be7..0000000000 --- a/frontend/rust-lib/flowy-core/src/sql_tables/trash/trash_sql.rs +++ /dev/null @@ -1,53 +0,0 @@ -use flowy_database::{ - prelude::*, - schema::{trash_table, trash_table::dsl}, - SqliteConnection, -}; - -use crate::{ - entities::trash::{RepeatedTrash, Trash}, - errors::WorkspaceError, - sql_tables::trash::{TrashTable, TrashTableChangeset}, -}; - -pub struct TrashTableSql {} - -impl TrashTableSql { - pub(crate) fn create_trash(repeated_trash: Vec, conn: &SqliteConnection) -> Result<(), WorkspaceError> { - for trash in repeated_trash { - let trash_table: TrashTable = trash.into(); - match diesel_record_count!(trash_table, &trash_table.id, conn) { - 0 => diesel_insert_table!(trash_table, &trash_table, conn), - _ => { - let changeset = TrashTableChangeset::from(trash_table); - diesel_update_table!(trash_table, changeset, conn) - }, - } - } - - Ok(()) - } - - pub(crate) fn read_all(conn: &SqliteConnection) -> Result { - let trash_tables = dsl::trash_table.load::(conn)?; - let items = trash_tables.into_iter().map(|t| t.into()).collect::>(); - Ok(RepeatedTrash { items }) - } - - pub(crate) fn delete_all(conn: &SqliteConnection) -> Result<(), WorkspaceError> { - let _ = diesel::delete(dsl::trash_table).execute(conn)?; - Ok(()) - } - - pub(crate) fn read(trash_id: &str, conn: &SqliteConnection) -> Result { - let trash_table = dsl::trash_table - .filter(trash_table::id.eq(trash_id)) - .first::(conn)?; - Ok(trash_table) - } - - pub(crate) fn delete_trash(trash_id: &str, conn: &SqliteConnection) -> Result<(), WorkspaceError> { - diesel_delete_table!(trash_table, trash_id, conn); - Ok(()) - } -} diff --git a/frontend/rust-lib/flowy-core/src/sql_tables/view/mod.rs b/frontend/rust-lib/flowy-core/src/sql_tables/view/mod.rs deleted file mode 100644 index b2730abed2..0000000000 --- a/frontend/rust-lib/flowy-core/src/sql_tables/view/mod.rs +++ /dev/null @@ -1,5 +0,0 @@ -mod view_sql; -mod view_table; - -pub use view_sql::*; -pub use view_table::*; diff --git a/frontend/rust-lib/flowy-core/src/sql_tables/view/view_sql.rs b/frontend/rust-lib/flowy-core/src/sql_tables/view/view_sql.rs deleted file mode 100644 index c9ef903111..0000000000 --- a/frontend/rust-lib/flowy-core/src/sql_tables/view/view_sql.rs +++ /dev/null @@ -1,104 +0,0 @@ -use flowy_database::{ - prelude::*, - schema::{view_table, view_table::dsl}, - SqliteConnection, -}; - -use crate::{ - errors::WorkspaceError, - sql_tables::view::{ViewTable, ViewTableChangeset}, -}; - -pub struct ViewTableSql {} - -impl ViewTableSql { - pub(crate) fn create_view(view_table: ViewTable, conn: &SqliteConnection) -> Result<(), WorkspaceError> { - match diesel_record_count!(view_table, &view_table.id, conn) { - 0 => diesel_insert_table!(view_table, &view_table, conn), - _ => { - let changeset = ViewTableChangeset::from_table(view_table); - diesel_update_table!(view_table, changeset, conn) - }, - } - Ok(()) - } - - pub(crate) fn read_view(view_id: &str, conn: &SqliteConnection) -> Result { - // https://docs.diesel.rs/diesel/query_builder/struct.UpdateStatement.html - // let mut filter = - // dsl::view_table.filter(view_table::id.eq(view_id)).into_boxed(); - // if let Some(is_trash) = is_trash { - // filter = filter.filter(view_table::is_trash.eq(is_trash)); - // } - // let repeated_view = filter.first::(conn)?; - let view_table = dsl::view_table - .filter(view_table::id.eq(view_id)) - .first::(conn)?; - - Ok(view_table) - } - - // belong_to_id will be the app_id or view_id. - pub(crate) fn read_views(belong_to_id: &str, conn: &SqliteConnection) -> Result, WorkspaceError> { - let view_tables = dsl::view_table - .filter(view_table::belong_to_id.eq(belong_to_id)) - .order(view_table::create_time.asc()) - .into_boxed() - .load::(conn)?; - - Ok(view_tables) - } - - pub(crate) fn update_view(changeset: ViewTableChangeset, conn: &SqliteConnection) -> Result<(), WorkspaceError> { - diesel_update_table!(view_table, changeset, conn); - Ok(()) - } - - pub(crate) fn delete_view(view_id: &str, conn: &SqliteConnection) -> Result<(), WorkspaceError> { - diesel_delete_table!(view_table, view_id, conn); - Ok(()) - } -} - -// pub(crate) fn read_views( -// belong_to_id: &str, -// is_trash: Option, -// conn: &SqliteConnection, -// ) -> Result { -// let views = dsl::view_table -// .inner_join(trash_table::dsl::trash_table.on(trash_id.ne(view_table:: -// id))) .filter(view_table::belong_to_id.eq(belong_to_id)) -// .select(( -// view_table::id, -// view_table::belong_to_id, -// view_table::name, -// view_table::desc, -// view_table::modified_time, -// view_table::create_time, -// view_table::thumbnail, -// view_table::view_type, -// view_table::version, -// )) -// .load(conn)? -// .into_iter() -// .map( -// |(id, belong_to_id, name, desc, create_time, modified_time, -// thumbnail, view_type, version)| { ViewTable { -// id, -// belong_to_id, -// name, -// desc, -// modified_time, -// create_time, -// thumbnail, -// view_type, -// version, -// is_trash: false, -// } -// .into() -// }, -// ) -// .collect::>(); -// -// Ok(RepeatedView { items: views }) -// } diff --git a/frontend/rust-lib/flowy-core/src/sql_tables/workspace/mod.rs b/frontend/rust-lib/flowy-core/src/sql_tables/workspace/mod.rs deleted file mode 100644 index e9461c942f..0000000000 --- a/frontend/rust-lib/flowy-core/src/sql_tables/workspace/mod.rs +++ /dev/null @@ -1,5 +0,0 @@ -mod workspace_sql; -mod workspace_table; - -pub(crate) use workspace_sql::*; -pub(crate) use workspace_table::*; diff --git a/frontend/rust-lib/flowy-core/src/sql_tables/workspace/workspace_table.rs b/frontend/rust-lib/flowy-core/src/sql_tables/workspace/workspace_table.rs deleted file mode 100644 index 02816ada2b..0000000000 --- a/frontend/rust-lib/flowy-core/src/sql_tables/workspace/workspace_table.rs +++ /dev/null @@ -1,71 +0,0 @@ -use crate::entities::{ - app::RepeatedApp, - workspace::{UpdateWorkspaceParams, Workspace}, -}; -use flowy_database::schema::workspace_table; - -#[derive(PartialEq, Clone, Debug, Queryable, Identifiable, Insertable)] -#[table_name = "workspace_table"] -pub struct WorkspaceTable { - pub id: String, - pub name: String, - pub desc: String, - pub modified_time: i64, - pub create_time: i64, - pub user_id: String, - pub version: i64, -} - -impl WorkspaceTable { - #[allow(dead_code)] - pub fn new(workspace: Workspace, user_id: &str) -> Self { - WorkspaceTable { - id: workspace.id, - name: workspace.name, - desc: workspace.desc, - modified_time: workspace.modified_time, - create_time: workspace.create_time, - user_id: user_id.to_owned(), - version: 0, - } - } -} - -impl std::convert::From for Workspace { - fn from(table: WorkspaceTable) -> Self { - Workspace { - id: table.id, - name: table.name, - desc: table.desc, - apps: RepeatedApp::default(), - modified_time: table.modified_time, - create_time: table.create_time, - } - } -} - -#[derive(AsChangeset, Identifiable, Clone, Default, Debug)] -#[table_name = "workspace_table"] -pub struct WorkspaceTableChangeset { - pub id: String, - pub name: Option, - pub desc: Option, -} - -impl WorkspaceTableChangeset { - pub fn new(params: UpdateWorkspaceParams) -> Self { - WorkspaceTableChangeset { - id: params.id, - name: params.name, - desc: params.desc, - } - } - - pub(crate) fn from_table(table: WorkspaceTable) -> Self { - WorkspaceTableChangeset { - id: table.id, - name: Some(table.name), - desc: Some(table.desc), - } - } -} diff --git a/frontend/rust-lib/flowy-sdk/src/lib.rs b/frontend/rust-lib/flowy-sdk/src/lib.rs index fc8aa73fca..2eaa4782f3 100644 --- a/frontend/rust-lib/flowy-sdk/src/lib.rs +++ b/frontend/rust-lib/flowy-sdk/src/lib.rs @@ -3,7 +3,7 @@ mod deps_resolve; pub mod module; use crate::deps_resolve::WorkspaceDepsResolver; use backend_service::configuration::ClientServerConfiguration; -use flowy_core::{errors::WorkspaceError, prelude::WorkspaceController}; +use flowy_core::{errors::WorkspaceError, module::init_core, prelude::FlowyCore}; use flowy_document::module::FlowyDocument; use flowy_user::{ prelude::UserStatus, @@ -66,7 +66,7 @@ pub struct FlowySDK { config: FlowySDKConfig, pub user_session: Arc, pub flowy_document: Arc, - pub workspace_ctrl: Arc, + pub core: Arc, pub dispatcher: Arc, } @@ -81,17 +81,17 @@ impl FlowySDK { let user_config = UserSessionConfig::new(&config.root, &config.server_config, &session_cache_key); let user_session = Arc::new(UserSession::new(user_config)); let flowy_document = mk_document_module(user_session.clone(), &config.server_config); - let workspace_ctrl = - mk_workspace_controller(user_session.clone(), flowy_document.clone(), &config.server_config); - let modules = mk_modules(workspace_ctrl.clone(), user_session.clone()); + let core = mk_core(user_session.clone(), flowy_document.clone(), &config.server_config); + + let modules = mk_modules(core.clone(), user_session.clone()); let dispatcher = Arc::new(EventDispatcher::construct(|| modules)); - _init(&dispatcher, user_session.clone(), workspace_ctrl.clone()); + _init(&dispatcher, user_session.clone(), core.clone()); Self { config, user_session, flowy_document, - workspace_ctrl, + core, dispatcher, } } @@ -99,38 +99,35 @@ impl FlowySDK { pub fn dispatcher(&self) -> Arc { self.dispatcher.clone() } } -fn _init(dispatch: &EventDispatcher, user_session: Arc, workspace_controller: Arc) { +fn _init(dispatch: &EventDispatcher, user_session: Arc, core: Arc) { let user_status_subscribe = user_session.notifier.user_status_subscribe(); let network_status_subscribe = user_session.notifier.network_type_subscribe(); - let cloned_workspace_controller = workspace_controller.clone(); + let cloned_core = core.clone(); dispatch.spawn(async move { user_session.init(); - _listen_user_status(user_status_subscribe, workspace_controller.clone()).await; + _listen_user_status(user_status_subscribe, core.clone()).await; }); dispatch.spawn(async move { - _listen_network_status(network_status_subscribe, cloned_workspace_controller).await; + _listen_network_status(network_status_subscribe, cloned_core).await; }); } -async fn _listen_user_status( - mut subscribe: broadcast::Receiver, - workspace_controller: Arc, -) { +async fn _listen_user_status(mut subscribe: broadcast::Receiver, core: Arc) { while let Ok(status) = subscribe.recv().await { let result = || async { match status { UserStatus::Login { token } => { - let _ = workspace_controller.user_did_sign_in(&token).await?; + let _ = core.user_did_sign_in(&token).await?; }, UserStatus::Logout { .. } => { - workspace_controller.user_did_logout().await; + core.user_did_logout().await; }, UserStatus::Expired { .. } => { - workspace_controller.user_session_expired().await; + core.user_session_expired().await; }, UserStatus::SignUp { profile, ret } => { - let _ = workspace_controller.user_did_sign_up(&profile.token).await?; + let _ = core.user_did_sign_up(&profile.token).await?; let _ = ret.send(()); }, } @@ -144,12 +141,9 @@ async fn _listen_user_status( } } -async fn _listen_network_status( - mut subscribe: broadcast::Receiver, - workspace_controller: Arc, -) { +async fn _listen_network_status(mut subscribe: broadcast::Receiver, core: Arc) { while let Ok(new_type) = subscribe.recv().await { - workspace_controller.network_state_changed(new_type); + core.network_state_changed(new_type); } } @@ -170,12 +164,12 @@ fn init_log(config: &FlowySDKConfig) { } } -fn mk_workspace_controller( +fn mk_core( user_session: Arc, flowy_document: Arc, server_config: &ClientServerConfiguration, -) -> Arc { +) -> Arc { let workspace_deps = WorkspaceDepsResolver::new(user_session); let (user, database) = workspace_deps.split_into(); - flowy_core::module::init_workspace_controller(user, database, flowy_document, server_config) + init_core(user, database, flowy_document, server_config) } diff --git a/frontend/rust-lib/flowy-sdk/src/module.rs b/frontend/rust-lib/flowy-sdk/src/module.rs index 61caf42922..ac410b91cf 100644 --- a/frontend/rust-lib/flowy-sdk/src/module.rs +++ b/frontend/rust-lib/flowy-sdk/src/module.rs @@ -1,22 +1,19 @@ use crate::deps_resolve::DocumentDepsResolver; use backend_service::configuration::ClientServerConfiguration; -use flowy_core::prelude::WorkspaceController; +use flowy_core::prelude::FlowyCore; use flowy_document::module::FlowyDocument; use flowy_user::services::user::UserSession; use lib_dispatch::prelude::Module; use std::sync::Arc; -pub fn mk_modules(workspace_controller: Arc, user_session: Arc) -> Vec { +pub fn mk_modules(core: Arc, user_session: Arc) -> Vec { let user_module = mk_user_module(user_session); - let workspace_module = mk_workspace_module(workspace_controller); + let workspace_module = mk_core_module(core); vec![user_module, workspace_module] } fn mk_user_module(user_session: Arc) -> Module { flowy_user::module::create(user_session) } - -fn mk_workspace_module(workspace_controller: Arc) -> Module { - flowy_core::module::create(workspace_controller) -} +fn mk_core_module(core: Arc) -> Module { flowy_core::module::create(core) } pub fn mk_document_module( user_session: Arc,