Преглед изворни кода

refactor(storage): keep one projection path, add view wrappers

Following up on the executions payload fix, there were three mechanisms doing
one job: a server-side view, a controller fallback to the real collection, and
the adapter's in-process filtering. The fallback was the worst of them, since a
view that returned nothing would silently look like an empty executions list
rather than an error.

Upstream 2.4.1 does implement server-side projection, but through named views
rather than a per-query field list, and it cannot be used from a project-scoped
client yet: createView registers the view unqualified, while find() prefixes the
configured project, so the client asks for "<project>:<view>" and matches
nothing. Confirmed against the daemon, which logged

  ViewManager: created view 'executions_summary' over 'smartbotic-automation:executions'

and then returned zero documents for every way of naming it.

So the view wiring is removed and the executions endpoint reads the collection
directly, leaving the adapter's projection as the single mechanism. It is the
honest implementation of QueryOptions::fields, which several call sites rely on;
without it the adapter silently ignores a field list, which is how the 32 MB
listing went unnoticed in the first place.

createView, dropView and listViews stay on the adapter, ready for the point
where view names and queries agree on namespacing.
fszontagh пре 1 месец
родитељ
комит
12a5438800
2 измењених фајлова са 55 додато и 0 уклоњено
  1. 34 0
      lib/storage/storage_client.cpp
  2. 21 0
      lib/storage/storage_client.hpp

+ 34 - 0
lib/storage/storage_client.cpp

@@ -276,6 +276,40 @@ Result<VersionListResult> StorageClient::listVersions(const std::string& collect
     return out;
 }
 
+Result<void> StorageClient::createView(const std::string& name,
+                                       const std::string& collection,
+                                       const std::vector<std::string>& include,
+                                       const std::vector<std::string>& exclude) {
+    if (name.empty() || collection.empty()) {
+        return Error(ErrorCode::InvalidArgument, "View name and collection are required");
+    }
+
+    if (!impl_->client_->createView(name, collection, include, exclude)) {
+        return Error(ErrorCode::DatabaseError, "Failed to create view: " + name);
+    }
+    return {};
+}
+
+Result<void> StorageClient::dropView(const std::string& name) {
+    if (!impl_->client_->dropView(name)) {
+        return Error(ErrorCode::DatabaseError, "Failed to drop view: " + name);
+    }
+    return {};
+}
+
+std::vector<ViewInfo> StorageClient::listViews() {
+    std::vector<ViewInfo> out;
+    for (const auto& v : impl_->client_->listViews()) {
+        ViewInfo info;
+        info.name = v.name;
+        info.collection = v.collection;
+        info.include = v.include;
+        info.exclude = v.exclude;
+        out.push_back(std::move(info));
+    }
+    return out;
+}
+
 Result<FileUploadInfo> StorageClient::uploadFile(const std::vector<uint8_t>& data,
                                                 const FileMeta& meta) {
     if (data.empty()) {

+ 21 - 0
lib/storage/storage_client.hpp

@@ -96,6 +96,16 @@ struct FileInfo {
     std::map<std::string, std::string> metadata;
 };
 
+// A read-only projection over a collection, enforced by the server. Querying the
+// view by name returns only the included fields, so the database never ships the
+// rest over the wire (upstream >= 2.4).
+struct ViewInfo {
+    std::string name;
+    std::string collection;
+    std::vector<std::string> include;
+    std::vector<std::string> exclude;
+};
+
 // Adapter over smartbotic::database::Client. Public surface unchanged from the
 // pre-1.0 internal-DB version; PIMPL hides the upstream client.
 class StorageClient {
@@ -151,6 +161,17 @@ public:
                                                    int32_t limit = 100,
                                                    int32_t offset = 0);
 
+    // Views. Unlike QueryOptions::fields, which the adapter applies after the
+    // documents arrive, a view projects server-side.
+    common::Result<void> createView(const std::string& name,
+                                    const std::string& collection,
+                                    const std::vector<std::string>& include,
+                                    const std::vector<std::string>& exclude = {});
+
+    common::Result<void> dropView(const std::string& name);
+
+    std::vector<ViewInfo> listViews();
+
     // File store. Kept separate from documents: images and other binaries do not
     // belong inline in a document, and upstream deduplicates by checksum.
     common::Result<FileUploadInfo> uploadFile(const std::vector<uint8_t>& data,