libpqxx: result.hxx Source File

libpqxx 4.0.1

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes

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;
90 typedef pqxx::tuple reference;
91 typedef const_result_iterator const_iterator;
92 typedef const_iterator pointer;
93 typedef const_iterator iterator;
94 typedef const_reverse_result_iterator const_reverse_iterator;
95 typedef const_reverse_iterator reverse_iterator;
96
98 typedef pqxx::tuple tuple;
100 typedef pqxx::field field;
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,
253 result::difference_type,
254 const_result_iterator,
255 tuple>,
256 public tuple
257 {
258 public:
259 typedef const tuple *pointer;
260 typedef tuple reference;
261 typedef result::size_type size_type;
262 typedef result::difference_type difference_type;
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;
346 using iterator_type::difference_type;
347 using iterator_type::pointer;
348 #ifndef _MSC_VER
349 using iterator_type::value_type;
350 using iterator_type::reference;
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
357 const_reverse_result_iterator( //[t75]
358 const const_reverse_result_iterator &rhs) :
359 const_result_iterator(rhs) {}
360 explicit const_reverse_result_iterator( //[t75]
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]
379 const const_reverse_result_iterator &r)
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
472 const_result_iterator::operator+(result::difference_type o) const
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
483 const_result_iterator::operator-(result::difference_type o) const
484 {
485 return const_result_iterator(
486 m_Home,
487 result::size_type(result::difference_type(m_Index) - o));
488 }
489
490 inline result::difference_type
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
498 inline const_reverse_result_iterator
499 operator+(result::difference_type n,
500 const const_reverse_result_iterator &i)
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