mysql/vector-use-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 // std
14 #include <ciso646>
15 #include <cstddef>
16 #include <cstdio>
17 #include <cstdlib>
18 #include <cstring>
19 #include <ctime>
20 #include <limits>
21 #include <string>
22 #include <vector>
23 
24 #ifdef _MSC_VER
25 #pragma warning(disable:4355)
26 #endif
27 
28 using namespace soci;
29 using namespace soci::details;
30 using namespace soci::details::mysql;
31 
32 
33 void mysql_vector_use_type_backend::bind_by_pos(int &position, void *data,
34  exchange_type type)
35 {
36  data_ = data;
37  type_ = type;
38  position_ = position++;
39 }
40 
42  std::string const &name, void *data, exchange_type type)
43 {
44  data_ = data;
45  type_ = type;
46  name_ = name;
47 }
48 
50 {
51  std::size_t const vsize = size();
52  for (size_t i = 0; i != vsize; ++i)
53  {
54  char *buf;
55 
56  // the data in vector can be either i_ok or i_null
57  if (ind != NULL && ind[i] == i_null)
58  {
59  buf = new char[5];
60  std::strcpy(buf, "NULL");
61  }
62  else
63  {
64  // allocate and fill the buffer with text-formatted client data
65  switch (type_)
66  {
67  case x_char:
68  {
69  std::vector<char> *pv
70  = static_cast<std::vector<char> *>(data_);
71  std::vector<char> &v = *pv;
72 
73  char tmp[] = { v[i], '\0' };
74  buf = quote(statement_.session_.conn_, tmp, 1);
75  }
76  break;
77  case x_stdstring:
78  {
79  std::vector<std::string> *pv
80  = static_cast<std::vector<std::string> *>(data_);
81  std::vector<std::string> &v = *pv;
82 
83  buf = quote(statement_.session_.conn_,
84  v[i].c_str(), v[i].size());
85  }
86  break;
87  case x_short:
88  {
89  std::vector<short> *pv
90  = static_cast<std::vector<short> *>(data_);
91  std::vector<short> &v = *pv;
92 
93  std::size_t const bufSize
94  = std::numeric_limits<short>::digits10 + 3;
95  buf = new char[bufSize];
96  snprintf(buf, bufSize, "%d", static_cast<int>(v[i]));
97  }
98  break;
99  case x_integer:
100  {
101  std::vector<int> *pv
102  = static_cast<std::vector<int> *>(data_);
103  std::vector<int> &v = *pv;
104 
105  std::size_t const bufSize
106  = std::numeric_limits<int>::digits10 + 3;
107  buf = new char[bufSize];
108  snprintf(buf, bufSize, "%d", v[i]);
109  }
110  break;
111  case x_long_long:
112  {
113  std::vector<long long> *pv
114  = static_cast<std::vector<long long> *>(data_);
115  std::vector<long long> &v = *pv;
116 
117  std::size_t const bufSize
118  = std::numeric_limits<long long>::digits10 + 3;
119  buf = new char[bufSize];
120  snprintf(buf, bufSize, "%" LL_FMT_FLAGS "d", v[i]);
121  }
122  break;
124  {
125  std::vector<unsigned long long> *pv
126  = static_cast<std::vector<unsigned long long> *>(data_);
127  std::vector<unsigned long long> &v = *pv;
128 
129  std::size_t const bufSize
130  = std::numeric_limits<unsigned long long>::digits10 + 3;
131  buf = new char[bufSize];
132  snprintf(buf, bufSize, "%" LL_FMT_FLAGS "u", v[i]);
133  }
134  break;
135  case x_double:
136  {
137  std::vector<double> *pv
138  = static_cast<std::vector<double> *>(data_);
139  std::vector<double> &v = *pv;
140 
141  if (is_infinity_or_nan(v[i])) {
142  throw soci_error(
143  "Use element used with infinity or NaN, which are "
144  "not supported by the MySQL server.");
145  }
146 
147  std::size_t const bufSize = 100;
148  buf = new char[bufSize];
149 
150  snprintf(buf, bufSize, "%.20g", v[i]);
151  }
152  break;
153  case x_stdtm:
154  {
155  std::vector<std::tm> *pv
156  = static_cast<std::vector<std::tm> *>(data_);
157  std::vector<std::tm> &v = *pv;
158 
159  std::size_t const bufSize = 22;
160  buf = new char[bufSize];
161 
162  snprintf(buf, bufSize, "\'%d-%02d-%02d %02d:%02d:%02d\'",
163  v[i].tm_year + 1900, v[i].tm_mon + 1, v[i].tm_mday,
164  v[i].tm_hour, v[i].tm_min, v[i].tm_sec);
165  }
166  break;
167 
168  default:
169  throw soci_error(
170  "Use vector element used with non-supported type.");
171  }
172  }
173 
174  buffers_.push_back(buf);
175  }
176 
177  if (position_ > 0)
178  {
179  // binding by position
180  statement_.useByPosBuffers_[position_] = &buffers_[0];
181  }
182  else
183  {
184  // binding by name
185  statement_.useByNameBuffers_[name_] = &buffers_[0];
186  }
187 }
188 
190 {
191  std::size_t sz = 0; // dummy initialization to please the compiler
192  switch (type_)
193  {
194  // simple cases
195  case x_char: sz = get_vector_size<char> (data_); break;
196  case x_short: sz = get_vector_size<short> (data_); break;
197  case x_integer: sz = get_vector_size<int> (data_); break;
198  case x_long_long: sz = get_vector_size<long long> (data_); break;
200  sz = get_vector_size<unsigned long long>(data_);
201  break;
202  case x_double: sz = get_vector_size<double> (data_); break;
203  case x_stdstring: sz = get_vector_size<std::string> (data_); break;
204  case x_stdtm: sz = get_vector_size<std::tm> (data_); break;
205 
206  default:
207  throw soci_error("Use vector element used with non-supported type.");
208  }
209 
210  return sz;
211 }
212 
214 {
215  std::size_t const bsize = buffers_.size();
216  for (std::size_t i = 0; i != bsize; ++i)
217  {
218  delete [] buffers_[i];
219  }
220 }
bool is_infinity_or_nan(T x)
Definition: mysql/common.h:39
virtual void bind_by_name(std::string const &name, void *data, details::exchange_type type)
char * quote(MYSQL *conn, const char *s, int len)
virtual void pre_use(indicator const *ind)
#define LL_FMT_FLAGS
Definition: soci-platform.h:14
virtual void bind_by_pos(int &position, void *data, details::exchange_type type)


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