add user_id in revision

This commit is contained in:
appflowy 2021-12-09 22:28:11 +08:00
parent 3fa0f97e74
commit 45d9a0918f
19 changed files with 186 additions and 91 deletions

View File

@ -22,6 +22,7 @@ class Revision extends $pb.GeneratedMessage {
..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'md5') ..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'md5')
..aOS(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'docId') ..aOS(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'docId')
..e<RevType>(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'ty', $pb.PbFieldType.OE, defaultOrMaker: RevType.Local, valueOf: RevType.valueOf, enumValues: RevType.values) ..e<RevType>(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'ty', $pb.PbFieldType.OE, defaultOrMaker: RevType.Local, valueOf: RevType.valueOf, enumValues: RevType.values)
..aOS(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'userId')
..hasRequiredFields = false ..hasRequiredFields = false
; ;
@ -33,6 +34,7 @@ class Revision extends $pb.GeneratedMessage {
$core.String? md5, $core.String? md5,
$core.String? docId, $core.String? docId,
RevType? ty, RevType? ty,
$core.String? userId,
}) { }) {
final _result = create(); final _result = create();
if (baseRevId != null) { if (baseRevId != null) {
@ -53,6 +55,9 @@ class Revision extends $pb.GeneratedMessage {
if (ty != null) { if (ty != null) {
_result.ty = ty; _result.ty = ty;
} }
if (userId != null) {
_result.userId = userId;
}
return _result; return _result;
} }
factory Revision.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); factory Revision.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
@ -129,6 +134,15 @@ class Revision extends $pb.GeneratedMessage {
$core.bool hasTy() => $_has(5); $core.bool hasTy() => $_has(5);
@$pb.TagNumber(6) @$pb.TagNumber(6)
void clearTy() => clearField(6); void clearTy() => clearField(6);
@$pb.TagNumber(7)
$core.String get userId => $_getSZ(6);
@$pb.TagNumber(7)
set userId($core.String v) { $_setString(6, v); }
@$pb.TagNumber(7)
$core.bool hasUserId() => $_has(6);
@$pb.TagNumber(7)
void clearUserId() => clearField(7);
} }
class RevId extends $pb.GeneratedMessage { class RevId extends $pb.GeneratedMessage {

View File

@ -29,11 +29,12 @@ const Revision$json = const {
const {'1': 'md5', '3': 4, '4': 1, '5': 9, '10': 'md5'}, const {'1': 'md5', '3': 4, '4': 1, '5': 9, '10': 'md5'},
const {'1': 'doc_id', '3': 5, '4': 1, '5': 9, '10': 'docId'}, const {'1': 'doc_id', '3': 5, '4': 1, '5': 9, '10': 'docId'},
const {'1': 'ty', '3': 6, '4': 1, '5': 14, '6': '.RevType', '10': 'ty'}, const {'1': 'ty', '3': 6, '4': 1, '5': 14, '6': '.RevType', '10': 'ty'},
const {'1': 'user_id', '3': 7, '4': 1, '5': 9, '10': 'userId'},
], ],
}; };
/// Descriptor for `Revision`. Decode as a `google.protobuf.DescriptorProto`. /// Descriptor for `Revision`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List revisionDescriptor = $convert.base64Decode('CghSZXZpc2lvbhIeCgtiYXNlX3Jldl9pZBgBIAEoA1IJYmFzZVJldklkEhUKBnJldl9pZBgCIAEoA1IFcmV2SWQSHQoKZGVsdGFfZGF0YRgDIAEoDFIJZGVsdGFEYXRhEhAKA21kNRgEIAEoCVIDbWQ1EhUKBmRvY19pZBgFIAEoCVIFZG9jSWQSGAoCdHkYBiABKA4yCC5SZXZUeXBlUgJ0eQ=='); final $typed_data.Uint8List revisionDescriptor = $convert.base64Decode('CghSZXZpc2lvbhIeCgtiYXNlX3Jldl9pZBgBIAEoA1IJYmFzZVJldklkEhUKBnJldl9pZBgCIAEoA1IFcmV2SWQSHQoKZGVsdGFfZGF0YRgDIAEoDFIJZGVsdGFEYXRhEhAKA21kNRgEIAEoCVIDbWQ1EhUKBmRvY19pZBgFIAEoCVIFZG9jSWQSGAoCdHkYBiABKA4yCC5SZXZUeXBlUgJ0eRIXCgd1c2VyX2lkGAcgASgJUgZ1c2VySWQ=');
@$core.Deprecated('Use revIdDescriptor instead') @$core.Deprecated('Use revIdDescriptor instead')
const RevId$json = const { const RevId$json = const {
'1': 'RevId', '1': 'RevId',

View File

@ -112,12 +112,13 @@ impl DocController {
// let doc = self.read_doc(doc_id, pool.clone()).await?; // let doc = self.read_doc(doc_id, pool.clone()).await?;
let ws_sender = self.ws_manager.ws(); let ws_sender = self.ws_manager.ws();
let token = self.user.token()?; let token = self.user.token()?;
let user_id = self.user.user_id()?;
let server = Arc::new(RevisionServerImpl { let server = Arc::new(RevisionServerImpl {
token, token,
server: self.server.clone(), server: self.server.clone(),
}); });
let cache = Arc::new(RevisionCache::new(doc_id, pool, server)); let cache = Arc::new(RevisionCache::new(&user_id, doc_id, pool, server));
Ok(RevisionManager::new(doc_id, cache, ws_sender)) Ok(RevisionManager::new(&user_id, doc_id, cache, ws_sender))
} }
} }

View File

