diff --git a/backend/src/application.rs b/backend/src/application.rs index ccf15a90ab..5a5a3e466d 100644 --- a/backend/src/application.rs +++ b/backend/src/application.rs @@ -111,9 +111,9 @@ fn user_scope() -> Scope { .route(web::patch().to(view::update_handler)) ) .service(web::resource("/document") - .route(web::post().to(doc::create_handler)) - .route(web::get().to(doc::read_handler)) - .route(web::patch().to(doc::update_handler)) + .route(web::post().to(doc::create_document_handler)) + .route(web::get().to(doc::read_document_handler)) + .route(web::patch().to(doc::reset_document_handler)) ) .service(web::resource("/trash") .route(web::post().to(trash::create_handler)) diff --git a/backend/src/context.rs b/backend/src/context.rs index 1d58e99c82..6f044e3903 100644 --- a/backend/src/context.rs +++ b/backend/src/context.rs @@ -1,5 +1,5 @@ use crate::services::{ - kv_store::{KVStore, PostgresKV}, + kv::{KVStore, PostgresKV}, web_socket::{WSServer, WebSocketReceivers}, }; use actix::Addr; diff --git a/backend/src/services/core/trash/router.rs b/backend/src/services/core/trash/router.rs index d2b349e35b..a3b4a3dfd2 100644 --- a/backend/src/services/core/trash/router.rs +++ b/backend/src/services/core/trash/router.rs @@ -1,4 +1,5 @@ use crate::{ + context::FlowyPersistence, entities::logged_user::LoggedUser, services::core::trash::{create_trash, delete_all_trash, delete_trash, read_trash}, util::serde_ext::parse_from_payload, @@ -15,6 +16,7 @@ use backend_service::{ }; use flowy_core_data_model::{parser::trash::TrashId, protobuf::TrashIdentifiers}; use sqlx::PgPool; +use std::sync::Arc; use uuid::Uuid; #[tracing::instrument(skip(payload, pool, logged_user), err)] @@ -39,12 +41,14 @@ pub async fn create_handler( Ok(FlowyResponse::success().into()) } -#[tracing::instrument(skip(payload, pool, logged_user), fields(delete_trash), err)] +#[tracing::instrument(skip(payload, persistence, logged_user), fields(delete_trash), err)] pub async fn delete_handler( payload: Payload, - pool: Data, + persistence: Data>, logged_user: LoggedUser, ) -> Result { + let pool = persistence.pg_pool(); + let kv_store = persistence.kv_store(); let params: TrashIdentifiers = parse_from_payload(payload).await?; let mut transaction = pool .begin() @@ -53,10 +57,10 @@ pub async fn delete_handler( if params.delete_all { tracing::Span::current().record("delete_trash", &"all"); - let _ = delete_all_trash(&mut transaction, &logged_user).await?; + let _ = delete_all_trash(&mut transaction, &kv_store, &logged_user).await?; } else { let records = make_records(params)?; - let _ = delete_trash(&mut transaction, records).await?; + let _ = delete_trash(&mut transaction, &kv_store, records).await?; } transaction diff --git a/backend/src/services/core/trash/trash.rs b/backend/src/services/core/trash/trash.rs index 64acb2058b..0cd2c54471 100644 --- a/backend/src/services/core/trash/trash.rs +++ b/backend/src/services/core/trash/trash.rs @@ -1,9 +1,12 @@ use crate::{ entities::logged_user::LoggedUser, - services::core::{ - app::controller::{delete_app, read_app_table}, - trash::persistence::{TrashTable, TRASH_TABLE}, - view::{delete_view, read_view_table}, + services::{ + core::{ + app::controller::{delete_app, read_app_table}, + trash::persistence::{TrashTable, TRASH_TABLE}, + view::{delete_view, read_view_table}, + }, + document::persistence::DocumentKVPersistence, }, util::sqlx_ext::{map_sqlx_error, DBTransaction, SqlBuilder}, }; @@ -11,6 +14,7 @@ use ::protobuf::ProtobufEnum; use backend_service::errors::ServerError; use flowy_core_data_model::protobuf::{RepeatedTrash, Trash, TrashType}; use sqlx::{postgres::PgArguments, Postgres, Row}; +use std::sync::Arc; use uuid::Uuid; #[tracing::instrument(skip(transaction, user), err)] @@ -35,9 +39,10 @@ pub(crate) async fn create_trash( Ok(()) } -#[tracing::instrument(skip(transaction, user), fields(delete_rows), err)] +#[tracing::instrument(skip(transaction, kv_store, user), fields(delete_rows), err)] pub(crate) async fn delete_all_trash( transaction: &mut DBTransaction<'_>, + kv_store: &Arc, user: &LoggedUser, ) -> Result<(), ServerError> { let (sql, args) = SqlBuilder::select(TRASH_TABLE) @@ -52,7 +57,7 @@ pub(crate) async fn delete_all_trash( .collect::>(); tracing::Span::current().record("delete_rows", &format!("{:?}", rows).as_str()); let affected_row_count = rows.len(); - let _ = delete_trash_associate_targets(transaction as &mut DBTransaction<'_>, rows).await?; + let _ = delete_trash_associate_targets(transaction as &mut DBTransaction<'_>, kv_store, rows).await?; let (sql, args) = SqlBuilder::delete(TRASH_TABLE) .and_where_eq("user_id", &user.user_id) @@ -67,9 +72,10 @@ pub(crate) async fn delete_all_trash( Ok(()) } -#[tracing::instrument(skip(transaction), err)] +#[tracing::instrument(skip(transaction, kv_store), err)] pub(crate) async fn delete_trash( transaction: &mut DBTransaction<'_>, + kv_store: &Arc, records: Vec<(Uuid, i32)>, ) -> Result<(), ServerError> { for (trash_id, _) in records { @@ -86,6 +92,7 @@ pub(crate) async fn delete_trash( let _ = delete_trash_associate_targets( transaction as &mut DBTransaction<'_>, + kv_store, vec![(trash_table.id, trash_table.ty)], ) .await?; @@ -100,9 +107,10 @@ pub(crate) async fn delete_trash( Ok(()) } -#[tracing::instrument(skip(transaction, targets), err)] +#[tracing::instrument(skip(transaction, kv_store, targets), err)] async fn delete_trash_associate_targets( transaction: &mut DBTransaction<'_>, + kv_store: &Arc, targets: Vec<(Uuid, i32)>, ) -> Result<(), ServerError> { for (id, ty) in targets { @@ -111,7 +119,7 @@ async fn delete_trash_associate_targets( Some(ty) => match ty { TrashType::Unknown => {}, TrashType::View => { - let _ = delete_view(transaction as &mut DBTransaction<'_>, vec![id]).await; + let _ = delete_view(transaction as &mut DBTransaction<'_>, kv_store, vec![id]).await; }, TrashType::App => { let _ = delete_app(transaction as &mut DBTransaction<'_>, id).await; diff --git a/backend/src/services/core/view/controller.rs b/backend/src/services/core/view/controller.rs index 3e389120a6..0f5d6d135d 100644 --- a/backend/src/services/core/view/controller.rs +++ b/backend/src/services/core/view/controller.rs @@ -2,13 +2,16 @@ use crate::{ entities::logged_user::LoggedUser, services::{ core::{trash::read_trash_ids, view::persistence::*}, - document::persistence::{create_doc_with_transaction, delete_doc, DocumentKVPersistence}, + document::persistence::{create_doc, delete_doc, DocumentKVPersistence}, }, util::sqlx_ext::{map_sqlx_error, DBTransaction, SqlBuilder}, }; use backend_service::errors::{invalid_params, ServerError}; use chrono::Utc; -use flowy_collaboration::protobuf::CreateDocParams; +use flowy_collaboration::{ + entities::revision::{RevType, Revision}, + protobuf::{CreateDocParams, RepeatedRevision}, +}; use flowy_core_data_model::{ parser::{ app::AppId, @@ -17,7 +20,7 @@ use flowy_core_data_model::{ protobuf::{CreateViewParams, RepeatedView, View}, }; use sqlx::{postgres::PgArguments, Postgres}; -use std::sync::Arc; +use std::{convert::TryInto, sync::Arc}; use uuid::Uuid; pub(crate) async fn update_view( @@ -43,8 +46,12 @@ pub(crate) async fn update_view( Ok(()) } -#[tracing::instrument(skip(transaction), err)] -pub(crate) async fn delete_view(transaction: &mut DBTransaction<'_>, view_ids: Vec) -> Result<(), ServerError> { +#[tracing::instrument(skip(transaction, kv_store), err)] +pub(crate) async fn delete_view( + transaction: &mut DBTransaction<'_>, + kv_store: &Arc, + view_ids: Vec, +) -> Result<(), ServerError> { for view_id in view_ids { let (sql, args) = SqlBuilder::delete(VIEW_TABLE).and_where_eq("id", &view_id).build()?; let _ = sqlx::query_with(&sql, args) @@ -52,7 +59,7 @@ pub(crate) async fn delete_view(transaction: &mut DBTransaction<'_>, view_ids: V .await .map_err(map_sqlx_error)?; - let _ = delete_doc(transaction, view_id).await?; + let _ = delete_doc(kv_store, view_id).await?; } Ok(()) } @@ -62,6 +69,7 @@ pub(crate) async fn create_view( transaction: &mut DBTransaction<'_>, kv_store: Arc, params: CreateViewParams, + user_id: &str, ) -> Result { let name = ViewName::parse(params.name).map_err(invalid_params)?; let belong_to_id = AppId::parse(params.belong_to_id).map_err(invalid_params)?; @@ -75,27 +83,25 @@ pub(crate) async fn create_view( .view_type(params.view_type) .build()?; - let view = create_view_with_args(transaction, kv_store, sql, args, view, params.data).await?; - Ok(view) -} - -async fn create_view_with_args( - transaction: &mut DBTransaction<'_>, - kv_store: Arc, - sql: String, - args: PgArguments, - view: View, - view_data: String, -) -> Result { let _ = sqlx::query_with(&sql, args) .execute(transaction as &mut DBTransaction<'_>) .await .map_err(map_sqlx_error)?; + let doc_id = view.id.clone(); + let revision: flowy_collaboration::protobuf::Revision = + Revision::initial_revision(user_id, &doc_id, RevType::Remote) + .try_into() + .unwrap(); + let mut repeated_revision = RepeatedRevision::new(); + repeated_revision.set_items(vec![revision].into()); + let mut create_doc_params = CreateDocParams::new(); - create_doc_params.set_data(view_data); + create_doc_params.set_revisions(repeated_revision); create_doc_params.set_id(view.id.clone()); - let _ = create_doc_with_transaction(transaction, kv_store, create_doc_params).await?; + + let _ = create_doc(&kv_store, create_doc_params).await?; + Ok(view) } diff --git a/backend/src/services/core/view/router.rs b/backend/src/services/core/view/router.rs index b315320a62..8828c2efa3 100644 --- a/backend/src/services/core/view/router.rs +++ b/backend/src/services/core/view/router.rs @@ -23,6 +23,7 @@ use std::sync::Arc; pub async fn create_handler( payload: Payload, persistence: Data>, + user: LoggedUser, ) -> Result { let params: CreateViewParams = parse_from_payload(payload).await?; let kv_store = persistence.kv_store(); @@ -32,7 +33,7 @@ pub async fn create_handler( .await .context("Failed to acquire a Postgres connection to create view")?; - let view = create_view(&mut transaction, kv_store, params).await?; + let view = create_view(&mut transaction, kv_store, params, &user.user_id).await?; transaction .commit() .await @@ -96,15 +97,20 @@ pub async fn update_handler(payload: Payload, pool: Data) -> Result) -> Result { +pub async fn delete_handler( + payload: Payload, + persistence: Data>, +) -> Result { let params: QueryViewRequest = parse_from_payload(payload).await?; + let pool = persistence.pg_pool(); + let kv_store = persistence.kv_store(); let view_ids = check_view_ids(params.view_ids.to_vec())?; let mut transaction = pool .begin() .await .context("Failed to acquire a Postgres connection to delete view")?; - let _ = delete_view(&mut transaction, view_ids).await?; + let _ = delete_view(&mut transaction, &kv_store, view_ids).await?; transaction .commit() diff --git a/backend/src/services/document/controller.rs b/backend/src/services/document/controller.rs index 1967a1ef18..d46814b627 100644 --- a/backend/src/services/document/controller.rs +++ b/backend/src/services/document/controller.rs @@ -1,6 +1,6 @@ use crate::services::{ document::{ - persistence::{create_doc, read_doc, update_doc}, + persistence::{create_doc, read_doc}, ws_actor::{DocumentWebSocketActor, WSActorMessage}, }, web_socket::{WSClientData, WebSocketReceiver}, @@ -10,12 +10,15 @@ use crate::context::FlowyPersistence; use backend_service::errors::ServerError; use flowy_collaboration::{ core::sync::{DocumentPersistence, ServerDocumentManager}, - entities::{doc::Doc, revision::Revision}, + entities::{ + doc::{CreateDocParams, Doc}, + revision::{RepeatedRevision, Revision}, + }, errors::CollaborateError, - protobuf::{CreateDocParams, DocIdentifier, UpdateDocParams}, + protobuf::DocIdentifier, }; use lib_infra::future::FutureResultSend; -use lib_ot::rich_text::RichTextDelta; + use std::{convert::TryInto, sync::Arc}; use tokio::sync::{mpsc, oneshot}; @@ -45,13 +48,13 @@ impl WebSocketReceiver for DocumentWebSocketReceiver { fn receive(&self, data: WSClientData) { let (ret, rx) = oneshot::channel(); let sender = self.ws_sender.clone(); - let pool = self.persistence.pg_pool(); + let persistence = self.persistence.clone(); actix_rt::spawn(async move { let msg = WSActorMessage::ClientData { client_data: data, ret, - pool, + persistence, }; match sender.send(msg).await { Ok(_) => {}, @@ -67,21 +70,21 @@ impl WebSocketReceiver for DocumentWebSocketReceiver { struct DocumentPersistenceImpl(Arc); impl DocumentPersistence for DocumentPersistenceImpl { - fn update_doc(&self, doc_id: &str, rev_id: i64, delta: RichTextDelta) -> FutureResultSend<(), CollaborateError> { - let pg_pool = self.0.pg_pool(); - let mut params = UpdateDocParams::new(); - let doc_json = delta.to_json(); - params.set_doc_id(doc_id.to_string()); - params.set_data(doc_json); - params.set_rev_id(rev_id); - - FutureResultSend::new(async move { - let _ = update_doc(&pg_pool, params) - .await - .map_err(server_error_to_collaborate_error)?; - Ok(()) - }) - } + // fn update_doc(&self, doc_id: &str, rev_id: i64, delta: RichTextDelta) -> + // FutureResultSend<(), CollaborateError> { let pg_pool = + // self.0.pg_pool(); let mut params = ResetDocumentParams::new(); + // let doc_json = delta.to_json(); + // params.set_doc_id(doc_id.to_string()); + // params.set_data(doc_json); + // params.set_rev_id(rev_id); + // + // FutureResultSend::new(async move { + // let _ = update_doc(&pg_pool, params) + // .await + // .map_err(server_error_to_collaborate_error)?; + // Ok(()) + // }) + // } fn read_doc(&self, doc_id: &str) -> FutureResultSend { let params = DocIdentifier { @@ -101,22 +104,17 @@ impl DocumentPersistence for DocumentPersistenceImpl { } fn create_doc(&self, revision: Revision) -> FutureResultSend { - let persistence = self.0.clone(); + let kv_store = self.0.kv_store(); FutureResultSend::new(async move { - let delta = RichTextDelta::from_bytes(&revision.delta_data)?; - let doc_json = delta.to_json(); + let doc: Doc = revision.clone().try_into()?; + let doc_id = revision.doc_id.clone(); + let revisions = RepeatedRevision { items: vec![revision] }; - let params = CreateDocParams { - id: revision.doc_id.clone(), - data: doc_json.clone(), - unknown_fields: Default::default(), - cached_size: Default::default(), - }; - - let _ = create_doc(&persistence, params) + let params = CreateDocParams { id: doc_id, revisions }; + let pb_params: flowy_collaboration::protobuf::CreateDocParams = params.try_into().unwrap(); + let _ = create_doc(&kv_store, pb_params) .await .map_err(server_error_to_collaborate_error)?; - let doc: Doc = revision.try_into()?; Ok(doc) }) } diff --git a/backend/src/services/document/persistence/kv.rs b/backend/src/services/document/persistence/kv.rs deleted file mode 100644 index 9fe40cf729..0000000000 --- a/backend/src/services/document/persistence/kv.rs +++ /dev/null @@ -1,48 +0,0 @@ -use crate::{services::kv_store::KVStore, util::serde_ext::parse_from_bytes}; -use backend_service::errors::ServerError; -use bytes::Bytes; -use flowy_collaboration::protobuf::{RepeatedRevision, Revision}; -use protobuf::Message; -use std::sync::Arc; - -pub struct DocumentKVPersistence { - inner: Arc, -} - -impl std::ops::Deref for DocumentKVPersistence { - type Target = Arc; - - fn deref(&self) -> &Self::Target { &self.inner } -} - -impl std::ops::DerefMut for DocumentKVPersistence { - fn deref_mut(&mut self) -> &mut Self::Target { &mut self.inner } -} - -impl DocumentKVPersistence { - pub(crate) fn new(kv_store: Arc) -> Self { DocumentKVPersistence { inner: kv_store } } - - pub(crate) async fn set_revision(&self, revision: Revision) -> Result<(), ServerError> { - let key = revision.rev_id.to_string(); - let bytes = revision.write_to_bytes()?; - let _ = self.inner.set(&key, Bytes::from(bytes)).await?; - Ok(()) - } - - pub(crate) async fn batch_get_revisions(&self, rev_ids: Vec) -> Result { - let keys = rev_ids - .into_iter() - .map(|rev_id| rev_id.to_string()) - .collect::>(); - - let items = self.inner.batch_get(keys).await?; - let revisions = items - .into_iter() - .filter_map(|kv| parse_from_bytes::(&kv.value).ok()) - .collect::>(); - - let mut repeated_revision = RepeatedRevision::new(); - repeated_revision.set_items(revisions.into()); - Ok(repeated_revision) - } -} diff --git a/backend/src/services/document/persistence/kv_store.rs b/backend/src/services/document/persistence/kv_store.rs new file mode 100644 index 0000000000..4c91ef23a6 --- /dev/null +++ b/backend/src/services/document/persistence/kv_store.rs @@ -0,0 +1,91 @@ +use crate::{services::kv::KVStore, util::serde_ext::parse_from_bytes}; +use backend_service::errors::ServerError; +use bytes::Bytes; +use flowy_collaboration::protobuf::{RepeatedRevision, Revision}; +use futures::stream::{self, StreamExt}; +use protobuf::Message; +use std::sync::Arc; + +pub struct DocumentKVPersistence { + inner: Arc, +} + +impl std::ops::Deref for DocumentKVPersistence { + type Target = Arc; + + fn deref(&self) -> &Self::Target { &self.inner } +} + +impl std::ops::DerefMut for DocumentKVPersistence { + fn deref_mut(&mut self) -> &mut Self::Target { &mut self.inner } +} + +impl DocumentKVPersistence { + pub(crate) fn new(kv_store: Arc) -> Self { DocumentKVPersistence { inner: kv_store } } + + pub(crate) async fn batch_set_revision(&self, revisions: Vec) -> Result<(), ServerError> { + let kv_store = self.inner.clone(); + + let f = |revision: Revision, kv_store: Arc| async move { + let key = make_revision_key(&revision.doc_id, revision.rev_id); + let bytes = revision.write_to_bytes().unwrap(); + let _ = kv_store.set(&key, Bytes::from(bytes)).await; + }; + + stream::iter(revisions) + .for_each_concurrent(None, |revision| f(revision, kv_store.clone())) + .await; + Ok(()) + } + + pub(crate) async fn batch_get_revisions>>>( + &self, + doc_id: &str, + rev_ids: T, + ) -> Result { + let rev_ids = rev_ids.into(); + let items = match rev_ids { + None => self.inner.batch_get_key_start_with(doc_id).await?, + Some(rev_ids) => { + let keys = rev_ids + .into_iter() + .map(|rev_id| make_revision_key(doc_id, rev_id)) + .collect::>(); + self.inner.batch_get(keys).await? + }, + }; + + let revisions = items + .into_iter() + .filter_map(|kv| parse_from_bytes::(&kv.value).ok()) + .collect::>(); + + let mut repeated_revision = RepeatedRevision::new(); + repeated_revision.set_items(revisions.into()); + Ok(repeated_revision) + } + + pub(crate) async fn batch_delete_revisions>>>( + &self, + doc_id: &str, + rev_ids: T, + ) -> Result<(), ServerError> { + match rev_ids.into() { + None => { + let _ = self.inner.batch_delete_key_start_with(doc_id).await?; + Ok(()) + }, + Some(rev_ids) => { + let keys = rev_ids + .into_iter() + .map(|rev_id| make_revision_key(doc_id, rev_id)) + .collect::>(); + let _ = self.inner.batch_delete(keys).await?; + Ok(()) + }, + } + } +} + +#[inline] +fn make_revision_key(doc_id: &str, rev_id: i64) -> String { format!("{}:{}", doc_id, rev_id) } diff --git a/backend/src/services/document/persistence/mod.rs b/backend/src/services/document/persistence/mod.rs index 2f958e7d67..c68a1dc3a8 100644 --- a/backend/src/services/document/persistence/mod.rs +++ b/backend/src/services/document/persistence/mod.rs @@ -1,5 +1,5 @@ -mod kv; +mod kv_store; mod postgres; -pub use kv::*; +pub use kv_store::*; pub use postgres::*; diff --git a/backend/src/services/document/persistence/postgres.rs b/backend/src/services/document/persistence/postgres.rs index 7f527cbdd1..2b61eda6d1 100644 --- a/backend/src/services/document/persistence/postgres.rs +++ b/backend/src/services/document/persistence/postgres.rs @@ -1,127 +1,42 @@ -use crate::{ - context::FlowyPersistence, - services::{document::persistence::DocumentKVPersistence, kv_store::KVStore}, - util::sqlx_ext::{map_sqlx_error, DBTransaction, SqlBuilder}, -}; -use anyhow::Context; -use backend_service::errors::ServerError; -use flowy_collaboration::protobuf::{CreateDocParams, Doc, DocIdentifier, UpdateDocParams}; +use crate::{context::FlowyPersistence, services::document::persistence::DocumentKVPersistence}; + +use backend_service::errors::{internal_error, ServerError}; +use flowy_collaboration::protobuf::{CreateDocParams, Doc, DocIdentifier, RepeatedRevision, ResetDocumentParams}; +use lib_ot::{core::OperationTransformable, rich_text::RichTextDelta}; use protobuf::Message; -use sqlx::{postgres::PgArguments, PgPool, Postgres}; +use sqlx::PgPool; use std::sync::Arc; use uuid::Uuid; const DOC_TABLE: &str = "doc_table"; -#[tracing::instrument(level = "debug", skip(transaction, kv_store), err)] -pub(crate) async fn create_doc_with_transaction( - transaction: &mut DBTransaction<'_>, - kv_store: Arc, - params: CreateDocParams, -) -> Result<(), ServerError> { - let uuid = Uuid::parse_str(¶ms.id)?; - let (sql, args) = SqlBuilder::create(DOC_TABLE) - .add_field_with_arg("id", uuid) - .add_field_with_arg("rev_id", 0) - .build()?; - - // TODO kv - // kv_store.set_revision() - let _ = sqlx::query_with(&sql, args) - .execute(transaction) - .await - .map_err(map_sqlx_error)?; - - Ok(()) -} - +#[tracing::instrument(level = "debug", skip(kv_store), err)] pub(crate) async fn create_doc( - persistence: &Arc, - params: CreateDocParams, + kv_store: &Arc, + mut params: CreateDocParams, ) -> Result<(), ServerError> { - let pool = persistence.pg_pool(); - let kv_store = persistence.kv_store(); - let mut transaction = pool - .begin() - .await - .context("Failed to acquire a Postgres connection to create document")?; - - let _ = create_doc_with_transaction(&mut transaction, kv_store, params).await?; - - transaction - .commit() - .await - .context("Failed to commit SQL transaction to create document.")?; - + let revisions = params.take_revisions().take_items(); + let _ = kv_store.batch_set_revision(revisions.into()).await?; Ok(()) } #[tracing::instrument(level = "debug", skip(persistence), err)] pub(crate) async fn read_doc(persistence: &Arc, params: DocIdentifier) -> Result { - let doc_id = Uuid::parse_str(¶ms.doc_id)?; - let mut transaction = pool - .begin() - .await - .context("Failed to acquire a Postgres connection to read document")?; + let _ = Uuid::parse_str(¶ms.doc_id)?; - 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 _table = sqlx::query_as_with::(&sql, args) - .fetch_one(&mut transaction) - .await - .map_err(map_sqlx_error)?; - - // TODO: kv - panic!("") - - // transaction - // .commit() - // .await - // .context("Failed to commit SQL transaction to read document.")?; - // - // Ok(doc) + let kv_store = persistence.kv_store(); + let revisions = kv_store.batch_get_revisions(¶ms.doc_id, None).await?; + make_doc_from_revisions(¶ms.doc_id, revisions) } -#[tracing::instrument(level = "debug", skip(pool, params), fields(delta), err)] -pub async fn update_doc(pool: &PgPool, mut params: UpdateDocParams) -> Result<(), ServerError> { - let doc_id = Uuid::parse_str(¶ms.doc_id)?; - let mut transaction = pool - .begin() - .await - .context("Failed to acquire a Postgres connection to update document")?; - - let data = Some(params.take_data()); - - tracing::Span::current().record("delta", &data.as_ref().unwrap_or(&"".to_owned()).as_str()); - - let (sql, args) = SqlBuilder::update(DOC_TABLE) - .add_some_arg("data", data) - .add_field_with_arg("rev_id", params.rev_id) - .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 document.")?; - - Ok(()) +#[tracing::instrument(level = "debug", skip(_pool, _params), fields(delta), err)] +pub async fn reset_document(_pool: &PgPool, _params: ResetDocumentParams) -> Result<(), ServerError> { + unimplemented!() } -#[tracing::instrument(level = "debug", skip(transaction), err)] -pub(crate) async fn delete_doc(transaction: &mut DBTransaction<'_>, doc_id: Uuid) -> Result<(), ServerError> { - let (sql, args) = SqlBuilder::delete(DOC_TABLE).and_where_eq("id", doc_id).build()?; - let _ = sqlx::query_with(&sql, args) - .execute(transaction) - .await - .map_err(map_sqlx_error)?; +#[tracing::instrument(level = "debug", skip(kv_store), err)] +pub(crate) async fn delete_doc(kv_store: &Arc, doc_id: Uuid) -> Result<(), ServerError> { + let _ = kv_store.batch_delete_revisions(&doc_id.to_string(), None).await?; Ok(()) } @@ -132,11 +47,23 @@ struct DocTable { rev_id: i64, } -// impl std::convert::From for Doc { -// fn from(table: DocTable) -> Self { -// let mut doc = Doc::new(); -// doc.set_id(table.id.to_string()); -// doc.set_rev_id(table.rev_id); -// doc -// } -// } +fn make_doc_from_revisions(doc_id: &str, mut revisions: RepeatedRevision) -> Result { + let revisions = revisions.take_items(); + let mut document_delta = RichTextDelta::new(); + let mut base_rev_id = 0; + let mut rev_id = 0; + // TODO: generate delta from revision should be wrapped into function. + for revision in revisions { + base_rev_id = revision.base_rev_id; + rev_id = revision.rev_id; + let delta = RichTextDelta::from_bytes(revision.delta_data).map_err(internal_error)?; + document_delta = document_delta.compose(&delta).map_err(internal_error)?; + } + let text = document_delta.to_json(); + let mut doc = Doc::new(); + doc.set_id(doc_id.to_owned()); + doc.set_text(text); + doc.set_base_rev_id(base_rev_id); + doc.set_rev_id(rev_id); + Ok(doc) +} diff --git a/backend/src/services/document/router.rs b/backend/src/services/document/router.rs index 873b829069..271a77b101 100644 --- a/backend/src/services/document/router.rs +++ b/backend/src/services/document/router.rs @@ -1,6 +1,6 @@ use crate::{ context::FlowyPersistence, - services::document::persistence::{create_doc, read_doc, update_doc}, + services::document::persistence::{create_doc, read_doc}, util::serde_ext::parse_from_payload, }; use actix_web::{ @@ -8,21 +8,22 @@ use actix_web::{ HttpResponse, }; use backend_service::{errors::ServerError, response::FlowyResponse}; -use flowy_collaboration::protobuf::{CreateDocParams, DocIdentifier, UpdateDocParams}; +use flowy_collaboration::protobuf::{CreateDocParams, DocIdentifier, ResetDocumentParams}; use sqlx::PgPool; use std::sync::Arc; -pub async fn create_handler( +pub async fn create_document_handler( payload: Payload, persistence: Data>, ) -> Result { let params: CreateDocParams = parse_from_payload(payload).await?; - let _ = create_doc(persistence.get_ref(), params).await?; + let kv_store = persistence.kv_store(); + let _ = create_doc(&kv_store, params).await?; Ok(FlowyResponse::success().into()) } #[tracing::instrument(level = "debug", skip(payload, persistence), err)] -pub async fn read_handler( +pub async fn read_document_handler( payload: Payload, persistence: Data>, ) -> Result { @@ -32,8 +33,8 @@ pub async fn read_handler( Ok(response.into()) } -pub async fn update_handler(payload: Payload, pool: Data) -> Result { - let params: UpdateDocParams = parse_from_payload(payload).await?; - let _ = update_doc(pool.get_ref(), params).await?; - Ok(FlowyResponse::success().into()) +pub async fn reset_document_handler(payload: Payload, _pool: Data) -> Result { + let _params: ResetDocumentParams = parse_from_payload(payload).await?; + // Ok(FlowyResponse::success().into()) + unimplemented!() } diff --git a/backend/src/services/document/ws_actor.rs b/backend/src/services/document/ws_actor.rs index 70bd7cbcab..0c4d823f9d 100644 --- a/backend/src/services/document/ws_actor.rs +++ b/backend/src/services/document/ws_actor.rs @@ -1,27 +1,25 @@ use crate::{ - services::{ - document::persistence::update_doc, - web_socket::{entities::Socket, WSClientData, WSMessageAdaptor, WSUser}, - }, + services::web_socket::{entities::Socket, WSClientData, WSMessageAdaptor, WSUser}, util::serde_ext::{md5, parse_from_bytes}, }; use actix_rt::task::spawn_blocking; +use crate::context::FlowyPersistence; use async_stream::stream; use backend_service::errors::{internal_error, Result, ServerError}; use flowy_collaboration::{ core::sync::{RevisionUser, ServerDocumentManager, SyncResponse}, - protobuf::{DocumentWSData, DocumentWSDataType, NewDocumentUser, Revision, UpdateDocParams}, + protobuf::{DocumentWSData, DocumentWSDataType, NewDocumentUser, Revision}, }; use futures::stream::StreamExt; -use sqlx::PgPool; + use std::{convert::TryInto, sync::Arc}; use tokio::sync::{mpsc, oneshot}; pub enum WSActorMessage { ClientData { client_data: WSClientData, - pool: PgPool, + persistence: Arc, ret: oneshot::Sender>, }, } @@ -59,13 +57,17 @@ impl DocumentWebSocketActor { async fn handle_message(&self, msg: WSActorMessage) { match msg { - WSActorMessage::ClientData { client_data, pool, ret } => { - let _ = ret.send(self.handle_client_data(client_data, pool).await); + WSActorMessage::ClientData { + client_data, + persistence, + ret, + } => { + let _ = ret.send(self.handle_client_data(client_data, persistence).await); }, } } - async fn handle_client_data(&self, client_data: WSClientData, pg_pool: PgPool) -> Result<()> { + async fn handle_client_data(&self, client_data: WSClientData, persistence: Arc) -> Result<()> { let WSClientData { user, socket, data } = client_data; let document_data = spawn_blocking(move || { let document_data: DocumentWSData = parse_from_bytes(&data)?; @@ -81,7 +83,11 @@ impl DocumentWebSocketActor { document_data.ty ); - let user = Arc::new(ServerDocUser { user, socket, pg_pool }); + let user = Arc::new(ServerDocUser { + user, + socket, + persistence, + }); let result = match &document_data.ty { DocumentWSDataType::Ack => Ok(()), DocumentWSDataType::PushRev => self.handle_pushed_rev(user, document_data.data).await, @@ -147,11 +153,20 @@ fn verify_md5(revision: &Revision) -> Result<()> { Ok(()) } -#[derive(Clone, Debug)] +#[derive(Clone)] pub struct ServerDocUser { pub user: Arc, pub(crate) socket: Socket, - pub pg_pool: PgPool, + pub persistence: Arc, +} + +impl std::fmt::Debug for ServerDocUser { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + f.debug_struct("ServerDocUser") + .field("user", &self.user) + .field("socket", &self.socket) + .finish() + } } impl RevisionUser for ServerDocUser { @@ -171,18 +186,11 @@ impl RevisionUser for ServerDocUser { let msg: WSMessageAdaptor = data.into(); self.socket.try_send(msg).map_err(internal_error) }, - SyncResponse::NewRevision { - rev_id, - doc_id, - doc_json, - } => { - let pg_pool = self.pg_pool.clone(); + SyncResponse::NewRevision(revision) => { + let kv_store = self.persistence.kv_store(); tokio::task::spawn(async move { - let mut params = UpdateDocParams::new(); - params.set_doc_id(doc_id); - params.set_data(doc_json); - params.set_rev_id(rev_id); - match update_doc(&pg_pool, params).await { + let revision: flowy_collaboration::protobuf::Revision = revision.try_into().unwrap(); + match kv_store.batch_set_revision(vec![revision]).await { Ok(_) => {}, Err(e) => log::error!("{}", e), } diff --git a/backend/src/services/kv_store/kv.rs b/backend/src/services/kv/kv.rs similarity index 60% rename from backend/src/services/kv_store/kv.rs rename to backend/src/services/kv/kv.rs index ffe7f3c415..a1995dffcf 100644 --- a/backend/src/services/kv_store/kv.rs +++ b/backend/src/services/kv/kv.rs @@ -1,5 +1,5 @@ use crate::{ - services::kv_store::{KVStore, KeyValue}, + services::kv::{KVStore, KeyValue}, util::sqlx_ext::{map_sqlx_error, SqlBuilder}, }; @@ -8,7 +8,13 @@ use backend_service::errors::ServerError; use bytes::Bytes; use lib_infra::future::FutureResultSend; use sql_builder::{quote, SqlBuilder as RawSqlBuilder}; -use sqlx::{postgres::PgArguments, Error, PgPool, Postgres, Row}; +use sqlx::{ + postgres::{PgArguments, PgRow}, + Error, + PgPool, + Postgres, + Row, +}; const KV_TABLE: &str = "kv_table"; @@ -137,16 +143,7 @@ impl KVStore for PostgresKV { .fetch_all(&mut transaction) .await .map_err(map_sqlx_error)?; - let kvs = rows - .into_iter() - .map(|row| { - let bytes: Vec = row.get("blob"); - KeyValue { - key: row.get("id"), - value: Bytes::from(bytes), - } - }) - .collect::>(); + let kvs = rows_to_key_values(rows); transaction .commit() @@ -156,6 +153,100 @@ impl KVStore for PostgresKV { Ok::, ServerError>(kvs) }) } + + fn batch_get_key_start_with(&self, prefix: &str) -> FutureResultSend, ServerError> { + let pg_pool = self.pg_pool.clone(); + let prefix = prefix.to_owned(); + FutureResultSend::new(async move { + let mut transaction = pg_pool + .begin() + .await + .context("[KV]:Failed to acquire a Postgres connection")?; + + let sql = RawSqlBuilder::select_from(KV_TABLE) + .field("id") + .field("blob") + .and_where_like_left("id", &prefix) + .sql()?; + + let rows = sqlx::query(&sql) + .fetch_all(&mut transaction) + .await + .map_err(map_sqlx_error)?; + + let kvs = rows_to_key_values(rows); + + transaction + .commit() + .await + .context("[KV]:Failed to commit SQL transaction.")?; + + Ok::, ServerError>(kvs) + }) + } + + fn batch_delete(&self, keys: Vec) -> FutureResultSend<(), ServerError> { + let pg_pool = self.pg_pool.clone(); + FutureResultSend::new(async move { + let mut transaction = pg_pool + .begin() + .await + .context("[KV]:Failed to acquire a Postgres connection")?; + + let sql = RawSqlBuilder::delete_from(KV_TABLE).and_where_in("id", &keys).sql()?; + + let _ = sqlx::query(&sql) + .execute(&mut transaction) + .await + .map_err(map_sqlx_error)?; + + transaction + .commit() + .await + .context("[KV]:Failed to commit SQL transaction.")?; + + Ok::<(), ServerError>(()) + }) + } + + fn batch_delete_key_start_with(&self, keyword: &str) -> FutureResultSend<(), ServerError> { + let pg_pool = self.pg_pool.clone(); + let keyword = keyword.to_owned(); + FutureResultSend::new(async move { + let mut transaction = pg_pool + .begin() + .await + .context("[KV]:Failed to acquire a Postgres connection")?; + + let sql = RawSqlBuilder::delete_from(KV_TABLE) + .and_where_like_left("id", &keyword) + .sql()?; + + let _ = sqlx::query(&sql) + .execute(&mut transaction) + .await + .map_err(map_sqlx_error)?; + + transaction + .commit() + .await + .context("[KV]:Failed to commit SQL transaction.")?; + + Ok::<(), ServerError>(()) + }) + } +} + +fn rows_to_key_values(rows: Vec) -> Vec { + rows.into_iter() + .map(|row| { + let bytes: Vec = row.get("blob"); + KeyValue { + key: row.get("id"), + value: Bytes::from(bytes), + } + }) + .collect::>() } #[derive(Debug, Clone, sqlx::FromRow)] diff --git a/backend/src/services/kv_store/mod.rs b/backend/src/services/kv/mod.rs similarity index 70% rename from backend/src/services/kv_store/mod.rs rename to backend/src/services/kv/mod.rs index 8e218e32ee..d3a010e4ad 100644 --- a/backend/src/services/kv_store/mod.rs +++ b/backend/src/services/kv/mod.rs @@ -18,4 +18,8 @@ pub trait KVStore: Send + Sync { fn delete(&self, key: &str) -> FutureResultSend<(), ServerError>; fn batch_set(&self, kvs: Vec) -> FutureResultSend<(), ServerError>; fn batch_get(&self, keys: Vec) -> FutureResultSend, ServerError>; + fn batch_get_key_start_with(&self, keyword: &str) -> FutureResultSend, ServerError>; + + fn batch_delete(&self, keys: Vec) -> FutureResultSend<(), ServerError>; + fn batch_delete_key_start_with(&self, keyword: &str) -> FutureResultSend<(), ServerError>; } diff --git a/backend/src/services/mod.rs b/backend/src/services/mod.rs index 400c29b088..094f796a65 100644 --- a/backend/src/services/mod.rs +++ b/backend/src/services/mod.rs @@ -1,5 +1,5 @@ pub mod core; pub mod document; -pub mod kv_store; +pub mod kv; pub mod user; pub mod web_socket; diff --git a/backend/tests/api_test/kv_test.rs b/backend/tests/api_test/kv_test.rs index 7b0491d0a6..f08485d02a 100644 --- a/backend/tests/api_test/kv_test.rs +++ b/backend/tests/api_test/kv_test.rs @@ -1,5 +1,5 @@ use crate::util::helper::spawn_server; -use backend::services::kv_store::KeyValue; +use backend::services::kv::KeyValue; use std::str; #[actix_rt::test] diff --git a/backend/tests/document_test/edit_script.rs b/backend/tests/document_test/edit_script.rs index c1e11736a1..3f30d3556c 100644 --- a/backend/tests/document_test/edit_script.rs +++ b/backend/tests/document_test/edit_script.rs @@ -11,7 +11,7 @@ use std::sync::Arc; use tokio::time::{sleep, Duration}; // use crate::helper::*; use crate::util::helper::{spawn_server, TestServer}; -use flowy_collaboration::{entities::doc::DocIdentifier, protobuf::UpdateDocParams}; +use flowy_collaboration::{entities::doc::DocIdentifier, protobuf::ResetDocumentParams}; use lib_ot::rich_text::{RichTextAttribute, RichTextDelta}; use parking_lot::RwLock; use lib_ot::core::Interval; @@ -167,7 +167,7 @@ async fn create_doc(flowy_test: &FlowySDKTest) -> String { } async fn save_doc(doc_id: &str, json: String, rev_id: i64, pool: Data) { - let mut params = UpdateDocParams::new(); + let mut params = ResetDocumentParams::new(); params.set_doc_id(doc_id.to_owned()); params.set_data(json); params.set_rev_id(rev_id); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/doc.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/doc.pb.dart index a78d0d1ca0..d9fe2c6028 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/doc.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/doc.pb.dart @@ -15,21 +15,21 @@ import 'revision.pb.dart' as $0; class CreateDocParams extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CreateDocParams', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') - ..aOM<$0.RepeatedRevision>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data', subBuilder: $0.RepeatedRevision.create) + ..aOM<$0.RepeatedRevision>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'revisions', subBuilder: $0.RepeatedRevision.create) ..hasRequiredFields = false ; CreateDocParams._() : super(); factory CreateDocParams({ $core.String? id, - $0.RepeatedRevision? data, + $0.RepeatedRevision? revisions, }) { final _result = create(); if (id != null) { _result.id = id; } - if (data != null) { - _result.data = data; + if (revisions != null) { + _result.revisions = revisions; } return _result; } @@ -64,21 +64,21 @@ class CreateDocParams extends $pb.GeneratedMessage { void clearId() => clearField(1); @$pb.TagNumber(2) - $0.RepeatedRevision get data => $_getN(1); + $0.RepeatedRevision get revisions => $_getN(1); @$pb.TagNumber(2) - set data($0.RepeatedRevision v) { setField(2, v); } + set revisions($0.RepeatedRevision v) { setField(2, v); } @$pb.TagNumber(2) - $core.bool hasData() => $_has(1); + $core.bool hasRevisions() => $_has(1); @$pb.TagNumber(2) - void clearData() => clearField(2); + void clearRevisions() => clearField(2); @$pb.TagNumber(2) - $0.RepeatedRevision ensureData() => $_ensure(1); + $0.RepeatedRevision ensureRevisions() => $_ensure(1); } class Doc extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Doc', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') - ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'text') ..aInt64(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'revId') ..aInt64(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'baseRevId') ..hasRequiredFields = false @@ -87,7 +87,7 @@ class Doc extends $pb.GeneratedMessage { Doc._() : super(); factory Doc({ $core.String? id, - $core.String? data, + $core.String? text, $fixnum.Int64? revId, $fixnum.Int64? baseRevId, }) { @@ -95,8 +95,8 @@ class Doc extends $pb.GeneratedMessage { if (id != null) { _result.id = id; } - if (data != null) { - _result.data = data; + if (text != null) { + _result.text = text; } if (revId != null) { _result.revId = revId; @@ -137,13 +137,13 @@ class Doc extends $pb.GeneratedMessage { void clearId() => clearField(1); @$pb.TagNumber(2) - $core.String get data => $_getSZ(1); + $core.String get text => $_getSZ(1); @$pb.TagNumber(2) - set data($core.String v) { $_setString(1, v); } + set text($core.String v) { $_setString(1, v); } @$pb.TagNumber(2) - $core.bool hasData() => $_has(1); + $core.bool hasText() => $_has(1); @$pb.TagNumber(2) - void clearData() => clearField(2); + void clearText() => clearField(2); @$pb.TagNumber(3) $fixnum.Int64 get revId => $_getI64(2); @@ -164,52 +164,47 @@ class Doc extends $pb.GeneratedMessage { void clearBaseRevId() => clearField(4); } -class UpdateDocParams extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'UpdateDocParams', createEmptyInstance: create) +class ResetDocumentParams extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'ResetDocumentParams', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'docId') - ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data') - ..aInt64(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'revId') + ..aOM<$0.RepeatedRevision>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'revisions', subBuilder: $0.RepeatedRevision.create) ..hasRequiredFields = false ; - UpdateDocParams._() : super(); - factory UpdateDocParams({ + ResetDocumentParams._() : super(); + factory ResetDocumentParams({ $core.String? docId, - $core.String? data, - $fixnum.Int64? revId, + $0.RepeatedRevision? revisions, }) { final _result = create(); if (docId != null) { _result.docId = docId; } - if (data != null) { - _result.data = data; - } - if (revId != null) { - _result.revId = revId; + if (revisions != null) { + _result.revisions = revisions; } return _result; } - factory UpdateDocParams.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory UpdateDocParams.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + factory ResetDocumentParams.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory ResetDocumentParams.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); @$core.Deprecated( 'Using this can add significant overhead to your binary. ' 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' 'Will be removed in next major version') - UpdateDocParams clone() => UpdateDocParams()..mergeFromMessage(this); + ResetDocumentParams clone() => ResetDocumentParams()..mergeFromMessage(this); @$core.Deprecated( 'Using this can add significant overhead to your binary. ' 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' 'Will be removed in next major version') - UpdateDocParams copyWith(void Function(UpdateDocParams) updates) => super.copyWith((message) => updates(message as UpdateDocParams)) as UpdateDocParams; // ignore: deprecated_member_use + ResetDocumentParams copyWith(void Function(ResetDocumentParams) updates) => super.copyWith((message) => updates(message as ResetDocumentParams)) as ResetDocumentParams; // ignore: deprecated_member_use $pb.BuilderInfo get info_ => _i; @$core.pragma('dart2js:noInline') - static UpdateDocParams create() => UpdateDocParams._(); - UpdateDocParams createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); + static ResetDocumentParams create() => ResetDocumentParams._(); + ResetDocumentParams createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); @$core.pragma('dart2js:noInline') - static UpdateDocParams getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static UpdateDocParams? _defaultInstance; + static ResetDocumentParams getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static ResetDocumentParams? _defaultInstance; @$pb.TagNumber(1) $core.String get docId => $_getSZ(0); @@ -221,22 +216,15 @@ class UpdateDocParams extends $pb.GeneratedMessage { void clearDocId() => clearField(1); @$pb.TagNumber(2) - $core.String get data => $_getSZ(1); + $0.RepeatedRevision get revisions => $_getN(1); @$pb.TagNumber(2) - set data($core.String v) { $_setString(1, v); } + set revisions($0.RepeatedRevision v) { setField(2, v); } @$pb.TagNumber(2) - $core.bool hasData() => $_has(1); + $core.bool hasRevisions() => $_has(1); @$pb.TagNumber(2) - void clearData() => clearField(2); - - @$pb.TagNumber(3) - $fixnum.Int64 get revId => $_getI64(2); - @$pb.TagNumber(3) - set revId($fixnum.Int64 v) { $_setInt64(2, v); } - @$pb.TagNumber(3) - $core.bool hasRevId() => $_has(2); - @$pb.TagNumber(3) - void clearRevId() => clearField(3); + void clearRevisions() => clearField(2); + @$pb.TagNumber(2) + $0.RepeatedRevision ensureRevisions() => $_ensure(1); } class DocDelta extends $pb.GeneratedMessage { diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/doc.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/doc.pbjson.dart index f505b96005..8078d0f360 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/doc.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/doc.pbjson.dart @@ -13,37 +13,36 @@ const CreateDocParams$json = const { '1': 'CreateDocParams', '2': const [ const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, - const {'1': 'data', '3': 2, '4': 1, '5': 11, '6': '.RepeatedRevision', '10': 'data'}, + const {'1': 'revisions', '3': 2, '4': 1, '5': 11, '6': '.RepeatedRevision', '10': 'revisions'}, ], }; /// Descriptor for `CreateDocParams`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List createDocParamsDescriptor = $convert.base64Decode('Cg9DcmVhdGVEb2NQYXJhbXMSDgoCaWQYASABKAlSAmlkEiUKBGRhdGEYAiABKAsyES5SZXBlYXRlZFJldmlzaW9uUgRkYXRh'); +final $typed_data.Uint8List createDocParamsDescriptor = $convert.base64Decode('Cg9DcmVhdGVEb2NQYXJhbXMSDgoCaWQYASABKAlSAmlkEi8KCXJldmlzaW9ucxgCIAEoCzIRLlJlcGVhdGVkUmV2aXNpb25SCXJldmlzaW9ucw=='); @$core.Deprecated('Use docDescriptor instead') const Doc$json = const { '1': 'Doc', '2': const [ const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, - const {'1': 'data', '3': 2, '4': 1, '5': 9, '10': 'data'}, + const {'1': 'text', '3': 2, '4': 1, '5': 9, '10': 'text'}, const {'1': 'rev_id', '3': 3, '4': 1, '5': 3, '10': 'revId'}, const {'1': 'base_rev_id', '3': 4, '4': 1, '5': 3, '10': 'baseRevId'}, ], }; /// Descriptor for `Doc`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List docDescriptor = $convert.base64Decode('CgNEb2MSDgoCaWQYASABKAlSAmlkEhIKBGRhdGEYAiABKAlSBGRhdGESFQoGcmV2X2lkGAMgASgDUgVyZXZJZBIeCgtiYXNlX3Jldl9pZBgEIAEoA1IJYmFzZVJldklk'); -@$core.Deprecated('Use updateDocParamsDescriptor instead') -const UpdateDocParams$json = const { - '1': 'UpdateDocParams', +final $typed_data.Uint8List docDescriptor = $convert.base64Decode('CgNEb2MSDgoCaWQYASABKAlSAmlkEhIKBHRleHQYAiABKAlSBHRleHQSFQoGcmV2X2lkGAMgASgDUgVyZXZJZBIeCgtiYXNlX3Jldl9pZBgEIAEoA1IJYmFzZVJldklk'); +@$core.Deprecated('Use resetDocumentParamsDescriptor instead') +const ResetDocumentParams$json = const { + '1': 'ResetDocumentParams', '2': const [ const {'1': 'doc_id', '3': 1, '4': 1, '5': 9, '10': 'docId'}, - const {'1': 'data', '3': 2, '4': 1, '5': 9, '10': 'data'}, - const {'1': 'rev_id', '3': 3, '4': 1, '5': 3, '10': 'revId'}, + const {'1': 'revisions', '3': 2, '4': 1, '5': 11, '6': '.RepeatedRevision', '10': 'revisions'}, ], }; -/// Descriptor for `UpdateDocParams`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List updateDocParamsDescriptor = $convert.base64Decode('Cg9VcGRhdGVEb2NQYXJhbXMSFQoGZG9jX2lkGAEgASgJUgVkb2NJZBISCgRkYXRhGAIgASgJUgRkYXRhEhUKBnJldl9pZBgDIAEoA1IFcmV2SWQ='); +/// Descriptor for `ResetDocumentParams`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List resetDocumentParamsDescriptor = $convert.base64Decode('ChNSZXNldERvY3VtZW50UGFyYW1zEhUKBmRvY19pZBgBIAEoCVIFZG9jSWQSLwoJcmV2aXNpb25zGAIgASgLMhEuUmVwZWF0ZWRSZXZpc2lvblIJcmV2aXNpb25z'); @$core.Deprecated('Use docDeltaDescriptor instead') const DocDelta$json = const { '1': 'DocDelta', diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-core-data-model/view_create.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-core-data-model/view_create.pb.dart index 92f16237d3..0b5d710a25 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-core-data-model/view_create.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-core-data-model/view_create.pb.dart @@ -137,7 +137,6 @@ class CreateViewParams extends $pb.GeneratedMessage { ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'desc') ..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'thumbnail') ..e(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'viewType', $pb.PbFieldType.OE, defaultOrMaker: ViewType.Blank, valueOf: ViewType.valueOf, enumValues: ViewType.values) - ..aOS(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data') ..hasRequiredFields = false ; @@ -148,7 +147,6 @@ class CreateViewParams extends $pb.GeneratedMessage { $core.String? desc, $core.String? thumbnail, ViewType? viewType, - $core.String? data, }) { final _result = create(); if (belongToId != null) { @@ -166,9 +164,6 @@ class CreateViewParams extends $pb.GeneratedMessage { if (viewType != null) { _result.viewType = viewType; } - if (data != null) { - _result.data = data; - } return _result; } factory CreateViewParams.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); @@ -236,15 +231,6 @@ class CreateViewParams extends $pb.GeneratedMessage { $core.bool hasViewType() => $_has(4); @$pb.TagNumber(5) void clearViewType() => clearField(5); - - @$pb.TagNumber(6) - $core.String get data => $_getSZ(5); - @$pb.TagNumber(6) - set data($core.String v) { $_setString(5, v); } - @$pb.TagNumber(6) - $core.bool hasData() => $_has(5); - @$pb.TagNumber(6) - void clearData() => clearField(6); } class View extends $pb.GeneratedMessage { diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-core-data-model/view_create.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-core-data-model/view_create.pbjson.dart index 904e984ba0..44e92472f2 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-core-data-model/view_create.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-core-data-model/view_create.pbjson.dart @@ -45,12 +45,11 @@ const CreateViewParams$json = const { const {'1': 'desc', '3': 3, '4': 1, '5': 9, '10': 'desc'}, const {'1': 'thumbnail', '3': 4, '4': 1, '5': 9, '10': 'thumbnail'}, const {'1': 'view_type', '3': 5, '4': 1, '5': 14, '6': '.ViewType', '10': 'viewType'}, - const {'1': 'data', '3': 6, '4': 1, '5': 9, '10': 'data'}, ], }; /// Descriptor for `CreateViewParams`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List createViewParamsDescriptor = $convert.base64Decode('ChBDcmVhdGVWaWV3UGFyYW1zEiAKDGJlbG9uZ190b19pZBgBIAEoCVIKYmVsb25nVG9JZBISCgRuYW1lGAIgASgJUgRuYW1lEhIKBGRlc2MYAyABKAlSBGRlc2MSHAoJdGh1bWJuYWlsGAQgASgJUgl0aHVtYm5haWwSJgoJdmlld190eXBlGAUgASgOMgkuVmlld1R5cGVSCHZpZXdUeXBlEhIKBGRhdGEYBiABKAlSBGRhdGE='); +final $typed_data.Uint8List createViewParamsDescriptor = $convert.base64Decode('ChBDcmVhdGVWaWV3UGFyYW1zEiAKDGJlbG9uZ190b19pZBgBIAEoCVIKYmVsb25nVG9JZBISCgRuYW1lGAIgASgJUgRuYW1lEhIKBGRlc2MYAyABKAlSBGRlc2MSHAoJdGh1bWJuYWlsGAQgASgJUgl0aHVtYm5haWwSJgoJdmlld190eXBlGAUgASgOMgkuVmlld1R5cGVSCHZpZXdUeXBl'); @$core.Deprecated('Use viewDescriptor instead') const View$json = const { '1': 'View', diff --git a/frontend/rust-lib/flowy-core/src/services/view/controller.rs b/frontend/rust-lib/flowy-core/src/services/view/controller.rs index cd363c3cb1..84982c6a76 100644 --- a/frontend/rust-lib/flowy-core/src/services/view/controller.rs +++ b/frontend/rust-lib/flowy-core/src/services/view/controller.rs @@ -138,7 +138,7 @@ impl ViewController { #[tracing::instrument(level = "debug", skip(self, params), fields(doc_id = %params.doc_id), err)] pub(crate) async fn duplicate_view(&self, params: DocIdentifier) -> Result<(), FlowyError> { let view: View = ViewTableSql::read_view(¶ms.doc_id, &*self.database.db_connection()?)?.into(); - let delta_data = self + let _delta_data = self .document .read_document_data(params, self.database.db_pool()?) .await?; @@ -149,7 +149,6 @@ impl ViewController { desc: view.desc.clone(), thumbnail: "".to_owned(), view_type: view.view_type.clone(), - data: delta_data.data, }; let _ = self.create_view_from_params(duplicate_params).await?; diff --git a/frontend/rust-lib/flowy-document/src/services/doc/revision/manager.rs b/frontend/rust-lib/flowy-document/src/services/doc/revision/manager.rs index 26f6a63e0a..7521d0487c 100644 --- a/frontend/rust-lib/flowy-document/src/services/doc/revision/manager.rs +++ b/frontend/rust-lib/flowy-document/src/services/doc/revision/manager.rs @@ -80,6 +80,7 @@ impl RevisionManager { debug_assert!(range.doc_id == self.doc_id); let revisions = self.cache.revisions_in_range(range.clone()).await?; let mut new_delta = RichTextDelta::new(); + // TODO: generate delta from revision should be wrapped into function. for revision in revisions { match RichTextDelta::from_bytes(revision.delta_data) { Ok(delta) => { @@ -127,7 +128,7 @@ impl RevisionLoader { let revisions: Vec; if records.is_empty() { let doc = self.server.fetch_document(&self.doc_id).await?; - let delta_data = Bytes::from(doc.data.clone()); + let delta_data = Bytes::from(doc.text.clone()); let doc_md5 = md5(&delta_data); let revision = Revision::new( &doc.id, @@ -174,7 +175,7 @@ fn mk_doc_from_revisions(doc_id: &str, revisions: Vec) -> FlowyResult< Result::::Ok(Doc { id: doc_id.to_owned(), - data: delta.to_json(), + text: delta.to_json(), rev_id, base_rev_id, }) diff --git a/frontend/rust-lib/flowy-document/src/services/server/mod.rs b/frontend/rust-lib/flowy-document/src/services/server/mod.rs index 4f19269cb0..58ca922503 100644 --- a/frontend/rust-lib/flowy-document/src/services/server/mod.rs +++ b/frontend/rust-lib/flowy-document/src/services/server/mod.rs @@ -6,7 +6,7 @@ pub use server_api::*; // TODO: ignore mock files in production use crate::errors::FlowyError; use backend_service::configuration::ClientServerConfiguration; -use flowy_collaboration::entities::doc::{CreateDocParams, Doc, DocIdentifier, UpdateDocParams}; +use flowy_collaboration::entities::doc::{CreateDocParams, Doc, DocIdentifier, ResetDocumentParams}; use lib_infra::future::FutureResult; pub use server_api_mock::*; use std::sync::Arc; @@ -17,7 +17,7 @@ pub trait DocumentServerAPI { fn read_doc(&self, token: &str, params: DocIdentifier) -> FutureResult, FlowyError>; - fn update_doc(&self, token: &str, params: UpdateDocParams) -> FutureResult<(), FlowyError>; + fn update_doc(&self, token: &str, params: ResetDocumentParams) -> FutureResult<(), FlowyError>; } pub(crate) fn construct_doc_server( diff --git a/frontend/rust-lib/flowy-document/src/services/server/server_api.rs b/frontend/rust-lib/flowy-document/src/services/server/server_api.rs index c12f0a9662..6a2d644ae0 100644 --- a/frontend/rust-lib/flowy-document/src/services/server/server_api.rs +++ b/frontend/rust-lib/flowy-document/src/services/server/server_api.rs @@ -1,6 +1,6 @@ use crate::{errors::FlowyError, services::server::DocumentServerAPI}; use backend_service::{configuration::*, request::HttpRequestBuilder}; -use flowy_collaboration::entities::doc::{CreateDocParams, Doc, DocIdentifier, UpdateDocParams}; +use flowy_collaboration::entities::doc::{CreateDocParams, Doc, DocIdentifier, ResetDocumentParams}; use lib_infra::future::FutureResult; pub struct DocServer { @@ -24,7 +24,7 @@ impl DocumentServerAPI for DocServer { FutureResult::new(async move { read_doc_request(&token, params, &url).await }) } - fn update_doc(&self, token: &str, params: UpdateDocParams) -> FutureResult<(), FlowyError> { + fn update_doc(&self, token: &str, params: ResetDocumentParams) -> FutureResult<(), FlowyError> { let token = token.to_owned(); let url = self.config.doc_url(); FutureResult::new(async move { update_doc_request(&token, params, &url).await }) @@ -56,7 +56,7 @@ pub async fn read_doc_request(token: &str, params: DocIdentifier, url: &str) -> Ok(doc) } -pub async fn update_doc_request(token: &str, params: UpdateDocParams, url: &str) -> Result<(), FlowyError> { +pub async fn update_doc_request(token: &str, params: ResetDocumentParams, url: &str) -> Result<(), FlowyError> { let _ = request_builder() .patch(&url.to_owned()) .header(HEADER_TOKEN, token) diff --git a/frontend/rust-lib/flowy-document/src/services/server/server_api_mock.rs b/frontend/rust-lib/flowy-document/src/services/server/server_api_mock.rs index b2bdd3b7ed..1829a1c46a 100644 --- a/frontend/rust-lib/flowy-document/src/services/server/server_api_mock.rs +++ b/frontend/rust-lib/flowy-document/src/services/server/server_api_mock.rs @@ -1,6 +1,6 @@ use flowy_collaboration::{ - core::document::default::initial_string, - entities::doc::{CreateDocParams, Doc, DocIdentifier, UpdateDocParams}, + core::document::default::initial_delta_string, + entities::doc::{CreateDocParams, Doc, DocIdentifier, ResetDocumentParams}, }; use lib_infra::future::FutureResult; @@ -16,14 +16,14 @@ impl DocumentServerAPI for DocServerMock { fn read_doc(&self, _token: &str, params: DocIdentifier) -> FutureResult, FlowyError> { let doc = Doc { id: params.doc_id, - data: initial_string(), + text: initial_delta_string(), rev_id: 0, base_rev_id: 0, }; FutureResult::new(async { Ok(Some(doc)) }) } - fn update_doc(&self, _token: &str, _params: UpdateDocParams) -> FutureResult<(), FlowyError> { + fn update_doc(&self, _token: &str, _params: ResetDocumentParams) -> FutureResult<(), FlowyError> { FutureResult::new(async { Ok(()) }) } } diff --git a/frontend/rust-lib/flowy-net/src/services/mock/ws_mock.rs b/frontend/rust-lib/flowy-net/src/services/mock/ws_mock.rs index 2b383a6a6c..6f832c057e 100644 --- a/frontend/rust-lib/flowy-net/src/services/mock/ws_mock.rs +++ b/frontend/rust-lib/flowy-net/src/services/mock/ws_mock.rs @@ -9,7 +9,6 @@ use flowy_collaboration::{ ws::{DocumentWSData, DocumentWSDataBuilder, DocumentWSDataType, NewDocumentUser}, }, errors::CollaborateError, - RichTextDelta, }; use lazy_static::lazy_static; use lib_infra::future::{FutureResult, FutureResultSend}; @@ -161,9 +160,9 @@ impl std::default::Default for MockDocServerPersistence { } impl DocumentPersistence for MockDocServerPersistence { - fn update_doc(&self, _doc_id: &str, _rev_id: i64, _delta: RichTextDelta) -> FutureResultSend<(), CollaborateError> { - unimplemented!() - } + // fn update_doc(&self, _doc_id: &str, _rev_id: i64, _delta: RichTextDelta) -> + // FutureResultSend<(), CollaborateError> { unimplemented!() + // } fn read_doc(&self, doc_id: &str) -> FutureResultSend { let inner = self.inner.clone(); @@ -227,11 +226,7 @@ impl RevisionUser for MockDocUser { }; sender.send(msg).await.unwrap(); }, - SyncResponse::NewRevision { - rev_id: _, - doc_id: _, - doc_json: _, - } => { + SyncResponse::NewRevision(_) => { // unimplemented!() }, } diff --git a/shared-lib/flowy-collaboration/src/core/document/default/mod.rs b/shared-lib/flowy-collaboration/src/core/document/default/mod.rs index 9a0f1e8216..db9396231c 100644 --- a/shared-lib/flowy-collaboration/src/core/document/default/mod.rs +++ b/shared-lib/flowy-collaboration/src/core/document/default/mod.rs @@ -4,7 +4,7 @@ use lib_ot::{core::DeltaBuilder, rich_text::RichTextDelta}; pub fn initial_delta() -> RichTextDelta { DeltaBuilder::new().insert("\n").build() } #[inline] -pub fn initial_string() -> String { initial_delta().to_json() } +pub fn initial_delta_string() -> String { initial_delta().to_json() } #[inline] pub fn initial_read_me() -> RichTextDelta { diff --git a/shared-lib/flowy-collaboration/src/core/document/document.rs b/shared-lib/flowy-collaboration/src/core/document/document.rs index 65fdfda9ad..4178488e78 100644 --- a/shared-lib/flowy-collaboration/src/core/document/document.rs +++ b/shared-lib/flowy-collaboration/src/core/document/document.rs @@ -63,7 +63,7 @@ impl Document { pub fn delta(&self) -> &RichTextDelta { &self.delta } pub fn md5(&self) -> String { - // Opti: calculate the md5 of delta would cause performance issues + // TODO: Optimize the cost of calculating the md5 let bytes = self.to_bytes(); format!("{:x}", md5::compute(bytes)) } diff --git a/shared-lib/flowy-collaboration/src/core/sync/server_editor.rs b/shared-lib/flowy-collaboration/src/core/sync/server_editor.rs index e8ff165366..77134d9098 100644 --- a/shared-lib/flowy-collaboration/src/core/sync/server_editor.rs +++ b/shared-lib/flowy-collaboration/src/core/sync/server_editor.rs @@ -18,7 +18,8 @@ use tokio::{ }; pub trait DocumentPersistence: Send + Sync { - fn update_doc(&self, doc_id: &str, rev_id: i64, delta: RichTextDelta) -> FutureResultSend<(), CollaborateError>; + // fn update_doc(&self, doc_id: &str, rev_id: i64, delta: RichTextDelta) -> + // FutureResultSend<(), CollaborateError>; fn read_doc(&self, doc_id: &str) -> FutureResultSend; fn create_doc(&self, revision: Revision) -> FutureResultSend; } @@ -205,7 +206,7 @@ pub struct ServerDocEditor { impl ServerDocEditor { pub fn new(doc: Doc) -> Result { - let delta = RichTextDelta::from_bytes(&doc.data)?; + let delta = RichTextDelta::from_bytes(&doc.text)?; let users = DashMap::new(); let synchronizer = Arc::new(RevisionSynchronizer::new( &doc.id, diff --git a/shared-lib/flowy-collaboration/src/core/sync/synchronizer.rs b/shared-lib/flowy-collaboration/src/core/sync/synchronizer.rs index c77147bd69..f20e265375 100644 --- a/shared-lib/flowy-collaboration/src/core/sync/synchronizer.rs +++ b/shared-lib/flowy-collaboration/src/core/sync/synchronizer.rs @@ -26,11 +26,7 @@ pub enum SyncResponse { Pull(DocumentWSData), Push(DocumentWSData), Ack(DocumentWSData), - NewRevision { - rev_id: i64, - doc_json: String, - doc_id: String, - }, + NewRevision(Revision), } pub struct RevisionSynchronizer { @@ -71,14 +67,7 @@ impl RevisionSynchronizer { &revision.doc_id, &revision.rev_id.to_string(), ))); - let rev_id = revision.rev_id; - let doc_id = self.doc_id.clone(); - let doc_json = self.doc_json(); - user.receive(SyncResponse::NewRevision { - rev_id, - doc_id, - doc_json, - }); + user.receive(SyncResponse::NewRevision(revision)); } else { // The server document is outdated, pull the missing revision from the client. let range = RevisionRange { @@ -105,13 +94,13 @@ impl RevisionSynchronizer { let _ = self.compose_delta(server_delta)?; // - let doc_id = self.doc_id.clone(); - let doc_json = self.doc_json(); - user.receive(SyncResponse::NewRevision { - rev_id: self.rev_id(), - doc_json, - doc_id, - }); + let _doc_id = self.doc_id.clone(); + let _doc_json = self.doc_json(); + // user.receive(SyncResponse::NewRevision { + // rev_id: self.rev_id(), + // doc_json, + // doc_id, + // }); let cli_revision = self.mk_revision(revision.rev_id, cli_delta); let data = DocumentWSDataBuilder::build_push_message(&self.doc_id, cli_revision, &id); diff --git a/shared-lib/flowy-collaboration/src/entities/doc.rs b/shared-lib/flowy-collaboration/src/entities/doc.rs index ed403c6009..72f15ac123 100644 --- a/shared-lib/flowy-collaboration/src/entities/doc.rs +++ b/shared-lib/flowy-collaboration/src/entities/doc.rs @@ -11,7 +11,7 @@ pub struct CreateDocParams { pub id: String, #[pb(index = 2)] - pub data: RepeatedRevision, + pub revisions: RepeatedRevision, } #[derive(ProtoBuf, Default, Debug, Clone, Eq, PartialEq)] @@ -20,7 +20,7 @@ pub struct Doc { pub id: String, #[pb(index = 2)] - pub data: String, + pub text: String, #[pb(index = 3)] pub rev_id: i64, @@ -31,7 +31,7 @@ pub struct Doc { impl Doc { pub fn delta(&self) -> Result { - let delta = RichTextDelta::from_bytes(&self.data)?; + let delta = RichTextDelta::from_bytes(&self.text)?; Ok(delta) } } @@ -50,7 +50,7 @@ impl std::convert::TryFrom for Doc { Ok(Doc { id: revision.doc_id, - data: doc_json, + text: doc_json, rev_id: revision.rev_id, base_rev_id: revision.base_rev_id, }) @@ -58,15 +58,12 @@ impl std::convert::TryFrom for Doc { } #[derive(ProtoBuf, Default, Debug, Clone)] -pub struct UpdateDocParams { +pub struct ResetDocumentParams { #[pb(index = 1)] pub doc_id: String, #[pb(index = 2)] - pub data: String, - - #[pb(index = 3)] - pub rev_id: i64, + pub revisions: RepeatedRevision, } #[derive(ProtoBuf, Default, Debug, Clone)] diff --git a/shared-lib/flowy-collaboration/src/entities/revision.rs b/shared-lib/flowy-collaboration/src/entities/revision.rs index c43f6185fb..fccfe88ab7 100644 --- a/shared-lib/flowy-collaboration/src/entities/revision.rs +++ b/shared-lib/flowy-collaboration/src/entities/revision.rs @@ -1,3 +1,4 @@ +use crate::core::document::default::initial_delta; use bytes::Bytes; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use lib_ot::rich_text::RichTextDelta; @@ -41,26 +42,13 @@ impl Revision { #[allow(dead_code)] pub fn is_initial(&self) -> bool { self.rev_id == 0 } -} -impl std::fmt::Debug for Revision { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - let _ = f.write_fmt(format_args!("doc_id {}, ", self.doc_id))?; - let _ = f.write_fmt(format_args!("base_rev_id {}, ", self.base_rev_id))?; - let _ = f.write_fmt(format_args!("rev_id {}, ", self.rev_id))?; - match RichTextDelta::from_bytes(&self.delta_data) { - Ok(delta) => { - let _ = f.write_fmt(format_args!("delta {:?}", delta.to_json()))?; - }, - Err(e) => { - let _ = f.write_fmt(format_args!("delta {:?}", e))?; - }, - } - Ok(()) + pub fn initial_revision(user_id: &str, doc_id: &str, ty: RevType) -> Self { + let delta_data = initial_delta().to_bytes(); + let md5 = format!("{:x}", md5::compute(&delta_data)); + Revision::new(doc_id, 0, 0, delta_data, ty, user_id, md5) } -} -impl Revision { pub fn new( doc_id: &str, base_rev_id: i64, @@ -92,6 +80,23 @@ impl Revision { } } +impl std::fmt::Debug for Revision { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + let _ = f.write_fmt(format_args!("doc_id {}, ", self.doc_id))?; + let _ = f.write_fmt(format_args!("base_rev_id {}, ", self.base_rev_id))?; + let _ = f.write_fmt(format_args!("rev_id {}, ", self.rev_id))?; + match RichTextDelta::from_bytes(&self.delta_data) { + Ok(delta) => { + let _ = f.write_fmt(format_args!("delta {:?}", delta.to_json()))?; + }, + Err(e) => { + let _ = f.write_fmt(format_args!("delta {:?}", e))?; + }, + } + Ok(()) + } +} + #[derive(PartialEq, Debug, Default, ProtoBuf, Clone)] pub struct RepeatedRevision { #[pb(index = 1)] diff --git a/shared-lib/flowy-collaboration/src/errors.rs b/shared-lib/flowy-collaboration/src/errors.rs index 767367ae23..88f6a7ab42 100644 --- a/shared-lib/flowy-collaboration/src/errors.rs +++ b/shared-lib/flowy-collaboration/src/errors.rs @@ -68,7 +68,7 @@ impl std::convert::From for CollaborateError { fn from(e: protobuf::ProtobufError) -> Self { CollaborateError::internal().context(e) } } -pub fn internal_error(e: T) -> CollaborateError +pub(crate) fn internal_error(e: T) -> CollaborateError where T: std::fmt::Debug, { diff --git a/shared-lib/flowy-collaboration/src/protobuf/model/doc.rs b/shared-lib/flowy-collaboration/src/protobuf/model/doc.rs index b4cfcee048..49cf1ee08b 100644 --- a/shared-lib/flowy-collaboration/src/protobuf/model/doc.rs +++ b/shared-lib/flowy-collaboration/src/protobuf/model/doc.rs @@ -27,7 +27,7 @@ pub struct CreateDocParams { // message fields pub id: ::std::string::String, - pub data: ::protobuf::SingularPtrField, + pub revisions: ::protobuf::SingularPtrField, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -70,43 +70,43 @@ impl CreateDocParams { ::std::mem::replace(&mut self.id, ::std::string::String::new()) } - // .RepeatedRevision data = 2; + // .RepeatedRevision revisions = 2; - pub fn get_data(&self) -> &super::revision::RepeatedRevision { - self.data.as_ref().unwrap_or_else(|| ::default_instance()) + pub fn get_revisions(&self) -> &super::revision::RepeatedRevision { + self.revisions.as_ref().unwrap_or_else(|| ::default_instance()) } - pub fn clear_data(&mut self) { - self.data.clear(); + pub fn clear_revisions(&mut self) { + self.revisions.clear(); } - pub fn has_data(&self) -> bool { - self.data.is_some() + pub fn has_revisions(&self) -> bool { + self.revisions.is_some() } // Param is passed by value, moved - pub fn set_data(&mut self, v: super::revision::RepeatedRevision) { - self.data = ::protobuf::SingularPtrField::some(v); + pub fn set_revisions(&mut self, v: super::revision::RepeatedRevision) { + self.revisions = ::protobuf::SingularPtrField::some(v); } // Mutable pointer to the field. // If field is not initialized, it is initialized with default value first. - pub fn mut_data(&mut self) -> &mut super::revision::RepeatedRevision { - if self.data.is_none() { - self.data.set_default(); + pub fn mut_revisions(&mut self) -> &mut super::revision::RepeatedRevision { + if self.revisions.is_none() { + self.revisions.set_default(); } - self.data.as_mut().unwrap() + self.revisions.as_mut().unwrap() } // Take field - pub fn take_data(&mut self) -> super::revision::RepeatedRevision { - self.data.take().unwrap_or_else(|| super::revision::RepeatedRevision::new()) + pub fn take_revisions(&mut self) -> super::revision::RepeatedRevision { + self.revisions.take().unwrap_or_else(|| super::revision::RepeatedRevision::new()) } } impl ::protobuf::Message for CreateDocParams { fn is_initialized(&self) -> bool { - for v in &self.data { + for v in &self.revisions { if !v.is_initialized() { return false; } @@ -122,7 +122,7 @@ impl ::protobuf::Message for CreateDocParams { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?; }, 2 => { - ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.data)?; + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.revisions)?; }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; @@ -139,7 +139,7 @@ impl ::protobuf::Message for CreateDocParams { if !self.id.is_empty() { my_size += ::protobuf::rt::string_size(1, &self.id); } - if let Some(ref v) = self.data.as_ref() { + if let Some(ref v) = self.revisions.as_ref() { let len = v.compute_size(); my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; } @@ -152,7 +152,7 @@ impl ::protobuf::Message for CreateDocParams { if !self.id.is_empty() { os.write_string(1, &self.id)?; } - if let Some(ref v) = self.data.as_ref() { + if let Some(ref v) = self.revisions.as_ref() { os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; os.write_raw_varint32(v.get_cached_size())?; v.write_to_with_cached_sizes(os)?; @@ -201,9 +201,9 @@ impl ::protobuf::Message for CreateDocParams { |m: &mut CreateDocParams| { &mut m.id }, )); fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "data", - |m: &CreateDocParams| { &m.data }, - |m: &mut CreateDocParams| { &mut m.data }, + "revisions", + |m: &CreateDocParams| { &m.revisions }, + |m: &mut CreateDocParams| { &mut m.revisions }, )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "CreateDocParams", @@ -222,7 +222,7 @@ impl ::protobuf::Message for CreateDocParams { impl ::protobuf::Clear for CreateDocParams { fn clear(&mut self) { self.id.clear(); - self.data.clear(); + self.revisions.clear(); self.unknown_fields.clear(); } } @@ -243,7 +243,7 @@ impl ::protobuf::reflect::ProtobufValue for CreateDocParams { pub struct Doc { // message fields pub id: ::std::string::String, - pub data: ::std::string::String, + pub text: ::std::string::String, pub rev_id: i64, pub base_rev_id: i64, // special fields @@ -288,30 +288,30 @@ impl Doc { ::std::mem::replace(&mut self.id, ::std::string::String::new()) } - // string data = 2; + // string text = 2; - pub fn get_data(&self) -> &str { - &self.data + pub fn get_text(&self) -> &str { + &self.text } - pub fn clear_data(&mut self) { - self.data.clear(); + pub fn clear_text(&mut self) { + self.text.clear(); } // Param is passed by value, moved - pub fn set_data(&mut self, v: ::std::string::String) { - self.data = v; + pub fn set_text(&mut self, v: ::std::string::String) { + self.text = v; } // Mutable pointer to the field. // If field is not initialized, it is initialized with default value first. - pub fn mut_data(&mut self) -> &mut ::std::string::String { - &mut self.data + pub fn mut_text(&mut self) -> &mut ::std::string::String { + &mut self.text } // Take field - pub fn take_data(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.data, ::std::string::String::new()) + pub fn take_text(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.text, ::std::string::String::new()) } // int64 rev_id = 3; @@ -358,7 +358,7 @@ impl ::protobuf::Message for Doc { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?; }, 2 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.data)?; + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.text)?; }, 3 => { if wire_type != ::protobuf::wire_format::WireTypeVarint { @@ -389,8 +389,8 @@ impl ::protobuf::Message for Doc { if !self.id.is_empty() { my_size += ::protobuf::rt::string_size(1, &self.id); } - if !self.data.is_empty() { - my_size += ::protobuf::rt::string_size(2, &self.data); + if !self.text.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.text); } if self.rev_id != 0 { my_size += ::protobuf::rt::value_size(3, self.rev_id, ::protobuf::wire_format::WireTypeVarint); @@ -407,8 +407,8 @@ impl ::protobuf::Message for Doc { if !self.id.is_empty() { os.write_string(1, &self.id)?; } - if !self.data.is_empty() { - os.write_string(2, &self.data)?; + if !self.text.is_empty() { + os.write_string(2, &self.text)?; } if self.rev_id != 0 { os.write_int64(3, self.rev_id)?; @@ -460,9 +460,9 @@ impl ::protobuf::Message for Doc { |m: &mut Doc| { &mut m.id }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "data", - |m: &Doc| { &m.data }, - |m: &mut Doc| { &mut m.data }, + "text", + |m: &Doc| { &m.text }, + |m: &mut Doc| { &mut m.text }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt64>( "rev_id", @@ -491,7 +491,7 @@ impl ::protobuf::Message for Doc { impl ::protobuf::Clear for Doc { fn clear(&mut self) { self.id.clear(); - self.data.clear(); + self.text.clear(); self.rev_id = 0; self.base_rev_id = 0; self.unknown_fields.clear(); @@ -511,24 +511,23 @@ impl ::protobuf::reflect::ProtobufValue for Doc { } #[derive(PartialEq,Clone,Default)] -pub struct UpdateDocParams { +pub struct ResetDocumentParams { // message fields pub doc_id: ::std::string::String, - pub data: ::std::string::String, - pub rev_id: i64, + pub revisions: ::protobuf::SingularPtrField, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, } -impl<'a> ::std::default::Default for &'a UpdateDocParams { - fn default() -> &'a UpdateDocParams { - ::default_instance() +impl<'a> ::std::default::Default for &'a ResetDocumentParams { + fn default() -> &'a ResetDocumentParams { + ::default_instance() } } -impl UpdateDocParams { - pub fn new() -> UpdateDocParams { +impl ResetDocumentParams { + pub fn new() -> ResetDocumentParams { ::std::default::Default::default() } @@ -558,50 +557,47 @@ impl UpdateDocParams { ::std::mem::replace(&mut self.doc_id, ::std::string::String::new()) } - // string data = 2; + // .RepeatedRevision revisions = 2; - pub fn get_data(&self) -> &str { - &self.data + pub fn get_revisions(&self) -> &super::revision::RepeatedRevision { + self.revisions.as_ref().unwrap_or_else(|| ::default_instance()) } - pub fn clear_data(&mut self) { - self.data.clear(); + pub fn clear_revisions(&mut self) { + self.revisions.clear(); + } + + pub fn has_revisions(&self) -> bool { + self.revisions.is_some() } // Param is passed by value, moved - pub fn set_data(&mut self, v: ::std::string::String) { - self.data = v; + pub fn set_revisions(&mut self, v: super::revision::RepeatedRevision) { + self.revisions = ::protobuf::SingularPtrField::some(v); } // Mutable pointer to the field. // If field is not initialized, it is initialized with default value first. - pub fn mut_data(&mut self) -> &mut ::std::string::String { - &mut self.data + pub fn mut_revisions(&mut self) -> &mut super::revision::RepeatedRevision { + if self.revisions.is_none() { + self.revisions.set_default(); + } + self.revisions.as_mut().unwrap() } // Take field - pub fn take_data(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.data, ::std::string::String::new()) - } - - // int64 rev_id = 3; - - - pub fn get_rev_id(&self) -> i64 { - self.rev_id - } - pub fn clear_rev_id(&mut self) { - self.rev_id = 0; - } - - // Param is passed by value, moved - pub fn set_rev_id(&mut self, v: i64) { - self.rev_id = v; + pub fn take_revisions(&mut self) -> super::revision::RepeatedRevision { + self.revisions.take().unwrap_or_else(|| super::revision::RepeatedRevision::new()) } } -impl ::protobuf::Message for UpdateDocParams { +impl ::protobuf::Message for ResetDocumentParams { fn is_initialized(&self) -> bool { + for v in &self.revisions { + if !v.is_initialized() { + return false; + } + }; true } @@ -613,14 +609,7 @@ impl ::protobuf::Message for UpdateDocParams { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.doc_id)?; }, 2 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.data)?; - }, - 3 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_int64()?; - self.rev_id = tmp; + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.revisions)?; }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; @@ -637,11 +626,9 @@ impl ::protobuf::Message for UpdateDocParams { if !self.doc_id.is_empty() { my_size += ::protobuf::rt::string_size(1, &self.doc_id); } - if !self.data.is_empty() { - my_size += ::protobuf::rt::string_size(2, &self.data); - } - if self.rev_id != 0 { - my_size += ::protobuf::rt::value_size(3, self.rev_id, ::protobuf::wire_format::WireTypeVarint); + if let Some(ref v) = self.revisions.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; } my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); @@ -652,11 +639,10 @@ impl ::protobuf::Message for UpdateDocParams { if !self.doc_id.is_empty() { os.write_string(1, &self.doc_id)?; } - if !self.data.is_empty() { - os.write_string(2, &self.data)?; - } - if self.rev_id != 0 { - os.write_int64(3, self.rev_id)?; + if let Some(ref v) = self.revisions.as_ref() { + os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; } os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) @@ -688,8 +674,8 @@ impl ::protobuf::Message for UpdateDocParams { Self::descriptor_static() } - fn new() -> UpdateDocParams { - UpdateDocParams::new() + fn new() -> ResetDocumentParams { + ResetDocumentParams::new() } fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { @@ -698,49 +684,43 @@ impl ::protobuf::Message for UpdateDocParams { let mut fields = ::std::vec::Vec::new(); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "doc_id", - |m: &UpdateDocParams| { &m.doc_id }, - |m: &mut UpdateDocParams| { &mut m.doc_id }, + |m: &ResetDocumentParams| { &m.doc_id }, + |m: &mut ResetDocumentParams| { &mut m.doc_id }, )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "data", - |m: &UpdateDocParams| { &m.data }, - |m: &mut UpdateDocParams| { &mut m.data }, + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "revisions", + |m: &ResetDocumentParams| { &m.revisions }, + |m: &mut ResetDocumentParams| { &mut m.revisions }, )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt64>( - "rev_id", - |m: &UpdateDocParams| { &m.rev_id }, - |m: &mut UpdateDocParams| { &mut m.rev_id }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "UpdateDocParams", + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "ResetDocumentParams", fields, file_descriptor_proto() ) }) } - fn default_instance() -> &'static UpdateDocParams { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(UpdateDocParams::new) + fn default_instance() -> &'static ResetDocumentParams { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(ResetDocumentParams::new) } } -impl ::protobuf::Clear for UpdateDocParams { +impl ::protobuf::Clear for ResetDocumentParams { fn clear(&mut self) { self.doc_id.clear(); - self.data.clear(); - self.rev_id = 0; + self.revisions.clear(); self.unknown_fields.clear(); } } -impl ::std::fmt::Debug for UpdateDocParams { +impl ::std::fmt::Debug for ResetDocumentParams { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } -impl ::protobuf::reflect::ProtobufValue for UpdateDocParams { +impl ::protobuf::reflect::ProtobufValue for ResetDocumentParams { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { ::protobuf::reflect::ReflectValueRef::Message(self) } @@ -1343,69 +1323,66 @@ impl ::protobuf::reflect::ProtobufValue for DocIdentifier { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\tdoc.proto\x1a\x0erevision.proto\"H\n\x0fCreateDocParams\x12\x0e\n\ - \x02id\x18\x01\x20\x01(\tR\x02id\x12%\n\x04data\x18\x02\x20\x01(\x0b2\ - \x11.RepeatedRevisionR\x04data\"`\n\x03Doc\x12\x0e\n\x02id\x18\x01\x20\ - \x01(\tR\x02id\x12\x12\n\x04data\x18\x02\x20\x01(\tR\x04data\x12\x15\n\ - \x06rev_id\x18\x03\x20\x01(\x03R\x05revId\x12\x1e\n\x0bbase_rev_id\x18\ - \x04\x20\x01(\x03R\tbaseRevId\"S\n\x0fUpdateDocParams\x12\x15\n\x06doc_i\ - d\x18\x01\x20\x01(\tR\x05docId\x12\x12\n\x04data\x18\x02\x20\x01(\tR\x04\ - data\x12\x15\n\x06rev_id\x18\x03\x20\x01(\x03R\x05revId\"5\n\x08DocDelta\ - \x12\x15\n\x06doc_id\x18\x01\x20\x01(\tR\x05docId\x12\x12\n\x04data\x18\ - \x02\x20\x01(\tR\x04data\"S\n\nNewDocUser\x12\x17\n\x07user_id\x18\x01\ - \x20\x01(\tR\x06userId\x12\x15\n\x06rev_id\x18\x02\x20\x01(\x03R\x05revI\ - d\x12\x15\n\x06doc_id\x18\x03\x20\x01(\tR\x05docId\"&\n\rDocIdentifier\ - \x12\x15\n\x06doc_id\x18\x01\x20\x01(\tR\x05docIdJ\xe6\x07\n\x06\x12\x04\ - \0\0\x1d\x01\n\x08\n\x01\x0c\x12\x03\0\0\x12\n\t\n\x02\x03\0\x12\x03\x01\ - \0\x18\n\n\n\x02\x04\0\x12\x04\x03\0\x06\x01\n\n\n\x03\x04\0\x01\x12\x03\ - \x03\x08\x17\n\x0b\n\x04\x04\0\x02\0\x12\x03\x04\x04\x12\n\x0c\n\x05\x04\ - \0\x02\0\x05\x12\x03\x04\x04\n\n\x0c\n\x05\x04\0\x02\0\x01\x12\x03\x04\ - \x0b\r\n\x0c\n\x05\x04\0\x02\0\x03\x12\x03\x04\x10\x11\n\x0b\n\x04\x04\0\ - \x02\x01\x12\x03\x05\x04\x1e\n\x0c\n\x05\x04\0\x02\x01\x06\x12\x03\x05\ - \x04\x14\n\x0c\n\x05\x04\0\x02\x01\x01\x12\x03\x05\x15\x19\n\x0c\n\x05\ - \x04\0\x02\x01\x03\x12\x03\x05\x1c\x1d\n\n\n\x02\x04\x01\x12\x04\x07\0\ - \x0c\x01\n\n\n\x03\x04\x01\x01\x12\x03\x07\x08\x0b\n\x0b\n\x04\x04\x01\ - \x02\0\x12\x03\x08\x04\x12\n\x0c\n\x05\x04\x01\x02\0\x05\x12\x03\x08\x04\ - \n\n\x0c\n\x05\x04\x01\x02\0\x01\x12\x03\x08\x0b\r\n\x0c\n\x05\x04\x01\ - \x02\0\x03\x12\x03\x08\x10\x11\n\x0b\n\x04\x04\x01\x02\x01\x12\x03\t\x04\ - \x14\n\x0c\n\x05\x04\x01\x02\x01\x05\x12\x03\t\x04\n\n\x0c\n\x05\x04\x01\ - \x02\x01\x01\x12\x03\t\x0b\x0f\n\x0c\n\x05\x04\x01\x02\x01\x03\x12\x03\t\ - \x12\x13\n\x0b\n\x04\x04\x01\x02\x02\x12\x03\n\x04\x15\n\x0c\n\x05\x04\ - \x01\x02\x02\x05\x12\x03\n\x04\t\n\x0c\n\x05\x04\x01\x02\x02\x01\x12\x03\ - \n\n\x10\n\x0c\n\x05\x04\x01\x02\x02\x03\x12\x03\n\x13\x14\n\x0b\n\x04\ - \x04\x01\x02\x03\x12\x03\x0b\x04\x1a\n\x0c\n\x05\x04\x01\x02\x03\x05\x12\ - \x03\x0b\x04\t\n\x0c\n\x05\x04\x01\x02\x03\x01\x12\x03\x0b\n\x15\n\x0c\n\ - \x05\x04\x01\x02\x03\x03\x12\x03\x0b\x18\x19\n\n\n\x02\x04\x02\x12\x04\r\ - \0\x11\x01\n\n\n\x03\x04\x02\x01\x12\x03\r\x08\x17\n\x0b\n\x04\x04\x02\ - \x02\0\x12\x03\x0e\x04\x16\n\x0c\n\x05\x04\x02\x02\0\x05\x12\x03\x0e\x04\ - \n\n\x0c\n\x05\x04\x02\x02\0\x01\x12\x03\x0e\x0b\x11\n\x0c\n\x05\x04\x02\ - \x02\0\x03\x12\x03\x0e\x14\x15\n\x0b\n\x04\x04\x02\x02\x01\x12\x03\x0f\ - \x04\x14\n\x0c\n\x05\x04\x02\x02\x01\x05\x12\x03\x0f\x04\n\n\x0c\n\x05\ - \x04\x02\x02\x01\x01\x12\x03\x0f\x0b\x0f\n\x0c\n\x05\x04\x02\x02\x01\x03\ - \x12\x03\x0f\x12\x13\n\x0b\n\x04\x04\x02\x02\x02\x12\x03\x10\x04\x15\n\ - \x0c\n\x05\x04\x02\x02\x02\x05\x12\x03\x10\x04\t\n\x0c\n\x05\x04\x02\x02\ - \x02\x01\x12\x03\x10\n\x10\n\x0c\n\x05\x04\x02\x02\x02\x03\x12\x03\x10\ - \x13\x14\n\n\n\x02\x04\x03\x12\x04\x12\0\x15\x01\n\n\n\x03\x04\x03\x01\ - \x12\x03\x12\x08\x10\n\x0b\n\x04\x04\x03\x02\0\x12\x03\x13\x04\x16\n\x0c\ - \n\x05\x04\x03\x02\0\x05\x12\x03\x13\x04\n\n\x0c\n\x05\x04\x03\x02\0\x01\ - \x12\x03\x13\x0b\x11\n\x0c\n\x05\x04\x03\x02\0\x03\x12\x03\x13\x14\x15\n\ - \x0b\n\x04\x04\x03\x02\x01\x12\x03\x14\x04\x14\n\x0c\n\x05\x04\x03\x02\ - \x01\x05\x12\x03\x14\x04\n\n\x0c\n\x05\x04\x03\x02\x01\x01\x12\x03\x14\ - \x0b\x0f\n\x0c\n\x05\x04\x03\x02\x01\x03\x12\x03\x14\x12\x13\n\n\n\x02\ - \x04\x04\x12\x04\x16\0\x1a\x01\n\n\n\x03\x04\x04\x01\x12\x03\x16\x08\x12\ - \n\x0b\n\x04\x04\x04\x02\0\x12\x03\x17\x04\x17\n\x0c\n\x05\x04\x04\x02\0\ - \x05\x12\x03\x17\x04\n\n\x0c\n\x05\x04\x04\x02\0\x01\x12\x03\x17\x0b\x12\ - \n\x0c\n\x05\x04\x04\x02\0\x03\x12\x03\x17\x15\x16\n\x0b\n\x04\x04\x04\ - \x02\x01\x12\x03\x18\x04\x15\n\x0c\n\x05\x04\x04\x02\x01\x05\x12\x03\x18\ - \x04\t\n\x0c\n\x05\x04\x04\x02\x01\x01\x12\x03\x18\n\x10\n\x0c\n\x05\x04\ - \x04\x02\x01\x03\x12\x03\x18\x13\x14\n\x0b\n\x04\x04\x04\x02\x02\x12\x03\ - \x19\x04\x16\n\x0c\n\x05\x04\x04\x02\x02\x05\x12\x03\x19\x04\n\n\x0c\n\ - \x05\x04\x04\x02\x02\x01\x12\x03\x19\x0b\x11\n\x0c\n\x05\x04\x04\x02\x02\ - \x03\x12\x03\x19\x14\x15\n\n\n\x02\x04\x05\x12\x04\x1b\0\x1d\x01\n\n\n\ - \x03\x04\x05\x01\x12\x03\x1b\x08\x15\n\x0b\n\x04\x04\x05\x02\0\x12\x03\ - \x1c\x04\x16\n\x0c\n\x05\x04\x05\x02\0\x05\x12\x03\x1c\x04\n\n\x0c\n\x05\ - \x04\x05\x02\0\x01\x12\x03\x1c\x0b\x11\n\x0c\n\x05\x04\x05\x02\0\x03\x12\ - \x03\x1c\x14\x15b\x06proto3\ + \n\tdoc.proto\x1a\x0erevision.proto\"R\n\x0fCreateDocParams\x12\x0e\n\ + \x02id\x18\x01\x20\x01(\tR\x02id\x12/\n\trevisions\x18\x02\x20\x01(\x0b2\ + \x11.RepeatedRevisionR\trevisions\"`\n\x03Doc\x12\x0e\n\x02id\x18\x01\ + \x20\x01(\tR\x02id\x12\x12\n\x04text\x18\x02\x20\x01(\tR\x04text\x12\x15\ + \n\x06rev_id\x18\x03\x20\x01(\x03R\x05revId\x12\x1e\n\x0bbase_rev_id\x18\ + \x04\x20\x01(\x03R\tbaseRevId\"]\n\x13ResetDocumentParams\x12\x15\n\x06d\ + oc_id\x18\x01\x20\x01(\tR\x05docId\x12/\n\trevisions\x18\x02\x20\x01(\ + \x0b2\x11.RepeatedRevisionR\trevisions\"5\n\x08DocDelta\x12\x15\n\x06doc\ + _id\x18\x01\x20\x01(\tR\x05docId\x12\x12\n\x04data\x18\x02\x20\x01(\tR\ + \x04data\"S\n\nNewDocUser\x12\x17\n\x07user_id\x18\x01\x20\x01(\tR\x06us\ + erId\x12\x15\n\x06rev_id\x18\x02\x20\x01(\x03R\x05revId\x12\x15\n\x06doc\ + _id\x18\x03\x20\x01(\tR\x05docId\"&\n\rDocIdentifier\x12\x15\n\x06doc_id\ + \x18\x01\x20\x01(\tR\x05docIdJ\xaf\x07\n\x06\x12\x04\0\0\x1c\x01\n\x08\n\ + \x01\x0c\x12\x03\0\0\x12\n\t\n\x02\x03\0\x12\x03\x01\0\x18\n\n\n\x02\x04\ + \0\x12\x04\x03\0\x06\x01\n\n\n\x03\x04\0\x01\x12\x03\x03\x08\x17\n\x0b\n\ + \x04\x04\0\x02\0\x12\x03\x04\x04\x12\n\x0c\n\x05\x04\0\x02\0\x05\x12\x03\ + \x04\x04\n\n\x0c\n\x05\x04\0\x02\0\x01\x12\x03\x04\x0b\r\n\x0c\n\x05\x04\ + \0\x02\0\x03\x12\x03\x04\x10\x11\n\x0b\n\x04\x04\0\x02\x01\x12\x03\x05\ + \x04#\n\x0c\n\x05\x04\0\x02\x01\x06\x12\x03\x05\x04\x14\n\x0c\n\x05\x04\ + \0\x02\x01\x01\x12\x03\x05\x15\x1e\n\x0c\n\x05\x04\0\x02\x01\x03\x12\x03\ + \x05!\"\n\n\n\x02\x04\x01\x12\x04\x07\0\x0c\x01\n\n\n\x03\x04\x01\x01\ + \x12\x03\x07\x08\x0b\n\x0b\n\x04\x04\x01\x02\0\x12\x03\x08\x04\x12\n\x0c\ + \n\x05\x04\x01\x02\0\x05\x12\x03\x08\x04\n\n\x0c\n\x05\x04\x01\x02\0\x01\ + \x12\x03\x08\x0b\r\n\x0c\n\x05\x04\x01\x02\0\x03\x12\x03\x08\x10\x11\n\ + \x0b\n\x04\x04\x01\x02\x01\x12\x03\t\x04\x14\n\x0c\n\x05\x04\x01\x02\x01\ + \x05\x12\x03\t\x04\n\n\x0c\n\x05\x04\x01\x02\x01\x01\x12\x03\t\x0b\x0f\n\ + \x0c\n\x05\x04\x01\x02\x01\x03\x12\x03\t\x12\x13\n\x0b\n\x04\x04\x01\x02\ + \x02\x12\x03\n\x04\x15\n\x0c\n\x05\x04\x01\x02\x02\x05\x12\x03\n\x04\t\n\ + \x0c\n\x05\x04\x01\x02\x02\x01\x12\x03\n\n\x10\n\x0c\n\x05\x04\x01\x02\ + \x02\x03\x12\x03\n\x13\x14\n\x0b\n\x04\x04\x01\x02\x03\x12\x03\x0b\x04\ + \x1a\n\x0c\n\x05\x04\x01\x02\x03\x05\x12\x03\x0b\x04\t\n\x0c\n\x05\x04\ + \x01\x02\x03\x01\x12\x03\x0b\n\x15\n\x0c\n\x05\x04\x01\x02\x03\x03\x12\ + \x03\x0b\x18\x19\n\n\n\x02\x04\x02\x12\x04\r\0\x10\x01\n\n\n\x03\x04\x02\ + \x01\x12\x03\r\x08\x1b\n\x0b\n\x04\x04\x02\x02\0\x12\x03\x0e\x04\x16\n\ + \x0c\n\x05\x04\x02\x02\0\x05\x12\x03\x0e\x04\n\n\x0c\n\x05\x04\x02\x02\0\ + \x01\x12\x03\x0e\x0b\x11\n\x0c\n\x05\x04\x02\x02\0\x03\x12\x03\x0e\x14\ + \x15\n\x0b\n\x04\x04\x02\x02\x01\x12\x03\x0f\x04#\n\x0c\n\x05\x04\x02\ + \x02\x01\x06\x12\x03\x0f\x04\x14\n\x0c\n\x05\x04\x02\x02\x01\x01\x12\x03\ + \x0f\x15\x1e\n\x0c\n\x05\x04\x02\x02\x01\x03\x12\x03\x0f!\"\n\n\n\x02\ + \x04\x03\x12\x04\x11\0\x14\x01\n\n\n\x03\x04\x03\x01\x12\x03\x11\x08\x10\ + \n\x0b\n\x04\x04\x03\x02\0\x12\x03\x12\x04\x16\n\x0c\n\x05\x04\x03\x02\0\ + \x05\x12\x03\x12\x04\n\n\x0c\n\x05\x04\x03\x02\0\x01\x12\x03\x12\x0b\x11\ + \n\x0c\n\x05\x04\x03\x02\0\x03\x12\x03\x12\x14\x15\n\x0b\n\x04\x04\x03\ + \x02\x01\x12\x03\x13\x04\x14\n\x0c\n\x05\x04\x03\x02\x01\x05\x12\x03\x13\ + \x04\n\n\x0c\n\x05\x04\x03\x02\x01\x01\x12\x03\x13\x0b\x0f\n\x0c\n\x05\ + \x04\x03\x02\x01\x03\x12\x03\x13\x12\x13\n\n\n\x02\x04\x04\x12\x04\x15\0\ + \x19\x01\n\n\n\x03\x04\x04\x01\x12\x03\x15\x08\x12\n\x0b\n\x04\x04\x04\ + \x02\0\x12\x03\x16\x04\x17\n\x0c\n\x05\x04\x04\x02\0\x05\x12\x03\x16\x04\ + \n\n\x0c\n\x05\x04\x04\x02\0\x01\x12\x03\x16\x0b\x12\n\x0c\n\x05\x04\x04\ + \x02\0\x03\x12\x03\x16\x15\x16\n\x0b\n\x04\x04\x04\x02\x01\x12\x03\x17\ + \x04\x15\n\x0c\n\x05\x04\x04\x02\x01\x05\x12\x03\x17\x04\t\n\x0c\n\x05\ + \x04\x04\x02\x01\x01\x12\x03\x17\n\x10\n\x0c\n\x05\x04\x04\x02\x01\x03\ + \x12\x03\x17\x13\x14\n\x0b\n\x04\x04\x04\x02\x02\x12\x03\x18\x04\x16\n\ + \x0c\n\x05\x04\x04\x02\x02\x05\x12\x03\x18\x04\n\n\x0c\n\x05\x04\x04\x02\ + \x02\x01\x12\x03\x18\x0b\x11\n\x0c\n\x05\x04\x04\x02\x02\x03\x12\x03\x18\ + \x14\x15\n\n\n\x02\x04\x05\x12\x04\x1a\0\x1c\x01\n\n\n\x03\x04\x05\x01\ + \x12\x03\x1a\x08\x15\n\x0b\n\x04\x04\x05\x02\0\x12\x03\x1b\x04\x16\n\x0c\ + \n\x05\x04\x05\x02\0\x05\x12\x03\x1b\x04\n\n\x0c\n\x05\x04\x05\x02\0\x01\ + \x12\x03\x1b\x0b\x11\n\x0c\n\x05\x04\x05\x02\0\x03\x12\x03\x1b\x14\x15b\ + \x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-collaboration/src/protobuf/proto/doc.proto b/shared-lib/flowy-collaboration/src/protobuf/proto/doc.proto index 52e21ac2cd..8c1f9076de 100644 --- a/shared-lib/flowy-collaboration/src/protobuf/proto/doc.proto +++ b/shared-lib/flowy-collaboration/src/protobuf/proto/doc.proto @@ -3,18 +3,17 @@ import "revision.proto"; message CreateDocParams { string id = 1; - RepeatedRevision data = 2; + RepeatedRevision revisions = 2; } message Doc { string id = 1; - string data = 2; + string text = 2; int64 rev_id = 3; int64 base_rev_id = 4; } -message UpdateDocParams { +message ResetDocumentParams { string doc_id = 1; - string data = 2; - int64 rev_id = 3; + RepeatedRevision revisions = 2; } message DocDelta { string doc_id = 1; diff --git a/shared-lib/flowy-core-data-model/src/entities/view/view_create.rs b/shared-lib/flowy-core-data-model/src/entities/view/view_create.rs index cffad1cbbd..6100f8a155 100644 --- a/shared-lib/flowy-core-data-model/src/entities/view/view_create.rs +++ b/shared-lib/flowy-core-data-model/src/entities/view/view_create.rs @@ -7,7 +7,7 @@ use crate::{ view::{ViewName, ViewThumbnail}, }, }; -use flowy_collaboration::core::document::default::initial_string; + use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use std::convert::TryInto; @@ -68,9 +68,6 @@ pub struct CreateViewParams { #[pb(index = 5)] pub view_type: ViewType, - - #[pb(index = 6)] - pub data: String, } impl CreateViewParams { @@ -81,7 +78,6 @@ impl CreateViewParams { desc, thumbnail, view_type, - data: initial_string(), } } } diff --git a/shared-lib/flowy-core-data-model/src/protobuf/model/view_create.rs b/shared-lib/flowy-core-data-model/src/protobuf/model/view_create.rs index f13b24c4ac..e21f461c1b 100644 --- a/shared-lib/flowy-core-data-model/src/protobuf/model/view_create.rs +++ b/shared-lib/flowy-core-data-model/src/protobuf/model/view_create.rs @@ -387,7 +387,6 @@ pub struct CreateViewParams { pub desc: ::std::string::String, pub thumbnail: ::std::string::String, pub view_type: ViewType, - pub data: ::std::string::String, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -522,32 +521,6 @@ impl CreateViewParams { pub fn set_view_type(&mut self, v: ViewType) { self.view_type = v; } - - // string data = 6; - - - pub fn get_data(&self) -> &str { - &self.data - } - pub fn clear_data(&mut self) { - self.data.clear(); - } - - // Param is passed by value, moved - pub fn set_data(&mut self, v: ::std::string::String) { - self.data = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_data(&mut self) -> &mut ::std::string::String { - &mut self.data - } - - // Take field - pub fn take_data(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.data, ::std::string::String::new()) - } } impl ::protobuf::Message for CreateViewParams { @@ -574,9 +547,6 @@ impl ::protobuf::Message for CreateViewParams { 5 => { ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.view_type, 5, &mut self.unknown_fields)? }, - 6 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.data)?; - }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; }, @@ -604,9 +574,6 @@ impl ::protobuf::Message for CreateViewParams { if self.view_type != ViewType::Blank { my_size += ::protobuf::rt::enum_size(5, self.view_type); } - if !self.data.is_empty() { - my_size += ::protobuf::rt::string_size(6, &self.data); - } my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); my_size @@ -628,9 +595,6 @@ impl ::protobuf::Message for CreateViewParams { if self.view_type != ViewType::Blank { os.write_enum(5, ::protobuf::ProtobufEnum::value(&self.view_type))?; } - if !self.data.is_empty() { - os.write_string(6, &self.data)?; - } os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) } @@ -694,11 +658,6 @@ impl ::protobuf::Message for CreateViewParams { |m: &CreateViewParams| { &m.view_type }, |m: &mut CreateViewParams| { &mut m.view_type }, )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "data", - |m: &CreateViewParams| { &m.data }, - |m: &mut CreateViewParams| { &mut m.data }, - )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "CreateViewParams", fields, @@ -720,7 +679,6 @@ impl ::protobuf::Clear for CreateViewParams { self.desc.clear(); self.thumbnail.clear(); self.view_type = ViewType::Blank; - self.data.clear(); self.unknown_fields.clear(); } } @@ -1436,92 +1394,88 @@ static file_descriptor_proto_data: &'static [u8] = b"\ long_to_id\x18\x01\x20\x01(\tR\nbelongToId\x12\x12\n\x04name\x18\x02\x20\ \x01(\tR\x04name\x12\x12\n\x04desc\x18\x03\x20\x01(\tR\x04desc\x12\x1e\n\ \tthumbnail\x18\x04\x20\x01(\tH\0R\tthumbnail\x12&\n\tview_type\x18\x05\ - \x20\x01(\x0e2\t.ViewTypeR\x08viewTypeB\x12\n\x10one_of_thumbnail\"\xb6\ + \x20\x01(\x0e2\t.ViewTypeR\x08viewTypeB\x12\n\x10one_of_thumbnail\"\xa2\ \x01\n\x10CreateViewParams\x12\x20\n\x0cbelong_to_id\x18\x01\x20\x01(\tR\ \nbelongToId\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x12\n\x04\ desc\x18\x03\x20\x01(\tR\x04desc\x12\x1c\n\tthumbnail\x18\x04\x20\x01(\t\ R\tthumbnail\x12&\n\tview_type\x18\x05\x20\x01(\x0e2\t.ViewTypeR\x08view\ - Type\x12\x12\n\x04data\x18\x06\x20\x01(\tR\x04data\"\x97\x02\n\x04View\ - \x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x20\n\x0cbelong_to_id\x18\ - \x02\x20\x01(\tR\nbelongToId\x12\x12\n\x04name\x18\x03\x20\x01(\tR\x04na\ - me\x12\x12\n\x04desc\x18\x04\x20\x01(\tR\x04desc\x12&\n\tview_type\x18\ - \x05\x20\x01(\x0e2\t.ViewTypeR\x08viewType\x12\x18\n\x07version\x18\x06\ - \x20\x01(\x03R\x07version\x12-\n\nbelongings\x18\x07\x20\x01(\x0b2\r.Rep\ - eatedViewR\nbelongings\x12#\n\rmodified_time\x18\x08\x20\x01(\x03R\x0cmo\ - difiedTime\x12\x1f\n\x0bcreate_time\x18\t\x20\x01(\x03R\ncreateTime\"+\n\ - \x0cRepeatedView\x12\x1b\n\x05items\x18\x01\x20\x03(\x0b2\x05.ViewR\x05i\ - tems*\x1e\n\x08ViewType\x12\t\n\x05Blank\x10\0\x12\x07\n\x03Doc\x10\x01J\ - \x88\x0b\n\x06\x12\x04\0\0\"\x01\n\x08\n\x01\x0c\x12\x03\0\0\x12\n\n\n\ - \x02\x04\0\x12\x04\x02\0\x08\x01\n\n\n\x03\x04\0\x01\x12\x03\x02\x08\x19\ - \n\x0b\n\x04\x04\0\x02\0\x12\x03\x03\x04\x1c\n\x0c\n\x05\x04\0\x02\0\x05\ - \x12\x03\x03\x04\n\n\x0c\n\x05\x04\0\x02\0\x01\x12\x03\x03\x0b\x17\n\x0c\ - \n\x05\x04\0\x02\0\x03\x12\x03\x03\x1a\x1b\n\x0b\n\x04\x04\0\x02\x01\x12\ - \x03\x04\x04\x14\n\x0c\n\x05\x04\0\x02\x01\x05\x12\x03\x04\x04\n\n\x0c\n\ - \x05\x04\0\x02\x01\x01\x12\x03\x04\x0b\x0f\n\x0c\n\x05\x04\0\x02\x01\x03\ - \x12\x03\x04\x12\x13\n\x0b\n\x04\x04\0\x02\x02\x12\x03\x05\x04\x14\n\x0c\ - \n\x05\x04\0\x02\x02\x05\x12\x03\x05\x04\n\n\x0c\n\x05\x04\0\x02\x02\x01\ - \x12\x03\x05\x0b\x0f\n\x0c\n\x05\x04\0\x02\x02\x03\x12\x03\x05\x12\x13\n\ - \x0b\n\x04\x04\0\x08\0\x12\x03\x06\x044\n\x0c\n\x05\x04\0\x08\0\x01\x12\ - \x03\x06\n\x1a\n\x0b\n\x04\x04\0\x02\x03\x12\x03\x06\x1d2\n\x0c\n\x05\ - \x04\0\x02\x03\x05\x12\x03\x06\x1d#\n\x0c\n\x05\x04\0\x02\x03\x01\x12\ - \x03\x06$-\n\x0c\n\x05\x04\0\x02\x03\x03\x12\x03\x0601\n\x0b\n\x04\x04\0\ - \x02\x04\x12\x03\x07\x04\x1b\n\x0c\n\x05\x04\0\x02\x04\x06\x12\x03\x07\ - \x04\x0c\n\x0c\n\x05\x04\0\x02\x04\x01\x12\x03\x07\r\x16\n\x0c\n\x05\x04\ - \0\x02\x04\x03\x12\x03\x07\x19\x1a\n\n\n\x02\x04\x01\x12\x04\t\0\x10\x01\ - \n\n\n\x03\x04\x01\x01\x12\x03\t\x08\x18\n\x0b\n\x04\x04\x01\x02\0\x12\ - \x03\n\x04\x1c\n\x0c\n\x05\x04\x01\x02\0\x05\x12\x03\n\x04\n\n\x0c\n\x05\ - \x04\x01\x02\0\x01\x12\x03\n\x0b\x17\n\x0c\n\x05\x04\x01\x02\0\x03\x12\ - \x03\n\x1a\x1b\n\x0b\n\x04\x04\x01\x02\x01\x12\x03\x0b\x04\x14\n\x0c\n\ - \x05\x04\x01\x02\x01\x05\x12\x03\x0b\x04\n\n\x0c\n\x05\x04\x01\x02\x01\ - \x01\x12\x03\x0b\x0b\x0f\n\x0c\n\x05\x04\x01\x02\x01\x03\x12\x03\x0b\x12\ - \x13\n\x0b\n\x04\x04\x01\x02\x02\x12\x03\x0c\x04\x14\n\x0c\n\x05\x04\x01\ - \x02\x02\x05\x12\x03\x0c\x04\n\n\x0c\n\x05\x04\x01\x02\x02\x01\x12\x03\ - \x0c\x0b\x0f\n\x0c\n\x05\x04\x01\x02\x02\x03\x12\x03\x0c\x12\x13\n\x0b\n\ - \x04\x04\x01\x02\x03\x12\x03\r\x04\x19\n\x0c\n\x05\x04\x01\x02\x03\x05\ - \x12\x03\r\x04\n\n\x0c\n\x05\x04\x01\x02\x03\x01\x12\x03\r\x0b\x14\n\x0c\ - \n\x05\x04\x01\x02\x03\x03\x12\x03\r\x17\x18\n\x0b\n\x04\x04\x01\x02\x04\ - \x12\x03\x0e\x04\x1b\n\x0c\n\x05\x04\x01\x02\x04\x06\x12\x03\x0e\x04\x0c\ - \n\x0c\n\x05\x04\x01\x02\x04\x01\x12\x03\x0e\r\x16\n\x0c\n\x05\x04\x01\ - \x02\x04\x03\x12\x03\x0e\x19\x1a\n\x0b\n\x04\x04\x01\x02\x05\x12\x03\x0f\ - \x04\x14\n\x0c\n\x05\x04\x01\x02\x05\x05\x12\x03\x0f\x04\n\n\x0c\n\x05\ - \x04\x01\x02\x05\x01\x12\x03\x0f\x0b\x0f\n\x0c\n\x05\x04\x01\x02\x05\x03\ - \x12\x03\x0f\x12\x13\n\n\n\x02\x04\x02\x12\x04\x11\0\x1b\x01\n\n\n\x03\ - \x04\x02\x01\x12\x03\x11\x08\x0c\n\x0b\n\x04\x04\x02\x02\0\x12\x03\x12\ - \x04\x12\n\x0c\n\x05\x04\x02\x02\0\x05\x12\x03\x12\x04\n\n\x0c\n\x05\x04\ - \x02\x02\0\x01\x12\x03\x12\x0b\r\n\x0c\n\x05\x04\x02\x02\0\x03\x12\x03\ - \x12\x10\x11\n\x0b\n\x04\x04\x02\x02\x01\x12\x03\x13\x04\x1c\n\x0c\n\x05\ - \x04\x02\x02\x01\x05\x12\x03\x13\x04\n\n\x0c\n\x05\x04\x02\x02\x01\x01\ - \x12\x03\x13\x0b\x17\n\x0c\n\x05\x04\x02\x02\x01\x03\x12\x03\x13\x1a\x1b\ - \n\x0b\n\x04\x04\x02\x02\x02\x12\x03\x14\x04\x14\n\x0c\n\x05\x04\x02\x02\ - \x02\x05\x12\x03\x14\x04\n\n\x0c\n\x05\x04\x02\x02\x02\x01\x12\x03\x14\ - \x0b\x0f\n\x0c\n\x05\x04\x02\x02\x02\x03\x12\x03\x14\x12\x13\n\x0b\n\x04\ - \x04\x02\x02\x03\x12\x03\x15\x04\x14\n\x0c\n\x05\x04\x02\x02\x03\x05\x12\ - \x03\x15\x04\n\n\x0c\n\x05\x04\x02\x02\x03\x01\x12\x03\x15\x0b\x0f\n\x0c\ - \n\x05\x04\x02\x02\x03\x03\x12\x03\x15\x12\x13\n\x0b\n\x04\x04\x02\x02\ - \x04\x12\x03\x16\x04\x1b\n\x0c\n\x05\x04\x02\x02\x04\x06\x12\x03\x16\x04\ - \x0c\n\x0c\n\x05\x04\x02\x02\x04\x01\x12\x03\x16\r\x16\n\x0c\n\x05\x04\ - \x02\x02\x04\x03\x12\x03\x16\x19\x1a\n\x0b\n\x04\x04\x02\x02\x05\x12\x03\ - \x17\x04\x16\n\x0c\n\x05\x04\x02\x02\x05\x05\x12\x03\x17\x04\t\n\x0c\n\ - \x05\x04\x02\x02\x05\x01\x12\x03\x17\n\x11\n\x0c\n\x05\x04\x02\x02\x05\ - \x03\x12\x03\x17\x14\x15\n\x0b\n\x04\x04\x02\x02\x06\x12\x03\x18\x04\x20\ - \n\x0c\n\x05\x04\x02\x02\x06\x06\x12\x03\x18\x04\x10\n\x0c\n\x05\x04\x02\ - \x02\x06\x01\x12\x03\x18\x11\x1b\n\x0c\n\x05\x04\x02\x02\x06\x03\x12\x03\ - \x18\x1e\x1f\n\x0b\n\x04\x04\x02\x02\x07\x12\x03\x19\x04\x1c\n\x0c\n\x05\ - \x04\x02\x02\x07\x05\x12\x03\x19\x04\t\n\x0c\n\x05\x04\x02\x02\x07\x01\ - \x12\x03\x19\n\x17\n\x0c\n\x05\x04\x02\x02\x07\x03\x12\x03\x19\x1a\x1b\n\ - \x0b\n\x04\x04\x02\x02\x08\x12\x03\x1a\x04\x1a\n\x0c\n\x05\x04\x02\x02\ - \x08\x05\x12\x03\x1a\x04\t\n\x0c\n\x05\x04\x02\x02\x08\x01\x12\x03\x1a\n\ - \x15\n\x0c\n\x05\x04\x02\x02\x08\x03\x12\x03\x1a\x18\x19\n\n\n\x02\x04\ - \x03\x12\x04\x1c\0\x1e\x01\n\n\n\x03\x04\x03\x01\x12\x03\x1c\x08\x14\n\ - \x0b\n\x04\x04\x03\x02\0\x12\x03\x1d\x04\x1c\n\x0c\n\x05\x04\x03\x02\0\ - \x04\x12\x03\x1d\x04\x0c\n\x0c\n\x05\x04\x03\x02\0\x06\x12\x03\x1d\r\x11\ - \n\x0c\n\x05\x04\x03\x02\0\x01\x12\x03\x1d\x12\x17\n\x0c\n\x05\x04\x03\ - \x02\0\x03\x12\x03\x1d\x1a\x1b\n\n\n\x02\x05\0\x12\x04\x1f\0\"\x01\n\n\n\ - \x03\x05\0\x01\x12\x03\x1f\x05\r\n\x0b\n\x04\x05\0\x02\0\x12\x03\x20\x04\ - \x0e\n\x0c\n\x05\x05\0\x02\0\x01\x12\x03\x20\x04\t\n\x0c\n\x05\x05\0\x02\ - \0\x02\x12\x03\x20\x0c\r\n\x0b\n\x04\x05\0\x02\x01\x12\x03!\x04\x0c\n\ - \x0c\n\x05\x05\0\x02\x01\x01\x12\x03!\x04\x07\n\x0c\n\x05\x05\0\x02\x01\ - \x02\x12\x03!\n\x0bb\x06proto3\ + Type\"\x97\x02\n\x04View\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\ + \x20\n\x0cbelong_to_id\x18\x02\x20\x01(\tR\nbelongToId\x12\x12\n\x04name\ + \x18\x03\x20\x01(\tR\x04name\x12\x12\n\x04desc\x18\x04\x20\x01(\tR\x04de\ + sc\x12&\n\tview_type\x18\x05\x20\x01(\x0e2\t.ViewTypeR\x08viewType\x12\ + \x18\n\x07version\x18\x06\x20\x01(\x03R\x07version\x12-\n\nbelongings\ + \x18\x07\x20\x01(\x0b2\r.RepeatedViewR\nbelongings\x12#\n\rmodified_time\ + \x18\x08\x20\x01(\x03R\x0cmodifiedTime\x12\x1f\n\x0bcreate_time\x18\t\ + \x20\x01(\x03R\ncreateTime\"+\n\x0cRepeatedView\x12\x1b\n\x05items\x18\ + \x01\x20\x03(\x0b2\x05.ViewR\x05items*\x1e\n\x08ViewType\x12\t\n\x05Blan\ + k\x10\0\x12\x07\n\x03Doc\x10\x01J\xd1\n\n\x06\x12\x04\0\0!\x01\n\x08\n\ + \x01\x0c\x12\x03\0\0\x12\n\n\n\x02\x04\0\x12\x04\x02\0\x08\x01\n\n\n\x03\ + \x04\0\x01\x12\x03\x02\x08\x19\n\x0b\n\x04\x04\0\x02\0\x12\x03\x03\x04\ + \x1c\n\x0c\n\x05\x04\0\x02\0\x05\x12\x03\x03\x04\n\n\x0c\n\x05\x04\0\x02\ + \0\x01\x12\x03\x03\x0b\x17\n\x0c\n\x05\x04\0\x02\0\x03\x12\x03\x03\x1a\ + \x1b\n\x0b\n\x04\x04\0\x02\x01\x12\x03\x04\x04\x14\n\x0c\n\x05\x04\0\x02\ + \x01\x05\x12\x03\x04\x04\n\n\x0c\n\x05\x04\0\x02\x01\x01\x12\x03\x04\x0b\ + \x0f\n\x0c\n\x05\x04\0\x02\x01\x03\x12\x03\x04\x12\x13\n\x0b\n\x04\x04\0\ + \x02\x02\x12\x03\x05\x04\x14\n\x0c\n\x05\x04\0\x02\x02\x05\x12\x03\x05\ + \x04\n\n\x0c\n\x05\x04\0\x02\x02\x01\x12\x03\x05\x0b\x0f\n\x0c\n\x05\x04\ + \0\x02\x02\x03\x12\x03\x05\x12\x13\n\x0b\n\x04\x04\0\x08\0\x12\x03\x06\ + \x044\n\x0c\n\x05\x04\0\x08\0\x01\x12\x03\x06\n\x1a\n\x0b\n\x04\x04\0\ + \x02\x03\x12\x03\x06\x1d2\n\x0c\n\x05\x04\0\x02\x03\x05\x12\x03\x06\x1d#\ + \n\x0c\n\x05\x04\0\x02\x03\x01\x12\x03\x06$-\n\x0c\n\x05\x04\0\x02\x03\ + \x03\x12\x03\x0601\n\x0b\n\x04\x04\0\x02\x04\x12\x03\x07\x04\x1b\n\x0c\n\ + \x05\x04\0\x02\x04\x06\x12\x03\x07\x04\x0c\n\x0c\n\x05\x04\0\x02\x04\x01\ + \x12\x03\x07\r\x16\n\x0c\n\x05\x04\0\x02\x04\x03\x12\x03\x07\x19\x1a\n\n\ + \n\x02\x04\x01\x12\x04\t\0\x0f\x01\n\n\n\x03\x04\x01\x01\x12\x03\t\x08\ + \x18\n\x0b\n\x04\x04\x01\x02\0\x12\x03\n\x04\x1c\n\x0c\n\x05\x04\x01\x02\ + \0\x05\x12\x03\n\x04\n\n\x0c\n\x05\x04\x01\x02\0\x01\x12\x03\n\x0b\x17\n\ + \x0c\n\x05\x04\x01\x02\0\x03\x12\x03\n\x1a\x1b\n\x0b\n\x04\x04\x01\x02\ + \x01\x12\x03\x0b\x04\x14\n\x0c\n\x05\x04\x01\x02\x01\x05\x12\x03\x0b\x04\ + \n\n\x0c\n\x05\x04\x01\x02\x01\x01\x12\x03\x0b\x0b\x0f\n\x0c\n\x05\x04\ + \x01\x02\x01\x03\x12\x03\x0b\x12\x13\n\x0b\n\x04\x04\x01\x02\x02\x12\x03\ + \x0c\x04\x14\n\x0c\n\x05\x04\x01\x02\x02\x05\x12\x03\x0c\x04\n\n\x0c\n\ + \x05\x04\x01\x02\x02\x01\x12\x03\x0c\x0b\x0f\n\x0c\n\x05\x04\x01\x02\x02\ + \x03\x12\x03\x0c\x12\x13\n\x0b\n\x04\x04\x01\x02\x03\x12\x03\r\x04\x19\n\ + \x0c\n\x05\x04\x01\x02\x03\x05\x12\x03\r\x04\n\n\x0c\n\x05\x04\x01\x02\ + \x03\x01\x12\x03\r\x0b\x14\n\x0c\n\x05\x04\x01\x02\x03\x03\x12\x03\r\x17\ + \x18\n\x0b\n\x04\x04\x01\x02\x04\x12\x03\x0e\x04\x1b\n\x0c\n\x05\x04\x01\ + \x02\x04\x06\x12\x03\x0e\x04\x0c\n\x0c\n\x05\x04\x01\x02\x04\x01\x12\x03\ + \x0e\r\x16\n\x0c\n\x05\x04\x01\x02\x04\x03\x12\x03\x0e\x19\x1a\n\n\n\x02\ + \x04\x02\x12\x04\x10\0\x1a\x01\n\n\n\x03\x04\x02\x01\x12\x03\x10\x08\x0c\ + \n\x0b\n\x04\x04\x02\x02\0\x12\x03\x11\x04\x12\n\x0c\n\x05\x04\x02\x02\0\ + \x05\x12\x03\x11\x04\n\n\x0c\n\x05\x04\x02\x02\0\x01\x12\x03\x11\x0b\r\n\ + \x0c\n\x05\x04\x02\x02\0\x03\x12\x03\x11\x10\x11\n\x0b\n\x04\x04\x02\x02\ + \x01\x12\x03\x12\x04\x1c\n\x0c\n\x05\x04\x02\x02\x01\x05\x12\x03\x12\x04\ + \n\n\x0c\n\x05\x04\x02\x02\x01\x01\x12\x03\x12\x0b\x17\n\x0c\n\x05\x04\ + \x02\x02\x01\x03\x12\x03\x12\x1a\x1b\n\x0b\n\x04\x04\x02\x02\x02\x12\x03\ + \x13\x04\x14\n\x0c\n\x05\x04\x02\x02\x02\x05\x12\x03\x13\x04\n\n\x0c\n\ + \x05\x04\x02\x02\x02\x01\x12\x03\x13\x0b\x0f\n\x0c\n\x05\x04\x02\x02\x02\ + \x03\x12\x03\x13\x12\x13\n\x0b\n\x04\x04\x02\x02\x03\x12\x03\x14\x04\x14\ + \n\x0c\n\x05\x04\x02\x02\x03\x05\x12\x03\x14\x04\n\n\x0c\n\x05\x04\x02\ + \x02\x03\x01\x12\x03\x14\x0b\x0f\n\x0c\n\x05\x04\x02\x02\x03\x03\x12\x03\ + \x14\x12\x13\n\x0b\n\x04\x04\x02\x02\x04\x12\x03\x15\x04\x1b\n\x0c\n\x05\ + \x04\x02\x02\x04\x06\x12\x03\x15\x04\x0c\n\x0c\n\x05\x04\x02\x02\x04\x01\ + \x12\x03\x15\r\x16\n\x0c\n\x05\x04\x02\x02\x04\x03\x12\x03\x15\x19\x1a\n\ + \x0b\n\x04\x04\x02\x02\x05\x12\x03\x16\x04\x16\n\x0c\n\x05\x04\x02\x02\ + \x05\x05\x12\x03\x16\x04\t\n\x0c\n\x05\x04\x02\x02\x05\x01\x12\x03\x16\n\ + \x11\n\x0c\n\x05\x04\x02\x02\x05\x03\x12\x03\x16\x14\x15\n\x0b\n\x04\x04\ + \x02\x02\x06\x12\x03\x17\x04\x20\n\x0c\n\x05\x04\x02\x02\x06\x06\x12\x03\ + \x17\x04\x10\n\x0c\n\x05\x04\x02\x02\x06\x01\x12\x03\x17\x11\x1b\n\x0c\n\ + \x05\x04\x02\x02\x06\x03\x12\x03\x17\x1e\x1f\n\x0b\n\x04\x04\x02\x02\x07\ + \x12\x03\x18\x04\x1c\n\x0c\n\x05\x04\x02\x02\x07\x05\x12\x03\x18\x04\t\n\ + \x0c\n\x05\x04\x02\x02\x07\x01\x12\x03\x18\n\x17\n\x0c\n\x05\x04\x02\x02\ + \x07\x03\x12\x03\x18\x1a\x1b\n\x0b\n\x04\x04\x02\x02\x08\x12\x03\x19\x04\ + \x1a\n\x0c\n\x05\x04\x02\x02\x08\x05\x12\x03\x19\x04\t\n\x0c\n\x05\x04\ + \x02\x02\x08\x01\x12\x03\x19\n\x15\n\x0c\n\x05\x04\x02\x02\x08\x03\x12\ + \x03\x19\x18\x19\n\n\n\x02\x04\x03\x12\x04\x1b\0\x1d\x01\n\n\n\x03\x04\ + \x03\x01\x12\x03\x1b\x08\x14\n\x0b\n\x04\x04\x03\x02\0\x12\x03\x1c\x04\ + \x1c\n\x0c\n\x05\x04\x03\x02\0\x04\x12\x03\x1c\x04\x0c\n\x0c\n\x05\x04\ + \x03\x02\0\x06\x12\x03\x1c\r\x11\n\x0c\n\x05\x04\x03\x02\0\x01\x12\x03\ + \x1c\x12\x17\n\x0c\n\x05\x04\x03\x02\0\x03\x12\x03\x1c\x1a\x1b\n\n\n\x02\ + \x05\0\x12\x04\x1e\0!\x01\n\n\n\x03\x05\0\x01\x12\x03\x1e\x05\r\n\x0b\n\ + \x04\x05\0\x02\0\x12\x03\x1f\x04\x0e\n\x0c\n\x05\x05\0\x02\0\x01\x12\x03\ + \x1f\x04\t\n\x0c\n\x05\x05\0\x02\0\x02\x12\x03\x1f\x0c\r\n\x0b\n\x04\x05\ + \0\x02\x01\x12\x03\x20\x04\x0c\n\x0c\n\x05\x05\0\x02\x01\x01\x12\x03\x20\ + \x04\x07\n\x0c\n\x05\x05\0\x02\x01\x02\x12\x03\x20\n\x0bb\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-core-data-model/src/protobuf/proto/view_create.proto b/shared-lib/flowy-core-data-model/src/protobuf/proto/view_create.proto index 03b5b26a64..059d1de7c7 100644 --- a/shared-lib/flowy-core-data-model/src/protobuf/proto/view_create.proto +++ b/shared-lib/flowy-core-data-model/src/protobuf/proto/view_create.proto @@ -13,7 +13,6 @@ message CreateViewParams { string desc = 3; string thumbnail = 4; ViewType view_type = 5; - string data = 6; } message View { string id = 1; diff --git a/shared-lib/flowy-derive/src/derive_cache/derive_cache.rs b/shared-lib/flowy-derive/src/derive_cache/derive_cache.rs index acc1e7d3d8..4f704a4df8 100644 --- a/shared-lib/flowy-derive/src/derive_cache/derive_cache.rs +++ b/shared-lib/flowy-derive/src/derive_cache/derive_cache.rs @@ -33,7 +33,7 @@ pub fn category_from_str(type_str: &str) -> TypeCategory { | "UpdateUserParams" | "CreateDocParams" | "Doc" - | "UpdateDocParams" + | "ResetDocumentParams" | "DocDelta" | "NewDocUser" | "DocIdentifier" diff --git a/shared-lib/lib-ot/src/errors.rs b/shared-lib/lib-ot/src/errors.rs index ea0df1b69e..2346908169 100644 --- a/shared-lib/lib-ot/src/errors.rs +++ b/shared-lib/lib-ot/src/errors.rs @@ -99,7 +99,7 @@ impl ErrorBuilder { pub fn build(mut self) -> OTError { OTError::new(self.code, &self.msg.take().unwrap_or_else(|| "".to_owned())) } } -pub fn internal_error(e: T) -> OTError +pub(crate) fn internal_error(e: T) -> OTError where T: std::fmt::Debug, { diff --git a/shared-lib/lib-ws/src/errors.rs b/shared-lib/lib-ws/src/errors.rs index 9003f9ebf9..ea80a298c7 100644 --- a/shared-lib/lib-ws/src/errors.rs +++ b/shared-lib/lib-ws/src/errors.rs @@ -45,7 +45,7 @@ impl WSError { static_ws_error!(unauthorized, ErrorCode::Unauthorized); } -pub fn internal_error(e: T) -> WSError +pub(crate) fn internal_error(e: T) -> WSError where T: std::fmt::Debug, {