fix: 040 bugs (#4285)

* test: add tests

* chore: set maximum log files

* fix: import row document

* chore: bump client api

* chore: fix analyzer

* chore: fix flutter unit test
This commit is contained in:
Nathan.fooo
2024-01-03 11:41:29 +08:00
committed by GitHub
parent eef5c2bf66
commit 7937fd1f3a
35 changed files with 537 additions and 280 deletions

View File

@ -25,7 +25,7 @@ CARGO_MAKE_EXTEND_WORKSPACE_MAKEFILE = true
CARGO_MAKE_CRATE_FS_NAME = "dart_ffi" CARGO_MAKE_CRATE_FS_NAME = "dart_ffi"
CARGO_MAKE_CRATE_NAME = "dart-ffi" CARGO_MAKE_CRATE_NAME = "dart-ffi"
LIB_NAME = "dart_ffi" LIB_NAME = "dart_ffi"
CURRENT_APP_VERSION = "0.4.0" APPFLOWY_VERSION = "0.4.0"
FLUTTER_DESKTOP_FEATURES = "dart,rev-sqlite" FLUTTER_DESKTOP_FEATURES = "dart,rev-sqlite"
PRODUCT_NAME = "AppFlowy" PRODUCT_NAME = "AppFlowy"
MACOSX_DEPLOYMENT_TARGET = "11.0" MACOSX_DEPLOYMENT_TARGET = "11.0"

View File

@ -7,6 +7,7 @@ import 'package:appflowy_backend/appflowy_backend.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get_it/get_it.dart'; import 'package:get_it/get_it.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'deps_resolver.dart'; import 'deps_resolver.dart';
import 'entry_point.dart'; import 'entry_point.dart';
@ -83,6 +84,12 @@ class FlowyRunner {
rustEnvs: rustEnvsBuilder?.call() ?? {}, rustEnvs: rustEnvsBuilder?.call() ?? {},
); );
if (!mode.isUnitTest) {
// Unit test can't use the package_info_plus plugin
config.rustEnvs["APP_VERSION"] =
await PackageInfo.fromPlatform().then((value) => value.version);
}
// Specify the env // Specify the env
await initGetIt(getIt, mode, f, config); await initGetIt(getIt, mode, f, config);
await didInitGetItCallback?.call(); await didInitGetItCallback?.call();

View File

@ -139,7 +139,7 @@ checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
[[package]] [[package]]
name = "app-error" name = "app-error"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=a455c9de8e6448cec956da5a00ba5cc136ed7274#a455c9de8e6448cec956da5a00ba5cc136ed7274" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40daff472d026d155fc703aacce899b1c5ab98ea#40daff472d026d155fc703aacce899b1c5ab98ea"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"reqwest", "reqwest",
@ -193,7 +193,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.32", "syn 2.0.46",
] ]
[[package]] [[package]]
@ -204,7 +204,7 @@ checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.32", "syn 2.0.46",
] ]
[[package]] [[package]]
@ -352,7 +352,7 @@ dependencies = [
"regex", "regex",
"rustc-hash", "rustc-hash",
"shlex", "shlex",
"syn 2.0.32", "syn 2.0.46",
] ]
[[package]] [[package]]
@ -734,7 +734,7 @@ dependencies = [
[[package]] [[package]]
name = "client-api" name = "client-api"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=a455c9de8e6448cec956da5a00ba5cc136ed7274#a455c9de8e6448cec956da5a00ba5cc136ed7274" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40daff472d026d155fc703aacce899b1c5ab98ea#40daff472d026d155fc703aacce899b1c5ab98ea"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"app-error", "app-error",
@ -831,7 +831,7 @@ dependencies = [
[[package]] [[package]]
name = "collab" name = "collab"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=7d7f53250f7a8297c69e2cdc72e441f5469eaf11#7d7f53250f7a8297c69e2cdc72e441f5469eaf11" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=b036feb396aa6a1dbbab9589bd032e29db8ab024#b036feb396aa6a1dbbab9589bd032e29db8ab024"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
@ -840,6 +840,7 @@ dependencies = [
"parking_lot", "parking_lot",
"serde", "serde",
"serde_json", "serde_json",
"serde_repr",
"thiserror", "thiserror",
"tokio", "tokio",
"tokio-stream", "tokio-stream",
@ -850,7 +851,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-database" name = "collab-database"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=7d7f53250f7a8297c69e2cdc72e441f5469eaf11#7d7f53250f7a8297c69e2cdc72e441f5469eaf11" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=b036feb396aa6a1dbbab9589bd032e29db8ab024#b036feb396aa6a1dbbab9589bd032e29db8ab024"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
@ -879,7 +880,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-document" name = "collab-document"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=7d7f53250f7a8297c69e2cdc72e441f5469eaf11#7d7f53250f7a8297c69e2cdc72e441f5469eaf11" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=b036feb396aa6a1dbbab9589bd032e29db8ab024#b036feb396aa6a1dbbab9589bd032e29db8ab024"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"collab", "collab",
@ -897,7 +898,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-entity" name = "collab-entity"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=7d7f53250f7a8297c69e2cdc72e441f5469eaf11#7d7f53250f7a8297c69e2cdc72e441f5469eaf11" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=b036feb396aa6a1dbbab9589bd032e29db8ab024#b036feb396aa6a1dbbab9589bd032e29db8ab024"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bytes", "bytes",
@ -911,7 +912,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-folder" name = "collab-folder"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=7d7f53250f7a8297c69e2cdc72e441f5469eaf11#7d7f53250f7a8297c69e2cdc72e441f5469eaf11" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=b036feb396aa6a1dbbab9589bd032e29db8ab024#b036feb396aa6a1dbbab9589bd032e29db8ab024"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"chrono", "chrono",
@ -948,7 +949,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-persistence" name = "collab-persistence"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=7d7f53250f7a8297c69e2cdc72e441f5469eaf11#7d7f53250f7a8297c69e2cdc72e441f5469eaf11" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=b036feb396aa6a1dbbab9589bd032e29db8ab024#b036feb396aa6a1dbbab9589bd032e29db8ab024"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
@ -969,7 +970,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-plugins" name = "collab-plugins"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=7d7f53250f7a8297c69e2cdc72e441f5469eaf11#7d7f53250f7a8297c69e2cdc72e441f5469eaf11" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=b036feb396aa6a1dbbab9589bd032e29db8ab024#b036feb396aa6a1dbbab9589bd032e29db8ab024"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
@ -995,7 +996,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-user" name = "collab-user"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=7d7f53250f7a8297c69e2cdc72e441f5469eaf11#7d7f53250f7a8297c69e2cdc72e441f5469eaf11" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=b036feb396aa6a1dbbab9589bd032e29db8ab024#b036feb396aa6a1dbbab9589bd032e29db8ab024"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"collab", "collab",
@ -1253,7 +1254,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331"
dependencies = [ dependencies = [
"quote", "quote",
"syn 2.0.32", "syn 2.0.46",
] ]
[[package]] [[package]]
@ -1317,7 +1318,7 @@ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"strsim", "strsim",
"syn 2.0.32", "syn 2.0.46",
] ]
[[package]] [[package]]
@ -1328,7 +1329,7 @@ checksum = "29a358ff9f12ec09c3e61fef9b5a9902623a695a46a917b07f269bff1445611a"
dependencies = [ dependencies = [
"darling_core", "darling_core",
"quote", "quote",
"syn 2.0.32", "syn 2.0.46",
] ]
[[package]] [[package]]
@ -1353,10 +1354,11 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308"
[[package]] [[package]]
name = "database-entity" name = "database-entity"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=a455c9de8e6448cec956da5a00ba5cc136ed7274#a455c9de8e6448cec956da5a00ba5cc136ed7274" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40daff472d026d155fc703aacce899b1c5ab98ea#40daff472d026d155fc703aacce899b1c5ab98ea"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"app-error", "app-error",
"bincode",
"chrono", "chrono",
"collab-entity", "collab-entity",
"serde", "serde",
@ -1431,7 +1433,7 @@ dependencies = [
"diesel_table_macro_syntax", "diesel_table_macro_syntax",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.32", "syn 2.0.46",
] ]
[[package]] [[package]]
@ -1451,7 +1453,7 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc5557efc453706fed5e4fa85006fe9817c224c3f480a34c7e5959fd700921c5" checksum = "fc5557efc453706fed5e4fa85006fe9817c224c3f480a34c7e5959fd700921c5"
dependencies = [ dependencies = [
"syn 2.0.32", "syn 2.0.46",
] ]
[[package]] [[package]]
@ -2320,7 +2322,7 @@ checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.32", "syn 2.0.46",
] ]
[[package]] [[package]]
@ -2649,7 +2651,7 @@ dependencies = [
[[package]] [[package]]
name = "gotrue" name = "gotrue"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=a455c9de8e6448cec956da5a00ba5cc136ed7274#a455c9de8e6448cec956da5a00ba5cc136ed7274" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40daff472d026d155fc703aacce899b1c5ab98ea#40daff472d026d155fc703aacce899b1c5ab98ea"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"futures-util", "futures-util",
@ -2665,7 +2667,7 @@ dependencies = [
[[package]] [[package]]
name = "gotrue-entity" name = "gotrue-entity"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=a455c9de8e6448cec956da5a00ba5cc136ed7274#a455c9de8e6448cec956da5a00ba5cc136ed7274" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40daff472d026d155fc703aacce899b1c5ab98ea#40daff472d026d155fc703aacce899b1c5ab98ea"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"app-error", "app-error",
@ -3087,7 +3089,7 @@ dependencies = [
[[package]] [[package]]
name = "infra" name = "infra"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=a455c9de8e6448cec956da5a00ba5cc136ed7274#a455c9de8e6448cec956da5a00ba5cc136ed7274" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40daff472d026d155fc703aacce899b1c5ab98ea#40daff472d026d155fc703aacce899b1c5ab98ea"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"reqwest", "reqwest",
@ -3893,7 +3895,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.32", "syn 2.0.46",
] ]
[[package]] [[package]]
@ -4103,7 +4105,7 @@ dependencies = [
"pest_meta", "pest_meta",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.32", "syn 2.0.46",
] ]
[[package]] [[package]]
@ -4257,7 +4259,7 @@ dependencies = [
"phf_shared 0.11.2", "phf_shared 0.11.2",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.32", "syn 2.0.46",
] ]
[[package]] [[package]]
@ -4305,7 +4307,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.32", "syn 2.0.46",
] ]
[[package]] [[package]]
@ -4422,7 +4424,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9825a04601d60621feed79c4e6b56d65db77cdca55cef43b46b0de1096d1c282" checksum = "9825a04601d60621feed79c4e6b56d65db77cdca55cef43b46b0de1096d1c282"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"syn 2.0.32", "syn 2.0.46",
] ]
[[package]] [[package]]
@ -4476,9 +4478,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.63" version = "1.0.74"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb" checksum = "2de98502f212cfcea8d0bb305bd0f49d7ebdd75b64ba0a68f937d888f4e0d6db"
dependencies = [ dependencies = [
"unicode-ident", "unicode-ident",
] ]
@ -4510,7 +4512,7 @@ dependencies = [
"prost", "prost",
"prost-types", "prost-types",
"regex", "regex",
"syn 2.0.32", "syn 2.0.46",
"tempfile", "tempfile",
"which", "which",
] ]
@ -4525,7 +4527,7 @@ dependencies = [
"itertools 0.11.0", "itertools 0.11.0",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.32", "syn 2.0.46",
] ]
[[package]] [[package]]
@ -4681,9 +4683,9 @@ dependencies = [
[[package]] [[package]]
name = "quote" name = "quote"
version = "1.0.30" version = "1.0.35"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5907a1b7c277254a8b15170f6e7c97cfa60ee7872a3217663bb81151e48184bb" checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
] ]
@ -4817,7 +4819,7 @@ dependencies = [
[[package]] [[package]]
name = "realtime-entity" name = "realtime-entity"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=a455c9de8e6448cec956da5a00ba5cc136ed7274#a455c9de8e6448cec956da5a00ba5cc136ed7274" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40daff472d026d155fc703aacce899b1c5ab98ea#40daff472d026d155fc703aacce899b1c5ab98ea"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bincode", "bincode",
@ -4839,7 +4841,7 @@ dependencies = [
[[package]] [[package]]
name = "realtime-protocol" name = "realtime-protocol"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=a455c9de8e6448cec956da5a00ba5cc136ed7274#a455c9de8e6448cec956da5a00ba5cc136ed7274" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40daff472d026d155fc703aacce899b1c5ab98ea#40daff472d026d155fc703aacce899b1c5ab98ea"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bincode", "bincode",
@ -5391,7 +5393,7 @@ checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.32", "syn 2.0.46",
] ]
[[package]] [[package]]
@ -5407,13 +5409,13 @@ dependencies = [
[[package]] [[package]]
name = "serde_repr" name = "serde_repr"
version = "0.1.16" version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8725e1dfadb3a50f7e5ce0b1a540466f6ed3fe7a0fca2ac2b8b831d31316bd00" checksum = "0b2e6b945e9d3df726b65d6ee24060aff8e3533d431f677a9695db04eff9dfdb"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.32", "syn 2.0.46",
] ]
[[package]] [[package]]
@ -5462,7 +5464,7 @@ dependencies = [
"darling", "darling",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.32", "syn 2.0.46",
] ]
[[package]] [[package]]
@ -5546,7 +5548,7 @@ dependencies = [
[[package]] [[package]]
name = "shared_entity" name = "shared_entity"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=a455c9de8e6448cec956da5a00ba5cc136ed7274#a455c9de8e6448cec956da5a00ba5cc136ed7274" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40daff472d026d155fc703aacce899b1c5ab98ea#40daff472d026d155fc703aacce899b1c5ab98ea"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"app-error", "app-error",
@ -5904,7 +5906,7 @@ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"rustversion", "rustversion",
"syn 2.0.32", "syn 2.0.46",
] ]
[[package]] [[package]]
@ -5926,9 +5928,9 @@ dependencies = [
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.32" version = "2.0.46"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "239814284fd6f1a4ffe4ca893952cdd93c224b6a1571c9a9eadd670295c0c9e2" checksum = "89456b690ff72fddcecf231caedbe615c59480c93358a93dfae7fc29e3ebbf0e"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -6309,7 +6311,7 @@ checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.32", "syn 2.0.46",
] ]
[[package]] [[package]]
@ -6401,7 +6403,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.32", "syn 2.0.46",
] ]
[[package]] [[package]]
@ -6562,11 +6564,12 @@ dependencies = [
[[package]] [[package]]
name = "tracing-appender" name = "tracing-appender"
version = "0.2.2" version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09d48f71a791638519505cefafe162606f706c25592e4bde4d97600c0195312e" checksum = "3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf"
dependencies = [ dependencies = [
"crossbeam-channel", "crossbeam-channel",
"thiserror",
"time", "time",
"tracing-subscriber", "tracing-subscriber",
] ]
@ -6579,7 +6582,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.32", "syn 2.0.46",
] ]
[[package]] [[package]]
@ -6596,7 +6599,7 @@ dependencies = [
"time", "time",
"tracing", "tracing",
"tracing-core", "tracing-core",
"tracing-log", "tracing-log 0.1.3",
"tracing-subscriber", "tracing-subscriber",
] ]
@ -6621,6 +6624,17 @@ dependencies = [
"tracing-core", "tracing-core",
] ]
[[package]]
name = "tracing-log"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3"
dependencies = [
"log",
"once_cell",
"tracing-core",
]
[[package]] [[package]]
name = "tracing-serde" name = "tracing-serde"
version = "0.1.3" version = "0.1.3"
@ -6633,9 +6647,9 @@ dependencies = [
[[package]] [[package]]
name = "tracing-subscriber" name = "tracing-subscriber"
version = "0.3.17" version = "0.3.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b"
dependencies = [ dependencies = [
"matchers", "matchers",
"nu-ansi-term", "nu-ansi-term",
@ -6648,7 +6662,7 @@ dependencies = [
"thread_local", "thread_local",
"tracing", "tracing",
"tracing-core", "tracing-core",
"tracing-log", "tracing-log 0.2.0",
"tracing-serde", "tracing-serde",
] ]
@ -6995,7 +7009,7 @@ dependencies = [
"once_cell", "once_cell",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.32", "syn 2.0.46",
"wasm-bindgen-shared", "wasm-bindgen-shared",
] ]
@ -7029,7 +7043,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.32", "syn 2.0.46",
"wasm-bindgen-backend", "wasm-bindgen-backend",
"wasm-bindgen-shared", "wasm-bindgen-shared",
] ]
@ -7436,7 +7450,7 @@ dependencies = [
[[package]] [[package]]
name = "workspace-template" name = "workspace-template"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=a455c9de8e6448cec956da5a00ba5cc136ed7274#a455c9de8e6448cec956da5a00ba5cc136ed7274" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40daff472d026d155fc703aacce899b1c5ab98ea#40daff472d026d155fc703aacce899b1c5ab98ea"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
@ -7562,7 +7576,7 @@ checksum = "dd7e48ccf166952882ca8bd778a43502c64f33bf94c12ebe2a7f08e5a0f6689f"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.32", "syn 2.0.46",
] ]
[[package]] [[package]]

