cursor.hxx
/*-------------------------------------------------------------------------
*
* FILE
* pqxx/cursor.hxx
*
* DESCRIPTION
* definition of the iterator/container-style cursor classes
* C++-style wrappers for SQL cursors
* DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/cursor instead.
*
* Copyright (c) 2004-2011, Jeroen T. Vermeulen <jtv@xs4all.nl>
*
* See COPYING for copyright license. If you did not receive a file called
* COPYING with this source code, please notify the distributor of this mistake,
* or contact the author.
*
*-------------------------------------------------------------------------
*/
#ifndef PQXX_H_CURSOR
#define PQXX_H_CURSOR
#include "pqxx/compiler-public.hxx"
#include "pqxx/compiler-internal-pre.hxx"
#include <stdexcept>
#ifdef PQXX_HAVE_LIMITS
#include <limits>
#endif
#include "pqxx/result"
#include "pqxx/transaction_base"
namespace pqxx
{
class dbtransaction;
class PQXX_LIBEXPORT cursor_base
{
public:
typedef result::size_type size_type;
typedef result::difference_type difference_type;
enum accesspolicy
{
forward_only,
random_access
};
enum updatepolicy
{
read_only,
update
};
enum ownershippolicy
{
owned,
loose
};
static difference_type all() throw (); //[t81]
static difference_type next() throw () { return 1; } //[t81]
static difference_type prior() throw () { return -1; } //[t0]
static difference_type backward_all() throw (); //[t0]
const PGSTD::string &name() const throw () { return m_name; } //[t81]
protected:
cursor_base(connection_base &,
const PGSTD::string &Name,
bool embellish_name=true);
const PGSTD::string m_name;
private:
cursor_base();
cursor_base(const cursor_base &);
cursor_base &operator=(const cursor_base &);
};
inline cursor_base::difference_type cursor_base::all() throw ()
{
#ifdef PQXX_HAVE_LIMITS
return PGSTD::numeric_limits<int>::max()-1;
#else
return INT_MAX-1;
#endif
}
inline cursor_base::difference_type cursor_base::backward_all() throw ()
{
#ifdef PQXX_HAVE_LIMITS
return PGSTD::numeric_limits<int>::min()+1;
#else
return INT_MIN+1;
#endif
}
namespace internal
{
class PQXX_LIBEXPORT sql_cursor : public cursor_base
{
public:
sql_cursor(transaction_base &t,
const PGSTD::string &query,
const PGSTD::string &cname,
cursor_base::accesspolicy ap,
cursor_base::updatepolicy up,
cursor_base::ownershippolicy op,
bool hold);
sql_cursor(transaction_base &t,
const PGSTD::string &cname,
cursor_base::ownershippolicy op);
~sql_cursor() throw () { close(); }
result fetch(difference_type rows, difference_type &displacement);
result fetch(difference_type rows)
{ difference_type d=0; return fetch(rows, d); }
difference_type move(difference_type rows, difference_type &displacement);
difference_type move(difference_type rows)
{ difference_type d=0; return move(rows, d); }
difference_type pos() const throw () { return m_pos; }
difference_type endpos() const throw () { return m_endpos; }
const result &empty_result() const throw () { return m_empty_result; }
void close() throw ();
private:
difference_type adjust(difference_type hoped, difference_type actual);
static PGSTD::string stridestring(difference_type);
void init_empty_result(transaction_base &);
connection_base &m_home;
result m_empty_result;
result m_cached_current_row;
bool m_adopted;
cursor_base::ownershippolicy m_ownership;
int m_at_end;
difference_type m_pos;
difference_type m_endpos;
};
result::size_type PQXX_LIBEXPORT obtain_stateless_cursor_size(sql_cursor &);
result PQXX_LIBEXPORT stateless_cursor_retrieve(
sql_cursor &,
result::difference_type size,
result::difference_type begin_pos,
result::difference_type end_pos);
} // namespace internal
template<cursor_base::updatepolicy up, cursor_base::ownershippolicy op>
class stateless_cursor
{
public:
typedef result::size_type size_type;
typedef result::difference_type difference_type;
stateless_cursor(
transaction_base &trans,
const PGSTD::string &query,
const PGSTD::string &cname,
bool hold) :
m_cur(trans, query, cname, cursor_base::random_access, up, op, hold)
{
}
stateless_cursor(
transaction_base &trans,
const PGSTD::string adopted_cursor) :
m_cur(trans, adopted_cursor, op)
{
// Put cursor in known position
m_cur.move(cursor_base::backward_all());
}
void close() throw () { m_cur.close(); }
size_type size() { return internal::obtain_stateless_cursor_size(m_cur); }
result retrieve(difference_type begin_pos, difference_type end_pos)
{
return internal::stateless_cursor_retrieve(
m_cur,
result::difference_type(size()),
begin_pos,
end_pos);
}
const PGSTD::string &name() const throw () { return m_cur.name(); }
private:
internal::sql_cursor m_cur;
};
class icursor_iterator;
namespace internal
{
namespace gate
{
class icursor_iterator_icursorstream;
class icursorstream_icursor_iterator;
} // namespace internal::gate
} // namespace internal
class PQXX_LIBEXPORT icursorstream
{
public:
typedef cursor_base::size_type size_type;
typedef cursor_base::difference_type difference_type;
icursorstream(transaction_base &context,
const PGSTD::string &query,
const PGSTD::string &basename,
difference_type sstride=1); //[t81]
icursorstream(transaction_base &context,
const field &cname,
difference_type sstride=1,
cursor_base::ownershippolicy op=cursor_base::owned); //[t84]
operator bool() const throw () { return !m_done; }
icursorstream &get(result &res) { res = fetchblock(); return *this; } //[t81]
icursorstream &operator>>(result &res) { return get(res); } //[t81]
icursorstream &ignore(PGSTD::streamsize n=1); //[t81]
void set_stride(difference_type stride); //[t81]
difference_type stride() const throw () { return m_stride; } //[t81]
private:
result fetchblock();
friend class internal::gate::icursorstream_icursor_iterator;
size_type forward(size_type n=1);
void insert_iterator(icursor_iterator *) throw ();
void remove_iterator(icursor_iterator *) const throw ();
void service_iterators(difference_type);
internal::sql_cursor m_cur;
difference_type m_stride;
difference_type m_realpos, m_reqpos;
mutable icursor_iterator *m_iterators;
bool m_done;
};
class PQXX_LIBEXPORT icursor_iterator :
public PGSTD::iterator<PGSTD::input_iterator_tag,
result,
cursor_base::size_type,
const result *,
const result &>
{
public:
typedef icursorstream istream_type;
typedef istream_type::size_type size_type;
typedef istream_type::difference_type difference_type;
icursor_iterator() throw (); //[t84]
explicit icursor_iterator(istream_type &) throw (); //[t84]
icursor_iterator(const icursor_iterator &) throw (); //[t84]
~icursor_iterator() throw ();
const result &operator*() const { refresh(); return m_here; } //[t84]
const result *operator->() const { refresh(); return &m_here; } //[t84]
icursor_iterator &operator++(); //[t84]
icursor_iterator operator++(int); //[t84]
icursor_iterator &operator+=(difference_type); //[t84]
icursor_iterator &operator=(const icursor_iterator &) throw (); //[t84]
bool operator==(const icursor_iterator &rhs) const; //[t84]
bool operator!=(const icursor_iterator &rhs) const throw () //[t84]
{ return !operator==(rhs); }
bool operator<(const icursor_iterator &rhs) const; //[t84]
bool operator>(const icursor_iterator &rhs) const //[t84]
{ return rhs < *this; }
bool operator<=(const icursor_iterator &rhs) const //[t84]
{ return !(*this > rhs); }
bool operator>=(const icursor_iterator &rhs) const //[t84]
{ return !(*this < rhs); }
private:
void refresh() const;
friend class internal::gate::icursor_iterator_icursorstream;
difference_type pos() const throw () { return m_pos; }
void fill(const result &);
icursorstream *m_stream;
result m_here;
difference_type m_pos;
icursor_iterator *m_prev, *m_next;
};
} // namespace pqxx
#include "pqxx/compiler-internal-post.hxx"
#endif
pqxx::result
Result set containing data returned by a query or command.
Definition: result.hxx:81
pqxx::connection_base
connection_base abstract base class; represents a connection to a database.
Definition: connection_base.hxx:151
pqxx::field
Reference to a field in a result set.
Definition: field.hxx:43
pqxx::cursor_base::ownershippolicy
ownershippolicy
Cursor destruction policy.
Definition: cursor.hxx:101
pqxx::icursor_iterator::size_type
istream_type::size_type size_type
Definition: cursor.hxx:524
pqxx::stateless_cursor::retrieve
result retrieve(difference_type begin_pos, difference_type end_pos)
Retrieve rows from begin_pos (inclusive) to end_pos (exclusive)
Definition: cursor.hxx:336
pqxx::internal::sql_cursor::empty_result
const result & empty_result() const
Return zero-row result for this cursor.
Definition: cursor.hxx:237
pqxx::cursor_base::accesspolicy
accesspolicy
Cursor access-pattern policy.
Definition: cursor.hxx:62
pqxx::stateless_cursor
"Stateless cursor" class: easy API for retrieving parts of result sets
Definition: cursor.hxx:290
pqxx::icursor_iterator::operator<=
bool operator<=(const icursor_iterator &rhs) const
Definition: cursor.hxx:545
pqxx::icursorstream::size_type
cursor_base::size_type size_type
Definition: cursor.hxx:384
pqxx::cursor_base::backward_all
static difference_type backward_all()
Special value: read backwards from current position back to origin.
Definition: cursor.hxx:167
pqxx::internal::sql_cursor::pos
difference_type pos() const
Current position, or -1 for unknown.
Definition: cursor.hxx:225
pqxx::icursorstream::stride
difference_type stride() const
Definition: cursor.hxx:465
pqxx::stateless_cursor::close
void close()
Definition: cursor.hxx:316
pqxx::icursor_iterator::operator>=
bool operator>=(const icursor_iterator &rhs) const
Definition: cursor.hxx:547
pqxx::internal::sql_cursor::endpos
difference_type endpos() const
End position, or -1 for unknown.
Definition: cursor.hxx:234
pqxx::cursor_base::name
const std::string & name() const
Name of underlying SQL cursor.
Definition: cursor.hxx:139
pqxx::icursorstream::operator>>
icursorstream & operator>>(result &res)
Read new value into given result object; same as get(result &)
Definition: cursor.hxx:451
pqxx::icursor_iterator::operator!=
bool operator!=(const icursor_iterator &rhs) const
Definition: cursor.hxx:540
pqxx::stateless_cursor::size
size_type size()
Number of rows in cursor&#39;s result set.
Definition: cursor.hxx:322
pqxx::icursor_iterator::difference_type
istream_type::difference_type difference_type
Definition: cursor.hxx:525
pqxx::icursorstream::difference_type
cursor_base::difference_type difference_type
Definition: cursor.hxx:385
pqxx::cursor_base::all
static difference_type all()
Special value: read until end.
Definition: cursor.hxx:158
pqxx::internal::sql_cursor::move
difference_type move(difference_type rows)
Definition: cursor.hxx:215
pqxx::icursor_iterator::operator>
bool operator>(const icursor_iterator &rhs) const
Definition: cursor.hxx:543
pqxx::cursor_base::size_type
result::size_type size_type
Definition: cursor.hxx:55
pqxx::cursor_base::prior
static difference_type prior()
Special value: read backwards, one row only.
Definition: cursor.hxx:125
pqxx::cursor_base::updatepolicy
updatepolicy
Cursor update policy.
Definition: cursor.hxx:74
pqxx::internal::stateless_cursor_retrieve
result stateless_cursor_retrieve(sql_cursor &, result::difference_type size, result::difference_type begin_pos, result::difference_type end_pos)
Definition: cursor.cxx:319
pqxx::stateless_cursor::size_type
result::size_type size_type
Definition: cursor.hxx:293
pqxx::cursor_base::difference_type
result::difference_type difference_type
Definition: cursor.hxx:56
pqxx::stateless_cursor::stateless_cursor
stateless_cursor(transaction_base &trans, const std::string adopted_cursor)
Adopt existing scrolling SQL cursor.
Definition: cursor.hxx:307
pqxx::cursor_base::read_only
Cursor can be used to read data but not to write.
Definition: cursor.hxx:77
pqxx::internal::sql_cursor::~sql_cursor
~sql_cursor()
Definition: cursor.hxx:209
pqxx::icursor_iterator
Approximate istream_iterator for icursorstream.
Definition: cursor.hxx:515
pqxx::internal::sql_cursor
Cursor with SQL positioning semantics.
Definition: cursor.hxx:194
pqxx::stateless_cursor::difference_type
result::difference_type difference_type
Definition: cursor.hxx:294
pqxx::cursor_base::m_name
const std::string m_name
Definition: cursor.hxx:146
pqxx::stateless_cursor::name
const std::string & name() const
Definition: cursor.hxx:345
pqxx::internal::sql_cursor::fetch
result fetch(difference_type rows)
Definition: cursor.hxx:212
pqxx::result::difference_type
signed long difference_type
Definition: result.hxx:89
pqxx::cursor_base::forward_only
Cursor can move forward only.
Definition: cursor.hxx:65
pqxx::icursor_iterator::istream_type
icursorstream istream_type
Definition: cursor.hxx:523
pqxx::result::size_type
unsigned long size_type
Definition: result.hxx:88
pqxx::icursor_iterator::operator->
const result * operator->() const
Definition: cursor.hxx:533
pqxx
The home of all libpqxx classes, functions, templates, etc.
Definition: basic_connection.hxx:35
pqxx::transaction_base
Definition: transaction_base.hxx:133
pqxx::stateless_cursor::stateless_cursor
stateless_cursor(transaction_base &trans, const std::string &query, const std::string &cname, bool hold)
Create cursor.
Definition: cursor.hxx:297
pqxx::cursor_base::owned
Destroy SQL cursor when cursor object is closed at end of transaction.
Definition: cursor.hxx:104
pqxx::internal::obtain_stateless_cursor_size
result::size_type obtain_stateless_cursor_size(sql_cursor &)
Definition: cursor.cxx:312
pqxx::icursorstream
Simple read-only cursor represented as a stream of results.
Definition: cursor.hxx:381
pqxx::cursor_base
Common definitions for cursor types.
Definition: cursor.hxx:52