From ef4c4180e2d517d74be7b727cebac2a85e825105 Mon Sep 17 00:00:00 2001 From: appflowy Date: Mon, 19 Jul 2021 16:15:20 +0800 Subject: [PATCH] fix sqlite database is lock issue by setting busy_timeout and wal mode --- .../protobuf/flowy-user/errors.pbenum.dart | 20 +- .../protobuf/flowy-user/errors.pbjson.dart | 12 +- .../flowy-workspace/errors.pbenum.dart | 4 +- .../flowy-workspace/errors.pbjson.dart | 4 +- .../flowy-workspace/event.pbenum.dart | 4 +- .../flowy-workspace/event.pbjson.dart | 4 +- .../protobuf/flowy-workspace/protobuf.dart | 1 + .../workspace_user_detail.pb.dart | 137 +++++ .../workspace_user_detail.pbenum.dart | 7 + .../workspace_user_detail.pbjson.dart | 32 ++ .../workspace_user_detail.pbserver.dart | 9 + .../src/derive_cache/derive_cache.rs | 2 + rust-lib/flowy-dispatch/src/dispatch.rs | 4 +- rust-lib/flowy-infra/src/kv/kv.rs | 15 +- rust-lib/flowy-sdk/src/deps_resolve/mod.rs | 3 + .../src/deps_resolve/workspace_user_impl.rs | 63 +++ rust-lib/flowy-sdk/src/lib.rs | 7 +- rust-lib/flowy-sdk/src/module.rs | 44 +- rust-lib/flowy-sqlite/src/conn_ext.rs | 30 ++ rust-lib/flowy-sqlite/src/lib.rs | 3 + rust-lib/flowy-sqlite/src/pool.rs | 51 +- rust-lib/flowy-sqlite/src/pragma.rs | 186 +++++++ rust-lib/flowy-test/src/builder.rs | 17 +- rust-lib/flowy-test/src/tester.rs | 14 +- rust-lib/flowy-user/src/errors.rs | 14 +- .../flowy-user/src/protobuf/model/errors.rs | 120 ++--- .../src/protobuf/proto/errors.proto | 10 +- .../src/services/user_session/database.rs | 13 +- .../src/services/user_session/user_session.rs | 24 +- .../flowy-user/tests/event/sign_in_test.rs | 230 --------- .../flowy-user/tests/event/sign_up_test.rs | 130 ++--- .../tests/event/user_status_test.rs | 72 +-- .../tests/event/user_update_test.rs | 280 +++++------ .../workspace/workspace_user_detail.rs | 22 +- rust-lib/flowy-workspace/src/errors.rs | 12 +- rust-lib/flowy-workspace/src/event.rs | 8 +- .../src/handlers/workspace_handler.rs | 19 +- rust-lib/flowy-workspace/src/module.rs | 8 +- .../src/protobuf/model/errors.rs | 16 +- .../src/protobuf/model/event.rs | 22 +- .../flowy-workspace/src/protobuf/model/mod.rs | 3 + .../protobuf/model/workspace_user_detail.rs | 476 ++++++++++++++++++ .../src/protobuf/proto/errors.proto | 2 +- .../src/protobuf/proto/event.proto | 2 +- .../proto/workspace_user_detail.proto | 11 + .../src/services/workspace_controller.rs | 32 +- .../tests/event/workspace_test.rs | 23 +- scripts/flowy-tool/Cargo.toml | 3 +- scripts/flowy-tool/src/proto/ast.rs | 1 + scripts/flowy-tool/src/proto/proto_info.rs | 2 + scripts/flowy-tool/src/util/file.rs | 11 + 51 files changed, 1539 insertions(+), 700 deletions(-) create mode 100644 app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/workspace_user_detail.pb.dart create mode 100644 app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/workspace_user_detail.pbenum.dart create mode 100644 app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/workspace_user_detail.pbjson.dart create mode 100644 app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/workspace_user_detail.pbserver.dart create mode 100644 rust-lib/flowy-sdk/src/deps_resolve/mod.rs create mode 100644 rust-lib/flowy-sdk/src/deps_resolve/workspace_user_impl.rs create mode 100644 rust-lib/flowy-sqlite/src/conn_ext.rs create mode 100644 rust-lib/flowy-sqlite/src/pragma.rs create mode 100644 rust-lib/flowy-workspace/src/protobuf/model/workspace_user_detail.rs create mode 100644 rust-lib/flowy-workspace/src/protobuf/proto/workspace_user_detail.proto diff --git a/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-user/errors.pbenum.dart b/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-user/errors.pbenum.dart index 9b07cc71c3..3743123065 100644 --- a/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-user/errors.pbenum.dart +++ b/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-user/errors.pbenum.dart @@ -11,11 +11,11 @@ import 'package:protobuf/protobuf.dart' as $pb; class UserErrorCode extends $pb.ProtobufEnum { static const UserErrorCode Unknown = UserErrorCode._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Unknown'); - static const UserErrorCode DatabaseInitFailed = UserErrorCode._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DatabaseInitFailed'); - static const UserErrorCode DatabaseWriteLocked = UserErrorCode._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DatabaseWriteLocked'); - static const UserErrorCode DatabaseReadLocked = UserErrorCode._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DatabaseReadLocked'); - static const UserErrorCode DatabaseUserDidNotMatch = UserErrorCode._(4, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DatabaseUserDidNotMatch'); - static const UserErrorCode DatabaseInternalError = UserErrorCode._(5, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DatabaseInternalError'); + static const UserErrorCode UserDatabaseInitFailed = UserErrorCode._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserDatabaseInitFailed'); + static const UserErrorCode UserDatabaseWriteLocked = UserErrorCode._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserDatabaseWriteLocked'); + static const UserErrorCode UserDatabaseReadLocked = UserErrorCode._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserDatabaseReadLocked'); + static const UserErrorCode UserDatabaseDidNotMatch = UserErrorCode._(4, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserDatabaseDidNotMatch'); + static const UserErrorCode UserDatabaseInternalError = UserErrorCode._(5, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserDatabaseInternalError'); static const UserErrorCode UserNotLoginYet = UserErrorCode._(10, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserNotLoginYet'); static const UserErrorCode ReadCurrentIdFailed = UserErrorCode._(11, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ReadCurrentIdFailed'); static const UserErrorCode WriteCurrentIdFailed = UserErrorCode._(12, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'WriteCurrentIdFailed'); @@ -27,11 +27,11 @@ class UserErrorCode extends $pb.ProtobufEnum { static const $core.List values = [ Unknown, - DatabaseInitFailed, - DatabaseWriteLocked, - DatabaseReadLocked, - DatabaseUserDidNotMatch, - DatabaseInternalError, + UserDatabaseInitFailed, + UserDatabaseWriteLocked, + UserDatabaseReadLocked, + UserDatabaseDidNotMatch, + UserDatabaseInternalError, UserNotLoginYet, ReadCurrentIdFailed, WriteCurrentIdFailed, diff --git a/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-user/errors.pbjson.dart b/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-user/errors.pbjson.dart index 217cb44134..1e2eb92c66 100644 --- a/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-user/errors.pbjson.dart +++ b/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-user/errors.pbjson.dart @@ -13,11 +13,11 @@ const UserErrorCode$json = const { '1': 'UserErrorCode', '2': const [ const {'1': 'Unknown', '2': 0}, - const {'1': 'DatabaseInitFailed', '2': 1}, - const {'1': 'DatabaseWriteLocked', '2': 2}, - const {'1': 'DatabaseReadLocked', '2': 3}, - const {'1': 'DatabaseUserDidNotMatch', '2': 4}, - const {'1': 'DatabaseInternalError', '2': 5}, + const {'1': 'UserDatabaseInitFailed', '2': 1}, + const {'1': 'UserDatabaseWriteLocked', '2': 2}, + const {'1': 'UserDatabaseReadLocked', '2': 3}, + const {'1': 'UserDatabaseDidNotMatch', '2': 4}, + const {'1': 'UserDatabaseInternalError', '2': 5}, const {'1': 'UserNotLoginYet', '2': 10}, const {'1': 'ReadCurrentIdFailed', '2': 11}, const {'1': 'WriteCurrentIdFailed', '2': 12}, @@ -30,7 +30,7 @@ const UserErrorCode$json = const { }; /// Descriptor for `UserErrorCode`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List userErrorCodeDescriptor = $convert.base64Decode('Cg1Vc2VyRXJyb3JDb2RlEgsKB1Vua25vd24QABIWChJEYXRhYmFzZUluaXRGYWlsZWQQARIXChNEYXRhYmFzZVdyaXRlTG9ja2VkEAISFgoSRGF0YWJhc2VSZWFkTG9ja2VkEAMSGwoXRGF0YWJhc2VVc2VyRGlkTm90TWF0Y2gQBBIZChVEYXRhYmFzZUludGVybmFsRXJyb3IQBRITCg9Vc2VyTm90TG9naW5ZZXQQChIXChNSZWFkQ3VycmVudElkRmFpbGVkEAsSGAoUV3JpdGVDdXJyZW50SWRGYWlsZWQQDBIQCgxFbWFpbEludmFsaWQQFBITCg9QYXNzd29yZEludmFsaWQQFRITCg9Vc2VyTmFtZUludmFsaWQQFhIYChRVc2VyV29ya3NwYWNlSW52YWxpZBAXEhEKDVVzZXJJZEludmFsaWQQGA=='); +final $typed_data.Uint8List userErrorCodeDescriptor = $convert.base64Decode('Cg1Vc2VyRXJyb3JDb2RlEgsKB1Vua25vd24QABIaChZVc2VyRGF0YWJhc2VJbml0RmFpbGVkEAESGwoXVXNlckRhdGFiYXNlV3JpdGVMb2NrZWQQAhIaChZVc2VyRGF0YWJhc2VSZWFkTG9ja2VkEAMSGwoXVXNlckRhdGFiYXNlRGlkTm90TWF0Y2gQBBIdChlVc2VyRGF0YWJhc2VJbnRlcm5hbEVycm9yEAUSEwoPVXNlck5vdExvZ2luWWV0EAoSFwoTUmVhZEN1cnJlbnRJZEZhaWxlZBALEhgKFFdyaXRlQ3VycmVudElkRmFpbGVkEAwSEAoMRW1haWxJbnZhbGlkEBQSEwoPUGFzc3dvcmRJbnZhbGlkEBUSEwoPVXNlck5hbWVJbnZhbGlkEBYSGAoUVXNlcldvcmtzcGFjZUludmFsaWQQFxIRCg1Vc2VySWRJbnZhbGlkEBg='); @$core.Deprecated('Use userErrorDescriptor instead') const UserError$json = const { '1': 'UserError', diff --git a/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/errors.pbenum.dart b/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/errors.pbenum.dart index ec32d54844..40189fb948 100644 --- a/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/errors.pbenum.dart +++ b/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/errors.pbenum.dart @@ -16,7 +16,7 @@ class WorkspaceErrorCode extends $pb.ProtobufEnum { static const WorkspaceErrorCode AppColorStyleInvalid = WorkspaceErrorCode._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'AppColorStyleInvalid'); static const WorkspaceErrorCode AppIdInvalid = WorkspaceErrorCode._(4, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'AppIdInvalid'); static const WorkspaceErrorCode DatabaseConnectionFail = WorkspaceErrorCode._(5, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DatabaseConnectionFail'); - static const WorkspaceErrorCode DatabaseInternalError = WorkspaceErrorCode._(6, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DatabaseInternalError'); + static const WorkspaceErrorCode WorkspaceDatabaseError = WorkspaceErrorCode._(6, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'WorkspaceDatabaseError'); static const WorkspaceErrorCode UserInternalError = WorkspaceErrorCode._(10, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserInternalError'); static const WorkspaceErrorCode UserNotLoginYet = WorkspaceErrorCode._(11, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserNotLoginYet'); @@ -27,7 +27,7 @@ class WorkspaceErrorCode extends $pb.ProtobufEnum { AppColorStyleInvalid, AppIdInvalid, DatabaseConnectionFail, - DatabaseInternalError, + WorkspaceDatabaseError, UserInternalError, UserNotLoginYet, ]; diff --git a/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/errors.pbjson.dart b/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/errors.pbjson.dart index 7bb4fc0447..b855710f36 100644 --- a/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/errors.pbjson.dart +++ b/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/errors.pbjson.dart @@ -18,14 +18,14 @@ const WorkspaceErrorCode$json = const { const {'1': 'AppColorStyleInvalid', '2': 3}, const {'1': 'AppIdInvalid', '2': 4}, const {'1': 'DatabaseConnectionFail', '2': 5}, - const {'1': 'DatabaseInternalError', '2': 6}, + const {'1': 'WorkspaceDatabaseError', '2': 6}, const {'1': 'UserInternalError', '2': 10}, const {'1': 'UserNotLoginYet', '2': 11}, ], }; /// Descriptor for `WorkspaceErrorCode`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List workspaceErrorCodeDescriptor = $convert.base64Decode('ChJXb3Jrc3BhY2VFcnJvckNvZGUSCwoHVW5rbm93bhAAEhgKFFdvcmtzcGFjZU5hbWVJbnZhbGlkEAESFgoSV29ya3NwYWNlSWRJbnZhbGlkEAISGAoUQXBwQ29sb3JTdHlsZUludmFsaWQQAxIQCgxBcHBJZEludmFsaWQQBBIaChZEYXRhYmFzZUNvbm5lY3Rpb25GYWlsEAUSGQoVRGF0YWJhc2VJbnRlcm5hbEVycm9yEAYSFQoRVXNlckludGVybmFsRXJyb3IQChITCg9Vc2VyTm90TG9naW5ZZXQQCw=='); +final $typed_data.Uint8List workspaceErrorCodeDescriptor = $convert.base64Decode('ChJXb3Jrc3BhY2VFcnJvckNvZGUSCwoHVW5rbm93bhAAEhgKFFdvcmtzcGFjZU5hbWVJbnZhbGlkEAESFgoSV29ya3NwYWNlSWRJbnZhbGlkEAISGAoUQXBwQ29sb3JTdHlsZUludmFsaWQQAxIQCgxBcHBJZEludmFsaWQQBBIaChZEYXRhYmFzZUNvbm5lY3Rpb25GYWlsEAUSGgoWV29ya3NwYWNlRGF0YWJhc2VFcnJvchAGEhUKEVVzZXJJbnRlcm5hbEVycm9yEAoSEwoPVXNlck5vdExvZ2luWWV0EAs='); @$core.Deprecated('Use workspaceErrorDescriptor instead') const WorkspaceError$json = const { '1': 'WorkspaceError', diff --git a/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/event.pbenum.dart b/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/event.pbenum.dart index 1d9502e8d9..02c50ad27f 100644 --- a/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/event.pbenum.dart +++ b/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/event.pbenum.dart @@ -11,11 +11,11 @@ import 'package:protobuf/protobuf.dart' as $pb; class WorkspaceEvent extends $pb.ProtobufEnum { static const WorkspaceEvent CreateWorkspace = WorkspaceEvent._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateWorkspace'); - static const WorkspaceEvent GetWorkspaceUserDetail = WorkspaceEvent._(100, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetWorkspaceUserDetail'); + static const WorkspaceEvent GetWorkspaceDetail = WorkspaceEvent._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetWorkspaceDetail'); static const $core.List values = [ CreateWorkspace, - GetWorkspaceUserDetail, + GetWorkspaceDetail, ]; static final $core.Map<$core.int, WorkspaceEvent> _byValue = $pb.ProtobufEnum.initByValue(values); diff --git a/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/event.pbjson.dart b/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/event.pbjson.dart index 7466b2d76b..86296a37ea 100644 --- a/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/event.pbjson.dart +++ b/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/event.pbjson.dart @@ -13,9 +13,9 @@ const WorkspaceEvent$json = const { '1': 'WorkspaceEvent', '2': const [ const {'1': 'CreateWorkspace', '2': 0}, - const {'1': 'GetWorkspaceUserDetail', '2': 100}, + const {'1': 'GetWorkspaceDetail', '2': 1}, ], }; /// Descriptor for `WorkspaceEvent`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List workspaceEventDescriptor = $convert.base64Decode('Cg5Xb3Jrc3BhY2VFdmVudBITCg9DcmVhdGVXb3Jrc3BhY2UQABIaChZHZXRXb3Jrc3BhY2VVc2VyRGV0YWlsEGQ='); +final $typed_data.Uint8List workspaceEventDescriptor = $convert.base64Decode('Cg5Xb3Jrc3BhY2VFdmVudBITCg9DcmVhdGVXb3Jrc3BhY2UQABIWChJHZXRXb3Jrc3BhY2VEZXRhaWwQAQ=='); diff --git a/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/protobuf.dart b/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/protobuf.dart index c2b727a826..cee28e7715 100644 --- a/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/protobuf.dart +++ b/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/protobuf.dart @@ -3,5 +3,6 @@ export './errors.pb.dart'; export './workspace_update.pb.dart'; export './app_create.pb.dart'; export './event.pb.dart'; +export './workspace_user_detail.pb.dart'; export './workspace_create.pb.dart'; export './app_update.pb.dart'; diff --git a/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/workspace_user_detail.pb.dart b/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/workspace_user_detail.pb.dart new file mode 100644 index 0000000000..94f2b8bc49 --- /dev/null +++ b/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/workspace_user_detail.pb.dart @@ -0,0 +1,137 @@ +/// +// Generated code. Do not modify. +// source: workspace_user_detail.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields + +import 'dart:core' as $core; + +import 'package:protobuf/protobuf.dart' as $pb; + +import 'workspace_create.pb.dart' as $0; + +class UserWorkspace extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'UserWorkspace', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'owner') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'workspaceId') + ..hasRequiredFields = false + ; + + UserWorkspace._() : super(); + factory UserWorkspace({ + $core.String? owner, + $core.String? workspaceId, + }) { + final _result = create(); + if (owner != null) { + _result.owner = owner; + } + if (workspaceId != null) { + _result.workspaceId = workspaceId; + } + return _result; + } + factory UserWorkspace.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory UserWorkspace.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') + UserWorkspace clone() => UserWorkspace()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + UserWorkspace copyWith(void Function(UserWorkspace) updates) => super.copyWith((message) => updates(message as UserWorkspace)) as UserWorkspace; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static UserWorkspace create() => UserWorkspace._(); + UserWorkspace createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static UserWorkspace getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static UserWorkspace? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get owner => $_getSZ(0); + @$pb.TagNumber(1) + set owner($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasOwner() => $_has(0); + @$pb.TagNumber(1) + void clearOwner() => clearField(1); + + @$pb.TagNumber(2) + $core.String get workspaceId => $_getSZ(1); + @$pb.TagNumber(2) + set workspaceId($core.String v) { $_setString(1, v); } + @$pb.TagNumber(2) + $core.bool hasWorkspaceId() => $_has(1); + @$pb.TagNumber(2) + void clearWorkspaceId() => clearField(2); +} + +class UserWorkspaceDetail extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'UserWorkspaceDetail', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'owner') + ..aOM<$0.WorkspaceDetail>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'workspace', subBuilder: $0.WorkspaceDetail.create) + ..hasRequiredFields = false + ; + + UserWorkspaceDetail._() : super(); + factory UserWorkspaceDetail({ + $core.String? owner, + $0.WorkspaceDetail? workspace, + }) { + final _result = create(); + if (owner != null) { + _result.owner = owner; + } + if (workspace != null) { + _result.workspace = workspace; + } + return _result; + } + factory UserWorkspaceDetail.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory UserWorkspaceDetail.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') + UserWorkspaceDetail clone() => UserWorkspaceDetail()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + UserWorkspaceDetail copyWith(void Function(UserWorkspaceDetail) updates) => super.copyWith((message) => updates(message as UserWorkspaceDetail)) as UserWorkspaceDetail; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static UserWorkspaceDetail create() => UserWorkspaceDetail._(); + UserWorkspaceDetail createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static UserWorkspaceDetail getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static UserWorkspaceDetail? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get owner => $_getSZ(0); + @$pb.TagNumber(1) + set owner($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasOwner() => $_has(0); + @$pb.TagNumber(1) + void clearOwner() => clearField(1); + + @$pb.TagNumber(2) + $0.WorkspaceDetail get workspace => $_getN(1); + @$pb.TagNumber(2) + set workspace($0.WorkspaceDetail v) { setField(2, v); } + @$pb.TagNumber(2) + $core.bool hasWorkspace() => $_has(1); + @$pb.TagNumber(2) + void clearWorkspace() => clearField(2); + @$pb.TagNumber(2) + $0.WorkspaceDetail ensureWorkspace() => $_ensure(1); +} + diff --git a/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/workspace_user_detail.pbenum.dart b/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/workspace_user_detail.pbenum.dart new file mode 100644 index 0000000000..ca5e23ef81 --- /dev/null +++ b/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/workspace_user_detail.pbenum.dart @@ -0,0 +1,7 @@ +/// +// Generated code. Do not modify. +// source: workspace_user_detail.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields + diff --git a/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/workspace_user_detail.pbjson.dart b/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/workspace_user_detail.pbjson.dart new file mode 100644 index 0000000000..10d0b093c9 --- /dev/null +++ b/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/workspace_user_detail.pbjson.dart @@ -0,0 +1,32 @@ +/// +// Generated code. Do not modify. +// source: workspace_user_detail.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package + +import 'dart:core' as $core; +import 'dart:convert' as $convert; +import 'dart:typed_data' as $typed_data; +@$core.Deprecated('Use userWorkspaceDescriptor instead') +const UserWorkspace$json = const { + '1': 'UserWorkspace', + '2': const [ + const {'1': 'owner', '3': 1, '4': 1, '5': 9, '10': 'owner'}, + const {'1': 'workspace_id', '3': 2, '4': 1, '5': 9, '10': 'workspaceId'}, + ], +}; + +/// Descriptor for `UserWorkspace`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List userWorkspaceDescriptor = $convert.base64Decode('Cg1Vc2VyV29ya3NwYWNlEhQKBW93bmVyGAEgASgJUgVvd25lchIhCgx3b3Jrc3BhY2VfaWQYAiABKAlSC3dvcmtzcGFjZUlk'); +@$core.Deprecated('Use userWorkspaceDetailDescriptor instead') +const UserWorkspaceDetail$json = const { + '1': 'UserWorkspaceDetail', + '2': const [ + const {'1': 'owner', '3': 1, '4': 1, '5': 9, '10': 'owner'}, + const {'1': 'workspace', '3': 2, '4': 1, '5': 11, '6': '.WorkspaceDetail', '10': 'workspace'}, + ], +}; + +/// Descriptor for `UserWorkspaceDetail`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List userWorkspaceDetailDescriptor = $convert.base64Decode('ChNVc2VyV29ya3NwYWNlRGV0YWlsEhQKBW93bmVyGAEgASgJUgVvd25lchIuCgl3b3Jrc3BhY2UYAiABKAsyEC5Xb3Jrc3BhY2VEZXRhaWxSCXdvcmtzcGFjZQ=='); diff --git a/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/workspace_user_detail.pbserver.dart b/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/workspace_user_detail.pbserver.dart new file mode 100644 index 0000000000..8fc33d92ca --- /dev/null +++ b/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/workspace_user_detail.pbserver.dart @@ -0,0 +1,9 @@ +/// +// Generated code. Do not modify. +// source: workspace_user_detail.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package + +export 'workspace_user_detail.pb.dart'; + diff --git a/rust-lib/flowy-derive/src/derive_cache/derive_cache.rs b/rust-lib/flowy-derive/src/derive_cache/derive_cache.rs index c0efa13115..088c2ee0c3 100644 --- a/rust-lib/flowy-derive/src/derive_cache/derive_cache.rs +++ b/rust-lib/flowy-derive/src/derive_cache/derive_cache.rs @@ -23,6 +23,8 @@ pub fn category_from_str(type_str: &str) -> TypeCategory { | "UpdateWorkspaceRequest" | "CreateWorkspaceRequest" | "WorkspaceDetail" + | "UserWorkspace" + | "UserWorkspaceDetail" | "WorkspaceError" | "FFIRequest" | "FFIResponse" diff --git a/rust-lib/flowy-dispatch/src/dispatch.rs b/rust-lib/flowy-dispatch/src/dispatch.rs index 435a4aca9b..308ba1f164 100644 --- a/rust-lib/flowy-dispatch/src/dispatch.rs +++ b/rust-lib/flowy-dispatch/src/dispatch.rs @@ -99,14 +99,14 @@ impl EventDispatch { } #[pin_project] -pub struct DispatchFuture { +pub struct DispatchFuture { #[pin] pub fut: Pin + Sync + Send>>, } impl Future for DispatchFuture where - T: Responder + Send + Sync, + T: Send + Sync, { type Output = T; diff --git a/rust-lib/flowy-infra/src/kv/kv.rs b/rust-lib/flowy-infra/src/kv/kv.rs index cadc0032b8..36bc30ecc1 100644 --- a/rust-lib/flowy-infra/src/kv/kv.rs +++ b/rust-lib/flowy-infra/src/kv/kv.rs @@ -18,22 +18,21 @@ pub struct KVStore { impl KVStore { fn new() -> Self { KVStore { database: None } } - pub fn set(item: KeyValue) -> Result<(), String> { - let conn = get_connection()?; + fn set(item: KeyValue) -> Result<(), String> { let _ = diesel::replace_into(kv_table::table) .values(&item) - .execute(&*conn) - .map_err(|e| format!("{:?}", e))?; + .execute(&*(get_connection()?)) + .map_err(|e| format!("KV set error: {:?}", e))?; Ok(()) } - pub fn get(key: &str) -> Result { + fn get(key: &str) -> Result { let conn = get_connection()?; let item = dsl::kv_table .filter(kv_table::key.eq(key)) .first::(&*conn) - .map_err(|e| format!("{:?}", e))?; + .map_err(|e| format!("KV get error: {:?}", e))?; Ok(item) } @@ -43,7 +42,7 @@ impl KVStore { let sql = dsl::kv_table.filter(kv_table::key.eq(key)); let _ = diesel::delete(sql) .execute(&*conn) - .map_err(|e| format!("{:?}", e))?; + .map_err(|e| format!("KV remove error: {:?}", e))?; Ok(()) } @@ -125,7 +124,7 @@ fn get_connection() -> Result { .as_ref() .expect("KVStore is not init") .get_connection() - .map_err(|e| format!("{:?}", e))?; + .map_err(|e| format!("KVStore error: {:?}", e))?; Ok(conn) }, Err(e) => { diff --git a/rust-lib/flowy-sdk/src/deps_resolve/mod.rs b/rust-lib/flowy-sdk/src/deps_resolve/mod.rs new file mode 100644 index 0000000000..a49be3ee06 --- /dev/null +++ b/rust-lib/flowy-sdk/src/deps_resolve/mod.rs @@ -0,0 +1,3 @@ +mod workspace_user_impl; + +pub use workspace_user_impl::*; diff --git a/rust-lib/flowy-sdk/src/deps_resolve/workspace_user_impl.rs b/rust-lib/flowy-sdk/src/deps_resolve/workspace_user_impl.rs new file mode 100644 index 0000000000..df069a33a5 --- /dev/null +++ b/rust-lib/flowy-sdk/src/deps_resolve/workspace_user_impl.rs @@ -0,0 +1,63 @@ +use flowy_database::DBConnection; +use flowy_dispatch::prelude::DispatchFuture; +use flowy_user::prelude::UserSession; +use flowy_workspace::{ + entities::workspace::UserWorkspace, + errors::{ErrorBuilder, WorkspaceError, WorkspaceErrorCode}, + module::WorkspaceUser, +}; +use std::sync::Arc; + +pub struct WorkspaceUserImpl { + pub(crate) user_session: Arc, +} + +impl WorkspaceUser for WorkspaceUserImpl { + fn set_cur_workspace_id( + &self, + workspace_id: &str, + ) -> DispatchFuture> { + let user_session = self.user_session.clone(); + let workspace_id = workspace_id.to_owned(); + DispatchFuture { + fut: Box::pin(async move { + let _ = user_session + .set_current_workspace(&workspace_id) + .await + .map_err(|e| { + ErrorBuilder::new(WorkspaceErrorCode::UserInternalError) + .error(e) + .build() + }); + + Ok(()) + }), + } + } + + fn get_cur_workspace(&self) -> DispatchFuture> { + let user_session = self.user_session.clone(); + DispatchFuture { + fut: Box::pin(async move { + let user_detail = user_session.user_detail().map_err(|e| { + ErrorBuilder::new(WorkspaceErrorCode::UserNotLoginYet) + .error(e) + .build() + })?; + + Ok(UserWorkspace { + owner: user_detail.email, + workspace_id: user_detail.workspace, + }) + }), + } + } + + fn db_connection(&self) -> Result { + self.user_session.get_db_connection().map_err(|e| { + ErrorBuilder::new(WorkspaceErrorCode::DatabaseConnectionFail) + .error(e) + .build() + }) + } +} diff --git a/rust-lib/flowy-sdk/src/lib.rs b/rust-lib/flowy-sdk/src/lib.rs index b0d93a4e97..0c73248108 100644 --- a/rust-lib/flowy-sdk/src/lib.rs +++ b/rust-lib/flowy-sdk/src/lib.rs @@ -1,7 +1,9 @@ +mod deps_resolve; mod flowy_server; pub mod module; pub use crate::flowy_server::{ArcFlowyServer, FlowyServerMocker}; +use deps_resolve::*; use flowy_dispatch::prelude::*; use module::build_modules; pub use module::*; @@ -31,7 +33,10 @@ impl FlowySDK { FlowySDK::init_log(root); tracing::info!("🔥 Root path: {}", root); - let _ = flowy_infra::kv::KVStore::init(root); + match flowy_infra::kv::KVStore::init(root) { + Ok(_) => {}, + Err(e) => tracing::error!("Init kv store failedL: {}", e), + } FlowySDK::init_modules(root, server); } diff --git a/rust-lib/flowy-sdk/src/module.rs b/rust-lib/flowy-sdk/src/module.rs index e0a809a4c1..7fceeefb2e 100644 --- a/rust-lib/flowy-sdk/src/module.rs +++ b/rust-lib/flowy-sdk/src/module.rs @@ -4,6 +4,8 @@ use flowy_dispatch::prelude::{DispatchFuture, Module}; use flowy_user::prelude::*; use flowy_workspace::prelude::*; +use crate::deps_resolve::WorkspaceUserImpl; +use flowy_workspace::entities::workspace::UserWorkspace; use std::sync::Arc; pub struct ModuleConfig { @@ -26,45 +28,3 @@ pub fn build_modules(config: ModuleConfig, _server: ArcFlowyServer) -> Vec, -} - -impl WorkspaceUser for WorkspaceUserImpl { - fn set_workspace(&self, workspace_id: &str) -> DispatchFuture> { - let user_session = self.user_session.clone(); - let workspace_id = workspace_id.to_owned(); - DispatchFuture { - fut: Box::pin(async move { - let _ = user_session - .set_current_workspace(&workspace_id) - .await - .map_err(|e| { - ErrorBuilder::new(WorkspaceErrorCode::UserInternalError) - .error(e) - .build() - }); - - Ok(()) - }), - } - } - - fn get_workspace(&self) -> Result { - let user_detail = self.user_session.user_detail().map_err(|e| { - ErrorBuilder::new(WorkspaceErrorCode::UserNotLoginYet) - .error(e) - .build() - })?; - Ok(user_detail.id) - } - - fn db_connection(&self) -> Result { - self.user_session.get_db_connection().map_err(|e| { - ErrorBuilder::new(WorkspaceErrorCode::DatabaseConnectionFail) - .error(e) - .build() - }) - } -} diff --git a/rust-lib/flowy-sqlite/src/conn_ext.rs b/rust-lib/flowy-sqlite/src/conn_ext.rs new file mode 100644 index 0000000000..2a39839178 --- /dev/null +++ b/rust-lib/flowy-sqlite/src/conn_ext.rs @@ -0,0 +1,30 @@ +use crate::errors::*; +use diesel::{ + dsl::sql, + expression::SqlLiteral, + query_dsl::LoadQuery, + Connection, + RunQueryDsl, + SqliteConnection, +}; + +pub trait ConnectionExtension: Connection { + fn query(&self, query: &str) -> Result + where + SqlLiteral: LoadQuery; + + fn exec(&self, query: impl AsRef) -> Result; +} + +impl ConnectionExtension for SqliteConnection { + fn query(&self, query: &str) -> Result + where + SqlLiteral: LoadQuery, + { + Ok(sql::(query).get_result(self)?) + } + + fn exec(&self, query: impl AsRef) -> Result { + Ok(SqliteConnection::execute(self, query.as_ref())?) + } +} diff --git a/rust-lib/flowy-sqlite/src/lib.rs b/rust-lib/flowy-sqlite/src/lib.rs index b631cf95b6..f6d5cbfd8d 100644 --- a/rust-lib/flowy-sqlite/src/lib.rs +++ b/rust-lib/flowy-sqlite/src/lib.rs @@ -1,7 +1,10 @@ +mod conn_ext; mod database; #[allow(deprecated, clippy::large_enum_variant)] mod errors; mod pool; +mod pragma; + pub use database::*; pub use pool::*; diff --git a/rust-lib/flowy-sqlite/src/pool.rs b/rust-lib/flowy-sqlite/src/pool.rs index ebc010eab1..f9f8646d58 100644 --- a/rust-lib/flowy-sqlite/src/pool.rs +++ b/rust-lib/flowy-sqlite/src/pool.rs @@ -1,6 +1,6 @@ -use crate::errors::*; +use crate::{conn_ext::*, errors::*, pragma::*}; use diesel::{connection::Connection, SqliteConnection}; -use r2d2::{ManageConnection, Pool}; +use r2d2::{CustomizeConnection, ManageConnection, Pool}; use scheduled_thread_pool::ScheduledThreadPool; use std::{ sync::{ @@ -34,10 +34,12 @@ impl ConnectionPool { let manager = ConnectionManager::new(uri); let thread_pool = DB_POOL.clone(); let config = Arc::new(config); + let customizer_config = DatabaseCustomizerConfig::default(); let pool = r2d2::Pool::builder() .thread_pool(thread_pool) .min_idle(Some(config.min_idle)) + .connection_customizer(Box::new(DatabaseCustomizer::new(customizer_config))) .max_size(config.max_size) .max_lifetime(None) .connection_timeout(config.connection_timeout) @@ -127,3 +129,48 @@ impl ManageConnection for ConnectionManager { impl ConnectionManager { pub fn new>(uri: S) -> Self { ConnectionManager { db_uri: uri.into() } } } + +#[derive(Debug)] +pub struct DatabaseCustomizerConfig { + pub(crate) journal_mode: SQLiteJournalMode, + pub(crate) synchronous: SQLiteSynchronous, + pub(crate) busy_timeout: i32, + pub(crate) secure_delete: bool, +} + +impl Default for DatabaseCustomizerConfig { + fn default() -> Self { + Self { + journal_mode: SQLiteJournalMode::WAL, + synchronous: SQLiteSynchronous::NORMAL, + busy_timeout: 5000, + secure_delete: true, + } + } +} + +#[derive(Debug)] +struct DatabaseCustomizer { + config: DatabaseCustomizerConfig, +} + +impl DatabaseCustomizer { + fn new(config: DatabaseCustomizerConfig) -> Self + where + Self: Sized, + { + Self { config } + } +} + +impl CustomizeConnection for DatabaseCustomizer { + fn on_acquire(&self, conn: &mut SqliteConnection) -> Result<()> { + conn.pragma_set_busy_timeout(self.config.busy_timeout)?; + if self.config.journal_mode != SQLiteJournalMode::WAL { + conn.pragma_set_journal_mode(self.config.journal_mode, None)?; + } + conn.pragma_set_synchronous(self.config.synchronous, None)?; + + Ok(()) + } +} diff --git a/rust-lib/flowy-sqlite/src/pragma.rs b/rust-lib/flowy-sqlite/src/pragma.rs new file mode 100644 index 0000000000..48c3df487c --- /dev/null +++ b/rust-lib/flowy-sqlite/src/pragma.rs @@ -0,0 +1,186 @@ +use crate::errors::{Error, Result}; +use diesel::{ + expression::SqlLiteral, + query_dsl::load_dsl::LoadQuery, + sql_types::{Integer, Text}, + SqliteConnection, +}; + +use crate::conn_ext::ConnectionExtension; +use std::{ + convert::{TryFrom, TryInto}, + fmt, + str::FromStr, +}; + +pub trait PragmaExtension: ConnectionExtension { + fn pragma(&self, key: &str, val: D, schema: Option<&str>) -> Result<()> { + let query = match schema { + Some(schema) => format!("PRAGMA {}.{} = '{}'", schema, key, val), + None => format!("PRAGMA {} = '{}'", key, val), + }; + log::trace!("SQLITE {}", query); + self.exec(&query)?; + Ok(()) + } + + fn pragma_ret( + &self, + key: &str, + val: D, + schema: Option<&str>, + ) -> Result + where + SqlLiteral: LoadQuery, + { + let query = match schema { + Some(schema) => format!("PRAGMA {}.{} = '{}'", schema, key, val), + None => format!("PRAGMA {} = '{}'", key, val), + }; + log::trace!("SQLITE {}", query); + Ok(self.query::(&query)?) + } + + fn pragma_get(&self, key: &str, schema: Option<&str>) -> Result + where + SqlLiteral: LoadQuery, + { + let query = match schema { + Some(schema) => format!("PRAGMA {}.{}", schema, key), + None => format!("PRAGMA {}", key), + }; + log::trace!("SQLITE {}", query); + Ok(self.query::(&query)?) + } + + fn pragma_set_busy_timeout(&self, timeout_ms: i32) -> Result { + self.pragma_ret::("busy_timeout", timeout_ms, None) + } + + fn pragma_get_busy_timeout(&self) -> Result { + self.pragma_get::("busy_timeout", None) + } + + fn pragma_set_journal_mode( + &self, + mode: SQLiteJournalMode, + schema: Option<&str>, + ) -> Result { + self.pragma_ret::("journal_mode", mode, schema) + } + + fn pragma_get_journal_mode(&self, schema: Option<&str>) -> Result { + Ok(self + .pragma_get::("journal_mode", schema)? + .parse()?) + } + + fn pragma_set_synchronous( + &self, + synchronous: SQLiteSynchronous, + schema: Option<&str>, + ) -> Result<()> { + self.pragma("synchronous", synchronous as u8, schema) + } + + fn pragma_get_synchronous(&self, schema: Option<&str>) -> Result { + Ok(self + .pragma_get::("synchronous", schema)? + .try_into()?) + } +} +impl PragmaExtension for SqliteConnection {} + +#[derive(Debug, PartialEq, Eq, Clone, Copy)] +pub enum SQLiteJournalMode { + DELETE, + TRUNCATE, + PERSIST, + MEMORY, + WAL, + OFF, +} + +impl fmt::Display for SQLiteJournalMode { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "{}", + match self { + Self::DELETE => "DELETE", + Self::TRUNCATE => "TRUNCATE", + Self::PERSIST => "PERSIST", + Self::MEMORY => "MEMORY", + Self::WAL => "WAL", + Self::OFF => "OFF", + } + ) + } +} + +impl FromStr for SQLiteJournalMode { + type Err = Error; + + fn from_str(s: &str) -> Result { + match s.to_uppercase().as_ref() { + "DELETE" => Ok(Self::DELETE), + "TRUNCATE" => Ok(Self::TRUNCATE), + "PERSIST" => Ok(Self::PERSIST), + "MEMORY" => Ok(Self::MEMORY), + "WAL" => Ok(Self::WAL), + "OFF" => Ok(Self::OFF), + _ => Err(format!("Unknown value {} for JournalMode", s).into()), + } + } +} + +#[derive(Debug, PartialEq, Eq, Clone, Copy)] +pub enum SQLiteSynchronous { + EXTRA = 3, + FULL = 2, + NORMAL = 1, + OFF = 0, +} + +impl fmt::Display for SQLiteSynchronous { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "{}", + match self { + Self::OFF => "OFF", + Self::NORMAL => "NORMAL", + Self::FULL => "FULL", + Self::EXTRA => "EXTRA", + } + ) + } +} + +impl TryFrom for SQLiteSynchronous { + type Error = Error; + + fn try_from(v: i32) -> Result { + match v { + 0 => Ok(Self::OFF), + 1 => Ok(Self::NORMAL), + 2 => Ok(Self::FULL), + 3 => Ok(Self::EXTRA), + _ => Err(format!("Unknown value {} for Synchronous", v).into()), + } + } +} + +impl FromStr for SQLiteSynchronous { + type Err = Error; + + fn from_str(s: &str) -> Result { + match s.to_uppercase().as_ref() { + "0" | "OFF" => Ok(Self::OFF), + "1" | "NORMAL" => Ok(Self::NORMAL), + "2" | "FULL" => Ok(Self::FULL), + "3" | "EXTRA" => Ok(Self::EXTRA), + _ => Err(format!("Unknown value {} for Synchronous", s).into()), + } + } +} diff --git a/rust-lib/flowy-test/src/builder.rs b/rust-lib/flowy-test/src/builder.rs index 1e47ce16f5..8c89780c07 100644 --- a/rust-lib/flowy-test/src/builder.rs +++ b/rust-lib/flowy-test/src/builder.rs @@ -20,18 +20,23 @@ impl WorkspaceTestBuilder { tester: Box::new(FixedUserTester::::new()), user_detail: None, }; - builder.login() + + builder.login_if_need() } } pub type UserTestBuilder = TestBuilder>; impl UserTestBuilder { pub fn new() -> Self { - Self { + let builder = Self { tester: Box::new(RandomUserTester::::new()), user_detail: None, - } + }; + + builder } + + pub fn reset(mut self) -> Self { self.logout().login() } } pub struct TestBuilder { @@ -49,6 +54,12 @@ where self } + pub fn login_if_need(mut self) -> Self { + let user_detail = self.tester.login_if_need(); + self.user_detail = Some(user_detail); + self + } + pub fn logout(self) -> Self { self.tester.logout(); self diff --git a/rust-lib/flowy-test/src/tester.rs b/rust-lib/flowy-test/src/tester.rs index 2d450f0209..5330ffc92e 100644 --- a/rust-lib/flowy-test/src/tester.rs +++ b/rust-lib/flowy-test/src/tester.rs @@ -6,7 +6,7 @@ use flowy_dispatch::prelude::*; pub use flowy_sdk::*; use flowy_user::{ errors::UserError, - event::UserEvent::{SignIn, SignOut}, + event::UserEvent::{GetStatus, SignIn, SignOut}, prelude::*, }; use std::{ @@ -99,7 +99,6 @@ pub trait TesterTrait { fn login(&self) -> UserDetail { init_test_sdk(self.context().server.clone()); - self.logout(); let payload = SignInRequest { email: self.context().user_email.clone(), password: valid_password(), @@ -116,6 +115,17 @@ pub trait TesterTrait { user_detail } + fn login_if_need(&self) -> UserDetail { + init_test_sdk(self.context().server.clone()); + match EventDispatch::sync_send(ModuleRequest::new(GetStatus)) + .parse::() + .unwrap() + { + Ok(user_detail) => user_detail, + Err(e) => self.login(), + } + } + fn logout(&self) { init_test_sdk(self.context().server.clone()); let _ = EventDispatch::sync_send(ModuleRequest::new(SignOut)); diff --git a/rust-lib/flowy-user/src/errors.rs b/rust-lib/flowy-user/src/errors.rs index b2ff67213b..b466090fc9 100644 --- a/rust-lib/flowy-user/src/errors.rs +++ b/rust-lib/flowy-user/src/errors.rs @@ -26,15 +26,15 @@ pub enum UserErrorCode { #[display(fmt = "Unknown")] Unknown = 0, #[display(fmt = "Database init failed")] - DatabaseInitFailed = 1, + UserDatabaseInitFailed = 1, #[display(fmt = "Get database write lock failed")] - DatabaseWriteLocked = 2, + UserDatabaseWriteLocked = 2, #[display(fmt = "Get database read lock failed")] - DatabaseReadLocked = 3, + UserDatabaseReadLocked = 3, #[display(fmt = "Opening database is not belonging to the current user")] - DatabaseUserDidNotMatch = 4, + UserDatabaseDidNotMatch = 4, #[display(fmt = "Database internal error")] - DatabaseInternalError = 5, + UserDatabaseInternalError = 5, #[display(fmt = "User not login yet")] UserNotLoginYet = 10, @@ -61,7 +61,7 @@ impl std::default::Default for UserErrorCode { impl std::convert::From for UserError { fn from(error: flowy_database::result::Error) -> Self { - ErrorBuilder::new(UserErrorCode::DatabaseInternalError) + ErrorBuilder::new(UserErrorCode::UserDatabaseInternalError) .error(error) .build() } @@ -69,7 +69,7 @@ impl std::convert::From for UserError { impl std::convert::From for UserError { fn from(error: flowy_sqlite::Error) -> Self { - ErrorBuilder::new(UserErrorCode::DatabaseInternalError) + ErrorBuilder::new(UserErrorCode::UserDatabaseInternalError) .error(error) .build() } diff --git a/rust-lib/flowy-user/src/protobuf/model/errors.rs b/rust-lib/flowy-user/src/protobuf/model/errors.rs index 56637c911d..ef1ed3e7b4 100644 --- a/rust-lib/flowy-user/src/protobuf/model/errors.rs +++ b/rust-lib/flowy-user/src/protobuf/model/errors.rs @@ -216,11 +216,11 @@ impl ::protobuf::reflect::ProtobufValue for UserError { #[derive(Clone,PartialEq,Eq,Debug,Hash)] pub enum UserErrorCode { Unknown = 0, - DatabaseInitFailed = 1, - DatabaseWriteLocked = 2, - DatabaseReadLocked = 3, - DatabaseUserDidNotMatch = 4, - DatabaseInternalError = 5, + UserDatabaseInitFailed = 1, + UserDatabaseWriteLocked = 2, + UserDatabaseReadLocked = 3, + UserDatabaseDidNotMatch = 4, + UserDatabaseInternalError = 5, UserNotLoginYet = 10, ReadCurrentIdFailed = 11, WriteCurrentIdFailed = 12, @@ -239,11 +239,11 @@ impl ::protobuf::ProtobufEnum for UserErrorCode { fn from_i32(value: i32) -> ::std::option::Option { match value { 0 => ::std::option::Option::Some(UserErrorCode::Unknown), - 1 => ::std::option::Option::Some(UserErrorCode::DatabaseInitFailed), - 2 => ::std::option::Option::Some(UserErrorCode::DatabaseWriteLocked), - 3 => ::std::option::Option::Some(UserErrorCode::DatabaseReadLocked), - 4 => ::std::option::Option::Some(UserErrorCode::DatabaseUserDidNotMatch), - 5 => ::std::option::Option::Some(UserErrorCode::DatabaseInternalError), + 1 => ::std::option::Option::Some(UserErrorCode::UserDatabaseInitFailed), + 2 => ::std::option::Option::Some(UserErrorCode::UserDatabaseWriteLocked), + 3 => ::std::option::Option::Some(UserErrorCode::UserDatabaseReadLocked), + 4 => ::std::option::Option::Some(UserErrorCode::UserDatabaseDidNotMatch), + 5 => ::std::option::Option::Some(UserErrorCode::UserDatabaseInternalError), 10 => ::std::option::Option::Some(UserErrorCode::UserNotLoginYet), 11 => ::std::option::Option::Some(UserErrorCode::ReadCurrentIdFailed), 12 => ::std::option::Option::Some(UserErrorCode::WriteCurrentIdFailed), @@ -259,11 +259,11 @@ impl ::protobuf::ProtobufEnum for UserErrorCode { fn values() -> &'static [Self] { static values: &'static [UserErrorCode] = &[ UserErrorCode::Unknown, - UserErrorCode::DatabaseInitFailed, - UserErrorCode::DatabaseWriteLocked, - UserErrorCode::DatabaseReadLocked, - UserErrorCode::DatabaseUserDidNotMatch, - UserErrorCode::DatabaseInternalError, + UserErrorCode::UserDatabaseInitFailed, + UserErrorCode::UserDatabaseWriteLocked, + UserErrorCode::UserDatabaseReadLocked, + UserErrorCode::UserDatabaseDidNotMatch, + UserErrorCode::UserDatabaseInternalError, UserErrorCode::UserNotLoginYet, UserErrorCode::ReadCurrentIdFailed, UserErrorCode::WriteCurrentIdFailed, @@ -302,51 +302,51 @@ impl ::protobuf::reflect::ProtobufValue for UserErrorCode { static file_descriptor_proto_data: &'static [u8] = b"\ \n\x0cerrors.proto\"A\n\tUserError\x12\"\n\x04code\x18\x01\x20\x01(\x0e2\ \x0e.UserErrorCodeR\x04code\x12\x10\n\x03msg\x18\x02\x20\x01(\tR\x03msg*\ - \xce\x02\n\rUserErrorCode\x12\x0b\n\x07Unknown\x10\0\x12\x16\n\x12Databa\ - seInitFailed\x10\x01\x12\x17\n\x13DatabaseWriteLocked\x10\x02\x12\x16\n\ - \x12DatabaseReadLocked\x10\x03\x12\x1b\n\x17DatabaseUserDidNotMatch\x10\ - \x04\x12\x19\n\x15DatabaseInternalError\x10\x05\x12\x13\n\x0fUserNotLogi\ - nYet\x10\n\x12\x17\n\x13ReadCurrentIdFailed\x10\x0b\x12\x18\n\x14WriteCu\ - rrentIdFailed\x10\x0c\x12\x10\n\x0cEmailInvalid\x10\x14\x12\x13\n\x0fPas\ - swordInvalid\x10\x15\x12\x13\n\x0fUserNameInvalid\x10\x16\x12\x18\n\x14U\ - serWorkspaceInvalid\x10\x17\x12\x11\n\rUserIdInvalid\x10\x18J\xee\x05\n\ - \x06\x12\x04\0\0\x15\x01\n\x08\n\x01\x0c\x12\x03\0\0\x12\n\n\n\x02\x04\0\ - \x12\x04\x02\0\x05\x01\n\n\n\x03\x04\0\x01\x12\x03\x02\x08\x11\n\x0b\n\ - \x04\x04\0\x02\0\x12\x03\x03\x04\x1b\n\x0c\n\x05\x04\0\x02\0\x06\x12\x03\ - \x03\x04\x11\n\x0c\n\x05\x04\0\x02\0\x01\x12\x03\x03\x12\x16\n\x0c\n\x05\ - \x04\0\x02\0\x03\x12\x03\x03\x19\x1a\n\x0b\n\x04\x04\0\x02\x01\x12\x03\ - \x04\x04\x13\n\x0c\n\x05\x04\0\x02\x01\x05\x12\x03\x04\x04\n\n\x0c\n\x05\ - \x04\0\x02\x01\x01\x12\x03\x04\x0b\x0e\n\x0c\n\x05\x04\0\x02\x01\x03\x12\ - \x03\x04\x11\x12\n\n\n\x02\x05\0\x12\x04\x06\0\x15\x01\n\n\n\x03\x05\0\ - \x01\x12\x03\x06\x05\x12\n\x0b\n\x04\x05\0\x02\0\x12\x03\x07\x04\x10\n\ - \x0c\n\x05\x05\0\x02\0\x01\x12\x03\x07\x04\x0b\n\x0c\n\x05\x05\0\x02\0\ - \x02\x12\x03\x07\x0e\x0f\n\x0b\n\x04\x05\0\x02\x01\x12\x03\x08\x04\x1b\n\ - \x0c\n\x05\x05\0\x02\x01\x01\x12\x03\x08\x04\x16\n\x0c\n\x05\x05\0\x02\ - \x01\x02\x12\x03\x08\x19\x1a\n\x0b\n\x04\x05\0\x02\x02\x12\x03\t\x04\x1c\ - \n\x0c\n\x05\x05\0\x02\x02\x01\x12\x03\t\x04\x17\n\x0c\n\x05\x05\0\x02\ - \x02\x02\x12\x03\t\x1a\x1b\n\x0b\n\x04\x05\0\x02\x03\x12\x03\n\x04\x1b\n\ - \x0c\n\x05\x05\0\x02\x03\x01\x12\x03\n\x04\x16\n\x0c\n\x05\x05\0\x02\x03\ - \x02\x12\x03\n\x19\x1a\n\x0b\n\x04\x05\0\x02\x04\x12\x03\x0b\x04\x20\n\ - \x0c\n\x05\x05\0\x02\x04\x01\x12\x03\x0b\x04\x1b\n\x0c\n\x05\x05\0\x02\ - \x04\x02\x12\x03\x0b\x1e\x1f\n\x0b\n\x04\x05\0\x02\x05\x12\x03\x0c\x04\ - \x1e\n\x0c\n\x05\x05\0\x02\x05\x01\x12\x03\x0c\x04\x19\n\x0c\n\x05\x05\0\ - \x02\x05\x02\x12\x03\x0c\x1c\x1d\n\x0b\n\x04\x05\0\x02\x06\x12\x03\r\x04\ - \x19\n\x0c\n\x05\x05\0\x02\x06\x01\x12\x03\r\x04\x13\n\x0c\n\x05\x05\0\ - \x02\x06\x02\x12\x03\r\x16\x18\n\x0b\n\x04\x05\0\x02\x07\x12\x03\x0e\x04\ - \x1d\n\x0c\n\x05\x05\0\x02\x07\x01\x12\x03\x0e\x04\x17\n\x0c\n\x05\x05\0\ - \x02\x07\x02\x12\x03\x0e\x1a\x1c\n\x0b\n\x04\x05\0\x02\x08\x12\x03\x0f\ - \x04\x1e\n\x0c\n\x05\x05\0\x02\x08\x01\x12\x03\x0f\x04\x18\n\x0c\n\x05\ - \x05\0\x02\x08\x02\x12\x03\x0f\x1b\x1d\n\x0b\n\x04\x05\0\x02\t\x12\x03\ - \x10\x04\x16\n\x0c\n\x05\x05\0\x02\t\x01\x12\x03\x10\x04\x10\n\x0c\n\x05\ - \x05\0\x02\t\x02\x12\x03\x10\x13\x15\n\x0b\n\x04\x05\0\x02\n\x12\x03\x11\ - \x04\x19\n\x0c\n\x05\x05\0\x02\n\x01\x12\x03\x11\x04\x13\n\x0c\n\x05\x05\ - \0\x02\n\x02\x12\x03\x11\x16\x18\n\x0b\n\x04\x05\0\x02\x0b\x12\x03\x12\ - \x04\x19\n\x0c\n\x05\x05\0\x02\x0b\x01\x12\x03\x12\x04\x13\n\x0c\n\x05\ - \x05\0\x02\x0b\x02\x12\x03\x12\x16\x18\n\x0b\n\x04\x05\0\x02\x0c\x12\x03\ - \x13\x04\x1e\n\x0c\n\x05\x05\0\x02\x0c\x01\x12\x03\x13\x04\x18\n\x0c\n\ - \x05\x05\0\x02\x0c\x02\x12\x03\x13\x1b\x1d\n\x0b\n\x04\x05\0\x02\r\x12\ - \x03\x14\x04\x17\n\x0c\n\x05\x05\0\x02\r\x01\x12\x03\x14\x04\x11\n\x0c\n\ - \x05\x05\0\x02\r\x02\x12\x03\x14\x14\x16b\x06proto3\ + \xde\x02\n\rUserErrorCode\x12\x0b\n\x07Unknown\x10\0\x12\x1a\n\x16UserDa\ + tabaseInitFailed\x10\x01\x12\x1b\n\x17UserDatabaseWriteLocked\x10\x02\ + \x12\x1a\n\x16UserDatabaseReadLocked\x10\x03\x12\x1b\n\x17UserDatabaseDi\ + dNotMatch\x10\x04\x12\x1d\n\x19UserDatabaseInternalError\x10\x05\x12\x13\ + \n\x0fUserNotLoginYet\x10\n\x12\x17\n\x13ReadCurrentIdFailed\x10\x0b\x12\ + \x18\n\x14WriteCurrentIdFailed\x10\x0c\x12\x10\n\x0cEmailInvalid\x10\x14\ + \x12\x13\n\x0fPasswordInvalid\x10\x15\x12\x13\n\x0fUserNameInvalid\x10\ + \x16\x12\x18\n\x14UserWorkspaceInvalid\x10\x17\x12\x11\n\rUserIdInvalid\ + \x10\x18J\xee\x05\n\x06\x12\x04\0\0\x15\x01\n\x08\n\x01\x0c\x12\x03\0\0\ + \x12\n\n\n\x02\x04\0\x12\x04\x02\0\x05\x01\n\n\n\x03\x04\0\x01\x12\x03\ + \x02\x08\x11\n\x0b\n\x04\x04\0\x02\0\x12\x03\x03\x04\x1b\n\x0c\n\x05\x04\ + \0\x02\0\x06\x12\x03\x03\x04\x11\n\x0c\n\x05\x04\0\x02\0\x01\x12\x03\x03\ + \x12\x16\n\x0c\n\x05\x04\0\x02\0\x03\x12\x03\x03\x19\x1a\n\x0b\n\x04\x04\ + \0\x02\x01\x12\x03\x04\x04\x13\n\x0c\n\x05\x04\0\x02\x01\x05\x12\x03\x04\ + \x04\n\n\x0c\n\x05\x04\0\x02\x01\x01\x12\x03\x04\x0b\x0e\n\x0c\n\x05\x04\ + \0\x02\x01\x03\x12\x03\x04\x11\x12\n\n\n\x02\x05\0\x12\x04\x06\0\x15\x01\ + \n\n\n\x03\x05\0\x01\x12\x03\x06\x05\x12\n\x0b\n\x04\x05\0\x02\0\x12\x03\ + \x07\x04\x10\n\x0c\n\x05\x05\0\x02\0\x01\x12\x03\x07\x04\x0b\n\x0c\n\x05\ + \x05\0\x02\0\x02\x12\x03\x07\x0e\x0f\n\x0b\n\x04\x05\0\x02\x01\x12\x03\ + \x08\x04\x1f\n\x0c\n\x05\x05\0\x02\x01\x01\x12\x03\x08\x04\x1a\n\x0c\n\ + \x05\x05\0\x02\x01\x02\x12\x03\x08\x1d\x1e\n\x0b\n\x04\x05\0\x02\x02\x12\ + \x03\t\x04\x20\n\x0c\n\x05\x05\0\x02\x02\x01\x12\x03\t\x04\x1b\n\x0c\n\ + \x05\x05\0\x02\x02\x02\x12\x03\t\x1e\x1f\n\x0b\n\x04\x05\0\x02\x03\x12\ + \x03\n\x04\x1f\n\x0c\n\x05\x05\0\x02\x03\x01\x12\x03\n\x04\x1a\n\x0c\n\ + \x05\x05\0\x02\x03\x02\x12\x03\n\x1d\x1e\n\x0b\n\x04\x05\0\x02\x04\x12\ + \x03\x0b\x04\x20\n\x0c\n\x05\x05\0\x02\x04\x01\x12\x03\x0b\x04\x1b\n\x0c\ + \n\x05\x05\0\x02\x04\x02\x12\x03\x0b\x1e\x1f\n\x0b\n\x04\x05\0\x02\x05\ + \x12\x03\x0c\x04\"\n\x0c\n\x05\x05\0\x02\x05\x01\x12\x03\x0c\x04\x1d\n\ + \x0c\n\x05\x05\0\x02\x05\x02\x12\x03\x0c\x20!\n\x0b\n\x04\x05\0\x02\x06\ + \x12\x03\r\x04\x19\n\x0c\n\x05\x05\0\x02\x06\x01\x12\x03\r\x04\x13\n\x0c\ + \n\x05\x05\0\x02\x06\x02\x12\x03\r\x16\x18\n\x0b\n\x04\x05\0\x02\x07\x12\ + \x03\x0e\x04\x1d\n\x0c\n\x05\x05\0\x02\x07\x01\x12\x03\x0e\x04\x17\n\x0c\ + \n\x05\x05\0\x02\x07\x02\x12\x03\x0e\x1a\x1c\n\x0b\n\x04\x05\0\x02\x08\ + \x12\x03\x0f\x04\x1e\n\x0c\n\x05\x05\0\x02\x08\x01\x12\x03\x0f\x04\x18\n\ + \x0c\n\x05\x05\0\x02\x08\x02\x12\x03\x0f\x1b\x1d\n\x0b\n\x04\x05\0\x02\t\ + \x12\x03\x10\x04\x16\n\x0c\n\x05\x05\0\x02\t\x01\x12\x03\x10\x04\x10\n\ + \x0c\n\x05\x05\0\x02\t\x02\x12\x03\x10\x13\x15\n\x0b\n\x04\x05\0\x02\n\ + \x12\x03\x11\x04\x19\n\x0c\n\x05\x05\0\x02\n\x01\x12\x03\x11\x04\x13\n\ + \x0c\n\x05\x05\0\x02\n\x02\x12\x03\x11\x16\x18\n\x0b\n\x04\x05\0\x02\x0b\ + \x12\x03\x12\x04\x19\n\x0c\n\x05\x05\0\x02\x0b\x01\x12\x03\x12\x04\x13\n\ + \x0c\n\x05\x05\0\x02\x0b\x02\x12\x03\x12\x16\x18\n\x0b\n\x04\x05\0\x02\ + \x0c\x12\x03\x13\x04\x1e\n\x0c\n\x05\x05\0\x02\x0c\x01\x12\x03\x13\x04\ + \x18\n\x0c\n\x05\x05\0\x02\x0c\x02\x12\x03\x13\x1b\x1d\n\x0b\n\x04\x05\0\ + \x02\r\x12\x03\x14\x04\x17\n\x0c\n\x05\x05\0\x02\r\x01\x12\x03\x14\x04\ + \x11\n\x0c\n\x05\x05\0\x02\r\x02\x12\x03\x14\x14\x16b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/rust-lib/flowy-user/src/protobuf/proto/errors.proto b/rust-lib/flowy-user/src/protobuf/proto/errors.proto index 0d880f5fa1..9a53106237 100644 --- a/rust-lib/flowy-user/src/protobuf/proto/errors.proto +++ b/rust-lib/flowy-user/src/protobuf/proto/errors.proto @@ -6,11 +6,11 @@ message UserError { } enum UserErrorCode { Unknown = 0; - DatabaseInitFailed = 1; - DatabaseWriteLocked = 2; - DatabaseReadLocked = 3; - DatabaseUserDidNotMatch = 4; - DatabaseInternalError = 5; + UserDatabaseInitFailed = 1; + UserDatabaseWriteLocked = 2; + UserDatabaseReadLocked = 3; + UserDatabaseDidNotMatch = 4; + UserDatabaseInternalError = 5; UserNotLoginYet = 10; ReadCurrentIdFailed = 11; WriteCurrentIdFailed = 12; diff --git a/rust-lib/flowy-user/src/services/user_session/database.rs b/rust-lib/flowy-user/src/services/user_session/database.rs index 6365868c31..f286957b99 100644 --- a/rust-lib/flowy-user/src/services/user_session/database.rs +++ b/rust-lib/flowy-user/src/services/user_session/database.rs @@ -22,20 +22,21 @@ impl UserDB { fn open_user_db(&self, user_id: &str) -> Result<(), UserError> { if user_id.is_empty() { - return Err(ErrorBuilder::new(UserErrorCode::DatabaseInitFailed) + return Err(ErrorBuilder::new(UserErrorCode::UserDatabaseInitFailed) .msg("user id is empty") .build()); } let dir = format!("{}/{}", self.db_dir, user_id); let db = flowy_database::init(&dir).map_err(|e| { - ErrorBuilder::new(UserErrorCode::DatabaseInitFailed) + log::error!("flowy_database::init failed, {:?}", e); + ErrorBuilder::new(UserErrorCode::UserDatabaseInitFailed) .error(e) .build() })?; let mut db_map = DB_MAP.write().map_err(|e| { - ErrorBuilder::new(UserErrorCode::DatabaseWriteLocked) + ErrorBuilder::new(UserErrorCode::UserDatabaseWriteLocked) .error(e) .build() })?; @@ -46,7 +47,7 @@ impl UserDB { pub(crate) fn close_user_db(&self, user_id: &str) -> Result<(), UserError> { let mut db_map = DB_MAP.write().map_err(|e| { - ErrorBuilder::new(UserErrorCode::DatabaseWriteLocked) + ErrorBuilder::new(UserErrorCode::UserDatabaseWriteLocked) .msg(format!("Close user db failed. {:?}", e)) .build() })?; @@ -62,13 +63,13 @@ impl UserDB { } let db_map = DB_MAP.read().map_err(|e| { - ErrorBuilder::new(UserErrorCode::DatabaseReadLocked) + ErrorBuilder::new(UserErrorCode::UserDatabaseReadLocked) .error(e) .build() })?; match db_map.get(user_id) { - None => Err(ErrorBuilder::new(UserErrorCode::DatabaseInitFailed) + None => Err(ErrorBuilder::new(UserErrorCode::UserDatabaseInitFailed) .msg("Get connection failed. The database is not initialization") .build()), Some(database) => Ok(database.get_connection()?), diff --git a/rust-lib/flowy-user/src/services/user_session/user_session.rs b/rust-lib/flowy-user/src/services/user_session/user_session.rs index 475a955bb0..64aa629fb0 100644 --- a/rust-lib/flowy-user/src/services/user_session/user_session.rs +++ b/rust-lib/flowy-user/src/services/user_session/user_session.rs @@ -104,11 +104,9 @@ impl UserSession { pub fn user_detail(&self) -> Result { let user_id = self.get_user_id()?; - let conn = self.get_db_connection()?; - let user = dsl::user_table .filter(user_table::id.eq(&user_id)) - .first::(&*conn)?; + .first::(&*(self.get_db_connection()?))?; match self.server.get_user_info(&user_id) { Ok(_user_detail) => { @@ -137,14 +135,15 @@ impl UserSession { } pub fn get_user_id(&self) -> Result { - let read_guard = self.user_id.read().map_err(|e| { - ErrorBuilder::new(UserErrorCode::ReadCurrentIdFailed) - .error(e) - .build() - })?; + let mut user_id = { + let read_guard = self.user_id.read().map_err(|e| { + ErrorBuilder::new(UserErrorCode::ReadCurrentIdFailed) + .error(e) + .build() + })?; - let mut user_id = (*read_guard).clone(); - drop(read_guard); + (*read_guard).clone() + }; if user_id.is_none() { user_id = KVStore::get_str(USER_ID_CACHE_KEY); @@ -165,11 +164,10 @@ impl UserSession { .unwrap(); let request = ModuleRequest::new(UpdateUser).payload(payload); - let _user_detail = EventDispatch::async_send(request) + let _ = EventDispatch::async_send(request) .await .parse::() - .unwrap() - .unwrap(); + .unwrap()?; Ok(()) } } diff --git a/rust-lib/flowy-user/tests/event/sign_in_test.rs b/rust-lib/flowy-user/tests/event/sign_in_test.rs index d29ff80df4..a3a28a33f7 100644 --- a/rust-lib/flowy-user/tests/event/sign_in_test.rs +++ b/rust-lib/flowy-user/tests/event/sign_in_test.rs @@ -60,233 +60,3 @@ fn sign_in_with_invalid_password() { ); } } - -#[test] -#[serial] -fn sign_up_success() { - let _ = UserTestBuilder::new().event(SignOut).sync_send(); - let request = SignUpRequest { - email: random_valid_email(), - name: valid_name(), - password: valid_password(), - }; - - let _response = UserTestBuilder::new() - .logout() - .event(SignUp) - .request(request) - .sync_send(); -} - -#[test] -#[serial] -fn sign_up_with_invalid_email() { - for email in invalid_email_test_case() { - let request = SignUpRequest { - email: email.to_string(), - name: valid_name(), - password: valid_password(), - }; - - assert_eq!( - UserTestBuilder::new() - .event(SignUp) - .request(request) - .sync_send() - .error() - .code, - UserErrorCode::EmailInvalid - ); - } -} -#[test] -#[serial] -fn sign_up_with_invalid_password() { - for password in invalid_password_test_case() { - let request = SignUpRequest { - email: random_valid_email(), - name: valid_name(), - password, - }; - - assert_eq!( - UserTestBuilder::new() - .event(SignUp) - .request(request) - .sync_send() - .error() - .code, - UserErrorCode::PasswordInvalid - ); - } -} - -#[test] -#[should_panic] -#[serial] -fn user_status_get_failed_before_login() { - let _ = UserTestBuilder::new() - .logout() - .event(GetStatus) - .sync_send() - .parse::(); -} - -#[test] -#[serial] -fn user_status_get_success_after_login() { - let request = SignInRequest { - email: random_valid_email(), - password: valid_password(), - }; - - let response = UserTestBuilder::new() - .logout() - .event(SignIn) - .request(request) - .sync_send() - .parse::(); - dbg!(&response); - - let _ = UserTestBuilder::new() - .event(GetStatus) - .sync_send() - .parse::(); -} - -#[test] -#[serial] -fn user_update_with_name() { - let user_detail = UserTestBuilder::new().login().user_detail.unwrap(); - let new_name = "hello_world".to_owned(); - let request = UpdateUserRequest { - id: user_detail.id.clone(), - name: Some(new_name.clone()), - email: None, - workspace: None, - password: None, - }; - - let user_detail = UserTestBuilder::new() - .event(UpdateUser) - .request(request) - .sync_send() - .parse::(); - - assert_eq!(user_detail.name, new_name,); -} - -#[test] -#[serial] -fn user_update_with_email() { - let user_detail = UserTestBuilder::new().login().user_detail.unwrap(); - let new_email = "123@gmai.com".to_owned(); - let request = UpdateUserRequest { - id: user_detail.id.clone(), - name: None, - email: Some(new_email.clone()), - workspace: None, - password: None, - }; - - let user_detail = UserTestBuilder::new() - .event(UpdateUser) - .request(request) - .sync_send() - .parse::(); - - assert_eq!(user_detail.email, new_email,); -} - -#[test] -#[serial] -fn user_update_with_password() { - let user_detail = UserTestBuilder::new().login().user_detail.unwrap(); - let new_password = "H123world!".to_owned(); - let request = UpdateUserRequest { - id: user_detail.id.clone(), - name: None, - email: None, - workspace: None, - password: Some(new_password.clone()), - }; - - let _ = UserTestBuilder::new() - .event(UpdateUser) - .request(request) - .sync_send() - .assert_success(); -} - -#[test] -#[serial] -fn user_update_with_invalid_email() { - let user_detail = UserTestBuilder::new().login().user_detail.unwrap(); - for email in invalid_email_test_case() { - let request = UpdateUserRequest { - id: user_detail.id.clone(), - name: None, - email: Some(email), - workspace: None, - password: None, - }; - - assert_eq!( - UserTestBuilder::new() - .event(UpdateUser) - .request(request) - .sync_send() - .error() - .code, - UserErrorCode::EmailInvalid - ); - } -} - -#[test] -#[serial] -fn user_update_with_invalid_password() { - let user_detail = UserTestBuilder::new().login().user_detail.unwrap(); - for password in invalid_password_test_case() { - let request = UpdateUserRequest { - id: user_detail.id.clone(), - name: None, - email: None, - workspace: None, - password: Some(password), - }; - - assert_eq!( - UserTestBuilder::new() - .event(UpdateUser) - .request(request) - .sync_send() - .error() - .code, - UserErrorCode::PasswordInvalid - ); - } -} - -#[test] -#[serial] -fn user_update_with_invalid_name() { - let user_detail = UserTestBuilder::new().login().user_detail.unwrap(); - let request = UpdateUserRequest { - id: user_detail.id.clone(), - name: Some("".to_string()), - email: None, - workspace: None, - password: None, - }; - - assert_eq!( - UserTestBuilder::new() - .event(UpdateUser) - .request(request) - .sync_send() - .error() - .code, - UserErrorCode::UserNameInvalid - ); -} diff --git a/rust-lib/flowy-user/tests/event/sign_up_test.rs b/rust-lib/flowy-user/tests/event/sign_up_test.rs index e023d80bf7..2122828e4d 100644 --- a/rust-lib/flowy-user/tests/event/sign_up_test.rs +++ b/rust-lib/flowy-user/tests/event/sign_up_test.rs @@ -1,65 +1,65 @@ -// use crate::helper::*; -// use flowy_user::{errors::*, event::UserEvent::*, prelude::*}; -// use serial_test::*; -// -// #[test] -// #[serial] -// fn sign_up_success() { -// let _ = UserTestBuilder::new().event(SignOut).sync_send(); -// let request = SignUpRequest { -// email: random_valid_email(), -// name: valid_name(), -// password: valid_password(), -// }; -// -// let _response = UserTestBuilder::new() -// .logout() -// .event(SignUp) -// .request(request) -// .sync_send(); -// // .parse::(); -// // dbg!(&response); -// } -// -// #[test] -// #[serial] -// fn sign_up_with_invalid_email() { -// for email in invalid_email_test_case() { -// let request = SignUpRequest { -// email: email.to_string(), -// name: valid_name(), -// password: valid_password(), -// }; -// -// assert_eq!( -// UserTestBuilder::new() -// .event(SignUp) -// .request(request) -// .sync_send() -// .error() -// .code, -// UserErrorCode::EmailInvalid -// ); -// } -// } -// #[test] -// #[serial] -// fn sign_up_with_invalid_password() { -// for password in invalid_password_test_case() { -// let request = SignUpRequest { -// email: random_valid_email(), -// name: valid_name(), -// password, -// }; -// -// assert_eq!( -// UserTestBuilder::new() -// .event(SignUp) -// .request(request) -// .sync_send() -// .error() -// .code, -// UserErrorCode::PasswordInvalid -// ); -// } -// } +use crate::helper::*; +use flowy_user::{errors::*, event::UserEvent::*, prelude::*}; +use serial_test::*; + +#[test] +#[serial] +fn sign_up_success() { + let _ = UserTestBuilder::new().event(SignOut).sync_send(); + let request = SignUpRequest { + email: random_valid_email(), + name: valid_name(), + password: valid_password(), + }; + + let _response = UserTestBuilder::new() + .logout() + .event(SignUp) + .request(request) + .sync_send(); + // .parse::(); + // dbg!(&response); +} + +#[test] +#[serial] +fn sign_up_with_invalid_email() { + for email in invalid_email_test_case() { + let request = SignUpRequest { + email: email.to_string(), + name: valid_name(), + password: valid_password(), + }; + + assert_eq!( + UserTestBuilder::new() + .event(SignUp) + .request(request) + .sync_send() + .error() + .code, + UserErrorCode::EmailInvalid + ); + } +} +#[test] +#[serial] +fn sign_up_with_invalid_password() { + for password in invalid_password_test_case() { + let request = SignUpRequest { + email: random_valid_email(), + name: valid_name(), + password, + }; + + assert_eq!( + UserTestBuilder::new() + .event(SignUp) + .request(request) + .sync_send() + .error() + .code, + UserErrorCode::PasswordInvalid + ); + } +} diff --git a/rust-lib/flowy-user/tests/event/user_status_test.rs b/rust-lib/flowy-user/tests/event/user_status_test.rs index a6350b1fc7..ee5e56345d 100644 --- a/rust-lib/flowy-user/tests/event/user_status_test.rs +++ b/rust-lib/flowy-user/tests/event/user_status_test.rs @@ -1,36 +1,36 @@ -// use crate::helper::*; -// use flowy_user::{event::UserEvent::*, prelude::*}; -// use serial_test::*; -// -// #[test] -// #[should_panic] -// #[serial] -// fn user_status_get_failed_before_login() { -// let _ = UserTestBuilder::new() -// .logout() -// .event(GetStatus) -// .sync_send() -// .parse::(); -// } -// -// #[test] -// #[serial] -// fn user_status_get_success_after_login() { -// let request = SignInRequest { -// email: random_valid_email(), -// password: valid_password(), -// }; -// -// let response = UserTestBuilder::new() -// .logout() -// .event(SignIn) -// .request(request) -// .sync_send() -// .parse::(); -// dbg!(&response); -// -// let _ = UserTestBuilder::new() -// .event(GetStatus) -// .sync_send() -// .parse::(); -// } +use crate::helper::*; +use flowy_user::{event::UserEvent::*, prelude::*}; +use serial_test::*; + +#[test] +#[should_panic] +#[serial] +fn user_status_get_failed_before_login() { + let _ = UserTestBuilder::new() + .logout() + .event(GetStatus) + .sync_send() + .parse::(); +} + +#[test] +#[serial] +fn user_status_get_success_after_login() { + let request = SignInRequest { + email: random_valid_email(), + password: valid_password(), + }; + + let response = UserTestBuilder::new() + .logout() + .event(SignIn) + .request(request) + .sync_send() + .parse::(); + dbg!(&response); + + let _ = UserTestBuilder::new() + .event(GetStatus) + .sync_send() + .parse::(); +} diff --git a/rust-lib/flowy-user/tests/event/user_update_test.rs b/rust-lib/flowy-user/tests/event/user_update_test.rs index 7dc83bfca4..78c9ca332f 100644 --- a/rust-lib/flowy-user/tests/event/user_update_test.rs +++ b/rust-lib/flowy-user/tests/event/user_update_test.rs @@ -1,140 +1,140 @@ -// use crate::helper::*; -// use flowy_user::{errors::UserErrorCode, event::UserEvent::*, prelude::*}; -// use serial_test::*; -// -// #[test] -// #[serial] -// fn user_update_with_name() { -// let user_detail = UserTestBuilder::new().login().user_detail.unwrap(); -// let new_name = "hello_world".to_owned(); -// let request = UpdateUserRequest { -// id: user_detail.id.clone(), -// name: Some(new_name.clone()), -// email: None, -// workspace: None, -// password: None, -// }; -// -// let user_detail = UserTestBuilder::new() -// .event(UpdateUser) -// .request(request) -// .sync_send() -// .parse::(); -// -// assert_eq!(user_detail.name, new_name,); -// } -// -// #[test] -// #[serial] -// fn user_update_with_email() { -// let user_detail = UserTestBuilder::new().login().user_detail.unwrap(); -// let new_email = "123@gmai.com".to_owned(); -// let request = UpdateUserRequest { -// id: user_detail.id.clone(), -// name: None, -// email: Some(new_email.clone()), -// workspace: None, -// password: None, -// }; -// -// let user_detail = UserTestBuilder::new() -// .event(UpdateUser) -// .request(request) -// .sync_send() -// .parse::(); -// -// assert_eq!(user_detail.email, new_email,); -// } -// -// #[test] -// #[serial] -// fn user_update_with_password() { -// let user_detail = UserTestBuilder::new().login().user_detail.unwrap(); -// let new_password = "H123world!".to_owned(); -// let request = UpdateUserRequest { -// id: user_detail.id.clone(), -// name: None, -// email: None, -// workspace: None, -// password: Some(new_password.clone()), -// }; -// -// let _ = UserTestBuilder::new() -// .event(UpdateUser) -// .request(request) -// .sync_send() -// .assert_success(); -// } -// -// #[test] -// #[serial] -// fn user_update_with_invalid_email() { -// let user_detail = UserTestBuilder::new().login().user_detail.unwrap(); -// for email in invalid_email_test_case() { -// let request = UpdateUserRequest { -// id: user_detail.id.clone(), -// name: None, -// email: Some(email), -// workspace: None, -// password: None, -// }; -// -// assert_eq!( -// UserTestBuilder::new() -// .event(UpdateUser) -// .request(request) -// .sync_send() -// .error() -// .code, -// UserErrorCode::EmailInvalid -// ); -// } -// } -// -// #[test] -// #[serial] -// fn user_update_with_invalid_password() { -// let user_detail = UserTestBuilder::new().login().user_detail.unwrap(); -// for password in invalid_password_test_case() { -// let request = UpdateUserRequest { -// id: user_detail.id.clone(), -// name: None, -// email: None, -// workspace: None, -// password: Some(password), -// }; -// -// assert_eq!( -// UserTestBuilder::new() -// .event(UpdateUser) -// .request(request) -// .sync_send() -// .error() -// .code, -// UserErrorCode::PasswordInvalid -// ); -// } -// } -// -// #[test] -// #[serial] -// fn user_update_with_invalid_name() { -// let user_detail = UserTestBuilder::new().login().user_detail.unwrap(); -// let request = UpdateUserRequest { -// id: user_detail.id.clone(), -// name: Some("".to_string()), -// email: None, -// workspace: None, -// password: None, -// }; -// -// assert_eq!( -// UserTestBuilder::new() -// .event(UpdateUser) -// .request(request) -// .sync_send() -// .error() -// .code, -// UserErrorCode::UserNameInvalid -// ); -// } +use crate::helper::*; +use flowy_user::{errors::UserErrorCode, event::UserEvent::*, prelude::*}; +use serial_test::*; + +#[test] +#[serial] +fn user_update_with_name() { + let user_detail = UserTestBuilder::new().reset().user_detail.unwrap(); + let new_name = "hello_world".to_owned(); + let request = UpdateUserRequest { + id: user_detail.id.clone(), + name: Some(new_name.clone()), + email: None, + workspace: None, + password: None, + }; + + let user_detail = UserTestBuilder::new() + .event(UpdateUser) + .request(request) + .sync_send() + .parse::(); + + assert_eq!(user_detail.name, new_name,); +} + +#[test] +#[serial] +fn user_update_with_email() { + let user_detail = UserTestBuilder::new().reset().user_detail.unwrap(); + let new_email = "123@gmai.com".to_owned(); + let request = UpdateUserRequest { + id: user_detail.id.clone(), + name: None, + email: Some(new_email.clone()), + workspace: None, + password: None, + }; + + let user_detail = UserTestBuilder::new() + .event(UpdateUser) + .request(request) + .sync_send() + .parse::(); + + assert_eq!(user_detail.email, new_email,); +} + +#[test] +#[serial] +fn user_update_with_password() { + let user_detail = UserTestBuilder::new().reset().user_detail.unwrap(); + let new_password = "H123world!".to_owned(); + let request = UpdateUserRequest { + id: user_detail.id.clone(), + name: None, + email: None, + workspace: None, + password: Some(new_password.clone()), + }; + + let _ = UserTestBuilder::new() + .event(UpdateUser) + .request(request) + .sync_send() + .assert_success(); +} + +#[test] +#[serial] +fn user_update_with_invalid_email() { + let user_detail = UserTestBuilder::new().reset().user_detail.unwrap(); + for email in invalid_email_test_case() { + let request = UpdateUserRequest { + id: user_detail.id.clone(), + name: None, + email: Some(email), + workspace: None, + password: None, + }; + + assert_eq!( + UserTestBuilder::new() + .event(UpdateUser) + .request(request) + .sync_send() + .error() + .code, + UserErrorCode::EmailInvalid + ); + } +} + +#[test] +#[serial] +fn user_update_with_invalid_password() { + let user_detail = UserTestBuilder::new().reset().user_detail.unwrap(); + for password in invalid_password_test_case() { + let request = UpdateUserRequest { + id: user_detail.id.clone(), + name: None, + email: None, + workspace: None, + password: Some(password), + }; + + assert_eq!( + UserTestBuilder::new() + .event(UpdateUser) + .request(request) + .sync_send() + .error() + .code, + UserErrorCode::PasswordInvalid + ); + } +} + +#[test] +#[serial] +fn user_update_with_invalid_name() { + let user_detail = UserTestBuilder::new().reset().user_detail.unwrap(); + let request = UpdateUserRequest { + id: user_detail.id.clone(), + name: Some("".to_string()), + email: None, + workspace: None, + password: None, + }; + + assert_eq!( + UserTestBuilder::new() + .event(UpdateUser) + .request(request) + .sync_send() + .error() + .code, + UserErrorCode::UserNameInvalid + ); +} diff --git a/rust-lib/flowy-workspace/src/entities/workspace/workspace_user_detail.rs b/rust-lib/flowy-workspace/src/entities/workspace/workspace_user_detail.rs index 6d9b69a7d0..efe9a30b65 100644 --- a/rust-lib/flowy-workspace/src/entities/workspace/workspace_user_detail.rs +++ b/rust-lib/flowy-workspace/src/entities/workspace/workspace_user_detail.rs @@ -1,6 +1,20 @@ -pub struct WorkspaceUserQueryRequest { - fetch_owner: bool, - fetch_all: bool, +use crate::entities::workspace::WorkspaceDetail; +use flowy_derive::ProtoBuf; + +#[derive(ProtoBuf, Default, Debug)] +pub struct UserWorkspace { + #[pb(index = 1)] + pub owner: String, + + #[pb(index = 2)] + pub workspace_id: String, } -pub struct WorkspaceUserDetail {} +#[derive(ProtoBuf, Default, Debug)] +pub struct UserWorkspaceDetail { + #[pb(index = 1)] + pub owner: String, + + #[pb(index = 2)] + pub workspace: WorkspaceDetail, +} diff --git a/rust-lib/flowy-workspace/src/errors.rs b/rust-lib/flowy-workspace/src/errors.rs index a3359375f5..a0eb1e50c7 100644 --- a/rust-lib/flowy-workspace/src/errors.rs +++ b/rust-lib/flowy-workspace/src/errors.rs @@ -42,7 +42,7 @@ pub enum WorkspaceErrorCode { DatabaseConnectionFail = 5, #[display(fmt = "Database internal error")] - DatabaseInternalError = 6, + WorkspaceDatabaseError = 6, #[display(fmt = "User internal error")] UserInternalError = 10, @@ -57,15 +57,7 @@ impl std::default::Default for WorkspaceErrorCode { impl std::convert::From for WorkspaceError { fn from(error: flowy_database::result::Error) -> Self { - ErrorBuilder::new(WorkspaceErrorCode::DatabaseInternalError) - .error(error) - .build() - } -} - -impl std::convert::From for WorkspaceError { - fn from(error: flowy_sqlite::Error) -> Self { - ErrorBuilder::new(WorkspaceErrorCode::DatabaseInternalError) + ErrorBuilder::new(WorkspaceErrorCode::WorkspaceDatabaseError) .error(error) .build() } diff --git a/rust-lib/flowy-workspace/src/event.rs b/rust-lib/flowy-workspace/src/event.rs index b8072ce17a..8a45318ac2 100644 --- a/rust-lib/flowy-workspace/src/event.rs +++ b/rust-lib/flowy-workspace/src/event.rs @@ -6,9 +6,9 @@ use flowy_derive::{Flowy_Event, ProtoBuf_Enum}; pub enum WorkspaceEvent { #[display(fmt = "Create workspace")] #[event(input = "CreateSpaceRequest", output = "WorkspaceDetail")] - CreateWorkspace = 0, + CreateWorkspace = 0, - #[display(fmt = "Get workspace user")] - #[event(output = "UserDetail")] - GetWorkspaceUserDetail = 100, + #[display(fmt = "Get user's workspace detail")] + #[event(output = "UserWorkspaceDetail")] + GetWorkspaceDetail = 1, } diff --git a/rust-lib/flowy-workspace/src/handlers/workspace_handler.rs b/rust-lib/flowy-workspace/src/handlers/workspace_handler.rs index e15ca53d9e..b19d7258a0 100644 --- a/rust-lib/flowy-workspace/src/handlers/workspace_handler.rs +++ b/rust-lib/flowy-workspace/src/handlers/workspace_handler.rs @@ -1,5 +1,11 @@ use crate::{ - entities::workspace::{CreateWorkspaceParams, CreateWorkspaceRequest, WorkspaceDetail}, + entities::workspace::{ + CreateWorkspaceParams, + CreateWorkspaceRequest, + UserWorkspace, + UserWorkspaceDetail, + WorkspaceDetail, + }, errors::WorkspaceError, services::WorkspaceController, }; @@ -16,12 +22,9 @@ pub async fn create_workspace( response_ok(detail) } -pub async fn workspace_user( - data: Data, +pub async fn get_workspace_detail( controller: ModuleData>, -) -> ResponseResult { - let controller = controller.get_ref().clone(); - let params: CreateWorkspaceParams = data.into_inner().try_into()?; - let detail = controller.save_workspace(params).await?; - response_ok(detail) +) -> ResponseResult { + let user_workspace = controller.get_user_workspace_detail().await?; + response_ok(user_workspace) } diff --git a/rust-lib/flowy-workspace/src/module.rs b/rust-lib/flowy-workspace/src/module.rs index e82a48515c..4033730c0f 100644 --- a/rust-lib/flowy-workspace/src/module.rs +++ b/rust-lib/flowy-workspace/src/module.rs @@ -7,12 +7,12 @@ use crate::{ }; use flowy_database::DBConnection; -use crate::handlers::*; +use crate::{entities::workspace::UserWorkspace, handlers::*}; use std::sync::Arc; pub trait WorkspaceUser: Send + Sync { - fn set_workspace(&self, id: &str) -> DispatchFuture>; - fn get_workspace(&self) -> Result; + fn set_cur_workspace_id(&self, id: &str) -> DispatchFuture>; + fn get_cur_workspace(&self) -> DispatchFuture>; fn db_connection(&self) -> Result; } @@ -25,5 +25,5 @@ pub fn create(user: Arc) -> Module { .data(workspace_controller) .data(app_controller) .event(WorkspaceEvent::CreateWorkspace, create_workspace) - .event(WorkspaceEvent::GetWorkspaceUserDetail, workspace_user) + .event(WorkspaceEvent::GetWorkspaceDetail, get_workspace_detail) } diff --git a/rust-lib/flowy-workspace/src/protobuf/model/errors.rs b/rust-lib/flowy-workspace/src/protobuf/model/errors.rs index 33a4dd78a1..eda3e0c478 100644 --- a/rust-lib/flowy-workspace/src/protobuf/model/errors.rs +++ b/rust-lib/flowy-workspace/src/protobuf/model/errors.rs @@ -221,7 +221,7 @@ pub enum WorkspaceErrorCode { AppColorStyleInvalid = 3, AppIdInvalid = 4, DatabaseConnectionFail = 5, - DatabaseInternalError = 6, + WorkspaceDatabaseError = 6, UserInternalError = 10, UserNotLoginYet = 11, } @@ -239,7 +239,7 @@ impl ::protobuf::ProtobufEnum for WorkspaceErrorCode { 3 => ::std::option::Option::Some(WorkspaceErrorCode::AppColorStyleInvalid), 4 => ::std::option::Option::Some(WorkspaceErrorCode::AppIdInvalid), 5 => ::std::option::Option::Some(WorkspaceErrorCode::DatabaseConnectionFail), - 6 => ::std::option::Option::Some(WorkspaceErrorCode::DatabaseInternalError), + 6 => ::std::option::Option::Some(WorkspaceErrorCode::WorkspaceDatabaseError), 10 => ::std::option::Option::Some(WorkspaceErrorCode::UserInternalError), 11 => ::std::option::Option::Some(WorkspaceErrorCode::UserNotLoginYet), _ => ::std::option::Option::None @@ -254,7 +254,7 @@ impl ::protobuf::ProtobufEnum for WorkspaceErrorCode { WorkspaceErrorCode::AppColorStyleInvalid, WorkspaceErrorCode::AppIdInvalid, WorkspaceErrorCode::DatabaseConnectionFail, - WorkspaceErrorCode::DatabaseInternalError, + WorkspaceErrorCode::WorkspaceDatabaseError, WorkspaceErrorCode::UserInternalError, WorkspaceErrorCode::UserNotLoginYet, ]; @@ -287,11 +287,11 @@ impl ::protobuf::reflect::ProtobufValue for WorkspaceErrorCode { static file_descriptor_proto_data: &'static [u8] = b"\ \n\x0cerrors.proto\"K\n\x0eWorkspaceError\x12'\n\x04code\x18\x01\x20\x01\ (\x0e2\x13.WorkspaceErrorCodeR\x04code\x12\x10\n\x03msg\x18\x02\x20\x01(\ - \tR\x03msg*\xe2\x01\n\x12WorkspaceErrorCode\x12\x0b\n\x07Unknown\x10\0\ + \tR\x03msg*\xe3\x01\n\x12WorkspaceErrorCode\x12\x0b\n\x07Unknown\x10\0\ \x12\x18\n\x14WorkspaceNameInvalid\x10\x01\x12\x16\n\x12WorkspaceIdInval\ id\x10\x02\x12\x18\n\x14AppColorStyleInvalid\x10\x03\x12\x10\n\x0cAppIdI\ - nvalid\x10\x04\x12\x1a\n\x16DatabaseConnectionFail\x10\x05\x12\x19\n\x15\ - DatabaseInternalError\x10\x06\x12\x15\n\x11UserInternalError\x10\n\x12\ + nvalid\x10\x04\x12\x1a\n\x16DatabaseConnectionFail\x10\x05\x12\x1a\n\x16\ + WorkspaceDatabaseError\x10\x06\x12\x15\n\x11UserInternalError\x10\n\x12\ \x13\n\x0fUserNotLoginYet\x10\x0bJ\xa1\x04\n\x06\x12\x04\0\0\x10\x01\n\ \x08\n\x01\x0c\x12\x03\0\0\x12\n\n\n\x02\x04\0\x12\x04\x02\0\x05\x01\n\n\ \n\x03\x04\0\x01\x12\x03\x02\x08\x16\n\x0b\n\x04\x04\0\x02\0\x12\x03\x03\ @@ -313,8 +313,8 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x03\x0b\x04\x10\n\x0c\n\x05\x05\0\x02\x04\x02\x12\x03\x0b\x13\x14\n\x0b\ \n\x04\x05\0\x02\x05\x12\x03\x0c\x04\x1f\n\x0c\n\x05\x05\0\x02\x05\x01\ \x12\x03\x0c\x04\x1a\n\x0c\n\x05\x05\0\x02\x05\x02\x12\x03\x0c\x1d\x1e\n\ - \x0b\n\x04\x05\0\x02\x06\x12\x03\r\x04\x1e\n\x0c\n\x05\x05\0\x02\x06\x01\ - \x12\x03\r\x04\x19\n\x0c\n\x05\x05\0\x02\x06\x02\x12\x03\r\x1c\x1d\n\x0b\ + \x0b\n\x04\x05\0\x02\x06\x12\x03\r\x04\x1f\n\x0c\n\x05\x05\0\x02\x06\x01\ + \x12\x03\r\x04\x1a\n\x0c\n\x05\x05\0\x02\x06\x02\x12\x03\r\x1d\x1e\n\x0b\ \n\x04\x05\0\x02\x07\x12\x03\x0e\x04\x1b\n\x0c\n\x05\x05\0\x02\x07\x01\ \x12\x03\x0e\x04\x15\n\x0c\n\x05\x05\0\x02\x07\x02\x12\x03\x0e\x18\x1a\n\ \x0b\n\x04\x05\0\x02\x08\x12\x03\x0f\x04\x19\n\x0c\n\x05\x05\0\x02\x08\ diff --git a/rust-lib/flowy-workspace/src/protobuf/model/event.rs b/rust-lib/flowy-workspace/src/protobuf/model/event.rs index d4836dbaee..4e3e978ea5 100644 --- a/rust-lib/flowy-workspace/src/protobuf/model/event.rs +++ b/rust-lib/flowy-workspace/src/protobuf/model/event.rs @@ -26,7 +26,7 @@ #[derive(Clone,PartialEq,Eq,Debug,Hash)] pub enum WorkspaceEvent { CreateWorkspace = 0, - GetWorkspaceUserDetail = 100, + GetWorkspaceDetail = 1, } impl ::protobuf::ProtobufEnum for WorkspaceEvent { @@ -37,7 +37,7 @@ impl ::protobuf::ProtobufEnum for WorkspaceEvent { fn from_i32(value: i32) -> ::std::option::Option { match value { 0 => ::std::option::Option::Some(WorkspaceEvent::CreateWorkspace), - 100 => ::std::option::Option::Some(WorkspaceEvent::GetWorkspaceUserDetail), + 1 => ::std::option::Option::Some(WorkspaceEvent::GetWorkspaceDetail), _ => ::std::option::Option::None } } @@ -45,7 +45,7 @@ impl ::protobuf::ProtobufEnum for WorkspaceEvent { fn values() -> &'static [Self] { static values: &'static [WorkspaceEvent] = &[ WorkspaceEvent::CreateWorkspace, - WorkspaceEvent::GetWorkspaceUserDetail, + WorkspaceEvent::GetWorkspaceDetail, ]; values } @@ -74,14 +74,14 @@ impl ::protobuf::reflect::ProtobufValue for WorkspaceEvent { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x0bevent.proto*A\n\x0eWorkspaceEvent\x12\x13\n\x0fCreateWorkspace\x10\ - \0\x12\x1a\n\x16GetWorkspaceUserDetail\x10dJ|\n\x06\x12\x04\0\0\x05\x01\ - \n\x08\n\x01\x0c\x12\x03\0\0\x12\n\n\n\x02\x05\0\x12\x04\x02\0\x05\x01\n\ - \n\n\x03\x05\0\x01\x12\x03\x02\x05\x13\n\x0b\n\x04\x05\0\x02\0\x12\x03\ - \x03\x04\x18\n\x0c\n\x05\x05\0\x02\0\x01\x12\x03\x03\x04\x13\n\x0c\n\x05\ - \x05\0\x02\0\x02\x12\x03\x03\x16\x17\n\x0b\n\x04\x05\0\x02\x01\x12\x03\ - \x04\x04!\n\x0c\n\x05\x05\0\x02\x01\x01\x12\x03\x04\x04\x1a\n\x0c\n\x05\ - \x05\0\x02\x01\x02\x12\x03\x04\x1d\x20b\x06proto3\ + \n\x0bevent.proto*=\n\x0eWorkspaceEvent\x12\x13\n\x0fCreateWorkspace\x10\ + \0\x12\x16\n\x12GetWorkspaceDetail\x10\x01J|\n\x06\x12\x04\0\0\x05\x01\n\ + \x08\n\x01\x0c\x12\x03\0\0\x12\n\n\n\x02\x05\0\x12\x04\x02\0\x05\x01\n\n\ + \n\x03\x05\0\x01\x12\x03\x02\x05\x13\n\x0b\n\x04\x05\0\x02\0\x12\x03\x03\ + \x04\x18\n\x0c\n\x05\x05\0\x02\0\x01\x12\x03\x03\x04\x13\n\x0c\n\x05\x05\ + \0\x02\0\x02\x12\x03\x03\x16\x17\n\x0b\n\x04\x05\0\x02\x01\x12\x03\x04\ + \x04\x1b\n\x0c\n\x05\x05\0\x02\x01\x01\x12\x03\x04\x04\x16\n\x0c\n\x05\ + \x05\0\x02\x01\x02\x12\x03\x04\x19\x1ab\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/rust-lib/flowy-workspace/src/protobuf/model/mod.rs b/rust-lib/flowy-workspace/src/protobuf/model/mod.rs index ed856a9b17..1d98328c6d 100644 --- a/rust-lib/flowy-workspace/src/protobuf/model/mod.rs +++ b/rust-lib/flowy-workspace/src/protobuf/model/mod.rs @@ -12,6 +12,9 @@ pub use app_create::*; mod event; pub use event::*; +mod workspace_user_detail; +pub use workspace_user_detail::*; + mod workspace_create; pub use workspace_create::*; diff --git a/rust-lib/flowy-workspace/src/protobuf/model/workspace_user_detail.rs b/rust-lib/flowy-workspace/src/protobuf/model/workspace_user_detail.rs new file mode 100644 index 0000000000..06507aa745 --- /dev/null +++ b/rust-lib/flowy-workspace/src/protobuf/model/workspace_user_detail.rs @@ -0,0 +1,476 @@ +// This file is generated by rust-protobuf 2.22.1. Do not edit +// @generated + +// https://github.com/rust-lang/rust-clippy/issues/702 +#![allow(unknown_lints)] +#![allow(clippy::all)] + +#![allow(unused_attributes)] +#![cfg_attr(rustfmt, rustfmt::skip)] + +#![allow(box_pointers)] +#![allow(dead_code)] +#![allow(missing_docs)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#![allow(trivial_casts)] +#![allow(unused_imports)] +#![allow(unused_results)] +//! Generated file from `workspace_user_detail.proto` + +/// Generated files are compatible only with the same version +/// of protobuf runtime. +// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_22_1; + +#[derive(PartialEq,Clone,Default)] +pub struct UserWorkspace { + // message fields + pub owner: ::std::string::String, + pub workspace_id: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a UserWorkspace { + fn default() -> &'a UserWorkspace { + ::default_instance() + } +} + +impl UserWorkspace { + pub fn new() -> UserWorkspace { + ::std::default::Default::default() + } + + // string owner = 1; + + + pub fn get_owner(&self) -> &str { + &self.owner + } + pub fn clear_owner(&mut self) { + self.owner.clear(); + } + + // Param is passed by value, moved + pub fn set_owner(&mut self, v: ::std::string::String) { + self.owner = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_owner(&mut self) -> &mut ::std::string::String { + &mut self.owner + } + + // Take field + pub fn take_owner(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.owner, ::std::string::String::new()) + } + + // string workspace_id = 2; + + + pub fn get_workspace_id(&self) -> &str { + &self.workspace_id + } + pub fn clear_workspace_id(&mut self) { + self.workspace_id.clear(); + } + + // Param is passed by value, moved + pub fn set_workspace_id(&mut self, v: ::std::string::String) { + self.workspace_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_workspace_id(&mut self) -> &mut ::std::string::String { + &mut self.workspace_id + } + + // Take field + pub fn take_workspace_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.workspace_id, ::std::string::String::new()) + } +} + +impl ::protobuf::Message for UserWorkspace { + 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.owner)?; + }, + 2 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.workspace_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.owner.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.owner); + } + if !self.workspace_id.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.workspace_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.owner.is_empty() { + os.write_string(1, &self.owner)?; + } + if !self.workspace_id.is_empty() { + os.write_string(2, &self.workspace_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() -> UserWorkspace { + UserWorkspace::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>( + "owner", + |m: &UserWorkspace| { &m.owner }, + |m: &mut UserWorkspace| { &mut m.owner }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "workspace_id", + |m: &UserWorkspace| { &m.workspace_id }, + |m: &mut UserWorkspace| { &mut m.workspace_id }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "UserWorkspace", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static UserWorkspace { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(UserWorkspace::new) + } +} + +impl ::protobuf::Clear for UserWorkspace { + fn clear(&mut self) { + self.owner.clear(); + self.workspace_id.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for UserWorkspace { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for UserWorkspace { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct UserWorkspaceDetail { + // message fields + pub owner: ::std::string::String, + pub workspace: ::protobuf::SingularPtrField, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a UserWorkspaceDetail { + fn default() -> &'a UserWorkspaceDetail { + ::default_instance() + } +} + +impl UserWorkspaceDetail { + pub fn new() -> UserWorkspaceDetail { + ::std::default::Default::default() + } + + // string owner = 1; + + + pub fn get_owner(&self) -> &str { + &self.owner + } + pub fn clear_owner(&mut self) { + self.owner.clear(); + } + + // Param is passed by value, moved + pub fn set_owner(&mut self, v: ::std::string::String) { + self.owner = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_owner(&mut self) -> &mut ::std::string::String { + &mut self.owner + } + + // Take field + pub fn take_owner(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.owner, ::std::string::String::new()) + } + + // .WorkspaceDetail workspace = 2; + + + pub fn get_workspace(&self) -> &super::workspace_create::WorkspaceDetail { + self.workspace.as_ref().unwrap_or_else(|| ::default_instance()) + } + pub fn clear_workspace(&mut self) { + self.workspace.clear(); + } + + pub fn has_workspace(&self) -> bool { + self.workspace.is_some() + } + + // Param is passed by value, moved + pub fn set_workspace(&mut self, v: super::workspace_create::WorkspaceDetail) { + self.workspace = ::protobuf::SingularPtrField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_workspace(&mut self) -> &mut super::workspace_create::WorkspaceDetail { + if self.workspace.is_none() { + self.workspace.set_default(); + } + self.workspace.as_mut().unwrap() + } + + // Take field + pub fn take_workspace(&mut self) -> super::workspace_create::WorkspaceDetail { + self.workspace.take().unwrap_or_else(|| super::workspace_create::WorkspaceDetail::new()) + } +} + +impl ::protobuf::Message for UserWorkspaceDetail { + fn is_initialized(&self) -> bool { + for v in &self.workspace { + 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_proto3_string_into(wire_type, is, &mut self.owner)?; + }, + 2 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.workspace)?; + }, + _ => { + ::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.owner.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.owner); + } + if let Some(ref v) = self.workspace.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 !self.owner.is_empty() { + os.write_string(1, &self.owner)?; + } + if let Some(ref v) = self.workspace.as_ref() { + os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + 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() -> UserWorkspaceDetail { + UserWorkspaceDetail::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>( + "owner", + |m: &UserWorkspaceDetail| { &m.owner }, + |m: &mut UserWorkspaceDetail| { &mut m.owner }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "workspace", + |m: &UserWorkspaceDetail| { &m.workspace }, + |m: &mut UserWorkspaceDetail| { &mut m.workspace }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "UserWorkspaceDetail", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static UserWorkspaceDetail { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(UserWorkspaceDetail::new) + } +} + +impl ::protobuf::Clear for UserWorkspaceDetail { + fn clear(&mut self) { + self.owner.clear(); + self.workspace.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for UserWorkspaceDetail { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for UserWorkspaceDetail { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +static file_descriptor_proto_data: &'static [u8] = b"\ + \n\x1bworkspace_user_detail.proto\x1a\x16workspace_create.proto\"H\n\rUs\ + erWorkspace\x12\x14\n\x05owner\x18\x01\x20\x01(\tR\x05owner\x12!\n\x0cwo\ + rkspace_id\x18\x02\x20\x01(\tR\x0bworkspaceId\"[\n\x13UserWorkspaceDetai\ + l\x12\x14\n\x05owner\x18\x01\x20\x01(\tR\x05owner\x12.\n\tworkspace\x18\ + \x02\x20\x01(\x0b2\x10.WorkspaceDetailR\tworkspaceJ\xa9\x02\n\x06\x12\ + \x04\0\0\n\x01\n\x08\n\x01\x0c\x12\x03\0\0\x12\n\t\n\x02\x03\0\x12\x03\ + \x01\0\x20\n\n\n\x02\x04\0\x12\x04\x03\0\x06\x01\n\n\n\x03\x04\0\x01\x12\ + \x03\x03\x08\x15\n\x0b\n\x04\x04\0\x02\0\x12\x03\x04\x04\x15\n\x0c\n\x05\ + \x04\0\x02\0\x05\x12\x03\x04\x04\n\n\x0c\n\x05\x04\0\x02\0\x01\x12\x03\ + \x04\x0b\x10\n\x0c\n\x05\x04\0\x02\0\x03\x12\x03\x04\x13\x14\n\x0b\n\x04\ + \x04\0\x02\x01\x12\x03\x05\x04\x1c\n\x0c\n\x05\x04\0\x02\x01\x05\x12\x03\ + \x05\x04\n\n\x0c\n\x05\x04\0\x02\x01\x01\x12\x03\x05\x0b\x17\n\x0c\n\x05\ + \x04\0\x02\x01\x03\x12\x03\x05\x1a\x1b\n\n\n\x02\x04\x01\x12\x04\x07\0\n\ + \x01\n\n\n\x03\x04\x01\x01\x12\x03\x07\x08\x1b\n\x0b\n\x04\x04\x01\x02\0\ + \x12\x03\x08\x04\x15\n\x0c\n\x05\x04\x01\x02\0\x05\x12\x03\x08\x04\n\n\ + \x0c\n\x05\x04\x01\x02\0\x01\x12\x03\x08\x0b\x10\n\x0c\n\x05\x04\x01\x02\ + \0\x03\x12\x03\x08\x13\x14\n\x0b\n\x04\x04\x01\x02\x01\x12\x03\t\x04\"\n\ + \x0c\n\x05\x04\x01\x02\x01\x06\x12\x03\t\x04\x13\n\x0c\n\x05\x04\x01\x02\ + \x01\x01\x12\x03\t\x14\x1d\n\x0c\n\x05\x04\x01\x02\x01\x03\x12\x03\t\x20\ + !b\x06proto3\ +"; + +static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; + +fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto { + ::protobuf::Message::parse_from_bytes(file_descriptor_proto_data).unwrap() +} + +pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto { + file_descriptor_proto_lazy.get(|| { + parse_descriptor_proto() + }) +} diff --git a/rust-lib/flowy-workspace/src/protobuf/proto/errors.proto b/rust-lib/flowy-workspace/src/protobuf/proto/errors.proto index 6b6af8b844..478a1c052b 100644 --- a/rust-lib/flowy-workspace/src/protobuf/proto/errors.proto +++ b/rust-lib/flowy-workspace/src/protobuf/proto/errors.proto @@ -11,7 +11,7 @@ enum WorkspaceErrorCode { AppColorStyleInvalid = 3; AppIdInvalid = 4; DatabaseConnectionFail = 5; - DatabaseInternalError = 6; + WorkspaceDatabaseError = 6; UserInternalError = 10; UserNotLoginYet = 11; } diff --git a/rust-lib/flowy-workspace/src/protobuf/proto/event.proto b/rust-lib/flowy-workspace/src/protobuf/proto/event.proto index 5d5a85f570..0ccba3d647 100644 --- a/rust-lib/flowy-workspace/src/protobuf/proto/event.proto +++ b/rust-lib/flowy-workspace/src/protobuf/proto/event.proto @@ -2,5 +2,5 @@ syntax = "proto3"; enum WorkspaceEvent { CreateWorkspace = 0; - GetWorkspaceUserDetail = 100; + GetWorkspaceDetail = 1; } diff --git a/rust-lib/flowy-workspace/src/protobuf/proto/workspace_user_detail.proto b/rust-lib/flowy-workspace/src/protobuf/proto/workspace_user_detail.proto new file mode 100644 index 0000000000..14036d8d00 --- /dev/null +++ b/rust-lib/flowy-workspace/src/protobuf/proto/workspace_user_detail.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; +import "workspace_create.proto"; + +message UserWorkspace { + string owner = 1; + string workspace_id = 2; +} +message UserWorkspaceDetail { + string owner = 1; + WorkspaceDetail workspace = 2; +} diff --git a/rust-lib/flowy-workspace/src/services/workspace_controller.rs b/rust-lib/flowy-workspace/src/services/workspace_controller.rs index dad0a817c0..5fdf48e2b1 100644 --- a/rust-lib/flowy-workspace/src/services/workspace_controller.rs +++ b/rust-lib/flowy-workspace/src/services/workspace_controller.rs @@ -1,6 +1,8 @@ use crate::{entities::workspace::*, errors::*, module::WorkspaceUser, sql_tables::workspace::*}; use flowy_database::{prelude::*, schema::workspace_table}; +use flowy_database::schema::workspace_table::dsl; +use flowy_dispatch::prelude::DispatchFuture; use std::sync::Arc; pub struct WorkspaceController { @@ -21,11 +23,29 @@ impl WorkspaceController { .values(workspace) .execute(&*(self.user.db_connection()?))?; - let _ = self.user.set_workspace(&detail.id).await?; + let _ = self.user.set_cur_workspace_id(&detail.id).await?; Ok(detail) } + pub fn get_workspace( + &self, + workspace_id: &str, + ) -> DispatchFuture> { + let user = self.user.clone(); + let workspace_id = workspace_id.to_owned(); + DispatchFuture { + fut: Box::pin(async move { + let workspace = dsl::workspace_table + .filter(workspace_table::id.eq(&workspace_id)) + .first::(&*(user.db_connection()?))?; + + // TODO: fetch workspace from remote server + Ok(workspace) + }), + } + } + pub fn update_workspace(&self, params: UpdateWorkspaceParams) -> Result<(), WorkspaceError> { let changeset = WorkspaceChangeset::new(params); let conn = self.user.db_connection()?; @@ -33,4 +53,14 @@ impl WorkspaceController { Ok(()) } + + pub async fn get_user_workspace_detail(&self) -> Result { + let user_workspace = self.user.get_cur_workspace().await?; + let workspace = self.get_workspace(&user_workspace.workspace_id).await?; + + Ok(UserWorkspaceDetail { + owner: user_workspace.owner, + workspace: workspace.into(), + }) + } } diff --git a/rust-lib/flowy-workspace/tests/event/workspace_test.rs b/rust-lib/flowy-workspace/tests/event/workspace_test.rs index 8c00414098..2c0ffc6855 100644 --- a/rust-lib/flowy-workspace/tests/event/workspace_test.rs +++ b/rust-lib/flowy-workspace/tests/event/workspace_test.rs @@ -1,6 +1,6 @@ use crate::helper::*; use flowy_workspace::{ - entities::workspace::{CreateWorkspaceRequest, WorkspaceDetail}, + entities::workspace::{CreateWorkspaceRequest, UserWorkspaceDetail, WorkspaceDetail}, event::WorkspaceEvent::*, prelude::*, }; @@ -20,6 +20,27 @@ fn workspace_create_success() { dbg!(&response); } +#[test] +fn workspace_get_detail_success() { + let request = CreateWorkspaceRequest { + name: "Team A".to_owned(), + desc: "Team A Description".to_owned(), + }; + + let workspace = WorkspaceTestBuilder::new() + .event(CreateWorkspace) + .request(request) + .sync_send() + .parse::(); + + let user_workspace = WorkspaceTestBuilder::new() + .event(GetWorkspaceDetail) + .sync_send() + .parse::(); + + assert_eq!(workspace.name, user_workspace.workspace.name); +} + #[test] fn workspace_create_with_invalid_name_test() { for name in invalid_workspace_name_test_case() { diff --git a/scripts/flowy-tool/Cargo.toml b/scripts/flowy-tool/Cargo.toml index 25ce86882d..efef3f7a1b 100644 --- a/scripts/flowy-tool/Cargo.toml +++ b/scripts/flowy-tool/Cargo.toml @@ -22,4 +22,5 @@ phf = { version = "0.8.0", features = ["macros"] } similar = "1.2.2" dialoguer = "0.8.0" toml = "0.5.8" -serde = { version = "1.0", features = ["derive"] } \ No newline at end of file +serde = { version = "1.0", features = ["derive"] } +pathdiff = "0.2.0" \ No newline at end of file diff --git a/scripts/flowy-tool/src/proto/ast.rs b/scripts/flowy-tool/src/proto/ast.rs index bf780bb1d9..ab4722897f 100644 --- a/scripts/flowy-tool/src/proto/ast.rs +++ b/scripts/flowy-tool/src/proto/ast.rs @@ -78,6 +78,7 @@ fn parse_files_protobuf(proto_crate_path: &str, proto_output_dir: &str) -> Vec

, pub enums: Vec, @@ -121,6 +122,7 @@ impl FlutterProtobufInfo { model_dir } + #[allow(dead_code)] pub fn mod_file_path(&self) -> String { let mod_file_path = format!("{}/protobuf.dart", self.package_path); mod_file_path diff --git a/scripts/flowy-tool/src/util/file.rs b/scripts/flowy-tool/src/util/file.rs index 1719631560..b752866200 100644 --- a/scripts/flowy-tool/src/util/file.rs +++ b/scripts/flowy-tool/src/util/file.rs @@ -154,3 +154,14 @@ where path_and_name(path, name); } } + +#[allow(dead_code)] +pub fn suffix_relative_to_path(path: &str, base: &str) -> String { + let base = Path::new(base); + let path = Path::new(path); + path.strip_prefix(base) + .unwrap() + .to_str() + .unwrap() + .to_owned() +}