fastcgi++  3.1alpha
A C++ FastCGI/Web API
parameters.cpp
Go to the documentation of this file.
1 
10 /*******************************************************************************
11 * Copyright (C) 2020 Eddie Carle [eddie@isatec.ca] *
12 * *
13 * This file is part of fastcgi++. *
14 * *
15 * fastcgi++ is free software: you can redistribute it and/or modify it under *
16 * the terms of the GNU Lesser General Public License as published by the Free *
17 * Software Foundation, either version 3 of the License, or (at your option) *
18 * any later version. *
19 * *
20 * fastcgi++ is distributed in the hope that it will be useful, but WITHOUT ANY *
21 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *
22 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for *
23 * more details. *
24 * *
25 * You should have received a copy of the GNU Lesser General Public License *
26 * along with fastcgi++. If not, see <http://www.gnu.org/licenses/>. *
27 *******************************************************************************/
28 
29 #include "sqlTraits.hpp"
31 #include "fastcgi++/log.hpp"
32 
33 #include <locale>
34 #include <codecvt>
35 
37 {
38  const int columns = size();
39  m_raws.clear();
40  m_raws.reserve(columns);
41  m_sizes.clear();
42  m_sizes.reserve(columns);
43  build_impl();
44 }
45 
46 std::string
48 {
49  std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> converter;
50  try
51  {
52  return converter.to_bytes(x);
53  }
54  catch(const std::range_error& e)
55  {
56  WARNING_LOG("Error in code conversion to utf8 in SQL parameter")
57  }
58  return std::string();
59 }
60 
61 const unsigned Fastcgipp::SQL::Parameter<bool>::oid = Traits<bool>::oid;
62 const unsigned Fastcgipp::SQL::Parameter<int16_t>::oid = Traits<int16_t>::oid;
63 const unsigned Fastcgipp::SQL::Parameter<int32_t>::oid = Traits<int32_t>::oid;
64 const unsigned Fastcgipp::SQL::Parameter<int64_t>::oid = Traits<int64_t>::oid;
65 const unsigned Fastcgipp::SQL::Parameter<float>::oid = Traits<float>::oid;
66 const unsigned Fastcgipp::SQL::Parameter<double>::oid = Traits<double>::oid;
68  = Traits<std::string>::oid;
70  = Traits<std::wstring>::oid;
72  = Traits<std::vector<char>>::oid;
73 const unsigned Fastcgipp::SQL::Parameter<
74  std::chrono::time_point<std::chrono::system_clock>>::oid
75  = Traits<std::chrono::time_point<std::chrono::system_clock>>::oid;
77  = Traits<Fastcgipp::Address>::oid;
79  = Traits<Fastcgipp::Address>::addressFamily;
80 template<typename Numeric>
82  = Traits<std::vector<Numeric>>::oid;
84  = Traits<std::vector<std::string>>::oid;
85 
86 template<typename Numeric>
88  const unsigned size)
89 {
90  m_size = sizeof(int32_t)*(5+size) + size*sizeof(Numeric);
91  m_data.reset(new char[m_size]);
92 
93  BigEndian<int32_t>& ndim(*reinterpret_cast<BigEndian<int32_t>*>(
94  m_data.get()+0*sizeof(int32_t)));
95  BigEndian<int32_t>& hasNull(*reinterpret_cast<BigEndian<int32_t>*>(
96  m_data.get()+1*sizeof(int32_t)));
97  BigEndian<int32_t>& elementType(*reinterpret_cast<BigEndian<int32_t>*>(
98  m_data.get()+2*sizeof(int32_t)));
99  BigEndian<int32_t>& dim(*reinterpret_cast<BigEndian<int32_t>*>(
100  m_data.get()+3*sizeof(int32_t)));
101  BigEndian<int32_t>& lBound(*reinterpret_cast<BigEndian<int32_t>*>(
102  m_data.get()+4*sizeof(int32_t)));
103 
104  ndim = 1;
105  hasNull = 0;
106  elementType = Traits<Numeric>::oid;
107  dim = size;
108  lBound = 1;
109 }
110 
111 template<typename Numeric>
114  const std::vector<Numeric>& x)
115 {
116  resize(x.size());
117 
118  for(unsigned i=0; i < x.size(); ++i)
119  {
120  char* ptr = m_data.get() + 5*sizeof(int32_t)
121  + i*(sizeof(int32_t) + sizeof(Numeric));
122 
123  BigEndian<int32_t>& length(
124  *reinterpret_cast<BigEndian<int32_t>*>(ptr));
125  BigEndian<Numeric>& value(
126  *reinterpret_cast<BigEndian<Numeric>*>(
127  ptr+sizeof(int32_t)));
128 
129  length = sizeof(Numeric);
130  value = x[i];
131  }
132 
133  return *this;
134 }
135 
141 
143  const std::vector<std::string>& x)
144 {
145  // Allocate the space
146  {
147  unsigned dataSize = 0;
148  for(const auto& string: x)
149  dataSize += string.size();
150  m_size = sizeof(int32_t)*(5+x.size()) + dataSize;
151  m_data.reset(new char[m_size]);
152  BigEndian<int32_t>& ndim(*reinterpret_cast<BigEndian<int32_t>*>(
153  m_data.get()+0*sizeof(int32_t)));
154  BigEndian<int32_t>& hasNull(*reinterpret_cast<BigEndian<int32_t>*>(
155  m_data.get()+1*sizeof(int32_t)));
156  BigEndian<int32_t>& elementType(*reinterpret_cast<BigEndian<int32_t>*>(
157  m_data.get()+2*sizeof(int32_t)));
158  BigEndian<int32_t>& dim(*reinterpret_cast<BigEndian<int32_t>*>(
159  m_data.get()+3*sizeof(int32_t)));
160  BigEndian<int32_t>& lBound(*reinterpret_cast<BigEndian<int32_t>*>(
161  m_data.get()+4*sizeof(int32_t)));
162 
163  ndim = 1;
164  hasNull = 0;
165  elementType = Traits<std::string>::oid;
166  dim = x.size();
167  lBound = 1;
168  }
169 
170  char* ptr = m_data.get() + 5*sizeof(int32_t);
171  for(const auto& string: x)
172  {
173  BigEndian<int32_t>& length(
174  *reinterpret_cast<BigEndian<int32_t>*>(ptr));
175  length = string.size();
176  ptr = std::copy(string.begin(), string.end(), ptr+sizeof(int32_t));
177  }
178 }
179 
181  const unsigned x) const
182 {
183  const char* ptr = m_data.get() + 5*sizeof(int32_t);
184  unsigned i = 0;
185  while(true)
186  {
187  const int32_t length(*reinterpret_cast<const BigEndian<int32_t>*>(ptr));
188  ptr += sizeof(int32_t);
189  if(i++ == x)
190  return std::string(ptr, length);
191  ptr += length;
192  }
193 }
194 
195 std::vector<std::string>
197  const std::vector<std::wstring>& x)
198 {
199  std::vector<std::string> result;
200  result.reserve(x.size());
201 
202  std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> converter;
203  try
204  {
205  for(const auto& string: x)
206  result.emplace_back(std::move(converter.to_bytes(string)));
207  }
208  catch(const std::range_error& e)
209  {
210  WARNING_LOG("Error in array code conversion to utf8 in SQL parameter")
211  }
212  return result;
213 }
214 
216  const std::string& x)
217 {
218  std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> converter;
219  try
220  {
221  return converter.from_bytes(x);
222  }
223  catch(const std::range_error& e)
224  {
225  WARNING_LOG("Error in array code conversion from utf8 in SQL parameter")
226  }
227  return std::wstring();
228 }
parameters.hpp
Declares SQL parameters types.
Fastcgipp::SQL::Parameter
A single parameter in an SQL query.
Definition: parameters.hpp:87
Fastcgipp::SQL::Parameters_base::m_raws
std::vector< const char * > m_raws
Array of raw data pointers for each parameter.
Definition: parameters.hpp:370
WARNING_LOG
#define WARNING_LOG(data)
Log any externally caused "errors".
Definition: log.hpp:124
log.hpp
Declares the Fastcgipp debugging/logging facilities.
Fastcgipp::SQL::Parameters_base::build
void build()
Initialize the arrays needed by SQL.
Definition: parameters.cpp:36
Fastcgipp::SQL::Parameters_base::m_sizes
std::vector< int > m_sizes
Array of sizes for each parameter.
Definition: parameters.hpp:376
Fastcgipp::SQL::Parameters_base::build_impl
virtual void build_impl()=0
Template side virtual to populate the above arrays.
Fastcgipp::SQL::Parameters_base::size
virtual int size() const =0
How many parameters in this tuple?