OZO 「お象」
Boost.Asio and libpq based asynchronous PostgreSQL unofficial header-only C++17 client library.
result.h
1 #pragma once
2 
3 #include <ozo/impl/result.h>
4 #include <boost/iterator/iterator_facade.hpp>
5 #include <memory>
6 #include <vector>
7 
8 
9 namespace ozo {
10 
22 #ifndef OZO_DOCUMENTATION
23 template <typename Result>
24 #endif
25 class value {
26 public:
27  struct coordinates {
28  const Result* res;
29  int row;
30  int col;
31  };
32 
33  value(const coordinates& v) noexcept : v_(v) {}
34 
40  oid_t oid() const noexcept {
41  return impl::field_type(res(), column());
42  }
43 
51  bool is_text() const noexcept {
52  return impl::field_format(res(), column()) == impl::result_format::text;
53  }
54 
62  bool is_binary() const noexcept {
63  return impl::field_format(res(), column()) == impl::result_format::binary;
64  }
65 
72  const char* data() const noexcept {
73  return impl::get_value(res(), row(), column());
74  }
75 
82  std::size_t size() const noexcept {
83  return impl::get_length(res(), row(), column());
84  }
85 
92  bool is_null() const noexcept {
93  return impl::get_isnull(res(), row(), column());
94  }
95 
96 private:
97  int column() const noexcept { return v_.col;}
98  int row() const noexcept { return v_.row;}
99  const Result& res() const noexcept { return *(v_.res);}
100 
101  coordinates v_;
102 };
103 
109 #ifndef OZO_DOCUMENTATION
110 template <typename Result>
111 #endif
112 class row {
113 public:
114  using value = ozo::value<Result>;
115  using coordinates = typename value::coordinates;
116 
117 #ifdef OZO_DOCUMENTATION
118 
126  using const_iterator = <implementation defined>;
127 #else
128  class const_iterator : public boost::iterator_facade<
129  const_iterator,
130  value,
131  boost::random_access_traversal_tag,
132  value,
133  int
134  > {
135  public:
136  const_iterator() = default;
137  const_iterator(const coordinates& v) noexcept : v_{v} {}
138 
139  private:
140  value dereference() const noexcept { return {v_}; }
141 
142  bool equal(const const_iterator& rhs) const noexcept {
143  return v_.res == rhs.v_.res && v_.col == rhs.v_.col && v_.row == rhs.v_.row;
144  }
145 
146  void increment() noexcept { advance(1); }
147  void decrement() noexcept { advance(-1); }
148  void advance(int n) noexcept { v_.col += n; }
149 
150  int distance_to(const const_iterator& z) noexcept { return z.col - v_.col; }
151 
152  coordinates v_ {nullptr, 0, 0};
153 
154  friend class boost::iterator_core_access;
155  };
156 #endif
157 
161 
162  row(const coordinates& first) noexcept : first_(first) {}
163 
169  const_iterator begin() const noexcept { return {first_}; }
170 
176  const_iterator end() const noexcept { return begin() + size(); }
177 
185  const_iterator find(const char* name) const noexcept {
186  int i = impl::field_number(*(first_.res), name);
187  return i == -1 ? end() : begin() + i;
188  }
189 
199  value operator[] (int index) const noexcept { return *(begin() + index); }
200 
206  std::size_t size() const noexcept { return impl::nfields(*(first_.res)); }
207 
214  [[nodiscard]] bool empty() const noexcept { return size() == 0; }
215 
224  value at(int index) const {
225  if (index < 0 || static_cast<std::size_t>(index) >= size()) {
226  throw std::out_of_range("ozo::row::at() field index "
227  + std::to_string(index) + " out of range");
228  }
229  return (*this)[index];
230  }
231 
240  value at(const char* name) const {
241  auto i = find(name);
242  if (i == end()) {
243  throw std::out_of_range(std::string("ozo::row::at() no such field name ")
244  + name);
245  }
246  return *i;
247  }
248 
249 private:
250  coordinates first_;
251 };
252 
262 template <typename T>
264 public:
265  using handle_type = T;
266  using native_handle_type = decltype(std::addressof(*std::declval<handle_type>()));
268  using value = typename row::value;
269  using coordinates = typename row::coordinates;
270 
271 #ifdef OZO_DOCUMENTATION
272 
280  using const_iterator = <implementation defined>;
281 #else
282  class const_iterator : public boost::iterator_facade<
283  const_iterator,
284  row,
285  boost::random_access_traversal_tag,
286  row,
287  int
288  > {
289  public:
290  const_iterator() = default;
291  const_iterator(const coordinates& v) noexcept : v_{v} {}
292 
293  private:
294  row dereference() const noexcept { return {v_}; }
295 
296  bool equal(const const_iterator& rhs) const noexcept {
297  return v_.res == rhs.v_.res && v_.row == rhs.v_.row;
298  }
299 
300  void increment() noexcept { advance(1); }
301  void decrement() noexcept { advance(-1); }
302  void advance(int n) noexcept { v_.row += n; }
303 
304  int distance_to(const const_iterator& z) noexcept { return z.row - v_.row; }
305 
306  coordinates v_ {nullptr, 0, 0};
307 
308  friend class boost::iterator_core_access;
309  };
310 #endif
311 
316 
317  basic_result() = default;
318  basic_result(handle_type res) noexcept(noexcept(handle_type(std::move(res))))
319  : handle_(std::move(res)) {}
320 
321  template <typename Other, typename = hana::when<
322  hana::is_convertible<Other, T>::value && !std::is_same_v<T, Other>
323  >>
324  basic_result(basic_result<Other>&& x) noexcept(
325  noexcept(handle_type{hana::to<T>(std::move(x.release()))}))
326  : handle_(hana::to<T>(std::move(x.release()))) {
327  }
328 
334  const_iterator begin() const noexcept { return {{native_handle(), 0, 0}}; }
335 
341  const_iterator end() const noexcept { return begin() + size(); }
342 
348  std::size_t size() const noexcept { return impl::ntuples(*native_handle());}
349 
356  [[nodiscard]] bool empty() const noexcept { return size() == 0; }
357 
367  row operator[] (int i) const noexcept { return *(begin() + i); }
368 
377  row at(int i) const {
378  if (i < 0 || static_cast<std::size_t>(i) >= size()) {
379  throw std::out_of_range("ozo::result::at() index " + std::to_string(i) + " out of range");
380  }
381  return (*this)[i];
382  }
383 
392  native_handle_type native_handle() const noexcept {
393  return std::addressof(*handle_);
394  }
395 
399  bool valid() const noexcept { return bool(handle_); }
400 
409  handle_type release() noexcept(std::is_nothrow_move_constructible_v<handle_type>) {
410  return std::move(handle_);
411  }
412 
413 private:
414 
415  handle_type handle_;
416 };
417 
435 
445 
446 template <typename T>
447 auto make_result(T&& handle) {
448  return ozo::basic_result<std::decay_t<T>>(std::forward<T>(handle));
449 }
450 
451 } // namespace ozo
ozo::row::size
std::size_t size() const noexcept
Definition: result.h:206
ozo::value::is_binary
bool is_binary() const noexcept
Definition: result.h:62
ozo::basic_result::begin
const_iterator begin() const noexcept
Definition: result.h:334
ozo::row::empty
bool empty() const noexcept
Definition: result.h:214
ozo::basic_result::native_handle
native_handle_type native_handle() const noexcept
Definition: result.h:392
ozo::row::operator[]
value operator[](int index) const noexcept
Definition: result.h:199
ozo::basic_result::at
row at(int i) const
Definition: result.h:377
ozo::basic_result::iterator
const_iterator iterator
Definition: result.h:315
ozo::row::begin
const_iterator begin() const noexcept
Definition: result.h:169
ozo::row::const_iterator
< implementation defined > const_iterator
Definition: result.h:126
ozo::value::is_null
bool is_null() const noexcept
Definition: result.h:92
ozo::value::oid
oid_t oid() const noexcept
Definition: result.h:40
ozo::value::size
std::size_t size() const noexcept
Definition: result.h:82
ozo::row
Database request result row proxy.
Definition: result.h:112
ozo::basic_result::size
std::size_t size() const noexcept
Definition: result.h:348
ozo::basic_result::end
const_iterator end() const noexcept
Definition: result.h:341
ozo::row::end
const_iterator end() const noexcept
Definition: result.h:176
ozo::basic_result::empty
bool empty() const noexcept
Definition: result.h:356
ozo::value::is_text
bool is_text() const noexcept
Definition: result.h:51
ozo::value
Database request result value proxy.
Definition: result.h:25
ozo::basic_result::operator[]
row operator[](int i) const noexcept
Definition: result.h:367
ozo::value::data
const char * data() const noexcept
Definition: result.h:72
ozo::basic_result::release
handle_type release() noexcept(std::is_nothrow_move_constructible_v< handle_type >)
Definition: result.h:409
ozo::basic_result::valid
bool valid() const noexcept
Definition: result.h:399
ozo::row::at
value at(int index) const
Definition: result.h:224
ozo::basic_result::const_iterator
< implementation defined > const_iterator
Definition: result.h:280
ozo::row::iterator
const_iterator iterator
Definition: result.h:160
ozo::row::find
const_iterator find(const char *name) const noexcept
Definition: result.h:185
ozo::basic_result
Database raw result representation.
Definition: result.h:263
ozo::oid_t
::Oid oid_t
PostgreSQL OID type - object identifier.
Definition: type_traits.h:70
ozo::row::at
value at(const char *name) const
Definition: result.h:240