mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
add get user detail event, extract remote serviceinto UserServer
This commit is contained in:
parent
546b3121e3
commit
1d74fbdd7b
3
.gitignore
vendored
3
.gitignore
vendored
@ -8,4 +8,5 @@ Cargo.lock
|
||||
|
||||
# These are backup files generated by rustfmt
|
||||
**/*.rs.bk
|
||||
**/target/
|
||||
**/target/
|
||||
**/*.db
|
@ -63,6 +63,9 @@
|
||||
<excludeFolder url="file://$MODULE_DIR$/app_flowy/packages/flowy_editor/.dart_tool" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/app_flowy/packages/flowy_editor/build" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/app_flowy/packages/flowy_editor/.pub" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/app_flowy/packages/flowy_editor/example/.dart_tool" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/app_flowy/packages/flowy_editor/example/.pub" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/app_flowy/packages/flowy_editor/example/build" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
|
@ -2,7 +2,9 @@
|
||||
export 'protobuf/kv.pb.dart';
|
||||
export 'protobuf/ffi_response.pb.dart';
|
||||
export 'protobuf/ffi_request.pb.dart';
|
||||
export 'protobuf/user_status.pb.dart';
|
||||
export 'protobuf/sign_up.pb.dart';
|
||||
export 'protobuf/sign_in.pb.dart';
|
||||
export 'protobuf/user_table.pb.dart';
|
||||
export 'protobuf/event.pb.dart';
|
||||
export 'protobuf/user.pb.dart';
|
||||
|
@ -10,13 +10,13 @@ import 'dart:core' as $core;
|
||||
import 'package:protobuf/protobuf.dart' as $pb;
|
||||
|
||||
class UserEvent extends $pb.ProtobufEnum {
|
||||
static const UserEvent AuthCheck = UserEvent._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'AuthCheck');
|
||||
static const UserEvent GetStatus = UserEvent._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetStatus');
|
||||
static const UserEvent SignIn = UserEvent._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'SignIn');
|
||||
static const UserEvent SignUp = UserEvent._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'SignUp');
|
||||
static const UserEvent SignOut = UserEvent._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'SignOut');
|
||||
|
||||
static const $core.List<UserEvent> values = <UserEvent> [
|
||||
AuthCheck,
|
||||
GetStatus,
|
||||
SignIn,
|
||||
SignUp,
|
||||
SignOut,
|
||||
|
@ -9,7 +9,7 @@ import 'dart:core' as $core;
|
||||
const UserEvent$json = const {
|
||||
'1': 'UserEvent',
|
||||
'2': const [
|
||||
const {'1': 'AuthCheck', '2': 0},
|
||||
const {'1': 'GetStatus', '2': 0},
|
||||
const {'1': 'SignIn', '2': 1},
|
||||
const {'1': 'SignUp', '2': 2},
|
||||
const {'1': 'SignOut', '2': 3},
|
||||
|
@ -165,50 +165,3 @@ class KeyValue extends $pb.GeneratedMessage {
|
||||
void clearBoolValue() => clearField(5);
|
||||
}
|
||||
|
||||
class KeyValueQuery extends $pb.GeneratedMessage {
|
||||
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'KeyValueQuery', createEmptyInstance: create)
|
||||
..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'key')
|
||||
..hasRequiredFields = false
|
||||
;
|
||||
|
||||
KeyValueQuery._() : super();
|
||||
factory KeyValueQuery({
|
||||
$core.String? key,
|
||||
}) {
|
||||
final _result = create();
|
||||
if (key != null) {
|
||||
_result.key = key;
|
||||
}
|
||||
return _result;
|
||||
}
|
||||
factory KeyValueQuery.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
|
||||
factory KeyValueQuery.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')
|
||||
KeyValueQuery clone() => KeyValueQuery()..mergeFromMessage(this);
|
||||
@$core.Deprecated(
|
||||
'Using this can add significant overhead to your binary. '
|
||||
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
|
||||
'Will be removed in next major version')
|
||||
KeyValueQuery copyWith(void Function(KeyValueQuery) updates) => super.copyWith((message) => updates(message as KeyValueQuery)) as KeyValueQuery; // ignore: deprecated_member_use
|
||||
$pb.BuilderInfo get info_ => _i;
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static KeyValueQuery create() => KeyValueQuery._();
|
||||
KeyValueQuery createEmptyInstance() => create();
|
||||
static $pb.PbList<KeyValueQuery> createRepeated() => $pb.PbList<KeyValueQuery>();
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static KeyValueQuery getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<KeyValueQuery>(create);
|
||||
static KeyValueQuery? _defaultInstance;
|
||||
|
||||
@$pb.TagNumber(1)
|
||||
$core.String get key => $_getSZ(0);
|
||||
@$pb.TagNumber(1)
|
||||
set key($core.String v) { $_setString(0, v); }
|
||||
@$pb.TagNumber(1)
|
||||
$core.bool hasKey() => $_has(0);
|
||||
@$pb.TagNumber(1)
|
||||
void clearKey() => clearField(1);
|
||||
}
|
||||
|
||||
|
@ -23,10 +23,3 @@ const KeyValue$json = const {
|
||||
],
|
||||
};
|
||||
|
||||
const KeyValueQuery$json = const {
|
||||
'1': 'KeyValueQuery',
|
||||
'2': const [
|
||||
const {'1': 'key', '3': 1, '4': 1, '5': 9, '10': 'key'},
|
||||
],
|
||||
};
|
||||
|
||||
|
@ -131,50 +131,3 @@ class SignInParams extends $pb.GeneratedMessage {
|
||||
void clearPassword() => clearField(2);
|
||||
}
|
||||
|
||||
class SignInResponse extends $pb.GeneratedMessage {
|
||||
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'SignInResponse', createEmptyInstance: create)
|
||||
..aOB(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'isSuccess')
|
||||
..hasRequiredFields = false
|
||||
;
|
||||
|
||||
SignInResponse._() : super();
|
||||
factory SignInResponse({
|
||||
$core.bool? isSuccess,
|
||||
}) {
|
||||
final _result = create();
|
||||
if (isSuccess != null) {
|
||||
_result.isSuccess = isSuccess;
|
||||
}
|
||||
return _result;
|
||||
}
|
||||
factory SignInResponse.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
|
||||
factory SignInResponse.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')
|
||||
SignInResponse clone() => SignInResponse()..mergeFromMessage(this);
|
||||
@$core.Deprecated(
|
||||
'Using this can add significant overhead to your binary. '
|
||||
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
|
||||
'Will be removed in next major version')
|
||||
SignInResponse copyWith(void Function(SignInResponse) updates) => super.copyWith((message) => updates(message as SignInResponse)) as SignInResponse; // ignore: deprecated_member_use
|
||||
$pb.BuilderInfo get info_ => _i;
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static SignInResponse create() => SignInResponse._();
|
||||
SignInResponse createEmptyInstance() => create();
|
||||
static $pb.PbList<SignInResponse> createRepeated() => $pb.PbList<SignInResponse>();
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static SignInResponse getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<SignInResponse>(create);
|
||||
static SignInResponse? _defaultInstance;
|
||||
|
||||
@$pb.TagNumber(1)
|
||||
$core.bool get isSuccess => $_getBF(0);
|
||||
@$pb.TagNumber(1)
|
||||
set isSuccess($core.bool v) { $_setBool(0, v); }
|
||||
@$pb.TagNumber(1)
|
||||
$core.bool hasIsSuccess() => $_has(0);
|
||||
@$pb.TagNumber(1)
|
||||
void clearIsSuccess() => clearField(1);
|
||||
}
|
||||
|
||||
|
@ -22,10 +22,3 @@ const SignInParams$json = const {
|
||||
],
|
||||
};
|
||||
|
||||
const SignInResponse$json = const {
|
||||
'1': 'SignInResponse',
|
||||
'2': const [
|
||||
const {'1': 'is_success', '3': 1, '4': 1, '5': 8, '10': 'isSuccess'},
|
||||
],
|
||||
};
|
||||
|
||||
|
100
app_flowy/packages/flowy_sdk/lib/protobuf/user.pb.dart
Normal file
100
app_flowy/packages/flowy_sdk/lib/protobuf/user.pb.dart
Normal file
@ -0,0 +1,100 @@
|
||||
///
|
||||
// Generated code. Do not modify.
|
||||
// source: user.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;
|
||||
|
||||
class User extends $pb.GeneratedMessage {
|
||||
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'User', createEmptyInstance: create)
|
||||
..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id')
|
||||
..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name')
|
||||
..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'email')
|
||||
..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'password')
|
||||
..hasRequiredFields = false
|
||||
;
|
||||
|
||||
User._() : super();
|
||||
factory User({
|
||||
$core.String? id,
|
||||
$core.String? name,
|
||||
$core.String? email,
|
||||
$core.String? password,
|
||||
}) {
|
||||
final _result = create();
|
||||
if (id != null) {
|
||||
_result.id = id;
|
||||
}
|
||||
if (name != null) {
|
||||
_result.name = name;
|
||||
}
|
||||
if (email != null) {
|
||||
_result.email = email;
|
||||
}
|
||||
if (password != null) {
|
||||
_result.password = password;
|
||||
}
|
||||
return _result;
|
||||
}
|
||||
factory User.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
|
||||
factory User.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')
|
||||
User clone() => User()..mergeFromMessage(this);
|
||||
@$core.Deprecated(
|
||||
'Using this can add significant overhead to your binary. '
|
||||
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
|
||||
'Will be removed in next major version')
|
||||
User copyWith(void Function(User) updates) => super.copyWith((message) => updates(message as User)) as User; // ignore: deprecated_member_use
|
||||
$pb.BuilderInfo get info_ => _i;
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static User create() => User._();
|
||||
User createEmptyInstance() => create();
|
||||
static $pb.PbList<User> createRepeated() => $pb.PbList<User>();
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static User getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<User>(create);
|
||||
static User? _defaultInstance;
|
||||
|
||||
@$pb.TagNumber(1)
|
||||
$core.String get id => $_getSZ(0);
|
||||
@$pb.TagNumber(1)
|
||||
set id($core.String v) { $_setString(0, v); }
|
||||
@$pb.TagNumber(1)
|
||||
$core.bool hasId() => $_has(0);
|
||||
@$pb.TagNumber(1)
|
||||
void clearId() => clearField(1);
|
||||
|
||||
@$pb.TagNumber(2)
|
||||
$core.String get name => $_getSZ(1);
|
||||
@$pb.TagNumber(2)
|
||||
set name($core.String v) { $_setString(1, v); }
|
||||
@$pb.TagNumber(2)
|
||||
$core.bool hasName() => $_has(1);
|
||||
@$pb.TagNumber(2)
|
||||
void clearName() => clearField(2);
|
||||
|
||||
@$pb.TagNumber(3)
|
||||
$core.String get email => $_getSZ(2);
|
||||
@$pb.TagNumber(3)
|
||||
set email($core.String v) { $_setString(2, v); }
|
||||
@$pb.TagNumber(3)
|
||||
$core.bool hasEmail() => $_has(2);
|
||||
@$pb.TagNumber(3)
|
||||
void clearEmail() => clearField(3);
|
||||
|
||||
@$pb.TagNumber(4)
|
||||
$core.String get password => $_getSZ(3);
|
||||
@$pb.TagNumber(4)
|
||||
set password($core.String v) { $_setString(3, v); }
|
||||
@$pb.TagNumber(4)
|
||||
$core.bool hasPassword() => $_has(3);
|
||||
@$pb.TagNumber(4)
|
||||
void clearPassword() => clearField(4);
|
||||
}
|
||||
|
@ -0,0 +1,7 @@
|
||||
///
|
||||
// Generated code. Do not modify.
|
||||
// source: user.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
|
||||
|
18
app_flowy/packages/flowy_sdk/lib/protobuf/user.pbjson.dart
Normal file
18
app_flowy/packages/flowy_sdk/lib/protobuf/user.pbjson.dart
Normal file
@ -0,0 +1,18 @@
|
||||
///
|
||||
// Generated code. Do not modify.
|
||||
// source: user.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;
|
||||
const User$json = const {
|
||||
'1': 'User',
|
||||
'2': const [
|
||||
const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'},
|
||||
const {'1': 'name', '3': 2, '4': 1, '5': 9, '10': 'name'},
|
||||
const {'1': 'email', '3': 3, '4': 1, '5': 9, '10': 'email'},
|
||||
const {'1': 'password', '3': 4, '4': 1, '5': 9, '10': 'password'},
|
||||
],
|
||||
};
|
||||
|
@ -0,0 +1,9 @@
|
||||
///
|
||||
// Generated code. Do not modify.
|
||||
// source: user.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
|
||||
|
||||
export 'user.pb.dart';
|
||||
|
@ -0,0 +1,90 @@
|
||||
///
|
||||
// Generated code. Do not modify.
|
||||
// source: user_status.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 'user_status.pbenum.dart';
|
||||
|
||||
export 'user_status.pbenum.dart';
|
||||
|
||||
class UserDetail extends $pb.GeneratedMessage {
|
||||
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'UserDetail', createEmptyInstance: create)
|
||||
..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'email')
|
||||
..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name')
|
||||
..e<UserStatus>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'status', $pb.PbFieldType.OE, defaultOrMaker: UserStatus.Unknown, valueOf: UserStatus.valueOf, enumValues: UserStatus.values)
|
||||
..hasRequiredFields = false
|
||||
;
|
||||
|
||||
UserDetail._() : super();
|
||||
factory UserDetail({
|
||||
$core.String? email,
|
||||
$core.String? name,
|
||||
UserStatus? status,
|
||||
}) {
|
||||
final _result = create();
|
||||
if (email != null) {
|
||||
_result.email = email;
|
||||
}
|
||||
if (name != null) {
|
||||
_result.name = name;
|
||||
}
|
||||
if (status != null) {
|
||||
_result.status = status;
|
||||
}
|
||||
return _result;
|
||||
}
|
||||
factory UserDetail.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
|
||||
factory UserDetail.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')
|
||||
UserDetail clone() => UserDetail()..mergeFromMessage(this);
|
||||
@$core.Deprecated(
|
||||
'Using this can add significant overhead to your binary. '
|
||||
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
|
||||
'Will be removed in next major version')
|
||||
UserDetail copyWith(void Function(UserDetail) updates) => super.copyWith((message) => updates(message as UserDetail)) as UserDetail; // ignore: deprecated_member_use
|
||||
$pb.BuilderInfo get info_ => _i;
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static UserDetail create() => UserDetail._();
|
||||
UserDetail createEmptyInstance() => create();
|
||||
static $pb.PbList<UserDetail> createRepeated() => $pb.PbList<UserDetail>();
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static UserDetail getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<UserDetail>(create);
|
||||
static UserDetail? _defaultInstance;
|
||||
|
||||
@$pb.TagNumber(1)
|
||||
$core.String get email => $_getSZ(0);
|
||||
@$pb.TagNumber(1)
|
||||
set email($core.String v) { $_setString(0, v); }
|
||||
@$pb.TagNumber(1)
|
||||
$core.bool hasEmail() => $_has(0);
|
||||
@$pb.TagNumber(1)
|
||||
void clearEmail() => clearField(1);
|
||||
|
||||
@$pb.TagNumber(2)
|
||||
$core.String get name => $_getSZ(1);
|
||||
@$pb.TagNumber(2)
|
||||
set name($core.String v) { $_setString(1, v); }
|
||||
@$pb.TagNumber(2)
|
||||
$core.bool hasName() => $_has(1);
|
||||
@$pb.TagNumber(2)
|
||||
void clearName() => clearField(2);
|
||||
|
||||
@$pb.TagNumber(3)
|
||||
UserStatus get status => $_getN(2);
|
||||
@$pb.TagNumber(3)
|
||||
set status(UserStatus v) { setField(3, v); }
|
||||
@$pb.TagNumber(3)
|
||||
$core.bool hasStatus() => $_has(2);
|
||||
@$pb.TagNumber(3)
|
||||
void clearStatus() => clearField(3);
|
||||
}
|
||||
|
@ -0,0 +1,28 @@
|
||||
///
|
||||
// Generated code. Do not modify.
|
||||
// source: user_status.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
|
||||
|
||||
// ignore_for_file: UNDEFINED_SHOWN_NAME
|
||||
import 'dart:core' as $core;
|
||||
import 'package:protobuf/protobuf.dart' as $pb;
|
||||
|
||||
class UserStatus extends $pb.ProtobufEnum {
|
||||
static const UserStatus Unknown = UserStatus._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Unknown');
|
||||
static const UserStatus Login = UserStatus._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Login');
|
||||
static const UserStatus Expired = UserStatus._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Expired');
|
||||
|
||||
static const $core.List<UserStatus> values = <UserStatus> [
|
||||
Unknown,
|
||||
Login,
|
||||
Expired,
|
||||
];
|
||||
|
||||
static final $core.Map<$core.int, UserStatus> _byValue = $pb.ProtobufEnum.initByValue(values);
|
||||
static UserStatus? valueOf($core.int value) => _byValue[value];
|
||||
|
||||
const UserStatus._($core.int v, $core.String n) : super(v, n);
|
||||
}
|
||||
|
@ -0,0 +1,26 @@
|
||||
///
|
||||
// Generated code. Do not modify.
|
||||
// source: user_status.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;
|
||||
const UserStatus$json = const {
|
||||
'1': 'UserStatus',
|
||||
'2': const [
|
||||
const {'1': 'Unknown', '2': 0},
|
||||
const {'1': 'Login', '2': 1},
|
||||
const {'1': 'Expired', '2': 2},
|
||||
],
|
||||
};
|
||||
|
||||
const UserDetail$json = const {
|
||||
'1': 'UserDetail',
|
||||
'2': const [
|
||||
const {'1': 'email', '3': 1, '4': 1, '5': 9, '10': 'email'},
|
||||
const {'1': 'name', '3': 2, '4': 1, '5': 9, '10': 'name'},
|
||||
const {'1': 'status', '3': 3, '4': 1, '5': 14, '6': '.UserStatus', '10': 'status'},
|
||||
],
|
||||
};
|
||||
|
@ -0,0 +1,9 @@
|
||||
///
|
||||
// Generated code. Do not modify.
|
||||
// source: user_status.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
|
||||
|
||||
export 'user_status.pb.dart';
|
||||
|
@ -16,18 +16,18 @@ pub fn category_from_str(type_str: &str) -> TypeCategory {
|
||||
"u8" => TypeCategory::Bytes,
|
||||
"String" => TypeCategory::Str,
|
||||
"KeyValue"
|
||||
| "KeyValueQuery"
|
||||
| "FFIRequest"
|
||||
| "FFIResponse"
|
||||
| "User"
|
||||
| "UserDetail"
|
||||
| "SignUpRequest"
|
||||
| "SignUpParams"
|
||||
| "SignUpResponse"
|
||||
| "SignInRequest"
|
||||
| "SignInParams"
|
||||
| "SignInResponse"
|
||||
=> TypeCategory::Protobuf,
|
||||
"FFIStatusCode"
|
||||
| "UserStatus"
|
||||
| "UserEvent"
|
||||
=> TypeCategory::Enum,
|
||||
|
||||
"Option" => TypeCategory::Opt,
|
||||
|
@ -4,7 +4,11 @@ use diesel::{Connection, SqliteConnection};
|
||||
use flowy_derive::ProtoBuf;
|
||||
use flowy_sqlite::{DBConnection, Database, PoolConfig};
|
||||
use lazy_static::lazy_static;
|
||||
use std::{path::Path, sync::RwLock};
|
||||
use std::{
|
||||
path::Path,
|
||||
sync::{PoisonError, RwLock, RwLockWriteGuard},
|
||||
};
|
||||
|
||||
const DB_NAME: &str = "kv.db";
|
||||
lazy_static! {
|
||||
pub static ref KV_HOLDER: RwLock<KVStore> = RwLock::new(KVStore::new());
|
||||
@ -17,59 +21,52 @@ pub struct KVStore {
|
||||
impl KVStore {
|
||||
fn new() -> Self { KVStore { database: None } }
|
||||
|
||||
pub fn init(&mut self, root: &str) -> Result<(), String> {
|
||||
pub fn set(item: KeyValue) -> Result<(), String> {
|
||||
let conn = get_connection()?;
|
||||
let _ = diesel::replace_into(kv_table::table)
|
||||
.values(&item)
|
||||
.execute(&*conn)
|
||||
.map_err(|e| format!("{:?}", e))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get(key: &str) -> Result<KeyValue, String> {
|
||||
let conn = get_connection()?;
|
||||
let item = dsl::kv_table
|
||||
.filter(kv_table::key.eq(key))
|
||||
.first::<KeyValue>(&*conn)
|
||||
.map_err(|e| format!("{:?}", e))?;
|
||||
Ok(item)
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn remove(key: &str) -> Result<(), String> {
|
||||
let conn = get_connection()?;
|
||||
let sql = dsl::kv_table.filter(kv_table::key.eq(key));
|
||||
let _ = diesel::delete(sql)
|
||||
.execute(&*conn)
|
||||
.map_err(|e| format!("{:?}", e))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn init(root: &str) -> Result<(), String> {
|
||||
if !Path::new(root).exists() {
|
||||
return Err(format!("{} not exists", root));
|
||||
return Err(format!("Init KVStore failed. {} not exists", root));
|
||||
}
|
||||
|
||||
let pool_config = PoolConfig::default();
|
||||
let database = Database::new(root, DB_NAME, pool_config).unwrap();
|
||||
let conn = database.get_connection().unwrap();
|
||||
SqliteConnection::execute(&*conn, KV_SQL).unwrap();
|
||||
self.database = Some(database);
|
||||
|
||||
let mut store = KV_HOLDER
|
||||
.write()
|
||||
.map_err(|e| format!("KVStore write failed: {:?}", e))?;
|
||||
store.database = Some(database);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn set(item: KeyValue) -> Result<(), String> {
|
||||
match get_connection() {
|
||||
Ok(conn) => {
|
||||
let _ = diesel::insert_into(kv_table::table)
|
||||
.values(&item)
|
||||
.execute(&*conn)
|
||||
.map_err(|e| format!("{:?}", e))?;
|
||||
|
||||
Ok(())
|
||||
},
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn remove(key: &str) -> Result<(), String> {
|
||||
match get_connection() {
|
||||
Ok(conn) => {
|
||||
let _ = diesel::delete(dsl::kv_table.filter(kv_table::key.eq(key)))
|
||||
.execute(&*conn)
|
||||
.map_err(|e| format!("{:?}", e))?;
|
||||
Ok(())
|
||||
},
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get(key: &str) -> Result<KeyValue, String> {
|
||||
match get_connection() {
|
||||
Ok(conn) => {
|
||||
let item = dsl::kv_table
|
||||
.filter(kv_table::key.eq(key))
|
||||
.first::<KeyValue>(&*conn)
|
||||
.map_err(|e| format!("{:?}", e))?;
|
||||
Ok(item)
|
||||
},
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_get_func {
|
||||
@ -142,9 +139,7 @@ fn get_connection() -> Result<DBConnection, String> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(
|
||||
PartialEq, Clone, Debug, ProtoBuf, Default, Queryable, Identifiable, Insertable, AsChangeset,
|
||||
)]
|
||||
#[derive(Clone, Debug, ProtoBuf, Default, Queryable, Identifiable, Insertable, AsChangeset)]
|
||||
#[table_name = "kv_table"]
|
||||
#[primary_key(key)]
|
||||
pub struct KeyValue {
|
||||
@ -173,16 +168,27 @@ impl KeyValue {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(ProtoBuf, Default, Debug)]
|
||||
pub struct KeyValueQuery {
|
||||
#[pb(index = 1)]
|
||||
key: String,
|
||||
}
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::kv::KVStore;
|
||||
|
||||
impl KeyValueQuery {
|
||||
pub fn new(key: &str) -> Self {
|
||||
let mut query = KeyValueQuery::default();
|
||||
query.key = key.to_string();
|
||||
query
|
||||
#[test]
|
||||
fn kv_store_test() {
|
||||
let dir = "./temp/";
|
||||
if !std::path::Path::new(dir).exists() {
|
||||
std::fs::create_dir_all(dir).unwrap();
|
||||
}
|
||||
|
||||
KVStore::init(dir);
|
||||
|
||||
KVStore::set_str("1", "hello".to_string());
|
||||
assert_eq!(KVStore::get_str("1").unwrap(), "hello");
|
||||
|
||||
assert_eq!(KVStore::get_str("2"), None);
|
||||
|
||||
KVStore::set_bool("1", true);
|
||||
assert_eq!(KVStore::get_bool("1").unwrap(), true);
|
||||
|
||||
assert_eq!(KVStore::get_bool("2"), None);
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ extern crate diesel_derives;
|
||||
#[macro_use]
|
||||
extern crate diesel_migrations;
|
||||
|
||||
mod kv;
|
||||
pub mod kv;
|
||||
mod protobuf;
|
||||
|
||||
pub fn uuid() -> String { uuid::Uuid::new_v4().to_string() }
|
||||
|
@ -435,165 +435,6 @@ impl ::protobuf::reflect::ProtobufValue for KeyValue {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq,Clone,Default)]
|
||||
pub struct KeyValueQuery {
|
||||
// message fields
|
||||
pub key: ::std::string::String,
|
||||
// special fields
|
||||
pub unknown_fields: ::protobuf::UnknownFields,
|
||||
pub cached_size: ::protobuf::CachedSize,
|
||||
}
|
||||
|
||||
impl<'a> ::std::default::Default for &'a KeyValueQuery {
|
||||
fn default() -> &'a KeyValueQuery {
|
||||
<KeyValueQuery as ::protobuf::Message>::default_instance()
|
||||
}
|
||||
}
|
||||
|
||||
impl KeyValueQuery {
|
||||
pub fn new() -> KeyValueQuery {
|
||||
::std::default::Default::default()
|
||||
}
|
||||
|
||||
// string key = 1;
|
||||
|
||||
|
||||
pub fn get_key(&self) -> &str {
|
||||
&self.key
|
||||
}
|
||||
pub fn clear_key(&mut self) {
|
||||
self.key.clear();
|
||||
}
|
||||
|
||||
// Param is passed by value, moved
|
||||
pub fn set_key(&mut self, v: ::std::string::String) {
|
||||
self.key = v;
|
||||
}
|
||||
|
||||
// Mutable pointer to the field.
|
||||
// If field is not initialized, it is initialized with default value first.
|
||||
pub fn mut_key(&mut self) -> &mut ::std::string::String {
|
||||
&mut self.key
|
||||
}
|
||||
|
||||
// Take field
|
||||
pub fn take_key(&mut self) -> ::std::string::String {
|
||||
::std::mem::replace(&mut self.key, ::std::string::String::new())
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::Message for KeyValueQuery {
|
||||
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.key)?;
|
||||
},
|
||||
_ => {
|
||||
::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.key.is_empty() {
|
||||
my_size += ::protobuf::rt::string_size(1, &self.key);
|
||||
}
|
||||
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.key.is_empty() {
|
||||
os.write_string(1, &self.key)?;
|
||||
}
|
||||
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<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
|
||||
self
|
||||
}
|
||||
|
||||
fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
|
||||
Self::descriptor_static()
|
||||
}
|
||||
|
||||
fn new() -> KeyValueQuery {
|
||||
KeyValueQuery::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>(
|
||||
"key",
|
||||
|m: &KeyValueQuery| { &m.key },
|
||||
|m: &mut KeyValueQuery| { &mut m.key },
|
||||
));
|
||||
::protobuf::reflect::MessageDescriptor::new_pb_name::<KeyValueQuery>(
|
||||
"KeyValueQuery",
|
||||
fields,
|
||||
file_descriptor_proto()
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
fn default_instance() -> &'static KeyValueQuery {
|
||||
static instance: ::protobuf::rt::LazyV2<KeyValueQuery> = ::protobuf::rt::LazyV2::INIT;
|
||||
instance.get(KeyValueQuery::new)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::Clear for KeyValueQuery {
|
||||
fn clear(&mut self) {
|
||||
self.key.clear();
|
||||
self.unknown_fields.clear();
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::fmt::Debug for KeyValueQuery {
|
||||
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
|
||||
::protobuf::text_format::fmt(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::reflect::ProtobufValue for KeyValueQuery {
|
||||
fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
|
||||
::protobuf::reflect::ReflectValueRef::Message(self)
|
||||
}
|
||||
}
|
||||
|
||||
static file_descriptor_proto_data: &'static [u8] = b"\
|
||||
\n\x08kv.proto\"\xf1\x01\n\x08KeyValue\x12\x10\n\x03key\x18\x01\x20\x01(\
|
||||
\tR\x03key\x12\x1d\n\tstr_value\x18\x02\x20\x01(\tH\0R\x08strValue\x12\
|
||||
@ -601,31 +442,27 @@ static file_descriptor_proto_data: &'static [u8] = b"\
|
||||
_value\x18\x04\x20\x01(\x01H\x02R\nfloatValue\x12\x1f\n\nbool_value\x18\
|
||||
\x05\x20\x01(\x08H\x03R\tboolValueB\x12\n\x10one_of_str_valueB\x12\n\x10\
|
||||
one_of_int_valueB\x14\n\x12one_of_float_valueB\x13\n\x11one_of_bool_valu\
|
||||
e\"!\n\rKeyValueQuery\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03keyJ\xf8\
|
||||
\x03\n\x06\x12\x04\0\0\x0b\x01\n\x08\n\x01\x0c\x12\x03\0\0\x12\n\n\n\x02\
|
||||
\x04\0\x12\x04\x02\0\x08\x01\n\n\n\x03\x04\0\x01\x12\x03\x02\x08\x10\n\
|
||||
\x0b\n\x04\x04\0\x02\0\x12\x03\x03\x04\x13\n\x0c\n\x05\x04\0\x02\0\x05\
|
||||
\x12\x03\x03\x04\n\n\x0c\n\x05\x04\0\x02\0\x01\x12\x03\x03\x0b\x0e\n\x0c\
|
||||
\n\x05\x04\0\x02\0\x03\x12\x03\x03\x11\x12\n\x0b\n\x04\x04\0\x08\0\x12\
|
||||
\x03\x04\x044\n\x0c\n\x05\x04\0\x08\0\x01\x12\x03\x04\n\x1a\n\x0b\n\x04\
|
||||
\x04\0\x02\x01\x12\x03\x04\x1d2\n\x0c\n\x05\x04\0\x02\x01\x05\x12\x03\
|
||||
\x04\x1d#\n\x0c\n\x05\x04\0\x02\x01\x01\x12\x03\x04$-\n\x0c\n\x05\x04\0\
|
||||
\x02\x01\x03\x12\x03\x0401\n\x0b\n\x04\x04\0\x08\x01\x12\x03\x05\x043\n\
|
||||
\x0c\n\x05\x04\0\x08\x01\x01\x12\x03\x05\n\x1a\n\x0b\n\x04\x04\0\x02\x02\
|
||||
\x12\x03\x05\x1d1\n\x0c\n\x05\x04\0\x02\x02\x05\x12\x03\x05\x1d\"\n\x0c\
|
||||
\n\x05\x04\0\x02\x02\x01\x12\x03\x05#,\n\x0c\n\x05\x04\0\x02\x02\x03\x12\
|
||||
\x03\x05/0\n\x0b\n\x04\x04\0\x08\x02\x12\x03\x06\x048\n\x0c\n\x05\x04\0\
|
||||
\x08\x02\x01\x12\x03\x06\n\x1c\n\x0b\n\x04\x04\0\x02\x03\x12\x03\x06\x1f\
|
||||
6\n\x0c\n\x05\x04\0\x02\x03\x05\x12\x03\x06\x1f%\n\x0c\n\x05\x04\0\x02\
|
||||
\x03\x01\x12\x03\x06&1\n\x0c\n\x05\x04\0\x02\x03\x03\x12\x03\x0645\n\x0b\
|
||||
\n\x04\x04\0\x08\x03\x12\x03\x07\x044\n\x0c\n\x05\x04\0\x08\x03\x01\x12\
|
||||
\x03\x07\n\x1b\n\x0b\n\x04\x04\0\x02\x04\x12\x03\x07\x1e2\n\x0c\n\x05\
|
||||
\x04\0\x02\x04\x05\x12\x03\x07\x1e\"\n\x0c\n\x05\x04\0\x02\x04\x01\x12\
|
||||
\x03\x07#-\n\x0c\n\x05\x04\0\x02\x04\x03\x12\x03\x0701\n\n\n\x02\x04\x01\
|
||||
\x12\x04\t\0\x0b\x01\n\n\n\x03\x04\x01\x01\x12\x03\t\x08\x15\n\x0b\n\x04\
|
||||
\x04\x01\x02\0\x12\x03\n\x04\x13\n\x0c\n\x05\x04\x01\x02\0\x05\x12\x03\n\
|
||||
\x04\n\n\x0c\n\x05\x04\x01\x02\0\x01\x12\x03\n\x0b\x0e\n\x0c\n\x05\x04\
|
||||
\x01\x02\0\x03\x12\x03\n\x11\x12b\x06proto3\
|
||||
eJ\xa9\x03\n\x06\x12\x04\0\0\x08\x01\n\x08\n\x01\x0c\x12\x03\0\0\x12\n\n\
|
||||
\n\x02\x04\0\x12\x04\x02\0\x08\x01\n\n\n\x03\x04\0\x01\x12\x03\x02\x08\
|
||||
\x10\n\x0b\n\x04\x04\0\x02\0\x12\x03\x03\x04\x13\n\x0c\n\x05\x04\0\x02\0\
|
||||
\x05\x12\x03\x03\x04\n\n\x0c\n\x05\x04\0\x02\0\x01\x12\x03\x03\x0b\x0e\n\
|
||||
\x0c\n\x05\x04\0\x02\0\x03\x12\x03\x03\x11\x12\n\x0b\n\x04\x04\0\x08\0\
|
||||
\x12\x03\x04\x044\n\x0c\n\x05\x04\0\x08\0\x01\x12\x03\x04\n\x1a\n\x0b\n\
|
||||
\x04\x04\0\x02\x01\x12\x03\x04\x1d2\n\x0c\n\x05\x04\0\x02\x01\x05\x12\
|
||||
\x03\x04\x1d#\n\x0c\n\x05\x04\0\x02\x01\x01\x12\x03\x04$-\n\x0c\n\x05\
|
||||
\x04\0\x02\x01\x03\x12\x03\x0401\n\x0b\n\x04\x04\0\x08\x01\x12\x03\x05\
|
||||
\x043\n\x0c\n\x05\x04\0\x08\x01\x01\x12\x03\x05\n\x1a\n\x0b\n\x04\x04\0\
|
||||
\x02\x02\x12\x03\x05\x1d1\n\x0c\n\x05\x04\0\x02\x02\x05\x12\x03\x05\x1d\
|
||||
\"\n\x0c\n\x05\x04\0\x02\x02\x01\x12\x03\x05#,\n\x0c\n\x05\x04\0\x02\x02\
|
||||
\x03\x12\x03\x05/0\n\x0b\n\x04\x04\0\x08\x02\x12\x03\x06\x048\n\x0c\n\
|
||||
\x05\x04\0\x08\x02\x01\x12\x03\x06\n\x1c\n\x0b\n\x04\x04\0\x02\x03\x12\
|
||||
\x03\x06\x1f6\n\x0c\n\x05\x04\0\x02\x03\x05\x12\x03\x06\x1f%\n\x0c\n\x05\
|
||||
\x04\0\x02\x03\x01\x12\x03\x06&1\n\x0c\n\x05\x04\0\x02\x03\x03\x12\x03\
|
||||
\x0645\n\x0b\n\x04\x04\0\x08\x03\x12\x03\x07\x044\n\x0c\n\x05\x04\0\x08\
|
||||
\x03\x01\x12\x03\x07\n\x1b\n\x0b\n\x04\x04\0\x02\x04\x12\x03\x07\x1e2\n\
|
||||
\x0c\n\x05\x04\0\x02\x04\x05\x12\x03\x07\x1e\"\n\x0c\n\x05\x04\0\x02\x04\
|
||||
\x01\x12\x03\x07#-\n\x0c\n\x05\x04\0\x02\x04\x03\x12\x03\x0701b\x06proto\
|
||||
3\
|
||||
";
|
||||
|
||||
static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;
|
||||
|
@ -7,6 +7,3 @@ message KeyValue {
|
||||
oneof one_of_float_value { double float_value = 4; };
|
||||
oneof one_of_bool_value { bool bool_value = 5; };
|
||||
}
|
||||
message KeyValueQuery {
|
||||
string key = 1;
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ flowy-dispatch = { path = "../flowy-dispatch", features = ["use_tracing"]}
|
||||
flowy-log = { path = "../flowy-log" }
|
||||
#flowy-log = { path = "../flowy-log", features = ["use_bunyan"] }
|
||||
flowy-user = { path = "../flowy-user" }
|
||||
flowy-infra = { path = "../flowy-infra" }
|
||||
tracing = { version = "0.1" }
|
||||
log = "0.4.14"
|
||||
|
||||
|
@ -10,7 +10,9 @@ impl FlowySDK {
|
||||
pub fn init_log(directory: &str) { flowy_log::init_log("flowy", directory, "Debug").unwrap(); }
|
||||
|
||||
pub fn init(path: &str) {
|
||||
tracing::trace!("🔥 Root path: {}", path);
|
||||
tracing::info!("🔥 Root path: {}", path);
|
||||
|
||||
flowy_infra::kv::KVStore::init(path);
|
||||
|
||||
let config = ModuleConfig {
|
||||
root: path.to_string(),
|
||||
|
@ -2,7 +2,6 @@ mod database;
|
||||
#[allow(deprecated, clippy::large_enum_variant)]
|
||||
mod errors;
|
||||
mod pool;
|
||||
|
||||
pub use database::*;
|
||||
pub use pool::*;
|
||||
|
||||
|
@ -1 +0,0 @@
|
||||
|
@ -110,6 +110,9 @@ impl EventTester {
|
||||
R: FromBytes,
|
||||
{
|
||||
let response = self.response.unwrap();
|
||||
if response.status_code == StatusCode::Err {
|
||||
dbg!(&response);
|
||||
}
|
||||
<Data<R>>::try_from(response.payload).unwrap().into_inner()
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,3 @@
|
||||
|
||||
proto_crates = ["src/domain"]
|
||||
proto_crates = ["src/entities", "src/event.rs"]
|
||||
event_files = ["src/event.rs"]
|
@ -1,3 +0,0 @@
|
||||
pub use user::*;
|
||||
pub mod tables;
|
||||
pub mod user;
|
@ -1,11 +1,15 @@
|
||||
mod sign_in;
|
||||
mod sign_up;
|
||||
mod user_email;
|
||||
mod user_id;
|
||||
mod user_name;
|
||||
mod user_password;
|
||||
mod user_status;
|
||||
|
||||
pub use sign_in::*;
|
||||
pub use sign_up::*;
|
||||
pub use user_email::*;
|
||||
pub use user_id::*;
|
||||
pub use user_name::*;
|
||||
pub use user_password::*;
|
||||
pub use user_status::*;
|
@ -1,4 +1,4 @@
|
||||
use crate::domain::{UserEmail, UserPassword};
|
||||
use crate::entities::{UserEmail, UserPassword};
|
||||
use flowy_derive::ProtoBuf;
|
||||
use std::convert::TryInto;
|
||||
|
||||
@ -33,13 +33,3 @@ impl TryInto<SignInParams> for SignInRequest {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(ProtoBuf, Default, Debug)]
|
||||
pub struct SignInResponse {
|
||||
#[pb(index = 1)]
|
||||
pub is_success: bool,
|
||||
}
|
||||
|
||||
impl SignInResponse {
|
||||
pub fn new(is_success: bool) -> Self { Self { is_success } }
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
use crate::domain::{UserEmail, UserName, UserPassword};
|
||||
use crate::entities::{UserEmail, UserName, UserPassword};
|
||||
use flowy_derive::ProtoBuf;
|
||||
use std::convert::TryInto;
|
||||
|
16
rust-lib/flowy-user/src/entities/user_id.rs
Normal file
16
rust-lib/flowy-user/src/entities/user_id.rs
Normal file
@ -0,0 +1,16 @@
|
||||
#[derive(Debug)]
|
||||
pub struct UserId(pub String);
|
||||
|
||||
impl UserId {
|
||||
pub fn parse(s: String) -> Result<UserId, String> {
|
||||
let is_empty_or_whitespace = s.trim().is_empty();
|
||||
if is_empty_or_whitespace {
|
||||
return Err(format!("user id is empty or whitespace"));
|
||||
}
|
||||
Ok(Self(s))
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<str> for UserId {
|
||||
fn as_ref(&self) -> &str { &self.0 }
|
||||
}
|
35
rust-lib/flowy-user/src/entities/user_status.rs
Normal file
35
rust-lib/flowy-user/src/entities/user_status.rs
Normal file
@ -0,0 +1,35 @@
|
||||
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
|
||||
|
||||
#[derive(Debug, ProtoBuf_Enum)]
|
||||
pub enum UserStatus {
|
||||
Unknown = 0,
|
||||
Login = 1,
|
||||
Expired = 2,
|
||||
}
|
||||
|
||||
impl std::default::Default for UserStatus {
|
||||
fn default() -> Self { UserStatus::Unknown }
|
||||
}
|
||||
|
||||
#[derive(ProtoBuf, Default, Debug)]
|
||||
pub struct UserDetail {
|
||||
#[pb(index = 1)]
|
||||
pub email: String,
|
||||
|
||||
#[pb(index = 2)]
|
||||
pub name: String,
|
||||
|
||||
#[pb(index = 3)]
|
||||
pub status: UserStatus,
|
||||
}
|
||||
|
||||
use crate::sql_tables::User;
|
||||
impl std::convert::From<User> for UserDetail {
|
||||
fn from(user: User) -> Self {
|
||||
UserDetail {
|
||||
email: user.email,
|
||||
name: user.name,
|
||||
status: UserStatus::Login,
|
||||
}
|
||||
}
|
||||
}
|
@ -3,13 +3,13 @@ use flowy_derive::{Flowy_Event, ProtoBuf_Enum};
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug, Display, Hash, ProtoBuf_Enum, Flowy_Event)]
|
||||
pub enum UserEvent {
|
||||
#[display(fmt = "AuthCheck")]
|
||||
AuthCheck = 0,
|
||||
#[display(fmt = "GetStatus")]
|
||||
GetStatus = 0,
|
||||
#[display(fmt = "SignIn")]
|
||||
#[event(input = "SignInRequest", output = "SignInResponse")]
|
||||
#[event(input = "SignInRequest", output = "UserDetail")]
|
||||
SignIn = 1,
|
||||
#[display(fmt = "SignUp")]
|
||||
#[event(input = "SignUpRequest", output = "SignUpResponse")]
|
||||
#[event(input = "SignUpRequest", output = "UserDetail")]
|
||||
SignUp = 2,
|
||||
#[display(fmt = "SignOut")]
|
||||
SignOut = 3,
|
||||
|
@ -1,20 +1,23 @@
|
||||
use crate::{domain::user::*, services::user_session::UserSession};
|
||||
use crate::{entities::*, services::user_session::UserSession};
|
||||
use flowy_dispatch::prelude::*;
|
||||
use std::{convert::TryInto, sync::Arc};
|
||||
|
||||
// tracing instrument 👉🏻 https://docs.rs/tracing/0.1.26/tracing/attr.instrument.html
|
||||
#[tracing::instrument(
|
||||
name = "user_sign_in",
|
||||
skip(data),
|
||||
skip(data, session),
|
||||
fields(
|
||||
email = %data.email,
|
||||
)
|
||||
)]
|
||||
pub async fn user_sign_in(data: Data<SignInRequest>) -> ResponseResult<SignInResponse, String> {
|
||||
let _params: SignInParams = data.into_inner().try_into()?;
|
||||
// TODO: user sign in
|
||||
let response = SignInResponse::new(true);
|
||||
response_ok(response)
|
||||
pub async fn user_sign_in(
|
||||
data: Data<SignInRequest>,
|
||||
session: ModuleData<Arc<UserSession>>,
|
||||
) -> ResponseResult<UserDetail, String> {
|
||||
let params: SignInParams = data.into_inner().try_into()?;
|
||||
let user = session.sign_in(params).await?;
|
||||
let user_detail = UserDetail::from(user);
|
||||
response_ok(user_detail)
|
||||
}
|
||||
|
||||
#[tracing::instrument(
|
||||
@ -28,12 +31,17 @@ pub async fn user_sign_in(data: Data<SignInRequest>) -> ResponseResult<SignInRes
|
||||
pub async fn user_sign_up(
|
||||
data: Data<SignUpRequest>,
|
||||
session: ModuleData<Arc<UserSession>>,
|
||||
) -> ResponseResult<SignUpResponse, String> {
|
||||
) -> ResponseResult<UserDetail, String> {
|
||||
let params: SignUpParams = data.into_inner().try_into()?;
|
||||
// TODO: user sign up
|
||||
|
||||
let _user = session.sign_up(params)?;
|
||||
|
||||
let fake_resp = SignUpResponse::new(true);
|
||||
response_ok(fake_resp)
|
||||
let user = session.sign_up(params).await?;
|
||||
let user_detail = UserDetail::from(user);
|
||||
response_ok(user_detail)
|
||||
}
|
||||
|
||||
pub async fn user_get_status(
|
||||
user_id: String,
|
||||
session: ModuleData<Arc<UserSession>>,
|
||||
) -> ResponseResult<UserDetail, String> {
|
||||
let user_detail = session.get_user_status(&user_id).await?;
|
||||
response_ok(user_detail)
|
||||
}
|
||||
|
@ -1,14 +1,15 @@
|
||||
mod domain;
|
||||
pub mod entities;
|
||||
mod errors;
|
||||
pub mod event;
|
||||
mod handlers;
|
||||
pub mod module;
|
||||
mod protobuf;
|
||||
mod services;
|
||||
pub mod sql_tables;
|
||||
|
||||
#[macro_use]
|
||||
extern crate flowy_database;
|
||||
|
||||
pub mod prelude {
|
||||
pub use crate::{domain::*, handlers::auth::*, services::user_session::*};
|
||||
pub use crate::{entities::*, handlers::auth::*, services::user_session::*};
|
||||
}
|
||||
|
@ -9,4 +9,5 @@ pub fn create(user_session: Arc<UserSession>) -> Module {
|
||||
.data(user_session)
|
||||
.event(UserEvent::SignIn, user_sign_in)
|
||||
.event(UserEvent::SignUp, user_sign_up)
|
||||
.event(UserEvent::GetStatus, user_get_status)
|
||||
}
|
||||
|
@ -25,7 +25,7 @@
|
||||
|
||||
#[derive(Clone,PartialEq,Eq,Debug,Hash)]
|
||||
pub enum UserEvent {
|
||||
AuthCheck = 0,
|
||||
GetStatus = 0,
|
||||
SignIn = 1,
|
||||
SignUp = 2,
|
||||
SignOut = 3,
|
||||
@ -38,7 +38,7 @@ impl ::protobuf::ProtobufEnum for UserEvent {
|
||||
|
||||
fn from_i32(value: i32) -> ::std::option::Option<UserEvent> {
|
||||
match value {
|
||||
0 => ::std::option::Option::Some(UserEvent::AuthCheck),
|
||||
0 => ::std::option::Option::Some(UserEvent::GetStatus),
|
||||
1 => ::std::option::Option::Some(UserEvent::SignIn),
|
||||
2 => ::std::option::Option::Some(UserEvent::SignUp),
|
||||
3 => ::std::option::Option::Some(UserEvent::SignOut),
|
||||
@ -48,7 +48,7 @@ impl ::protobuf::ProtobufEnum for UserEvent {
|
||||
|
||||
fn values() -> &'static [Self] {
|
||||
static values: &'static [UserEvent] = &[
|
||||
UserEvent::AuthCheck,
|
||||
UserEvent::GetStatus,
|
||||
UserEvent::SignIn,
|
||||
UserEvent::SignUp,
|
||||
UserEvent::SignOut,
|
||||
@ -69,7 +69,7 @@ impl ::std::marker::Copy for UserEvent {
|
||||
|
||||
impl ::std::default::Default for UserEvent {
|
||||
fn default() -> Self {
|
||||
UserEvent::AuthCheck
|
||||
UserEvent::GetStatus
|
||||
}
|
||||
}
|
||||
|
||||
@ -80,7 +80,7 @@ impl ::protobuf::reflect::ProtobufValue for UserEvent {
|
||||
}
|
||||
|
||||
static file_descriptor_proto_data: &'static [u8] = b"\
|
||||
\n\x0bevent.proto*?\n\tUserEvent\x12\r\n\tAuthCheck\x10\0\x12\n\n\x06Sig\
|
||||
\n\x0bevent.proto*?\n\tUserEvent\x12\r\n\tGetStatus\x10\0\x12\n\n\x06Sig\
|
||||
nIn\x10\x01\x12\n\n\x06SignUp\x10\x02\x12\x0b\n\x07SignOut\x10\x03J\xce\
|
||||
\x01\n\x06\x12\x04\0\0\x07\x01\n\x08\n\x01\x0c\x12\x03\0\0\x12\n\n\n\x02\
|
||||
\x05\0\x12\x04\x02\0\x07\x01\n\n\n\x03\x05\0\x01\x12\x03\x02\x05\x0e\n\
|
||||
|
@ -1,5 +1,8 @@
|
||||
// Auto-generated, do not edit
|
||||
|
||||
mod user_status;
|
||||
pub use user_status::*;
|
||||
|
||||
mod sign_up;
|
||||
pub use sign_up::*;
|
||||
|
||||
|
@ -425,182 +425,25 @@ impl ::protobuf::reflect::ProtobufValue for SignInParams {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq,Clone,Default)]
|
||||
pub struct SignInResponse {
|
||||
// message fields
|
||||
pub is_success: bool,
|
||||
// special fields
|
||||
pub unknown_fields: ::protobuf::UnknownFields,
|
||||
pub cached_size: ::protobuf::CachedSize,
|
||||
}
|
||||
|
||||
impl<'a> ::std::default::Default for &'a SignInResponse {
|
||||
fn default() -> &'a SignInResponse {
|
||||
<SignInResponse as ::protobuf::Message>::default_instance()
|
||||
}
|
||||
}
|
||||
|
||||
impl SignInResponse {
|
||||
pub fn new() -> SignInResponse {
|
||||
::std::default::Default::default()
|
||||
}
|
||||
|
||||
// bool is_success = 1;
|
||||
|
||||
|
||||
pub fn get_is_success(&self) -> bool {
|
||||
self.is_success
|
||||
}
|
||||
pub fn clear_is_success(&mut self) {
|
||||
self.is_success = false;
|
||||
}
|
||||
|
||||
// Param is passed by value, moved
|
||||
pub fn set_is_success(&mut self, v: bool) {
|
||||
self.is_success = v;
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::Message for SignInResponse {
|
||||
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 => {
|
||||
if wire_type != ::protobuf::wire_format::WireTypeVarint {
|
||||
return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
|
||||
}
|
||||
let tmp = is.read_bool()?;
|
||||
self.is_success = tmp;
|
||||
},
|
||||
_ => {
|
||||
::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
|
||||
},
|
||||
};
|
||||
}
|
||||
::std::result::Result::Ok(())
|
||||
}
|
||||
|
||||
// Compute sizes of nested messages
|
||||
#[allow(unused_variables)]
|
||||
fn compute_size(&self) -> u32 {
|
||||
let mut my_size = 0;
|
||||
if self.is_success != false {
|
||||
my_size += 2;
|
||||
}
|
||||
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.is_success != false {
|
||||
os.write_bool(1, self.is_success)?;
|
||||
}
|
||||
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<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
|
||||
self
|
||||
}
|
||||
|
||||
fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
|
||||
Self::descriptor_static()
|
||||
}
|
||||
|
||||
fn new() -> SignInResponse {
|
||||
SignInResponse::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::ProtobufTypeBool>(
|
||||
"is_success",
|
||||
|m: &SignInResponse| { &m.is_success },
|
||||
|m: &mut SignInResponse| { &mut m.is_success },
|
||||
));
|
||||
::protobuf::reflect::MessageDescriptor::new_pb_name::<SignInResponse>(
|
||||
"SignInResponse",
|
||||
fields,
|
||||
file_descriptor_proto()
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
fn default_instance() -> &'static SignInResponse {
|
||||
static instance: ::protobuf::rt::LazyV2<SignInResponse> = ::protobuf::rt::LazyV2::INIT;
|
||||
instance.get(SignInResponse::new)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::Clear for SignInResponse {
|
||||
fn clear(&mut self) {
|
||||
self.is_success = false;
|
||||
self.unknown_fields.clear();
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::fmt::Debug for SignInResponse {
|
||||
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
|
||||
::protobuf::text_format::fmt(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::reflect::ProtobufValue for SignInResponse {
|
||||
fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
|
||||
::protobuf::reflect::ReflectValueRef::Message(self)
|
||||
}
|
||||
}
|
||||
|
||||
static file_descriptor_proto_data: &'static [u8] = b"\
|
||||
\n\rsign_in.proto\"A\n\rSignInRequest\x12\x14\n\x05email\x18\x01\x20\x01\
|
||||
(\tR\x05email\x12\x1a\n\x08password\x18\x02\x20\x01(\tR\x08password\"@\n\
|
||||
\x0cSignInParams\x12\x14\n\x05email\x18\x01\x20\x01(\tR\x05email\x12\x1a\
|
||||
\n\x08password\x18\x02\x20\x01(\tR\x08password\"/\n\x0eSignInResponse\
|
||||
\x12\x1d\n\nis_success\x18\x01\x20\x01(\x08R\tisSuccessJ\xed\x02\n\x06\
|
||||
\x12\x04\0\0\x0c\x01\n\x08\n\x01\x0c\x12\x03\0\0\x12\n\n\n\x02\x04\0\x12\
|
||||
\x04\x02\0\x05\x01\n\n\n\x03\x04\0\x01\x12\x03\x02\x08\x15\n\x0b\n\x04\
|
||||
\x04\0\x02\0\x12\x03\x03\x04\x15\n\x0c\n\x05\x04\0\x02\0\x05\x12\x03\x03\
|
||||
\x04\n\n\x0c\n\x05\x04\0\x02\0\x01\x12\x03\x03\x0b\x10\n\x0c\n\x05\x04\0\
|
||||
\x02\0\x03\x12\x03\x03\x13\x14\n\x0b\n\x04\x04\0\x02\x01\x12\x03\x04\x04\
|
||||
\x18\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\x13\n\x0c\n\x05\x04\0\x02\x01\x03\x12\x03\
|
||||
\x04\x16\x17\n\n\n\x02\x04\x01\x12\x04\x06\0\t\x01\n\n\n\x03\x04\x01\x01\
|
||||
\x12\x03\x06\x08\x14\n\x0b\n\x04\x04\x01\x02\0\x12\x03\x07\x04\x15\n\x0c\
|
||||
\n\x05\x04\x01\x02\0\x05\x12\x03\x07\x04\n\n\x0c\n\x05\x04\x01\x02\0\x01\
|
||||
\x12\x03\x07\x0b\x10\n\x0c\n\x05\x04\x01\x02\0\x03\x12\x03\x07\x13\x14\n\
|
||||
\x0b\n\x04\x04\x01\x02\x01\x12\x03\x08\x04\x18\n\x0c\n\x05\x04\x01\x02\
|
||||
\x01\x05\x12\x03\x08\x04\n\n\x0c\n\x05\x04\x01\x02\x01\x01\x12\x03\x08\
|
||||
\x0b\x13\n\x0c\n\x05\x04\x01\x02\x01\x03\x12\x03\x08\x16\x17\n\n\n\x02\
|
||||
\x04\x02\x12\x04\n\0\x0c\x01\n\n\n\x03\x04\x02\x01\x12\x03\n\x08\x16\n\
|
||||
\x0b\n\x04\x04\x02\x02\0\x12\x03\x0b\x04\x18\n\x0c\n\x05\x04\x02\x02\0\
|
||||
\x05\x12\x03\x0b\x04\x08\n\x0c\n\x05\x04\x02\x02\0\x01\x12\x03\x0b\t\x13\
|
||||
\n\x0c\n\x05\x04\x02\x02\0\x03\x12\x03\x0b\x16\x17b\x06proto3\
|
||||
\n\x08password\x18\x02\x20\x01(\tR\x08passwordJ\x9e\x02\n\x06\x12\x04\0\
|
||||
\0\t\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\x15\n\x0b\n\x04\x04\0\x02\0\
|
||||
\x12\x03\x03\x04\x15\n\x0c\n\x05\x04\0\x02\0\x05\x12\x03\x03\x04\n\n\x0c\
|
||||
\n\x05\x04\0\x02\0\x01\x12\x03\x03\x0b\x10\n\x0c\n\x05\x04\0\x02\0\x03\
|
||||
\x12\x03\x03\x13\x14\n\x0b\n\x04\x04\0\x02\x01\x12\x03\x04\x04\x18\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\x13\n\x0c\n\x05\x04\0\x02\x01\x03\x12\x03\x04\x16\x17\n\
|
||||
\n\n\x02\x04\x01\x12\x04\x06\0\t\x01\n\n\n\x03\x04\x01\x01\x12\x03\x06\
|
||||
\x08\x14\n\x0b\n\x04\x04\x01\x02\0\x12\x03\x07\x04\x15\n\x0c\n\x05\x04\
|
||||
\x01\x02\0\x05\x12\x03\x07\x04\n\n\x0c\n\x05\x04\x01\x02\0\x01\x12\x03\
|
||||
\x07\x0b\x10\n\x0c\n\x05\x04\x01\x02\0\x03\x12\x03\x07\x13\x14\n\x0b\n\
|
||||
\x04\x04\x01\x02\x01\x12\x03\x08\x04\x18\n\x0c\n\x05\x04\x01\x02\x01\x05\
|
||||
\x12\x03\x08\x04\n\n\x0c\n\x05\x04\x01\x02\x01\x01\x12\x03\x08\x0b\x13\n\
|
||||
\x0c\n\x05\x04\x01\x02\x01\x03\x12\x03\x08\x16\x17b\x06proto3\
|
||||
";
|
||||
|
||||
static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;
|
||||
|
346
rust-lib/flowy-user/src/protobuf/model/user_status.rs
Normal file
346
rust-lib/flowy-user/src/protobuf/model/user_status.rs
Normal file
@ -0,0 +1,346 @@
|
||||
// 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 `user_status.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 UserDetail {
|
||||
// message fields
|
||||
pub email: ::std::string::String,
|
||||
pub name: ::std::string::String,
|
||||
pub status: UserStatus,
|
||||
// special fields
|
||||
pub unknown_fields: ::protobuf::UnknownFields,
|
||||
pub cached_size: ::protobuf::CachedSize,
|
||||
}
|
||||
|
||||
impl<'a> ::std::default::Default for &'a UserDetail {
|
||||
fn default() -> &'a UserDetail {
|
||||
<UserDetail as ::protobuf::Message>::default_instance()
|
||||
}
|
||||
}
|
||||
|
||||
impl UserDetail {
|
||||
pub fn new() -> UserDetail {
|
||||
::std::default::Default::default()
|
||||
}
|
||||
|
||||
// string email = 1;
|
||||
|
||||
|
||||
pub fn get_email(&self) -> &str {
|
||||
&self.email
|
||||
}
|
||||
pub fn clear_email(&mut self) {
|
||||
self.email.clear();
|
||||
}
|
||||
|
||||
// Param is passed by value, moved
|
||||
pub fn set_email(&mut self, v: ::std::string::String) {
|
||||
self.email = v;
|
||||
}
|
||||
|
||||
// Mutable pointer to the field.
|
||||
// If field is not initialized, it is initialized with default value first.
|
||||
pub fn mut_email(&mut self) -> &mut ::std::string::String {
|
||||
&mut self.email
|
||||
}
|
||||
|
||||
// Take field
|
||||
pub fn take_email(&mut self) -> ::std::string::String {
|
||||
::std::mem::replace(&mut self.email, ::std::string::String::new())
|
||||
}
|
||||
|
||||
// string name = 2;
|
||||
|
||||
|
||||
pub fn get_name(&self) -> &str {
|
||||
&self.name
|
||||
}
|
||||
pub fn clear_name(&mut self) {
|
||||
self.name.clear();
|
||||
}
|
||||
|
||||
// Param is passed by value, moved
|
||||
pub fn set_name(&mut self, v: ::std::string::String) {
|
||||
self.name = v;
|
||||
}
|
||||
|
||||
// Mutable pointer to the field.
|
||||
// If field is not initialized, it is initialized with default value first.
|
||||
pub fn mut_name(&mut self) -> &mut ::std::string::String {
|
||||
&mut self.name
|
||||
}
|
||||
|
||||
// Take field
|
||||
pub fn take_name(&mut self) -> ::std::string::String {
|
||||
::std::mem::replace(&mut self.name, ::std::string::String::new())
|
||||
}
|
||||
|
||||
// .UserStatus status = 3;
|
||||
|
||||
|
||||
pub fn get_status(&self) -> UserStatus {
|
||||
self.status
|
||||
}
|
||||
pub fn clear_status(&mut self) {
|
||||
self.status = UserStatus::Unknown;
|
||||
}
|
||||
|
||||
// Param is passed by value, moved
|
||||
pub fn set_status(&mut self, v: UserStatus) {
|
||||
self.status = v;
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::Message for UserDetail {
|
||||
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.email)?;
|
||||
},
|
||||
2 => {
|
||||
::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.name)?;
|
||||
},
|
||||
3 => {
|
||||
::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.status, 3, &mut self.unknown_fields)?
|
||||
},
|
||||
_ => {
|
||||
::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.email.is_empty() {
|
||||
my_size += ::protobuf::rt::string_size(1, &self.email);
|
||||
}
|
||||
if !self.name.is_empty() {
|
||||
my_size += ::protobuf::rt::string_size(2, &self.name);
|
||||
}
|
||||
if self.status != UserStatus::Unknown {
|
||||
my_size += ::protobuf::rt::enum_size(3, self.status);
|
||||
}
|
||||
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.email.is_empty() {
|
||||
os.write_string(1, &self.email)?;
|
||||
}
|
||||
if !self.name.is_empty() {
|
||||
os.write_string(2, &self.name)?;
|
||||
}
|
||||
if self.status != UserStatus::Unknown {
|
||||
os.write_enum(3, ::protobuf::ProtobufEnum::value(&self.status))?;
|
||||
}
|
||||
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<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
|
||||
self
|
||||
}
|
||||
|
||||
fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
|
||||
Self::descriptor_static()
|
||||
}
|
||||
|
||||
fn new() -> UserDetail {
|
||||
UserDetail::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>(
|
||||
"email",
|
||||
|m: &UserDetail| { &m.email },
|
||||
|m: &mut UserDetail| { &mut m.email },
|
||||
));
|
||||
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
|
||||
"name",
|
||||
|m: &UserDetail| { &m.name },
|
||||
|m: &mut UserDetail| { &mut m.name },
|
||||
));
|
||||
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum<UserStatus>>(
|
||||
"status",
|
||||
|m: &UserDetail| { &m.status },
|
||||
|m: &mut UserDetail| { &mut m.status },
|
||||
));
|
||||
::protobuf::reflect::MessageDescriptor::new_pb_name::<UserDetail>(
|
||||
"UserDetail",
|
||||
fields,
|
||||
file_descriptor_proto()
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
fn default_instance() -> &'static UserDetail {
|
||||
static instance: ::protobuf::rt::LazyV2<UserDetail> = ::protobuf::rt::LazyV2::INIT;
|
||||
instance.get(UserDetail::new)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::Clear for UserDetail {
|
||||
fn clear(&mut self) {
|
||||
self.email.clear();
|
||||
self.name.clear();
|
||||
self.status = UserStatus::Unknown;
|
||||
self.unknown_fields.clear();
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::fmt::Debug for UserDetail {
|
||||
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
|
||||
::protobuf::text_format::fmt(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::reflect::ProtobufValue for UserDetail {
|
||||
fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
|
||||
::protobuf::reflect::ReflectValueRef::Message(self)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone,PartialEq,Eq,Debug,Hash)]
|
||||
pub enum UserStatus {
|
||||
Unknown = 0,
|
||||
Login = 1,
|
||||
Expired = 2,
|
||||
}
|
||||
|
||||
impl ::protobuf::ProtobufEnum for UserStatus {
|
||||
fn value(&self) -> i32 {
|
||||
*self as i32
|
||||
}
|
||||
|
||||
fn from_i32(value: i32) -> ::std::option::Option<UserStatus> {
|
||||
match value {
|
||||
0 => ::std::option::Option::Some(UserStatus::Unknown),
|
||||
1 => ::std::option::Option::Some(UserStatus::Login),
|
||||
2 => ::std::option::Option::Some(UserStatus::Expired),
|
||||
_ => ::std::option::Option::None
|
||||
}
|
||||
}
|
||||
|
||||
fn values() -> &'static [Self] {
|
||||
static values: &'static [UserStatus] = &[
|
||||
UserStatus::Unknown,
|
||||
UserStatus::Login,
|
||||
UserStatus::Expired,
|
||||
];
|
||||
values
|
||||
}
|
||||
|
||||
fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor {
|
||||
static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::EnumDescriptor> = ::protobuf::rt::LazyV2::INIT;
|
||||
descriptor.get(|| {
|
||||
::protobuf::reflect::EnumDescriptor::new_pb_name::<UserStatus>("UserStatus", file_descriptor_proto())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::marker::Copy for UserStatus {
|
||||
}
|
||||
|
||||
impl ::std::default::Default for UserStatus {
|
||||
fn default() -> Self {
|
||||
UserStatus::Unknown
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::reflect::ProtobufValue for UserStatus {
|
||||
fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
|
||||
::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self))
|
||||
}
|
||||
}
|
||||
|
||||
static file_descriptor_proto_data: &'static [u8] = b"\
|
||||
\n\x11user_status.proto\"[\n\nUserDetail\x12\x14\n\x05email\x18\x01\x20\
|
||||
\x01(\tR\x05email\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12#\n\
|
||||
\x06status\x18\x03\x20\x01(\x0e2\x0b.UserStatusR\x06status*1\n\nUserStat\
|
||||
us\x12\x0b\n\x07Unknown\x10\0\x12\t\n\x05Login\x10\x01\x12\x0b\n\x07Expi\
|
||||
red\x10\x02J\xe2\x02\n\x06\x12\x04\0\0\x0b\x01\n\x08\n\x01\x0c\x12\x03\0\
|
||||
\0\x12\n\n\n\x02\x04\0\x12\x04\x02\0\x06\x01\n\n\n\x03\x04\0\x01\x12\x03\
|
||||
\x02\x08\x12\n\x0b\n\x04\x04\0\x02\0\x12\x03\x03\x04\x15\n\x0c\n\x05\x04\
|
||||
\0\x02\0\x05\x12\x03\x03\x04\n\n\x0c\n\x05\x04\0\x02\0\x01\x12\x03\x03\
|
||||
\x0b\x10\n\x0c\n\x05\x04\0\x02\0\x03\x12\x03\x03\x13\x14\n\x0b\n\x04\x04\
|
||||
\0\x02\x01\x12\x03\x04\x04\x14\n\x0c\n\x05\x04\0\x02\x01\x05\x12\x03\x04\
|
||||
\x04\n\n\x0c\n\x05\x04\0\x02\x01\x01\x12\x03\x04\x0b\x0f\n\x0c\n\x05\x04\
|
||||
\0\x02\x01\x03\x12\x03\x04\x12\x13\n\x0b\n\x04\x04\0\x02\x02\x12\x03\x05\
|
||||
\x04\x1a\n\x0c\n\x05\x04\0\x02\x02\x06\x12\x03\x05\x04\x0e\n\x0c\n\x05\
|
||||
\x04\0\x02\x02\x01\x12\x03\x05\x0f\x15\n\x0c\n\x05\x04\0\x02\x02\x03\x12\
|
||||
\x03\x05\x18\x19\n\n\n\x02\x05\0\x12\x04\x07\0\x0b\x01\n\n\n\x03\x05\0\
|
||||
\x01\x12\x03\x07\x05\x0f\n\x0b\n\x04\x05\0\x02\0\x12\x03\x08\x04\x10\n\
|
||||
\x0c\n\x05\x05\0\x02\0\x01\x12\x03\x08\x04\x0b\n\x0c\n\x05\x05\0\x02\0\
|
||||
\x02\x12\x03\x08\x0e\x0f\n\x0b\n\x04\x05\0\x02\x01\x12\x03\t\x04\x0e\n\
|
||||
\x0c\n\x05\x05\0\x02\x01\x01\x12\x03\t\x04\t\n\x0c\n\x05\x05\0\x02\x01\
|
||||
\x02\x12\x03\t\x0c\r\n\x0b\n\x04\x05\0\x02\x02\x12\x03\n\x04\x10\n\x0c\n\
|
||||
\x05\x05\0\x02\x02\x01\x12\x03\n\x04\x0b\n\x0c\n\x05\x05\0\x02\x02\x02\
|
||||
\x12\x03\n\x0e\x0fb\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()
|
||||
})
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
syntax = "proto3";
|
||||
|
||||
enum UserEvent {
|
||||
AuthCheck = 0;
|
||||
GetStatus = 0;
|
||||
SignIn = 1;
|
||||
SignUp = 2;
|
||||
SignOut = 3;
|
||||
|
@ -8,6 +8,3 @@ message SignInParams {
|
||||
string email = 1;
|
||||
string password = 2;
|
||||
}
|
||||
message SignInResponse {
|
||||
bool is_success = 1;
|
||||
}
|
||||
|
12
rust-lib/flowy-user/src/protobuf/proto/user_status.proto
Normal file
12
rust-lib/flowy-user/src/protobuf/proto/user_status.proto
Normal file
@ -0,0 +1,12 @@
|
||||
syntax = "proto3";
|
||||
|
||||
message UserDetail {
|
||||
string email = 1;
|
||||
string name = 2;
|
||||
UserStatus status = 3;
|
||||
}
|
||||
enum UserStatus {
|
||||
Unknown = 0;
|
||||
Login = 1;
|
||||
Expired = 2;
|
||||
}
|
@ -1,3 +1 @@
|
||||
pub mod database;
|
||||
mod register;
|
||||
pub mod user_session;
|
||||
|
@ -1,22 +0,0 @@
|
||||
use crate::{
|
||||
domain::{tables::User, SignUpParams},
|
||||
errors::UserError,
|
||||
};
|
||||
|
||||
pub trait UserRegister {
|
||||
fn register_user(&self, params: SignUpParams) -> Result<User, UserError>;
|
||||
}
|
||||
|
||||
pub struct MockUserRegister {}
|
||||
|
||||
impl UserRegister for MockUserRegister {
|
||||
fn register_user(&self, params: SignUpParams) -> Result<User, UserError> {
|
||||
let user_id = "9527".to_owned();
|
||||
Ok(User::new(
|
||||
user_id,
|
||||
params.name,
|
||||
params.email,
|
||||
params.password,
|
||||
))
|
||||
}
|
||||
}
|
@ -1,7 +1,4 @@
|
||||
use crate::services::{
|
||||
register::MockUserRegister,
|
||||
user_session::{UserSession, UserSessionConfig},
|
||||
};
|
||||
use crate::services::user_session::{register::MockUserServer, UserSession, UserSessionConfig};
|
||||
|
||||
pub struct UserSessionBuilder {
|
||||
config: Option<UserSessionConfig>,
|
||||
@ -17,7 +14,7 @@ impl UserSessionBuilder {
|
||||
|
||||
pub fn build(mut self) -> UserSession {
|
||||
let config = self.config.take().unwrap();
|
||||
let register = MockUserRegister {};
|
||||
let register = MockUserServer {};
|
||||
UserSession::new(config, register)
|
||||
}
|
||||
}
|
||||
|
@ -9,18 +9,6 @@ use std::{
|
||||
},
|
||||
};
|
||||
|
||||
thread_local! {
|
||||
static USER_ID: RefCell<Option<String>> = RefCell::new(None);
|
||||
}
|
||||
fn set_user_id(user_id: Option<String>) {
|
||||
USER_ID.with(|id| {
|
||||
*id.borrow_mut() = user_id;
|
||||
});
|
||||
}
|
||||
fn get_user_id() -> Option<String> { USER_ID.with(|id| id.borrow().clone()) }
|
||||
|
||||
static IS_USER_DB_INIT: AtomicBool = AtomicBool::new(false);
|
||||
|
||||
lazy_static! {
|
||||
static ref DB: RwLock<Option<Database>> = RwLock::new(None);
|
||||
}
|
||||
@ -37,8 +25,10 @@ impl UserDB {
|
||||
}
|
||||
|
||||
fn open_user_db(&self, user_id: &str) -> Result<(), UserError> {
|
||||
INIT_FLAG.store(true, Ordering::SeqCst);
|
||||
let dir = format!("{}/{}", self.db_dir, user_id);
|
||||
let db = flowy_database::init(&dir).map_err(|e| UserError::Database(format!("{:?}", e)))?;
|
||||
let db =
|
||||
flowy_database::init(&dir).map_err(|e| UserError::Database(format!("😁{:?}", e)))?;
|
||||
|
||||
let mut user_db = DB
|
||||
.write()
|
||||
@ -46,33 +36,36 @@ impl UserDB {
|
||||
*(user_db) = Some(db);
|
||||
|
||||
set_user_id(Some(user_id.to_owned()));
|
||||
IS_USER_DB_INIT.store(true, Ordering::SeqCst);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn close_user_db(&mut self) -> Result<(), UserError> {
|
||||
INIT_FLAG.store(false, Ordering::SeqCst);
|
||||
|
||||
let mut write_guard = DB
|
||||
.write()
|
||||
.map_err(|e| UserError::Database(format!("Close user db failed. {:?}", e)))?;
|
||||
*write_guard = None;
|
||||
set_user_id(None);
|
||||
IS_USER_DB_INIT.store(false, Ordering::SeqCst);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn get_connection(&self, user_id: &str) -> Result<DBConnection, UserError> {
|
||||
if !IS_USER_DB_INIT.load(Ordering::SeqCst) {
|
||||
if !INIT_FLAG.load(Ordering::SeqCst) {
|
||||
let _ = self.open_user_db(user_id);
|
||||
}
|
||||
|
||||
let thread_user_id = get_user_id();
|
||||
if thread_user_id != Some(user_id.to_owned()) {
|
||||
let msg = format!(
|
||||
"Database owner does not match. origin: {:?}, current: {}",
|
||||
thread_user_id, user_id
|
||||
);
|
||||
log::error!("{}", msg);
|
||||
return Err(UserError::Database(msg));
|
||||
if thread_user_id.is_some() {
|
||||
if thread_user_id != Some(user_id.to_owned()) {
|
||||
let msg = format!(
|
||||
"Database owner does not match. origin: {:?}, current: {}",
|
||||
thread_user_id, user_id
|
||||
);
|
||||
log::error!("{}", msg);
|
||||
return Err(UserError::Database(msg));
|
||||
}
|
||||
}
|
||||
|
||||
let read_guard = DB
|
||||
@ -87,6 +80,18 @@ impl UserDB {
|
||||
}
|
||||
}
|
||||
|
||||
thread_local! {
|
||||
static USER_ID: RefCell<Option<String>> = RefCell::new(None);
|
||||
}
|
||||
fn set_user_id(user_id: Option<String>) {
|
||||
USER_ID.with(|id| {
|
||||
*id.borrow_mut() = user_id;
|
||||
});
|
||||
}
|
||||
fn get_user_id() -> Option<String> { USER_ID.with(|id| id.borrow().clone()) }
|
||||
|
||||
static INIT_FLAG: AtomicBool = AtomicBool::new(false);
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
@ -1,5 +1,7 @@
|
||||
mod builder;
|
||||
mod user_session;
|
||||
|
||||
pub use builder::*;
|
||||
pub use user_session::*;
|
||||
|
||||
mod builder;
|
||||
pub mod database;
|
||||
mod register;
|
||||
mod user_session;
|
||||
|
67
rust-lib/flowy-user/src/services/user_session/register.rs
Normal file
67
rust-lib/flowy-user/src/services/user_session/register.rs
Normal file
@ -0,0 +1,67 @@
|
||||
use std::sync::RwLock;
|
||||
|
||||
use lazy_static::lazy_static;
|
||||
|
||||
use flowy_infra::kv::KVStore;
|
||||
|
||||
use crate::{
|
||||
entities::{SignInParams, SignUpParams},
|
||||
errors::UserError,
|
||||
sql_tables::User,
|
||||
};
|
||||
|
||||
lazy_static! {
|
||||
pub static ref CURRENT_USER_ID: RwLock<Option<String>> = RwLock::new(None);
|
||||
}
|
||||
const USER_ID: &str = "user_id";
|
||||
pub(crate) fn get_current_user_id() -> Result<Option<String>, UserError> {
|
||||
let read_guard = CURRENT_USER_ID
|
||||
.read()
|
||||
.map_err(|e| UserError::Auth(format!("Read current user id failed. {:?}", e)))?;
|
||||
|
||||
let mut current_user_id = (*read_guard).clone();
|
||||
if current_user_id.is_none() {
|
||||
current_user_id = KVStore::get_str(USER_ID);
|
||||
}
|
||||
|
||||
Ok(current_user_id)
|
||||
}
|
||||
|
||||
pub(crate) fn set_current_user_id(user_id: Option<String>) -> Result<(), UserError> {
|
||||
KVStore::set_str(USER_ID, user_id.clone().unwrap_or("".to_owned()));
|
||||
|
||||
let mut current_user_id = CURRENT_USER_ID
|
||||
.write()
|
||||
.map_err(|e| UserError::Auth(format!("Write current user id failed. {:?}", e)))?;
|
||||
*current_user_id = user_id;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub trait UserServer {
|
||||
fn sign_up(&self, params: SignUpParams) -> Result<User, UserError>;
|
||||
fn sign_in(&self, params: SignInParams) -> Result<User, UserError>;
|
||||
}
|
||||
|
||||
pub struct MockUserServer {}
|
||||
|
||||
impl UserServer for MockUserServer {
|
||||
fn sign_up(&self, params: SignUpParams) -> Result<User, UserError> {
|
||||
let user_id = "9527".to_owned();
|
||||
Ok(User::new(
|
||||
user_id,
|
||||
params.name,
|
||||
params.email,
|
||||
params.password,
|
||||
))
|
||||
}
|
||||
|
||||
fn sign_in(&self, params: SignInParams) -> Result<User, UserError> {
|
||||
let user_id = "9527".to_owned();
|
||||
Ok(User::new(
|
||||
user_id,
|
||||
"".to_owned(),
|
||||
params.email,
|
||||
params.password,
|
||||
))
|
||||
}
|
||||
}
|
@ -1,14 +1,23 @@
|
||||
use crate::{
|
||||
domain::{tables::User, SignUpParams},
|
||||
errors::UserError,
|
||||
services::{database::UserDB, register::UserRegister},
|
||||
use flowy_database::{
|
||||
query_dsl::*,
|
||||
schema::{user_table, user_table::dsl},
|
||||
DBConnection,
|
||||
ExpressionMethods,
|
||||
};
|
||||
use ::diesel::query_dsl::*;
|
||||
use flowy_database::schema::user_table;
|
||||
use flowy_sqlite::DBConnection;
|
||||
use flowy_infra::kv::KVStore;
|
||||
use lazy_static::lazy_static;
|
||||
use std::sync::RwLock;
|
||||
|
||||
use crate::{
|
||||
entities::{SignInParams, SignUpParams, UserDetail, UserId},
|
||||
errors::UserError,
|
||||
services::user_session::{
|
||||
database::UserDB,
|
||||
register::{UserServer, *},
|
||||
},
|
||||
sql_tables::User,
|
||||
};
|
||||
|
||||
pub struct UserSessionConfig {
|
||||
root_dir: String,
|
||||
}
|
||||
@ -24,63 +33,67 @@ impl UserSessionConfig {
|
||||
pub struct UserSession {
|
||||
database: UserDB,
|
||||
config: UserSessionConfig,
|
||||
register: Box<dyn UserRegister + Send + Sync>,
|
||||
server: Box<dyn UserServer + Send + Sync>,
|
||||
}
|
||||
|
||||
impl UserSession {
|
||||
pub fn new<R>(config: UserSessionConfig, register: R) -> Self
|
||||
where
|
||||
R: 'static + UserRegister + Send + Sync,
|
||||
R: 'static + UserServer + Send + Sync,
|
||||
{
|
||||
let db = UserDB::new(&config.root_dir);
|
||||
Self {
|
||||
database: db,
|
||||
config,
|
||||
register: Box::new(register),
|
||||
server: Box::new(register),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn sign_in(&self, params: SignInParams) -> Result<User, UserError> {
|
||||
let user = self.server.sign_in(params)?;
|
||||
let _ = set_current_user_id(Some(user.id.clone()))?;
|
||||
self.save_user(user)
|
||||
}
|
||||
|
||||
pub async fn sign_up(&self, params: SignUpParams) -> Result<User, UserError> {
|
||||
let user = self.server.sign_up(params)?;
|
||||
let _ = set_current_user_id(Some(user.id.clone()))?;
|
||||
self.save_user(user)
|
||||
}
|
||||
|
||||
pub fn sign_out(&self) -> Result<(), UserError> {
|
||||
let _ = set_current_user_id(None)?;
|
||||
// TODO: close the db
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub async fn get_user_status(&self, user_id: &str) -> Result<UserDetail, UserError> {
|
||||
let user_id = UserId::parse(user_id.to_owned()).map_err(|e| UserError::Auth(e))?;
|
||||
let conn = self.get_db_connection()?;
|
||||
|
||||
let user = dsl::user_table
|
||||
.filter(user_table::id.eq(user_id.as_ref()))
|
||||
.first::<User>(&*conn)?;
|
||||
|
||||
// TODO: getting user detail from remote
|
||||
Ok(UserDetail::from(user))
|
||||
}
|
||||
|
||||
pub fn get_db_connection(&self) -> Result<DBConnection, UserError> {
|
||||
match get_current_user_id()? {
|
||||
None => Err(UserError::Auth("User is not login yet".to_owned())),
|
||||
Some(user_id) => self.database.get_connection(&user_id),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sign_up(&self, params: SignUpParams) -> Result<User, UserError> {
|
||||
let user = self.register.register_user(params)?;
|
||||
set_current_user_id(Some(user.id.clone()));
|
||||
|
||||
impl UserSession {
|
||||
fn save_user(&self, user: User) -> Result<User, UserError> {
|
||||
let conn = self.get_db_connection()?;
|
||||
let _ = diesel::insert_into(user_table::table)
|
||||
let result = diesel::insert_into(user_table::table)
|
||||
.values(user.clone())
|
||||
.execute(&*conn)?;
|
||||
|
||||
Ok(user)
|
||||
}
|
||||
|
||||
pub fn sign_out(&self) -> Result<(), UserError> {
|
||||
set_current_user_id(None);
|
||||
// TODO: close the db
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
pub static ref CURRENT_USER_ID: RwLock<Option<String>> = RwLock::new(None);
|
||||
}
|
||||
fn get_current_user_id() -> Result<Option<String>, UserError> {
|
||||
let current_user_id = CURRENT_USER_ID
|
||||
.read()
|
||||
.map_err(|e| UserError::Auth(format!("Read current user id failed. {:?}", e)))?;
|
||||
|
||||
Ok((*current_user_id).clone())
|
||||
}
|
||||
|
||||
pub fn set_current_user_id(user_id: Option<String>) -> Result<(), UserError> {
|
||||
let mut current_user_id = CURRENT_USER_ID
|
||||
.write()
|
||||
.map_err(|e| UserError::Auth(format!("Write current user id failed. {:?}", e)))?;
|
||||
*current_user_id = user_id;
|
||||
Ok(())
|
||||
}
|
||||
|
@ -8,10 +8,10 @@ pub struct User {
|
||||
pub(crate) id: String,
|
||||
|
||||
#[pb(index = 2)]
|
||||
name: String,
|
||||
pub(crate) name: String,
|
||||
|
||||
#[pb(index = 3)]
|
||||
email: String,
|
||||
pub(crate) email: String,
|
||||
|
||||
#[pb(index = 4)]
|
||||
password: String,
|
@ -1,130 +0,0 @@
|
||||
use flowy_test::prelude::*;
|
||||
use flowy_user::{event::UserEvent::*, prelude::*};
|
||||
|
||||
#[test]
|
||||
fn sign_up_success() {
|
||||
let request = SignUpRequest {
|
||||
email: valid_email(),
|
||||
name: valid_name(),
|
||||
password: valid_password(),
|
||||
};
|
||||
|
||||
let _response = EventTester::new(SignUp).request(request).sync_send();
|
||||
// .parse::<SignUpResponse>();
|
||||
// dbg!(&response);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sign_in_success() {
|
||||
let request = SignInRequest {
|
||||
email: valid_email(),
|
||||
password: valid_password(),
|
||||
};
|
||||
|
||||
let response = EventTester::new(SignIn)
|
||||
.request(request)
|
||||
.sync_send()
|
||||
.parse::<SignInResponse>();
|
||||
dbg!(&response);
|
||||
}
|
||||
|
||||
#[test]
|
||||
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(),
|
||||
};
|
||||
|
||||
let _ = EventTester::new(SignUp)
|
||||
.request(request)
|
||||
.assert_error()
|
||||
.sync_send();
|
||||
}
|
||||
}
|
||||
#[test]
|
||||
fn sign_up_with_invalid_password() {
|
||||
for password in invalid_password_test_case() {
|
||||
let request = SignUpRequest {
|
||||
email: valid_email(),
|
||||
name: valid_name(),
|
||||
password,
|
||||
};
|
||||
|
||||
let _ = EventTester::new(SignUp)
|
||||
.request(request)
|
||||
.assert_error()
|
||||
.sync_send();
|
||||
}
|
||||
}
|
||||
#[test]
|
||||
fn sign_in_with_invalid_email() {
|
||||
for email in invalid_email_test_case() {
|
||||
let request = SignInRequest {
|
||||
email: email.to_string(),
|
||||
password: valid_password(),
|
||||
};
|
||||
|
||||
let _ = EventTester::new(SignIn)
|
||||
.request(request)
|
||||
.assert_error()
|
||||
.sync_send();
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sign_in_with_invalid_password() {
|
||||
for password in invalid_password_test_case() {
|
||||
let request = SignInRequest {
|
||||
email: valid_email(),
|
||||
password,
|
||||
};
|
||||
|
||||
let _ = EventTester::new(SignIn)
|
||||
.request(request)
|
||||
.assert_error()
|
||||
.sync_send();
|
||||
}
|
||||
}
|
||||
|
||||
fn invalid_email_test_case() -> Vec<String> {
|
||||
// https://gist.github.com/cjaoude/fd9910626629b53c4d25
|
||||
vec![
|
||||
"",
|
||||
"annie@",
|
||||
"annie@gmail@",
|
||||
"#@%^%#$@#$@#.com",
|
||||
"@example.com",
|
||||
"Joe Smith <email@example.com>",
|
||||
"email.example.com",
|
||||
"email@example@example.com",
|
||||
"email@-example.com",
|
||||
"email@example..com",
|
||||
"あいうえお@example.com",
|
||||
/* The following email is valid according to the validate_email function return
|
||||
* ".email@example.com",
|
||||
* "email.@example.com",
|
||||
* "email..email@example.com",
|
||||
* "email@example",
|
||||
* "email@example.web",
|
||||
* "email@111.222.333.44444",
|
||||
* "Abc..123@example.com", */
|
||||
]
|
||||
.iter()
|
||||
.map(|s| s.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
}
|
||||
|
||||
fn invalid_password_test_case() -> Vec<String> {
|
||||
vec!["", "123456", "1234".repeat(100).as_str()]
|
||||
.iter()
|
||||
.map(|s| s.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
}
|
||||
|
||||
fn valid_email() -> String { "annie@appflowy.io".to_string() }
|
||||
|
||||
fn valid_password() -> String { "HelloWorld!123".to_string() }
|
||||
|
||||
fn valid_name() -> String { "AppFlowy".to_string() }
|
40
rust-lib/flowy-user/tests/event/helper.rs
Normal file
40
rust-lib/flowy-user/tests/event/helper.rs
Normal file
@ -0,0 +1,40 @@
|
||||
pub(crate) fn invalid_email_test_case() -> Vec<String> {
|
||||
// https://gist.github.com/cjaoude/fd9910626629b53c4d25
|
||||
vec![
|
||||
"",
|
||||
"annie@",
|
||||
"annie@gmail@",
|
||||
"#@%^%#$@#$@#.com",
|
||||
"@example.com",
|
||||
"Joe Smith <email@example.com>",
|
||||
"email.example.com",
|
||||
"email@example@example.com",
|
||||
"email@-example.com",
|
||||
"email@example..com",
|
||||
"あいうえお@example.com",
|
||||
/* The following email is valid according to the validate_email function return
|
||||
* ".email@example.com",
|
||||
* "email.@example.com",
|
||||
* "email..email@example.com",
|
||||
* "email@example",
|
||||
* "email@example.web",
|
||||
* "email@111.222.333.44444",
|
||||
* "Abc..123@example.com", */
|
||||
]
|
||||
.iter()
|
||||
.map(|s| s.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
}
|
||||
|
||||
pub(crate) fn invalid_password_test_case() -> Vec<String> {
|
||||
vec!["", "123456", "1234".repeat(100).as_str()]
|
||||
.iter()
|
||||
.map(|s| s.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
}
|
||||
|
||||
pub(crate) fn valid_email() -> String { "annie@appflowy.io".to_string() }
|
||||
|
||||
pub(crate) fn valid_password() -> String { "HelloWorld!123".to_string() }
|
||||
|
||||
pub(crate) fn valid_name() -> String { "AppFlowy".to_string() }
|
4
rust-lib/flowy-user/tests/event/main.rs
Normal file
4
rust-lib/flowy-user/tests/event/main.rs
Normal file
@ -0,0 +1,4 @@
|
||||
mod helper;
|
||||
mod sign_in_test;
|
||||
mod sign_up_test;
|
||||
mod user_status_test;
|
46
rust-lib/flowy-user/tests/event/sign_in_test.rs
Normal file
46
rust-lib/flowy-user/tests/event/sign_in_test.rs
Normal file
@ -0,0 +1,46 @@
|
||||
use crate::helper::*;
|
||||
use flowy_test::prelude::*;
|
||||
use flowy_user::{event::UserEvent::*, prelude::*};
|
||||
#[test]
|
||||
fn sign_in_success() {
|
||||
let request = SignInRequest {
|
||||
email: valid_email(),
|
||||
password: valid_password(),
|
||||
};
|
||||
|
||||
let response = EventTester::new(SignIn)
|
||||
.request(request)
|
||||
.sync_send()
|
||||
.parse::<UserDetail>();
|
||||
dbg!(&response);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sign_in_with_invalid_email() {
|
||||
for email in invalid_email_test_case() {
|
||||
let request = SignInRequest {
|
||||
email: email.to_string(),
|
||||
password: valid_password(),
|
||||
};
|
||||
|
||||
let _ = EventTester::new(SignIn)
|
||||
.request(request)
|
||||
.assert_error()
|
||||
.sync_send();
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sign_in_with_invalid_password() {
|
||||
for password in invalid_password_test_case() {
|
||||
let request = SignInRequest {
|
||||
email: valid_email(),
|
||||
password,
|
||||
};
|
||||
|
||||
let _ = EventTester::new(SignIn)
|
||||
.request(request)
|
||||
.assert_error()
|
||||
.sync_send();
|
||||
}
|
||||
}
|
47
rust-lib/flowy-user/tests/event/sign_up_test.rs
Normal file
47
rust-lib/flowy-user/tests/event/sign_up_test.rs
Normal file
@ -0,0 +1,47 @@
|
||||
use crate::helper::*;
|
||||
use flowy_test::prelude::*;
|
||||
use flowy_user::{event::UserEvent::*, prelude::*};
|
||||
|
||||
#[test]
|
||||
fn sign_up_success() {
|
||||
let request = SignUpRequest {
|
||||
email: valid_email(),
|
||||
name: valid_name(),
|
||||
password: valid_password(),
|
||||
};
|
||||
|
||||
let _response = EventTester::new(SignUp).request(request).sync_send();
|
||||
// .parse::<SignUpResponse>();
|
||||
// dbg!(&response);
|
||||
}
|
||||
|
||||
#[test]
|
||||
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(),
|
||||
};
|
||||
|
||||
let _ = EventTester::new(SignUp)
|
||||
.request(request)
|
||||
.assert_error()
|
||||
.sync_send();
|
||||
}
|
||||
}
|
||||
#[test]
|
||||
fn sign_up_with_invalid_password() {
|
||||
for password in invalid_password_test_case() {
|
||||
let request = SignUpRequest {
|
||||
email: valid_email(),
|
||||
name: valid_name(),
|
||||
password,
|
||||
};
|
||||
|
||||
let _ = EventTester::new(SignUp)
|
||||
.request(request)
|
||||
.assert_error()
|
||||
.sync_send();
|
||||
}
|
||||
}
|
5
rust-lib/flowy-user/tests/event/user_status_test.rs
Normal file
5
rust-lib/flowy-user/tests/event/user_status_test.rs
Normal file
@ -0,0 +1,5 @@
|
||||
use crate::helper::*;
|
||||
use flowy_test::prelude::*;
|
||||
use flowy_user::{event::UserEvent::*, prelude::*};
|
||||
#[test]
|
||||
fn user_status_get_after_login() {}
|
@ -1 +0,0 @@
|
||||
mod auth_test;
|
@ -12,4 +12,8 @@ cargo install cargo-cache
|
||||
|
||||
#protobuf code gen env
|
||||
brew install protobuf@3.13
|
||||
brew tap dart-lang/dart
|
||||
brew install dart
|
||||
pub global activate protoc_plugin
|
||||
|
||||
cargo install --version 2.20.0 protobuf-codegen
|
Loading…
Reference in New Issue
Block a user