mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
move flowy-ot document to flowy-document
This commit is contained in:
parent
47f3a187c4
commit
2b9bc7a0cd
@ -7,6 +7,7 @@
|
||||
|
||||
import 'dart:core' as $core;
|
||||
|
||||
import 'package:fixnum/fixnum.dart' as $fixnum;
|
||||
import 'package:protobuf/protobuf.dart' as $pb;
|
||||
|
||||
class CreateDocParams extends $pb.GeneratedMessage {
|
||||
@ -74,6 +75,7 @@ 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')
|
||||
..a<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data', $pb.PbFieldType.OY)
|
||||
..aInt64(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'revision')
|
||||
..hasRequiredFields = false
|
||||
;
|
||||
|
||||
@ -81,6 +83,7 @@ class Doc extends $pb.GeneratedMessage {
|
||||
factory Doc({
|
||||
$core.String? id,
|
||||
$core.List<$core.int>? data,
|
||||
$fixnum.Int64? revision,
|
||||
}) {
|
||||
final _result = create();
|
||||
if (id != null) {
|
||||
@ -89,6 +92,9 @@ class Doc extends $pb.GeneratedMessage {
|
||||
if (data != null) {
|
||||
_result.data = data;
|
||||
}
|
||||
if (revision != null) {
|
||||
_result.revision = revision;
|
||||
}
|
||||
return _result;
|
||||
}
|
||||
factory Doc.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
|
||||
@ -129,49 +135,58 @@ class Doc extends $pb.GeneratedMessage {
|
||||
$core.bool hasData() => $_has(1);
|
||||
@$pb.TagNumber(2)
|
||||
void clearData() => clearField(2);
|
||||
|
||||
@$pb.TagNumber(3)
|
||||
$fixnum.Int64 get revision => $_getI64(2);
|
||||
@$pb.TagNumber(3)
|
||||
set revision($fixnum.Int64 v) { $_setInt64(2, v); }
|
||||
@$pb.TagNumber(3)
|
||||
$core.bool hasRevision() => $_has(2);
|
||||
@$pb.TagNumber(3)
|
||||
void clearRevision() => clearField(3);
|
||||
}
|
||||
|
||||
class SaveDocParams extends $pb.GeneratedMessage {
|
||||
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'SaveDocParams', createEmptyInstance: create)
|
||||
class UpdateDocParams extends $pb.GeneratedMessage {
|
||||
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'UpdateDocParams', createEmptyInstance: create)
|
||||
..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id')
|
||||
..a<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data', $pb.PbFieldType.OY)
|
||||
..a<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'docData', $pb.PbFieldType.OY)
|
||||
..hasRequiredFields = false
|
||||
;
|
||||
|
||||
SaveDocParams._() : super();
|
||||
factory SaveDocParams({
|
||||
UpdateDocParams._() : super();
|
||||
factory UpdateDocParams({
|
||||
$core.String? id,
|
||||
$core.List<$core.int>? data,
|
||||
$core.List<$core.int>? docData,
|
||||
}) {
|
||||
final _result = create();
|
||||
if (id != null) {
|
||||
_result.id = id;
|
||||
}
|
||||
if (data != null) {
|
||||
_result.data = data;
|
||||
if (docData != null) {
|
||||
_result.docData = docData;
|
||||
}
|
||||
return _result;
|
||||
}
|
||||
factory SaveDocParams.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
|
||||
factory SaveDocParams.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
|
||||
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);
|
||||
@$core.Deprecated(
|
||||
'Using this can add significant overhead to your binary. '
|
||||
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
|
||||
'Will be removed in next major version')
|
||||
SaveDocParams clone() => SaveDocParams()..mergeFromMessage(this);
|
||||
UpdateDocParams clone() => UpdateDocParams()..mergeFromMessage(this);
|
||||
@$core.Deprecated(
|
||||
'Using this can add significant overhead to your binary. '
|
||||
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
|
||||
'Will be removed in next major version')
|
||||
SaveDocParams copyWith(void Function(SaveDocParams) updates) => super.copyWith((message) => updates(message as SaveDocParams)) as SaveDocParams; // ignore: deprecated_member_use
|
||||
UpdateDocParams copyWith(void Function(UpdateDocParams) updates) => super.copyWith((message) => updates(message as UpdateDocParams)) as UpdateDocParams; // ignore: deprecated_member_use
|
||||
$pb.BuilderInfo get info_ => _i;
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static SaveDocParams create() => SaveDocParams._();
|
||||
SaveDocParams createEmptyInstance() => create();
|
||||
static $pb.PbList<SaveDocParams> createRepeated() => $pb.PbList<SaveDocParams>();
|
||||
static UpdateDocParams create() => UpdateDocParams._();
|
||||
UpdateDocParams createEmptyInstance() => create();
|
||||
static $pb.PbList<UpdateDocParams> createRepeated() => $pb.PbList<UpdateDocParams>();
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static SaveDocParams getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<SaveDocParams>(create);
|
||||
static SaveDocParams? _defaultInstance;
|
||||
static UpdateDocParams getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<UpdateDocParams>(create);
|
||||
static UpdateDocParams? _defaultInstance;
|
||||
|
||||
@$pb.TagNumber(1)
|
||||
$core.String get id => $_getSZ(0);
|
||||
@ -183,24 +198,24 @@ class SaveDocParams extends $pb.GeneratedMessage {
|
||||
void clearId() => clearField(1);
|
||||
|
||||
@$pb.TagNumber(2)
|
||||
$core.List<$core.int> get data => $_getN(1);
|
||||
$core.List<$core.int> get docData => $_getN(1);
|
||||
@$pb.TagNumber(2)
|
||||
set data($core.List<$core.int> v) { $_setBytes(1, v); }
|
||||
set docData($core.List<$core.int> v) { $_setBytes(1, v); }
|
||||
@$pb.TagNumber(2)
|
||||
$core.bool hasData() => $_has(1);
|
||||
$core.bool hasDocData() => $_has(1);
|
||||
@$pb.TagNumber(2)
|
||||
void clearData() => clearField(2);
|
||||
void clearDocData() => clearField(2);
|
||||
}
|
||||
|
||||
class ApplyChangesetParams extends $pb.GeneratedMessage {
|
||||
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'ApplyChangesetParams', createEmptyInstance: create)
|
||||
class DocChangeset extends $pb.GeneratedMessage {
|
||||
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'DocChangeset', createEmptyInstance: create)
|
||||
..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id')
|
||||
..a<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data', $pb.PbFieldType.OY)
|
||||
..hasRequiredFields = false
|
||||
;
|
||||
|
||||
ApplyChangesetParams._() : super();
|
||||
factory ApplyChangesetParams({
|
||||
DocChangeset._() : super();
|
||||
factory DocChangeset({
|
||||
$core.String? id,
|
||||
$core.List<$core.int>? data,
|
||||
}) {
|
||||
@ -213,26 +228,26 @@ class ApplyChangesetParams extends $pb.GeneratedMessage {
|
||||
}
|
||||
return _result;
|
||||
}
|
||||
factory ApplyChangesetParams.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
|
||||
factory ApplyChangesetParams.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
|
||||
factory DocChangeset.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
|
||||
factory DocChangeset.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')
|
||||
ApplyChangesetParams clone() => ApplyChangesetParams()..mergeFromMessage(this);
|
||||
DocChangeset clone() => DocChangeset()..mergeFromMessage(this);
|
||||
@$core.Deprecated(
|
||||
'Using this can add significant overhead to your binary. '
|
||||
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
|
||||
'Will be removed in next major version')
|
||||
ApplyChangesetParams copyWith(void Function(ApplyChangesetParams) updates) => super.copyWith((message) => updates(message as ApplyChangesetParams)) as ApplyChangesetParams; // ignore: deprecated_member_use
|
||||
DocChangeset copyWith(void Function(DocChangeset) updates) => super.copyWith((message) => updates(message as DocChangeset)) as DocChangeset; // ignore: deprecated_member_use
|
||||
$pb.BuilderInfo get info_ => _i;
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static ApplyChangesetParams create() => ApplyChangesetParams._();
|
||||
ApplyChangesetParams createEmptyInstance() => create();
|
||||
static $pb.PbList<ApplyChangesetParams> createRepeated() => $pb.PbList<ApplyChangesetParams>();
|
||||
static DocChangeset create() => DocChangeset._();
|
||||
DocChangeset createEmptyInstance() => create();
|
||||
static $pb.PbList<DocChangeset> createRepeated() => $pb.PbList<DocChangeset>();
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static ApplyChangesetParams getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ApplyChangesetParams>(create);
|
||||
static ApplyChangesetParams? _defaultInstance;
|
||||
static DocChangeset getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<DocChangeset>(create);
|
||||
static DocChangeset? _defaultInstance;
|
||||
|
||||
@$pb.TagNumber(1)
|
||||
$core.String get id => $_getSZ(0);
|
||||
|
@ -25,33 +25,34 @@ const Doc$json = const {
|
||||
'2': const [
|
||||
const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'},
|
||||
const {'1': 'data', '3': 2, '4': 1, '5': 12, '10': 'data'},
|
||||
const {'1': 'revision', '3': 3, '4': 1, '5': 3, '10': 'revision'},
|
||||
],
|
||||
};
|
||||
|
||||
/// Descriptor for `Doc`. Decode as a `google.protobuf.DescriptorProto`.
|
||||
final $typed_data.Uint8List docDescriptor = $convert.base64Decode('CgNEb2MSDgoCaWQYASABKAlSAmlkEhIKBGRhdGEYAiABKAxSBGRhdGE=');
|
||||
@$core.Deprecated('Use saveDocParamsDescriptor instead')
|
||||
const SaveDocParams$json = const {
|
||||
'1': 'SaveDocParams',
|
||||
final $typed_data.Uint8List docDescriptor = $convert.base64Decode('CgNEb2MSDgoCaWQYASABKAlSAmlkEhIKBGRhdGEYAiABKAxSBGRhdGESGgoIcmV2aXNpb24YAyABKANSCHJldmlzaW9u');
|
||||
@$core.Deprecated('Use updateDocParamsDescriptor instead')
|
||||
const UpdateDocParams$json = const {
|
||||
'1': 'UpdateDocParams',
|
||||
'2': const [
|
||||
const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'},
|
||||
const {'1': 'doc_data', '3': 2, '4': 1, '5': 12, '10': 'docData'},
|
||||
],
|
||||
};
|
||||
|
||||
/// Descriptor for `UpdateDocParams`. Decode as a `google.protobuf.DescriptorProto`.
|
||||
final $typed_data.Uint8List updateDocParamsDescriptor = $convert.base64Decode('Cg9VcGRhdGVEb2NQYXJhbXMSDgoCaWQYASABKAlSAmlkEhkKCGRvY19kYXRhGAIgASgMUgdkb2NEYXRh');
|
||||
@$core.Deprecated('Use docChangesetDescriptor instead')
|
||||
const DocChangeset$json = const {
|
||||
'1': 'DocChangeset',
|
||||
'2': const [
|
||||
const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'},
|
||||
const {'1': 'data', '3': 2, '4': 1, '5': 12, '10': 'data'},
|
||||
],
|
||||
};
|
||||
|
||||
/// Descriptor for `SaveDocParams`. Decode as a `google.protobuf.DescriptorProto`.
|
||||
final $typed_data.Uint8List saveDocParamsDescriptor = $convert.base64Decode('Cg1TYXZlRG9jUGFyYW1zEg4KAmlkGAEgASgJUgJpZBISCgRkYXRhGAIgASgMUgRkYXRh');
|
||||
@$core.Deprecated('Use applyChangesetParamsDescriptor instead')
|
||||
const ApplyChangesetParams$json = const {
|
||||
'1': 'ApplyChangesetParams',
|
||||
'2': const [
|
||||
const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'},
|
||||
const {'1': 'data', '3': 2, '4': 1, '5': 12, '10': 'data'},
|
||||
],
|
||||
};
|
||||
|
||||
/// Descriptor for `ApplyChangesetParams`. Decode as a `google.protobuf.DescriptorProto`.
|
||||
final $typed_data.Uint8List applyChangesetParamsDescriptor = $convert.base64Decode('ChRBcHBseUNoYW5nZXNldFBhcmFtcxIOCgJpZBgBIAEoCVICaWQSEgoEZGF0YRgCIAEoDFIEZGF0YQ==');
|
||||
/// Descriptor for `DocChangeset`. Decode as a `google.protobuf.DescriptorProto`.
|
||||
final $typed_data.Uint8List docChangesetDescriptor = $convert.base64Decode('CgxEb2NDaGFuZ2VzZXQSDgoCaWQYASABKAlSAmlkEhIKBGRhdGEYAiABKAxSBGRhdGE=');
|
||||
@$core.Deprecated('Use queryDocParamsDescriptor instead')
|
||||
const QueryDocParams$json = const {
|
||||
'1': 'QueryDocParams',
|
||||
|
@ -13,6 +13,9 @@ class ErrorCode extends $pb.ProtobufEnum {
|
||||
static const ErrorCode DocIdInvalid = ErrorCode._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DocIdInvalid');
|
||||
static const ErrorCode DocNotfound = ErrorCode._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DocNotfound');
|
||||
static const ErrorCode WsConnectError = ErrorCode._(10, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'WsConnectError');
|
||||
static const ErrorCode UndoFail = ErrorCode._(200, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UndoFail');
|
||||
static const ErrorCode RedoFail = ErrorCode._(201, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'RedoFail');
|
||||
static const ErrorCode OutOfBound = ErrorCode._(202, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'OutOfBound');
|
||||
static const ErrorCode UserUnauthorized = ErrorCode._(999, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserUnauthorized');
|
||||
static const ErrorCode InternalError = ErrorCode._(1000, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'InternalError');
|
||||
|
||||
@ -20,6 +23,9 @@ class ErrorCode extends $pb.ProtobufEnum {
|
||||
DocIdInvalid,
|
||||
DocNotfound,
|
||||
WsConnectError,
|
||||
UndoFail,
|
||||
RedoFail,
|
||||
OutOfBound,
|
||||
UserUnauthorized,
|
||||
InternalError,
|
||||
];
|
||||
|
@ -15,13 +15,16 @@ const ErrorCode$json = const {
|
||||
const {'1': 'DocIdInvalid', '2': 0},
|
||||
const {'1': 'DocNotfound', '2': 1},
|
||||
const {'1': 'WsConnectError', '2': 10},
|
||||
const {'1': 'UndoFail', '2': 200},
|
||||
const {'1': 'RedoFail', '2': 201},
|
||||
const {'1': 'OutOfBound', '2': 202},
|
||||
const {'1': 'UserUnauthorized', '2': 999},
|
||||
const {'1': 'InternalError', '2': 1000},
|
||||
],
|
||||
};
|
||||
|
||||
/// Descriptor for `ErrorCode`. Decode as a `google.protobuf.EnumDescriptorProto`.
|
||||
final $typed_data.Uint8List errorCodeDescriptor = $convert.base64Decode('CglFcnJvckNvZGUSEAoMRG9jSWRJbnZhbGlkEAASDwoLRG9jTm90Zm91bmQQARISCg5Xc0Nvbm5lY3RFcnJvchAKEhUKEFVzZXJVbmF1dGhvcml6ZWQQ5wcSEgoNSW50ZXJuYWxFcnJvchDoBw==');
|
||||
final $typed_data.Uint8List errorCodeDescriptor = $convert.base64Decode('CglFcnJvckNvZGUSEAoMRG9jSWRJbnZhbGlkEAASDwoLRG9jTm90Zm91bmQQARISCg5Xc0Nvbm5lY3RFcnJvchAKEg0KCFVuZG9GYWlsEMgBEg0KCFJlZG9GYWlsEMkBEg8KCk91dE9mQm91bmQQygESFQoQVXNlclVuYXV0aG9yaXplZBDnBxISCg1JbnRlcm5hbEVycm9yEOgH');
|
||||
@$core.Deprecated('Use docErrorDescriptor instead')
|
||||
const DocError$json = const {
|
||||
'1': 'DocError',
|
||||
|
@ -2,5 +2,5 @@
|
||||
CREATE TABLE doc_table (
|
||||
id TEXT NOT NULL PRIMARY KEY,
|
||||
data BLOB NOT NULL DEFAULT (x''),
|
||||
version BIGINT NOT NULL DEFAULT 0
|
||||
revision BIGINT NOT NULL DEFAULT 0
|
||||
);
|
@ -0,0 +1 @@
|
||||
-- This file should undo anything in `up.sql`
|
@ -0,0 +1 @@
|
||||
-- Your SQL goes here
|
@ -17,7 +17,7 @@ table! {
|
||||
doc_table (id) {
|
||||
id -> Text,
|
||||
data -> Binary,
|
||||
version -> BigInt,
|
||||
revision -> BigInt,
|
||||
}
|
||||
}
|
||||
|
||||
@ -58,4 +58,10 @@ table! {
|
||||
}
|
||||
}
|
||||
|
||||
allow_tables_to_appear_in_same_query!(app_table, doc_table, user_table, view_table, workspace_table,);
|
||||
allow_tables_to_appear_in_same_query!(
|
||||
app_table,
|
||||
doc_table,
|
||||
user_table,
|
||||
view_table,
|
||||
workspace_table,
|
||||
);
|
||||
|
@ -57,8 +57,8 @@ pub fn category_from_str(type_str: &str) -> TypeCategory {
|
||||
| "WsMessage"
|
||||
| "CreateDocParams"
|
||||
| "Doc"
|
||||
| "SaveDocParams"
|
||||
| "ApplyChangesetParams"
|
||||
| "UpdateDocParams"
|
||||
| "DocChangeset"
|
||||
| "QueryDocParams"
|
||||
| "WsDocumentData"
|
||||
| "DocError"
|
||||
|
@ -30,9 +30,19 @@ strum = "0.21"
|
||||
strum_macros = "0.21"
|
||||
dashmap = "4.0"
|
||||
parking_lot = "0.11"
|
||||
bytecount = "0.6.0"
|
||||
url = "2.2"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = {version = "1.0"}
|
||||
chrono = "0.4.19"
|
||||
|
||||
[dev-dependencies]
|
||||
flowy-test = { path = "../flowy-test" }
|
||||
color-eyre = { version = "0.5", default-features = false }
|
||||
criterion = "0.3"
|
||||
rand = "0.7.3"
|
||||
env_logger = "0.8.2"
|
||||
|
||||
|
||||
[features]
|
||||
http_server = []
|
@ -20,19 +20,22 @@ pub struct Doc {
|
||||
|
||||
#[pb(index = 2)]
|
||||
pub data: Vec<u8>,
|
||||
|
||||
#[pb(index = 3)]
|
||||
pub revision: i64,
|
||||
}
|
||||
|
||||
#[derive(ProtoBuf, Default, Debug, Clone)]
|
||||
pub struct SaveDocParams {
|
||||
pub struct UpdateDocParams {
|
||||
#[pb(index = 1)]
|
||||
pub id: String,
|
||||
|
||||
#[pb(index = 2)]
|
||||
pub data: Vec<u8>,
|
||||
pub doc_data: Vec<u8>,
|
||||
}
|
||||
|
||||
#[derive(ProtoBuf, Default, Debug, Clone)]
|
||||
pub struct ApplyChangesetParams {
|
||||
pub struct DocChangeset {
|
||||
#[pb(index = 1)]
|
||||
pub id: String,
|
||||
|
||||
|
@ -41,6 +41,9 @@ impl DocError {
|
||||
static_doc_error!(not_found, ErrorCode::DocNotfound);
|
||||
static_doc_error!(unauthorized, ErrorCode::UserUnauthorized);
|
||||
static_doc_error!(ws, ErrorCode::WsConnectError);
|
||||
static_doc_error!(undo, ErrorCode::UndoFail);
|
||||
static_doc_error!(redo, ErrorCode::RedoFail);
|
||||
static_doc_error!(out_of_bound, ErrorCode::OutOfBound);
|
||||
}
|
||||
|
||||
pub fn internal_error<T>(e: T) -> DocError
|
||||
@ -61,6 +64,14 @@ pub enum ErrorCode {
|
||||
#[display(fmt = "Document websocket error")]
|
||||
WsConnectError = 10,
|
||||
|
||||
#[display(fmt = "Undo failed")]
|
||||
UndoFail = 200,
|
||||
#[display(fmt = "Redo failed")]
|
||||
RedoFail = 201,
|
||||
|
||||
#[display(fmt = "Interval out of bound")]
|
||||
OutOfBound = 202,
|
||||
|
||||
#[display(fmt = "UserUnauthorized")]
|
||||
UserUnauthorized = 999,
|
||||
|
||||
@ -89,6 +100,10 @@ impl std::convert::From<std::io::Error> for DocError {
|
||||
fn from(error: std::io::Error) -> Self { DocError::internal().context(error) }
|
||||
}
|
||||
|
||||
impl std::convert::From<serde_json::Error> for DocError {
|
||||
fn from(error: serde_json::Error) -> Self { DocError::internal().context(error) }
|
||||
}
|
||||
|
||||
// impl std::convert::From<::r2d2::Error> for DocError {
|
||||
// fn from(error: r2d2::Error) -> Self {
|
||||
// ErrorBuilder::new(ErrorCode::InternalError).error(error).build() } }
|
||||
|
@ -3,7 +3,7 @@ pub mod errors;
|
||||
pub mod module;
|
||||
mod observable;
|
||||
pub mod protobuf;
|
||||
mod services;
|
||||
pub mod services;
|
||||
mod sql_tables;
|
||||
|
||||
#[macro_use]
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
entities::doc::{ApplyChangesetParams, CreateDocParams, Doc, QueryDocParams},
|
||||
entities::doc::{CreateDocParams, Doc, DocChangeset, QueryDocParams},
|
||||
errors::DocError,
|
||||
services::{doc_controller::DocController, open_doc::OpenedDocManager, server::construct_doc_server, ws::WsManager},
|
||||
services::{doc_controller::DocController, server::construct_doc_server, ws::WsManager},
|
||||
};
|
||||
use bytes::Bytes;
|
||||
use diesel::SqliteConnection;
|
||||
@ -17,16 +17,13 @@ pub trait DocumentUser: Send + Sync {
|
||||
|
||||
pub struct FlowyDocument {
|
||||
controller: Arc<DocController>,
|
||||
doc_manager: Arc<OpenedDocManager>,
|
||||
}
|
||||
|
||||
impl FlowyDocument {
|
||||
pub fn new(user: Arc<dyn DocumentUser>, ws_manager: Arc<RwLock<WsManager>>) -> FlowyDocument {
|
||||
let server = construct_doc_server();
|
||||
let controller = Arc::new(DocController::new(server.clone(), user.clone()));
|
||||
let doc_manager = Arc::new(OpenedDocManager::new(ws_manager, controller.clone()));
|
||||
|
||||
Self { controller, doc_manager }
|
||||
let controller = Arc::new(DocController::new(server.clone(), user.clone(), ws_manager.clone()));
|
||||
Self { controller }
|
||||
}
|
||||
|
||||
pub fn create(&self, params: CreateDocParams, conn: &SqliteConnection) -> Result<(), DocError> {
|
||||
@ -35,31 +32,23 @@ impl FlowyDocument {
|
||||
}
|
||||
|
||||
pub fn delete(&self, params: QueryDocParams, conn: &SqliteConnection) -> Result<(), DocError> {
|
||||
let _ = self.doc_manager.close(¶ms.doc_id)?;
|
||||
let _ = self.controller.delete(params.into(), conn)?;
|
||||
let _ = self.controller.delete(params, conn)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn open(&self, params: QueryDocParams, pool: Arc<ConnectionPool>) -> Result<Doc, DocError> {
|
||||
let doc = match self.doc_manager.is_opened(¶ms.doc_id) {
|
||||
true => {
|
||||
let data = self.doc_manager.read_doc(¶ms.doc_id).await?;
|
||||
Doc { id: params.doc_id, data }
|
||||
},
|
||||
false => {
|
||||
let doc = self.controller.open(params, pool).await?;
|
||||
let _ = self.doc_manager.open(&doc.id, doc.data.clone())?;
|
||||
doc
|
||||
},
|
||||
};
|
||||
|
||||
Ok(doc)
|
||||
let open_doc = self.controller.open(params, pool).await?;
|
||||
Ok(open_doc.doc())
|
||||
}
|
||||
|
||||
pub async fn apply_changeset(&self, params: ApplyChangesetParams, pool: Arc<ConnectionPool>) -> Result<Doc, DocError> {
|
||||
let _ = self.doc_manager.apply_changeset(¶ms.id, Bytes::from(params.data), pool).await?;
|
||||
let data = self.doc_manager.read_doc(¶ms.id).await?;
|
||||
let doc = Doc { id: params.id, data };
|
||||
Ok(doc)
|
||||
pub async fn apply_changeset(&self, params: DocChangeset, pool: Arc<ConnectionPool>) -> Result<Doc, DocError> {
|
||||
// let _ = self.doc_manager.apply_changeset(¶ms.id,
|
||||
// Bytes::from(params.data), pool).await?;
|
||||
//
|
||||
// // workaround: compare the rust's delta with flutter's delta. Will be removed
|
||||
// // very soon
|
||||
// let doc = self.doc_manager.read_doc(¶ms.id)?;
|
||||
// Ok(doc)
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
@ -229,6 +229,7 @@ pub struct Doc {
|
||||
// message fields
|
||||
pub id: ::std::string::String,
|
||||
pub data: ::std::vec::Vec<u8>,
|
||||
pub revision: i64,
|
||||
// special fields
|
||||
pub unknown_fields: ::protobuf::UnknownFields,
|
||||
pub cached_size: ::protobuf::CachedSize,
|
||||
@ -296,6 +297,21 @@ impl Doc {
|
||||
pub fn take_data(&mut self) -> ::std::vec::Vec<u8> {
|
||||
::std::mem::replace(&mut self.data, ::std::vec::Vec::new())
|
||||
}
|
||||
|
||||
// int64 revision = 3;
|
||||
|
||||
|
||||
pub fn get_revision(&self) -> i64 {
|
||||
self.revision
|
||||
}
|
||||
pub fn clear_revision(&mut self) {
|
||||
self.revision = 0;
|
||||
}
|
||||
|
||||
// Param is passed by value, moved
|
||||
pub fn set_revision(&mut self, v: i64) {
|
||||
self.revision = v;
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::Message for Doc {
|
||||
@ -313,6 +329,13 @@ impl ::protobuf::Message for Doc {
|
||||
2 => {
|
||||
::protobuf::rt::read_singular_proto3_bytes_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.revision = tmp;
|
||||
},
|
||||
_ => {
|
||||
::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
|
||||
},
|
||||
@ -331,6 +354,9 @@ impl ::protobuf::Message for Doc {
|
||||
if !self.data.is_empty() {
|
||||
my_size += ::protobuf::rt::bytes_size(2, &self.data);
|
||||
}
|
||||
if self.revision != 0 {
|
||||
my_size += ::protobuf::rt::value_size(3, self.revision, ::protobuf::wire_format::WireTypeVarint);
|
||||
}
|
||||
my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
|
||||
self.cached_size.set(my_size);
|
||||
my_size
|
||||
@ -343,6 +369,9 @@ impl ::protobuf::Message for Doc {
|
||||
if !self.data.is_empty() {
|
||||
os.write_bytes(2, &self.data)?;
|
||||
}
|
||||
if self.revision != 0 {
|
||||
os.write_int64(3, self.revision)?;
|
||||
}
|
||||
os.write_unknown_fields(self.get_unknown_fields())?;
|
||||
::std::result::Result::Ok(())
|
||||
}
|
||||
@ -391,6 +420,11 @@ impl ::protobuf::Message for Doc {
|
||||
|m: &Doc| { &m.data },
|
||||
|m: &mut Doc| { &mut m.data },
|
||||
));
|
||||
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt64>(
|
||||
"revision",
|
||||
|m: &Doc| { &m.revision },
|
||||
|m: &mut Doc| { &mut m.revision },
|
||||
));
|
||||
::protobuf::reflect::MessageDescriptor::new_pb_name::<Doc>(
|
||||
"Doc",
|
||||
fields,
|
||||
@ -409,6 +443,7 @@ impl ::protobuf::Clear for Doc {
|
||||
fn clear(&mut self) {
|
||||
self.id.clear();
|
||||
self.data.clear();
|
||||
self.revision = 0;
|
||||
self.unknown_fields.clear();
|
||||
}
|
||||
}
|
||||
@ -426,23 +461,23 @@ impl ::protobuf::reflect::ProtobufValue for Doc {
|
||||
}
|
||||
|
||||
#[derive(PartialEq,Clone,Default)]
|
||||
pub struct SaveDocParams {
|
||||
pub struct UpdateDocParams {
|
||||
// message fields
|
||||
pub id: ::std::string::String,
|
||||
pub data: ::std::vec::Vec<u8>,
|
||||
pub doc_data: ::std::vec::Vec<u8>,
|
||||
// special fields
|
||||
pub unknown_fields: ::protobuf::UnknownFields,
|
||||
pub cached_size: ::protobuf::CachedSize,
|
||||
}
|
||||
|
||||
impl<'a> ::std::default::Default for &'a SaveDocParams {
|
||||
fn default() -> &'a SaveDocParams {
|
||||
<SaveDocParams as ::protobuf::Message>::default_instance()
|
||||
impl<'a> ::std::default::Default for &'a UpdateDocParams {
|
||||
fn default() -> &'a UpdateDocParams {
|
||||
<UpdateDocParams as ::protobuf::Message>::default_instance()
|
||||
}
|
||||
}
|
||||
|
||||
impl SaveDocParams {
|
||||
pub fn new() -> SaveDocParams {
|
||||
impl UpdateDocParams {
|
||||
pub fn new() -> UpdateDocParams {
|
||||
::std::default::Default::default()
|
||||
}
|
||||
|
||||
@ -472,34 +507,34 @@ impl SaveDocParams {
|
||||
::std::mem::replace(&mut self.id, ::std::string::String::new())
|
||||
}
|
||||
|
||||
// bytes data = 2;
|
||||
// bytes doc_data = 2;
|
||||
|
||||
|
||||
pub fn get_data(&self) -> &[u8] {
|
||||
&self.data
|
||||
pub fn get_doc_data(&self) -> &[u8] {
|
||||
&self.doc_data
|
||||
}
|
||||
pub fn clear_data(&mut self) {
|
||||
self.data.clear();
|
||||
pub fn clear_doc_data(&mut self) {
|
||||
self.doc_data.clear();
|
||||
}
|
||||
|
||||
// Param is passed by value, moved
|
||||
pub fn set_data(&mut self, v: ::std::vec::Vec<u8>) {
|
||||
self.data = v;
|
||||
pub fn set_doc_data(&mut self, v: ::std::vec::Vec<u8>) {
|
||||
self.doc_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::vec::Vec<u8> {
|
||||
&mut self.data
|
||||
pub fn mut_doc_data(&mut self) -> &mut ::std::vec::Vec<u8> {
|
||||
&mut self.doc_data
|
||||
}
|
||||
|
||||
// Take field
|
||||
pub fn take_data(&mut self) -> ::std::vec::Vec<u8> {
|
||||
::std::mem::replace(&mut self.data, ::std::vec::Vec::new())
|
||||
pub fn take_doc_data(&mut self) -> ::std::vec::Vec<u8> {
|
||||
::std::mem::replace(&mut self.doc_data, ::std::vec::Vec::new())
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::Message for SaveDocParams {
|
||||
impl ::protobuf::Message for UpdateDocParams {
|
||||
fn is_initialized(&self) -> bool {
|
||||
true
|
||||
}
|
||||
@ -512,7 +547,7 @@ impl ::protobuf::Message for SaveDocParams {
|
||||
::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?;
|
||||
},
|
||||
2 => {
|
||||
::protobuf::rt::read_singular_proto3_bytes_into(wire_type, is, &mut self.data)?;
|
||||
::protobuf::rt::read_singular_proto3_bytes_into(wire_type, is, &mut self.doc_data)?;
|
||||
},
|
||||
_ => {
|
||||
::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
|
||||
@ -529,8 +564,8 @@ impl ::protobuf::Message for SaveDocParams {
|
||||
if !self.id.is_empty() {
|
||||
my_size += ::protobuf::rt::string_size(1, &self.id);
|
||||
}
|
||||
if !self.data.is_empty() {
|
||||
my_size += ::protobuf::rt::bytes_size(2, &self.data);
|
||||
if !self.doc_data.is_empty() {
|
||||
my_size += ::protobuf::rt::bytes_size(2, &self.doc_data);
|
||||
}
|
||||
my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
|
||||
self.cached_size.set(my_size);
|
||||
@ -541,8 +576,8 @@ impl ::protobuf::Message for SaveDocParams {
|
||||
if !self.id.is_empty() {
|
||||
os.write_string(1, &self.id)?;
|
||||
}
|
||||
if !self.data.is_empty() {
|
||||
os.write_bytes(2, &self.data)?;
|
||||
if !self.doc_data.is_empty() {
|
||||
os.write_bytes(2, &self.doc_data)?;
|
||||
}
|
||||
os.write_unknown_fields(self.get_unknown_fields())?;
|
||||
::std::result::Result::Ok(())
|
||||
@ -574,8 +609,8 @@ impl ::protobuf::Message for SaveDocParams {
|
||||
Self::descriptor_static()
|
||||
}
|
||||
|
||||
fn new() -> SaveDocParams {
|
||||
SaveDocParams::new()
|
||||
fn new() -> UpdateDocParams {
|
||||
UpdateDocParams::new()
|
||||
}
|
||||
|
||||
fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
|
||||
@ -584,50 +619,50 @@ impl ::protobuf::Message for SaveDocParams {
|
||||
let mut fields = ::std::vec::Vec::new();
|
||||
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
|
||||
"id",
|
||||
|m: &SaveDocParams| { &m.id },
|
||||
|m: &mut SaveDocParams| { &mut m.id },
|
||||
|m: &UpdateDocParams| { &m.id },
|
||||
|m: &mut UpdateDocParams| { &mut m.id },
|
||||
));
|
||||
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
|
||||
"data",
|
||||
|m: &SaveDocParams| { &m.data },
|
||||
|m: &mut SaveDocParams| { &mut m.data },
|
||||
"doc_data",
|
||||
|m: &UpdateDocParams| { &m.doc_data },
|
||||
|m: &mut UpdateDocParams| { &mut m.doc_data },
|
||||
));
|
||||
::protobuf::reflect::MessageDescriptor::new_pb_name::<SaveDocParams>(
|
||||
"SaveDocParams",
|
||||
::protobuf::reflect::MessageDescriptor::new_pb_name::<UpdateDocParams>(
|
||||
"UpdateDocParams",
|
||||
fields,
|
||||
file_descriptor_proto()
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
fn default_instance() -> &'static SaveDocParams {
|
||||
static instance: ::protobuf::rt::LazyV2<SaveDocParams> = ::protobuf::rt::LazyV2::INIT;
|
||||
instance.get(SaveDocParams::new)
|
||||
fn default_instance() -> &'static UpdateDocParams {
|
||||
static instance: ::protobuf::rt::LazyV2<UpdateDocParams> = ::protobuf::rt::LazyV2::INIT;
|
||||
instance.get(UpdateDocParams::new)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::Clear for SaveDocParams {
|
||||
impl ::protobuf::Clear for UpdateDocParams {
|
||||
fn clear(&mut self) {
|
||||
self.id.clear();
|
||||
self.data.clear();
|
||||
self.doc_data.clear();
|
||||
self.unknown_fields.clear();
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::fmt::Debug for SaveDocParams {
|
||||
impl ::std::fmt::Debug for UpdateDocParams {
|
||||
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
|
||||
::protobuf::text_format::fmt(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::reflect::ProtobufValue for SaveDocParams {
|
||||
impl ::protobuf::reflect::ProtobufValue for UpdateDocParams {
|
||||
fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
|
||||
::protobuf::reflect::ReflectValueRef::Message(self)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq,Clone,Default)]
|
||||
pub struct ApplyChangesetParams {
|
||||
pub struct DocChangeset {
|
||||
// message fields
|
||||
pub id: ::std::string::String,
|
||||
pub data: ::std::vec::Vec<u8>,
|
||||
@ -636,14 +671,14 @@ pub struct ApplyChangesetParams {
|
||||
pub cached_size: ::protobuf::CachedSize,
|
||||
}
|
||||
|
||||
impl<'a> ::std::default::Default for &'a ApplyChangesetParams {
|
||||
fn default() -> &'a ApplyChangesetParams {
|
||||
<ApplyChangesetParams as ::protobuf::Message>::default_instance()
|
||||
impl<'a> ::std::default::Default for &'a DocChangeset {
|
||||
fn default() -> &'a DocChangeset {
|
||||
<DocChangeset as ::protobuf::Message>::default_instance()
|
||||
}
|
||||
}
|
||||
|
||||
impl ApplyChangesetParams {
|
||||
pub fn new() -> ApplyChangesetParams {
|
||||
impl DocChangeset {
|
||||
pub fn new() -> DocChangeset {
|
||||
::std::default::Default::default()
|
||||
}
|
||||
|
||||
@ -700,7 +735,7 @@ impl ApplyChangesetParams {
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::Message for ApplyChangesetParams {
|
||||
impl ::protobuf::Message for DocChangeset {
|
||||
fn is_initialized(&self) -> bool {
|
||||
true
|
||||
}
|
||||
@ -775,8 +810,8 @@ impl ::protobuf::Message for ApplyChangesetParams {
|
||||
Self::descriptor_static()
|
||||
}
|
||||
|
||||
fn new() -> ApplyChangesetParams {
|
||||
ApplyChangesetParams::new()
|
||||
fn new() -> DocChangeset {
|
||||
DocChangeset::new()
|
||||
}
|
||||
|
||||
fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
|
||||
@ -785,29 +820,29 @@ impl ::protobuf::Message for ApplyChangesetParams {
|
||||
let mut fields = ::std::vec::Vec::new();
|
||||
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
|
||||
"id",
|
||||
|m: &ApplyChangesetParams| { &m.id },
|
||||
|m: &mut ApplyChangesetParams| { &mut m.id },
|
||||
|m: &DocChangeset| { &m.id },
|
||||
|m: &mut DocChangeset| { &mut m.id },
|
||||
));
|
||||
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
|
||||
"data",
|
||||
|m: &ApplyChangesetParams| { &m.data },
|
||||
|m: &mut ApplyChangesetParams| { &mut m.data },
|
||||
|m: &DocChangeset| { &m.data },
|
||||
|m: &mut DocChangeset| { &mut m.data },
|
||||
));
|
||||
::protobuf::reflect::MessageDescriptor::new_pb_name::<ApplyChangesetParams>(
|
||||
"ApplyChangesetParams",
|
||||
::protobuf::reflect::MessageDescriptor::new_pb_name::<DocChangeset>(
|
||||
"DocChangeset",
|
||||
fields,
|
||||
file_descriptor_proto()
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
fn default_instance() -> &'static ApplyChangesetParams {
|
||||
static instance: ::protobuf::rt::LazyV2<ApplyChangesetParams> = ::protobuf::rt::LazyV2::INIT;
|
||||
instance.get(ApplyChangesetParams::new)
|
||||
fn default_instance() -> &'static DocChangeset {
|
||||
static instance: ::protobuf::rt::LazyV2<DocChangeset> = ::protobuf::rt::LazyV2::INIT;
|
||||
instance.get(DocChangeset::new)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::Clear for ApplyChangesetParams {
|
||||
impl ::protobuf::Clear for DocChangeset {
|
||||
fn clear(&mut self) {
|
||||
self.id.clear();
|
||||
self.data.clear();
|
||||
@ -815,13 +850,13 @@ impl ::protobuf::Clear for ApplyChangesetParams {
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::fmt::Debug for ApplyChangesetParams {
|
||||
impl ::std::fmt::Debug for DocChangeset {
|
||||
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
|
||||
::protobuf::text_format::fmt(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::reflect::ProtobufValue for ApplyChangesetParams {
|
||||
impl ::protobuf::reflect::ProtobufValue for DocChangeset {
|
||||
fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
|
||||
::protobuf::reflect::ReflectValueRef::Message(self)
|
||||
}
|
||||
@ -988,44 +1023,48 @@ impl ::protobuf::reflect::ProtobufValue for QueryDocParams {
|
||||
|
||||
static file_descriptor_proto_data: &'static [u8] = b"\
|
||||
\n\tdoc.proto\"5\n\x0fCreateDocParams\x12\x0e\n\x02id\x18\x01\x20\x01(\t\
|
||||
R\x02id\x12\x12\n\x04data\x18\x02\x20\x01(\x0cR\x04data\")\n\x03Doc\x12\
|
||||
R\x02id\x12\x12\n\x04data\x18\x02\x20\x01(\x0cR\x04data\"E\n\x03Doc\x12\
|
||||
\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x12\n\x04data\x18\x02\x20\x01\
|
||||
(\x0cR\x04data\"3\n\rSaveDocParams\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\
|
||||
\x02id\x12\x12\n\x04data\x18\x02\x20\x01(\x0cR\x04data\":\n\x14ApplyChan\
|
||||
gesetParams\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x12\n\x04data\
|
||||
\x18\x02\x20\x01(\x0cR\x04data\"'\n\x0eQueryDocParams\x12\x15\n\x06doc_i\
|
||||
d\x18\x01\x20\x01(\tR\x05docIdJ\xf9\x04\n\x06\x12\x04\0\0\x14\x01\n\x08\
|
||||
\n\x01\x0c\x12\x03\0\0\x12\n\n\n\x02\x04\0\x12\x04\x02\0\x05\x01\n\n\n\
|
||||
\x03\x04\0\x01\x12\x03\x02\x08\x17\n\x0b\n\x04\x04\0\x02\0\x12\x03\x03\
|
||||
\x04\x12\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\r\n\x0c\n\x05\x04\0\x02\0\x03\x12\x03\x03\x10\
|
||||
\x11\n\x0b\n\x04\x04\0\x02\x01\x12\x03\x04\x04\x13\n\x0c\n\x05\x04\0\x02\
|
||||
\x01\x05\x12\x03\x04\x04\t\n\x0c\n\x05\x04\0\x02\x01\x01\x12\x03\x04\n\
|
||||
\x0e\n\x0c\n\x05\x04\0\x02\x01\x03\x12\x03\x04\x11\x12\n\n\n\x02\x04\x01\
|
||||
\x12\x04\x06\0\t\x01\n\n\n\x03\x04\x01\x01\x12\x03\x06\x08\x0b\n\x0b\n\
|
||||
\x04\x04\x01\x02\0\x12\x03\x07\x04\x12\n\x0c\n\x05\x04\x01\x02\0\x05\x12\
|
||||
\x03\x07\x04\n\n\x0c\n\x05\x04\x01\x02\0\x01\x12\x03\x07\x0b\r\n\x0c\n\
|
||||
\x05\x04\x01\x02\0\x03\x12\x03\x07\x10\x11\n\x0b\n\x04\x04\x01\x02\x01\
|
||||
\x12\x03\x08\x04\x13\n\x0c\n\x05\x04\x01\x02\x01\x05\x12\x03\x08\x04\t\n\
|
||||
\x0c\n\x05\x04\x01\x02\x01\x01\x12\x03\x08\n\x0e\n\x0c\n\x05\x04\x01\x02\
|
||||
\x01\x03\x12\x03\x08\x11\x12\n\n\n\x02\x04\x02\x12\x04\n\0\r\x01\n\n\n\
|
||||
\x03\x04\x02\x01\x12\x03\n\x08\x15\n\x0b\n\x04\x04\x02\x02\0\x12\x03\x0b\
|
||||
\x04\x12\n\x0c\n\x05\x04\x02\x02\0\x05\x12\x03\x0b\x04\n\n\x0c\n\x05\x04\
|
||||
\x02\x02\0\x01\x12\x03\x0b\x0b\r\n\x0c\n\x05\x04\x02\x02\0\x03\x12\x03\
|
||||
\x0b\x10\x11\n\x0b\n\x04\x04\x02\x02\x01\x12\x03\x0c\x04\x13\n\x0c\n\x05\
|
||||
\x04\x02\x02\x01\x05\x12\x03\x0c\x04\t\n\x0c\n\x05\x04\x02\x02\x01\x01\
|
||||
\x12\x03\x0c\n\x0e\n\x0c\n\x05\x04\x02\x02\x01\x03\x12\x03\x0c\x11\x12\n\
|
||||
\n\n\x02\x04\x03\x12\x04\x0e\0\x11\x01\n\n\n\x03\x04\x03\x01\x12\x03\x0e\
|
||||
\x08\x1c\n\x0b\n\x04\x04\x03\x02\0\x12\x03\x0f\x04\x12\n\x0c\n\x05\x04\
|
||||
\x03\x02\0\x05\x12\x03\x0f\x04\n\n\x0c\n\x05\x04\x03\x02\0\x01\x12\x03\
|
||||
\x0f\x0b\r\n\x0c\n\x05\x04\x03\x02\0\x03\x12\x03\x0f\x10\x11\n\x0b\n\x04\
|
||||
\x04\x03\x02\x01\x12\x03\x10\x04\x13\n\x0c\n\x05\x04\x03\x02\x01\x05\x12\
|
||||
\x03\x10\x04\t\n\x0c\n\x05\x04\x03\x02\x01\x01\x12\x03\x10\n\x0e\n\x0c\n\
|
||||
\x05\x04\x03\x02\x01\x03\x12\x03\x10\x11\x12\n\n\n\x02\x04\x04\x12\x04\
|
||||
\x12\0\x14\x01\n\n\n\x03\x04\x04\x01\x12\x03\x12\x08\x16\n\x0b\n\x04\x04\
|
||||
\x04\x02\0\x12\x03\x13\x04\x16\n\x0c\n\x05\x04\x04\x02\0\x05\x12\x03\x13\
|
||||
\x04\n\n\x0c\n\x05\x04\x04\x02\0\x01\x12\x03\x13\x0b\x11\n\x0c\n\x05\x04\
|
||||
\x04\x02\0\x03\x12\x03\x13\x14\x15b\x06proto3\
|
||||
(\x0cR\x04data\x12\x1a\n\x08revision\x18\x03\x20\x01(\x03R\x08revision\"\
|
||||
<\n\x0fUpdateDocParams\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x19\
|
||||
\n\x08doc_data\x18\x02\x20\x01(\x0cR\x07docData\"2\n\x0cDocChangeset\x12\
|
||||
\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x12\n\x04data\x18\x02\x20\x01\
|
||||
(\x0cR\x04data\"'\n\x0eQueryDocParams\x12\x15\n\x06doc_id\x18\x01\x20\
|
||||
\x01(\tR\x05docIdJ\xb0\x05\n\x06\x12\x04\0\0\x15\x01\n\x08\n\x01\x0c\x12\
|
||||
\x03\0\0\x12\n\n\n\x02\x04\0\x12\x04\x02\0\x05\x01\n\n\n\x03\x04\0\x01\
|
||||
\x12\x03\x02\x08\x17\n\x0b\n\x04\x04\0\x02\0\x12\x03\x03\x04\x12\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\r\n\x0c\n\x05\x04\0\x02\0\x03\x12\x03\x03\x10\x11\n\x0b\n\
|
||||
\x04\x04\0\x02\x01\x12\x03\x04\x04\x13\n\x0c\n\x05\x04\0\x02\x01\x05\x12\
|
||||
\x03\x04\x04\t\n\x0c\n\x05\x04\0\x02\x01\x01\x12\x03\x04\n\x0e\n\x0c\n\
|
||||
\x05\x04\0\x02\x01\x03\x12\x03\x04\x11\x12\n\n\n\x02\x04\x01\x12\x04\x06\
|
||||
\0\n\x01\n\n\n\x03\x04\x01\x01\x12\x03\x06\x08\x0b\n\x0b\n\x04\x04\x01\
|
||||
\x02\0\x12\x03\x07\x04\x12\n\x0c\n\x05\x04\x01\x02\0\x05\x12\x03\x07\x04\
|
||||
\n\n\x0c\n\x05\x04\x01\x02\0\x01\x12\x03\x07\x0b\r\n\x0c\n\x05\x04\x01\
|
||||
\x02\0\x03\x12\x03\x07\x10\x11\n\x0b\n\x04\x04\x01\x02\x01\x12\x03\x08\
|
||||
\x04\x13\n\x0c\n\x05\x04\x01\x02\x01\x05\x12\x03\x08\x04\t\n\x0c\n\x05\
|
||||
\x04\x01\x02\x01\x01\x12\x03\x08\n\x0e\n\x0c\n\x05\x04\x01\x02\x01\x03\
|
||||
\x12\x03\x08\x11\x12\n\x0b\n\x04\x04\x01\x02\x02\x12\x03\t\x04\x17\n\x0c\
|
||||
\n\x05\x04\x01\x02\x02\x05\x12\x03\t\x04\t\n\x0c\n\x05\x04\x01\x02\x02\
|
||||
\x01\x12\x03\t\n\x12\n\x0c\n\x05\x04\x01\x02\x02\x03\x12\x03\t\x15\x16\n\
|
||||
\n\n\x02\x04\x02\x12\x04\x0b\0\x0e\x01\n\n\n\x03\x04\x02\x01\x12\x03\x0b\
|
||||
\x08\x17\n\x0b\n\x04\x04\x02\x02\0\x12\x03\x0c\x04\x12\n\x0c\n\x05\x04\
|
||||
\x02\x02\0\x05\x12\x03\x0c\x04\n\n\x0c\n\x05\x04\x02\x02\0\x01\x12\x03\
|
||||
\x0c\x0b\r\n\x0c\n\x05\x04\x02\x02\0\x03\x12\x03\x0c\x10\x11\n\x0b\n\x04\
|
||||
\x04\x02\x02\x01\x12\x03\r\x04\x17\n\x0c\n\x05\x04\x02\x02\x01\x05\x12\
|
||||
\x03\r\x04\t\n\x0c\n\x05\x04\x02\x02\x01\x01\x12\x03\r\n\x12\n\x0c\n\x05\
|
||||
\x04\x02\x02\x01\x03\x12\x03\r\x15\x16\n\n\n\x02\x04\x03\x12\x04\x0f\0\
|
||||
\x12\x01\n\n\n\x03\x04\x03\x01\x12\x03\x0f\x08\x14\n\x0b\n\x04\x04\x03\
|
||||
\x02\0\x12\x03\x10\x04\x12\n\x0c\n\x05\x04\x03\x02\0\x05\x12\x03\x10\x04\
|
||||
\n\n\x0c\n\x05\x04\x03\x02\0\x01\x12\x03\x10\x0b\r\n\x0c\n\x05\x04\x03\
|
||||
\x02\0\x03\x12\x03\x10\x10\x11\n\x0b\n\x04\x04\x03\x02\x01\x12\x03\x11\
|
||||
\x04\x13\n\x0c\n\x05\x04\x03\x02\x01\x05\x12\x03\x11\x04\t\n\x0c\n\x05\
|
||||
\x04\x03\x02\x01\x01\x12\x03\x11\n\x0e\n\x0c\n\x05\x04\x03\x02\x01\x03\
|
||||
\x12\x03\x11\x11\x12\n\n\n\x02\x04\x04\x12\x04\x13\0\x15\x01\n\n\n\x03\
|
||||
\x04\x04\x01\x12\x03\x13\x08\x16\n\x0b\n\x04\x04\x04\x02\0\x12\x03\x14\
|
||||
\x04\x16\n\x0c\n\x05\x04\x04\x02\0\x05\x12\x03\x14\x04\n\n\x0c\n\x05\x04\
|
||||
\x04\x02\0\x01\x12\x03\x14\x0b\x11\n\x0c\n\x05\x04\x04\x02\0\x03\x12\x03\
|
||||
\x14\x14\x15b\x06proto3\
|
||||
";
|
||||
|
||||
static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;
|
||||
|
@ -218,6 +218,9 @@ pub enum ErrorCode {
|
||||
DocIdInvalid = 0,
|
||||
DocNotfound = 1,
|
||||
WsConnectError = 10,
|
||||
UndoFail = 200,
|
||||
RedoFail = 201,
|
||||
OutOfBound = 202,
|
||||
UserUnauthorized = 999,
|
||||
InternalError = 1000,
|
||||
}
|
||||
@ -232,6 +235,9 @@ impl ::protobuf::ProtobufEnum for ErrorCode {
|
||||
0 => ::std::option::Option::Some(ErrorCode::DocIdInvalid),
|
||||
1 => ::std::option::Option::Some(ErrorCode::DocNotfound),
|
||||
10 => ::std::option::Option::Some(ErrorCode::WsConnectError),
|
||||
200 => ::std::option::Option::Some(ErrorCode::UndoFail),
|
||||
201 => ::std::option::Option::Some(ErrorCode::RedoFail),
|
||||
202 => ::std::option::Option::Some(ErrorCode::OutOfBound),
|
||||
999 => ::std::option::Option::Some(ErrorCode::UserUnauthorized),
|
||||
1000 => ::std::option::Option::Some(ErrorCode::InternalError),
|
||||
_ => ::std::option::Option::None
|
||||
@ -243,6 +249,9 @@ impl ::protobuf::ProtobufEnum for ErrorCode {
|
||||
ErrorCode::DocIdInvalid,
|
||||
ErrorCode::DocNotfound,
|
||||
ErrorCode::WsConnectError,
|
||||
ErrorCode::UndoFail,
|
||||
ErrorCode::RedoFail,
|
||||
ErrorCode::OutOfBound,
|
||||
ErrorCode::UserUnauthorized,
|
||||
ErrorCode::InternalError,
|
||||
];
|
||||
@ -274,29 +283,36 @@ impl ::protobuf::reflect::ProtobufValue for ErrorCode {
|
||||
|
||||
static file_descriptor_proto_data: &'static [u8] = b"\
|
||||
\n\x0cerrors.proto\"<\n\x08DocError\x12\x1e\n\x04code\x18\x01\x20\x01(\
|
||||
\x0e2\n.ErrorCodeR\x04code\x12\x10\n\x03msg\x18\x02\x20\x01(\tR\x03msg*m\
|
||||
\n\tErrorCode\x12\x10\n\x0cDocIdInvalid\x10\0\x12\x0f\n\x0bDocNotfound\
|
||||
\x10\x01\x12\x12\n\x0eWsConnectError\x10\n\x12\x15\n\x10UserUnauthorized\
|
||||
\x10\xe7\x07\x12\x12\n\rInternalError\x10\xe8\x07J\xfd\x02\n\x06\x12\x04\
|
||||
\0\0\x0c\x01\n\x08\n\x01\x0c\x12\x03\0\0\x12\n\n\n\x02\x04\0\x12\x04\x02\
|
||||
\0\x05\x01\n\n\n\x03\x04\0\x01\x12\x03\x02\x08\x10\n\x0b\n\x04\x04\0\x02\
|
||||
\0\x12\x03\x03\x04\x17\n\x0c\n\x05\x04\0\x02\0\x06\x12\x03\x03\x04\r\n\
|
||||
\x0c\n\x05\x04\0\x02\0\x01\x12\x03\x03\x0e\x12\n\x0c\n\x05\x04\0\x02\0\
|
||||
\x03\x12\x03\x03\x15\x16\n\x0b\n\x04\x04\0\x02\x01\x12\x03\x04\x04\x13\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\x0e\n\x0c\n\x05\x04\0\x02\x01\x03\x12\x03\x04\x11\
|
||||
\x12\n\n\n\x02\x05\0\x12\x04\x06\0\x0c\x01\n\n\n\x03\x05\0\x01\x12\x03\
|
||||
\x06\x05\x0e\n\x0b\n\x04\x05\0\x02\0\x12\x03\x07\x04\x15\n\x0c\n\x05\x05\
|
||||
\0\x02\0\x01\x12\x03\x07\x04\x10\n\x0c\n\x05\x05\0\x02\0\x02\x12\x03\x07\
|
||||
\x13\x14\n\x0b\n\x04\x05\0\x02\x01\x12\x03\x08\x04\x14\n\x0c\n\x05\x05\0\
|
||||
\x02\x01\x01\x12\x03\x08\x04\x0f\n\x0c\n\x05\x05\0\x02\x01\x02\x12\x03\
|
||||
\x08\x12\x13\n\x0b\n\x04\x05\0\x02\x02\x12\x03\t\x04\x18\n\x0c\n\x05\x05\
|
||||
\0\x02\x02\x01\x12\x03\t\x04\x12\n\x0c\n\x05\x05\0\x02\x02\x02\x12\x03\t\
|
||||
\x15\x17\n\x0b\n\x04\x05\0\x02\x03\x12\x03\n\x04\x1b\n\x0c\n\x05\x05\0\
|
||||
\x02\x03\x01\x12\x03\n\x04\x14\n\x0c\n\x05\x05\0\x02\x03\x02\x12\x03\n\
|
||||
\x17\x1a\n\x0b\n\x04\x05\0\x02\x04\x12\x03\x0b\x04\x19\n\x0c\n\x05\x05\0\
|
||||
\x02\x04\x01\x12\x03\x0b\x04\x11\n\x0c\n\x05\x05\0\x02\x04\x02\x12\x03\
|
||||
\x0b\x14\x18b\x06proto3\
|
||||
\x0e2\n.ErrorCodeR\x04code\x12\x10\n\x03msg\x18\x02\x20\x01(\tR\x03msg*\
|
||||
\x9c\x01\n\tErrorCode\x12\x10\n\x0cDocIdInvalid\x10\0\x12\x0f\n\x0bDocNo\
|
||||
tfound\x10\x01\x12\x12\n\x0eWsConnectError\x10\n\x12\r\n\x08UndoFail\x10\
|
||||
\xc8\x01\x12\r\n\x08RedoFail\x10\xc9\x01\x12\x0f\n\nOutOfBound\x10\xca\
|
||||
\x01\x12\x15\n\x10UserUnauthorized\x10\xe7\x07\x12\x12\n\rInternalError\
|
||||
\x10\xe8\x07J\xf8\x03\n\x06\x12\x04\0\0\x0f\x01\n\x08\n\x01\x0c\x12\x03\
|
||||
\0\0\x12\n\n\n\x02\x04\0\x12\x04\x02\0\x05\x01\n\n\n\x03\x04\0\x01\x12\
|
||||
\x03\x02\x08\x10\n\x0b\n\x04\x04\0\x02\0\x12\x03\x03\x04\x17\n\x0c\n\x05\
|
||||
\x04\0\x02\0\x06\x12\x03\x03\x04\r\n\x0c\n\x05\x04\0\x02\0\x01\x12\x03\
|
||||
\x03\x0e\x12\n\x0c\n\x05\x04\0\x02\0\x03\x12\x03\x03\x15\x16\n\x0b\n\x04\
|
||||
\x04\0\x02\x01\x12\x03\x04\x04\x13\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\x0e\n\x0c\n\x05\
|
||||
\x04\0\x02\x01\x03\x12\x03\x04\x11\x12\n\n\n\x02\x05\0\x12\x04\x06\0\x0f\
|
||||
\x01\n\n\n\x03\x05\0\x01\x12\x03\x06\x05\x0e\n\x0b\n\x04\x05\0\x02\0\x12\
|
||||
\x03\x07\x04\x15\n\x0c\n\x05\x05\0\x02\0\x01\x12\x03\x07\x04\x10\n\x0c\n\
|
||||
\x05\x05\0\x02\0\x02\x12\x03\x07\x13\x14\n\x0b\n\x04\x05\0\x02\x01\x12\
|
||||
\x03\x08\x04\x14\n\x0c\n\x05\x05\0\x02\x01\x01\x12\x03\x08\x04\x0f\n\x0c\
|
||||
\n\x05\x05\0\x02\x01\x02\x12\x03\x08\x12\x13\n\x0b\n\x04\x05\0\x02\x02\
|
||||
\x12\x03\t\x04\x18\n\x0c\n\x05\x05\0\x02\x02\x01\x12\x03\t\x04\x12\n\x0c\
|
||||
\n\x05\x05\0\x02\x02\x02\x12\x03\t\x15\x17\n\x0b\n\x04\x05\0\x02\x03\x12\
|
||||
\x03\n\x04\x13\n\x0c\n\x05\x05\0\x02\x03\x01\x12\x03\n\x04\x0c\n\x0c\n\
|
||||
\x05\x05\0\x02\x03\x02\x12\x03\n\x0f\x12\n\x0b\n\x04\x05\0\x02\x04\x12\
|
||||
\x03\x0b\x04\x13\n\x0c\n\x05\x05\0\x02\x04\x01\x12\x03\x0b\x04\x0c\n\x0c\
|
||||
\n\x05\x05\0\x02\x04\x02\x12\x03\x0b\x0f\x12\n\x0b\n\x04\x05\0\x02\x05\
|
||||
\x12\x03\x0c\x04\x15\n\x0c\n\x05\x05\0\x02\x05\x01\x12\x03\x0c\x04\x0e\n\
|
||||
\x0c\n\x05\x05\0\x02\x05\x02\x12\x03\x0c\x11\x14\n\x0b\n\x04\x05\0\x02\
|
||||
\x06\x12\x03\r\x04\x1b\n\x0c\n\x05\x05\0\x02\x06\x01\x12\x03\r\x04\x14\n\
|
||||
\x0c\n\x05\x05\0\x02\x06\x02\x12\x03\r\x17\x1a\n\x0b\n\x04\x05\0\x02\x07\
|
||||
\x12\x03\x0e\x04\x19\n\x0c\n\x05\x05\0\x02\x07\x01\x12\x03\x0e\x04\x11\n\
|
||||
\x0c\n\x05\x05\0\x02\x07\x02\x12\x03\x0e\x14\x18b\x06proto3\
|
||||
";
|
||||
|
||||
static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;
|
||||
|
@ -7,12 +7,13 @@ message CreateDocParams {
|
||||
message Doc {
|
||||
string id = 1;
|
||||
bytes data = 2;
|
||||
int64 revision = 3;
|
||||
}
|
||||
message SaveDocParams {
|
||||
message UpdateDocParams {
|
||||
string id = 1;
|
||||
bytes data = 2;
|
||||
bytes doc_data = 2;
|
||||
}
|
||||
message ApplyChangesetParams {
|
||||
message DocChangeset {
|
||||
string id = 1;
|
||||
bytes data = 2;
|
||||
}
|
||||
|
@ -8,6 +8,9 @@ enum ErrorCode {
|
||||
DocIdInvalid = 0;
|
||||
DocNotfound = 1;
|
||||
WsConnectError = 10;
|
||||
UndoFail = 200;
|
||||
RedoFail = 201;
|
||||
OutOfBound = 202;
|
||||
UserUnauthorized = 999;
|
||||
InternalError = 1000;
|
||||
}
|
||||
|
48
rust-lib/flowy-document/src/services/cache.rs
Normal file
48
rust-lib/flowy-document/src/services/cache.rs
Normal file
@ -0,0 +1,48 @@
|
||||
use crate::{
|
||||
entities::doc::Doc,
|
||||
errors::DocError,
|
||||
services::{
|
||||
open_doc::{DocId, OpenedDoc},
|
||||
ws::WsManager,
|
||||
},
|
||||
};
|
||||
use bytes::Bytes;
|
||||
use dashmap::DashMap;
|
||||
use flowy_database::ConnectionPool;
|
||||
use flowy_ot::{core::Delta, errors::OTError};
|
||||
use parking_lot::RwLock;
|
||||
use std::{convert::TryInto, fmt::Debug, sync::Arc};
|
||||
|
||||
pub(crate) struct DocCache {
|
||||
doc_map: DashMap<DocId, Arc<OpenedDoc>>,
|
||||
}
|
||||
|
||||
impl DocCache {
|
||||
pub(crate) fn new() -> Self { Self { doc_map: DashMap::new() } }
|
||||
|
||||
pub(crate) fn set(&self, doc: Arc<OpenedDoc>) -> Result<(), DocError> {
|
||||
self.doc_map.insert(doc.id.clone(), doc);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn is_opened(&self, doc_id: &str) -> bool {
|
||||
let doc_id: DocId = doc_id.into();
|
||||
self.doc_map.get(&doc_id).is_some()
|
||||
}
|
||||
|
||||
pub(crate) fn get(&self, doc_id: &str) -> Result<Arc<OpenedDoc>, DocError> {
|
||||
if !self.is_opened(&doc_id) {
|
||||
return Err(doc_not_found());
|
||||
}
|
||||
let doc_id: DocId = doc_id.into();
|
||||
let opened_doc = self.doc_map.get(&doc_id).unwrap();
|
||||
Ok(opened_doc.clone())
|
||||
}
|
||||
|
||||
pub(crate) fn remove(&self, id: &str) {
|
||||
let doc_id: DocId = id.into();
|
||||
self.doc_map.remove(&doc_id);
|
||||
}
|
||||
}
|
||||
|
||||
fn doc_not_found() -> DocError { DocError::not_found().context("Doc is close or you should call open first") }
|
@ -1,8 +1,8 @@
|
||||
use crate::{client::DocumentData, errors::OTError};
|
||||
use crate::{errors::DocError, services::doc::DocumentData};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
impl<T: AsRef<str>> DocumentData for T {
|
||||
fn into_string(self) -> Result<String, OTError> { Ok(self.as_ref().to_string()) }
|
||||
fn into_string(self) -> Result<String, DocError> { Ok(self.as_ref().to_string()) }
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
@ -11,7 +11,7 @@ pub struct ImageData {
|
||||
}
|
||||
|
||||
impl DocumentData for ImageData {
|
||||
fn into_string(self) -> Result<String, OTError> {
|
||||
fn into_string(self) -> Result<String, DocError> {
|
||||
let s = serde_json::to_string(&self)?;
|
||||
Ok(s)
|
||||
}
|
@ -1,12 +1,13 @@
|
||||
use crate::{
|
||||
client::{view::View, History, RevId, UndoResult, RECORD_THRESHOLD},
|
||||
core::*,
|
||||
errors::{ErrorBuilder, OTError, OTErrorCode, OTErrorCode::*},
|
||||
errors::DocError,
|
||||
services::doc::{view::View, History, UndoResult, RECORD_THRESHOLD},
|
||||
};
|
||||
use bytes::Bytes;
|
||||
use flowy_ot::core::*;
|
||||
use std::convert::TryInto;
|
||||
|
||||
pub trait DocumentData {
|
||||
fn into_string(self) -> Result<String, OTError>;
|
||||
fn into_string(self) -> Result<String, DocError>;
|
||||
}
|
||||
|
||||
pub trait CustomDocument {
|
||||
@ -23,6 +24,19 @@ impl CustomDocument for FlowyDoc {
|
||||
fn init_delta() -> Delta { DeltaBuilder::new().insert("\n").build() }
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct RevId(pub usize);
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Revision {
|
||||
rev_id: RevId,
|
||||
pub delta: Delta,
|
||||
}
|
||||
|
||||
impl Revision {
|
||||
pub fn new(rev_id: RevId, delta: Delta) -> Revision { Self { rev_id, delta } }
|
||||
}
|
||||
|
||||
pub struct Document {
|
||||
delta: Delta,
|
||||
history: History,
|
||||
@ -44,7 +58,7 @@ impl Document {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_json(json: &str) -> Result<Self, OTError> {
|
||||
pub fn from_json(json: &str) -> Result<Self, DocError> {
|
||||
let delta = Delta::from_json(json)?;
|
||||
Ok(Self::from_delta(delta))
|
||||
}
|
||||
@ -55,18 +69,20 @@ impl Document {
|
||||
|
||||
pub fn to_string(&self) -> String { self.delta.apply("").unwrap() }
|
||||
|
||||
pub fn apply_changeset<T>(&mut self, changeset: T) -> Result<(), OTError>
|
||||
where
|
||||
T: TryInto<Delta, Error = OTError>,
|
||||
{
|
||||
let new_delta: Delta = changeset.try_into()?;
|
||||
log::debug!("Delta changeset: {}", new_delta);
|
||||
pub fn apply_delta(&mut self, data: Bytes) -> Result<(), DocError> {
|
||||
let new_delta = Delta::from_bytes(data.to_vec())?;
|
||||
|
||||
log::debug!("Apply delta: {}", new_delta);
|
||||
|
||||
let rev_id = self.next_rev_id();
|
||||
let revision = Revision::new(rev_id, new_delta.clone());
|
||||
|
||||
let _ = self.add_delta(&new_delta)?;
|
||||
log::debug!("Document: {}", self.to_json());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn insert<T: DocumentData>(&mut self, index: usize, data: T) -> Result<Delta, OTError> {
|
||||
pub fn insert<T: DocumentData>(&mut self, index: usize, data: T) -> Result<Delta, DocError> {
|
||||
let interval = Interval::new(index, index);
|
||||
let _ = validate_interval(&self.delta, &interval)?;
|
||||
|
||||
@ -77,7 +93,7 @@ impl Document {
|
||||
Ok(delta)
|
||||
}
|
||||
|
||||
pub fn delete(&mut self, interval: Interval) -> Result<Delta, OTError> {
|
||||
pub fn delete(&mut self, interval: Interval) -> Result<Delta, DocError> {
|
||||
let _ = validate_interval(&self.delta, &interval)?;
|
||||
debug_assert_eq!(interval.is_empty(), false);
|
||||
let delete = self.view.delete(&self.delta, interval)?;
|
||||
@ -88,7 +104,7 @@ impl Document {
|
||||
Ok(delete)
|
||||
}
|
||||
|
||||
pub fn format(&mut self, interval: Interval, attribute: Attribute) -> Result<(), OTError> {
|
||||
pub fn format(&mut self, interval: Interval, attribute: Attribute) -> Result<(), DocError> {
|
||||
let _ = validate_interval(&self.delta, &interval)?;
|
||||
log::trace!("format with {} at {}", attribute, interval);
|
||||
let format_delta = self.view.format(&self.delta, attribute.clone(), interval).unwrap();
|
||||
@ -98,7 +114,7 @@ impl Document {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn replace<T: DocumentData>(&mut self, interval: Interval, data: T) -> Result<Delta, OTError> {
|
||||
pub fn replace<T: DocumentData>(&mut self, interval: Interval, data: T) -> Result<Delta, DocError> {
|
||||
let _ = validate_interval(&self.delta, &interval)?;
|
||||
let mut delta = Delta::default();
|
||||
let text = data.into_string()?;
|
||||
@ -120,9 +136,9 @@ impl Document {
|
||||
|
||||
pub fn can_redo(&self) -> bool { self.history.can_redo() }
|
||||
|
||||
pub fn undo(&mut self) -> Result<UndoResult, OTError> {
|
||||
pub fn undo(&mut self) -> Result<UndoResult, DocError> {
|
||||
match self.history.undo() {
|
||||
None => Err(ErrorBuilder::new(UndoFail).msg("Undo stack is empty").build()),
|
||||
None => Err(DocError::undo().context("Undo stack is empty")),
|
||||
Some(undo_delta) => {
|
||||
let (new_delta, inverted_delta) = self.invert_change(&undo_delta)?;
|
||||
let result = UndoResult::success(new_delta.target_len as usize);
|
||||
@ -134,9 +150,9 @@ impl Document {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn redo(&mut self) -> Result<UndoResult, OTError> {
|
||||
pub fn redo(&mut self) -> Result<UndoResult, DocError> {
|
||||
match self.history.redo() {
|
||||
None => Err(ErrorBuilder::new(RedoFail).build()),
|
||||
None => Err(DocError::redo()),
|
||||
Some(redo_delta) => {
|
||||
let (new_delta, inverted_delta) = self.invert_change(&redo_delta)?;
|
||||
let result = UndoResult::success(new_delta.target_len as usize);
|
||||
@ -154,7 +170,7 @@ impl Document {
|
||||
}
|
||||
|
||||
impl Document {
|
||||
fn add_delta(&mut self, delta: &Delta) -> Result<(), OTError> {
|
||||
fn add_delta(&mut self, delta: &Delta) -> Result<(), DocError> {
|
||||
let composed_delta = self.delta.compose(delta)?;
|
||||
let mut undo_delta = delta.invert(&self.delta);
|
||||
self.rev_id_counter += 1;
|
||||
@ -181,7 +197,7 @@ impl Document {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn invert_change(&self, change: &Delta) -> Result<(Delta, Delta), OTError> {
|
||||
fn invert_change(&self, change: &Delta) -> Result<(Delta, Delta), DocError> {
|
||||
// c = a.compose(b)
|
||||
// d = b.invert(a)
|
||||
// a = c.compose(d)
|
||||
@ -195,10 +211,10 @@ impl Document {
|
||||
fn next_rev_id(&self) -> RevId { RevId(self.rev_id_counter) }
|
||||
}
|
||||
|
||||
fn validate_interval(delta: &Delta, interval: &Interval) -> Result<(), OTError> {
|
||||
fn validate_interval(delta: &Delta, interval: &Interval) -> Result<(), DocError> {
|
||||
if delta.target_len < interval.end {
|
||||
log::error!("{:?} out of bounds. should 0..{}", interval, delta.target_len);
|
||||
return Err(ErrorBuilder::new(OTErrorCode::IntervalOutOfBound).build());
|
||||
return Err(DocError::out_of_bound());
|
||||
}
|
||||
Ok(())
|
||||
}
|
@ -1,7 +1,5 @@
|
||||
use crate::{
|
||||
client::extensions::DeleteExt,
|
||||
core::{Delta, DeltaBuilder, Interval},
|
||||
};
|
||||
use crate::services::doc::extensions::DeleteExt;
|
||||
use flowy_ot::core::{Delta, DeltaBuilder, Interval};
|
||||
|
||||
pub struct DefaultDelete {}
|
||||
impl DeleteExt for DefaultDelete {
|
@ -1,7 +1,5 @@
|
||||
use crate::{
|
||||
client::{extensions::DeleteExt, util::is_newline},
|
||||
core::{plain_attributes, CharMetric, Delta, DeltaBuilder, DeltaIter, Interval, NEW_LINE},
|
||||
};
|
||||
use crate::services::doc::{extensions::DeleteExt, util::is_newline};
|
||||
use flowy_ot::core::{plain_attributes, CharMetric, Delta, DeltaBuilder, DeltaIter, Interval, NEW_LINE};
|
||||
|
||||
pub struct PreserveLineFormatOnMerge {}
|
||||
impl DeleteExt for PreserveLineFormatOnMerge {
|
@ -1,7 +1,5 @@
|
||||
use crate::{
|
||||
client::util::find_newline,
|
||||
core::{plain_attributes, Attribute, AttributeScope, Delta, Operation},
|
||||
};
|
||||
use crate::services::doc::util::find_newline;
|
||||
use flowy_ot::core::{plain_attributes, Attribute, AttributeScope, Delta, Operation};
|
||||
|
||||
pub(crate) fn line_break(op: &Operation, attribute: &Attribute, scope: AttributeScope) -> Delta {
|
||||
let mut new_delta = Delta::new();
|
@ -1,10 +1,8 @@
|
||||
use crate::{
|
||||
client::{
|
||||
extensions::{format::helper::line_break, FormatExt},
|
||||
util::find_newline,
|
||||
},
|
||||
core::{plain_attributes, Attribute, AttributeScope, Delta, DeltaBuilder, DeltaIter, Interval},
|
||||
use crate::services::doc::{
|
||||
extensions::{format::helper::line_break, FormatExt},
|
||||
util::find_newline,
|
||||
};
|
||||
use flowy_ot::core::{plain_attributes, Attribute, AttributeScope, Delta, DeltaBuilder, DeltaIter, Interval};
|
||||
|
||||
pub struct ResolveBlockFormat {}
|
||||
impl FormatExt for ResolveBlockFormat {
|
@ -1,10 +1,8 @@
|
||||
use crate::{
|
||||
client::{
|
||||
extensions::{format::helper::line_break, FormatExt},
|
||||
util::find_newline,
|
||||
},
|
||||
core::{Attribute, AttributeScope, Delta, DeltaBuilder, DeltaIter, Interval},
|
||||
use crate::services::doc::{
|
||||
extensions::{format::helper::line_break, FormatExt},
|
||||
util::find_newline,
|
||||
};
|
||||
use flowy_ot::core::{Attribute, AttributeScope, Delta, DeltaBuilder, DeltaIter, Interval};
|
||||
|
||||
pub struct ResolveInlineFormat {}
|
||||
impl FormatExt for ResolveInlineFormat {
|
@ -1,9 +1,5 @@
|
||||
use crate::{
|
||||
client::{extensions::InsertExt, util::is_newline},
|
||||
core::{AttributeKey, Delta, DeltaBuilder, DeltaIter},
|
||||
};
|
||||
|
||||
use crate::core::{attributes_except_header, is_empty_line_at_index};
|
||||
use crate::services::doc::{extensions::InsertExt, util::is_newline};
|
||||
use flowy_ot::core::{attributes_except_header, is_empty_line_at_index, AttributeKey, Delta, DeltaBuilder, DeltaIter};
|
||||
|
||||
pub struct AutoExitBlock {}
|
||||
|
@ -1,7 +1,8 @@
|
||||
use crate::{
|
||||
client::{extensions::InsertExt, util::is_whitespace},
|
||||
core::{Delta, DeltaIter},
|
||||
};
|
||||
use crate::services::doc::{extensions::InsertExt, util::is_whitespace};
|
||||
use bytecount::num_chars;
|
||||
use flowy_ot::core::{plain_attributes, Attribute, Attributes, Delta, DeltaBuilder, DeltaIter};
|
||||
use std::cmp::min;
|
||||
use url::Url;
|
||||
|
||||
pub struct AutoFormatExt {}
|
||||
impl InsertExt for AutoFormatExt {
|
||||
@ -50,11 +51,6 @@ impl InsertExt for AutoFormatExt {
|
||||
}
|
||||
}
|
||||
|
||||
use crate::core::{plain_attributes, Attribute, Attributes, DeltaBuilder};
|
||||
use bytecount::num_chars;
|
||||
use std::cmp::min;
|
||||
use url::Url;
|
||||
|
||||
pub enum AutoFormatter {
|
||||
Url(Url),
|
||||
}
|
@ -1,7 +1,5 @@
|
||||
use crate::{
|
||||
client::extensions::InsertExt,
|
||||
core::{AttributeKey, Attributes, Delta, DeltaBuilder, DeltaIter, NEW_LINE},
|
||||
};
|
||||
use crate::services::doc::extensions::InsertExt;
|
||||
use flowy_ot::core::{AttributeKey, Attributes, Delta, DeltaBuilder, DeltaIter, NEW_LINE};
|
||||
|
||||
pub struct DefaultInsertAttribute {}
|
||||
impl InsertExt for DefaultInsertAttribute {
|
@ -1,6 +1,8 @@
|
||||
use crate::services::doc::extensions::InsertExt;
|
||||
pub use auto_exit_block::*;
|
||||
pub use auto_format::*;
|
||||
pub use default_insert::*;
|
||||
use flowy_ot::core::Delta;
|
||||
pub use preserve_block_format::*;
|
||||
pub use preserve_inline_format::*;
|
||||
pub use reset_format_on_new_line::*;
|
||||
@ -12,8 +14,6 @@ mod preserve_block_format;
|
||||
mod preserve_inline_format;
|
||||
mod reset_format_on_new_line;
|
||||
|
||||
use crate::{client::extensions::InsertExt, core::Delta};
|
||||
|
||||
pub struct InsertEmbedsExt {}
|
||||
impl InsertExt for InsertEmbedsExt {
|
||||
fn ext_name(&self) -> &str { "InsertEmbedsExt" }
|
@ -1,6 +1,14 @@
|
||||
use crate::{
|
||||
client::{extensions::InsertExt, util::is_newline},
|
||||
core::{attributes_except_header, plain_attributes, Attribute, AttributeKey, Attributes, Delta, DeltaBuilder, DeltaIter, NEW_LINE},
|
||||
use crate::services::doc::{extensions::InsertExt, util::is_newline};
|
||||
use flowy_ot::core::{
|
||||
attributes_except_header,
|
||||
plain_attributes,
|
||||
Attribute,
|
||||
AttributeKey,
|
||||
Attributes,
|
||||
Delta,
|
||||
DeltaBuilder,
|
||||
DeltaIter,
|
||||
NEW_LINE,
|
||||
};
|
||||
|
||||
pub struct PreserveBlockFormatOnInsert {}
|
@ -1,10 +1,8 @@
|
||||
use crate::{
|
||||
client::{
|
||||
extensions::InsertExt,
|
||||
util::{contain_newline, is_newline},
|
||||
},
|
||||
core::{plain_attributes, AttributeKey, Delta, DeltaBuilder, DeltaIter, OpNewline, NEW_LINE},
|
||||
use crate::services::doc::{
|
||||
extensions::InsertExt,
|
||||
util::{contain_newline, is_newline},
|
||||
};
|
||||
use flowy_ot::core::{plain_attributes, AttributeKey, Delta, DeltaBuilder, DeltaIter, OpNewline, NEW_LINE};
|
||||
|
||||
pub struct PreserveInlineFormat {}
|
||||
impl InsertExt for PreserveInlineFormat {
|
@ -1,7 +1,5 @@
|
||||
use crate::{
|
||||
client::{extensions::InsertExt, util::is_newline},
|
||||
core::{AttributeKey, Attributes, CharMetric, Delta, DeltaBuilder, DeltaIter, NEW_LINE},
|
||||
};
|
||||
use crate::services::doc::{extensions::InsertExt, util::is_newline};
|
||||
use flowy_ot::core::{AttributeKey, Attributes, CharMetric, Delta, DeltaBuilder, DeltaIter, NEW_LINE};
|
||||
|
||||
pub struct ResetLineFormatOnNewLine {}
|
||||
impl InsertExt for ResetLineFormatOnNewLine {
|
@ -2,7 +2,7 @@ pub use delete::*;
|
||||
pub use format::*;
|
||||
pub use insert::*;
|
||||
|
||||
use crate::core::{Attribute, Delta, Interval};
|
||||
use flowy_ot::core::{Attribute, Delta, Interval};
|
||||
|
||||
mod delete;
|
||||
mod format;
|
@ -1,20 +1,7 @@
|
||||
use crate::core::Delta;
|
||||
use flowy_ot::core::Delta;
|
||||
|
||||
const MAX_UNDOS: usize = 20;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct RevId(pub usize);
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Revision {
|
||||
rev_id: RevId,
|
||||
pub delta: Delta,
|
||||
}
|
||||
|
||||
impl Revision {
|
||||
pub fn new(rev_id: RevId, delta: Delta) -> Revision { Self { rev_id, delta } }
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct UndoResult {
|
||||
success: bool,
|
@ -1,4 +1,4 @@
|
||||
use crate::core::{NEW_LINE, WHITESPACE};
|
||||
use flowy_ot::core::{NEW_LINE, WHITESPACE};
|
||||
|
||||
#[inline]
|
||||
pub fn find_newline(s: &str) -> Option<usize> {
|
@ -1,5 +1,5 @@
|
||||
use super::extensions::*;
|
||||
use crate::{
|
||||
use flowy_ot::{
|
||||
core::{Attribute, Delta, Interval},
|
||||
errors::{ErrorBuilder, OTError, OTErrorCode},
|
||||
};
|
@ -1,5 +1,5 @@
|
||||
use crate::{
|
||||
entities::doc::{CreateDocParams, Doc, QueryDocParams, SaveDocParams},
|
||||
entities::doc::{CreateDocParams, Doc, QueryDocParams, UpdateDocParams},
|
||||
errors::DocError,
|
||||
module::DocumentUser,
|
||||
services::server::Server,
|
||||
@ -7,20 +7,37 @@ use crate::{
|
||||
};
|
||||
use flowy_database::{ConnectionPool, SqliteConnection};
|
||||
|
||||
use crate::{errors::internal_error, services::open_doc::OpenedDocPersistence};
|
||||
use crate::{
|
||||
errors::internal_error,
|
||||
services::{
|
||||
cache::DocCache,
|
||||
open_doc::{DocId, OpenedDoc, OpenedDocPersistence},
|
||||
ws::WsManager,
|
||||
},
|
||||
};
|
||||
use parking_lot::RwLock;
|
||||
use std::sync::Arc;
|
||||
use tokio::task::JoinHandle;
|
||||
|
||||
pub(crate) struct DocController {
|
||||
server: Server,
|
||||
sql: Arc<DocTableSql>,
|
||||
ws: Arc<RwLock<WsManager>>,
|
||||
cache: Arc<DocCache>,
|
||||
user: Arc<dyn DocumentUser>,
|
||||
}
|
||||
|
||||
impl DocController {
|
||||
pub(crate) fn new(server: Server, user: Arc<dyn DocumentUser>) -> Self {
|
||||
pub(crate) fn new(server: Server, user: Arc<dyn DocumentUser>, ws: Arc<RwLock<WsManager>>) -> Self {
|
||||
let sql = Arc::new(DocTableSql {});
|
||||
Self { sql, server, user }
|
||||
let cache = Arc::new(DocCache::new());
|
||||
Self {
|
||||
sql,
|
||||
server,
|
||||
user,
|
||||
ws,
|
||||
cache,
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self, conn), err)]
|
||||
@ -28,22 +45,53 @@ impl DocController {
|
||||
let doc = Doc {
|
||||
id: params.id,
|
||||
data: params.data,
|
||||
revision: 0,
|
||||
};
|
||||
let _ = self.sql.create_doc_table(DocTable::new(doc), conn)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(self, pool), err)]
|
||||
pub(crate) async fn open(&self, params: QueryDocParams, pool: Arc<ConnectionPool>) -> Result<Doc, DocError> {
|
||||
match self._open(params.clone(), pool.clone()) {
|
||||
Ok(doc_table) => Ok(doc_table.into()),
|
||||
Err(error) => self.try_read_on_server(params, pool.clone(), error).await,
|
||||
pub(crate) async fn open(&self, params: QueryDocParams, pool: Arc<ConnectionPool>) -> Result<Arc<OpenedDoc>, DocError> {
|
||||
if self.cache.is_opened(¶ms.doc_id) == false {
|
||||
return match self._open(params.clone(), pool.clone()) {
|
||||
Ok(doc) => Ok(doc),
|
||||
Err(error) => Err(error),
|
||||
};
|
||||
}
|
||||
|
||||
let doc = self.cache.get(¶ms.doc_id)?;
|
||||
Ok(doc)
|
||||
}
|
||||
|
||||
pub(crate) fn close(&self, doc_id: &str) -> Result<(), DocError> {
|
||||
self.cache.remove(doc_id);
|
||||
self.ws.write().remove_handler(doc_id);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// #[tracing::instrument(level = "debug", skip(self, changeset, pool), err)]
|
||||
// pub(crate) async fn apply_changeset<T>(&self, id: T, changeset: Bytes, pool:
|
||||
// Arc<ConnectionPool>) -> Result<(), DocError> where
|
||||
// T: Into<DocId> + Debug,
|
||||
// {
|
||||
// let id = id.into();
|
||||
// match self.doc_map.get(&id) {
|
||||
// None => Err(doc_not_found()),
|
||||
// Some(doc) => {
|
||||
// let _ = doc.apply_delta(changeset, pool)?;
|
||||
// Ok(())
|
||||
// },
|
||||
// }
|
||||
// }
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(self, conn), err)]
|
||||
pub(crate) fn delete(&self, params: QueryDocParams, conn: &SqliteConnection) -> Result<(), DocError> {
|
||||
let _ = self.sql.delete_doc(¶ms.doc_id, &*conn)?;
|
||||
let doc_id = ¶ms.doc_id;
|
||||
let _ = self.sql.delete_doc(doc_id, &*conn)?;
|
||||
|
||||
self.cache.remove(doc_id);
|
||||
self.ws.write().remove_handler(doc_id);
|
||||
let _ = self.delete_doc_on_server(params)?;
|
||||
Ok(())
|
||||
}
|
||||
@ -51,7 +99,7 @@ impl DocController {
|
||||
|
||||
impl DocController {
|
||||
#[tracing::instrument(level = "debug", skip(self, params), err)]
|
||||
fn update_doc_on_server(&self, params: SaveDocParams) -> Result<(), DocError> {
|
||||
fn update_doc_on_server(&self, params: UpdateDocParams) -> Result<(), DocError> {
|
||||
let token = self.user.token()?;
|
||||
let server = self.server.clone();
|
||||
tokio::spawn(async move {
|
||||
@ -89,15 +137,6 @@ impl DocController {
|
||||
}))
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(self), err)]
|
||||
async fn sync_read_doc_from_server(&self, params: QueryDocParams) -> Result<Doc, DocError> {
|
||||
let token = self.user.token()?;
|
||||
match self.server.read_doc(&token, params).await? {
|
||||
None => Err(DocError::not_found()),
|
||||
Some(doc) => Ok(doc),
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(self), err)]
|
||||
fn delete_doc_on_server(&self, params: QueryDocParams) -> Result<(), DocError> {
|
||||
let token = self.user.token()?;
|
||||
@ -114,25 +153,30 @@ impl DocController {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn _open(&self, params: QueryDocParams, pool: Arc<ConnectionPool>) -> Result<Doc, DocError> {
|
||||
let doc_table = self.sql.read_doc_table(¶ms.doc_id, &*(pool.get().map_err(internal_error)?))?;
|
||||
let doc: Doc = doc_table.into();
|
||||
let _ = self.read_doc_from_server(params, pool.clone())?;
|
||||
Ok(doc)
|
||||
}
|
||||
fn _open(&self, params: QueryDocParams, pool: Arc<ConnectionPool>) -> Result<Arc<OpenedDoc>, DocError> {
|
||||
match self.sql.read_doc_table(¶ms.doc_id, &*(pool.get().map_err(internal_error)?)) {
|
||||
Ok(doc_table) => {
|
||||
let doc = Arc::new(OpenedDoc::new(doc_table.into(), self.ws.read().sender.clone())?);
|
||||
self.ws.write().register_handler(doc.id.as_ref(), doc.clone());
|
||||
self.cache.set(doc.clone());
|
||||
|
||||
async fn try_read_on_server(&self, params: QueryDocParams, pool: Arc<ConnectionPool>, error: DocError) -> Result<Doc, DocError> {
|
||||
if error.is_record_not_found() {
|
||||
log::debug!("Doc:{} don't exist, reading from server", params.doc_id);
|
||||
self.read_doc_from_server(params, pool)?.await.map_err(internal_error)?
|
||||
} else {
|
||||
Err(error)
|
||||
Ok(doc)
|
||||
},
|
||||
Err(error) => {
|
||||
if error.is_record_not_found() {
|
||||
log::debug!("Doc:{} don't exist, reading from server", params.doc_id);
|
||||
// TODO: notify doc update
|
||||
let _ = self.read_doc_from_server(params, pool);
|
||||
}
|
||||
|
||||
return Err(error);
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl OpenedDocPersistence for DocController {
|
||||
fn save(&self, params: SaveDocParams, pool: Arc<ConnectionPool>) -> Result<(), DocError> {
|
||||
fn save(&self, params: UpdateDocParams, pool: Arc<ConnectionPool>) -> Result<(), DocError> {
|
||||
let changeset = DocTableChangeset::new(params.clone());
|
||||
let _ = self.sql.update_doc_table(changeset, &*(pool.get().map_err(internal_error)?))?;
|
||||
Ok(())
|
||||
|
@ -1,4 +1,6 @@
|
||||
mod cache;
|
||||
pub mod doc;
|
||||
pub(crate) mod doc_controller;
|
||||
pub(crate) mod open_doc;
|
||||
mod open_doc;
|
||||
pub mod server;
|
||||
pub mod ws;
|
||||
|
@ -1,16 +1,19 @@
|
||||
use crate::{
|
||||
entities::{
|
||||
doc::SaveDocParams,
|
||||
doc::{Doc, UpdateDocParams},
|
||||
ws::{WsDocumentData, WsSource},
|
||||
},
|
||||
errors::DocError,
|
||||
services::ws::{WsHandler, WsSender},
|
||||
services::{
|
||||
doc::Document,
|
||||
ws::{WsHandler, WsSender},
|
||||
},
|
||||
};
|
||||
use bytes::Bytes;
|
||||
use flowy_database::ConnectionPool;
|
||||
use flowy_ot::{client::Document, core::Delta};
|
||||
use flowy_ot::core::Delta;
|
||||
use parking_lot::RwLock;
|
||||
use std::sync::Arc;
|
||||
use std::{convert::TryInto, sync::Arc};
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
|
||||
pub struct DocId(pub(crate) String);
|
||||
@ -25,32 +28,42 @@ where
|
||||
}
|
||||
|
||||
pub(crate) trait OpenedDocPersistence: Send + Sync {
|
||||
fn save(&self, params: SaveDocParams, pool: Arc<ConnectionPool>) -> Result<(), DocError>;
|
||||
fn save(&self, params: UpdateDocParams, pool: Arc<ConnectionPool>) -> Result<(), DocError>;
|
||||
}
|
||||
|
||||
pub(crate) struct OpenedDoc {
|
||||
pub(crate) id: DocId,
|
||||
pub(crate) revision: i64,
|
||||
document: RwLock<Document>,
|
||||
ws_sender: Arc<dyn WsSender>,
|
||||
persistence: Arc<dyn OpenedDocPersistence>,
|
||||
}
|
||||
|
||||
impl OpenedDoc {
|
||||
pub(crate) fn new(id: DocId, delta: Delta, persistence: Arc<dyn OpenedDocPersistence>, ws_sender: Arc<dyn WsSender>) -> Self {
|
||||
pub(crate) fn new(doc: Doc, ws_sender: Arc<dyn WsSender>) -> Result<Self, DocError> {
|
||||
let id: DocId = doc.id.into();
|
||||
let revision = doc.revision;
|
||||
let delta: Delta = doc.data.try_into()?;
|
||||
let document = RwLock::new(Document::from_delta(delta));
|
||||
Self {
|
||||
|
||||
Ok(Self {
|
||||
id,
|
||||
revision,
|
||||
document,
|
||||
ws_sender,
|
||||
persistence,
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn doc(&self) -> Doc {
|
||||
Doc {
|
||||
id: self.id.0.clone(),
|
||||
data: self.document.read().to_bytes(),
|
||||
revision: self.revision,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn data(&self) -> Vec<u8> { self.document.read().to_bytes() }
|
||||
|
||||
pub(crate) fn apply_delta(&self, data: Bytes, pool: Arc<ConnectionPool>) -> Result<(), DocError> {
|
||||
let mut write_guard = self.document.write();
|
||||
let _ = write_guard.apply_changeset(data.clone())?;
|
||||
let _ = write_guard.apply_delta(data.clone())?;
|
||||
|
||||
match self.ws_sender.send_data(data) {
|
||||
Ok(_) => {},
|
||||
@ -61,11 +74,11 @@ impl OpenedDoc {
|
||||
}
|
||||
|
||||
// Opti: strategy to save the document
|
||||
let save = SaveDocParams {
|
||||
let save = UpdateDocParams {
|
||||
id: self.id.0.clone(),
|
||||
data: write_guard.to_bytes(),
|
||||
doc_data: write_guard.to_bytes(),
|
||||
};
|
||||
let _ = self.persistence.save(save, pool)?;
|
||||
// let _ = self.persistence.save(save, pool)?;
|
||||
|
||||
Ok(())
|
||||
}
|
@ -1,94 +0,0 @@
|
||||
use crate::{
|
||||
errors::DocError,
|
||||
services::{
|
||||
open_doc::{DocId, OpenedDoc, OpenedDocPersistence},
|
||||
ws::WsManager,
|
||||
},
|
||||
};
|
||||
use bytes::Bytes;
|
||||
use dashmap::DashMap;
|
||||
use flowy_database::ConnectionPool;
|
||||
use flowy_ot::{core::Delta, errors::OTError};
|
||||
use parking_lot::RwLock;
|
||||
use std::{convert::TryInto, fmt::Debug, sync::Arc};
|
||||
|
||||
pub(crate) struct OpenedDocManager {
|
||||
doc_map: DashMap<DocId, Arc<OpenedDoc>>,
|
||||
ws_manager: Arc<RwLock<WsManager>>,
|
||||
persistence: Arc<dyn OpenedDocPersistence>,
|
||||
}
|
||||
|
||||
impl OpenedDocManager {
|
||||
pub(crate) fn new(ws_manager: Arc<RwLock<WsManager>>, persistence: Arc<dyn OpenedDocPersistence>) -> Self {
|
||||
Self {
|
||||
doc_map: DashMap::new(),
|
||||
ws_manager,
|
||||
persistence,
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(self, data), err)]
|
||||
pub(crate) fn open<T, D>(&self, id: T, data: D) -> Result<(), DocError>
|
||||
where
|
||||
T: Into<DocId> + Debug,
|
||||
D: TryInto<Delta, Error = OTError>,
|
||||
{
|
||||
let doc = Arc::new(OpenedDoc::new(
|
||||
id.into(),
|
||||
data.try_into()?,
|
||||
self.persistence.clone(),
|
||||
self.ws_manager.read().sender.clone(),
|
||||
));
|
||||
self.ws_manager.write().register_handler(doc.id.as_ref(), doc.clone());
|
||||
self.doc_map.insert(doc.id.clone(), doc.clone());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn is_opened<T>(&self, id: T) -> bool
|
||||
where
|
||||
T: Into<DocId>,
|
||||
{
|
||||
let doc_id = id.into();
|
||||
self.doc_map.get(&doc_id).is_some()
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(self, changeset, pool), err)]
|
||||
pub(crate) async fn apply_changeset<T>(&self, id: T, changeset: Bytes, pool: Arc<ConnectionPool>) -> Result<(), DocError>
|
||||
where
|
||||
T: Into<DocId> + Debug,
|
||||
{
|
||||
let id = id.into();
|
||||
match self.doc_map.get(&id) {
|
||||
None => Err(doc_not_found()),
|
||||
Some(doc) => {
|
||||
let _ = doc.apply_delta(changeset, pool)?;
|
||||
Ok(())
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn read_doc<T>(&self, id: T) -> Result<Vec<u8>, DocError>
|
||||
where
|
||||
T: Into<DocId> + Clone,
|
||||
{
|
||||
if !self.is_opened(id.clone()) {
|
||||
return Err(doc_not_found());
|
||||
}
|
||||
|
||||
let doc_id = id.into();
|
||||
let doc = self.doc_map.get(&doc_id).unwrap();
|
||||
Ok(doc.data())
|
||||
}
|
||||
|
||||
pub(crate) fn close<T>(&self, id: T) -> Result<(), DocError>
|
||||
where
|
||||
T: Into<DocId>,
|
||||
{
|
||||
let doc_id = id.into();
|
||||
self.doc_map.remove(&doc_id);
|
||||
self.ws_manager.write().remove_handler(doc_id.as_ref());
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn doc_not_found() -> DocError { DocError::not_found().context("Doc is close or you should call open first") }
|
@ -1,5 +0,0 @@
|
||||
mod manager;
|
||||
mod open_doc;
|
||||
|
||||
pub(crate) use manager::*;
|
||||
pub use open_doc::*;
|
@ -5,7 +5,7 @@ mod server_api_mock;
|
||||
pub use server_api::*;
|
||||
// TODO: ignore mock files in production
|
||||
use crate::{
|
||||
entities::doc::{CreateDocParams, Doc, QueryDocParams, SaveDocParams},
|
||||
entities::doc::{CreateDocParams, Doc, QueryDocParams, UpdateDocParams},
|
||||
errors::DocError,
|
||||
};
|
||||
use flowy_infra::future::ResultFuture;
|
||||
@ -18,7 +18,7 @@ pub trait DocumentServerAPI {
|
||||
|
||||
fn read_doc(&self, token: &str, params: QueryDocParams) -> ResultFuture<Option<Doc>, DocError>;
|
||||
|
||||
fn update_doc(&self, token: &str, params: SaveDocParams) -> ResultFuture<(), DocError>;
|
||||
fn update_doc(&self, token: &str, params: UpdateDocParams) -> ResultFuture<(), DocError>;
|
||||
|
||||
fn delete_doc(&self, token: &str, params: QueryDocParams) -> ResultFuture<(), DocError>;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::{
|
||||
entities::doc::{CreateDocParams, Doc, QueryDocParams, SaveDocParams},
|
||||
entities::doc::{CreateDocParams, Doc, QueryDocParams, UpdateDocParams},
|
||||
errors::DocError,
|
||||
services::server::DocumentServerAPI,
|
||||
};
|
||||
@ -19,7 +19,7 @@ impl DocumentServerAPI for DocServer {
|
||||
ResultFuture::new(async move { read_doc_request(&token, params, DOC_URL.as_ref()).await })
|
||||
}
|
||||
|
||||
fn update_doc(&self, token: &str, params: SaveDocParams) -> ResultFuture<(), DocError> {
|
||||
fn update_doc(&self, token: &str, params: UpdateDocParams) -> ResultFuture<(), DocError> {
|
||||
let token = token.to_owned();
|
||||
ResultFuture::new(async move { update_doc_request(&token, params, DOC_URL.as_ref()).await })
|
||||
}
|
||||
@ -53,7 +53,7 @@ pub async fn read_doc_request(token: &str, params: QueryDocParams, url: &str) ->
|
||||
Ok(doc)
|
||||
}
|
||||
|
||||
pub async fn update_doc_request(token: &str, params: SaveDocParams, url: &str) -> Result<(), DocError> {
|
||||
pub async fn update_doc_request(token: &str, params: UpdateDocParams, url: &str) -> Result<(), DocError> {
|
||||
let _ = request_builder()
|
||||
.patch(&url.to_owned())
|
||||
.header(HEADER_TOKEN, token)
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::{
|
||||
entities::doc::{CreateDocParams, Doc, QueryDocParams, SaveDocParams},
|
||||
entities::doc::{CreateDocParams, Doc, QueryDocParams, UpdateDocParams},
|
||||
errors::DocError,
|
||||
services::server::DocumentServerAPI,
|
||||
};
|
||||
@ -13,7 +13,7 @@ impl DocumentServerAPI for DocServerMock {
|
||||
ResultFuture::new(async { Ok(None) })
|
||||
}
|
||||
|
||||
fn update_doc(&self, _token: &str, _params: SaveDocParams) -> ResultFuture<(), DocError> { ResultFuture::new(async { Ok(()) }) }
|
||||
fn update_doc(&self, _token: &str, _params: UpdateDocParams) -> ResultFuture<(), DocError> { ResultFuture::new(async { Ok(()) }) }
|
||||
|
||||
fn delete_doc(&self, _token: &str, _params: QueryDocParams) -> ResultFuture<(), DocError> { ResultFuture::new(async { Ok(()) }) }
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::entities::doc::{Doc, SaveDocParams};
|
||||
use crate::entities::doc::{Doc, UpdateDocParams};
|
||||
use flowy_database::schema::doc_table;
|
||||
|
||||
#[derive(PartialEq, Clone, Debug, Queryable, Identifiable, Insertable, Associations)]
|
||||
@ -6,7 +6,7 @@ use flowy_database::schema::doc_table;
|
||||
pub(crate) struct DocTable {
|
||||
pub id: String,
|
||||
pub data: Vec<u8>,
|
||||
pub version: i64,
|
||||
pub revision: i64,
|
||||
}
|
||||
|
||||
impl DocTable {
|
||||
@ -14,7 +14,7 @@ impl DocTable {
|
||||
Self {
|
||||
id: doc.id,
|
||||
data: doc.data,
|
||||
version: 0,
|
||||
revision: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -27,10 +27,10 @@ pub(crate) struct DocTableChangeset {
|
||||
}
|
||||
|
||||
impl DocTableChangeset {
|
||||
pub(crate) fn new(params: SaveDocParams) -> Self {
|
||||
pub(crate) fn new(params: UpdateDocParams) -> Self {
|
||||
Self {
|
||||
id: params.id,
|
||||
data: params.data,
|
||||
data: params.doc_data,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -40,6 +40,7 @@ impl std::convert::Into<Doc> for DocTable {
|
||||
Doc {
|
||||
id: self.id,
|
||||
data: self.data,
|
||||
revision: self.revision,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,6 @@
|
||||
pub mod helper;
|
||||
|
||||
use crate::helper::{TestOp::*, *};
|
||||
use flowy_ot::{
|
||||
client::{FlowyDoc, PlainDoc},
|
||||
core::{Interval, NEW_LINE, WHITESPACE},
|
||||
};
|
||||
use crate::editor::{TestBuilder, TestOp::*};
|
||||
use flowy_document::services::doc::{FlowyDoc, PlainDoc};
|
||||
use flowy_ot::core::{Interval, NEW_LINE, WHITESPACE};
|
||||
|
||||
#[test]
|
||||
fn attributes_bold_added() {
|
@ -1 +0,0 @@
|
||||
|
@ -1,8 +1,11 @@
|
||||
mod attribute_test;
|
||||
mod op_test;
|
||||
mod serde_test;
|
||||
mod undo_redo_test;
|
||||
|
||||
use derive_more::Display;
|
||||
use flowy_ot::{
|
||||
client::{CustomDocument, Document},
|
||||
core::*,
|
||||
};
|
||||
use flowy_document::services::doc::{CustomDocument, Document};
|
||||
use flowy_ot::core::*;
|
||||
use rand::{prelude::*, Rng as WrappedRng};
|
||||
use std::{sync::Once, time::Duration};
|
||||
|
@ -1,9 +1,7 @@
|
||||
pub mod helper;
|
||||
|
||||
use crate::helper::TestOp::*;
|
||||
use crate::editor::{Rng, TestBuilder, TestOp::*};
|
||||
use bytecount::num_chars;
|
||||
use flowy_ot::{client::PlainDoc, core::*};
|
||||
use helper::*;
|
||||
use flowy_document::services::doc::PlainDoc;
|
||||
use flowy_ot::core::*;
|
||||
|
||||
#[test]
|
||||
fn attributes_insert_text() {
|
@ -1,7 +1,5 @@
|
||||
use flowy_ot::{
|
||||
client::{Document, PlainDoc},
|
||||
core::*,
|
||||
};
|
||||
use flowy_document::services::doc::{Document, PlainDoc};
|
||||
use flowy_ot::core::*;
|
||||
|
||||
#[test]
|
||||
fn operation_insert_serialize_test() {
|
@ -1,10 +1,6 @@
|
||||
pub mod helper;
|
||||
|
||||
use crate::helper::{TestOp::*, *};
|
||||
use flowy_ot::{
|
||||
client::{FlowyDoc, PlainDoc, RECORD_THRESHOLD},
|
||||
core::{Interval, NEW_LINE, WHITESPACE},
|
||||
};
|
||||
use crate::editor::{TestBuilder, TestOp::*};
|
||||
use flowy_document::services::doc::{FlowyDoc, PlainDoc, RECORD_THRESHOLD};
|
||||
use flowy_ot::core::{Interval, NEW_LINE, WHITESPACE};
|
||||
|
||||
#[test]
|
||||
fn history_insert_undo() {
|
1
rust-lib/flowy-document/tests/main.rs
Normal file
1
rust-lib/flowy-document/tests/main.rs
Normal file
@ -0,0 +1 @@
|
||||
mod editor;
|
@ -11,17 +11,10 @@ serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = {version = "1.0"}
|
||||
derive_more = {version = "0.99", features = ["display"]}
|
||||
log = "0.4"
|
||||
color-eyre = { version = "0.5", default-features = false }
|
||||
chrono = "0.4.19"
|
||||
lazy_static = "1.4.0"
|
||||
url = "2.2"
|
||||
strum = "0.21"
|
||||
strum_macros = "0.21"
|
||||
bytes = "1.0"
|
||||
|
||||
|
||||
[dev-dependencies]
|
||||
criterion = "0.3"
|
||||
rand = "0.7.3"
|
||||
env_logger = "0.8.2"
|
||||
|
||||
|
@ -1,4 +1,2 @@
|
||||
pub mod client;
|
||||
pub mod core;
|
||||
pub mod errors;
|
||||
pub mod server;
|
||||
|
@ -1 +0,0 @@
|
||||
|
@ -3,7 +3,7 @@ use crate::{
|
||||
errors::WorkspaceError,
|
||||
};
|
||||
use flowy_derive::ProtoBuf;
|
||||
use flowy_document::entities::doc::{ApplyChangesetParams, SaveDocParams};
|
||||
use flowy_document::entities::doc::{DocChangeset, UpdateDocParams};
|
||||
use std::convert::TryInto;
|
||||
|
||||
#[derive(Default, ProtoBuf)]
|
||||
@ -109,16 +109,19 @@ pub struct SaveViewDataRequest {
|
||||
pub data: Vec<u8>,
|
||||
}
|
||||
|
||||
impl TryInto<SaveDocParams> for SaveViewDataRequest {
|
||||
impl TryInto<UpdateDocParams> for SaveViewDataRequest {
|
||||
type Error = WorkspaceError;
|
||||
|
||||
fn try_into(self) -> Result<SaveDocParams, Self::Error> {
|
||||
fn try_into(self) -> Result<UpdateDocParams, Self::Error> {
|
||||
let view_id = ViewId::parse(self.view_id).map_err(|e| WorkspaceError::view_id().context(e))?.0;
|
||||
|
||||
// Opti: Vec<u8> -> Delta -> Vec<u8>
|
||||
let data = DeltaData::parse(self.data).map_err(|e| WorkspaceError::view_data().context(e))?.0;
|
||||
|
||||
Ok(SaveDocParams { id: view_id, data })
|
||||
Ok(UpdateDocParams {
|
||||
id: view_id,
|
||||
doc_data: data,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -131,15 +134,15 @@ pub struct ApplyChangesetRequest {
|
||||
pub data: Vec<u8>,
|
||||
}
|
||||
|
||||
impl TryInto<ApplyChangesetParams> for ApplyChangesetRequest {
|
||||
impl TryInto<DocChangeset> for ApplyChangesetRequest {
|
||||
type Error = WorkspaceError;
|
||||
|
||||
fn try_into(self) -> Result<ApplyChangesetParams, Self::Error> {
|
||||
fn try_into(self) -> Result<DocChangeset, Self::Error> {
|
||||
let view_id = ViewId::parse(self.view_id).map_err(|e| WorkspaceError::view_id().context(e))?.0;
|
||||
|
||||
// Opti: Vec<u8> -> Delta -> Vec<u8>
|
||||
let data = DeltaData::parse(self.data).map_err(|e| WorkspaceError::view_data().context(e))?.0;
|
||||
|
||||
Ok(ApplyChangesetParams { id: view_id, data })
|
||||
Ok(DocChangeset { id: view_id, data })
|
||||
}
|
||||
}
|
||||
|
@ -49,6 +49,6 @@ pub enum WorkspaceEvent {
|
||||
#[event(input = "OpenViewRequest", output = "Doc")]
|
||||
OpenView = 205,
|
||||
|
||||
#[event(input = "ApplyChangesetRequest", output = "Doc")]
|
||||
#[event(input = "DocChangeset", output = "Doc")]
|
||||
ApplyChangeset = 206,
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ use crate::{
|
||||
services::ViewController,
|
||||
};
|
||||
use flowy_dispatch::prelude::{data_result, Data, DataResult, Unit};
|
||||
use flowy_document::entities::doc::{ApplyChangesetParams, Doc, QueryDocParams};
|
||||
use flowy_document::entities::doc::{Doc, DocChangeset, QueryDocParams};
|
||||
use std::{convert::TryInto, sync::Arc};
|
||||
|
||||
#[tracing::instrument(skip(data, controller), err)]
|
||||
@ -60,7 +60,7 @@ pub(crate) async fn apply_changeset_handler(
|
||||
data: Data<ApplyChangesetRequest>,
|
||||
controller: Unit<Arc<ViewController>>,
|
||||
) -> DataResult<Doc, WorkspaceError> {
|
||||
let params: ApplyChangesetParams = data.into_inner().try_into()?;
|
||||
let params: DocChangeset = data.into_inner().try_into()?;
|
||||
let doc = controller.apply_changeset(params).await?;
|
||||
data_result(doc)
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ use crate::{
|
||||
};
|
||||
use flowy_database::SqliteConnection;
|
||||
use flowy_document::{
|
||||
entities::doc::{ApplyChangesetParams, CreateDocParams, Doc, QueryDocParams},
|
||||
entities::doc::{CreateDocParams, Doc, DocChangeset, QueryDocParams},
|
||||
module::FlowyDocument,
|
||||
};
|
||||
use std::sync::Arc;
|
||||
@ -125,7 +125,7 @@ impl ViewController {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) async fn apply_changeset(&self, params: ApplyChangesetParams) -> Result<Doc, WorkspaceError> {
|
||||
pub(crate) async fn apply_changeset(&self, params: DocChangeset) -> Result<Doc, WorkspaceError> {
|
||||
let pool = self.database.db_pool()?;
|
||||
let doc = self.document.apply_changeset(params, pool).await?;
|
||||
Ok(doc)
|
||||
|
Loading…
Reference in New Issue
Block a user