oracle/vector-use-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 "error.h"
11 #include <soci-platform.h>
12 #include <cctype>
13 #include <cstdio>
14 #include <cstring>
15 #include <ctime>
16 #include <sstream>
17 
18 #ifdef _MSC_VER
19 #pragma warning(disable:4355)
20 #define snprintf _snprintf
21 #endif
22 
23 using namespace soci;
24 using namespace soci::details;
25 using namespace soci::details::oracle;
26 
28 {
29  if (size == 0)
30  {
31  throw soci_error("Vectors of size 0 are not allowed.");
32  }
33 
34  indOCIHolderVec_.resize(size);
35  indOCIHolders_ = &indOCIHolderVec_[0];
36 }
37 
39  void *&data, sb4 &size, ub2 &oracleType)
40 {
41  switch (type_)
42  {
43  // simple cases
44  case x_char:
45  {
46  oracleType = SQLT_AFC;
47  size = sizeof(char);
48  std::vector<char> *vp = static_cast<std::vector<char> *>(data);
49  std::vector<char> &v(*vp);
50  prepare_indicators(v.size());
51  data = &v[0];
52  }
53  break;
54  case x_short:
55  {
56  oracleType = SQLT_INT;
57  size = sizeof(short);
58  std::vector<short> *vp = static_cast<std::vector<short> *>(data);
59  std::vector<short> &v(*vp);
60  prepare_indicators(v.size());
61  data = &v[0];
62  }
63  break;
64  case x_integer:
65  {
66  oracleType = SQLT_INT;
67  size = sizeof(int);
68  std::vector<int> *vp = static_cast<std::vector<int> *>(data);
69  std::vector<int> &v(*vp);
70  prepare_indicators(v.size());
71  data = &v[0];
72  }
73  break;
74  case x_double:
75  {
76  oracleType = SQLT_FLT;
77  size = sizeof(double);
78  std::vector<double> *vp = static_cast<std::vector<double> *>(data);
79  std::vector<double> &v(*vp);
80  prepare_indicators(v.size());
81  data = &v[0];
82  }
83  break;
84 
85  // cases that require adjustments and buffer management
86 
87  case x_long_long:
88  {
89  std::vector<long long> *vp
90  = static_cast<std::vector<long long> *>(data);
91  std::vector<long long> &v(*vp);
92 
93  std::size_t const vecSize = v.size();
94  std::size_t const entrySize = 100; // arbitrary
95  std::size_t const bufSize = entrySize * vecSize;
96  buf_ = new char[bufSize];
97 
98  oracleType = SQLT_STR;
99  data = buf_;
100  size = entrySize;
101 
102  prepare_indicators(vecSize);
103  }
104  break;
106  {
107  std::vector<unsigned long long> *vp
108  = static_cast<std::vector<unsigned long long> *>(data);
109  std::vector<unsigned long long> &v(*vp);
110 
111  std::size_t const vecSize = v.size();
112  std::size_t const entrySize = 100; // arbitrary
113  std::size_t const bufSize = entrySize * vecSize;
114  buf_ = new char[bufSize];
115 
116  oracleType = SQLT_STR;
117  data = buf_;
118  size = entrySize;
119 
120  prepare_indicators(vecSize);
121  }
122  break;
123  case x_stdstring:
124  {
125  std::vector<std::string> *vp
126  = static_cast<std::vector<std::string> *>(data);
127  std::vector<std::string> &v(*vp);
128 
129  std::size_t maxSize = 0;
130  std::size_t const vecSize = v.size();
131  prepare_indicators(vecSize);
132  for (std::size_t i = 0; i != vecSize; ++i)
133  {
134  std::size_t sz = v[i].length();
135  sizes_.push_back(static_cast<ub2>(sz));
136  maxSize = sz > maxSize ? sz : maxSize;
137  }
138 
139  buf_ = new char[maxSize * vecSize];
140  char *pos = buf_;
141  for (std::size_t i = 0; i != vecSize; ++i)
142  {
143  strncpy(pos, v[i].c_str(), v[i].length());
144  pos += maxSize;
145  }
146 
147  oracleType = SQLT_CHR;
148  data = buf_;
149  size = static_cast<sb4>(maxSize);
150  }
151  break;
152  case x_stdtm:
153  {
154  std::vector<std::tm> *vp
155  = static_cast<std::vector<std::tm> *>(data);
156 
157  prepare_indicators(vp->size());
158 
159  sb4 const dlen = 7; // size of SQLT_DAT
160  buf_ = new char[dlen * vp->size()];
161 
162  oracleType = SQLT_DAT;
163  data = buf_;
164  size = dlen;
165  }
166  break;
167 
168  case x_statement: break; // not supported
169  case x_rowid: break; // not supported
170  case x_blob: break; // not supported
171  }
172 }
173 
175  void *data, exchange_type type)
176 {
177  data_ = data; // for future reference
178  type_ = type; // for future reference
179 
180  ub2 oracleType;
181  sb4 size;
182 
183  prepare_for_bind(data, size, oracleType);
184 
185  ub2 *sizesP = 0; // used only for std::string
186  if (type == x_stdstring)
187  {
188  sizesP = &sizes_[0];
189  }
190 
191  sword res = OCIBindByPos(statement_.stmtp_, &bindp_,
192  statement_.session_.errhp_,
193  position++, data, size, oracleType,
194  indOCIHolders_, sizesP, 0, 0, 0, OCI_DEFAULT);
195  if (res != OCI_SUCCESS)
196  {
197  throw_oracle_soci_error(res, statement_.session_.errhp_);
198  }
199 }
200 
202  std::string const &name, void *data, exchange_type type)
203 {
204  data_ = data; // for future reference
205  type_ = type; // for future reference
206 
207  ub2 oracleType;
208  sb4 size;
209 
210  prepare_for_bind(data, size, oracleType);
211 
212  ub2 *sizesP = 0; // used only for std::string
213  if (type == x_stdstring)
214  {
215  sizesP = &sizes_[0];
216  }
217 
218  sword res = OCIBindByName(statement_.stmtp_, &bindp_,
219  statement_.session_.errhp_,
220  reinterpret_cast<text*>(const_cast<char*>(name.c_str())),
221  static_cast<sb4>(name.size()),
222  data, size, oracleType,
223  indOCIHolders_, sizesP, 0, 0, 0, OCI_DEFAULT);
224  if (res != OCI_SUCCESS)
225  {
226  throw_oracle_soci_error(res, statement_.session_.errhp_);
227  }
228 }
229 
231 {
232  // first deal with data
233  if (type_ == x_stdstring)
234  {
235  // nothing to do - it's already done during bind
236  // (and it's probably impossible to separate them, because
237  // changes in the string size could not be handled here)
238  }
239  else if (type_ == x_long_long)
240  {
241  std::vector<long long> *vp
242  = static_cast<std::vector<long long> *>(data_);
243  std::vector<long long> &v(*vp);
244 
245  char *pos = buf_;
246  std::size_t const entrySize = 100; // arbitrary, but consistent
247  std::size_t const vecSize = v.size();
248  for (std::size_t i = 0; i != vecSize; ++i)
249  {
250  snprintf(pos, entrySize, "%" LL_FMT_FLAGS "d", v[i]);
251  pos += entrySize;
252  }
253  }
254  else if (type_ == x_unsigned_long_long)
255  {
256  std::vector<unsigned long long> *vp
257  = static_cast<std::vector<unsigned long long> *>(data_);
258  std::vector<unsigned long long> &v(*vp);
259 
260  char *pos = buf_;
261  std::size_t const entrySize = 100; // arbitrary, but consistent
262  std::size_t const vecSize = v.size();
263  for (std::size_t i = 0; i != vecSize; ++i)
264  {
265  snprintf(pos, entrySize, "%" LL_FMT_FLAGS "u", v[i]);
266  pos += entrySize;
267  }
268  }
269  else if (type_ == x_stdtm)
270  {
271  std::vector<std::tm> *vp
272  = static_cast<std::vector<std::tm> *>(data_);
273  std::vector<std::tm> &v(*vp);
274 
275  ub1* pos = reinterpret_cast<ub1*>(buf_);
276  std::size_t const vsize = v.size();
277  for (std::size_t i = 0; i != vsize; ++i)
278  {
279  *pos++ = static_cast<ub1>(100 + (1900 + v[i].tm_year) / 100);
280  *pos++ = static_cast<ub1>(100 + v[i].tm_year % 100);
281  *pos++ = static_cast<ub1>(v[i].tm_mon + 1);
282  *pos++ = static_cast<ub1>(v[i].tm_mday);
283  *pos++ = static_cast<ub1>(v[i].tm_hour + 1);
284  *pos++ = static_cast<ub1>(v[i].tm_min + 1);
285  *pos++ = static_cast<ub1>(v[i].tm_sec + 1);
286  }
287  }
288 
289  // then handle indicators
290  if (ind != NULL)
291  {
292  std::size_t const vsize = size();
293  for (std::size_t i = 0; i != vsize; ++i, ++ind)
294  {
295  if (*ind == i_null)
296  {
297  indOCIHolderVec_[i] = -1; // null
298  }
299  else
300  {
301  indOCIHolderVec_[i] = 0; // value is OK
302  }
303  }
304  }
305  else
306  {
307  // no indicators - treat all fields as OK
308  std::size_t const vsize = size();
309  for (std::size_t i = 0; i != vsize; ++i, ++ind)
310  {
311  indOCIHolderVec_[i] = 0; // value is OK
312  }
313  }
314 }
315 
317 {
318  std::size_t sz = 0; // dummy initialization to please the compiler
319  switch (type_)
320  {
321  // simple cases
322  case x_char:
323  {
324  std::vector<char> *vp = static_cast<std::vector<char> *>(data_);
325  sz = vp->size();
326  }
327  break;
328  case x_short:
329  {
330  std::vector<short> *vp = static_cast<std::vector<short> *>(data_);
331  sz = vp->size();
332  }
333  break;
334  case x_integer:
335  {
336  std::vector<int> *vp = static_cast<std::vector<int> *>(data_);
337  sz = vp->size();
338  }
339  break;
340  case x_long_long:
341  {
342  std::vector<long long> *vp
343  = static_cast<std::vector<long long> *>(data_);
344  sz = vp->size();
345  }
346  break;
348  {
349  std::vector<unsigned long long> *vp
350  = static_cast<std::vector<unsigned long long> *>(data_);
351  sz = vp->size();
352  }
353  break;
354  case x_double:
355  {
356  std::vector<double> *vp
357  = static_cast<std::vector<double> *>(data_);
358  sz = vp->size();
359  }
360  break;
361  case x_stdstring:
362  {
363  std::vector<std::string> *vp
364  = static_cast<std::vector<std::string> *>(data_);
365  sz = vp->size();
366  }
367  break;
368  case x_stdtm:
369  {
370  std::vector<std::tm> *vp
371  = static_cast<std::vector<std::tm> *>(data_);
372  sz = vp->size();
373  }
374  break;
375 
376  case x_statement: break; // not supported
377  case x_rowid: break; // not supported
378  case x_blob: break; // not supported
379  }
380 
381  return sz;
382 }
383 
385 {
386  if (buf_ != NULL)
387  {
388  delete [] buf_;
389  buf_ = NULL;
390  }
391 
392  if (bindp_ != NULL)
393  {
394  OCIHandleFree(bindp_, OCI_HTYPE_DEFINE);
395  bindp_ = NULL;
396  }
397 }
virtual void bind_by_name(std::string const &name, void *data, details::exchange_type type)
virtual void pre_use(indicator const *ind)
virtual void bind_by_pos(int &position, void *data, details::exchange_type type)
void prepare_for_bind(void *&data, sb4 &size, ub2 &oracleType)
void throw_oracle_soci_error(sword res, OCIError *errhp)
#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