diff options
| author | Dan Engelbrecht <[email protected]> | 2024-10-03 12:35:44 +0200 |
|---|---|---|
| committer | GitHub Enterprise <[email protected]> | 2024-10-03 12:35:44 +0200 |
| commit | db531191789f48a141c42fef229bca7a7922443d (patch) | |
| tree | cc1570bf8dedccb975d594bd91284ac5d0bd0bae /src/zen/cmds/cache_cmd.cpp | |
| parent | simplified CleanDirectory implementation (#182) (diff) | |
| download | archived-zen-db531191789f48a141c42fef229bca7a7922443d.tar.xz archived-zen-db531191789f48a141c42fef229bca7a7922443d.zip | |
cache get command (#183)
* move TryParseObjectId and TryParseIoHash to Oid::TryParse and IoHash::TryParse respectively
* zen cache-get command
Diffstat (limited to 'src/zen/cmds/cache_cmd.cpp')
| -rw-r--r-- | src/zen/cmds/cache_cmd.cpp | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/src/zen/cmds/cache_cmd.cpp b/src/zen/cmds/cache_cmd.cpp index eecc3494e..d6fec3b12 100644 --- a/src/zen/cmds/cache_cmd.cpp +++ b/src/zen/cmds/cache_cmd.cpp @@ -5,6 +5,7 @@ #include <zencore/compress.h> #include <zencore/except.h> #include <zencore/filesystem.h> +#include <zencore/fmtutils.h> #include <zencore/logging.h> #include <zencore/scopeguard.h> #include <zencore/thread.h> @@ -514,4 +515,133 @@ CacheGenerateCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** a return 0; } +CacheGetCommand::CacheGetCommand() +{ + m_Options.add_options()("h,help", "Print help"); + m_Options.add_option("", "u", "hosturl", "Host URL", cxxopts::value(m_HostName)->default_value(""), "<hosturl>"); + m_Options + .add_option("", "n", "namespace", "Namespace to generate cache values/records for", cxxopts::value(m_Namespace), "<namespace>"); + m_Options.add_option("", "b", "bucket", "Bucket name to generate cache values/records for", cxxopts::value(m_Bucket), "<bucket>"); + m_Options.add_option("", "v", "valuekey", "Cache entry iohash id", cxxopts::value(m_ValueKey), "<valuekey>"); + m_Options.add_option("", + "a", + "attachmentid", + "For a cache entry record, get a particular attachment based on IoHash", + cxxopts::value(m_AttachmentId), + "<attachmentid>"); + m_Options.add_option("", "o", "output-path", "File path for output data", cxxopts::value(m_OutputPath), "<path>"); + m_Options.add_option("", "t", "text", "Ouput content of cache entry record as text", cxxopts::value(m_AsText), "<text>"); + m_Options.parse_positional({"namespace", "bucket", "valuekey", "attachmentid"}); + m_Options.positional_help("namespace bucket valuekey attachmentid"); +} + +CacheGetCommand::~CacheGetCommand() = default; + +int +CacheGetCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) +{ + ZEN_UNUSED(GlobalOptions); + + using namespace std::literals; + + if (!ParseOptions(argc, argv)) + { + return 0; + } + + m_HostName = ResolveTargetHostSpec(m_HostName); + + if (m_HostName.empty()) + { + throw zen::OptionParseException("unable to resolve server specification"); + } + + if (m_Namespace.empty()) + { + throw zen::OptionParseException("cache-get command requires a namespace"); + } + + if (m_Bucket.empty()) + { + throw zen::OptionParseException("cache-get command requires a bucket"); + } + + if (m_ValueKey.empty()) + { + throw zen::OptionParseException("cache-get command requires a value key"); + } + + IoHash ValueId; + if (!IoHash::TryParse(m_ValueKey, ValueId)) + { + throw zen::OptionParseException("cache-get --valuekey option requires a valid IoHash string"); + } + + IoHash AttachmentHash; + if (!m_AttachmentId.empty()) + { + if (!IoHash::TryParse(m_AttachmentId, AttachmentHash)) + { + throw zen::OptionParseException("cache-get --attachmentid option requires a valid IoHash string"); + } + } + + HttpClient Http(m_HostName); + + std::filesystem::path TargetPath; + if (!m_OutputPath.empty()) + { + TargetPath = std::filesystem::path(m_OutputPath); + if (std::filesystem::is_directory(TargetPath)) + { + TargetPath = TargetPath / (m_AttachmentId.empty() ? m_ValueKey : m_AttachmentId); + } + else + { + CreateDirectories(TargetPath.parent_path()); + } + } + if (TargetPath.empty()) + { + TargetPath = (m_AttachmentId.empty() ? m_ValueKey : m_AttachmentId); + } + + std::string Url = fmt::format("/z$/{}/{}/{}", m_Namespace, m_Bucket, m_ValueKey); + if (AttachmentHash != IoHash::Zero) + { + Url = fmt::format("{}/{}", Url, AttachmentHash); + } + if (HttpClient::Response Result = Http.Download(Url, std::filesystem::temp_directory_path()); Result) + { + IoBuffer ChunkData = Result.ResponsePayload; + if (m_AsText) + { + std::string StringData = Result.ToText(); + if (m_OutputPath.empty()) + { + ZEN_CONSOLE("{}", StringData); + } + else + { + WriteFile(TargetPath, IoBuffer(IoBuffer::Wrap, StringData.data(), StringData.length())); + ZEN_CONSOLE("Wrote {} to '{}' ({})", NiceBytes(StringData.length()), TargetPath, ToString(ChunkData.GetContentType())); + } + } + else + { + if (!MoveToFile(TargetPath, ChunkData)) + { + WriteFile(TargetPath, ChunkData); + } + ZEN_CONSOLE("Wrote {} to '{}' ({})", NiceBytes(ChunkData.GetSize()), TargetPath, ToString(ChunkData.GetContentType())); + } + } + else + { + Result.ThrowError("Failed to fetch data"sv); + } + + return 0; +} + } // namespace zen |