1//
2// Row.h
3//
4// Library: SQL
5// Package: SQLCore
6// Module: Row
7//
8// Definition of the Row class.
9//
10// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
11// and Contributors.
12//
13// SPDX-License-Identifier: BSL-1.0
14//
15
16
17#ifndef SQL_Row_INCLUDED
18#define SQL_Row_INCLUDED
19
20
21#include "Poco/SQL/SQL.h"
22#include "Poco/SQL/RowFormatter.h"
23#include "Poco/Dynamic/Var.h"
24#include "Poco/Tuple.h"
25#include "Poco/SharedPtr.h"
26#include <vector>
27#include <string>
28#include <ostream>
29
30
31namespace Poco {
32namespace SQL {
33
34
35class RecordSet;
36
37
38class Poco_SQL_API Row
39 /// Row class provides a data type for RecordSet iteration purposes.
40 /// Dereferencing a RowIterator returns Row.
41 /// Rows are sortable. The sortability is maintained at all times (i.e. there
42 /// is always at least one column specified as a sorting criteria) .
43 /// The default and minimal sorting criteria is the first field (position 0).
44 /// The default sorting criteria can be replaced with any other field by
45 /// calling replaceSortField() member function.
46 /// Additional fields can be added to sorting criteria, in which case the
47 /// field precedence corresponds to addition order (i.e. later added fields
48 /// have lower sorting precedence).
49 /// These features make Row suitable for use with standard sorted
50 /// containers and algorithms. The main constraint is that all the rows from
51 /// a set that is being sorted must have the same sorting criteria (i.e., the same
52 /// set of fields must be in sorting criteria in the same order). Since rows don't
53 /// know about each other, it is the programmer's responsibility to ensure this
54 /// constraint is satisfied.
55 /// Field names are a shared pointer to a vector of strings. For efficiency sake,
56 /// a constructor taking a shared pointer to names vector argument is provided.
57 /// The stream operator is provided for Row data type as a free-standing function.
58{
59public:
60 typedef RowFormatter::NameVec NameVec;
61 typedef RowFormatter::NameVecPtr NameVecPtr;
62 typedef RowFormatter::ValueVec ValueVec;
63
64 enum ComparisonType
65 {
66 COMPARE_AS_EMPTY,
67 COMPARE_AS_INTEGER,
68 COMPARE_AS_FLOAT,
69 COMPARE_AS_STRING
70 };
71
72 typedef Tuple<std::size_t, ComparisonType> SortTuple;
73 typedef std::vector<SortTuple> SortMap;
74 /// The type for map holding fields used for sorting criteria.
75 /// Fields are added sequentially and have precedence that
76 /// corresponds to field adding sequence order (rather than field's
77 /// position in the row).
78 /// This requirement rules out use of std::map due to its sorted nature.
79 typedef SharedPtr<SortMap> SortMapPtr;
80
81 Row();
82 /// Creates the Row.
83
84 Row(NameVecPtr pNames,
85 const RowFormatter::Ptr& pFormatter = 0);
86 /// Creates the Row.
87
88 Row(NameVecPtr pNames,
89 const SortMapPtr& pSortMap,
90 const RowFormatter::Ptr& pFormatter = 0);
91 /// Creates the Row.
92
93 ~Row();
94 /// Destroys the Row.
95
96 Poco::Dynamic::Var& get(std::size_t col);
97 /// Returns the reference to data value at column location.
98
99 Poco::Dynamic::Var& operator [] (std::size_t col);
100 /// Returns the reference to data value at column location.
101
102 Poco::Dynamic::Var& operator [] (const std::string& name);
103 /// Returns the reference to data value at named column location.
104
105 const Poco::Dynamic::Var& get(std::size_t col) const;
106 /// Returns the reference to data value at column location.
107
108 const Poco::Dynamic::Var& operator [] (std::size_t col) const;
109 /// Returns the reference to data value at column location.
110
111 const Poco::Dynamic::Var& operator [] (const std::string& name) const;
112 /// Returns the reference to data value at named column location.
113
114 template <typename T>
115 void append(const std::string& name, const T& val)
116 /// Appends the value to the row.
117 {
118 if (!_pNames) _pNames = new NameVec;
119 _values.push_back(val);
120 _pNames->push_back(name);
121 if (1 == _values.size()) addSortField(0);
122 }
123
124 template <typename T>
125 void set(std::size_t pos, const T& val)
126 /// Assigns the value to the row.
127 {
128 try
129 {
130 _values.at(pos) = val;
131 }
132 catch (std::out_of_range&)
133 {
134 throw RangeException("Invalid column number.");
135 }
136 }
137
138 template <typename T>
139 void set(const std::string& name, const T& val)
140 /// Assigns the value to the row.
141 {
142 NameVec::iterator it = _pNames->begin();
143 NameVec::iterator end = _pNames->end();
144 for (int i = 0; it != end; ++it, ++i)
145 {
146 if (*it == name)
147 return set(i, val);
148 }
149
150 std::ostringstream os;
151 os << "Column with name " << name << " not found.";
152 throw NotFoundException(os.str());
153 }
154
155 std::size_t fieldCount() const;
156 /// Returns the number of fields in this row.
157
158 void reset();
159 /// Resets the row by clearing all field names and values.
160
161 void separator(const std::string& sep);
162 /// Sets the separator.
163
164 void addSortField(std::size_t pos);
165 /// Adds the field used for sorting.
166
167 void addSortField(const std::string& name);
168 /// Adds the field used for sorting.
169
170 void removeSortField(std::size_t pos);
171 /// Removes the field used for sorting.
172
173 void removeSortField(const std::string& name);
174 /// Removes the field used for sorting.
175
176 void replaceSortField(std::size_t oldPos, std::size_t newPos);
177 /// Replaces the field used for sorting.
178
179 void replaceSortField(const std::string& oldName, const std::string& newName);
180 /// Replaces the field used for sorting.
181
182 void resetSort();
183 /// Resets the sorting criteria to field 0 only.
184
185 const std::string& namesToString() const;
186 /// Converts the column names to string.
187
188 void formatNames() const;
189 /// Formats the column names.
190
191 const std::string& valuesToString() const;
192 /// Converts the row values to string and returns the formatted string.
193
194 void formatValues() const;
195 /// Formats the row values.
196
197 bool operator == (const Row& other) const;
198 /// Equality operator.
199
200 bool operator != (const Row& other) const;
201 /// Inequality operator.
202
203 bool operator < (const Row& other) const;
204 /// Less-than operator.
205
206 const NameVecPtr names() const;
207 /// Returns the shared pointer to names vector.
208
209 const ValueVec& values() const;
210 /// Returns the const reference to values vector.
211
212 void setFormatter(const RowFormatter::Ptr& pFormatter = 0);
213 /// Sets the formatter for this row and takes the
214 /// shared ownership of it.
215
216 const RowFormatter& getFormatter() const;
217 /// Returns the reference to the formatter.
218
219 void setSortMap(const SortMapPtr& pSortMap = 0);
220 /// Adds the sorting fields entry and takes the
221 /// shared ownership of it.
222
223 const SortMapPtr& getSortMap() const;
224 /// Returns the reference to the sorting fields.
225
226private:
227 void init(const SortMapPtr& pSortMap, const RowFormatter::Ptr& pFormatter);
228
229 ValueVec& values();
230 /// Returns the reference to values vector.
231
232 std::size_t getPosition(const std::string& name) const;
233 bool isEqualSize(const Row& other) const;
234 bool isEqualType(const Row& other) const;
235
236 NameVecPtr _pNames;
237 ValueVec _values;
238 SortMapPtr _pSortMap;
239 mutable RowFormatter::Ptr _pFormatter;
240 mutable std::string _nameStr;
241 mutable std::string _valueStr;
242};
243
244
245Poco_SQL_API std::ostream& operator << (std::ostream &os, const Row& row);
246
247
248///
249/// inlines
250///
251inline std::size_t Row::fieldCount() const
252{
253 return static_cast<std::size_t>(_values.size());
254}
255
256
257inline void Row::reset()
258{
259 _pNames->clear();
260 _values.clear();
261}
262
263
264inline const Row::NameVecPtr Row::names() const
265{
266 return _pNames;
267}
268
269
270inline const Row::ValueVec& Row::values() const
271{
272 return _values;
273}
274
275
276inline Row::ValueVec& Row::values()
277{
278 return _values;
279}
280
281
282inline Poco::Dynamic::Var& Row::operator [] (std::size_t col)
283{
284 return get(col);
285}
286
287
288inline Poco::Dynamic::Var& Row::operator [] (const std::string& name)
289{
290 return get(getPosition(name));
291}
292
293
294inline const Poco::Dynamic::Var& Row::operator [] (std::size_t col) const
295{
296 return get(col);
297}
298
299
300inline const Poco::Dynamic::Var& Row::operator [] (const std::string& name) const
301{
302 return get(getPosition(name));
303}
304
305
306inline const RowFormatter& Row::getFormatter() const
307{
308 return *_pFormatter;
309}
310
311
312inline const Row::SortMapPtr& Row::getSortMap() const
313{
314 return _pSortMap;
315}
316
317
318inline const std::string& Row::valuesToString() const
319{
320 return _pFormatter->formatValues(values(), _valueStr);
321}
322
323
324inline void Row::formatValues() const
325{
326 return _pFormatter->formatValues(values());
327}
328
329
330} } // namespace Poco::SQL
331
332
333#endif // Data_Row_INCLUDED
334