sqlite3/vector-use-type.cpp
Go to the documentation of this file.
1 //
2 // Copyright (C) 2004-2006 Maciej Sobczak, Stephen Hutton, David Courtney
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 #include "soci-sqlite3.h"
9 #include <soci-platform.h>
10 #include "common.h"
11 // std
12 #include <cstdio>
13 #include <cstdlib>
14 #include <cstring>
15 #include <limits>
16 #include <sstream>
17 
18 #ifdef _MSC_VER
19 #pragma warning(disable:4355 4996)
20 #define snprintf _snprintf // TODO: use soci-platform.h
21 #endif
22 
23 using namespace soci;
24 using namespace soci::details;
25 using namespace soci::details::sqlite3;
26 
28  void * data,
29  exchange_type type)
30 {
31  if (statement_.boundByName_)
32  {
33  throw soci_error(
34  "Binding for use elements must be either by position or by name.");
35  }
36 
37  data_ = data;
38  type_ = type;
39  position_ = position++;
40 
41  statement_.boundByPos_ = true;
42 }
43 
44 void sqlite3_vector_use_type_backend::bind_by_name(std::string const & name,
45  void * data,
46  exchange_type type)
47 {
48  if (statement_.boundByPos_)
49  {
50  throw soci_error(
51  "Binding for use elements must be either by position or by name.");
52  }
53 
54  data_ = data;
55  type_ = type;
56  name_ = ":" + name;
57 
58  statement_.reset_if_needed();
59  position_ = sqlite3_bind_parameter_index(statement_.stmt_, name_.c_str());
60 
61  if (0 == position_)
62  {
63  std::ostringstream ss;
64  ss << "Cannot bind (by name) to " << name_;
65  throw soci_error(ss.str());
66  }
67  statement_.boundByName_ = true;
68 }
69 
71 {
72  std::size_t const vsize = size();
73 
74  // make sure that useData can hold enough rows
75  if (statement_.useData_.size() != vsize)
76  {
77  statement_.useData_.resize(vsize);
78  }
79 
80  int const pos = position_ - 1;
81 
82  for (size_t i = 0; i != vsize; ++i)
83  {
84  char *buf = 0;
85 
86  // make sure that each row can accomodate the number of columns
87  if (statement_.useData_[i].size() < static_cast<std::size_t>(position_))
88  {
89  statement_.useData_[i].resize(position_);
90  }
91 
92  // the data in vector can be either i_ok or i_null
93  if (ind != NULL && ind[i] == i_null)
94  {
95  statement_.useData_[i][pos].isNull_ = true;
96  statement_.useData_[i][pos].data_ = "";
97  statement_.useData_[i][pos].blobBuf_ = 0;
98  statement_.useData_[i][pos].blobSize_ = 0;
99  }
100  else
101  {
102  // allocate and fill the buffer with text-formatted client data
103  switch (type_)
104  {
105  case x_char:
106  {
107  std::vector<char> *pv
108  = static_cast<std::vector<char> *>(data_);
109  std::vector<char> &v = *pv;
110 
111  buf = new char[2];
112  buf[0] = v[i];
113  buf[1] = '\0';
114  }
115  break;
116  case x_stdstring:
117  {
118  std::vector<std::string> *pv
119  = static_cast<std::vector<std::string> *>(data_);
120  std::vector<std::string> &v = *pv;
121 
122  buf = new char[v[i].size() + 1];
123  std::strcpy(buf, v[i].c_str());
124  }
125  break;
126  case x_short:
127  {
128  std::vector<short> *pv
129  = static_cast<std::vector<short> *>(data_);
130  std::vector<short> &v = *pv;
131 
132  std::size_t const bufSize
133  = std::numeric_limits<short>::digits10 + 3;
134  buf = new char[bufSize];
135  snprintf(buf, bufSize, "%d", static_cast<int>(v[i]));
136  }
137  break;
138  case x_integer:
139  {
140  std::vector<int> *pv
141  = static_cast<std::vector<int> *>(data_);
142  std::vector<int> &v = *pv;
143 
144  std::size_t const bufSize
145  = std::numeric_limits<int>::digits10 + 3;
146  buf = new char[bufSize];
147  snprintf(buf, bufSize, "%d", v[i]);
148  }
149  break;
150  case x_long_long:
151  {
152  std::vector<long long> *pv
153  = static_cast<std::vector<long long> *>(data_);
154  std::vector<long long> &v = *pv;
155 
156  std::size_t const bufSize
157  = std::numeric_limits<long long>::digits10 + 3;
158  buf = new char[bufSize];
159  snprintf(buf, bufSize, "%" LL_FMT_FLAGS "d", v[i]);
160  }
161  break;
163  {
164  std::vector<unsigned long long>* pv
165  = static_cast<std::vector<unsigned long long>*>(data_);
166  std::vector<unsigned long long>& v = *pv;
167 
168  std::size_t const bufSize
169  = std::numeric_limits<unsigned long long>::digits10 + 2;
170  buf = new char[bufSize];
171  snprintf(buf, bufSize, "%" LL_FMT_FLAGS "u", v[i]);
172  }
173  break;
174  case x_double:
175  {
176  // no need to overengineer it (KISS)...
177 
178  std::vector<double> *pv
179  = static_cast<std::vector<double> *>(data_);
180  std::vector<double> &v = *pv;
181 
182  std::size_t const bufSize = 100;
183  buf = new char[bufSize];
184 
185  snprintf(buf, bufSize, "%.20g", v[i]);
186  }
187  break;
188  case x_stdtm:
189  {
190  std::vector<std::tm> *pv
191  = static_cast<std::vector<std::tm> *>(data_);
192  std::vector<std::tm> &v = *pv;
193 
194  std::size_t const bufSize = 20;
195  buf = new char[bufSize];
196 
197  snprintf(buf, bufSize, "%d-%02d-%02d %02d:%02d:%02d",
198  v[i].tm_year + 1900, v[i].tm_mon + 1, v[i].tm_mday,
199  v[i].tm_hour, v[i].tm_min, v[i].tm_sec);
200  }
201  break;
202  default:
203  throw soci_error(
204  "Use vector element used with non-supported type.");
205  }
206 
207  statement_.useData_[i][pos].isNull_ = false;
208  statement_.useData_[i][pos].data_ = buf;
209  statement_.useData_[i][pos].blobBuf_ = 0;
210  statement_.useData_[i][pos].blobSize_ = 0;
211  }
212 
213  if (buf)
214  {
215  delete [] buf;
216  }
217  }
218 }
219 
221 {
222  std::size_t sz = 0; // dummy initialization to please the compiler
223  switch (type_)
224  {
225  // simple cases
226  case x_char:
227  sz = get_vector_size<char>(data_);
228  break;
229  case x_short:
230  sz = get_vector_size<short>(data_);
231  break;
232  case x_integer:
233  sz = get_vector_size<int>(data_);
234  break;
235  case x_long_long:
236  sz = get_vector_size<long long>(data_);
237  break;
239  sz = get_vector_size<unsigned long long>(data_);
240  break;
241  case x_double:
242  sz = get_vector_size<double>(data_);
243  break;
244  case x_stdstring:
245  sz = get_vector_size<std::string>(data_);
246  break;
247  case x_stdtm:
248  sz = get_vector_size<std::tm>(data_);
249  break;
250  default:
251  throw soci_error("Use vector element used with non-supported type.");
252  }
253 
254  return sz;
255 }
256 
258 {
259  // ...
260 }
virtual void pre_use(indicator const *ind)
virtual void bind_by_name(std::string const &name, void *data, details::exchange_type type)
virtual void bind_by_pos(int &position, void *data, details::exchange_type type)
#define LL_FMT_FLAGS
Definition: soci-platform.h:14


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