drogon
C++14/17-based HTTP application framework
Loading...
Searching...
No Matches
Field.h
Go to the documentation of this file.
1
14
15// Taken from libpqxx and modified.
16// The license for libpqxx can be found in the COPYING file.
17
18#pragma once
19
20#include <drogon/exports.h>
21#include <string_view>
23#include <drogon/orm/Result.h>
24#include <drogon/orm/Row.h>
25#include <trantor/utils/Logger.h>
26#include <memory>
27#include <sstream>
28#include <string>
29#include <vector>
30#ifdef __linux__
31#include <arpa/inet.h>
32#endif
33
34namespace drogon
35{
36namespace orm
37{
39
43class DROGON_EXPORT Field
44{
45 public:
46 using SizeType = unsigned long;
47
49 const char *name() const;
50
52 bool isNull() const;
53
55
61 const char *c_str() const;
62
64 size_t length() const
65 {
66 return result_.getLength(row_, column_);
67 }
68
70 template <typename T>
71 T as() const
72 {
73 if (isNull())
74 return T();
75 auto data_ = result_.getValue(row_, column_);
76 // auto dataLength_ = result_.getLength(row_, column_);
77 // For binary format!
78 // if (dataLength_ == 1)
79 // {
80 // return *data_;
81 // }
82 // else if (dataLength_ == 4)
83 // {
84 // const int32_t *n = (int32_t *)data_;
85 // return ntohl(*n);
86 // }
87 // else if (dataLength_ == 8)
88 // {
89 // const int64_t *n = (int64_t *)data_;
90 // return ntohll(*n);
91 // }
92 // return 0;
93 T value = T();
94 if (data_)
95 {
96 try
97 {
98 std::stringstream ss(data_);
99 ss >> value;
100 }
101 catch (...)
102 {
103 LOG_DEBUG << "Type error";
104 }
105 }
106 return value;
107 }
108
110
118 {
119 return ArrayParser(result_.getValue(row_, column_));
120 }
121
122 template <typename T>
123 std::vector<std::shared_ptr<T>> asArray() const
124 {
125 std::vector<std::shared_ptr<T>> ret;
126 auto arrParser = getArrayParser();
127 while (1)
128 {
129 auto arrVal = arrParser.getNext();
130 if (arrVal.first == ArrayParser::juncture::done)
131 {
132 break;
133 }
134 if (arrVal.first == ArrayParser::juncture::string_value)
135 {
136 T val;
137 std::stringstream ss(std::move(arrVal.second));
138 ss >> val;
139 ret.push_back(std::shared_ptr<T>(new T(val)));
140 }
141 else if (arrVal.first == ArrayParser::juncture::null_value)
142 {
143 ret.push_back(std::shared_ptr<T>());
144 }
145 }
146 return ret;
147 }
148
149 protected:
150 Result::SizeType row_;
157 friend class Row;
158 Field(const Row &row, Row::SizeType columnNum) noexcept;
159
160 private:
161 const Result result_;
162};
163
164template <>
165DROGON_EXPORT std::string Field::as<std::string>() const;
166template <>
167DROGON_EXPORT const char *Field::as<const char *>() const;
168template <>
169DROGON_EXPORT char *Field::as<char *>() const;
170template <>
171DROGON_EXPORT std::vector<char> Field::as<std::vector<char>>() const;
172
173template <>
174inline std::string_view Field::as<std::string_view>() const
175{
176 auto first = result_.getValue(row_, column_);
177 auto length = result_.getLength(row_, column_);
178 return {first, length};
179}
180
181template <>
182inline float Field::as<float>() const
183{
184 if (isNull())
185 return 0.0;
186 return std::stof(result_.getValue(row_, column_));
187}
188
189template <>
190inline double Field::as<double>() const
191{
192 if (isNull())
193 return 0.0;
194 return std::stod(result_.getValue(row_, column_));
195}
196
197template <>
198inline bool Field::as<bool>() const
199{
200 if (result_.getLength(row_, column_) != 1)
201 {
202 return false;
203 }
204 auto value = result_.getValue(row_, column_);
205 if (*value == 't' || *value == '1')
206 return true;
207 return false;
208}
209
210template <>
211inline int Field::as<int>() const
212{
213 if (isNull())
214 return 0;
215 return std::stoi(result_.getValue(row_, column_));
216}
217
218template <>
219inline long Field::as<long>() const
220{
221 if (isNull())
222 return 0;
223 return std::stol(result_.getValue(row_, column_));
224}
225
226template <>
227inline int8_t Field::as<int8_t>() const
228{
229 if (isNull())
230 return 0;
231 return static_cast<int8_t>(atoi(result_.getValue(row_, column_)));
232}
233
234template <>
235inline long long Field::as<long long>() const
236{
237 if (isNull())
238 return 0;
239 return atoll(result_.getValue(row_, column_));
240}
241
242template <>
243inline unsigned int Field::as<unsigned int>() const
244{
245 if (isNull())
246 return 0;
247 return static_cast<unsigned int>(
248 std::stoul(result_.getValue(row_, column_)));
249}
250
251template <>
252inline unsigned long Field::as<unsigned long>() const
253{
254 if (isNull())
255 return 0;
256 return std::stoul(result_.getValue(row_, column_));
257}
258
259template <>
260inline uint8_t Field::as<uint8_t>() const
261{
262 if (isNull())
263 return 0;
264 return static_cast<uint8_t>(atoi(result_.getValue(row_, column_)));
265}
266
267template <>
268inline unsigned long long Field::as<unsigned long long>() const
269{
270 if (isNull())
271 return 0;
272 return std::stoull(result_.getValue(row_, column_));
273}
274
275// std::vector<int32_t> Field::as<std::vector<int32_t>>() const;
276// template <>
277// std::vector<int64_t> Field::as<std::vector<int64_t>>() const;
278} // namespace orm
279} // namespace drogon
Low-level array parser.
Definition ArrayParser.h:53
@ done
Parsing has completed.
Definition ArrayParser.h:67
size_t length() const
Get the length of the plain C string.
Definition Field.h:64
T as() const
Convert to a type T value.
Definition Field.h:71
const char * c_str() const
Read as plain C string.
long column_
Definition Field.h:156
ArrayParser getArrayParser() const
Parse the field as an SQL array.
Definition Field.h:117
const char * name() const
Column name.
bool isNull() const
Is this field's value null?
Result set containing data returned by a query or command.
Definition Result.h:58
Drogon Test is a minimal effort test framework developed because the major C++ test frameworks doesn'...
Definition Attribute.h:23