Переглянути джерело

[backend]: create defaultw workspace

appflowy 3 роки тому
батько
коміт
fb608be79e

+ 2 - 2
app_flowy/lib/user/presentation/splash_screen.dart

@@ -59,9 +59,9 @@ class SplashScreen extends StatelessWidget {
 
   void _handleUnauthenticated(BuildContext context, Unauthenticated result) {
     Log.error(result.error);
-    // getIt<ISplashRoute>().pushSignInScreen(context);
+    getIt<ISplashRoute>().pushSignInScreen(context);
 
-    getIt<ISplashRoute>().pushSkipLoginScreen(context);
+    // getIt<ISplashRoute>().pushSkipLoginScreen(context);
   }
 }
 

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

@@ -1,5 +1,5 @@
 use chrono::Utc;
-use flowy_workspace_infra::protobuf::{App, RepeatedView, Trash, TrashType, View, ViewType};
+use flowy_workspace_infra::protobuf::{App, RepeatedView, Trash, TrashType, View, ViewType, Workspace};
 use protobuf::ProtobufEnum;
 
 pub(crate) const WORKSPACE_TABLE: &'static str = "workspace_table";
@@ -17,6 +17,18 @@ pub struct WorkspaceTable {
     pub(crate) user_id: String,
 }
 
