Cppinecone
A C++ client for the Pinecone vector database
operation.hpp
Go to the documentation of this file.
1 #pragma once
7 #include <sstream>
8 #include <string>
9 #include <variant>
10 
11 #include <curl/curl.h>
12 #include <curl/easy.h>
13 
18 
19 namespace pinecone::domain
20 {
25 struct arg_base {
26  explicit arg_base(std::string url) : _url(std::move(url)) {}
27  virtual ~arg_base() = default;
28  arg_base(arg_base const&) = default;
29  arg_base(arg_base&&) noexcept = default;
30  auto operator=(arg_base const&) -> arg_base& = default;
31  auto operator=(arg_base&&) noexcept -> arg_base& = default;
32 
33  [[nodiscard]] auto url() const noexcept -> char const* { return _url.c_str(); }
34 
35  private:
36  std::string _url;
37 };
38 
43 template <operation_type op>
44 struct list_operation_args : public arg_base {
45  explicit list_operation_args(net::url_builder const& url_builder) noexcept
46  : arg_base(url_builder.build<op>())
47  {
48  }
49 };
50 
59 template <operation_type op>
60 [[nodiscard]] inline auto build_url(net::url_builder const& url_builder,
61  std::string_view resource_name) noexcept -> std::string
62 {
63  if constexpr (op_api_type(op) == api_type::service) {
64  return url_builder.build<op>(resource_name);
65  } else if constexpr (op_api_type(op) == api_type::controller) {
67  oss << url_builder.build<op>() << resource_name;
68  return oss.str();
69  }
70 }
71 
76 template <operation_type op>
79  std::string_view resource_name) noexcept
80  : arg_base(build_url<op>(url_builder, resource_name))
81  {
82  }
83 };
84 
92 template <operation_type op, typename Body>
93 struct patch_operation_args : public arg_base {
94  patch_operation_args(net::url_builder const& url_builder, std::string_view resource_name,
95  Body body) noexcept
96  : arg_base(build_url<op>(url_builder, resource_name))
97  {
98  json j;
99  to_json(j, body);
100  _body = j.dump();
101  }
102 
106  [[nodiscard]] auto body() noexcept -> char const* { return _body.c_str(); }
107 
108  private:
109  std::string _body;
110 };
111 
119 template <operation_type op, typename Body>
121  create_operation_args(net::url_builder const& url_builder, Body body) noexcept
122  : arg_base(url_builder.build<op>())
123  {
124  json j;
125  to_json(j, body);
126  _body = j.dump();
127  }
128 
132  [[nodiscard]] auto body() noexcept -> char const* { return _body.c_str(); }
133 
134  private:
135  std::string _body;
136 };
137 
145 template <operation_type op, typename Body>
147  vector_operation_args(net::url_builder const& url_builder, std::string_view resource_name,
148  Body body) noexcept
149  : arg_base(build_url<op>(url_builder, resource_name))
150  {
151  json j;
152  to_json(j, body);
153  _body = j.dump();
154  }
155 
159  [[nodiscard]] auto body() noexcept -> char const* { return _body.c_str(); }
160 
161  private:
162  std::string _body;
163 };
164 
171 template <operation_type, typename Body = std::monostate>
173 
174 static constexpr auto kDelete = "DELETE";
175 static constexpr auto kPatch = "PATCH";
176 
180 template <operation_type Op, typename Dep = std::monostate>
181 struct operation {
182  explicit operation(operation_args<Op, Dep> args) noexcept
183  : _args(std::move(args)), _method(op_method(op_type))
184  {
185  }
186 
190  static constexpr auto op_type = Op;
191 
195  [[nodiscard]] constexpr auto method() const noexcept { return _method; }
196 
204  constexpr auto set_opts(CURL* curl, curl_slist* headers) noexcept -> util::curl_result
205  {
206  curl_easy_reset(curl);
207 
208  return set_method_opts(curl)
209  .and_then([this, curl]() { return curl_easy_setopt(curl, CURLOPT_URL, _args.url()); })
210  .and_then([this, curl, headers]() {
211  return curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
212  });
213  }
214 
215  private:
216  constexpr auto set_method_opts(CURL* curl) noexcept -> util::curl_result
217  {
218  if constexpr (op_method(op_type) == method::del) {
219  return {curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, kDelete)};
220  }
221  if constexpr (op_method(op_type) == method::patch) {
222  return util::curl_result(curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, kPatch))
223  .and_then(
224  [this, curl]() { return curl_easy_setopt(curl, CURLOPT_POSTFIELDS, _args.body()); });
225  }
226  if constexpr (op_method(op_type) == method::post) {
227  return util::curl_result(curl_easy_setopt(curl, CURLOPT_POST, 1L)).and_then([this, curl]() {
228  return curl_easy_setopt(curl, CURLOPT_POSTFIELDS, _args.body());
229  });
230  }
231 
232  return {};
233  }
234 
235  operation_args<Op, Dep> _args;
236  domain::method _method;
237 };
238 } // namespace pinecone::domain
T c_str(T... args)
Wraps CURL results for type and exception safety.
HTTP method definitions.
T move(T... args)
auto build_url(net::url_builder const &url_builder, std::string_view resource_name) noexcept -> std::string
Constructs a URL for an operation that represents a unary resource.
Definition: operation.hpp:60
Operations made available by the Pinecone API.
constexpr auto op_api_type(operation_type op) -> api_type
Returns the API type of an operation.
constexpr auto op_method(operation_type op) -> method
Returns the HTTP method for an operation.
T str(T... args)
All operations require a common subset of information; this information forms the base arguments.
Definition: operation.hpp:25
Create operations construct themselves using a unique resource name and an operation-dependent body p...
Definition: operation.hpp:120
auto body() noexcept -> char const *
Definition: operation.hpp:132
Describe operations construct themselves using a unique resource name.
Definition: operation.hpp:77
List operations are simple and construct themselves using only a URL.
Definition: operation.hpp:44
Operation-specific arguments.
Definition: operation.hpp:172
Data common to all Pinecone API operation types.
Definition: operation.hpp:181
constexpr auto method() const noexcept
Definition: operation.hpp:195
constexpr auto set_opts(CURL *curl, curl_slist *headers) noexcept -> util::curl_result
Set CURL options for the operation.
Definition: operation.hpp:204
static constexpr auto op_type
The type of the operation.
Definition: operation.hpp:190
Patch operations construct themselves using a unique resource name and an operation-dependent body pa...
Definition: operation.hpp:93
auto body() noexcept -> char const *
Definition: operation.hpp:106
Vector operations construct themselves using a unique resource name and an operation-dependent body p...
Definition: operation.hpp:146
auto body() noexcept -> char const *
Definition: operation.hpp:159
Constructs Pinecone API URLs.
Definition: url_builder.hpp:20
auto build() const noexcept -> std::string
Constructs a URL for a specific operation_type.
Definition: url_builder.hpp:57
Models the possibly of failure for remote HTTP operations.
Definition: curl_result.hpp:20
constexpr auto and_then(std::function< curl_result()> const &func) const noexcept -> curl_result
Runs a transformation function on a successful result; does nothing on a failed result.
Definition: curl_result.hpp:80
Constructs Pinecone API URLs.