[backend]: create defaultw workspace

This commit is contained in:
appflowy 2021-11-08 15:58:38 +08:00
parent b8dcc9414d
commit fb608be79e
11 changed files with 184 additions and 79 deletions

View File

@ -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);
}
}

View File

@ -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 {

View File

@ -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

View File

@ -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)
}

View File

@ -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

View File

@ -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)

View File

@ -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())?;

View File

@ -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);
}

View File

@ -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 = []

View File

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

View File

@ -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(),
}
}