@ -163,7 +163,8 @@ impl ClientDocEditor {
let delta_data = delta.to_bytes(); let delta_data = delta.to_bytes();
let (base_rev_id, rev_id) = self.rev_manager.next_rev_id(); let (base_rev_id, rev_id) = self.rev_manager.next_rev_id();
let delta_data = delta_data.to_vec(); let delta_data = delta_data.to_vec();
let revision = Revision::new(base_rev_id, rev_id, delta_data, &self.doc_id, RevType::Local); let user_id = self.user.user_id()?;
let revision = Revision::new(base_rev_id, rev_id, delta_data, &self.doc_id, RevType::Local, user_id);
let _ = self.rev_manager.add_revision(&revision).await?; let _ = self.rev_manager.add_revision(&revision).await?;
Ok(rev_id.into()) Ok(rev_id.into())
} }
@ -236,22 +237,26 @@ impl ClientDocEditor {
let (local_base_rev_id, local_rev_id) = self.rev_manager.next_rev_id(); let (local_base_rev_id, local_rev_id) = self.rev_manager.next_rev_id();
// save the revision // save the revision
let user_id = self.user.user_id()?;
let revision = Revision::new( let revision = Revision::new(
local_base_rev_id, local_base_rev_id,
local_rev_id, local_rev_id,
client_prime.to_bytes().to_vec(), client_prime.to_bytes().to_vec(),
&self.doc_id, &self.doc_id,
RevType::Remote, RevType::Remote,
user_id,
); );
let _ = self.rev_manager.add_revision(&revision).await?; let _ = self.rev_manager.add_revision(&revision).await?;
// send the server_prime delta // send the server_prime delta
let user_id = self.user.user_id()?;
let revision = Revision::new( let revision = Revision::new(
local_base_rev_id, local_base_rev_id,
local_rev_id, local_rev_id,
server_prime.to_bytes().to_vec(), server_prime.to_bytes().to_vec(),
&self.doc_id, &self.doc_id,
RevType::Remote, RevType::Remote,
user_id,
); );
let _ = self.ws_sender.send(revision.into()); let _ = self.ws_sender.send(revision.into());
Ok(()) Ok(())

View File

@ -24,6 +24,7 @@ pub trait RevisionIterator: Send + Sync {
type DocRevisionDeskCache = dyn RevisionDiskCache<Error = DocError>; type DocRevisionDeskCache = dyn RevisionDiskCache<Error = DocError>;
pub struct RevisionCache { pub struct RevisionCache {
user_id: String,
doc_id: String, doc_id: String,
dish_cache: Arc<DocRevisionDeskCache>, dish_cache: Arc<DocRevisionDeskCache>,
memory_cache: Arc<RevisionMemoryCache>, memory_cache: Arc<RevisionMemoryCache>,
@ -32,11 +33,17 @@ pub struct RevisionCache {
} }
impl RevisionCache { impl RevisionCache {
pub fn new(doc_id: &str, pool: Arc<ConnectionPool>, server: Arc<dyn RevisionServer>) -> RevisionCache { pub fn new(
user_id: &str,
doc_id: &str,
pool: Arc<ConnectionPool>,
server: Arc<dyn RevisionServer>,
) -> RevisionCache {
let doc_id = doc_id.to_owned(); let doc_id = doc_id.to_owned();
let dish_cache = Arc::new(Persistence::new(pool)); let dish_cache = Arc::new(Persistence::new(user_id, pool));
let memory_cache = Arc::new(RevisionMemoryCache::new()); let memory_cache = Arc::new(RevisionMemoryCache::new());
Self { Self {
user_id: user_id.to_owned(),
doc_id, doc_id,
dish_cache, dish_cache,
memory_cache, memory_cache,
@ -117,6 +124,7 @@ impl RevisionCache {
delta_data.to_owned(), delta_data.to_owned(),
&doc.id, &doc.id,
RevType::Remote, RevType::Remote,
self.user_id.clone(),
); );
let record = RevisionRecord { let record = RevisionRecord {
revision, revision,
@ -215,6 +223,7 @@ fn correct_delta_if_need(delta: &mut RichTextDelta) {
} }
pub(crate) struct Persistence { pub(crate) struct Persistence {
user_id: String,
pub(crate) pool: Arc<ConnectionPool>, pub(crate) pool: Arc<ConnectionPool>,
} }
@ -231,25 +240,30 @@ impl RevisionDiskCache for Persistence {
fn revisions_in_range(&self, doc_id: &str, range: &RevisionRange) -> Result<Vec<Revision>, Self::Error> { fn revisions_in_range(&self, doc_id: &str, range: &RevisionRange) -> Result<Vec<Revision>, Self::Error> {
let conn = &*self.pool.get().map_err(internal_error).unwrap(); let conn = &*self.pool.get().map_err(internal_error).unwrap();
let revisions = RevTableSql::read_rev_tables_with_range(doc_id, range.clone(), conn)?; let revisions = RevTableSql::read_rev_tables_with_range(&self.user_id, doc_id, range.clone(), conn)?;
Ok(revisions) Ok(revisions)
} }
fn read_revision(&self, doc_id: &str, rev_id: i64) -> Result<Option<Revision>, Self::Error> { fn read_revision(&self, doc_id: &str, rev_id: i64) -> Result<Option<Revision>, Self::Error> {
let conn = self.pool.get().map_err(internal_error)?; let conn = self.pool.get().map_err(internal_error)?;
let some = RevTableSql::read_rev_table(doc_id, &rev_id, &*conn)?; let some = RevTableSql::read_rev_table(&self.user_id, doc_id, &rev_id, &*conn)?;
Ok(some) Ok(some)
} }
fn read_revisions(&self, doc_id: &str) -> Result<Vec<Revision>, Self::Error> { fn read_revisions(&self, doc_id: &str) -> Result<Vec<Revision>, Self::Error> {
let conn = self.pool.get().map_err(internal_error)?; let conn = self.pool.get().map_err(internal_error)?;
let some = RevTableSql::read_rev_tables(doc_id, &*conn)?; let some = RevTableSql::read_rev_tables(&self.user_id, doc_id, &*conn)?;
Ok(some) Ok(some)
} }
} }
impl Persistence { impl Persistence {
pub(crate) fn new(pool: Arc<ConnectionPool>) -> Self { Self { pool } } pub(crate) fn new(user_id: &str, pool: Arc<ConnectionPool>) -> Self {
Self {
user_id: user_id.to_owned(),
pool,
}
}
} }
#[cfg(feature = "flowy_unit_test")] #[cfg(feature = "flowy_unit_test")]

View File

@ -20,16 +20,18 @@ pub trait RevisionServer: Send + Sync {
pub struct RevisionManager { pub struct RevisionManager {
doc_id: String, doc_id: String,
user_id: String,
rev_id_counter: RevIdCounter, rev_id_counter: RevIdCounter,
cache: Arc<RevisionCache>, cache: Arc<RevisionCache>,
ws_sender: Arc<dyn DocumentWebSocket>, ws_sender: Arc<dyn DocumentWebSocket>,
} }
impl RevisionManager { impl RevisionManager {
pub fn new(doc_id: &str, cache: Arc<RevisionCache>, ws_sender: Arc<dyn DocumentWebSocket>) -> Self { pub fn new(user_id: &str, doc_id: &str, cache: Arc<RevisionCache>, ws_sender: Arc<dyn DocumentWebSocket>) -> Self {
let rev_id_counter = RevIdCounter::new(0); let rev_id_counter = RevIdCounter::new(0);
Self { Self {
doc_id: doc_id.to_string(), doc_id: doc_id.to_string(),
user_id: user_id.to_owned(),
rev_id_counter, rev_id_counter,
cache, cache,
ws_sender, ws_sender,
@ -83,6 +85,7 @@ impl RevisionManager {
delta_data.to_vec(), delta_data.to_vec(),
&self.doc_id, &self.doc_id,
RevType::Remote, RevType::Remote,
self.user_id.clone(),
); );
Ok(revision) Ok(revision)

View File

@ -1,6 +1,6 @@
use crate::{ use crate::{
errors::DocError, errors::DocError,
sql_tables::{doc::RevTable, RevChangeset, RevTableState, RevTableType}, sql_tables::{doc::RevTable, mk_revision_from_table, RevChangeset, RevTableState, RevTableType},
}; };
use diesel::update; use diesel::update;
use flowy_database::{insert_or_ignore_into, prelude::*, schema::rev_table::dsl, SqliteConnection}; use flowy_database::{insert_or_ignore_into, prelude::*, schema::rev_table::dsl, SqliteConnection};
@ -41,7 +41,11 @@ impl RevTableSql {
Ok(()) Ok(())
} }
pub(crate) fn read_rev_tables(doc_id: &str, conn: &SqliteConnection) -> Result<Vec<Revision>, DocError> { pub(crate) fn read_rev_tables(
user_id: &str,
doc_id: &str,
conn: &SqliteConnection,
) -> Result<Vec<Revision>, DocError> {
let filter = dsl::rev_table let filter = dsl::rev_table
.filter(dsl::doc_id.eq(doc_id)) .filter(dsl::doc_id.eq(doc_id))
.order(dsl::rev_id.asc()) .order(dsl::rev_id.asc())
@ -49,12 +53,13 @@ impl RevTableSql {
let rev_tables = filter.load::<RevTable>(conn)?; let rev_tables = filter.load::<RevTable>(conn)?;
let revisions = rev_tables let revisions = rev_tables
.into_iter() .into_iter()
.map(|table| table.into()) .map(|table| mk_revision_from_table(user_id, table))
.collect::<Vec<Revision>>(); .collect::<Vec<Revision>>();
Ok(revisions) Ok(revisions)
} }
pub(crate) fn read_rev_table( pub(crate) fn read_rev_table(
user_id: &str,
doc_id: &str, doc_id: &str,
revision_id: &i64, revision_id: &i64,
conn: &SqliteConnection, conn: &SqliteConnection,
@ -67,25 +72,26 @@ impl RevTableSql {
if Err(diesel::NotFound) == result { if Err(diesel::NotFound) == result {
Ok(None) Ok(None)
} else { } else {
Ok(Some(result?.into())) Ok(Some(mk_revision_from_table(user_id, result?)))
} }
} }
pub(crate) fn read_rev_tables_with_range( pub(crate) fn read_rev_tables_with_range(
doc_id_s: &str, user_id: &str,
doc_id: &str,
range: RevisionRange, range: RevisionRange,
conn: &SqliteConnection, conn: &SqliteConnection,
) -> Result<Vec<Revision>, DocError> { ) -> Result<Vec<Revision>, DocError> {
let rev_tables = dsl::rev_table let rev_tables = dsl::rev_table
.filter(dsl::rev_id.ge(range.start)) .filter(dsl::rev_id.ge(range.start))
.filter(dsl::rev_id.le(range.end)) .filter(dsl::rev_id.le(range.end))
.filter(dsl::doc_id.eq(doc_id_s)) .filter(dsl::doc_id.eq(doc_id))
.order(dsl::rev_id.asc()) .order(dsl::rev_id.asc())
.load::<RevTable>(conn)?; .load::<RevTable>(conn)?;
let revisions = rev_tables let revisions = rev_tables
.into_iter() .into_iter()
.map(|table| table.into()) .map(|table| mk_revision_from_table(user_id, table))
.collect::<Vec<Revision>>(); .collect::<Vec<Revision>>();
Ok(revisions) Ok(revisions)
} }

View File

@ -1,5 +1,6 @@
use diesel::sql_types::Integer; use diesel::sql_types::Integer;
use flowy_database::schema::rev_table; use flowy_database::schema::rev_table;
use flowy_document_infra::util::md5; use flowy_document_infra::util::md5;
use lib_ot::revision::{RevId, RevState, RevType, Revision}; use lib_ot::revision::{RevId, RevState, RevType, Revision};
@ -63,17 +64,16 @@ impl std::convert::From<RevState> for RevTableState {
} }
} }
impl std::convert::From<RevTable> for Revision { pub(crate) fn mk_revision_from_table(user_id: &str, table: RevTable) -> Revision {
fn from(table: RevTable) -> Self { let md5 = md5(&table.data);
let md5 = md5(&table.data); Revision {
Revision { base_rev_id: table.base_rev_id,
base_rev_id: table.base_rev_id, rev_id: table.rev_id,
rev_id: table.rev_id, delta_data: table.data,
delta_data: table.data, md5,
md5, doc_id: table.doc_id,
doc_id: table.doc_id, ty: table.ty.into(),
ty: table.ty.into(), user_id: user_id.to_owned(),
}
} }
} }

View File

@ -1,5 +1,5 @@
use flowy_test::editor::{EditorScript::*, *}; use flowy_test::editor::{EditorScript::*, *};
use lib_ot::{core::DeltaBuilder, revision::RevState, rich_text::RichTextDeltaBuilder}; use lib_ot::{revision::RevState, rich_text::RichTextDeltaBuilder};
#[tokio::test] #[tokio::test]
async fn doc_rev_state_test1() { async fn doc_rev_state_test1() {

View File

@ -9,7 +9,7 @@ use lib_ot::{
revision::{RevState, RevType, Revision, RevisionRange}, revision::{RevState, RevType, Revision, RevisionRange},
rich_text::RichTextDelta, rich_text::RichTextDelta,
}; };
use std::{str::FromStr, sync::Arc}; use std::sync::Arc;
use tokio::time::{sleep, Duration}; use tokio::time::{sleep, Duration};
pub enum EditorScript { pub enum EditorScript {
@ -56,10 +56,12 @@ impl EditorTest {
let _memory_cache = cache.memory_cache(); let _memory_cache = cache.memory_cache();
let _disk_cache = cache.dish_cache(); let _disk_cache = cache.dish_cache();
let doc_id = self.editor.doc_id.clone(); let doc_id = self.editor.doc_id.clone();
let user_id = self.sdk.user_session.user_id().unwrap();
match script { match script {
EditorScript::InsertText(s, offset) => { EditorScript::InsertText(s, offset) => {
self.editor.insert(offset, s).await.unwrap(); self.editor.insert(offset, s).await.unwrap();
sleep(Duration::from_millis(200)).await;
}, },
EditorScript::Delete(interval) => { EditorScript::Delete(interval) => {
self.editor.delete(interval).await.unwrap(); self.editor.delete(interval).await.unwrap();
@ -98,6 +100,7 @@ impl EditorTest {
delta.to_bytes().to_vec(), delta.to_bytes().to_vec(),
&doc_id, &doc_id,
RevType::Remote, RevType::Remote,
user_id,
); );
let data = WsDocumentDataBuilder::build_push_rev_message(&doc_id, revision); let data = WsDocumentDataBuilder::build_push_rev_message(&doc_id, revision);
self.send_ws_message(data).await; self.send_ws_message(data).await;

View File

@ -184,6 +184,8 @@ impl UserSession {
pub fn user_id(&self) -> Result<String, UserError> { Ok(self.get_session()?.user_id) } pub fn user_id(&self) -> Result<String, UserError> { Ok(self.get_session()?.user_id) }
pub fn user_name(&self) -> Result<String, UserError> { Ok(self.get_session()?.name) }
pub fn token(&self) -> Result<String, UserError> { Ok(self.get_session()?.token) } pub fn token(&self) -> Result<String, UserError> { Ok(self.get_session()?.token) }
pub fn add_ws_handler(&self, handler: Arc<dyn WsMessageHandler>) { let _ = self.ws_manager.add_handler(handler); } pub fn add_ws_handler(&self, handler: Arc<dyn WsMessageHandler>) { let _ = self.ws_manager.add_handler(handler); }

View File

@ -47,7 +47,13 @@ pub fn make_de_token_steam(ctxt: &Ctxt, ast: &ASTContainer) -> Option<TokenStrea
fn token_stream_for_one_of(ctxt: &Ctxt, field: &ASTField) -> Option<TokenStream> { fn token_stream_for_one_of(ctxt: &Ctxt, field: &ASTField) -> Option<TokenStream> {
let member = &field.member; let member = &field.member;
let ident = get_member_ident(ctxt, member)?; let ident = get_member_ident(ctxt, member)?;
let ty_info = parse_ty(ctxt, &field.ty)?; let ty_info = match parse_ty(ctxt, &field.ty) {
Ok(ty_info) => ty_info,
Err(e) => {
eprintln!("token_stream_for_one_of failed: {:?} with error: {}", member, e);
panic!();
}
}?;
let bracketed_ty_info = ty_info.bracket_ty_info.as_ref().as_ref(); let bracketed_ty_info = ty_info.bracket_ty_info.as_ref().as_ref();
let has_func = format_ident!("has_{}", ident.to_string()); let has_func = format_ident!("has_{}", ident.to_string());

View File

@ -109,7 +109,7 @@ impl Document {
let text = data.to_string(); let text = data.to_string();
let delta = self.view.insert(&self.delta, &text, interval)?; let delta = self.view.insert(&self.delta, &text, interval)?;
tracing::trace!("👉 receive change: {}", delta); tracing::debug!("👉 receive change: {}", delta);
self.compose_delta(delta.clone())?; self.compose_delta(delta.clone())?;
Ok(delta) Ok(delta)
} }

View File

@ -32,7 +32,7 @@ impl View {
for ext in &self.insert_exts { for ext in &self.insert_exts {
if let Some(mut delta) = ext.apply(delta, interval.size(), text, interval.start) { if let Some(mut delta) = ext.apply(delta, interval.size(), text, interval.start) {
trim(&mut delta); trim(&mut delta);
tracing::trace!("[{}]: applied, delta: {}", ext.ext_name(), delta); tracing::debug!("[{}]: applied, delta: {}", ext.ext_name(), delta);
new_delta = Some(delta); new_delta = Some(delta);
break; break;
} }

View File

@ -29,15 +29,6 @@ impl std::default::Default for WsDataType {
fn default() -> Self { WsDataType::Acked } fn default() -> Self { WsDataType::Acked }
} }
// #[derive(ProtoBuf, Default, Debug, Clone)]
// pub struct WsDocumentUser {
// #[pb(index = 1)]
// pub user_id: String,
//
// #[pb(index = 2)]
// pub name: String,
// }
#[derive(ProtoBuf, Default, Debug, Clone)] #[derive(ProtoBuf, Default, Debug, Clone)]
pub struct WsDocumentData { pub struct WsDocumentData {
#[pb(index = 1)] #[pb(index = 1)]
@ -48,8 +39,6 @@ pub struct WsDocumentData {
#[pb(index = 3)] #[pb(index = 3)]
pub data: Vec<u8>, pub data: Vec<u8>,
/* #[pb(index = 4)]
* pub user: WsDocumentUser, */
} }
impl std::convert::From<Revision> for WsDocumentData { impl std::convert::From<Revision> for WsDocumentData {

View File

@ -28,7 +28,7 @@ pub struct SignInParams {
pub name: String, pub name: String,
} }
#[derive(Debug, Default, ProtoBuf)] #[derive(Debug, Default, ProtoBuf, Clone)]
pub struct SignInResponse { pub struct SignInResponse {
#[pb(index = 1)] #[pb(index = 1)]
pub user_id: String, pub user_id: String,
@ -97,7 +97,7 @@ pub struct SignUpParams {
pub password: String, pub password: String,
} }
#[derive(ProtoBuf, Debug, Default)] #[derive(ProtoBuf, Debug, Default, Clone)]
pub struct SignUpResponse { pub struct SignUpResponse {
#[pb(index = 1)] #[pb(index = 1)]
pub user_id: String, pub user_id: String,

View File

@ -32,6 +32,7 @@ pub struct Revision {
pub md5: ::std::string::String, pub md5: ::std::string::String,
pub doc_id: ::std::string::String, pub doc_id: ::std::string::String,
pub ty: RevType, pub ty: RevType,
pub user_id: ::std::string::String,
// special fields // special fields
pub unknown_fields: ::protobuf::UnknownFields, pub unknown_fields: ::protobuf::UnknownFields,
pub cached_size: ::protobuf::CachedSize, pub cached_size: ::protobuf::CachedSize,
@ -170,6 +171,32 @@ impl Revision {
pub fn set_ty(&mut self, v: RevType) { pub fn set_ty(&mut self, v: RevType) {
self.ty = v; self.ty = v;
} }
// string user_id = 7;
pub fn get_user_id(&self) -> &str {
&self.user_id
}
pub fn clear_user_id(&mut self) {
self.user_id.clear();
}
// Param is passed by value, moved
pub fn set_user_id(&mut self, v: ::std::string::String) {
self.user_id = v;
}
// Mutable pointer to the field.
// If field is not initialized, it is initialized with default value first.
pub fn mut_user_id(&mut self) -> &mut ::std::string::String {
&mut self.user_id
}
// Take field
pub fn take_user_id(&mut self) -> ::std::string::String {
::std::mem::replace(&mut self.user_id, ::std::string::String::new())
}
} }
impl ::protobuf::Message for Revision { impl ::protobuf::Message for Revision {
@ -207,6 +234,9 @@ impl ::protobuf::Message for Revision {
6 => { 6 => {
::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.ty, 6, &mut self.unknown_fields)? ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.ty, 6, &mut self.unknown_fields)?
}, },
7 => {
::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.user_id)?;
},
_ => { _ => {
::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
}, },
@ -237,6 +267,9 @@ impl ::protobuf::Message for Revision {
if self.ty != RevType::Local { if self.ty != RevType::Local {
my_size += ::protobuf::rt::enum_size(6, self.ty); my_size += ::protobuf::rt::enum_size(6, self.ty);
} }
if !self.user_id.is_empty() {
my_size += ::protobuf::rt::string_size(7, &self.user_id);
}
my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
self.cached_size.set(my_size); self.cached_size.set(my_size);
my_size my_size
@ -261,6 +294,9 @@ impl ::protobuf::Message for Revision {
if self.ty != RevType::Local { if self.ty != RevType::Local {
os.write_enum(6, ::protobuf::ProtobufEnum::value(&self.ty))?; os.write_enum(6, ::protobuf::ProtobufEnum::value(&self.ty))?;
} }
if !self.user_id.is_empty() {
os.write_string(7, &self.user_id)?;
}
os.write_unknown_fields(self.get_unknown_fields())?; os.write_unknown_fields(self.get_unknown_fields())?;
::std::result::Result::Ok(()) ::std::result::Result::Ok(())
} }
@ -329,6 +365,11 @@ impl ::protobuf::Message for Revision {
|m: &Revision| { &m.ty }, |m: &Revision| { &m.ty },
|m: &mut Revision| { &mut m.ty }, |m: &mut Revision| { &mut m.ty },
)); ));
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
"user_id",
|m: &Revision| { &m.user_id },
|m: &mut Revision| { &mut m.user_id },
));
::protobuf::reflect::MessageDescriptor::new_pb_name::<Revision>( ::protobuf::reflect::MessageDescriptor::new_pb_name::<Revision>(
"Revision", "Revision",
fields, fields,
@ -351,6 +392,7 @@ impl ::protobuf::Clear for Revision {
self.md5.clear(); self.md5.clear();
self.doc_id.clear(); self.doc_id.clear();
self.ty = RevType::Local; self.ty = RevType::Local;
self.user_id.clear();
self.unknown_fields.clear(); self.unknown_fields.clear();
} }
} }
@ -799,52 +841,56 @@ impl ::protobuf::reflect::ProtobufValue for RevType {
} }
static file_descriptor_proto_data: &'static [u8] = b"\ static file_descriptor_proto_data: &'static [u8] = b"\
\n\x0bmodel.proto\"\xa3\x01\n\x08Revision\x12\x1e\n\x0bbase_rev_id\x18\ \n\x0bmodel.proto\"\xbc\x01\n\x08Revision\x12\x1e\n\x0bbase_rev_id\x18\
\x01\x20\x01(\x03R\tbaseRevId\x12\x15\n\x06rev_id\x18\x02\x20\x01(\x03R\ \x01\x20\x01(\x03R\tbaseRevId\x12\x15\n\x06rev_id\x18\x02\x20\x01(\x03R\
\x05revId\x12\x1d\n\ndelta_data\x18\x03\x20\x01(\x0cR\tdeltaData\x12\x10\ \x05revId\x12\x1d\n\ndelta_data\x18\x03\x20\x01(\x0cR\tdeltaData\x12\x10\
\n\x03md5\x18\x04\x20\x01(\tR\x03md5\x12\x15\n\x06doc_id\x18\x05\x20\x01\ \n\x03md5\x18\x04\x20\x01(\tR\x03md5\x12\x15\n\x06doc_id\x18\x05\x20\x01\
(\tR\x05docId\x12\x18\n\x02ty\x18\x06\x20\x01(\x0e2\x08.RevTypeR\x02ty\"\ (\tR\x05docId\x12\x18\n\x02ty\x18\x06\x20\x01(\x0e2\x08.RevTypeR\x02ty\
\x1d\n\x05RevId\x12\x14\n\x05value\x18\x01\x20\x01(\x03R\x05value\"N\n\r\ \x12\x17\n\x07user_id\x18\x07\x20\x01(\tR\x06userId\"\x1d\n\x05RevId\x12\
RevisionRange\x12\x15\n\x06doc_id\x18\x01\x20\x01(\tR\x05docId\x12\x14\n\ \x14\n\x05value\x18\x01\x20\x01(\x03R\x05value\"N\n\rRevisionRange\x12\
\x05start\x18\x02\x20\x01(\x03R\x05start\x12\x10\n\x03end\x18\x03\x20\ \x15\n\x06doc_id\x18\x01\x20\x01(\tR\x05docId\x12\x14\n\x05start\x18\x02\
\x01(\x03R\x03end*\x20\n\x07RevType\x12\t\n\x05Local\x10\0\x12\n\n\x06Re\ \x20\x01(\x03R\x05start\x12\x10\n\x03end\x18\x03\x20\x01(\x03R\x03end*\
mote\x10\x01J\xea\x05\n\x06\x12\x04\0\0\x15\x01\n\x08\n\x01\x0c\x12\x03\ \x20\n\x07RevType\x12\t\n\x05Local\x10\0\x12\n\n\x06Remote\x10\x01J\xa1\
\0\0\x12\n\n\n\x02\x04\0\x12\x04\x02\0\t\x01\n\n\n\x03\x04\0\x01\x12\x03\ \x06\n\x06\x12\x04\0\0\x16\x01\n\x08\n\x01\x0c\x12\x03\0\0\x12\n\n\n\x02\
\x02\x08\x10\n\x0b\n\x04\x04\0\x02\0\x12\x03\x03\x04\x1a\n\x0c\n\x05\x04\ \x04\0\x12\x04\x02\0\n\x01\n\n\n\x03\x04\0\x01\x12\x03\x02\x08\x10\n\x0b\
\0\x02\0\x05\x12\x03\x03\x04\t\n\x0c\n\x05\x04\0\x02\0\x01\x12\x03\x03\n\ \n\x04\x04\0\x02\0\x12\x03\x03\x04\x1a\n\x0c\n\x05\x04\0\x02\0\x05\x12\
\x15\n\x0c\n\x05\x04\0\x02\0\x03\x12\x03\x03\x18\x19\n\x0b\n\x04\x04\0\ \x03\x03\x04\t\n\x0c\n\x05\x04\0\x02\0\x01\x12\x03\x03\n\x15\n\x0c\n\x05\
\x02\x01\x12\x03\x04\x04\x15\n\x0c\n\x05\x04\0\x02\x01\x05\x12\x03\x04\ \x04\0\x02\0\x03\x12\x03\x03\x18\x19\n\x0b\n\x04\x04\0\x02\x01\x12\x03\
\x04\t\n\x0c\n\x05\x04\0\x02\x01\x01\x12\x03\x04\n\x10\n\x0c\n\x05\x04\0\ \x04\x04\x15\n\x0c\n\x05\x04\0\x02\x01\x05\x12\x03\x04\x04\t\n\x0c\n\x05\
\x02\x01\x03\x12\x03\x04\x13\x14\n\x0b\n\x04\x04\0\x02\x02\x12\x03\x05\ \x04\0\x02\x01\x01\x12\x03\x04\n\x10\n\x0c\n\x05\x04\0\x02\x01\x03\x12\
\x04\x19\n\x0c\n\x05\x04\0\x02\x02\x05\x12\x03\x05\x04\t\n\x0c\n\x05\x04\ \x03\x04\x13\x14\n\x0b\n\x04\x04\0\x02\x02\x12\x03\x05\x04\x19\n\x0c\n\
\0\x02\x02\x01\x12\x03\x05\n\x14\n\x0c\n\x05\x04\0\x02\x02\x03\x12\x03\ \x05\x04\0\x02\x02\x05\x12\x03\x05\x04\t\n\x0c\n\x05\x04\0\x02\x02\x01\
\x05\x17\x18\n\x0b\n\x04\x04\0\x02\x03\x12\x03\x06\x04\x13\n\x0c\n\x05\ \x12\x03\x05\n\x14\n\x0c\n\x05\x04\0\x02\x02\x03\x12\x03\x05\x17\x18\n\
\x04\0\x02\x03\x05\x12\x03\x06\x04\n\n\x0c\n\x05\x04\0\x02\x03\x01\x12\ \x0b\n\x04\x04\0\x02\x03\x12\x03\x06\x04\x13\n\x0c\n\x05\x04\0\x02\x03\
\x03\x06\x0b\x0e\n\x0c\n\x05\x04\0\x02\x03\x03\x12\x03\x06\x11\x12\n\x0b\ \x05\x12\x03\x06\x04\n\n\x0c\n\x05\x04\0\x02\x03\x01\x12\x03\x06\x0b\x0e\
\n\x04\x04\0\x02\x04\x12\x03\x07\x04\x16\n\x0c\n\x05\x04\0\x02\x04\x05\ \n\x0c\n\x05\x04\0\x02\x03\x03\x12\x03\x06\x11\x12\n\x0b\n\x04\x04\0\x02\
\x12\x03\x07\x04\n\n\x0c\n\x05\x04\0\x02\x04\x01\x12\x03\x07\x0b\x11\n\ \x04\x12\x03\x07\x04\x16\n\x0c\n\x05\x04\0\x02\x04\x05\x12\x03\x07\x04\n\
\x0c\n\x05\x04\0\x02\x04\x03\x12\x03\x07\x14\x15\n\x0b\n\x04\x04\0\x02\ \n\x0c\n\x05\x04\0\x02\x04\x01\x12\x03\x07\x0b\x11\n\x0c\n\x05\x04\0\x02\
\x05\x12\x03\x08\x04\x13\n\x0c\n\x05\x04\0\x02\x05\x06\x12\x03\x08\x04\ \x04\x03\x12\x03\x07\x14\x15\n\x0b\n\x04\x04\0\x02\x05\x12\x03\x08\x04\
\x0b\n\x0c\n\x05\x04\0\x02\x05\x01\x12\x03\x08\x0c\x0e\n\x0c\n\x05\x04\0\ \x13\n\x0c\n\x05\x04\0\x02\x05\x06\x12\x03\x08\x04\x0b\n\x0c\n\x05\x04\0\
\x02\x05\x03\x12\x03\x08\x11\x12\n\n\n\x02\x04\x01\x12\x04\n\0\x0c\x01\n\ \x02\x05\x01\x12\x03\x08\x0c\x0e\n\x0c\n\x05\x04\0\x02\x05\x03\x12\x03\
\n\n\x03\x04\x01\x01\x12\x03\n\x08\r\n\x0b\n\x04\x04\x01\x02\0\x12\x03\ \x08\x11\x12\n\x0b\n\x04\x04\0\x02\x06\x12\x03\t\x04\x17\n\x0c\n\x05\x04\
\x0b\x04\x14\n\x0c\n\x05\x04\x01\x02\0\x05\x12\x03\x0b\x04\t\n\x0c\n\x05\ \0\x02\x06\x05\x12\x03\t\x04\n\n\x0c\n\x05\x04\0\x02\x06\x01\x12\x03\t\
\x04\x01\x02\0\x01\x12\x03\x0b\n\x0f\n\x0c\n\x05\x04\x01\x02\0\x03\x12\ \x0b\x12\n\x0c\n\x05\x04\0\x02\x06\x03\x12\x03\t\x15\x16\n\n\n\x02\x04\
\x03\x0b\x12\x13\n\n\n\x02\x04\x02\x12\x04\r\0\x11\x01\n\n\n\x03\x04\x02\ \x01\x12\x04\x0b\0\r\x01\n\n\n\x03\x04\x01\x01\x12\x03\x0b\x08\r\n\x0b\n\
\x01\x12\x03\r\x08\x15\n\x0b\n\x04\x04\x02\x02\0\x12\x03\x0e\x04\x16\n\ \x04\x04\x01\x02\0\x12\x03\x0c\x04\x14\n\x0c\n\x05\x04\x01\x02\0\x05\x12\
\x0c\n\x05\x04\x02\x02\0\x05\x12\x03\x0e\x04\n\n\x0c\n\x05\x04\x02\x02\0\ \x03\x0c\x04\t\n\x0c\n\x05\x04\x01\x02\0\x01\x12\x03\x0c\n\x0f\n\x0c\n\
\x01\x12\x03\x0e\x0b\x11\n\x0c\n\x05\x04\x02\x02\0\x03\x12\x03\x0e\x14\ \x05\x04\x01\x02\0\x03\x12\x03\x0c\x12\x13\n\n\n\x02\x04\x02\x12\x04\x0e\
\x15\n\x0b\n\x04\x04\x02\x02\x01\x12\x03\x0f\x04\x14\n\x0c\n\x05\x04\x02\ \0\x12\x01\n\n\n\x03\x04\x02\x01\x12\x03\x0e\x08\x15\n\x0b\n\x04\x04\x02\
\x02\x01\x05\x12\x03\x0f\x04\t\n\x0c\n\x05\x04\x02\x02\x01\x01\x12\x03\ \x02\0\x12\x03\x0f\x04\x16\n\x0c\n\x05\x04\x02\x02\0\x05\x12\x03\x0f\x04\
\x0f\n\x0f\n\x0c\n\x05\x04\x02\x02\x01\x03\x12\x03\x0f\x12\x13\n\x0b\n\ \n\n\x0c\n\x05\x04\x02\x02\0\x01\x12\x03\x0f\x0b\x11\n\x0c\n\x05\x04\x02\
\x04\x04\x02\x02\x02\x12\x03\x10\x04\x12\n\x0c\n\x05\x04\x02\x02\x02\x05\ \x02\0\x03\x12\x03\x0f\x14\x15\n\x0b\n\x04\x04\x02\x02\x01\x12\x03\x10\
\x12\x03\x10\x04\t\n\x0c\n\x05\x04\x02\x02\x02\x01\x12\x03\x10\n\r\n\x0c\ \x04\x14\n\x0c\n\x05\x04\x02\x02\x01\x05\x12\x03\x10\x04\t\n\x0c\n\x05\
\n\x05\x04\x02\x02\x02\x03\x12\x03\x10\x10\x11\n\n\n\x02\x05\0\x12\x04\ \x04\x02\x02\x01\x01\x12\x03\x10\n\x0f\n\x0c\n\x05\x04\x02\x02\x01\x03\
\x12\0\x15\x01\n\n\n\x03\x05\0\x01\x12\x03\x12\x05\x0c\n\x0b\n\x04\x05\0\ \x12\x03\x10\x12\x13\n\x0b\n\x04\x04\x02\x02\x02\x12\x03\x11\x04\x12\n\
\x02\0\x12\x03\x13\x04\x0e\n\x0c\n\x05\x05\0\x02\0\x01\x12\x03\x13\x04\t\ \x0c\n\x05\x04\x02\x02\x02\x05\x12\x03\x11\x04\t\n\x0c\n\x05\x04\x02\x02\
\n\x0c\n\x05\x05\0\x02\0\x02\x12\x03\x13\x0c\r\n\x0b\n\x04\x05\0\x02\x01\ \x02\x01\x12\x03\x11\n\r\n\x0c\n\x05\x04\x02\x02\x02\x03\x12\x03\x11\x10\
\x12\x03\x14\x04\x0f\n\x0c\n\x05\x05\0\x02\x01\x01\x12\x03\x14\x04\n\n\ \x11\n\n\n\x02\x05\0\x12\x04\x13\0\x16\x01\n\n\n\x03\x05\0\x01\x12\x03\
\x0c\n\x05\x05\0\x02\x01\x02\x12\x03\x14\r\x0eb\x06proto3\ \x13\x05\x0c\n\x0b\n\x04\x05\0\x02\0\x12\x03\x14\x04\x0e\n\x0c\n\x05\x05\
\0\x02\0\x01\x12\x03\x14\x04\t\n\x0c\n\x05\x05\0\x02\0\x02\x12\x03\x14\
\x0c\r\n\x0b\n\x04\x05\0\x02\x01\x12\x03\x15\x04\x0f\n\x0c\n\x05\x05\0\
\x02\x01\x01\x12\x03\x15\x04\n\n\x0c\n\x05\x05\0\x02\x01\x02\x12\x03\x15\
\r\x0eb\x06proto3\
"; ";
static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;

View File

@ -7,6 +7,7 @@ message Revision {
string md5 = 4; string md5 = 4;
string doc_id = 5; string doc_id = 5;
RevType ty = 6; RevType ty = 6;
string user_id = 7;
} }
message RevId { message RevId {
int64 value = 1; int64 value = 1;

View File

@ -21,6 +21,9 @@ pub struct Revision {
#[pb(index = 6)] #[pb(index = 6)]
pub ty: RevType, pub ty: RevType,
#[pb(index = 7)]
pub user_id: String,
} }
impl Revision { impl Revision {
@ -47,7 +50,7 @@ impl std::fmt::Debug for Revision {
} }
impl Revision { impl Revision {
pub fn new<T1, T2, D>(base_rev_id: T1, rev_id: T2, delta: D, doc_id: &str, ty: RevType) -> Revision pub fn new<T1, T2, D>(base_rev_id: T1, rev_id: T2, delta: D, doc_id: &str, ty: RevType, user_id: String) -> Revision
where where
T1: Into<i64>, T1: Into<i64>,
T2: Into<i64>, T2: Into<i64>,
@ -70,6 +73,7 @@ impl Revision {
md5, md5,
doc_id, doc_id,
ty, ty,
user_id,
} }
} }
} }