View File

@ -57,7 +57,7 @@ custom-protocol = ["tauri/custom-protocol"]
# Run the script: # Run the script:
# scripts/tool/update_client_api_rev.sh new_rev_id # scripts/tool/update_client_api_rev.sh new_rev_id
# ⚠️⚠️⚠️️ # ⚠️⚠️⚠️️
client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "a455c9de8e6448cec956da5a00ba5cc136ed7274" } client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "40daff472d026d155fc703aacce899b1c5ab98ea" }
# Please use the following script to update collab. # Please use the following script to update collab.
# Working directory: frontend # Working directory: frontend
# #
@ -67,14 +67,14 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "a45
# To switch to the local path, run: # To switch to the local path, run:
# scripts/tool/update_collab_source.sh # scripts/tool/update_collab_source.sh
# ⚠️⚠️⚠️️ # ⚠️⚠️⚠️️
collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "7d7f53250f7a8297c69e2cdc72e441f5469eaf11" } collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "b036feb396aa6a1dbbab9589bd032e29db8ab024" }
collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "7d7f53250f7a8297c69e2cdc72e441f5469eaf11" } collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "b036feb396aa6a1dbbab9589bd032e29db8ab024" }
collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "7d7f53250f7a8297c69e2cdc72e441f5469eaf11" } collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "b036feb396aa6a1dbbab9589bd032e29db8ab024" }
collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "7d7f53250f7a8297c69e2cdc72e441f5469eaf11" } collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "b036feb396aa6a1dbbab9589bd032e29db8ab024" }
collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "7d7f53250f7a8297c69e2cdc72e441f5469eaf11" } collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "b036feb396aa6a1dbbab9589bd032e29db8ab024" }
collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "7d7f53250f7a8297c69e2cdc72e441f5469eaf11" } collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "b036feb396aa6a1dbbab9589bd032e29db8ab024" }
collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "7d7f53250f7a8297c69e2cdc72e441f5469eaf11" } collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "b036feb396aa6a1dbbab9589bd032e29db8ab024" }
collab-persistence = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "7d7f53250f7a8297c69e2cdc72e441f5469eaf11" } collab-persistence = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "b036feb396aa6a1dbbab9589bd032e29db8ab024" }

View File

