postgresql/vector-use-type.cpp
Go to the documentation of this file.
1 //
2 // Copyright (C) 2004-2008 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_POSTGRESQL_SOURCE
9 #include <soci-platform.h>
10 #include "soci-postgresql.h"
11 #include "common.h"
12 #include <libpq/libpq-fs.h> // libpq
13 #include <cctype>
14 #include <cstdio>
15 #include <cstring>
16 #include <ctime>
17 #include <limits>
18 #include <sstream>
19 
20 #ifdef SOCI_POSTGRESQL_NOPARAMS
21 #ifndef SOCI_POSTGRESQL_NOBINDBYNAME
22 #define SOCI_POSTGRESQL_NOBINDBYNAME
23 #endif // SOCI_POSTGRESQL_NOBINDBYNAME
24 #endif // SOCI_POSTGRESQL_NOPARAMS
25 
26 #ifdef _MSC_VER
27 #pragma warning(disable:4355 4996)
28 #define snprintf _snprintf
29 #endif
30 
31 using namespace soci;
32 using namespace soci::details;
33 using namespace soci::details::postgresql;
34 
35 
37  void * data, exchange_type type)
38 {
39  data_ = data;
40  type_ = type;
41  position_ = position++;
42 }
43 
45  std::string const & name, void * data, exchange_type type)
46 {
47  data_ = data;
48  type_ = type;
49  name_ = name;
50 }
51 
53 {
54  std::size_t const vsize = size();
55  for (size_t i = 0; i != vsize; ++i)
56  {
57  char * buf;
58 
59  // the data in vector can be either i_ok or i_null
60  if (ind != NULL && ind[i] == i_null)
61  {
62  buf = NULL;
63  }
64  else
65  {
66  // allocate and fill the buffer with text-formatted client data
67  switch (type_)
68  {
69  case x_char:
70  {
71  std::vector<char> * pv
72  = static_cast<std::vector<char> *>(data_);
73  std::vector<char> & v = *pv;
74 
75  buf = new char[2];
76  buf[0] = v[i];
77  buf[1] = '\0';
78  }
79  break;
80  case x_stdstring:
81  {
82  std::vector<std::string> * pv
83  = static_cast<std::vector<std::string> *>(data_);
84  std::vector<std::string> & v = *pv;
85 
86  buf = new char[v[i].size() + 1];
87  std::strcpy(buf, v[i].c_str());
88  }
89  break;
90  case x_short:
91  {
92  std::vector<short> * pv
93  = static_cast<std::vector<short> *>(data_);
94  std::vector<short> & v = *pv;
95 
96  std::size_t const bufSize
97  = std::numeric_limits<short>::digits10 + 3;
98  buf = new char[bufSize];
99  snprintf(buf, bufSize, "%d", static_cast<int>(v[i]));
100  }
101  break;
102  case x_integer:
103  {
104  std::vector<int> * pv
105  = static_cast<std::vector<int> *>(data_);
106  std::vector<int> & v = *pv;
107 
108  std::size_t const bufSize
109  = std::numeric_limits<int>::digits10 + 3;
110  buf = new char[bufSize];
111  snprintf(buf, bufSize, "%d", v[i]);
112  }
113  break;
114  case x_long_long:
115  {
116  std::vector<long long>* pv
117  = static_cast<std::vector<long long>*>(data_);
118  std::vector<long long>& v = *pv;
119 
120  std::size_t const bufSize
121  = std::numeric_limits<long long>::digits10 + 3;
122  buf = new char[bufSize];
123  snprintf(buf, bufSize, "%" LL_FMT_FLAGS "d", v[i]);
124  }
125  break;
127  {
128  std::vector<unsigned long long>* pv
129  = static_cast<std::vector<unsigned long long>*>(data_);
130  std::vector<unsigned long long>& v = *pv;
131 
132  std::size_t const bufSize
133  = std::numeric_limits<unsigned long long>::digits10 + 2;
134  buf = new char[bufSize];
135  snprintf(buf, bufSize, "%" LL_FMT_FLAGS "u", v[i]);
136  }
137  break;
138  case x_double:
139  {
140  // no need to overengineer it (KISS)...
141 
142  std::vector<double> * pv
143  = static_cast<std::vector<double> *>(data_);
144  std::vector<double> & v = *pv;
145 
146  std::size_t const bufSize = 100;
147  buf = new char[bufSize];
148 
149  snprintf(buf, bufSize, "%.20g", v[i]);
150  }
151  break;
152  case x_stdtm:
153  {
154  std::vector<std::tm> * pv
155  = static_cast<std::vector<std::tm> *>(data_);
156  std::vector<std::tm> & v = *pv;
157 
158  std::size_t const bufSize = 20;
159  buf = new char[bufSize];
160 
161  snprintf(buf, bufSize, "%d-%02d-%02d %02d:%02d:%02d",
162  v[i].tm_year + 1900, v[i].tm_mon + 1, v[i].tm_mday,
163  v[i].tm_hour, v[i].tm_min, v[i].tm_sec);
164  }
165  break;
166 
167  default:
168  throw soci_error(
169  "Use vector element used with non-supported type.");
170  }
171  }
172 
173  buffers_.push_back(buf);
174  }
175 
176  if (position_ > 0)
177  {
178  // binding by position
179  statement_.useByPosBuffers_[position_] = &buffers_[0];
180  }
181  else
182  {
183  // binding by name
184  statement_.useByNameBuffers_[name_] = &buffers_[0];
185  }
186 }
187 
189 {
190  std::size_t sz = 0; // dummy initialization to please the compiler
191  switch (type_)
192  {
193  // simple cases
194  case x_char:
195  sz = get_vector_size<char>(data_);
196  break;
197  case x_short:
198  sz = get_vector_size<short>(data_);
199  break;
200  case x_integer:
201  sz = get_vector_size<int>(data_);
202  break;
203  case x_long_long:
204  sz = get_vector_size<long long>(data_);
205  break;
207  sz = get_vector_size<unsigned long long>(data_);
208  break;
209  case x_double:
210  sz = get_vector_size<double>(data_);
211  break;
212  case x_stdstring:
213  sz = get_vector_size<std::string>(data_);
214  break;
215  case x_stdtm:
216  sz = get_vector_size<std::tm>(data_);
217  break;
218  default:
219  throw soci_error("Use vector element used with non-supported type.");
220  }
221 
222  return sz;
223 }
224 
226 {
227  std::size_t const bsize = buffers_.size();
228  for (std::size_t i = 0; i != bsize; ++i)
229  {
230  delete [] buffers_[i];
231  }
232 }
virtual void bind_by_pos(int &position, void *data, details::exchange_type type)
virtual void bind_by_name(std::string const &name, void *data, details::exchange_type type)
#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