1//
2// JSONRowFormatter.cpp
3//
4// Library: Data
5// Package: DataCore
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/Data/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 Data {
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 //setPostfix("]}");
44 }
45
46 setJSONMode(mode);
47}
48
49
50JSONRowFormatter::~JSONRowFormatter()
51{
52}
53
54
55void JSONRowFormatter::adjustPrefix()
56{
57 if (printRowCount())
58 {
59 std::ostringstream ostr;
60 ostr << "{\"count\":" << getTotalRowCount() << ",";
61 if (_mode & JSON_FMT_MODE_FULL)
62 ostr << '[';
63 setPrefix(ostr.str());
64 }
65}
66
67
68void JSONRowFormatter::setJSONMode(int mode)
69{
70 if (mode < JSON_FMT_MODE_SMALL ||
71 mode > (JSON_FMT_MODE_SMALL | JSON_FMT_MODE_ROW_COUNT | JSON_FMT_MODE_COLUMN_NAMES | JSON_FMT_MODE_FULL))
72 {
73 throw Poco::InvalidArgumentException(
74 Poco::format("JSONRowFormatter mode must be between "
75 "%d (JSON_FMT_MODE_SMALL) and %d (JSON_FMT_MODE_FULL)",
76 JSON_FMT_MODE_SMALL,
77 JSON_FMT_MODE_FULL));
78 }
79
80 _mode = mode;
81 if (!(_mode & JSON_FMT_MODE_SMALL) && !(_mode & JSON_FMT_MODE_FULL))
82 _mode |= JSON_FMT_MODE_SMALL;
83 else if (_mode & JSON_FMT_MODE_FULL)
84 {
85 _mode |= JSON_FMT_MODE_ROW_COUNT;
86 }
87
88 adjustPrefix();
89}
90
91
92std::string& JSONRowFormatter::formatValues(const ValueVec& vals, std::string& formattedValues)
93{
94 std::ostringstream str;
95 if (!_firstTime) str << ',';
96 if (isSmall())
97 {
98 if (_firstTime)
99 {
100 if (printColumnNames())
101 str << ",\"values\":";
102
103 str << '[';
104 }
105
106 str << '[';
107 ValueVec::const_iterator it = vals.begin();
108 ValueVec::const_iterator end = vals.end();
109 for (; it != end;)
110 {
111 if (!it->isEmpty())
112 {
113 if (it->isString() || it->isDate() || it->isTime())
114 {
115 std::string val = it->convert<std::string>();
116 trimInPlace(val);
117 str << toJSON(val);
118 }
119 else
120 str << it->convert<std::string>();
121 }
122 else
123 str << "null";
124
125 if (++it == end) break;
126
127 str << ',';
128 }
129 str << ']';
130 }
131 else if (isFull())
132 {
133 str << '{';
134 ValueVec::const_iterator it = vals.begin();
135 ValueVec::const_iterator end = vals.end();
136 NameVec::iterator nIt = _pNames->begin();
137 NameVec::iterator nEnd = _pNames->end();
138 for (; it != end && nIt != nEnd; ++nIt)
139 {
140 if (!it->isEmpty())
141 {
142 if (it->isString() || it->isDate() || it->isTime())
143 {
144 std::string val = it->convert<std::string>();
145 trimInPlace(val);
146 str << '"' << *nIt << "\":" << toJSON(val);
147 }
148 else
149 str << '"' << *nIt << "\":" << it->convert<std::string>();
150 }
151 else
152 str << '"' << *nIt << "\":null";
153
154 if (++it != end) str << ',';
155 }
156 str << '}';
157 }
158
159 _firstTime = false;
160 return formattedValues = str.str();
161}
162
163
164std::string& JSONRowFormatter::formatNames(const NameVecPtr pNames, std::string& formattedNames)
165{
166 if (isFull())
167 {
168 // names are used in formatValues
169 if (pNames && !_pNames) _pNames = pNames;
170 return formattedNames = "";
171 }
172 else if (printColumnNames())
173 {
174 std::ostringstream ostr;
175 ostr << "\"names\":[";
176 for (NameVec::const_iterator it = pNames->begin(),
177 end = pNames->end();;)
178 {
179 ostr << '"' << *it << '"';
180 if (++it == end) break;
181 ostr << ',';
182 }
183 ostr << "]";
184 return formattedNames = ostr.str();
185 }
186
187 return formattedNames = "";
188}
189
190
191} }// namespace Poco::Data
192