diff options
Diffstat (limited to 'src/zenstore/workspaces.cpp')
| -rw-r--r-- | src/zenstore/workspaces.cpp | 234 |
1 files changed, 97 insertions, 137 deletions
diff --git a/src/zenstore/workspaces.cpp b/src/zenstore/workspaces.cpp index 669d675dd..6d8f8970d 100644 --- a/src/zenstore/workspaces.cpp +++ b/src/zenstore/workspaces.cpp @@ -19,73 +19,90 @@ namespace zen { namespace { - std::string WorkspaceShareToJson(const Workspaces::WorkspaceShareConfiguration& ShareConfig) + + std::string WorkspacesToJson(std::span<Workspaces::WorkspaceInfo> Workspaces) { using namespace std::literals; - CbObjectWriter ShareWriter; - ShareWriter.AddObjectId("id"sv, ShareConfig.Id); - ShareWriter.AddString("share_path"sv, reinterpret_cast<const char*>(ShareConfig.SharePath.u8string().c_str())); - if (!ShareConfig.Alias.empty()) - { - ShareWriter.AddString("alias"sv, ShareConfig.Alias); - } - ExtendableStringBuilder<256> Json; - ShareWriter.Save().ToJson(Json); - return Json.ToString(); - } + CbObjectWriter Writer; - Workspaces::WorkspaceShareConfiguration WorkspaceShareFromJson(const IoBuffer& ShareJson, std::string& OutError) - { - using namespace std::literals; + Writer.BeginArray("workspaces"); - CbFieldIterator StateField = - LoadCompactBinaryFromJson(std::string_view((const char*)(ShareJson.Data()), ShareJson.GetSize()), OutError); - if (OutError.empty()) + for (const Workspaces::WorkspaceInfo& Workspace : Workspaces) { - if (CbObjectView Object = StateField.AsObjectView(); Object) + Writer.BeginObject(); { - Oid ShareId = Object["id"sv].AsObjectId(); - std::filesystem::path SharePath = Object["share_path"sv].AsU8String(); - std::string_view Alias = Object["alias"sv].AsString(); - if (ShareId != Oid::Zero && !SharePath.empty()) + Writer.AddObjectId("id"sv, Workspace.Config.Id); + Writer.AddString("root_path"sv, reinterpret_cast<const char*>(Workspace.Config.RootPath.u8string().c_str())); + Writer.BeginArray("shares"); + for (const Workspaces::WorkspaceShareConfiguration& Share : Workspace.Shares) { - return {.Id = ShareId, .SharePath = SharePath, .Alias = std::string(Alias)}; + Writer.BeginObject(); + { + Writer.AddObjectId("id"sv, Share.Id); + Writer.AddString("share_path"sv, reinterpret_cast<const char*>(Share.SharePath.u8string().c_str())); + if (!Share.Alias.empty()) + { + Writer.AddString("alias"sv, Share.Alias); + } + } + Writer.EndObject(); } + Writer.EndArray(); } + Writer.EndObject(); } - return {}; - } - - std::string WorkspaceToJson(const Workspaces::WorkspaceConfiguration& WorkspaceConfig) - { - using namespace std::literals; - - CbObjectWriter ShareWriter; - ShareWriter.AddObjectId("id"sv, WorkspaceConfig.Id); - ShareWriter.AddString("root_path"sv, reinterpret_cast<const char*>(WorkspaceConfig.RootPath.u8string().c_str())); - ExtendableStringBuilder<256> Json; - ShareWriter.Save().ToJson(Json); + Writer.EndArray(); + ExtendableStringBuilder<512> Json; + Writer.Save().ToJson(Json); return Json.ToString(); } - Workspaces::WorkspaceConfiguration WorkspaceFromJson(const IoBuffer& WorkspaceJson, std::string& OutError) + std::vector<Workspaces::WorkspaceInfo> WorkspacesFromJson(const IoBuffer& WorkspaceJson, + const std::function<Oid(const std::filesystem::path& Path)>& PathToIdCB, + std::string& OutError) { using namespace std::literals; - CbFieldIterator StateField = + CbFieldIterator RootField = LoadCompactBinaryFromJson(std::string_view((const char*)(WorkspaceJson.Data()), WorkspaceJson.GetSize()), OutError); if (OutError.empty()) { - if (CbObjectView Object = StateField.AsObjectView(); Object) + std::vector<Workspaces::WorkspaceInfo> Workspaces; + if (CbObjectView RootObject = RootField.AsObjectView(); RootObject) { - Oid WorkspaceId = Object["id"sv].AsObjectId(); - std::filesystem::path RootPath = Object["root_path"sv].AsU8String(); - if (WorkspaceId != Oid::Zero && !RootPath.empty()) + for (CbFieldView WorkspaceField : RootObject["workspaces"].AsArrayView()) { - return {.Id = WorkspaceId, .RootPath = RootPath}; + CbObjectView Workspace = WorkspaceField.AsObjectView(); + Oid WorkspaceId = Workspace["id"sv].AsObjectId(); + std::filesystem::path RootPath = Workspace["root_path"sv].AsU8String(); + if (WorkspaceId == Oid::Zero && !RootPath.empty()) + { + WorkspaceId = PathToIdCB(RootPath); + } + if (WorkspaceId != Oid::Zero && !RootPath.empty()) + { + std::vector<Workspaces::WorkspaceShareConfiguration> Shares; + for (CbFieldView ShareField : Workspace["shares"].AsArrayView()) + { + CbObjectView Share = ShareField.AsObjectView(); + Oid ShareId = Share["id"sv].AsObjectId(); + std::filesystem::path SharePath = Share["share_path"sv].AsU8String(); + if (ShareId == Oid::Zero && !SharePath.empty()) + { + ShareId = PathToIdCB(SharePath); + } + std::string_view Alias = Share["alias"sv].AsString(); + if (ShareId != Oid::Zero && !SharePath.empty()) + { + Shares.push_back({.Id = ShareId, .SharePath = SharePath, .Alias = std::string(Alias)}); + } + } + Workspaces.push_back({.Config = {.Id = WorkspaceId, .RootPath = RootPath}, .Shares = std::move(Shares)}); + } } } + return Workspaces; } return {}; } @@ -134,9 +151,9 @@ private: class WorkspaceShare : public RefCounted { public: - WorkspaceShare(const Workspaces::WorkspaceShareConfiguration& Config, - std::unique_ptr<FolderStructure>&& FolderStructure, - std::function<Oid(const std::filesystem::path& Path)>&& PathToId); + WorkspaceShare(const Workspaces::WorkspaceShareConfiguration& Config, + std::unique_ptr<FolderStructure>&& FolderStructure, + const std::function<Oid(const std::filesystem::path& Path)>& PathToId); const Workspaces::WorkspaceShareConfiguration& GetConfig() const; @@ -297,11 +314,11 @@ ScanFolder(LoggerRef InLog, //////////////////////////////////////////////////////////// -WorkspaceShare::WorkspaceShare(const Workspaces::WorkspaceShareConfiguration& Config, - std::unique_ptr<FolderStructure>&& FolderStructure, - std::function<Oid(const std::filesystem::path& Path)>&& PathToId) +WorkspaceShare::WorkspaceShare(const Workspaces::WorkspaceShareConfiguration& Config, + std::unique_ptr<FolderStructure>&& FolderStructure, + const std::function<Oid(const std::filesystem::path& Path)>& PathToId) : m_Config(Config) -, m_PathToid(std::move(PathToId)) +, m_PathToid(PathToId) , m_FolderStructure(std::move(FolderStructure)) { } @@ -464,9 +481,9 @@ Workspaces::RemoveWorkspace(const Oid& WorkspaceId) } bool -Workspaces::AddWorkspaceShare(const Oid& WorkspaceId, - const WorkspaceShareConfiguration& Configuration, - std::function<Oid(const std::filesystem::path& Path)>&& PathToIdCB) +Workspaces::AddWorkspaceShare(const Oid& WorkspaceId, + const WorkspaceShareConfiguration& Configuration, + const std::function<Oid(const std::filesystem::path& Path)>& PathToIdCB) { Ref<Workspace> Workspace; { @@ -482,7 +499,7 @@ Workspaces::AddWorkspaceShare(const Oid& WorkspaceId, } } - Ref<WorkspaceShare> NewShare(new WorkspaceShare(Configuration, {}, std::move(PathToIdCB))); + Ref<WorkspaceShare> NewShare(new WorkspaceShare(Configuration, {}, PathToIdCB)); { RwLock::ExclusiveLockScope _(m_Lock); Workspace->SetShare(Configuration.Id, std::move(NewShare)); @@ -655,104 +672,47 @@ Workspaces::WriteState(const std::filesystem::path& WorkspaceStatePath) ZEN_INFO("Writing workspaces state to {}", WorkspaceStatePath); - std::filesystem::path TempWritePath = WorkspaceStatePath.parent_path() / (WorkspaceStatePath.filename().string() + "_new"); - CreateDirectories(TempWritePath); - - RwLock::SharedLockScope _(m_Lock); - for (auto It : m_Workspaces) - { - const WorkspaceConfiguration& WorkspaceConfig = It.second->GetConfig(); - ZEN_ASSERT(WorkspaceConfig.Id == It.first); - std::filesystem::path WorkspaceConfigDir = TempWritePath / WorkspaceConfig.Id.ToString(); - CreateDirectories(WorkspaceConfigDir); - std::string WorkspaceConfigJson = WorkspaceToJson(WorkspaceConfig); - TemporaryFile::SafeWriteFile(WorkspaceConfigDir / "config.json"sv, - MemoryView(WorkspaceConfigJson.data(), WorkspaceConfigJson.size())); - - std::vector<Ref<WorkspaceShare>> Shares = It.second->GetShares(); - for (const Ref<WorkspaceShare>& Share : Shares) - { - const WorkspaceShareConfiguration& ShareConfig = Share->GetConfig(); - std::filesystem::path ShareConfigDir = WorkspaceConfigDir / "shares"sv / ShareConfig.Id.ToString(); - CreateDirectories(ShareConfigDir); - std::string ShareConfigJson = WorkspaceShareToJson(ShareConfig); - TemporaryFile::SafeWriteFile(ShareConfigDir / "config.json"sv, MemoryView(ShareConfigJson.data(), ShareConfigJson.size())); - } - } + CreateDirectories(WorkspaceStatePath); - // Overwrite with rename - std::filesystem::path OldStateDirectory = WorkspaceStatePath.parent_path() / (WorkspaceStatePath.filename().string() + "_old"); - if (std::filesystem::is_directory(WorkspaceStatePath)) + std::vector<WorkspaceInfo> Workspaces; { - if (std::filesystem::is_directory(OldStateDirectory)) + RwLock::SharedLockScope _(m_Lock); + for (auto WorkspaceIt : m_Workspaces) { - std::filesystem::remove_all(OldStateDirectory); + std::vector<Workspaces::WorkspaceShareConfiguration> Shares; + for (auto ShareIt : WorkspaceIt.second->GetShares()) + { + Shares.push_back(ShareIt->GetConfig()); + } + Workspaces.push_back({.Config = WorkspaceIt.second->GetConfig(), .Shares = std::move(Shares)}); } - std::filesystem::rename(WorkspaceStatePath, OldStateDirectory); - } - - std::filesystem::rename(TempWritePath, WorkspaceStatePath); - - if (std::filesystem::is_directory(OldStateDirectory)) - { - std::filesystem::remove_all(OldStateDirectory); } + std::string ConfigJson = WorkspacesToJson(Workspaces); + TemporaryFile::SafeWriteFile(WorkspaceStatePath / "config.json", MemoryView(ConfigJson.data(), ConfigJson.size())); } void -Workspaces::ReadState(const std::filesystem::path& WorkspaceStatePath, std::function<Oid(const std::filesystem::path& Path)>&& PathToIdCB) +Workspaces::ReadState(const std::filesystem::path& WorkspaceStatePath, + const std::function<Oid(const std::filesystem::path& Path)>& PathToIdCB) { using namespace std::literals; - if (std::filesystem::is_directory(WorkspaceStatePath)) + std::string Error; + std::vector<Workspaces::WorkspaceInfo> Workspaces = + WorkspacesFromJson(IoBufferBuilder::MakeFromFile(WorkspaceStatePath / "config.json"sv), PathToIdCB, Error); + if (!Error.empty()) + { + ZEN_WARN("Failed to read workspace state from {}. Reason: '{}'", WorkspaceStatePath / "config.json"sv, Error); + } + else { - ZEN_INFO("Reading workspaces state from {}", WorkspaceStatePath); - DirectoryContent WorkspacesDirContent; - GetDirectoryContent(WorkspaceStatePath, DirectoryContent::IncludeDirsFlag, WorkspacesDirContent); - for (const std::filesystem::path& WorkspaceDirPath : WorkspacesDirContent.Directories) + for (const Workspaces::WorkspaceInfo& Workspace : Workspaces) { - Oid WorkspaceId = Oid::TryFromHexString(WorkspaceDirPath.filename().string()); - if (WorkspaceId != Oid::Zero) + if (AddWorkspace(Workspace.Config)) { - std::string Error; - WorkspaceConfiguration WorkspaceConfig = - WorkspaceFromJson(IoBufferBuilder::MakeFromFile(WorkspaceDirPath / "config.json"sv), Error); - if (!Error.empty()) - { - ZEN_WARN("Failed to read workspace state from {}. Reason: '{}'", WorkspaceDirPath / "config.json"sv, Error); - } - else if (WorkspaceConfig.Id == WorkspaceId) + for (const Workspaces::WorkspaceShareConfiguration& Share : Workspace.Shares) { - if (AddWorkspace(WorkspaceConfig)) - { - std::filesystem::path WorkspaceSharesStatePath = WorkspaceDirPath / "shares"sv; - if (std::filesystem::is_directory(WorkspaceSharesStatePath)) - { - DirectoryContent SharesDirContent; - GetDirectoryContent(WorkspaceDirPath / "shares"sv, DirectoryContent::IncludeDirsFlag, SharesDirContent); - for (const std::filesystem::path& ShareDirPath : SharesDirContent.Directories) - { - Oid ShareId = Oid::TryFromHexString(ShareDirPath.filename().string()); - if (ShareId != Oid::Zero) - { - WorkspaceShareConfiguration ShareConfig = - WorkspaceShareFromJson(IoBufferBuilder::MakeFromFile(ShareDirPath / "config.json"sv), Error); - if (!Error.empty()) - { - ZEN_WARN("Failed to read workspace share state from {}. Reason: '{}'", - ShareDirPath / "config.json"sv, - Error); - } - else if (ShareConfig.Id == ShareId) - { - AddWorkspaceShare(WorkspaceId, - ShareConfig, - std::function<Oid(const std::filesystem::path& Path)>(PathToIdCB)); - } - } - } - } - } + (void)AddWorkspaceShare(Workspace.Config.Id, Share, PathToIdCB); } } } |