fastcgi++  3.1alpha
A C++ FastCGI/Web API
parameters.hpp
Go to the documentation of this file.
1 
9 /*******************************************************************************
10 * Copyright (C) 2020 Eddie Carle [eddie@isatec.ca] *
11 * *
12 * This file is part of fastcgi++. *
13 * *
14 * fastcgi++ is free software: you can redistribute it and/or modify it under *
15 * the terms of the GNU Lesser General Public License as published by the Free *
16 * Software Foundation, either version 3 of the License, or (at your option) *
17 * any later version. *
18 * *
19 * fastcgi++ is distributed in the hope that it will be useful, but WITHOUT ANY *
20 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *
21 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for *
22 * more details. *
23 * *
24 * You should have received a copy of the GNU Lesser General Public License *
25 * along with fastcgi++. If not, see <http://www.gnu.org/licenses/>. *
26 *******************************************************************************/
27 
28 #ifndef FASTCGIPP_SQL_PARAMETERS_HPP
29 #define FASTCGIPP_SQL_PARAMETERS_HPP
30 
31 #include "fastcgi++/endian.hpp"
32 #include "fastcgi++/address.hpp"
33 
34 #include <tuple>
35 #include <string>
36 #include <vector>
37 #include <chrono>
38 #include <memory>
39 
41 namespace Fastcgipp
42 {
44  namespace SQL
45  {
47 
53  template<typename T> class Parameter;
54 
55  template<>
56  class Parameter<bool>
57  {
58  private:
59  char m_data;
60  public:
61  static const unsigned oid;
62  constexpr Parameter(bool x) noexcept:
63  m_data(static_cast<char>(x))
64  {}
65  constexpr Parameter& operator=(bool x) noexcept
66  {
67  m_data = static_cast<char>(x);
68  return *this;
69  }
70  constexpr const char* data() const
71  {
72  return &m_data;
73  }
74  constexpr unsigned size() const
75  {
76  return 1;
77  }
78  };
79 
80  template<>
81  struct Parameter<int16_t>: public BigEndian<int16_t>
82  {
84  using BigEndian<int16_t>::operator=;
85  static const unsigned oid;
86  };
87 
88  template<>
89  struct Parameter<int32_t>: public BigEndian<int32_t>
90  {
93  static const unsigned oid;
94  };
95 
96  template<>
97  struct Parameter<int64_t>: public BigEndian<int64_t>
98  {
101  static const unsigned oid;
102  };
103 
104  template<>
105  struct Parameter<float>: public BigEndian<float>
106  {
109  static const unsigned oid;
110  };
111 
112  template<>
113  struct Parameter<double>: public BigEndian<double>
114  {
117  static const unsigned oid;
118  };
119 
120  template<>
121  struct Parameter<std::string>: public std::string
122  {
123  Parameter(const std::string& x):
124  std::string(x)
125  {}
126  using std::string::string;
127  using std::string::operator=;
128  static const unsigned oid;
129  };
130 
131  template<>
132  struct Parameter<std::vector<char>>: public std::vector<char>
133  {
134  Parameter(const std::vector<char>& x):
135  std::vector<char>(x)
136  {}
137  using std::vector<char>::vector;
138  using std::vector<char>::operator=;
139  static const unsigned oid;
140  };
141 
142  template<>
143  class Parameter<std::wstring>: public std::string
144  {
145  private:
146  static std::string convert(const std::wstring& x);
147 
148  public:
149  Parameter& operator=(const std::wstring& x)
150  {
151  assign(convert(x));
152  return *this;
153  }
154 
155  Parameter(const std::wstring& x):
156  std::string(convert(x))
157  {}
158 
159  static const unsigned oid;
160  };
161 
162  template<>
163  class Parameter<std::chrono::time_point<std::chrono::system_clock>>:
164  public BigEndian<int64_t>
165  {
166  private:
167  using BigEndian<int64_t>::operator=;
168  static int64_t convert(
169  const std::chrono::time_point<std::chrono::system_clock>& x)
170  {
171  return std::chrono::duration_cast<
172  std::chrono::duration<int64_t, std::micro>>(
173  x.time_since_epoch()-std::chrono::seconds(946684800)).count();
174  }
175 
176  public:
177  Parameter& operator=(
178  const std::chrono::time_point<std::chrono::system_clock>& x)
179  {
180  *this = convert(x);
181  return *this;
182  }
183 
184  Parameter(
185  const std::chrono::time_point<std::chrono::system_clock>& x):
186  BigEndian<int64_t>(convert(x))
187  {}
188 
189  static const unsigned oid;
190  };
191 
192  template<>
193  struct Parameter<Address>: public std::array<char, 20>
194  {
195  Parameter& operator=(const Address& x)
196  {
197  auto next = begin();
198  *next++ = addressFamily;
199  *next++ = 128;
200  *next++ = 0;
201  *next++ = 16;
202  next = std::copy_n(
203  reinterpret_cast<const char*>(&x),
205  next);
206  return *this;
207  }
208  Parameter(const Address& x)
209  {
210  *this = x;
211  }
212  static const unsigned oid;
213  static const char addressFamily;
214  };
215 
216  template<typename Numeric>
217  class Parameter<std::vector<Numeric>>
218  {
219  private:
220  static_assert(
221  std::is_integral<Numeric>::value ||
222  std::is_floating_point<Numeric>::value,
223  "Numeric must be a numeric type.");
224  unsigned m_size;
225  std::unique_ptr<char[]> m_data;
226  public:
227  void resize(const unsigned size);
228 
229  Parameter& operator=(const std::vector<Numeric>& x);
230 
231  Parameter(const std::vector<Numeric>& x)
232  {
233  *this = x;
234  }
235 
236  Parameter(const unsigned size)
237  {
238  resize(size);
239  }
240 
241  BigEndian<Numeric>& operator[](const unsigned i)
242  {
243  return *reinterpret_cast<BigEndian<Numeric>*>(
244  m_data.get() + 6*sizeof(int32_t)
245  + i*(sizeof(int32_t) + sizeof(Numeric)));
246  }
247 
248  unsigned size() const
249  {
250  return m_size;
251  }
252 
253  const char* data() const
254  {
255  return m_data.get();
256  }
257 
258  static const unsigned oid;
259  };
260 
261  template<>
262  class Parameter<std::vector<std::string>>
263  {
264  private:
265  unsigned m_size;
266  std::unique_ptr<char[]> m_data;
267  protected:
268  void assign(const std::vector<std::string>& x);
269  public:
270  Parameter& operator=(const std::vector<std::string>& x)
271  {
272  assign(x);
273  return *this;
274  }
275 
276  Parameter(const std::vector<std::string>& x)
277  {
278  assign(x);
279  }
280 
281  std::string operator[](const unsigned i) const;
282 
283  unsigned size() const
284  {
285  return m_size;
286  }
287 
288  const char* data() const
289  {
290  return m_data.get();
291  }
292 
293  static const unsigned oid;
294  };
295 
296  template<>
297  class Parameter<std::vector<std::wstring>>:
298  public Parameter<std::vector<std::string>>
299  {
300  private:
301  static std::vector<std::string> convert(
302  const std::vector<std::wstring>& x);
303  static std::wstring convert(const std::string& x);
304  public:
305  Parameter& operator=(const std::vector<std::wstring>& x)
306  {
307  assign(convert(x));
308  return *this;
309  }
310 
311  Parameter(const std::vector<std::wstring>& x):
312  Parameter<std::vector<std::string>>(convert(x))
313  {}
314 
315  std::wstring operator[](const unsigned i) const
316  {
317  return convert(
318  Parameter<std::vector<std::string>>::operator[](i));
319  }
320  };
321 
323  class Parameters_base
324  {
325  protected:
327 
330  const std::vector<unsigned>* m_oids;
331 
333 
336  std::vector<const char*> m_raws;
337 
339 
342  std::vector<int> m_sizes;
343 
345 
349  const std::vector<int>* m_formats;
350 
352 
355  virtual void build_impl() =0;
356 
357  public:
359  void build();
360 
362 
365  const unsigned* oids() const
366  {
367  return m_oids->data();
368  }
369 
371 
374  const char* const* raws() const
375  {
376  return m_raws.data();
377  }
378 
380  const int* sizes() const
381  {
382  return m_sizes.data();
383  }
384 
386  const int* formats() const
387  {
388  return m_formats->data();
389  }
390 
392  virtual int size() const =0;
393 
394  virtual ~Parameters_base() {}
395  };
396 
398 
408  template<typename... Types>
409  class Parameters:
410  public std::tuple<Parameter<Types>...>,
411  public Parameters_base
412  {
413  private:
414  static const std::vector<unsigned> s_oids;
415  static const std::vector<int> s_formats;
416 
418  constexpr int size() const
419  {
420  return sizeof...(Types);
421  }
422 
424  template<size_t column, size_t... columns>
425  inline void build_impl(std::index_sequence<column, columns...>)
426  {
427  m_raws.push_back(std::get<column>(*this).data());
428  m_sizes.push_back(std::get<column>(*this).size());
429  build_impl(std::index_sequence<columns...>{});
430  }
431 
433  template<size_t column>
434  inline void build_impl(std::index_sequence<column>)
435  {
436  m_raws.push_back(std::get<column>(*this).data());
437  m_sizes.push_back(std::get<column>(*this).size());
438  }
439 
440  void build_impl();
441 
442  public:
443  using std::tuple<Parameter<Types>...>::tuple;
444  using std::tuple<Parameter<Types>...>::operator=;
445  };
446 
447  template<typename... Types>
448  std::shared_ptr<Parameters<Types...>> make_Parameters(
449  const Types&... args)
450  {
451  return std::shared_ptr<Parameters<Types...>>(
452  new Parameters<Types...>(args...));
453  }
454 
455  template<typename... Types>
456  std::shared_ptr<Parameters<Types...>> make_Parameters(
457  const std::tuple<Types...>& tuple)
458  {
459  return std::shared_ptr<Parameters<Types...>>(
460  new Parameters<Types...>(tuple));
461  }
462  }
463 }
464 
465 template<typename... Types>
467 {
468  m_oids = &s_oids;
469  m_formats = &s_formats;
470  build_impl(std::index_sequence_for<Types...>{});
471 }
472 
473 template<typename... Types>
474 const std::vector<unsigned> Fastcgipp::SQL::Parameters<Types...>::s_oids
475 {
477 };
478 
479 template<typename... Types>
481  sizeof...(Types),
482  1);
483 
484 #endif
endian.hpp
Defines the BigEndian class.
Fastcgipp::SQL::Parameters_base::~Parameters_base
virtual ~Parameters_base()
Definition: parameters.hpp:428
Fastcgipp::SQL::Parameters::build_impl
void build_impl()
Template side virtual to populate the above arrays.
Definition: parameters.hpp:466
Fastcgipp::SQL::Parameters::size
constexpr int size() const
How many items in the tuple?
Definition: parameters.hpp:452
Fastcgipp::SQL::Parameters_base::raws
const char *const * raws() const
Constant pointer to pointer array of all raw parameter data.
Definition: parameters.hpp:408
Fastcgipp::Address::size
static constexpr size_t size
This is the data length of the IPv6 address.
Definition: address.hpp:87
Fastcgipp::SQL::Parameter
A single parameter in an SQL query.
Definition: parameters.hpp:87
Fastcgipp::SQL::Parameters_base::oids
const unsigned * oids() const
Constant pointer to array of all parameter oids.
Definition: parameters.hpp:399
Fastcgipp::SQL::Parameters_base::m_raws
std::vector< const char * > m_raws
Array of raw data pointers for each parameter.
Definition: parameters.hpp:370
Fastcgipp::SQL::Parameter< Address >::operator=
Parameter & operator=(const Address &x)
Definition: parameters.hpp:229
Fastcgipp::SQL::make_Parameters
std::shared_ptr< Parameters< Types... > > make_Parameters(const Types &... args)
Definition: parameters.hpp:482
Fastcgipp::SQL::Parameters_base::formats
const int * formats() const
Constant pointer to array of all formats.
Definition: parameters.hpp:420
Fastcgipp::SQL::Parameters::s_formats
static const std::vector< int > s_formats
Definition: parameters.hpp:449
address.hpp
Fastcgipp::SQL::Parameters_base
De-templated base class for Parameters.
Definition: parameters.hpp:357
Fastcgipp::SQL::Parameters
A tuple of parameters to tie to a SQL query.
Definition: parameters.hpp:443
Fastcgipp
Topmost namespace for the fastcgi++ library.
Definition: fcgistreambuf.cpp:34
Fastcgipp::SQL::Parameters_base::sizes
const int * sizes() const
Constant pointer to array of all parameter sizes.
Definition: parameters.hpp:414
Fastcgipp::SQL::Parameters_base::m_oids
const std::vector< unsigned > * m_oids
Array of oids for each parameter.
Definition: parameters.hpp:364
Fastcgipp::SQL::Parameters_base::m_formats
const std::vector< int > * m_formats
Array of formats for each parameter.
Definition: parameters.hpp:383
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::s_oids
static const std::vector< unsigned > s_oids
Definition: parameters.hpp:448
Fastcgipp::BigEndian< int16_t >::BigEndian
constexpr BigEndian() noexcept
Definition: endian.hpp:179
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?
Fastcgipp::BigEndian
Allows raw storage of types in big endian format.
Definition: endian.hpp:142