refactor flowy-core pb

This commit is contained in:
appflowy
2022-01-13 11:16:26 +08:00
parent 718613de42
commit dac86ef857
190 changed files with 11262 additions and 12183 deletions

View File

@ -1,3 +1,3 @@
proto_crates = ["src/entities", "src/event.rs", "src/notify"]
proto_crates = ["src/entities", "src/event.rs", "src/dart_notification.rs"]
event_files = ["src/event.rs"]

View File

@ -6,10 +6,10 @@ use parking_lot::RwLock;
use std::{collections::HashMap, sync::Arc};
use crate::{
dart_notification::{send_dart_notification, WorkspaceNotification},
entities::workspace::RepeatedWorkspace,
errors::{FlowyError, FlowyResult},
module::{WorkspaceCloudService, WorkspaceDatabase, WorkspaceUser},
notify::{send_dart_notification, WorkspaceNotification},
services::{AppController, TrashController, ViewController, WorkspaceController},
};

View File

@ -2,8 +2,6 @@ use dart_notify::DartNotifyBuilder;
use flowy_derive::ProtoBuf_Enum;
const OBSERVABLE_CATEGORY: &str = "Workspace";
// Opti: Using the Rust macro to generate the serde code automatically that can
// be use directly in flutter
#[derive(ProtoBuf_Enum, Debug)]
pub(crate) enum WorkspaceNotification {
Unknown = 0,

View File

@ -1,112 +0,0 @@
use crate::{
context::CoreContext,
errors::FlowyError,
notify::{send_dart_notification, WorkspaceNotification},
services::{
get_current_workspace,
read_local_workspace_apps,
workspace::sql::{WorkspaceTable, WorkspaceTableSql},
},
};
use flowy_core_data_model::entities::{
view::View,
workspace::{CurrentWorkspaceSetting, QueryWorkspaceRequest, RepeatedWorkspace, WorkspaceId},
};
use lib_dispatch::prelude::{data_result, Data, DataResult, Unit};
use std::{convert::TryInto, sync::Arc};
#[tracing::instrument(skip(data, core), err)]
pub(crate) async fn read_workspaces_handler(
data: Data<QueryWorkspaceRequest>,
core: Unit<Arc<CoreContext>>,
) -> DataResult<RepeatedWorkspace, FlowyError> {
let params: WorkspaceId = data.into_inner().try_into()?;
let user_id = core.user.user_id()?;
let conn = &*core.database.db_connection()?;
let workspace_controller = core.workspace_controller.clone();
let trash_controller = core.trash_controller.clone();
let workspaces = conn.immediate_transaction::<_, FlowyError, _>(|| {
let mut workspaces = workspace_controller.read_local_workspaces(params.workspace_id.clone(), &user_id, conn)?;
for workspace in workspaces.iter_mut() {
let apps = read_local_workspace_apps(&workspace.id, trash_controller.clone(), conn)?.into_inner();
workspace.apps.items = apps;
}
Ok(workspaces)
})?;
let _ = read_workspaces_on_server(core, user_id, params);
data_result(workspaces)
}
#[tracing::instrument(skip(core), err)]
pub async fn read_cur_workspace_handler(
core: Unit<Arc<CoreContext>>,
) -> DataResult<CurrentWorkspaceSetting, FlowyError> {
let workspace_id = get_current_workspace()?;
let user_id = core.user.user_id()?;
let params = WorkspaceId {
workspace_id: Some(workspace_id.clone()),
};
let conn = &*core.database.db_connection()?;
let workspace = core
.workspace_controller
.read_local_workspace(workspace_id, &user_id, conn)?;
let latest_view: Option<View> = core.view_controller.latest_visit_view().unwrap_or(None);
let setting = CurrentWorkspaceSetting { workspace, latest_view };
let _ = read_workspaces_on_server(core, user_id, params);
data_result(setting)
}
#[tracing::instrument(level = "debug", skip(core), err)]
fn read_workspaces_on_server(
core: Unit<Arc<CoreContext>>,
user_id: String,
params: WorkspaceId,
) -> Result<(), FlowyError> {
let (token, server) = (core.user.token()?, core.cloud_service.clone());
let app_ctrl = core.app_controller.clone();
let view_ctrl = core.view_controller.clone();
let conn = core.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::<_, FlowyError, _>(|| {
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 _ = WorkspaceTableSql::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::<(), FlowyError>::Ok(())
});
Ok(())
}

View File

@ -11,8 +11,7 @@ mod macros;
extern crate flowy_database;
pub mod context;
pub mod event_handler;
mod notify;
mod dart_notification;
pub mod protobuf;
mod util;

View File

@ -8,7 +8,6 @@ use crate::{
},
errors::FlowyError,
event::WorkspaceEvent,
event_handler::*,
services::{
app::event_handler::*,
trash::event_handler::*,

View File

@ -1,3 +0,0 @@
pub(crate) mod observable;
pub(crate) use observable::*;

View File

@ -17,7 +17,7 @@
#![allow(trivial_casts)]
#![allow(unused_imports)]
#![allow(unused_results)]
//! Generated file from `observable.proto`
//! Generated file from `dart_notification.proto`
/// Generated files are compatible only with the same version
/// of protobuf runtime.
@ -107,42 +107,43 @@ impl ::protobuf::reflect::ProtobufValue for WorkspaceNotification {
}
static file_descriptor_proto_data: &'static [u8] = b"\
\n\x10observable.proto*\xa2\x02\n\x15WorkspaceNotification\x12\x0b\n\x07\
Unknown\x10\0\x12\x17\n\x13UserCreateWorkspace\x10\n\x12\x17\n\x13UserDe\
leteWorkspace\x10\x0b\x12\x14\n\x10WorkspaceUpdated\x10\x0c\x12\x18\n\
\x14WorkspaceListUpdated\x10\r\x12\x18\n\x14WorkspaceAppsChanged\x10\x0e\
\x12\x0e\n\nAppUpdated\x10\x15\x12\x13\n\x0fAppViewsChanged\x10\x18\x12\
\x0f\n\x0bViewUpdated\x10\x1f\x12\x0f\n\x0bViewDeleted\x10\x20\x12\x10\n\
\x0cViewRestored\x10!\x12\x14\n\x10UserUnauthorized\x10d\x12\x11\n\x0cTr\
ashUpdated\x10\xe8\x07J\xbf\x04\n\x06\x12\x04\0\0\x10\x01\n\x08\n\x01\
\x0c\x12\x03\0\0\x12\n\n\n\x02\x05\0\x12\x04\x02\0\x10\x01\n\n\n\x03\x05\
\0\x01\x12\x03\x02\x05\x1a\n\x0b\n\x04\x05\0\x02\0\x12\x03\x03\x04\x10\n\
\x0c\n\x05\x05\0\x02\0\x01\x12\x03\x03\x04\x0b\n\x0c\n\x05\x05\0\x02\0\
\x02\x12\x03\x03\x0e\x0f\n\x0b\n\x04\x05\0\x02\x01\x12\x03\x04\x04\x1d\n\
\x0c\n\x05\x05\0\x02\x01\x01\x12\x03\x04\x04\x17\n\x0c\n\x05\x05\0\x02\
\x01\x02\x12\x03\x04\x1a\x1c\n\x0b\n\x04\x05\0\x02\x02\x12\x03\x05\x04\
\x1d\n\x0c\n\x05\x05\0\x02\x02\x01\x12\x03\x05\x04\x17\n\x0c\n\x05\x05\0\
\x02\x02\x02\x12\x03\x05\x1a\x1c\n\x0b\n\x04\x05\0\x02\x03\x12\x03\x06\
\x04\x1a\n\x0c\n\x05\x05\0\x02\x03\x01\x12\x03\x06\x04\x14\n\x0c\n\x05\
\x05\0\x02\x03\x02\x12\x03\x06\x17\x19\n\x0b\n\x04\x05\0\x02\x04\x12\x03\
\x07\x04\x1e\n\x0c\n\x05\x05\0\x02\x04\x01\x12\x03\x07\x04\x18\n\x0c\n\
\x05\x05\0\x02\x04\x02\x12\x03\x07\x1b\x1d\n\x0b\n\x04\x05\0\x02\x05\x12\
\x03\x08\x04\x1e\n\x0c\n\x05\x05\0\x02\x05\x01\x12\x03\x08\x04\x18\n\x0c\
\n\x05\x05\0\x02\x05\x02\x12\x03\x08\x1b\x1d\n\x0b\n\x04\x05\0\x02\x06\
\x12\x03\t\x04\x14\n\x0c\n\x05\x05\0\x02\x06\x01\x12\x03\t\x04\x0e\n\x0c\
\n\x05\x05\0\x02\x06\x02\x12\x03\t\x11\x13\n\x0b\n\x04\x05\0\x02\x07\x12\
\x03\n\x04\x19\n\x0c\n\x05\x05\0\x02\x07\x01\x12\x03\n\x04\x13\n\x0c\n\
\x05\x05\0\x02\x07\x02\x12\x03\n\x16\x18\n\x0b\n\x04\x05\0\x02\x08\x12\
\x03\x0b\x04\x15\n\x0c\n\x05\x05\0\x02\x08\x01\x12\x03\x0b\x04\x0f\n\x0c\
\n\x05\x05\0\x02\x08\x02\x12\x03\x0b\x12\x14\n\x0b\n\x04\x05\0\x02\t\x12\
\x03\x0c\x04\x15\n\x0c\n\x05\x05\0\x02\t\x01\x12\x03\x0c\x04\x0f\n\x0c\n\
\x05\x05\0\x02\t\x02\x12\x03\x0c\x12\x14\n\x0b\n\x04\x05\0\x02\n\x12\x03\
\r\x04\x16\n\x0c\n\x05\x05\0\x02\n\x01\x12\x03\r\x04\x10\n\x0c\n\x05\x05\
\0\x02\n\x02\x12\x03\r\x13\x15\n\x0b\n\x04\x05\0\x02\x0b\x12\x03\x0e\x04\
\x1b\n\x0c\n\x05\x05\0\x02\x0b\x01\x12\x03\x0e\x04\x14\n\x0c\n\x05\x05\0\
\x02\x0b\x02\x12\x03\x0e\x17\x1a\n\x0b\n\x04\x05\0\x02\x0c\x12\x03\x0f\
\x04\x18\n\x0c\n\x05\x05\0\x02\x0c\x01\x12\x03\x0f\x04\x10\n\x0c\n\x05\
\x05\0\x02\x0c\x02\x12\x03\x0f\x13\x17b\x06proto3\
\n\x17dart_notification.proto*\xa2\x02\n\x15WorkspaceNotification\x12\
\x0b\n\x07Unknown\x10\0\x12\x17\n\x13UserCreateWorkspace\x10\n\x12\x17\n\
\x13UserDeleteWorkspace\x10\x0b\x12\x14\n\x10WorkspaceUpdated\x10\x0c\
\x12\x18\n\x14WorkspaceListUpdated\x10\r\x12\x18\n\x14WorkspaceAppsChang\
ed\x10\x0e\x12\x0e\n\nAppUpdated\x10\x15\x12\x13\n\x0fAppViewsChanged\
\x10\x18\x12\x0f\n\x0bViewUpdated\x10\x1f\x12\x0f\n\x0bViewDeleted\x10\
\x20\x12\x10\n\x0cViewRestored\x10!\x12\x14\n\x10UserUnauthorized\x10d\
\x12\x11\n\x0cTrashUpdated\x10\xe8\x07J\xbf\x04\n\x06\x12\x04\0\0\x10\
\x01\n\x08\n\x01\x0c\x12\x03\0\0\x12\n\n\n\x02\x05\0\x12\x04\x02\0\x10\
\x01\n\n\n\x03\x05\0\x01\x12\x03\x02\x05\x1a\n\x0b\n\x04\x05\0\x02\0\x12\
\x03\x03\x04\x10\n\x0c\n\x05\x05\0\x02\0\x01\x12\x03\x03\x04\x0b\n\x0c\n\
\x05\x05\0\x02\0\x02\x12\x03\x03\x0e\x0f\n\x0b\n\x04\x05\0\x02\x01\x12\
\x03\x04\x04\x1d\n\x0c\n\x05\x05\0\x02\x01\x01\x12\x03\x04\x04\x17\n\x0c\
\n\x05\x05\0\x02\x01\x02\x12\x03\x04\x1a\x1c\n\x0b\n\x04\x05\0\x02\x02\
\x12\x03\x05\x04\x1d\n\x0c\n\x05\x05\0\x02\x02\x01\x12\x03\x05\x04\x17\n\
\x0c\n\x05\x05\0\x02\x02\x02\x12\x03\x05\x1a\x1c\n\x0b\n\x04\x05\0\x02\
\x03\x12\x03\x06\x04\x1a\n\x0c\n\x05\x05\0\x02\x03\x01\x12\x03\x06\x04\
\x14\n\x0c\n\x05\x05\0\x02\x03\x02\x12\x03\x06\x17\x19\n\x0b\n\x04\x05\0\
\x02\x04\x12\x03\x07\x04\x1e\n\x0c\n\x05\x05\0\x02\x04\x01\x12\x03\x07\
\x04\x18\n\x0c\n\x05\x05\0\x02\x04\x02\x12\x03\x07\x1b\x1d\n\x0b\n\x04\
\x05\0\x02\x05\x12\x03\x08\x04\x1e\n\x0c\n\x05\x05\0\x02\x05\x01\x12\x03\
\x08\x04\x18\n\x0c\n\x05\x05\0\x02\x05\x02\x12\x03\x08\x1b\x1d\n\x0b\n\
\x04\x05\0\x02\x06\x12\x03\t\x04\x14\n\x0c\n\x05\x05\0\x02\x06\x01\x12\
\x03\t\x04\x0e\n\x0c\n\x05\x05\0\x02\x06\x02\x12\x03\t\x11\x13\n\x0b\n\
\x04\x05\0\x02\x07\x12\x03\n\x04\x19\n\x0c\n\x05\x05\0\x02\x07\x01\x12\
\x03\n\x04\x13\n\x0c\n\x05\x05\0\x02\x07\x02\x12\x03\n\x16\x18\n\x0b\n\
\x04\x05\0\x02\x08\x12\x03\x0b\x04\x15\n\x0c\n\x05\x05\0\x02\x08\x01\x12\
\x03\x0b\x04\x0f\n\x0c\n\x05\x05\0\x02\x08\x02\x12\x03\x0b\x12\x14\n\x0b\
\n\x04\x05\0\x02\t\x12\x03\x0c\x04\x15\n\x0c\n\x05\x05\0\x02\t\x01\x12\
\x03\x0c\x04\x0f\n\x0c\n\x05\x05\0\x02\t\x02\x12\x03\x0c\x12\x14\n\x0b\n\
\x04\x05\0\x02\n\x12\x03\r\x04\x16\n\x0c\n\x05\x05\0\x02\n\x01\x12\x03\r\
\x04\x10\n\x0c\n\x05\x05\0\x02\n\x02\x12\x03\r\x13\x15\n\x0b\n\x04\x05\0\
\x02\x0b\x12\x03\x0e\x04\x1b\n\x0c\n\x05\x05\0\x02\x0b\x01\x12\x03\x0e\
\x04\x14\n\x0c\n\x05\x05\0\x02\x0b\x02\x12\x03\x0e\x17\x1a\n\x0b\n\x04\
\x05\0\x02\x0c\x12\x03\x0f\x04\x18\n\x0c\n\x05\x05\0\x02\x0c\x01\x12\x03\
\x0f\x04\x10\n\x0c\n\x05\x05\0\x02\x0c\x02\x12\x03\x0f\x13\x17b\x06proto\
3\
";
static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;

View File

@ -1,8 +1,8 @@
#![cfg_attr(rustfmt, rustfmt::skip)]
// Auto-generated, do not edit
mod observable;
pub use observable::*;
mod dart_notification;
pub use dart_notification::*;
mod event;
pub use event::*;

View File

@ -1,13 +1,13 @@
use crate::{
dart_notification::*,
entities::{
app::{App, CreateAppParams, *},
trash::TrashType,
},
errors::*,
module::{WorkspaceCloudService, WorkspaceDatabase, WorkspaceUser},
notify::*,
services::{
app::sql::{AppTable, AppTableChangeset, AppTableSql},
app::sql::{AppChangeset, AppTable, AppTableSql},
TrashController,
TrashEvent,
},
@ -61,8 +61,7 @@ impl AppController {
}
pub(crate) fn save_app(&self, app: App, conn: &SqliteConnection) -> Result<(), FlowyError> {
let app_table = AppTable::new(app);
let _ = AppTableSql::create_app(app_table, &*conn)?;
let _ = AppTableSql::create_app(app, &*conn)?;
Ok(())
}
@ -80,7 +79,7 @@ impl AppController {
}
pub(crate) async fn update_app(&self, params: UpdateAppParams) -> Result<(), FlowyError> {
let changeset = AppTableChangeset::new(params.clone());
let changeset = AppChangeset::new(params.clone());
let app_id = changeset.id.clone();
let conn = &*self.database.db_connection()?;
conn.immediate_transaction::<_, FlowyError, _>(|| {
@ -144,8 +143,7 @@ impl AppController {
match server.read_app(&token, params).await {
Ok(Some(app)) => match pool.get() {
Ok(conn) => {
let app_table = AppTable::new(app.clone());
let result = AppTableSql::create_app(app_table, &*conn);
let result = AppTableSql::create_app(app.clone(), &*conn);
match result {
Ok(_) => {
send_dart_notification(&app.id, WorkspaceNotification::AppUpdated)

View File

@ -20,18 +20,19 @@ use crate::errors::FlowyError;
pub struct AppTableSql {}
impl AppTableSql {
pub(crate) fn create_app(app_table: AppTable, conn: &SqliteConnection) -> Result<(), FlowyError> {
pub(crate) fn create_app(app: App, conn: &SqliteConnection) -> Result<(), FlowyError> {
let app_table = AppTable::new(app);
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);
let changeset = AppChangeset::from_table(app_table);
diesel_update_table!(app_table, changeset, conn)
},
}
Ok(())
}
pub(crate) fn update_app(changeset: AppTableChangeset, conn: &SqliteConnection) -> Result<(), FlowyError> {
pub(crate) fn update_app(changeset: AppChangeset, conn: &SqliteConnection) -> Result<(), FlowyError> {
diesel_update_table!(app_table, changeset, conn);
Ok(())
}
@ -160,16 +161,16 @@ impl_sql_binary_expression!(ColorStyleCol);
#[derive(AsChangeset, Identifiable, Default, Debug)]
#[table_name = "app_table"]
pub(crate) struct AppTableChangeset {
pub(crate) struct AppChangeset {
pub id: String,
pub name: Option<String>,
pub desc: Option<String>,
pub is_trash: Option<bool>,
}
impl AppTableChangeset {
impl AppChangeset {
pub(crate) fn new(params: UpdateAppParams) -> Self {
AppTableChangeset {
AppChangeset {
id: params.app_id,
name: params.name,
desc: params.desc,
@ -178,7 +179,7 @@ impl AppTableChangeset {
}
pub(crate) fn from_table(table: AppTable) -> Self {
AppTableChangeset {
AppChangeset {
id: table.id,
name: Some(table.name),
desc: Some(table.desc),

View File

@ -1,8 +1,8 @@
use crate::{
dart_notification::{send_anonymous_dart_notification, WorkspaceNotification},
entities::trash::{RepeatedTrash, RepeatedTrashId, Trash, TrashId, TrashType},
errors::{FlowyError, FlowyResult},
module::{WorkspaceCloudService, WorkspaceDatabase, WorkspaceUser},
notify::{send_anonymous_dart_notification, WorkspaceNotification},
services::trash::sql::TrashTableSql,
};
use crossbeam_utils::thread;

View File

@ -12,13 +12,13 @@ use flowy_database::{
pub struct TrashTableSql {}
impl TrashTableSql {
pub(crate) fn create_trash(repeated_trash: Vec<Trash>, conn: &SqliteConnection) -> Result<(), FlowyError> {
for trash in repeated_trash {
pub(crate) fn create_trash(trashes: Vec<Trash>, conn: &SqliteConnection) -> Result<(), FlowyError> {
for trash in trashes {
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);
let changeset = TrashChangeset::from(trash_table);
diesel_update_table!(trash_table, changeset, conn)
},
}
@ -88,15 +88,15 @@ impl std::convert::From<Trash> for TrashTable {
#[derive(AsChangeset, Identifiable, Clone, Default, Debug)]
#[table_name = "trash_table"]
pub(crate) struct TrashTableChangeset {
pub(crate) struct TrashChangeset {
pub id: String,
pub name: Option<String>,
pub modified_time: i64,
}
impl std::convert::From<TrashTable> for TrashTableChangeset {
impl std::convert::From<TrashTable> for TrashChangeset {
fn from(trash: TrashTable) -> Self {
TrashTableChangeset {
TrashChangeset {
id: trash.id,
name: Some(trash.name),
modified_time: trash.modified_time,

View File

@ -8,15 +8,15 @@ use futures::{FutureExt, StreamExt};
use std::{collections::HashSet, sync::Arc};
use crate::{
dart_notification::{send_dart_notification, WorkspaceNotification},
entities::{
trash::{RepeatedTrashId, TrashType},
view::{CreateViewParams, RepeatedView, UpdateViewParams, View, ViewId},
},
errors::{FlowyError, FlowyResult},
module::{WorkspaceCloudService, WorkspaceDatabase, WorkspaceUser},
notify::{send_dart_notification, WorkspaceNotification},
services::{
view::sql::{ViewTable, ViewTableChangeset, ViewTableSql},
view::sql::{ViewChangeset, ViewTable, ViewTableSql},
TrashController,
TrashEvent,
},
@ -92,8 +92,7 @@ impl ViewController {
}
pub(crate) fn save_view(&self, view: View, conn: &SqliteConnection) -> Result<(), FlowyError> {
let view_table = ViewTable::new(view);
let _ = ViewTableSql::create_view(view_table, conn)?;
let _ = ViewTableSql::create_view(view, conn)?;
Ok(())
}
@ -196,7 +195,7 @@ impl ViewController {
#[tracing::instrument(level = "debug", skip(self, params), err)]
pub(crate) async fn update_view(&self, params: UpdateViewParams) -> Result<View, FlowyError> {
let conn = &*self.database.db_connection()?;
let changeset = ViewTableChangeset::new(params.clone());
let changeset = ViewChangeset::new(params.clone());
let view_id = changeset.id.clone();
let updated_view = conn.immediate_transaction::<_, FlowyError, _>(|| {
@ -267,8 +266,7 @@ impl ViewController {
match server.read_view(&token, params).await {
Ok(Some(view)) => match pool.get() {
Ok(conn) => {
let view_table = ViewTable::new(view.clone());
let result = ViewTableSql::create_view(view_table, &conn);
let result = ViewTableSql::create_view(view.clone(), &conn);
match result {
Ok(_) => {
send_dart_notification(&view.id, WorkspaceNotification::ViewUpdated)

View File

@ -17,11 +17,12 @@ use lib_infra::timestamp;
pub struct ViewTableSql {}
impl ViewTableSql {
pub(crate) fn create_view(view_table: ViewTable, conn: &SqliteConnection) -> Result<(), FlowyError> {
pub(crate) fn create_view(view: View, conn: &SqliteConnection) -> Result<(), FlowyError> {
let view_table = ViewTable::new(view);
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);
let changeset = ViewChangeset::from_table(view_table);
diesel_update_table!(view_table, changeset, conn)
},
}
@ -54,7 +55,7 @@ impl ViewTableSql {
Ok(view_tables)
}
pub(crate) fn update_view(changeset: ViewTableChangeset, conn: &SqliteConnection) -> Result<(), FlowyError> {
pub(crate) fn update_view(changeset: ViewChangeset, conn: &SqliteConnection) -> Result<(), FlowyError> {
diesel_update_table!(view_table, changeset, conn);
Ok(())
}
@ -181,7 +182,7 @@ impl std::convert::From<ViewTable> for Trash {
#[derive(AsChangeset, Identifiable, Clone, Default, Debug)]
#[table_name = "view_table"]
pub(crate) struct ViewTableChangeset {
pub(crate) struct ViewChangeset {
pub id: String,
pub name: Option<String>,
pub desc: Option<String>,
@ -189,9 +190,9 @@ pub(crate) struct ViewTableChangeset {
pub modified_time: i64,
}
impl ViewTableChangeset {
impl ViewChangeset {
pub(crate) fn new(params: UpdateViewParams) -> Self {
ViewTableChangeset {
ViewChangeset {
id: params.view_id,
name: params.name,
desc: params.desc,
@ -201,7 +202,7 @@ impl ViewTableChangeset {
}
pub(crate) fn from_table(table: ViewTable) -> Self {
ViewTableChangeset {
ViewChangeset {
id: table.id,
name: Some(table.name),
desc: Some(table.desc),

View File

@ -1,10 +1,10 @@
use crate::{
dart_notification::*,
errors::*,
module::{WorkspaceCloudService, WorkspaceDatabase, WorkspaceUser},
notify::*,
services::{
read_local_workspace_apps,
workspace::sql::{WorkspaceTable, WorkspaceTableChangeset, WorkspaceTableSql},
workspace::sql::{WorkspaceTableChangeset, WorkspaceTableSql},
TrashController,
},
};
@ -47,7 +47,6 @@ impl WorkspaceController {
pub(crate) async fn create_workspace_on_local(&self, workspace: Workspace) -> Result<Workspace, FlowyError> {
let user_id = self.user.user_id()?;
let token = self.user.token()?;
let workspace_table = WorkspaceTable::new(workspace.clone(), &user_id);
let conn = &*self.database.db_connection()?;
//[[immediate_transaction]]
// https://sqlite.org/lang_transaction.html
@ -61,7 +60,7 @@ impl WorkspaceController {
// other journaling modes, EXCLUSIVE prevents other database connections from
// reading the database while the transaction is underway.
conn.immediate_transaction::<_, FlowyError, _>(|| {
WorkspaceTableSql::create_workspace(workspace_table, conn)?;
WorkspaceTableSql::create_workspace(&user_id, workspace.clone(), conn)?;
let repeated_workspace = self.read_local_workspaces(None, &user_id, conn)?;
send_dart_notification(&token, WorkspaceNotification::UserCreateWorkspace)
.payload(repeated_workspace)

View File

@ -1,6 +1,19 @@
use crate::{errors::FlowyError, services::WorkspaceController};
use flowy_core_data_model::entities::{app::RepeatedApp, workspace::*};
use crate::{
context::CoreContext,
dart_notification::{send_dart_notification, WorkspaceNotification},
errors::FlowyError,
services::{
get_current_workspace,
read_local_workspace_apps,
workspace::sql::WorkspaceTableSql,
WorkspaceController,
},
};
use flowy_core_data_model::entities::{
app::RepeatedApp,
view::View,
workspace::{CurrentWorkspaceSetting, QueryWorkspaceRequest, RepeatedWorkspace, WorkspaceId, *},
};
use lib_dispatch::prelude::{data_result, Data, DataResult, Unit};
use std::{convert::TryInto, sync::Arc};
@ -32,3 +45,97 @@ pub(crate) async fn open_workspace_handler(
let workspaces = controller.open_workspace(params).await?;
data_result(workspaces)
}
#[tracing::instrument(skip(data, core), err)]
pub(crate) async fn read_workspaces_handler(
data: Data<QueryWorkspaceRequest>,
core: Unit<Arc<CoreContext>>,
) -> DataResult<RepeatedWorkspace, FlowyError> {
let params: WorkspaceId = data.into_inner().try_into()?;
let user_id = core.user.user_id()?;
let conn = &*core.database.db_connection()?;
let workspace_controller = core.workspace_controller.clone();
let trash_controller = core.trash_controller.clone();
let workspaces = conn.immediate_transaction::<_, FlowyError, _>(|| {
let mut workspaces = workspace_controller.read_local_workspaces(params.workspace_id.clone(), &user_id, conn)?;
for workspace in workspaces.iter_mut() {
let apps = read_local_workspace_apps(&workspace.id, trash_controller.clone(), conn)?.into_inner();
workspace.apps.items = apps;
}
Ok(workspaces)
})?;
let _ = read_workspaces_on_server(core, user_id, params);
data_result(workspaces)
}
#[tracing::instrument(skip(core), err)]
pub async fn read_cur_workspace_handler(
core: Unit<Arc<CoreContext>>,
) -> DataResult<CurrentWorkspaceSetting, FlowyError> {
let workspace_id = get_current_workspace()?;
let user_id = core.user.user_id()?;
let params = WorkspaceId {
workspace_id: Some(workspace_id.clone()),
};
let conn = &*core.database.db_connection()?;
let workspace = core
.workspace_controller
.read_local_workspace(workspace_id, &user_id, conn)?;
let latest_view: Option<View> = core.view_controller.latest_visit_view().unwrap_or(None);
let setting = CurrentWorkspaceSetting { workspace, latest_view };
let _ = read_workspaces_on_server(core, user_id, params);
data_result(setting)
}
#[tracing::instrument(level = "debug", skip(core), err)]
fn read_workspaces_on_server(
core: Unit<Arc<CoreContext>>,
user_id: String,
params: WorkspaceId,
) -> Result<(), FlowyError> {
let (token, server) = (core.user.token()?, core.cloud_service.clone());
let app_ctrl = core.app_controller.clone();
let view_ctrl = core.view_controller.clone();
let conn = core.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::<_, FlowyError, _>(|| {
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 _ = WorkspaceTableSql::create_workspace(&user_id, m_workspace, &*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::<(), FlowyError>::Ok(())
});
Ok(())
}

View File

@ -13,7 +13,12 @@ use flowy_database::{
pub(crate) struct WorkspaceTableSql {}
impl WorkspaceTableSql {
pub(crate) fn create_workspace(table: WorkspaceTable, conn: &SqliteConnection) -> Result<(), FlowyError> {
pub(crate) fn create_workspace(
user_id: &str,
workspace: Workspace,
conn: &SqliteConnection,
) -> Result<(), FlowyError> {
let table = WorkspaceTable::new(workspace, &user_id);
match diesel_record_count!(workspace_table, &table.id, conn) {
0 => diesel_insert_table!(workspace_table, &table, conn),
_ => {

View File

@ -1,3 +1,2 @@
proto_crates = ["src/notify"]
proto_crates = []
event_files = []

View File

@ -1,7 +1,7 @@
pub mod context;
pub(crate) mod controller;
pub mod core;
mod notify;
// mod notify;
pub mod protobuf;
mod ws_receivers;

View File

@ -1 +0,0 @@
mod observable;

View File

@ -1,16 +0,0 @@
use dart_notify::DartNotifyBuilder;
use flowy_derive::ProtoBuf_Enum;
const OBSERVABLE_CATEGORY: &str = "Doc";
#[derive(ProtoBuf_Enum, Debug)]
pub(crate) enum DocObservable {
UserCreateDoc = 0,
}
impl std::convert::From<DocObservable> for i32 {
fn from(o: DocObservable) -> Self { o as i32 }
}
#[allow(dead_code)]
pub(crate) fn dart_notify(id: &str, ty: DocObservable) -> DartNotifyBuilder {
DartNotifyBuilder::new(id, ty, OBSERVABLE_CATEGORY)
}

View File

@ -1,5 +1,2 @@
#![cfg_attr(rustfmt, rustfmt::skip)]
// Auto-generated, do not edit
mod observable;
pub use observable::*;

View File

@ -1,92 +0,0 @@
// This file is generated by rust-protobuf 2.22.1. Do not edit
// @generated
// https://github.com/rust-lang/rust-clippy/issues/702
#![allow(unknown_lints)]
#![allow(clippy::all)]
#![allow(unused_attributes)]
#![cfg_attr(rustfmt, rustfmt::skip)]
#![allow(box_pointers)]
#![allow(dead_code)]
#![allow(missing_docs)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
#![allow(non_upper_case_globals)]
#![allow(trivial_casts)]
#![allow(unused_imports)]
#![allow(unused_results)]
//! Generated file from `observable.proto`
/// Generated files are compatible only with the same version
/// of protobuf runtime.
// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_22_1;
#[derive(Clone,PartialEq,Eq,Debug,Hash)]
pub enum DocObservable {
UserCreateDoc = 0,
}
impl ::protobuf::ProtobufEnum for DocObservable {
fn value(&self) -> i32 {
*self as i32
}
fn from_i32(value: i32) -> ::std::option::Option<DocObservable> {
match value {
0 => ::std::option::Option::Some(DocObservable::UserCreateDoc),
_ => ::std::option::Option::None
}
}
fn values() -> &'static [Self] {
static values: &'static [DocObservable] = &[
DocObservable::UserCreateDoc,
];
values
}
fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor {
static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::EnumDescriptor> = ::protobuf::rt::LazyV2::INIT;
descriptor.get(|| {
::protobuf::reflect::EnumDescriptor::new_pb_name::<DocObservable>("DocObservable", file_descriptor_proto())
})
}
}
impl ::std::marker::Copy for DocObservable {
}
impl ::std::default::Default for DocObservable {
fn default() -> Self {
DocObservable::UserCreateDoc
}
}
impl ::protobuf::reflect::ProtobufValue for DocObservable {
fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self))
}
}
static file_descriptor_proto_data: &'static [u8] = b"\
\n\x10observable.proto*\"\n\rDocObservable\x12\x11\n\rUserCreateDoc\x10\
\0JS\n\x06\x12\x04\0\0\x04\x01\n\x08\n\x01\x0c\x12\x03\0\0\x12\n\n\n\x02\
\x05\0\x12\x04\x02\0\x04\x01\n\n\n\x03\x05\0\x01\x12\x03\x02\x05\x12\n\
\x0b\n\x04\x05\0\x02\0\x12\x03\x03\x04\x16\n\x0c\n\x05\x05\0\x02\0\x01\
\x12\x03\x03\x04\x11\n\x0c\n\x05\x05\0\x02\0\x02\x12\x03\x03\x14\x15b\
\x06proto3\
";
static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;
fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto {
::protobuf::Message::parse_from_bytes(file_descriptor_proto_data).unwrap()
}
pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto {
file_descriptor_proto_lazy.get(|| {
parse_descriptor_proto()
})
}

View File

@ -1,5 +0,0 @@
syntax = "proto3";
enum DocObservable {
UserCreateDoc = 0;
}

View File

@ -1,3 +1,3 @@
proto_crates = ["src/event.rs", "src/notify"]
proto_crates = ["src/event.rs", "src/dart_notification.rs"]
event_files = ["src/event.rs"]

View File

@ -1,7 +1,7 @@
mod dart_notification;
pub mod event;
mod handlers;
pub mod module;
pub mod notify;
pub mod protobuf;
pub mod services;
// mod sql_tables;

View File

@ -1,2 +0,0 @@
mod observable;
pub(crate) use observable::*;

View File

@ -17,7 +17,7 @@
#![allow(trivial_casts)]
#![allow(unused_imports)]
#![allow(unused_results)]
//! Generated file from `observable.proto`
//! Generated file from `dart_notification.proto`
/// Generated files are compatible only with the same version
/// of protobuf runtime.
@ -83,22 +83,22 @@ impl ::protobuf::reflect::ProtobufValue for UserNotification {
}
static file_descriptor_proto_data: &'static [u8] = b"\
\n\x10observable.proto*\x81\x01\n\x10UserNotification\x12\x0b\n\x07Unkno\
wn\x10\0\x12\x13\n\x0fUserAuthChanged\x10\x01\x12\x16\n\x12UserProfileUp\
dated\x10\x02\x12\x14\n\x10UserUnauthorized\x10\x03\x12\x1d\n\x19UserWsC\
onnectStateChanged\x10\x04J\xf7\x01\n\x06\x12\x04\0\0\x08\x01\n\x08\n\
\x01\x0c\x12\x03\0\0\x12\n\n\n\x02\x05\0\x12\x04\x02\0\x08\x01\n\n\n\x03\
\x05\0\x01\x12\x03\x02\x05\x15\n\x0b\n\x04\x05\0\x02\0\x12\x03\x03\x04\
\x10\n\x0c\n\x05\x05\0\x02\0\x01\x12\x03\x03\x04\x0b\n\x0c\n\x05\x05\0\
\x02\0\x02\x12\x03\x03\x0e\x0f\n\x0b\n\x04\x05\0\x02\x01\x12\x03\x04\x04\
\x18\n\x0c\n\x05\x05\0\x02\x01\x01\x12\x03\x04\x04\x13\n\x0c\n\x05\x05\0\
\x02\x01\x02\x12\x03\x04\x16\x17\n\x0b\n\x04\x05\0\x02\x02\x12\x03\x05\
\x04\x1b\n\x0c\n\x05\x05\0\x02\x02\x01\x12\x03\x05\x04\x16\n\x0c\n\x05\
\x05\0\x02\x02\x02\x12\x03\x05\x19\x1a\n\x0b\n\x04\x05\0\x02\x03\x12\x03\
\x06\x04\x19\n\x0c\n\x05\x05\0\x02\x03\x01\x12\x03\x06\x04\x14\n\x0c\n\
\x05\x05\0\x02\x03\x02\x12\x03\x06\x17\x18\n\x0b\n\x04\x05\0\x02\x04\x12\
\x03\x07\x04\"\n\x0c\n\x05\x05\0\x02\x04\x01\x12\x03\x07\x04\x1d\n\x0c\n\
\x05\x05\0\x02\x04\x02\x12\x03\x07\x20!b\x06proto3\
\n\x17dart_notification.proto*\x81\x01\n\x10UserNotification\x12\x0b\n\
\x07Unknown\x10\0\x12\x13\n\x0fUserAuthChanged\x10\x01\x12\x16\n\x12User\
ProfileUpdated\x10\x02\x12\x14\n\x10UserUnauthorized\x10\x03\x12\x1d\n\
\x19UserWsConnectStateChanged\x10\x04J\xf7\x01\n\x06\x12\x04\0\0\x07\x01\
\n\x08\n\x01\x0c\x12\x03\0\0\x12\n\n\n\x02\x05\0\x12\x04\x01\0\x07\x01\n\
\n\n\x03\x05\0\x01\x12\x03\x01\x05\x15\n\x0b\n\x04\x05\0\x02\0\x12\x03\
\x02\x04\x10\n\x0c\n\x05\x05\0\x02\0\x01\x12\x03\x02\x04\x0b\n\x0c\n\x05\
\x05\0\x02\0\x02\x12\x03\x02\x0e\x0f\n\x0b\n\x04\x05\0\x02\x01\x12\x03\
\x03\x04\x18\n\x0c\n\x05\x05\0\x02\x01\x01\x12\x03\x03\x04\x13\n\x0c\n\
\x05\x05\0\x02\x01\x02\x12\x03\x03\x16\x17\n\x0b\n\x04\x05\0\x02\x02\x12\
\x03\x04\x04\x1b\n\x0c\n\x05\x05\0\x02\x02\x01\x12\x03\x04\x04\x16\n\x0c\
\n\x05\x05\0\x02\x02\x02\x12\x03\x04\x19\x1a\n\x0b\n\x04\x05\0\x02\x03\
\x12\x03\x05\x04\x19\n\x0c\n\x05\x05\0\x02\x03\x01\x12\x03\x05\x04\x14\n\
\x0c\n\x05\x05\0\x02\x03\x02\x12\x03\x05\x17\x18\n\x0b\n\x04\x05\0\x02\
\x04\x12\x03\x06\x04\"\n\x0c\n\x05\x05\0\x02\x04\x01\x12\x03\x06\x04\x1d\
\n\x0c\n\x05\x05\0\x02\x04\x02\x12\x03\x06\x20!b\x06proto3\
";
static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;

View File

@ -1,8 +1,8 @@
#![cfg_attr(rustfmt, rustfmt::skip)]
// Auto-generated, do not edit
mod observable;
pub use observable::*;
mod dart_notification;
pub use dart_notification::*;
mod event;
pub use event::*;

View File

@ -1,5 +1,4 @@
syntax = "proto3";
enum UserNotification {
Unknown = 0;
UserAuthChanged = 1;

View File

@ -1,7 +1,7 @@
use crate::{
dart_notification::*,
errors::{ErrorCode, FlowyError},
module::UserCloudService,
notify::*,
services::{
database::{UserDB, UserTable, UserTableChangeset},
notifier::UserNotifier,