@ -125,7 +125,7 @@ checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
[[package]] [[package]]
name = "app-error" name = "app-error"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=a455c9de8e6448cec956da5a00ba5cc136ed7274#a455c9de8e6448cec956da5a00ba5cc136ed7274" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40daff472d026d155fc703aacce899b1c5ab98ea#40daff472d026d155fc703aacce899b1c5ab98ea"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"reqwest", "reqwest",
@ -204,7 +204,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.31", "syn 2.0.46",
] ]
[[package]] [[package]]
@ -215,7 +215,7 @@ checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.31", "syn 2.0.46",
] ]
[[package]] [[package]]
@ -413,7 +413,7 @@ dependencies = [
"regex", "regex",
"rustc-hash", "rustc-hash",
"shlex", "shlex",
"syn 2.0.31", "syn 2.0.46",
] ]
[[package]] [[package]]
@ -670,7 +670,7 @@ dependencies = [
[[package]] [[package]]
name = "client-api" name = "client-api"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=a455c9de8e6448cec956da5a00ba5cc136ed7274#a455c9de8e6448cec956da5a00ba5cc136ed7274" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40daff472d026d155fc703aacce899b1c5ab98ea#40daff472d026d155fc703aacce899b1c5ab98ea"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"app-error", "app-error",
@ -736,7 +736,7 @@ dependencies = [
[[package]] [[package]]
name = "collab" name = "collab"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=7d7f53250f7a8297c69e2cdc72e441f5469eaf11#7d7f53250f7a8297c69e2cdc72e441f5469eaf11" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=b036feb396aa6a1dbbab9589bd032e29db8ab024#b036feb396aa6a1dbbab9589bd032e29db8ab024"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
@ -745,6 +745,7 @@ dependencies = [
"parking_lot", "parking_lot",
"serde", "serde",
"serde_json", "serde_json",
"serde_repr",
"thiserror", "thiserror",
"tokio", "tokio",
"tokio-stream", "tokio-stream",
@ -755,7 +756,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-database" name = "collab-database"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=7d7f53250f7a8297c69e2cdc72e441f5469eaf11#7d7f53250f7a8297c69e2cdc72e441f5469eaf11" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=b036feb396aa6a1dbbab9589bd032e29db8ab024#b036feb396aa6a1dbbab9589bd032e29db8ab024"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
@ -784,7 +785,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-document" name = "collab-document"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=7d7f53250f7a8297c69e2cdc72e441f5469eaf11#7d7f53250f7a8297c69e2cdc72e441f5469eaf11" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=b036feb396aa6a1dbbab9589bd032e29db8ab024#b036feb396aa6a1dbbab9589bd032e29db8ab024"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"collab", "collab",
@ -802,7 +803,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-entity" name = "collab-entity"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=7d7f53250f7a8297c69e2cdc72e441f5469eaf11#7d7f53250f7a8297c69e2cdc72e441f5469eaf11" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=b036feb396aa6a1dbbab9589bd032e29db8ab024#b036feb396aa6a1dbbab9589bd032e29db8ab024"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bytes", "bytes",
@ -816,7 +817,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-folder" name = "collab-folder"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=7d7f53250f7a8297c69e2cdc72e441f5469eaf11#7d7f53250f7a8297c69e2cdc72e441f5469eaf11" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=b036feb396aa6a1dbbab9589bd032e29db8ab024#b036feb396aa6a1dbbab9589bd032e29db8ab024"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"chrono", "chrono",
@ -853,7 +854,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-persistence" name = "collab-persistence"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=7d7f53250f7a8297c69e2cdc72e441f5469eaf11#7d7f53250f7a8297c69e2cdc72e441f5469eaf11" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=b036feb396aa6a1dbbab9589bd032e29db8ab024#b036feb396aa6a1dbbab9589bd032e29db8ab024"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
@ -874,7 +875,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-plugins" name = "collab-plugins"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=7d7f53250f7a8297c69e2cdc72e441f5469eaf11#7d7f53250f7a8297c69e2cdc72e441f5469eaf11" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=b036feb396aa6a1dbbab9589bd032e29db8ab024#b036feb396aa6a1dbbab9589bd032e29db8ab024"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
@ -900,7 +901,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-user" name = "collab-user"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=7d7f53250f7a8297c69e2cdc72e441f5469eaf11#7d7f53250f7a8297c69e2cdc72e441f5469eaf11" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=b036feb396aa6a1dbbab9589bd032e29db8ab024#b036feb396aa6a1dbbab9589bd032e29db8ab024"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"collab", "collab",
@ -1132,7 +1133,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331"
dependencies = [ dependencies = [
"quote", "quote",
"syn 2.0.31", "syn 2.0.46",
] ]
[[package]] [[package]]
@ -1249,10 +1250,11 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308"
[[package]] [[package]]
name = "database-entity" name = "database-entity"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=a455c9de8e6448cec956da5a00ba5cc136ed7274#a455c9de8e6448cec956da5a00ba5cc136ed7274" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40daff472d026d155fc703aacce899b1c5ab98ea#40daff472d026d155fc703aacce899b1c5ab98ea"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"app-error", "app-error",
"bincode",
"chrono", "chrono",
"collab-entity", "collab-entity",
"serde", "serde",
@ -1365,7 +1367,7 @@ dependencies = [
"diesel_table_macro_syntax", "diesel_table_macro_syntax",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.31", "syn 2.0.46",
] ]
[[package]] [[package]]
@ -1385,7 +1387,7 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc5557efc453706fed5e4fa85006fe9817c224c3f480a34c7e5959fd700921c5" checksum = "fc5557efc453706fed5e4fa85006fe9817c224c3f480a34c7e5959fd700921c5"
dependencies = [ dependencies = [
"syn 2.0.31", "syn 2.0.46",
] ]
[[package]] [[package]]
@ -1532,6 +1534,7 @@ dependencies = [
"anyhow", "anyhow",
"assert-json-diff", "assert-json-diff",
"bytes", "bytes",
"chrono",
"collab", "collab",
"collab-database", "collab-database",
"collab-document", "collab-document",
@ -2300,7 +2303,7 @@ checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.31", "syn 2.0.46",
] ]
[[package]] [[package]]
@ -2450,7 +2453,7 @@ dependencies = [
[[package]] [[package]]
name = "gotrue" name = "gotrue"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=a455c9de8e6448cec956da5a00ba5cc136ed7274#a455c9de8e6448cec956da5a00ba5cc136ed7274" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40daff472d026d155fc703aacce899b1c5ab98ea#40daff472d026d155fc703aacce899b1c5ab98ea"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"futures-util", "futures-util",
@ -2466,7 +2469,7 @@ dependencies = [
[[package]] [[package]]
name = "gotrue-entity" name = "gotrue-entity"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=a455c9de8e6448cec956da5a00ba5cc136ed7274#a455c9de8e6448cec956da5a00ba5cc136ed7274" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40daff472d026d155fc703aacce899b1c5ab98ea#40daff472d026d155fc703aacce899b1c5ab98ea"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"app-error", "app-error",
@ -2827,7 +2830,7 @@ dependencies = [
[[package]] [[package]]
name = "infra" name = "infra"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=a455c9de8e6448cec956da5a00ba5cc136ed7274#a455c9de8e6448cec956da5a00ba5cc136ed7274" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40daff472d026d155fc703aacce899b1c5ab98ea#40daff472d026d155fc703aacce899b1c5ab98ea"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"reqwest", "reqwest",
@ -3392,7 +3395,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.31", "syn 2.0.46",
] ]
[[package]] [[package]]
@ -3572,7 +3575,7 @@ dependencies = [
"pest_meta", "pest_meta",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.31", "syn 2.0.46",
] ]
[[package]] [[package]]
@ -3700,7 +3703,7 @@ dependencies = [
"phf_shared 0.11.2", "phf_shared 0.11.2",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.31", "syn 2.0.46",
] ]
[[package]] [[package]]
@ -3747,7 +3750,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.31", "syn 2.0.46",
] ]
[[package]] [[package]]
@ -3837,7 +3840,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8832c0f9be7e3cae60727e6256cfd2cd3c3e2b6cd5dad4190ecb2fd658c9030b" checksum = "8832c0f9be7e3cae60727e6256cfd2cd3c3e2b6cd5dad4190ecb2fd658c9030b"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"syn 2.0.31", "syn 2.0.46",
] ]
[[package]] [[package]]
@ -3881,9 +3884,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.66" version = "1.0.74"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" checksum = "2de98502f212cfcea8d0bb305bd0f49d7ebdd75b64ba0a68f937d888f4e0d6db"
dependencies = [ dependencies = [
"unicode-ident", "unicode-ident",
] ]
@ -3915,7 +3918,7 @@ dependencies = [
"prost", "prost",
"prost-types", "prost-types",
"regex", "regex",
"syn 2.0.31", "syn 2.0.46",
"tempfile", "tempfile",
"which", "which",
] ]
@ -3930,7 +3933,7 @@ dependencies = [
"itertools 0.11.0", "itertools 0.11.0",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.31", "syn 2.0.46",
] ]
[[package]] [[package]]
@ -4099,9 +4102,9 @@ dependencies = [
[[package]] [[package]]
name = "quote" name = "quote"
version = "1.0.33" version = "1.0.35"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
] ]
@ -4266,7 +4269,7 @@ dependencies = [
[[package]] [[package]]
name = "realtime-entity" name = "realtime-entity"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=a455c9de8e6448cec956da5a00ba5cc136ed7274#a455c9de8e6448cec956da5a00ba5cc136ed7274" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40daff472d026d155fc703aacce899b1c5ab98ea#40daff472d026d155fc703aacce899b1c5ab98ea"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bincode", "bincode",
@ -4288,7 +4291,7 @@ dependencies = [
[[package]] [[package]]
name = "realtime-protocol" name = "realtime-protocol"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=a455c9de8e6448cec956da5a00ba5cc136ed7274#a455c9de8e6448cec956da5a00ba5cc136ed7274" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40daff472d026d155fc703aacce899b1c5ab98ea#40daff472d026d155fc703aacce899b1c5ab98ea"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bincode", "bincode",
@ -4838,7 +4841,7 @@ checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.31", "syn 2.0.46",
] ]
[[package]] [[package]]
@ -4854,13 +4857,13 @@ dependencies = [
[[package]] [[package]]
name = "serde_repr" name = "serde_repr"
version = "0.1.16" version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8725e1dfadb3a50f7e5ce0b1a540466f6ed3fe7a0fca2ac2b8b831d31316bd00" checksum = "0b2e6b945e9d3df726b65d6ee24060aff8e3533d431f677a9695db04eff9dfdb"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.31", "syn 2.0.46",
] ]
[[package]] [[package]]
@ -4946,7 +4949,7 @@ dependencies = [
[[package]] [[package]]
name = "shared_entity" name = "shared_entity"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=a455c9de8e6448cec956da5a00ba5cc136ed7274#a455c9de8e6448cec956da5a00ba5cc136ed7274" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40daff472d026d155fc703aacce899b1c5ab98ea#40daff472d026d155fc703aacce899b1c5ab98ea"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"app-error", "app-error",
@ -5262,7 +5265,7 @@ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"rustversion", "rustversion",
"syn 2.0.31", "syn 2.0.46",
] ]
[[package]] [[package]]
@ -5284,9 +5287,9 @@ dependencies = [
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.31" version = "2.0.46"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "718fa2415bcb8d8bd775917a1bf12a7931b6dfa890753378538118181e0cb398" checksum = "89456b690ff72fddcecf231caedbe615c59480c93358a93dfae7fc29e3ebbf0e"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -5397,7 +5400,7 @@ checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.31", "syn 2.0.46",
] ]
[[package]] [[package]]
@ -5502,7 +5505,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.31", "syn 2.0.46",
] ]
[[package]] [[package]]
@ -5718,11 +5721,12 @@ dependencies = [
[[package]] [[package]]
name = "tracing-appender" name = "tracing-appender"
version = "0.2.2" version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09d48f71a791638519505cefafe162606f706c25592e4bde4d97600c0195312e" checksum = "3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf"
dependencies = [ dependencies = [
"crossbeam-channel", "crossbeam-channel",
"thiserror",
"time", "time",
"tracing-subscriber", "tracing-subscriber",
] ]
@ -5735,7 +5739,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.31", "syn 2.0.46",
] ]
[[package]] [[package]]
@ -5752,7 +5756,7 @@ dependencies = [
"time", "time",
"tracing", "tracing",
"tracing-core", "tracing-core",
"tracing-log", "tracing-log 0.1.3",
"tracing-subscriber", "tracing-subscriber",
] ]
@ -5777,6 +5781,17 @@ dependencies = [
"tracing-core", "tracing-core",
] ]
[[package]]
name = "tracing-log"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3"
dependencies = [
"log",
"once_cell",
"tracing-core",
]
[[package]] [[package]]
name = "tracing-serde" name = "tracing-serde"
version = "0.1.3" version = "0.1.3"
@ -5789,9 +5804,9 @@ dependencies = [
[[package]] [[package]]
name = "tracing-subscriber" name = "tracing-subscriber"
version = "0.3.17" version = "0.3.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b"
dependencies = [ dependencies = [
"matchers", "matchers",
"nu-ansi-term", "nu-ansi-term",
@ -5804,7 +5819,7 @@ dependencies = [
"thread_local", "thread_local",
"tracing", "tracing",
"tracing-core", "tracing-core",
"tracing-log", "tracing-log 0.2.0",
"tracing-serde", "tracing-serde",
] ]
@ -6127,7 +6142,7 @@ dependencies = [
"once_cell", "once_cell",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.31", "syn 2.0.46",
"wasm-bindgen-shared", "wasm-bindgen-shared",
] ]
@ -6161,7 +6176,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.31", "syn 2.0.46",
"wasm-bindgen-backend", "wasm-bindgen-backend",
"wasm-bindgen-shared", "wasm-bindgen-shared",
] ]
@ -6351,7 +6366,7 @@ dependencies = [
[[package]] [[package]]
name = "workspace-template" name = "workspace-template"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=a455c9de8e6448cec956da5a00ba5cc136ed7274#a455c9de8e6448cec956da5a00ba5cc136ed7274" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40daff472d026d155fc703aacce899b1c5ab98ea#40daff472d026d155fc703aacce899b1c5ab98ea"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
@ -6409,7 +6424,7 @@ checksum = "dd7e48ccf166952882ca8bd778a43502c64f33bf94c12ebe2a7f08e5a0f6689f"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.31", "syn 2.0.46",
] ]
[[package]] [[package]]

