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-database/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/.dart_tool" />
|
||||
<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 {
|
||||
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(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'email')
|
||||
..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'password')
|
||||
..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;
|
||||
}
|
||||
@ -57,30 +62,39 @@ class User extends $pb.GeneratedMessage {
|
||||
static User? _defaultInstance;
|
||||
|
||||
@$pb.TagNumber(1)
|
||||
$core.String get name => $_getSZ(0);
|
||||
$core.String get id => $_getSZ(0);
|
||||
@$pb.TagNumber(1)
|
||||
set name($core.String v) { $_setString(0, v); }
|
||||
set id($core.String v) { $_setString(0, v); }
|
||||
@$pb.TagNumber(1)
|
||||
$core.bool hasName() => $_has(0);
|
||||
$core.bool hasId() => $_has(0);
|
||||
@$pb.TagNumber(1)
|
||||
void clearName() => clearField(1);
|
||||
void clearId() => clearField(1);
|
||||
|
||||
@$pb.TagNumber(2)
|
||||
$core.String get email => $_getSZ(1);
|
||||
$core.String get name => $_getSZ(1);
|
||||
@$pb.TagNumber(2)
|
||||
set email($core.String v) { $_setString(1, v); }
|
||||
set name($core.String v) { $_setString(1, v); }
|
||||
@$pb.TagNumber(2)
|
||||
$core.bool hasEmail() => $_has(1);
|
||||
$core.bool hasName() => $_has(1);
|
||||
@$pb.TagNumber(2)
|
||||
void clearEmail() => clearField(2);
|
||||
void clearName() => clearField(2);
|
||||
|
||||
@$pb.TagNumber(3)
|
||||
$core.String get password => $_getSZ(2);
|
||||
$core.String get email => $_getSZ(2);
|
||||
@$pb.TagNumber(3)
|
||||
set password($core.String v) { $_setString(2, v); }
|
||||
set email($core.String v) { $_setString(2, v); }
|
||||
@$pb.TagNumber(3)
|
||||
$core.bool hasPassword() => $_has(2);
|
||||
$core.bool hasEmail() => $_has(2);
|
||||
@$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 {
|
||||
'1': 'User',
|
||||
'2': const [
|
||||
const {'1': 'name', '3': 1, '4': 1, '5': 9, '10': 'name'},
|
||||
const {'1': 'email', '3': 2, '4': 1, '5': 9, '10': 'email'},
|
||||
const {'1': 'password', '3': 3, '4': 1, '5': 9, '10': 'password'},
|
||||
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'},
|
||||
],
|
||||
};
|
||||
|
||||
|
@ -10,6 +10,7 @@ members = [
|
||||
"flowy-test",
|
||||
"flowy-sqlite",
|
||||
"flowy-database",
|
||||
"flowy-infra",
|
||||
]
|
||||
|
||||
[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();
|
||||
log::trace!(
|
||||
"[FFI]: {} Async Event: {:?} with {} port",
|
||||
&request.id(),
|
||||
&request.event(),
|
||||
&request.id,
|
||||
&request.event,
|
||||
port
|
||||
);
|
||||
|
||||
@ -50,11 +50,7 @@ pub extern "C" fn async_command(port: i64, input: *const u8, len: usize) {
|
||||
#[no_mangle]
|
||||
pub extern "C" fn sync_command(input: *const u8, len: usize) -> *const u8 {
|
||||
let request: ModuleRequest = FFIRequest::from_u8_pointer(input, len).into();
|
||||
log::trace!(
|
||||
"[FFI]: {} Sync Event: {:?}",
|
||||
&request.id(),
|
||||
&request.event(),
|
||||
);
|
||||
log::trace!("[FFI]: {} Sync Event: {:?}", &request.id, &request.event,);
|
||||
let _response = EventDispatch::sync_send(request);
|
||||
|
||||
// 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;
|
||||
mod schema;
|
||||
pub mod schema;
|
||||
|
||||
#[macro_use]
|
||||
extern crate diesel;
|
||||
pub use diesel::*;
|
||||
|
||||
#[macro_use]
|
||||
extern crate diesel_derives;
|
||||
pub use diesel_derives::*;
|
||||
|
||||
#[macro_use]
|
||||
extern crate diesel_migrations;
|
||||
|
||||
pub use errors::*;
|
||||
pub use flowy_sqlite::{DBConnection, DataBase};
|
||||
pub use flowy_sqlite::{DBConnection, Database};
|
||||
|
||||
use diesel_migrations::*;
|
||||
use flowy_sqlite::PoolConfig;
|
||||
use std::path::Path;
|
||||
use flowy_sqlite::{Error, PoolConfig};
|
||||
use std::{io, path::Path};
|
||||
|
||||
embed_migrations!("../flowy-database/migrations/");
|
||||
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() {
|
||||
std::fs::create_dir_all(storage_path)?;
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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::{
|
||||
error::{InternalError, SystemError},
|
||||
errors::{DispatchError, InternalError},
|
||||
request::{unexpected_none_payload, EventRequest, FromRequest, Payload},
|
||||
response::{EventResponse, Responder, ResponseBuilder, ToBytes},
|
||||
util::ready::{ready, Ready},
|
||||
@ -53,8 +53,8 @@ impl<T> FromRequest for Data<T>
|
||||
where
|
||||
T: FromBytes + 'static,
|
||||
{
|
||||
type Error = SystemError;
|
||||
type Future = Ready<Result<Self, SystemError>>;
|
||||
type Error = DispatchError;
|
||||
type Future = Ready<Result<Self, DispatchError>>;
|
||||
|
||||
#[inline]
|
||||
fn from_request(req: &EventRequest, payload: &mut Payload) -> Self::Future {
|
||||
@ -76,7 +76,7 @@ where
|
||||
match self.into_inner().into_bytes() {
|
||||
Ok(bytes) => ResponseBuilder::Ok().data(bytes.to_vec()).build(),
|
||||
Err(e) => {
|
||||
let system_err: SystemError = InternalError::new(format!("{:?}", e)).into();
|
||||
let system_err: DispatchError = InternalError::new(format!("{:?}", e)).into();
|
||||
system_err.into()
|
||||
},
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::{
|
||||
error::{Error, InternalError, SystemError},
|
||||
errors::{DispatchError, Error, InternalError},
|
||||
module::{as_module_map, Module, ModuleMap, ModuleRequest},
|
||||
response::EventResponse,
|
||||
service::{Service, ServiceFactory},
|
||||
@ -129,7 +129,7 @@ pub(crate) struct DispatchService {
|
||||
|
||||
impl Service<DispatchContext> for DispatchService {
|
||||
type Response = EventResponse;
|
||||
type Error = SystemError;
|
||||
type Error = DispatchError;
|
||||
type Future = BoxFuture<'static, Result<Self::Response, Self::Error>>;
|
||||
|
||||
#[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;
|
||||
|
||||
pub trait Error: fmt::Debug + fmt::Display + DynClone + Send + Sync {
|
||||
fn status_code(&self) -> StatusCode;
|
||||
|
||||
fn as_response(&self) -> EventResponse { EventResponse::new(self.status_code()) }
|
||||
fn as_response(&self) -> EventResponse { EventResponse::new(StatusCode::Err) }
|
||||
}
|
||||
|
||||
dyn_clone::clone_trait_object!(Error);
|
||||
|
||||
impl<T: Error + 'static> From<T> for SystemError {
|
||||
fn from(err: T) -> SystemError {
|
||||
SystemError {
|
||||
impl<T: Error + 'static> From<T> for DispatchError {
|
||||
fn from(err: T) -> DispatchError {
|
||||
DispatchError {
|
||||
inner: Box::new(err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct SystemError {
|
||||
pub struct DispatchError {
|
||||
inner: Box<dyn Error>,
|
||||
}
|
||||
|
||||
impl SystemError {
|
||||
impl DispatchError {
|
||||
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) }
|
||||
}
|
||||
|
||||
impl fmt::Debug for SystemError {
|
||||
impl fmt::Debug for DispatchError {
|
||||
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 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 {
|
||||
InternalError {
|
||||
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 {
|
||||
InternalError {
|
||||
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() }
|
||||
}
|
||||
|
||||
impl From<SystemError> for EventResponse {
|
||||
fn from(err: SystemError) -> Self { err.inner_error().as_response() }
|
||||
impl From<DispatchError> for EventResponse {
|
||||
fn from(err: DispatchError) -> Self { err.inner_error().as_response() }
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct InternalError<T: Clone> {
|
||||
pub(crate) struct InternalError<T: Clone> {
|
||||
inner: T,
|
||||
}
|
||||
|
||||
@ -99,8 +97,6 @@ impl<T> Error for InternalError<T>
|
||||
where
|
||||
T: fmt::Debug + fmt::Display + 'static + Clone + Send + Sync,
|
||||
{
|
||||
fn status_code(&self) -> StatusCode { StatusCode::Err }
|
||||
|
||||
fn as_response(&self) -> EventResponse {
|
||||
let error = InternalError {
|
||||
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>
|
||||
where
|
||||
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)]
|
||||
|
||||
mod error;
|
||||
mod errors;
|
||||
mod module;
|
||||
mod request;
|
||||
mod response;
|
||||
@ -11,6 +11,8 @@ mod data;
|
||||
mod dispatch;
|
||||
mod system;
|
||||
|
||||
pub use errors::Error;
|
||||
|
||||
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::{
|
||||
error::{InternalError, SystemError},
|
||||
errors::{DispatchError, InternalError},
|
||||
request::{payload::Payload, EventRequest, FromRequest},
|
||||
util::ready::{ready, Ready},
|
||||
};
|
||||
@ -43,15 +43,18 @@ impl<T> FromRequest for ModuleData<T>
|
||||
where
|
||||
T: ?Sized + Send + Sync + 'static,
|
||||
{
|
||||
type Error = SystemError;
|
||||
type Future = Ready<Result<Self, SystemError>>;
|
||||
type Error = DispatchError;
|
||||
type Future = Ready<Result<Self, DispatchError>>;
|
||||
|
||||
#[inline]
|
||||
fn from_request(req: &EventRequest, _: &mut Payload) -> Self::Future {
|
||||
if let Some(data) = req.module_data::<ModuleData<T>>() {
|
||||
ready(Ok(data.clone()))
|
||||
} 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,);
|
||||
ready(Err(InternalError::new(msg).into()))
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ use futures_core::ready;
|
||||
use pin_project::pin_project;
|
||||
|
||||
use crate::{
|
||||
error::{InternalError, SystemError},
|
||||
errors::{DispatchError, InternalError},
|
||||
module::{container::ModuleDataMap, ModuleData},
|
||||
request::{payload::Payload, EventRequest, FromRequest},
|
||||
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)) }
|
||||
}
|
||||
|
||||
pub type EventServiceFactory = BoxServiceFactory<(), ServiceRequest, ServiceResponse, SystemError>;
|
||||
pub type EventServiceFactory =
|
||||
BoxServiceFactory<(), ServiceRequest, ServiceResponse, DispatchError>;
|
||||
|
||||
pub struct Module {
|
||||
pub name: String,
|
||||
@ -111,8 +112,8 @@ impl Module {
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ModuleRequest {
|
||||
pub(crate) id: String,
|
||||
pub(crate) event: Event,
|
||||
pub id: String,
|
||||
pub event: Event,
|
||||
pub(crate) payload: Payload,
|
||||
}
|
||||
|
||||
@ -145,7 +146,7 @@ impl std::fmt::Display for ModuleRequest {
|
||||
|
||||
impl ServiceFactory<ModuleRequest> for Module {
|
||||
type Response = EventResponse;
|
||||
type Error = SystemError;
|
||||
type Error = DispatchError;
|
||||
type Service = BoxService<ModuleRequest, Self::Response, Self::Error>;
|
||||
type Context = ();
|
||||
type Future = BoxFuture<'static, Result<Self::Service, Self::Error>>;
|
||||
@ -171,7 +172,7 @@ pub struct ModuleService {
|
||||
|
||||
impl Service<ModuleRequest> for ModuleService {
|
||||
type Response = EventResponse;
|
||||
type Error = SystemError;
|
||||
type Error = DispatchError;
|
||||
type Future = BoxFuture<'static, Result<Self::Response, Self::Error>>;
|
||||
|
||||
fn call(&self, request: ModuleRequest) -> Self::Future {
|
||||
@ -196,17 +197,14 @@ impl Service<ModuleRequest> for ModuleService {
|
||||
}
|
||||
}
|
||||
|
||||
// type BoxModuleService = BoxService<ServiceRequest, ServiceResponse,
|
||||
// SystemError>;
|
||||
|
||||
#[pin_project]
|
||||
pub struct ModuleServiceFuture {
|
||||
#[pin]
|
||||
fut: BoxFuture<'static, Result<ServiceResponse, SystemError>>,
|
||||
fut: BoxFuture<'static, Result<ServiceResponse, DispatchError>>,
|
||||
}
|
||||
|
||||
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> {
|
||||
loop {
|
||||
|
@ -1,7 +1,7 @@
|
||||
use std::future::Future;
|
||||
|
||||
use crate::{
|
||||
error::{InternalError, SystemError},
|
||||
errors::{DispatchError, InternalError},
|
||||
module::{Event, ModuleDataMap},
|
||||
request::payload::Payload,
|
||||
util::ready::{ready, Ready},
|
||||
@ -48,7 +48,7 @@ impl EventRequest {
|
||||
}
|
||||
|
||||
pub trait FromRequest: Sized {
|
||||
type Error: Into<SystemError>;
|
||||
type Error: Into<DispatchError>;
|
||||
type Future: Future<Output = Result<Self, Self::Error>>;
|
||||
|
||||
fn from_request(req: &EventRequest, payload: &mut Payload) -> Self::Future;
|
||||
@ -56,15 +56,15 @@ pub trait FromRequest: Sized {
|
||||
|
||||
#[doc(hidden)]
|
||||
impl FromRequest for () {
|
||||
type Error = SystemError;
|
||||
type Future = Ready<Result<(), SystemError>>;
|
||||
type Error = DispatchError;
|
||||
type Future = Ready<Result<(), DispatchError>>;
|
||||
|
||||
fn from_request(_req: &EventRequest, _payload: &mut Payload) -> Self::Future { ready(Ok(())) }
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
impl FromRequest for String {
|
||||
type Error = SystemError;
|
||||
type Error = DispatchError;
|
||||
type Future = Ready<Result<Self, Self::Error>>;
|
||||
|
||||
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);
|
||||
InternalError::new("Expected payload").into()
|
||||
}
|
||||
@ -85,7 +85,7 @@ impl<T> FromRequest for Result<T, T::Error>
|
||||
where
|
||||
T: FromRequest,
|
||||
{
|
||||
type Error = SystemError;
|
||||
type Error = DispatchError;
|
||||
type Future = FromRequestFuture<T::Future>;
|
||||
|
||||
fn from_request(req: &EventRequest, payload: &mut Payload) -> Self::Future {
|
||||
@ -105,7 +105,7 @@ impl<Fut, T, E> Future for FromRequestFuture<Fut>
|
||||
where
|
||||
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> {
|
||||
let this = self.project();
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::{
|
||||
error::SystemError,
|
||||
errors::DispatchError,
|
||||
request::Payload,
|
||||
response::{EventResponse, StatusCode},
|
||||
};
|
||||
@ -14,7 +14,7 @@ macro_rules! static_response {
|
||||
pub struct ResponseBuilder<T = Payload> {
|
||||
pub payload: T,
|
||||
pub status: StatusCode,
|
||||
pub error: Option<SystemError>,
|
||||
pub error: Option<DispatchError>,
|
||||
}
|
||||
|
||||
impl ResponseBuilder {
|
||||
@ -31,7 +31,7 @@ impl ResponseBuilder {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn error(mut self, error: SystemError) -> Self {
|
||||
pub fn error(mut self, error: DispatchError) -> Self {
|
||||
self.error = Some(error);
|
||||
self
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
#[allow(unused_imports)]
|
||||
use crate::error::{InternalError, SystemError};
|
||||
use crate::errors::{DispatchError, InternalError};
|
||||
use crate::{
|
||||
request::EventRequest,
|
||||
response::{EventResponse, ResponseBuilder},
|
||||
@ -28,7 +28,7 @@ impl_responder!(Bytes);
|
||||
impl<T, E> Responder for Result<T, E>
|
||||
where
|
||||
T: Responder,
|
||||
E: Into<SystemError>,
|
||||
E: Into<DispatchError>,
|
||||
{
|
||||
fn respond_to(self, request: &EventRequest) -> EventResponse {
|
||||
match self {
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
data::Data,
|
||||
error::SystemError,
|
||||
errors::DispatchError,
|
||||
request::{EventRequest, Payload},
|
||||
response::Responder,
|
||||
};
|
||||
@ -19,7 +19,7 @@ pub struct EventResponse {
|
||||
#[derivative(Debug = "ignore")]
|
||||
pub payload: Payload,
|
||||
pub status_code: StatusCode,
|
||||
pub error: Option<SystemError>,
|
||||
pub error: Option<DispatchError>,
|
||||
}
|
||||
|
||||
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>
|
||||
where
|
||||
E: Into<SystemError>,
|
||||
E: Into<DispatchError>,
|
||||
{
|
||||
Ok(Data(data))
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ use futures_core::ready;
|
||||
use pin_project::pin_project;
|
||||
|
||||
use crate::{
|
||||
error::SystemError,
|
||||
errors::DispatchError,
|
||||
request::{payload::Payload, EventRequest, FromRequest},
|
||||
response::{EventResponse, Responder},
|
||||
service::{Service, ServiceFactory, ServiceRequest, ServiceResponse},
|
||||
@ -73,7 +73,7 @@ where
|
||||
R::Output: Responder,
|
||||
{
|
||||
type Response = ServiceResponse;
|
||||
type Error = SystemError;
|
||||
type Error = DispatchError;
|
||||
type Service = Self;
|
||||
type Context = ();
|
||||
type Future = Ready<Result<Self::Service, Self::Error>>;
|
||||
@ -89,7 +89,7 @@ where
|
||||
R::Output: Responder,
|
||||
{
|
||||
type Response = ServiceResponse;
|
||||
type Error = SystemError;
|
||||
type Error = DispatchError;
|
||||
type Future = HandlerServiceFuture<H, T, R>;
|
||||
|
||||
fn call(&self, req: ServiceRequest) -> Self::Future {
|
||||
@ -118,7 +118,7 @@ where
|
||||
R: Future + Sync + Send,
|
||||
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> {
|
||||
loop {
|
||||
@ -132,7 +132,7 @@ where
|
||||
},
|
||||
Err(err) => {
|
||||
let req = req.take().unwrap();
|
||||
let system_err: SystemError = err.into();
|
||||
let system_err: DispatchError = err.into();
|
||||
let res: EventResponse = system_err.into();
|
||||
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)]
|
||||
impl<$($T: FromRequest + 'static),+> FromRequest for ($($T,)+)
|
||||
{
|
||||
type Error = SystemError;
|
||||
type Error = DispatchError;
|
||||
type Future = $tuple_type<$($T),+>;
|
||||
|
||||
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),+>
|
||||
{
|
||||
type Output = Result<($($T,)+), SystemError>;
|
||||
type Output = Result<($($T,)+), DispatchError>;
|
||||
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
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_user::prelude::user_session::{UserSession, UserSessionConfig};
|
||||
use flowy_user::prelude::{UserSession, UserSessionBuilder, UserSessionConfig};
|
||||
use std::sync::Arc;
|
||||
|
||||
pub struct ModuleConfig {
|
||||
@ -7,8 +7,6 @@ pub struct ModuleConfig {
|
||||
}
|
||||
|
||||
pub fn build_modules(config: ModuleConfig) -> Vec<Module> {
|
||||
let user_config = UserSessionConfig::new(&config.root);
|
||||
let user_session = Arc::new(UserSession::new(user_config));
|
||||
|
||||
vec![flowy_user::module::create(user_session)]
|
||||
let user_session = UserSessionBuilder::new().root_dir(&config.root).build();
|
||||
vec![flowy_user::module::create(Arc::new(user_session))]
|
||||
}
|
||||
|
@ -4,16 +4,21 @@ use crate::{
|
||||
};
|
||||
use r2d2::PooledConnection;
|
||||
|
||||
pub struct DataBase {
|
||||
pub struct Database {
|
||||
uri: String,
|
||||
pool: ConnectionPool,
|
||||
}
|
||||
|
||||
pub type DBConnection = PooledConnection<ConnectionManager>;
|
||||
|
||||
impl DataBase {
|
||||
impl Database {
|
||||
pub fn new(dir: &str, name: &str, pool_config: PoolConfig) -> Result<Self> {
|
||||
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)?;
|
||||
Ok(Self { uri, pool })
|
||||
}
|
||||
|
@ -115,12 +115,7 @@ impl ManageConnection for ConnectionManager {
|
||||
type Connection = SqliteConnection;
|
||||
type Error = crate::Error;
|
||||
|
||||
fn connect(&self) -> Result<Self::Connection> {
|
||||
if !std::path::PathBuf::from(&self.db_uri).exists() {
|
||||
log::error!("db file not exists");
|
||||
}
|
||||
Ok(SqliteConnection::establish(&self.db_uri)?)
|
||||
}
|
||||
fn connect(&self) -> Result<Self::Connection> { Ok(SqliteConnection::establish(&self.db_uri)?) }
|
||||
|
||||
fn is_valid(&self, conn: &mut Self::Connection) -> Result<()> {
|
||||
Ok(conn.execute("SELECT 1").map(|_| ())?)
|
||||
|
@ -12,6 +12,7 @@ flowy-log = { path = "../flowy-log" }
|
||||
flowy-derive = { path = "../flowy-derive" }
|
||||
flowy-database = { path = "../flowy-database" }
|
||||
flowy-sqlite = { path = "../flowy-sqlite" }
|
||||
flowy-infra = { path = "../flowy-infra" }
|
||||
|
||||
tracing = { version = "0.1", features = ["log"] }
|
||||
bytes = "1.0"
|
||||
@ -23,6 +24,8 @@ log = "0.4.14"
|
||||
protobuf = {version = "2.18.0"}
|
||||
lazy_static = "1.4.0"
|
||||
fancy-regex = "0.5.0"
|
||||
diesel = {version = "1.4.7", features = ["sqlite"]}
|
||||
diesel_derives = {version = "1.4.1", features = ["sqlite"]}
|
||||
|
||||
[dev-dependencies]
|
||||
quickcheck = "0.9.2"
|
||||
|
@ -1,4 +1,3 @@
|
||||
pub use user::*;
|
||||
pub mod tables;
|
||||
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_up;
|
||||
mod user;
|
||||
mod user_email;
|
||||
mod user_name;
|
||||
mod user_password;
|
||||
|
||||
pub use sign_in::*;
|
||||
pub use sign_up::*;
|
||||
pub use user::*;
|
||||
pub use user_email::*;
|
||||
pub use user_name::*;
|
||||
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 std::sync::PoisonError;
|
||||
use derive_more::Display;
|
||||
use flowy_dispatch::prelude::{DispatchError, EventResponse, ResponseBuilder, StatusCode};
|
||||
use std::{io, sync::PoisonError};
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone, Display)]
|
||||
pub enum UserError {
|
||||
DBInit(String),
|
||||
DBNotInit,
|
||||
UserNotLogin,
|
||||
DBConnection(String),
|
||||
#[display(fmt = "User db error:{}", _0)]
|
||||
Database(String),
|
||||
#[display(fmt = "User auth error:{}", _0)]
|
||||
Auth(String),
|
||||
#[display(fmt = "User sync error: {}", _0)]
|
||||
PoisonError(String),
|
||||
}
|
||||
|
||||
impl std::convert::From<DataBaseError> for UserError {
|
||||
fn from(error: DataBaseError) -> Self { UserError::DBInit(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_database::result::Error> for UserError {
|
||||
fn from(error: flowy_database::result::Error) -> Self {
|
||||
UserError::Database(format!("{:?}", error))
|
||||
}
|
||||
}
|
||||
|
||||
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 std::{convert::TryInto, sync::Arc};
|
||||
|
||||
@ -22,15 +22,18 @@ pub async fn user_sign_in(data: Data<SignInRequest>) -> ResponseResult<SignInRes
|
||||
skip(data, session),
|
||||
fields(
|
||||
email = %data.email,
|
||||
name = %data.name,
|
||||
)
|
||||
)]
|
||||
pub async fn user_sign_up(
|
||||
data: Data<SignUpRequest>,
|
||||
session: ModuleData<Arc<UserSession>>,
|
||||
) -> ResponseResult<SignUpResponse, String> {
|
||||
let _params: SignUpParams = data.into_inner().try_into()?;
|
||||
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)
|
||||
}
|
||||
|
@ -4,7 +4,11 @@ pub mod event;
|
||||
mod handlers;
|
||||
pub mod module;
|
||||
mod protobuf;
|
||||
mod services;
|
||||
|
||||
#[macro_use]
|
||||
extern crate flowy_database;
|
||||
|
||||
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 crate::{
|
||||
domain::{user_db::*, user_session::UserSession},
|
||||
event::UserEvent,
|
||||
handlers::*,
|
||||
};
|
||||
use crate::{event::UserEvent, handlers::*, services::user_session::UserSession};
|
||||
use std::sync::Arc;
|
||||
|
||||
pub fn create(user_session: Arc<UserSession>) -> Module {
|
||||
|
@ -26,6 +26,7 @@
|
||||
#[derive(PartialEq,Clone,Default)]
|
||||
pub struct User {
|
||||
// message fields
|
||||
pub id: ::std::string::String,
|
||||
pub name: ::std::string::String,
|
||||
pub email: ::std::string::String,
|
||||
pub password: ::std::string::String,
|
||||
@ -45,7 +46,33 @@ impl User {
|
||||
::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 {
|
||||
@ -71,7 +98,7 @@ impl User {
|
||||
::std::mem::replace(&mut self.name, ::std::string::String::new())
|
||||
}
|
||||
|
||||
// string email = 2;
|
||||
// string email = 3;
|
||||
|
||||
|
||||
pub fn get_email(&self) -> &str {
|
||||
@ -97,7 +124,7 @@ impl User {
|
||||
::std::mem::replace(&mut self.email, ::std::string::String::new())
|
||||
}
|
||||
|
||||
// string password = 3;
|
||||
// string password = 4;
|
||||
|
||||
|
||||
pub fn get_password(&self) -> &str {
|
||||
@ -134,12 +161,15 @@ impl ::protobuf::Message for User {
|
||||
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.name)?;
|
||||
::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?;
|
||||
},
|
||||
2 => {
|
||||
::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.email)?;
|
||||
::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.name)?;
|
||||
},
|
||||
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)?;
|
||||
},
|
||||
_ => {
|
||||
@ -154,14 +184,17 @@ impl ::protobuf::Message for User {
|
||||
#[allow(unused_variables)]
|
||||
fn compute_size(&self) -> u32 {
|
||||
let mut my_size = 0;
|
||||
if !self.id.is_empty() {
|
||||
my_size += ::protobuf::rt::string_size(1, &self.id);
|
||||
}
|
||||
if !self.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() {
|
||||
my_size += ::protobuf::rt::string_size(2, &self.email);
|
||||
my_size += ::protobuf::rt::string_size(3, &self.email);
|
||||
}
|
||||
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());
|
||||
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<()> {
|
||||
if !self.id.is_empty() {
|
||||
os.write_string(1, &self.id)?;
|
||||
}
|
||||
if !self.name.is_empty() {
|
||||
os.write_string(1, &self.name)?;
|
||||
os.write_string(2, &self.name)?;
|
||||
}
|
||||
if !self.email.is_empty() {
|
||||
os.write_string(2, &self.email)?;
|
||||
os.write_string(3, &self.email)?;
|
||||
}
|
||||
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())?;
|
||||
::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;
|
||||
descriptor.get(|| {
|
||||
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>(
|
||||
"name",
|
||||
|m: &User| { &m.name },
|
||||
@ -247,6 +288,7 @@ impl ::protobuf::Message for User {
|
||||
|
||||
impl ::protobuf::Clear for User {
|
||||
fn clear(&mut self) {
|
||||
self.id.clear();
|
||||
self.name.clear();
|
||||
self.email.clear();
|
||||
self.password.clear();
|
||||
@ -267,19 +309,23 @@ impl ::protobuf::reflect::ProtobufValue for User {
|
||||
}
|
||||
|
||||
static file_descriptor_proto_data: &'static [u8] = b"\
|
||||
\n\nuser.proto\"L\n\x04User\x12\x12\n\x04name\x18\x01\x20\x01(\tR\x04nam\
|
||||
e\x12\x14\n\x05email\x18\x02\x20\x01(\tR\x05email\x12\x1a\n\x08password\
|
||||
\x18\x03\x20\x01(\tR\x08passwordJ\xcf\x01\n\x06\x12\x04\0\0\x06\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\x0c\n\x0b\n\x04\x04\0\x02\0\x12\x03\x03\
|
||||
\x04\x14\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\x0f\n\x0c\n\x05\x04\0\x02\0\x03\x12\x03\x03\
|
||||
\x12\x13\n\x0b\n\x04\x04\0\x02\x01\x12\x03\x04\x04\x15\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\x10\n\x0c\n\x05\x04\0\x02\x01\x03\x12\x03\x04\x13\x14\n\x0b\n\x04\
|
||||
\x04\0\x02\x02\x12\x03\x05\x04\x18\n\x0c\n\x05\x04\0\x02\x02\x05\x12\x03\
|
||||
\x05\x04\n\n\x0c\n\x05\x04\0\x02\x02\x01\x12\x03\x05\x0b\x13\n\x0c\n\x05\
|
||||
\x04\0\x02\x02\x03\x12\x03\x05\x16\x17b\x06proto3\
|
||||
\n\nuser.proto\"\\\n\x04User\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\
|
||||
\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x14\n\x05email\x18\
|
||||
\x03\x20\x01(\tR\x05email\x12\x1a\n\x08password\x18\x04\x20\x01(\tR\x08p\
|
||||
asswordJ\x86\x02\n\x06\x12\x04\0\0\x07\x01\n\x08\n\x01\x0c\x12\x03\0\0\
|
||||
\x12\n\n\n\x02\x04\0\x12\x04\x02\0\x07\x01\n\n\n\x03\x04\0\x01\x12\x03\
|
||||
\x02\x08\x0c\n\x0b\n\x04\x04\0\x02\0\x12\x03\x03\x04\x12\n\x0c\n\x05\x04\
|
||||
\0\x02\0\x05\x12\x03\x03\x04\n\n\x0c\n\x05\x04\0\x02\0\x01\x12\x03\x03\
|
||||
\x0b\r\n\x0c\n\x05\x04\0\x02\0\x03\x12\x03\x03\x10\x11\n\x0b\n\x04\x04\0\
|
||||
\x02\x01\x12\x03\x04\x04\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\x15\n\x0c\n\x05\x04\0\x02\x02\x05\x12\x03\x05\x04\n\n\x0c\n\x05\x04\
|
||||
\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;
|
||||
|
@ -1,7 +1,8 @@
|
||||
syntax = "proto3";
|
||||
|
||||
message User {
|
||||
string name = 1;
|
||||
string email = 2;
|
||||
string password = 3;
|
||||
string id = 1;
|
||||
string name = 2;
|
||||
string email = 3;
|
||||
string password = 4;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::errors::UserError;
|
||||
use flowy_database::{DBConnection, DataBase};
|
||||
use flowy_database::{DBConnection, Database};
|
||||
use lazy_static::lazy_static;
|
||||
use std::{
|
||||
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);
|
||||
|
||||
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 {
|
||||
@ -37,17 +37,23 @@ impl UserDB {
|
||||
}
|
||||
|
||||
fn open_user_db(&self, user_id: &str) -> Result<(), UserError> {
|
||||
let user_dir = format!("{}/{}", self.db_dir, user_id);
|
||||
let database = flowy_database::init(&user_dir)?;
|
||||
let mut write_guard = USER_DB_INNER.write()?;
|
||||
let dir = format!("{}/{}", self.db_dir, user_id);
|
||||
let db = flowy_database::init(&dir).map_err(|e| UserError::Database(format!("{:?}", e)))?;
|
||||
|
||||
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()));
|
||||
*(write_guard) = Some(database);
|
||||
IS_USER_DB_INIT.store(true, Ordering::SeqCst);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
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;
|
||||
set_user_id(None);
|
||||
IS_USER_DB_INIT.store(false, Ordering::SeqCst);
|
||||
@ -62,16 +68,20 @@ impl UserDB {
|
||||
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: {}",
|
||||
"Database owner does not match. origin: {:?}, current: {}",
|
||||
thread_user_id, user_id
|
||||
);
|
||||
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() {
|
||||
None => Err(UserError::DBNotInit),
|
||||
None => Err(UserError::Database(
|
||||
"Database is not initialization".to_owned(),
|
||||
)),
|
||||
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(),
|
||||
};
|
||||
|
||||
let response = EventTester::new(SignUp)
|
||||
.request(request)
|
||||
.sync_send()
|
||||
.parse::<SignUpResponse>();
|
||||
dbg!(&response);
|
||||
let response = EventTester::new(SignUp).request(request).sync_send();
|
||||
// .parse::<SignUpResponse>();
|
||||
// dbg!(&response);
|
||||
}
|
||||
|
||||
#[test]
|
@ -1 +1 @@
|
||||
mod auth;
|
||||
mod auth_test;
|
||||
|
Loading…
Reference in New Issue
Block a user