libpqxx  4.0.1
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 tuples from a database query
9  * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/result instead.
10  *
11  * Copyright (c) 2001-2012, 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 #ifdef PQXX_HAVE_IOS
26 #include <ios>
27 #endif
28 
29 #include <stdexcept>
30 
31 #include "pqxx/internal/result_data.hxx"
32 
33 #include "pqxx/except"
34 #include "pqxx/field"
35 #include "pqxx/tuple"
36 #include "pqxx/util"
37 
38 /* Methods tested in eg. self-test program test001 are marked with "//[t1]"
39  */
40 
41 // TODO: Support SQL arrays
42 
43 namespace pqxx
44 {
45 namespace internal
46 {
47 namespace gate
48 {
49 class result_connection;
50 class result_creation;
51 class result_sql_cursor;
52 } // namespace internal::gate
53 } // namespace internal
54 
55 
56 class const_result_iterator;
57 class const_reverse_result_iterator;
58 
59 
61 
81 class PQXX_LIBEXPORT result :
82  private internal::PQAlloc<
83  const internal::result_data, internal::freemem_result_data>
84 {
85  typedef internal::PQAlloc<
86  const internal::result_data, internal::freemem_result_data> super;
87 public:
88  typedef unsigned long size_type;
89  typedef signed long difference_type;
92  typedef const_iterator pointer;
93  typedef const_iterator iterator;
95  typedef const_reverse_iterator reverse_iterator;
96 
98  typedef pqxx::tuple tuple;
101 
102  result() throw () : super(), m_data(0) {} //[t3]
103  result(const result &rhs) throw () : //[t1]
104  super(rhs), m_data(rhs.m_data) {}
105 
106  result &operator=(const result &rhs) throw () //[t10]
107  { super::operator=(rhs); m_data=rhs.m_data; return *this; }
108 
113  bool operator==(const result &) const throw (); //[t70]
114  bool operator!=(const result &rhs) const throw () //[t70]
115  { return !operator==(rhs); }
117 
118  const_reverse_iterator rbegin() const; //[t75]
119  const_reverse_iterator rend() const; //[t75]
120 
121  const_iterator begin() const throw (); //[t1]
122  inline const_iterator end() const throw (); //[t1]
123 
124  reference front() const throw () { return tuple(this,0); } //[t74]
125  reference back() const throw () {return tuple(this,size()-1);} //[t75]
126 
127  size_type PQXX_PURE size() const throw (); //[t2]
128  bool PQXX_PURE empty() const throw (); //[t11]
129  size_type capacity() const throw () { return size(); } //[t20]
130 
131  void swap(result &) throw (); //[t77]
132 
133  const tuple operator[](size_type i) const throw () //[t2]
134  { return tuple(this, i); }
135  const tuple at(size_type) const throw (range_error); //[t10]
136 
137  void clear() throw () { super::reset(); m_data = 0; } //[t20]
138 
143  tuple::size_type PQXX_PURE columns() const throw (); //[t11]
145 
147  tuple::size_type column_number(const char ColName[]) const; //[t11]
148 
150  tuple::size_type column_number(const PGSTD::string &Name) const //[t11]
151  {return column_number(Name.c_str());}
152 
154  const char *column_name(tuple::size_type Number) const; //[t11]
155 
157  oid column_type(tuple::size_type ColNum) const; //[t7]
159  oid column_type(int ColNum) const //[t7]
160  { return column_type(tuple::size_type(ColNum)); }
161 
163  oid column_type(const PGSTD::string &ColName) const //[t7]
164  { return column_type(column_number(ColName)); }
165 
167  oid column_type(const char ColName[]) const //[t7]
168  { return column_type(column_number(ColName)); }
169 
171  oid column_table(tuple::size_type ColNum) const; //[t2]
172 
174  oid column_table(int ColNum) const //[t2]
175  { return column_table(tuple::size_type(ColNum)); }
176 
178  oid column_table(const PGSTD::string &ColName) const //[t2]
179  { return column_table(column_number(ColName)); }
180 
182  tuple::size_type table_column(tuple::size_type ColNum) const; //[t93]
183 
185  tuple::size_type table_column(int ColNum) const //[t93]
186  { return table_column(tuple::size_type(ColNum)); }
187 
189  tuple::size_type table_column(const PGSTD::string &ColName) const //[t93]
190  { return table_column(column_number(ColName)); }
192 
194  const PGSTD::string & PQXX_PURE query() const throw (); //[t70]
195 
197 
200  oid PQXX_PURE inserted_oid() const; //[t13]
201 
203 
206  size_type PQXX_PURE affected_rows() const; //[t7]
207 
208 
209 private:
210  friend class pqxx::field;
211  const char * PQXX_PURE GetValue(size_type Row, tuple::size_type Col) const;
212  bool PQXX_PURE GetIsNull(size_type Row, tuple::size_type Col) const;
213  field::size_type PQXX_PURE GetLength(
214  size_type,
215  tuple::size_type) const throw ();
216 
217  friend class pqxx::internal::gate::result_creation;
218  result(internal::pq::PGresult *rhs,
219  int protocol,
220  const PGSTD::string &Query,
221  int encoding_code);
222  void PQXX_PRIVATE CheckStatus() const;
223 
224  friend class pqxx::internal::gate::result_connection;
225  bool operator!() const throw () { return !m_data; }
226  operator bool() const throw () { return m_data != 0; }
227 
228  void PQXX_PRIVATE PQXX_NORETURN ThrowSQLError(
229  const PGSTD::string &Err,
230  const PGSTD::string &Query) const;
231  int PQXX_PRIVATE PQXX_PURE errorposition() const throw ();
232  PGSTD::string PQXX_PRIVATE StatusError() const;
233 
234  friend class pqxx::internal::gate::result_sql_cursor;
235  const char * PQXX_PURE CmdStatus() const throw ();
236 
238  pqxx::internal::pq::PGresult *m_data;
239 
240  static const PGSTD::string PQXX_PRIVATE s_empty_string;
241 };
242 
243 
245 
249 class PQXX_LIBEXPORT const_result_iterator :
250  public PGSTD::iterator<
251  PGSTD::random_access_iterator_tag,
252  const tuple,
253  result::difference_type,
255  tuple>,
256  public tuple
257 {
258 public:
259  typedef const tuple *pointer;
260  typedef tuple reference;
263 
264  const_result_iterator() throw () : tuple(0,0) {}
265  const_result_iterator(const tuple &t) throw () : tuple(t) {}
266 
282  pointer operator->() const { return this; } //[t12]
283  reference operator*() const { return tuple(*this); } //[t12]
285 
290  const_result_iterator operator++(int); //[t12]
291  const_result_iterator &operator++() { ++m_Index; return *this; } //[t1]
292  const_result_iterator operator--(int); //[t12]
293  const_result_iterator &operator--() { --m_Index; return *this; } //[t12]
294 
295  const_result_iterator &operator+=(difference_type i) //[t12]
296  { m_Index = size_type(difference_type(m_Index) + i); return *this; }
297  const_result_iterator &operator-=(difference_type i) //[t12]
298  { m_Index = size_type(difference_type (m_Index) - i); return *this; }
300 
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;}
313  bool operator>(const const_result_iterator &i) const //[t12]
314  {return m_Index>i.m_Index;}
315  bool operator>=(const const_result_iterator &i) const //[t12]
316  {return m_Index>=i.m_Index;}
318 
323  inline const_result_iterator operator+(difference_type) const; //[t12]
324  friend const_result_iterator operator+( //[t12]
325  difference_type,
326  const_result_iterator);
327  inline const_result_iterator operator-(difference_type) const; //[t12]
328  inline difference_type operator-(const_result_iterator) const; //[t12]
330 
331 private:
332  friend class pqxx::result;
333  const_result_iterator(const pqxx::result *r, result::size_type i) throw () :
334  tuple(r, i) {}
335 };
336 
337 
339 class PQXX_LIBEXPORT const_reverse_result_iterator :
340  private const_result_iterator
341 {
342 public:
343  typedef const_result_iterator super;
344  typedef const_result_iterator iterator_type;
345  using iterator_type::iterator_category;
348 #ifndef _MSC_VER
349  using iterator_type::value_type;
351 #else
352  // Workaround for Visual C++.NET 2003, which has access problems
353  typedef const tuple &reference;
354  typedef tuple value_type;
355 #endif
356 
358  const const_reverse_result_iterator &rhs) :
359  const_result_iterator(rhs) {}
361  const const_result_iterator &rhs) :
362  const_result_iterator(rhs) { super::operator--(); }
363 
364  const_result_iterator PQXX_PURE base() const throw (); //[t75]
365 
370  using const_result_iterator::operator->; //[t75]
371  using const_result_iterator::operator*; //[t75]
373 
380  { iterator_type::operator=(r); return *this; }
382  { iterator_type::operator--(); return *this; }
383  const_reverse_result_iterator operator++(int); //[t75]
385  { iterator_type::operator++(); return *this; }
386  const_reverse_result_iterator operator--(int); //[t75]
387  const_reverse_result_iterator &operator+=(difference_type i) //[t75]
388  { iterator_type::operator-=(i); return *this; }
389  const_reverse_result_iterator &operator-=(difference_type i) //[t75]
390  { iterator_type::operator+=(i); return *this; }
392 
397  const_reverse_result_iterator operator+(difference_type i) const //[t75]
398  { return const_reverse_result_iterator(base() - i); }
399  const_reverse_result_iterator operator-(difference_type i) //[t75]
400  { return const_reverse_result_iterator(base() + i); }
401  difference_type operator-( //[t75]
402  const const_reverse_result_iterator &rhs) const
403  { return rhs.const_result_iterator::operator-(*this); }
405 
410  bool operator==( //[t75]
411  const const_reverse_result_iterator &rhs) const throw ()
412  { return iterator_type::operator==(rhs); }
413  bool operator!=( //[t75]
414  const const_reverse_result_iterator &rhs) const throw ()
415  { return !operator==(rhs); }
416 
417  bool operator<(const const_reverse_result_iterator &rhs) const //[t75]
418  { return iterator_type::operator>(rhs); }
419  bool operator<=(const const_reverse_result_iterator &rhs) const //[t75]
420  { return iterator_type::operator>=(rhs); }
421  bool operator>(const const_reverse_result_iterator &rhs) const //[t75]
422  { return iterator_type::operator<(rhs); }
423  bool operator>=(const const_reverse_result_iterator &rhs) const //[t75]
424  { return iterator_type::operator<=(rhs); }
426 };
427 
428 
429 
431 
451 template<typename CHAR>
452 inline PGSTD::basic_ostream<CHAR> &operator<<(
453  PGSTD::basic_ostream<CHAR> &S, const pqxx::field &F) //[t46]
454 {
455  S.write(F.c_str(), PGSTD::streamsize(F.size()));
456  return S;
457 }
458 
459 
461 template<typename T>
462 inline void from_string(const field &F, T &Obj) //[t46]
463  { from_string(F.c_str(), Obj, F.size()); }
464 
466 template<>
467 inline PGSTD::string to_string(const field &Obj) //[t74]
468  { return PGSTD::string(Obj.c_str(), Obj.size()); }
469 
470 
471 inline const_result_iterator
473 {
474  return const_result_iterator(
475  m_Home, size_type(result::difference_type(m_Index) + o));
476 }
477 
478 inline const_result_iterator
479 operator+(result::difference_type o, const_result_iterator i)
480  { return i + o; }
481 
482 inline const_result_iterator
484 {
485  return const_result_iterator(
486  m_Home,
488 }
489 
491 const_result_iterator::operator-(const_result_iterator i) const
492  { return result::difference_type(num() - i.num()); }
493 
494 inline const_result_iterator result::end() const throw ()
495  { return const_result_iterator(this, size()); }
496 
497 
501  { return const_reverse_result_iterator(i.base() - n); }
502 
503 } // namespace pqxx
504 
505 
506 #include "pqxx/compiler-internal-post.hxx"
507 
508 #endif
const_reverse_iterator reverse_iterator
Definition: result.hxx:95
const_result_iterator & operator+=(difference_type i)
Definition: result.hxx:295
result(const result &rhs)
Definition: result.hxx:103
oid column_type(const char ColName[]) const
Type of given column.
Definition: result.hxx:167
Iterator for rows (tuples) in a result. Use as result::const_iterator.
Definition: result.hxx:249
const_reverse_result_iterator & operator--()
Definition: result.hxx:384
pqxx::field field
For backward compatibility only.
Definition: result.hxx:100
tuple_size_type size_type
Definition: tuple.hxx:55
const_reverse_result_iterator operator+(difference_type i) const
Definition: result.hxx:397
Reference to a field in a result set.
Definition: field.hxx:43
const_result_iterator iterator_type
Definition: result.hxx:344
signed long difference_type
Definition: result.hxx:89
tuple::size_type table_column(int ColNum) const
What column in its table did this column come from?
Definition: result.hxx:185
const_iterator iterator
Definition: result.hxx:93
const_reverse_result_iterator(const const_result_iterator &rhs)
Definition: result.hxx:360
const_result_iterator super
Definition: result.hxx:343
result()
Definition: result.hxx:102
tuple reference
Definition: result.hxx:260
tuple::size_type column_number(const std::string &Name) const
Number of given column (throws exception if it doesn&#39;t exist)
Definition: result.hxx:150
reference back() const
Definition: result.hxx:125
difference_type operator-(const const_reverse_result_iterator &rhs) const
Definition: result.hxx:401
const_result_iterator()
Definition: result.hxx:264
bool operator>=(const const_reverse_result_iterator &rhs) const
Definition: result.hxx:423
Something is out of range, similar to std::out_of_range.
Definition: except.hxx:203
pqxx::tuple tuple
For backward compatibility only.
Definition: result.hxx:98
const_reverse_result_iterator const_reverse_iterator
Definition: result.hxx:94
Result set containing data returned by a query or command.
Definition: result.hxx:81
tuple::size_type table_column(const std::string &ColName) const
What column in its table did this column come from?
Definition: result.hxx:189
void from_string(const field &F, T &Obj)
Convert a field&#39;s string contents to another type.
Definition: result.hxx:462
size_type size() const
Definition: field.cxx:86
bool operator==(const const_reverse_result_iterator &rhs) const
Definition: result.hxx:410
bool operator<=(const const_result_iterator &i) const
Definition: result.hxx:311
bool operator<(const const_result_iterator &i) const
Definition: result.hxx:309
Reference-counted smart pointer to libpq-allocated object.
Definition: util.hxx:559
Reference to one row in a result.
Definition: tuple.hxx:52
size_type capacity() const
Definition: result.hxx:129
const_result_iterator const_iterator
Definition: result.hxx:91
reference operator*() const
Definition: result.hxx:283
const_result_iterator(const tuple &t)
Definition: result.hxx:265
const_result_iterator PQXX_PURE base() const
Definition: result.cxx:386
const_result_iterator operator+(difference_type) const
Definition: result.hxx:472
const char * c_str() const
Read as plain C string.
Definition: field.cxx:74
const_result_iterator & operator-=(difference_type i)
Definition: result.hxx:297
unsigned long size_type
Definition: result.hxx:88
bool operator==(const const_result_iterator &i) const
Definition: result.hxx:305
bool operator!=(const const_reverse_result_iterator &rhs) const
Definition: result.hxx:413
const tuple * pointer
Definition: result.hxx:259
const tuple operator[](size_type i) const
Definition: result.hxx:133
bool operator>(const const_result_iterator &i) const
Definition: result.hxx:313
bool operator>(const const_reverse_result_iterator &rhs) const
Definition: result.hxx:421
The home of all libpqxx classes, functions, templates, etc.
Definition: basic_connection.hxx:35
size_t size_type
Definition: field.hxx:46
const_reverse_result_iterator operator++()
Definition: result.hxx:381
const_reverse_result_iterator & operator-=(difference_type i)
Definition: result.hxx:389
const_reverse_result_iterator & operator+=(difference_type i)
Definition: result.hxx:387
const_result_iterator & operator++()
Definition: result.hxx:291
oid column_type(int ColNum) const
Type of given column.
Definition: result.hxx:159
const_iterator pointer
Definition: result.hxx:92
std::string to_string(const field &Obj)
Convert a field to a string.
Definition: result.hxx:467
oid column_table(const std::string &ColName) const
What table did this column come from?
Definition: result.hxx:178
bool operator!=(const result &rhs) const
Definition: result.hxx:114
result::difference_type difference_type
Definition: result.hxx:262
bool operator!=(const const_result_iterator &i) const
Definition: result.hxx:307
result & operator=(const result &rhs)
Definition: result.hxx:106
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:452
reference front() const
Definition: result.hxx:124
const_result_iterator & operator--()
Definition: result.hxx:293
size_t num() const
Definition: tuple.hxx:166
const_result_iterator operator+(result::difference_type o, const_result_iterator i)
Definition: result.hxx:479
void clear()
Definition: result.hxx:137
Reverse iterator for result. Use as result::const_reverse_iterator.
Definition: result.hxx:339
pointer operator->() const
Definition: result.hxx:282
const_reverse_result_iterator(const const_reverse_result_iterator &rhs)
Definition: result.hxx:357
oid column_table(int ColNum) const
What table did this column come from?
Definition: result.hxx:174
const_result_iterator operator-(difference_type) const
Definition: result.hxx:483
bool operator>=(const const_result_iterator &i) const
Definition: result.hxx:315
const_iterator end() const
Definition: result.hxx:494
oid column_type(const std::string &ColName) const
Type of given column.
Definition: result.hxx:163
const_reverse_result_iterator operator-(difference_type i)
Definition: result.hxx:399
pqxx::tuple reference
Definition: result.hxx:90
bool operator<=(const const_reverse_result_iterator &rhs) const
Definition: result.hxx:419
const_reverse_result_iterator & operator=(const const_reverse_result_iterator &r)
Definition: result.hxx:378
result::size_type size_type
Definition: result.hxx:261
bool operator<(const const_reverse_result_iterator &rhs) const
Definition: result.hxx:417