View File

@ -107,7 +107,7 @@ incremental = false
# Run the script: # Run the script:
# scripts/tool/update_client_api_rev.sh new_rev_id # scripts/tool/update_client_api_rev.sh new_rev_id
# ⚠️⚠️⚠️️ # ⚠️⚠️⚠️️
client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "a455c9de8e6448cec956da5a00ba5cc136ed7274" } client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "40daff472d026d155fc703aacce899b1c5ab98ea" }
# Please use the following script to update collab. # Please use the following script to update collab.
# Working directory: frontend # Working directory: frontend
# #
@ -117,11 +117,11 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "a45
# To switch to the local path, run: # To switch to the local path, run:
# scripts/tool/update_collab_source.sh # scripts/tool/update_collab_source.sh
# ⚠️⚠️⚠️️ # ⚠️⚠️⚠️️
collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "7d7f53250f7a8297c69e2cdc72e441f5469eaf11" } collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "b036feb396aa6a1dbbab9589bd032e29db8ab024" }
collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "7d7f53250f7a8297c69e2cdc72e441f5469eaf11" } collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "b036feb396aa6a1dbbab9589bd032e29db8ab024" }
collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "7d7f53250f7a8297c69e2cdc72e441f5469eaf11" } collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "b036feb396aa6a1dbbab9589bd032e29db8ab024" }
collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "7d7f53250f7a8297c69e2cdc72e441f5469eaf11" } collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "b036feb396aa6a1dbbab9589bd032e29db8ab024" }
collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "7d7f53250f7a8297c69e2cdc72e441f5469eaf11" } collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "b036feb396aa6a1dbbab9589bd032e29db8ab024" }
collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "7d7f53250f7a8297c69e2cdc72e441f5469eaf11" } collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "b036feb396aa6a1dbbab9589bd032e29db8ab024" }
collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "7d7f53250f7a8297c69e2cdc72e441f5469eaf11" } collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "b036feb396aa6a1dbbab9589bd032e29db8ab024" }
collab-persistence = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "7d7f53250f7a8297c69e2cdc72e441f5469eaf11" } collab-persistence = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "b036feb396aa6a1dbbab9589bd032e29db8ab024" }

View File

@ -48,6 +48,7 @@ tempdir = "0.3.7"
uuid.workspace = true uuid.workspace = true
assert-json-diff = "2.0.2" assert-json-diff = "2.0.2"
tokio-postgres = { version = "0.7.8" } tokio-postgres = { version = "0.7.8" }
chrono = "0.4.31"
zip = "0.6.6" zip = "0.6.6"
[features] [features]

View File

