mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
fix: migrate anon user to appflowy cloud (#4106)
* chore: fix migrate anon user to appflowy cloud * chore: remove log * fix: test * chore: fmt
This commit is contained in:
parent
d765806337
commit
4837d7f7fe
@ -202,4 +202,4 @@ SPEC CHECKSUMS:
|
||||
|
||||
PODFILE CHECKSUM: 8c681999c7764593c94846b2a64b44d86f7a27ac
|
||||
|
||||
COCOAPODS: 1.12.1
|
||||
COCOAPODS: 1.11.3
|
||||
|
@ -346,9 +346,11 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
DEAD_CODE_STRIPPING = NO;
|
||||
DEVELOPMENT_TEAM = "";
|
||||
DEVELOPMENT_TEAM = VHB67HRSZG;
|
||||
ENABLE_BITCODE = NO;
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = AppFlowy;
|
||||
@ -359,6 +361,7 @@
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.appflowy.appflowy.flutter;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
STRIP_STYLE = "non-global";
|
||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
@ -482,9 +485,11 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
DEAD_CODE_STRIPPING = NO;
|
||||
DEVELOPMENT_TEAM = "";
|
||||
DEVELOPMENT_TEAM = VHB67HRSZG;
|
||||
ENABLE_BITCODE = NO;
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = AppFlowy;
|
||||
@ -495,6 +500,7 @@
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.appflowy.appflowy.flutter;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
STRIP_STYLE = "non-global";
|
||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
@ -513,6 +519,8 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
DEAD_CODE_STRIPPING = NO;
|
||||
DEVELOPMENT_TEAM = VHB67HRSZG;
|
||||
@ -526,6 +534,7 @@
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.appflowy.appflowy.flutter;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
STRIP_STYLE = "non-global";
|
||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
|
18
frontend/appflowy_tauri/src-tauri/Cargo.lock
generated
18
frontend/appflowy_tauri/src-tauri/Cargo.lock
generated
@ -139,7 +139,7 @@ checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
|
||||
[[package]]
|
||||
name = "app-error"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=f13a03beada8b7c3991f98016ccc0b708b22090c#f13a03beada8b7c3991f98016ccc0b708b22090c"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ee31a680b5789b8c7c5397e6eadd4dd7739526f9#ee31a680b5789b8c7c5397e6eadd4dd7739526f9"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"reqwest",
|
||||
@ -786,7 +786,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "client-api"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=f13a03beada8b7c3991f98016ccc0b708b22090c#f13a03beada8b7c3991f98016ccc0b708b22090c"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ee31a680b5789b8c7c5397e6eadd4dd7739526f9#ee31a680b5789b8c7c5397e6eadd4dd7739526f9"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"app-error",
|
||||
@ -1469,7 +1469,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308"
|
||||
[[package]]
|
||||
name = "database-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=f13a03beada8b7c3991f98016ccc0b708b22090c#f13a03beada8b7c3991f98016ccc0b708b22090c"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ee31a680b5789b8c7c5397e6eadd4dd7739526f9#ee31a680b5789b8c7c5397e6eadd4dd7739526f9"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"app-error",
|
||||
@ -2828,7 +2828,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "gotrue"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=f13a03beada8b7c3991f98016ccc0b708b22090c#f13a03beada8b7c3991f98016ccc0b708b22090c"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ee31a680b5789b8c7c5397e6eadd4dd7739526f9#ee31a680b5789b8c7c5397e6eadd4dd7739526f9"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"futures-util",
|
||||
@ -2844,7 +2844,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "gotrue-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=f13a03beada8b7c3991f98016ccc0b708b22090c#f13a03beada8b7c3991f98016ccc0b708b22090c"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ee31a680b5789b8c7c5397e6eadd4dd7739526f9#ee31a680b5789b8c7c5397e6eadd4dd7739526f9"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"app-error",
|
||||
@ -3266,7 +3266,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "infra"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=f13a03beada8b7c3991f98016ccc0b708b22090c#f13a03beada8b7c3991f98016ccc0b708b22090c"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ee31a680b5789b8c7c5397e6eadd4dd7739526f9#ee31a680b5789b8c7c5397e6eadd4dd7739526f9"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"reqwest",
|
||||
@ -5026,7 +5026,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "realtime-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=f13a03beada8b7c3991f98016ccc0b708b22090c#f13a03beada8b7c3991f98016ccc0b708b22090c"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ee31a680b5789b8c7c5397e6eadd4dd7739526f9#ee31a680b5789b8c7c5397e6eadd4dd7739526f9"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bincode",
|
||||
@ -5779,7 +5779,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "shared_entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=f13a03beada8b7c3991f98016ccc0b708b22090c#f13a03beada8b7c3991f98016ccc0b708b22090c"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ee31a680b5789b8c7c5397e6eadd4dd7739526f9#ee31a680b5789b8c7c5397e6eadd4dd7739526f9"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"app-error",
|
||||
@ -7669,7 +7669,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "workspace-template"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=f13a03beada8b7c3991f98016ccc0b708b22090c#f13a03beada8b7c3991f98016ccc0b708b22090c"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ee31a680b5789b8c7c5397e6eadd4dd7739526f9#ee31a680b5789b8c7c5397e6eadd4dd7739526f9"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
|
@ -57,7 +57,7 @@ custom-protocol = ["tauri/custom-protocol"]
|
||||
# Run the script:
|
||||
# scripts/tool/update_client_api_rev.sh new_rev_id
|
||||
# ⚠️⚠️⚠️️
|
||||
client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "f13a03beada8b7c3991f98016ccc0b708b22090c" }
|
||||
client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "ee31a680b5789b8c7c5397e6eadd4dd7739526f9" }
|
||||
# Please use the following script to update collab.
|
||||
# Working directory: frontend
|
||||
#
|
||||
|
40
frontend/rust-lib/Cargo.lock
generated
40
frontend/rust-lib/Cargo.lock
generated
@ -125,7 +125,7 @@ checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
|
||||
[[package]]
|
||||
name = "app-error"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=f13a03beada8b7c3991f98016ccc0b708b22090c#f13a03beada8b7c3991f98016ccc0b708b22090c"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ee31a680b5789b8c7c5397e6eadd4dd7739526f9#ee31a680b5789b8c7c5397e6eadd4dd7739526f9"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"reqwest",
|
||||
@ -667,7 +667,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "client-api"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=f13a03beada8b7c3991f98016ccc0b708b22090c#f13a03beada8b7c3991f98016ccc0b708b22090c"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ee31a680b5789b8c7c5397e6eadd4dd7739526f9#ee31a680b5789b8c7c5397e6eadd4dd7739526f9"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"app-error",
|
||||
@ -1147,7 +1147,7 @@ dependencies = [
|
||||
"cssparser-macros",
|
||||
"dtoa-short",
|
||||
"itoa",
|
||||
"phf 0.11.2",
|
||||
"phf 0.8.0",
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
@ -1275,7 +1275,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308"
|
||||
[[package]]
|
||||
name = "database-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=f13a03beada8b7c3991f98016ccc0b708b22090c#f13a03beada8b7c3991f98016ccc0b708b22090c"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ee31a680b5789b8c7c5397e6eadd4dd7739526f9#ee31a680b5789b8c7c5397e6eadd4dd7739526f9"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"app-error",
|
||||
@ -2469,7 +2469,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "gotrue"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=f13a03beada8b7c3991f98016ccc0b708b22090c#f13a03beada8b7c3991f98016ccc0b708b22090c"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ee31a680b5789b8c7c5397e6eadd4dd7739526f9#ee31a680b5789b8c7c5397e6eadd4dd7739526f9"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"futures-util",
|
||||
@ -2485,7 +2485,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "gotrue-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=f13a03beada8b7c3991f98016ccc0b708b22090c#f13a03beada8b7c3991f98016ccc0b708b22090c"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ee31a680b5789b8c7c5397e6eadd4dd7739526f9#ee31a680b5789b8c7c5397e6eadd4dd7739526f9"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"app-error",
|
||||
@ -2846,7 +2846,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "infra"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=f13a03beada8b7c3991f98016ccc0b708b22090c#f13a03beada8b7c3991f98016ccc0b708b22090c"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ee31a680b5789b8c7c5397e6eadd4dd7739526f9#ee31a680b5789b8c7c5397e6eadd4dd7739526f9"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"reqwest",
|
||||
@ -3651,7 +3651,7 @@ version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12"
|
||||
dependencies = [
|
||||
"phf_macros 0.8.0",
|
||||
"phf_macros",
|
||||
"phf_shared 0.8.0",
|
||||
"proc-macro-hack",
|
||||
]
|
||||
@ -3671,7 +3671,6 @@ version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc"
|
||||
dependencies = [
|
||||
"phf_macros 0.11.2",
|
||||
"phf_shared 0.11.2",
|
||||
]
|
||||
|
||||
@ -3739,19 +3738,6 @@ dependencies = [
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_macros"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b"
|
||||
dependencies = [
|
||||
"phf_generator 0.11.2",
|
||||
"phf_shared 0.11.2",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.31",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_shared"
|
||||
version = "0.8.0"
|
||||
@ -3955,7 +3941,7 @@ checksum = "8bdf592881d821b83d471f8af290226c8d51402259e9bb5be7f9f8bdebbb11ac"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"heck 0.4.1",
|
||||
"itertools 0.11.0",
|
||||
"itertools 0.10.5",
|
||||
"log",
|
||||
"multimap",
|
||||
"once_cell",
|
||||
@ -3976,7 +3962,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "265baba7fabd416cf5078179f7d2cbeca4ce7a9041111900675ea7c4cb8a4c32"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"itertools 0.11.0",
|
||||
"itertools 0.10.5",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.31",
|
||||
@ -4315,7 +4301,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "realtime-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=f13a03beada8b7c3991f98016ccc0b708b22090c#f13a03beada8b7c3991f98016ccc0b708b22090c"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ee31a680b5789b8c7c5397e6eadd4dd7739526f9#ee31a680b5789b8c7c5397e6eadd4dd7739526f9"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bincode",
|
||||
@ -4981,7 +4967,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "shared_entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=f13a03beada8b7c3991f98016ccc0b708b22090c#f13a03beada8b7c3991f98016ccc0b708b22090c"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ee31a680b5789b8c7c5397e6eadd4dd7739526f9#ee31a680b5789b8c7c5397e6eadd4dd7739526f9"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"app-error",
|
||||
@ -6319,7 +6305,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "workspace-template"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=f13a03beada8b7c3991f98016ccc0b708b22090c#f13a03beada8b7c3991f98016ccc0b708b22090c"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ee31a680b5789b8c7c5397e6eadd4dd7739526f9#ee31a680b5789b8c7c5397e6eadd4dd7739526f9"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
|
@ -99,7 +99,7 @@ incremental = false
|
||||
# Run the script:
|
||||
# scripts/tool/update_client_api_rev.sh new_rev_id
|
||||
# ⚠️⚠️⚠️️
|
||||
client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "f13a03beada8b7c3991f98016ccc0b708b22090c" }
|
||||
client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "ee31a680b5789b8c7c5397e6eadd4dd7739526f9" }
|
||||
# Please use the following script to update collab.
|
||||
# Working directory: frontend
|
||||
#
|
||||
|
@ -1,2 +1,3 @@
|
||||
mod auth_test;
|
||||
mod member_test;
|
||||
mod sync_anon_data_test;
|
||||
|
@ -0,0 +1 @@
|
||||
|
@ -1,5 +1,7 @@
|
||||
pub use anon_user_data::*;
|
||||
pub use sync_new_user::*;
|
||||
pub use sync_af_cloud_new_user::*;
|
||||
pub use sync_supabase_new_user::*;
|
||||
|
||||
mod anon_user_data;
|
||||
mod sync_new_user;
|
||||
mod sync_af_cloud_new_user;
|
||||
mod sync_supabase_new_user;
|
||||
|
@ -0,0 +1,369 @@
|
||||
use std::future::Future;
|
||||
use std::ops::Deref;
|
||||
use std::pin::Pin;
|
||||
use std::sync::Arc;
|
||||
|
||||
use anyhow::{anyhow, Error};
|
||||
use collab::core::collab::MutexCollab;
|
||||
use collab::preclude::Collab;
|
||||
use collab_database::database::get_database_row_ids;
|
||||
use collab_database::rows::database_row_document_id_from_row_id;
|
||||
use collab_database::user::{get_database_with_views, DatabaseWithViews};
|
||||
use collab_entity::{CollabObject, CollabType};
|
||||
use collab_folder::{Folder, View, ViewLayout};
|
||||
use parking_lot::Mutex;
|
||||
|
||||
use collab_integrate::{PersistenceError, RocksCollabDB, YrsDocAction};
|
||||
use flowy_error::FlowyResult;
|
||||
use flowy_user_deps::cloud::UserCloudService;
|
||||
|
||||
use crate::migrations::MigrationUser;
|
||||
|
||||
#[tracing::instrument(level = "info", skip_all, err)]
|
||||
pub async fn sync_af_user_data_to_cloud(
|
||||
user_service: Arc<dyn UserCloudService>,
|
||||
device_id: &str,
|
||||
new_user: &MigrationUser,
|
||||
collab_db: &Arc<RocksCollabDB>,
|
||||
) -> FlowyResult<()> {
|
||||
let workspace_id = new_user.session.user_workspace.id.clone();
|
||||
let uid = new_user.session.user_id;
|
||||
let folder = Arc::new(
|
||||
sync_folder(
|
||||
uid,
|
||||
&workspace_id,
|
||||
device_id,
|
||||
collab_db,
|
||||
user_service.clone(),
|
||||
)
|
||||
.await?,
|
||||
);
|
||||
|
||||
let database_records = sync_database_views(
|
||||
uid,
|
||||
&workspace_id,
|
||||
device_id,
|
||||
&new_user.session.user_workspace.database_views_aggregate_id,
|
||||
collab_db,
|
||||
user_service.clone(),
|
||||
)
|
||||
.await;
|
||||
|
||||
let views = folder.lock().get_current_workspace_views();
|
||||
for view in views {
|
||||
let view_id = view.id.clone();
|
||||
if let Err(err) = sync_view(
|
||||
uid,
|
||||
folder.clone(),
|
||||
database_records.clone(),
|
||||
workspace_id.to_string(),
|
||||
device_id.to_string(),
|
||||
view,
|
||||
collab_db.clone(),
|
||||
user_service.clone(),
|
||||
)
|
||||
.await
|
||||
{
|
||||
tracing::error!("🔴sync {} failed: {:?}", view_id, err);
|
||||
}
|
||||
}
|
||||
tokio::task::yield_now().await;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn sync_view(
|
||||
uid: i64,
|
||||
folder: Arc<MutexFolder>,
|
||||
database_records: Vec<Arc<DatabaseWithViews>>,
|
||||
workspace_id: String,
|
||||
device_id: String,
|
||||
view: Arc<View>,
|
||||
collab_db: Arc<RocksCollabDB>,
|
||||
user_service: Arc<dyn UserCloudService>,
|
||||
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + Sync>> {
|
||||
Box::pin(async move {
|
||||
let collab_type = collab_type_from_view_layout(&view.layout);
|
||||
let object_id = object_id_from_view(&view, &database_records)?;
|
||||
tracing::debug!(
|
||||
"sync view: {:?}:{} with object_id: {}",
|
||||
view.layout,
|
||||
view.id,
|
||||
object_id
|
||||
);
|
||||
|
||||
let collab_object = CollabObject::new(
|
||||
uid,
|
||||
object_id,
|
||||
collab_type,
|
||||
workspace_id.to_string(),
|
||||
device_id.clone(),
|
||||
);
|
||||
|
||||
match view.layout {
|
||||
ViewLayout::Document => {
|
||||
let encode_v1 = get_collab_encode_v1(uid, &collab_object, &collab_db)?;
|
||||
tracing::info!(
|
||||
"sync object: {} with update: {}",
|
||||
collab_object,
|
||||
encode_v1.len()
|
||||
);
|
||||
user_service
|
||||
.create_collab_object(&collab_object, encode_v1)
|
||||
.await?;
|
||||
},
|
||||
ViewLayout::Grid | ViewLayout::Board | ViewLayout::Calendar => {
|
||||
let (database_encode_v1, row_ids) =
|
||||
get_database_encode_v1(uid, &collab_object, &collab_db)?;
|
||||
tracing::info!(
|
||||
"sync object: {} with update: {}",
|
||||
collab_object,
|
||||
database_encode_v1.len()
|
||||
);
|
||||
user_service
|
||||
.create_collab_object(&collab_object, database_encode_v1)
|
||||
.await?;
|
||||
|
||||
// sync database's row
|
||||
for row_id in row_ids {
|
||||
tracing::debug!("sync row: {}", row_id);
|
||||
let document_id = database_row_document_id_from_row_id(&row_id);
|
||||
|
||||
let database_row_collab_object = CollabObject::new(
|
||||
uid,
|
||||
row_id,
|
||||
CollabType::DatabaseRow,
|
||||
workspace_id.to_string(),
|
||||
device_id.clone(),
|
||||
);
|
||||
let database_row_encode_v1 =
|
||||
get_collab_encode_v1(uid, &database_row_collab_object, &collab_db)?;
|
||||
tracing::info!(
|
||||
"sync object: {} with update: {}",
|
||||
database_row_collab_object,
|
||||
database_row_encode_v1.len()
|
||||
);
|
||||
|
||||
let _ = user_service
|
||||
.create_collab_object(&database_row_collab_object, database_row_encode_v1)
|
||||
.await;
|
||||
|
||||
let database_row_document = CollabObject::new(
|
||||
uid,
|
||||
document_id,
|
||||
CollabType::Document,
|
||||
workspace_id.to_string(),
|
||||
device_id.to_string(),
|
||||
);
|
||||
// sync document in the row if exist
|
||||
if let Ok(document_encode_v1) =
|
||||
get_collab_encode_v1(uid, &database_row_document, &collab_db)
|
||||
{
|
||||
tracing::info!(
|
||||
"sync database row document: {} with update: {}",
|
||||
database_row_document,
|
||||
document_encode_v1.len()
|
||||
);
|
||||
let _ = user_service
|
||||
.create_collab_object(&database_row_document, document_encode_v1)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
tokio::task::yield_now().await;
|
||||
|
||||
let child_views = folder.lock().views.get_views_belong_to(&view.id);
|
||||
for child_view in child_views {
|
||||
let cloned_child_view = child_view.clone();
|
||||
if let Err(err) = Box::pin(sync_view(
|
||||
uid,
|
||||
folder.clone(),
|
||||
database_records.clone(),
|
||||
workspace_id.clone(),
|
||||
device_id.to_string(),
|
||||
child_view,
|
||||
collab_db.clone(),
|
||||
user_service.clone(),
|
||||
))
|
||||
.await
|
||||
{
|
||||
tracing::error!(
|
||||
"🔴sync {:?}:{} failed: {:?}",
|
||||
cloned_child_view.layout,
|
||||
cloned_child_view.id,
|
||||
err
|
||||
)
|
||||
}
|
||||
tokio::task::yield_now().await;
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
fn get_collab_encode_v1(
|
||||
uid: i64,
|
||||
collab_object: &CollabObject,
|
||||
collab_db: &Arc<RocksCollabDB>,
|
||||
) -> Result<Vec<u8>, PersistenceError> {
|
||||
let collab = Collab::new(uid, &collab_object.object_id, "phantom", vec![]);
|
||||
let _ = collab.with_origin_transact_mut(|txn| {
|
||||
collab_db
|
||||
.read_txn()
|
||||
.load_doc_with_txn(uid, &collab_object.object_id, txn)
|
||||
})?;
|
||||
Ok(collab.encode_collab_v1().encode_to_bytes()?)
|
||||
}
|
||||
|
||||
fn get_database_encode_v1(
|
||||
uid: i64,
|
||||
collab_object: &CollabObject,
|
||||
collab_db: &Arc<RocksCollabDB>,
|
||||
) -> Result<(Vec<u8>, Vec<String>), PersistenceError> {
|
||||
let collab = Collab::new(uid, &collab_object.object_id, "phantom", vec![]);
|
||||
let _ = collab.with_origin_transact_mut(|txn| {
|
||||
collab_db
|
||||
.read_txn()
|
||||
.load_doc_with_txn(uid, &collab_object.object_id, txn)
|
||||
})?;
|
||||
|
||||
let row_ids = get_database_row_ids(&collab).unwrap_or_default();
|
||||
Ok((collab.encode_collab_v1().encode_to_bytes()?, row_ids))
|
||||
}
|
||||
|
||||
async fn sync_folder(
|
||||
uid: i64,
|
||||
workspace_id: &str,
|
||||
device_id: &str,
|
||||
collab_db: &Arc<RocksCollabDB>,
|
||||
user_service: Arc<dyn UserCloudService>,
|
||||
) -> Result<MutexFolder, Error> {
|
||||
let (folder, encode_v1) = {
|
||||
let collab = Collab::new(uid, workspace_id, "phantom", vec![]);
|
||||
// Use the temporary result to short the lifetime of the TransactionMut
|
||||
collab.with_origin_transact_mut(|txn| {
|
||||
collab_db
|
||||
.read_txn()
|
||||
.load_doc_with_txn(uid, workspace_id, txn)
|
||||
})?;
|
||||
let data = collab.encode_collab_v1().encode_to_bytes();
|
||||
(
|
||||
MutexFolder::new(Folder::open(
|
||||
uid,
|
||||
Arc::new(MutexCollab::from_collab(collab)),
|
||||
None,
|
||||
)?),
|
||||
data,
|
||||
)
|
||||
};
|
||||
let encode_v1 = encode_v1?;
|
||||
let collab_object = CollabObject::new(
|
||||
uid,
|
||||
workspace_id.to_string(),
|
||||
CollabType::Folder,
|
||||
workspace_id.to_string(),
|
||||
device_id.to_string(),
|
||||
);
|
||||
tracing::info!(
|
||||
"sync object: {} with update: {}",
|
||||
collab_object,
|
||||
encode_v1.len()
|
||||
);
|
||||
if let Err(err) = user_service
|
||||
.create_collab_object(&collab_object, encode_v1)
|
||||
.await
|
||||
{
|
||||
tracing::error!("🔴sync folder failed: {:?}", err);
|
||||
}
|
||||
|
||||
Ok(folder)
|
||||
}
|
||||
|
||||
async fn sync_database_views(
|
||||
uid: i64,
|
||||
workspace_id: &str,
|
||||
device_id: &str,
|
||||
database_views_aggregate_id: &str,
|
||||
collab_db: &Arc<RocksCollabDB>,
|
||||
user_service: Arc<dyn UserCloudService>,
|
||||
) -> Vec<Arc<DatabaseWithViews>> {
|
||||
let collab_object = CollabObject::new(
|
||||
uid,
|
||||
database_views_aggregate_id.to_string(),
|
||||
CollabType::WorkspaceDatabase,
|
||||
workspace_id.to_string(),
|
||||
device_id.to_string(),
|
||||
);
|
||||
|
||||
// Use the temporary result to short the lifetime of the TransactionMut
|
||||
let result = {
|
||||
let collab = Collab::new(uid, database_views_aggregate_id, "phantom", vec![]);
|
||||
collab
|
||||
.with_origin_transact_mut(|txn| {
|
||||
collab_db
|
||||
.read_txn()
|
||||
.load_doc_with_txn(uid, database_views_aggregate_id, txn)
|
||||
})
|
||||
.map(|_| {
|
||||
(
|
||||
get_database_with_views(&collab),
|
||||
collab.encode_collab_v1().encode_to_bytes(),
|
||||
)
|
||||
})
|
||||
};
|
||||
|
||||
if let Ok((records, encode_v1)) = result {
|
||||
if let Ok(encode_v1) = encode_v1 {
|
||||
let _ = user_service
|
||||
.create_collab_object(&collab_object, encode_v1)
|
||||
.await;
|
||||
}
|
||||
|
||||
records.into_iter().map(Arc::new).collect()
|
||||
} else {
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
|
||||
struct MutexFolder(Mutex<Folder>);
|
||||
impl MutexFolder {
|
||||
pub fn new(folder: Folder) -> Self {
|
||||
Self(Mutex::new(folder))
|
||||
}
|
||||
}
|
||||
impl Deref for MutexFolder {
|
||||
type Target = Mutex<Folder>;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
unsafe impl Sync for MutexFolder {}
|
||||
unsafe impl Send for MutexFolder {}
|
||||
|
||||
fn collab_type_from_view_layout(view_layout: &ViewLayout) -> CollabType {
|
||||
match view_layout {
|
||||
ViewLayout::Document => CollabType::Document,
|
||||
ViewLayout::Grid | ViewLayout::Board | ViewLayout::Calendar => CollabType::Database,
|
||||
}
|
||||
}
|
||||
|
||||
fn object_id_from_view(
|
||||
view: &Arc<View>,
|
||||
database_records: &[Arc<DatabaseWithViews>],
|
||||
) -> Result<String, Error> {
|
||||
if view.layout.is_database() {
|
||||
match database_records
|
||||
.iter()
|
||||
.find(|record| record.linked_views.contains(&view.id))
|
||||
{
|
||||
None => Err(anyhow!(
|
||||
"🔴sync view: {} failed: no database for this view",
|
||||
view.id
|
||||
)),
|
||||
Some(record) => Ok(record.database_id.clone()),
|
||||
}
|
||||
} else {
|
||||
Ok(view.id.clone())
|
||||
}
|
||||
}
|
@ -20,7 +20,7 @@ use flowy_user_deps::cloud::UserCloudService;
|
||||
use crate::migrations::MigrationUser;
|
||||
|
||||
#[tracing::instrument(level = "info", skip_all, err)]
|
||||
pub async fn sync_user_data_to_cloud(
|
||||
pub async fn sync_supabase_user_data_to_cloud(
|
||||
user_service: Arc<dyn UserCloudService>,
|
||||
device_id: &str,
|
||||
new_user: &MigrationUser,
|
||||
@ -52,7 +52,7 @@ pub async fn sync_user_data_to_cloud(
|
||||
let views = folder.lock().get_current_workspace_views();
|
||||
for view in views {
|
||||
let view_id = view.id.clone();
|
||||
if let Err(err) = sync_views(
|
||||
if let Err(err) = sync_view(
|
||||
uid,
|
||||
folder.clone(),
|
||||
database_records.clone(),
|
||||
@ -72,7 +72,7 @@ pub async fn sync_user_data_to_cloud(
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn sync_views(
|
||||
fn sync_view(
|
||||
uid: i64,
|
||||
folder: Arc<MutexFolder>,
|
||||
database_records: Vec<Arc<DatabaseWithViews>>,
|
||||
@ -172,10 +172,12 @@ fn sync_views(
|
||||
},
|
||||
}
|
||||
|
||||
tokio::task::yield_now().await;
|
||||
|
||||
let child_views = folder.lock().views.get_views_belong_to(&view.id);
|
||||
for child_view in child_views {
|
||||
let cloned_child_view = child_view.clone();
|
||||
if let Err(err) = Box::pin(sync_views(
|
||||
if let Err(err) = Box::pin(sync_view(
|
||||
uid,
|
||||
folder.clone(),
|
||||
database_records.clone(),
|
||||
@ -194,6 +196,7 @@ fn sync_views(
|
||||
err
|
||||
)
|
||||
}
|
||||
tokio::task::yield_now().await;
|
||||
}
|
||||
Ok(())
|
||||
})
|
@ -26,7 +26,9 @@ use flowy_user_deps::entities::*;
|
||||
use lib_dispatch::prelude::af_spawn;
|
||||
use lib_infra::box_any::BoxAny;
|
||||
|
||||
use crate::anon_user_upgrade::{migration_anon_user_on_sign_up, sync_user_data_to_cloud};
|
||||
use crate::anon_user_upgrade::{
|
||||
migration_anon_user_on_sign_up, sync_af_user_data_to_cloud, sync_supabase_user_data_to_cloud,
|
||||
};
|
||||
use crate::entities::{AuthStateChangedPB, AuthStatePB, UserProfilePB, UserSettingPB};
|
||||
use crate::event_map::{DefaultUserStatusCallback, UserCloudServiceProvider, UserStatusCallback};
|
||||
use crate::migrations::document_empty_content::HistoricalEmptyDocumentMigration;
|
||||
@ -357,30 +359,30 @@ impl UserManager {
|
||||
params: BoxAny,
|
||||
) -> Result<UserProfile, FlowyError> {
|
||||
// sign out the current user if there is one
|
||||
let migration_user = self.get_migration_user(&authenticator).await;
|
||||
let _ = self.sign_out().await;
|
||||
|
||||
self.update_authenticator(&authenticator).await;
|
||||
let migration_user = self.get_migration_user(&authenticator).await;
|
||||
let auth_service = self.cloud_services.get_user_service()?;
|
||||
let response: AuthResponse = auth_service.sign_up(params).await?;
|
||||
let user_profile = UserProfile::from((&response, &authenticator));
|
||||
if user_profile.encryption_type.require_encrypt_secret() {
|
||||
let new_user_profile = UserProfile::from((&response, &authenticator));
|
||||
if new_user_profile.encryption_type.require_encrypt_secret() {
|
||||
self
|
||||
.resumable_sign_up
|
||||
.lock()
|
||||
.await
|
||||
.replace(ResumableSignUp {
|
||||
user_profile: user_profile.clone(),
|
||||
user_profile: new_user_profile.clone(),
|
||||
migration_user,
|
||||
response,
|
||||
authenticator,
|
||||
});
|
||||
} else {
|
||||
self
|
||||
.continue_sign_up(&user_profile, migration_user, response, &authenticator)
|
||||
.continue_sign_up(&new_user_profile, migration_user, response, &authenticator)
|
||||
.await?;
|
||||
}
|
||||
Ok(user_profile)
|
||||
Ok(new_user_profile)
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "info", skip(self))]
|
||||
@ -408,7 +410,7 @@ impl UserManager {
|
||||
#[tracing::instrument(level = "info", skip_all, err)]
|
||||
async fn continue_sign_up(
|
||||
&self,
|
||||
user_profile: &UserProfile,
|
||||
new_user_profile: &UserProfile,
|
||||
migration_user: Option<MigrationUser>,
|
||||
response: AuthResponse,
|
||||
authenticator: &Authenticator,
|
||||
@ -425,7 +427,7 @@ impl UserManager {
|
||||
if response.is_new_user {
|
||||
if let Some(old_user) = migration_user {
|
||||
let new_user = MigrationUser {
|
||||
user_profile: user_profile.clone(),
|
||||
user_profile: new_user_profile.clone(),
|
||||
session: new_session.clone(),
|
||||
};
|
||||
event!(
|
||||
@ -435,7 +437,7 @@ impl UserManager {
|
||||
new_user.user_profile.uid
|
||||
);
|
||||
self
|
||||
.migrate_anon_user_data_to_cloud(&old_user, &new_user)
|
||||
.migrate_anon_user_data_to_cloud(&old_user, &new_user, authenticator)
|
||||
.await?;
|
||||
let _ = self.database.close(old_user.session.user_id);
|
||||
}
|
||||
@ -454,7 +456,7 @@ impl UserManager {
|
||||
.await
|
||||
.did_sign_up(
|
||||
response.is_new_user,
|
||||
user_profile,
|
||||
new_user_profile,
|
||||
&new_session.user_workspace,
|
||||
&self.user_config.device_id,
|
||||
)
|
||||
@ -791,12 +793,15 @@ impl UserManager {
|
||||
&self,
|
||||
old_user: &MigrationUser,
|
||||
new_user: &MigrationUser,
|
||||
authenticator: &Authenticator,
|
||||
) -> Result<(), FlowyError> {
|
||||
let old_collab_db = self.database.get_collab_db(old_user.session.user_id)?;
|
||||
let new_collab_db = self.database.get_collab_db(new_user.session.user_id)?;
|
||||
migration_anon_user_on_sign_up(old_user, &old_collab_db, new_user, &new_collab_db)?;
|
||||
|
||||
if let Err(err) = sync_user_data_to_cloud(
|
||||
match authenticator {
|
||||
Authenticator::Supabase => {
|
||||
if let Err(err) = sync_supabase_user_data_to_cloud(
|
||||
self.cloud_services.get_user_service()?,
|
||||
&self.user_config.device_id,
|
||||
new_user,
|
||||
@ -806,6 +811,21 @@ impl UserManager {
|
||||
{
|
||||
error!("Sync user data to cloud failed: {:?}", err);
|
||||
}
|
||||
},
|
||||
Authenticator::AppFlowyCloud => {
|
||||
if let Err(err) = sync_af_user_data_to_cloud(
|
||||
self.cloud_services.get_user_service()?,
|
||||
&self.user_config.device_id,
|
||||
new_user,
|
||||
&new_collab_db,
|
||||
)
|
||||
.await
|
||||
{
|
||||
error!("Sync user data to cloud failed: {:?}", err);
|
||||
}
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
|
||||
// Save the old user workspace setting.
|
||||
save_user_workspaces(
|
||||
|
@ -2,7 +2,7 @@ use flowy_user_deps::entities::UserProfile;
|
||||
|
||||
use crate::services::entities::Session;
|
||||
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct MigrationUser {
|
||||
pub user_profile: UserProfile,
|
||||
pub session: Session,
|
||||
|
@ -34,6 +34,15 @@ pub struct UserDB {
|
||||
|
||||
impl UserDB {
|
||||
pub fn new(paths: impl UserDBPath) -> Self {
|
||||
// if let Some(mut db) = DB_MAP.try_write_for(Duration::from_millis(300)) {
|
||||
// info!("clear sqlite db map");
|
||||
// db.clear();
|
||||
// }
|
||||
//
|
||||
// if let Some(mut collab_db) = COLLAB_DB_MAP.try_write_for(Duration::from_millis(300)) {
|
||||
// info!("clear collab db map");
|
||||
// collab_db.clear();
|
||||
// }
|
||||
Self {
|
||||
paths: Box::new(paths),
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
use diesel::RunQueryDsl;
|
||||
use tracing::instrument;
|
||||
|
||||
use flowy_error::FlowyResult;
|
||||
use flowy_sqlite::schema::user_workspace_table;
|
||||
@ -13,6 +14,7 @@ use crate::services::user_workspace_sql::UserWorkspaceTable;
|
||||
|
||||
const HISTORICAL_USER: &str = "af_historical_users";
|
||||
impl UserManager {
|
||||
#[instrument(skip_all)]
|
||||
pub async fn get_migration_user(&self, auth_type: &Authenticator) -> Option<MigrationUser> {
|
||||
// Only migrate the data if the user is login in as a guest and sign up as a new user if the current
|
||||
// auth type is not [AuthType::Local].
|
||||
|
Loading…
Reference in New Issue
Block a user