libpqxx 4.0
|
Let's say you have a result object. For example, your program may have done:
pqxx::result r = w.exec("SELECT * FROM mytable");
Now how do you access the data inside r
?
The simplest way is array indexing. A result acts as an array of tuples, and a tuple acts as an array of fields.
for (int rownum=0; rownum < r.size(); ++rownum) { const result::tuple row = r[rownum]; for (int colnum=0; colnum < row.size(); ++colnum) { const result::field = row[colnum]; std::cout << field.c_str() << '\t'; } std::cout << std::endl; }
But results and rows also define const_iterator
types:
for (pqxx::result::const_iterator row = r.begin(); row != r.end(); ++row) { for (pqxx::result::tuple::const_iterator field = row->begin(); field != row->end(); ++field) std::cout << field->c_str() << '\t'; std::cout << std::endl; }
They also have const_reverse_iterator
types, which iterate backwards from rbegin()
to rend()
exclusive.
All these iterator types provide one extra bit of convenience that you won't normally find in C++ iterators: referential transparency. You don't need to dereference them to get to the row or field they refer to. That is, instead of row->end()
you can also choose to say row.end()
. Similarly, you may prefer field.c_str()
over field->c_str()
.
This becomes really helpful with the array-indexing operator. With regular C++ iterators you would need ugly expressions like (*row)[0] or
row->operator[](0)
. With the iterator types defined by the result and tuple classes you can simply say row
[0].