+impl std::convert::Into<Workspace> for WorkspaceTable {
+    fn into(self) -> Workspace {
+        let mut workspace = Workspace::default();
+        workspace.set_id(self.id.to_string());
+        workspace.set_name(self.name.clone());
+        workspace.set_desc(self.description.clone());
+        workspace.set_modified_time(self.modified_time.timestamp());
+        workspace.set_create_time(self.create_time.timestamp());
+        workspace
+    }
+}
+
 #[derive(Debug, Clone, sqlx::FromRow)]
 pub struct AppTable {
     pub(crate) id: uuid::Uuid,
@@ -28,7 +40,6 @@ pub struct AppTable {
     pub(crate) modified_time: chrono::DateTime<Utc>,
     pub(crate) create_time: chrono::DateTime<Utc>,
     pub(crate) user_id: String,
-    pub(crate) is_trash: bool,
 }
 
 impl std::convert::Into<App> for AppTable {

+ 21 - 2
backend/src/service/app/sql_builder.rs

@@ -2,7 +2,7 @@ use crate::{
     entities::workspace::{AppTable, APP_TABLE},
     sqlx_ext::SqlBuilder,
 };
-use chrono::Utc;
+use chrono::{DateTime, NaiveDateTime, Utc};
 use flowy_net::errors::{invalid_params, ServerError};
 use flowy_workspace_infra::{
     parser::app::AppId,
@@ -31,12 +31,31 @@ impl NewAppSqlBuilder {
             modified_time: time,
             create_time: time,
             user_id: user_id.to_string(),
-            is_trash: false,
         };
 
         Self { table }
     }
 
+    pub fn from_app(user_id: &str, app: App) -> Result<Self, ServerError> {
+        let app_id = check_app_id(app.id)?;
+        let create_time = DateTime::<Utc>::from_utc(NaiveDateTime::from_timestamp(app.create_time, 0), Utc);
+        let modified_time = DateTime::<Utc>::from_utc(NaiveDateTime::from_timestamp(app.modified_time, 0), Utc);
+
+        let table = AppTable {
+            id: app_id,
+            workspace_id: app.workspace_id,
+            name: app.name,
+            description: app.desc,
+            color_style: default_color_style(),
+            last_view_id: "".to_string(),
+            modified_time,
+            create_time,
+            user_id: user_id.to_string(),
+        };
+
+        Ok(Self { table })
+    }
+
     pub fn name(mut self, name: &str) -> Self {
         self.table.name = name.to_string();
         self

+ 24 - 47
backend/src/service/user/user_default.rs

@@ -7,66 +7,43 @@ use crate::{
     sqlx_ext::{map_sqlx_error, DBTransaction},
 };
 
+use crate::service::view::{create_view_with_args, sql_builder::NewViewSqlBuilder};
+use chrono::Utc;
 use flowy_document::services::doc::doc_initial_string;
 use flowy_net::errors::ServerError;
 use flowy_workspace_infra::protobuf::{App, CreateViewParams, View, ViewType, Workspace};
+use std::convert::TryInto;
 
 pub async fn create_default_workspace(
     transaction: &mut DBTransaction<'_>,
     user_id: &str,
 ) -> Result<Workspace, ServerError> {
-    let workspace = create_workspace(transaction, user_id).await?;
-    let app = create_app(transaction, user_id, &workspace).await?;
-    let _ = create_default_view(transaction, &app).await?;
+    let time = Utc::now();
+    let workspace: Workspace = flowy_workspace_infra::user_default::create_default_workspace(time)
+        .try_into()
+        .unwrap();
 
-    Ok(workspace)
-}
-
-async fn create_workspace(transaction: &mut DBTransaction<'_>, user_id: &str) -> Result<Workspace, ServerError> {
-    let (sql, args, workspace) = WorkspaceBuilder::new(user_id.as_ref())
-        .name("DefaultWorkspace")
-        .desc("")
-        .build()?;
+    let mut cloned_workspace = workspace.clone();
+    let mut apps = cloned_workspace.take_apps();
 
+    let (sql, args, _) = WorkspaceBuilder::from_workspace(user_id, cloned_workspace)?.build()?;
     let _ = sqlx::query_with(&sql, args)
-        .execute(transaction)
+        .execute(transaction as &mut DBTransaction<'_>)
         .await
         .map_err(map_sqlx_error)?;
 
+    for mut app in apps.take_items() {
+        let mut views = app.take_belongings();
+        let (sql, args, _) = AppBuilder::from_app(user_id, app)?.build()?;
+        let _ = sqlx::query_with(&sql, args)
+            .execute(transaction as &mut DBTransaction<'_>)
+            .await
+            .map_err(map_sqlx_error)?;
+
+        for view in views.take_items() {
+            let (sql, args, view) = NewViewSqlBuilder::from_view(view)?.build()?;
+            let _ = create_view_with_args(transaction, sql, args, view, doc_initial_string()).await?;
+        }
+    }
     Ok(workspace)
 }
-
-async fn create_app(
-    transaction: &mut DBTransaction<'_>,
-    user_id: &str,
-    workspace: &Workspace,
-) -> Result<App, ServerError> {
-    let (sql, args, app) = AppBuilder::new(user_id, &workspace.id)
-        .name("Getting Started")
-        .desc("")
-        .build()?;
-
-    let _ = sqlx::query_with(&sql, args)
-        .execute(transaction)
-        .await
-        .map_err(map_sqlx_error)?;
-
-    Ok(app)
-}
-
-async fn create_default_view(transaction: &mut DBTransaction<'_>, app: &App) -> Result<View, ServerError> {
-    let params = CreateViewParams {
-        belong_to_id: app.id.clone(),
-        name: "Read Me".to_string(),
-        desc: "".to_string(),
-        thumbnail: "".to_string(),
-        view_type: ViewType::Doc,
-        data: doc_initial_string(),
-        unknown_fields: Default::default(),
-        cached_size: Default::default(),
-    };
-
-    let view = create_view(transaction, params).await?;
-
-    Ok(view)
-}

+ 20 - 1
backend/src/service/view/sql_builder.rs

@@ -2,7 +2,7 @@ use crate::{
     entities::workspace::{ViewTable, VIEW_TABLE},
     sqlx_ext::SqlBuilder,
 };
-use chrono::Utc;
+use chrono::{DateTime, NaiveDateTime, Utc};
 use flowy_net::errors::{invalid_params, ServerError};
 use flowy_workspace_infra::{
     parser::view::ViewId,
@@ -35,6 +35,25 @@ impl NewViewSqlBuilder {
         Self { table }
     }
 
+    pub fn from_view(view: View) -> Result<Self, ServerError> {
+        let view_id = ViewId::parse(view.id).map_err(invalid_params)?;
+        let view_id = Uuid::parse_str(view_id.as_ref())?;
+        let create_time = DateTime::<Utc>::from_utc(NaiveDateTime::from_timestamp(view.create_time, 0), Utc);
+        let modified_time = DateTime::<Utc>::from_utc(NaiveDateTime::from_timestamp(view.modified_time, 0), Utc);
+
+        let table = ViewTable {
+            id: view_id,
+            belong_to_id: view.belong_to_id,
+            name: view.name,
+            description: view.desc,
+            modified_time,
+            create_time,
+            thumbnail: "".to_string(),
+            view_type: view.view_type.value(),
+        };
+        Ok(Self { table })
+    }
+
     pub fn name(mut self, name: &str) -> Self {
         self.table.name = name.to_string();
         self

+ 12 - 1
backend/src/service/view/view.rs

@@ -75,13 +75,24 @@ pub(crate) async fn create_view(
         .view_type(params.view_type)
         .build()?;
 
+    let view = create_view_with_args(transaction, sql, args, view, params.data).await?;
+    Ok(view)
+}
+
+pub(crate) async fn create_view_with_args(
+    transaction: &mut DBTransaction<'_>,
+    sql: String,
+    args: PgArguments,
+    view: View,
+    view_data: String,
+) -> Result<View, ServerError> {
     let _ = sqlx::query_with(&sql, args)
         .execute(transaction as &mut DBTransaction<'_>)
         .await
         .map_err(map_sqlx_error)?;
 
     let mut create_doc_params = CreateDocParams::new();
-    create_doc_params.set_data(params.data);
+    create_doc_params.set_data(view_data);
     create_doc_params.set_id(view.id.clone());
     let _ = create_doc(transaction, create_doc_params).await?;
     Ok(view)

+ 19 - 22
backend/src/service/workspace/sql_builder.rs

@@ -2,7 +2,7 @@ use crate::{
     entities::workspace::{WorkspaceTable, WORKSPACE_TABLE},
     sqlx_ext::SqlBuilder,
 };
-use chrono::Utc;
+use chrono::{DateTime, NaiveDateTime, Utc};
 use flowy_net::errors::{invalid_params, ServerError};
 use flowy_workspace_infra::{
     parser::workspace::WorkspaceId,
@@ -31,6 +31,23 @@ impl NewWorkspaceBuilder {
         Self { table }
     }
 
+    pub fn from_workspace(user_id: &str, workspace: Workspace) -> Result<Self, ServerError> {
+        let workspace_id = check_workspace_id(workspace.id)?;
+        let create_time = DateTime::<Utc>::from_utc(NaiveDateTime::from_timestamp(workspace.create_time, 0), Utc);
+        let modified_time = DateTime::<Utc>::from_utc(NaiveDateTime::from_timestamp(workspace.modified_time, 0), Utc);
+
+        let table = WorkspaceTable {
+            id: workspace_id,
+            name: workspace.name,
+            description: workspace.desc,
+            modified_time,
+            create_time,
+            user_id: user_id.to_string(),
+        };
+
+        Ok(Self { table })
+    }
+
     pub fn name(mut self, name: &str) -> Self {
         self.table.name = name.to_string();
         self
@@ -42,8 +59,7 @@ impl NewWorkspaceBuilder {
     }
 
     pub fn build(self) -> Result<(String, PgArguments, Workspace), ServerError> {
-        let workspace = make_workspace_from_table(self.table.clone(), None);
-
+        let workspace: Workspace = self.table.clone().into();
         // TODO: use macro to fetch each field from struct
         let (sql, args) = SqlBuilder::create(WORKSPACE_TABLE)
             .add_arg("id", self.table.id)
@@ -58,25 +74,6 @@ impl NewWorkspaceBuilder {
     }
 }
 
-pub(crate) fn make_workspace_from_table(table: WorkspaceTable, apps: Option<RepeatedApp>) -> Workspace {
-    let mut workspace = Workspace {
-        id: table.id.to_string(),
-        name: table.name,
-        desc: table.description,
-        apps: Default::default(),
-        modified_time: table.modified_time.timestamp(),
-        create_time: table.create_time.timestamp(),
-        unknown_fields: Default::default(),
-        cached_size: Default::default(),
-    };
-
-    if let Some(apps) = apps {
-        workspace.set_apps(apps);
-    }
-
-    workspace
-}
-
 pub(crate) fn check_workspace_id(id: String) -> Result<Uuid, ServerError> {
     let workspace_id = WorkspaceId::parse(id).map_err(invalid_params)?;
     let workspace_id = Uuid::parse_str(workspace_id.as_ref())?;

+ 2 - 1
backend/src/service/workspace/workspace.rs

@@ -102,7 +102,8 @@ pub async fn read_workspaces(
         .context("Get workspace app")
         .unwrap_or(RepeatedApp::default());
 
-        let workspace = make_workspace_from_table(table, Some(apps));
+        let mut workspace: Workspace = table.into();
+        workspace.set_apps(apps);
         workspaces.push(workspace);
     }
 

+ 2 - 1
rust-lib/flowy-workspace-infra/Cargo.toml

@@ -15,7 +15,8 @@ strum_macros = "0.21"
 derive_more = {version = "0.99", features = ["display"]}
 log = "0.4.14"
 flowy-document = { path = "../flowy-document" }
-
+uuid = { version = "0.8", features = ["serde", "v4"] }
+chrono = { version = "0.4" }
 
 [features]
 default = []

+ 1 - 0
rust-lib/flowy-workspace-infra/src/lib.rs

@@ -7,3 +7,4 @@ mod macros;
 
 // #[cfg(feature = "backend")]
 pub mod protobuf;
+pub mod user_default;

+ 68 - 0
rust-lib/flowy-workspace-infra/src/user_default.rs

@@ -0,0 +1,68 @@
+use crate::entities::{
+    app::{App, RepeatedApp},
+    view::{RepeatedView, View, ViewType},
+    workspace::Workspace,
+};
+use chrono::Utc;
+use uuid::Uuid;
+
+pub fn create_default_workspace(time: chrono::DateTime<Utc>) -> Workspace {
+    let workspace_id = uuid::Uuid::new_v4();
+    let name = "Workspace".to_string();
+    let desc = "".to_string();
+
+    let apps = RepeatedApp {
+        items: vec![create_default_app(workspace_id.to_string(), time.clone())],
+    };
+
+    let workspace = Workspace {
+        id: workspace_id.to_string(),
+        name,
+        desc,
+        apps,
+        modified_time: time.timestamp(),
+        create_time: time.timestamp(),
+    };
+
+    workspace
+}
+
+fn create_default_app(workspace_id: String, time: chrono::DateTime<Utc>) -> App {
+    let app_id = uuid::Uuid::new_v4();
+    let name = "Getting Started".to_string();
+    let desc = "".to_string();
+
+    let views = RepeatedView {
+        items: vec![create_default_view(app_id.to_string(), time.clone())],
+    };
+
+    App {
+        id: app_id.to_string(),
+        workspace_id,
+        name,
+        desc,
+        belongings: views,
+        version: 0,
+        modified_time: time.timestamp(),
+        create_time: time.timestamp(),
+    }
+}
+
+fn create_default_view(app_id: String, time: chrono::DateTime<Utc>) -> View {
+    let view_id = uuid::Uuid::new_v4();
+    let name = "Read me".to_string();
+    let desc = "".to_string();
+    let view_type = ViewType::Doc;
+
+    View {
+        id: view_id.to_string(),
+        belong_to_id: app_id,
+        name,
+        desc,
+        view_type,
+        version: 0,
+        belongings: Default::default(),
+        modified_time: time.timestamp(),
+        create_time: time.timestamp(),
+    }
+}