oracle/standard-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 "blob.h"
11 #include "error.h"
12 #include "rowid.h"
13 #include "statement.h"
14 #include <soci-platform.h>
15 #include <cctype>
16 #include <cstdio>
17 #include <cstring>
18 #include <cstdlib>
19 #include <ctime>
20 #include <sstream>
21 
22 #ifdef _MSC_VER
23 #pragma warning(disable:4355)
24 #endif
25 
26 using namespace soci;
27 using namespace soci::details;
28 using namespace soci::details::oracle;
29 
32 {
33  return new oracle_standard_into_type_backend(*this);
34 }
35 
38 {
39  return new oracle_standard_use_type_backend(*this);
40 }
41 
44 {
45  return new oracle_vector_into_type_backend(*this);
46 }
47 
50 {
51  return new oracle_vector_use_type_backend(*this);
52 }
53 
55  int &position, void *data, exchange_type type)
56 {
57  data_ = data; // for future reference
58  type_ = type; // for future reference
59 
60  ub2 oracleType = 0; // dummy initialization to please the compiler
61  sb4 size = 0; // also dummy
62 
63  switch (type)
64  {
65  // simple cases
66  case x_char:
67  oracleType = SQLT_AFC;
68  size = sizeof(char);
69  break;
70  case x_short:
71  oracleType = SQLT_INT;
72  size = sizeof(short);
73  break;
74  case x_integer:
75  oracleType = SQLT_INT;
76  size = sizeof(int);
77  break;
78  case x_double:
79  oracleType = SQLT_FLT;
80  size = sizeof(double);
81  break;
82 
83  // cases that require adjustments and buffer management
84  case x_long_long:
86  oracleType = SQLT_STR;
87  size = 100; // arbitrary buffer length
88  buf_ = new char[size];
89  data = buf_;
90  break;
91  case x_stdstring:
92  oracleType = SQLT_STR;
93  size = 32769; // support selecting strings from LONG columns
94  buf_ = new char[size];
95  data = buf_;
96  break;
97  case x_stdtm:
98  oracleType = SQLT_DAT;
99  size = 7 * sizeof(ub1);
100  buf_ = new char[size];
101  data = buf_;
102  break;
103 
104  // cases that require special handling
105  case x_statement:
106  {
107  oracleType = SQLT_RSET;
108 
109  statement *st = static_cast<statement *>(data);
110  st->alloc();
111 
113  = static_cast<oracle_statement_backend *>(st->get_backend());
114  size = 0;
115  data = &stbe->stmtp_;
116  }
117  break;
118  case x_rowid:
119  {
120  oracleType = SQLT_RDD;
121 
122  rowid *rid = static_cast<rowid *>(data);
123 
125  = static_cast<oracle_rowid_backend *>(rid->get_backend());
126 
127  size = 0;
128  data = &rbe->rowidp_;
129  }
130  break;
131  case x_blob:
132  {
133  oracleType = SQLT_BLOB;
134 
135  blob *b = static_cast<blob *>(data);
136 
138  = static_cast<oracle_blob_backend *>(b->get_backend());
139 
140  size = 0;
141  data = &bbe->lobp_;
142  }
143  break;
144  }
145 
146  sword res = OCIDefineByPos(statement_.stmtp_, &defnp_,
147  statement_.session_.errhp_,
148  position++, data, size, oracleType,
149  &indOCIHolder_, 0, &rCode_, OCI_DEFAULT);
150 
151  if (res != OCI_SUCCESS)
152  {
153  throw_oracle_soci_error(res, statement_.session_.errhp_);
154  }
155 }
156 
158 {
159  // nothing to do except with Statement into objects
160 
161  if (type_ == x_statement)
162  {
163  statement *st = static_cast<statement *>(data_);
164  st->undefine_and_bind();
165  }
166 }
167 
169  bool gotData, bool calledFromFetch, indicator *ind)
170 {
171  // first, deal with data
172  if (gotData)
173  {
174  // only std::string, std::tm and Statement need special handling
175  if (type_ == x_stdstring)
176  {
177  if (indOCIHolder_ != -1)
178  {
179  std::string *s = static_cast<std::string *>(data_);
180  *s = buf_;
181  }
182  }
183  else if (type_ == x_long_long)
184  {
185  if (indOCIHolder_ != -1)
186  {
187  long long *v = static_cast<long long *>(data_);
188  *v = std::strtoll(buf_, NULL, 10);
189  }
190  }
191  else if (type_ == x_unsigned_long_long)
192  {
193  if (indOCIHolder_ != -1)
194  {
195  unsigned long long *v = static_cast<unsigned long long *>(data_);
196  *v = std::strtoull(buf_, NULL, 10);
197  }
198  }
199  else if (type_ == x_stdtm)
200  {
201  if (indOCIHolder_ != -1)
202  {
203  std::tm *t = static_cast<std::tm *>(data_);
204 
205  ub1 *pos = reinterpret_cast<ub1*>(buf_);
206  t->tm_isdst = -1;
207  t->tm_year = (*pos++ - 100) * 100;
208  t->tm_year += *pos++ - 2000;
209  t->tm_mon = *pos++ - 1;
210  t->tm_mday = *pos++;
211  t->tm_hour = *pos++ - 1;
212  t->tm_min = *pos++ - 1;
213  t->tm_sec = *pos++ - 1;
214 
215  // normalize and compute the remaining fields
216  std::mktime(t);
217  }
218  }
219  else if (type_ == x_statement)
220  {
221  statement *st = static_cast<statement *>(data_);
222  st->define_and_bind();
223  }
224  }
225 
226  // then - deal with indicators
227  if (calledFromFetch == true && gotData == false)
228  {
229  // this is a normal end-of-rowset condition,
230  // no need to set anything (fetch() will return false)
231  return;
232  }
233  if (ind != NULL)
234  {
235  if (gotData)
236  {
237  if (indOCIHolder_ == 0)
238  {
239  *ind = i_ok;
240  }
241  else if (indOCIHolder_ == -1)
242  {
243  *ind = i_null;
244  }
245  else
246  {
247  *ind = i_truncated;
248  }
249  }
250  }
251  else
252  {
253  if (indOCIHolder_ == -1)
254  {
255  // fetched null and no indicator - programming error!
256  throw soci_error("Null value fetched and no indicator defined.");
257  }
258  }
259 }
260 
262 {
263  if (defnp_ != NULL)
264  {
265  OCIHandleFree(defnp_, OCI_HTYPE_DEFINE);
266  defnp_ = NULL;
267  }
268 
269  if (buf_ != NULL)
270  {
271  delete [] buf_;
272  buf_ = NULL;
273  }
274 }
details::statement_backend * get_backend()
Definition: statement.h:243
details::rowid_backend * get_backend()
Definition: rowid.h:33
void undefine_and_bind()
Definition: statement.h:207
void throw_oracle_soci_error(sword res, OCIError *errhp)
virtual oracle_standard_into_type_backend * make_into_type_backend()
virtual oracle_vector_into_type_backend * make_vector_into_type_backend()
void define_and_bind()
Definition: statement.h:206
details::blob_backend * get_backend()
Definition: blob.h:39
virtual void define_by_pos(int &position, void *data, details::exchange_type type)
OCILobLocator * lobp_
Definition: soci-oracle.h:240
virtual void post_fetch(bool gotData, bool calledFromFetch, indicator *ind)
virtual oracle_vector_use_type_backend * make_vector_use_type_backend()
virtual oracle_standard_use_type_backend * make_use_type_backend()


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