|
@@ -1,5 +1,6 @@
|
|
|
#include "storage/storage_client.hpp"
|
|
#include "storage/storage_client.hpp"
|
|
|
|
|
|
|
|
|
|
+#include <algorithm>
|
|
|
#include <chrono>
|
|
#include <chrono>
|
|
|
#include <smartbotic/database/client.hpp>
|
|
#include <smartbotic/database/client.hpp>
|
|
|
|
|
|
|
@@ -14,6 +15,11 @@ using common::Result;
|
|
|
|
|
|
|
|
namespace {
|
|
namespace {
|
|
|
|
|
|
|
|
|
|
+// Upstream treats an empty project and "default" as the same back-compat namespace.
|
|
|
|
|
+bool project_isDefault(const std::string& project) {
|
|
|
|
|
+ return project.empty() || project == "default";
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
uint32_t msToSec(int64_t ms) {
|
|
uint32_t msToSec(int64_t ms) {
|
|
|
if (ms <= 0) return 0;
|
|
if (ms <= 0) return 0;
|
|
|
return static_cast<uint32_t>((ms + 999) / 1000);
|
|
return static_cast<uint32_t>((ms + 999) / 1000);
|
|
@@ -52,17 +58,22 @@ dbc::Client::Filter buildFilter(const std::string& field, const nlohmann::json&
|
|
|
|
|
|
|
|
class StorageClient::Impl {
|
|
class StorageClient::Impl {
|
|
|
public:
|
|
public:
|
|
|
- explicit Impl(const StorageClientConfig& cfg) {
|
|
|
|
|
|
|
+ explicit Impl(const StorageClientConfig& cfg) : project_(cfg.project) {
|
|
|
dbc::Client::Config config;
|
|
dbc::Client::Config config;
|
|
|
config.address = cfg.address;
|
|
config.address = cfg.address;
|
|
|
config.timeoutMs = static_cast<uint32_t>(cfg.timeout_ms);
|
|
config.timeoutMs = static_cast<uint32_t>(cfg.timeout_ms);
|
|
|
|
|
+ config.project = cfg.project;
|
|
|
client_ = std::make_unique<dbc::Client>(std::move(config));
|
|
client_ = std::make_unique<dbc::Client>(std::move(config));
|
|
|
if (!client_->connect()) {
|
|
if (!client_->connect()) {
|
|
|
- LOG_WARN("StorageClient: connect() to {} returned false", cfg.address);
|
|
|
|
|
|
|
+ LOG_WARN("StorageClient: connect() to {} (project '{}') returned false",
|
|
|
|
|
+ cfg.address, cfg.project);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ LOG_INFO("StorageClient: connected to {} (project '{}')", cfg.address, cfg.project);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
std::unique_ptr<dbc::Client> client_;
|
|
std::unique_ptr<dbc::Client> client_;
|
|
|
|
|
+ std::string project_;
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
StorageClient::StorageClient(const StorageClientConfig& config)
|
|
StorageClient::StorageClient(const StorageClientConfig& config)
|
|
@@ -188,8 +199,29 @@ Result<void> StorageClient::dropCollection(const std::string& name) {
|
|
|
return {};
|
|
return {};
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+// Upstream's listCollections() is instance-wide, not project-scoped: it returns
|
|
|
|
|
+// every collection on the daemon, qualified as "<project>:<collection>" for named
|
|
|
|
|
+// projects and bare for the default one. Every other method here applies
|
|
|
|
|
+// Config::project itself, so an unfiltered list both leaks other projects'
|
|
|
|
|
+// collections and hands callers names that resolve to nothing when read back.
|
|
|
|
|
+// Scope to our own project and strip the prefix, so the names round-trip.
|
|
|
std::vector<std::string> StorageClient::listCollections() {
|
|
std::vector<std::string> StorageClient::listCollections() {
|
|
|
- return impl_->client_->listCollections();
|
|
|
|
|
|
|
+ const bool is_default = project_isDefault(impl_->project_);
|
|
|
|
|
+ const std::string prefix = (is_default ? std::string("default") : impl_->project_) + ":";
|
|
|
|
|
+
|
|
|
|
|
+ std::vector<std::string> out;
|
|
|
|
|
+ for (const auto& name : impl_->client_->listCollections()) {
|
|
|
|
|
+ if (name.rfind(prefix, 0) == 0) {
|
|
|
|
|
+ out.push_back(name.substr(prefix.size()));
|
|
|
|
|
+ } else if (is_default && name.find(':') == std::string::npos) {
|
|
|
|
|
+ // Legacy unqualified collections belong to the default project.
|
|
|
|
|
+ out.push_back(name);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ std::sort(out.begin(), out.end());
|
|
|
|
|
+ out.erase(std::unique(out.begin(), out.end()), out.end());
|
|
|
|
|
+ return out;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
Result<nlohmann::json> StorageClient::getVersion(const std::string& collection,
|
|
Result<nlohmann::json> StorageClient::getVersion(const std::string& collection,
|