mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
save user info to database after sign up
This commit is contained in:
parent
b9d7902acb
commit
55454c5bec
@ -18,6 +18,7 @@
|
|||||||
<sourceFolder url="file://$MODULE_DIR$/rust-lib/flowy-user/tests" isTestSource="true" />
|
<sourceFolder url="file://$MODULE_DIR$/rust-lib/flowy-user/tests" isTestSource="true" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/rust-lib/flowy-database/src" isTestSource="false" />
|
<sourceFolder url="file://$MODULE_DIR$/rust-lib/flowy-database/src" isTestSource="false" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/rust-lib/flowy-sqlite/src" isTestSource="false" />
|
<sourceFolder url="file://$MODULE_DIR$/rust-lib/flowy-sqlite/src" isTestSource="false" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/rust-lib/flowy-infra/src" isTestSource="false" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/app_flowy/packages/af_protobuf/.pub" />
|
<excludeFolder url="file://$MODULE_DIR$/app_flowy/packages/af_protobuf/.pub" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/app_flowy/packages/af_protobuf/.dart_tool" />
|
<excludeFolder url="file://$MODULE_DIR$/app_flowy/packages/af_protobuf/.dart_tool" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/app_flowy/packages/af_protobuf/build" />
|
<excludeFolder url="file://$MODULE_DIR$/app_flowy/packages/af_protobuf/build" />
|
||||||
|
@ -11,19 +11,24 @@ import 'package:protobuf/protobuf.dart' as $pb;
|
|||||||
|
|
||||||
class User extends $pb.GeneratedMessage {
|
class User extends $pb.GeneratedMessage {
|
||||||
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'User', createEmptyInstance: create)
|
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') ? '' : 'name')
|
..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id')
|
||||||
..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'email')
|
..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name')
|
||||||
..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'password')
|
..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'email')
|
||||||
|
..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'password')
|
||||||
..hasRequiredFields = false
|
..hasRequiredFields = false
|
||||||
;
|
;
|
||||||
|
|
||||||
User._() : super();
|
User._() : super();
|
||||||
factory User({
|
factory User({
|
||||||
|
$core.String? id,
|
||||||
$core.String? name,
|
$core.String? name,
|
||||||
$core.String? email,
|
$core.String? email,
|
||||||
$core.String? password,
|
$core.String? password,
|
||||||
}) {
|
}) {
|
||||||
final _result = create();
|
final _result = create();
|
||||||
|
if (id != null) {
|
||||||
|
_result.id = id;
|
||||||
|
}
|
||||||
if (name != null) {
|
if (name != null) {
|
||||||
_result.name = name;
|
_result.name = name;
|
||||||
}
|
}
|
||||||
@ -57,30 +62,39 @@ class User extends $pb.GeneratedMessage {
|
|||||||
static User? _defaultInstance;
|
static User? _defaultInstance;
|
||||||
|
|
||||||
@$pb.TagNumber(1)
|
@$pb.TagNumber(1)
|
||||||
$core.String get name => $_getSZ(0);
|
$core.String get id => $_getSZ(0);
|
||||||
@$pb.TagNumber(1)
|
@$pb.TagNumber(1)
|
||||||
set name($core.String v) { $_setString(0, v); }
|
set id($core.String v) { $_setString(0, v); }
|
||||||
@$pb.TagNumber(1)
|
@$pb.TagNumber(1)
|
||||||
$core.bool hasName() => $_has(0);
|
$core.bool hasId() => $_has(0);
|
||||||
@$pb.TagNumber(1)
|
@$pb.TagNumber(1)
|
||||||
void clearName() => clearField(1);
|
void clearId() => clearField(1);
|
||||||
|
|
||||||
@$pb.TagNumber(2)
|
@$pb.TagNumber(2)
|
||||||
$core.String get email => $_getSZ(1);
|
$core.String get name => $_getSZ(1);
|
||||||
@$pb.TagNumber(2)
|
@$pb.TagNumber(2)
|
||||||
set email($core.String v) { $_setString(1, v); }
|
set name($core.String v) { $_setString(1, v); }
|
||||||
@$pb.TagNumber(2)
|
@$pb.TagNumber(2)
|
||||||
$core.bool hasEmail() => $_has(1);
|
$core.bool hasName() => $_has(1);
|
||||||
@$pb.TagNumber(2)
|
@$pb.TagNumber(2)
|
||||||
void clearEmail() => clearField(2);
|
void clearName() => clearField(2);
|
||||||
|
|
||||||
@$pb.TagNumber(3)
|
@$pb.TagNumber(3)
|
||||||
$core.String get password => $_getSZ(2);
|
$core.String get email => $_getSZ(2);
|
||||||
@$pb.TagNumber(3)
|
@$pb.TagNumber(3)
|
||||||
set password($core.String v) { $_setString(2, v); }
|
set email($core.String v) { $_setString(2, v); }
|
||||||
@$pb.TagNumber(3)
|
@$pb.TagNumber(3)
|
||||||
$core.bool hasPassword() => $_has(2);
|
$core.bool hasEmail() => $_has(2);
|
||||||
@$pb.TagNumber(3)
|
@$pb.TagNumber(3)
|
||||||
void clearPassword() => clearField(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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,9 +9,10 @@ import 'dart:core' as $core;
|
|||||||
const User$json = const {
|
const User$json = const {
|
||||||
'1': 'User',
|
'1': 'User',
|
||||||
'2': const [
|
'2': const [
|
||||||
const {'1': 'name', '3': 1, '4': 1, '5': 9, '10': 'name'},
|
const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'},
|
||||||
const {'1': 'email', '3': 2, '4': 1, '5': 9, '10': 'email'},
|
const {'1': 'name', '3': 2, '4': 1, '5': 9, '10': 'name'},
|
||||||
const {'1': 'password', '3': 3, '4': 1, '5': 9, '10': 'password'},
|
const {'1': 'email', '3': 3, '4': 1, '5': 9, '10': 'email'},
|
||||||
|
const {'1': 'password', '3': 4, '4': 1, '5': 9, '10': 'password'},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -8,8 +8,9 @@ members = [
|
|||||||
"flowy-ast",
|
"flowy-ast",
|
||||||
"flowy-derive",
|
"flowy-derive",
|
||||||
"flowy-test",
|
"flowy-test",
|
||||||
"flowy-sqlite",
|
"flowy-sqlite",
|
||||||
"flowy-database",
|
"flowy-database",
|
||||||
|
"flowy-infra",
|
||||||
]
|
]
|
||||||
|
|
||||||
[profile.dev]
|
[profile.dev]
|
||||||
|
@ -36,8 +36,8 @@ pub extern "C" fn async_command(port: i64, input: *const u8, len: usize) {
|
|||||||
let request: ModuleRequest = FFIRequest::from_u8_pointer(input, len).into();
|
let request: ModuleRequest = FFIRequest::from_u8_pointer(input, len).into();
|
||||||
log::trace!(
|
log::trace!(
|
||||||
"[FFI]: {} Async Event: {:?} with {} port",
|
"[FFI]: {} Async Event: {:?} with {} port",
|
||||||
&request.id(),
|
&request.id,
|
||||||
&request.event(),
|
&request.event,
|
||||||
port
|
port
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -50,11 +50,7 @@ pub extern "C" fn async_command(port: i64, input: *const u8, len: usize) {
|
|||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn sync_command(input: *const u8, len: usize) -> *const u8 {
|
pub extern "C" fn sync_command(input: *const u8, len: usize) -> *const u8 {
|
||||||
let request: ModuleRequest = FFIRequest::from_u8_pointer(input, len).into();
|
let request: ModuleRequest = FFIRequest::from_u8_pointer(input, len).into();
|
||||||
log::trace!(
|
log::trace!("[FFI]: {} Sync Event: {:?}", &request.id, &request.event,);
|
||||||
"[FFI]: {} Sync Event: {:?}",
|
|
||||||
&request.id(),
|
|
||||||
&request.event(),
|
|
||||||
);
|
|
||||||
let _response = EventDispatch::sync_send(request);
|
let _response = EventDispatch::sync_send(request);
|
||||||
|
|
||||||
// FFIResponse { }
|
// FFIResponse { }
|
||||||
|
@ -1,16 +0,0 @@
|
|||||||
use flowy_sqlite::Error;
|
|
||||||
use std::io;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum DataBaseError {
|
|
||||||
InitError(String),
|
|
||||||
IOError(String),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl std::convert::From<flowy_sqlite::Error> for DataBaseError {
|
|
||||||
fn from(error: flowy_sqlite::Error) -> Self { DataBaseError::InitError(format!("{:?}", error)) }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl std::convert::From<io::Error> for DataBaseError {
|
|
||||||
fn from(error: io::Error) -> Self { DataBaseError::IOError(format!("{:?}", error)) }
|
|
||||||
}
|
|
@ -1,29 +1,37 @@
|
|||||||
mod errors;
|
pub mod schema;
|
||||||
mod schema;
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate diesel;
|
extern crate diesel;
|
||||||
|
pub use diesel::*;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate diesel_derives;
|
extern crate diesel_derives;
|
||||||
|
pub use diesel_derives::*;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate diesel_migrations;
|
extern crate diesel_migrations;
|
||||||
|
|
||||||
pub use errors::*;
|
pub use flowy_sqlite::{DBConnection, Database};
|
||||||
pub use flowy_sqlite::{DBConnection, DataBase};
|
|
||||||
|
|
||||||
use diesel_migrations::*;
|
use diesel_migrations::*;
|
||||||
use flowy_sqlite::PoolConfig;
|
use flowy_sqlite::{Error, PoolConfig};
|
||||||
use std::path::Path;
|
use std::{io, path::Path};
|
||||||
|
|
||||||
embed_migrations!("../flowy-database/migrations/");
|
embed_migrations!("../flowy-database/migrations/");
|
||||||
pub const DB_NAME: &str = "flowy-database.db";
|
pub const DB_NAME: &str = "flowy-database.db";
|
||||||
|
|
||||||
pub fn init(storage_path: &str) -> Result<DataBase, DataBaseError> {
|
pub fn init(storage_path: &str) -> Result<Database, io::Error> {
|
||||||
if !Path::new(storage_path).exists() {
|
if !Path::new(storage_path).exists() {
|
||||||
std::fs::create_dir_all(storage_path)?;
|
std::fs::create_dir_all(storage_path)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let pool_config = PoolConfig::default();
|
let pool_config = PoolConfig::default();
|
||||||
let database = DataBase::new(storage_path, DB_NAME, pool_config)?;
|
let database = Database::new(storage_path, DB_NAME, pool_config).map_err(as_io_error)?;
|
||||||
|
let conn = database.get_connection().map_err(as_io_error)?;
|
||||||
|
embedded_migrations::run(&*conn);
|
||||||
Ok(database)
|
Ok(database)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn as_io_error(e: Error) -> io::Error {
|
||||||
|
let msg = format!("{:?}", e);
|
||||||
|
io::Error::new(io::ErrorKind::NotConnected, msg)
|
||||||
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
error::{InternalError, SystemError},
|
errors::{DispatchError, InternalError},
|
||||||
request::{unexpected_none_payload, EventRequest, FromRequest, Payload},
|
request::{unexpected_none_payload, EventRequest, FromRequest, Payload},
|
||||||
response::{EventResponse, Responder, ResponseBuilder, ToBytes},
|
response::{EventResponse, Responder, ResponseBuilder, ToBytes},
|
||||||
util::ready::{ready, Ready},
|
util::ready::{ready, Ready},
|
||||||
@ -53,8 +53,8 @@ impl<T> FromRequest for Data<T>
|
|||||||
where
|
where
|
||||||
T: FromBytes + 'static,
|
T: FromBytes + 'static,
|
||||||
{
|
{
|
||||||
type Error = SystemError;
|
type Error = DispatchError;
|
||||||
type Future = Ready<Result<Self, SystemError>>;
|
type Future = Ready<Result<Self, DispatchError>>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_request(req: &EventRequest, payload: &mut Payload) -> Self::Future {
|
fn from_request(req: &EventRequest, payload: &mut Payload) -> Self::Future {
|
||||||
@ -76,7 +76,7 @@ where
|
|||||||
match self.into_inner().into_bytes() {
|
match self.into_inner().into_bytes() {
|
||||||
Ok(bytes) => ResponseBuilder::Ok().data(bytes.to_vec()).build(),
|
Ok(bytes) => ResponseBuilder::Ok().data(bytes.to_vec()).build(),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
let system_err: SystemError = InternalError::new(format!("{:?}", e)).into();
|
let system_err: DispatchError = InternalError::new(format!("{:?}", e)).into();
|
||||||
system_err.into()
|
system_err.into()
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
error::{Error, InternalError, SystemError},
|
errors::{DispatchError, Error, InternalError},
|
||||||
module::{as_module_map, Module, ModuleMap, ModuleRequest},
|
module::{as_module_map, Module, ModuleMap, ModuleRequest},
|
||||||
response::EventResponse,
|
response::EventResponse,
|
||||||
service::{Service, ServiceFactory},
|
service::{Service, ServiceFactory},
|
||||||
@ -129,7 +129,7 @@ pub(crate) struct DispatchService {
|
|||||||
|
|
||||||
impl Service<DispatchContext> for DispatchService {
|
impl Service<DispatchContext> for DispatchService {
|
||||||
type Response = EventResponse;
|
type Response = EventResponse;
|
||||||
type Error = SystemError;
|
type Error = DispatchError;
|
||||||
type Future = BoxFuture<'static, Result<Self::Response, Self::Error>>;
|
type Future = BoxFuture<'static, Result<Self::Response, Self::Error>>;
|
||||||
|
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
mod error;
|
|
||||||
|
|
||||||
pub use error::*;
|
|
@ -8,45 +8,43 @@ use std::{fmt, option::NoneError};
|
|||||||
use tokio::sync::mpsc::error::SendError;
|
use tokio::sync::mpsc::error::SendError;
|
||||||
|
|
||||||
pub trait Error: fmt::Debug + fmt::Display + DynClone + Send + Sync {
|
pub trait Error: fmt::Debug + fmt::Display + DynClone + Send + Sync {
|
||||||
fn status_code(&self) -> StatusCode;
|
fn as_response(&self) -> EventResponse { EventResponse::new(StatusCode::Err) }
|
||||||
|
|
||||||
fn as_response(&self) -> EventResponse { EventResponse::new(self.status_code()) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dyn_clone::clone_trait_object!(Error);
|
dyn_clone::clone_trait_object!(Error);
|
||||||
|
|
||||||
impl<T: Error + 'static> From<T> for SystemError {
|
impl<T: Error + 'static> From<T> for DispatchError {
|
||||||
fn from(err: T) -> SystemError {
|
fn from(err: T) -> DispatchError {
|
||||||
SystemError {
|
DispatchError {
|
||||||
inner: Box::new(err),
|
inner: Box::new(err),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct SystemError {
|
pub struct DispatchError {
|
||||||
inner: Box<dyn Error>,
|
inner: Box<dyn Error>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SystemError {
|
impl DispatchError {
|
||||||
pub fn inner_error(&self) -> &dyn Error { self.inner.as_ref() }
|
pub fn inner_error(&self) -> &dyn Error { self.inner.as_ref() }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for SystemError {
|
impl fmt::Display for DispatchError {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Display::fmt(&self.inner, f) }
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Display::fmt(&self.inner, f) }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Debug for SystemError {
|
impl fmt::Debug for DispatchError {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{:?}", &self.inner) }
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{:?}", &self.inner) }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::error::Error for SystemError {
|
impl std::error::Error for DispatchError {
|
||||||
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
|
||||||
|
|
||||||
fn cause(&self) -> Option<&dyn std::error::Error> { None }
|
fn cause(&self) -> Option<&dyn std::error::Error> { None }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<SendError<EventRequest>> for SystemError {
|
impl From<SendError<EventRequest>> for DispatchError {
|
||||||
fn from(err: SendError<EventRequest>) -> Self {
|
fn from(err: SendError<EventRequest>) -> Self {
|
||||||
InternalError {
|
InternalError {
|
||||||
inner: format!("{}", err),
|
inner: format!("{}", err),
|
||||||
@ -55,7 +53,7 @@ impl From<SendError<EventRequest>> for SystemError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<NoneError> for SystemError {
|
impl From<NoneError> for DispatchError {
|
||||||
fn from(s: NoneError) -> Self {
|
fn from(s: NoneError) -> Self {
|
||||||
InternalError {
|
InternalError {
|
||||||
inner: format!("Unexpected none: {:?}", s),
|
inner: format!("Unexpected none: {:?}", s),
|
||||||
@ -64,16 +62,16 @@ impl From<NoneError> for SystemError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<String> for SystemError {
|
impl From<String> for DispatchError {
|
||||||
fn from(s: String) -> Self { InternalError { inner: s }.into() }
|
fn from(s: String) -> Self { InternalError { inner: s }.into() }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<SystemError> for EventResponse {
|
impl From<DispatchError> for EventResponse {
|
||||||
fn from(err: SystemError) -> Self { err.inner_error().as_response() }
|
fn from(err: DispatchError) -> Self { err.inner_error().as_response() }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct InternalError<T: Clone> {
|
pub(crate) struct InternalError<T: Clone> {
|
||||||
inner: T,
|
inner: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,8 +97,6 @@ impl<T> Error for InternalError<T>
|
|||||||
where
|
where
|
||||||
T: fmt::Debug + fmt::Display + 'static + Clone + Send + Sync,
|
T: fmt::Debug + fmt::Display + 'static + Clone + Send + Sync,
|
||||||
{
|
{
|
||||||
fn status_code(&self) -> StatusCode { StatusCode::Err }
|
|
||||||
|
|
||||||
fn as_response(&self) -> EventResponse {
|
fn as_response(&self) -> EventResponse {
|
||||||
let error = InternalError {
|
let error = InternalError {
|
||||||
inner: format!("{}", self.inner),
|
inner: format!("{}", self.inner),
|
||||||
@ -111,7 +107,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Serialize for SystemError {
|
impl Serialize for DispatchError {
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
|
||||||
where
|
where
|
||||||
S: Serializer,
|
S: Serializer,
|
3
rust-lib/flowy-dispatch/src/errors/mod.rs
Normal file
3
rust-lib/flowy-dispatch/src/errors/mod.rs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
mod errors;
|
||||||
|
|
||||||
|
pub use errors::*;
|
@ -1,6 +1,6 @@
|
|||||||
#![feature(try_trait)]
|
#![feature(try_trait)]
|
||||||
|
|
||||||
mod error;
|
mod errors;
|
||||||
mod module;
|
mod module;
|
||||||
mod request;
|
mod request;
|
||||||
mod response;
|
mod response;
|
||||||
@ -11,6 +11,8 @@ mod data;
|
|||||||
mod dispatch;
|
mod dispatch;
|
||||||
mod system;
|
mod system;
|
||||||
|
|
||||||
|
pub use errors::Error;
|
||||||
|
|
||||||
pub mod prelude {
|
pub mod prelude {
|
||||||
pub use crate::{data::*, dispatch::*, error::*, module::*, request::*, response::*};
|
pub use crate::{data::*, dispatch::*, errors::*, module::*, request::*, response::*};
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
error::{InternalError, SystemError},
|
errors::{DispatchError, InternalError},
|
||||||
request::{payload::Payload, EventRequest, FromRequest},
|
request::{payload::Payload, EventRequest, FromRequest},
|
||||||
util::ready::{ready, Ready},
|
util::ready::{ready, Ready},
|
||||||
};
|
};
|
||||||
@ -43,15 +43,18 @@ impl<T> FromRequest for ModuleData<T>
|
|||||||
where
|
where
|
||||||
T: ?Sized + Send + Sync + 'static,
|
T: ?Sized + Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
type Error = SystemError;
|
type Error = DispatchError;
|
||||||
type Future = Ready<Result<Self, SystemError>>;
|
type Future = Ready<Result<Self, DispatchError>>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_request(req: &EventRequest, _: &mut Payload) -> Self::Future {
|
fn from_request(req: &EventRequest, _: &mut Payload) -> Self::Future {
|
||||||
if let Some(data) = req.module_data::<ModuleData<T>>() {
|
if let Some(data) = req.module_data::<ModuleData<T>>() {
|
||||||
ready(Ok(data.clone()))
|
ready(Ok(data.clone()))
|
||||||
} else {
|
} else {
|
||||||
let msg = format!("Failed to get the module data(type: {})", type_name::<T>());
|
let msg = format!(
|
||||||
|
"Failed to get the module data of type: {}",
|
||||||
|
type_name::<T>()
|
||||||
|
);
|
||||||
log::error!("{}", msg,);
|
log::error!("{}", msg,);
|
||||||
ready(Err(InternalError::new(msg).into()))
|
ready(Err(InternalError::new(msg).into()))
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ use futures_core::ready;
|
|||||||
use pin_project::pin_project;
|
use pin_project::pin_project;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::{InternalError, SystemError},
|
errors::{DispatchError, InternalError},
|
||||||
module::{container::ModuleDataMap, ModuleData},
|
module::{container::ModuleDataMap, ModuleData},
|
||||||
request::{payload::Payload, EventRequest, FromRequest},
|
request::{payload::Payload, EventRequest, FromRequest},
|
||||||
response::{EventResponse, Responder},
|
response::{EventResponse, Responder},
|
||||||
@ -51,7 +51,8 @@ impl<T: Display + Eq + Hash + Debug + Clone> std::convert::From<T> for Event {
|
|||||||
fn from(t: T) -> Self { Event(format!("{}", t)) }
|
fn from(t: T) -> Self { Event(format!("{}", t)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type EventServiceFactory = BoxServiceFactory<(), ServiceRequest, ServiceResponse, SystemError>;
|
pub type EventServiceFactory =
|
||||||
|
BoxServiceFactory<(), ServiceRequest, ServiceResponse, DispatchError>;
|
||||||
|
|
||||||
pub struct Module {
|
pub struct Module {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
@ -111,8 +112,8 @@ impl Module {
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ModuleRequest {
|
pub struct ModuleRequest {
|
||||||
pub(crate) id: String,
|
pub id: String,
|
||||||
pub(crate) event: Event,
|
pub event: Event,
|
||||||
pub(crate) payload: Payload,
|
pub(crate) payload: Payload,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,7 +146,7 @@ impl std::fmt::Display for ModuleRequest {
|
|||||||
|
|
||||||
impl ServiceFactory<ModuleRequest> for Module {
|
impl ServiceFactory<ModuleRequest> for Module {
|
||||||
type Response = EventResponse;
|
type Response = EventResponse;
|
||||||
type Error = SystemError;
|
type Error = DispatchError;
|
||||||
type Service = BoxService<ModuleRequest, Self::Response, Self::Error>;
|
type Service = BoxService<ModuleRequest, Self::Response, Self::Error>;
|
||||||
type Context = ();
|
type Context = ();
|
||||||
type Future = BoxFuture<'static, Result<Self::Service, Self::Error>>;
|
type Future = BoxFuture<'static, Result<Self::Service, Self::Error>>;
|
||||||
@ -171,7 +172,7 @@ pub struct ModuleService {
|
|||||||
|
|
||||||
impl Service<ModuleRequest> for ModuleService {
|
impl Service<ModuleRequest> for ModuleService {
|
||||||
type Response = EventResponse;
|
type Response = EventResponse;
|
||||||
type Error = SystemError;
|
type Error = DispatchError;
|
||||||
type Future = BoxFuture<'static, Result<Self::Response, Self::Error>>;
|
type Future = BoxFuture<'static, Result<Self::Response, Self::Error>>;
|
||||||
|
|
||||||
fn call(&self, request: ModuleRequest) -> Self::Future {
|
fn call(&self, request: ModuleRequest) -> Self::Future {
|
||||||
@ -196,17 +197,14 @@ impl Service<ModuleRequest> for ModuleService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// type BoxModuleService = BoxService<ServiceRequest, ServiceResponse,
|
|
||||||
// SystemError>;
|
|
||||||
|
|
||||||
#[pin_project]
|
#[pin_project]
|
||||||
pub struct ModuleServiceFuture {
|
pub struct ModuleServiceFuture {
|
||||||
#[pin]
|
#[pin]
|
||||||
fut: BoxFuture<'static, Result<ServiceResponse, SystemError>>,
|
fut: BoxFuture<'static, Result<ServiceResponse, DispatchError>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Future for ModuleServiceFuture {
|
impl Future for ModuleServiceFuture {
|
||||||
type Output = Result<EventResponse, SystemError>;
|
type Output = Result<EventResponse, DispatchError>;
|
||||||
|
|
||||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
loop {
|
loop {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::{InternalError, SystemError},
|
errors::{DispatchError, InternalError},
|
||||||
module::{Event, ModuleDataMap},
|
module::{Event, ModuleDataMap},
|
||||||
request::payload::Payload,
|
request::payload::Payload,
|
||||||
util::ready::{ready, Ready},
|
util::ready::{ready, Ready},
|
||||||
@ -48,7 +48,7 @@ impl EventRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait FromRequest: Sized {
|
pub trait FromRequest: Sized {
|
||||||
type Error: Into<SystemError>;
|
type Error: Into<DispatchError>;
|
||||||
type Future: Future<Output = Result<Self, Self::Error>>;
|
type Future: Future<Output = Result<Self, Self::Error>>;
|
||||||
|
|
||||||
fn from_request(req: &EventRequest, payload: &mut Payload) -> Self::Future;
|
fn from_request(req: &EventRequest, payload: &mut Payload) -> Self::Future;
|
||||||
@ -56,15 +56,15 @@ pub trait FromRequest: Sized {
|
|||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
impl FromRequest for () {
|
impl FromRequest for () {
|
||||||
type Error = SystemError;
|
type Error = DispatchError;
|
||||||
type Future = Ready<Result<(), SystemError>>;
|
type Future = Ready<Result<(), DispatchError>>;
|
||||||
|
|
||||||
fn from_request(_req: &EventRequest, _payload: &mut Payload) -> Self::Future { ready(Ok(())) }
|
fn from_request(_req: &EventRequest, _payload: &mut Payload) -> Self::Future { ready(Ok(())) }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
impl FromRequest for String {
|
impl FromRequest for String {
|
||||||
type Error = SystemError;
|
type Error = DispatchError;
|
||||||
type Future = Ready<Result<Self, Self::Error>>;
|
type Future = Ready<Result<Self, Self::Error>>;
|
||||||
|
|
||||||
fn from_request(req: &EventRequest, payload: &mut Payload) -> Self::Future {
|
fn from_request(req: &EventRequest, payload: &mut Payload) -> Self::Future {
|
||||||
@ -75,7 +75,7 @@ impl FromRequest for String {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unexpected_none_payload(request: &EventRequest) -> SystemError {
|
pub fn unexpected_none_payload(request: &EventRequest) -> DispatchError {
|
||||||
log::warn!("{:?} expected payload", &request.event);
|
log::warn!("{:?} expected payload", &request.event);
|
||||||
InternalError::new("Expected payload").into()
|
InternalError::new("Expected payload").into()
|
||||||
}
|
}
|
||||||
@ -85,7 +85,7 @@ impl<T> FromRequest for Result<T, T::Error>
|
|||||||
where
|
where
|
||||||
T: FromRequest,
|
T: FromRequest,
|
||||||
{
|
{
|
||||||
type Error = SystemError;
|
type Error = DispatchError;
|
||||||
type Future = FromRequestFuture<T::Future>;
|
type Future = FromRequestFuture<T::Future>;
|
||||||
|
|
||||||
fn from_request(req: &EventRequest, payload: &mut Payload) -> Self::Future {
|
fn from_request(req: &EventRequest, payload: &mut Payload) -> Self::Future {
|
||||||
@ -105,7 +105,7 @@ impl<Fut, T, E> Future for FromRequestFuture<Fut>
|
|||||||
where
|
where
|
||||||
Fut: Future<Output = Result<T, E>>,
|
Fut: Future<Output = Result<T, E>>,
|
||||||
{
|
{
|
||||||
type Output = Result<Result<T, E>, SystemError>;
|
type Output = Result<Result<T, E>, DispatchError>;
|
||||||
|
|
||||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
let this = self.project();
|
let this = self.project();
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
error::SystemError,
|
errors::DispatchError,
|
||||||
request::Payload,
|
request::Payload,
|
||||||
response::{EventResponse, StatusCode},
|
response::{EventResponse, StatusCode},
|
||||||
};
|
};
|
||||||
@ -14,7 +14,7 @@ macro_rules! static_response {
|
|||||||
pub struct ResponseBuilder<T = Payload> {
|
pub struct ResponseBuilder<T = Payload> {
|
||||||
pub payload: T,
|
pub payload: T,
|
||||||
pub status: StatusCode,
|
pub status: StatusCode,
|
||||||
pub error: Option<SystemError>,
|
pub error: Option<DispatchError>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ResponseBuilder {
|
impl ResponseBuilder {
|
||||||
@ -31,7 +31,7 @@ impl ResponseBuilder {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn error(mut self, error: SystemError) -> Self {
|
pub fn error(mut self, error: DispatchError) -> Self {
|
||||||
self.error = Some(error);
|
self.error = Some(error);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
use crate::error::{InternalError, SystemError};
|
use crate::errors::{DispatchError, InternalError};
|
||||||
use crate::{
|
use crate::{
|
||||||
request::EventRequest,
|
request::EventRequest,
|
||||||
response::{EventResponse, ResponseBuilder},
|
response::{EventResponse, ResponseBuilder},
|
||||||
@ -28,7 +28,7 @@ impl_responder!(Bytes);
|
|||||||
impl<T, E> Responder for Result<T, E>
|
impl<T, E> Responder for Result<T, E>
|
||||||
where
|
where
|
||||||
T: Responder,
|
T: Responder,
|
||||||
E: Into<SystemError>,
|
E: Into<DispatchError>,
|
||||||
{
|
{
|
||||||
fn respond_to(self, request: &EventRequest) -> EventResponse {
|
fn respond_to(self, request: &EventRequest) -> EventResponse {
|
||||||
match self {
|
match self {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
data::Data,
|
data::Data,
|
||||||
error::SystemError,
|
errors::DispatchError,
|
||||||
request::{EventRequest, Payload},
|
request::{EventRequest, Payload},
|
||||||
response::Responder,
|
response::Responder,
|
||||||
};
|
};
|
||||||
@ -19,7 +19,7 @@ pub struct EventResponse {
|
|||||||
#[derivative(Debug = "ignore")]
|
#[derivative(Debug = "ignore")]
|
||||||
pub payload: Payload,
|
pub payload: Payload,
|
||||||
pub status_code: StatusCode,
|
pub status_code: StatusCode,
|
||||||
pub error: Option<SystemError>,
|
pub error: Option<DispatchError>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EventResponse {
|
impl EventResponse {
|
||||||
@ -58,7 +58,7 @@ pub type ResponseResult<T, E> = std::result::Result<Data<T>, E>;
|
|||||||
|
|
||||||
pub fn response_ok<T, E>(data: T) -> Result<Data<T>, E>
|
pub fn response_ok<T, E>(data: T) -> Result<Data<T>, E>
|
||||||
where
|
where
|
||||||
E: Into<SystemError>,
|
E: Into<DispatchError>,
|
||||||
{
|
{
|
||||||
Ok(Data(data))
|
Ok(Data(data))
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ use futures_core::ready;
|
|||||||
use pin_project::pin_project;
|
use pin_project::pin_project;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::SystemError,
|
errors::DispatchError,
|
||||||
request::{payload::Payload, EventRequest, FromRequest},
|
request::{payload::Payload, EventRequest, FromRequest},
|
||||||
response::{EventResponse, Responder},
|
response::{EventResponse, Responder},
|
||||||
service::{Service, ServiceFactory, ServiceRequest, ServiceResponse},
|
service::{Service, ServiceFactory, ServiceRequest, ServiceResponse},
|
||||||
@ -73,7 +73,7 @@ where
|
|||||||
R::Output: Responder,
|
R::Output: Responder,
|
||||||
{
|
{
|
||||||
type Response = ServiceResponse;
|
type Response = ServiceResponse;
|
||||||
type Error = SystemError;
|
type Error = DispatchError;
|
||||||
type Service = Self;
|
type Service = Self;
|
||||||
type Context = ();
|
type Context = ();
|
||||||
type Future = Ready<Result<Self::Service, Self::Error>>;
|
type Future = Ready<Result<Self::Service, Self::Error>>;
|
||||||
@ -89,7 +89,7 @@ where
|
|||||||
R::Output: Responder,
|
R::Output: Responder,
|
||||||
{
|
{
|
||||||
type Response = ServiceResponse;
|
type Response = ServiceResponse;
|
||||||
type Error = SystemError;
|
type Error = DispatchError;
|
||||||
type Future = HandlerServiceFuture<H, T, R>;
|
type Future = HandlerServiceFuture<H, T, R>;
|
||||||
|
|
||||||
fn call(&self, req: ServiceRequest) -> Self::Future {
|
fn call(&self, req: ServiceRequest) -> Self::Future {
|
||||||
@ -118,7 +118,7 @@ where
|
|||||||
R: Future + Sync + Send,
|
R: Future + Sync + Send,
|
||||||
R::Output: Responder,
|
R::Output: Responder,
|
||||||
{
|
{
|
||||||
type Output = Result<ServiceResponse, SystemError>;
|
type Output = Result<ServiceResponse, DispatchError>;
|
||||||
|
|
||||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
loop {
|
loop {
|
||||||
@ -132,7 +132,7 @@ where
|
|||||||
},
|
},
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
let req = req.take().unwrap();
|
let req = req.take().unwrap();
|
||||||
let system_err: SystemError = err.into();
|
let system_err: DispatchError = err.into();
|
||||||
let res: EventResponse = system_err.into();
|
let res: EventResponse = system_err.into();
|
||||||
return Poll::Ready(Ok(ServiceResponse::new(req, res)));
|
return Poll::Ready(Ok(ServiceResponse::new(req, res)));
|
||||||
},
|
},
|
||||||
@ -175,7 +175,7 @@ macro_rules! tuple_from_req ({$tuple_type:ident, $(($n:tt, $T:ident)),+} => {
|
|||||||
#[allow(unused_parens)]
|
#[allow(unused_parens)]
|
||||||
impl<$($T: FromRequest + 'static),+> FromRequest for ($($T,)+)
|
impl<$($T: FromRequest + 'static),+> FromRequest for ($($T,)+)
|
||||||
{
|
{
|
||||||
type Error = SystemError;
|
type Error = DispatchError;
|
||||||
type Future = $tuple_type<$($T),+>;
|
type Future = $tuple_type<$($T),+>;
|
||||||
|
|
||||||
fn from_request(req: &EventRequest, payload: &mut Payload) -> Self::Future {
|
fn from_request(req: &EventRequest, payload: &mut Payload) -> Self::Future {
|
||||||
@ -196,7 +196,7 @@ macro_rules! tuple_from_req ({$tuple_type:ident, $(($n:tt, $T:ident)),+} => {
|
|||||||
|
|
||||||
impl<$($T: FromRequest),+> Future for $tuple_type<$($T),+>
|
impl<$($T: FromRequest),+> Future for $tuple_type<$($T),+>
|
||||||
{
|
{
|
||||||
type Output = Result<($($T,)+), SystemError>;
|
type Output = Result<($($T,)+), DispatchError>;
|
||||||
|
|
||||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
let mut this = self.project();
|
let mut this = self.project();
|
||||||
|
9
rust-lib/flowy-infra/Cargo.toml
Normal file
9
rust-lib/flowy-infra/Cargo.toml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
[package]
|
||||||
|
name = "flowy-infra"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
uuid = { version = "0.8", features = ["serde", "v4"] }
|
1
rust-lib/flowy-infra/src/lib.rs
Normal file
1
rust-lib/flowy-infra/src/lib.rs
Normal file
@ -0,0 +1 @@
|
|||||||
|
pub fn uuid() -> String { uuid::Uuid::new_v4().to_string() }
|
@ -1,5 +1,5 @@
|
|||||||
use flowy_dispatch::prelude::Module;
|
use flowy_dispatch::prelude::Module;
|
||||||
use flowy_user::prelude::user_session::{UserSession, UserSessionConfig};
|
use flowy_user::prelude::{UserSession, UserSessionBuilder, UserSessionConfig};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
pub struct ModuleConfig {
|
pub struct ModuleConfig {
|
||||||
@ -7,8 +7,6 @@ pub struct ModuleConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_modules(config: ModuleConfig) -> Vec<Module> {
|
pub fn build_modules(config: ModuleConfig) -> Vec<Module> {
|
||||||
let user_config = UserSessionConfig::new(&config.root);
|
let user_session = UserSessionBuilder::new().root_dir(&config.root).build();
|
||||||
let user_session = Arc::new(UserSession::new(user_config));
|
vec![flowy_user::module::create(Arc::new(user_session))]
|
||||||
|
|
||||||
vec![flowy_user::module::create(user_session)]
|
|
||||||
}
|
}
|
||||||
|
@ -4,16 +4,21 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use r2d2::PooledConnection;
|
use r2d2::PooledConnection;
|
||||||
|
|
||||||
pub struct DataBase {
|
pub struct Database {
|
||||||
uri: String,
|
uri: String,
|
||||||
pool: ConnectionPool,
|
pool: ConnectionPool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type DBConnection = PooledConnection<ConnectionManager>;
|
pub type DBConnection = PooledConnection<ConnectionManager>;
|
||||||
|
|
||||||
impl DataBase {
|
impl Database {
|
||||||
pub fn new(dir: &str, name: &str, pool_config: PoolConfig) -> Result<Self> {
|
pub fn new(dir: &str, name: &str, pool_config: PoolConfig) -> Result<Self> {
|
||||||
let uri = db_file_uri(dir, name);
|
let uri = db_file_uri(dir, name);
|
||||||
|
|
||||||
|
if !std::path::PathBuf::from(dir).exists() {
|
||||||
|
log::error!("Create database failed. {} not exists", &dir);
|
||||||
|
}
|
||||||
|
|
||||||
let pool = ConnectionPool::new(pool_config, &uri)?;
|
let pool = ConnectionPool::new(pool_config, &uri)?;
|
||||||
Ok(Self { uri, pool })
|
Ok(Self { uri, pool })
|
||||||
}
|
}
|
||||||
|
@ -115,12 +115,7 @@ impl ManageConnection for ConnectionManager {
|
|||||||
type Connection = SqliteConnection;
|
type Connection = SqliteConnection;
|
||||||
type Error = crate::Error;
|
type Error = crate::Error;
|
||||||
|
|
||||||
fn connect(&self) -> Result<Self::Connection> {
|
fn connect(&self) -> Result<Self::Connection> { Ok(SqliteConnection::establish(&self.db_uri)?) }
|
||||||
if !std::path::PathBuf::from(&self.db_uri).exists() {
|
|
||||||
log::error!("db file not exists");
|
|
||||||
}
|
|
||||||
Ok(SqliteConnection::establish(&self.db_uri)?)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_valid(&self, conn: &mut Self::Connection) -> Result<()> {
|
fn is_valid(&self, conn: &mut Self::Connection) -> Result<()> {
|
||||||
Ok(conn.execute("SELECT 1").map(|_| ())?)
|
Ok(conn.execute("SELECT 1").map(|_| ())?)
|
||||||
|
@ -12,6 +12,7 @@ flowy-log = { path = "../flowy-log" }
|
|||||||
flowy-derive = { path = "../flowy-derive" }
|
flowy-derive = { path = "../flowy-derive" }
|
||||||
flowy-database = { path = "../flowy-database" }
|
flowy-database = { path = "../flowy-database" }
|
||||||
flowy-sqlite = { path = "../flowy-sqlite" }
|
flowy-sqlite = { path = "../flowy-sqlite" }
|
||||||
|
flowy-infra = { path = "../flowy-infra" }
|
||||||
|
|
||||||
tracing = { version = "0.1", features = ["log"] }
|
tracing = { version = "0.1", features = ["log"] }
|
||||||
bytes = "1.0"
|
bytes = "1.0"
|
||||||
@ -23,6 +24,8 @@ log = "0.4.14"
|
|||||||
protobuf = {version = "2.18.0"}
|
protobuf = {version = "2.18.0"}
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
fancy-regex = "0.5.0"
|
fancy-regex = "0.5.0"
|
||||||
|
diesel = {version = "1.4.7", features = ["sqlite"]}
|
||||||
|
diesel_derives = {version = "1.4.1", features = ["sqlite"]}
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
quickcheck = "0.9.2"
|
quickcheck = "0.9.2"
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
pub use user::*;
|
pub use user::*;
|
||||||
|
pub mod tables;
|
||||||
pub mod user;
|
pub mod user;
|
||||||
pub mod user_db;
|
|
||||||
pub mod user_session;
|
|
||||||
|
3
rust-lib/flowy-user/src/domain/tables/mod.rs
Normal file
3
rust-lib/flowy-user/src/domain/tables/mod.rs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
mod user_table;
|
||||||
|
|
||||||
|
pub use user_table::*;
|
30
rust-lib/flowy-user/src/domain/tables/user_table.rs
Normal file
30
rust-lib/flowy-user/src/domain/tables/user_table.rs
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
use crate::domain::{UserEmail, UserName, UserPassword};
|
||||||
|
use flowy_database::schema::user_table;
|
||||||
|
use flowy_derive::ProtoBuf;
|
||||||
|
|
||||||
|
#[derive(ProtoBuf, Clone, Default, Queryable, Identifiable, Insertable)]
|
||||||
|
#[table_name = "user_table"]
|
||||||
|
pub struct User {
|
||||||
|
#[pb(index = 1)]
|
||||||
|
pub(crate) id: String,
|
||||||
|
|
||||||
|
#[pb(index = 2)]
|
||||||
|
name: String,
|
||||||
|
|
||||||
|
#[pb(index = 3)]
|
||||||
|
email: String,
|
||||||
|
|
||||||
|
#[pb(index = 4)]
|
||||||
|
password: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl User {
|
||||||
|
pub fn new(id: String, name: String, email: String, password: String) -> Self {
|
||||||
|
Self {
|
||||||
|
id,
|
||||||
|
name,
|
||||||
|
email,
|
||||||
|
password,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,13 +1,11 @@
|
|||||||
mod sign_in;
|
mod sign_in;
|
||||||
mod sign_up;
|
mod sign_up;
|
||||||
mod user;
|
|
||||||
mod user_email;
|
mod user_email;
|
||||||
mod user_name;
|
mod user_name;
|
||||||
mod user_password;
|
mod user_password;
|
||||||
|
|
||||||
pub use sign_in::*;
|
pub use sign_in::*;
|
||||||
pub use sign_up::*;
|
pub use sign_up::*;
|
||||||
pub use user::*;
|
|
||||||
pub use user_email::*;
|
pub use user_email::*;
|
||||||
pub use user_name::*;
|
pub use user_name::*;
|
||||||
pub use user_password::*;
|
pub use user_password::*;
|
||||||
|
@ -1,24 +0,0 @@
|
|||||||
use crate::domain::{UserEmail, UserName, UserPassword};
|
|
||||||
use flowy_derive::ProtoBuf;
|
|
||||||
|
|
||||||
#[derive(ProtoBuf, Default)]
|
|
||||||
pub struct User {
|
|
||||||
#[pb(index = 1)]
|
|
||||||
name: String,
|
|
||||||
|
|
||||||
#[pb(index = 2)]
|
|
||||||
email: String,
|
|
||||||
|
|
||||||
#[pb(index = 3)]
|
|
||||||
password: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl User {
|
|
||||||
pub fn new(name: UserName, email: UserEmail, password: UserPassword) -> Self {
|
|
||||||
Self {
|
|
||||||
name: name.0,
|
|
||||||
email: email.0,
|
|
||||||
password: password.0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,48 +0,0 @@
|
|||||||
use crate::{domain::user_db::UserDB, errors::UserError};
|
|
||||||
use flowy_sqlite::DBConnection;
|
|
||||||
use lazy_static::lazy_static;
|
|
||||||
use std::sync::RwLock;
|
|
||||||
|
|
||||||
lazy_static! {
|
|
||||||
pub static ref CURRENT_USER_ID: RwLock<Option<String>> = RwLock::new(None);
|
|
||||||
}
|
|
||||||
fn get_current_user_id() -> Result<Option<String>, UserError> {
|
|
||||||
match CURRENT_USER_ID.read() {
|
|
||||||
Ok(read_guard) => Ok((*read_guard).clone()),
|
|
||||||
Err(e) => {
|
|
||||||
log::error!("Get current user id failed: {:?}", e);
|
|
||||||
Err(e.into())
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct UserSessionConfig {
|
|
||||||
root_dir: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl UserSessionConfig {
|
|
||||||
pub fn new(root_dir: &str) -> Self {
|
|
||||||
Self {
|
|
||||||
root_dir: root_dir.to_owned(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct UserSession {
|
|
||||||
db: UserDB,
|
|
||||||
config: UserSessionConfig,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl UserSession {
|
|
||||||
pub fn new(config: UserSessionConfig) -> Self {
|
|
||||||
let db = UserDB::new(&config.root_dir);
|
|
||||||
Self { db, config }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_db_connection(&self) -> Result<DBConnection, UserError> {
|
|
||||||
match get_current_user_id()? {
|
|
||||||
None => Err(UserError::UserNotLogin),
|
|
||||||
Some(user_id) => self.db.get_connection(&user_id),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,23 +1,34 @@
|
|||||||
use flowy_database::DataBaseError;
|
use derive_more::Display;
|
||||||
use std::sync::PoisonError;
|
use flowy_dispatch::prelude::{DispatchError, EventResponse, ResponseBuilder, StatusCode};
|
||||||
|
use std::{io, sync::PoisonError};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone, Display)]
|
||||||
pub enum UserError {
|
pub enum UserError {
|
||||||
DBInit(String),
|
#[display(fmt = "User db error:{}", _0)]
|
||||||
DBNotInit,
|
Database(String),
|
||||||
UserNotLogin,
|
#[display(fmt = "User auth error:{}", _0)]
|
||||||
DBConnection(String),
|
Auth(String),
|
||||||
|
#[display(fmt = "User sync error: {}", _0)]
|
||||||
PoisonError(String),
|
PoisonError(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::convert::From<DataBaseError> for UserError {
|
impl std::convert::From<flowy_database::result::Error> for UserError {
|
||||||
fn from(error: DataBaseError) -> Self { UserError::DBInit(format!("{:?}", error)) }
|
fn from(error: flowy_database::result::Error) -> Self {
|
||||||
}
|
UserError::Database(format!("{:?}", error))
|
||||||
|
}
|
||||||
impl<T> std::convert::From<PoisonError<T>> for UserError {
|
|
||||||
fn from(error: PoisonError<T>) -> Self { UserError::PoisonError(format!("{:?}", error)) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::convert::From<flowy_sqlite::Error> for UserError {
|
impl std::convert::From<flowy_sqlite::Error> for UserError {
|
||||||
fn from(e: flowy_sqlite::Error) -> Self { UserError::DBConnection(format!("{:?}", e)) }
|
fn from(e: flowy_sqlite::Error) -> Self { UserError::Database(format!("{:?}", e)) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::convert::From<UserError> for String {
|
||||||
|
fn from(e: UserError) -> Self { format!("{:?}", e) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::convert::Into<DispatchError> for UserError {
|
||||||
|
fn into(self) -> DispatchError {
|
||||||
|
let user_error: String = self.into();
|
||||||
|
user_error.into()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::domain::{user::*, user_session::UserSession};
|
use crate::{domain::user::*, services::user_session::UserSession};
|
||||||
use flowy_dispatch::prelude::*;
|
use flowy_dispatch::prelude::*;
|
||||||
use std::{convert::TryInto, sync::Arc};
|
use std::{convert::TryInto, sync::Arc};
|
||||||
|
|
||||||
@ -21,16 +21,19 @@ pub async fn user_sign_in(data: Data<SignInRequest>) -> ResponseResult<SignInRes
|
|||||||
name = "user_sign_up",
|
name = "user_sign_up",
|
||||||
skip(data, session),
|
skip(data, session),
|
||||||
fields(
|
fields(
|
||||||
email = %data.email,
|
email = %data.email,
|
||||||
|
name = %data.name,
|
||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
pub async fn user_sign_up(
|
pub async fn user_sign_up(
|
||||||
data: Data<SignUpRequest>,
|
data: Data<SignUpRequest>,
|
||||||
session: ModuleData<Arc<UserSession>>,
|
session: ModuleData<Arc<UserSession>>,
|
||||||
) -> ResponseResult<SignUpResponse, String> {
|
) -> ResponseResult<SignUpResponse, String> {
|
||||||
let _params: SignUpParams = data.into_inner().try_into()?;
|
let params: SignUpParams = data.into_inner().try_into()?;
|
||||||
// TODO: user sign up
|
// TODO: user sign up
|
||||||
|
|
||||||
|
let _user = session.sign_up(params)?;
|
||||||
|
|
||||||
let fake_resp = SignUpResponse::new(true);
|
let fake_resp = SignUpResponse::new(true);
|
||||||
response_ok(fake_resp)
|
response_ok(fake_resp)
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,11 @@ pub mod event;
|
|||||||
mod handlers;
|
mod handlers;
|
||||||
pub mod module;
|
pub mod module;
|
||||||
mod protobuf;
|
mod protobuf;
|
||||||
|
mod services;
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate flowy_database;
|
||||||
|
|
||||||
pub mod prelude {
|
pub mod prelude {
|
||||||
pub use crate::{domain::*, handlers::auth::*};
|
pub use crate::{domain::*, handlers::auth::*, services::user_session::*};
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,6 @@
|
|||||||
use flowy_dispatch::prelude::*;
|
use flowy_dispatch::prelude::*;
|
||||||
|
|
||||||
use crate::{
|
use crate::{event::UserEvent, handlers::*, services::user_session::UserSession};
|
||||||
domain::{user_db::*, user_session::UserSession},
|
|
||||||
event::UserEvent,
|
|
||||||
handlers::*,
|
|
||||||
};
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
pub fn create(user_session: Arc<UserSession>) -> Module {
|
pub fn create(user_session: Arc<UserSession>) -> Module {
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#[derive(PartialEq,Clone,Default)]
|
#[derive(PartialEq,Clone,Default)]
|
||||||
pub struct User {
|
pub struct User {
|
||||||
// message fields
|
// message fields
|
||||||
|
pub id: ::std::string::String,
|
||||||
pub name: ::std::string::String,
|
pub name: ::std::string::String,
|
||||||
pub email: ::std::string::String,
|
pub email: ::std::string::String,
|
||||||
pub password: ::std::string::String,
|
pub password: ::std::string::String,
|
||||||
@ -45,7 +46,33 @@ impl User {
|
|||||||
::std::default::Default::default()
|
::std::default::Default::default()
|
||||||
}
|
}
|
||||||
|
|
||||||
// string name = 1;
|
// string id = 1;
|
||||||
|
|
||||||
|
|
||||||
|
pub fn get_id(&self) -> &str {
|
||||||
|
&self.id
|
||||||
|
}
|
||||||
|
pub fn clear_id(&mut self) {
|
||||||
|
self.id.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Param is passed by value, moved
|
||||||
|
pub fn set_id(&mut self, v: ::std::string::String) {
|
||||||
|
self.id = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mutable pointer to the field.
|
||||||
|
// If field is not initialized, it is initialized with default value first.
|
||||||
|
pub fn mut_id(&mut self) -> &mut ::std::string::String {
|
||||||
|
&mut self.id
|
||||||
|
}
|
||||||
|
|
||||||
|
// Take field
|
||||||
|
pub fn take_id(&mut self) -> ::std::string::String {
|
||||||
|
::std::mem::replace(&mut self.id, ::std::string::String::new())
|
||||||
|
}
|
||||||
|
|
||||||
|
// string name = 2;
|
||||||
|
|
||||||
|
|
||||||
pub fn get_name(&self) -> &str {
|
pub fn get_name(&self) -> &str {
|
||||||
@ -71,7 +98,7 @@ impl User {
|
|||||||
::std::mem::replace(&mut self.name, ::std::string::String::new())
|
::std::mem::replace(&mut self.name, ::std::string::String::new())
|
||||||
}
|
}
|
||||||
|
|
||||||
// string email = 2;
|
// string email = 3;
|
||||||
|
|
||||||
|
|
||||||
pub fn get_email(&self) -> &str {
|
pub fn get_email(&self) -> &str {
|
||||||
@ -97,7 +124,7 @@ impl User {
|
|||||||
::std::mem::replace(&mut self.email, ::std::string::String::new())
|
::std::mem::replace(&mut self.email, ::std::string::String::new())
|
||||||
}
|
}
|
||||||
|
|
||||||
// string password = 3;
|
// string password = 4;
|
||||||
|
|
||||||
|
|
||||||
pub fn get_password(&self) -> &str {
|
pub fn get_password(&self) -> &str {
|
||||||
@ -134,12 +161,15 @@ impl ::protobuf::Message for User {
|
|||||||
let (field_number, wire_type) = is.read_tag_unpack()?;
|
let (field_number, wire_type) = is.read_tag_unpack()?;
|
||||||
match field_number {
|
match field_number {
|
||||||
1 => {
|
1 => {
|
||||||
::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.name)?;
|
::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?;
|
||||||
},
|
},
|
||||||
2 => {
|
2 => {
|
||||||
::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.email)?;
|
::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.name)?;
|
||||||
},
|
},
|
||||||
3 => {
|
3 => {
|
||||||
|
::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.email)?;
|
||||||
|
},
|
||||||
|
4 => {
|
||||||
::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.password)?;
|
::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.password)?;
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
@ -154,14 +184,17 @@ impl ::protobuf::Message for User {
|
|||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
fn compute_size(&self) -> u32 {
|
fn compute_size(&self) -> u32 {
|
||||||
let mut my_size = 0;
|
let mut my_size = 0;
|
||||||
|
if !self.id.is_empty() {
|
||||||
|
my_size += ::protobuf::rt::string_size(1, &self.id);
|
||||||
|
}
|
||||||
if !self.name.is_empty() {
|
if !self.name.is_empty() {
|
||||||
my_size += ::protobuf::rt::string_size(1, &self.name);
|
my_size += ::protobuf::rt::string_size(2, &self.name);
|
||||||
}
|
}
|
||||||
if !self.email.is_empty() {
|
if !self.email.is_empty() {
|
||||||
my_size += ::protobuf::rt::string_size(2, &self.email);
|
my_size += ::protobuf::rt::string_size(3, &self.email);
|
||||||
}
|
}
|
||||||
if !self.password.is_empty() {
|
if !self.password.is_empty() {
|
||||||
my_size += ::protobuf::rt::string_size(3, &self.password);
|
my_size += ::protobuf::rt::string_size(4, &self.password);
|
||||||
}
|
}
|
||||||
my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
|
my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
|
||||||
self.cached_size.set(my_size);
|
self.cached_size.set(my_size);
|
||||||
@ -169,14 +202,17 @@ impl ::protobuf::Message for User {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
|
fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
|
||||||
|
if !self.id.is_empty() {
|
||||||
|
os.write_string(1, &self.id)?;
|
||||||
|
}
|
||||||
if !self.name.is_empty() {
|
if !self.name.is_empty() {
|
||||||
os.write_string(1, &self.name)?;
|
os.write_string(2, &self.name)?;
|
||||||
}
|
}
|
||||||
if !self.email.is_empty() {
|
if !self.email.is_empty() {
|
||||||
os.write_string(2, &self.email)?;
|
os.write_string(3, &self.email)?;
|
||||||
}
|
}
|
||||||
if !self.password.is_empty() {
|
if !self.password.is_empty() {
|
||||||
os.write_string(3, &self.password)?;
|
os.write_string(4, &self.password)?;
|
||||||
}
|
}
|
||||||
os.write_unknown_fields(self.get_unknown_fields())?;
|
os.write_unknown_fields(self.get_unknown_fields())?;
|
||||||
::std::result::Result::Ok(())
|
::std::result::Result::Ok(())
|
||||||
@ -216,6 +252,11 @@ impl ::protobuf::Message for User {
|
|||||||
static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT;
|
static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT;
|
||||||
descriptor.get(|| {
|
descriptor.get(|| {
|
||||||
let mut fields = ::std::vec::Vec::new();
|
let mut fields = ::std::vec::Vec::new();
|
||||||
|
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
|
||||||
|
"id",
|
||||||
|
|m: &User| { &m.id },
|
||||||
|
|m: &mut User| { &mut m.id },
|
||||||
|
));
|
||||||
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
|
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
|
||||||
"name",
|
"name",
|
||||||
|m: &User| { &m.name },
|
|m: &User| { &m.name },
|
||||||
@ -247,6 +288,7 @@ impl ::protobuf::Message for User {
|
|||||||
|
|
||||||
impl ::protobuf::Clear for User {
|
impl ::protobuf::Clear for User {
|
||||||
fn clear(&mut self) {
|
fn clear(&mut self) {
|
||||||
|
self.id.clear();
|
||||||
self.name.clear();
|
self.name.clear();
|
||||||
self.email.clear();
|
self.email.clear();
|
||||||
self.password.clear();
|
self.password.clear();
|
||||||
@ -267,19 +309,23 @@ impl ::protobuf::reflect::ProtobufValue for User {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static file_descriptor_proto_data: &'static [u8] = b"\
|
static file_descriptor_proto_data: &'static [u8] = b"\
|
||||||
\n\nuser.proto\"L\n\x04User\x12\x12\n\x04name\x18\x01\x20\x01(\tR\x04nam\
|
\n\nuser.proto\"\\\n\x04User\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\
|
||||||
e\x12\x14\n\x05email\x18\x02\x20\x01(\tR\x05email\x12\x1a\n\x08password\
|
\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x14\n\x05email\x18\
|
||||||
\x18\x03\x20\x01(\tR\x08passwordJ\xcf\x01\n\x06\x12\x04\0\0\x06\x01\n\
|
\x03\x20\x01(\tR\x05email\x12\x1a\n\x08password\x18\x04\x20\x01(\tR\x08p\
|
||||||
\x08\n\x01\x0c\x12\x03\0\0\x12\n\n\n\x02\x04\0\x12\x04\x02\0\x06\x01\n\n\
|
asswordJ\x86\x02\n\x06\x12\x04\0\0\x07\x01\n\x08\n\x01\x0c\x12\x03\0\0\
|
||||||
\n\x03\x04\0\x01\x12\x03\x02\x08\x0c\n\x0b\n\x04\x04\0\x02\0\x12\x03\x03\
|
\x12\n\n\n\x02\x04\0\x12\x04\x02\0\x07\x01\n\n\n\x03\x04\0\x01\x12\x03\
|
||||||
\x04\x14\n\x0c\n\x05\x04\0\x02\0\x05\x12\x03\x03\x04\n\n\x0c\n\x05\x04\0\
|
\x02\x08\x0c\n\x0b\n\x04\x04\0\x02\0\x12\x03\x03\x04\x12\n\x0c\n\x05\x04\
|
||||||
\x02\0\x01\x12\x03\x03\x0b\x0f\n\x0c\n\x05\x04\0\x02\0\x03\x12\x03\x03\
|
\0\x02\0\x05\x12\x03\x03\x04\n\n\x0c\n\x05\x04\0\x02\0\x01\x12\x03\x03\
|
||||||
\x12\x13\n\x0b\n\x04\x04\0\x02\x01\x12\x03\x04\x04\x15\n\x0c\n\x05\x04\0\
|
\x0b\r\n\x0c\n\x05\x04\0\x02\0\x03\x12\x03\x03\x10\x11\n\x0b\n\x04\x04\0\
|
||||||
\x02\x01\x05\x12\x03\x04\x04\n\n\x0c\n\x05\x04\0\x02\x01\x01\x12\x03\x04\
|
\x02\x01\x12\x03\x04\x04\x14\n\x0c\n\x05\x04\0\x02\x01\x05\x12\x03\x04\
|
||||||
\x0b\x10\n\x0c\n\x05\x04\0\x02\x01\x03\x12\x03\x04\x13\x14\n\x0b\n\x04\
|
\x04\n\n\x0c\n\x05\x04\0\x02\x01\x01\x12\x03\x04\x0b\x0f\n\x0c\n\x05\x04\
|
||||||
\x04\0\x02\x02\x12\x03\x05\x04\x18\n\x0c\n\x05\x04\0\x02\x02\x05\x12\x03\
|
\0\x02\x01\x03\x12\x03\x04\x12\x13\n\x0b\n\x04\x04\0\x02\x02\x12\x03\x05\
|
||||||
\x05\x04\n\n\x0c\n\x05\x04\0\x02\x02\x01\x12\x03\x05\x0b\x13\n\x0c\n\x05\
|
\x04\x15\n\x0c\n\x05\x04\0\x02\x02\x05\x12\x03\x05\x04\n\n\x0c\n\x05\x04\
|
||||||
\x04\0\x02\x02\x03\x12\x03\x05\x16\x17b\x06proto3\
|
\0\x02\x02\x01\x12\x03\x05\x0b\x10\n\x0c\n\x05\x04\0\x02\x02\x03\x12\x03\
|
||||||
|
\x05\x13\x14\n\x0b\n\x04\x04\0\x02\x03\x12\x03\x06\x04\x18\n\x0c\n\x05\
|
||||||
|
\x04\0\x02\x03\x05\x12\x03\x06\x04\n\n\x0c\n\x05\x04\0\x02\x03\x01\x12\
|
||||||
|
\x03\x06\x0b\x13\n\x0c\n\x05\x04\0\x02\x03\x03\x12\x03\x06\x16\x17b\x06p\
|
||||||
|
roto3\
|
||||||
";
|
";
|
||||||
|
|
||||||
static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;
|
static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
syntax = "proto3";
|
syntax = "proto3";
|
||||||
|
|
||||||
message User {
|
message User {
|
||||||
string name = 1;
|
string id = 1;
|
||||||
string email = 2;
|
string name = 2;
|
||||||
string password = 3;
|
string email = 3;
|
||||||
|
string password = 4;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::errors::UserError;
|
use crate::errors::UserError;
|
||||||
use flowy_database::{DBConnection, DataBase};
|
use flowy_database::{DBConnection, Database};
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use std::{
|
use std::{
|
||||||
cell::RefCell,
|
cell::RefCell,
|
||||||
@ -22,7 +22,7 @@ fn get_user_id() -> Option<String> { USER_ID.with(|id| id.borrow().clone()) }
|
|||||||
static IS_USER_DB_INIT: AtomicBool = AtomicBool::new(false);
|
static IS_USER_DB_INIT: AtomicBool = AtomicBool::new(false);
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref USER_DB_INNER: RwLock<Option<DataBase>> = RwLock::new(None);
|
static ref DB: RwLock<Option<Database>> = RwLock::new(None);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct UserDB {
|
pub(crate) struct UserDB {
|
||||||
@ -37,17 +37,23 @@ impl UserDB {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn open_user_db(&self, user_id: &str) -> Result<(), UserError> {
|
fn open_user_db(&self, user_id: &str) -> Result<(), UserError> {
|
||||||
let user_dir = format!("{}/{}", self.db_dir, user_id);
|
let dir = format!("{}/{}", self.db_dir, user_id);
|
||||||
let database = flowy_database::init(&user_dir)?;
|
let db = flowy_database::init(&dir).map_err(|e| UserError::Database(format!("{:?}", e)))?;
|
||||||
let mut write_guard = USER_DB_INNER.write()?;
|
|
||||||
|
let mut user_db = DB
|
||||||
|
.write()
|
||||||
|
.map_err(|e| UserError::Database(format!("Open user db failed. {:?}", e)))?;
|
||||||
|
*(user_db) = Some(db);
|
||||||
|
|
||||||
set_user_id(Some(user_id.to_owned()));
|
set_user_id(Some(user_id.to_owned()));
|
||||||
*(write_guard) = Some(database);
|
|
||||||
IS_USER_DB_INIT.store(true, Ordering::SeqCst);
|
IS_USER_DB_INIT.store(true, Ordering::SeqCst);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn close_user_db(&mut self) -> Result<(), UserError> {
|
pub(crate) fn close_user_db(&mut self) -> Result<(), UserError> {
|
||||||
let mut write_guard = USER_DB_INNER.write()?;
|
let mut write_guard = DB
|
||||||
|
.write()
|
||||||
|
.map_err(|e| UserError::Database(format!("Close user db failed. {:?}", e)))?;
|
||||||
*write_guard = None;
|
*write_guard = None;
|
||||||
set_user_id(None);
|
set_user_id(None);
|
||||||
IS_USER_DB_INIT.store(false, Ordering::SeqCst);
|
IS_USER_DB_INIT.store(false, Ordering::SeqCst);
|
||||||
@ -62,16 +68,20 @@ impl UserDB {
|
|||||||
let thread_user_id = get_user_id();
|
let thread_user_id = get_user_id();
|
||||||
if thread_user_id != Some(user_id.to_owned()) {
|
if thread_user_id != Some(user_id.to_owned()) {
|
||||||
let msg = format!(
|
let msg = format!(
|
||||||
"DataBase owner does not match. origin: {:?}, current: {}",
|
"Database owner does not match. origin: {:?}, current: {}",
|
||||||
thread_user_id, user_id
|
thread_user_id, user_id
|
||||||
);
|
);
|
||||||
log::error!("{}", msg);
|
log::error!("{}", msg);
|
||||||
return Err(UserError::DBConnection(msg));
|
return Err(UserError::Database(msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
let read_guard = USER_DB_INNER.read()?;
|
let read_guard = DB
|
||||||
|
.read()
|
||||||
|
.map_err(|e| UserError::Database(format!("Get user db connection fail. {:?}", e)))?;
|
||||||
match read_guard.as_ref() {
|
match read_guard.as_ref() {
|
||||||
None => Err(UserError::DBNotInit),
|
None => Err(UserError::Database(
|
||||||
|
"Database is not initialization".to_owned(),
|
||||||
|
)),
|
||||||
Some(database) => Ok(database.get_connection()?),
|
Some(database) => Ok(database.get_connection()?),
|
||||||
}
|
}
|
||||||
}
|
}
|
3
rust-lib/flowy-user/src/services/mod.rs
Normal file
3
rust-lib/flowy-user/src/services/mod.rs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
pub mod database;
|
||||||
|
mod register;
|
||||||
|
pub mod user_session;
|
22
rust-lib/flowy-user/src/services/register.rs
Normal file
22
rust-lib/flowy-user/src/services/register.rs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
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,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
23
rust-lib/flowy-user/src/services/user_session/builder.rs
Normal file
23
rust-lib/flowy-user/src/services/user_session/builder.rs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
use crate::services::{
|
||||||
|
register::MockUserRegister,
|
||||||
|
user_session::{UserSession, UserSessionConfig},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct UserSessionBuilder {
|
||||||
|
config: Option<UserSessionConfig>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UserSessionBuilder {
|
||||||
|
pub fn new() -> Self { Self { config: None } }
|
||||||
|
|
||||||
|
pub fn root_dir(mut self, dir: &str) -> Self {
|
||||||
|
self.config = Some(UserSessionConfig::new(dir));
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn build(mut self) -> UserSession {
|
||||||
|
let config = self.config.take().unwrap();
|
||||||
|
let register = MockUserRegister {};
|
||||||
|
UserSession::new(config, register)
|
||||||
|
}
|
||||||
|
}
|
5
rust-lib/flowy-user/src/services/user_session/mod.rs
Normal file
5
rust-lib/flowy-user/src/services/user_session/mod.rs
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
mod builder;
|
||||||
|
mod user_session;
|
||||||
|
|
||||||
|
pub use builder::*;
|
||||||
|
pub use user_session::*;
|
@ -0,0 +1,86 @@
|
|||||||
|
use crate::{
|
||||||
|
domain::{tables::User, SignUpParams},
|
||||||
|
errors::UserError,
|
||||||
|
services::{database::UserDB, register::UserRegister},
|
||||||
|
};
|
||||||
|
use ::diesel::query_dsl::*;
|
||||||
|
use flowy_database::schema::user_table;
|
||||||
|
use flowy_sqlite::DBConnection;
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
use std::sync::RwLock;
|
||||||
|
|
||||||
|
pub struct UserSessionConfig {
|
||||||
|
root_dir: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UserSessionConfig {
|
||||||
|
pub fn new(root_dir: &str) -> Self {
|
||||||
|
Self {
|
||||||
|
root_dir: root_dir.to_owned(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct UserSession {
|
||||||
|
database: UserDB,
|
||||||
|
config: UserSessionConfig,
|
||||||
|
register: Box<dyn UserRegister + Send + Sync>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UserSession {
|
||||||
|
pub fn new<R>(config: UserSessionConfig, register: R) -> Self
|
||||||
|
where
|
||||||
|
R: 'static + UserRegister + Send + Sync,
|
||||||
|
{
|
||||||
|
let db = UserDB::new(&config.root_dir);
|
||||||
|
Self {
|
||||||
|
database: db,
|
||||||
|
config,
|
||||||
|
register: Box::new(register),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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()));
|
||||||
|
|
||||||
|
let conn = self.get_db_connection()?;
|
||||||
|
let _ = 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(())
|
||||||
|
}
|
@ -9,11 +9,9 @@ fn sign_up_success() {
|
|||||||
password: valid_password(),
|
password: valid_password(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let response = EventTester::new(SignUp)
|
let response = EventTester::new(SignUp).request(request).sync_send();
|
||||||
.request(request)
|
// .parse::<SignUpResponse>();
|
||||||
.sync_send()
|
// dbg!(&response);
|
||||||
.parse::<SignUpResponse>();
|
|
||||||
dbg!(&response);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
@ -1 +1 @@
|
|||||||
mod auth;
|
mod auth_test;
|
||||||
|
Loading…
Reference in New Issue
Block a user