field.hxx
#ifndef PQXX_H_FIELD
#define PQXX_H_FIELD
#include "pqxx/compiler-public.hxx"
#include "pqxx/compiler-internal-pre.hxx"
#include "pqxx/internal/type_utils.hxx"
#if defined(PQXX_HAVE_OPTIONAL)
#include <optional>
/* Use std::experimental::optional as a fallback for std::optional, if
* present.
*
* This may break compilation for some software, if using a libpqxx that was
* configured for a different language version. To stop libpqxx headers from
* using or supporting std::experimental::optional, define a macro
* PQXX_HIDE_EXP_OPTIONAL when building your software.
*/
#elif defined(PQXX_HAVE_EXP_OPTIONAL) && !defined(PQXX_HIDE_EXP_OPTIONAL)
#include <experimental/optional>
#endif
#include "pqxx/array.hxx"
#include "pqxx/result.hxx"
#include "pqxx/strconv.hxx"
#include "pqxx/types.hxx"
// Methods tested in eg. test module test01 are marked with "//[t01]".
namespace pqxx
{
class PQXX_LIBEXPORT field
{
public:
using size_type = field_size_type;
field(const row &R, row_size_type C) noexcept; //[t01]
bool operator==(const field &) const; //[t75]
bool operator!=(const field &rhs) const //[t82]
{return not operator==(rhs);}
const char *name() const; //[t11]
oid type() const; //[t07]
oid table() const; //[t02]
row_size_type num() const { return col(); } //[t82]
row_size_type table_column() const; //[t93]
const char *c_str() const; //[t02]
bool is_null() const noexcept; //[t12]
size_type size() const noexcept; //[t11]
template<typename T> auto to(T &Obj) const //[t03]
-> typename std::enable_if<(
not std::is_pointer<T>::value
or std::is_same<T, const char*>::value
), bool>::type
{
const char *const bytes = c_str();
if (bytes[0] == '\0' and is_null()) return false;
from_string(bytes, Obj);
return true;
}
template<typename T> bool operator>>(T &Obj) const //[t07]
{ return to(Obj); }
template<typename T> auto to(T &Obj, const T &Default) const //[t12]
-> typename std::enable_if<(
not std::is_pointer<T>::value
or std::is_same<T, const char*>::value
), bool>::type
{
const bool NotNull = to(Obj);
if (not NotNull) Obj = Default;
return NotNull;
}
template<typename T> T as(const T &Default) const //[t01]
{
T Obj;
to(Obj, Default);
return Obj;
}
template<typename T> T as() const //[t45]
{
T Obj;
if (not to(Obj)) Obj = string_traits<T>::null();
return Obj;
}
template<typename T, template<typename> class O
#if defined(PQXX_HAVE_OPTIONAL)
= std::optional
#elif defined(PQXX_HAVE_EXP_OPTIONAL) && !defined(PQXX_HIDE_EXP_OPTIONAL)
= std::experimental::optional
#endif
> constexpr O<T> get() const { return as<O<T>>(); }
array_parser as_array() const
{ return array_parser{c_str(), m_home.m_encoding}; }
protected:
const result &home() const noexcept { return m_home; }
size_t idx() const noexcept { return m_row; }
row_size_type col() const noexcept { return row_size_type(m_col); }
long m_col;
private:
result m_home;
size_t m_row;
};
template<>
inline bool field::to<std::string>(std::string &Obj) const
{
const char *const bytes = c_str();
if (bytes[0] == '\0' and is_null()) return false;
Obj = std::string{bytes, size()};
return true;
}
template<>
inline bool field::to<const char *>(const char *&Obj) const
{
if (is_null()) return false;
Obj = c_str();
return true;
}
template<typename CHAR=char, typename TRAITS=std::char_traits<CHAR>>
class field_streambuf :
public std::basic_streambuf<CHAR, TRAITS>
{
public:
using char_type = CHAR;
using traits_type = TRAITS;
using int_type = typename traits_type::int_type;
using pos_type = typename traits_type::pos_type;
using off_type = typename traits_type::off_type;
using openmode = std::ios::openmode;
using seekdir = std::ios::seekdir;
explicit field_streambuf(const field &F) : //[t74]
m_field{F}
{
initialize();
}
protected:
virtual int sync() override { return traits_type::eof(); }
protected:
virtual pos_type seekoff(off_type, seekdir, openmode) override
{ return traits_type::eof(); }
virtual pos_type seekpos(pos_type, openmode) override
{return traits_type::eof();}
virtual int_type overflow(int_type) override
{ return traits_type::eof(); }
virtual int_type underflow() override
{ return traits_type::eof(); }
private:
const field &m_field;
int_type initialize()
{
char_type *G =
reinterpret_cast<char_type *>(const_cast<char *>(m_field.c_str()));
this->setg(G, G, G + m_field.size());
return int_type(m_field.size());
}
};
template<typename CHAR=char, typename TRAITS=std::char_traits<CHAR>>
class basic_fieldstream :
public std::basic_istream<CHAR, TRAITS>
{
using super = std::basic_istream<CHAR, TRAITS>;
public:
using char_type = CHAR;
using traits_type = TRAITS;
using int_type = typename traits_type::int_type;
using pos_type = typename traits_type::pos_type;
using off_type = typename traits_type::off_type;
basic_fieldstream(const field &F) : super{nullptr}, m_buf{F}
{ super::init(&m_buf); }
private:
field_streambuf<CHAR, TRAITS> m_buf;
};
using fieldstream = basic_fieldstream<char>;
template<typename CHAR>
inline std::basic_ostream<CHAR> &operator<<(
std::basic_ostream<CHAR> &S, const field &F) //[t46]
{
S.write(F.c_str(), std::streamsize(F.size()));
return S;
}
template<typename T>
inline void from_string(const field &F, T &Obj) //[t46]
{ from_string(F.c_str(), Obj, F.size()); }
template<> PQXX_LIBEXPORT std::string to_string(const field &Obj); //[t74]
} // namespace pqxx
#include "pqxx/compiler-internal-post.hxx"
#endif
pqxx::basic_fieldstream::pos_type
typename traits_type::pos_type pos_type
Definition: field.hxx:321
pqxx::field::col
row_size_type col() const noexcept
Definition: field.hxx:218
pqxx::field_streambuf::field_streambuf
field_streambuf(const field &F)
Definition: field.hxx:270
pqxx::field::size_type
field_size_type size_type
Definition: field.hxx:52
pqxx::operator<<
std::basic_ostream< CHAR > & operator<<(std::basic_ostream< CHAR > &S, const field &F)
Write a result field to any type of stream.
Definition: field.hxx:355
pqxx::field::operator==
bool operator==(const field &) const
Byte-by-byte comparison of two fields (all nulls are considered equal)
Definition: field.cxx:28
pqxx::array_parser
Low-level array parser.
Definition: array.hxx:46
pqxx::field_streambuf::seekoff
virtual pos_type seekoff(off_type, seekdir, openmode) override
Definition: field.hxx:280
pqxx::field_streambuf< char, std::char_traits< char > >::openmode
std::ios::openmode openmode
Definition: field.hxx:267
pqxx::field::table
oid table() const
What table did this column come from?
Definition: field.cxx:50
pqxx::field::as_array
array_parser as_array() const
Parse the field as an SQL array.
Definition: field.hxx:210
pqxx::field_streambuf::sync
virtual int sync() override
Definition: field.hxx:277
pqxx::result
Result set containing data returned by a query or command.
Definition: result.hxx:69
pqxx::field::field
field(const row &R, row_size_type C) noexcept
Constructor.
Definition: field.cxx:20
pqxx::field::get
constexpr O< T > get() const
Return value wrapped in some optional type (empty for nulls)
Definition: field.hxx:201
pqxx::row_size_type
unsigned int row_size_type
Number of fields in a row of database data.
Definition: types.hxx:24
pqxx::from_string
void from_string(const field &F, T &Obj)
Convert a field's string contents to another type.
Definition: field.hxx:365
pqxx::field_streambuf< char, std::char_traits< char > >::char_type
char char_type
Definition: field.hxx:262
pqxx::field::m_col
long m_col
Definition: field.hxx:224
pqxx::field
Reference to a field in a result set.
Definition: field.hxx:49
pqxx::field_streambuf< char, std::char_traits< char > >::seekdir
std::ios::seekdir seekdir
Definition: field.hxx:268
pqxx::basic_fieldstream::traits_type
TRAITS traits_type
Definition: field.hxx:319
pqxx::field::num
row_size_type num() const
Definition: field.hxx:104
pqxx::field_streambuf< char, std::char_traits< char > >::int_type
typename traits_type::int_type int_type
Definition: field.hxx:264
pqxx::field::is_null
bool is_null() const noexcept
Is this field's value null?
Definition: field.cxx:68
pqxx::field::type
oid type() const
Column type.
Definition: field.cxx:44
pqxx::field_streambuf::underflow
virtual int_type underflow() override
Definition: field.hxx:286
pqxx::field_streambuf::seekpos
virtual pos_type seekpos(pos_type, openmode) override
Definition: field.hxx:282
pqxx::field::home
const result & home() const noexcept
Definition: field.hxx:216
pqxx::field::as
T as(const T &Default) const
Return value as object of given type, or Default if null.
Definition: field.hxx:170
pqxx::field::to
auto to(T &Obj, const T &Default) const -> typename std::enable_if<(not std::is_pointer< T >::value or std::is_same< T, const char * >::value), bool >::type
Read value into Obj; or use Default & return false if null.
Definition: field.hxx:155
pqxx::basic_fieldstream::char_type
CHAR char_type
Definition: field.hxx:318
pqxx::field::name
const char * name() const
Column name.
Definition: field.cxx:38
pqxx::field::operator!=
bool operator!=(const field &rhs) const
Byte-by-byte comparison (all nulls are considered equal)
Definition: field.hxx:87
pqxx::basic_fieldstream
Input stream that gets its data from a result field.
Definition: field.hxx:312
pqxx::result_size_type
unsigned long result_size_type
Number of rows in a result set.
Definition: types.hxx:18
pqxx::field::idx
size_t idx() const noexcept
Definition: field.hxx:217
pqxx::field::size
size_type size() const noexcept
Return number of bytes taken up by the field's value.
Definition: field.cxx:74
pqxx::field::table_column
row_size_type table_column() const
What column number in its originating table did this column come from?
Definition: field.cxx:56
pqxx::basic_fieldstream::basic_fieldstream
basic_fieldstream(const field &F)
Definition: field.hxx:324
pqxx::field_streambuf< char, std::char_traits< char > >::pos_type
typename traits_type::pos_type pos_type
Definition: field.hxx:265
pqxx::to_string
std::string to_string(const field &Obj)
Convert a field to a string.
Definition: result.cxx:451
pqxx::field_streambuf
Definition: field.hxx:258
pqxx::field_size_type
std::size_t field_size_type
Number of bytes in a field of database data.
Definition: types.hxx:30
pqxx::field_streambuf< char, std::char_traits< char > >::traits_type
std::char_traits< char > traits_type
Definition: field.hxx:263
pqxx::string_traits
Traits class for use in string conversions.
Definition: strconv.hxx:51
pqxx::field_streambuf< char, std::char_traits< char > >::off_type
typename traits_type::off_type off_type
Definition: field.hxx:266
pqxx
The home of all libpqxx classes, functions, templates, etc.
Definition: array.hxx:25
pqxx::row
Reference to one row in a result.
Definition: row.hxx:40
pqxx::row::size_type
row_size_type size_type
Definition: row.hxx:43
pqxx::field::as
T as() const
Return value as object of given type, or throw exception if null.
Definition: field.hxx:183
pqxx::basic_fieldstream::int_type
typename traits_type::int_type int_type
Definition: field.hxx:320
pqxx::field::operator>>
bool operator>>(T &Obj) const
Read value into Obj; or leave Obj untouched and return false if null.
Definition: field.hxx:148
pqxx::field::c_str
const char * c_str() const
Read as plain C string.
Definition: field.cxx:62
pqxx::basic_fieldstream::off_type
typename traits_type::off_type off_type
Definition: field.hxx:322
pqxx::field_streambuf::overflow
virtual int_type overflow(int_type) override
Definition: field.hxx:284