migration.rs 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  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_database::kv::KV;
  7. use flowy_error::{FlowyError, FlowyResult};
  8. use flowy_folder_data_model::entities::{
  9. app::{App, RepeatedApp},
  10. view::{RepeatedView, View},
  11. workspace::Workspace,
  12. };
  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) {
  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. KV::set_bool(&key, true);
  57. return Ok(None);
  58. }
  59. let trash = conn.immediate_transaction::<_, FlowyError, _>(|| {
  60. let trash = TrashTableSql::read_all(conn)?.take_items();
  61. Ok(trash)
  62. })?;
  63. let folder = FolderPad::new(workspaces, trash)?;
  64. KV::set_bool(&key, true);
  65. Ok(Some(folder))
  66. }
  67. }