db2/standard-use-type.cpp
Go to the documentation of this file.
1 //
2 // Copyright (C) 2011-2013 Denis Chapligin
3 // Copyright (C) 2004-2006 Maciej Sobczak, Stephen Hutton, David Courtney
4 // Distributed under the Boost Software License, Version 1.0.
5 // (See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
7 
8 #define SOCI_DB2_SOURCE
9 #include "soci-db2.h"
10 #include <cctype>
11 #include <cstdio>
12 #include <cstring>
13 #include <ctime>
14 #include <sstream>
15 
16 using namespace soci;
17 using namespace soci::details;
18 
20  void *data, SQLLEN &size, SQLSMALLINT &sqlType, SQLSMALLINT &cType)
21 {
22  switch (type)
23  {
24  // simple cases
25  case x_short:
26  sqlType = SQL_SMALLINT;
27  cType = SQL_C_SSHORT;
28  size = sizeof(short);
29  break;
30  case x_integer:
31  sqlType = SQL_INTEGER;
32  cType = SQL_C_SLONG;
33  size = sizeof(int);
34  break;
35  case x_long_long:
36  sqlType = SQL_BIGINT;
37  cType = SQL_C_SBIGINT;
38  size = sizeof(long long);
39  break;
41  sqlType = SQL_BIGINT;
42  cType = SQL_C_UBIGINT;
43  size = sizeof(unsigned long long);
44  break;
45  case x_double:
46  sqlType = SQL_DOUBLE;
47  cType = SQL_C_DOUBLE;
48  size = sizeof(double);
49  break;
50 
51  // cases that require adjustments and buffer management
52  case x_char:
53  {
54  sqlType = SQL_CHAR;
55  cType = SQL_C_CHAR;
56  size = sizeof(char) + 1;
57  buf = new char[size];
58  char *c = static_cast<char*>(data);
59  buf[0] = *c;
60  buf[1] = '\0';
61  ind = SQL_NTS;
62  }
63  break;
64  case x_stdstring:
65  {
66  // TODO: No textual value is assigned here!
67 
68  std::string* s = static_cast<std::string*>(data);
69  sqlType = SQL_LONGVARCHAR;
70  cType = SQL_C_CHAR;
71  size = s->size() + 1;
72  buf = new char[size];
73  strncpy(buf, s->c_str(), size);
74  ind = SQL_NTS;
75  }
76  break;
77  case x_stdtm:
78  {
79  sqlType = SQL_TIMESTAMP;
80  cType = SQL_C_TIMESTAMP;
81  buf = new char[sizeof(TIMESTAMP_STRUCT)];
82  std::tm *t = static_cast<std::tm *>(data);
83  data = buf;
84  size = 19; // This number is not the size in bytes, but the number
85  // of characters in the date if it was written out
86  // yyyy-mm-dd hh:mm:ss
87 
88  TIMESTAMP_STRUCT * ts = reinterpret_cast<TIMESTAMP_STRUCT*>(buf);
89 
90  ts->year = static_cast<SQLSMALLINT>(t->tm_year + 1900);
91  ts->month = static_cast<SQLUSMALLINT>(t->tm_mon + 1);
92  ts->day = static_cast<SQLUSMALLINT>(t->tm_mday);
93  ts->hour = static_cast<SQLUSMALLINT>(t->tm_hour);
94  ts->minute = static_cast<SQLUSMALLINT>(t->tm_min);
95  ts->second = static_cast<SQLUSMALLINT>(t->tm_sec);
96  ts->fraction = 0;
97  }
98  break;
99 
100  case x_blob:
101  break;
102  case x_statement:
103  case x_rowid:
104  break;
105  }
106 
107  // Return either the pointer to C++ data itself or the buffer that we
108  // allocated, if any.
109  return buf ? buf : data;
110 }
111 
113  int &position, void *data, exchange_type type, bool /* readOnly */)
114 {
115  if (statement_.use_binding_method_ == details::db2::BOUND_BY_NAME)
116  {
117  throw soci_error("Binding for use elements must be either by position or by name.");
118  }
119  statement_.use_binding_method_ = details::db2::BOUND_BY_POSITION;
120 
121  this->data = data; // for future reference
122  this->type = type; // for future reference
123  this->position = position++;
124 }
125 
127  std::string const &name, void *data, exchange_type type, bool /* readOnly */)
128 {
129  if (statement_.use_binding_method_ == details::db2::BOUND_BY_POSITION)
130  {
131  throw soci_error("Binding for use elements must be either by position or by name.");
132  }
133  statement_.use_binding_method_ = details::db2::BOUND_BY_NAME;
134 
135  int position = -1;
136  int count = 1;
137 
138  for (std::vector<std::string>::iterator it = statement_.names.begin();
139  it != statement_.names.end(); ++it)
140  {
141  if (*it == name)
142  {
143  position = count;
144  break;
145  }
146  count++;
147  }
148 
149  if (position != -1)
150  {
151  this->data = data; // for future reference
152  this->type = type; // for future reference
153  this->position = position;
154  }
155  else
156  {
157  std::ostringstream ss;
158  ss << "Unable to find name '" << name << "' to bind to";
159  throw soci_error(ss.str().c_str());
160  }
161 }
162 
164 {
165  // first deal with data
166  SQLSMALLINT sqlType;
167  SQLSMALLINT cType;
168  SQLLEN size;
169 
170  void *sqlData = prepare_for_bind(data, size, sqlType, cType);
171 
172  SQLRETURN cliRC = SQLBindParameter(statement_.hStmt,
173  static_cast<SQLUSMALLINT>(position),
174  SQL_PARAM_INPUT,
175  cType, sqlType, size, 0, sqlData, size, &ind);
176 
177  if (cliRC != SQL_SUCCESS)
178  {
179  throw db2_soci_error("Error while binding value",cliRC);
180  }
181 
182  // then handle indicators
183  if (ind_ptr != NULL && *ind_ptr == i_null)
184  {
185  ind = SQL_NULL_DATA; // null
186  }
187 }
188 
189 void db2_standard_use_type_backend::post_use(bool /*gotData*/, indicator* /*ind*/)
190 {
191 
192 }
193 
195 {
196  if (buf != NULL)
197  {
198  delete [] buf;
199  buf = NULL;
200  }
201 }
void bind_by_name(std::string const &name, void *data, details::exchange_type type, bool readOnly)
void post_use(bool gotData, indicator *ind)
void * prepare_for_bind(void *data, SQLLEN &size, SQLSMALLINT &sqlType, SQLSMALLINT &cType)
void bind_by_pos(int &position, void *data, details::exchange_type type, bool readOnly)


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