postgresql/vector-into-type.cpp
Go to the documentation of this file.
1 //
2 // Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
3 // Distributed under the Boost Software License, Version 1.0.
4 // (See accompanying file LICENSE_1_0.txt or copy at
5 // http://www.boost.org/LICENSE_1_0.txt)
6 //
7 
8 #define SOCI_POSTGRESQL_SOURCE
9 #include <soci-platform.h>
10 #include "soci-postgresql.h"
11 #include "common.h"
12 #include <libpq/libpq-fs.h> // libpq
13 #include <cassert>
14 #include <cctype>
15 #include <cstdio>
16 #include <cstring>
17 #include <ctime>
18 #include <sstream>
19 
20 #ifdef SOCI_POSTGRESQL_NOPARAMS
21 #ifndef SOCI_POSTGRESQL_NOBINDBYNAME
22 #define SOCI_POSTGRESQL_NOBINDBYNAME
23 #endif // SOCI_POSTGRESQL_NOBINDBYNAME
24 #endif // SOCI_POSTGRESQL_NOPARAMS
25 
26 using namespace soci;
27 using namespace soci::details;
28 using namespace soci::details::postgresql;
29 
30 
32  int & position, void * data, exchange_type type)
33 {
34  data_ = data;
35  type_ = type;
36  position_ = position++;
37 }
38 
40 {
41  // nothing to do here
42 }
43 
44 namespace // anonymous
45 {
46 
47 template <typename T>
48 void set_invector_(void * p, int indx, T const & val)
49 {
50  std::vector<T> * dest =
51  static_cast<std::vector<T> *>(p);
52 
53  std::vector<T> & v = *dest;
54  v[indx] = val;
55 }
56 
57 } // namespace anonymous
58 
60 {
61  if (gotData)
62  {
63  // Here, rowsToConsume_ in the Statement object designates
64  // the number of rows that need to be put in the user's buffers.
65 
66  // postgresql_ column positions start at 0
67  int const pos = position_ - 1;
68 
69  int const endRow = statement_.currentRow_ + statement_.rowsToConsume_;
70 
71  for (int curRow = statement_.currentRow_, i = 0;
72  curRow != endRow; ++curRow, ++i)
73  {
74  // first, deal with indicators
75  if (PQgetisnull(statement_.result_, curRow, pos) != 0)
76  {
77  if (ind == NULL)
78  {
79  throw soci_error(
80  "Null value fetched and no indicator defined.");
81  }
82 
83  ind[i] = i_null;
84 
85  // no need to convert data if it is null, go to next row
86  continue;
87  }
88  else
89  {
90  if (ind != NULL)
91  {
92  ind[i] = i_ok;
93  }
94  }
95 
96  // buffer with data retrieved from server, in text format
97  char * buf = PQgetvalue(statement_.result_, curRow, pos);
98 
99  switch (type_)
100  {
101  case x_char:
102  set_invector_(data_, i, *buf);
103  break;
104  case x_stdstring:
105  set_invector_<std::string>(data_, i, buf);
106  break;
107  case x_short:
108  {
109  short const val = string_to_integer<short>(buf);
110  set_invector_(data_, i, val);
111  }
112  break;
113  case x_integer:
114  {
115  int const val = string_to_integer<int>(buf);
116  set_invector_(data_, i, val);
117  }
118  break;
119  case x_long_long:
120  {
121  long long const val = string_to_integer<long long>(buf);
122  set_invector_(data_, i, val);
123  }
124  break;
126  {
127  unsigned long long const val =
128  string_to_unsigned_integer<unsigned long long>(buf);
129  set_invector_(data_, i, val);
130  }
131  break;
132  case x_double:
133  {
134  double const val = string_to_double(buf);
135  set_invector_(data_, i, val);
136  }
137  break;
138  case x_stdtm:
139  {
140  // attempt to parse the string and convert to std::tm
141  std::tm t;
142  parse_std_tm(buf, t);
143 
144  set_invector_(data_, i, t);
145  }
146  break;
147 
148  default:
149  throw soci_error("Into element used with non-supported type.");
150  }
151  }
152  }
153  else // no data retrieved
154  {
155  // nothing to do, into vectors are already truncated
156  }
157 }
158 
159 namespace // anonymous
160 {
161 
162 template <typename T>
163 void resizevector_(void * p, std::size_t sz)
164 {
165  std::vector<T> * v = static_cast<std::vector<T> *>(p);
166  v->resize(sz);
167 }
168 
169 } // namespace anonymous
170 
172 {
173  assert(sz < 10u*std::numeric_limits<unsigned short>::max()); // Not a strong constraint, for debugging only. Notice my fix is even worse
174 
175  switch (type_)
176  {
177  // simple cases
178  case x_char:
179  resizevector_<char>(data_, sz);
180  break;
181  case x_short:
182  resizevector_<short>(data_, sz);
183  break;
184  case x_integer:
185  resizevector_<int>(data_, sz);
186  break;
187  case x_long_long:
188  resizevector_<long long>(data_, sz);
189  break;
191  resizevector_<unsigned long long>(data_, sz);
192  break;
193  case x_double:
194  resizevector_<double>(data_, sz);
195  break;
196  case x_stdstring:
197  resizevector_<std::string>(data_, sz);
198  break;
199  case x_stdtm:
200  resizevector_<std::tm>(data_, sz);
201  break;
202  default:
203  throw soci_error("Into vector element used with non-supported type.");
204  }
205 }
206 
208 {
209  std::size_t sz = 0; // dummy initialization to please the compiler
210  switch (type_)
211  {
212  // simple cases
213  case x_char:
214  sz = get_vector_size<char>(data_);
215  break;
216  case x_short:
217  sz = get_vector_size<short>(data_);
218  break;
219  case x_integer:
220  sz = get_vector_size<int>(data_);
221  break;
222  case x_long_long:
223  sz = get_vector_size<long long>(data_);
224  break;
226  sz = get_vector_size<unsigned long long>(data_);
227  break;
228  case x_double:
229  sz = get_vector_size<double>(data_);
230  break;
231  case x_stdstring:
232  sz = get_vector_size<std::string>(data_);
233  break;
234  case x_stdtm:
235  sz = get_vector_size<std::tm>(data_);
236  break;
237  default:
238  throw soci_error("Into vector element used with non-supported type.");
239  }
240 
241  return sz;
242 }
243 
245 {
246  // nothing to do here
247 }
virtual void define_by_pos(int &position, void *data, details::exchange_type type)
virtual void post_fetch(bool gotData, indicator *ind)
void parse_std_tm(char const *buf, std::tm &t)
double string_to_double(char const *buf)


asr_lib_ism
Author(s): Hanselmann Fabian, Heller Florian, Heizmann Heinrich, Kübler Marcel, Mehlhaus Jonas, Meißner Pascal, Qattan Mohamad, Reckling Reno, Stroh Daniel
autogenerated on Wed Jan 8 2020 04:02:41