mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2025-04-24 14:47:13 -04:00
chore: fix test
This commit is contained in:
parent
7e88a3897c
commit
db5e4766af
21 changed files with 297 additions and 278 deletions
|
@ -144,34 +144,34 @@ EXTERNAL SOURCES:
|
|||
:path: Flutter/ephemeral/.symlinks/plugins/window_manager/macos
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
app_links: 9028728e32c83a0831d9db8cf91c526d16cc5468
|
||||
appflowy_backend: 464aeb3e5c6966a41641a2111e5ead72ce2695f7
|
||||
auto_updater_macos: 3a42f1a06be6981f1a18be37e6e7bf86aa732118
|
||||
bitsdojo_window_macos: 7959fb0ca65a3ccda30095c181ecb856fae48ea9
|
||||
connectivity_plus: e74b9f74717d2d99d45751750e266e55912baeb5
|
||||
desktop_drop: e0b672a7d84c0a6cbc378595e82cdb15f2970a43
|
||||
device_info_plus: 4fb280989f669696856f8b129e4a5e3cd6c48f76
|
||||
file_selector_macos: 6280b52b459ae6c590af5d78fc35c7267a3c4b31
|
||||
flowy_infra_ui: 8760ff42a789de40bf5007a5f176b454722a341e
|
||||
app_links: 10e0a0ab602ffaf34d142cd4862f29d34b303b2a
|
||||
appflowy_backend: 865496343de667fc8c600e04b9fd05234e130cf9
|
||||
auto_updater_macos: 3e3462c418fe4e731917eacd8d28eef7af84086d
|
||||
bitsdojo_window_macos: 44e3b8fe3dd463820e0321f6256c5b1c16bb6a00
|
||||
connectivity_plus: 18d3c32514c886e046de60e9c13895109866c747
|
||||
desktop_drop: 69eeff437544aa619c8db7f4481b3a65f7696898
|
||||
device_info_plus: 1b14eed9bf95428983aed283a8d51cce3d8c4215
|
||||
file_selector_macos: cc3858c981fe6889f364731200d6232dac1d812d
|
||||
flowy_infra_ui: 03301a39ad118771adbf051a664265c61c507f38
|
||||
FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24
|
||||
HotKey: 400beb7caa29054ea8d864c96f5ba7e5b4852277
|
||||
hotkey_manager: b443f35f4d772162937aa73fd8995e579f8ac4e2
|
||||
irondash_engine_context: 893c7d96d20ce361d7e996f39d360c4c2f9869ba
|
||||
local_notifier: ebf072651e35ae5e47280ad52e2707375cb2ae4e
|
||||
package_info_plus: f0052d280d17aa382b932f399edf32507174e870
|
||||
path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564
|
||||
hotkey_manager: c32bf0bfe8f934b7bc17ab4ad5c4c142960b023c
|
||||
irondash_engine_context: da62996ee25616d2f01bbeb85dc115d813359478
|
||||
local_notifier: e9506bc66fc70311e8bc7291fb70f743c081e4ff
|
||||
package_info_plus: 12f1c5c2cfe8727ca46cbd0b26677728972d9a5b
|
||||
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
|
||||
ReachabilitySwift: 32793e867593cfc1177f5d16491e3a197d2fccda
|
||||
screen_retriever_macos: 452e51764a9e1cdb74b3c541238795849f21557f
|
||||
screen_retriever_macos: 776e0fa5d42c6163d2bf772d22478df4b302b161
|
||||
Sentry: 1fe34e9c2cbba1e347623610d26db121dcb569f1
|
||||
sentry_flutter: e24b397f9a61fa5bbefd8279c3b2242ca86faa90
|
||||
share_plus: 510bf0af1a42cd602274b4629920c9649c52f4cc
|
||||
shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7
|
||||
sentry_flutter: a39c2a2d67d5e5b9cb0b94a4985c76dd5b3fc737
|
||||
share_plus: 1fa619de8392a4398bfaf176d441853922614e89
|
||||
shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
|
||||
Sparkle: 5f8960a7a119aa7d45dacc0d5837017170bc5675
|
||||
sqflite_darwin: 20b2a3a3b70e43edae938624ce550a3cbf66a3d0
|
||||
super_native_extensions: c2795d6d9aedf4a79fae25cb6160b71b50549189
|
||||
url_launcher_macos: 0fba8ddabfc33ce0a9afe7c5fef5aab3d8d2d673
|
||||
webview_flutter_wkwebview: 44d4dee7d7056d5ad185d25b38404436d56c547c
|
||||
window_manager: 1d01fa7ac65a6e6f83b965471b1a7fdd3f06166c
|
||||
sqflite_darwin: 5a7236e3b501866c1c9befc6771dfd73ffb8702d
|
||||
super_native_extensions: 85efee3a7495b46b04befcfc86ed12069264ebf3
|
||||
url_launcher_macos: c82c93949963e55b228a30115bd219499a6fe404
|
||||
webview_flutter_wkwebview: 0982481e3d9c78fd5c6f62a002fcd24fc791f1e4
|
||||
window_manager: 3a1844359a6295ab1e47659b1a777e36773cd6e8
|
||||
|
||||
PODFILE CHECKSUM: 0532f3f001ca3110b8be345d6491fff690e95823
|
||||
|
||||
|
|
|
@ -11,7 +11,6 @@ async fn migrate_historical_empty_document_test() {
|
|||
"historical_empty_document",
|
||||
)
|
||||
.unwrap();
|
||||
let s = user_db_path.to_str().unwrap().to_string();
|
||||
let test =
|
||||
EventIntegrationTest::new_with_user_data_path(user_db_path, DEFAULT_NAME.to_string()).await;
|
||||
|
||||
|
|
|
@ -104,7 +104,7 @@ impl AIManager {
|
|||
}
|
||||
}
|
||||
|
||||
async fn reload_with_workspace_id(&self, workspace_id: &str) {
|
||||
async fn reload_with_workspace_id(&self, workspace_id: &Uuid) {
|
||||
// Check if local AI is enabled for this workspace and if we're in local mode
|
||||
let result = self.user_service.is_local_model().await;
|
||||
if let Err(err) = &result {
|
||||
|
@ -115,7 +115,9 @@ impl AIManager {
|
|||
}
|
||||
|
||||
let is_local = result.unwrap_or(false);
|
||||
let is_enabled = self.local_ai.is_enabled_on_workspace(workspace_id);
|
||||
let is_enabled = self
|
||||
.local_ai
|
||||
.is_enabled_on_workspace(&workspace_id.to_string());
|
||||
let is_running = self.local_ai.is_running();
|
||||
info!(
|
||||
"[AI Manager] Reloading workspace: {}, is_local: {}, is_enabled: {}, is_running: {}",
|
||||
|
@ -161,17 +163,17 @@ impl AIManager {
|
|||
}
|
||||
|
||||
#[instrument(skip_all, err)]
|
||||
pub async fn on_launch_if_authenticated(&self, workspace_id: &str) -> Result<(), FlowyError> {
|
||||
pub async fn on_launch_if_authenticated(&self, workspace_id: &Uuid) -> Result<(), FlowyError> {
|
||||
self.reload_with_workspace_id(workspace_id).await;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn initialize_after_sign_in(&self, workspace_id: &str) -> Result<(), FlowyError> {
|
||||
pub async fn initialize_after_sign_in(&self, workspace_id: &Uuid) -> Result<(), FlowyError> {
|
||||
self.reload_with_workspace_id(workspace_id).await;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn initialize_after_sign_up(&self, workspace_id: &str) -> Result<(), FlowyError> {
|
||||
pub async fn initialize_after_sign_up(&self, workspace_id: &Uuid) -> Result<(), FlowyError> {
|
||||
self.reload_with_workspace_id(workspace_id).await;
|
||||
Ok(())
|
||||
}
|
||||
|
@ -181,9 +183,7 @@ impl AIManager {
|
|||
&self,
|
||||
workspace_id: &Uuid,
|
||||
) -> Result<(), FlowyError> {
|
||||
self
|
||||
.reload_with_workspace_id(&workspace_id.to_string())
|
||||
.await;
|
||||
self.reload_with_workspace_id(workspace_id).await;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
@ -81,11 +81,10 @@ impl UserStatusCallback for UserStatusCallbackImpl {
|
|||
&self,
|
||||
user_id: i64,
|
||||
cloud_config: &Option<UserCloudConfig>,
|
||||
user_workspace: &UserWorkspace,
|
||||
workspace_id: &Uuid,
|
||||
_device_id: &str,
|
||||
auth_type: &AuthType,
|
||||
) -> FlowyResult<()> {
|
||||
let workspace_id = user_workspace.workspace_id()?;
|
||||
if let Some(cloud_config) = cloud_config {
|
||||
self
|
||||
.server_provider
|
||||
|
@ -101,7 +100,7 @@ impl UserStatusCallback for UserStatusCallbackImpl {
|
|||
.folder_manager
|
||||
.initialize(
|
||||
user_id,
|
||||
&workspace_id,
|
||||
workspace_id,
|
||||
FolderInitDataSource::LocalDisk {
|
||||
create_if_not_exist: false,
|
||||
},
|
||||
|
@ -113,8 +112,8 @@ impl UserStatusCallback for UserStatusCallbackImpl {
|
|||
.await?;
|
||||
self.document_manager.initialize(user_id).await?;
|
||||
|
||||
let workspace_id = user_workspace.id.clone();
|
||||
let cloned_ai_manager = self.ai_manager.clone();
|
||||
let workspace_id = *workspace_id;
|
||||
self.runtime.spawn(async move {
|
||||
if let Err(err) = cloned_ai_manager
|
||||
.on_launch_if_authenticated(&workspace_id)
|
||||
|
@ -129,19 +128,18 @@ impl UserStatusCallback for UserStatusCallbackImpl {
|
|||
async fn on_sign_in(
|
||||
&self,
|
||||
user_id: i64,
|
||||
user_workspace: &UserWorkspace,
|
||||
workspace_id: &Uuid,
|
||||
device_id: &str,
|
||||
auth_type: &AuthType,
|
||||
) -> FlowyResult<()> {
|
||||
event!(
|
||||
tracing::Level::TRACE,
|
||||
"Notify did sign in: latest_workspace: {:?}, device_id: {}",
|
||||
user_workspace,
|
||||
workspace_id,
|
||||
device_id
|
||||
);
|
||||
let workspace_id = user_workspace.workspace_id()?;
|
||||
let data_source = self
|
||||
.folder_init_data_source(user_id, &workspace_id, auth_type)
|
||||
.folder_init_data_source(user_id, workspace_id, auth_type)
|
||||
.await?;
|
||||
self
|
||||
.folder_manager
|
||||
|
@ -158,7 +156,7 @@ impl UserStatusCallback for UserStatusCallbackImpl {
|
|||
|
||||
self
|
||||
.ai_manager
|
||||
.initialize_after_sign_in(&user_workspace.id)
|
||||
.initialize_after_sign_in(workspace_id)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
|
@ -168,7 +166,7 @@ impl UserStatusCallback for UserStatusCallbackImpl {
|
|||
&self,
|
||||
is_new_user: bool,
|
||||
user_profile: &UserProfile,
|
||||
user_workspace: &UserWorkspace,
|
||||
workspace_id: &Uuid,
|
||||
device_id: &str,
|
||||
auth_type: &AuthType,
|
||||
) -> FlowyResult<()> {
|
||||
|
@ -176,12 +174,11 @@ impl UserStatusCallback for UserStatusCallbackImpl {
|
|||
tracing::Level::TRACE,
|
||||
"Notify did sign up: is new: {} user_workspace: {:?}, device_id: {}",
|
||||
is_new_user,
|
||||
user_workspace,
|
||||
workspace_id,
|
||||
device_id
|
||||
);
|
||||
let workspace_id = user_workspace.workspace_id()?;
|
||||
let data_source = self
|
||||
.folder_init_data_source(user_profile.uid, &workspace_id, auth_type)
|
||||
.folder_init_data_source(user_profile.uid, workspace_id, auth_type)
|
||||
.await?;
|
||||
|
||||
self
|
||||
|
@ -191,7 +188,7 @@ impl UserStatusCallback for UserStatusCallbackImpl {
|
|||
&user_profile.token,
|
||||
is_new_user,
|
||||
data_source,
|
||||
&workspace_id,
|
||||
workspace_id,
|
||||
)
|
||||
.await
|
||||
.context("FolderManager error")?;
|
||||
|
@ -210,7 +207,7 @@ impl UserStatusCallback for UserStatusCallbackImpl {
|
|||
|
||||
self
|
||||
.ai_manager
|
||||
.initialize_after_sign_up(&user_workspace.id)
|
||||
.initialize_after_sign_up(workspace_id)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1,106 +1,26 @@
|
|||
use crate::entities::{AuthType, UserAuthResponse, UserWorkspace};
|
||||
use base64::engine::general_purpose::STANDARD;
|
||||
use base64::Engine;
|
||||
use chrono::Utc;
|
||||
use serde::de::{MapAccess, Visitor};
|
||||
use serde::{Deserialize, Deserializer, Serialize};
|
||||
use serde_json::Value;
|
||||
use crate::entities::UserAuthResponse;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
use std::fmt::Display;
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Session {
|
||||
pub user_id: i64,
|
||||
pub user_uuid: Uuid,
|
||||
pub user_workspace: UserWorkspace,
|
||||
pub workspace_id: String,
|
||||
}
|
||||
|
||||
impl Display for Session {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"user_id: {}, user_workspace: {}:{}",
|
||||
self.user_id, self.user_workspace.name, self.user_workspace.id,
|
||||
"user_id: {}, user_workspace: {}",
|
||||
self.user_id, self.workspace_id,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
struct SessionVisitor;
|
||||
impl<'de> Visitor<'de> for SessionVisitor {
|
||||
type Value = Session;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("Session")
|
||||
}
|
||||
|
||||
fn visit_map<M>(self, mut map: M) -> Result<Self::Value, M::Error>
|
||||
where
|
||||
M: MapAccess<'de>,
|
||||
{
|
||||
let mut user_id = None;
|
||||
let mut user_uuid = None;
|
||||
// For historical reasons, the session used to contain a workspace_id field.
|
||||
// This field is no longer used, and is replaced by user_workspace.
|
||||
let mut workspace_id = None;
|
||||
let mut user_workspace = None;
|
||||
|
||||
while let Some(key) = map.next_key::<String>()? {
|
||||
match key.as_str() {
|
||||
"user_id" => {
|
||||
user_id = Some(map.next_value()?);
|
||||
},
|
||||
"user_uuid" => {
|
||||
user_uuid = Some(map.next_value()?);
|
||||
},
|
||||
"workspace_id" => {
|
||||
workspace_id = Some(map.next_value()?);
|
||||
},
|
||||
"user_workspace" => {
|
||||
user_workspace = Some(map.next_value()?);
|
||||
},
|
||||
_ => {
|
||||
let _ = map.next_value::<Value>();
|
||||
},
|
||||
}
|
||||
}
|
||||
let user_id = user_id.ok_or(serde::de::Error::missing_field("user_id"))?;
|
||||
let user_uuid = user_uuid.ok_or(serde::de::Error::missing_field("user_uuid"))?;
|
||||
if user_workspace.is_none() {
|
||||
if let Some(workspace_id) = workspace_id {
|
||||
user_workspace = Some(UserWorkspace {
|
||||
id: workspace_id,
|
||||
name: "My Workspace".to_string(),
|
||||
created_at: Utc::now(),
|
||||
// For historical reasons, the database_storage_id is constructed by the user_id.
|
||||
workspace_database_id: STANDARD.encode(format!("{}:user:database", user_id)),
|
||||
icon: "".to_owned(),
|
||||
member_count: 1,
|
||||
role: None,
|
||||
workspace_type: AuthType::Local,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
let session = Session {
|
||||
user_id,
|
||||
user_uuid,
|
||||
user_workspace: user_workspace.ok_or(serde::de::Error::missing_field("user_workspace"))?,
|
||||
};
|
||||
|
||||
Ok(session)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for Session {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
deserializer.deserialize_any(SessionVisitor)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<&T> for Session
|
||||
where
|
||||
T: UserAuthResponse,
|
||||
|
@ -109,7 +29,7 @@ where
|
|||
Self {
|
||||
user_id: value.user_id(),
|
||||
user_uuid: *value.user_uuid(),
|
||||
user_workspace: value.latest_workspace().clone(),
|
||||
workspace_id: value.latest_workspace().clone().id,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -99,6 +99,17 @@ pub fn select_user_workspace(
|
|||
Ok(row)
|
||||
}
|
||||
|
||||
pub fn select_user_workspace_type(
|
||||
workspace_id: &str,
|
||||
conn: &mut SqliteConnection,
|
||||
) -> FlowyResult<AuthType> {
|
||||
let row = dsl::user_workspace_table
|
||||
.filter(user_workspace_table::id.eq(workspace_id))
|
||||
.select(user_workspace_table::workspace_type)
|
||||
.first::<i32>(conn)?;
|
||||
Ok(AuthType::from(row))
|
||||
}
|
||||
|
||||
pub fn select_all_user_workspace(
|
||||
uid: i64,
|
||||
conn: &mut SqliteConnection,
|
||||
|
|
|
@ -94,12 +94,12 @@ pub async fn get_user_profile_handler(
|
|||
let session = manager.get_session()?;
|
||||
|
||||
let mut user_profile = manager
|
||||
.get_user_profile_from_disk(session.user_id, &session.user_workspace.id)
|
||||
.get_user_profile_from_disk(session.user_id, &session.workspace_id)
|
||||
.await?;
|
||||
|
||||
let weak_manager = Arc::downgrade(&manager);
|
||||
let cloned_user_profile = user_profile.clone();
|
||||
let workspace_id = session.user_workspace.id.clone();
|
||||
let workspace_id = session.workspace_id.clone();
|
||||
|
||||
// Refresh the user profile in the background
|
||||
tokio::spawn(async move {
|
||||
|
@ -433,7 +433,7 @@ pub async fn get_all_workspace_handler(
|
|||
let manager = upgrade_manager(manager)?;
|
||||
let session = manager.get_session()?;
|
||||
let profile = manager
|
||||
.get_user_profile_from_disk(session.user_id, &session.user_workspace.id)
|
||||
.get_user_profile_from_disk(session.user_id, &session.workspace_id)
|
||||
.await?;
|
||||
let user_workspaces = manager
|
||||
.get_all_user_workspaces(profile.uid, profile.auth_type)
|
||||
|
@ -822,7 +822,7 @@ pub async fn get_workspace_member_info(
|
|||
manager: AFPluginState<Weak<UserManager>>,
|
||||
) -> DataResult<WorkspaceMemberPB, FlowyError> {
|
||||
let manager = upgrade_manager(manager)?;
|
||||
let workspace_id = manager.get_session()?.user_workspace.workspace_id()?;
|
||||
let workspace_id = Uuid::parse_str(&manager.get_session()?.workspace_id)?;
|
||||
let member = manager
|
||||
.get_workspace_member_info(param.uid, &workspace_id)
|
||||
.await?;
|
||||
|
|
|
@ -285,7 +285,7 @@ pub trait UserStatusCallback: Send + Sync + 'static {
|
|||
&self,
|
||||
_user_id: i64,
|
||||
_cloud_config: &Option<UserCloudConfig>,
|
||||
_user_workspace: &UserWorkspace,
|
||||
_workspace_id: &Uuid,
|
||||
_device_id: &str,
|
||||
_auth_type: &AuthType,
|
||||
) -> FlowyResult<()> {
|
||||
|
@ -300,7 +300,7 @@ pub trait UserStatusCallback: Send + Sync + 'static {
|
|||
async fn on_sign_in(
|
||||
&self,
|
||||
_user_id: i64,
|
||||
_user_workspace: &UserWorkspace,
|
||||
_workspace_id: &Uuid,
|
||||
_device_id: &str,
|
||||
_auth_type: &AuthType,
|
||||
) -> FlowyResult<()> {
|
||||
|
@ -312,7 +312,7 @@ pub trait UserStatusCallback: Send + Sync + 'static {
|
|||
&self,
|
||||
_is_new_user: bool,
|
||||
_user_profile: &UserProfile,
|
||||
_user_workspace: &UserWorkspace,
|
||||
_workspace_id: &Uuid,
|
||||
_device_id: &str,
|
||||
_auth_type: &AuthType,
|
||||
) -> FlowyResult<()> {
|
||||
|
|
|
@ -5,11 +5,13 @@ use tracing::instrument;
|
|||
|
||||
use collab_integrate::CollabKVDB;
|
||||
use flowy_error::FlowyResult;
|
||||
use flowy_sqlite::kv::KVStorePreferences;
|
||||
use flowy_user_pub::entities::AuthType;
|
||||
|
||||
use crate::migrations::migration::UserDataMigration;
|
||||
use crate::migrations::session_migration::get_session_workspace;
|
||||
use flowy_user_pub::session::Session;
|
||||
use flowy_user_pub::sql::upsert_user_workspace;
|
||||
use flowy_user_pub::sql::{select_user_workspace, upsert_user_workspace};
|
||||
|
||||
pub struct AnonUserWorkspaceTableMigration;
|
||||
|
||||
|
@ -32,17 +34,21 @@ impl UserDataMigration for AnonUserWorkspaceTableMigration {
|
|||
#[instrument(name = "AnonUserWorkspaceTableMigration", skip_all, err)]
|
||||
fn run(
|
||||
&self,
|
||||
session: &Session,
|
||||
user: &Session,
|
||||
_collab_db: &Arc<CollabKVDB>,
|
||||
user_auth_type: &AuthType,
|
||||
db: &mut SqliteConnection,
|
||||
store_preferences: &Arc<KVStorePreferences>,
|
||||
) -> FlowyResult<()> {
|
||||
// For historical reason, anon user doesn't have a workspace in user_workspace_table.
|
||||
// So we need to create a new entry for the anon user in the user_workspace_table.
|
||||
if matches!(user_auth_type, AuthType::Local) {
|
||||
let mut user_workspace = session.user_workspace.clone();
|
||||
user_workspace.workspace_type = AuthType::Local;
|
||||
upsert_user_workspace(session.user_id, *user_auth_type, user_workspace, db)?;
|
||||
if let Some(mut user_workspace) = get_session_workspace(store_preferences) {
|
||||
if select_user_workspace(&user_workspace.id, db).ok().is_none() {
|
||||
user_workspace.workspace_type = AuthType::Local;
|
||||
upsert_user_workspace(user.user_id, *user_auth_type, user_workspace, db)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
|
@ -8,6 +8,7 @@ use tracing::{instrument, trace};
|
|||
|
||||
use collab_integrate::CollabKVDB;
|
||||
use flowy_error::FlowyResult;
|
||||
use flowy_sqlite::kv::KVStorePreferences;
|
||||
use flowy_user_pub::entities::AuthType;
|
||||
|
||||
use crate::migrations::migration::UserDataMigration;
|
||||
|
@ -38,17 +39,15 @@ impl UserDataMigration for CollabDocKeyWithWorkspaceIdMigration {
|
|||
#[instrument(name = "CollabDocKeyWithWorkspaceIdMigration", skip_all, err)]
|
||||
fn run(
|
||||
&self,
|
||||
session: &Session,
|
||||
user: &Session,
|
||||
collab_db: &Arc<CollabKVDB>,
|
||||
_user_auth_type: &AuthType,
|
||||
_db: &mut SqliteConnection,
|
||||
_store_preferences: &Arc<KVStorePreferences>,
|
||||
) -> FlowyResult<()> {
|
||||
trace!(
|
||||
"migrate key with workspace id:{}",
|
||||
session.user_workspace.id
|
||||
);
|
||||
trace!("migrate key with workspace id:{}", user.workspace_id);
|
||||
collab_db.with_write_txn(|txn| {
|
||||
migrate_old_keys(txn, &session.user_workspace.id)?;
|
||||
migrate_old_keys(txn, &user.workspace_id)?;
|
||||
Ok(())
|
||||
})?;
|
||||
Ok(())
|
||||
|
|
|
@ -12,6 +12,7 @@ use tracing::{event, instrument};
|
|||
|
||||
use collab_integrate::{CollabKVAction, CollabKVDB, PersistenceError};
|
||||
use flowy_error::{FlowyError, FlowyResult};
|
||||
use flowy_sqlite::kv::KVStorePreferences;
|
||||
use flowy_user_pub::entities::AuthType;
|
||||
|
||||
use crate::migrations::migration::UserDataMigration;
|
||||
|
@ -40,10 +41,11 @@ impl UserDataMigration for HistoricalEmptyDocumentMigration {
|
|||
#[instrument(name = "HistoricalEmptyDocumentMigration", skip_all, err)]
|
||||
fn run(
|
||||
&self,
|
||||
session: &Session,
|
||||
user: &Session,
|
||||
collab_db: &Arc<CollabKVDB>,
|
||||
user_auth_type: &AuthType,
|
||||
_db: &mut SqliteConnection,
|
||||
_store_preferences: &Arc<KVStorePreferences>,
|
||||
) -> FlowyResult<()> {
|
||||
// - The `empty document` struct has already undergone refactoring prior to the launch of the AppFlowy cloud version.
|
||||
// - Consequently, if a user is utilizing the AppFlowy cloud version, there is no need to perform any migration for the `empty document` struct.
|
||||
|
@ -52,32 +54,26 @@ impl UserDataMigration for HistoricalEmptyDocumentMigration {
|
|||
return Ok(());
|
||||
}
|
||||
collab_db.with_write_txn(|write_txn| {
|
||||
let origin = CollabOrigin::Client(CollabClient::new(session.user_id, "phantom"));
|
||||
let origin = CollabOrigin::Client(CollabClient::new(user.user_id, "phantom"));
|
||||
let folder_collab = match load_collab(
|
||||
session.user_id,
|
||||
user.user_id,
|
||||
write_txn,
|
||||
&session.user_workspace.id,
|
||||
&session.user_workspace.id,
|
||||
&user.workspace_id,
|
||||
&user.workspace_id,
|
||||
) {
|
||||
Ok(fc) => fc,
|
||||
Err(_) => return Ok(()),
|
||||
};
|
||||
|
||||
let folder = Folder::open(session.user_id, folder_collab, None)
|
||||
let folder = Folder::open(user.user_id, folder_collab, None)
|
||||
.map_err(|err| PersistenceError::Internal(err.into()))?;
|
||||
if let Some(workspace_id) = folder.get_workspace_id() {
|
||||
let migration_views = folder.get_views_belong_to(&workspace_id);
|
||||
// For historical reasons, the first level documents are empty. So migrate them by inserting
|
||||
// the default document data.
|
||||
for view in migration_views {
|
||||
if migrate_empty_document(
|
||||
write_txn,
|
||||
&origin,
|
||||
&view,
|
||||
session.user_id,
|
||||
&session.user_workspace.id,
|
||||
)
|
||||
.is_err()
|
||||
if migrate_empty_document(write_txn, &origin, &view, user.user_id, &user.workspace_id)
|
||||
.is_err()
|
||||
{
|
||||
event!(
|
||||
tracing::Level::ERROR,
|
||||
|
|
|
@ -75,7 +75,13 @@ impl UserLocalDataMigration {
|
|||
|
||||
let migration_name = migration.name().to_string();
|
||||
if !duplicated_names.contains(&migration_name) {
|
||||
migration.run(&self.session, &self.collab_db, user_auth_type, &mut conn)?;
|
||||
migration.run(
|
||||
&self.session,
|
||||
&self.collab_db,
|
||||
user_auth_type,
|
||||
&mut conn,
|
||||
&self.kv,
|
||||
)?;
|
||||
applied_migrations.push(migration.name().to_string());
|
||||
save_migration_record(&mut conn, &migration_name);
|
||||
duplicated_names.push(migration_name);
|
||||
|
@ -100,6 +106,7 @@ pub trait UserDataMigration {
|
|||
collab_db: &Arc<CollabKVDB>,
|
||||
user_auth_type: &AuthType,
|
||||
db: &mut SqliteConnection,
|
||||
store_preferences: &Arc<KVStorePreferences>,
|
||||
) -> FlowyResult<()>;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,45 +1,120 @@
|
|||
use crate::user_manager::manager_history_user::ANON_USER;
|
||||
use chrono::Utc;
|
||||
use flowy_sqlite::kv::KVStorePreferences;
|
||||
use flowy_user_pub::entities::AuthType;
|
||||
use flowy_user_pub::entities::{AuthType, Role, UserWorkspace};
|
||||
use flowy_user_pub::session::Session;
|
||||
use serde_json::{json, Value};
|
||||
use serde::de::{MapAccess, Visitor};
|
||||
use serde::{Deserialize, Deserializer, Serialize};
|
||||
use serde_json::Value;
|
||||
use std::fmt;
|
||||
use std::sync::Arc;
|
||||
use uuid::Uuid;
|
||||
|
||||
const MIGRATION_USER_NO_USER_UUID: &str = "migration_user_no_user_uuid";
|
||||
const MIGRATION_SESSION: &str = "migration_session_key";
|
||||
pub const SESSION_CACHE_KEY_BACKUP: &str = "session_cache_key_backup";
|
||||
|
||||
pub fn migrate_session(
|
||||
session_cache_key: &str,
|
||||
store_preferences: &Arc<KVStorePreferences>,
|
||||
) -> Option<Session> {
|
||||
if !store_preferences.get_bool_or_default(MIGRATION_USER_NO_USER_UUID)
|
||||
&& store_preferences
|
||||
.set_bool(MIGRATION_USER_NO_USER_UUID, true)
|
||||
.is_ok()
|
||||
if !store_preferences.get_bool_or_default(MIGRATION_SESSION)
|
||||
&& store_preferences.set_bool(MIGRATION_SESSION, true).is_ok()
|
||||
{
|
||||
if let Some(mut value) = store_preferences.get_object::<Value>(session_cache_key) {
|
||||
if value.get("user_uuid").is_none() {
|
||||
if let Some(map) = value.as_object_mut() {
|
||||
map.insert("user_uuid".to_string(), json!(Uuid::new_v4()));
|
||||
}
|
||||
}
|
||||
|
||||
if let Ok(new_session) = serde_json::from_value::<Session>(value) {
|
||||
let _ = store_preferences.set_object(session_cache_key, &new_session);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(mut session) = store_preferences.get_object::<Session>(session_cache_key) {
|
||||
if let Some(anon_session) = store_preferences.get_object::<Session>(ANON_USER) {
|
||||
if session.user_id == anon_session.user_id
|
||||
&& session.user_workspace.workspace_type != AuthType::Local
|
||||
{
|
||||
session.user_workspace.workspace_type = AuthType::Local;
|
||||
let _ = store_preferences.set_object(session_cache_key, &session);
|
||||
}
|
||||
if let Some(session) = store_preferences.get_object::<SessionBackup>(session_cache_key) {
|
||||
let _ = store_preferences.set_object(SESSION_CACHE_KEY_BACKUP, &session);
|
||||
let new_session = Session {
|
||||
user_id: session.user_id,
|
||||
user_uuid: session.user_uuid,
|
||||
workspace_id: session.user_workspace.id,
|
||||
};
|
||||
let _ = store_preferences.set_object(session_cache_key, &new_session);
|
||||
}
|
||||
}
|
||||
|
||||
store_preferences.get_object::<Session>(session_cache_key)
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
struct SessionBackup {
|
||||
user_id: i64,
|
||||
user_uuid: Uuid,
|
||||
user_workspace: UserWorkspace,
|
||||
}
|
||||
pub fn get_session_workspace(store_preferences: &Arc<KVStorePreferences>) -> Option<UserWorkspace> {
|
||||
store_preferences
|
||||
.get_object::<SessionBackup>(SESSION_CACHE_KEY_BACKUP)
|
||||
.map(|v| v.user_workspace)
|
||||
}
|
||||
|
||||
struct SessionVisitor;
|
||||
impl<'de> Visitor<'de> for SessionVisitor {
|
||||
type Value = SessionBackup;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("SessionBackup")
|
||||
}
|
||||
|
||||
fn visit_map<M>(self, mut map: M) -> Result<Self::Value, M::Error>
|
||||
where
|
||||
M: MapAccess<'de>,
|
||||
{
|
||||
let mut user_id = None;
|
||||
let mut user_uuid = None;
|
||||
// For historical reasons, the session used to contain a workspace_id field.
|
||||
// This field is no longer used, and is replaced by user_workspace.
|
||||
let mut workspace_id = None;
|
||||
let mut user_workspace = None;
|
||||
|
||||
while let Some(key) = map.next_key::<String>()? {
|
||||
match key.as_str() {
|
||||
"user_id" => {
|
||||
user_id = Some(map.next_value()?);
|
||||
},
|
||||
"user_uuid" => {
|
||||
user_uuid = Some(map.next_value()?);
|
||||
},
|
||||
"workspace_id" => {
|
||||
workspace_id = Some(map.next_value()?);
|
||||
},
|
||||
"user_workspace" => {
|
||||
user_workspace = Some(map.next_value()?);
|
||||
},
|
||||
_ => {
|
||||
let _ = map.next_value::<Value>();
|
||||
},
|
||||
}
|
||||
}
|
||||
let user_id = user_id.ok_or(serde::de::Error::missing_field("user_id"))?;
|
||||
let user_uuid = user_uuid.unwrap_or_else(Uuid::new_v4);
|
||||
if user_workspace.is_none() {
|
||||
if let Some(workspace_id) = workspace_id {
|
||||
user_workspace = Some(UserWorkspace {
|
||||
id: workspace_id,
|
||||
name: "My Workspace".to_string(),
|
||||
created_at: Utc::now(),
|
||||
workspace_database_id: Uuid::new_v4().to_string(),
|
||||
icon: "".to_owned(),
|
||||
member_count: 1,
|
||||
role: Some(Role::Owner),
|
||||
workspace_type: AuthType::Local,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
let session = SessionBackup {
|
||||
user_id,
|
||||
user_uuid,
|
||||
user_workspace: user_workspace.ok_or(serde::de::Error::missing_field("user_workspace"))?,
|
||||
};
|
||||
|
||||
Ok(session)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for SessionBackup {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
deserializer.deserialize_any(SessionVisitor)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ use tracing::instrument;
|
|||
|
||||
use collab_integrate::{CollabKVAction, CollabKVDB};
|
||||
use flowy_error::FlowyResult;
|
||||
use flowy_sqlite::kv::KVStorePreferences;
|
||||
use flowy_user_pub::entities::AuthType;
|
||||
|
||||
use crate::migrations::migration::UserDataMigration;
|
||||
|
@ -38,19 +39,20 @@ impl UserDataMigration for FavoriteV1AndWorkspaceArrayMigration {
|
|||
#[instrument(name = "FavoriteV1AndWorkspaceArrayMigration", skip_all, err)]
|
||||
fn run(
|
||||
&self,
|
||||
session: &Session,
|
||||
user: &Session,
|
||||
collab_db: &Arc<CollabKVDB>,
|
||||
_user_auth_type: &AuthType,
|
||||
_db: &mut SqliteConnection,
|
||||
_store_preferences: &Arc<KVStorePreferences>,
|
||||
) -> FlowyResult<()> {
|
||||
collab_db.with_write_txn(|write_txn| {
|
||||
if let Ok(collab) = load_collab(
|
||||
session.user_id,
|
||||
user.user_id,
|
||||
write_txn,
|
||||
&session.user_workspace.id,
|
||||
&session.user_workspace.id,
|
||||
&user.workspace_id,
|
||||
&user.workspace_id,
|
||||
) {
|
||||
let mut folder = Folder::open(session.user_id, collab, None)
|
||||
let mut folder = Folder::open(user.user_id, collab, None)
|
||||
.map_err(|err| PersistenceError::Internal(err.into()))?;
|
||||
folder
|
||||
.body
|
||||
|
@ -70,9 +72,9 @@ impl UserDataMigration for FavoriteV1AndWorkspaceArrayMigration {
|
|||
.encode_collab()
|
||||
.map_err(|err| PersistenceError::Internal(err.into()))?;
|
||||
write_txn.flush_doc(
|
||||
session.user_id,
|
||||
&session.user_workspace.id,
|
||||
&session.user_workspace.id,
|
||||
user.user_id,
|
||||
&user.workspace_id,
|
||||
&user.workspace_id,
|
||||
encode.state_vector.to_vec(),
|
||||
encode.doc_state.to_vec(),
|
||||
)?;
|
||||
|
|
|
@ -8,6 +8,7 @@ use tracing::instrument;
|
|||
|
||||
use collab_integrate::{CollabKVAction, CollabKVDB};
|
||||
use flowy_error::FlowyResult;
|
||||
use flowy_sqlite::kv::KVStorePreferences;
|
||||
use flowy_user_pub::entities::AuthType;
|
||||
|
||||
use crate::migrations::migration::UserDataMigration;
|
||||
|
@ -36,19 +37,20 @@ impl UserDataMigration for WorkspaceTrashMapToSectionMigration {
|
|||
#[instrument(name = "WorkspaceTrashMapToSectionMigration", skip_all, err)]
|
||||
fn run(
|
||||
&self,
|
||||
session: &Session,
|
||||
user: &Session,
|
||||
collab_db: &Arc<CollabKVDB>,
|
||||
_user_auth_type: &AuthType,
|
||||
_db: &mut SqliteConnection,
|
||||
_store_preferences: &Arc<KVStorePreferences>,
|
||||
) -> FlowyResult<()> {
|
||||
collab_db.with_write_txn(|write_txn| {
|
||||
if let Ok(collab) = load_collab(
|
||||
session.user_id,
|
||||
user.user_id,
|
||||
write_txn,
|
||||
&session.user_workspace.id,
|
||||
&session.user_workspace.id,
|
||||
&user.workspace_id,
|
||||
&user.workspace_id,
|
||||
) {
|
||||
let mut folder = Folder::open(session.user_id, collab, None)
|
||||
let mut folder = Folder::open(user.user_id, collab, None)
|
||||
.map_err(|err| PersistenceError::Internal(err.into()))?;
|
||||
let trash_ids = folder
|
||||
.get_trash_v1()
|
||||
|
@ -64,9 +66,9 @@ impl UserDataMigration for WorkspaceTrashMapToSectionMigration {
|
|||
.encode_collab()
|
||||
.map_err(|err| PersistenceError::Internal(err.into()))?;
|
||||
write_txn.flush_doc(
|
||||
session.user_id,
|
||||
&session.user_workspace.id,
|
||||
&session.user_workspace.id,
|
||||
user.user_id,
|
||||
&user.workspace_id,
|
||||
&user.workspace_id,
|
||||
encode.state_vector.to_vec(),
|
||||
encode.doc_state.to_vec(),
|
||||
)?;
|
||||
|
|
|
@ -11,6 +11,7 @@ use flowy_sqlite::kv::KVStorePreferences;
|
|||
use flowy_sqlite::DBConnection;
|
||||
use flowy_user_pub::entities::{AuthType, UserWorkspace};
|
||||
use flowy_user_pub::session::Session;
|
||||
use flowy_user_pub::sql::{select_user_workspace, select_user_workspace_type};
|
||||
use std::path::PathBuf;
|
||||
use std::str::FromStr;
|
||||
use std::sync::{Arc, Weak};
|
||||
|
@ -46,10 +47,9 @@ impl AuthenticateUser {
|
|||
|
||||
pub async fn is_local_mode(&self) -> FlowyResult<bool> {
|
||||
let session = self.get_session()?;
|
||||
Ok(matches!(
|
||||
session.user_workspace.workspace_type,
|
||||
AuthType::Local
|
||||
))
|
||||
let mut conn = self.get_sqlite_connection(session.user_id)?;
|
||||
let workspace_type = select_user_workspace_type(&session.workspace_id, &mut conn)?;
|
||||
Ok(matches!(workspace_type, AuthType::Local))
|
||||
}
|
||||
|
||||
pub fn device_id(&self) -> FlowyResult<String> {
|
||||
|
@ -58,13 +58,15 @@ impl AuthenticateUser {
|
|||
|
||||
pub fn workspace_id(&self) -> FlowyResult<Uuid> {
|
||||
let session = self.get_session()?;
|
||||
let workspace_uuid = Uuid::from_str(&session.user_workspace.id)?;
|
||||
let workspace_uuid = Uuid::from_str(&session.workspace_id)?;
|
||||
Ok(workspace_uuid)
|
||||
}
|
||||
|
||||
pub fn workspace_database_object_id(&self) -> FlowyResult<Uuid> {
|
||||
let session = self.get_session()?;
|
||||
let id = Uuid::from_str(&session.user_workspace.workspace_database_id)?;
|
||||
let mut conn = self.get_sqlite_connection(session.user_id)?;
|
||||
let workspace = select_user_workspace(&session.workspace_id, &mut conn)?;
|
||||
let id = Uuid::from_str(&workspace.database_storage_id)?;
|
||||
Ok(id)
|
||||
}
|
||||
|
||||
|
@ -104,7 +106,7 @@ impl AuthenticateUser {
|
|||
let session = self.get_session()?;
|
||||
let collab_db = self.database.get_collab_db(uid)?;
|
||||
let read_txn = collab_db.read_txn();
|
||||
Ok(read_txn.is_exist(uid, session.user_workspace.id.as_str(), object_id))
|
||||
Ok(read_txn.is_exist(uid, session.workspace_id.as_str(), object_id))
|
||||
}
|
||||
|
||||
pub fn set_session(&self, session: Option<Arc<Session>>) -> Result<(), FlowyError> {
|
||||
|
@ -133,7 +135,7 @@ impl AuthenticateUser {
|
|||
self.set_session(Some(Arc::new(Session {
|
||||
user_id: session.user_id,
|
||||
user_uuid: session.user_uuid,
|
||||
user_workspace,
|
||||
workspace_id: user_workspace.id,
|
||||
})))
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::migrations::session_migration::migrate_session;
|
||||
use crate::migrations::session_migration::{get_session_workspace, migrate_session};
|
||||
|
||||
use crate::services::data_import::importer::load_collab_by_object_ids;
|
||||
use crate::services::db::UserDBPath;
|
||||
|
@ -51,6 +51,7 @@ pub(crate) struct ImportedFolder {
|
|||
pub container_name: Option<String>,
|
||||
pub parent_view_id: Option<String>,
|
||||
pub source: ImportedSource,
|
||||
pub workspace_database_id: String,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
|
@ -81,6 +82,11 @@ pub(crate) fn prepare_import(
|
|||
let user_paths = UserPaths::new(path.to_string());
|
||||
let other_store_preferences = Arc::new(KVStorePreferences::new(path)?);
|
||||
migrate_session("appflowy_session_cache", &other_store_preferences);
|
||||
|
||||
let session_workspace = get_session_workspace(&other_store_preferences)
|
||||
.ok_or(anyhow!("Can't find the session workspace"))?;
|
||||
let workspace_database_id = session_workspace.workspace_database_id;
|
||||
|
||||
let imported_session = other_store_preferences
|
||||
.get_object::<Session>("appflowy_session_cache")
|
||||
.ok_or(anyhow!(
|
||||
|
@ -105,7 +111,7 @@ pub(crate) fn prepare_import(
|
|||
let mut conn = imported_sqlite_db.get_connection()?;
|
||||
let imported_user_auth_type = select_user_profile(
|
||||
imported_session.user_id,
|
||||
&imported_session.user_workspace.id,
|
||||
&imported_session.workspace_id,
|
||||
&mut conn,
|
||||
)
|
||||
.map(|v| v.auth_type)
|
||||
|
@ -126,6 +132,7 @@ pub(crate) fn prepare_import(
|
|||
container_name: None,
|
||||
parent_view_id,
|
||||
source: ImportedSource::ExternalFolder,
|
||||
workspace_database_id,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -154,13 +161,13 @@ pub(crate) fn generate_import_data(
|
|||
imported_folder: ImportedFolder,
|
||||
) -> anyhow::Result<ImportedAppFlowyData> {
|
||||
info!(
|
||||
"[AppflowyData]:importing workspace: {}:{}",
|
||||
imported_folder.imported_session.user_workspace.name,
|
||||
imported_folder.imported_session.user_workspace.id,
|
||||
"[AppflowyData]:importing workspace: {}",
|
||||
imported_folder.imported_session.workspace_id,
|
||||
);
|
||||
let workspace_id = current_session.user_workspace.id.clone();
|
||||
let imported_workspace_id = imported_folder.imported_session.user_workspace.id.clone();
|
||||
let workspace_id = current_session.workspace_id.clone();
|
||||
let imported_workspace_id = imported_folder.imported_session.workspace_id.clone();
|
||||
let imported_session = imported_folder.imported_session.clone();
|
||||
let imported_workspace_database_id = imported_folder.workspace_database_id.clone();
|
||||
let imported_collab_db = imported_folder.imported_collab_db.clone();
|
||||
let imported_container_view_name = imported_folder.container_name.clone();
|
||||
|
||||
|
@ -202,18 +209,18 @@ pub(crate) fn generate_import_data(
|
|||
// 2. workspace database views
|
||||
// 3. user awareness
|
||||
// So we remove these object ids from the list
|
||||
let user_workspace_id = &imported_session.user_workspace.id;
|
||||
let workspace_database_id = &imported_session.user_workspace.workspace_database_id;
|
||||
let user_workspace_id = &imported_session.workspace_id;
|
||||
let user_awareness_id =
|
||||
user_awareness_object_id(&imported_session.user_uuid, user_workspace_id).to_string();
|
||||
all_imported_object_ids.retain(|id| {
|
||||
id != user_workspace_id && id != workspace_database_id && id != &user_awareness_id
|
||||
id != user_workspace_id && id != &imported_workspace_database_id && id != &user_awareness_id
|
||||
});
|
||||
|
||||
// 2. mapping the workspace database ids
|
||||
if let Err(err) = mapping_workspace_database_ids(
|
||||
&mut old_to_new_id_map,
|
||||
&imported_session,
|
||||
&imported_workspace_database_id,
|
||||
&imported_collab_db_read_txn,
|
||||
&mut database_view_ids_by_database_id,
|
||||
&mut database_object_ids,
|
||||
|
@ -293,7 +300,7 @@ pub(crate) fn generate_import_data(
|
|||
for view_id in not_exist_parent_view_ids {
|
||||
if let Err(err) = create_empty_document_for_view(
|
||||
current_session.user_id,
|
||||
¤t_session.user_workspace.id,
|
||||
¤t_session.workspace_id,
|
||||
&view_id,
|
||||
current_collab_db_write_txn,
|
||||
) {
|
||||
|
@ -489,7 +496,7 @@ where
|
|||
write_collab_object(
|
||||
&collab,
|
||||
current_session.user_id,
|
||||
current_session.user_workspace.id.as_str(),
|
||||
current_session.workspace_id.as_str(),
|
||||
import_container_view_id,
|
||||
collab_write_txn,
|
||||
CollabType::Document,
|
||||
|
@ -499,7 +506,7 @@ where
|
|||
|
||||
let import_container_views = NestedChildViewBuilder::new(
|
||||
current_session.user_id,
|
||||
current_session.user_workspace.id.clone(),
|
||||
current_session.workspace_id.clone(),
|
||||
)
|
||||
.with_view_id(import_container_view_id)
|
||||
.with_layout(ViewLayout::Document)
|
||||
|
@ -514,6 +521,7 @@ where
|
|||
fn mapping_workspace_database_ids<'a, W>(
|
||||
old_to_new_id_map: &mut OldToNewIdMap,
|
||||
imported_session: &Session,
|
||||
imported_session_workspace_database_id: &str,
|
||||
imported_collab_db_read_txn: &W,
|
||||
database_view_ids_by_database_id: &mut HashMap<String, Vec<String>>,
|
||||
database_object_ids: &mut HashSet<String>,
|
||||
|
@ -524,20 +532,20 @@ where
|
|||
{
|
||||
let mut workspace_database_collab = Collab::new(
|
||||
imported_session.user_id,
|
||||
&imported_session.user_workspace.workspace_database_id,
|
||||
imported_session_workspace_database_id,
|
||||
"import_device",
|
||||
vec![],
|
||||
false,
|
||||
);
|
||||
imported_collab_db_read_txn.load_doc_with_txn(
|
||||
imported_session.user_id,
|
||||
&imported_session.user_workspace.id,
|
||||
&imported_session.user_workspace.workspace_database_id,
|
||||
&imported_session.workspace_id,
|
||||
imported_session_workspace_database_id,
|
||||
&mut workspace_database_collab.transact_mut(),
|
||||
)?;
|
||||
|
||||
let workspace_database = init_workspace_database(
|
||||
&imported_session.user_workspace.workspace_database_id,
|
||||
imported_session_workspace_database_id,
|
||||
workspace_database_collab,
|
||||
);
|
||||
for database_meta_list in workspace_database.get_all_database_meta() {
|
||||
|
@ -661,7 +669,7 @@ where
|
|||
write_collab_object(
|
||||
database_collab,
|
||||
session.user_id,
|
||||
session.user_workspace.id.as_str(),
|
||||
&session.workspace_id,
|
||||
&new_database_object_id,
|
||||
collab_write_txn,
|
||||
CollabType::Database,
|
||||
|
@ -684,7 +692,7 @@ where
|
|||
})
|
||||
.collect::<Vec<_>>();
|
||||
for gen_collab in gen_database_row_document_collabs {
|
||||
write_gen_collab(&session.user_workspace.id, gen_collab, collab_write_txn);
|
||||
write_gen_collab(&session.workspace_id, gen_collab, collab_write_txn);
|
||||
}
|
||||
|
||||
// remove the database object ids from the object ids
|
||||
|
@ -771,7 +779,7 @@ where
|
|||
.collect::<Vec<_>>();
|
||||
|
||||
for gen_collab in gen_database_row_collabs {
|
||||
write_gen_collab(&session.user_workspace.id, gen_collab, collab_write_txn);
|
||||
write_gen_collab(&session.workspace_id, gen_collab, collab_write_txn);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -936,7 +944,7 @@ where
|
|||
{
|
||||
let mut imported_folder_collab = Collab::new(
|
||||
imported_session.user_id,
|
||||
&imported_session.user_workspace.id,
|
||||
&imported_session.workspace_id,
|
||||
"migrate_device",
|
||||
vec![],
|
||||
false,
|
||||
|
@ -945,15 +953,15 @@ where
|
|||
imported_collab_db_read_txn
|
||||
.load_doc_with_txn(
|
||||
imported_session.user_id,
|
||||
&imported_session.user_workspace.id,
|
||||
&imported_session.user_workspace.id,
|
||||
&imported_session.workspace_id,
|
||||
&imported_session.workspace_id,
|
||||
&mut imported_folder_collab.transact_mut(),
|
||||
)
|
||||
.map_err(|err| {
|
||||
PersistenceError::Internal(anyhow!(
|
||||
"[AppflowyData]: Can't load the user:{} folder:{}. {}",
|
||||
imported_session.user_id,
|
||||
imported_session.user_workspace.id,
|
||||
imported_session.workspace_id,
|
||||
err
|
||||
))
|
||||
})?;
|
||||
|
@ -964,7 +972,7 @@ where
|
|||
})?;
|
||||
|
||||
let mut imported_folder_data = imported_folder
|
||||
.get_folder_data(&imported_session.user_workspace.id)
|
||||
.get_folder_data(&imported_session.workspace_id)
|
||||
.ok_or(PersistenceError::Internal(anyhow!(
|
||||
"[AppflowyData]: Can't read the folder data"
|
||||
)))?;
|
||||
|
@ -1005,7 +1013,7 @@ where
|
|||
|
||||
// replace the old parent view id of the workspace
|
||||
old_to_new_id_map.0.insert(
|
||||
imported_session.user_workspace.id.clone(),
|
||||
imported_session.workspace_id.clone(),
|
||||
root_view_id.to_string(),
|
||||
);
|
||||
|
||||
|
|
|
@ -128,11 +128,13 @@ impl UserManager {
|
|||
|
||||
if let Ok(session) = self.get_session() {
|
||||
info!(
|
||||
"Init user session: {}:{}, workspace: {}",
|
||||
session.user_id, session.user_workspace.name, session.user_workspace.id
|
||||
"Init user session: {}, workspace: {}",
|
||||
session.user_id, session.workspace_id
|
||||
);
|
||||
let workspace_uuid = Uuid::parse_str(&session.workspace_id)?;
|
||||
let mut conn = self.db_connection(session.user_id)?;
|
||||
let auth_type = select_user_workspace_type(&session.workspace_id, &mut conn)?;
|
||||
|
||||
let auth_type = session.user_workspace.workspace_type;
|
||||
let uid = session.user_id;
|
||||
let token = self.token_from_auth_type(&auth_type)?;
|
||||
self
|
||||
|
@ -158,11 +160,11 @@ impl UserManager {
|
|||
let weak_cloud_services = Arc::downgrade(&self.cloud_service);
|
||||
let weak_authenticate_user = Arc::downgrade(&self.authenticate_user);
|
||||
let weak_pool = Arc::downgrade(&self.db_pool(uid)?);
|
||||
let workspace_id = session.workspace_id.clone();
|
||||
let cloned_session = session.clone();
|
||||
if let Some(mut token_state_rx) = self.cloud_service.subscribe_token_state() {
|
||||
event!(tracing::Level::DEBUG, "Listen token state change");
|
||||
let user_uid = uid;
|
||||
let workspace_id = session.user_workspace.id.clone();
|
||||
tokio::spawn(async move {
|
||||
while let Some(token_state) = token_state_rx.next().await {
|
||||
debug!("Token state changed: {:?}", token_state);
|
||||
|
@ -260,7 +262,7 @@ impl UserManager {
|
|||
.on_launch_if_authenticated(
|
||||
uid,
|
||||
&cloud_config,
|
||||
&session.user_workspace,
|
||||
&workspace_uuid,
|
||||
&self.authenticate_user.user_config.device_id,
|
||||
&auth_type,
|
||||
)
|
||||
|
@ -340,6 +342,7 @@ impl UserManager {
|
|||
self.prepare_user(&session).await;
|
||||
|
||||
let latest_workspace = response.latest_workspace.clone();
|
||||
let workspace_id = Uuid::parse_str(&latest_workspace.id)?;
|
||||
let user_profile = UserProfile::from((&response, &auth_type));
|
||||
self.save_auth_data(&response, auth_type, &session).await?;
|
||||
|
||||
|
@ -352,7 +355,7 @@ impl UserManager {
|
|||
.await
|
||||
.on_sign_in(
|
||||
user_profile.uid,
|
||||
&latest_workspace,
|
||||
&workspace_id,
|
||||
&self.authenticate_user.user_config.device_id,
|
||||
&auth_type,
|
||||
)
|
||||
|
@ -404,6 +407,7 @@ impl UserManager {
|
|||
.save_auth_data(&response, *auth_type, &new_session)
|
||||
.await?;
|
||||
let _ = self.initial_user_awareness(&new_session, auth_type).await;
|
||||
let workspace_id = Uuid::parse_str(&new_session.workspace_id)?;
|
||||
self
|
||||
.user_status_callback
|
||||
.read()
|
||||
|
@ -411,7 +415,7 @@ impl UserManager {
|
|||
.on_sign_up(
|
||||
response.is_new_user,
|
||||
new_user_profile,
|
||||
&new_session.user_workspace,
|
||||
&workspace_id,
|
||||
&self.authenticate_user.user_config.device_id,
|
||||
auth_type,
|
||||
)
|
||||
|
@ -493,7 +497,7 @@ impl UserManager {
|
|||
let session = self.get_session()?;
|
||||
upsert_user_profile_change(
|
||||
session.user_id,
|
||||
&session.user_workspace.id,
|
||||
&session.workspace_id,
|
||||
self.db_connection(session.user_id)?,
|
||||
changeset,
|
||||
)?;
|
||||
|
@ -523,7 +527,7 @@ impl UserManager {
|
|||
self
|
||||
.authenticate_user
|
||||
.database
|
||||
.backup(session.user_id, &session.user_workspace.id);
|
||||
.backup(session.user_id, &session.workspace_id);
|
||||
}
|
||||
|
||||
/// Fetches the user profile for the given user ID.
|
||||
|
@ -627,7 +631,7 @@ impl UserManager {
|
|||
|
||||
pub fn workspace_id(&self) -> Result<String, FlowyError> {
|
||||
let session = self.get_session()?;
|
||||
Ok(session.user_workspace.id.clone())
|
||||
Ok(session.workspace_id.clone())
|
||||
}
|
||||
|
||||
pub fn token(&self) -> Result<Option<String>, FlowyError> {
|
||||
|
@ -758,7 +762,7 @@ impl UserManager {
|
|||
// Save the user profile change
|
||||
upsert_user_profile_change(
|
||||
user_update.uid,
|
||||
&session.user_workspace.id,
|
||||
&session.workspace_id,
|
||||
self.db_connection(user_update.uid)?,
|
||||
UserTableChangeset::from(user_update),
|
||||
)?;
|
||||
|
@ -784,17 +788,6 @@ impl UserManager {
|
|||
.await?;
|
||||
}
|
||||
|
||||
// Save the old user workspace setting.
|
||||
let mut conn = self
|
||||
.authenticate_user
|
||||
.database
|
||||
.get_connection(old_user.session.user_id)?;
|
||||
upsert_user_workspace(
|
||||
old_user.session.user_id,
|
||||
*auth_type,
|
||||
old_user.session.user_workspace.clone(),
|
||||
&mut conn,
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ impl UserManager {
|
|||
|
||||
let session = self.get_session().ok()?;
|
||||
let user_profile = self
|
||||
.get_user_profile_from_disk(session.user_id, &session.user_workspace.id)
|
||||
.get_user_profile_from_disk(session.user_id, &session.workspace_id)
|
||||
.await
|
||||
.ok()?;
|
||||
|
||||
|
@ -48,7 +48,7 @@ impl UserManager {
|
|||
"Anon user not found",
|
||||
))?;
|
||||
let profile = self
|
||||
.get_user_profile_from_disk(anon_session.user_id, &anon_session.user_workspace.id)
|
||||
.get_user_profile_from_disk(anon_session.user_id, &anon_session.workspace_id)
|
||||
.await?;
|
||||
Ok(UserProfilePB::from(profile))
|
||||
}
|
||||
|
|
|
@ -121,7 +121,7 @@ impl UserManager {
|
|||
session: &Session,
|
||||
auth_type: &AuthType,
|
||||
) -> FlowyResult<()> {
|
||||
let object_id = user_awareness_object_id(&session.user_uuid, &session.user_workspace.id);
|
||||
let object_id = user_awareness_object_id(&session.user_uuid, &session.workspace_id);
|
||||
|
||||
// Try to acquire mutable access to `is_loading_awareness`.
|
||||
// Thread-safety is ensured by DashMap
|
||||
|
@ -162,7 +162,7 @@ impl UserManager {
|
|||
auth_type
|
||||
);
|
||||
let collab_db = self.get_collab_db(session.user_id)?;
|
||||
let workspace_id = session.user_workspace.workspace_id()?;
|
||||
let workspace_id = Uuid::parse_str(&session.workspace_id)?;
|
||||
let doc_state =
|
||||
CollabPersistenceImpl::new(collab_db.clone(), session.user_id, workspace_id)
|
||||
.into_data_source();
|
||||
|
@ -227,7 +227,7 @@ impl UserManager {
|
|||
}
|
||||
};
|
||||
|
||||
let workspace_id = session.user_workspace.workspace_id()?;
|
||||
let workspace_id = Uuid::parse_str(&session.workspace_id)?;
|
||||
let create_awareness = if authenticator.is_local() {
|
||||
let doc_state =
|
||||
CollabPersistenceImpl::new(collab_db.clone(), session.user_id, workspace_id)
|
||||
|
@ -289,7 +289,7 @@ impl UserManager {
|
|||
Ok(new_user_awareness) => {
|
||||
// Validate session before storing the awareness
|
||||
if let Ok(current_session) = authenticate_user.get_session() {
|
||||
if current_session.user_workspace.id == session.user_workspace.id {
|
||||
if current_session.workspace_id == session.workspace_id {
|
||||
if let Some(user_awareness) = user_awareness.upgrade() {
|
||||
info!("User awareness initialized successfully");
|
||||
user_awareness.store(Some(new_user_awareness));
|
||||
|
@ -366,7 +366,7 @@ impl UserManager {
|
|||
info!("User awareness is not loaded when trying to access it");
|
||||
|
||||
let session = self.get_session()?;
|
||||
let object_id = user_awareness_object_id(&session.user_uuid, &session.user_workspace.id);
|
||||
let object_id = user_awareness_object_id(&session.user_uuid, &session.workspace_id);
|
||||
let is_loading = self
|
||||
.is_loading_awareness
|
||||
.get(&object_id)
|
||||
|
@ -375,7 +375,7 @@ impl UserManager {
|
|||
|
||||
if !is_loading {
|
||||
let user_profile = self
|
||||
.get_user_profile_from_disk(session.user_id, &session.user_workspace.id)
|
||||
.get_user_profile_from_disk(session.user_id, &session.workspace_id)
|
||||
.await?;
|
||||
self
|
||||
.initial_user_awareness(&session, &user_profile.workspace_auth_type)
|
||||
|
|
|
@ -101,7 +101,7 @@ impl UserManager {
|
|||
collab_data: ImportedCollabData,
|
||||
) -> Result<(), FlowyError> {
|
||||
let user = self
|
||||
.get_user_profile_from_disk(current_session.user_id, ¤t_session.user_workspace.id)
|
||||
.get_user_profile_from_disk(current_session.user_id, ¤t_session.workspace_id)
|
||||
.await?;
|
||||
let user_collab_db = self
|
||||
.get_collab_db(current_session.user_id)?
|
||||
|
@ -109,12 +109,13 @@ impl UserManager {
|
|||
.ok_or_else(|| FlowyError::internal().with_context("Collab db not found"))?;
|
||||
|
||||
let user_id = current_session.user_id;
|
||||
let workspace_id = Uuid::parse_str(¤t_session.workspace_id)?;
|
||||
let weak_user_collab_db = Arc::downgrade(&user_collab_db);
|
||||
let weak_user_cloud_service = self.cloud_service.get_user_service()?;
|
||||
match upload_collab_objects_data(
|
||||
user_id,
|
||||
weak_user_collab_db,
|
||||
¤t_session.user_workspace.workspace_id()?,
|
||||
&workspace_id,
|
||||
&user.workspace_auth_type,
|
||||
collab_data,
|
||||
weak_user_cloud_service,
|
||||
|
@ -146,6 +147,7 @@ impl UserManager {
|
|||
container_name: None,
|
||||
parent_view_id: None,
|
||||
source: ImportedSource::AnonUser,
|
||||
workspace_database_id: "".to_string(),
|
||||
};
|
||||
self.perform_import(import_context).await?;
|
||||
Ok(())
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue