From f8ec4b3e2403a1ebf246c62f24108f84eb5e2059 Mon Sep 17 00:00:00 2001 From: appflowy Date: Mon, 13 Jun 2022 20:59:46 +0800 Subject: [PATCH] refactor: replace object with object's revision entity --- .../workspace/application/view/view_ext.dart | 5 +- .../flowy-folder-data-model/view.pb.dart | 468 ++++- .../flowy-folder-data-model/view.pbjson.dart | 77 +- .../rust-lib/flowy-folder/src/event_map.rs | 27 +- frontend/rust-lib/flowy-folder/src/manager.rs | 13 +- .../src/services/app/controller.rs | 39 +- .../src/services/app/event_handler.rs | 16 +- .../src/services/persistence/migration.rs | 19 +- .../src/services/persistence/mod.rs | 30 +- .../services/persistence/version_1/app_sql.rs | 28 +- .../persistence/version_1/trash_sql.rs | 38 +- .../services/persistence/version_1/v1_impl.rs | 87 +- .../persistence/version_1/view_sql.rs | 40 +- .../persistence/version_1/workspace_sql.rs | 32 +- .../services/persistence/version_2/v2_impl.rs | 68 +- .../src/services/trash/controller.rs | 58 +- .../src/services/view/controller.rs | 120 +- .../src/services/view/event_handler.rs | 25 +- .../src/services/workspace/controller.rs | 42 +- .../src/services/workspace/event_handler.rs | 59 +- .../tests/workspace/folder_test.rs | 11 +- .../flowy-folder/tests/workspace/script.rs | 34 +- .../flowy-net/src/http_server/folder.rs | 180 +- .../flowy-net/src/local_server/server.rs | 53 +- frontend/rust-lib/flowy-test/src/helper.rs | 5 +- .../flowy-user/src/services/database.rs | 68 +- .../src/entities/app.rs | 2 +- .../src/entities/trash.rs | 28 +- .../src/entities/view.rs | 83 +- .../src/protobuf/model/view.rs | 1597 ++++++++++++++--- .../src/protobuf/proto/view.proto | 33 +- .../src/revision/app.rs | 35 +- .../src/revision/trash.rs | 31 +- .../src/revision/view.rs | 109 +- .../src/revision/workspace.rs | 15 +- .../src/user_default.rs | 32 +- .../flowy-sync/src/client_folder/builder.rs | 12 +- .../src/client_folder/folder_pad.rs | 128 +- .../src/client_grid/grid_meta_pad.rs | 2 +- 39 files changed, 2646 insertions(+), 1103 deletions(-) diff --git a/frontend/app_flowy/lib/workspace/application/view/view_ext.dart b/frontend/app_flowy/lib/workspace/application/view/view_ext.dart index 78230e1311..1fb36125e9 100644 --- a/frontend/app_flowy/lib/workspace/application/view/view_ext.dart +++ b/frontend/app_flowy/lib/workspace/application/view/view_ext.dart @@ -34,10 +34,7 @@ extension FlowyPluginExtension on FlowyPlugin { extension ViewExtension on View { Widget renderThumbnail({Color? iconColor}) { - String thumbnail = this.thumbnail; - if (thumbnail.isEmpty) { - thumbnail = "file_icon"; - } + String thumbnail = "file_icon"; final Widget widget = svgWidget(thumbnail, color: iconColor); return widget; diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pb.dart index 781a2fcdca..42d99339b7 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pb.dart @@ -19,15 +19,10 @@ class View extends $pb.GeneratedMessage { ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'belongToId') ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name') - ..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'desc') - ..e(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'dataType', $pb.PbFieldType.OE, defaultOrMaker: ViewDataType.TextBlock, valueOf: ViewDataType.valueOf, enumValues: ViewDataType.values) - ..aInt64(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'version') - ..aOM(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'belongings', subBuilder: RepeatedView.create) - ..aInt64(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'modifiedTime') - ..aInt64(9, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'createTime') - ..aOS(10, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'extData') - ..aOS(11, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'thumbnail') - ..a<$core.int>(12, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'pluginType', $pb.PbFieldType.O3) + ..e(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'dataType', $pb.PbFieldType.OE, defaultOrMaker: ViewDataType.TextBlock, valueOf: ViewDataType.valueOf, enumValues: ViewDataType.values) + ..aInt64(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'modifiedTime') + ..aInt64(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'createTime') + ..a<$core.int>(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'pluginType', $pb.PbFieldType.O3) ..hasRequiredFields = false ; @@ -36,14 +31,9 @@ class View extends $pb.GeneratedMessage { $core.String? id, $core.String? belongToId, $core.String? name, - $core.String? desc, ViewDataType? dataType, - $fixnum.Int64? version, - RepeatedView? belongings, $fixnum.Int64? modifiedTime, $fixnum.Int64? createTime, - $core.String? extData, - $core.String? thumbnail, $core.int? pluginType, }) { final _result = create(); @@ -56,30 +46,15 @@ class View extends $pb.GeneratedMessage { if (name != null) { _result.name = name; } - if (desc != null) { - _result.desc = desc; - } if (dataType != null) { _result.dataType = dataType; } - if (version != null) { - _result.version = version; - } - if (belongings != null) { - _result.belongings = belongings; - } if (modifiedTime != null) { _result.modifiedTime = modifiedTime; } if (createTime != null) { _result.createTime = createTime; } - if (extData != null) { - _result.extData = extData; - } - if (thumbnail != null) { - _result.thumbnail = thumbnail; - } if (pluginType != null) { _result.pluginType = pluginType; } @@ -133,6 +108,137 @@ class View extends $pb.GeneratedMessage { @$pb.TagNumber(3) void clearName() => clearField(3); + @$pb.TagNumber(4) + ViewDataType get dataType => $_getN(3); + @$pb.TagNumber(4) + set dataType(ViewDataType v) { setField(4, v); } + @$pb.TagNumber(4) + $core.bool hasDataType() => $_has(3); + @$pb.TagNumber(4) + void clearDataType() => clearField(4); + + @$pb.TagNumber(5) + $fixnum.Int64 get modifiedTime => $_getI64(4); + @$pb.TagNumber(5) + set modifiedTime($fixnum.Int64 v) { $_setInt64(4, v); } + @$pb.TagNumber(5) + $core.bool hasModifiedTime() => $_has(4); + @$pb.TagNumber(5) + void clearModifiedTime() => clearField(5); + + @$pb.TagNumber(6) + $fixnum.Int64 get createTime => $_getI64(5); + @$pb.TagNumber(6) + set createTime($fixnum.Int64 v) { $_setInt64(5, v); } + @$pb.TagNumber(6) + $core.bool hasCreateTime() => $_has(5); + @$pb.TagNumber(6) + void clearCreateTime() => clearField(6); + + @$pb.TagNumber(7) + $core.int get pluginType => $_getIZ(6); + @$pb.TagNumber(7) + set pluginType($core.int v) { $_setSignedInt32(6, v); } + @$pb.TagNumber(7) + $core.bool hasPluginType() => $_has(6); + @$pb.TagNumber(7) + void clearPluginType() => clearField(7); +} + +class ViewInfo extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'ViewInfo', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'belongToId') + ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name') + ..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'desc') + ..e(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'dataType', $pb.PbFieldType.OE, defaultOrMaker: ViewDataType.TextBlock, valueOf: ViewDataType.valueOf, enumValues: ViewDataType.values) + ..aOM(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'belongings', subBuilder: RepeatedView.create) + ..aOM(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'extData', subBuilder: ViewExtData.create) + ..hasRequiredFields = false + ; + + ViewInfo._() : super(); + factory ViewInfo({ + $core.String? id, + $core.String? belongToId, + $core.String? name, + $core.String? desc, + ViewDataType? dataType, + RepeatedView? belongings, + ViewExtData? extData, + }) { + final _result = create(); + if (id != null) { + _result.id = id; + } + if (belongToId != null) { + _result.belongToId = belongToId; + } + if (name != null) { + _result.name = name; + } + if (desc != null) { + _result.desc = desc; + } + if (dataType != null) { + _result.dataType = dataType; + } + if (belongings != null) { + _result.belongings = belongings; + } + if (extData != null) { + _result.extData = extData; + } + return _result; + } + factory ViewInfo.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory ViewInfo.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') + ViewInfo clone() => ViewInfo()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + ViewInfo copyWith(void Function(ViewInfo) updates) => super.copyWith((message) => updates(message as ViewInfo)) as ViewInfo; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static ViewInfo create() => ViewInfo._(); + ViewInfo createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static ViewInfo getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static ViewInfo? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get id => $_getSZ(0); + @$pb.TagNumber(1) + set id($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasId() => $_has(0); + @$pb.TagNumber(1) + void clearId() => clearField(1); + + @$pb.TagNumber(2) + $core.String get belongToId => $_getSZ(1); + @$pb.TagNumber(2) + set belongToId($core.String v) { $_setString(1, v); } + @$pb.TagNumber(2) + $core.bool hasBelongToId() => $_has(1); + @$pb.TagNumber(2) + void clearBelongToId() => clearField(2); + + @$pb.TagNumber(3) + $core.String get name => $_getSZ(2); + @$pb.TagNumber(3) + set name($core.String v) { $_setString(2, v); } + @$pb.TagNumber(3) + $core.bool hasName() => $_has(2); + @$pb.TagNumber(3) + void clearName() => clearField(3); + @$pb.TagNumber(4) $core.String get desc => $_getSZ(3); @$pb.TagNumber(4) @@ -152,69 +258,275 @@ class View extends $pb.GeneratedMessage { void clearDataType() => clearField(5); @$pb.TagNumber(6) - $fixnum.Int64 get version => $_getI64(5); + RepeatedView get belongings => $_getN(5); @$pb.TagNumber(6) - set version($fixnum.Int64 v) { $_setInt64(5, v); } + set belongings(RepeatedView v) { setField(6, v); } @$pb.TagNumber(6) - $core.bool hasVersion() => $_has(5); + $core.bool hasBelongings() => $_has(5); @$pb.TagNumber(6) - void clearVersion() => clearField(6); + void clearBelongings() => clearField(6); + @$pb.TagNumber(6) + RepeatedView ensureBelongings() => $_ensure(5); @$pb.TagNumber(7) - RepeatedView get belongings => $_getN(6); + ViewExtData get extData => $_getN(6); @$pb.TagNumber(7) - set belongings(RepeatedView v) { setField(7, v); } + set extData(ViewExtData v) { setField(7, v); } @$pb.TagNumber(7) - $core.bool hasBelongings() => $_has(6); + $core.bool hasExtData() => $_has(6); @$pb.TagNumber(7) - void clearBelongings() => clearField(7); + void clearExtData() => clearField(7); @$pb.TagNumber(7) - RepeatedView ensureBelongings() => $_ensure(6); + ViewExtData ensureExtData() => $_ensure(6); +} - @$pb.TagNumber(8) - $fixnum.Int64 get modifiedTime => $_getI64(7); - @$pb.TagNumber(8) - set modifiedTime($fixnum.Int64 v) { $_setInt64(7, v); } - @$pb.TagNumber(8) - $core.bool hasModifiedTime() => $_has(7); - @$pb.TagNumber(8) - void clearModifiedTime() => clearField(8); +class ViewExtData extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'ViewExtData', createEmptyInstance: create) + ..aOM(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'filter', subBuilder: ViewFilter.create) + ..aOM(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'group', subBuilder: ViewGroup.create) + ..aOM(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'sort', subBuilder: ViewSort.create) + ..hasRequiredFields = false + ; - @$pb.TagNumber(9) - $fixnum.Int64 get createTime => $_getI64(8); - @$pb.TagNumber(9) - set createTime($fixnum.Int64 v) { $_setInt64(8, v); } - @$pb.TagNumber(9) - $core.bool hasCreateTime() => $_has(8); - @$pb.TagNumber(9) - void clearCreateTime() => clearField(9); + ViewExtData._() : super(); + factory ViewExtData({ + ViewFilter? filter, + ViewGroup? group, + ViewSort? sort, + }) { + final _result = create(); + if (filter != null) { + _result.filter = filter; + } + if (group != null) { + _result.group = group; + } + if (sort != null) { + _result.sort = sort; + } + return _result; + } + factory ViewExtData.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory ViewExtData.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') + ViewExtData clone() => ViewExtData()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + ViewExtData copyWith(void Function(ViewExtData) updates) => super.copyWith((message) => updates(message as ViewExtData)) as ViewExtData; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static ViewExtData create() => ViewExtData._(); + ViewExtData createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static ViewExtData getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static ViewExtData? _defaultInstance; - @$pb.TagNumber(10) - $core.String get extData => $_getSZ(9); - @$pb.TagNumber(10) - set extData($core.String v) { $_setString(9, v); } - @$pb.TagNumber(10) - $core.bool hasExtData() => $_has(9); - @$pb.TagNumber(10) - void clearExtData() => clearField(10); + @$pb.TagNumber(1) + ViewFilter get filter => $_getN(0); + @$pb.TagNumber(1) + set filter(ViewFilter v) { setField(1, v); } + @$pb.TagNumber(1) + $core.bool hasFilter() => $_has(0); + @$pb.TagNumber(1) + void clearFilter() => clearField(1); + @$pb.TagNumber(1) + ViewFilter ensureFilter() => $_ensure(0); - @$pb.TagNumber(11) - $core.String get thumbnail => $_getSZ(10); - @$pb.TagNumber(11) - set thumbnail($core.String v) { $_setString(10, v); } - @$pb.TagNumber(11) - $core.bool hasThumbnail() => $_has(10); - @$pb.TagNumber(11) - void clearThumbnail() => clearField(11); + @$pb.TagNumber(2) + ViewGroup get group => $_getN(1); + @$pb.TagNumber(2) + set group(ViewGroup v) { setField(2, v); } + @$pb.TagNumber(2) + $core.bool hasGroup() => $_has(1); + @$pb.TagNumber(2) + void clearGroup() => clearField(2); + @$pb.TagNumber(2) + ViewGroup ensureGroup() => $_ensure(1); - @$pb.TagNumber(12) - $core.int get pluginType => $_getIZ(11); - @$pb.TagNumber(12) - set pluginType($core.int v) { $_setSignedInt32(11, v); } - @$pb.TagNumber(12) - $core.bool hasPluginType() => $_has(11); - @$pb.TagNumber(12) - void clearPluginType() => clearField(12); + @$pb.TagNumber(3) + ViewSort get sort => $_getN(2); + @$pb.TagNumber(3) + set sort(ViewSort v) { setField(3, v); } + @$pb.TagNumber(3) + $core.bool hasSort() => $_has(2); + @$pb.TagNumber(3) + void clearSort() => clearField(3); + @$pb.TagNumber(3) + ViewSort ensureSort() => $_ensure(2); +} + +class ViewFilter extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'ViewFilter', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') + ..hasRequiredFields = false + ; + + ViewFilter._() : super(); + factory ViewFilter({ + $core.String? fieldId, + }) { + final _result = create(); + if (fieldId != null) { + _result.fieldId = fieldId; + } + return _result; + } + factory ViewFilter.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory ViewFilter.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') + ViewFilter clone() => ViewFilter()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + ViewFilter copyWith(void Function(ViewFilter) updates) => super.copyWith((message) => updates(message as ViewFilter)) as ViewFilter; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static ViewFilter create() => ViewFilter._(); + ViewFilter createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static ViewFilter getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static ViewFilter? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get fieldId => $_getSZ(0); + @$pb.TagNumber(1) + set fieldId($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasFieldId() => $_has(0); + @$pb.TagNumber(1) + void clearFieldId() => clearField(1); +} + +enum ViewGroup_OneOfSubGroupFieldId { + subGroupFieldId, + notSet +} + +class ViewGroup extends $pb.GeneratedMessage { + static const $core.Map<$core.int, ViewGroup_OneOfSubGroupFieldId> _ViewGroup_OneOfSubGroupFieldIdByTag = { + 2 : ViewGroup_OneOfSubGroupFieldId.subGroupFieldId, + 0 : ViewGroup_OneOfSubGroupFieldId.notSet + }; + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'ViewGroup', createEmptyInstance: create) + ..oo(0, [2]) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'groupFieldId') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'subGroupFieldId') + ..hasRequiredFields = false + ; + + ViewGroup._() : super(); + factory ViewGroup({ + $core.String? groupFieldId, + $core.String? subGroupFieldId, + }) { + final _result = create(); + if (groupFieldId != null) { + _result.groupFieldId = groupFieldId; + } + if (subGroupFieldId != null) { + _result.subGroupFieldId = subGroupFieldId; + } + return _result; + } + factory ViewGroup.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory ViewGroup.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') + ViewGroup clone() => ViewGroup()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + ViewGroup copyWith(void Function(ViewGroup) updates) => super.copyWith((message) => updates(message as ViewGroup)) as ViewGroup; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static ViewGroup create() => ViewGroup._(); + ViewGroup createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static ViewGroup getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static ViewGroup? _defaultInstance; + + ViewGroup_OneOfSubGroupFieldId whichOneOfSubGroupFieldId() => _ViewGroup_OneOfSubGroupFieldIdByTag[$_whichOneof(0)]!; + void clearOneOfSubGroupFieldId() => clearField($_whichOneof(0)); + + @$pb.TagNumber(1) + $core.String get groupFieldId => $_getSZ(0); + @$pb.TagNumber(1) + set groupFieldId($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasGroupFieldId() => $_has(0); + @$pb.TagNumber(1) + void clearGroupFieldId() => clearField(1); + + @$pb.TagNumber(2) + $core.String get subGroupFieldId => $_getSZ(1); + @$pb.TagNumber(2) + set subGroupFieldId($core.String v) { $_setString(1, v); } + @$pb.TagNumber(2) + $core.bool hasSubGroupFieldId() => $_has(1); + @$pb.TagNumber(2) + void clearSubGroupFieldId() => clearField(2); +} + +class ViewSort extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'ViewSort', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') + ..hasRequiredFields = false + ; + + ViewSort._() : super(); + factory ViewSort({ + $core.String? fieldId, + }) { + final _result = create(); + if (fieldId != null) { + _result.fieldId = fieldId; + } + return _result; + } + factory ViewSort.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory ViewSort.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') + ViewSort clone() => ViewSort()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + ViewSort copyWith(void Function(ViewSort) updates) => super.copyWith((message) => updates(message as ViewSort)) as ViewSort; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static ViewSort create() => ViewSort._(); + ViewSort createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static ViewSort getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static ViewSort? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get fieldId => $_getSZ(0); + @$pb.TagNumber(1) + set fieldId($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasFieldId() => $_has(0); + @$pb.TagNumber(1) + void clearFieldId() => clearField(1); } class RepeatedView extends $pb.GeneratedMessage { diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pbjson.dart index fd2504389f..b83147e64e 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pbjson.dart @@ -37,20 +37,77 @@ const View$json = const { const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, const {'1': 'belong_to_id', '3': 2, '4': 1, '5': 9, '10': 'belongToId'}, const {'1': 'name', '3': 3, '4': 1, '5': 9, '10': 'name'}, - const {'1': 'desc', '3': 4, '4': 1, '5': 9, '10': 'desc'}, - const {'1': 'data_type', '3': 5, '4': 1, '5': 14, '6': '.ViewDataType', '10': 'dataType'}, - const {'1': 'version', '3': 6, '4': 1, '5': 3, '10': 'version'}, - const {'1': 'belongings', '3': 7, '4': 1, '5': 11, '6': '.RepeatedView', '10': 'belongings'}, - const {'1': 'modified_time', '3': 8, '4': 1, '5': 3, '10': 'modifiedTime'}, - const {'1': 'create_time', '3': 9, '4': 1, '5': 3, '10': 'createTime'}, - const {'1': 'ext_data', '3': 10, '4': 1, '5': 9, '10': 'extData'}, - const {'1': 'thumbnail', '3': 11, '4': 1, '5': 9, '10': 'thumbnail'}, - const {'1': 'plugin_type', '3': 12, '4': 1, '5': 5, '10': 'pluginType'}, + const {'1': 'data_type', '3': 4, '4': 1, '5': 14, '6': '.ViewDataType', '10': 'dataType'}, + const {'1': 'modified_time', '3': 5, '4': 1, '5': 3, '10': 'modifiedTime'}, + const {'1': 'create_time', '3': 6, '4': 1, '5': 3, '10': 'createTime'}, + const {'1': 'plugin_type', '3': 7, '4': 1, '5': 5, '10': 'pluginType'}, ], }; /// Descriptor for `View`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List viewDescriptor = $convert.base64Decode('CgRWaWV3Eg4KAmlkGAEgASgJUgJpZBIgCgxiZWxvbmdfdG9faWQYAiABKAlSCmJlbG9uZ1RvSWQSEgoEbmFtZRgDIAEoCVIEbmFtZRISCgRkZXNjGAQgASgJUgRkZXNjEioKCWRhdGFfdHlwZRgFIAEoDjINLlZpZXdEYXRhVHlwZVIIZGF0YVR5cGUSGAoHdmVyc2lvbhgGIAEoA1IHdmVyc2lvbhItCgpiZWxvbmdpbmdzGAcgASgLMg0uUmVwZWF0ZWRWaWV3UgpiZWxvbmdpbmdzEiMKDW1vZGlmaWVkX3RpbWUYCCABKANSDG1vZGlmaWVkVGltZRIfCgtjcmVhdGVfdGltZRgJIAEoA1IKY3JlYXRlVGltZRIZCghleHRfZGF0YRgKIAEoCVIHZXh0RGF0YRIcCgl0aHVtYm5haWwYCyABKAlSCXRodW1ibmFpbBIfCgtwbHVnaW5fdHlwZRgMIAEoBVIKcGx1Z2luVHlwZQ=='); +final $typed_data.Uint8List viewDescriptor = $convert.base64Decode('CgRWaWV3Eg4KAmlkGAEgASgJUgJpZBIgCgxiZWxvbmdfdG9faWQYAiABKAlSCmJlbG9uZ1RvSWQSEgoEbmFtZRgDIAEoCVIEbmFtZRIqCglkYXRhX3R5cGUYBCABKA4yDS5WaWV3RGF0YVR5cGVSCGRhdGFUeXBlEiMKDW1vZGlmaWVkX3RpbWUYBSABKANSDG1vZGlmaWVkVGltZRIfCgtjcmVhdGVfdGltZRgGIAEoA1IKY3JlYXRlVGltZRIfCgtwbHVnaW5fdHlwZRgHIAEoBVIKcGx1Z2luVHlwZQ=='); +@$core.Deprecated('Use viewInfoDescriptor instead') +const ViewInfo$json = const { + '1': 'ViewInfo', + '2': const [ + const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, + const {'1': 'belong_to_id', '3': 2, '4': 1, '5': 9, '10': 'belongToId'}, + const {'1': 'name', '3': 3, '4': 1, '5': 9, '10': 'name'}, + const {'1': 'desc', '3': 4, '4': 1, '5': 9, '10': 'desc'}, + const {'1': 'data_type', '3': 5, '4': 1, '5': 14, '6': '.ViewDataType', '10': 'dataType'}, + const {'1': 'belongings', '3': 6, '4': 1, '5': 11, '6': '.RepeatedView', '10': 'belongings'}, + const {'1': 'ext_data', '3': 7, '4': 1, '5': 11, '6': '.ViewExtData', '10': 'extData'}, + ], +}; + +/// Descriptor for `ViewInfo`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List viewInfoDescriptor = $convert.base64Decode('CghWaWV3SW5mbxIOCgJpZBgBIAEoCVICaWQSIAoMYmVsb25nX3RvX2lkGAIgASgJUgpiZWxvbmdUb0lkEhIKBG5hbWUYAyABKAlSBG5hbWUSEgoEZGVzYxgEIAEoCVIEZGVzYxIqCglkYXRhX3R5cGUYBSABKA4yDS5WaWV3RGF0YVR5cGVSCGRhdGFUeXBlEi0KCmJlbG9uZ2luZ3MYBiABKAsyDS5SZXBlYXRlZFZpZXdSCmJlbG9uZ2luZ3MSJwoIZXh0X2RhdGEYByABKAsyDC5WaWV3RXh0RGF0YVIHZXh0RGF0YQ=='); +@$core.Deprecated('Use viewExtDataDescriptor instead') +const ViewExtData$json = const { + '1': 'ViewExtData', + '2': const [ + const {'1': 'filter', '3': 1, '4': 1, '5': 11, '6': '.ViewFilter', '10': 'filter'}, + const {'1': 'group', '3': 2, '4': 1, '5': 11, '6': '.ViewGroup', '10': 'group'}, + const {'1': 'sort', '3': 3, '4': 1, '5': 11, '6': '.ViewSort', '10': 'sort'}, + ], +}; + +/// Descriptor for `ViewExtData`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List viewExtDataDescriptor = $convert.base64Decode('CgtWaWV3RXh0RGF0YRIjCgZmaWx0ZXIYASABKAsyCy5WaWV3RmlsdGVyUgZmaWx0ZXISIAoFZ3JvdXAYAiABKAsyCi5WaWV3R3JvdXBSBWdyb3VwEh0KBHNvcnQYAyABKAsyCS5WaWV3U29ydFIEc29ydA=='); +@$core.Deprecated('Use viewFilterDescriptor instead') +const ViewFilter$json = const { + '1': 'ViewFilter', + '2': const [ + const {'1': 'field_id', '3': 1, '4': 1, '5': 9, '10': 'fieldId'}, + ], +}; + +/// Descriptor for `ViewFilter`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List viewFilterDescriptor = $convert.base64Decode('CgpWaWV3RmlsdGVyEhkKCGZpZWxkX2lkGAEgASgJUgdmaWVsZElk'); +@$core.Deprecated('Use viewGroupDescriptor instead') +const ViewGroup$json = const { + '1': 'ViewGroup', + '2': const [ + const {'1': 'group_field_id', '3': 1, '4': 1, '5': 9, '10': 'groupFieldId'}, + const {'1': 'sub_group_field_id', '3': 2, '4': 1, '5': 9, '9': 0, '10': 'subGroupFieldId'}, + ], + '8': const [ + const {'1': 'one_of_sub_group_field_id'}, + ], +}; + +/// Descriptor for `ViewGroup`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List viewGroupDescriptor = $convert.base64Decode('CglWaWV3R3JvdXASJAoOZ3JvdXBfZmllbGRfaWQYASABKAlSDGdyb3VwRmllbGRJZBItChJzdWJfZ3JvdXBfZmllbGRfaWQYAiABKAlIAFIPc3ViR3JvdXBGaWVsZElkQhsKGW9uZV9vZl9zdWJfZ3JvdXBfZmllbGRfaWQ='); +@$core.Deprecated('Use viewSortDescriptor instead') +const ViewSort$json = const { + '1': 'ViewSort', + '2': const [ + const {'1': 'field_id', '3': 1, '4': 1, '5': 9, '10': 'fieldId'}, + ], +}; + +/// Descriptor for `ViewSort`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List viewSortDescriptor = $convert.base64Decode('CghWaWV3U29ydBIZCghmaWVsZF9pZBgBIAEoCVIHZmllbGRJZA=='); @$core.Deprecated('Use repeatedViewDescriptor instead') const RepeatedView$json = const { '1': 'RepeatedView', diff --git a/frontend/rust-lib/flowy-folder/src/event_map.rs b/frontend/rust-lib/flowy-folder/src/event_map.rs index 22eb2c10d5..c9f1ebcd27 100644 --- a/frontend/rust-lib/flowy-folder/src/event_map.rs +++ b/frontend/rust-lib/flowy-folder/src/event_map.rs @@ -1,9 +1,9 @@ use crate::{ entities::{ - app::{App, AppId, CreateAppParams, UpdateAppParams}, - trash::{RepeatedTrash, RepeatedTrashId}, - view::{CreateViewParams, RepeatedViewId, UpdateViewParams, View, ViewId}, - workspace::{CreateWorkspaceParams, RepeatedWorkspace, UpdateWorkspaceParams, Workspace, WorkspaceId}, + app::{AppId, CreateAppParams, UpdateAppParams}, + trash::RepeatedTrashId, + view::{CreateViewParams, RepeatedViewId, UpdateViewParams, ViewId}, + workspace::{CreateWorkspaceParams, UpdateWorkspaceParams, WorkspaceId}, }, errors::FlowyError, manager::FolderManager, @@ -11,6 +11,7 @@ use crate::{ }; use flowy_database::{ConnectionPool, DBConnection}; use flowy_derive::{Flowy_Event, ProtoBuf_Enum}; +use flowy_folder_data_model::revision::{AppRevision, TrashRevision, ViewRevision, WorkspaceRevision}; use lib_dispatch::prelude::*; use lib_infra::future::FutureResult; use std::sync::Arc; @@ -155,27 +156,31 @@ pub trait FolderCouldServiceV1: Send + Sync { fn init(&self); // Workspace - fn create_workspace(&self, token: &str, params: CreateWorkspaceParams) -> FutureResult; + fn create_workspace( + &self, + token: &str, + params: CreateWorkspaceParams, + ) -> FutureResult; - fn read_workspace(&self, token: &str, params: WorkspaceId) -> FutureResult; + fn read_workspace(&self, token: &str, params: WorkspaceId) -> FutureResult, FlowyError>; fn update_workspace(&self, token: &str, params: UpdateWorkspaceParams) -> FutureResult<(), FlowyError>; fn delete_workspace(&self, token: &str, params: WorkspaceId) -> FutureResult<(), FlowyError>; // View - fn create_view(&self, token: &str, params: CreateViewParams) -> FutureResult; + fn create_view(&self, token: &str, params: CreateViewParams) -> FutureResult; - fn read_view(&self, token: &str, params: ViewId) -> FutureResult, FlowyError>; + fn read_view(&self, token: &str, params: ViewId) -> FutureResult, FlowyError>; fn delete_view(&self, token: &str, params: RepeatedViewId) -> FutureResult<(), FlowyError>; fn update_view(&self, token: &str, params: UpdateViewParams) -> FutureResult<(), FlowyError>; // App - fn create_app(&self, token: &str, params: CreateAppParams) -> FutureResult; + fn create_app(&self, token: &str, params: CreateAppParams) -> FutureResult; - fn read_app(&self, token: &str, params: AppId) -> FutureResult, FlowyError>; + fn read_app(&self, token: &str, params: AppId) -> FutureResult, FlowyError>; fn update_app(&self, token: &str, params: UpdateAppParams) -> FutureResult<(), FlowyError>; @@ -186,5 +191,5 @@ pub trait FolderCouldServiceV1: Send + Sync { fn delete_trash(&self, token: &str, params: RepeatedTrashId) -> FutureResult<(), FlowyError>; - fn read_trash(&self, token: &str) -> FutureResult; + fn read_trash(&self, token: &str) -> FutureResult, FlowyError>; } diff --git a/frontend/rust-lib/flowy-folder/src/manager.rs b/frontend/rust-lib/flowy-folder/src/manager.rs index 3181c14625..d9664004c9 100644 --- a/frontend/rust-lib/flowy-folder/src/manager.rs +++ b/frontend/rust-lib/flowy-folder/src/manager.rs @@ -13,6 +13,7 @@ use flowy_sync::client_document::default::{initial_quill_delta_string, initial_r use flowy_error::FlowyError; use flowy_folder_data_model::entities::view::ViewDataType; + use flowy_folder_data_model::user_default; use flowy_revision::disk::SQLiteTextBlockRevisionPersistence; use flowy_revision::{RevisionManager, RevisionPersistence, RevisionWebSocket}; @@ -199,9 +200,9 @@ impl DefaultFolderBuilder { view_controller: Arc, ) -> FlowyResult<()> { log::debug!("Create user default workspace"); - let workspace = user_default::create_default_workspace(); - set_current_workspace(&workspace.id); - for app in workspace.apps.iter() { + let workspace_rev = user_default::create_default_workspace(); + set_current_workspace(&workspace_rev.id); + for app in workspace_rev.apps.iter() { for (index, view) in app.belongings.iter().enumerate() { let view_data = if index == 0 { initial_read_me().to_delta_str() @@ -214,10 +215,12 @@ impl DefaultFolderBuilder { .await?; } } - let folder = FolderPad::new(vec![workspace.clone()], vec![])?; + let folder = FolderPad::new(vec![workspace_rev.clone()], vec![])?; let folder_id = FolderId::new(user_id); let _ = persistence.save_folder(user_id, &folder_id, folder).await?; - let repeated_workspace = RepeatedWorkspace { items: vec![workspace] }; + let repeated_workspace = RepeatedWorkspace { + items: vec![workspace_rev.into()], + }; send_dart_notification(token, FolderNotification::UserCreateWorkspace) .payload(repeated_workspace) .send(); diff --git a/frontend/rust-lib/flowy-folder/src/services/app/controller.rs b/frontend/rust-lib/flowy-folder/src/services/app/controller.rs index d33f40b4c6..481af85ccd 100644 --- a/frontend/rust-lib/flowy-folder/src/services/app/controller.rs +++ b/frontend/rust-lib/flowy-folder/src/services/app/controller.rs @@ -12,6 +12,7 @@ use crate::{ }, }; +use flowy_folder_data_model::revision::AppRevision; use futures::{FutureExt, StreamExt}; use std::{collections::HashSet, sync::Arc}; @@ -48,7 +49,7 @@ impl AppController { self.create_app_on_local(app).await } - pub(crate) async fn create_app_on_local(&self, app: App) -> Result { + pub(crate) async fn create_app_on_local(&self, app: AppRevision) -> Result { let _ = self .persistence .begin_transaction(|transaction| { @@ -57,10 +58,10 @@ impl AppController { Ok(()) }) .await?; - Ok(app) + Ok(app.into()) } - pub(crate) async fn read_app(&self, params: AppId) -> Result { + pub(crate) async fn read_app(&self, params: AppId) -> Result { let app = self .persistence .begin_transaction(|transaction| { @@ -80,14 +81,15 @@ impl AppController { let changeset = AppChangeset::new(params.clone()); let app_id = changeset.id.clone(); - let app = self + let app: App = self .persistence .begin_transaction(|transaction| { let _ = transaction.update_app(changeset)?; let app = transaction.read_app(&app_id)?; Ok(app) }) - .await?; + .await? + .into(); send_dart_notification(&app_id, FolderNotification::AppUpdated) .payload(app) .send(); @@ -108,8 +110,8 @@ impl AppController { Ok(()) } - pub(crate) async fn read_local_apps(&self, ids: Vec) -> Result, FlowyError> { - let apps = self + pub(crate) async fn read_local_apps(&self, ids: Vec) -> Result, FlowyError> { + let app_revs = self .persistence .begin_transaction(|transaction| { let mut apps = vec![]; @@ -119,13 +121,13 @@ impl AppController { Ok(apps) }) .await?; - Ok(apps) + Ok(app_revs) } } impl AppController { #[tracing::instrument(level = "trace", skip(self), err)] - async fn create_app_on_server(&self, params: CreateAppParams) -> Result { + async fn create_app_on_server(&self, params: CreateAppParams) -> Result { let token = self.user.token()?; let app = self.cloud_service.create_app(&token, params).await?; Ok(app) @@ -154,12 +156,13 @@ impl AppController { let persistence = self.persistence.clone(); tokio::spawn(async move { match server.read_app(&token, params).await { - Ok(Some(app)) => { + Ok(Some(app_rev)) => { match persistence - .begin_transaction(|transaction| transaction.create_app(app.clone())) + .begin_transaction(|transaction| transaction.create_app(app_rev.clone())) .await { Ok(_) => { + let app: App = app_rev.into(); send_dart_notification(&app.id, FolderNotification::AppUpdated) .payload(app) .send(); @@ -240,7 +243,11 @@ fn notify_apps_changed<'a>( trash_controller: Arc, transaction: &'a (dyn FolderPersistenceTransaction + 'a), ) -> FlowyResult<()> { - let repeated_app = read_local_workspace_apps(workspace_id, trash_controller, transaction)?; + let items = read_local_workspace_apps(workspace_id, trash_controller, transaction)? + .into_iter() + .map(|app_rev| app_rev.into()) + .collect(); + let repeated_app = RepeatedApp { items }; send_dart_notification(workspace_id, FolderNotification::WorkspaceAppsChanged) .payload(repeated_app) .send(); @@ -251,9 +258,9 @@ pub fn read_local_workspace_apps<'a>( workspace_id: &str, trash_controller: Arc, transaction: &'a (dyn FolderPersistenceTransaction + 'a), -) -> Result { - let mut apps = transaction.read_workspace_apps(workspace_id)?; +) -> Result, FlowyError> { + let mut app_revs = transaction.read_workspace_apps(workspace_id)?; let trash_ids = trash_controller.read_trash_ids(transaction)?; - apps.retain(|app| !trash_ids.contains(&app.id)); - Ok(RepeatedApp { items: apps }) + app_revs.retain(|app| !trash_ids.contains(&app.id)); + Ok(app_revs) } diff --git a/frontend/rust-lib/flowy-folder/src/services/app/event_handler.rs b/frontend/rust-lib/flowy-folder/src/services/app/event_handler.rs index b95b91dc2e..28885c69d7 100644 --- a/frontend/rust-lib/flowy-folder/src/services/app/event_handler.rs +++ b/frontend/rust-lib/flowy-folder/src/services/app/event_handler.rs @@ -1,11 +1,9 @@ use crate::{ - entities::{ - app::{App, AppId, CreateAppParams, CreateAppPayload, UpdateAppParams, UpdateAppPayload}, - trash::Trash, - }, + entities::app::{App, AppId, CreateAppParams, CreateAppPayload, UpdateAppParams, UpdateAppPayload}, errors::FlowyError, services::{AppController, TrashController, ViewController}, }; +use flowy_folder_data_model::revision::TrashRevision; use lib_dispatch::prelude::{data_result, AppData, Data, DataResult}; use std::{convert::TryInto, sync::Arc}; @@ -29,8 +27,8 @@ pub(crate) async fn delete_app_handler( .read_local_apps(vec![params.value]) .await? .into_iter() - .map(|app| app.into()) - .collect::>(); + .map(|app_rev| app_rev.into()) + .collect::>(); let _ = trash_controller.add(trash).await?; Ok(()) @@ -53,8 +51,8 @@ pub(crate) async fn read_app_handler( view_controller: AppData>, ) -> DataResult { let params: AppId = data.into_inner(); - let mut app = app_controller.read_app(params.clone()).await?; - app.belongings = view_controller.read_views_belong_to(¶ms.value).await?; + let mut app_rev = app_controller.read_app(params.clone()).await?; + app_rev.belongings = view_controller.read_views_belong_to(¶ms.value).await?; - data_result(app) + data_result(app_rev.into()) } diff --git a/frontend/rust-lib/flowy-folder/src/services/persistence/migration.rs b/frontend/rust-lib/flowy-folder/src/services/persistence/migration.rs index bc8838059a..4c147ad0d4 100644 --- a/frontend/rust-lib/flowy-folder/src/services/persistence/migration.rs +++ b/frontend/rust-lib/flowy-folder/src/services/persistence/migration.rs @@ -5,11 +5,8 @@ use crate::{ }; use flowy_database::kv::KV; use flowy_error::{FlowyError, FlowyResult}; -use flowy_folder_data_model::entities::{ - app::{App, RepeatedApp}, - view::{RepeatedView, View}, - workspace::Workspace, -}; + +use flowy_folder_data_model::revision::{AppRevision, ViewRevision, WorkspaceRevision}; use flowy_revision::disk::SQLiteTextBlockRevisionPersistence; use flowy_revision::{RevisionLoader, RevisionPersistence}; use flowy_sync::{client_folder::FolderPad, entities::revision::md5}; @@ -42,25 +39,25 @@ impl FolderMigration { let workspaces = conn.immediate_transaction::<_, FlowyError, _>(|| { let mut workspaces = WorkspaceTableSql::read_workspaces(&self.user_id, None, conn)? .into_iter() - .map(Workspace::from) + .map(WorkspaceRevision::from) .collect::>(); for workspace in workspaces.iter_mut() { let mut apps = AppTableSql::read_workspace_apps(&workspace.id, conn)? .into_iter() - .map(App::from) + .map(AppRevision::from) .collect::>(); for app in apps.iter_mut() { let views = ViewTableSql::read_views(&app.id, conn)? .into_iter() - .map(View::from) + .map(ViewRevision::from) .collect::>(); - app.belongings = RepeatedView { items: views }; + app.belongings = views; } - workspace.apps = RepeatedApp { items: apps }; + workspace.apps = apps; } Ok(workspaces) })?; @@ -72,7 +69,7 @@ impl FolderMigration { } let trash = conn.immediate_transaction::<_, FlowyError, _>(|| { - let trash = TrashTableSql::read_all(conn)?.take_items(); + let trash = TrashTableSql::read_all(conn)?; Ok(trash) })?; diff --git a/frontend/rust-lib/flowy-folder/src/services/persistence/mod.rs b/frontend/rust-lib/flowy-folder/src/services/persistence/mod.rs index d5bbb3a277..81aaa9bda6 100644 --- a/frontend/rust-lib/flowy-folder/src/services/persistence/mod.rs +++ b/frontend/rust-lib/flowy-folder/src/services/persistence/mod.rs @@ -9,12 +9,8 @@ use crate::{ }; use flowy_database::ConnectionPool; use flowy_error::{FlowyError, FlowyResult}; -use flowy_folder_data_model::entities::{ - app::App, - trash::{RepeatedTrash, Trash}, - view::View, - workspace::Workspace, -}; + +use flowy_folder_data_model::revision::{AppRevision, TrashRevision, ViewRevision, WorkspaceRevision}; use flowy_revision::disk::{RevisionRecord, RevisionState}; use flowy_revision::mk_revision_disk_cache; use flowy_sync::client_folder::initial_folder_delta; @@ -24,27 +20,27 @@ use tokio::sync::RwLock; pub use version_1::{app_sql::*, trash_sql::*, v1_impl::V1Transaction, view_sql::*, workspace_sql::*}; pub trait FolderPersistenceTransaction { - fn create_workspace(&self, user_id: &str, workspace: Workspace) -> FlowyResult<()>; - fn read_workspaces(&self, user_id: &str, workspace_id: Option) -> FlowyResult>; + fn create_workspace(&self, user_id: &str, workspace_rev: WorkspaceRevision) -> FlowyResult<()>; + fn read_workspaces(&self, user_id: &str, workspace_id: Option) -> FlowyResult>; fn update_workspace(&self, changeset: WorkspaceChangeset) -> FlowyResult<()>; fn delete_workspace(&self, workspace_id: &str) -> FlowyResult<()>; - fn create_app(&self, app: App) -> FlowyResult<()>; + fn create_app(&self, app_rev: AppRevision) -> FlowyResult<()>; fn update_app(&self, changeset: AppChangeset) -> FlowyResult<()>; - fn read_app(&self, app_id: &str) -> FlowyResult; - fn read_workspace_apps(&self, workspace_id: &str) -> FlowyResult>; - fn delete_app(&self, app_id: &str) -> FlowyResult; + fn read_app(&self, app_id: &str) -> FlowyResult; + fn read_workspace_apps(&self, workspace_id: &str) -> FlowyResult>; + fn delete_app(&self, app_id: &str) -> FlowyResult; fn move_app(&self, app_id: &str, from: usize, to: usize) -> FlowyResult<()>; - fn create_view(&self, view: View) -> FlowyResult<()>; - fn read_view(&self, view_id: &str) -> FlowyResult; - fn read_views(&self, belong_to_id: &str) -> FlowyResult>; + fn create_view(&self, view_rev: ViewRevision) -> FlowyResult<()>; + fn read_view(&self, view_id: &str) -> FlowyResult; + fn read_views(&self, belong_to_id: &str) -> FlowyResult>; fn update_view(&self, changeset: ViewChangeset) -> FlowyResult<()>; fn delete_view(&self, view_id: &str) -> FlowyResult<()>; fn move_view(&self, view_id: &str, from: usize, to: usize) -> FlowyResult<()>; - fn create_trash(&self, trashes: Vec) -> FlowyResult<()>; - fn read_trash(&self, trash_id: Option) -> FlowyResult; + fn create_trash(&self, trashes: Vec) -> FlowyResult<()>; + fn read_trash(&self, trash_id: Option) -> FlowyResult>; fn delete_trash(&self, trash_ids: Option>) -> FlowyResult<()>; } diff --git a/frontend/rust-lib/flowy-folder/src/services/persistence/version_1/app_sql.rs b/frontend/rust-lib/flowy-folder/src/services/persistence/version_1/app_sql.rs index 46f351ff03..6b5f47c2b7 100644 --- a/frontend/rust-lib/flowy-folder/src/services/persistence/version_1/app_sql.rs +++ b/frontend/rust-lib/flowy-folder/src/services/persistence/version_1/app_sql.rs @@ -1,7 +1,6 @@ use crate::entities::{ - app::{App, UpdateAppParams}, + app::UpdateAppParams, trash::{Trash, TrashType}, - view::RepeatedView, }; use crate::{errors::FlowyError, services::persistence::version_1::workspace_sql::WorkspaceTable}; use flowy_database::{ @@ -9,11 +8,12 @@ use flowy_database::{ schema::{app_table, app_table::dsl}, SqliteConnection, }; +use flowy_folder_data_model::revision::AppRevision; pub struct AppTableSql(); impl AppTableSql { - pub(crate) fn create_app(app: App, conn: &SqliteConnection) -> Result<(), FlowyError> { - let app_table = AppTable::new(app); + pub(crate) fn create_app(app_rev: AppRevision, conn: &SqliteConnection) -> Result<(), FlowyError> { + let app_table = AppTable::new(app_rev); match diesel_record_count!(app_table, &app_table.id, conn) { 0 => diesel_insert_table!(app_table, &app_table, conn), _ => { @@ -91,16 +91,16 @@ pub(crate) struct AppTable { } impl AppTable { - pub fn new(app: App) -> Self { + pub fn new(app_rev: AppRevision) -> Self { Self { - id: app.id, - workspace_id: app.workspace_id, - name: app.name, - desc: app.desc, + id: app_rev.id, + workspace_id: app_rev.workspace_id, + name: app_rev.name, + desc: app_rev.desc, color_style: Default::default(), last_view_id: None, - modified_time: app.modified_time, - create_time: app.create_time, + modified_time: app_rev.modified_time, + create_time: app_rev.create_time, version: 0, is_trash: false, } @@ -147,14 +147,14 @@ impl AppChangeset { } } } -impl std::convert::From for App { +impl std::convert::From for AppRevision { fn from(table: AppTable) -> Self { - App { + AppRevision { id: table.id, workspace_id: table.workspace_id, name: table.name, desc: table.desc, - belongings: RepeatedView::default(), + belongings: vec![], version: table.version, modified_time: table.modified_time, create_time: table.create_time, diff --git a/frontend/rust-lib/flowy-folder/src/services/persistence/version_1/trash_sql.rs b/frontend/rust-lib/flowy-folder/src/services/persistence/version_1/trash_sql.rs index 14bdce0d10..c4f6fff365 100644 --- a/frontend/rust-lib/flowy-folder/src/services/persistence/version_1/trash_sql.rs +++ b/frontend/rust-lib/flowy-folder/src/services/persistence/version_1/trash_sql.rs @@ -1,5 +1,5 @@ use crate::{ - entities::trash::{RepeatedTrash, Trash, TrashType}, + entities::trash::{Trash, TrashType}, errors::FlowyError, }; use diesel::sql_types::Integer; @@ -8,12 +8,13 @@ use flowy_database::{ schema::{trash_table, trash_table::dsl}, SqliteConnection, }; +use flowy_folder_data_model::revision::TrashRevision; pub struct TrashTableSql(); impl TrashTableSql { - pub(crate) fn create_trash(trashes: Vec, conn: &SqliteConnection) -> Result<(), FlowyError> { - for trash in trashes { - let trash_table: TrashTable = trash.into(); + pub(crate) fn create_trash(trashes: Vec, conn: &SqliteConnection) -> Result<(), FlowyError> { + for trash_rev in trashes { + let trash_table: TrashTable = trash_rev.into(); match diesel_record_count!(trash_table, &trash_table.id, conn) { 0 => diesel_insert_table!(trash_table, &trash_table, conn), _ => { @@ -26,10 +27,13 @@ impl TrashTableSql { Ok(()) } - pub(crate) fn read_all(conn: &SqliteConnection) -> Result { + pub(crate) fn read_all(conn: &SqliteConnection) -> Result, FlowyError> { let trash_tables = dsl::trash_table.load::(conn)?; - let items = trash_tables.into_iter().map(|t| t.into()).collect::>(); - Ok(RepeatedTrash { items }) + let items = trash_tables + .into_iter() + .map(TrashRevision::from) + .collect::>(); + Ok(items) } pub(crate) fn delete_all(conn: &SqliteConnection) -> Result<(), FlowyError> { @@ -72,12 +76,11 @@ impl std::convert::From for Trash { } } -impl std::convert::From for TrashTable { - fn from(trash: Trash) -> Self { - TrashTable { +impl std::convert::From for TrashRevision { + fn from(trash: TrashTable) -> Self { + TrashRevision { id: trash.id, name: trash.name, - desc: "".to_owned(), modified_time: trash.modified_time, create_time: trash.create_time, ty: trash.ty.into(), @@ -85,6 +88,19 @@ impl std::convert::From for TrashTable { } } +impl std::convert::From for TrashTable { + fn from(trash_rev: TrashRevision) -> Self { + TrashTable { + id: trash_rev.id, + name: trash_rev.name, + desc: "".to_string(), + modified_time: trash_rev.modified_time, + create_time: trash_rev.create_time, + ty: trash_rev.ty.into(), + } + } +} + #[derive(AsChangeset, Identifiable, Clone, Default, Debug)] #[table_name = "trash_table"] pub(crate) struct TrashChangeset { diff --git a/frontend/rust-lib/flowy-folder/src/services/persistence/version_1/v1_impl.rs b/frontend/rust-lib/flowy-folder/src/services/persistence/version_1/v1_impl.rs index 4f5a2d181d..619aa156ca 100644 --- a/frontend/rust-lib/flowy-folder/src/services/persistence/version_1/v1_impl.rs +++ b/frontend/rust-lib/flowy-folder/src/services/persistence/version_1/v1_impl.rs @@ -8,24 +8,19 @@ use crate::services::persistence::{ }; use flowy_database::DBConnection; use flowy_error::FlowyResult; -use flowy_folder_data_model::entities::{ - app::App, - trash::{RepeatedTrash, Trash}, - view::View, - workspace::Workspace, -}; +use flowy_folder_data_model::revision::{AppRevision, TrashRevision, ViewRevision, WorkspaceRevision}; pub struct V1Transaction<'a>(pub &'a DBConnection); impl<'a> FolderPersistenceTransaction for V1Transaction<'a> { - fn create_workspace(&self, user_id: &str, workspace: Workspace) -> FlowyResult<()> { - let _ = WorkspaceTableSql::create_workspace(user_id, workspace, &*self.0)?; + fn create_workspace(&self, user_id: &str, workspace_rev: WorkspaceRevision) -> FlowyResult<()> { + let _ = WorkspaceTableSql::create_workspace(user_id, workspace_rev, &*self.0)?; Ok(()) } - fn read_workspaces(&self, user_id: &str, workspace_id: Option) -> FlowyResult> { + fn read_workspaces(&self, user_id: &str, workspace_id: Option) -> FlowyResult> { let tables = WorkspaceTableSql::read_workspaces(user_id, workspace_id, &*self.0)?; - let workspaces = tables.into_iter().map(Workspace::from).collect::>(); + let workspaces = tables.into_iter().map(WorkspaceRevision::from).collect::>(); Ok(workspaces) } @@ -37,8 +32,8 @@ impl<'a> FolderPersistenceTransaction for V1Transaction<'a> { WorkspaceTableSql::delete_workspace(workspace_id, &*self.0) } - fn create_app(&self, app: App) -> FlowyResult<()> { - let _ = AppTableSql::create_app(app, &*self.0)?; + fn create_app(&self, app_rev: AppRevision) -> FlowyResult<()> { + let _ = AppTableSql::create_app(app_rev, &*self.0)?; Ok(()) } @@ -47,39 +42,39 @@ impl<'a> FolderPersistenceTransaction for V1Transaction<'a> { Ok(()) } - fn read_app(&self, app_id: &str) -> FlowyResult { - let table = AppTableSql::read_app(app_id, &*self.0)?; - Ok(App::from(table)) + fn read_app(&self, app_id: &str) -> FlowyResult { + let app_revision: AppRevision = AppTableSql::read_app(app_id, &*self.0)?.into(); + Ok(app_revision) } - fn read_workspace_apps(&self, workspace_id: &str) -> FlowyResult> { + fn read_workspace_apps(&self, workspace_id: &str) -> FlowyResult> { let tables = AppTableSql::read_workspace_apps(workspace_id, &*self.0)?; - let apps = tables.into_iter().map(App::from).collect::>(); + let apps = tables.into_iter().map(AppRevision::from).collect::>(); Ok(apps) } - fn delete_app(&self, app_id: &str) -> FlowyResult { - let table = AppTableSql::delete_app(app_id, &*self.0)?; - Ok(App::from(table)) + fn delete_app(&self, app_id: &str) -> FlowyResult { + let app_revision: AppRevision = AppTableSql::delete_app(app_id, &*self.0)?.into(); + Ok(app_revision) } fn move_app(&self, _app_id: &str, _from: usize, _to: usize) -> FlowyResult<()> { Ok(()) } - fn create_view(&self, view: View) -> FlowyResult<()> { - let _ = ViewTableSql::create_view(view, &*self.0)?; + fn create_view(&self, view_rev: ViewRevision) -> FlowyResult<()> { + let _ = ViewTableSql::create_view(view_rev, &*self.0)?; Ok(()) } - fn read_view(&self, view_id: &str) -> FlowyResult { - let table = ViewTableSql::read_view(view_id, &*self.0)?; - Ok(View::from(table)) + fn read_view(&self, view_id: &str) -> FlowyResult { + let view_revision: ViewRevision = ViewTableSql::read_view(view_id, &*self.0)?.into(); + Ok(view_revision) } - fn read_views(&self, belong_to_id: &str) -> FlowyResult> { + fn read_views(&self, belong_to_id: &str) -> FlowyResult> { let tables = ViewTableSql::read_views(belong_to_id, &*self.0)?; - let views = tables.into_iter().map(View::from).collect::>(); + let views = tables.into_iter().map(ViewRevision::from).collect::>(); Ok(views) } @@ -97,19 +92,17 @@ impl<'a> FolderPersistenceTransaction for V1Transaction<'a> { Ok(()) } - fn create_trash(&self, trashes: Vec) -> FlowyResult<()> { + fn create_trash(&self, trashes: Vec) -> FlowyResult<()> { let _ = TrashTableSql::create_trash(trashes, &*self.0)?; Ok(()) } - fn read_trash(&self, trash_id: Option) -> FlowyResult { + fn read_trash(&self, trash_id: Option) -> FlowyResult> { match trash_id { None => TrashTableSql::read_all(&*self.0), Some(trash_id) => { - let table = TrashTableSql::read(&trash_id, &*self.0)?; - Ok(RepeatedTrash { - items: vec![Trash::from(table)], - }) + let trash_revision: TrashRevision = TrashTableSql::read(&trash_id, &*self.0)?.into(); + Ok(vec![trash_revision]) } } } @@ -132,11 +125,11 @@ impl FolderPersistenceTransaction for Box where T: FolderPersistenceTransaction + ?Sized, { - fn create_workspace(&self, user_id: &str, workspace: Workspace) -> FlowyResult<()> { - (**self).create_workspace(user_id, workspace) + fn create_workspace(&self, user_id: &str, workspace_rev: WorkspaceRevision) -> FlowyResult<()> { + (**self).create_workspace(user_id, workspace_rev) } - fn read_workspaces(&self, user_id: &str, workspace_id: Option) -> FlowyResult> { + fn read_workspaces(&self, user_id: &str, workspace_id: Option) -> FlowyResult> { (**self).read_workspaces(user_id, workspace_id) } @@ -148,23 +141,23 @@ where (**self).delete_workspace(workspace_id) } - fn create_app(&self, app: App) -> FlowyResult<()> { - (**self).create_app(app) + fn create_app(&self, app_rev: AppRevision) -> FlowyResult<()> { + (**self).create_app(app_rev) } fn update_app(&self, changeset: AppChangeset) -> FlowyResult<()> { (**self).update_app(changeset) } - fn read_app(&self, app_id: &str) -> FlowyResult { + fn read_app(&self, app_id: &str) -> FlowyResult { (**self).read_app(app_id) } - fn read_workspace_apps(&self, workspace_id: &str) -> FlowyResult> { + fn read_workspace_apps(&self, workspace_id: &str) -> FlowyResult> { (**self).read_workspace_apps(workspace_id) } - fn delete_app(&self, app_id: &str) -> FlowyResult { + fn delete_app(&self, app_id: &str) -> FlowyResult { (**self).delete_app(app_id) } @@ -172,15 +165,15 @@ where Ok(()) } - fn create_view(&self, view: View) -> FlowyResult<()> { - (**self).create_view(view) + fn create_view(&self, view_rev: ViewRevision) -> FlowyResult<()> { + (**self).create_view(view_rev) } - fn read_view(&self, view_id: &str) -> FlowyResult { + fn read_view(&self, view_id: &str) -> FlowyResult { (**self).read_view(view_id) } - fn read_views(&self, belong_to_id: &str) -> FlowyResult> { + fn read_views(&self, belong_to_id: &str) -> FlowyResult> { (**self).read_views(belong_to_id) } @@ -196,11 +189,11 @@ where Ok(()) } - fn create_trash(&self, trashes: Vec) -> FlowyResult<()> { + fn create_trash(&self, trashes: Vec) -> FlowyResult<()> { (**self).create_trash(trashes) } - fn read_trash(&self, trash_id: Option) -> FlowyResult { + fn read_trash(&self, trash_id: Option) -> FlowyResult> { (**self).read_trash(trash_id) } diff --git a/frontend/rust-lib/flowy-folder/src/services/persistence/version_1/view_sql.rs b/frontend/rust-lib/flowy-folder/src/services/persistence/version_1/view_sql.rs index 0677110cda..08c96ac90c 100644 --- a/frontend/rust-lib/flowy-folder/src/services/persistence/version_1/view_sql.rs +++ b/frontend/rust-lib/flowy-folder/src/services/persistence/version_1/view_sql.rs @@ -1,7 +1,7 @@ use crate::{ entities::{ trash::{Trash, TrashType}, - view::{RepeatedView, UpdateViewParams, View, ViewDataType}, + view::{UpdateViewParams, ViewDataType}, }, errors::FlowyError, services::persistence::version_1::app_sql::AppTable, @@ -12,12 +12,14 @@ use flowy_database::{ schema::{view_table, view_table::dsl}, SqliteConnection, }; + +use flowy_folder_data_model::revision::ViewRevision; use lib_infra::util::timestamp; pub struct ViewTableSql(); impl ViewTableSql { - pub(crate) fn create_view(view: View, conn: &SqliteConnection) -> Result<(), FlowyError> { - let view_table = ViewTable::new(view); + pub(crate) fn create_view(view_rev: ViewRevision, conn: &SqliteConnection) -> Result<(), FlowyError> { + let view_table = ViewTable::new(view_rev); match diesel_record_count!(view_table, &view_table.id, conn) { 0 => diesel_insert_table!(view_table, &view_table, conn), _ => { @@ -83,49 +85,49 @@ pub(crate) struct ViewTable { } impl ViewTable { - pub fn new(view: View) -> Self { - let data_type = match view.data_type { + pub fn new(view_rev: ViewRevision) -> Self { + let data_type = match view_rev.data_type { ViewDataType::TextBlock => SqlViewDataType::Block, ViewDataType::Grid => SqlViewDataType::Grid, }; ViewTable { - id: view.id, - belong_to_id: view.belong_to_id, - name: view.name, - desc: view.desc, - modified_time: view.modified_time, - create_time: view.create_time, - thumbnail: view.thumbnail, + id: view_rev.id, + belong_to_id: view_rev.belong_to_id, + name: view_rev.name, + desc: view_rev.desc, + modified_time: view_rev.modified_time, + create_time: view_rev.create_time, + thumbnail: view_rev.thumbnail, view_type: data_type, - ext_data: view.ext_data, - version: 0, + ext_data: view_rev.ext_data, + version: view_rev.version, is_trash: false, } } } -impl std::convert::From for View { +impl std::convert::From for ViewRevision { fn from(table: ViewTable) -> Self { let data_type = match table.view_type { SqlViewDataType::Block => ViewDataType::TextBlock, SqlViewDataType::Grid => ViewDataType::Grid, }; - View { + ViewRevision { id: table.id, belong_to_id: table.belong_to_id, name: table.name, desc: table.desc, data_type, - belongings: RepeatedView::default(), + belongings: vec![], modified_time: table.modified_time, version: table.version, create_time: table.create_time, - ext_data: table.ext_data, + ext_data: "".to_string(), thumbnail: table.thumbnail, // Store the view in ViewTable was deprecated since v0.0.2. - // No need worry about plugin_type. + // No need to worry about plugin_type. plugin_type: 0, } } diff --git a/frontend/rust-lib/flowy-folder/src/services/persistence/version_1/workspace_sql.rs b/frontend/rust-lib/flowy-folder/src/services/persistence/version_1/workspace_sql.rs index ce95d09275..4de8f7df34 100644 --- a/frontend/rust-lib/flowy-folder/src/services/persistence/version_1/workspace_sql.rs +++ b/frontend/rust-lib/flowy-folder/src/services/persistence/version_1/workspace_sql.rs @@ -1,23 +1,19 @@ -use crate::{ - entities::{ - app::RepeatedApp, - workspace::{UpdateWorkspaceParams, Workspace}, - }, - errors::FlowyError, -}; +use crate::{entities::workspace::UpdateWorkspaceParams, errors::FlowyError}; use diesel::SqliteConnection; use flowy_database::{ prelude::*, schema::{workspace_table, workspace_table::dsl}, }; +use flowy_folder_data_model::revision::WorkspaceRevision; + pub(crate) struct WorkspaceTableSql(); impl WorkspaceTableSql { pub(crate) fn create_workspace( user_id: &str, - workspace: Workspace, + workspace_rev: WorkspaceRevision, conn: &SqliteConnection, ) -> Result<(), FlowyError> { - let table = WorkspaceTable::new(workspace, user_id); + let table = WorkspaceTable::new(workspace_rev, user_id); match diesel_record_count!(workspace_table, &table.id, conn) { 0 => diesel_insert_table!(workspace_table, &table, conn), _ => { @@ -74,26 +70,26 @@ pub struct WorkspaceTable { impl WorkspaceTable { #[allow(dead_code)] - pub fn new(workspace: Workspace, user_id: &str) -> Self { + pub fn new(workspace_rev: WorkspaceRevision, user_id: &str) -> Self { WorkspaceTable { - id: workspace.id, - name: workspace.name, - desc: workspace.desc, - modified_time: workspace.modified_time, - create_time: workspace.create_time, + id: workspace_rev.id, + name: workspace_rev.name, + desc: workspace_rev.desc, + modified_time: workspace_rev.modified_time, + create_time: workspace_rev.create_time, user_id: user_id.to_owned(), version: 0, } } } -impl std::convert::From for Workspace { +impl std::convert::From for WorkspaceRevision { fn from(table: WorkspaceTable) -> Self { - Workspace { + WorkspaceRevision { id: table.id, name: table.name, desc: table.desc, - apps: RepeatedApp::default(), + apps: vec![], modified_time: table.modified_time, create_time: table.create_time, } diff --git a/frontend/rust-lib/flowy-folder/src/services/persistence/version_2/v2_impl.rs b/frontend/rust-lib/flowy-folder/src/services/persistence/version_2/v2_impl.rs index 40f72e10b0..7a51ac4e88 100644 --- a/frontend/rust-lib/flowy-folder/src/services/persistence/version_2/v2_impl.rs +++ b/frontend/rust-lib/flowy-folder/src/services/persistence/version_2/v2_impl.rs @@ -3,23 +3,19 @@ use crate::services::{ persistence::{AppChangeset, FolderPersistenceTransaction, ViewChangeset, WorkspaceChangeset}, }; use flowy_error::{FlowyError, FlowyResult}; -use flowy_folder_data_model::entities::{ - app::App, - trash::{RepeatedTrash, Trash}, - view::View, - workspace::Workspace, -}; + +use flowy_folder_data_model::revision::{AppRevision, TrashRevision, ViewRevision, WorkspaceRevision}; use std::sync::Arc; impl FolderPersistenceTransaction for FolderEditor { - fn create_workspace(&self, _user_id: &str, workspace: Workspace) -> FlowyResult<()> { - if let Some(change) = self.folder.write().create_workspace(workspace)? { + fn create_workspace(&self, _user_id: &str, workspace_rev: WorkspaceRevision) -> FlowyResult<()> { + if let Some(change) = self.folder.write().create_workspace(workspace_rev)? { let _ = self.apply_change(change)?; } Ok(()) } - fn read_workspaces(&self, _user_id: &str, workspace_id: Option) -> FlowyResult> { + fn read_workspaces(&self, _user_id: &str, workspace_id: Option) -> FlowyResult> { let workspaces = self.folder.read().read_workspaces(workspace_id)?; Ok(workspaces) } @@ -42,8 +38,8 @@ impl FolderPersistenceTransaction for FolderEditor { Ok(()) } - fn create_app(&self, app: App) -> FlowyResult<()> { - if let Some(change) = self.folder.write().create_app(app)? { + fn create_app(&self, app_rev: AppRevision) -> FlowyResult<()> { + if let Some(change) = self.folder.write().create_app(app_rev)? { let _ = self.apply_change(change)?; } Ok(()) @@ -60,22 +56,22 @@ impl FolderPersistenceTransaction for FolderEditor { Ok(()) } - fn read_app(&self, app_id: &str) -> FlowyResult { + fn read_app(&self, app_id: &str) -> FlowyResult { let app = self.folder.read().read_app(app_id)?; Ok(app) } - fn read_workspace_apps(&self, workspace_id: &str) -> FlowyResult> { + fn read_workspace_apps(&self, workspace_id: &str) -> FlowyResult> { let workspaces = self.folder.read().read_workspaces(Some(workspace_id.to_owned()))?; match workspaces.first() { None => { Err(FlowyError::record_not_found().context(format!("can't find workspace with id {}", workspace_id))) } - Some(workspace) => Ok(workspace.apps.clone().take_items()), + Some(workspace) => Ok(workspace.apps.clone()), } } - fn delete_app(&self, app_id: &str) -> FlowyResult { + fn delete_app(&self, app_id: &str) -> FlowyResult { let app = self.folder.read().read_app(app_id)?; if let Some(change) = self.folder.write().delete_app(app_id)? { let _ = self.apply_change(change)?; @@ -90,19 +86,19 @@ impl FolderPersistenceTransaction for FolderEditor { Ok(()) } - fn create_view(&self, view: View) -> FlowyResult<()> { - if let Some(change) = self.folder.write().create_view(view)? { + fn create_view(&self, view_rev: ViewRevision) -> FlowyResult<()> { + if let Some(change) = self.folder.write().create_view(view_rev)? { let _ = self.apply_change(change)?; } Ok(()) } - fn read_view(&self, view_id: &str) -> FlowyResult { + fn read_view(&self, view_id: &str) -> FlowyResult { let view = self.folder.read().read_view(view_id)?; Ok(view) } - fn read_views(&self, belong_to_id: &str) -> FlowyResult> { + fn read_views(&self, belong_to_id: &str) -> FlowyResult> { let views = self.folder.read().read_views(belong_to_id)?; Ok(views) } @@ -132,16 +128,16 @@ impl FolderPersistenceTransaction for FolderEditor { Ok(()) } - fn create_trash(&self, trashes: Vec) -> FlowyResult<()> { + fn create_trash(&self, trashes: Vec) -> FlowyResult<()> { if let Some(change) = self.folder.write().create_trash(trashes)? { let _ = self.apply_change(change)?; } Ok(()) } - fn read_trash(&self, trash_id: Option) -> FlowyResult { + fn read_trash(&self, trash_id: Option) -> FlowyResult> { let trash = self.folder.read().read_trash(trash_id)?; - Ok(RepeatedTrash { items: trash }) + Ok(trash) } fn delete_trash(&self, trash_ids: Option>) -> FlowyResult<()> { @@ -156,11 +152,11 @@ impl FolderPersistenceTransaction for Arc where T: FolderPersistenceTransaction + ?Sized, { - fn create_workspace(&self, user_id: &str, workspace: Workspace) -> FlowyResult<()> { - (**self).create_workspace(user_id, workspace) + fn create_workspace(&self, user_id: &str, workspace_rev: WorkspaceRevision) -> FlowyResult<()> { + (**self).create_workspace(user_id, workspace_rev) } - fn read_workspaces(&self, user_id: &str, workspace_id: Option) -> FlowyResult> { + fn read_workspaces(&self, user_id: &str, workspace_id: Option) -> FlowyResult> { (**self).read_workspaces(user_id, workspace_id) } @@ -172,23 +168,23 @@ where (**self).delete_workspace(workspace_id) } - fn create_app(&self, app: App) -> FlowyResult<()> { - (**self).create_app(app) + fn create_app(&self, app_rev: AppRevision) -> FlowyResult<()> { + (**self).create_app(app_rev) } fn update_app(&self, changeset: AppChangeset) -> FlowyResult<()> { (**self).update_app(changeset) } - fn read_app(&self, app_id: &str) -> FlowyResult { + fn read_app(&self, app_id: &str) -> FlowyResult { (**self).read_app(app_id) } - fn read_workspace_apps(&self, workspace_id: &str) -> FlowyResult> { + fn read_workspace_apps(&self, workspace_id: &str) -> FlowyResult> { (**self).read_workspace_apps(workspace_id) } - fn delete_app(&self, app_id: &str) -> FlowyResult { + fn delete_app(&self, app_id: &str) -> FlowyResult { (**self).delete_app(app_id) } @@ -196,15 +192,15 @@ where (**self).move_app(app_id, from, to) } - fn create_view(&self, view: View) -> FlowyResult<()> { - (**self).create_view(view) + fn create_view(&self, view_rev: ViewRevision) -> FlowyResult<()> { + (**self).create_view(view_rev) } - fn read_view(&self, view_id: &str) -> FlowyResult { + fn read_view(&self, view_id: &str) -> FlowyResult { (**self).read_view(view_id) } - fn read_views(&self, belong_to_id: &str) -> FlowyResult> { + fn read_views(&self, belong_to_id: &str) -> FlowyResult> { (**self).read_views(belong_to_id) } @@ -220,11 +216,11 @@ where (**self).move_view(view_id, from, to) } - fn create_trash(&self, trashes: Vec) -> FlowyResult<()> { + fn create_trash(&self, trashes: Vec) -> FlowyResult<()> { (**self).create_trash(trashes) } - fn read_trash(&self, trash_id: Option) -> FlowyResult { + fn read_trash(&self, trash_id: Option) -> FlowyResult> { (**self).read_trash(trash_id) } diff --git a/frontend/rust-lib/flowy-folder/src/services/trash/controller.rs b/frontend/rust-lib/flowy-folder/src/services/trash/controller.rs index cdbabc1320..5fe144e81f 100644 --- a/frontend/rust-lib/flowy-folder/src/services/trash/controller.rs +++ b/frontend/rust-lib/flowy-folder/src/services/trash/controller.rs @@ -6,6 +6,7 @@ use crate::{ services::persistence::{FolderPersistence, FolderPersistenceTransaction}, }; +use flowy_folder_data_model::revision::TrashRevision; use std::{fmt::Formatter, sync::Arc}; use tokio::sync::{broadcast, mpsc}; @@ -66,18 +67,18 @@ impl TrashController { #[tracing::instrument(level = "debug", skip(self) err)] pub async fn restore_all_trash(&self) -> FlowyResult<()> { - let repeated_trash = self + let trash_identifier: RepeatedTrashId = self .persistence .begin_transaction(|transaction| { let trash = transaction.read_trash(None); let _ = transaction.delete_trash(None); trash }) - .await?; + .await? + .into(); - let identifiers: RepeatedTrashId = repeated_trash.items.clone().into(); let (tx, mut rx) = mpsc::channel::>(1); - let _ = self.notify.send(TrashEvent::Putback(identifiers, tx)); + let _ = self.notify.send(TrashEvent::Putback(trash_identifier, tx)); let _ = rx.recv().await; notify_trash_changed(RepeatedTrash { items: vec![] }); @@ -87,12 +88,13 @@ impl TrashController { #[tracing::instrument(level = "debug", skip(self), err)] pub async fn delete_all_trash(&self) -> FlowyResult<()> { - let repeated_trash = self + let all_trash_identifiers: RepeatedTrashId = self .persistence .begin_transaction(|transaction| transaction.read_trash(None)) - .await?; - let trash_identifiers: RepeatedTrashId = repeated_trash.items.clone().into(); - let _ = self.delete_with_identifiers(trash_identifiers.clone()).await?; + .await? + .into(); + + let _ = self.delete_with_identifiers(all_trash_identifiers).await?; notify_trash_changed(RepeatedTrash { items: vec![] }); let _ = self.delete_all_trash_on_server().await?; @@ -102,11 +104,12 @@ impl TrashController { #[tracing::instrument(level = "debug", skip(self), err)] pub async fn delete(&self, trash_identifiers: RepeatedTrashId) -> FlowyResult<()> { let _ = self.delete_with_identifiers(trash_identifiers.clone()).await?; - let repeated_trash = self + let trash_revs = self .persistence .begin_transaction(|transaction| transaction.read_trash(None)) .await?; - notify_trash_changed(repeated_trash); + + notify_trash_changed(trash_revs); let _ = self.delete_trash_on_server(trash_identifiers)?; Ok(()) @@ -147,10 +150,10 @@ impl TrashController { // CREATE and DROP tables operations because those are auto-commit in the // database. #[tracing::instrument(name = "add_trash", level = "debug", skip(self, trash), fields(trash_ids), err)] - pub async fn add>(&self, trash: Vec) -> Result<(), FlowyError> { + pub async fn add>(&self, trash: Vec) -> Result<(), FlowyError> { let (tx, mut rx) = mpsc::channel::>(1); - let repeated_trash = trash.into_iter().map(|t| t.into()).collect::>(); - let identifiers = repeated_trash.iter().map(|t| t.into()).collect::>(); + let trash_revs: Vec = trash.into_iter().map(|t| t.into()).collect(); + let identifiers = trash_revs.iter().map(|t| t.into()).collect::>(); tracing::Span::current().record( "trash_ids", @@ -167,8 +170,9 @@ impl TrashController { let _ = self .persistence .begin_transaction(|transaction| { - let _ = transaction.create_trash(repeated_trash.clone())?; - let _ = self.create_trash_on_server(repeated_trash); + let _ = transaction.create_trash(trash_revs.clone())?; + let _ = self.create_trash_on_server(trash_revs); + notify_trash_changed(transaction.read_trash(None)?); Ok(()) }) @@ -184,12 +188,16 @@ impl TrashController { } pub async fn read_trash(&self) -> Result { - let repeated_trash = self + let items: Vec = self .persistence .begin_transaction(|transaction| transaction.read_trash(None)) - .await?; + .await? + .into_iter() + .map(|trash_rev| trash_rev.into()) + .collect(); + let _ = self.read_trash_on_server()?; - Ok(repeated_trash) + Ok(RepeatedTrash { items }) } pub fn read_trash_ids<'a>( @@ -198,7 +206,6 @@ impl TrashController { ) -> Result, FlowyError> { let ids = transaction .read_trash(None)? - .into_inner() .into_iter() .map(|item| item.id) .collect::>(); @@ -244,18 +251,18 @@ impl TrashController { tokio::spawn(async move { match server.read_trash(&token).await { - Ok(repeated_trash) => { - tracing::debug!("Remote trash count: {}", repeated_trash.items.len()); + Ok(trash_rev) => { + tracing::debug!("Remote trash count: {}", trash_rev.len()); let result = persistence .begin_transaction(|transaction| { - let _ = transaction.create_trash(repeated_trash.items.clone())?; + let _ = transaction.create_trash(trash_rev.clone())?; transaction.read_trash(None) }) .await; match result { - Ok(repeated_trash) => { - notify_trash_changed(repeated_trash); + Ok(trash_revs) => { + notify_trash_changed(trash_revs); } Err(e) => log::error!("Save trash failed: {:?}", e), } @@ -275,7 +282,8 @@ impl TrashController { } #[tracing::instrument(level = "debug", skip(repeated_trash), fields(n_trash))] -fn notify_trash_changed(repeated_trash: RepeatedTrash) { +fn notify_trash_changed>(repeated_trash: T) { + let repeated_trash = repeated_trash.into(); tracing::Span::current().record("n_trash", &repeated_trash.len()); send_anonymous_dart_notification(FolderNotification::TrashUpdated) .payload(repeated_trash) diff --git a/frontend/rust-lib/flowy-folder/src/services/view/controller.rs b/frontend/rust-lib/flowy-folder/src/services/view/controller.rs index 4de3b306d8..54551fd431 100644 --- a/frontend/rust-lib/flowy-folder/src/services/view/controller.rs +++ b/frontend/rust-lib/flowy-folder/src/services/view/controller.rs @@ -15,6 +15,7 @@ use crate::{ use bytes::Bytes; use flowy_database::kv::KV; use flowy_folder_data_model::entities::view::{gen_view_id, ViewDataType}; +use flowy_folder_data_model::revision::ViewRevision; use flowy_sync::entities::text_block_info::TextBlockId; use futures::{FutureExt, StreamExt}; use std::{collections::HashSet, sync::Arc}; @@ -52,7 +53,10 @@ impl ViewController { } #[tracing::instrument(level = "trace", skip(self, params), fields(name = %params.name), err)] - pub(crate) async fn create_view_from_params(&self, mut params: CreateViewParams) -> Result { + pub(crate) async fn create_view_from_params( + &self, + mut params: CreateViewParams, + ) -> Result { let processor = self.get_data_processor(¶ms.data_type)?; let user_id = self.user.user_id()?; if params.data.is_empty() { @@ -67,9 +71,9 @@ impl ViewController { .await?; }; - let view = self.create_view_on_server(params).await?; - let _ = self.create_view_on_local(view.clone()).await?; - Ok(view) + let view_rev = self.create_view_on_server(params).await?; + let _ = self.create_view_on_local(view_rev.clone()).await?; + Ok(view_rev) } #[tracing::instrument(level = "debug", skip(self, view_id, delta_data), err)] @@ -88,12 +92,12 @@ impl ViewController { Ok(()) } - pub(crate) async fn create_view_on_local(&self, view: View) -> Result<(), FlowyError> { + pub(crate) async fn create_view_on_local(&self, view_rev: ViewRevision) -> Result<(), FlowyError> { let trash_controller = self.trash_controller.clone(); self.persistence .begin_transaction(|transaction| { - let belong_to_id = view.belong_to_id.clone(); - let _ = transaction.create_view(view)?; + let belong_to_id = view_rev.belong_to_id.clone(); + let _ = transaction.create_view(view_rev)?; let _ = notify_views_changed(&belong_to_id, trash_controller, &transaction)?; Ok(()) }) @@ -101,8 +105,8 @@ impl ViewController { } #[tracing::instrument(level = "debug", skip(self, view_id), fields(view_id = %view_id.value), err)] - pub(crate) async fn read_view(&self, view_id: ViewId) -> Result { - let view = self + pub(crate) async fn read_view(&self, view_id: ViewId) -> Result { + let view_rev = self .persistence .begin_transaction(|transaction| { let view = transaction.read_view(&view_id.value)?; @@ -114,10 +118,10 @@ impl ViewController { }) .await?; let _ = self.read_view_on_server(view_id); - Ok(view) + Ok(view_rev) } - pub(crate) async fn read_local_views(&self, ids: Vec) -> Result, FlowyError> { + pub(crate) async fn read_local_views(&self, ids: Vec) -> Result, FlowyError> { self.persistence .begin_transaction(|transaction| { let mut views = vec![]; @@ -170,22 +174,22 @@ impl ViewController { #[tracing::instrument(level = "debug", skip(self), err)] pub(crate) async fn duplicate_view(&self, view_id: &str) -> Result<(), FlowyError> { - let view = self + let view_rev = self .persistence .begin_transaction(|transaction| transaction.read_view(view_id)) .await?; - let processor = self.get_data_processor(&view.data_type)?; + let processor = self.get_data_processor(&view_rev.data_type)?; let delta_bytes = processor.view_delta_data(view_id).await?; let duplicate_params = CreateViewParams { - belong_to_id: view.belong_to_id.clone(), - name: format!("{} (copy)", &view.name), - desc: view.desc, - thumbnail: view.thumbnail, - data_type: view.data_type, + belong_to_id: view_rev.belong_to_id.clone(), + name: format!("{} (copy)", &view_rev.name), + desc: view_rev.desc, + thumbnail: view_rev.thumbnail, + data_type: view_rev.data_type, data: delta_bytes.to_vec(), view_id: gen_view_id(), - plugin_type: view.plugin_type, + plugin_type: view_rev.plugin_type, }; let _ = self.create_view_from_params(duplicate_params).await?; @@ -194,7 +198,7 @@ impl ViewController { // belong_to_id will be the app_id or view_id. #[tracing::instrument(level = "trace", skip(self), err)] - pub(crate) async fn read_views_belong_to(&self, belong_to_id: &str) -> Result { + pub(crate) async fn read_views_belong_to(&self, belong_to_id: &str) -> Result, FlowyError> { self.persistence .begin_transaction(|transaction| { read_belonging_views_on_local(belong_to_id, self.trash_controller.clone(), &transaction) @@ -203,35 +207,36 @@ impl ViewController { } #[tracing::instrument(level = "debug", skip(self, params), err)] - pub(crate) async fn update_view(&self, params: UpdateViewParams) -> Result { + pub(crate) async fn update_view(&self, params: UpdateViewParams) -> Result { let changeset = ViewChangeset::new(params.clone()); let view_id = changeset.id.clone(); - let view = self + let view_rev = self .persistence .begin_transaction(|transaction| { let _ = transaction.update_view(changeset)?; - let view = transaction.read_view(&view_id)?; + let view_rev = transaction.read_view(&view_id)?; + let view: View = view_rev.clone().into(); send_dart_notification(&view_id, FolderNotification::ViewUpdated) - .payload(view.clone()) + .payload(view) .send(); - let _ = notify_views_changed(&view.belong_to_id, self.trash_controller.clone(), &transaction)?; - Ok(view) + let _ = notify_views_changed(&view_rev.belong_to_id, self.trash_controller.clone(), &transaction)?; + Ok(view_rev) }) .await?; let _ = self.update_view_on_server(params); - Ok(view) + Ok(view_rev) } - pub(crate) async fn latest_visit_view(&self) -> FlowyResult> { + pub(crate) async fn latest_visit_view(&self) -> FlowyResult> { match KV::get_str(LATEST_VIEW_ID) { None => Ok(None), Some(view_id) => { - let view = self + let view_rev = self .persistence .begin_transaction(|transaction| transaction.read_view(&view_id)) .await?; - Ok(Some(view)) + Ok(Some(view_rev)) } } } @@ -239,10 +244,10 @@ impl ViewController { impl ViewController { #[tracing::instrument(level = "debug", skip(self, params), err)] - async fn create_view_on_server(&self, params: CreateViewParams) -> Result { + async fn create_view_on_server(&self, params: CreateViewParams) -> Result { let token = self.user.token()?; - let view = self.cloud_service.create_view(&token, params).await?; - Ok(view) + let view_rev = self.cloud_service.create_view(&token, params).await?; + Ok(view_rev) } #[tracing::instrument(level = "debug", skip(self), err)] @@ -269,14 +274,15 @@ impl ViewController { // TODO: Retry with RetryAction? tokio::spawn(async move { match server.read_view(&token, params).await { - Ok(Some(view)) => { + Ok(Some(view_rev)) => { match persistence - .begin_transaction(|transaction| transaction.create_view(view.clone())) + .begin_transaction(|transaction| transaction.create_view(view_rev.clone())) .await { Ok(_) => { + let view: View = view_rev.into(); send_dart_notification(&view.id, FolderNotification::ViewUpdated) - .payload(view.clone()) + .payload(view) .send(); } Err(e) => log::error!("Save view failed: {:?}", e), @@ -350,10 +356,10 @@ async fn handle_trash_event( TrashEvent::NewTrash(identifiers, ret) => { let result = persistence .begin_transaction(|transaction| { - let views = read_local_views_with_transaction(identifiers, &transaction)?; - for view in views { - let _ = notify_views_changed(&view.belong_to_id, trash_can.clone(), &transaction)?; - notify_dart(view, FolderNotification::ViewDeleted); + let view_revs = read_local_views_with_transaction(identifiers, &transaction)?; + for view_rev in view_revs { + let _ = notify_views_changed(&view_rev.belong_to_id, trash_can.clone(), &transaction)?; + notify_dart(view_rev.into(), FolderNotification::ViewDeleted); } Ok(()) }) @@ -363,10 +369,10 @@ async fn handle_trash_event( TrashEvent::Putback(identifiers, ret) => { let result = persistence .begin_transaction(|transaction| { - let views = read_local_views_with_transaction(identifiers, &transaction)?; - for view in views { - let _ = notify_views_changed(&view.belong_to_id, trash_can.clone(), &transaction)?; - notify_dart(view, FolderNotification::ViewRestored); + let view_revs = read_local_views_with_transaction(identifiers, &transaction)?; + for view_rev in view_revs { + let _ = notify_views_changed(&view_rev.belong_to_id, trash_can.clone(), &transaction)?; + notify_dart(view_rev.into(), FolderNotification::ViewRestored); } Ok(()) }) @@ -425,13 +431,12 @@ fn get_data_processor( fn read_local_views_with_transaction<'a>( identifiers: RepeatedTrashId, transaction: &'a (dyn FolderPersistenceTransaction + 'a), -) -> Result, FlowyError> { - let mut views = vec![]; +) -> Result, FlowyError> { + let mut view_revs = vec![]; for identifier in identifiers.items { - let view = transaction.read_view(&identifier.id)?; - views.push(view); + view_revs.push(transaction.read_view(&identifier.id)?); } - Ok(views) + Ok(view_revs) } fn notify_dart(view: View, notification: FolderNotification) { @@ -449,8 +454,13 @@ fn notify_views_changed<'a>( trash_controller: Arc, transaction: &'a (dyn FolderPersistenceTransaction + 'a), ) -> FlowyResult<()> { - let repeated_view = read_belonging_views_on_local(belong_to_id, trash_controller.clone(), transaction)?; - tracing::Span::current().record("view_count", &format!("{}", repeated_view.len()).as_str()); + let items: Vec = read_belonging_views_on_local(belong_to_id, trash_controller.clone(), transaction)? + .into_iter() + .map(|view_rev| view_rev.into()) + .collect(); + tracing::Span::current().record("view_count", &format!("{}", items.len()).as_str()); + + let repeated_view = RepeatedView { items }; send_dart_notification(belong_to_id, FolderNotification::AppViewsChanged) .payload(repeated_view) .send(); @@ -461,10 +471,10 @@ fn read_belonging_views_on_local<'a>( belong_to_id: &str, trash_controller: Arc, transaction: &'a (dyn FolderPersistenceTransaction + 'a), -) -> FlowyResult { - let mut views = transaction.read_views(belong_to_id)?; +) -> FlowyResult> { + let mut view_revs = transaction.read_views(belong_to_id)?; let trash_ids = trash_controller.read_trash_ids(transaction)?; - views.retain(|view_table| !trash_ids.contains(&view_table.id)); + view_revs.retain(|view_table| !trash_ids.contains(&view_table.id)); - Ok(RepeatedView { items: views }) + Ok(view_revs) } diff --git a/frontend/rust-lib/flowy-folder/src/services/view/event_handler.rs b/frontend/rust-lib/flowy-folder/src/services/view/event_handler.rs index caa8134785..3714578cf4 100644 --- a/frontend/rust-lib/flowy-folder/src/services/view/event_handler.rs +++ b/frontend/rust-lib/flowy-folder/src/services/view/event_handler.rs @@ -11,6 +11,8 @@ use crate::{ services::{TrashController, ViewController}, }; use flowy_folder_data_model::entities::view::{MoveFolderItemParams, MoveFolderItemPayload, MoveFolderItemType}; +use flowy_folder_data_model::entities::ViewInfo; +use flowy_folder_data_model::revision::TrashRevision; use lib_dispatch::prelude::{data_result, AppData, Data, DataResult}; use std::{convert::TryInto, sync::Arc}; @@ -19,8 +21,8 @@ pub(crate) async fn create_view_handler( controller: AppData>, ) -> DataResult { let params: CreateViewParams = data.into_inner().try_into()?; - let view = controller.create_view_from_params(params).await?; - data_result(view) + let view_rev = controller.create_view_from_params(params).await?; + data_result(view_rev.into()) } pub(crate) async fn read_view_handler( @@ -28,12 +30,18 @@ pub(crate) async fn read_view_handler( controller: AppData>, ) -> DataResult { let view_id: ViewId = data.into_inner(); - let mut view = controller.read_view(view_id.clone()).await?; + let view_rev = controller.read_view(view_id.clone()).await?; + data_result(view_rev.into()) +} + +pub(crate) async fn read_view_info_handler( + _data: Data, + _controller: AppData>, +) -> DataResult { // For the moment, app and view can contains lots of views. Reading the view // belongings using the view_id. - view.belongings = controller.read_views_belong_to(&view_id.value).await?; - - data_result(view) + // view.belongings = controller.read_views_belong_to(&view_id.value).await?; + todo!() } #[tracing::instrument(level = "debug", skip(data, controller), err)] @@ -61,7 +69,10 @@ pub(crate) async fn delete_view_handler( .read_local_views(params.items) .await? .into_iter() - .map(|view| view.into()) + .map(|view| { + let trash_rev: TrashRevision = view.into(); + trash_rev.into() + }) .collect::>(); let _ = trash_controller.add(trash).await?; diff --git a/frontend/rust-lib/flowy-folder/src/services/workspace/controller.rs b/frontend/rust-lib/flowy-folder/src/services/workspace/controller.rs index b343c5b46d..f1b4ab5289 100644 --- a/frontend/rust-lib/flowy-folder/src/services/workspace/controller.rs +++ b/frontend/rust-lib/flowy-folder/src/services/workspace/controller.rs @@ -9,7 +9,8 @@ use crate::{ }, }; use flowy_database::kv::KV; -use flowy_folder_data_model::entities::{app::RepeatedApp, workspace::*}; +use flowy_folder_data_model::entities::workspace::*; +use flowy_folder_data_model::revision::{AppRevision, WorkspaceRevision}; use std::sync::Arc; pub struct WorkspaceController { @@ -37,7 +38,7 @@ impl WorkspaceController { pub(crate) async fn create_workspace_from_params( &self, params: CreateWorkspaceParams, - ) -> Result { + ) -> Result { let workspace = self.create_workspace_on_server(params.clone()).await?; let user_id = self.user.user_id()?; let token = self.user.token()?; @@ -47,7 +48,10 @@ impl WorkspaceController { let _ = transaction.create_workspace(&user_id, workspace.clone())?; transaction.read_workspaces(&user_id, None) }) - .await?; + .await? + .into_iter() + .map(|workspace_rev| workspace_rev.into()) + .collect(); let repeated_workspace = RepeatedWorkspace { items: workspaces }; send_dart_notification(&token, FolderNotification::UserCreateWorkspace) .payload(repeated_workspace) @@ -109,16 +113,16 @@ impl WorkspaceController { } } - pub(crate) async fn read_current_workspace_apps(&self) -> Result { + pub(crate) async fn read_current_workspace_apps(&self) -> Result, FlowyError> { let workspace_id = get_current_workspace()?; - let repeated_app = self + let app_revs = self .persistence .begin_transaction(|transaction| { read_local_workspace_apps(&workspace_id, self.trash_controller.clone(), &transaction) }) .await?; // TODO: read from server - Ok(repeated_app) + Ok(app_revs) } #[tracing::instrument(level = "debug", skip(self, transaction), err)] @@ -129,7 +133,11 @@ impl WorkspaceController { transaction: &'a (dyn FolderPersistenceTransaction + 'a), ) -> Result { let workspace_id = workspace_id.to_owned(); - let workspaces = transaction.read_workspaces(user_id, workspace_id)?; + let workspaces = transaction + .read_workspaces(user_id, workspace_id)? + .into_iter() + .map(|workspace_rev| workspace_rev.into()) + .collect(); Ok(RepeatedWorkspace { items: workspaces }) } @@ -139,22 +147,26 @@ impl WorkspaceController { user_id: &str, transaction: &'a (dyn FolderPersistenceTransaction + 'a), ) -> Result { - let mut workspaces = transaction.read_workspaces(user_id, Some(workspace_id.clone()))?; - if workspaces.is_empty() { + let mut workspace_revs = transaction.read_workspaces(user_id, Some(workspace_id.clone()))?; + if workspace_revs.is_empty() { return Err(FlowyError::record_not_found().context(format!("{} workspace not found", workspace_id))); } - debug_assert_eq!(workspaces.len(), 1); - let workspace = workspaces.drain(..1).collect::>().pop().unwrap(); + debug_assert_eq!(workspace_revs.len(), 1); + let workspace = workspace_revs + .drain(..1) + .map(|workspace_rev| workspace_rev.into()) + .collect::>() + .pop() + .unwrap(); Ok(workspace) } } impl WorkspaceController { #[tracing::instrument(level = "trace", skip(self), err)] - async fn create_workspace_on_server(&self, params: CreateWorkspaceParams) -> Result { + async fn create_workspace_on_server(&self, params: CreateWorkspaceParams) -> Result { let token = self.user.token()?; - let workspace = self.cloud_service.create_workspace(&token, params).await?; - Ok(workspace) + self.cloud_service.create_workspace(&token, params).await } #[tracing::instrument(level = "trace", skip(self), err)] @@ -211,7 +223,7 @@ pub async fn notify_workspace_setting_did_change( let setting = match transaction.read_view(view_id) { Ok(latest_view) => CurrentWorkspaceSetting { workspace, - latest_view: Some(latest_view), + latest_view: Some(latest_view.into()), }, Err(_) => CurrentWorkspaceSetting { workspace, diff --git a/frontend/rust-lib/flowy-folder/src/services/workspace/event_handler.rs b/frontend/rust-lib/flowy-folder/src/services/workspace/event_handler.rs index d274e42f7f..3760d06bf6 100644 --- a/frontend/rust-lib/flowy-folder/src/services/workspace/event_handler.rs +++ b/frontend/rust-lib/flowy-folder/src/services/workspace/event_handler.rs @@ -9,7 +9,6 @@ use flowy_folder_data_model::entities::{ view::View, workspace::{CurrentWorkspaceSetting, RepeatedWorkspace, WorkspaceId, *}, }; - use lib_dispatch::prelude::{data_result, AppData, Data, DataResult}; use std::{convert::TryInto, sync::Arc}; @@ -20,15 +19,21 @@ pub(crate) async fn create_workspace_handler( ) -> DataResult { let controller = controller.get_ref().clone(); let params: CreateWorkspaceParams = data.into_inner().try_into()?; - let detail = controller.create_workspace_from_params(params).await?; - data_result(detail) + let workspace_rev = controller.create_workspace_from_params(params).await?; + data_result(workspace_rev.into()) } #[tracing::instrument(level = "debug", skip(controller), err)] pub(crate) async fn read_workspace_apps_handler( controller: AppData>, ) -> DataResult { - let repeated_app = controller.read_current_workspace_apps().await?; + let items = controller + .read_current_workspace_apps() + .await? + .into_iter() + .map(|app_rev| app_rev.into()) + .collect(); + let repeated_app = RepeatedApp { items }; data_result(repeated_app) } @@ -58,8 +63,10 @@ pub(crate) async fn read_workspaces_handler( let mut workspaces = workspace_controller.read_local_workspaces(params.value.clone(), &user_id, &transaction)?; for workspace in workspaces.iter_mut() { - let apps = - read_local_workspace_apps(&workspace.id, trash_controller.clone(), &transaction)?.into_inner(); + let apps = read_local_workspace_apps(&workspace.id, trash_controller.clone(), &transaction)? + .into_iter() + .map(|app_rev| app_rev.into()) + .collect(); workspace.apps.items = apps; } Ok(workspaces) @@ -88,7 +95,12 @@ pub async fn read_cur_workspace_handler( }) .await?; - let latest_view: Option = folder.view_controller.latest_visit_view().await.unwrap_or(None); + let latest_view: Option = folder + .view_controller + .latest_visit_view() + .await + .unwrap_or(None) + .map(|view_rev| view_rev.into()); let setting = CurrentWorkspaceSetting { workspace, latest_view }; let _ = read_workspaces_on_server(folder, user_id, params); data_result(setting) @@ -104,25 +116,25 @@ fn read_workspaces_on_server( let persistence = folder_manager.persistence.clone(); tokio::spawn(async move { - let workspaces = server.read_workspace(&token, params).await?; + let workspace_revs = server.read_workspace(&token, params).await?; let _ = persistence .begin_transaction(|transaction| { - tracing::trace!("Save {} workspace", workspaces.len()); - for workspace in &workspaces.items { - let m_workspace = workspace.clone(); - let apps = m_workspace.apps.clone().into_inner(); + tracing::trace!("Save {} workspace", workspace_revs.len()); + for workspace_rev in &workspace_revs { + let m_workspace = workspace_rev.clone(); + let app_revs = m_workspace.apps.clone(); let _ = transaction.create_workspace(&user_id, m_workspace)?; - tracing::trace!("Save {} apps", apps.len()); - for app in apps { - let views = app.belongings.clone().into_inner(); - match transaction.create_app(app) { + tracing::trace!("Save {} apps", app_revs.len()); + for app_rev in app_revs { + let view_revs = app_rev.belongings.clone(); + match transaction.create_app(app_rev) { Ok(_) => {} Err(e) => log::error!("create app failed: {:?}", e), } - tracing::trace!("Save {} views", views.len()); - for view in views { - match transaction.create_view(view) { + tracing::trace!("Save {} views", view_revs.len()); + for view_rev in view_revs { + match transaction.create_view(view_rev) { Ok(_) => {} Err(e) => log::error!("create view failed: {:?}", e), } @@ -133,8 +145,15 @@ fn read_workspaces_on_server( }) .await?; + let repeated_workspace = RepeatedWorkspace { + items: workspace_revs + .into_iter() + .map(|workspace_rev| workspace_rev.into()) + .collect(), + }; + send_dart_notification(&token, FolderNotification::WorkspaceListUpdated) - .payload(workspaces) + .payload(repeated_workspace) .send(); Result::<(), FlowyError>::Ok(()) }); diff --git a/frontend/rust-lib/flowy-folder/tests/workspace/folder_test.rs b/frontend/rust-lib/flowy-folder/tests/workspace/folder_test.rs index b9fc8c2585..9eaee19b61 100644 --- a/frontend/rust-lib/flowy-folder/tests/workspace/folder_test.rs +++ b/frontend/rust-lib/flowy-folder/tests/workspace/folder_test.rs @@ -1,7 +1,7 @@ use crate::script::{invalid_workspace_name_test_case, FolderScript::*, FolderTest}; use flowy_folder::entities::workspace::CreateWorkspacePayload; use flowy_folder_data_model::entities::view::ViewDataType; -use flowy_folder_data_model::revision::{AppRevision, WorkspaceRevision}; + use flowy_revision::disk::RevisionState; use flowy_test::{event_builder::*, FlowySDKTest}; @@ -38,12 +38,9 @@ async fn workspace_create() { async fn workspace_read() { let mut test = FolderTest::new().await; let workspace = test.workspace.clone(); - let workspace_revision: WorkspaceRevision = workspace.clone().into(); - let json = serde_json::to_string(&workspace_revision).unwrap(); test.run_scripts(vec![ ReadWorkspace(Some(workspace.id.clone())), - AssertWorkspaceRevisionJson(json), AssertWorkspace(workspace), ]) .await; @@ -59,10 +56,7 @@ async fn workspace_create_with_apps() { .await; let app = test.app.clone(); - let app_revision: AppRevision = app.clone().into(); - let json = serde_json::to_string(&app_revision).unwrap(); - test.run_scripts(vec![ReadApp(app.id), AssertAppRevisionJson(json)]) - .await; + test.run_scripts(vec![ReadApp(app.id)]).await; } #[tokio::test] @@ -346,7 +340,6 @@ async fn folder_sync_revision_with_new_view() { let view = test.view.clone(); assert_eq!(view.name, view_name); - assert_eq!(view.desc, view_desc); test.run_scripts(vec![ReadView(view.id.clone()), AssertView(view)]) .await; } diff --git a/frontend/rust-lib/flowy-folder/tests/workspace/script.rs b/frontend/rust-lib/flowy-folder/tests/workspace/script.rs index e4fcc78fa4..e8303f9c42 100644 --- a/frontend/rust-lib/flowy-folder/tests/workspace/script.rs +++ b/frontend/rust-lib/flowy-folder/tests/workspace/script.rs @@ -14,7 +14,7 @@ use flowy_folder_data_model::entities::{ view::{CreateViewPayload, UpdateViewPayload}, workspace::{CreateWorkspacePayload, RepeatedWorkspace}, }; -use flowy_folder_data_model::revision::{AppRevision, WorkspaceRevision}; + use flowy_revision::disk::RevisionState; use flowy_revision::REVISION_WRITE_INTERVAL_IN_MILLIS; use flowy_sync::entities::text_block_info::TextBlockInfo; @@ -29,7 +29,7 @@ pub enum FolderScript { name: String, desc: String, }, - AssertWorkspaceRevisionJson(String), + // AssertWorkspaceRevisionJson(String), AssertWorkspace(Workspace), ReadWorkspace(Option), @@ -38,7 +38,7 @@ pub enum FolderScript { name: String, desc: String, }, - AssertAppRevisionJson(String), + // AssertAppRevisionJson(String), AssertApp(App), ReadApp(String), UpdateApp { @@ -139,15 +139,15 @@ impl FolderTest { let workspace = create_workspace(sdk, &name, &desc).await; self.workspace = workspace; } - FolderScript::AssertWorkspaceRevisionJson(expected_json) => { - let workspace = read_workspace(sdk, Some(self.workspace.id.clone())) - .await - .pop() - .unwrap(); - let workspace_revision: WorkspaceRevision = workspace.into(); - let json = serde_json::to_string(&workspace_revision).unwrap(); - assert_eq!(json, expected_json); - } + // FolderScript::AssertWorkspaceRevisionJson(expected_json) => { + // let workspace = read_workspace(sdk, Some(self.workspace.id.clone())) + // .await + // .pop() + // .unwrap(); + // let workspace_revision: WorkspaceRevision = workspace.into(); + // let json = serde_json::to_string(&workspace_revision).unwrap(); + // assert_eq!(json, expected_json); + // } FolderScript::AssertWorkspace(workspace) => { assert_eq!(self.workspace, workspace); } @@ -159,11 +159,11 @@ impl FolderTest { let app = create_app(sdk, &self.workspace.id, &name, &desc).await; self.app = app; } - FolderScript::AssertAppRevisionJson(expected_json) => { - let app_revision: AppRevision = self.app.clone().into(); - let json = serde_json::to_string(&app_revision).unwrap(); - assert_eq!(json, expected_json); - } + // FolderScript::AssertAppRevisionJson(expected_json) => { + // let app_revision: AppRevision = self.app.clone().into(); + // let json = serde_json::to_string(&app_revision).unwrap(); + // assert_eq!(json, expected_json); + // } FolderScript::AssertApp(app) => { assert_eq!(self.app, app); } diff --git a/frontend/rust-lib/flowy-net/src/http_server/folder.rs b/frontend/rust-lib/flowy-net/src/http_server/folder.rs index e70d690bb7..9781ea727a 100644 --- a/frontend/rust-lib/flowy-net/src/http_server/folder.rs +++ b/frontend/rust-lib/flowy-net/src/http_server/folder.rs @@ -4,13 +4,14 @@ use crate::{ }; use flowy_error::FlowyError; use flowy_folder_data_model::entities::{ - app::{App, AppId, CreateAppParams, UpdateAppParams}, - trash::{RepeatedTrash, RepeatedTrashId}, - view::{CreateViewParams, RepeatedViewId, UpdateViewParams, View, ViewId}, - workspace::{CreateWorkspaceParams, RepeatedWorkspace, UpdateWorkspaceParams, Workspace, WorkspaceId}, + trash::RepeatedTrashId, + view::{CreateViewParams, RepeatedViewId, UpdateViewParams, ViewId}, + workspace::{CreateWorkspaceParams, UpdateWorkspaceParams, WorkspaceId}, + {AppId, CreateAppParams, UpdateAppParams}, }; use flowy_folder::event_map::FolderCouldServiceV1; +use flowy_folder_data_model::revision::{AppRevision, TrashRevision, ViewRevision, WorkspaceRevision}; use http_flowy::errors::ServerError; use http_flowy::response::FlowyResponse; use lazy_static::lazy_static; @@ -31,7 +32,11 @@ impl FolderHttpCloudService { impl FolderCouldServiceV1 for FolderHttpCloudService { fn init(&self) {} - fn create_workspace(&self, token: &str, params: CreateWorkspaceParams) -> FutureResult { + fn create_workspace( + &self, + token: &str, + params: CreateWorkspaceParams, + ) -> FutureResult { let token = token.to_owned(); let url = self.config.workspace_url(); FutureResult::new(async move { @@ -40,12 +45,12 @@ impl FolderCouldServiceV1 for FolderHttpCloudService { }) } - fn read_workspace(&self, token: &str, params: WorkspaceId) -> FutureResult { + fn read_workspace(&self, token: &str, params: WorkspaceId) -> FutureResult, FlowyError> { let token = token.to_owned(); let url = self.config.workspace_url(); FutureResult::new(async move { - let repeated_workspace = read_workspaces_request(&token, params, &url).await?; - Ok(repeated_workspace) + let workspace_revs = read_workspaces_request(&token, params, &url).await?; + Ok(workspace_revs) }) } @@ -67,7 +72,7 @@ impl FolderCouldServiceV1 for FolderHttpCloudService { }) } - fn create_view(&self, token: &str, params: CreateViewParams) -> FutureResult { + fn create_view(&self, token: &str, params: CreateViewParams) -> FutureResult { let token = token.to_owned(); let url = self.config.view_url(); FutureResult::new(async move { @@ -76,12 +81,12 @@ impl FolderCouldServiceV1 for FolderHttpCloudService { }) } - fn read_view(&self, token: &str, params: ViewId) -> FutureResult, FlowyError> { + fn read_view(&self, token: &str, params: ViewId) -> FutureResult, FlowyError> { let token = token.to_owned(); let url = self.config.view_url(); FutureResult::new(async move { - let view = read_view_request(&token, params, &url).await?; - Ok(view) + let view_rev = read_view_request(&token, params, &url).await?; + Ok(view_rev) }) } @@ -103,7 +108,7 @@ impl FolderCouldServiceV1 for FolderHttpCloudService { }) } - fn create_app(&self, token: &str, params: CreateAppParams) -> FutureResult { + fn create_app(&self, token: &str, params: CreateAppParams) -> FutureResult { let token = token.to_owned(); let url = self.config.app_url(); FutureResult::new(async move { @@ -112,12 +117,12 @@ impl FolderCouldServiceV1 for FolderHttpCloudService { }) } - fn read_app(&self, token: &str, params: AppId) -> FutureResult, FlowyError> { + fn read_app(&self, token: &str, params: AppId) -> FutureResult, FlowyError> { let token = token.to_owned(); let url = self.config.app_url(); FutureResult::new(async move { - let app = read_app_request(&token, params, &url).await?; - Ok(app) + let app_rev = read_app_request(&token, params, &url).await?; + Ok(app_rev) }) } @@ -157,7 +162,7 @@ impl FolderCouldServiceV1 for FolderHttpCloudService { }) } - fn read_trash(&self, token: &str) -> FutureResult { + fn read_trash(&self, token: &str) -> FutureResult, FlowyError> { let token = token.to_owned(); let url = self.config.trash_url(); FutureResult::new(async move { @@ -172,32 +177,34 @@ fn request_builder() -> HttpRequestBuilder { } pub async fn create_workspace_request( - token: &str, - params: CreateWorkspaceParams, - url: &str, -) -> Result { - let workspace = request_builder() - .post(&url.to_owned()) - .header(HEADER_TOKEN, token) - .protobuf(params)? - .response() - .await?; - Ok(workspace) + _token: &str, + _params: CreateWorkspaceParams, + _url: &str, +) -> Result { + // let workspace = request_builder() + // .post(&url.to_owned()) + // .header(HEADER_TOKEN, token) + // .protobuf(params)? + // .response() + // .await?; + // Ok(workspace) + unimplemented!() } pub async fn read_workspaces_request( - token: &str, - params: WorkspaceId, - url: &str, -) -> Result { - let repeated_workspace = request_builder() - .get(&url.to_owned()) - .header(HEADER_TOKEN, token) - .protobuf(params)? - .response::() - .await?; - - Ok(repeated_workspace) + _token: &str, + _params: WorkspaceId, + _url: &str, +) -> Result, ServerError> { + // let repeated_workspace = request_builder() + // .get(&url.to_owned()) + // .header(HEADER_TOKEN, token) + // .protobuf(params)? + // .response::() + // .await?; + // + // Ok(repeated_workspace) + unimplemented!() } pub async fn update_workspace_request( @@ -225,25 +232,31 @@ pub async fn delete_workspace_request(token: &str, params: WorkspaceId, url: &st } // App -pub async fn create_app_request(token: &str, params: CreateAppParams, url: &str) -> Result { - let app = request_builder() - .post(&url.to_owned()) - .header(HEADER_TOKEN, token) - .protobuf(params)? - .response() - .await?; - Ok(app) +pub async fn create_app_request( + _token: &str, + _params: CreateAppParams, + _url: &str, +) -> Result { + // let app = request_builder() + // .post(&url.to_owned()) + // .header(HEADER_TOKEN, token) + // .protobuf(params)? + // .response() + // .await?; + // Ok(app) + unimplemented!() } -pub async fn read_app_request(token: &str, params: AppId, url: &str) -> Result, ServerError> { - let app = request_builder() - .get(&url.to_owned()) - .header(HEADER_TOKEN, token) - .protobuf(params)? - .option_response() - .await?; +pub async fn read_app_request(_token: &str, _params: AppId, _url: &str) -> Result, ServerError> { + // let app = request_builder() + // .get(&url.to_owned()) + // .header(HEADER_TOKEN, token) + // .protobuf(params)? + // .option_response() + // .await?; + // Ok(app) - Ok(app) + unimplemented!() } pub async fn update_app_request(token: &str, params: UpdateAppParams, url: &str) -> Result<(), ServerError> { @@ -267,25 +280,31 @@ pub async fn delete_app_request(token: &str, params: AppId, url: &str) -> Result } // View -pub async fn create_view_request(token: &str, params: CreateViewParams, url: &str) -> Result { - let view = request_builder() - .post(&url.to_owned()) - .header(HEADER_TOKEN, token) - .protobuf(params)? - .response() - .await?; - Ok(view) +pub async fn create_view_request( + _token: &str, + _params: CreateViewParams, + _url: &str, +) -> Result { + // let view = request_builder() + // .post(&url.to_owned()) + // .header(HEADER_TOKEN, token) + // .protobuf(params)? + // .response() + // .await?; + // Ok(view) + unimplemented!() } -pub async fn read_view_request(token: &str, params: ViewId, url: &str) -> Result, ServerError> { - let view = request_builder() - .get(&url.to_owned()) - .header(HEADER_TOKEN, token) - .protobuf(params)? - .option_response() - .await?; - - Ok(view) +pub async fn read_view_request(_token: &str, _params: ViewId, _url: &str) -> Result, ServerError> { + // let view = request_builder() + // .get(&url.to_owned()) + // .header(HEADER_TOKEN, token) + // .protobuf(params)? + // .option_response() + // .await?; + // + // Ok(view) + unimplemented!() } pub async fn update_view_request(token: &str, params: UpdateViewParams, url: &str) -> Result<(), ServerError> { @@ -328,13 +347,14 @@ pub async fn delete_trash_request(token: &str, params: RepeatedTrashId, url: &st Ok(()) } -pub async fn read_trash_request(token: &str, url: &str) -> Result { - let repeated_trash = request_builder() - .get(&url.to_owned()) - .header(HEADER_TOKEN, token) - .response::() - .await?; - Ok(repeated_trash) +pub async fn read_trash_request(_token: &str, _url: &str) -> Result, ServerError> { + // let repeated_trash = request_builder() + // .get(&url.to_owned()) + // .header(HEADER_TOKEN, token) + // .response::() + // .await?; + // Ok(repeated_trash) + unimplemented!() } lazy_static! { diff --git a/frontend/rust-lib/flowy-net/src/local_server/server.rs b/frontend/rust-lib/flowy-net/src/local_server/server.rs index c9a6d20cf3..87f4f46f4e 100644 --- a/frontend/rust-lib/flowy-net/src/local_server/server.rs +++ b/frontend/rust-lib/flowy-net/src/local_server/server.rs @@ -255,11 +255,12 @@ impl RevisionUser for LocalRevisionUser { use flowy_folder_data_model::entities::app::gen_app_id; use flowy_folder_data_model::entities::workspace::gen_workspace_id; use flowy_folder_data_model::entities::{ - app::{App, AppId, CreateAppParams, RepeatedApp, UpdateAppParams}, - trash::{RepeatedTrash, RepeatedTrashId}, - view::{CreateViewParams, RepeatedView, RepeatedViewId, UpdateViewParams, View, ViewId}, - workspace::{CreateWorkspaceParams, RepeatedWorkspace, UpdateWorkspaceParams, Workspace, WorkspaceId}, + app::{AppId, CreateAppParams, UpdateAppParams}, + trash::RepeatedTrashId, + view::{CreateViewParams, RepeatedViewId, UpdateViewParams, ViewId}, + workspace::{CreateWorkspaceParams, UpdateWorkspaceParams, WorkspaceId}, }; +use flowy_folder_data_model::revision::{AppRevision, TrashRevision, ViewRevision, WorkspaceRevision}; use flowy_text_block::BlockCloudService; use flowy_user::event_map::UserCloudService; use flowy_user_data_model::entities::{ @@ -270,13 +271,17 @@ use lib_infra::{future::FutureResult, util::timestamp}; impl FolderCouldServiceV1 for LocalServer { fn init(&self) {} - fn create_workspace(&self, _token: &str, params: CreateWorkspaceParams) -> FutureResult { + fn create_workspace( + &self, + _token: &str, + params: CreateWorkspaceParams, + ) -> FutureResult { let time = timestamp(); - let workspace = Workspace { + let workspace = WorkspaceRevision { id: gen_workspace_id(), name: params.name, desc: params.desc, - apps: RepeatedApp::default(), + apps: vec![], modified_time: time, create_time: time, }; @@ -284,11 +289,8 @@ impl FolderCouldServiceV1 for LocalServer { FutureResult::new(async { Ok(workspace) }) } - fn read_workspace(&self, _token: &str, _params: WorkspaceId) -> FutureResult { - FutureResult::new(async { - let repeated_workspace = RepeatedWorkspace { items: vec![] }; - Ok(repeated_workspace) - }) + fn read_workspace(&self, _token: &str, _params: WorkspaceId) -> FutureResult, FlowyError> { + FutureResult::new(async { Ok(vec![]) }) } fn update_workspace(&self, _token: &str, _params: UpdateWorkspaceParams) -> FutureResult<(), FlowyError> { @@ -299,16 +301,16 @@ impl FolderCouldServiceV1 for LocalServer { FutureResult::new(async { Ok(()) }) } - fn create_view(&self, _token: &str, params: CreateViewParams) -> FutureResult { + fn create_view(&self, _token: &str, params: CreateViewParams) -> FutureResult { let time = timestamp(); - let view = View { + let view = ViewRevision { id: params.view_id, belong_to_id: params.belong_to_id, name: params.name, desc: params.desc, data_type: params.data_type, version: 0, - belongings: RepeatedView::default(), + belongings: vec![], modified_time: time, create_time: time, ext_data: "".to_string(), @@ -318,7 +320,7 @@ impl FolderCouldServiceV1 for LocalServer { FutureResult::new(async { Ok(view) }) } - fn read_view(&self, _token: &str, _params: ViewId) -> FutureResult, FlowyError> { + fn read_view(&self, _token: &str, _params: ViewId) -> FutureResult, FlowyError> { FutureResult::new(async { Ok(None) }) } @@ -330,14 +332,14 @@ impl FolderCouldServiceV1 for LocalServer { FutureResult::new(async { Ok(()) }) } - fn create_app(&self, _token: &str, params: CreateAppParams) -> FutureResult { + fn create_app(&self, _token: &str, params: CreateAppParams) -> FutureResult { let time = timestamp(); - let app = App { + let app = AppRevision { id: gen_app_id(), workspace_id: params.workspace_id, name: params.name, desc: params.desc, - belongings: RepeatedView::default(), + belongings: vec![], version: 0, modified_time: time, create_time: time, @@ -345,7 +347,7 @@ impl FolderCouldServiceV1 for LocalServer { FutureResult::new(async { Ok(app) }) } - fn read_app(&self, _token: &str, _params: AppId) -> FutureResult, FlowyError> { + fn read_app(&self, _token: &str, _params: AppId) -> FutureResult, FlowyError> { FutureResult::new(async { Ok(None) }) } @@ -365,17 +367,14 @@ impl FolderCouldServiceV1 for LocalServer { FutureResult::new(async { Ok(()) }) } - fn read_trash(&self, _token: &str) -> FutureResult { - FutureResult::new(async { - let repeated_trash = RepeatedTrash { items: vec![] }; - Ok(repeated_trash) - }) + fn read_trash(&self, _token: &str) -> FutureResult, FlowyError> { + FutureResult::new(async { Ok(vec![]) }) } } impl UserCloudService for LocalServer { fn sign_up(&self, params: SignUpParams) -> FutureResult { - let uid = nanoid!(10); + let uid = nanoid!(20); FutureResult::new(async move { Ok(SignUpResponse { user_id: uid.clone(), @@ -387,7 +386,7 @@ impl UserCloudService for LocalServer { } fn sign_in(&self, params: SignInParams) -> FutureResult { - let user_id = nanoid!(10); + let user_id = nanoid!(20); FutureResult::new(async { Ok(SignInResponse { user_id: user_id.clone(), diff --git a/frontend/rust-lib/flowy-test/src/helper.rs b/frontend/rust-lib/flowy-test/src/helper.rs index d840069ca0..2bb9622914 100644 --- a/frontend/rust-lib/flowy-test/src/helper.rs +++ b/frontend/rust-lib/flowy-test/src/helper.rs @@ -126,7 +126,7 @@ pub fn root_dir() -> String { } pub fn random_email() -> String { - format!("{}@appflowy.io", nanoid!(10)) + format!("{}@appflowy.io", nanoid!(20)) } pub fn login_email() -> String { @@ -163,8 +163,9 @@ pub fn sign_up(dispatch: Arc) -> SignUpContext { pub async fn async_sign_up(dispatch: Arc) -> SignUpContext { let password = login_password(); + let email = random_email(); let payload = SignUpPayload { - email: random_email(), + email, name: "app flowy".to_string(), password: password.clone(), } diff --git a/frontend/rust-lib/flowy-user/src/services/database.rs b/frontend/rust-lib/flowy-user/src/services/database.rs index f3ddf48fa5..f46d86ad5e 100644 --- a/frontend/rust-lib/flowy-user/src/services/database.rs +++ b/frontend/rust-lib/flowy-user/src/services/database.rs @@ -3,8 +3,7 @@ use flowy_database::{schema::user_table, DBConnection, Database}; use flowy_error::{ErrorCode, FlowyError}; use flowy_user_data_model::entities::{SignInResponse, SignUpResponse, UpdateUserParams, UserProfile}; use lazy_static::lazy_static; -use once_cell::sync::Lazy; -use parking_lot::{Mutex, RwLock}; +use parking_lot::RwLock; use std::{collections::HashMap, sync::Arc, time::Duration}; lazy_static! { @@ -22,32 +21,38 @@ impl UserDB { } } - fn open_user_db(&self, user_id: &str) -> Result<(), FlowyError> { + fn open_user_db_if_need(&self, user_id: &str) -> Result, FlowyError> { if user_id.is_empty() { return Err(ErrorCode::UserIdIsEmpty.into()); } + if let Some(database) = DB_MAP.read().get(user_id) { + return Ok(database.get_pool()); + } + + let mut write_guard = DB_MAP.write(); + // The Write guard acquire exclusive access that will guarantee the user db only initialize once. + match write_guard.get(user_id) { + None => {} + Some(database) => return Ok(database.get_pool()), + } + tracing::trace!("open user db {}", user_id); let dir = format!("{}/{}", self.db_dir, user_id); let db = flowy_database::init(&dir).map_err(|e| { - log::error!("init user db failed, {:?}, user_id: {}", e, user_id); + log::error!("open user: {} db failed, {:?}", user_id, e); FlowyError::internal().context(e) })?; - - match DB_MAP.try_write_for(Duration::from_millis(300)) { - None => Err(FlowyError::internal().context("Acquire write lock to save user db failed")), - Some(mut write_guard) => { - write_guard.insert(user_id.to_owned(), db); - Ok(()) - } - } + let pool = db.get_pool(); + write_guard.insert(user_id.to_owned(), db); + drop(write_guard); + Ok(pool) } pub(crate) fn close_user_db(&self, user_id: &str) -> Result<(), FlowyError> { match DB_MAP.try_write_for(Duration::from_millis(300)) { None => Err(FlowyError::internal().context("Acquire write lock to close user db failed")), Some(mut write_guard) => { - set_user_db_init(false, user_id); write_guard.remove(user_id); Ok(()) } @@ -60,27 +65,8 @@ impl UserDB { } pub(crate) fn get_pool(&self, user_id: &str) -> Result, FlowyError> { - // Opti: INIT_LOCK try to lock the INIT_RECORD accesses. Because the write guard - // can not nested in the read guard that will cause the deadlock. - match INIT_LOCK.try_lock_for(Duration::from_millis(300)) { - None => log::error!("get_pool fail"), - Some(_) => { - if !is_user_db_init(user_id) { - let _ = self.open_user_db(user_id)?; - set_user_db_init(true, user_id); - } - } - } - - match DB_MAP.try_read_for(Duration::from_millis(300)) { - None => Err(FlowyError::internal().context("Acquire read lock to read user db failed")), - Some(read_guard) => match read_guard.get(user_id) { - None => { - Err(FlowyError::internal().context("Get connection failed. The database is not initialization")) - } - Some(database) => Ok(database.get_pool()), - }, - } + let pool = self.open_user_db_if_need(user_id)?; + Ok(pool) } } @@ -88,20 +74,6 @@ lazy_static! { static ref DB_MAP: RwLock> = RwLock::new(HashMap::new()); } -static INIT_LOCK: Lazy> = Lazy::new(|| Mutex::new(())); -static INIT_RECORD: Lazy>> = Lazy::new(|| Mutex::new(HashMap::new())); -fn set_user_db_init(is_init: bool, user_id: &str) { - let mut record = INIT_RECORD.lock(); - record.insert(user_id.to_owned(), is_init); -} - -fn is_user_db_init(user_id: &str) -> bool { - match INIT_RECORD.lock().get(user_id) { - None => false, - Some(flag) => *flag, - } -} - #[derive(Clone, Default, Queryable, Identifiable, Insertable)] #[table_name = "user_table"] pub struct UserTable { diff --git a/shared-lib/flowy-folder-data-model/src/entities/app.rs b/shared-lib/flowy-folder-data-model/src/entities/app.rs index cdf4c8fa69..87983320d2 100644 --- a/shared-lib/flowy-folder-data-model/src/entities/app.rs +++ b/shared-lib/flowy-folder-data-model/src/entities/app.rs @@ -15,7 +15,7 @@ use std::convert::TryInto; pub fn gen_app_id() -> String { nanoid!(10) } -#[derive(Eq, PartialEq, ProtoBuf, Default, Debug, Clone)] +#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)] pub struct App { #[pb(index = 1)] pub id: String, diff --git a/shared-lib/flowy-folder-data-model/src/entities/trash.rs b/shared-lib/flowy-folder-data-model/src/entities/trash.rs index bd9d101cb4..68b3d0a26e 100644 --- a/shared-lib/flowy-folder-data-model/src/entities/trash.rs +++ b/shared-lib/flowy-folder-data-model/src/entities/trash.rs @@ -1,4 +1,5 @@ -use crate::{entities::app::App, impl_def_and_def_mut}; +use crate::impl_def_and_def_mut; +use crate::revision::TrashRevision; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use serde::{Deserialize, Serialize}; use std::fmt::Formatter; @@ -29,18 +30,6 @@ pub struct RepeatedTrash { impl_def_and_def_mut!(RepeatedTrash, Trash); -impl std::convert::From for Trash { - fn from(app: App) -> Self { - Trash { - id: app.id, - name: app.name, - modified_time: app.modified_time, - create_time: app.create_time, - ty: TrashType::TrashApp, - } - } -} - #[derive(Eq, PartialEq, Debug, ProtoBuf_Enum, Clone, Serialize, Deserialize)] pub enum TrashType { Unknown = 0, @@ -103,8 +92,8 @@ impl std::convert::From> for RepeatedTrashId { } } -impl std::convert::From> for RepeatedTrashId { - fn from(trash: Vec) -> Self { +impl std::convert::From> for RepeatedTrashId { + fn from(trash: Vec) -> Self { let items = trash .into_iter() .map(|t| TrashId { id: t.id, ty: t.ty }) @@ -126,15 +115,6 @@ pub struct TrashId { pub ty: TrashType, } -impl std::convert::From<&Trash> for TrashId { - fn from(trash: &Trash) -> Self { - TrashId { - id: trash.id.clone(), - ty: trash.ty.clone(), - } - } -} - impl std::fmt::Display for TrashId { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.write_str(&format!("{:?}:{}", self.ty, self.id)) diff --git a/shared-lib/flowy-folder-data-model/src/entities/view.rs b/shared-lib/flowy-folder-data-model/src/entities/view.rs index 7b29bd6c37..affe373caf 100644 --- a/shared-lib/flowy-folder-data-model/src/entities/view.rs +++ b/shared-lib/flowy-folder-data-model/src/entities/view.rs @@ -1,5 +1,4 @@ use crate::{ - entities::trash::{Trash, TrashType}, errors::ErrorCode, impl_def_and_def_mut, parser::{ @@ -17,7 +16,7 @@ pub fn gen_view_id() -> String { nanoid!(10) } -#[derive(Eq, PartialEq, ProtoBuf, Default, Debug, Clone)] +#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)] pub struct View { #[pb(index = 1)] pub id: String, @@ -28,6 +27,30 @@ pub struct View { #[pb(index = 3)] pub name: String, + #[pb(index = 4)] + pub data_type: ViewDataType, + + #[pb(index = 5)] + pub modified_time: i64, + + #[pb(index = 6)] + pub create_time: i64, + + #[pb(index = 7)] + pub plugin_type: i32, +} + +#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)] +pub struct ViewInfo { + #[pb(index = 1)] + pub id: String, + + #[pb(index = 2)] + pub belong_to_id: String, + + #[pb(index = 3)] + pub name: String, + #[pb(index = 4)] pub desc: String, @@ -35,25 +58,43 @@ pub struct View { pub data_type: ViewDataType, #[pb(index = 6)] - pub version: i64, - - #[pb(index = 7)] pub belongings: RepeatedView, - #[pb(index = 8)] - pub modified_time: i64, + #[pb(index = 7)] + pub ext_data: ViewExtData, +} - #[pb(index = 9)] - pub create_time: i64, +#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)] +pub struct ViewExtData { + #[pb(index = 1)] + pub filter: ViewFilter, - #[pb(index = 10)] - pub ext_data: String, + #[pb(index = 2)] + pub group: ViewGroup, - #[pb(index = 11)] - pub thumbnail: String, + #[pb(index = 3)] + pub sort: ViewSort, +} - #[pb(index = 12)] - pub plugin_type: i32, +#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)] +pub struct ViewFilter { + #[pb(index = 1)] + pub field_id: String, +} + +#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)] +pub struct ViewGroup { + #[pb(index = 1)] + pub group_field_id: String, + + #[pb(index = 2, one_of)] + pub sub_group_field_id: Option, +} + +#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)] +pub struct ViewSort { + #[pb(index = 1)] + pub field_id: String, } #[derive(Eq, PartialEq, Debug, Default, ProtoBuf, Clone)] @@ -65,18 +106,6 @@ pub struct RepeatedView { impl_def_and_def_mut!(RepeatedView, View); -impl std::convert::From for Trash { - fn from(view: View) -> Self { - Trash { - id: view.id, - name: view.name, - modified_time: view.modified_time, - create_time: view.create_time, - ty: TrashType::TrashView, - } - } -} - #[derive(Eq, PartialEq, Hash, Debug, ProtoBuf_Enum, Clone, Serialize_repr, Deserialize_repr)] #[repr(u8)] pub enum ViewDataType { diff --git a/shared-lib/flowy-folder-data-model/src/protobuf/model/view.rs b/shared-lib/flowy-folder-data-model/src/protobuf/model/view.rs index 3b119c3bc1..2954cfa693 100644 --- a/shared-lib/flowy-folder-data-model/src/protobuf/model/view.rs +++ b/shared-lib/flowy-folder-data-model/src/protobuf/model/view.rs @@ -29,14 +29,9 @@ pub struct View { pub id: ::std::string::String, pub belong_to_id: ::std::string::String, pub name: ::std::string::String, - pub desc: ::std::string::String, pub data_type: ViewDataType, - pub version: i64, - pub belongings: ::protobuf::SingularPtrField, pub modified_time: i64, pub create_time: i64, - pub ext_data: ::std::string::String, - pub thumbnail: ::std::string::String, pub plugin_type: i32, // special fields pub unknown_fields: ::protobuf::UnknownFields, @@ -109,6 +104,385 @@ impl View { // string name = 3; + pub fn get_name(&self) -> &str { + &self.name + } + pub fn clear_name(&mut self) { + self.name.clear(); + } + + // Param is passed by value, moved + pub fn set_name(&mut self, v: ::std::string::String) { + self.name = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_name(&mut self) -> &mut ::std::string::String { + &mut self.name + } + + // Take field + pub fn take_name(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.name, ::std::string::String::new()) + } + + // .ViewDataType data_type = 4; + + + pub fn get_data_type(&self) -> ViewDataType { + self.data_type + } + pub fn clear_data_type(&mut self) { + self.data_type = ViewDataType::TextBlock; + } + + // Param is passed by value, moved + pub fn set_data_type(&mut self, v: ViewDataType) { + self.data_type = v; + } + + // int64 modified_time = 5; + + + pub fn get_modified_time(&self) -> i64 { + self.modified_time + } + pub fn clear_modified_time(&mut self) { + self.modified_time = 0; + } + + // Param is passed by value, moved + pub fn set_modified_time(&mut self, v: i64) { + self.modified_time = v; + } + + // int64 create_time = 6; + + + pub fn get_create_time(&self) -> i64 { + self.create_time + } + pub fn clear_create_time(&mut self) { + self.create_time = 0; + } + + // Param is passed by value, moved + pub fn set_create_time(&mut self, v: i64) { + self.create_time = v; + } + + // int32 plugin_type = 7; + + + pub fn get_plugin_type(&self) -> i32 { + self.plugin_type + } + pub fn clear_plugin_type(&mut self) { + self.plugin_type = 0; + } + + // Param is passed by value, moved + pub fn set_plugin_type(&mut self, v: i32) { + self.plugin_type = v; + } +} + +impl ::protobuf::Message for View { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?; + }, + 2 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.belong_to_id)?; + }, + 3 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.name)?; + }, + 4 => { + ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.data_type, 4, &mut self.unknown_fields)? + }, + 5 => { + 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.modified_time = tmp; + }, + 6 => { + 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.create_time = tmp; + }, + 7 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_int32()?; + self.plugin_type = tmp; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.id); + } + if !self.belong_to_id.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.belong_to_id); + } + if !self.name.is_empty() { + my_size += ::protobuf::rt::string_size(3, &self.name); + } + if self.data_type != ViewDataType::TextBlock { + my_size += ::protobuf::rt::enum_size(4, self.data_type); + } + if self.modified_time != 0 { + my_size += ::protobuf::rt::value_size(5, self.modified_time, ::protobuf::wire_format::WireTypeVarint); + } + if self.create_time != 0 { + my_size += ::protobuf::rt::value_size(6, self.create_time, ::protobuf::wire_format::WireTypeVarint); + } + if self.plugin_type != 0 { + my_size += ::protobuf::rt::value_size(7, self.plugin_type, ::protobuf::wire_format::WireTypeVarint); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.id.is_empty() { + os.write_string(1, &self.id)?; + } + if !self.belong_to_id.is_empty() { + os.write_string(2, &self.belong_to_id)?; + } + if !self.name.is_empty() { + os.write_string(3, &self.name)?; + } + if self.data_type != ViewDataType::TextBlock { + os.write_enum(4, ::protobuf::ProtobufEnum::value(&self.data_type))?; + } + if self.modified_time != 0 { + os.write_int64(5, self.modified_time)?; + } + if self.create_time != 0 { + os.write_int64(6, self.create_time)?; + } + if self.plugin_type != 0 { + os.write_int32(7, self.plugin_type)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> View { + View::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "id", + |m: &View| { &m.id }, + |m: &mut View| { &mut m.id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "belong_to_id", + |m: &View| { &m.belong_to_id }, + |m: &mut View| { &mut m.belong_to_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "name", + |m: &View| { &m.name }, + |m: &mut View| { &mut m.name }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( + "data_type", + |m: &View| { &m.data_type }, + |m: &mut View| { &mut m.data_type }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt64>( + "modified_time", + |m: &View| { &m.modified_time }, + |m: &mut View| { &mut m.modified_time }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt64>( + "create_time", + |m: &View| { &m.create_time }, + |m: &mut View| { &mut m.create_time }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( + "plugin_type", + |m: &View| { &m.plugin_type }, + |m: &mut View| { &mut m.plugin_type }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "View", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static View { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(View::new) + } +} + +impl ::protobuf::Clear for View { + fn clear(&mut self) { + self.id.clear(); + self.belong_to_id.clear(); + self.name.clear(); + self.data_type = ViewDataType::TextBlock; + self.modified_time = 0; + self.create_time = 0; + self.plugin_type = 0; + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for View { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for View { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct ViewInfo { + // message fields + pub id: ::std::string::String, + pub belong_to_id: ::std::string::String, + pub name: ::std::string::String, + pub desc: ::std::string::String, + pub data_type: ViewDataType, + pub belongings: ::protobuf::SingularPtrField, + pub ext_data: ::protobuf::SingularPtrField, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a ViewInfo { + fn default() -> &'a ViewInfo { + ::default_instance() + } +} + +impl ViewInfo { + pub fn new() -> ViewInfo { + ::std::default::Default::default() + } + + // string id = 1; + + + pub fn get_id(&self) -> &str { + &self.id + } + pub fn clear_id(&mut self) { + self.id.clear(); + } + + // Param is passed by value, moved + pub fn set_id(&mut self, v: ::std::string::String) { + self.id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_id(&mut self) -> &mut ::std::string::String { + &mut self.id + } + + // Take field + pub fn take_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.id, ::std::string::String::new()) + } + + // string belong_to_id = 2; + + + pub fn get_belong_to_id(&self) -> &str { + &self.belong_to_id + } + pub fn clear_belong_to_id(&mut self) { + self.belong_to_id.clear(); + } + + // Param is passed by value, moved + pub fn set_belong_to_id(&mut self, v: ::std::string::String) { + self.belong_to_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_belong_to_id(&mut self) -> &mut ::std::string::String { + &mut self.belong_to_id + } + + // Take field + pub fn take_belong_to_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.belong_to_id, ::std::string::String::new()) + } + + // string name = 3; + + pub fn get_name(&self) -> &str { &self.name } @@ -173,22 +547,7 @@ impl View { self.data_type = v; } - // int64 version = 6; - - - pub fn get_version(&self) -> i64 { - self.version - } - pub fn clear_version(&mut self) { - self.version = 0; - } - - // Param is passed by value, moved - pub fn set_version(&mut self, v: i64) { - self.version = v; - } - - // .RepeatedView belongings = 7; + // .RepeatedView belongings = 6; pub fn get_belongings(&self) -> &RepeatedView { @@ -221,111 +580,52 @@ impl View { self.belongings.take().unwrap_or_else(|| RepeatedView::new()) } - // int64 modified_time = 8; + // .ViewExtData ext_data = 7; - pub fn get_modified_time(&self) -> i64 { - self.modified_time - } - pub fn clear_modified_time(&mut self) { - self.modified_time = 0; - } - - // Param is passed by value, moved - pub fn set_modified_time(&mut self, v: i64) { - self.modified_time = v; - } - - // int64 create_time = 9; - - - pub fn get_create_time(&self) -> i64 { - self.create_time - } - pub fn clear_create_time(&mut self) { - self.create_time = 0; - } - - // Param is passed by value, moved - pub fn set_create_time(&mut self, v: i64) { - self.create_time = v; - } - - // string ext_data = 10; - - - pub fn get_ext_data(&self) -> &str { - &self.ext_data + pub fn get_ext_data(&self) -> &ViewExtData { + self.ext_data.as_ref().unwrap_or_else(|| ::default_instance()) } pub fn clear_ext_data(&mut self) { self.ext_data.clear(); } + pub fn has_ext_data(&self) -> bool { + self.ext_data.is_some() + } + // Param is passed by value, moved - pub fn set_ext_data(&mut self, v: ::std::string::String) { - self.ext_data = v; + pub fn set_ext_data(&mut self, v: ViewExtData) { + self.ext_data = ::protobuf::SingularPtrField::some(v); } // Mutable pointer to the field. // If field is not initialized, it is initialized with default value first. - pub fn mut_ext_data(&mut self) -> &mut ::std::string::String { - &mut self.ext_data + pub fn mut_ext_data(&mut self) -> &mut ViewExtData { + if self.ext_data.is_none() { + self.ext_data.set_default(); + } + self.ext_data.as_mut().unwrap() } // Take field - pub fn take_ext_data(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.ext_data, ::std::string::String::new()) - } - - // string thumbnail = 11; - - - pub fn get_thumbnail(&self) -> &str { - &self.thumbnail - } - pub fn clear_thumbnail(&mut self) { - self.thumbnail.clear(); - } - - // Param is passed by value, moved - pub fn set_thumbnail(&mut self, v: ::std::string::String) { - self.thumbnail = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_thumbnail(&mut self) -> &mut ::std::string::String { - &mut self.thumbnail - } - - // Take field - pub fn take_thumbnail(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.thumbnail, ::std::string::String::new()) - } - - // int32 plugin_type = 12; - - - pub fn get_plugin_type(&self) -> i32 { - self.plugin_type - } - pub fn clear_plugin_type(&mut self) { - self.plugin_type = 0; - } - - // Param is passed by value, moved - pub fn set_plugin_type(&mut self, v: i32) { - self.plugin_type = v; + pub fn take_ext_data(&mut self) -> ViewExtData { + self.ext_data.take().unwrap_or_else(|| ViewExtData::new()) } } -impl ::protobuf::Message for View { +impl ::protobuf::Message for ViewInfo { fn is_initialized(&self) -> bool { for v in &self.belongings { if !v.is_initialized() { return false; } }; + for v in &self.ext_data { + if !v.is_initialized() { + return false; + } + }; true } @@ -349,41 +649,10 @@ impl ::protobuf::Message for View { ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.data_type, 5, &mut self.unknown_fields)? }, 6 => { - 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.version = tmp; - }, - 7 => { ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.belongings)?; }, - 8 => { - 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.modified_time = tmp; - }, - 9 => { - 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.create_time = tmp; - }, - 10 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.ext_data)?; - }, - 11 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.thumbnail)?; - }, - 12 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_int32()?; - self.plugin_type = tmp; + 7 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.ext_data)?; }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; @@ -412,27 +681,13 @@ impl ::protobuf::Message for View { if self.data_type != ViewDataType::TextBlock { my_size += ::protobuf::rt::enum_size(5, self.data_type); } - if self.version != 0 { - my_size += ::protobuf::rt::value_size(6, self.version, ::protobuf::wire_format::WireTypeVarint); - } if let Some(ref v) = self.belongings.as_ref() { let len = v.compute_size(); my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; } - if self.modified_time != 0 { - my_size += ::protobuf::rt::value_size(8, self.modified_time, ::protobuf::wire_format::WireTypeVarint); - } - if self.create_time != 0 { - my_size += ::protobuf::rt::value_size(9, self.create_time, ::protobuf::wire_format::WireTypeVarint); - } - if !self.ext_data.is_empty() { - my_size += ::protobuf::rt::string_size(10, &self.ext_data); - } - if !self.thumbnail.is_empty() { - my_size += ::protobuf::rt::string_size(11, &self.thumbnail); - } - if self.plugin_type != 0 { - my_size += ::protobuf::rt::value_size(12, self.plugin_type, ::protobuf::wire_format::WireTypeVarint); + if let Some(ref v) = self.ext_data.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; } my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); @@ -455,28 +710,15 @@ impl ::protobuf::Message for View { if self.data_type != ViewDataType::TextBlock { os.write_enum(5, ::protobuf::ProtobufEnum::value(&self.data_type))?; } - if self.version != 0 { - os.write_int64(6, self.version)?; - } if let Some(ref v) = self.belongings.as_ref() { - os.write_tag(7, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_tag(6, ::protobuf::wire_format::WireTypeLengthDelimited)?; os.write_raw_varint32(v.get_cached_size())?; v.write_to_with_cached_sizes(os)?; } - if self.modified_time != 0 { - os.write_int64(8, self.modified_time)?; - } - if self.create_time != 0 { - os.write_int64(9, self.create_time)?; - } - if !self.ext_data.is_empty() { - os.write_string(10, &self.ext_data)?; - } - if !self.thumbnail.is_empty() { - os.write_string(11, &self.thumbnail)?; - } - if self.plugin_type != 0 { - os.write_int32(12, self.plugin_type)?; + if let Some(ref v) = self.ext_data.as_ref() { + os.write_tag(7, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; } os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) @@ -508,8 +750,8 @@ impl ::protobuf::Message for View { Self::descriptor_static() } - fn new() -> View { - View::new() + fn new() -> ViewInfo { + ViewInfo::new() } fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { @@ -518,103 +760,920 @@ impl ::protobuf::Message for View { let mut fields = ::std::vec::Vec::new(); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "id", - |m: &View| { &m.id }, - |m: &mut View| { &mut m.id }, + |m: &ViewInfo| { &m.id }, + |m: &mut ViewInfo| { &mut m.id }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "belong_to_id", - |m: &View| { &m.belong_to_id }, - |m: &mut View| { &mut m.belong_to_id }, + |m: &ViewInfo| { &m.belong_to_id }, + |m: &mut ViewInfo| { &mut m.belong_to_id }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "name", - |m: &View| { &m.name }, - |m: &mut View| { &mut m.name }, + |m: &ViewInfo| { &m.name }, + |m: &mut ViewInfo| { &mut m.name }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "desc", - |m: &View| { &m.desc }, - |m: &mut View| { &mut m.desc }, + |m: &ViewInfo| { &m.desc }, + |m: &mut ViewInfo| { &mut m.desc }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( "data_type", - |m: &View| { &m.data_type }, - |m: &mut View| { &mut m.data_type }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt64>( - "version", - |m: &View| { &m.version }, - |m: &mut View| { &mut m.version }, + |m: &ViewInfo| { &m.data_type }, + |m: &mut ViewInfo| { &mut m.data_type }, )); fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( "belongings", - |m: &View| { &m.belongings }, - |m: &mut View| { &mut m.belongings }, + |m: &ViewInfo| { &m.belongings }, + |m: &mut ViewInfo| { &mut m.belongings }, )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt64>( - "modified_time", - |m: &View| { &m.modified_time }, - |m: &mut View| { &mut m.modified_time }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt64>( - "create_time", - |m: &View| { &m.create_time }, - |m: &mut View| { &mut m.create_time }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( "ext_data", - |m: &View| { &m.ext_data }, - |m: &mut View| { &mut m.ext_data }, + |m: &ViewInfo| { &m.ext_data }, + |m: &mut ViewInfo| { &mut m.ext_data }, )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "thumbnail", - |m: &View| { &m.thumbnail }, - |m: &mut View| { &mut m.thumbnail }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( - "plugin_type", - |m: &View| { &m.plugin_type }, - |m: &mut View| { &mut m.plugin_type }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "View", + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "ViewInfo", fields, file_descriptor_proto() ) }) } - fn default_instance() -> &'static View { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(View::new) + fn default_instance() -> &'static ViewInfo { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(ViewInfo::new) } } -impl ::protobuf::Clear for View { +impl ::protobuf::Clear for ViewInfo { fn clear(&mut self) { self.id.clear(); self.belong_to_id.clear(); self.name.clear(); self.desc.clear(); self.data_type = ViewDataType::TextBlock; - self.version = 0; self.belongings.clear(); - self.modified_time = 0; - self.create_time = 0; self.ext_data.clear(); - self.thumbnail.clear(); - self.plugin_type = 0; self.unknown_fields.clear(); } } -impl ::std::fmt::Debug for View { +impl ::std::fmt::Debug for ViewInfo { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } -impl ::protobuf::reflect::ProtobufValue for View { +impl ::protobuf::reflect::ProtobufValue for ViewInfo { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct ViewExtData { + // message fields + pub filter: ::protobuf::SingularPtrField, + pub group: ::protobuf::SingularPtrField, + pub sort: ::protobuf::SingularPtrField, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a ViewExtData { + fn default() -> &'a ViewExtData { + ::default_instance() + } +} + +impl ViewExtData { + pub fn new() -> ViewExtData { + ::std::default::Default::default() + } + + // .ViewFilter filter = 1; + + + pub fn get_filter(&self) -> &ViewFilter { + self.filter.as_ref().unwrap_or_else(|| ::default_instance()) + } + pub fn clear_filter(&mut self) { + self.filter.clear(); + } + + pub fn has_filter(&self) -> bool { + self.filter.is_some() + } + + // Param is passed by value, moved + pub fn set_filter(&mut self, v: ViewFilter) { + self.filter = ::protobuf::SingularPtrField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_filter(&mut self) -> &mut ViewFilter { + if self.filter.is_none() { + self.filter.set_default(); + } + self.filter.as_mut().unwrap() + } + + // Take field + pub fn take_filter(&mut self) -> ViewFilter { + self.filter.take().unwrap_or_else(|| ViewFilter::new()) + } + + // .ViewGroup group = 2; + + + pub fn get_group(&self) -> &ViewGroup { + self.group.as_ref().unwrap_or_else(|| ::default_instance()) + } + pub fn clear_group(&mut self) { + self.group.clear(); + } + + pub fn has_group(&self) -> bool { + self.group.is_some() + } + + // Param is passed by value, moved + pub fn set_group(&mut self, v: ViewGroup) { + self.group = ::protobuf::SingularPtrField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_group(&mut self) -> &mut ViewGroup { + if self.group.is_none() { + self.group.set_default(); + } + self.group.as_mut().unwrap() + } + + // Take field + pub fn take_group(&mut self) -> ViewGroup { + self.group.take().unwrap_or_else(|| ViewGroup::new()) + } + + // .ViewSort sort = 3; + + + pub fn get_sort(&self) -> &ViewSort { + self.sort.as_ref().unwrap_or_else(|| ::default_instance()) + } + pub fn clear_sort(&mut self) { + self.sort.clear(); + } + + pub fn has_sort(&self) -> bool { + self.sort.is_some() + } + + // Param is passed by value, moved + pub fn set_sort(&mut self, v: ViewSort) { + self.sort = ::protobuf::SingularPtrField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_sort(&mut self) -> &mut ViewSort { + if self.sort.is_none() { + self.sort.set_default(); + } + self.sort.as_mut().unwrap() + } + + // Take field + pub fn take_sort(&mut self) -> ViewSort { + self.sort.take().unwrap_or_else(|| ViewSort::new()) + } +} + +impl ::protobuf::Message for ViewExtData { + fn is_initialized(&self) -> bool { + for v in &self.filter { + if !v.is_initialized() { + return false; + } + }; + for v in &self.group { + if !v.is_initialized() { + return false; + } + }; + for v in &self.sort { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.filter)?; + }, + 2 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.group)?; + }, + 3 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.sort)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if let Some(ref v) = self.filter.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + if let Some(ref v) = self.group.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + if let Some(ref v) = self.sort.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if let Some(ref v) = self.filter.as_ref() { + os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + if let Some(ref v) = self.group.as_ref() { + os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + if let Some(ref v) = self.sort.as_ref() { + os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> ViewExtData { + ViewExtData::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "filter", + |m: &ViewExtData| { &m.filter }, + |m: &mut ViewExtData| { &mut m.filter }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "group", + |m: &ViewExtData| { &m.group }, + |m: &mut ViewExtData| { &mut m.group }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "sort", + |m: &ViewExtData| { &m.sort }, + |m: &mut ViewExtData| { &mut m.sort }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "ViewExtData", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static ViewExtData { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(ViewExtData::new) + } +} + +impl ::protobuf::Clear for ViewExtData { + fn clear(&mut self) { + self.filter.clear(); + self.group.clear(); + self.sort.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for ViewExtData { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for ViewExtData { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct ViewFilter { + // message fields + pub field_id: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a ViewFilter { + fn default() -> &'a ViewFilter { + ::default_instance() + } +} + +impl ViewFilter { + pub fn new() -> ViewFilter { + ::std::default::Default::default() + } + + // string field_id = 1; + + + pub fn get_field_id(&self) -> &str { + &self.field_id + } + pub fn clear_field_id(&mut self) { + self.field_id.clear(); + } + + // Param is passed by value, moved + pub fn set_field_id(&mut self, v: ::std::string::String) { + self.field_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_field_id(&mut self) -> &mut ::std::string::String { + &mut self.field_id + } + + // Take field + pub fn take_field_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.field_id, ::std::string::String::new()) + } +} + +impl ::protobuf::Message for ViewFilter { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.field_id)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.field_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.field_id); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.field_id.is_empty() { + os.write_string(1, &self.field_id)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> ViewFilter { + ViewFilter::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "field_id", + |m: &ViewFilter| { &m.field_id }, + |m: &mut ViewFilter| { &mut m.field_id }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "ViewFilter", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static ViewFilter { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(ViewFilter::new) + } +} + +impl ::protobuf::Clear for ViewFilter { + fn clear(&mut self) { + self.field_id.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for ViewFilter { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for ViewFilter { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct ViewGroup { + // message fields + pub group_field_id: ::std::string::String, + // message oneof groups + pub one_of_sub_group_field_id: ::std::option::Option, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a ViewGroup { + fn default() -> &'a ViewGroup { + ::default_instance() + } +} + +#[derive(Clone,PartialEq,Debug)] +pub enum ViewGroup_oneof_one_of_sub_group_field_id { + sub_group_field_id(::std::string::String), +} + +impl ViewGroup { + pub fn new() -> ViewGroup { + ::std::default::Default::default() + } + + // string group_field_id = 1; + + + pub fn get_group_field_id(&self) -> &str { + &self.group_field_id + } + pub fn clear_group_field_id(&mut self) { + self.group_field_id.clear(); + } + + // Param is passed by value, moved + pub fn set_group_field_id(&mut self, v: ::std::string::String) { + self.group_field_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_group_field_id(&mut self) -> &mut ::std::string::String { + &mut self.group_field_id + } + + // Take field + pub fn take_group_field_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.group_field_id, ::std::string::String::new()) + } + + // string sub_group_field_id = 2; + + + pub fn get_sub_group_field_id(&self) -> &str { + match self.one_of_sub_group_field_id { + ::std::option::Option::Some(ViewGroup_oneof_one_of_sub_group_field_id::sub_group_field_id(ref v)) => v, + _ => "", + } + } + pub fn clear_sub_group_field_id(&mut self) { + self.one_of_sub_group_field_id = ::std::option::Option::None; + } + + pub fn has_sub_group_field_id(&self) -> bool { + match self.one_of_sub_group_field_id { + ::std::option::Option::Some(ViewGroup_oneof_one_of_sub_group_field_id::sub_group_field_id(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_sub_group_field_id(&mut self, v: ::std::string::String) { + self.one_of_sub_group_field_id = ::std::option::Option::Some(ViewGroup_oneof_one_of_sub_group_field_id::sub_group_field_id(v)) + } + + // Mutable pointer to the field. + pub fn mut_sub_group_field_id(&mut self) -> &mut ::std::string::String { + if let ::std::option::Option::Some(ViewGroup_oneof_one_of_sub_group_field_id::sub_group_field_id(_)) = self.one_of_sub_group_field_id { + } else { + self.one_of_sub_group_field_id = ::std::option::Option::Some(ViewGroup_oneof_one_of_sub_group_field_id::sub_group_field_id(::std::string::String::new())); + } + match self.one_of_sub_group_field_id { + ::std::option::Option::Some(ViewGroup_oneof_one_of_sub_group_field_id::sub_group_field_id(ref mut v)) => v, + _ => panic!(), + } + } + + // Take field + pub fn take_sub_group_field_id(&mut self) -> ::std::string::String { + if self.has_sub_group_field_id() { + match self.one_of_sub_group_field_id.take() { + ::std::option::Option::Some(ViewGroup_oneof_one_of_sub_group_field_id::sub_group_field_id(v)) => v, + _ => panic!(), + } + } else { + ::std::string::String::new() + } + } +} + +impl ::protobuf::Message for ViewGroup { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.group_field_id)?; + }, + 2 => { + if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + self.one_of_sub_group_field_id = ::std::option::Option::Some(ViewGroup_oneof_one_of_sub_group_field_id::sub_group_field_id(is.read_string()?)); + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.group_field_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.group_field_id); + } + if let ::std::option::Option::Some(ref v) = self.one_of_sub_group_field_id { + match v { + &ViewGroup_oneof_one_of_sub_group_field_id::sub_group_field_id(ref v) => { + my_size += ::protobuf::rt::string_size(2, &v); + }, + }; + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.group_field_id.is_empty() { + os.write_string(1, &self.group_field_id)?; + } + if let ::std::option::Option::Some(ref v) = self.one_of_sub_group_field_id { + match v { + &ViewGroup_oneof_one_of_sub_group_field_id::sub_group_field_id(ref v) => { + os.write_string(2, v)?; + }, + }; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> ViewGroup { + ViewGroup::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "group_field_id", + |m: &ViewGroup| { &m.group_field_id }, + |m: &mut ViewGroup| { &mut m.group_field_id }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_string_accessor::<_>( + "sub_group_field_id", + ViewGroup::has_sub_group_field_id, + ViewGroup::get_sub_group_field_id, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "ViewGroup", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static ViewGroup { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(ViewGroup::new) + } +} + +impl ::protobuf::Clear for ViewGroup { + fn clear(&mut self) { + self.group_field_id.clear(); + self.one_of_sub_group_field_id = ::std::option::Option::None; + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for ViewGroup { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for ViewGroup { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct ViewSort { + // message fields + pub field_id: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a ViewSort { + fn default() -> &'a ViewSort { + ::default_instance() + } +} + +impl ViewSort { + pub fn new() -> ViewSort { + ::std::default::Default::default() + } + + // string field_id = 1; + + + pub fn get_field_id(&self) -> &str { + &self.field_id + } + pub fn clear_field_id(&mut self) { + self.field_id.clear(); + } + + // Param is passed by value, moved + pub fn set_field_id(&mut self, v: ::std::string::String) { + self.field_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_field_id(&mut self) -> &mut ::std::string::String { + &mut self.field_id + } + + // Take field + pub fn take_field_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.field_id, ::std::string::String::new()) + } +} + +impl ::protobuf::Message for ViewSort { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.field_id)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.field_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.field_id); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.field_id.is_empty() { + os.write_string(1, &self.field_id)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> ViewSort { + ViewSort::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "field_id", + |m: &ViewSort| { &m.field_id }, + |m: &mut ViewSort| { &mut m.field_id }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "ViewSort", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static ViewSort { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(ViewSort::new) + } +} + +impl ::protobuf::Clear for ViewSort { + fn clear(&mut self) { + self.field_id.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for ViewSort { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for ViewSort { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { ::protobuf::reflect::ReflectValueRef::Message(self) } @@ -3138,46 +4197,56 @@ impl ::protobuf::reflect::ProtobufValue for MoveFolderItemType { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\nview.proto\"\xf5\x02\n\x04View\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\ + \n\nview.proto\"\xdf\x01\n\x04View\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\ \x02id\x12\x20\n\x0cbelong_to_id\x18\x02\x20\x01(\tR\nbelongToId\x12\x12\ - \n\x04name\x18\x03\x20\x01(\tR\x04name\x12\x12\n\x04desc\x18\x04\x20\x01\ - (\tR\x04desc\x12*\n\tdata_type\x18\x05\x20\x01(\x0e2\r.ViewDataTypeR\x08\ - dataType\x12\x18\n\x07version\x18\x06\x20\x01(\x03R\x07version\x12-\n\nb\ - elongings\x18\x07\x20\x01(\x0b2\r.RepeatedViewR\nbelongings\x12#\n\rmodi\ - fied_time\x18\x08\x20\x01(\x03R\x0cmodifiedTime\x12\x1f\n\x0bcreate_time\ - \x18\t\x20\x01(\x03R\ncreateTime\x12\x19\n\x08ext_data\x18\n\x20\x01(\tR\ - \x07extData\x12\x1c\n\tthumbnail\x18\x0b\x20\x01(\tR\tthumbnail\x12\x1f\ - \n\x0bplugin_type\x18\x0c\x20\x01(\x05R\npluginType\"+\n\x0cRepeatedView\ - \x12\x1b\n\x05items\x18\x01\x20\x03(\x0b2\x05.ViewR\x05items\"\xf2\x01\n\ - \x11CreateViewPayload\x12\x20\n\x0cbelong_to_id\x18\x01\x20\x01(\tR\nbel\ - ongToId\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x12\n\x04desc\ - \x18\x03\x20\x01(\tR\x04desc\x12\x1e\n\tthumbnail\x18\x04\x20\x01(\tH\0R\ - \tthumbnail\x12*\n\tdata_type\x18\x05\x20\x01(\x0e2\r.ViewDataTypeR\x08d\ - ataType\x12\x1f\n\x0bplugin_type\x18\x06\x20\x01(\x05R\npluginType\x12\ - \x12\n\x04data\x18\x07\x20\x01(\x0cR\x04dataB\x12\n\x10one_of_thumbnail\ - \"\xf4\x01\n\x10CreateViewParams\x12\x20\n\x0cbelong_to_id\x18\x01\x20\ - \x01(\tR\nbelongToId\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\ - \x12\n\x04desc\x18\x03\x20\x01(\tR\x04desc\x12\x1c\n\tthumbnail\x18\x04\ - \x20\x01(\tR\tthumbnail\x12*\n\tdata_type\x18\x05\x20\x01(\x0e2\r.ViewDa\ - taTypeR\x08dataType\x12\x17\n\x07view_id\x18\x06\x20\x01(\tR\x06viewId\ - \x12\x12\n\x04data\x18\x07\x20\x01(\x0cR\x04data\x12\x1f\n\x0bplugin_typ\ - e\x18\x08\x20\x01(\x05R\npluginType\"\x1e\n\x06ViewId\x12\x14\n\x05value\ - \x18\x01\x20\x01(\tR\x05value\"&\n\x0eRepeatedViewId\x12\x14\n\x05items\ - \x18\x01\x20\x03(\tR\x05items\"\xaa\x01\n\x11UpdateViewPayload\x12\x17\n\ - \x07view_id\x18\x01\x20\x01(\tR\x06viewId\x12\x14\n\x04name\x18\x02\x20\ - \x01(\tH\0R\x04name\x12\x14\n\x04desc\x18\x03\x20\x01(\tH\x01R\x04desc\ - \x12\x1e\n\tthumbnail\x18\x04\x20\x01(\tH\x02R\tthumbnailB\r\n\x0bone_of\ - _nameB\r\n\x0bone_of_descB\x12\n\x10one_of_thumbnail\"\xa9\x01\n\x10Upda\ - teViewParams\x12\x17\n\x07view_id\x18\x01\x20\x01(\tR\x06viewId\x12\x14\ - \n\x04name\x18\x02\x20\x01(\tH\0R\x04name\x12\x14\n\x04desc\x18\x03\x20\ - \x01(\tH\x01R\x04desc\x12\x1e\n\tthumbnail\x18\x04\x20\x01(\tH\x02R\tthu\ - mbnailB\r\n\x0bone_of_nameB\r\n\x0bone_of_descB\x12\n\x10one_of_thumbnai\ - l\"y\n\x15MoveFolderItemPayload\x12\x17\n\x07item_id\x18\x01\x20\x01(\tR\ - \x06itemId\x12\x12\n\x04from\x18\x02\x20\x01(\x05R\x04from\x12\x0e\n\x02\ - to\x18\x03\x20\x01(\x05R\x02to\x12#\n\x02ty\x18\x04\x20\x01(\x0e2\x13.Mo\ - veFolderItemTypeR\x02ty*'\n\x0cViewDataType\x12\r\n\tTextBlock\x10\0\x12\ - \x08\n\x04Grid\x10\x01*/\n\x12MoveFolderItemType\x12\x0b\n\x07MoveApp\ - \x10\0\x12\x0c\n\x08MoveView\x10\x01b\x06proto3\ + \n\x04name\x18\x03\x20\x01(\tR\x04name\x12*\n\tdata_type\x18\x04\x20\x01\ + (\x0e2\r.ViewDataTypeR\x08dataType\x12#\n\rmodified_time\x18\x05\x20\x01\ + (\x03R\x0cmodifiedTime\x12\x1f\n\x0bcreate_time\x18\x06\x20\x01(\x03R\nc\ + reateTime\x12\x1f\n\x0bplugin_type\x18\x07\x20\x01(\x05R\npluginType\"\ + \xe8\x01\n\x08ViewInfo\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x20\ + \n\x0cbelong_to_id\x18\x02\x20\x01(\tR\nbelongToId\x12\x12\n\x04name\x18\ + \x03\x20\x01(\tR\x04name\x12\x12\n\x04desc\x18\x04\x20\x01(\tR\x04desc\ + \x12*\n\tdata_type\x18\x05\x20\x01(\x0e2\r.ViewDataTypeR\x08dataType\x12\ + -\n\nbelongings\x18\x06\x20\x01(\x0b2\r.RepeatedViewR\nbelongings\x12'\n\ + \x08ext_data\x18\x07\x20\x01(\x0b2\x0c.ViewExtDataR\x07extData\"s\n\x0bV\ + iewExtData\x12#\n\x06filter\x18\x01\x20\x01(\x0b2\x0b.ViewFilterR\x06fil\ + ter\x12\x20\n\x05group\x18\x02\x20\x01(\x0b2\n.ViewGroupR\x05group\x12\ + \x1d\n\x04sort\x18\x03\x20\x01(\x0b2\t.ViewSortR\x04sort\"'\n\nViewFilte\ + r\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\"}\n\tViewGroup\ + \x12$\n\x0egroup_field_id\x18\x01\x20\x01(\tR\x0cgroupFieldId\x12-\n\x12\ + sub_group_field_id\x18\x02\x20\x01(\tH\0R\x0fsubGroupFieldIdB\x1b\n\x19o\ + ne_of_sub_group_field_id\"%\n\x08ViewSort\x12\x19\n\x08field_id\x18\x01\ + \x20\x01(\tR\x07fieldId\"+\n\x0cRepeatedView\x12\x1b\n\x05items\x18\x01\ + \x20\x03(\x0b2\x05.ViewR\x05items\"\xf2\x01\n\x11CreateViewPayload\x12\ + \x20\n\x0cbelong_to_id\x18\x01\x20\x01(\tR\nbelongToId\x12\x12\n\x04name\ + \x18\x02\x20\x01(\tR\x04name\x12\x12\n\x04desc\x18\x03\x20\x01(\tR\x04de\ + sc\x12\x1e\n\tthumbnail\x18\x04\x20\x01(\tH\0R\tthumbnail\x12*\n\tdata_t\ + ype\x18\x05\x20\x01(\x0e2\r.ViewDataTypeR\x08dataType\x12\x1f\n\x0bplugi\ + n_type\x18\x06\x20\x01(\x05R\npluginType\x12\x12\n\x04data\x18\x07\x20\ + \x01(\x0cR\x04dataB\x12\n\x10one_of_thumbnail\"\xf4\x01\n\x10CreateViewP\ + arams\x12\x20\n\x0cbelong_to_id\x18\x01\x20\x01(\tR\nbelongToId\x12\x12\ + \n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x12\n\x04desc\x18\x03\x20\x01\ + (\tR\x04desc\x12\x1c\n\tthumbnail\x18\x04\x20\x01(\tR\tthumbnail\x12*\n\ + \tdata_type\x18\x05\x20\x01(\x0e2\r.ViewDataTypeR\x08dataType\x12\x17\n\ + \x07view_id\x18\x06\x20\x01(\tR\x06viewId\x12\x12\n\x04data\x18\x07\x20\ + \x01(\x0cR\x04data\x12\x1f\n\x0bplugin_type\x18\x08\x20\x01(\x05R\nplugi\ + nType\"\x1e\n\x06ViewId\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05value\ + \"&\n\x0eRepeatedViewId\x12\x14\n\x05items\x18\x01\x20\x03(\tR\x05items\ + \"\xaa\x01\n\x11UpdateViewPayload\x12\x17\n\x07view_id\x18\x01\x20\x01(\ + \tR\x06viewId\x12\x14\n\x04name\x18\x02\x20\x01(\tH\0R\x04name\x12\x14\n\ + \x04desc\x18\x03\x20\x01(\tH\x01R\x04desc\x12\x1e\n\tthumbnail\x18\x04\ + \x20\x01(\tH\x02R\tthumbnailB\r\n\x0bone_of_nameB\r\n\x0bone_of_descB\ + \x12\n\x10one_of_thumbnail\"\xa9\x01\n\x10UpdateViewParams\x12\x17\n\x07\ + view_id\x18\x01\x20\x01(\tR\x06viewId\x12\x14\n\x04name\x18\x02\x20\x01(\ + \tH\0R\x04name\x12\x14\n\x04desc\x18\x03\x20\x01(\tH\x01R\x04desc\x12\ + \x1e\n\tthumbnail\x18\x04\x20\x01(\tH\x02R\tthumbnailB\r\n\x0bone_of_nam\ + eB\r\n\x0bone_of_descB\x12\n\x10one_of_thumbnail\"y\n\x15MoveFolderItemP\ + ayload\x12\x17\n\x07item_id\x18\x01\x20\x01(\tR\x06itemId\x12\x12\n\x04f\ + rom\x18\x02\x20\x01(\x05R\x04from\x12\x0e\n\x02to\x18\x03\x20\x01(\x05R\ + \x02to\x12#\n\x02ty\x18\x04\x20\x01(\x0e2\x13.MoveFolderItemTypeR\x02ty*\ + '\n\x0cViewDataType\x12\r\n\tTextBlock\x10\0\x12\x08\n\x04Grid\x10\x01*/\ + \n\x12MoveFolderItemType\x12\x0b\n\x07MoveApp\x10\0\x12\x0c\n\x08MoveVie\ + w\x10\x01b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-folder-data-model/src/protobuf/proto/view.proto b/shared-lib/flowy-folder-data-model/src/protobuf/proto/view.proto index 8b77c323b1..6009fb407c 100644 --- a/shared-lib/flowy-folder-data-model/src/protobuf/proto/view.proto +++ b/shared-lib/flowy-folder-data-model/src/protobuf/proto/view.proto @@ -1,18 +1,37 @@ syntax = "proto3"; message View { + string id = 1; + string belong_to_id = 2; + string name = 3; + ViewDataType data_type = 4; + int64 modified_time = 5; + int64 create_time = 6; + int32 plugin_type = 7; +} +message ViewInfo { string id = 1; string belong_to_id = 2; string name = 3; string desc = 4; ViewDataType data_type = 5; - int64 version = 6; - RepeatedView belongings = 7; - int64 modified_time = 8; - int64 create_time = 9; - string ext_data = 10; - string thumbnail = 11; - int32 plugin_type = 12; + RepeatedView belongings = 6; + ViewExtData ext_data = 7; +} +message ViewExtData { + ViewFilter filter = 1; + ViewGroup group = 2; + ViewSort sort = 3; +} +message ViewFilter { + string field_id = 1; +} +message ViewGroup { + string group_field_id = 1; + oneof one_of_sub_group_field_id { string sub_group_field_id = 2; }; +} +message ViewSort { + string field_id = 1; } message RepeatedView { repeated View items = 1; diff --git a/shared-lib/flowy-folder-data-model/src/revision/app.rs b/shared-lib/flowy-folder-data-model/src/revision/app.rs index 3ed12ca933..82b9af3812 100644 --- a/shared-lib/flowy-folder-data-model/src/revision/app.rs +++ b/shared-lib/flowy-folder-data-model/src/revision/app.rs @@ -1,9 +1,9 @@ use crate::entities::app::App; -use crate::entities::RepeatedApp; -use crate::revision::ViewRevision; +use crate::entities::{RepeatedApp, TrashType}; +use crate::revision::{TrashRevision, ViewRevision}; use serde::{Deserialize, Serialize}; -#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +#[derive(Default, Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] pub struct AppRevision { pub id: String, @@ -37,17 +37,14 @@ impl std::convert::From for App { } } -impl std::convert::From for AppRevision { - fn from(app: App) -> Self { - AppRevision { - id: app.id, - workspace_id: app.workspace_id, - name: app.name, - desc: app.desc, - belongings: app.belongings.into(), - version: app.version, - modified_time: app.modified_time, - create_time: app.create_time, +impl std::convert::From for TrashRevision { + fn from(app_rev: AppRevision) -> Self { + TrashRevision { + id: app_rev.id, + name: app_rev.name, + modified_time: app_rev.modified_time, + create_time: app_rev.create_time, + ty: TrashType::TrashApp, } } } @@ -58,13 +55,3 @@ impl std::convert::From> for RepeatedApp { RepeatedApp { items } } } - -impl std::convert::From for Vec { - fn from(repeated_app: RepeatedApp) -> Self { - repeated_app - .items - .into_iter() - .map(|value| value.into()) - .collect::>() - } -} diff --git a/shared-lib/flowy-folder-data-model/src/revision/trash.rs b/shared-lib/flowy-folder-data-model/src/revision/trash.rs index f4a4d3a932..08f3bb27a1 100644 --- a/shared-lib/flowy-folder-data-model/src/revision/trash.rs +++ b/shared-lib/flowy-folder-data-model/src/revision/trash.rs @@ -1,7 +1,8 @@ use crate::entities::trash::{Trash, TrashType}; +use crate::entities::{RepeatedTrash, TrashId}; use serde::{Deserialize, Serialize}; -#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +#[derive(Default, Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] pub struct TrashRevision { pub id: String, @@ -14,14 +15,21 @@ pub struct TrashRevision { pub ty: TrashType, } +impl std::convert::From> for RepeatedTrash { + fn from(trash_revs: Vec) -> Self { + let items: Vec = trash_revs.into_iter().map(|trash_rev| trash_rev.into()).collect(); + RepeatedTrash { items } + } +} + impl std::convert::From for Trash { - fn from(trash_serde: TrashRevision) -> Self { + fn from(trash_rev: TrashRevision) -> Self { Trash { - id: trash_serde.id, - name: trash_serde.name, - modified_time: trash_serde.modified_time, - create_time: trash_serde.create_time, - ty: trash_serde.ty, + id: trash_rev.id, + name: trash_rev.name, + modified_time: trash_rev.modified_time, + create_time: trash_rev.create_time, + ty: trash_rev.ty, } } } @@ -37,3 +45,12 @@ impl std::convert::From for TrashRevision { } } } + +impl std::convert::From<&TrashRevision> for TrashId { + fn from(trash: &TrashRevision) -> Self { + TrashId { + id: trash.id.clone(), + ty: trash.ty.clone(), + } + } +} diff --git a/shared-lib/flowy-folder-data-model/src/revision/view.rs b/shared-lib/flowy-folder-data-model/src/revision/view.rs index 313ecf3013..e58ee95928 100644 --- a/shared-lib/flowy-folder-data-model/src/revision/view.rs +++ b/shared-lib/flowy-folder-data-model/src/revision/view.rs @@ -1,8 +1,9 @@ use crate::entities::view::{View, ViewDataType}; -use crate::entities::RepeatedView; +use crate::entities::{RepeatedView, TrashType, ViewExtData, ViewFilter, ViewGroup, ViewSort}; +use crate::revision::TrashRevision; use serde::{Deserialize, Serialize}; -#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +#[derive(Default, Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] pub struct ViewRevision { pub id: String, @@ -43,51 +44,95 @@ impl std::convert::From for View { id: view_serde.id, belong_to_id: view_serde.belong_to_id, name: view_serde.name, - desc: view_serde.desc, data_type: view_serde.data_type, - version: view_serde.version, - belongings: view_serde.belongings.into(), modified_time: view_serde.modified_time, create_time: view_serde.create_time, - ext_data: view_serde.ext_data, - thumbnail: view_serde.thumbnail, plugin_type: view_serde.plugin_type, } } } -impl std::convert::From for ViewRevision { - fn from(view: View) -> Self { - ViewRevision { - id: view.id, - belong_to_id: view.belong_to_id, - name: view.name, - desc: view.desc, - data_type: view.data_type, - version: view.version, - belongings: view.belongings.into(), - modified_time: view.modified_time, - create_time: view.create_time, - ext_data: view.ext_data, - thumbnail: view.thumbnail, - plugin_type: view.plugin_type, +impl std::convert::From for TrashRevision { + fn from(view_rev: ViewRevision) -> Self { + TrashRevision { + id: view_rev.id, + name: view_rev.name, + modified_time: view_rev.modified_time, + create_time: view_rev.create_time, + ty: TrashType::TrashView, } } } +#[derive(Serialize, Deserialize)] +pub struct ViewExtDataRevision { + pub filter: ViewFilterRevision, + pub group: ViewGroupRevision, + pub sort: ViewSortRevision, +} + +#[derive(Serialize, Deserialize)] +pub struct ViewFilterRevision { + pub field_id: String, +} + +#[derive(Serialize, Deserialize)] +pub struct ViewGroupRevision { + pub group_field_id: String, + pub sub_group_field_id: Option, +} + +#[derive(Serialize, Deserialize)] +pub struct ViewSortRevision { + field_id: String, +} + +impl std::convert::From for ViewExtData { + fn from(s: String) -> Self { + match serde_json::from_str::(&s) { + Ok(data) => data.into(), + Err(err) => { + log::error!("{:?}", err); + ViewExtData::default() + } + } + } +} + +impl std::convert::From for ViewExtData { + fn from(rev: ViewExtDataRevision) -> Self { + ViewExtData { + filter: rev.filter.into(), + group: rev.group.into(), + sort: rev.sort.into(), + } + } +} + +impl std::convert::From for ViewFilter { + fn from(rev: ViewFilterRevision) -> Self { + ViewFilter { field_id: rev.field_id } + } +} + +impl std::convert::From for ViewGroup { + fn from(rev: ViewGroupRevision) -> Self { + ViewGroup { + group_field_id: rev.group_field_id, + sub_group_field_id: rev.sub_group_field_id, + } + } +} + +impl std::convert::From for ViewSort { + fn from(rev: ViewSortRevision) -> Self { + ViewSort { field_id: rev.field_id } + } +} + impl std::convert::From> for RepeatedView { fn from(values: Vec) -> Self { let items = values.into_iter().map(|value| value.into()).collect::>(); RepeatedView { items } } } - -impl std::convert::From for Vec { - fn from(repeated_view: RepeatedView) -> Self { - repeated_view - .items - .into_iter() - .map(|value| value.into()) - .collect::>() - } -} diff --git a/shared-lib/flowy-folder-data-model/src/revision/workspace.rs b/shared-lib/flowy-folder-data-model/src/revision/workspace.rs index fb4fb974f6..5070041211 100644 --- a/shared-lib/flowy-folder-data-model/src/revision/workspace.rs +++ b/shared-lib/flowy-folder-data-model/src/revision/workspace.rs @@ -2,7 +2,7 @@ use crate::entities::workspace::Workspace; use crate::revision::AppRevision; use serde::{Deserialize, Serialize}; -#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +#[derive(Default, Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] pub struct WorkspaceRevision { pub id: String, @@ -29,16 +29,3 @@ impl std::convert::From for Workspace { } } } - -impl std::convert::From for WorkspaceRevision { - fn from(workspace: Workspace) -> Self { - WorkspaceRevision { - id: workspace.id, - name: workspace.name, - desc: workspace.desc, - apps: workspace.apps.into(), - modified_time: workspace.modified_time, - create_time: workspace.create_time, - } - } -} diff --git a/shared-lib/flowy-folder-data-model/src/user_default.rs b/shared-lib/flowy-folder-data-model/src/user_default.rs index ed56d2d80a..7e8023067c 100644 --- a/shared-lib/flowy-folder-data-model/src/user_default.rs +++ b/shared-lib/flowy-folder-data-model/src/user_default.rs @@ -1,24 +1,19 @@ use crate::entities::app::gen_app_id; use crate::entities::view::gen_view_id; +use crate::entities::view::ViewDataType; use crate::entities::workspace::gen_workspace_id; -use crate::entities::{ - app::{App, RepeatedApp}, - view::{RepeatedView, View, ViewDataType}, - workspace::Workspace, -}; +use crate::revision::{AppRevision, ViewRevision, WorkspaceRevision}; use chrono::Utc; -pub fn create_default_workspace() -> Workspace { +pub fn create_default_workspace() -> WorkspaceRevision { let time = Utc::now(); let workspace_id = gen_workspace_id(); let name = "Workspace".to_string(); let desc = "".to_string(); - let apps = RepeatedApp { - items: vec![create_default_app(workspace_id.to_string(), time)], - }; + let apps = vec![create_default_app(workspace_id.to_string(), time)]; - Workspace { + WorkspaceRevision { id: workspace_id, name, desc, @@ -28,16 +23,14 @@ pub fn create_default_workspace() -> Workspace { } } -fn create_default_app(workspace_id: String, time: chrono::DateTime) -> App { +fn create_default_app(workspace_id: String, time: chrono::DateTime) -> AppRevision { let app_id = gen_app_id(); let name = "⭐️ Getting started".to_string(); let desc = "".to_string(); - let views = RepeatedView { - items: vec![create_default_view(app_id.to_string(), time)], - }; + let views = vec![create_default_view(app_id.to_string(), time)]; - App { + AppRevision { id: app_id, workspace_id, name, @@ -49,20 +42,19 @@ fn create_default_app(workspace_id: String, time: chrono::DateTime) -> App } } -fn create_default_view(app_id: String, time: chrono::DateTime) -> View { +fn create_default_view(app_id: String, time: chrono::DateTime) -> ViewRevision { let view_id = gen_view_id(); let name = "Read me".to_string(); - let desc = "".to_string(); let data_type = ViewDataType::TextBlock; - View { + ViewRevision { id: view_id, belong_to_id: app_id, name, - desc, + desc: "".to_string(), data_type, version: 0, - belongings: Default::default(), + belongings: vec![], modified_time: time.timestamp(), create_time: time.timestamp(), ext_data: "".to_string(), diff --git a/shared-lib/flowy-sync/src/client_folder/builder.rs b/shared-lib/flowy-sync/src/client_folder/builder.rs index 8dd82481a2..73d9aac24f 100644 --- a/shared-lib/flowy-sync/src/client_folder/builder.rs +++ b/shared-lib/flowy-sync/src/client_folder/builder.rs @@ -6,7 +6,6 @@ use crate::{ errors::{CollaborateError, CollaborateResult}, }; -use flowy_folder_data_model::entities::{Trash, Workspace}; use flowy_folder_data_model::revision::{TrashRevision, WorkspaceRevision}; use lib_ot::core::{PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder}; use serde::{Deserialize, Serialize}; @@ -26,16 +25,13 @@ impl FolderPadBuilder { } } - pub(crate) fn with_workspace(mut self, workspaces: Vec) -> Self { - self.workspaces = workspaces - .into_iter() - .map(|workspace| Arc::new(workspace.into())) - .collect::>(); + pub(crate) fn with_workspace(mut self, workspaces: Vec) -> Self { + self.workspaces = workspaces.into_iter().map(Arc::new).collect(); self } - pub(crate) fn with_trash(mut self, trash: Vec) -> Self { - self.trash = trash.into_iter().map(|t| Arc::new(t.into())).collect::>(); + pub(crate) fn with_trash(mut self, trash: Vec) -> Self { + self.trash = trash.into_iter().map(Arc::new).collect::>(); self } diff --git a/shared-lib/flowy-sync/src/client_folder/folder_pad.rs b/shared-lib/flowy-sync/src/client_folder/folder_pad.rs index 4fbbfed723..ac5758e64c 100644 --- a/shared-lib/flowy-sync/src/client_folder/folder_pad.rs +++ b/shared-lib/flowy-sync/src/client_folder/folder_pad.rs @@ -8,7 +8,7 @@ use crate::{ }, errors::{CollaborateError, CollaborateResult}, }; -use flowy_folder_data_model::entities::{App, Trash, View, Workspace}; + use flowy_folder_data_model::revision::{AppRevision, TrashRevision, ViewRevision, WorkspaceRevision}; use lib_infra::util::move_vec_element; use lib_ot::core::*; @@ -24,7 +24,7 @@ pub struct FolderPad { } impl FolderPad { - pub fn new(workspaces: Vec, trash: Vec) -> CollaborateResult { + pub fn new(workspaces: Vec, trash: Vec) -> CollaborateResult { FolderPadBuilder::new() .with_workspace(workspaces) .with_trash(trash) @@ -61,9 +61,9 @@ impl FolderPad { self.workspaces.is_empty() && self.trash.is_empty() } - #[tracing::instrument(level = "trace", skip(self, workspace), fields(workspace_name=%workspace.name), err)] - pub fn create_workspace(&mut self, workspace: Workspace) -> CollaborateResult> { - let workspace = Arc::new(workspace.into()); + #[tracing::instrument(level = "trace", skip(self, workspace_rev), fields(workspace_name=%workspace_rev.name), err)] + pub fn create_workspace(&mut self, workspace_rev: WorkspaceRevision) -> CollaborateResult> { + let workspace = Arc::new(workspace_rev); if self.workspaces.contains(&workspace) { tracing::warn!("[RootFolder]: Duplicate workspace"); return Ok(None); @@ -93,19 +93,19 @@ impl FolderPad { }) } - pub fn read_workspaces(&self, workspace_id: Option) -> CollaborateResult> { + pub fn read_workspaces(&self, workspace_id: Option) -> CollaborateResult> { match workspace_id { None => { let workspaces = self .workspaces .iter() - .map(|workspace| workspace.as_ref().clone().into()) - .collect::>(); + .map(|workspace| workspace.as_ref().clone()) + .collect::>(); Ok(workspaces) } Some(workspace_id) => { if let Some(workspace) = self.workspaces.iter().find(|workspace| workspace.id == workspace_id) { - Ok(vec![workspace.as_ref().clone().into()]) + Ok(vec![workspace.as_ref().clone()]) } else { Err(CollaborateError::record_not_found() .context(format!("Can't find workspace with id {}", workspace_id))) @@ -122,24 +122,23 @@ impl FolderPad { }) } - #[tracing::instrument(level = "trace", skip(self), fields(app_name=%app.name), err)] - pub fn create_app(&mut self, app: App) -> CollaborateResult> { - let workspace_id = app.workspace_id.clone(); - let app_serde: AppRevision = app.into(); + #[tracing::instrument(level = "trace", skip(self), fields(app_name=%app_rev.name), err)] + pub fn create_app(&mut self, app_rev: AppRevision) -> CollaborateResult> { + let workspace_id = app_rev.workspace_id.clone(); self.with_workspace(&workspace_id, move |workspace| { - if workspace.apps.contains(&app_serde) { + if workspace.apps.contains(&app_rev) { tracing::warn!("[RootFolder]: Duplicate app"); return Ok(None); } - workspace.apps.push(app_serde); + workspace.apps.push(app_rev); Ok(Some(())) }) } - pub fn read_app(&self, app_id: &str) -> CollaborateResult { + pub fn read_app(&self, app_id: &str) -> CollaborateResult { for workspace in &self.workspaces { if let Some(app) = workspace.apps.iter().find(|app| app.id == app_id) { - return Ok(app.clone().into()); + return Ok(app.clone()); } } Err(CollaborateError::record_not_found().context(format!("Can't find app with id {}", app_id))) @@ -183,36 +182,35 @@ impl FolderPad { }) } - #[tracing::instrument(level = "trace", skip(self), fields(view_name=%view.name), err)] - pub fn create_view(&mut self, view: View) -> CollaborateResult> { - let app_id = view.belong_to_id.clone(); - let view_serde: ViewRevision = view.into(); + #[tracing::instrument(level = "trace", skip(self), fields(view_name=%view_rev.name), err)] + pub fn create_view(&mut self, view_rev: ViewRevision) -> CollaborateResult> { + let app_id = view_rev.belong_to_id.clone(); self.with_app(&app_id, move |app| { - if app.belongings.contains(&view_serde) { + if app.belongings.contains(&view_rev) { tracing::warn!("[RootFolder]: Duplicate view"); return Ok(None); } - app.belongings.push(view_serde); + app.belongings.push(view_rev); Ok(Some(())) }) } - pub fn read_view(&self, view_id: &str) -> CollaborateResult { + pub fn read_view(&self, view_id: &str) -> CollaborateResult { for workspace in &self.workspaces { for app in &(*workspace.apps) { if let Some(view) = app.belongings.iter().find(|b| b.id == view_id) { - return Ok(view.clone().into()); + return Ok(view.clone()); } } } Err(CollaborateError::record_not_found().context(format!("Can't find view with id {}", view_id))) } - pub fn read_views(&self, belong_to_id: &str) -> CollaborateResult> { + pub fn read_views(&self, belong_to_id: &str) -> CollaborateResult> { for workspace in &self.workspaces { for app in &(*workspace.apps) { if app.id == belong_to_id { - return Ok(app.belongings.iter().map(|view| view.clone().into()).collect()); + return Ok(app.belongings.to_vec()); } } } @@ -261,27 +259,24 @@ impl FolderPad { }) } - pub fn create_trash(&mut self, trash: Vec) -> CollaborateResult> { + pub fn create_trash(&mut self, trash: Vec) -> CollaborateResult> { self.with_trash(|t| { - let mut new_trash = trash - .into_iter() - .map(|t| Arc::new(t.into())) - .collect::>>(); + let mut new_trash = trash.into_iter().map(Arc::new).collect::>>(); t.append(&mut new_trash); Ok(Some(())) }) } - pub fn read_trash(&self, trash_id: Option) -> CollaborateResult> { + pub fn read_trash(&self, trash_id: Option) -> CollaborateResult> { match trash_id { None => Ok(self .trash .iter() - .map(|t| t.as_ref().clone().into()) - .collect::>()), + .map(|t| t.as_ref().clone()) + .collect::>()), Some(trash_id) => match self.trash.iter().find(|t| t.id == trash_id) { - Some(trash) => Ok(vec![trash.as_ref().clone().into()]), + Some(trash) => Ok(vec![trash.as_ref().clone()]), None => Ok(vec![]), }, } @@ -438,7 +433,8 @@ mod tests { #![allow(clippy::all)] use crate::{client_folder::folder_pad::FolderPad, entities::folder_info::FolderDelta}; use chrono::Utc; - use flowy_folder_data_model::entities::{app::App, trash::Trash, view::View, workspace::Workspace}; + + use flowy_folder_data_model::revision::{AppRevision, TrashRevision, ViewRevision, WorkspaceRevision}; use lib_ot::core::{OperationTransformable, PlainTextDelta, PlainTextDeltaBuilder}; #[test] @@ -446,11 +442,11 @@ mod tests { let (mut folder, initial_delta, _) = test_folder(); let _time = Utc::now(); - let mut workspace_1 = Workspace::default(); + let mut workspace_1 = WorkspaceRevision::default(); workspace_1.name = "My first workspace".to_owned(); let delta_1 = folder.create_workspace(workspace_1).unwrap().unwrap().delta; - let mut workspace_2 = Workspace::default(); + let mut workspace_2 = WorkspaceRevision::default(); workspace_2.name = "My second workspace".to_owned(); let delta_2 = folder.create_workspace(workspace_2).unwrap().unwrap().delta; @@ -751,62 +747,68 @@ mod tests { ); } - fn test_folder() -> (FolderPad, FolderDelta, Workspace) { + fn test_folder() -> (FolderPad, FolderDelta, WorkspaceRevision) { let mut folder = FolderPad::default(); let folder_json = serde_json::to_string(&folder).unwrap(); let mut delta = PlainTextDeltaBuilder::new().insert(&folder_json).build(); - let mut workspace = Workspace::default(); - workspace.name = "😁 my first workspace".to_owned(); - workspace.id = "1".to_owned(); + let mut workspace_rev = WorkspaceRevision::default(); + workspace_rev.name = "😁 my first workspace".to_owned(); + workspace_rev.id = "1".to_owned(); delta = delta - .compose(&folder.create_workspace(workspace.clone()).unwrap().unwrap().delta) + .compose(&folder.create_workspace(workspace_rev.clone()).unwrap().unwrap().delta) .unwrap(); - (folder, delta, workspace) + (folder, delta, workspace_rev) } - fn test_app_folder() -> (FolderPad, FolderDelta, App) { + fn test_app_folder() -> (FolderPad, FolderDelta, AppRevision) { let (mut folder, mut initial_delta, workspace) = test_folder(); - let mut app = App::default(); - app.workspace_id = workspace.id; - app.name = "😁 my first app".to_owned(); + let mut app_rev = AppRevision::default(); + app_rev.workspace_id = workspace.id; + app_rev.name = "😁 my first app".to_owned(); initial_delta = initial_delta - .compose(&folder.create_app(app.clone()).unwrap().unwrap().delta) + .compose(&folder.create_app(app_rev.clone()).unwrap().unwrap().delta) .unwrap(); - (folder, initial_delta, app) + (folder, initial_delta, app_rev) } - fn test_view_folder() -> (FolderPad, FolderDelta, View) { + fn test_view_folder() -> (FolderPad, FolderDelta, ViewRevision) { let (mut folder, mut initial_delta, app) = test_app_folder(); - let mut view = View::default(); - view.belong_to_id = app.id.clone(); - view.name = "🎃 my first view".to_owned(); + let mut view_rev = ViewRevision::default(); + view_rev.belong_to_id = app.id.clone(); + view_rev.name = "🎃 my first view".to_owned(); initial_delta = initial_delta - .compose(&folder.create_view(view.clone()).unwrap().unwrap().delta) + .compose(&folder.create_view(view_rev.clone()).unwrap().unwrap().delta) .unwrap(); - (folder, initial_delta, view) + (folder, initial_delta, view_rev) } - fn test_trash() -> (FolderPad, FolderDelta, Trash) { + fn test_trash() -> (FolderPad, FolderDelta, TrashRevision) { let mut folder = FolderPad::default(); let folder_json = serde_json::to_string(&folder).unwrap(); let mut delta = PlainTextDeltaBuilder::new().insert(&folder_json).build(); - let mut trash = Trash::default(); - trash.name = "🚽 my first trash".to_owned(); - trash.id = "1".to_owned(); + let mut trash_rev = TrashRevision::default(); + trash_rev.name = "🚽 my first trash".to_owned(); + trash_rev.id = "1".to_owned(); delta = delta - .compose(&folder.create_trash(vec![trash.clone()]).unwrap().unwrap().delta) + .compose( + &folder + .create_trash(vec![trash_rev.clone().into()]) + .unwrap() + .unwrap() + .delta, + ) .unwrap(); - (folder, delta, trash) + (folder, delta, trash_rev) } fn make_folder_from_delta(mut initial_delta: FolderDelta, deltas: Vec) -> FolderPad { diff --git a/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs b/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs index d0c2853fe6..da80dfebd0 100644 --- a/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs +++ b/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs @@ -25,7 +25,7 @@ pub trait JsonDeserializer { impl GridMetaPad { pub async fn duplicate_grid_meta(&self) -> (Vec, Vec) { - let fields = self.grid_meta.fields.iter().cloned().collect::>(); + let fields = self.grid_meta.fields.to_vec(); let blocks = self .grid_meta