db2/vector-into-type.cpp
Go to the documentation of this file.
1 //
2 // Copyright (C) 2011-2013 Denis Chapligin
3 // Copyright (C) 2004-2006 Maciej Sobczak, Stephen Hutton, David Courtney
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_DB2_SOURCE
10 #include "soci-db2.h"
11 #include <cctype>
12 #include <cstdio>
13 #include <cstring>
14 #include <ctime>
15 #include <sstream>
16 
17 using namespace soci;
18 using namespace soci::details;
19 
21 {
22  if (size == 0)
23  {
24  throw soci_error("Vectors of size 0 are not allowed.");
25  }
26 
27  indVec.resize(size);
28  indptr = &indVec[0];
29 }
30 
32  int &position, void *data, exchange_type type)
33 {
34  this->data = data; // for future reference
35  this->type = type; // for future reference
36 
37  SQLINTEGER size = 0; // also dummy
38 
39  switch (type)
40  {
41  // simple cases
42  case x_short:
43  {
44  cType = SQL_C_SSHORT;
45  size = sizeof(short);
46  std::vector<short> *vp = static_cast<std::vector<short> *>(data);
47  std::vector<short> &v(*vp);
48  prepare_indicators(v.size());
49  data = &v[0];
50  }
51  break;
52  case x_integer:
53  {
54  cType = SQL_C_SLONG;
55  size = sizeof(SQLINTEGER);
56  std::vector<SQLINTEGER> *vp = static_cast<std::vector<SQLINTEGER> *>(data);
57  std::vector<SQLINTEGER> &v(*vp);
58  prepare_indicators(v.size());
59  data = &v[0];
60  }
61  break;
62  case x_long_long:
63  {
64  cType = SQL_C_SBIGINT;
65  size = sizeof(long long);
66  std::vector<long long> *vp
67  = static_cast<std::vector<long long> *>(data);
68  std::vector<long long> &v(*vp);
69  prepare_indicators(v.size());
70  data = &v[0];
71  }
72  break;
74  {
75  cType = SQL_C_UBIGINT;
76  size = sizeof(unsigned long long);
77  std::vector<unsigned long long> *vp
78  = static_cast<std::vector<unsigned long long> *>(data);
79  std::vector<unsigned long long> &v(*vp);
80  prepare_indicators(v.size());
81  data = &v[0];
82  }
83  break;
84  case x_double:
85  {
86  cType = SQL_C_DOUBLE;
87  size = sizeof(double);
88  std::vector<double> *vp = static_cast<std::vector<double> *>(data);
89  std::vector<double> &v(*vp);
90  prepare_indicators(v.size());
91  data = &v[0];
92  }
93  break;
94 
95  // cases that require adjustments and buffer management
96 
97  case x_char:
98  {
99  cType = SQL_C_CHAR;
100 
101  std::vector<char> *v
102  = static_cast<std::vector<char> *>(data);
103 
104  prepare_indicators(v->size());
105 
106  size = sizeof(char) * 2;
107  std::size_t bufSize = size * v->size();
108 
109  colSize = size;
110 
111  buf = new char[bufSize];
112  data = buf;
113  }
114  break;
115  case x_stdstring:
116  {
117  cType = SQL_C_CHAR;
118  std::vector<std::string> *v
119  = static_cast<std::vector<std::string> *>(data);
120  colSize = statement_.column_size(position) + 1;
121  std::size_t bufSize = colSize * v->size();
122  buf = new char[bufSize];
123 
124  prepare_indicators(v->size());
125 
126  size = static_cast<SQLINTEGER>(colSize);
127  data = buf;
128  }
129  break;
130  case x_stdtm:
131  {
132  cType = SQL_C_TYPE_TIMESTAMP;
133  std::vector<std::tm> *v
134  = static_cast<std::vector<std::tm> *>(data);
135 
136  prepare_indicators(v->size());
137 
138  size = sizeof(TIMESTAMP_STRUCT);
139  colSize = size;
140 
141  std::size_t bufSize = size * v->size();
142 
143  buf = new char[bufSize];
144  data = buf;
145  }
146  break;
147 
148  case x_statement: break; // not supported
149  case x_rowid: break; // not supported
150  case x_blob: break; // not supported
151  }
152 
153  SQLRETURN cliRC = SQLBindCol(statement_.hStmt, static_cast<SQLUSMALLINT>(position++),
154  cType, data, size, indptr);
155  if (cliRC != SQL_SUCCESS)
156  {
157  throw db2_soci_error("Error while pre-fetching into vector",cliRC);
158  }
159 }
160 
162 {
163  // nothing to do for the supported types
164 }
165 
167 {
168  if (gotData)
169  {
170  // first, deal with data
171 
172  // only std::string, std::tm and Statement need special handling
173  if (type == x_char)
174  {
175  std::vector<char> *vp
176  = static_cast<std::vector<char> *>(data);
177 
178  std::vector<char> &v(*vp);
179  char *pos = buf;
180  std::size_t const vsize = v.size();
181  for (std::size_t i = 0; i != vsize; ++i)
182  {
183  v[i] = *pos;
184  pos += colSize;
185  }
186  }
187  if (type == x_stdstring)
188  {
189  std::vector<std::string> *vp
190  = static_cast<std::vector<std::string> *>(data);
191 
192  std::vector<std::string> &v(*vp);
193 
194  char *pos = buf;
195  std::size_t const vsize = v.size();
196  for (std::size_t i = 0; i != vsize; ++i)
197  {
198  v[i].assign(pos, strlen(pos));
199  pos += colSize;
200  }
201  }
202  else if (type == x_stdtm)
203  {
204  std::vector<std::tm> *vp
205  = static_cast<std::vector<std::tm> *>(data);
206 
207  std::vector<std::tm> &v(*vp);
208  char *pos = buf;
209  std::size_t const vsize = v.size();
210  for (std::size_t i = 0; i != vsize; ++i)
211  {
212  std::tm t;
213 
214  TIMESTAMP_STRUCT * ts = reinterpret_cast<TIMESTAMP_STRUCT*>(pos);
215  t.tm_isdst = -1;
216  t.tm_year = ts->year - 1900;
217  t.tm_mon = ts->month - 1;
218  t.tm_mday = ts->day;
219  t.tm_hour = ts->hour;
220  t.tm_min = ts->minute;
221  t.tm_sec = ts->second;
222 
223  // normalize and compute the remaining fields
224  std::mktime(&t);
225  v[i] = t;
226  pos += colSize;
227  }
228  }
229 
230  // then - deal with indicators
231  if (ind != NULL)
232  {
233  std::size_t const indSize = statement_.get_number_of_rows();
234  for (std::size_t i = 0; i != indSize; ++i)
235  {
236  if (indVec[i] > 0)
237  {
238  ind[i] = i_ok;
239  }
240  else if (indVec[i] == SQL_NULL_DATA)
241  {
242  ind[i] = i_null;
243  }
244  else
245  {
246  ind[i] = i_truncated;
247  }
248  }
249  }
250  else
251  {
252  std::size_t const indSize = statement_.get_number_of_rows();
253  for (std::size_t i = 0; i != indSize; ++i)
254  {
255  if (indVec[i] == SQL_NULL_DATA)
256  {
257  // fetched null and no indicator - programming error!
258  throw soci_error(
259  "Null value fetched and no indicator defined.");
260  }
261  }
262  }
263  }
264  else // gotData == false
265  {
266  // nothing to do here, vectors are truncated anyway
267  }
268 }
269 
271 {
272  indVec.resize(sz);
273  switch (type)
274  {
275  // simple cases
276  case x_char:
277  {
278  std::vector<char> *v = static_cast<std::vector<char> *>(data);
279  v->resize(sz);
280  }
281  break;
282  case x_short:
283  {
284  std::vector<short> *v = static_cast<std::vector<short> *>(data);
285  v->resize(sz);
286  }
287  break;
288  case x_integer:
289  {
290  std::vector<SQLINTEGER> *v = static_cast<std::vector<SQLINTEGER> *>(data);
291  v->resize(sz);
292  }
293  break;
294  case x_long_long:
295  {
296  std::vector<long long> *v
297  = static_cast<std::vector<long long> *>(data);
298  v->resize(sz);
299  }
300  break;
302  {
303  std::vector<unsigned long long> *v
304  = static_cast<std::vector<unsigned long long> *>(data);
305  v->resize(sz);
306  }
307  break;
308  case x_double:
309  {
310  std::vector<double> *v
311  = static_cast<std::vector<double> *>(data);
312  v->resize(sz);
313  }
314  break;
315  case x_stdstring:
316  {
317  std::vector<std::string> *v
318  = static_cast<std::vector<std::string> *>(data);
319  v->resize(sz);
320  }
321  break;
322  case x_stdtm:
323  {
324  std::vector<std::tm> *v
325  = static_cast<std::vector<std::tm> *>(data);
326  v->resize(sz);
327  }
328  break;
329 
330  case x_statement: break; // not supported
331  case x_rowid: break; // not supported
332  case x_blob: break; // not supported
333  }
334 }
335 
337 {
338  std::size_t sz = 0; // dummy initialization to please the compiler
339  switch (type)
340  {
341  // simple cases
342  case x_char:
343  {
344  std::vector<char> *v = static_cast<std::vector<char> *>(data);
345  sz = v->size();
346  }
347  break;
348  case x_short:
349  {
350  std::vector<short> *v = static_cast<std::vector<short> *>(data);
351  sz = v->size();
352  }
353  break;
354  case x_integer:
355  {
356  std::vector<SQLINTEGER> *v = static_cast<std::vector<SQLINTEGER> *>(data);
357  sz = v->size();
358  }
359  break;
360  case x_long_long:
361  {
362  std::vector<long long> *v
363  = static_cast<std::vector<long long> *>(data);
364  sz = v->size();
365  }
366  break;
368  {
369  std::vector<unsigned long long> *v
370  = static_cast<std::vector<unsigned long long> *>(data);
371  sz = v->size();
372  }
373  break;
374  case x_double:
375  {
376  std::vector<double> *v
377  = static_cast<std::vector<double> *>(data);
378  sz = v->size();
379  }
380  break;
381  case x_stdstring:
382  {
383  std::vector<std::string> *v
384  = static_cast<std::vector<std::string> *>(data);
385  sz = v->size();
386  }
387  break;
388  case x_stdtm:
389  {
390  std::vector<std::tm> *v
391  = static_cast<std::vector<std::tm> *>(data);
392  sz = v->size();
393  }
394  break;
395 
396  case x_statement: break; // not supported
397  case x_rowid: break; // not supported
398  case x_blob: break; // not supported
399  }
400 
401  return sz;
402 }
403 
405 {
406  if (buf != NULL)
407  {
408  delete [] buf;
409  buf = NULL;
410  }
411 }
void post_fetch(bool gotData, indicator *ind)
void define_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