migration.rs 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. use crate::{
  2. module::WorkspaceDatabase,
  3. services::persistence::{AppTableSql, TrashTableSql, ViewTableSql, WorkspaceTableSql},
  4. };
  5. use flowy_collaboration::{client_folder::FolderPad, entities::revision::md5};
  6. use flowy_core_data_model::entities::{
  7. app::{App, RepeatedApp},
  8. view::{RepeatedView, View},
  9. workspace::Workspace,
  10. };
  11. use flowy_database::kv::KV;
  12. use flowy_error::{FlowyError, FlowyResult};
  13. use std::sync::Arc;
  14. pub(crate) const V1_MIGRATION: &str = "FOLDER_V1_MIGRATION";
  15. pub(crate) struct FolderMigration {
  16. user_id: String,
  17. database: Arc<dyn WorkspaceDatabase>,
  18. }
  19. impl FolderMigration {
  20. pub fn new(user_id: &str, database: Arc<dyn WorkspaceDatabase>) -> Self {
  21. Self {
  22. user_id: user_id.to_owned(),
  23. database,
  24. }
  25. }
  26. pub fn run_v1_migration(&self) -> FlowyResult<Option<FolderPad>> {
  27. let key = md5(format!("{}{}", self.user_id, V1_MIGRATION));
  28. if KV::get_bool(&key).unwrap_or(false) {
  29. return Ok(None);
  30. }
  31. tracing::trace!("Run folder version 1 migrations");
  32. let pool = self.database.db_pool()?;
  33. let conn = &*pool.get()?;
  34. let workspaces = conn.immediate_transaction::<_, FlowyError, _>(|| {
  35. let mut workspaces = WorkspaceTableSql::read_workspaces(&self.user_id, None, conn)?
  36. .into_iter()
  37. .map(Workspace::from)
  38. .collect::<Vec<_>>();
  39. for workspace in workspaces.iter_mut() {
  40. let mut apps = AppTableSql::read_workspace_apps(&workspace.id, conn)?
  41. .into_iter()
  42. .map(App::from)
  43. .collect::<Vec<_>>();
  44. for app in apps.iter_mut() {
  45. let views = ViewTableSql::read_views(&app.id, conn)?
  46. .into_iter()
  47. .map(View::from)
  48. .collect::<Vec<_>>();
  49. app.belongings = RepeatedView { items: views };
  50. }
  51. workspace.apps = RepeatedApp { items: apps };
  52. }
  53. Ok(workspaces)
  54. })?;
  55. if workspaces.is_empty() {
  56. return Ok(None);
  57. }
  58. let trash = conn.immediate_transaction::<_, FlowyError, _>(|| {
  59. let trash = TrashTableSql::read_all(conn)?.take_items();
  60. Ok(trash)
  61. })?;
  62. let folder = FolderPad::new(workspaces, trash)?;
  63. KV::set_bool(&key, true);
  64. Ok(Some(folder))
  65. }
  66. }