libpqxx  5.0
result.hxx
1 /*-------------------------------------------------------------------------
2  *
3  * FILE
4  * pqxx/result.hxx
5  *
6  * DESCRIPTION
7  * definitions for the pqxx::result class and support classes.
8  * pqxx::result represents the set of result rows from a database query
9  * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/result instead.
10  *
11  * Copyright (c) 2001-2016, Jeroen T. Vermeulen <jtv@xs4all.nl>
12  *
13  * See COPYING for copyright license. If you did not receive a file called
14  * COPYING with this source code, please notify the distributor of this mistake,
15  * or contact the author.
16  *
17  *-------------------------------------------------------------------------
18  */
19 #ifndef PQXX_H_RESULT
20 #define PQXX_H_RESULT
21 
22 #include "pqxx/compiler-public.hxx"
23 #include "pqxx/compiler-internal-pre.hxx"
24 
25 #include <ios>
26 #include <stdexcept>
27 
28 #include "pqxx/internal/result_data.hxx"
29 
30 #include "pqxx/except"
31 #include "pqxx/field"
32 #include "pqxx/row"
33 #include "pqxx/util"
34 
35 /* Methods tested in eg. self-test program test001 are marked with "//[t1]"
36  */
37 
38 // TODO: Support SQL arrays
39 
40 namespace pqxx
41 {
42 namespace internal
43 {
44 namespace gate
45 {
46 class result_connection;
47 class result_creation;
48 class result_sql_cursor;
49 } // namespace internal::gate
50 } // namespace internal
51 
52 
53 class const_result_iterator;
54 class const_reverse_result_iterator;
55 
56 
58 
78 class PQXX_LIBEXPORT result :
79  private internal::PQAlloc<
80  const internal::result_data, internal::freemem_result_data>
81 {
82  typedef internal::PQAlloc<
83  const internal::result_data, internal::freemem_result_data> super;
84 public:
85  typedef unsigned long size_type;
86  typedef signed long difference_type;
87  typedef row reference;
93 
94  result() PQXX_NOEXCEPT : super(), m_data(0) {} //[t3]
95  result(const result &rhs) PQXX_NOEXCEPT : //[t1]
96  super(rhs), m_data(rhs.m_data) {}
97 
98  result &operator=(const result &rhs) PQXX_NOEXCEPT //[t10]
99  { super::operator=(rhs); m_data=rhs.m_data; return *this; }
100 
105  bool operator==(const result &) const PQXX_NOEXCEPT; //[t70]
106  bool operator!=(const result &rhs) const PQXX_NOEXCEPT //[t70]
107  { return !operator==(rhs); }
109 
110  const_reverse_iterator rbegin() const; //[t75]
111  const_reverse_iterator crbegin() const;
112  const_reverse_iterator rend() const; //[t75]
113  const_reverse_iterator crend() const;
114 
115  const_iterator begin() const PQXX_NOEXCEPT; //[t1]
116  const_iterator cbegin() const PQXX_NOEXCEPT;
117  inline const_iterator end() const PQXX_NOEXCEPT; //[t1]
118  inline const_iterator cend() const PQXX_NOEXCEPT;
119 
120  reference front() const PQXX_NOEXCEPT { return row(this,0); } //[t74]
121  reference back() const PQXX_NOEXCEPT {return row(this,size()-1);} //[t75]
122 
123  PQXX_PURE size_type size() const PQXX_NOEXCEPT; //[t2]
124  PQXX_PURE bool empty() const PQXX_NOEXCEPT; //[t11]
125  size_type capacity() const PQXX_NOEXCEPT { return size(); } //[t20]
126 
127  void swap(result &) PQXX_NOEXCEPT; //[t77]
128 
129  const row operator[](size_type i) const PQXX_NOEXCEPT //[t2]
130  { return row(this, i); }
131  const row at(size_type) const; //[t10]
132 
133  void clear() PQXX_NOEXCEPT { super::reset(); m_data = 0; } //[t20]
134 
139  PQXX_PURE row::size_type columns() const PQXX_NOEXCEPT; //[t11]
141 
143  row::size_type column_number(const char ColName[]) const; //[t11]
144 
146  row::size_type column_number(const std::string &Name) const //[t11]
147  {return column_number(Name.c_str());}
148 
150  const char *column_name(row::size_type Number) const; //[t11]
151 
153  oid column_type(row::size_type ColNum) const; //[t7]
155  oid column_type(int ColNum) const //[t7]
156  { return column_type(row::size_type(ColNum)); }
157 
159  oid column_type(const std::string &ColName) const //[t7]
160  { return column_type(column_number(ColName)); }
161 
163  oid column_type(const char ColName[]) const //[t7]
164  { return column_type(column_number(ColName)); }
165 
167  oid column_table(row::size_type ColNum) const; //[t2]
168 
170  oid column_table(int ColNum) const //[t2]
171  { return column_table(row::size_type(ColNum)); }
172 
174  oid column_table(const std::string &ColName) const //[t2]
175  { return column_table(column_number(ColName)); }
176 
178  row::size_type table_column(row::size_type ColNum) const; //[t93]
179 
181  row::size_type table_column(int ColNum) const //[t93]
182  { return table_column(row::size_type(ColNum)); }
183 
185  row::size_type table_column(const std::string &ColName) const //[t93]
186  { return table_column(column_number(ColName)); }
188 
190  PQXX_PURE const std::string &query() const PQXX_NOEXCEPT; //[t70]
191 
193 
196  PQXX_PURE oid inserted_oid() const; //[t13]
197 
199 
202  PQXX_PURE size_type affected_rows() const; //[t7]
203 
204 
205 private:
206  friend class pqxx::field;
207  PQXX_PURE const char *GetValue(size_type Row, row::size_type Col) const;
208  PQXX_PURE bool GetIsNull(size_type Row, row::size_type Col) const;
209  PQXX_PURE field::size_type GetLength(
210  size_type,
211  row::size_type) const PQXX_NOEXCEPT;
212 
213  friend class pqxx::internal::gate::result_creation;
214  result(internal::pq::PGresult *rhs,
215  int protocol,
216  const std::string &Query,
217  int encoding_code);
218  PQXX_PRIVATE void CheckStatus() const;
219 
220  friend class pqxx::internal::gate::result_connection;
221  bool operator!() const PQXX_NOEXCEPT { return !m_data; }
222  operator bool() const PQXX_NOEXCEPT { return m_data != 0; }
223 
224  PQXX_NORETURN PQXX_PRIVATE void ThrowSQLError(
225  const std::string &Err,
226  const std::string &Query) const;
227  PQXX_PRIVATE PQXX_PURE int errorposition() const PQXX_NOEXCEPT;
228  PQXX_PRIVATE std::string StatusError() const;
229 
230  friend class pqxx::internal::gate::result_sql_cursor;
231  PQXX_PURE const char *CmdStatus() const PQXX_NOEXCEPT;
232 
234  pqxx::internal::pq::PGresult *m_data;
235 
236  PQXX_PRIVATE static const std::string s_empty_string;
237 };
238 
239 
241 
245 class PQXX_LIBEXPORT const_result_iterator :
246  public std::iterator<
247  std::random_access_iterator_tag,
248  const row,
251  row>,
252  public row
253 {
254 public:
255  typedef const row *pointer;
256  typedef row reference;
259 
260  const_result_iterator() PQXX_NOEXCEPT : row(0,0) {}
261  const_result_iterator(const row &t) PQXX_NOEXCEPT : row(t) {}
262 
278  pointer operator->() const { return this; } //[t12]
279  reference operator*() const { return row(*this); } //[t12]
281 
286  const_result_iterator operator++(int); //[t12]
287  const_result_iterator &operator++() { ++m_Index; return *this; } //[t1]
288  const_result_iterator operator--(int); //[t12]
289  const_result_iterator &operator--() { --m_Index; return *this; } //[t12]
290 
291  const_result_iterator &operator+=(difference_type i) //[t12]
292  { m_Index = size_type(difference_type(m_Index) + i); return *this; }
293  const_result_iterator &operator-=(difference_type i) //[t12]
294  { m_Index = size_type(difference_type(m_Index) - i); return *this; }
296 
301  bool operator==(const const_result_iterator &i) const //[t12]
302  {return m_Index==i.m_Index;}
303  bool operator!=(const const_result_iterator &i) const //[t12]
304  {return m_Index!=i.m_Index;}
305  bool operator<(const const_result_iterator &i) const //[t12]
306  {return m_Index<i.m_Index;}
307  bool operator<=(const const_result_iterator &i) const //[t12]
308  {return m_Index<=i.m_Index;}
309  bool operator>(const const_result_iterator &i) const //[t12]
310  {return m_Index>i.m_Index;}
311  bool operator>=(const const_result_iterator &i) const //[t12]
312  {return m_Index>=i.m_Index;}
314 
319  inline const_result_iterator operator+(difference_type) const; //[t12]
320  friend const_result_iterator operator+( //[t12]
321  difference_type,
322  const_result_iterator);
323  inline const_result_iterator operator-(difference_type) const; //[t12]
324  inline difference_type operator-(const_result_iterator) const; //[t12]
326 
327 private:
328  friend class pqxx::result;
329  const_result_iterator(const pqxx::result *r, result::size_type i)
330  PQXX_NOEXCEPT :
331  row(r, i) {}
332 };
333 
334 
336 class PQXX_LIBEXPORT const_reverse_result_iterator :
337  private const_result_iterator
338 {
339 public:
342  using iterator_type::iterator_category;
345 #ifndef _MSC_VER
346  using iterator_type::value_type;
348 #else
349  // Workaround for Visual C++.NET 2003, which has access problems
350  typedef const row &reference;
351  typedef row value_type;
352 #endif
353 
355  const const_reverse_result_iterator &rhs) :
356  const_result_iterator(rhs) {}
358  const const_result_iterator &rhs) :
359  const_result_iterator(rhs) { super::operator--(); }
360 
361  PQXX_PURE const_result_iterator base() const PQXX_NOEXCEPT; //[t75]
362 
367  using const_result_iterator::operator->; //[t75]
368  using const_result_iterator::operator*; //[t75]
370 
375  const_reverse_result_iterator &operator=( //[t75]
377  { iterator_type::operator=(r); return *this; }
379  { iterator_type::operator--(); return *this; }
380  const_reverse_result_iterator operator++(int); //[t75]
382  { iterator_type::operator++(); return *this; }
383  const_reverse_result_iterator operator--(int); //[t75]
385  { iterator_type::operator-=(i); return *this; }
387  { iterator_type::operator+=(i); return *this; }
389 
395  { return const_reverse_result_iterator(base() - i); }
397  { return const_reverse_result_iterator(base() + i); }
399  const const_reverse_result_iterator &rhs) const
400  { return rhs.const_result_iterator::operator-(*this); }
402 
407  bool operator==( //[t75]
408  const const_reverse_result_iterator &rhs) const PQXX_NOEXCEPT
409  { return iterator_type::operator==(rhs); }
410  bool operator!=( //[t75]
411  const const_reverse_result_iterator &rhs) const PQXX_NOEXCEPT
412  { return !operator==(rhs); }
413 
414  bool operator<(const const_reverse_result_iterator &rhs) const //[t75]
415  { return iterator_type::operator>(rhs); }
416  bool operator<=(const const_reverse_result_iterator &rhs) const //[t75]
417  { return iterator_type::operator>=(rhs); }
418  bool operator>(const const_reverse_result_iterator &rhs) const //[t75]
419  { return iterator_type::operator<(rhs); }
420  bool operator>=(const const_reverse_result_iterator &rhs) const //[t75]
421  { return iterator_type::operator<=(rhs); }
423 };
424 
425 
426 
428 
448 template<typename CHAR>
449 inline std::basic_ostream<CHAR> &operator<<(
450  std::basic_ostream<CHAR> &S, const pqxx::field &F) //[t46]
451 {
452  S.write(F.c_str(), std::streamsize(F.size()));
453  return S;
454 }
455 
456 
458 template<typename T>
459 inline void from_string(const field &F, T &Obj) //[t46]
460  { from_string(F.c_str(), Obj, F.size()); }
461 
463 template<>
464 inline std::string to_string(const field &Obj) //[t74]
465  { return std::string(Obj.c_str(), Obj.size()); }
466 
467 
468 inline const_result_iterator
470 {
471  return const_result_iterator(
472  m_Home, size_type(result::difference_type(m_Index) + o));
473 }
474 
477  { return i + o; }
478 
479 inline const_result_iterator
481 {
482  return const_result_iterator(
483  m_Home,
485 }
486 
489  { return result::difference_type(num() - i.num()); }
490 
491 inline const_result_iterator result::end() const PQXX_NOEXCEPT
492  { return const_result_iterator(this, size()); }
493 
494 
495 inline const_result_iterator result::cend() const PQXX_NOEXCEPT
496  { return end(); }
497 
498 
502  { return const_reverse_result_iterator(i.base() - n); }
503 
504 } // namespace pqxx
505 
506 
507 #include "pqxx/compiler-internal-post.hxx"
508 
509 #endif
PQXX_PURE const_result_iterator base() const PQXX_NOEXCEPT
Definition: result.cxx:407
row_size_type size_type
Definition: row.hxx:55
bool operator>(const const_reverse_result_iterator &rhs) const
Definition: result.hxx:418
row::size_type table_column(const std::string &ColName) const
What column in its table did this column come from?
Definition: result.hxx:185
void clear() PQXX_NOEXCEPT
Definition: result.hxx:133
const_result_iterator super
Definition: result.hxx:340
oid column_type(const char ColName[]) const
Type of given column.
Definition: result.hxx:163
Reverse iterator for result. Use as result::const_reverse_iterator.
Definition: result.hxx:336
const_reverse_result_iterator(const const_reverse_result_iterator &rhs)
Definition: result.hxx:354
unsigned long size_type
Definition: result.hxx:85
const_reverse_iterator reverse_iterator
Definition: result.hxx:92
const_result_iterator iterator_type
Definition: result.hxx:341
difference_type operator-(const const_reverse_result_iterator &rhs) const
Definition: result.hxx:398
const char * c_str() const
Read as plain C string.
Definition: field.cxx:72
const_reverse_result_iterator operator+(difference_type i) const
Definition: result.hxx:394
const_result_iterator() PQXX_NOEXCEPT
Definition: result.hxx:260
const_reverse_result_iterator const_reverse_iterator
Definition: result.hxx:91
const_result_iterator operator+(result::difference_type o, const_result_iterator i)
Definition: result.hxx:476
const_iterator iterator
Definition: result.hxx:90
row reference
Definition: result.hxx:87
const_iterator end() const PQXX_NOEXCEPT
Definition: result.hxx:491
Reference to one row in a result.
Definition: row.hxx:52
oid column_table(const std::string &ColName) const
What table did this column come from?
Definition: result.hxx:174
const row * pointer
Definition: result.hxx:255
Reference to a field in a result set.
Definition: field.hxx:51
bool operator<=(const const_reverse_result_iterator &rhs) const
Definition: result.hxx:416
const_result_iterator operator+(difference_type) const
Definition: result.hxx:469
bool operator<=(const const_result_iterator &i) const
Definition: result.hxx:307
const_reverse_result_iterator(const const_result_iterator &rhs)
Definition: result.hxx:357
const_reverse_result_iterator & operator+=(difference_type i)
Definition: result.hxx:384
Iterator for rows in a result. Use as result::const_iterator.
Definition: result.hxx:245
signed long difference_type
Definition: result.hxx:86
result(const result &rhs) PQXX_NOEXCEPT
Definition: result.hxx:95
const_reverse_result_iterator operator++()
Definition: result.hxx:378
const_reverse_result_iterator & operator-=(difference_type i)
Definition: result.hxx:386
const_reverse_result_iterator & operator--()
Definition: result.hxx:381
Iterator for fields in a row. Use as row::const_iterator.
Definition: row.hxx:212
const_result_iterator & operator-=(difference_type i)
Definition: result.hxx:293
const_reverse_result_iterator operator-(difference_type i)
Definition: result.hxx:396
result & operator=(const result &rhs) PQXX_NOEXCEPT
Definition: result.hxx:98
oid column_type(const std::string &ColName) const
Type of given column.
Definition: result.hxx:159
const_iterator pointer
Definition: result.hxx:89
std::basic_ostream< CHAR > & operator<<(std::basic_ostream< CHAR > &S, const pqxx::field &F)
Write a result field to any type of stream.
Definition: result.hxx:449
const_result_iterator & operator++()
Definition: result.hxx:287
bool operator<(const const_result_iterator &i) const
Definition: result.hxx:305
bool operator>(const const_result_iterator &i) const
Definition: result.hxx:309
reference operator*() const
Definition: result.hxx:279
const_result_iterator(const row &t) PQXX_NOEXCEPT
Definition: result.hxx:261
const_result_iterator operator-(difference_type) const
Definition: result.hxx:480
size_t num() const
Definition: row.hxx:179
bool operator==(const const_reverse_result_iterator &rhs) const PQXX_NOEXCEPT
Definition: result.hxx:407
const_iterator cend() const PQXX_NOEXCEPT
Definition: result.hxx:495
const_result_iterator const_iterator
Definition: result.hxx:88
result::size_type size_type
Definition: result.hxx:257
bool operator==(const const_result_iterator &i) const
Definition: result.hxx:301
const_result_iterator & operator--()
Definition: result.hxx:289
reference back() const PQXX_NOEXCEPT
Definition: result.hxx:121
size_type size() const PQXX_NOEXCEPT
Return number of bytes taken up by the field&#39;s value.
Definition: field.cxx:84
result::difference_type difference_type
Definition: result.hxx:258
oid column_table(int ColNum) const
What table did this column come from?
Definition: result.hxx:170
const_result_iterator & operator+=(difference_type i)
Definition: result.hxx:291
pointer operator->() const
Definition: result.hxx:278
bool operator>=(const const_reverse_result_iterator &rhs) const
Definition: result.hxx:420
row::size_type table_column(int ColNum) const
What column in its table did this column come from?
Definition: result.hxx:181
result() PQXX_NOEXCEPT
Definition: result.hxx:94
Result set containing data returned by a query or command.
Definition: result.hxx:78
void from_string(const field &F, T &Obj)
Convert a field&#39;s string contents to another type.
Definition: result.hxx:459
oid column_type(int ColNum) const
Type of given column.
Definition: result.hxx:155
bool operator<(const const_reverse_result_iterator &rhs) const
Definition: result.hxx:414
bool operator!=(const const_reverse_result_iterator &rhs) const PQXX_NOEXCEPT
Definition: result.hxx:410
std::string to_string(const field &Obj)
Convert a field to a string.
Definition: result.hxx:464
bool operator>=(const const_result_iterator &i) const
Definition: result.hxx:311
row reference
Definition: result.hxx:256
bool operator!=(const const_result_iterator &i) const
Definition: result.hxx:303
Reference-counted smart pointer to libpq-allocated object.
Definition: util.hxx:551