mysql/vector-into-type.cpp
Go to the documentation of this file.
1 //
2 // Copyright (C) 2004-2006 Maciej Sobczak, Stephen Hutton
3 // MySQL backend copyright (C) 2006 Pawel Aleksander Fedorynski
4 // Distributed under the Boost Software License, Version 1.0.
5 // (See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
7 //
8 
9 #define SOCI_MYSQL_SOURCE
10 #include "soci-mysql.h"
11 #include "common.h"
12 #include <soci-platform.h>
13 #include <ciso646>
14 #include <cstdlib>
15 
16 #ifdef _MSC_VER
17 #pragma warning(disable:4355)
18 #endif
19 
20 using namespace soci;
21 using namespace soci::details;
22 using namespace soci::details::mysql;
23 
24 
26  int &position, void *data, exchange_type type)
27 {
28  data_ = data;
29  type_ = type;
30  position_ = position++;
31 }
32 
34 {
35  // nothing to do here
36 }
37 
38 namespace // anonymous
39 {
40 
41 template <typename T>
42 void set_invector_(void *p, int indx, T const &val)
43 {
44  std::vector<T> *dest =
45  static_cast<std::vector<T> *>(p);
46 
47  std::vector<T> &v = *dest;
48  v[indx] = val;
49 }
50 
51 } // namespace anonymous
52 
54 {
55  if (gotData)
56  {
57  // Here, rowsToConsume_ in the Statement object designates
58  // the number of rows that need to be put in the user's buffers.
59 
60  // MySQL column positions start at 0
61  int pos = position_ - 1;
62 
63  int const endRow = statement_.currentRow_ + statement_.rowsToConsume_;
64 
65  //mysql_data_seek(statement_.result_, statement_.currentRow_);
66  mysql_row_seek(statement_.result_,
67  statement_.resultRowOffsets_[statement_.currentRow_]);
68  for (int curRow = statement_.currentRow_, i = 0;
69  curRow != endRow; ++curRow, ++i)
70  {
71  MYSQL_ROW row = mysql_fetch_row(statement_.result_);
72  // first, deal with indicators
73  if (row[pos] == NULL)
74  {
75  if (ind == NULL)
76  {
77  throw soci_error(
78  "Null value fetched and no indicator defined.");
79  }
80 
81  ind[i] = i_null;
82 
83  // no need to convert data if it is null, go to next row
84  continue;
85  }
86  else
87  {
88  if (ind != NULL)
89  {
90  ind[i] = i_ok;
91  }
92  }
93 
94  // buffer with data retrieved from server, in text format
95  const char *buf = row[pos] != NULL ? row[pos] : "";
96 
97  switch (type_)
98  {
99  case x_char:
100  set_invector_(data_, i, *buf);
101  break;
102  case x_stdstring:
103  {
104  unsigned long * lengths =
105  mysql_fetch_lengths(statement_.result_);
106  // Not sure if it's necessary, but the code below is used
107  // instead of
108  // set_invector_(data_, i, std::string(buf, lengths[pos]);
109  // to avoid copying the (possibly large) temporary string.
110  std::vector<std::string> *dest =
111  static_cast<std::vector<std::string> *>(data_);
112  (*dest)[i].assign(buf, lengths[pos]);
113  }
114  break;
115  case x_short:
116  {
117  short val;
118  parse_num(buf, val);
119  set_invector_(data_, i, val);
120  }
121  break;
122  case x_integer:
123  {
124  int val;
125  parse_num(buf, val);
126  set_invector_(data_, i, val);
127  }
128  break;
129  case x_long_long:
130  {
131  long long val;
132  parse_num(buf, val);
133  set_invector_(data_, i, val);
134  }
135  break;
137  {
138  unsigned long long val;
139  parse_num(buf, val);
140  set_invector_(data_, i, val);
141  }
142  break;
143  case x_double:
144  {
145  double val;
146  parse_num(buf, val);
147  set_invector_(data_, i, val);
148  }
149  break;
150  case x_stdtm:
151  {
152  // attempt to parse the string and convert to std::tm
153  std::tm t;
154  parse_std_tm(buf, t);
155 
156  set_invector_(data_, i, t);
157  }
158  break;
159 
160  default:
161  throw soci_error("Into element used with non-supported type.");
162  }
163  }
164  }
165  else // no data retrieved
166  {
167  // nothing to do, into vectors are already truncated
168  }
169 }
170 
171 namespace // anonymous
172 {
173 
174 template <typename T>
175 void resizevector_(void *p, std::size_t sz)
176 {
177  std::vector<T> *v = static_cast<std::vector<T> *>(p);
178  v->resize(sz);
179 }
180 
181 } // namespace anonymous
182 
184 {
185  switch (type_)
186  {
187  // simple cases
188  case x_char: resizevector_<char> (data_, sz); break;
189  case x_short: resizevector_<short> (data_, sz); break;
190  case x_integer: resizevector_<int> (data_, sz); break;
191  case x_long_long: resizevector_<long long> (data_, sz); break;
193  resizevector_<unsigned long long>(data_, sz);
194  break;
195  case x_double: resizevector_<double> (data_, sz); break;
196  case x_stdstring: resizevector_<std::string> (data_, sz); break;
197  case x_stdtm: resizevector_<std::tm> (data_, sz); break;
198 
199  default:
200  throw soci_error("Into vector element used with non-supported type.");
201  }
202 }
203 
205 {
206  std::size_t sz = 0; // dummy initialization to please the compiler
207  switch (type_)
208  {
209  // simple cases
210  case x_char: sz = get_vector_size<char> (data_); break;
211  case x_short: sz = get_vector_size<short> (data_); break;
212  case x_integer: sz = get_vector_size<int> (data_); break;
213  case x_long_long: sz = get_vector_size<long long> (data_); break;
215  sz = get_vector_size<unsigned long long>(data_);
216  break;
217  case x_double: sz = get_vector_size<double> (data_); break;
218  case x_stdstring: sz = get_vector_size<std::string> (data_); break;
219  case x_stdtm: sz = get_vector_size<std::tm> (data_); break;
220 
221  default:
222  throw soci_error("Into vector element used with non-supported type.");
223  }
224 
225  return sz;
226 }
227 
229 {
230  // nothing to do here
231 }
virtual void define_by_pos(int &position, void *data, details::exchange_type type)
void parse_std_tm(char const *buf, std::tm &t)
Definition: row.h:41
void parse_num(char const *buf, T &x)
Definition: mysql/common.h:46
virtual void post_fetch(bool gotData, indicator *ind)


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