Browse Source

config doc server api

appflowy 3 years ago
parent
commit
464d5396e6
30 changed files with 354 additions and 132 deletions
  1. 1 0
      backend/Cargo.toml
  2. 6 0
      backend/migrations/20210909115140_doc.sql
  3. 7 0
      backend/src/application.rs
  4. 124 0
      backend/src/doc_service/doc.rs
  5. 6 0
      backend/src/doc_service/mod.rs
  6. 37 0
      backend/src/doc_service/router.rs
  7. 37 0
      backend/src/doc_service/sql_builder.rs
  8. 18 0
      backend/src/entities/doc.rs
  9. 1 0
      backend/src/entities/mod.rs
  10. 38 13
      backend/src/entities/workspace.rs
  11. 4 3
      backend/src/lib.rs
  12. 9 11
      backend/src/workspace_service/app/app.rs
  13. 1 2
      backend/src/workspace_service/app/mod.rs
  14. 7 17
      backend/src/workspace_service/app/sql_builder.rs
  15. 3 3
      backend/src/workspace_service/user_default/user_default.rs
  16. 1 2
      backend/src/workspace_service/view/mod.rs
  17. 7 20
      backend/src/workspace_service/view/sql_builder.rs
  18. 9 7
      backend/src/workspace_service/view/view.rs
  19. 1 2
      backend/src/workspace_service/workspace/mod.rs
  20. 5 2
      backend/src/workspace_service/workspace/sql_builder.rs
  21. 8 19
      backend/src/workspace_service/workspace/workspace.rs
  22. 1 1
      rust-lib/flowy-document/src/entities/doc/mod.rs
  23. 1 1
      rust-lib/flowy-document/src/event.rs
  24. 3 3
      rust-lib/flowy-document/src/handlers/doc_handler.rs
  25. 1 1
      rust-lib/flowy-document/src/lib.rs
  26. 0 2
      rust-lib/flowy-document/src/observable/mod.rs
  27. 11 9
      rust-lib/flowy-document/src/services/doc_controller.rs
  28. 1 1
      rust-lib/flowy-document/src/services/server/mod.rs
  29. 5 5
      rust-lib/flowy-document/src/services/server/server_api.rs
  30. 1 8
      rust-lib/flowy-document/src/services/server/server_api_mock.rs

+ 1 - 0
backend/Cargo.toml

@@ -45,6 +45,7 @@ tokio = { version = "1", features = ["full"] }
 flowy-log = { path = "../rust-lib/flowy-log" }
 flowy-user = { path = "../rust-lib/flowy-user" }
 flowy-workspace = { path = "../rust-lib/flowy-workspace" }
+flowy-document = { path = "../rust-lib/flowy-document" }
 flowy-net = { path = "../rust-lib/flowy-net", features = ["http_server"] }
 
 ormx = { version = "0.7", features = ["postgres"]}

+ 6 - 0
backend/migrations/20210909115140_doc.sql

@@ -0,0 +1,6 @@
+-- Add migration script here
+CREATE TABLE IF NOT EXISTS doc_table(
+    id uuid NOT NULL,
+    PRIMARY KEY (id),
+    data TEXT NOT NULL
+);

+ 7 - 0
backend/src/application.rs

@@ -5,6 +5,7 @@ use crate::{
         Settings,
     },
     context::AppContext,
+    doc_service::router as doc,
     user_service::router as user,
     workspace_service::{app::router as app, view::router as view, workspace::router as workspace},
     ws_service,
@@ -112,6 +113,12 @@ fn user_scope() -> Scope {
             .route(web::get().to(view::read_handler))
             .route(web::patch().to(view::update_handler))
         )
