Loading...
Searching...
No Matches
cursor.hxx
/* 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) 2000-2024, Jeroen T. Vermeulen.
*
* 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
#if !defined(PQXX_HEADER_PRE)
# error "Include libpqxx headers as <pqxx/header>, not <pqxx/header.hxx>."
#endif
#include <limits>
#include <stdexcept>
#include "pqxx/result.hxx"
#include "pqxx/transaction_base.hxx"
namespace pqxx
{
class PQXX_LIBEXPORT cursor_base
{
public:
using size_type = result_size_type;
using difference_type = result_difference_type;
enum access_policy
{
forward_only,
random_access
};
enum update_policy
{
read_only,
update
};
enum ownership_policy
{
owned,
loose
};
cursor_base() = delete;
cursor_base(cursor_base const &) = delete;
cursor_base &operator=(cursor_base const &) = delete;
[[nodiscard]] static constexpr difference_type all() noexcept
{
return (std::numeric_limits<int>::max)() - 1;
}
[[nodiscard]] static constexpr difference_type next() noexcept { return 1; }
[[nodiscard]] static constexpr difference_type prior() noexcept
{
return -1;
}
[[nodiscard]] static constexpr difference_type backward_all() noexcept
{
return (std::numeric_limits<int>::min)() + 1;
}
[[nodiscard]] constexpr std::string const &name() const noexcept
{
return m_name;
}
protected:
cursor_base(connection &, std::string_view Name, bool embellish_name = true);
std::string const m_name;
};
} // namespace pqxx
#include <pqxx/internal/sql_cursor.hxx>
namespace pqxx
{
template<cursor_base::update_policy up, cursor_base::ownership_policy op>
class stateless_cursor
{
public:
using size_type = result_size_type;
using difference_type = result_difference_type;
stateless_cursor(
transaction_base &tx, std::string_view query, std::string_view cname,
bool hold) :
m_cur{tx, query, cname, cursor_base::random_access, up, op, hold}
{}
stateless_cursor(transaction_base &tx, std::string_view adopted_cursor) :
m_cur{tx, adopted_cursor, op}
{
// Put cursor in known position
m_cur.move(cursor_base::backward_all());
}
void close() noexcept { m_cur.close(); }
[[nodiscard]] 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);
}
[[nodiscard]] constexpr std::string const &name() const noexcept
{
return m_cur.name();
}
private:
internal::sql_cursor m_cur;
};
class icursor_iterator;
} // namespace pqxx
namespace pqxx::internal::gate
{
class icursor_iterator_icursorstream;
class icursorstream_icursor_iterator;
} // namespace pqxx::internal::gate
namespace pqxx
{
class PQXX_LIBEXPORT icursorstream
{
public:
using size_type = cursor_base::size_type;
using difference_type = cursor_base::difference_type;
icursorstream(
transaction_base &context, std::string_view query,
std::string_view basename, difference_type sstride = 1);
icursorstream(
transaction_base &context, field const &cname, difference_type sstride = 1,
cursor_base::ownership_policy op = cursor_base::owned);
constexpr operator bool() const & noexcept { return not m_done; }
icursorstream &get(result &res)
{
res = fetchblock();
return *this;
}
icursorstream &operator>>(result &res) { return get(res); }
icursorstream &ignore(std::streamsize n = 1) &;
void set_stride(difference_type stride) &;
[[nodiscard]] constexpr difference_type stride() const noexcept
{
return m_stride;
}
private:
result fetchblock();
friend class internal::gate::icursorstream_icursor_iterator;
size_type forward(size_type n = 1);
void insert_iterator(icursor_iterator *) noexcept;
void remove_iterator(icursor_iterator *) const noexcept;
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:
using iterator_category = std::input_iterator_tag;
using value_type = result;
using pointer = result const *;
using reference = result const &;
using istream_type = icursorstream;
using size_type = istream_type::size_type;
using difference_type = istream_type::difference_type;
icursor_iterator() noexcept;
explicit icursor_iterator(istream_type &) noexcept;
icursor_iterator(icursor_iterator const &) noexcept;
~icursor_iterator() noexcept;
result const &operator*() const
{
refresh();
return m_here;
}
result const *operator->() const
{
refresh();
return &m_here;
}
icursor_iterator &operator++();
icursor_iterator operator++(int) &;
icursor_iterator &operator+=(difference_type);
icursor_iterator &operator=(icursor_iterator const &) noexcept;
[[nodiscard]] bool operator==(icursor_iterator const &rhs) const;
[[nodiscard]] bool operator!=(icursor_iterator const &rhs) const noexcept
{
return not operator==(rhs);
}
[[nodiscard]] bool operator<(icursor_iterator const &rhs) const;
[[nodiscard]] bool operator>(icursor_iterator const &rhs) const
{
return rhs < *this;
}
[[nodiscard]] bool operator<=(icursor_iterator const &rhs) const
{
return not(*this > rhs);
}
[[nodiscard]] bool operator>=(icursor_iterator const &rhs) const
{
return not(*this < rhs);
}
private:
void refresh() const;
friend class internal::gate::icursor_iterator_icursorstream;
difference_type pos() const noexcept { return m_pos; }
void fill(result const &);
icursorstream *m_stream{nullptr};
result m_here;
difference_type m_pos;
icursor_iterator *m_prev{nullptr}, *m_next{nullptr};
};
} // namespace pqxx
#endif
pqxx::internal::gate::icursor_iterator_icursorstream
Definition icursor_iterator-icursorstream.hxx:6
pqxx::internal::gate::icursorstream_icursor_iterator
Definition icursorstream-icursor_iterator.hxx:6
pqxx::internal::sql_cursor
Cursor with SQL positioning semantics.
Definition sql_cursor.hxx:32
pqxx::result
Result set containing data returned by a query or command.
Definition result.hxx:92
pqxx::stateless_cursor::name
constexpr std::string const & name() const noexcept
Return this cursor's name.
Definition cursor.hxx:239
pqxx::stateless_cursor::close
void close() noexcept
Close this cursor.
Definition cursor.hxx:209
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:232
pqxx::stateless_cursor::stateless_cursor
stateless_cursor(transaction_base &tx, std::string_view query, std::string_view cname, bool hold)
Create cursor.
Definition cursor.hxx:183
pqxx::stateless_cursor::size
size_type size()
Number of rows in cursor's result set.
Definition cursor.hxx:215
pqxx::stateless_cursor::stateless_cursor
stateless_cursor(transaction_base &tx, std::string_view adopted_cursor)
Adopt an existing scrolling SQL cursor.
Definition cursor.hxx:196
pqxx
The home of all libpqxx classes, functions, templates, etc.
Definition array.cxx:27
pqxx::result_size_type
int result_size_type
Number of rows in a result set.
Definition types.hxx:28
pqxx::value_type
strip_t< decltype(*std::begin(std::declval< CONTAINER >()))> value_type
The type of a container's elements.
Definition types.hxx:96
pqxx::result_difference_type
int result_difference_type
Difference between result sizes.
Definition types.hxx:31