postgresql/standard-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-postgresql.h"
10 #include "blob.h"
11 #include "rowid.h"
12 #include <soci-platform.h>
13 #include <libpq/libpq-fs.h> // libpq
14 #include <cctype>
15 #include <cstdio>
16 #include <cstring>
17 #include <ctime>
18 #include <limits>
19 #include <sstream>
20 
21 #ifdef SOCI_POSTGRESQL_NOPARAMS
22 #ifndef SOCI_POSTGRESQL_NOBINDBYNAME
23 #define SOCI_POSTGRESQL_NOBINDBYNAME
24 #endif // SOCI_POSTGRESQL_NOBINDBYNAME
25 #endif // SOCI_POSTGRESQL_NOPARAMS
26 
27 #ifdef _MSC_VER
28 #pragma warning(disable:4355 4996)
29 #define snprintf _snprintf
30 #endif
31 
32 using namespace soci;
33 using namespace soci::details;
34 
36  int & position, void * data, exchange_type type, bool /* readOnly */)
37 {
38  // readOnly is ignored, because PostgreSQL does not support
39  // any data to be written back to used (bound) objects.
40 
41  data_ = data;
42  type_ = type;
43  position_ = position++;
44 }
45 
47  std::string const & name, void * data, exchange_type type, bool /* readOnly */)
48 {
49  // readOnly is ignored, because PostgreSQL does not support
50  // any data to be written back to used (bound) objects.
51 
52  data_ = data;
53  type_ = type;
54  name_ = name;
55 }
56 
58 {
59  if (ind != NULL && *ind == i_null)
60  {
61  // leave the working buffer as NULL
62  }
63  else
64  {
65  // allocate and fill the buffer with text-formatted client data
66  switch (type_)
67  {
68  case x_char:
69  {
70  buf_ = new char[2];
71  buf_[0] = *static_cast<char *>(data_);
72  buf_[1] = '\0';
73  }
74  break;
75  case x_stdstring:
76  {
77  std::string * s = static_cast<std::string *>(data_);
78  buf_ = new char[s->size() + 1];
79  std::strcpy(buf_, s->c_str());
80  }
81  break;
82  case x_short:
83  {
84  std::size_t const bufSize
85  = std::numeric_limits<short>::digits10 + 3;
86  buf_ = new char[bufSize];
87  snprintf(buf_, bufSize, "%d",
88  static_cast<int>(*static_cast<short *>(data_)));
89  }
90  break;
91  case x_integer:
92  {
93  std::size_t const bufSize
94  = std::numeric_limits<int>::digits10 + 3;
95  buf_ = new char[bufSize];
96  snprintf(buf_, bufSize, "%d",
97  *static_cast<int *>(data_));
98  }
99  break;
100  case x_long_long:
101  {
102  std::size_t const bufSize
103  = std::numeric_limits<long long>::digits10 + 3;
104  buf_ = new char[bufSize];
105  snprintf(buf_, bufSize, "%" LL_FMT_FLAGS "d",
106  *static_cast<long long *>(data_));
107  }
108  break;
110  {
111  std::size_t const bufSize
112  = std::numeric_limits<unsigned long long>::digits10 + 2;
113  buf_ = new char[bufSize];
114  snprintf(buf_, bufSize, "%" LL_FMT_FLAGS "u",
115  *static_cast<unsigned long long *>(data_));
116  }
117  break;
118  case x_double:
119  {
120  // no need to overengineer it (KISS)...
121 
122  std::size_t const bufSize = 100;
123  buf_ = new char[bufSize];
124 
125  snprintf(buf_, bufSize, "%.20g",
126  *static_cast<double *>(data_));
127  }
128  break;
129  case x_stdtm:
130  {
131  std::size_t const bufSize = 20;
132  buf_ = new char[bufSize];
133 
134  std::tm * t = static_cast<std::tm *>(data_);
135  snprintf(buf_, bufSize, "%d-%02d-%02d %02d:%02d:%02d",
136  t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
137  t->tm_hour, t->tm_min, t->tm_sec);
138  }
139  break;
140  case x_rowid:
141  {
142  // RowID is internally identical to unsigned long
143 
144  rowid * rid = static_cast<rowid *>(data_);
146  = static_cast<postgresql_rowid_backend *>(
147  rid->get_backend());
148 
149  std::size_t const bufSize
150  = std::numeric_limits<unsigned long>::digits10 + 2;
151  buf_ = new char[bufSize];
152 
153  snprintf(buf_, bufSize, "%lu", rbe->value_);
154  }
155  break;
156  case x_blob:
157  {
158  blob * b = static_cast<blob *>(data_);
160  static_cast<postgresql_blob_backend *>(b->get_backend());
161 
162  std::size_t const bufSize
163  = std::numeric_limits<unsigned long>::digits10 + 2;
164  buf_ = new char[bufSize];
165  snprintf(buf_, bufSize, "%lu", bbe->oid_);
166  }
167  break;
168 
169  default:
170  throw soci_error("Use element used with non-supported type.");
171  }
172  }
173 
174  if (position_ > 0)
175  {
176  // binding by position
177  statement_.useByPosBuffers_[position_] = &buf_;
178  }
179  else
180  {
181  // binding by name
182  statement_.useByNameBuffers_[name_] = &buf_;
183  }
184 }
185 
187  bool /* gotData */, indicator * /* ind */)
188 {
189  // PostgreSQL does not support any data moving back the same channel,
190  // so there is nothing to do here.
191  // In particular, there is nothing to protect, because both const and non-const
192  // objects will never be modified.
193 
194  // clean up the working buffer, it might be allocated anew in
195  // the next run of preUse
196  clean_up();
197 }
198 
200 {
201  if (buf_ != NULL)
202  {
203  delete [] buf_;
204  buf_ = NULL;
205  }
206 }
details::rowid_backend * get_backend()
Definition: rowid.h:33
virtual void bind_by_name(std::string const &name, void *data, details::exchange_type type, bool readOnly)
details::blob_backend * get_backend()
Definition: blob.h:39
virtual void post_use(bool gotData, indicator *ind)
#define LL_FMT_FLAGS
Definition: soci-platform.h:14
virtual 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