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 
22 /* Use std::experimental::optional as a fallback for std::optional, if
23  * present.
24  *
25  * This may break compilation for some software, if using a libpqxx that was
26  * configured for a different language version. To stop libpqxx headers from
27  * using or supporting std::experimental::optional, define a macro
28  * PQXX_HIDE_EXP_OPTIONAL when building your software.
29  */
30 #elif defined(PQXX_HAVE_EXP_OPTIONAL) && !defined(PQXX_HIDE_EXP_OPTIONAL)
31 #include <experimental/optional>
32 #endif
33 
34 #include "pqxx/array.hxx"
35 #include "pqxx/result.hxx"
36 #include "pqxx/strconv.hxx"
37 #include "pqxx/types.hxx"
38 
39 
40 // Methods tested in eg. test module test01 are marked with "//[t01]".
41 
42 namespace pqxx
43 {
45 
48 class PQXX_LIBEXPORT field
49 {
50 public:
52 
54 
58  field(const row &R, row_size_type C) noexcept; //[t01]
59 
64 
81  bool operator==(const field &) const; //[t75]
82 
84 
86  bool operator!=(const field &rhs) const //[t82]
87  {return !operator==(rhs);}
89 
94  const char *name() const; //[t11]
96 
98  oid type() const; //[t07]
99 
101  oid table() const; //[t02]
102 
103  row_size_type num() const { return col(); } //[t82]
104 
106  row_size_type table_column() const; //[t93]
108 
113 
119  const char *c_str() const; //[t02]
120 
122  bool is_null() const noexcept; //[t12]
123 
125 
128  size_type size() const noexcept; //[t11]
129 
131  template<typename T> bool to(T &Obj) const //[t03]
132  {
133  const char *const bytes = c_str();
134  if (!bytes[0] && is_null()) return false;
135  from_string(bytes, Obj);
136  return true;
137  }
138 
140  template<typename T> bool operator>>(T &Obj) const //[t07]
141  { return to(Obj); }
142 
144  template<typename T> bool to(T &Obj, const T &Default) const //[t12]
145  {
146  const bool NotNull = to(Obj);
147  if (!NotNull) Obj = Default;
148  return NotNull;
149  }
150 
152 
155  template<typename T> T as(const T &Default) const //[t01]
156  {
157  T Obj;
158  to(Obj, Default);
159  return Obj;
160  }
161 
163  template<typename T> T as() const //[t45]
164  {
165  T Obj;
166  const bool NotNull = to(Obj);
167  if (!NotNull) Obj = string_traits<T>::null();
168  return Obj;
169  }
170 
171 #if defined(PQXX_HAVE_OPTIONAL)
172  template<typename T> std::optional<T> get() const
174  { return get_opt<T, std::optional<T>>(); }
175 #elif defined(PQXX_HAVE_EXP_OPTIONAL) && !defined(PQXX_HIDE_EXP_OPTIONAL)
176  template<typename T> std::experimental::optional<T> get() const
178  { return get_opt<T, std::experimental::optional<T>>(); }
179 #endif
180 
182 
188  array_parser as_array() const { return array_parser(c_str()); }
190 
191 
192 protected:
193  const result &home() const noexcept { return m_home; }
194  size_t idx() const noexcept { return m_row; }
195  row_size_type col() const noexcept { return row_size_type(m_col); }
196 
201  long m_col;
202 
203 private:
205 
210  template<typename T, typename OPTIONAL_T> OPTIONAL_T get_opt() const
211  {
212  if (is_null()) return OPTIONAL_T();
213  else return OPTIONAL_T(as<T>());
214  }
215 
216  result m_home;
217  size_t m_row;
218 };
219 
220 
222 template<>
223 inline bool field::to<std::string>(std::string &Obj) const
224 {
225  const char *const bytes = c_str();
226  if (!bytes[0] && is_null()) return false;
227  Obj = std::string(bytes, size());
228  return true;
229 }
230 
232 
237 template<>
238 inline bool field::to<const char *>(const char *&Obj) const
239 {
240  if (is_null()) return false;
241  Obj = c_str();
242  return true;
243 }
244 
245 
246 template<typename CHAR=char, typename TRAITS=std::char_traits<CHAR>>
248  public std::basic_streambuf<CHAR, TRAITS>
249 {
250 public:
251  using char_type = CHAR;
252  using traits_type = TRAITS;
253  using int_type = typename traits_type::int_type;
254  using pos_type = typename traits_type::pos_type;
255  using off_type = typename traits_type::off_type;
256  using openmode = std::ios::openmode;
257  using seekdir = std::ios::seekdir;
258 
259  explicit field_streambuf(const field &F) : //[t74]
260  m_field(F)
261  {
262  initialize();
263  }
264 
265 protected:
266  virtual int sync() override { return traits_type::eof(); }
267 
268 protected:
270  { return traits_type::eof(); }
271  virtual pos_type seekpos(pos_type, openmode) override
272  {return traits_type::eof();}
273  virtual int_type overflow(int_type) override
274  { return traits_type::eof(); }
275  virtual int_type underflow() override
276  { return traits_type::eof(); }
277 
278 private:
279  const field &m_field;
280 
281  int_type initialize()
282  {
283  char_type *G =
284  reinterpret_cast<char_type *>(const_cast<char *>(m_field.c_str()));
285  this->setg(G, G, G + m_field.size());
286  return int_type(m_field.size());
287  }
288 };
289 
290 
292 
300 template<typename CHAR=char, typename TRAITS=std::char_traits<CHAR>>
302  public std::basic_istream<CHAR, TRAITS>
303 {
304  using super = std::basic_istream<CHAR, TRAITS>;
305 
306 public:
307  using char_type = CHAR;
308  using traits_type = TRAITS;
309  using int_type = typename traits_type::int_type;
310  using pos_type = typename traits_type::pos_type;
311  using off_type = typename traits_type::off_type;
312 
313  basic_fieldstream(const field &F) : super(nullptr), m_buf(F)
314  { super::init(&m_buf); }
315 
316 private:
318 };
319 
321 
323 
343 template<typename CHAR>
344 inline std::basic_ostream<CHAR> &operator<<(
345  std::basic_ostream<CHAR> &S, const field &F) //[t46]
346 {
347  S.write(F.c_str(), std::streamsize(F.size()));
348  return S;
349 }
350 
351 
353 template<typename T>
354 inline void from_string(const field &F, T &Obj) //[t46]
355  { from_string(F.c_str(), Obj, F.size()); }
356 
358 template<> PQXX_LIBEXPORT std::string to_string(const field &Obj); //[t74]
359 
360 } // namespace pqxx
361 #include "pqxx/compiler-internal-post.hxx"
362 #endif
TRAITS traits_type
Definition: field.hxx:252
size_t idx() const noexcept
Definition: field.hxx:194
bool to(T &Obj, const T &Default) const
Read value into Obj; or use Default & return false if null.
Definition: field.hxx:144
T as() const
Return value as object of given type, or throw exception if null.
Definition: field.hxx:163
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:259
row_size_type col() const noexcept
Definition: field.hxx:195
typename traits_type::int_type int_type
Definition: field.hxx:253
CHAR char_type
Definition: field.hxx:307
const result & home() const noexcept
Definition: field.hxx:193
std::ios::openmode openmode
Definition: field.hxx:256
TRAITS traits_type
Definition: field.hxx:308
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:354
typename traits_type::off_type off_type
Definition: field.hxx:311
std::ios::seekdir seekdir
Definition: field.hxx:257
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:344
virtual pos_type seekoff(off_type, seekdir, openmode) override
Definition: field.hxx:269
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:301
virtual pos_type seekpos(pos_type, openmode) override
Definition: field.hxx:271
const char * c_str() const
Read as plain C string.
Definition: field.cxx:62
field_size_type size_type
Definition: field.hxx:51
row_size_type num() const
Definition: field.hxx:103
T as(const T &Default) const
Return value as object of given type, or Default if null.
Definition: field.hxx:155
The home of all libpqxx classes, functions, templates, etc.
Definition: array.hxx:22
basic_fieldstream(const field &F)
Definition: field.hxx:313
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:254
long m_col
Definition: field.hxx:201
Definition: field.hxx:247
bool operator>>(T &Obj) const
Read value into Obj; or leave Obj untouched and return false if null.
Definition: field.hxx:140
bool operator!=(const field &rhs) const
Byte-by-byte comparison (all nulls are considered equal)
Definition: field.hxx:86
typename traits_type::off_type off_type
Definition: field.hxx:255
Reference to a field in a result set.
Definition: field.hxx:48
virtual int_type overflow(int_type) override
Definition: field.hxx:273
Traits class for use in string conversions.
Definition: strconv.hxx:52
typename traits_type::pos_type pos_type
Definition: field.hxx:310
bool to(T &Obj) const
Read value into Obj; or leave Obj untouched and return false if null.
Definition: field.hxx:131
virtual int_type underflow() override
Definition: field.hxx:275
CHAR char_type
Definition: field.hxx:251
virtual int sync() override
Definition: field.hxx:266
Low-level array parser.
Definition: array.hxx:43
array_parser as_array() const
Parse the field as an SQL array.
Definition: field.hxx:188