libpqxx
field.hxx
1 
13 #ifndef PQXX_H_FIELD
14 #define PQXX_H_FIELD
15 
16 #include "pqxx/compiler-public.hxx"
17 #include "pqxx/compiler-internal-pre.hxx"
18 #include "pqxx/internal/type_utils.hxx"
19 
20 #if defined(PQXX_HAVE_OPTIONAL)
21 #include <optional>
22 
23 /* Use std::experimental::optional as a fallback for std::optional, if
24  * present.
25  *
26  * This may break compilation for some software, if using a libpqxx that was
27  * configured for a different language version. To stop libpqxx headers from
28  * using or supporting std::experimental::optional, define a macro
29  * PQXX_HIDE_EXP_OPTIONAL when building your software.
30  */
31 #elif defined(PQXX_HAVE_EXP_OPTIONAL) && !defined(PQXX_HIDE_EXP_OPTIONAL)
32 #include <experimental/optional>
33 #endif
34 
35 #include "pqxx/array.hxx"
36 #include "pqxx/result.hxx"
37 #include "pqxx/strconv.hxx"
38 #include "pqxx/types.hxx"
39 
40 
41 // Methods tested in eg. test module test01 are marked with "//[t01]".
42 
43 namespace pqxx
44 {
46 
49 class PQXX_LIBEXPORT field
50 {
51 public:
53 
55 
59  field(const row &R, row_size_type C) noexcept; //[t01]
60 
65 
82  bool operator==(const field &) const; //[t75]
83 
85 
87  bool operator!=(const field &rhs) const //[t82]
88  {return not operator==(rhs);}
90 
95  const char *name() const; //[t11]
97 
99  oid type() const; //[t07]
100 
102  oid table() const; //[t02]
103 
104  row_size_type num() const { return col(); } //[t82]
105 
107  row_size_type table_column() const; //[t93]
109 
114 
120  const char *c_str() const; //[t02]
121 
123  bool is_null() const noexcept; //[t12]
124 
126 
129  size_type size() const noexcept; //[t11]
130 
132 
135  template<typename T> auto to(T &Obj) const //[t03]
136  -> typename std::enable_if<(
137  not std::is_pointer<T>::value
138  or std::is_same<T, const char*>::value
139  ), bool>::type
140  {
141  const char *const bytes = c_str();
142  if (bytes[0] == '\0' and is_null()) return false;
143  from_string(bytes, Obj);
144  return true;
145  }
146 
148  template<typename T> bool operator>>(T &Obj) const //[t07]
149  { return to(Obj); }
150 
152 
155  template<typename T> auto to(T &Obj, const T &Default) const //[t12]
156  -> typename std::enable_if<(
157  not std::is_pointer<T>::value
158  or std::is_same<T, const char*>::value
159  ), bool>::type
160  {
161  const bool NotNull = to(Obj);
162  if (not NotNull) Obj = Default;
163  return NotNull;
164  }
165 
167 
170  template<typename T> T as(const T &Default) const //[t01]
171  {
172  T Obj;
173  to(Obj, Default);
174  return Obj;
175  }
176 
178 
183  template<typename T> T as() const //[t45]
184  {
185  T Obj;
186  if (not to(Obj)) Obj = string_traits<T>::null();
187  return Obj;
188  }
189 
191 
195  template<typename T, template<typename> class O
196 #if defined(PQXX_HAVE_OPTIONAL)
197  = std::optional
198 #elif defined(PQXX_HAVE_EXP_OPTIONAL) && !defined(PQXX_HIDE_EXP_OPTIONAL)
199  = std::experimental::optional
200 #endif
201  > constexpr O<T> get() const { return as<O<T>>(); }
202 
204 
211  { return array_parser{c_str(), m_home.m_encoding}; }
213 
214 
215 protected:
216  const result &home() const noexcept { return m_home; }
217  size_t idx() const noexcept { return m_row; }
218  row_size_type col() const noexcept { return row_size_type(m_col); }
219 
224  long m_col;
225 
226 private:
227  result m_home;
228  size_t m_row;
229 };
230 
231 
233 template<>
234 inline bool field::to<std::string>(std::string &Obj) const
235 {
236  const char *const bytes = c_str();
237  if (bytes[0] == '\0' and is_null()) return false;
238  Obj = std::string{bytes, size()};
239  return true;
240 }
241 
243 
248 template<>
249 inline bool field::to<const char *>(const char *&Obj) const
250 {
251  if (is_null()) return false;
252  Obj = c_str();
253  return true;
254 }
255 
256 
257 template<typename CHAR=char, typename TRAITS=std::char_traits<CHAR>>
259  public std::basic_streambuf<CHAR, TRAITS>
260 {
261 public:
262  using char_type = CHAR;
263  using traits_type = TRAITS;
264  using int_type = typename traits_type::int_type;
265  using pos_type = typename traits_type::pos_type;
266  using off_type = typename traits_type::off_type;
267  using openmode = std::ios::openmode;
268  using seekdir = std::ios::seekdir;
269 
270  explicit field_streambuf(const field &F) : //[t74]
271  m_field{F}
272  {
273  initialize();
274  }
275 
276 protected:
277  virtual int sync() override { return traits_type::eof(); }
278 
279 protected:
281  { return traits_type::eof(); }
282  virtual pos_type seekpos(pos_type, openmode) override
283  {return traits_type::eof();}
284  virtual int_type overflow(int_type) override
285  { return traits_type::eof(); }
286  virtual int_type underflow() override
287  { return traits_type::eof(); }
288 
289 private:
290  const field &m_field;
291 
292  int_type initialize()
293  {
294  char_type *G =
295  reinterpret_cast<char_type *>(const_cast<char *>(m_field.c_str()));
296  this->setg(G, G, G + m_field.size());
297  return int_type(m_field.size());
298  }
299 };
300 
301 
303 
311 template<typename CHAR=char, typename TRAITS=std::char_traits<CHAR>>
313  public std::basic_istream<CHAR, TRAITS>
314 {
315  using super = std::basic_istream<CHAR, TRAITS>;
316 
317 public:
318  using char_type = CHAR;
319  using traits_type = TRAITS;
320  using int_type = typename traits_type::int_type;
321  using pos_type = typename traits_type::pos_type;
322  using off_type = typename traits_type::off_type;
323 
324  basic_fieldstream(const field &F) : super{nullptr}, m_buf{F}
325  { super::init(&m_buf); }
326 
327 private:
329 };
330 
332 
334 
354 template<typename CHAR>
355 inline std::basic_ostream<CHAR> &operator<<(
356  std::basic_ostream<CHAR> &S, const field &F) //[t46]
357 {
358  S.write(F.c_str(), std::streamsize(F.size()));
359  return S;
360 }
361 
362 
364 template<typename T>
365 inline void from_string(const field &F, T &Obj) //[t46]
366  { from_string(F.c_str(), Obj, F.size()); }
367 
369 template<> PQXX_LIBEXPORT std::string to_string(const field &Obj); //[t74]
370 
371 } // namespace pqxx
372 #include "pqxx/compiler-internal-post.hxx"
373 #endif
typename traits_type::pos_type pos_type
Definition: field.hxx:265
void from_string(const field &F, T &Obj)
Convert a field&#39;s string contents to another type.
Definition: field.hxx:365
std::ios::seekdir seekdir
Definition: field.hxx:268
T as(const T &Default) const
Return value as object of given type, or Default if null.
Definition: field.hxx:170
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
virtual int_type overflow(int_type) override
Definition: field.hxx:284
Input stream that gets its data from a result field.
Definition: field.hxx:312
bool operator!=(const field &rhs) const
Byte-by-byte comparison (all nulls are considered equal)
Definition: field.hxx:87
array_parser as_array() const
Parse the field as an SQL array.
Definition: field.hxx:210
typename traits_type::pos_type pos_type
Definition: field.hxx:321
bool operator>>(T &Obj) const
Read value into Obj; or leave Obj untouched and return false if null.
Definition: field.hxx:148
unsigned int row_size_type
Number of fields in a row of database data.
Definition: types.hxx:24
Result set containing data returned by a query or command.
Definition: result.hxx:69
std::string to_string(const field &Obj)
Convert a field to a string.
Definition: result.cxx:451
size_t idx() const noexcept
Definition: field.hxx:217
Traits class for use in string conversions.
Definition: strconv.hxx:51
CHAR char_type
Definition: field.hxx:318
Reference to one row in a result.
Definition: row.hxx:40
field_size_type size_type
Definition: field.hxx:52
std::size_t field_size_type
Number of bytes in a field of database data.
Definition: types.hxx:30
Definition: field.hxx:258
typename traits_type::int_type int_type
Definition: field.hxx:264
TRAITS traits_type
Definition: field.hxx:263
typename traits_type::off_type off_type
Definition: field.hxx:322
auto to(T &Obj) 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 leave Obj untouched and return false if null.
Definition: field.hxx:135
long m_col
Definition: field.hxx:224
row_size_type col() const noexcept
Definition: field.hxx:218
basic_fieldstream(const field &F)
Definition: field.hxx:324
Reference to a field in a result set.
Definition: field.hxx:49
const result & home() const noexcept
Definition: field.hxx:216
size_type size() const noexcept
Return number of bytes taken up by the field&#39;s value.
Definition: field.cxx:74
std::ios::openmode openmode
Definition: field.hxx:267
typename traits_type::off_type off_type
Definition: field.hxx:266
const char * c_str() const
Read as plain C string.
Definition: field.cxx:62
field_streambuf(const field &F)
Definition: field.hxx:270
TRAITS traits_type
Definition: field.hxx:319
T as() const
Return value as object of given type, or throw exception if null.
Definition: field.hxx:183
virtual pos_type seekpos(pos_type, openmode) override
Definition: field.hxx:282
Low-level array parser.
Definition: array.hxx:46
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
row_size_type num() const
Definition: field.hxx:104
The home of all libpqxx classes, functions, templates, etc.
Definition: array.hxx:25
virtual pos_type seekoff(off_type, seekdir, openmode) override
Definition: field.hxx:280
CHAR char_type
Definition: field.hxx:262
virtual int sync() override
Definition: field.hxx:277
virtual int_type underflow() override
Definition: field.hxx:286