backends/oracle/statement.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 
10 #include "soci-oracle.h"
11 #include "error.h"
12 #include <soci-backend.h>
13 #include <cctype>
14 #include <cstdio>
15 #include <cstring>
16 #include <ctime>
17 #include <limits>
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  : session_(session), stmtp_(NULL), boundByName_(false), boundByPos_(false),
30  noData_(false)
31 {
32 }
33 
35 {
36  sword res = OCIHandleAlloc(session_.envhp_,
37  reinterpret_cast<dvoid**>(&stmtp_),
38  OCI_HTYPE_STMT, 0, 0);
39  if (res != OCI_SUCCESS)
40  {
41  throw soci_error("Cannot allocate statement handle");
42  }
43 }
44 
46 {
47  // deallocate statement handle
48  if (stmtp_ != NULL)
49  {
50  OCIHandleFree(stmtp_, OCI_HTYPE_STMT);
51  stmtp_ = NULL;
52  }
53 
54  boundByName_ = false;
55  boundByPos_ = false;
56 }
57 
58 void oracle_statement_backend::prepare(std::string const &query,
59  statement_type /* eType */)
60 {
61  sb4 stmtLen = static_cast<sb4>(query.size());
62  sword res = OCIStmtPrepare(stmtp_,
64  reinterpret_cast<text*>(const_cast<char*>(query.c_str())),
65  stmtLen, OCI_V7_SYNTAX, OCI_DEFAULT);
66  if (res != OCI_SUCCESS)
67  {
69  }
70 }
71 
73 {
74  sword res = OCIStmtExecute(session_.svchp_, stmtp_, session_.errhp_,
75  static_cast<ub4>(number), 0, 0, 0, OCI_DEFAULT);
76 
77  if (res == OCI_SUCCESS || res == OCI_SUCCESS_WITH_INFO)
78  {
79  noData_ = false;
80  return ef_success;
81  }
82  else if (res == OCI_NO_DATA)
83  {
84  noData_ = true;
85  return ef_no_data;
86  }
87  else
88  {
90  return ef_no_data; // unreachable dummy return to please the compiler
91  }
92 }
93 
95 {
96  if (noData_)
97  {
98  return ef_no_data;
99  }
100 
101  sword res = OCIStmtFetch(stmtp_, session_.errhp_,
102  static_cast<ub4>(number), OCI_FETCH_NEXT, OCI_DEFAULT);
103 
104  if (res == OCI_SUCCESS || res == OCI_SUCCESS_WITH_INFO)
105  {
106  return ef_success;
107  }
108  else if (res == OCI_NO_DATA)
109  {
110  noData_ = true;
111  return ef_no_data;
112  }
113  else
114  {
116  return ef_no_data; // unreachable dummy return to please the compiler
117  }
118 }
119 
121 {
122  ub4 row_count;
123  sword res = OCIAttrGet(static_cast<dvoid*>(stmtp_),
124  OCI_HTYPE_STMT, &row_count,
125  0, OCI_ATTR_ROW_COUNT, session_.errhp_);
126 
127  if (res != OCI_SUCCESS)
128  {
130  }
131 
132  return row_count;
133 }
134 
136 {
137  int rows;
138  sword res = OCIAttrGet(static_cast<dvoid*>(stmtp_),
139  OCI_HTYPE_STMT, static_cast<dvoid*>(&rows),
140  0, OCI_ATTR_ROWS_FETCHED, session_.errhp_);
141 
142  if (res != OCI_SUCCESS)
143  {
145  }
146 
147  return rows;
148 }
149 
151  std::string const &query)
152 {
153  std::string newQuery("begin ");
154  newQuery += query;
155  newQuery += "; end;";
156  return newQuery;
157 }
158 
160 {
161  sword res = OCIStmtExecute(session_.svchp_, stmtp_, session_.errhp_,
162  1, 0, 0, 0, OCI_DESCRIBE_ONLY);
163  if (res != OCI_SUCCESS)
164  {
166  }
167 
168  int cols;
169  res = OCIAttrGet(static_cast<dvoid*>(stmtp_),
170  static_cast<ub4>(OCI_HTYPE_STMT), static_cast<dvoid*>(&cols),
171  0, static_cast<ub4>(OCI_ATTR_PARAM_COUNT), session_.errhp_);
172 
173  if (res != OCI_SUCCESS)
174  {
176  }
177 
178  return cols;
179 }
180 
182  std::string &columnName)
183 {
184  int size;
185  int precision;
186  int scale;
187 
188  ub2 dbtype;
189  text* dbname;
190  ub4 nameLength;
191 
192  ub2 dbsize;
193  sb2 dbprec;
194  ub1 dbscale; //sb2 in some versions of Oracle?
195 
196  // Get the column handle
197  OCIParam* colhd;
198  sword res = OCIParamGet(reinterpret_cast<dvoid*>(stmtp_),
199  static_cast<ub4>(OCI_HTYPE_STMT),
200  reinterpret_cast<OCIError*>(session_.errhp_),
201  reinterpret_cast<dvoid**>(&colhd),
202  static_cast<ub4>(colNum));
203  if (res != OCI_SUCCESS)
204  {
206  }
207 
208  // Get the column name
209  res = OCIAttrGet(reinterpret_cast<dvoid*>(colhd),
210  static_cast<ub4>(OCI_DTYPE_PARAM),
211  reinterpret_cast<dvoid**>(&dbname),
212  reinterpret_cast<ub4*>(&nameLength),
213  static_cast<ub4>(OCI_ATTR_NAME),
214  reinterpret_cast<OCIError*>(session_.errhp_));
215  if (res != OCI_SUCCESS)
216  {
218  }
219 
220  // Get the column type
221  res = OCIAttrGet(reinterpret_cast<dvoid*>(colhd),
222  static_cast<ub4>(OCI_DTYPE_PARAM),
223  reinterpret_cast<dvoid*>(&dbtype),
224  0,
225  static_cast<ub4>(OCI_ATTR_DATA_TYPE),
226  reinterpret_cast<OCIError*>(session_.errhp_));
227  if (res != OCI_SUCCESS)
228  {
230  }
231 
232  // get the data size
233  res = OCIAttrGet(reinterpret_cast<dvoid*>(colhd),
234  static_cast<ub4>(OCI_DTYPE_PARAM),
235  reinterpret_cast<dvoid*>(&dbsize),
236  0,
237  static_cast<ub4>(OCI_ATTR_DATA_SIZE),
238  reinterpret_cast<OCIError*>(session_.errhp_));
239  if (res != OCI_SUCCESS)
240  {
242  }
243 
244  // get the precision
245  res = OCIAttrGet(reinterpret_cast<dvoid*>(colhd),
246  static_cast<ub4>(OCI_DTYPE_PARAM),
247  reinterpret_cast<dvoid*>(&dbprec),
248  0,
249  static_cast<ub4>(OCI_ATTR_PRECISION),
250  reinterpret_cast<OCIError*>(session_.errhp_));
251  if (res != OCI_SUCCESS)
252  {
254  }
255 
256  // get the scale
257  res = OCIAttrGet(reinterpret_cast<dvoid*>(colhd),
258  static_cast<ub4>(OCI_DTYPE_PARAM),
259  reinterpret_cast<dvoid*>(&dbscale),
260  0,
261  static_cast<ub4>(OCI_ATTR_SCALE),
262  reinterpret_cast<OCIError*>(session_.errhp_));
263  if (res != OCI_SUCCESS)
264  {
266  }
267 
268  columnName.assign(dbname, dbname + nameLength);
269  size = static_cast<int>(dbsize);
270  precision = static_cast<int>(dbprec);
271  scale = static_cast<int>(dbscale);
272 
273  switch (dbtype)
274  {
275  case SQLT_CHR:
276  case SQLT_AFC:
277  type = dt_string;
278  break;
279  case SQLT_NUM:
280  if (scale > 0)
281  {
283  type = dt_string;
284  else
285  type = dt_double;
286  }
287  else if (precision <= std::numeric_limits<int>::digits10)
288  {
289  type = dt_integer;
290  }
291  else
292  {
293  type = dt_long_long;
294  }
295  break;
296  case SQLT_DAT:
297  type = dt_date;
298  break;
299  }
300 }
301 
302 std::size_t oracle_statement_backend::column_size(int position)
303 {
304  // Note: we may want to optimize so that the OCI_DESCRIBE_ONLY call
305  // happens only once per statement.
306  // Possibly use existing statement::describe() / make column prop
307  // access lazy at same time
308 
309  int colSize(0);
310 
311  sword res = OCIStmtExecute(session_.svchp_, stmtp_,
312  session_.errhp_, 1, 0, 0, 0, OCI_DESCRIBE_ONLY);
313  if (res != OCI_SUCCESS)
314  {
316  }
317 
318  // Get The Column Handle
319  OCIParam* colhd;
320  res = OCIParamGet(reinterpret_cast<dvoid*>(stmtp_),
321  static_cast<ub4>(OCI_HTYPE_STMT),
322  reinterpret_cast<OCIError*>(session_.errhp_),
323  reinterpret_cast<dvoid**>(&colhd),
324  static_cast<ub4>(position));
325  if (res != OCI_SUCCESS)
326  {
328  }
329 
330  // Get The Data Size
331  res = OCIAttrGet(reinterpret_cast<dvoid*>(colhd),
332  static_cast<ub4>(OCI_DTYPE_PARAM),
333  reinterpret_cast<dvoid*>(&colSize),
334  0,
335  static_cast<ub4>(OCI_ATTR_DATA_SIZE),
336  reinterpret_cast<OCIError*>(session_.errhp_));
337  if (res != OCI_SUCCESS)
338  {
340  }
341 
342  return static_cast<std::size_t>(colSize);
343 }
virtual exec_fetch_result execute(int number)
virtual void describe_column(int colNum, data_type &dtype, std::string &columnName)
virtual std::string rewrite_for_procedure_call(std::string const &query)
oracle_statement_backend(oracle_session_backend &session)
virtual exec_fetch_result fetch(int number)
oracle_session_backend & session_
Definition: soci-oracle.h:206
void throw_oracle_soci_error(sword res, OCIError *errhp)
virtual void prepare(std::string const &query, details::statement_type eType)


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