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 
19 #if defined(PQXX_HAVE_OPTIONAL)
20 #include <optional>
21 #endif
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 #if 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 !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  template<typename T> bool to(T &Obj) const //[t03]
133  {
134  const char *const bytes = c_str();
135  if (!bytes[0] && is_null()) return false;
136  from_string(bytes, Obj);
137  return true;
138  }
139 
141  template<typename T> bool operator>>(T &Obj) const //[t07]
142  { return to(Obj); }
143 
145  template<typename T> bool to(T &Obj, const T &Default) const //[t12]
146  {
147  const bool NotNull = to(Obj);
148  if (!NotNull) Obj = Default;
149  return NotNull;
150  }
151 
153 
156  template<typename T> T as(const T &Default) const //[t01]
157  {
158  T Obj;
159  to(Obj, Default);
160  return Obj;
161  }
162 
164  template<typename T> T as() const //[t45]
165  {
166  T Obj;
167  const bool NotNull = to(Obj);
168  if (!NotNull) Obj = string_traits<T>::null();
169  return Obj;
170  }
171 
172 #if defined(PQXX_HAVE_OPTIONAL)
173  template<typename T> std::optional<T> get() const
175  { return get_opt<T, std::optional<T>>(); }
176 #elif defined(PQXX_HAVE_EXP_OPTIONAL) && !defined(PQXX_HIDE_EXP_OPTIONAL)
177  template<typename T> std::experimental::optional<T> get() const
179  { return get_opt<T, std::experimental::optional<T>>(); }
180 #endif
181 
183 
189  array_parser as_array() const { return array_parser(c_str()); }
191 
192 
193 protected:
194  const result &home() const noexcept { return m_home; }
195  size_t idx() const noexcept { return m_row; }
196  row_size_type col() const noexcept { return row_size_type(m_col); }
197 
202  long m_col;
203 
204 private:
206 
211  template<typename T, typename OPTIONAL_T> OPTIONAL_T get_opt() const
212  {
213  if (is_null()) return OPTIONAL_T();
214  else return OPTIONAL_T(as<T>());
215  }
216 
217  result m_home;
218  size_t m_row;
219 };
220 
221 
223 template<>
224 inline bool field::to<std::string>(std::string &Obj) const
225 {
226  const char *const bytes = c_str();
227  if (!bytes[0] && is_null()) return false;
228  Obj = std::string(bytes, size());
229  return true;
230 }
231 
233 
238 template<>
239 inline bool field::to<const char *>(const char *&Obj) const
240 {
241  if (is_null()) return false;
242  Obj = c_str();
243  return true;
244 }
245 
246 
247 template<typename CHAR=char, typename TRAITS=std::char_traits<CHAR>>
249  public std::basic_streambuf<CHAR, TRAITS>
250 {
251 public:
252  using char_type = CHAR;
253  using traits_type = TRAITS;
254  using int_type = typename traits_type::int_type;
255  using pos_type = typename traits_type::pos_type;
256  using off_type = typename traits_type::off_type;
257  using openmode = std::ios::openmode;
258  using seekdir = std::ios::seekdir;
259 
260  explicit field_streambuf(const field &F) : //[t74]
261  m_field(F)
262  {
263  initialize();
264  }
265 
266 protected:
267  virtual int sync() override { return traits_type::eof(); }
268 
269 protected:
271  { return traits_type::eof(); }
272  virtual pos_type seekpos(pos_type, openmode) override
273  {return traits_type::eof();}
274  virtual int_type overflow(int_type) override
275  { return traits_type::eof(); }
276  virtual int_type underflow() override
277  { return traits_type::eof(); }
278 
279 private:
280  const field &m_field;
281 
282  int_type initialize()
283  {
284  char_type *G =
285  reinterpret_cast<char_type *>(const_cast<char *>(m_field.c_str()));
286  this->setg(G, G, G + m_field.size());
287  return int_type(m_field.size());
288  }
289 };
290 
291 
293 
301 template<typename CHAR=char, typename TRAITS=std::char_traits<CHAR>>
303  public std::basic_istream<CHAR, TRAITS>
304 {
305  using super = std::basic_istream<CHAR, TRAITS>;
306 
307 public:
308  using char_type = CHAR;
309  using traits_type = TRAITS;
310  using int_type = typename traits_type::int_type;
311  using pos_type = typename traits_type::pos_type;
312  using off_type = typename traits_type::off_type;
313 
314  basic_fieldstream(const field &F) : super(nullptr), m_buf(F)
315  { super::init(&m_buf); }
316 
317 private:
319 };
320 
322 
324 
344 template<typename CHAR>
345 inline std::basic_ostream<CHAR> &operator<<(
346  std::basic_ostream<CHAR> &S, const field &F) //[t46]
347 {
348  S.write(F.c_str(), std::streamsize(F.size()));
349  return S;
350 }
351 
352 
354 template<typename T>
355 inline void from_string(const field &F, T &Obj) //[t46]
356  { from_string(F.c_str(), Obj, F.size()); }
357 
359 template<> PQXX_LIBEXPORT std::string to_string(const field &Obj); //[t74]
360 
361 } // namespace pqxx
362 #include "pqxx/compiler-internal-post.hxx"
363 #endif
TRAITS traits_type
Definition: field.hxx:253
size_t idx() const noexcept
Definition: field.hxx:195
bool to(T &Obj, const T &Default) const
Read value into Obj; or use Default & return false if null.
Definition: field.hxx:145
T as() const
Return value as object of given type, or throw exception if null.
Definition: field.hxx:164
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:65
field_streambuf(const field &F)
Definition: field.hxx:260
row_size_type col() const noexcept
Definition: field.hxx:196
typename traits_type::int_type int_type
Definition: field.hxx:254
CHAR char_type
Definition: field.hxx:308
const result & home() const noexcept
Definition: field.hxx:194
std::ios::openmode openmode
Definition: field.hxx:257
TRAITS traits_type
Definition: field.hxx:309
std::string to_string(const field &Obj)
Convert a field to a string.
Definition: result.cxx:434
Reference to one row in a result.
Definition: row.hxx:40
void from_string(const field &F, T &Obj)
Convert a field&#39;s string contents to another type.
Definition: field.hxx:355
typename traits_type::off_type off_type
Definition: field.hxx:312
std::ios::seekdir seekdir
Definition: field.hxx:258
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:345
virtual pos_type seekoff(off_type, seekdir, openmode) override
Definition: field.hxx:270
size_type size() const noexcept
Return number of bytes taken up by the field&#39;s value.
Definition: field.cxx:74
Input stream that gets its data from a result field.
Definition: field.hxx:302
virtual pos_type seekpos(pos_type, openmode) override
Definition: field.hxx:272
const char * c_str() const
Read as plain C string.
Definition: field.cxx:62
field_size_type size_type
Definition: field.hxx:52
row_size_type num() const
Definition: field.hxx:104
T as(const T &Default) const
Return value as object of given type, or Default if null.
Definition: field.hxx:156
The home of all libpqxx classes, functions, templates, etc.
Definition: array.hxx:22
basic_fieldstream(const field &F)
Definition: field.hxx:314
std::size_t field_size_type
Number of bytes in a field of database data.
Definition: types.hxx:30
typename traits_type::pos_type pos_type
Definition: field.hxx:255
long m_col
Definition: field.hxx:202
Definition: field.hxx:248
bool operator>>(T &Obj) const
Read value into Obj; or leave Obj untouched and return false if null.
Definition: field.hxx:141
bool operator!=(const field &rhs) const
Byte-by-byte comparison (all nulls are considered equal)
Definition: field.hxx:87
typename traits_type::off_type off_type
Definition: field.hxx:256
Reference to a field in a result set.
Definition: field.hxx:49
virtual int_type overflow(int_type) override
Definition: field.hxx:274
Traits class for use in string conversions.
Definition: strconv.hxx:39
typename traits_type::pos_type pos_type
Definition: field.hxx:311
bool to(T &Obj) const
Read value into Obj; or leave Obj untouched and return false if null.
Definition: field.hxx:132
virtual int_type underflow() override
Definition: field.hxx:276
CHAR char_type
Definition: field.hxx:252
virtual int sync() override
Definition: field.hxx:267
Low-level array parser.
Definition: array.hxx:38
array_parser as_array() const
Parse the field as an SQL array.
Definition: field.hxx:189