odbc/standard-into-type.cpp
Go to the documentation of this file.
1 //
2 // Copyright (C) 2004-2006 Maciej Sobczak, Stephen Hutton, David Courtney
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_ODBC_SOURCE
9 #include <soci-platform.h>
10 #include "soci-odbc.h"
11 #include <ctime>
12 #include <stdio.h> // sscanf()
13 
14 using namespace soci;
15 using namespace soci::details;
16 
18  int & position, void * data, exchange_type type)
19 {
20  data_ = data;
21  type_ = type;
22  position_ = position++;
23 
24  SQLUINTEGER size = 0;
25 
26  switch (type_)
27  {
28  case x_char:
29  odbcType_ = SQL_C_CHAR;
30  size = sizeof(char) + 1;
31  buf_ = new char[size];
32  data = buf_;
33  break;
34  case x_stdstring:
35  odbcType_ = SQL_C_CHAR;
36  // Patch: set to min between column size and 100MB (used ot be 32769)
37  // Column size for text data type can be too large for buffer allocation
38  size = statement_.column_size(position_);
39  size = size > odbc_max_buffer_length ? odbc_max_buffer_length : size;
40  size++;
41  buf_ = new char[size];
42  data = buf_;
43  break;
44  case x_short:
45  odbcType_ = SQL_C_SSHORT;
46  size = sizeof(short);
47  break;
48  case x_integer:
49  odbcType_ = SQL_C_SLONG;
50  size = sizeof(int);
51  break;
52  case x_long_long:
53  if (use_string_for_bigint())
54  {
55  odbcType_ = SQL_C_CHAR;
56  size = max_bigint_length;
57  buf_ = new char[size];
58  data = buf_;
59  }
60  else // Normal case, use ODBC support.
61  {
62  odbcType_ = SQL_C_SBIGINT;
63  size = sizeof(long long);
64  }
65  break;
67  if (use_string_for_bigint())
68  {
69  odbcType_ = SQL_C_CHAR;
70  size = max_bigint_length;
71  buf_ = new char[size];
72  data = buf_;
73  }
74  else // Normal case, use ODBC support.
75  {
76  odbcType_ = SQL_C_UBIGINT;
77  size = sizeof(unsigned long long);
78  }
79  break;
80  case x_double:
81  odbcType_ = SQL_C_DOUBLE;
82  size = sizeof(double);
83  break;
84  case x_stdtm:
85  odbcType_ = SQL_C_TYPE_TIMESTAMP;
86  size = sizeof(TIMESTAMP_STRUCT);
87  buf_ = new char[size];
88  data = buf_;
89  break;
90  case x_rowid:
91  odbcType_ = SQL_C_ULONG;
92  size = sizeof(unsigned long);
93  break;
94  default:
95  throw soci_error("Into element used with non-supported type.");
96  }
97 
98  valueLen_ = 0;
99 
100  SQLRETURN rc = SQLBindCol(statement_.hstmt_, static_cast<SQLUSMALLINT>(position_),
101  static_cast<SQLUSMALLINT>(odbcType_), data, size, &valueLen_);
102  if (is_odbc_error(rc))
103  {
104  throw odbc_soci_error(SQL_HANDLE_STMT, statement_.hstmt_,
105  "into type pre_fetch");
106  }
107 }
108 
110 {
111  //...
112 }
113 
115  bool gotData, bool calledFromFetch, indicator * ind)
116 {
117  if (calledFromFetch == true && gotData == false)
118  {
119  // this is a normal end-of-rowset condition,
120  // no need to do anything (fetch() will return false)
121  return;
122  }
123 
124  if (gotData)
125  {
126  // first, deal with indicators
127  if (SQL_NULL_DATA == valueLen_)
128  {
129  if (ind == NULL)
130  {
131  throw soci_error(
132  "Null value fetched and no indicator defined.");
133  }
134 
135  *ind = i_null;
136  return;
137  }
138  else
139  {
140  if (ind != NULL)
141  {
142  *ind = i_ok;
143  }
144  }
145 
146  // only std::string and std::tm need special handling
147  if (type_ == x_char)
148  {
149  char *c = static_cast<char*>(data_);
150  *c = buf_[0];
151  }
152  if (type_ == x_stdstring)
153  {
154  std::string *s = static_cast<std::string *>(data_);
155  *s = buf_;
156  if (s->size() >= (odbc_max_buffer_length - 1))
157  {
158  throw soci_error("Buffer size overflow; maybe got too large string");
159  }
160  }
161  else if (type_ == x_stdtm)
162  {
163  std::tm *t = static_cast<std::tm *>(data_);
164 
165  TIMESTAMP_STRUCT * ts = reinterpret_cast<TIMESTAMP_STRUCT*>(buf_);
166  t->tm_isdst = -1;
167  t->tm_year = ts->year - 1900;
168  t->tm_mon = ts->month - 1;
169  t->tm_mday = ts->day;
170  t->tm_hour = ts->hour;
171  t->tm_min = ts->minute;
172  t->tm_sec = ts->second;
173 
174  // normalize and compute the remaining fields
175  std::mktime(t);
176  }
177  else if (type_ == x_long_long && use_string_for_bigint())
178  {
179  long long *ll = static_cast<long long *>(data_);
180  if (sscanf(buf_, "%" LL_FMT_FLAGS "d", ll) != 1)
181  {
182  throw soci_error("Failed to parse the returned 64-bit integer value");
183  }
184  }
185  else if (type_ == x_unsigned_long_long && use_string_for_bigint())
186  {
187  unsigned long long *ll = static_cast<unsigned long long *>(data_);
188  if (sscanf(buf_, "%" LL_FMT_FLAGS "u", ll) != 1)
189  {
190  throw soci_error("Failed to parse the returned 64-bit integer value");
191  }
192  }
193  }
194 }
195 
197 {
198  if (buf_)
199  {
200  delete [] buf_;
201  buf_ = 0;
202  }
203 }
std::size_t const odbc_max_buffer_length
Definition: soci-odbc.h:42
virtual void define_by_pos(int &position, void *data, details::exchange_type type)
bool is_odbc_error(SQLRETURN rc)
Definition: soci-odbc.h:399
virtual void post_fetch(bool gotData, bool calledFromFetch, indicator *ind)
#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