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
21using Poco::trimInPlace;
22using Poco::format;
23using Poco::toJSON;
24
25
26namespace Poco {
27namespace SQL {
28
29
30const int JSONRowFormatter::JSON_FMT_MODE_SMALL;
31const int JSONRowFormatter::JSON_FMT_MODE_ROW_COUNT;
32const int JSONRowFormatter::JSON_FMT_MODE_COLUMN_NAMES;
33const int JSONRowFormatter::JSON_FMT_MODE_FULL;
34
35
36JSONRowFormatter::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
49JSONRowFormatter::~JSONRowFormatter()
50{
51}
52
53
54void 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
67void 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
91std::string& JSONRowFormatter::formatValues(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
163std::string& JSONRowFormatter::formatNames(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