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;
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 
144  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,
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 
378  const_reverse_result_iterator &operator=( //[t75]
380  { iterator_type::operator=(r); return *this; }
381  const_reverse_result_iterator operator++() //[t75]
382  { iterator_type::operator--(); return *this; }
383  const_reverse_result_iterator operator++(int); //[t75]
384  const_reverse_result_iterator &operator--() //[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