@ -64,17 +64,6 @@ impl EventIntegrationTest {
.items .items
} }
pub async fn get_views(&self, parent_view_id: &str) -> ViewPB {
EventBuilder::new(self.clone())
.event(FolderEvent::GetView)
.payload(ViewIdPB {
value: parent_view_id.to_string(),
})
.async_send()
.await
.parse::<ViewPB>()
}
pub async fn get_trash(&self) -> RepeatedTrashPB { pub async fn get_trash(&self) -> RepeatedTrashPB {
EventBuilder::new(self.clone()) EventBuilder::new(self.clone())
.event(FolderEvent::ListTrashItems) .event(FolderEvent::ListTrashItems)

View File

@ -53,7 +53,7 @@ impl EventIntegrationTest {
let path = path_buf.to_str().unwrap().to_string(); let path = path_buf.to_str().unwrap().to_string();
let device_id = uuid::Uuid::new_v4().to_string(); let device_id = uuid::Uuid::new_v4().to_string();
let level = "info"; let level = "trace";
std::env::set_var("RUST_LOG", level); std::env::set_var("RUST_LOG", level);
let config = AppFlowyCoreConfig::new(path.clone(), path, device_id, name).log_filter( let config = AppFlowyCoreConfig::new(path.clone(), path, device_id, name).log_filter(
level, level,

View File

@ -24,12 +24,12 @@ async fn reading_039_anon_user_data_test() {
); );
assert_eq!(first_level_views[0].name, "Document1".to_string()); assert_eq!(first_level_views[0].name, "Document1".to_string());
let second_level_views = test.get_views(&first_level_views[0].id).await.child_views; let second_level_views = test.get_view(&first_level_views[0].id).await.child_views;
assert_eq!(second_level_views.len(), 1); assert_eq!(second_level_views.len(), 1);
assert_eq!(second_level_views[0].name, "Document2".to_string()); assert_eq!(second_level_views[0].name, "Document2".to_string());
// In the 039_local, there is only one view of the workspaces child // In the 039_local, there is only one view of the workspaces child
let third_level_views = test.get_views(&second_level_views[0].id).await.child_views; let third_level_views = test.get_view(&second_level_views[0].id).await.child_views;
assert_eq!(third_level_views.len(), 2); assert_eq!(third_level_views.len(), 2);
assert_eq!(third_level_views[0].name, "Grid1".to_string()); assert_eq!(third_level_views[0].name, "Grid1".to_string());
assert_eq!(third_level_views[1].name, "Grid2".to_string()); assert_eq!(third_level_views[1].name, "Grid2".to_string());
@ -62,11 +62,11 @@ async fn migrate_anon_user_data_to_af_cloud_test() {
let anon_first_level_views = test.get_all_workspace_views().await; let anon_first_level_views = test.get_all_workspace_views().await;
let anon_second_level_views = test let anon_second_level_views = test
.get_views(&anon_first_level_views[0].id) .get_view(&anon_first_level_views[0].id)
.await .await
.child_views; .child_views;
let anon_third_level_views = test let anon_third_level_views = test
.get_views(&anon_second_level_views[0].id) .get_view(&anon_second_level_views[0].id)
.await .await
.child_views; .child_views;
@ -82,12 +82,12 @@ async fn migrate_anon_user_data_to_af_cloud_test() {
println!("user first level views: {:?}", user_first_level_views); println!("user first level views: {:?}", user_first_level_views);
let user_second_level_views = test let user_second_level_views = test
.get_views(&user_first_level_views[0].id) .get_view(&user_first_level_views[0].id)
.await .await
.child_views; .child_views;
println!("user second level views: {:?}", user_second_level_views); println!("user second level views: {:?}", user_second_level_views);
let user_third_level_views = test let user_third_level_views = test
.get_views(&user_second_level_views[0].id) .get_view(&user_second_level_views[0].id)
.await .await
.child_views; .child_views;
println!("user third level views: {:?}", user_third_level_views); println!("user third level views: {:?}", user_third_level_views);

View File

@ -45,16 +45,16 @@ async fn import_appflowy_data_folder_into_new_view_test() {
assert_eq!(views.len(), 2); assert_eq!(views.len(), 2);
assert_eq!(views[1].name, import_container_name); assert_eq!(views[1].name, import_container_name);
let local_child_views = test.get_views(&views[1].id).await.child_views; let local_child_views = test.get_view(&views[1].id).await.child_views;
assert_eq!(local_child_views.len(), 1); assert_eq!(local_child_views.len(), 1);
assert_eq!(local_child_views[0].name, "Document1"); assert_eq!(local_child_views[0].name, "Document1");
let document1_child_views = test.get_views(&local_child_views[0].id).await.child_views; let document1_child_views = test.get_view(&local_child_views[0].id).await.child_views;
assert_eq!(document1_child_views.len(), 1); assert_eq!(document1_child_views.len(), 1);
assert_eq!(document1_child_views[0].name, "Document2"); assert_eq!(document1_child_views[0].name, "Document2");
let document2_child_views = test let document2_child_views = test
.get_views(&document1_child_views[0].id) .get_view(&document1_child_views[0].id)
.await .await
.child_views; .child_views;
assert_eq!(document2_child_views.len(), 2); assert_eq!(document2_child_views.len(), 2);
@ -97,12 +97,12 @@ async fn import_appflowy_data_folder_into_current_workspace_test() {
assert_eq!(views.len(), 2); assert_eq!(views.len(), 2);
assert_eq!(views[1].name, "Document1"); assert_eq!(views[1].name, "Document1");
let document_1_child_views = test.get_views(&views[1].id).await.child_views; let document_1_child_views = test.get_view(&views[1].id).await.child_views;
assert_eq!(document_1_child_views.len(), 1); assert_eq!(document_1_child_views.len(), 1);
assert_eq!(document_1_child_views[0].name, "Document2"); assert_eq!(document_1_child_views[0].name, "Document2");
let document2_child_views = test let document2_child_views = test
.get_views(&document_1_child_views[0].id) .get_view(&document_1_child_views[0].id)
.await .await
.child_views; .child_views;
assert_eq!(document2_child_views.len(), 2); assert_eq!(document2_child_views.len(), 2);
@ -216,14 +216,12 @@ async fn assert_040_local_2_import_content(test: &EventIntegrationTest, view_id:
// Doc3_grid_1 // Doc3_grid_1
// Doc3_grid_2 // Doc3_grid_2
// Doc3_calendar_1 // Doc3_calendar_1
let _local_2_child_views = test.get_views(view_id).await.child_views; let _local_2_child_views = test.get_view(view_id).await.child_views;
assert_eq!(_local_2_child_views.len(), 1); assert_eq!(_local_2_child_views.len(), 1);
assert_eq!(_local_2_child_views[0].name, "Getting started"); assert_eq!(_local_2_child_views[0].name, "Getting started");
let local_2_getting_started_child_views = test let local_2_getting_started_child_views =
.get_views(&_local_2_child_views[0].id) test.get_view(&_local_2_child_views[0].id).await.child_views;
.await
.child_views;
// Check doc 1 local content // Check doc 1 local content
let doc_1 = local_2_getting_started_child_views[0].clone(); let doc_1 = local_2_getting_started_child_views[0].clone();
@ -258,7 +256,7 @@ async fn assert_040_local_2_import_content(test: &EventIntegrationTest, view_id:
assert_eq!(local_2_getting_started_child_views[3].name, "Doc3"); assert_eq!(local_2_getting_started_child_views[3].name, "Doc3");
let doc_3_child_views = test let doc_3_child_views = test
.get_views(&local_2_getting_started_child_views[3].id) .get_view(&local_2_getting_started_child_views[3].id)
.await .await
.child_views; .child_views;
assert_eq!(doc_3_child_views.len(), 3); assert_eq!(doc_3_child_views.len(), 3);

View File

@ -26,7 +26,7 @@ async fn migrate_020_historical_empty_document_test() {
assert!(!data.meta.children_map.is_empty()); assert!(!data.meta.children_map.is_empty());
// Check the child views of the parent view // Check the child views of the parent view
let child_views = test.get_views(&parent_view.id).await.child_views; let child_views = test.get_view(&parent_view.id).await.child_views;
assert_eq!(child_views.len(), 4); assert_eq!(child_views.len(), 4);
assert_eq!(child_views[0].layout, ViewLayoutPB::Document); assert_eq!(child_views[0].layout, ViewLayoutPB::Document);
assert_eq!(child_views[1].layout, ViewLayoutPB::Grid); assert_eq!(child_views[1].layout, ViewLayoutPB::Grid);
@ -55,8 +55,125 @@ async fn migrate_036_fav_v1_workspace_array_test() {
assert_eq!(views[0].name, "root page"); assert_eq!(views[0].name, "root page");
assert_eq!(views[1].name, "\u{fe0f} Getting started"); assert_eq!(views[1].name, "\u{fe0f} Getting started");
let views = test.get_views(&views[1].id).await; let views = test.get_view(&views[1].id).await;
assert_eq!(views.child_views.len(), 3); assert_eq!(views.child_views.len(), 3);
assert!(views.child_views[2].is_favorite); assert!(views.child_views[2].is_favorite);
drop(cleaner); drop(cleaner);
} }
#[tokio::test]
async fn migrate_038_trash_test() {
// Used to test migration: WorkspaceTrashMapToSectionMigration
let (cleaner, user_db_path) = unzip_history_user_db("./tests/asset", "038_local").unwrap();
// Getting started
// Document1
// Document2(deleted)
// Document3(deleted)
// Document
// Document4(deleted)
// Document5
let test =
EventIntegrationTest::new_with_user_data_path(user_db_path, DEFAULT_NAME.to_string()).await;
let views = test.get_all_workspace_views().await;
assert_eq!(views.len(), 2);
assert_eq!(views[0].name, "Getting started");
assert_eq!(views[1].name, "Documents");
let get_started_child_views = test.get_view(&views[0].id).await.child_views;
assert_eq!(get_started_child_views.len(), 1);
assert_eq!(get_started_child_views[0].name, "Document1");
let get_started_child_views = test.get_view(&views[1].id).await.child_views;
assert_eq!(get_started_child_views.len(), 1);
assert_eq!(get_started_child_views[0].name, "Document5");
let trash_items = test.get_trash().await.items;
assert_eq!(trash_items.len(), 3);
assert_eq!(trash_items[0].name, "Document3");
assert_eq!(trash_items[1].name, "Document2");
assert_eq!(trash_items[2].name, "Document4");
drop(cleaner);
}
#[tokio::test]
async fn migrate_038_trash_test2() {
// Used to test migration: WorkspaceTrashMapToSectionMigration
let (cleaner, user_db_path) =
unzip_history_user_db("./tests/asset", "038_document_with_grid").unwrap();
// Getting started
// document
// grid
// board
let test =
EventIntegrationTest::new_with_user_data_path(user_db_path, DEFAULT_NAME.to_string()).await;
let views = test.get_all_workspace_views().await;
assert_eq!(views.len(), 1);
assert_eq!(views[0].name, "Getting started");
let views = test.get_view(&views[0].id).await.child_views;
assert_eq!(views[0].name, "document");
let views = test.get_view(&views[0].id).await.child_views;
assert_eq!(views[0].name, "grid");
let views = test.get_view(&views[0].id).await.child_views;
assert_eq!(views[0].name, "board");
drop(cleaner);
}
#[tokio::test]
async fn collab_db_backup_test() {
// Used to test migration: WorkspaceTrashMapToSectionMigration
let (cleaner, user_db_path) = unzip_history_user_db("./tests/asset", "038_local").unwrap();
let test =
EventIntegrationTest::new_with_user_data_path(user_db_path, DEFAULT_NAME.to_string()).await;
let uid = test.get_user_profile().await.unwrap().id;
let backups = test.user_manager.get_collab_backup_list(uid);
assert_eq!(backups.len(), 1);
assert_eq!(
backups[0],
format!(
"collab_db_{}",
chrono::Local::now().format("%Y%m%d").to_string()
)
);
drop(cleaner);
}
#[tokio::test]
async fn delete_outdated_collab_db_backup_test() {
// Used to test migration: WorkspaceTrashMapToSectionMigration
let (cleaner, user_db_path) =
unzip_history_user_db("./tests/asset", "040_collab_backups").unwrap();
let test =
EventIntegrationTest::new_with_user_data_path(user_db_path, DEFAULT_NAME.to_string()).await;
let uid = test.get_user_profile().await.unwrap().id;
let backups = test.user_manager.get_collab_backup_list(uid);
assert_eq!(backups.len(), 10);
assert_eq!(backups[0], "collab_db_0.4.0_20231202");
assert_eq!(backups[1], "collab_db_0.4.0_20231203");
assert_eq!(backups[2], "collab_db_0.4.0_20231204");
assert_eq!(backups[3], "collab_db_0.4.0_20231205");
assert_eq!(backups[4], "collab_db_0.4.0_20231206");
assert_eq!(backups[5], "collab_db_0.4.0_20231207");
assert_eq!(backups[6], "collab_db_0.4.0_20231208");
assert_eq!(backups[7], "collab_db_0.4.0_20231209");
assert_eq!(backups[8], "collab_db_0.4.0_20231210");
assert_eq!(
backups[9],
format!(
"collab_db_{}",
chrono::Local::now().format("%Y%m%d").to_string()
)
);
drop(cleaner);
}

View File

@ -41,7 +41,7 @@ impl fmt::Debug for AppFlowyCoreConfig {
} }
} }
fn migrate_local_version_data_folder(root: &str, url: &str) -> String { fn make_user_data_folder(root: &str, url: &str) -> String {
// Isolate the user data folder by using the base url of AppFlowy cloud. This is to avoid // Isolate the user data folder by using the base url of AppFlowy cloud. This is to avoid
// the user data folder being shared by different AppFlowy cloud. // the user data folder being shared by different AppFlowy cloud.
let storage_path = if !url.is_empty() { let storage_path = if !url.is_empty() {
@ -82,10 +82,10 @@ impl AppFlowyCoreConfig {
let supabase_config = SupabaseConfiguration::from_env().ok(); let supabase_config = SupabaseConfiguration::from_env().ok();
match &supabase_config { match &supabase_config {
None => custom_application_path, None => custom_application_path,
Some(config) => migrate_local_version_data_folder(&custom_application_path, &config.url), Some(config) => make_user_data_folder(&custom_application_path, &config.url),
} }
}, },
Some(config) => migrate_local_version_data_folder(&custom_application_path, &config.base_url), Some(config) => make_user_data_folder(&custom_application_path, &config.base_url),
}; };
AppFlowyCoreConfig { AppFlowyCoreConfig {

View File

@ -1,6 +1,6 @@
use std::sync::{Arc, Weak}; use std::sync::{Arc, Weak};
use collab::core::collab_plugin::EncodedCollabV1; use collab::core::collab_plugin::EncodedCollab;
use collab_plugins::local_storage::rocksdb::RocksdbBackup; use collab_plugins::local_storage::rocksdb::RocksdbBackup;
use diesel::SqliteConnection; use diesel::SqliteConnection;
@ -22,12 +22,7 @@ impl RocksdbBackupImpl {
} }
impl RocksdbBackup for RocksdbBackupImpl { impl RocksdbBackup for RocksdbBackupImpl {
fn save_doc( fn save_doc(&self, uid: i64, object_id: &str, data: EncodedCollab) -> Result<(), anyhow::Error> {
&self,
uid: i64,
object_id: &str,
data: EncodedCollabV1,
) -> Result<(), anyhow::Error> {
let row = RocksdbBackupRow { let row = RocksdbBackupRow {
object_id: object_id.to_string(), object_id: object_id.to_string(),
timestamp: timestamp(), timestamp: timestamp(),
@ -40,7 +35,7 @@ impl RocksdbBackup for RocksdbBackupImpl {
Ok(()) Ok(())
} }
fn get_doc(&self, uid: i64, object_id: &str) -> Result<EncodedCollabV1, anyhow::Error> { fn get_doc(&self, uid: i64, object_id: &str) -> Result<EncodedCollab, anyhow::Error> {
let sql = dsl::rocksdb_backup let sql = dsl::rocksdb_backup
.filter(dsl::object_id.eq(object_id)) .filter(dsl::object_id.eq(object_id))
.into_boxed(); .into_boxed();
@ -50,7 +45,7 @@ impl RocksdbBackup for RocksdbBackupImpl {
.get() .get()
.map(|mut conn| sql.first::<RocksdbBackupRow>(&mut *conn))??; .map(|mut conn| sql.first::<RocksdbBackupRow>(&mut *conn))??;
Ok(EncodedCollabV1::decode_from_bytes(&row.data)?) Ok(EncodedCollab::decode_from_bytes(&row.data)?)
} }
} }

View File

@ -238,8 +238,16 @@ impl FolderOperationHandler for DocumentFolderOperation {
let view_id = view_id.to_string(); let view_id = view_id.to_string();
let manager = self.0.clone(); let manager = self.0.clone();
FutureResult::new(async move { FutureResult::new(async move {
manager.create_document(user_id, &view_id, None).await?; match manager.create_document(user_id, &view_id, None).await {
Ok(()) Ok(_) => Ok(()),
Err(err) => {
if err.is_already_exists() {
Ok(())
} else {
Err(err)
}
},
}
}) })
} }
@ -368,8 +376,17 @@ impl FolderOperationHandler for DatabaseFolderOperation {
}, },
}; };
FutureResult::new(async move { FutureResult::new(async move {
database_manager.create_database_with_params(data).await?; let result = database_manager.create_database_with_params(data).await;
Ok(()) match result {
Ok(_) => Ok(()),
Err(err) => {
if err.is_already_exists() {
Ok(())
} else {
Err(err)
}
},
}
}) })
} }

View File

@ -3,7 +3,7 @@ use std::sync::Arc;
use std::sync::Weak; use std::sync::Weak;
use collab::core::collab::{CollabDocState, MutexCollab}; use collab::core::collab::{CollabDocState, MutexCollab};
use collab::core::collab_plugin::EncodedCollabV1; use collab::core::collab_plugin::EncodedCollab;
use collab::core::origin::CollabOrigin; use collab::core::origin::CollabOrigin;
use collab::preclude::Collab; use collab::preclude::Collab;
use collab_document::blocks::DocumentData; use collab_document::blocks::DocumentData;
@ -273,7 +273,7 @@ impl DocumentManager {
fn doc_state_from_document_data( fn doc_state_from_document_data(
doc_id: &str, doc_id: &str,
data: DocumentData, data: DocumentData,
) -> Result<EncodedCollabV1, FlowyError> { ) -> Result<EncodedCollab, FlowyError> {
let collab = Arc::new(MutexCollab::from_collab(Collab::new_with_origin( let collab = Arc::new(MutexCollab::from_collab(Collab::new_with_origin(
CollabOrigin::Empty, CollabOrigin::Empty,
doc_id, doc_id,

View File

@ -55,6 +55,10 @@ impl FlowyError {
self.code == ErrorCode::RecordNotFound self.code == ErrorCode::RecordNotFound
} }
pub fn is_already_exists(&self) -> bool {
self.code == ErrorCode::RecordAlreadyExists
}
pub fn is_unauthorized(&self) -> bool { pub fn is_unauthorized(&self) -> bool {
self.code == ErrorCode::UserUnauthorized || self.code == ErrorCode::RecordNotFound self.code == ErrorCode::UserUnauthorized || self.code == ErrorCode::RecordNotFound
} }

View File

@ -403,6 +403,7 @@ impl FolderManager {
handler handler
.create_built_in_view(user_id, &params.view_id, &params.name, view_layout.clone()) .create_built_in_view(user_id, &params.view_id, &params.name, view_layout.clone())
.await?; .await?;
let view = create_view(self.user.user_id()?, params, view_layout); let view = create_view(self.user.user_id()?, params, view_layout);
self.with_folder( self.with_folder(
|| (), || (),

View File

@ -3,7 +3,7 @@ use client_api::entity::QueryCollabResult::{Failed, Success};
use client_api::entity::{QueryCollab, QueryCollabParams}; use client_api::entity::{QueryCollab, QueryCollabParams};
use client_api::error::ErrorCode::RecordNotFound; use client_api::error::ErrorCode::RecordNotFound;
use collab::core::collab::CollabDocState; use collab::core::collab::CollabDocState;
use collab::core::collab_plugin::EncodedCollabV1; use collab::core::collab_plugin::EncodedCollab;
use collab_entity::CollabType; use collab_entity::CollabType;
use tracing::error; use tracing::error;
@ -72,7 +72,7 @@ where
.into_iter() .into_iter()
.flat_map(|(object_id, result)| match result { .flat_map(|(object_id, result)| match result {
Success { encode_collab_v1 } => { Success { encode_collab_v1 } => {
match EncodedCollabV1::decode_from_bytes(&encode_collab_v1) { match EncodedCollab::decode_from_bytes(&encode_collab_v1) {
Ok(encode) => Some((object_id, encode.doc_state.to_vec())), Ok(encode) => Some((object_id, encode.doc_state.to_vec())),
Err(err) => { Err(err) => {
error!("Failed to decode collab: {}", err); error!("Failed to decode collab: {}", err);

View File

@ -264,7 +264,7 @@ where
.into_iter() .into_iter()
.map(|object| CollabParams { .map(|object| CollabParams {
object_id: object.object_id, object_id: object.object_id,
encoded_collab_v1: object.encoded_collab_v1, encoded_collab_v1: object.encoded_collab,
collab_type: object.collab_type, collab_type: object.collab_type,
override_if_exist: false, override_if_exist: false,
}) })

View File

@ -247,6 +247,6 @@ pub fn uuid_from_map(map: &HashMap<String, String>) -> Result<Uuid, Error> {
#[derive(Debug)] #[derive(Debug)]
pub struct UserCollabParams { pub struct UserCollabParams {
pub object_id: String, pub object_id: String,
pub encoded_collab_v1: Vec<u8>, pub encoded_collab: Vec<u8>,
pub collab_type: CollabType, pub collab_type: CollabType,
} }

View File

@ -268,6 +268,11 @@ impl UserManager {
.map(|collab_db| Arc::downgrade(&collab_db)) .map(|collab_db| Arc::downgrade(&collab_db))
} }
#[cfg(debug_assertions)]
pub fn get_collab_backup_list(&self, uid: i64) -> Vec<String> {
self.database.get_collab_backup_list(uid)
}
/// Performs a user sign-in, initializing user awareness and sending relevant notifications. /// Performs a user sign-in, initializing user awareness and sending relevant notifications.
/// ///
/// This asynchronous function interacts with an external user service to authenticate and sign in a user /// This asynchronous function interacts with an external user service to authenticate and sign in a user
@ -513,15 +518,9 @@ impl UserManager {
// users opt for cloud storage, the application should automatically create a backup of the user // users opt for cloud storage, the application should automatically create a backup of the user
// data. This backup should be in the form of a zip file and stored locally on the user's disk // data. This backup should be in the form of a zip file and stored locally on the user's disk
// for safety and data integrity purposes // for safety and data integrity purposes
if self.user_config.is_custom_storage_path() { self
self .database
.database .backup_or_restore(session.user_id, &session.user_workspace.id);
.backup_or_restore(session.user_id, &session.user_workspace.id);
} else {
self
.database
.restore_if_need(session.user_id, &session.user_workspace.id);
}
} }
/// Fetches the user profile for the given user ID. /// Fetches the user profile for the given user ID.

View File

@ -59,9 +59,10 @@ impl UserDataMigration for FavoriteV1AndWorkspaceArrayMigration {
&encode.state_vector, &encode.state_vector,
) )
.map_err(internal_error)?; .map_err(internal_error)?;
write_txn.commit_transaction().map_err(internal_error)?;
} }
write_txn.commit_transaction().map_err(internal_error)?;
Ok(()) Ok(())
} }
} }

View File

@ -48,9 +48,10 @@ impl UserDataMigration for WorkspaceTrashMapToSectionMigration {
&encode.state_vector, &encode.state_vector,
) )
.map_err(internal_error)?; .map_err(internal_error)?;
write_txn.commit_transaction().map_err(internal_error)?;
} }
write_txn.commit_transaction().map_err(internal_error)?;
Ok(()) Ok(())
} }
} }

View File

@ -28,7 +28,7 @@ use parking_lot::{Mutex, RwLock};
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use std::ops::{Deref, DerefMut}; use std::ops::{Deref, DerefMut};
use std::sync::Arc; use std::sync::Arc;
use tracing::info; use tracing::{debug, event, info, instrument};
pub(crate) struct ImportContext { pub(crate) struct ImportContext {
pub imported_session: Session, pub imported_session: Session,
@ -92,15 +92,16 @@ pub(crate) fn import_appflowy_data_folder(
let views = collab_db.with_write_txn(|collab_write_txn| { let views = collab_db.with_write_txn(|collab_write_txn| {
// use the old_to_new_id_map to keep track of the other collab object id and the new collab object id // use the old_to_new_id_map to keep track of the other collab object id and the new collab object id
let old_to_new_id_map = Arc::new(Mutex::new(OldToNewIdMap::new())); let old_to_new_id_map = Arc::new(Mutex::new(OldToNewIdMap::new()));
let mut all_object_ids = imported_collab_read_txn let mut all_imported_object_ids = imported_collab_read_txn
.get_all_docs() .get_all_docs()
.map(|iter| iter.collect::<Vec<String>>()) .map(|iter| iter.collect::<Vec<String>>())
.unwrap_or_default(); .unwrap_or_default();
// when doing import, we don't want to import the user workspace, database view tracker and the user awareness // when doing import, we don't want to import the user workspace, database view tracker and the user awareness
all_object_ids.retain(|id| id != &imported_session.user_workspace.id); all_imported_object_ids.retain(|id| id != &imported_session.user_workspace.id);
all_object_ids.retain(|id| id != &imported_session.user_workspace.database_view_tracker_id); all_imported_object_ids
all_object_ids .retain(|id| id != &imported_session.user_workspace.database_view_tracker_id);
all_imported_object_ids
.retain(|id| id != &awareness_oid_from_user_uuid(&imported_session.user_uuid).to_string()); .retain(|id| id != &awareness_oid_from_user_uuid(&imported_session.user_uuid).to_string());
// import database view tracker // import database view tracker
@ -118,32 +119,37 @@ pub(crate) fn import_appflowy_data_folder(
.flatten() .flatten()
.cloned() .cloned()
.collect(); .collect();
all_object_ids.retain(|id| !database_view_ids.contains(id)); all_imported_object_ids.retain(|id| !database_view_ids.contains(id));
// load other collab objects // load other collab objects
let collab_by_oid = load_collab_by_oid( let imported_collab_by_oid = load_collab_by_oid(
imported_session.user_id, imported_session.user_id,
&imported_collab_read_txn, &imported_collab_read_txn,
&all_object_ids, &all_imported_object_ids,
); );
// import the database // import the database
migrate_databases( migrate_databases(
&old_to_new_id_map, &old_to_new_id_map,
session, session,
collab_write_txn, collab_write_txn,
&mut all_object_ids, &mut all_imported_object_ids,
&collab_by_oid, &imported_collab_by_oid,
&row_object_ids, &row_object_ids,
&document_object_ids, &document_object_ids,
)?; )?;
// the object ids now only contains the document collab object ids // the object ids now only contains the document collab object ids
for object_id in &all_object_ids { for object_id in &all_imported_object_ids {
if let Some(collab) = collab_by_oid.get(object_id) { if let Some(imported_collab) = imported_collab_by_oid.get(object_id) {
let new_object_id = old_to_new_id_map.lock().renew_id(object_id); let new_object_id = old_to_new_id_map.lock().renew_id(object_id);
document_object_ids.lock().insert(new_object_id.clone()); document_object_ids.lock().insert(new_object_id.clone());
tracing::debug!("migrate from: {}, to: {}", object_id, new_object_id,); tracing::debug!("import from: {}, to: {}", object_id, new_object_id,);
import_collab_object(collab, session.user_id, &new_object_id, collab_write_txn); import_collab_object(
imported_collab,
session.user_id,
&new_object_id,
collab_write_txn,
);
} }
} }
@ -247,8 +253,8 @@ fn migrate_databases<'a, W>(
old_to_new_id_map: &Arc<Mutex<OldToNewIdMap>>, old_to_new_id_map: &Arc<Mutex<OldToNewIdMap>>,
session: &Session, session: &Session,
collab_write_txn: &'a W, collab_write_txn: &'a W,
object_ids: &mut Vec<String>, imported_object_ids: &mut Vec<String>,
collab_by_oid: &HashMap<String, Collab>, imported_collab_by_oid: &HashMap<String, Collab>,
row_object_ids: &Mutex<HashSet<String>>, row_object_ids: &Mutex<HashSet<String>>,
document_object_ids: &Mutex<HashSet<String>>, document_object_ids: &Mutex<HashSet<String>>,
) -> Result<(), PersistenceError> ) -> Result<(), PersistenceError>
@ -258,20 +264,21 @@ where
{ {
// Migrate databases // Migrate databases
let mut database_object_ids = vec![]; let mut database_object_ids = vec![];
let database_row_object_ids = RwLock::new(HashSet::new()); let imported_database_row_object_ids = RwLock::new(HashSet::new());
let imported_database_row_document_object_ids = RwLock::new(HashSet::new());
for object_id in &mut *object_ids { for object_id in &mut *imported_object_ids {
if let Some(collab) = collab_by_oid.get(object_id) { if let Some(database_collab) = imported_collab_by_oid.get(object_id) {
if !is_database_collab(collab) { if !is_database_collab(database_collab) {
continue; continue;
} }
database_object_ids.push(object_id.clone()); database_object_ids.push(object_id.clone());
reset_inline_view_id(collab, |old_inline_view_id| { reset_inline_view_id(database_collab, |old_inline_view_id| {
old_to_new_id_map.lock().renew_id(&old_inline_view_id) old_to_new_id_map.lock().renew_id(&old_inline_view_id)
}); });
mut_database_views_with_collab(collab, |database_view| { mut_database_views_with_collab(database_collab, |database_view| {
let new_view_id = old_to_new_id_map.lock().renew_id(&database_view.id); let new_view_id = old_to_new_id_map.lock().renew_id(&database_view.id);
let new_database_id = old_to_new_id_map let new_database_id = old_to_new_id_map
.lock() .lock()
@ -284,64 +291,96 @@ where
let old_row_document_id = database_row_document_id_from_row_id(&old_row_id); let old_row_document_id = database_row_document_id_from_row_id(&old_row_id);
let new_row_id = old_to_new_id_map.lock().renew_id(&old_row_id); let new_row_id = old_to_new_id_map.lock().renew_id(&old_row_id);
let new_row_document_id = database_row_document_id_from_row_id(&new_row_id); let new_row_document_id = database_row_document_id_from_row_id(&new_row_id);
tracing::debug!("migrate row id: {} to {}", row_order.id, new_row_id);
tracing::debug!(
"migrate row document id: {} to {}",
old_row_document_id,
new_row_document_id
);
old_to_new_id_map old_to_new_id_map
.lock() .lock()
.insert(old_row_document_id, new_row_document_id); .insert(old_row_document_id.clone(), new_row_document_id);
row_order.id = RowId::from(new_row_id); row_order.id = RowId::from(new_row_id);
database_row_object_ids.write().insert(old_row_id); imported_database_row_object_ids.write().insert(old_row_id);
imported_database_row_document_object_ids
.write()
.insert(old_row_document_id);
}); });
// collect the ids // collect the ids
let row_ids = database_view let new_row_ids = database_view
.row_orders .row_orders
.iter() .iter()
.map(|order| order.id.clone().into_inner()) .map(|order| order.id.clone().into_inner())
.collect::<Vec<String>>(); .collect::<Vec<String>>();
let row_document_ids = row_ids let new_row_document_ids = new_row_ids
.iter() .iter()
.map(|id| database_row_document_id_from_row_id(id)) .map(|id| database_row_document_id_from_row_id(id))
.collect::<Vec<String>>(); .collect::<Vec<String>>();
row_object_ids.lock().extend(row_ids); row_object_ids.lock().extend(new_row_ids);
document_object_ids.lock().extend(row_document_ids); document_object_ids.lock().extend(new_row_document_ids);
}); });
let new_object_id = old_to_new_id_map.lock().renew_id(object_id); let new_object_id = old_to_new_id_map.lock().renew_id(object_id);
tracing::debug!( debug!(
"migrate database from: {}, to: {}", "migrate database from: {}, to: {}",
object_id, object_id, new_object_id,
new_object_id, );
import_collab_object(
database_collab,
session.user_id,
&new_object_id,
collab_write_txn,
); );
import_collab_object(collab, session.user_id, &new_object_id, collab_write_txn);
} }
} }
let database_row_object_ids = database_row_object_ids.read(); let imported_database_row_object_ids = imported_database_row_object_ids.read();
let imported_database_row_document_object_ids = imported_database_row_document_object_ids.read();
debug!(
"imported_database_row_object_ids: {:?}",
imported_database_row_object_ids
);
debug!(
"imported_database_row_document_object_ids: {:?}",
imported_database_row_document_object_ids
);
// remove the database object ids from the object ids // remove the database object ids from the object ids
object_ids.retain(|id| !database_object_ids.contains(id)); imported_object_ids.retain(|id| !database_object_ids.contains(id));
object_ids.retain(|id| !database_row_object_ids.contains(id)); imported_object_ids.retain(|id| !imported_database_row_object_ids.contains(id));
imported_object_ids.retain(|id| !imported_database_row_document_object_ids.contains(id));
for object_id in &*database_row_object_ids { for imported_row_id in &*imported_database_row_object_ids {
if let Some(collab) = collab_by_oid.get(object_id) { if let Some(imported_collab) = imported_collab_by_oid.get(imported_row_id) {
let new_object_id = old_to_new_id_map.lock().renew_id(object_id); let new_row_id = old_to_new_id_map.lock().renew_id(imported_row_id);
tracing::info!( info!(
"migrate database row from: {}, to: {}", "import database row from: {}, to: {}",
object_id, imported_row_id, new_row_id,
new_object_id,
); );
mut_row_with_collab(collab, |row_update| { mut_row_with_collab(imported_collab, |row_update| {
row_update.set_row_id(RowId::from(new_object_id.clone())); row_update.set_row_id(RowId::from(new_row_id.clone()));
}); });
import_collab_object(collab, session.user_id, &new_object_id, collab_write_txn); import_collab_object(
imported_collab,
session.user_id,
&new_row_id,
collab_write_txn,
);
}
let imported_row_document_id = database_row_document_id_from_row_id(imported_row_id);
if let Some(imported_collab) = imported_collab_by_oid.get(&imported_row_document_id) {
let new_row_document_id = old_to_new_id_map.lock().renew_id(&imported_row_document_id);
info!(
"import database row document from: {}, to: {}",
imported_row_document_id, new_row_document_id,
);
import_collab_object(
imported_collab,
session.user_id,
&new_row_document_id,
collab_write_txn,
);
} }
} }
Ok(()) Ok(())
@ -354,7 +393,7 @@ where
{ {
let txn = collab.transact(); let txn = collab.transact();
if let Err(err) = w_txn.create_new_doc(new_uid, &new_object_id, &txn) { if let Err(err) = w_txn.create_new_doc(new_uid, &new_object_id, &txn) {
tracing::error!("import collab failed: {:?}", err); tracing::error!("import collab:{} failed: {:?}", new_object_id, err);
} }
} }
@ -519,6 +558,7 @@ impl DerefMut for OldToNewIdMap {
} }
} }
#[instrument(level = "debug", skip_all)]
pub async fn upload_imported_data( pub async fn upload_imported_data(
uid: i64, uid: i64,
user_collab_db: Arc<RocksCollabDB>, user_collab_db: Arc<RocksCollabDB>,
@ -549,16 +589,20 @@ pub async fn upload_imported_data(
let object_by_collab_type = tokio::task::spawn_blocking(move || { let object_by_collab_type = tokio::task::spawn_blocking(move || {
let collab_read = user_collab_db.read_txn(); let collab_read = user_collab_db.read_txn();
let mut object_by_collab_type = HashMap::new(); let mut object_by_collab_type = HashMap::new();
event!(tracing::Level::DEBUG, "upload database collab data");
object_by_collab_type.insert( object_by_collab_type.insert(
CollabType::Database, CollabType::Database,
load_and_process_collab_data(uid, &collab_read, &database_object_ids), load_and_process_collab_data(uid, &collab_read, &database_object_ids),
); );
event!(tracing::Level::DEBUG, "upload document collab data");
object_by_collab_type.insert( object_by_collab_type.insert(
CollabType::Document, CollabType::Document,
load_and_process_collab_data(uid, &collab_read, &document_object_ids), load_and_process_collab_data(uid, &collab_read, &document_object_ids),
); );
event!(tracing::Level::DEBUG, "upload database row collab data");
object_by_collab_type.insert( object_by_collab_type.insert(
CollabType::DatabaseRow, CollabType::DatabaseRow,
load_and_process_collab_data(uid, &collab_read, &row_object_ids), load_and_process_collab_data(uid, &collab_read, &row_object_ids),
@ -573,17 +617,26 @@ pub async fn upload_imported_data(
let mut size_counter = 0; let mut size_counter = 0;
let mut objects: Vec<UserCollabParams> = vec![]; let mut objects: Vec<UserCollabParams> = vec![];
let upload_size_limit = 2 * 1024 * 1024; let upload_size_limit = 2 * 1024 * 1024;
for (collab_type, encoded_v1_by_oid) in object_by_collab_type { for (collab_type, encoded_collab_by_oid) in object_by_collab_type {
info!( info!(
"Batch import collab:{} ids: {:?}", "Batch import collab:{} ids: {:?}",
collab_type, collab_type,
encoded_v1_by_oid.keys(), encoded_collab_by_oid.keys(),
); );
for (oid, encoded_v1) in encoded_v1_by_oid { for (oid, encoded_collab) in encoded_collab_by_oid {
let obj_size = encoded_v1.len(); let obj_size = encoded_collab.len();
if size_counter + obj_size > upload_size_limit && !objects.is_empty() { if size_counter + obj_size > upload_size_limit && !objects.is_empty() {
// When the limit is exceeded, batch create with the current list of objects // When the limit is exceeded, batch create with the current list of objects
// and reset for the next batch. // and reset for the next batch.
info!(
"Exceeded maximum payload size. Batch creating collab objects: {}, payload size: {}",
objects
.iter()
.map(|o| o.object_id.clone())
.collect::<Vec<_>>()
.join(", "),
size_counter
);
user_cloud_service user_cloud_service
.batch_create_collab_object(workspace_id, objects) .batch_create_collab_object(workspace_id, objects)
.await?; .await?;
@ -594,7 +647,7 @@ pub async fn upload_imported_data(
// Add the current object to the batch. // Add the current object to the batch.
objects.push(UserCollabParams { objects.push(UserCollabParams {
object_id: oid, object_id: oid,
encoded_collab_v1: encoded_v1, encoded_collab,
collab_type: collab_type.clone(), collab_type: collab_type.clone(),
}); });
size_counter += obj_size; size_counter += obj_size;
@ -619,6 +672,7 @@ pub async fn upload_imported_data(
Ok(()) Ok(())
} }
#[instrument(level = "debug", skip_all)]
fn load_and_process_collab_data<'a, R>( fn load_and_process_collab_data<'a, R>(
uid: i64, uid: i64,
collab_read: &R, collab_read: &R,
@ -635,7 +689,7 @@ where
.encode_collab_v1() .encode_collab_v1()
.encode_to_bytes() .encode_to_bytes()
.ok() .ok()
.map(|encoded_v1| (oid, encoded_v1)) .map(|encoded_collab| (oid, encoded_collab))
}) })
.collect() .collect()
} }

View File

@ -7,6 +7,7 @@ use crate::services::data_import::ImportContext;
use collab::preclude::Collab; use collab::preclude::Collab;
use flowy_folder_deps::entities::ImportData; use flowy_folder_deps::entities::ImportData;
use std::sync::Arc; use std::sync::Arc;
use tracing::instrument;
pub enum ImportDataSource { pub enum ImportDataSource {
AppFlowyDataFolder { AppFlowyDataFolder {
@ -26,6 +27,7 @@ pub(crate) fn import_data(
import_appflowy_data_folder(session, &session.user_workspace.id, &collab_db, context) import_appflowy_data_folder(session, &session.user_workspace.id, &collab_db, context)
} }
#[instrument(level = "debug", skip_all)]
pub fn load_collab_by_oid<'a, R>( pub fn load_collab_by_oid<'a, R>(
uid: i64, uid: i64,
collab_read_txn: &R, collab_read_txn: &R,
@ -44,7 +46,7 @@ where
Ok(_) => { Ok(_) => {
collab_by_oid.insert(object_id.clone(), collab); collab_by_oid.insert(object_id.clone(), collab);
}, },
Err(err) => tracing::error!("🔴Initialize migration collab failed: {:?} ", err), Err(err) => tracing::error!("🔴import collab:{} failed: {:?} ", object_id, err),
} }
} }

View File

@ -84,6 +84,17 @@ impl UserDB {
} }
} }
#[cfg(debug_assertions)]
pub fn get_collab_backup_list(&self, uid: i64) -> Vec<String> {
let collab_db_path = self.paths.collab_db_path(uid);
if let Ok(history_folder) = self.paths.collab_db_history(uid, true) {
return CollabDBZipBackup::new(collab_db_path.clone(), history_folder)
.get_backup_list()
.unwrap_or_default();
}
vec![]
}
#[instrument(level = "debug", skip_all)] #[instrument(level = "debug", skip_all)]
pub fn restore_if_need(&self, uid: i64, workspace_id: &str) { pub fn restore_if_need(&self, uid: i64, workspace_id: &str) {
if let Ok(history_folder) = self.paths.collab_db_history(uid, false) { if let Ok(history_folder) = self.paths.collab_db_history(uid, false) {
@ -224,9 +235,16 @@ impl CollabDBZipBackup {
#[instrument(name = "backup_collab_db", skip_all, err)] #[instrument(name = "backup_collab_db", skip_all, err)]
pub fn backup(&self) -> io::Result<()> { pub fn backup(&self) -> io::Result<()> {
let today_zip_file = self let file_name = match std::env::var("APP_VERSION") {
.history_folder Ok(version_num) => {
.join(format!("collab_db_{}.zip", today_zip_timestamp())); format!("collab_db_{}_{}.zip", version_num, today_zip_timestamp())
},
Err(_) => {
format!("collab_db_{}.zip", today_zip_timestamp())
},
};
let today_zip_file = self.history_folder.join(file_name);
// Remove today's existing zip file if it exists // Remove today's existing zip file if it exists
if !today_zip_file.exists() { if !today_zip_file.exists() {
@ -245,6 +263,22 @@ impl CollabDBZipBackup {
Ok(()) Ok(())
} }
#[cfg(debug_assertions)]
pub fn get_backup_list(&self) -> io::Result<Vec<String>> {
let mut backups = Vec::new();
for entry in fs::read_dir(&self.history_folder)? {
let entry = entry?;
let path = entry.path();
if path.is_file() && path.extension().and_then(|s| s.to_str()) == Some("zip") {
if let Some(file_name) = path.file_stem().and_then(|s| s.to_str()) {
backups.push(file_name.to_string());
}
}
}
backups.sort();
Ok(backups)
}
#[instrument(skip_all, err)] #[instrument(skip_all, err)]
pub fn restore_latest_backup(&self) -> io::Result<()> { pub fn restore_latest_backup(&self) -> io::Result<()> {
let mut latest_zip: Option<(String, PathBuf)> = None; let mut latest_zip: Option<(String, PathBuf)> = None;
@ -258,7 +292,7 @@ impl CollabDBZipBackup {
let path = entry.path(); let path = entry.path();
if path.is_file() && path.extension().and_then(|s| s.to_str()) == Some("zip") { if path.is_file() && path.extension().and_then(|s| s.to_str()) == Some("zip") {
if let Some(file_name) = path.file_stem().and_then(|s| s.to_str()) { if let Some(file_name) = path.file_stem().and_then(|s| s.to_str()) {
if let Some(timestamp_str) = file_name.strip_prefix("collab_db_") { if let Some(timestamp_str) = file_name.split("_").last() {
match latest_zip { match latest_zip {
Some((latest_timestamp, _)) if timestamp_str > latest_timestamp.as_str() => { Some((latest_timestamp, _)) if timestamp_str > latest_timestamp.as_str() => {
latest_zip = Some((timestamp_str.to_string(), path)); latest_zip = Some((timestamp_str.to_string(), path));

View File

@ -9,7 +9,7 @@ edition = "2018"
tracing-subscriber = { version = "0.3.17", features = ["registry", "env-filter", "ansi", "json"] } tracing-subscriber = { version = "0.3.17", features = ["registry", "env-filter", "ansi", "json"] }
tracing-bunyan-formatter = "0.3.9" tracing-bunyan-formatter = "0.3.9"
tracing-appender = "0.2.2" tracing-appender = "0.2.3"
tracing-core = "0.1" tracing-core = "0.1"
tracing.workspace = true tracing.workspace = true
serde_json.workspace = true serde_json.workspace = true

View File

@ -3,6 +3,7 @@ use std::sync::RwLock;
use chrono::Local; use chrono::Local;
use lazy_static::lazy_static; use lazy_static::lazy_static;
use tracing::subscriber::set_global_default; use tracing::subscriber::set_global_default;
use tracing_appender::rolling::Rotation;
use tracing_appender::{non_blocking::WorkerGuard, rolling::RollingFileAppender}; use tracing_appender::{non_blocking::WorkerGuard, rolling::RollingFileAppender};
use tracing_bunyan_formatter::JsonStorageLayer; use tracing_bunyan_formatter::JsonStorageLayer;
use tracing_subscriber::fmt::format::Writer; use tracing_subscriber::fmt::format::Writer;
@ -25,10 +26,17 @@ pub struct Builder {
impl Builder { impl Builder {
pub fn new(name: &str, directory: &str) -> Self { pub fn new(name: &str, directory: &str) -> Self {
let file_appender = RollingFileAppender::builder()
.rotation(Rotation::DAILY)
.filename_prefix(name)
.max_log_files(6)
.build(directory)
.unwrap_or(tracing_appender::rolling::daily(directory, name));
Builder { Builder {
name: name.to_owned(), name: name.to_owned(),
env_filter: "Info".to_owned(), env_filter: "Info".to_owned(),
file_appender: tracing_appender::rolling::daily(directory, name), file_appender,
} }
} }

View File

@ -47,6 +47,7 @@ run_task = { name = [
# #
[tasks.sdk-dev-build] [tasks.sdk-dev-build]
dependencies = ["set-app-version"]
private = true private = true
script = [ script = [
""" """
@ -58,6 +59,7 @@ script = [
script_runner = "@shell" script_runner = "@shell"
[tasks.sdk-dev-build.mac] [tasks.sdk-dev-build.mac]
dependencies = ["set-app-version"]
private = true private = true
script = [ script = [
""" """
@ -69,6 +71,7 @@ script = [
script_runner = "@shell" script_runner = "@shell"
[tasks.sdk-dev-build.windows] [tasks.sdk-dev-build.windows]
dependencies = ["set-app-version"]
private = true private = true
script = [ script = [
""" """
@ -93,6 +96,7 @@ run_task = { name = [
# #
[tasks.sdk-release-build] [tasks.sdk-release-build]
dependencies = ["set-app-version"]
script = [ script = [
""" """
cd rust-lib/ cd rust-lib/
@ -103,6 +107,7 @@ script = [
script_runner = "@shell" script_runner = "@shell"
[tasks.sdk-release-build.mac] [tasks.sdk-release-build.mac]
dependencies = ["set-app-version"]
script = [ script = [
""" """
cd rust-lib/ cd rust-lib/
@ -172,3 +177,13 @@ script = [
""", """,
] ]
script_runner = "@duckscript" script_runner = "@duckscript"
[tasks.set-app-version]
script = ["""
if is_empty ${APP_VERSION}
APP_VERSION = set ${APPFLOWY_VERSION}
set_env APP_VERSION ${APPFLOWY_VERSION}
end
echo APP_VERSION: ${APP_VERSION}
"""]
script_runner = "@duckscript"

View File

@ -7,7 +7,6 @@ linux_alias = "appflowy-linux"
dependencies = ["appflowy-core-release"] dependencies = ["appflowy-core-release"]
run_task = { name = [ run_task = { name = [
"code_generation", "code_generation",
"set-app-version",
"flutter-build", "flutter-build",
"copy-to-product", "copy-to-product",
] } ] }
@ -16,7 +15,6 @@ script_runner = "@shell"
[tasks.appflowy-macos-universal] [tasks.appflowy-macos-universal]
run_task = { name = [ run_task = { name = [
"code_generation", "code_generation",
"set-app-version",
"flutter-build", "flutter-build",
"copy-to-product", "copy-to-product",
] } ] }
@ -71,7 +69,6 @@ linux_alias = "appflowy-linux-dev"
dependencies = ["appflowy-core-dev-ios"] dependencies = ["appflowy-core-dev-ios"]
run_task = { name = [ run_task = { name = [
"code_generation", "code_generation",
"set-app-version",
"flutter-build-ios", "flutter-build-ios",
] } ] }
script_runner = "@shell" script_runner = "@shell"
@ -80,7 +77,6 @@ script_runner = "@shell"
dependencies = ["appflowy-core-dev-android"] dependencies = ["appflowy-core-dev-android"]
run_task = { name = [ run_task = { name = [
"code_generation", "code_generation",
"set-app-version",
"flutter-build-android", "flutter-build-android",
] } ] }
script_runner = "@shell" script_runner = "@shell"
@ -89,7 +85,6 @@ script_runner = "@shell"
dependencies = ["appflowy-core-dev-android"] dependencies = ["appflowy-core-dev-android"]
run_task = { name = [ run_task = { name = [
"code_generation", "code_generation",
"set-app-version",
"flutter-build-android", "flutter-build-android",
] } ] }
script_runner = "@shell" script_runner = "@shell"
@ -98,7 +93,6 @@ script_runner = "@shell"
dependencies = ["appflowy-core-dev"] dependencies = ["appflowy-core-dev"]
run_task = { name = [ run_task = { name = [
"code_generation", "code_generation",
"set-app-version",
"flutter-build", "flutter-build",
"copy-to-product", "copy-to-product",
] } ] }
@ -108,7 +102,6 @@ script_runner = "@shell"
dependencies = ["appflowy-core-dev"] dependencies = ["appflowy-core-dev"]
run_task = { name = [ run_task = { name = [
"code_generation", "code_generation",
"set-app-version",
"flutter-build", "flutter-build",
"copy-to-product", "copy-to-product",
] } ] }
@ -117,7 +110,6 @@ run_task = { name = [
dependencies = ["appflowy-core-dev"] dependencies = ["appflowy-core-dev"]
run_task = { name = [ run_task = { name = [
"code_generation", "code_generation",
"set-app-version",
"flutter-build", "flutter-build",
"copy-to-product", "copy-to-product",
] } ] }
@ -216,15 +208,6 @@ script = [
] ]
script_runner = "@duckscript" script_runner = "@duckscript"
[tasks.set-app-version]
script = ["""
if is_empty ${APP_VERSION}
APP_VERSION = set ${CURRENT_APP_VERSION}
set_env APP_VERSION ${CURRENT_APP_VERSION}
end
echo APP_VERSION: ${APP_VERSION}
"""]
script_runner = "@duckscript"
# The following tasks will create an archive that will be used on the GitHub Releases section # The following tasks will create an archive that will be used on the GitHub Releases section
# The archives are created using different compression programs depending on the target OS # The archives are created using different compression programs depending on the target OS

View File

@ -12,7 +12,7 @@ condition = { env_set = [
[tasks.appflowy-core-dev-ios] [tasks.appflowy-core-dev-ios]
category = "Build" category = "Build"
dependencies = ["env_check"] dependencies = ["env_check", "set-app-version"]
run_task = { name = [ run_task = { name = [
"setup-crate-type", "setup-crate-type",
"sdk-build-ios", "sdk-build-ios",
@ -21,6 +21,7 @@ run_task = { name = [
] } ] }
[tasks.sdk-build-ios] [tasks.sdk-build-ios]
dependencies = ["set-app-version"]
private = true private = true
script = [ script = [
""" """
@ -40,7 +41,7 @@ script_runner = "@shell"
[tasks.appflowy-core-dev-android] [tasks.appflowy-core-dev-android]
category = "Build" category = "Build"
dependencies = ["env_check"] dependencies = ["env_check", "set-app-version"]
run_task = { name = [ run_task = { name = [
"setup-crate-type", "setup-crate-type",
"sdk-build-android", "sdk-build-android",
@ -49,6 +50,7 @@ run_task = { name = [
] } ] }
[tasks.sdk-build-android] [tasks.sdk-build-android]
dependencies = ["set-app-version"]
private = true private = true
script = [ script = [
""" """