pg_async
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
resultset.hpp
Go to the documentation of this file.
1 
9 #ifndef TIP_DB_PG_RESULT_HPP_
10 #define TIP_DB_PG_RESULT_HPP_
11 
12 #include <tip/db/pg/common.hpp>
13 #include <tip/db/pg/error.hpp>
15 
16 #include <iterator>
17 #include <istream>
18 #include <memory>
19 #include <tuple>
20 
21 namespace tip {
22 namespace db {
23 namespace pg {
24 
25 namespace detail {
26 struct result_impl;
27 }
28 
56 class resultset {
57 public:
59 
63 
64  class row;
65  class field;
67 
69  typedef std::shared_ptr<detail::result_impl> result_impl_ptr;
70 
72 
74  typedef std::reverse_iterator< const_iterator > const_reverse_iterator;
75 
76  typedef row value_type;
77  typedef const value_type reference;
80 
82 
84  typedef std::reverse_iterator<const_field_iterator> const_reverse_field_iterator;
86 private:
87  typedef resultset const* result_pointer;
88 public:
90  static const size_type npos;
91 public:
95  resultset();
103 
104  size_type
105  size() const;
106  bool
107  empty() const;
110  begin() const;
112  end() const;
115  rbegin() const;
117  rend() const;
124  reference
125  front() const;
131  reference
132  back() const;
133 
140  reference
141  operator[](size_type index) const;
148  reference
149  at(size_type index) const;
151 
153 
165  operator bool() const
166  {
167  return !empty();
168  }
180  bool
181  operator!() const
182  {
183  return *this;
184  }
186 public:
188 
189  size_type
190  columns_size() const;
192  row_description_type const&
193  row_description() const;
199  size_type
200  index_of_name(std::string const& name) const;
201 
208  field_description const&
209  field(size_type col_index) const;
210 
217  field_description const&
218  field(std::string const& name) const;
219 
226  std::string const&
227  field_name(size_type col_index) const;
229 public:
231 
238  class row {
239  public:
242 
244 
247 
248  typedef class field value_type;
249  typedef class field reference;
252  static const size_type npos;
253  public:
254  size_type
255  row_index() const
256  { return row_index_; }
257 
259 
260  size_type
261  size() const;
267  bool
268  empty() const;
269 
271  begin() const;
273  end() const;
276  rbegin() const;
278  rend() const;
280 
281 
287  reference
288  operator[](size_type index) const;
294  reference
295  operator[](std::string const& name) const;
297 
302  template < typename ... T >
303  void
304  to( std::tuple< T ... >& ) const;
305 
306  template < typename ... T >
307  void
308  to( std::tuple< T& ... > ) const;
309 
310  template < typename ... T >
311  void
312  to(T& ... ) const;
313  protected:
314  friend class resultset;
320  row(result_pointer res, resultset::size_type idx)
321  : result_(res), row_index_(idx) {}
322 
323  result_pointer result_;
325  }; // row
331  class field {
332  public:
333  size_type
334  row_index() const
335  { return row_index_; }
337  field_index() const
338  { return field_index_; }
339 
340  std::string const&
341  name() const;
343  field_description const&
344  description() const;
346  bool
347  is_null() const;
349  bool
350  empty() const;
360  template < typename T >
361  bool
362  to( T& val ) const
363  {
364  if (is_null())
365  throw error::value_is_null(name());
366  return to_impl(val,
368  }
369 
379  template < typename T >
380  bool
381  to( boost::optional< T >& val ) const
382  {
383  if (is_null()) {
384  val = boost::optional< T >();
385  return true;
386  } else {
387  typename std::decay<T>::type tmp;
389  val = boost::optional< T > (tmp);
390  return true;
391  }
392  return false;
393  }
394 
402  template < typename T >
403  typename std::decay<T>::type
404  as() const
405  {
406  typename std::decay<T>::type val;
407  to(val);
408  return val;
409  }
417  template < typename T >
418  typename std::decay<T>::type
419  coalesce(T const& default_val)
420  {
421  if (is_null())
422  return default_val;
423  return as< T >();
424  }
425  private:
426  template < typename T >
427  bool
428  to_impl( T& val, std::true_type const& ) const
429  {
430  field_description const& fd = description();
431  field_buffer b = input_buffer();
432  if (fd.format_code == TEXT_DATA_FORMAT) {
433  io::protocol_read< TEXT_DATA_FORMAT >(b.begin(), b.end(), val);
434  } else {
435  io::protocol_read< BINARY_DATA_FORMAT >(b.begin(), b.end(), val);
436  }
437  return true;
438  }
439 
440  template < typename T >
441  bool
442  to_impl( T& val, std::false_type const& ) const
443  {
444  field_buffer b = input_buffer();
445  io::protocol_read< TEXT_DATA_FORMAT >(b.begin(), b.end(), val);
446  return true;
447  }
448 
450  input_buffer() const;
451  protected:
452  friend class resultset;
453  friend class row;
454  field(result_pointer res, size_type row, row::size_type col) :
455  result_(res), row_index_(row), field_index_(col) {}
456 
457  result_pointer result_;
460  }; // field
462 
463 
467  class const_row_iterator : public row {
468  public:
470 
471  typedef row value_type;
474  typedef value_type const* pointer;
475  typedef std::random_access_iterator_tag iterator_category;
477  public:
481  const_row_iterator() : row(nullptr, npos) {}
482 
484 
485  reference
486  operator*() const
487  {
488  return reference(*this);
489  }
490  pointer
491  operator->() const
492  {
493  return this;
494  }
496 
497 
504  operator bool() const
505  { return result_ && row_index_ <= result_->size(); }
506  bool
507  operator !() const
508  { return !(this->operator bool()); }
510 
511 
514  { return advance(1); }
515 
518  {
519  const_row_iterator i(*this);
520  advance(1);
521  return i;
522  }
525  { return advance(-1); }
526 
529  {
530  const_row_iterator i(*this);
531  advance(-1);
532  return i;
533  }
534 
537  { return advance(distance); }
540  { return advance(-distance); }
542 
544 
545  bool
547  { return compare(rhs) == 0; }
548 
549  bool
551  { return !(*this == rhs); }
552 
553  bool
554  operator < (const_row_iterator const& rhs) const
555  { return compare(rhs) < 0; }
556  bool
558  { return compare(rhs) <= 0; }
559  bool
560  operator > (const_row_iterator const& rhs) const
561  { return compare(rhs) > 0; }
562  bool
564  { return compare(rhs) >= 0; }
566 
567  private:
568  friend class resultset;
569  const_row_iterator(result_pointer res, resultset::size_type index)
570  : row(res, index) {}
571  int
572  compare(const_row_iterator const& rhs) const;
574  advance(difference_type);
575  }; // const_row_iterator
576 
580  class const_field_iterator : public field {
581  public:
583 
584  typedef field value_type;
587  typedef value_type const* pointer;
588  typedef std::random_access_iterator_tag iterator_category;
590  public:
595 
597 
598  reference
599  operator*() const
600  {
601  return reference(*this);
602  }
603  pointer
604  operator->() const
605  {
606  return this;
607  }
609 
610 
617  operator bool() const
618  { return result_
619  && row_index_ < result_->size()
620  && field_index_ <= result_->columns_size(); }
621  bool
622  operator !() const
623  { return !(this->operator bool()); }
625 
626 
629  { return advance(1); }
630 
633  {
634  const_field_iterator i(*this);
635  advance(1);
636  return i;
637  }
640  { return advance(-1); }
641 
644  {
645  const_field_iterator i(*this);
646  advance(-1);
647  return i;
648  }
649 
652  { return advance(distance); }
655  { return advance(-distance); }
657 
659 
660  bool
662  { return compare(rhs) == 0; }
663 
664  bool
666  { return !(*this == rhs); }
667 
668  bool
670  { return compare(rhs) < 0; }
671  bool
673  { return compare(rhs) <= 0; }
674  bool
676  { return compare(rhs) > 0; }
677  bool
679  { return compare(rhs) >= 0; }
681  private:
682  friend class row;
683  const_field_iterator(result_pointer res, size_type row, size_type col)
684  : field(res, row, col) {}
685  int
686  compare(const_field_iterator const& rhs) const;
688  advance(difference_type distance);
689  }; // const_field_iterator
691 private:
692  friend class row;
693  friend class field;
694  typedef std::shared_ptr<const detail::result_impl> const_result_impl_ptr;
695  const_result_impl_ptr pimpl_;
696 
698  at(size_type r, row::size_type c) const;
699 
700  bool
701  is_null(size_type r, row::size_type c) const;
702 }; // resultset
703 
706 {
707  return a.row_index() - b.row_index();
708 }
709 
710 } // namespace pg
711 } // namespace db
712 } // namespace tip
713 
714 #include <tip/db/pg/resultset.inl>
715 
716 #endif /* TIP_DB_PG_RESULT_HPP_ */
reference operator[](size_type index) const
const value_type reference
Definition: resultset.hpp:77
const_row_iterator & operator+=(difference_type distance)
Definition: resultset.hpp:536
size_type row_index() const
Definition: resultset.hpp:255
const_row_iterator & operator-=(difference_type distance)
Definition: resultset.hpp:539
bool operator!=(const_row_iterator const &rhs) const
Definition: resultset.hpp:550
tip::util::input_iterator_buffer field_buffer
Definition: common.hpp:201
bool operator>(const_row_iterator const &rhs) const
Definition: resultset.hpp:560
std::reverse_iterator< const_field_iterator > const_reverse_field_iterator
Definition: resultset.hpp:83
field(result_pointer res, size_type row, row::size_type col)
Definition: resultset.hpp:454
bool operator==(const_field_iterator const &rhs) const
Definition: resultset.hpp:661
std::shared_ptr< detail::result_impl > result_impl_ptr
Definition: resultset.hpp:66
const_iterator end() const
bool operator>=(const_field_iterator const &rhs) const
Definition: resultset.hpp:678
size_type row_index() const
Index of owner row.
Definition: resultset.hpp:334
reference at(size_type index) const
std::random_access_iterator_tag iterator_category
Definition: resultset.hpp:475
const_reverse_iterator rend() const
resultset::difference_type difference_type
Definition: resultset.hpp:241
size_type size() const
boost::int_t< 32 >::exact integer
4-byte integer, to match PostgreSQL integer and serial types
Definition: common.hpp:162
reference operator[](size_type index) const
const_field_iterator & operator+=(difference_type distance)
Definition: resultset.hpp:651
const_reverse_field_iterator const_reverse_iterator
Definition: resultset.hpp:246
bool operator!() const
Definition: resultset.hpp:181
bool operator>=(const_row_iterator const &rhs) const
Definition: resultset.hpp:563
row(result_pointer res, resultset::size_type idx)
Definition: resultset.hpp:320
std::decay< T >::type coalesce(T const &default_val)
Definition: resultset.hpp:419
bool operator<(const_row_iterator const &rhs) const
Definition: resultset.hpp:554
const_field_iterator const_iterator
Definition: resultset.hpp:245
row_description_type const & row_description() const
std::random_access_iterator_tag iterator_category
Definition: resultset.hpp:588
resultset::row::difference_type operator-(resultset::row const &a, resultset::row const &b)
Definition: resultset.hpp:705
reference front() const
bool operator<(const_field_iterator const &rhs) const
Definition: resultset.hpp:669
const_iterator pointer
Definition: resultset.hpp:78
protocol_data_format format_code
The format code being used for the field. Currently will be zero (text) or one (binary). In a RowDescription returned from the statement variant of Describe, the format code is not yet known and will always be zero.
Definition: common.hpp:319
const_reverse_iterator rbegin() const
size_type index_of_name(std::string const &name) const
static const size_type npos
Not-a-position constant.
Definition: resultset.hpp:90
bool operator<=(const_row_iterator const &rhs) const
Definition: resultset.hpp:557
std::decay< T >::type as() const
Definition: resultset.hpp:404
const_iterator begin() const
std::string const & name() const
Name of field.
const_reverse_iterator rend() const
bool operator!=(const_field_iterator const &rhs) const
Definition: resultset.hpp:665
resultset::difference_type difference_type
Definition: resultset.hpp:585
void to(std::tuple< T... > &) const
Definition: resultset.inl:78
bool is_null() const
Is field value null.
bool to(boost::optional< T > &val) const
Definition: resultset.hpp:381
boost::uint_t< 32 >::exact uinteger
4-byte unsigned integer
Definition: common.hpp:166
const_row_iterator const_iterator
Definition: resultset.hpp:73
An attempt to extract a value from a null field was made.
Definition: error.hpp:76
boost::int_t< 16 >::exact smallint
2-byte integer, to match PostgreSQL smallint and smallserial types
Definition: common.hpp:154
Description of a field returned by the backend.
Definition: common.hpp:291
field_description const & description() const
Field description.
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: resultset.hpp:74
resultset::size_type row_index_
Definition: resultset.hpp:324
reference back() const
bool empty() const
Is field value empty (not null)
const_reverse_iterator rbegin() const
bool operator<=(const_field_iterator const &rhs) const
Definition: resultset.hpp:672
std::vector< field_description > row_description_type
Result set's row description.
Definition: common.hpp:325
const_field_iterator & operator-=(difference_type distance)
Definition: resultset.hpp:654
static const size_type npos
Definition: resultset.hpp:252
TEXT_DATA_FORMAT.
Definition: common.hpp:284
size_type size() const
bool operator>(const_field_iterator const &rhs) const
Definition: resultset.hpp:675
std::string const & field_name(size_type col_index) const
const_iterator begin() const
const_iterator end() const
bool to(T &val) const
Definition: resultset.hpp:362
resultset()
Construct an empty resultset.
bool operator==(const_row_iterator const &rhs) const
Definition: resultset.hpp:546
size_type columns_size() const
row::size_type field_index() const
Index of field in the row.
Definition: resultset.hpp:337
resultset::difference_type difference_type
Definition: resultset.hpp:472