oracle/vector-into-type.cpp
Go to the documentation of this file.
1 //
2 // Copyright (C) 2004-2007 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_ORACLE_SOURCE
9 #include "soci-oracle.h"
10 #include "statement.h"
11 #include "error.h"
12 #include <soci-platform.h>
13 #include <cctype>
14 #include <cstdio>
15 #include <cstring>
16 #include <cstdlib>
17 #include <ctime>
18 #include <sstream>
19 
20 #ifdef _MSC_VER
21 #pragma warning(disable:4355)
22 #endif
23 
24 using namespace soci;
25 using namespace soci::details;
26 using namespace soci::details::oracle;
27 
29 {
30  if (size == 0)
31  {
32  throw soci_error("Vectors of size 0 are not allowed.");
33  }
34 
35  indOCIHolderVec_.resize(size);
36  indOCIHolders_ = &indOCIHolderVec_[0];
37 
38  sizes_.resize(size);
39  rCodes_.resize(size);
40 }
41 
43  int &position, void *data, exchange_type type)
44 {
45  data_ = data; // for future reference
46  type_ = type; // for future reference
47 
48  ub2 oracleType = 0; // dummy initialization to please the compiler
49  sb4 size = 0; // also dummy
50 
51  switch (type)
52  {
53  // simple cases
54  case x_char:
55  {
56  oracleType = SQLT_AFC;
57  size = sizeof(char);
58  std::vector<char> *vp = static_cast<std::vector<char> *>(data);
59  std::vector<char> &v(*vp);
60  prepare_indicators(v.size());
61  data = &v[0];
62  }
63  break;
64  case x_short:
65  {
66  oracleType = SQLT_INT;
67  size = sizeof(short);
68  std::vector<short> *vp = static_cast<std::vector<short> *>(data);
69  std::vector<short> &v(*vp);
70  prepare_indicators(v.size());
71  data = &v[0];
72  }
73  break;
74  case x_integer:
75  {
76  oracleType = SQLT_INT;
77  size = sizeof(int);
78  std::vector<int> *vp = static_cast<std::vector<int> *>(data);
79  std::vector<int> &v(*vp);
80  prepare_indicators(v.size());
81  data = &v[0];
82  }
83  break;
84  case x_double:
85  {
86  oracleType = SQLT_FLT;
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_long_long:
98  {
99  oracleType = SQLT_STR;
100  std::vector<long long> *v
101  = static_cast<std::vector<long long> *>(data);
102  colSize_ = 100; // arbitrary buffer size for each entry
103  std::size_t const bufSize = colSize_ * v->size();
104  buf_ = new char[bufSize];
105 
106  prepare_indicators(v->size());
107 
108  size = static_cast<sb4>(colSize_);
109  data = buf_;
110  }
111  break;
113  {
114  oracleType = SQLT_STR;
115  std::vector<unsigned long long> *v
116  = static_cast<std::vector<unsigned long long> *>(data);
117  colSize_ = 100; // arbitrary buffer size for each entry
118  std::size_t const bufSize = colSize_ * v->size();
119  buf_ = new char[bufSize];
120 
121  prepare_indicators(v->size());
122 
123  size = static_cast<sb4>(colSize_);
124  data = buf_;
125  }
126  break;
127  case x_stdstring:
128  {
129  oracleType = SQLT_CHR;
130  std::vector<std::string> *v
131  = static_cast<std::vector<std::string> *>(data);
132  colSize_ = statement_.column_size(position) + 1;
133  std::size_t bufSize = colSize_ * v->size();
134  buf_ = new char[bufSize];
135 
136  prepare_indicators(v->size());
137 
138  size = static_cast<sb4>(colSize_);
139  data = buf_;
140  }
141  break;
142  case x_stdtm:
143  {
144  oracleType = SQLT_DAT;
145  std::vector<std::tm> *v
146  = static_cast<std::vector<std::tm> *>(data);
147 
148  prepare_indicators(v->size());
149 
150  size = 7; // 7 is the size of SQLT_DAT
151  std::size_t bufSize = size * v->size();
152 
153  buf_ = new char[bufSize];
154  data = buf_;
155  }
156  break;
157 
158  case x_statement: break; // not supported
159  case x_rowid: break; // not supported
160  case x_blob: break; // not supported
161  }
162 
163  sword res = OCIDefineByPos(statement_.stmtp_, &defnp_,
164  statement_.session_.errhp_,
165  position++, data, size, oracleType,
166  indOCIHolders_, &sizes_[0], &rCodes_[0], OCI_DEFAULT);
167  if (res != OCI_SUCCESS)
168  {
169  throw_oracle_soci_error(res, statement_.session_.errhp_);
170  }
171 }
172 
174 {
175  // nothing to do for the supported types
176 }
177 
179 {
180  if (gotData)
181  {
182  // first, deal with data
183 
184  // only std::string, std::tm, long long and Statement need special handling
185  if (type_ == x_stdstring)
186  {
187  std::vector<std::string> *vp
188  = static_cast<std::vector<std::string> *>(data_);
189 
190  std::vector<std::string> &v(*vp);
191 
192  char *pos = buf_;
193  std::size_t const vsize = v.size();
194  for (std::size_t i = 0; i != vsize; ++i)
195  {
196  if (indOCIHolderVec_[i] != -1)
197  {
198  v[i].assign(pos, sizes_[i]);
199  }
200  pos += colSize_;
201  }
202  }
203  else if (type_ == x_long_long)
204  {
205  std::vector<long long> *vp
206  = static_cast<std::vector<long long> *>(data_);
207 
208  std::vector<long long> &v(*vp);
209 
210  char *pos = buf_;
211  std::size_t const vsize = v.size();
212  for (std::size_t i = 0; i != vsize; ++i)
213  {
214  if (indOCIHolderVec_[i] != -1)
215  {
216  v[i] = std::strtoll(pos, NULL, 10);
217  }
218  pos += colSize_;
219  }
220  }
221  else if (type_ == x_unsigned_long_long)
222  {
223  std::vector<unsigned long long> *vp
224  = static_cast<std::vector<unsigned long long> *>(data_);
225 
226  std::vector<unsigned long long> &v(*vp);
227 
228  char *pos = buf_;
229  std::size_t const vsize = v.size();
230  for (std::size_t i = 0; i != vsize; ++i)
231  {
232  if (indOCIHolderVec_[i] != -1)
233  {
234  v[i] = std::strtoull(pos, NULL, 10);
235  }
236  pos += colSize_;
237  }
238  }
239  else if (type_ == x_stdtm)
240  {
241  std::vector<std::tm> *vp
242  = static_cast<std::vector<std::tm> *>(data_);
243 
244  std::vector<std::tm> &v(*vp);
245 
246  ub1 *pos = reinterpret_cast<ub1*>(buf_);
247  std::size_t const vsize = v.size();
248  for (std::size_t i = 0; i != vsize; ++i)
249  {
250  if (indOCIHolderVec_[i] == -1)
251  {
252  pos += 7; // size of SQLT_DAT
253  }
254  else
255  {
256  std::tm t;
257  t.tm_isdst = -1;
258 
259  t.tm_year = (*pos++ - 100) * 100;
260  t.tm_year += *pos++ - 2000;
261  t.tm_mon = *pos++ - 1;
262  t.tm_mday = *pos++;
263  t.tm_hour = *pos++ - 1;
264  t.tm_min = *pos++ - 1;
265  t.tm_sec = *pos++ - 1;
266 
267  // normalize and compute the remaining fields
268  std::mktime(&t);
269  v[i] = t;
270  }
271  }
272  }
273  else if (type_ == x_statement)
274  {
275  statement *st = static_cast<statement *>(data_);
276  st->define_and_bind();
277  }
278 
279  // then - deal with indicators
280  if (ind != NULL)
281  {
282  std::size_t const indSize = statement_.get_number_of_rows();
283  for (std::size_t i = 0; i != indSize; ++i)
284  {
285  if (indOCIHolderVec_[i] == 0)
286  {
287  ind[i] = i_ok;
288  }
289  else if (indOCIHolderVec_[i] == -1)
290  {
291  ind[i] = i_null;
292  }
293  else
294  {
295  ind[i] = i_truncated;
296  }
297  }
298  }
299  else
300  {
301  std::size_t const indSize = indOCIHolderVec_.size();
302  for (std::size_t i = 0; i != indSize; ++i)
303  {
304  if (indOCIHolderVec_[i] == -1)
305  {
306  // fetched null and no indicator - programming error!
307  throw soci_error(
308  "Null value fetched and no indicator defined.");
309  }
310  }
311  }
312  }
313  else // gotData == false
314  {
315  // nothing to do here, vectors are truncated anyway
316  }
317 }
318 
320 {
321  switch (type_)
322  {
323  // simple cases
324  case x_char:
325  {
326  std::vector<char> *v = static_cast<std::vector<char> *>(data_);
327  v->resize(sz);
328  }
329  break;
330  case x_short:
331  {
332  std::vector<short> *v = static_cast<std::vector<short> *>(data_);
333  v->resize(sz);
334  }
335  break;
336  case x_integer:
337  {
338  std::vector<int> *v = static_cast<std::vector<int> *>(data_);
339  v->resize(sz);
340  }
341  break;
342  case x_long_long:
343  {
344  std::vector<long long> *v
345  = static_cast<std::vector<long long> *>(data_);
346  v->resize(sz);
347  }
348  break;
350  {
351  std::vector<unsigned long long> *v
352  = static_cast<std::vector<unsigned long long> *>(data_);
353  v->resize(sz);
354  }
355  break;
356  case x_double:
357  {
358  std::vector<double> *v
359  = static_cast<std::vector<double> *>(data_);
360  v->resize(sz);
361  }
362  break;
363  case x_stdstring:
364  {
365  std::vector<std::string> *v
366  = static_cast<std::vector<std::string> *>(data_);
367  v->resize(sz);
368  }
369  break;
370  case x_stdtm:
371  {
372  std::vector<std::tm> *v
373  = static_cast<std::vector<std::tm> *>(data_);
374  v->resize(sz);
375  }
376  break;
377 
378  case x_statement: break; // not supported
379  case x_rowid: break; // not supported
380  case x_blob: break; // not supported
381  }
382 }
383 
385 {
386  std::size_t sz = 0; // dummy initialization to please the compiler
387  switch (type_)
388  {
389  // simple cases
390  case x_char:
391  {
392  std::vector<char> *v = static_cast<std::vector<char> *>(data_);
393  sz = v->size();
394  }
395  break;
396  case x_short:
397  {
398  std::vector<short> *v = static_cast<std::vector<short> *>(data_);
399  sz = v->size();
400  }
401  break;
402  case x_integer:
403  {
404  std::vector<int> *v = static_cast<std::vector<int> *>(data_);
405  sz = v->size();
406  }
407  break;
408  case x_long_long:
409  {
410  std::vector<long long> *v
411  = static_cast<std::vector<long long> *>(data_);
412  sz = v->size();
413  }
414  break;
416  {
417  std::vector<unsigned long long> *v
418  = static_cast<std::vector<unsigned long long> *>(data_);
419  sz = v->size();
420  }
421  break;
422  case x_double:
423  {
424  std::vector<double> *v
425  = static_cast<std::vector<double> *>(data_);
426  sz = v->size();
427  }
428  break;
429  case x_stdstring:
430  {
431  std::vector<std::string> *v
432  = static_cast<std::vector<std::string> *>(data_);
433  sz = v->size();
434  }
435  break;
436  case x_stdtm:
437  {
438  std::vector<std::tm> *v
439  = static_cast<std::vector<std::tm> *>(data_);
440  sz = v->size();
441  }
442  break;
443 
444  case x_statement: break; // not supported
445  case x_rowid: break; // not supported
446  case x_blob: break; // not supported
447  }
448 
449  return sz;
450 }
451 
453 {
454  if (defnp_ != NULL)
455  {
456  OCIHandleFree(defnp_, OCI_HTYPE_DEFINE);
457  defnp_ = NULL;
458  }
459 
460  if (buf_ != NULL)
461  {
462  delete [] buf_;
463  buf_ = NULL;
464  }
465 }
virtual void define_by_pos(int &position, void *data, details::exchange_type type)
void throw_oracle_soci_error(sword res, OCIError *errhp)
void define_and_bind()
Definition: statement.h:206
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