1 | // |
2 | // JSONRowFormatter.cpp |
3 | // |
4 | // Library: SQL |
5 | // Package: SQLCore |
6 | // Module: JSONRowFormatter |
7 | // |
8 | // Copyright (c) 2006, Applied Informatics Software Engineering GmbH. |
9 | // and Contributors. |
10 | // |
11 | // SPDX-License-Identifier: BSL-1.0 |
12 | // |
13 | |
14 | |
15 | #include "Poco/SQL/JSONRowFormatter.h" |
16 | #include "Poco/String.h" |
17 | #include "Poco/JSONString.h" |
18 | #include "Poco/Format.h" |
19 | |
20 | |
21 | using Poco::trimInPlace; |
22 | using Poco::format; |
23 | using Poco::toJSON; |
24 | |
25 | |
26 | namespace Poco { |
27 | namespace SQL { |
28 | |
29 | |
30 | const int JSONRowFormatter::JSON_FMT_MODE_SMALL; |
31 | const int JSONRowFormatter::JSON_FMT_MODE_ROW_COUNT; |
32 | const int JSONRowFormatter::JSON_FMT_MODE_COLUMN_NAMES; |
33 | const int JSONRowFormatter::JSON_FMT_MODE_FULL; |
34 | |
35 | |
36 | JSONRowFormatter::JSONRowFormatter(int mode) : RowFormatter("{" , "]}" ), |
37 | _firstTime(true) |
38 | { |
39 | if (mode == JSON_FMT_MODE_FULL) |
40 | { |
41 | mode |= JSON_FMT_MODE_ROW_COUNT; |
42 | mode |= JSON_FMT_MODE_COLUMN_NAMES; |
43 | } |
44 | |
45 | setJSONMode(mode); |
46 | } |
47 | |
48 | |
49 | JSONRowFormatter::~JSONRowFormatter() |
50 | { |
51 | } |
52 | |
53 | |
54 | void JSONRowFormatter::adjustPrefix() |
55 | { |
56 | if (printRowCount()) |
57 | { |
58 | std::ostringstream ostr; |
59 | ostr << "{\"count\":" << getTotalRowCount() << "," ; |
60 | if (_mode & JSON_FMT_MODE_FULL) |
61 | ostr << '['; |
62 | setPrefix(ostr.str()); |
63 | } |
64 | } |
65 | |
66 | |
67 | void JSONRowFormatter::setJSONMode(int mode) |
68 | { |
69 | if (mode < JSON_FMT_MODE_SMALL || |
70 | mode > (JSON_FMT_MODE_SMALL | JSON_FMT_MODE_ROW_COUNT | JSON_FMT_MODE_COLUMN_NAMES | JSON_FMT_MODE_FULL)) |
71 | { |
72 | throw Poco::InvalidArgumentException( |
73 | Poco::format("JSONRowFormatter mode must be between " |
74 | "%d (JSON_FMT_MODE_SMALL) and %d (JSON_FMT_MODE_FULL)" , |
75 | JSON_FMT_MODE_SMALL, |
76 | JSON_FMT_MODE_FULL)); |
77 | } |
78 | |
79 | _mode = mode; |
80 | if (!(_mode & JSON_FMT_MODE_SMALL) && !(_mode & JSON_FMT_MODE_FULL)) |
81 | _mode |= JSON_FMT_MODE_SMALL; |
82 | else if (_mode & JSON_FMT_MODE_FULL) |
83 | { |
84 | _mode |= JSON_FMT_MODE_ROW_COUNT; |
85 | } |
86 | |
87 | adjustPrefix(); |
88 | } |
89 | |
90 | |
91 | std::string& JSONRowFormatter::(const ValueVec& vals, std::string& formattedValues) |
92 | { |
93 | std::ostringstream str; |
94 | if (!_firstTime) str << ','; |
95 | if (isSmall()) |
96 | { |
97 | if (_firstTime) |
98 | { |
99 | if (printColumnNames()) |
100 | str << ",\"values\":" ; |
101 | |
102 | str << '['; |
103 | } |
104 | |
105 | str << '['; |
106 | ValueVec::const_iterator it = vals.begin(); |
107 | ValueVec::const_iterator end = vals.end(); |
108 | for (; it != end;) |
109 | { |
110 | if (!it->isEmpty()) |
111 | { |
112 | if (it->isString() || it->isDate() || it->isTime()) |
113 | { |
114 | std::string val = it->convert<std::string>(); |
115 | trimInPlace(val); |
116 | str << toJSON(val); |
117 | } |
118 | else |
119 | str << it->convert<std::string>(); |
120 | } |
121 | else |
122 | str << "null" ; |
123 | |
124 | if (++it == end) break; |
125 | |
126 | str << ','; |
127 | } |
128 | str << ']'; |
129 | } |
130 | else if (isFull()) |
131 | { |
132 | str << '{'; |
133 | ValueVec::const_iterator it = vals.begin(); |
134 | ValueVec::const_iterator end = vals.end(); |
135 | NameVec::iterator nIt = _pNames->begin(); |
136 | NameVec::iterator nEnd = _pNames->end(); |
137 | for (; it != end && nIt != nEnd; ++nIt) |
138 | { |
139 | if (!it->isEmpty()) |
140 | { |
141 | if (it->isString() || it->isDate() || it->isTime()) |
142 | { |
143 | std::string val = it->convert<std::string>(); |
144 | trimInPlace(val); |
145 | str << '"' << *nIt << "\":" << toJSON(val); |
146 | } |
147 | else |
148 | str << '"' << *nIt << "\":" << it->convert<std::string>(); |
149 | } |
150 | else |
151 | str << '"' << *nIt << "\":null" ; |
152 | |
153 | if (++it != end) str << ','; |
154 | } |
155 | str << '}'; |
156 | } |
157 | |
158 | _firstTime = false; |
159 | return formattedValues = str.str(); |
160 | } |
161 | |
162 | |
163 | std::string& JSONRowFormatter::(const NameVecPtr pNames, std::string& formattedNames) |
164 | { |
165 | if (isFull()) |
166 | { |
167 | // names are used in formatValues |
168 | if (pNames && !_pNames) _pNames = pNames; |
169 | return formattedNames = "" ; |
170 | } |
171 | else if (printColumnNames()) |
172 | { |
173 | std::ostringstream ostr; |
174 | ostr << "\"names\":[" ; |
175 | for (NameVec::const_iterator it = pNames->begin(), |
176 | end = pNames->end();;) |
177 | { |
178 | ostr << '"' << *it << '"'; |
179 | if (++it == end) break; |
180 | ostr << ','; |
181 | } |
182 | ostr << "]" ; |
183 | return formattedNames = ostr.str(); |
184 | } |
185 | |
186 | return formattedNames = "" ; |
187 | } |
188 | |
189 | |
190 | } }// namespace Poco::SQL |
191 | |