aboutsummaryrefslogtreecommitdiff
path: root/src/zen/cmds/cache_cmd.cpp
diff options
context:
space:
mode:
authorDan Engelbrecht <[email protected]>2024-10-03 12:35:44 +0200
committerGitHub Enterprise <[email protected]>2024-10-03 12:35:44 +0200
commitdb531191789f48a141c42fef229bca7a7922443d (patch)
treecc1570bf8dedccb975d594bd91284ac5d0bd0bae /src/zen/cmds/cache_cmd.cpp
parentsimplified CleanDirectory implementation (#182) (diff)
downloadarchived-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.cpp130
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