+        .service(web::resource("/doc")
+            .route(web::post().to(doc::create_handler))
+            .route(web::delete().to(doc::delete_handler))
+            .route(web::get().to(doc::read_handler))
+            .route(web::patch().to(doc::update_handler))
+        )
         // password
         .service(web::resource("/password_change")
             .route(web::post().to(user::change_password))

+ 124 - 0
backend/src/doc_service/doc.rs

@@ -0,0 +1,124 @@
+use super::sql_builder::*;
+use crate::{
+    entities::doc::{DocTable, DOC_TABLE},
+    sqlx_ext::{map_sqlx_error, SqlBuilder},
+};
+use anyhow::Context;
+use flowy_document::protobuf::{CreateDocParams, Doc, QueryDocParams, UpdateDocParams};
+use flowy_net::{errors::ServerError, response::FlowyResponse};
+use sqlx::{postgres::PgArguments, PgPool, Postgres};
+use uuid::Uuid;
+
+pub(crate) async fn create_doc(
+    pool: &PgPool,
+    params: CreateDocParams,
+) -> Result<FlowyResponse, ServerError> {
+    let uuid = Uuid::parse_str(&params.id)?;
+    let mut transaction = pool
+        .begin()
+        .await
+        .context("Failed to acquire a Postgres connection to create doc")?;
+    let (sql, args) = Builder::new(uuid).data(params.data).build()?;
+
+    let _ = sqlx::query_with(&sql, args)
+        .execute(&mut transaction)
+        .await
+        .map_err(map_sqlx_error)?;
+
+    transaction
+        .commit()
+        .await
+        .context("Failed to commit SQL transaction to create doc.")?;
+
+    Ok(FlowyResponse::success())
+}
+
+pub(crate) async fn read_doc(
+    pool: &PgPool,
+    params: QueryDocParams,
+) -> Result<FlowyResponse, ServerError> {
+    let doc_id = Uuid::parse_str(&params.doc_id)?;
+    let mut transaction = pool
+        .begin()
+        .await
+        .context("Failed to acquire a Postgres connection to read doc")?;
+
+    let builder = SqlBuilder::select(DOC_TABLE)
+        .add_field("*")
+        .and_where_eq("id", &doc_id);
+
+    let (sql, args) = builder.build()?;
+    // TODO: benchmark the speed of different documents with different size
+    let doc: Doc = sqlx::query_as_with::<Postgres, DocTable, PgArguments>(&sql, args)
+        .fetch_one(&mut transaction)
+        .await
+        .map_err(map_sqlx_error)?
+        .into();
+
+    transaction
+        .commit()
+        .await
+        .context("Failed to commit SQL transaction to read doc.")?;
+
+    FlowyResponse::success().pb(doc)
+}
+
+pub(crate) async fn update_doc(
+    pool: &PgPool,
+    mut params: UpdateDocParams,
+) -> Result<FlowyResponse, ServerError> {
+    let doc_id = Uuid::parse_str(&params.id)?;
+    let mut transaction = pool
+        .begin()
+        .await
+        .context("Failed to acquire a Postgres connection to update doc")?;
+
+    let data = match params.has_data() {
+        true => Some(params.take_data()),
+        false => None,
+    };
+
+    let (sql, args) = SqlBuilder::update(DOC_TABLE)
+        .add_some_arg("data", data)
+        .and_where_eq("id", doc_id)
+        .build()?;
+
+    sqlx::query_with(&sql, args)
+        .execute(&mut transaction)
+        .await
+        .map_err(map_sqlx_error)?;
+
+    transaction
+        .commit()
+        .await
+        .context("Failed to commit SQL transaction to update doc.")?;
+
+    Ok(FlowyResponse::success())
+}
+
+pub(crate) async fn delete_doc(
+    pool: &PgPool,
+    params: QueryDocParams,
+) -> Result<FlowyResponse, ServerError> {
+    let doc_id = Uuid::parse_str(&params.doc_id)?;
+    let mut transaction = pool
+        .begin()
+        .await
+        .context("Failed to acquire a Postgres connection to delete doc")?;
+
+    let (sql, args) = SqlBuilder::delete(DOC_TABLE)
+        .and_where_eq("id", doc_id)
+        .build()?;
+
+    let _ = sqlx::query_with(&sql, args)
+        .execute(&mut transaction)
+        .await
+        .map_err(map_sqlx_error)?;
+
+    transaction
+        .commit()
+        .await
+        .context("Failed to commit SQL transaction to delete doc.")?;
+
+    Ok(FlowyResponse::success())
+}

+ 6 - 0
backend/src/doc_service/mod.rs

@@ -0,0 +1,6 @@
+mod doc;
+pub mod router;
+mod sql_builder;
+
+pub use doc::*;
+pub use router::*;

+ 37 - 0
backend/src/doc_service/router.rs

@@ -0,0 +1,37 @@
+use crate::routers::utils::parse_from_payload;
+use actix_web::{
+    web::{Data, Payload},
+    HttpResponse,
+};
+use flowy_document::protobuf::CreateDocParams;
+use flowy_net::errors::ServerError;
+use sqlx::PgPool;
+
+pub async fn create_handler(
+    payload: Payload,
+    _pool: Data<PgPool>,
+) -> Result<HttpResponse, ServerError> {
+    let _params: CreateDocParams = parse_from_payload(payload).await?;
+    unimplemented!()
+}
+
+pub async fn read_handler(
+    _payload: Payload,
+    _pool: Data<PgPool>,
+) -> Result<HttpResponse, ServerError> {
+    unimplemented!()
+}
+
+pub async fn update_handler(
+    _payload: Payload,
+    _pool: Data<PgPool>,
+) -> Result<HttpResponse, ServerError> {
+    unimplemented!()
+}
+
+pub async fn delete_handler(
+    _payload: Payload,
+    _pool: Data<PgPool>,
+) -> Result<HttpResponse, ServerError> {
+    unimplemented!()
+}

+ 37 - 0
backend/src/doc_service/sql_builder.rs

@@ -0,0 +1,37 @@
+use crate::{
+    entities::doc::{DocTable, DOC_TABLE},
+    sqlx_ext::SqlBuilder,
+};
+
+use flowy_net::errors::ServerError;
+
+use sqlx::postgres::PgArguments;
+use uuid::Uuid;
+
+pub struct Builder {
+    table: DocTable,
+}
+
+impl Builder {
+    pub fn new(id: Uuid) -> Self {
+        let table = DocTable {
+            id,
+            data: "".to_owned(),
+        };
+        Self { table }
+    }
+
+    pub fn data(mut self, data: String) -> Self {
+        self.table.data = data;
+        self
+    }
+
+    pub fn build(self) -> Result<(String, PgArguments), ServerError> {
+        let (sql, args) = SqlBuilder::create(DOC_TABLE)
+            .add_arg("id", self.table.id)
+            .add_arg("data", self.table.data)
+            .build()?;
+
+        Ok((sql, args))
+    }
+}

+ 18 - 0
backend/src/entities/doc.rs

@@ -0,0 +1,18 @@
+use flowy_document::protobuf::Doc;
+
+pub(crate) const DOC_TABLE: &'static str = "doc_table";
+
+#[derive(Debug, Clone, sqlx::FromRow)]
+pub struct DocTable {
+    pub(crate) id: uuid::Uuid,
+    pub(crate) data: String,
+}
+
+impl std::convert::Into<Doc> for DocTable {
+    fn into(self) -> Doc {
+        let mut doc = Doc::new();
+        doc.set_id(self.id.to_string());
+        doc.set_data(self.data);
+        doc
+    }
+}

+ 1 - 0
backend/src/entities/mod.rs

@@ -1,3 +1,4 @@
+pub mod doc;
 pub mod token;
 pub mod user;
 pub mod workspace;

+ 38 - 13
backend/src/entities/workspace.rs

@@ -1,4 +1,10 @@
 use chrono::Utc;
+use flowy_workspace::protobuf::{App, RepeatedView, View, ViewType};
+use protobuf::ProtobufEnum;
+
+pub(crate) const WORKSPACE_TABLE: &'static str = "workspace_table";
+pub(crate) const APP_TABLE: &'static str = "app_table";
+pub(crate) const VIEW_TABLE: &'static str = "view_table";
 
 #[derive(Debug, Clone, sqlx::FromRow)]
 pub struct WorkspaceTable {
@@ -24,6 +30,21 @@ pub struct AppTable {
     pub(crate) is_trash: bool,
 }
 
+impl std::convert::Into<App> for AppTable {
+    fn into(self) -> App {
+        let mut app = App::default();
+        app.set_id(self.id.to_string());
+        app.set_workspace_id(self.workspace_id.to_string());
+        app.set_name(self.name.clone());
+        app.set_desc(self.description.clone());
+        app.set_belongings(RepeatedView::default());
+        app.set_modified_time(self.modified_time.timestamp());
+        app.set_create_time(self.create_time.timestamp());
+
+        app
+    }
+}
+
 #[derive(Debug, Clone, sqlx::FromRow)]
 pub struct ViewTable {
     pub(crate) id: uuid::Uuid,
@@ -36,16 +57,20 @@ pub struct ViewTable {
     pub(crate) view_type: i32,
     pub(crate) is_trash: bool,
 }
-// impl std::convert::Into<View> for ViewTable {
-//     fn into(self) -> View {
-//         View {
-//             id: self.id.to_string(),
-//             belong_to_id: self.belong_to_id,
-//             name: self.name,
-//             desc: self.description,
-//             view_type: ViewType::from(self.view_type),
-//             version: 0,
-//             belongings: RepeatedView::default(),
-//         }
-//     }
-// }
+impl std::convert::Into<View> for ViewTable {
+    fn into(self) -> View {
+        let view_type = ViewType::from_i32(self.view_type).unwrap_or(ViewType::Doc);
+
+        let mut view = View::default();
+        view.set_id(self.id.to_string());
+        view.set_belong_to_id(self.belong_to_id);
+        view.set_name(self.name);
+        view.set_desc(self.description);
+        view.set_view_type(view_type);
+        view.set_belongings(RepeatedView::default());
+        view.set_create_time(self.create_time.timestamp());
+        view.set_modified_time(self.modified_time.timestamp());
+
+        view
+    }
+}

+ 4 - 3
backend/src/lib.rs

@@ -1,10 +1,11 @@
 pub mod application;
 pub mod config;
 mod context;
+mod doc_service;
 mod entities;
 mod middleware;
 mod routers;
 mod sqlx_ext;
-pub mod user_service;
-pub mod workspace_service;
-pub mod ws_service;
+mod user_service;
+mod workspace_service;
+mod ws_service;

+ 9 - 11
backend/src/workspace_service/app/app.rs

@@ -1,24 +1,20 @@
 use flowy_net::{errors::ServerError, response::FlowyResponse};
 
 use crate::{
-    entities::workspace::AppTable,
+    entities::workspace::{AppTable, APP_TABLE},
     sqlx_ext::{map_sqlx_error, SqlBuilder},
     user_service::LoggedUser,
-    workspace_service::{
-        app::{check_app_id, make_app_from_table, Builder},
-        view::read_views_belong_to_id,
-    },
+    workspace_service::{app::sql_builder::*, view::read_views_belong_to_id},
 };
 use anyhow::Context;
 use chrono::Utc;
 use flowy_net::errors::invalid_params;
-
 use flowy_workspace::{
     entities::{
         app::parser::{AppDesc, AppName},
         workspace::parser::WorkspaceId,
     },
-    protobuf::{CreateAppParams, QueryAppParams, RepeatedView, UpdateAppParams},
+    protobuf::{App, CreateAppParams, QueryAppParams, RepeatedView, UpdateAppParams},
 };
 use protobuf::Message;
 use sqlx::{postgres::PgArguments, PgPool, Postgres};
@@ -67,7 +63,7 @@ pub(crate) async fn read_app(
         .await
         .context("Failed to acquire a Postgres connection to read app")?;
 
-    let (sql, args) = SqlBuilder::select("app_table")
+    let (sql, args) = SqlBuilder::select(APP_TABLE)
         .add_field("*")
         .and_where_eq("id", app_id)
         .build()?;
@@ -91,7 +87,9 @@ pub(crate) async fn read_app(
         .await
         .context("Failed to commit SQL transaction to read app.")?;
 
-    let app = make_app_from_table(table, views);
+    let mut app: App = table.into();
+    app.set_belongings(views);
+
     FlowyResponse::success().pb(app)
 }
 
@@ -131,7 +129,7 @@ pub(crate) async fn update_app(
         .await
         .context("Failed to acquire a Postgres connection to update app")?;
 
-    let (sql, args) = SqlBuilder::update("app_table")
+    let (sql, args) = SqlBuilder::update(APP_TABLE)
         .add_some_arg("name", name)
         .add_some_arg("color_style", color_style)
         .add_some_arg("description", desc)
@@ -160,7 +158,7 @@ pub(crate) async fn delete_app(pool: &PgPool, app_id: &str) -> Result<FlowyRespo
         .await
         .context("Failed to acquire a Postgres connection to delete app")?;
 
-    let (sql, args) = SqlBuilder::delete("app_table")
+    let (sql, args) = SqlBuilder::delete(APP_TABLE)
         .and_where_eq("id", app_id)
         .build()?;
 

+ 1 - 2
backend/src/workspace_service/app/mod.rs

@@ -1,5 +1,4 @@
 pub mod app;
 pub mod router;
 
-mod builder;
-pub use builder::*;
+pub mod sql_builder;

+ 7 - 17
backend/src/workspace_service/app/builder.rs → backend/src/workspace_service/app/sql_builder.rs

@@ -1,9 +1,12 @@
-use crate::{entities::workspace::AppTable, sqlx_ext::SqlBuilder};
+use crate::{
+    entities::workspace::{AppTable, APP_TABLE},
+    sqlx_ext::SqlBuilder,
+};
 use chrono::Utc;
 use flowy_net::errors::{invalid_params, ServerError};
 use flowy_workspace::{
     entities::app::parser::AppId,
-    protobuf::{App, ColorStyle, RepeatedView},
+    protobuf::{App, ColorStyle},
 };
 use protobuf::Message;
 use sqlx::postgres::PgArguments;
@@ -57,9 +60,9 @@ impl Builder {
     }
 
     pub fn build(self) -> Result<(String, PgArguments, App), ServerError> {
-        let app = make_app_from_table(self.table.clone(), RepeatedView::default());
+        let app: App = self.table.clone().into();
 
-        let (sql, args) = SqlBuilder::create("app_table")
+        let (sql, args) = SqlBuilder::create(APP_TABLE)
             .add_arg("id", self.table.id)
             .add_arg("workspace_id", self.table.workspace_id)
             .add_arg("name", self.table.name)
@@ -85,19 +88,6 @@ fn default_color_style() -> Vec<u8> {
     }
 }
 
-pub(crate) fn make_app_from_table(table: AppTable, views: RepeatedView) -> App {
-    let mut app = App::default();
-    app.set_id(table.id.to_string());
-    app.set_workspace_id(table.workspace_id.to_string());
-    app.set_name(table.name.clone());
-    app.set_desc(table.description.clone());
-    app.set_belongings(views);
-    app.set_modified_time(table.modified_time.timestamp());
-    app.set_create_time(table.create_time.timestamp());
-
-    app
-}
-
 pub(crate) fn check_app_id(id: String) -> Result<Uuid, ServerError> {
     let app_id = AppId::parse(id).map_err(invalid_params)?;
     let app_id = Uuid::parse_str(app_id.as_ref())?;

+ 3 - 3
backend/src/workspace_service/user_default/user_default.rs

@@ -1,9 +1,9 @@
 use crate::{
     sqlx_ext::{map_sqlx_error, DBTransaction},
     workspace_service::{
-        app::Builder as AppBuilder,
-        view::Builder as ViewBuilder,
-        workspace::Builder as WorkspaceBuilder,
+        app::sql_builder::Builder as AppBuilder,
+        view::sql_builder::Builder as ViewBuilder,
+        workspace::sql_builder::Builder as WorkspaceBuilder,
     },
 };
 

+ 1 - 2
backend/src/workspace_service/view/mod.rs

@@ -1,6 +1,5 @@
-mod builder;
 pub mod router;
+pub mod sql_builder;
 mod view;
 
-pub use builder::*;
 pub(crate) use view::*;

+ 7 - 20
backend/src/workspace_service/view/builder.rs → backend/src/workspace_service/view/sql_builder.rs

@@ -1,9 +1,12 @@
-use crate::{entities::workspace::ViewTable, sqlx_ext::SqlBuilder};
+use crate::{
+    entities::workspace::{ViewTable, VIEW_TABLE},
+    sqlx_ext::SqlBuilder,
+};
 use chrono::Utc;
 use flowy_net::errors::{invalid_params, ServerError};
 use flowy_workspace::{
     entities::view::parser::ViewId,
-    protobuf::{RepeatedView, View, ViewType},
+    protobuf::{View, ViewType},
 };
 use protobuf::ProtobufEnum;
 use sqlx::postgres::PgArguments;
@@ -54,9 +57,9 @@ impl Builder {
     }
 
     pub fn build(self) -> Result<(String, PgArguments, View), ServerError> {
-        let view = make_view_from_table(self.table.clone(), RepeatedView::default());
+        let view: View = self.table.clone().into();
 
-        let (sql, args) = SqlBuilder::create("view_table")
+        let (sql, args) = SqlBuilder::create(VIEW_TABLE)
             .add_arg("id", self.table.id)
             .add_arg("belong_to_id", self.table.belong_to_id)
             .add_arg("name", self.table.name)
@@ -71,22 +74,6 @@ impl Builder {
     }
 }
 
-pub(crate) fn make_view_from_table(table: ViewTable, views: RepeatedView) -> View {
-    let view_type = ViewType::from_i32(table.view_type).unwrap_or(ViewType::Doc);
-
-    let mut view = View::default();
-    view.set_id(table.id.to_string());
-    view.set_belong_to_id(table.belong_to_id);
-    view.set_name(table.name);
-    view.set_desc(table.description);
-    view.set_view_type(view_type);
-    view.set_belongings(views);
-    view.set_create_time(table.create_time.timestamp());
-    view.set_modified_time(table.modified_time.timestamp());
-
-    view
-}
-
 pub(crate) fn check_view_id(id: String) -> Result<Uuid, ServerError> {
     let view_id = ViewId::parse(id).map_err(invalid_params)?;
     let view_id = Uuid::parse_str(view_id.as_ref())?;

+ 9 - 7
backend/src/workspace_service/view/view.rs

@@ -1,7 +1,7 @@
 use crate::{
     entities::workspace::ViewTable,
     sqlx_ext::{map_sqlx_error, DBTransaction, SqlBuilder},
-    workspace_service::view::{check_view_id, make_view_from_table, Builder},
+    workspace_service::view::sql_builder::*,
 };
 use anyhow::Context;
 use chrono::Utc;
@@ -17,6 +17,7 @@ use flowy_workspace::{
     protobuf::{CreateViewParams, QueryViewParams, RepeatedView, UpdateViewParams, View},
 };
 
+use crate::entities::workspace::VIEW_TABLE;
 use sqlx::{postgres::PgArguments, PgPool, Postgres};
 
 pub(crate) async fn create_view(
@@ -63,7 +64,7 @@ pub(crate) async fn read_view(
         .await
         .context("Failed to acquire a Postgres connection to read view")?;
 
-    let (sql, args) = SqlBuilder::select("view_table")
+    let (sql, args) = SqlBuilder::select(VIEW_TABLE)
         .add_field("*")
         .and_where_eq("id", view_id)
         .build()?;
@@ -87,7 +88,8 @@ pub(crate) async fn read_view(
         .await
         .context("Failed to commit SQL transaction to read view.")?;
 
-    let view = make_view_from_table(table, views);
+    let mut view: View = table.into();
+    view.set_belongings(views);
 
     FlowyResponse::success().pb(view)
 }
@@ -130,7 +132,7 @@ pub(crate) async fn update_view(
         .await
         .context("Failed to acquire a Postgres connection to update app")?;
 
-    let (sql, args) = SqlBuilder::update("view_table")
+    let (sql, args) = SqlBuilder::update(VIEW_TABLE)
         .add_some_arg("name", name)
         .add_some_arg("description", desc)
         .add_some_arg("thumbnail", thumbnail)
@@ -162,7 +164,7 @@ pub(crate) async fn delete_view(
         .await
         .context("Failed to acquire a Postgres connection to delete view")?;
 
-    let (sql, args) = SqlBuilder::delete("view_table")
+    let (sql, args) = SqlBuilder::delete(VIEW_TABLE)
         .and_where_eq("id", view_id)
         .build()?;
 
@@ -185,7 +187,7 @@ pub(crate) async fn read_views_belong_to_id<'c>(
     id: &str,
 ) -> Result<Vec<View>, ServerError> {
     // TODO: add index for app_table
-    let (sql, args) = SqlBuilder::select("view_table")
+    let (sql, args) = SqlBuilder::select(VIEW_TABLE)
         .add_field("*")
         .and_where_eq("belong_to_id", id)
         .and_where_eq("is_trash", false)
@@ -198,7 +200,7 @@ pub(crate) async fn read_views_belong_to_id<'c>(
 
     let views = tables
         .into_iter()
-        .map(|table| make_view_from_table(table, RepeatedView::default()))
+        .map(|table| table.into())
         .collect::<Vec<View>>();
 
     Ok(views)

+ 1 - 2
backend/src/workspace_service/workspace/mod.rs

@@ -1,6 +1,5 @@
-pub mod builder;
 pub mod router;
+pub mod sql_builder;
 mod workspace;
 
-pub use builder::*;
 pub use workspace::*;

+ 5 - 2
backend/src/workspace_service/workspace/builder.rs → backend/src/workspace_service/workspace/sql_builder.rs

@@ -1,4 +1,7 @@
-use crate::{entities::workspace::WorkspaceTable, sqlx_ext::SqlBuilder};
+use crate::{
+    entities::workspace::{WorkspaceTable, WORKSPACE_TABLE},
+    sqlx_ext::SqlBuilder,
+};
 use chrono::Utc;
 use flowy_net::errors::{invalid_params, ServerError};
 use flowy_workspace::{
@@ -42,7 +45,7 @@ impl Builder {
         let workspace = make_workspace_from_table(self.table.clone(), None);
 
         // TODO: use macro to fetch each field from struct
-        let (sql, args) = SqlBuilder::create("workspace_table")
+        let (sql, args) = SqlBuilder::create(WORKSPACE_TABLE)
             .add_arg("id", self.table.id)
             .add_arg("name", self.table.name)
             .add_arg("description", self.table.description)

+ 8 - 19
backend/src/workspace_service/workspace/workspace.rs

@@ -1,4 +1,4 @@
-use super::builder::Builder;
+use super::sql_builder::Builder;
 use crate::{entities::workspace::WorkspaceTable, sqlx_ext::*};
 use anyhow::Context;
 
@@ -8,24 +8,13 @@ use flowy_net::{
 };
 
 use crate::{
-    entities::workspace::AppTable,
+    entities::workspace::{AppTable, WORKSPACE_TABLE},
     user_service::LoggedUser,
-    workspace_service::{
-        app::make_app_from_table,
-        view::read_views_belong_to_id,
-        workspace::{check_workspace_id, make_workspace_from_table},
-    },
+    workspace_service::{view::read_views_belong_to_id, workspace::sql_builder::*},
 };
 use flowy_workspace::{
     entities::workspace::parser::{WorkspaceDesc, WorkspaceId, WorkspaceName},
-    protobuf::{
-        App,
-        CreateWorkspaceParams,
-        RepeatedApp,
-        RepeatedView,
-        RepeatedWorkspace,
-        UpdateWorkspaceParams,
-    },
+    protobuf::{App, CreateWorkspaceParams, RepeatedApp, RepeatedWorkspace, UpdateWorkspaceParams},
 };
 use sqlx::{postgres::PgArguments, PgPool, Postgres};
 
@@ -91,7 +80,7 @@ pub(crate) async fn update_workspace(
         .await
         .context("Failed to acquire a Postgres connection to update workspace")?;
 
-    let (sql, args) = SqlBuilder::update("workspace_table")
+    let (sql, args) = SqlBuilder::update(WORKSPACE_TABLE)
         .add_some_arg("name", name)
         .add_some_arg("description", desc)
         .and_where_eq("id", workspace_id)
@@ -120,7 +109,7 @@ pub(crate) async fn delete_workspace(
         .await
         .context("Failed to acquire a Postgres connection to delete workspace")?;
 
-    let (sql, args) = SqlBuilder::delete("workspace_table")
+    let (sql, args) = SqlBuilder::delete(WORKSPACE_TABLE)
         .and_where_eq("id", workspace_id)
         .build()?;
 
@@ -148,7 +137,7 @@ pub async fn read_workspaces(
         .await
         .context("Failed to acquire a Postgres connection to read workspace")?;
 
-    let mut builder = SqlBuilder::select("workspace_table")
+    let mut builder = SqlBuilder::select(WORKSPACE_TABLE)
         .add_field("*")
         .and_where_eq("user_id", &user_id);
 
@@ -208,7 +197,7 @@ async fn read_apps_belong_to_workspace<'c>(
 
     let apps = tables
         .into_iter()
-        .map(|table| make_app_from_table(table, RepeatedView::default()))
+        .map(|table| table.into())
         .collect::<Vec<App>>();
 
     let mut repeated_app = RepeatedApp::default();

+ 1 - 1
rust-lib/flowy-document/src/entities/doc/mod.rs

@@ -1,7 +1,7 @@
 mod doc_create;
 mod doc_modify;
 mod doc_query;
-mod parser;
+pub mod parser;
 
 pub use doc_create::*;
 pub use doc_modify::*;

+ 1 - 1
rust-lib/flowy-document/src/event.rs

@@ -4,7 +4,7 @@ use strum_macros::Display;
 #[derive(Clone, Copy, PartialEq, Eq, Debug, Display, Hash, ProtoBuf_Enum, Flowy_Event)]
 #[event_err = "DocError"]
 pub enum EditorEvent {
-    #[event(input = "CreateDocRequest", output = "Doc")]
+    #[event(input = "CreateDocRequest")]
     CreateDoc = 0,
 
     #[event(input = "UpdateDocRequest")]

+ 3 - 3
rust-lib/flowy-document/src/handlers/doc_handler.rs

@@ -3,10 +3,10 @@ use flowy_dispatch::prelude::*;
 use std::convert::TryInto;
 
 #[tracing::instrument(skip(data, controller))]
-pub async fn create_doc_handler(data: Data<CreateDocRequest>, controller: Unit<DocController>) -> DataResult<Doc, DocError> {
+pub async fn create_doc_handler(data: Data<CreateDocRequest>, controller: Unit<DocController>) -> Result<(), DocError> {
     let params: CreateDocParams = data.into_inner().try_into()?;
-    let doc_desc = controller.create_doc(params).await?;
-    data_result(doc_desc)
+    let _ = controller.create_doc(params).await?;
+    Ok(())
 }
 
 #[tracing::instrument(skip(data, controller))]

+ 1 - 1
rust-lib/flowy-document/src/lib.rs

@@ -4,7 +4,7 @@ pub mod event;
 mod handlers;
 pub mod module;
 mod observable;
-mod protobuf;
+pub mod protobuf;
 mod services;
 mod sql_tables;
 

+ 0 - 2
rust-lib/flowy-document/src/observable/mod.rs

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

+ 11 - 9
rust-lib/flowy-document/src/services/doc_controller.rs

@@ -25,14 +25,16 @@ impl DocController {
         }
     }
 
-    pub(crate) async fn create_doc(&self, params: CreateDocParams) -> Result<Doc, DocError> {
-        let doc = self.create_doc_on_server(params).await?;
-        let doc_table = DocTable::new(doc.clone());
-
+    pub(crate) async fn create_doc(&self, params: CreateDocParams) -> Result<(), DocError> {
+        let _ = self.create_doc_on_server(params.clone()).await?;
+        let doc = Doc {
+            id: params.id,
+            data: params.data,
+        };
         let conn = self.database.db_connection()?;
-        let _ = self.sql.create_doc_table(doc_table, &*conn)?;
+        let _ = self.sql.create_doc_table(DocTable::new(doc), &*conn)?;
 
-        Ok(doc)
+        Ok(())
     }
 
     pub(crate) async fn update_doc(&self, params: UpdateDocParams) -> Result<(), DocError> {
@@ -63,10 +65,10 @@ impl DocController {
 
 impl DocController {
     #[tracing::instrument(skip(self), err)]
-    async fn create_doc_on_server(&self, params: CreateDocParams) -> Result<Doc, DocError> {
+    async fn create_doc_on_server(&self, params: CreateDocParams) -> Result<(), DocError> {
         let token = self.user.token()?;
-        let doc = self.server.create_doc(&token, params).await?;
-        Ok(doc)
+        let _ = self.server.create_doc(&token, params).await?;
+        Ok(())
     }
 
     #[tracing::instrument(level = "debug", skip(self), err)]

+ 1 - 1
rust-lib/flowy-document/src/services/server/mod.rs

@@ -14,7 +14,7 @@ use std::sync::Arc;
 
 pub(crate) type Server = Arc<dyn DocumentServerAPI + Send + Sync>;
 pub trait DocumentServerAPI {
-    fn create_doc(&self, token: &str, params: CreateDocParams) -> ResultFuture<Doc, DocError>;
+    fn create_doc(&self, token: &str, params: CreateDocParams) -> ResultFuture<(), DocError>;
 
     fn read_doc(&self, token: &str, params: QueryDocParams) -> ResultFuture<Option<Doc>, DocError>;
 

+ 5 - 5
rust-lib/flowy-document/src/services/server/server_api.rs

@@ -9,7 +9,7 @@ use flowy_net::{config::*, request::HttpRequestBuilder};
 pub struct DocServer {}
 
 impl DocumentServerAPI for DocServer {
-    fn create_doc(&self, token: &str, params: CreateDocParams) -> ResultFuture<Doc, DocError> {
+    fn create_doc(&self, token: &str, params: CreateDocParams) -> ResultFuture<(), DocError> {
         let token = token.to_owned();
         ResultFuture::new(async move { create_doc_request(&token, params, DOC_URL.as_ref()).await })
     }
@@ -32,14 +32,14 @@ impl DocumentServerAPI for DocServer {
 
 pub(crate) fn request_builder() -> HttpRequestBuilder { HttpRequestBuilder::new().middleware(super::middleware::MIDDLEWARE.clone()) }
 
-pub async fn create_doc_request(token: &str, params: CreateDocParams, url: &str) -> Result<Doc, DocError> {
-    let doc = request_builder()
+pub async fn create_doc_request(token: &str, params: CreateDocParams, url: &str) -> Result<(), DocError> {
+    let _ = request_builder()
         .post(&url.to_owned())
         .header(HEADER_TOKEN, token)
         .protobuf(params)?
-        .response()
+        .send()
         .await?;
-    Ok(doc)
+    Ok(())
 }
 
 pub async fn read_doc_request(token: &str, params: QueryDocParams, url: &str) -> Result<Option<Doc>, DocError> {

+ 1 - 8
rust-lib/flowy-document/src/services/server/server_api_mock.rs

@@ -7,14 +7,7 @@ use flowy_infra::future::ResultFuture;
 pub struct DocServerMock {}
 
 impl DocumentServerAPI for DocServerMock {
-    fn create_doc(&self, _token: &str, params: CreateDocParams) -> ResultFuture<Doc, DocError> {
-        let doc = Doc {
-            id: params.id,
-            data: params.data,
-        };
-
-        ResultFuture::new(async { Ok(doc) })
-    }
+    fn create_doc(&self, _token: &str, _params: CreateDocParams) -> ResultFuture<(), DocError> { ResultFuture::new(async { Ok(()) }) }
 
     fn read_doc(&self, _token: &str, _params: QueryDocParams) -> ResultFuture<Option<Doc>, DocError> {
         ResultFuture::new(async { Ok(None) })