stream_from.hxx
#ifndef PQXX_H_STREAM_FROM
#define PQXX_H_STREAM_FROM
#include "pqxx/compiler-public.hxx"
#include "pqxx/compiler-internal-pre.hxx"
#include "pqxx/transaction_base.hxx"
#include "pqxx/stream_base.hxx"
#include "pqxx/internal/type_utils.hxx"
#include <string>
namespace pqxx
{
class PQXX_LIBEXPORT stream_from : public stream_base
{
public:
stream_from(
transaction_base &,
const std::string &table_name
);
template<typename Columns> stream_from(
transaction_base &,
const std::string &table_name,
const Columns& columns
);
template<typename Iter> stream_from(
transaction_base &,
const std::string &table_name,
Iter columns_begin,
Iter columns_end
);
~stream_from() noexcept;
void complete() override;
bool get_raw_line(std::string &);
template<typename Tuple> stream_from & operator>>(Tuple &);
private:
internal::encoding_group m_copy_encoding;
std::string m_current_line;
bool m_retry_line;
void set_up(transaction_base &, const std::string &table_name);
void set_up(
transaction_base &,
const std::string &table_name,
const std::string &columns
);
void close() override;
bool extract_field(
const std::string &,
std::string::size_type &,
std::string &
) const;
template<typename Tuple, std::size_t I> auto tokenize_ith(
const std::string &,
Tuple &,
std::string::size_type,
std::string &
) const -> typename std::enable_if<(
std::tuple_size<Tuple>::value > I
)>::type;
template<typename Tuple, std::size_t I> auto tokenize_ith(
const std::string &,
Tuple &,
std::string::size_type,
std::string &
) const -> typename std::enable_if<(
std::tuple_size<Tuple>::value <= I
)>::type;
template<typename T> void extract_value(
const std::string &line,
T& t,
std::string::size_type &here,
std::string &workspace
) const;
};
template<typename Columns> stream_from::stream_from(
transaction_base &tb,
const std::string &table_name,
const Columns& columns
) : stream_from{
tb,
table_name,
std::begin(columns),
std::end(columns)
} {}
template<typename Iter> stream_from::stream_from(
transaction_base &tb,
const std::string &table_name,
Iter columns_begin,
Iter columns_end
) :
namedclass{"stream_from", table_name},
stream_base{tb}
{
set_up(
tb,
table_name,
columnlist(columns_begin, columns_end)
);
}
template<typename Tuple> stream_from & stream_from::operator>>(
Tuple &t
)
{
if (m_retry_line or get_raw_line(m_current_line))
{
std::string workspace;
try
{
tokenize_ith<Tuple, 0>(m_current_line, t, 0, workspace);
m_retry_line = false;
}
catch (...)
{
m_retry_line = true;
throw;
}
}
return *this;
}
template<typename Tuple, std::size_t I> auto stream_from::tokenize_ith(
const std::string &line,
Tuple &t,
std::string::size_type here,
std::string &workspace
) const -> typename std::enable_if<(
std::tuple_size<Tuple>::value > I
)>::type
{
if (here >= line.size())
throw usage_error{"Too few fields to extract from stream_from line."};
extract_value(line, std::get<I>(t), here, workspace);
tokenize_ith<Tuple, I+1>(line, t, here, workspace);
}
template<typename Tuple, std::size_t I> auto stream_from::tokenize_ith(
const std::string &line,
Tuple & /* t */,
std::string::size_type here,
std::string & /* workspace */
) const -> typename std::enable_if<(
std::tuple_size<Tuple>::value <= I
)>::type
{
// Zero-column line may still have a trailing newline
if (
here < line.size() and
not (here == line.size() - 1 and line[here] == '\n'))
throw usage_error{"Not all fields extracted from stream_from line"};
}
template<typename T> void stream_from::extract_value(
const std::string &line,
T& t,
std::string::size_type &here,
std::string &workspace
) const
{
if (extract_field(line, here, workspace))
from_string<T>(workspace, t);
else
t = internal::null_value<T>();
}
template<> void stream_from::extract_value<std::nullptr_t>(
const std::string &line,
std::nullptr_t&,
std::string::size_type &here,
std::string &workspace
) const;
} // namespace pqxx
#include "pqxx/compiler-internal-post.hxx"
#endif
pqxx::stream_from::operator>>
stream_from & operator>>(Tuple &)
Definition: stream_from.hxx:130
pqxx::conversion_error
Value conversion failed, e.g. when converting "Hello" to int.
Definition: except.hxx:240
pqxx::internal
Private namespace for libpqxx's internal use; do not access.
Definition: connection_base.hxx:43
pqxx::stream_from::~stream_from
~stream_from() noexcept
Definition: stream_from.cxx:53
pqxx::stream_base::close
virtual void close()
Definition: stream_base.cxx:36
pqxx::stream_from::get_raw_line
bool get_raw_line(std::string &)
Definition: stream_from.cxx:72
pqxx::stream_from
Efficiently pull data directly out of a table.
Definition: stream_from.hxx:29
pqxx::internal::enc_group
encoding_group enc_group(int libpq_enc_id)
Definition: encodings.cxx:637
pqxx::internal::get_glyph_scanner
glyph_scanner_func * get_glyph_scanner(encoding_group enc)
Definition: encodings.cxx:738
pqxx::internal::find_with_encoding
std::string::size_type find_with_encoding(encoding_group enc, const std::string &haystack, char needle, std::string::size_type start)
Definition: encodings.cxx:790
pqxx::transaction_base
Interface definition (and common code) for "transaction" classes.
Definition: transaction_base.hxx:136
pqxx
The home of all libpqxx classes, functions, templates, etc.
Definition: array.hxx:25
pqxx::usage_error
Error in usage of libpqxx library, similar to std::logic_error.
Definition: except.hxx:218
pqxx::stream_from::stream_from
stream_from(transaction_base &, const std::string &table_name)
Definition: stream_from.cxx:41
pqxx::stream_from::complete
void complete() override
Definition: stream_from.cxx:66
pqxx::stream_base
Definition: stream_base.hxx:27