mirror of
https://github.com/pocoproject/poco.git
synced 2025-01-18 00:15:27 +01:00
JSON Formatter modifications
This commit is contained in:
parent
16260784da
commit
07a2529d9d
@ -303,7 +303,7 @@
|
||||
<ClInclude Include="include\Poco\Data\DynamicDateTime.h" />
|
||||
<ClInclude Include="include\Poco\Data\DynamicLOB.h" />
|
||||
<ClInclude Include="include\Poco\Data\Extraction.h" />
|
||||
<ClInclude Include="include\Poco\Data\JSONFormatter.h" />
|
||||
<ClInclude Include="include\Poco\Data\JSONRowFormatter.h" />
|
||||
<ClInclude Include="include\Poco\Data\Limit.h" />
|
||||
<ClInclude Include="include\Poco\Data\LOB.h" />
|
||||
<ClInclude Include="include\Poco\Data\LOBStream.h" />
|
||||
@ -345,7 +345,7 @@
|
||||
<ClCompile Include="src\DataException.cpp" />
|
||||
<ClCompile Include="src\Date.cpp" />
|
||||
<ClCompile Include="src\DynamicLOB.cpp" />
|
||||
<ClCompile Include="src\JSONFormatter.cpp" />
|
||||
<ClCompile Include="src\JSONRowFormatter.cpp" />
|
||||
<ClCompile Include="src\Limit.cpp" />
|
||||
<ClCompile Include="src\MetaColumn.cpp" />
|
||||
<ClCompile Include="src\PooledSessionHolder.cpp" />
|
||||
|
@ -177,7 +177,7 @@
|
||||
<ClInclude Include="include\Poco\Data\SQLChannel.h">
|
||||
<Filter>Logging\Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\Poco\Data\JSONFormatter.h">
|
||||
<ClInclude Include="include\Poco\Data\JSONRowFormatter.h">
|
||||
<Filter>DataCore\Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
@ -287,7 +287,7 @@
|
||||
<ClCompile Include="src\SQLChannel.cpp">
|
||||
<Filter>Logging\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\JSONFormatter.cpp">
|
||||
<ClCompile Include="src\JSONRowFormatter.cpp">
|
||||
<Filter>DataCore\Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "Poco/Data/LOB.h"
|
||||
#include "Poco/Data/Statement.h"
|
||||
#include "Poco/Data/RecordSet.h"
|
||||
#include "Poco/Data/JSONRowFormatter.h"
|
||||
#include "Poco/Data/SQLChannel.h"
|
||||
#include "Poco/Data/SessionFactory.h"
|
||||
#include "Poco/Data/SQLite/Connector.h"
|
||||
@ -49,6 +50,7 @@ using namespace Poco::Data::Keywords;
|
||||
using Poco::Data::Session;
|
||||
using Poco::Data::Statement;
|
||||
using Poco::Data::RecordSet;
|
||||
using Poco::Data::JSONRowFormatter;
|
||||
using Poco::Data::Column;
|
||||
using Poco::Data::Row;
|
||||
using Poco::Data::SQLChannel;
|
||||
@ -3356,6 +3358,85 @@ void SQLiteTest::testFTS3()
|
||||
}
|
||||
|
||||
|
||||
void SQLiteTest::testJSONRowFormatter()
|
||||
{
|
||||
Session tmp(Poco::Data::SQLite::Connector::KEY, "dummy.db");
|
||||
assert(tmp.isConnected());
|
||||
std::string lastName("Simpson");
|
||||
std::string firstName("Bart");
|
||||
std::string address("Springfield");
|
||||
int age = 12;
|
||||
|
||||
tmp << "DROP TABLE IF EXISTS Simpsons", now;
|
||||
tmp << "CREATE TABLE IF NOT EXISTS Simpsons (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now;
|
||||
|
||||
checkJSON("SELECT * FROM Simpsons", "");
|
||||
|
||||
tmp << "INSERT INTO Simpsons VALUES(?, ?, ?, ?)", use(lastName), use(firstName), use(address), use(age), now;
|
||||
|
||||
checkJSON("SELECT * FROM Simpsons",
|
||||
"{"
|
||||
"\"names\":[\"LastName\",\"FirstName\",\"Address\",\"Age\"],"
|
||||
"\"values\":[[\"Simpson\",\"Bart\",\"Springfield\",12]]"
|
||||
"}");
|
||||
|
||||
lastName = "Simpson";
|
||||
firstName ="Lisa";
|
||||
address ="Springfield";
|
||||
age = 10;
|
||||
tmp << "INSERT INTO Simpsons VALUES(?, ?, ?, ?)", use(lastName), use(firstName), use(address), use(age), now;
|
||||
|
||||
checkJSON("SELECT * FROM Simpsons",
|
||||
"{"
|
||||
"\"names\":[\"LastName\",\"FirstName\",\"Address\",\"Age\"],"
|
||||
"\"values\":[[\"Simpson\",\"Bart\",\"Springfield\",12],"
|
||||
"[\"Simpson\",\"Lisa\",\"Springfield\",10]]"
|
||||
"}");
|
||||
|
||||
checkJSON("SELECT * FROM Simpsons",
|
||||
"{"
|
||||
"[[\"Simpson\",\"Bart\",\"Springfield\",12],"
|
||||
"[\"Simpson\",\"Lisa\",\"Springfield\",10]]"
|
||||
"}", JSONRowFormatter::JSON_FMT_MODE_SMALL);
|
||||
|
||||
checkJSON("SELECT * FROM Simpsons",
|
||||
"{\"count\":2,"
|
||||
"[[\"Simpson\",\"Bart\",\"Springfield\",12],"
|
||||
"[\"Simpson\",\"Lisa\",\"Springfield\",10]]"
|
||||
"}", JSONRowFormatter::JSON_FMT_MODE_ROW_COUNT);
|
||||
|
||||
checkJSON("SELECT * FROM Simpsons",
|
||||
"{"
|
||||
"\"names\":[\"LastName\",\"FirstName\",\"Address\",\"Age\"],"
|
||||
"\"values\":[[\"Simpson\",\"Bart\",\"Springfield\",12],"
|
||||
"[\"Simpson\",\"Lisa\",\"Springfield\",10]]"
|
||||
"}", JSONRowFormatter::JSON_FMT_MODE_COLUMN_NAMES);
|
||||
|
||||
checkJSON("SELECT * FROM Simpsons",
|
||||
"{\"count\":2,"
|
||||
"[{\"LastName\":\"Simpson\",\"FirstName\":\"Bart\",\"Address\":\"Springfield\",\"Age\":12},"
|
||||
"{\"LastName\":\"Simpson\",\"FirstName\":\"Lisa\",\"Address\":\"Springfield\",\"Age\":10}]"
|
||||
"}", JSONRowFormatter::JSON_FMT_MODE_FULL);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void SQLiteTest::checkJSON(const std::string& sql, const std::string& json, int mode)
|
||||
{
|
||||
Session tmp(Poco::Data::SQLite::Connector::KEY, "dummy.db");
|
||||
|
||||
JSONRowFormatter jf;
|
||||
if (mode > 0)
|
||||
jf.setJSONMode(mode);
|
||||
|
||||
Statement stmt = (tmp << sql, format(jf), now);
|
||||
RecordSet rs(stmt);
|
||||
std::ostringstream ostr;
|
||||
ostr << rs;
|
||||
assert(ostr.str() == json);
|
||||
}
|
||||
|
||||
|
||||
void SQLiteTest::setUp()
|
||||
{
|
||||
}
|
||||
@ -3456,6 +3537,7 @@ CppUnit::Test* SQLiteTest::suite()
|
||||
CppUnit_addTest(pSuite, SQLiteTest, testTransaction);
|
||||
CppUnit_addTest(pSuite, SQLiteTest, testTransactor);
|
||||
CppUnit_addTest(pSuite, SQLiteTest, testFTS3);
|
||||
CppUnit_addTest(pSuite, SQLiteTest, testJSONRowFormatter);
|
||||
|
||||
return pSuite;
|
||||
}
|
||||
|
@ -135,6 +135,8 @@ public:
|
||||
|
||||
void testFTS3();
|
||||
|
||||
void testJSONRowFormatter();
|
||||
|
||||
void setUp();
|
||||
void tearDown();
|
||||
|
||||
@ -152,6 +154,7 @@ public:
|
||||
|
||||
private:
|
||||
void setTransactionIsolation(Poco::Data::Session& session, Poco::UInt32 ti);
|
||||
void checkJSON(const std::string& sql, const std::string& json, int mode = 0);
|
||||
|
||||
static int _insertCounter;
|
||||
static int _updateCounter;
|
||||
|
@ -215,6 +215,21 @@ public:
|
||||
return _val;
|
||||
}
|
||||
|
||||
bool isDate() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isTime() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isDateTime() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
VarHolderImpl();
|
||||
Poco::Data::Date _val;
|
||||
|
@ -1,62 +0,0 @@
|
||||
//
|
||||
// JSONFormatter.h
|
||||
//
|
||||
// $Id: //poco/Main/Data/include/Poco/Data/JSONFormatter.h#9 $
|
||||
//
|
||||
// Library: Data
|
||||
// Package: DataCore
|
||||
// Module: JSONFormatter
|
||||
//
|
||||
// Definition of the JSONFormatter class.
|
||||
//
|
||||
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#ifndef Data_JSONFormatter_INCLUDED
|
||||
#define Data_JSONFormatter_INCLUDED
|
||||
|
||||
|
||||
#include "Poco/Data/RowFormatter.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Data {
|
||||
|
||||
|
||||
class Data_API JSONFormatter: public Poco::Data::RowFormatter
|
||||
/// Class for JSON formatting of data rows.
|
||||
{
|
||||
public:
|
||||
JSONFormatter();
|
||||
/// Creates a new JSONFormatter.
|
||||
|
||||
~JSONFormatter();
|
||||
/// Destroy the JSONFormatter.
|
||||
|
||||
std::string& formatNames(const NameVecPtr pNames, std::string& formattedNames);
|
||||
std::string& formatValues(const ValueVec& vals, std::string& formattedValues);
|
||||
|
||||
private:
|
||||
NameVecPtr _pNames;
|
||||
int _rowCounter;
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// inlines
|
||||
//
|
||||
inline std::string& JSONFormatter::formatNames(const NameVecPtr pNames, std::string& formattedNames)
|
||||
{
|
||||
// names are used in formatValues
|
||||
if (pNames && !_pNames) _pNames = pNames;
|
||||
return formattedNames = "";
|
||||
}
|
||||
|
||||
} } // namespace Poco::Data
|
||||
|
||||
|
||||
#endif // Data_JSONFormatter_INCLUDED
|
116
Data/include/Poco/Data/JSONRowFormatter.h
Normal file
116
Data/include/Poco/Data/JSONRowFormatter.h
Normal file
@ -0,0 +1,116 @@
|
||||
//
|
||||
// JSONRowFormatter.h
|
||||
//
|
||||
// $Id: //poco/Main/Data/include/Poco/Data/JSONRowFormatter.h#9 $
|
||||
//
|
||||
// Library: Data
|
||||
// Package: DataCore
|
||||
// Module: JSONRowFormatter
|
||||
//
|
||||
// Definition of the JSONRowFormatter class.
|
||||
//
|
||||
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#ifndef Data_JSONRowFormatter_INCLUDED
|
||||
#define Data_JSONRowFormatter_INCLUDED
|
||||
|
||||
|
||||
#include "Poco/Data/RowFormatter.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Data {
|
||||
|
||||
|
||||
class Data_API JSONRowFormatter: public Poco::Data::RowFormatter
|
||||
/// Class for JSON formatting of data rows.
|
||||
{
|
||||
public:
|
||||
static const int JSON_FMT_MODE_SMALL = 1;
|
||||
static const int JSON_FMT_MODE_ROW_COUNT = 2;
|
||||
static const int JSON_FMT_MODE_COLUMN_NAMES = 4;
|
||||
static const int JSON_FMT_MODE_FULL = 8;
|
||||
|
||||
JSONRowFormatter(int mode = (JSON_FMT_MODE_COLUMN_NAMES | JSON_FMT_MODE_SMALL));
|
||||
/// Creates a new JSONRowFormatter.
|
||||
|
||||
~JSONRowFormatter();
|
||||
/// Destroys the JSONRowFormatter.
|
||||
|
||||
std::string& formatNames(const NameVecPtr pNames, std::string& formattedNames);
|
||||
/// Formats names.
|
||||
|
||||
std::string& formatValues(const ValueVec& vals, std::string& formattedValues);
|
||||
// Formats values.
|
||||
|
||||
void setJSONMode(int mode);
|
||||
/// Sets the mode. Valid mode values are:
|
||||
/// JSON_FMT_MODE_SMALL
|
||||
/// JSON_FMT_MODE_ROW_COUNT
|
||||
/// JSON_FMT_MODE_COLUMN_NAMES
|
||||
/// JSON_FMT_MODE_FULL
|
||||
|
||||
bool printRowCount();
|
||||
/// Returns true if row count printing is enabled,
|
||||
/// false otherwise.
|
||||
|
||||
bool printColumnNames();
|
||||
/// Returns true if column names printing is enabled,
|
||||
/// false otherwise.
|
||||
|
||||
bool isSmall();
|
||||
/// Returns true if compact mode formatting is enabled,
|
||||
/// false otherwise.
|
||||
|
||||
bool isFull();
|
||||
/// Returns true if full mode formatting is enabled,
|
||||
/// false otherwise.
|
||||
|
||||
|
||||
private:
|
||||
void adjustPrefix();
|
||||
|
||||
NameVecPtr _pNames;
|
||||
int _mode;
|
||||
bool _firstTime;
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// inlines
|
||||
//
|
||||
|
||||
|
||||
inline bool JSONRowFormatter::printRowCount()
|
||||
{
|
||||
return (_mode & JSON_FMT_MODE_ROW_COUNT) != 0;
|
||||
}
|
||||
|
||||
|
||||
inline bool JSONRowFormatter::printColumnNames()
|
||||
{
|
||||
return (_mode & JSON_FMT_MODE_COLUMN_NAMES) != 0;
|
||||
}
|
||||
|
||||
|
||||
inline bool JSONRowFormatter::isSmall()
|
||||
{
|
||||
return (_mode & JSON_FMT_MODE_SMALL) != 0;
|
||||
}
|
||||
|
||||
|
||||
inline bool JSONRowFormatter::isFull()
|
||||
{
|
||||
return (_mode & JSON_FMT_MODE_FULL) != 0;
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Data
|
||||
|
||||
|
||||
#endif // Data_JSONRowFormatter_INCLUDED
|
@ -40,7 +40,7 @@ class Data_API RowFormatter
|
||||
/// Row formatter can be either passed to the RecordSet at construction time,
|
||||
/// like in the following example:
|
||||
///
|
||||
/// RecordSet rs(session. "SELECT * FROM Table", new MyRowFormater);
|
||||
/// RecordSet rs(session, "SELECT * FROM Table", new MyRowFormater);
|
||||
///
|
||||
/// or it can be supplied to the statement as in the following example:
|
||||
///
|
||||
@ -147,6 +147,12 @@ protected:
|
||||
void setPostfix(const std::string& postfix);
|
||||
/// Sets the postfix for the formatter
|
||||
|
||||
virtual void adjustPrefix();
|
||||
/// Adjusts prefix after it has been set.
|
||||
/// No-op here, called by setTotalRowCount and
|
||||
/// should be implemented by inheriting classes,
|
||||
/// if needed.
|
||||
|
||||
private:
|
||||
|
||||
mutable std::string _prefix;
|
||||
@ -174,6 +180,7 @@ inline int RowFormatter::getTotalRowCount() const
|
||||
inline void RowFormatter::setTotalRowCount(int count)
|
||||
{
|
||||
_totalRowCount = count;
|
||||
adjustPrefix();
|
||||
}
|
||||
|
||||
|
||||
@ -213,6 +220,11 @@ inline void RowFormatter::setMode(Mode mode)
|
||||
}
|
||||
|
||||
|
||||
inline void RowFormatter::adjustPrefix()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
namespace Keywords {
|
||||
|
||||
|
||||
|
@ -219,6 +219,21 @@ public:
|
||||
return _val;
|
||||
}
|
||||
|
||||
bool isDate() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isTime() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isDateTime() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
VarHolderImpl();
|
||||
Poco::Data::Time _val;
|
||||
|
@ -1,87 +0,0 @@
|
||||
//
|
||||
// JSONFormatter.cpp
|
||||
//
|
||||
// $Id: //poco/Main/Data/src/JSONFormatter.cpp#1 $
|
||||
//
|
||||
// Library: Data
|
||||
// Package: DataCore
|
||||
// Module: JSONFormatter
|
||||
//
|
||||
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Data/JSONFormatter.h"
|
||||
#include "Poco/String.h"
|
||||
#include "Poco/JSONString.h"
|
||||
#include "Poco/Format.h"
|
||||
|
||||
|
||||
using Poco::trimInPlace;
|
||||
using Poco::format;
|
||||
using Poco::toJSON;
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Data {
|
||||
|
||||
|
||||
JSONFormatter::JSONFormatter() : _rowCounter(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
JSONFormatter::~JSONFormatter()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
std::string& JSONFormatter::formatValues(const ValueVec& vals, std::string& formattedValues)
|
||||
{
|
||||
std::ostringstream str;
|
||||
|
||||
str << "{\"count\":" << getTotalRowCount() << ",\"rows\":[{";
|
||||
|
||||
std::string pref = str.str();
|
||||
if (prefix() != pref) setPrefix(pref);
|
||||
else
|
||||
{
|
||||
str.str("");
|
||||
str << ",{";
|
||||
}
|
||||
|
||||
if (postfix().empty()) setPostfix("]}");
|
||||
|
||||
ValueVec::const_iterator it = vals.begin();
|
||||
ValueVec::const_iterator end = vals.end();
|
||||
NameVec::iterator nIt = _pNames->begin();
|
||||
NameVec::iterator nEnd = _pNames->end();
|
||||
for (; it != end && nIt != nEnd; ++nIt)
|
||||
{
|
||||
if (!it->isEmpty())
|
||||
{
|
||||
if (it->isString())
|
||||
{
|
||||
std::string val = it->convert<std::string>();
|
||||
trimInPlace(val);
|
||||
str << '"' << *nIt << "\":" << toJSON(val);
|
||||
}
|
||||
else
|
||||
str << '"' << *nIt << "\":" << it->convert<std::string>();
|
||||
}
|
||||
else
|
||||
str << '"' << *nIt << "\":null";
|
||||
|
||||
if (++it != end) str << ',';
|
||||
}
|
||||
|
||||
str << '}';
|
||||
++_rowCounter;
|
||||
return formattedValues = str.str();
|
||||
}
|
||||
|
||||
|
||||
} }// namespace Poco::Data
|
187
Data/src/JSONRowFormatter.cpp
Normal file
187
Data/src/JSONRowFormatter.cpp
Normal file
@ -0,0 +1,187 @@
|
||||
//
|
||||
// JSONRowFormatter.cpp
|
||||
//
|
||||
// $Id: //poco/Main/Data/src/JSONRowFormatter.cpp#1 $
|
||||
//
|
||||
// Library: Data
|
||||
// Package: DataCore
|
||||
// Module: JSONRowFormatter
|
||||
//
|
||||
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Data/JSONRowFormatter.h"
|
||||
#include "Poco/String.h"
|
||||
#include "Poco/JSONString.h"
|
||||
#include "Poco/Format.h"
|
||||
|
||||
|
||||
using Poco::trimInPlace;
|
||||
using Poco::format;
|
||||
using Poco::toJSON;
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Data {
|
||||
|
||||
|
||||
JSONRowFormatter::JSONRowFormatter(int mode) : RowFormatter("{", "]}"),
|
||||
_firstTime(true)
|
||||
{
|
||||
if (mode == JSON_FMT_MODE_FULL)
|
||||
{
|
||||
mode |= JSON_FMT_MODE_ROW_COUNT;
|
||||
mode |= JSON_FMT_MODE_COLUMN_NAMES;
|
||||
//setPostfix("]}");
|
||||
}
|
||||
|
||||
setJSONMode(mode);
|
||||
}
|
||||
|
||||
|
||||
JSONRowFormatter::~JSONRowFormatter()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void JSONRowFormatter::adjustPrefix()
|
||||
{
|
||||
if (printRowCount())
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
ostr << "{\"count\":" << getTotalRowCount() << ",";
|
||||
if (_mode & JSON_FMT_MODE_FULL)
|
||||
ostr << '[';
|
||||
setPrefix(ostr.str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void JSONRowFormatter::setJSONMode(int mode)
|
||||
{
|
||||
if (mode < JSON_FMT_MODE_SMALL ||
|
||||
mode > (JSON_FMT_MODE_SMALL | JSON_FMT_MODE_ROW_COUNT | JSON_FMT_MODE_COLUMN_NAMES | JSON_FMT_MODE_FULL))
|
||||
{
|
||||
throw Poco::InvalidArgumentException(
|
||||
Poco::format("JSONRowFormatter mode must be between "
|
||||
"%d (JSON_FMT_MODE_SMALL) and %d (JSON_FMT_MODE_FULL)",
|
||||
JSON_FMT_MODE_SMALL,
|
||||
JSON_FMT_MODE_FULL));
|
||||
}
|
||||
|
||||
_mode = mode;
|
||||
if (!(_mode & JSON_FMT_MODE_SMALL) && !(_mode & JSON_FMT_MODE_FULL))
|
||||
_mode |= JSON_FMT_MODE_SMALL;
|
||||
else if (_mode & JSON_FMT_MODE_FULL)
|
||||
{
|
||||
_mode |= JSON_FMT_MODE_ROW_COUNT;
|
||||
}
|
||||
|
||||
adjustPrefix();
|
||||
}
|
||||
|
||||
|
||||
std::string& JSONRowFormatter::formatValues(const ValueVec& vals, std::string& formattedValues)
|
||||
{
|
||||
std::ostringstream str;
|
||||
if (!_firstTime) str << ',';
|
||||
if (isSmall())
|
||||
{
|
||||
if (_firstTime)
|
||||
{
|
||||
if (printColumnNames())
|
||||
str << ",\"values\":";
|
||||
|
||||
str << '[';
|
||||
}
|
||||
|
||||
str << '[';
|
||||
ValueVec::const_iterator it = vals.begin();
|
||||
ValueVec::const_iterator end = vals.end();
|
||||
for (; it != end;)
|
||||
{
|
||||
if (!it->isEmpty())
|
||||
{
|
||||
if (it->isString() || it->isDate() || it->isTime())
|
||||
{
|
||||
std::string val = it->convert<std::string>();
|
||||
trimInPlace(val);
|
||||
str << toJSON(val);
|
||||
}
|
||||
else
|
||||
str << it->convert<std::string>();
|
||||
}
|
||||
else
|
||||
str << "null";
|
||||
|
||||
if (++it == end) break;
|
||||
|
||||
str << ',';
|
||||
}
|
||||
str << ']';
|
||||
}
|
||||
else if (isFull())
|
||||
{
|
||||
str << '{';
|
||||
ValueVec::const_iterator it = vals.begin();
|
||||
ValueVec::const_iterator end = vals.end();
|
||||
NameVec::iterator nIt = _pNames->begin();
|
||||
NameVec::iterator nEnd = _pNames->end();
|
||||
for (; it != end && nIt != nEnd; ++nIt)
|
||||
{
|
||||
if (!it->isEmpty())
|
||||
{
|
||||
if (it->isString() || it->isDate() || it->isTime())
|
||||
{
|
||||
std::string val = it->convert<std::string>();
|
||||
trimInPlace(val);
|
||||
str << '"' << *nIt << "\":" << toJSON(val);
|
||||
}
|
||||
else
|
||||
str << '"' << *nIt << "\":" << it->convert<std::string>();
|
||||
}
|
||||
else
|
||||
str << '"' << *nIt << "\":null";
|
||||
|
||||
if (++it != end) str << ',';
|
||||
}
|
||||
str << '}';
|
||||
}
|
||||
|
||||
_firstTime = false;
|
||||
return formattedValues = str.str();
|
||||
}
|
||||
|
||||
|
||||
std::string& JSONRowFormatter::formatNames(const NameVecPtr pNames, std::string& formattedNames)
|
||||
{
|
||||
if (isFull())
|
||||
{
|
||||
// names are used in formatValues
|
||||
if (pNames && !_pNames) _pNames = pNames;
|
||||
return formattedNames = "";
|
||||
}
|
||||
else if (printColumnNames())
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
ostr << "\"names\":[";
|
||||
for (NameVec::const_iterator it = pNames->begin(),
|
||||
end = pNames->end();;)
|
||||
{
|
||||
ostr << '"' << *it << '"';
|
||||
if (++it == end) break;
|
||||
ostr << ',';
|
||||
}
|
||||
ostr << "]";
|
||||
return formattedNames = ostr.str();
|
||||
}
|
||||
|
||||
return formattedNames = "";
|
||||
}
|
||||
|
||||
|
||||
} }// namespace Poco::Data
|
@ -311,6 +311,8 @@ void RecordSet::setRowFormatter(RowFormatter::Ptr pRowFormatter)
|
||||
|
||||
std::ostream& RecordSet::copyNames(std::ostream& os) const
|
||||
{
|
||||
if (begin() == end()) return os;
|
||||
|
||||
std::string names = (*_pBegin)->namesToString();
|
||||
if (!names.empty()) os << names;
|
||||
return os;
|
||||
@ -319,6 +321,8 @@ std::ostream& RecordSet::copyNames(std::ostream& os) const
|
||||
|
||||
std::ostream& RecordSet::copyValues(std::ostream& os, std::size_t offset, std::size_t length) const
|
||||
{
|
||||
if (begin() == end()) return os;
|
||||
|
||||
RowIterator it = *_pBegin + offset;
|
||||
RowIterator end = (RowIterator::POSITION_END != length) ? it + length : *_pEnd;
|
||||
std::copy(it, end, std::ostream_iterator<Row>(os));
|
||||
@ -328,6 +332,8 @@ std::ostream& RecordSet::copyValues(std::ostream& os, std::size_t offset, std::s
|
||||
|
||||
void RecordSet::formatValues(std::size_t offset, std::size_t length) const
|
||||
{
|
||||
if (begin() == end()) return;
|
||||
|
||||
RowIterator it = *_pBegin + offset;
|
||||
RowIterator end = (RowIterator::POSITION_END != length) ? it + length : *_pEnd;
|
||||
std::string val;
|
||||
@ -337,6 +343,8 @@ void RecordSet::formatValues(std::size_t offset, std::size_t length) const
|
||||
|
||||
std::ostream& RecordSet::copy(std::ostream& os, std::size_t offset, std::size_t length) const
|
||||
{
|
||||
if (begin() == end()) return os;
|
||||
|
||||
RowFormatter& rf = const_cast<RowFormatter&>((*_pBegin)->getFormatter());
|
||||
rf.setTotalRowCount(static_cast<int>(getTotalRowCount()));
|
||||
if (RowFormatter::FORMAT_PROGRESSIVE == rf.getMode())
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "Poco/Data/Date.h"
|
||||
#include "Poco/Data/Time.h"
|
||||
#include "Poco/Data/SimpleRowFormatter.h"
|
||||
#include "Poco/Data/JSONRowFormatter.h"
|
||||
#include "Poco/Data/DataException.h"
|
||||
#include "Connector.h"
|
||||
#include "Poco/BinaryReader.h"
|
||||
@ -64,7 +65,9 @@ using Poco::Data::CLOBOutputStream;
|
||||
using Poco::Data::MetaColumn;
|
||||
using Poco::Data::Column;
|
||||
using Poco::Data::Row;
|
||||
using Poco::Data::RowFormatter;
|
||||
using Poco::Data::SimpleRowFormatter;
|
||||
using Poco::Data::JSONRowFormatter;
|
||||
using Poco::Data::Date;
|
||||
using Poco::Data::Time;
|
||||
using Poco::Data::AbstractExtraction;
|
||||
@ -1166,7 +1169,7 @@ void DataTest::testRowStrictWeak(const Row& row1, const Row& row2, const Row& ro
|
||||
}
|
||||
|
||||
|
||||
void DataTest::testRowFormat()
|
||||
void DataTest::testSimpleRowFormatter()
|
||||
{
|
||||
Row row1;
|
||||
row1.append("field0", 0);
|
||||
@ -1210,6 +1213,40 @@ void DataTest::testRowFormat()
|
||||
}
|
||||
|
||||
|
||||
void DataTest::testJSONRowFormatter()
|
||||
{
|
||||
Row row1;
|
||||
row1.append("field0", 0);
|
||||
row1.append("field1", "1");
|
||||
row1.append("field2", DateTime(2007, 3, 13, 8, 12, 15));
|
||||
row1.append("field3", Var());
|
||||
row1.append("field4", 4);
|
||||
row1.setFormatter(new JSONRowFormatter);
|
||||
|
||||
assert(row1.getFormatter().prefix() == "{");
|
||||
assert(row1.getFormatter().postfix() == "]}");
|
||||
assert(row1.getFormatter().getMode() == RowFormatter::FORMAT_PROGRESSIVE);
|
||||
assert(row1.namesToString() == "\"names\":[\"field0\",\"field1\",\"field2\",\"field3\",\"field4\"]");
|
||||
assert(row1.valuesToString() == ",\"values\":[[0,\"1\",\"2007-03-13T08:12:15Z\",null,4]");
|
||||
|
||||
row1.setFormatter(new JSONRowFormatter(JSONRowFormatter::JSON_FMT_MODE_SMALL));
|
||||
assert(row1.getFormatter().getMode() == RowFormatter::FORMAT_PROGRESSIVE);
|
||||
assert(row1.namesToString() == "");
|
||||
//std::cout << row1.valuesToString() << std::endl;
|
||||
assert(row1.valuesToString() == "[[0,\"1\",\"2007-03-13T08:12:15Z\",null,4]");
|
||||
assert(row1.valuesToString() == ",[0,\"1\",\"2007-03-13T08:12:15Z\",null,4]");
|
||||
|
||||
row1.setFormatter(new JSONRowFormatter(JSONRowFormatter::JSON_FMT_MODE_FULL));
|
||||
assert(row1.getFormatter().prefix() == "{\"count\":0,[");
|
||||
assert(row1.getFormatter().postfix() == "]}");
|
||||
assert(row1.getFormatter().getMode() == RowFormatter::FORMAT_PROGRESSIVE);
|
||||
std::cout << row1.namesToString() << std::endl;
|
||||
assert(row1.namesToString() == "");
|
||||
assert(row1.valuesToString() == "{\"field0\":0,\"field1\":\"1\",\"field2\":\"2007-03-13T08:12:15Z\",\"field3\":null,\"field4\":4}");
|
||||
assert(row1.valuesToString() == ",{\"field0\":0,\"field1\":\"1\",\"field2\":\"2007-03-13T08:12:15Z\",\"field3\":null,\"field4\":4}");
|
||||
}
|
||||
|
||||
|
||||
void DataTest::testDateAndTime()
|
||||
{
|
||||
DateTime dt;
|
||||
@ -1399,7 +1436,8 @@ CppUnit::Test* DataTest::suite()
|
||||
CppUnit_addTest(pSuite, DataTest, testColumnList);
|
||||
CppUnit_addTest(pSuite, DataTest, testRow);
|
||||
CppUnit_addTest(pSuite, DataTest, testRowSort);
|
||||
CppUnit_addTest(pSuite, DataTest, testRowFormat);
|
||||
CppUnit_addTest(pSuite, DataTest, testSimpleRowFormatter);
|
||||
CppUnit_addTest(pSuite, DataTest, testJSONRowFormatter);
|
||||
CppUnit_addTest(pSuite, DataTest, testDateAndTime);
|
||||
CppUnit_addTest(pSuite, DataTest, testExternalBindingAndExtraction);
|
||||
|
||||
|
@ -42,7 +42,8 @@ public:
|
||||
void testColumnList();
|
||||
void testRow();
|
||||
void testRowSort();
|
||||
void testRowFormat();
|
||||
void testSimpleRowFormatter();
|
||||
void testJSONRowFormatter();
|
||||
void testDateAndTime();
|
||||
void testExternalBindingAndExtraction();
|
||||
|
||||
|
@ -502,6 +502,15 @@ public:
|
||||
bool isString() const;
|
||||
/// Returns true if stored value is std::string.
|
||||
|
||||
bool isDate() const;
|
||||
/// Returns true if stored value represents a date.
|
||||
|
||||
bool isTime() const;
|
||||
/// Returns true if stored value represents time or date/time.
|
||||
|
||||
bool isDateTime() const;
|
||||
/// Returns true if stored value represents a date/time.
|
||||
|
||||
std::size_t size() const;
|
||||
/// Returns the size of this Var.
|
||||
/// This function returns 0 when Var is empty, 1 for POD or the size (i.e. length)
|
||||
@ -844,6 +853,27 @@ inline bool Var::isString() const
|
||||
}
|
||||
|
||||
|
||||
inline bool Var::isDate() const
|
||||
{
|
||||
VarHolder* pHolder = content();
|
||||
return pHolder ? pHolder->isDate() : false;
|
||||
}
|
||||
|
||||
|
||||
inline bool Var::isTime() const
|
||||
{
|
||||
VarHolder* pHolder = content();
|
||||
return pHolder ? pHolder->isTime() : false;
|
||||
}
|
||||
|
||||
|
||||
inline bool Var::isDateTime() const
|
||||
{
|
||||
VarHolder* pHolder = content();
|
||||
return pHolder ? pHolder->isDateTime() : false;
|
||||
}
|
||||
|
||||
|
||||
inline std::size_t Var::size() const
|
||||
{
|
||||
VarHolder* pHolder = content();
|
||||
|
@ -254,6 +254,18 @@ public:
|
||||
/// Returns false. Must be properly overriden in a type
|
||||
/// specialization in order to suport the diagnostic.
|
||||
|
||||
virtual bool isDate() const;
|
||||
/// Returns false. Must be properly overriden in a type
|
||||
/// specialization in order to suport the diagnostic.
|
||||
|
||||
virtual bool isTime() const;
|
||||
/// Returns false. Must be properly overriden in a type
|
||||
/// specialization in order to suport the diagnostic.
|
||||
|
||||
virtual bool isDateTime() const;
|
||||
/// Returns false. Must be properly overriden in a type
|
||||
/// specialization in order to suport the diagnostic.
|
||||
|
||||
virtual std::size_t size() const;
|
||||
/// Returns 1 iff Var is not empty or this function overriden.
|
||||
|
||||
@ -609,6 +621,24 @@ inline bool VarHolder::isString() const
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
inline bool VarHolder::isDate() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
inline bool VarHolder::isTime() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
inline bool VarHolder::isDateTime() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
inline std::size_t VarHolder::size() const
|
||||
{
|
||||
return 1u;
|
||||
@ -3331,6 +3361,21 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isDate() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isTime() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isDateTime() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
VarHolderImpl();
|
||||
VarHolderImpl(const VarHolderImpl&);
|
||||
@ -3432,6 +3477,21 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isDate() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isTime() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isDateTime() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
VarHolderImpl();
|
||||
VarHolderImpl(const VarHolderImpl&);
|
||||
@ -3533,6 +3593,21 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isDate() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isTime() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isDateTime() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
VarHolderImpl();
|
||||
VarHolderImpl(const VarHolderImpl&);
|
||||
|
@ -2392,8 +2392,17 @@ void VarTest::testDate()
|
||||
Poco::Timestamp tsNow = dtNow.timestamp();
|
||||
Poco::LocalDateTime ldtNow(dtNow.timestamp());
|
||||
Var dt(dtNow);
|
||||
assert(dt.isDate());
|
||||
assert(dt.isTime());
|
||||
assert(dt.isDateTime());
|
||||
Var ts(tsNow);
|
||||
assert(ts.isDate());
|
||||
assert(ts.isTime());
|
||||
assert(ts.isDateTime());
|
||||
Var ldt(ldtNow);
|
||||
assert(ldt.isDate());
|
||||
assert(ldt.isTime());
|
||||
assert(ldt.isDateTime());
|
||||
Var dtStr(dt.convert<std::string>());
|
||||
Var tsStr(ts.convert<std::string>());
|
||||
Var ldtStr(ldt.convert<std::string>());
|
||||
|
Loading…
x
Reference in New Issue
Block a user