mirror of
https://github.com/pocoproject/poco.git
synced 2025-04-01 09:24:55 +02:00
fix(Extractor): move extraction decoding to AbstractExtractor #3396
This commit is contained in:
parent
7f26310ef2
commit
4dfbcd33db
@ -33,7 +33,6 @@
|
|||||||
#include "Poco/Nullable.h"
|
#include "Poco/Nullable.h"
|
||||||
#include "Poco/UTFString.h"
|
#include "Poco/UTFString.h"
|
||||||
#include "Poco/TextEncoding.h"
|
#include "Poco/TextEncoding.h"
|
||||||
#include "Poco/TextConverter.h"
|
|
||||||
#include "Poco/Exception.h"
|
#include "Poco/Exception.h"
|
||||||
#include <map>
|
#include <map>
|
||||||
#ifdef POCO_OS_FAMILY_WINDOWS
|
#ifdef POCO_OS_FAMILY_WINDOWS
|
||||||
@ -592,11 +591,10 @@ private:
|
|||||||
val.clear();
|
val.clear();
|
||||||
if (ret)
|
if (ret)
|
||||||
{
|
{
|
||||||
Poco::TextConverter conv(*_pDBEncoding, *_pToEncoding);
|
|
||||||
val.resize(res.size());
|
val.resize(res.size());
|
||||||
typename C::iterator vIt = val.begin();
|
typename C::iterator vIt = val.begin();
|
||||||
typename C::iterator it = res.begin();
|
typename C::iterator it = res.begin();
|
||||||
for (; it != res.end(); ++it, ++vIt) conv.convert(*it, *vIt);
|
for (; it != res.end(); ++it, ++vIt) transcode(*it, *vIt);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -607,7 +605,7 @@ private:
|
|||||||
bool ret = false;
|
bool ret = false;
|
||||||
if (Preparator::DE_BOUND == _dataExtraction)
|
if (Preparator::DE_BOUND == _dataExtraction)
|
||||||
{
|
{
|
||||||
if (!_transcode)
|
if (!transcodeRequired())
|
||||||
ret = extractBoundImplContainer(pos, val);
|
ret = extractBoundImplContainer(pos, val);
|
||||||
else
|
else
|
||||||
ret = stringContainerExtractConvert(pos, val);
|
ret = stringContainerExtractConvert(pos, val);
|
||||||
@ -628,9 +626,6 @@ private:
|
|||||||
PreparatorPtr _pPreparator;
|
PreparatorPtr _pPreparator;
|
||||||
Preparator::DataExtraction _dataExtraction;
|
Preparator::DataExtraction _dataExtraction;
|
||||||
std::vector<SQLLEN> _lengths;
|
std::vector<SQLLEN> _lengths;
|
||||||
Poco::TextEncoding::Ptr _pDBEncoding;
|
|
||||||
bool _transcode;
|
|
||||||
Poco::TextEncoding::Ptr _pToEncoding;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -35,13 +35,10 @@ const std::string Extractor::FLD_SIZE_EXCEEDED_FMT = "Specified data size (%z by
|
|||||||
|
|
||||||
Extractor::Extractor(const StatementHandle& rStmt,
|
Extractor::Extractor(const StatementHandle& rStmt,
|
||||||
Preparator::Ptr pPreparator,
|
Preparator::Ptr pPreparator,
|
||||||
TextEncoding::Ptr pDBEncoding):
|
TextEncoding::Ptr pDBEncoding): AbstractExtractor(pDBEncoding),
|
||||||
_rStmt(rStmt),
|
_rStmt(rStmt),
|
||||||
_pPreparator(pPreparator),
|
_pPreparator(pPreparator),
|
||||||
_dataExtraction(pPreparator->getDataExtraction()),
|
_dataExtraction(pPreparator->getDataExtraction())
|
||||||
_pDBEncoding(pDBEncoding),
|
|
||||||
_transcode(_pDBEncoding && !_pDBEncoding->isA("UTF-8")),
|
|
||||||
_pToEncoding(_transcode ? Poco::TextEncoding::find("UTF-8") : nullptr)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -707,7 +704,7 @@ bool Extractor::extract(std::size_t pos, std::string& val)
|
|||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
if (!_transcode)
|
if (!transcodeRequired())
|
||||||
{
|
{
|
||||||
if (Preparator::DE_MANUAL == _dataExtraction)
|
if (Preparator::DE_MANUAL == _dataExtraction)
|
||||||
ret = extractManualImpl(pos, val, SQL_C_CHAR);
|
ret = extractManualImpl(pos, val, SQL_C_CHAR);
|
||||||
@ -721,8 +718,7 @@ bool Extractor::extract(std::size_t pos, std::string& val)
|
|||||||
ret = extractManualImpl(pos, result, SQL_C_CHAR);
|
ret = extractManualImpl(pos, result, SQL_C_CHAR);
|
||||||
else
|
else
|
||||||
ret = extractBoundImpl(pos, result);
|
ret = extractBoundImpl(pos, result);
|
||||||
Poco::TextConverter converter(*_pDBEncoding, *_pToEncoding);
|
transcode(result, val);
|
||||||
converter.convert(result, val);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -23,6 +23,9 @@
|
|||||||
#include "Poco/Data/LOB.h"
|
#include "Poco/Data/LOB.h"
|
||||||
#include "Poco/UUID.h"
|
#include "Poco/UUID.h"
|
||||||
#include "Poco/UTFString.h"
|
#include "Poco/UTFString.h"
|
||||||
|
#include "Poco/TextConverter.h"
|
||||||
|
#include "Poco/TextEncoding.h"
|
||||||
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <list>
|
#include <list>
|
||||||
@ -54,7 +57,8 @@ class Data_API AbstractExtractor
|
|||||||
public:
|
public:
|
||||||
using Ptr = SharedPtr<AbstractExtractor>;
|
using Ptr = SharedPtr<AbstractExtractor>;
|
||||||
|
|
||||||
AbstractExtractor();
|
AbstractExtractor(Poco::TextEncoding::Ptr pDBEncoding = nullptr,
|
||||||
|
Poco::TextEncoding::Ptr pToEncoding = nullptr);
|
||||||
/// Creates the AbstractExtractor.
|
/// Creates the AbstractExtractor.
|
||||||
|
|
||||||
virtual ~AbstractExtractor();
|
virtual ~AbstractExtractor();
|
||||||
@ -346,6 +350,15 @@ public:
|
|||||||
|
|
||||||
virtual void reset();
|
virtual void reset();
|
||||||
/// Resets any information internally cached by the extractor.
|
/// Resets any information internally cached by the extractor.
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool transcodeRequired() const;
|
||||||
|
void transcode(const std::string& val1, std::string& val2);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Poco::TextEncoding::Ptr _pDBEncoding;
|
||||||
|
Poco::TextEncoding::Ptr _pToEncoding;
|
||||||
|
std::unique_ptr<Poco::TextConverter> _pConverter;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -358,6 +371,22 @@ inline void AbstractExtractor::reset()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool AbstractExtractor::transcodeRequired() const
|
||||||
|
{
|
||||||
|
return _pConverter.operator bool();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void AbstractExtractor::transcode(const std::string& val1, std::string& val2)
|
||||||
|
{
|
||||||
|
if (_pConverter)
|
||||||
|
{
|
||||||
|
val2.clear();
|
||||||
|
_pConverter->convert(val1, val2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Data
|
} } // namespace Poco::Data
|
||||||
|
|
||||||
|
|
||||||
|
@ -20,8 +20,18 @@ namespace Poco {
|
|||||||
namespace Data {
|
namespace Data {
|
||||||
|
|
||||||
|
|
||||||
AbstractExtractor::AbstractExtractor()
|
AbstractExtractor::AbstractExtractor(Poco::TextEncoding::Ptr pDBEncoding,
|
||||||
|
Poco::TextEncoding::Ptr pToEncoding):
|
||||||
|
_pDBEncoding(pDBEncoding),
|
||||||
|
_pToEncoding(pToEncoding ?
|
||||||
|
pToEncoding : _pDBEncoding ?
|
||||||
|
Poco::TextEncoding::find("UTF-8") : nullptr),
|
||||||
|
_pConverter(_pDBEncoding ?
|
||||||
|
new Poco::TextConverter(*pDBEncoding, *_pToEncoding) :
|
||||||
|
nullptr)
|
||||||
{
|
{
|
||||||
|
poco_assert_dbg((!_pDBEncoding && !_pToEncoding) ||
|
||||||
|
(_pDBEncoding && _pToEncoding));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "DataTest.h"
|
#include "DataTest.h"
|
||||||
|
#include "Extractor.h"
|
||||||
#include "CppUnit/TestCaller.h"
|
#include "CppUnit/TestCaller.h"
|
||||||
#include "CppUnit/TestSuite.h"
|
#include "CppUnit/TestSuite.h"
|
||||||
#include "Poco/Data/Session.h"
|
#include "Poco/Data/Session.h"
|
||||||
@ -29,6 +30,7 @@
|
|||||||
#include "Poco/Dynamic/Var.h"
|
#include "Poco/Dynamic/Var.h"
|
||||||
#include "Poco/Data/DynamicLOB.h"
|
#include "Poco/Data/DynamicLOB.h"
|
||||||
#include "Poco/Data/DynamicDateTime.h"
|
#include "Poco/Data/DynamicDateTime.h"
|
||||||
|
#include "Poco/Latin1Encoding.h"
|
||||||
#include "Poco/Exception.h"
|
#include "Poco/Exception.h"
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
@ -45,6 +47,7 @@ using Poco::UInt32;
|
|||||||
using Poco::Int64;
|
using Poco::Int64;
|
||||||
using Poco::UInt64;
|
using Poco::UInt64;
|
||||||
using Poco::DateTime;
|
using Poco::DateTime;
|
||||||
|
using Poco::Latin1Encoding;
|
||||||
using Poco::Dynamic::Var;
|
using Poco::Dynamic::Var;
|
||||||
using Poco::InvalidAccessException;
|
using Poco::InvalidAccessException;
|
||||||
using Poco::IllegalStateException;
|
using Poco::IllegalStateException;
|
||||||
@ -65,6 +68,7 @@ using Poco::Data::Row;
|
|||||||
using Poco::Data::SimpleRowFormatter;
|
using Poco::Data::SimpleRowFormatter;
|
||||||
using Poco::Data::Date;
|
using Poco::Data::Date;
|
||||||
using Poco::Data::Time;
|
using Poco::Data::Time;
|
||||||
|
using Poco::Data::AbstractExtractor;
|
||||||
using Poco::Data::AbstractExtraction;
|
using Poco::Data::AbstractExtraction;
|
||||||
using Poco::Data::AbstractExtractionVec;
|
using Poco::Data::AbstractExtractionVec;
|
||||||
using Poco::Data::AbstractExtractionVecVec;
|
using Poco::Data::AbstractExtractionVecVec;
|
||||||
@ -1358,6 +1362,29 @@ void DataTest::testExternalBindingAndExtraction()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DataTest::testTranscode()
|
||||||
|
{
|
||||||
|
Latin1Encoding::Ptr pL2E = new Latin1Encoding();
|
||||||
|
|
||||||
|
const unsigned char latin1Chars[] = { 'g', 252, 'n', 't', 'e', 'r', 0 };
|
||||||
|
const unsigned char utf8Chars[] = { 'g', 195, 188, 'n', 't', 'e', 'r', 0 };
|
||||||
|
std::string latin1Text((const char*)latin1Chars);
|
||||||
|
std::string utf8Text((const char*)utf8Chars);
|
||||||
|
|
||||||
|
Poco::Data::Test::Extractor ext;
|
||||||
|
ext.setString(latin1Text);
|
||||||
|
std::string utf8Out;
|
||||||
|
assertTrue (ext.extract(0, utf8Out));
|
||||||
|
assertTrue(utf8Out == latin1Text);
|
||||||
|
|
||||||
|
Poco::Data::Test::Extractor ext2(new Latin1Encoding());
|
||||||
|
ext2.setString(latin1Text);
|
||||||
|
utf8Out.clear();
|
||||||
|
assertTrue(ext2.extract(0, utf8Out));
|
||||||
|
assertTrue(utf8Out == utf8Text);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void DataTest::setUp()
|
void DataTest::setUp()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -1388,6 +1415,7 @@ CppUnit::Test* DataTest::suite()
|
|||||||
CppUnit_addTest(pSuite, DataTest, testRowFormat);
|
CppUnit_addTest(pSuite, DataTest, testRowFormat);
|
||||||
CppUnit_addTest(pSuite, DataTest, testDateAndTime);
|
CppUnit_addTest(pSuite, DataTest, testDateAndTime);
|
||||||
CppUnit_addTest(pSuite, DataTest, testExternalBindingAndExtraction);
|
CppUnit_addTest(pSuite, DataTest, testExternalBindingAndExtraction);
|
||||||
|
CppUnit_addTest(pSuite, DataTest, testTranscode);
|
||||||
|
|
||||||
return pSuite;
|
return pSuite;
|
||||||
}
|
}
|
||||||
|
@ -43,6 +43,7 @@ public:
|
|||||||
void testRowFormat();
|
void testRowFormat();
|
||||||
void testDateAndTime();
|
void testDateAndTime();
|
||||||
void testExternalBindingAndExtraction();
|
void testExternalBindingAndExtraction();
|
||||||
|
void testTranscode();
|
||||||
|
|
||||||
void setUp();
|
void setUp();
|
||||||
void tearDown();
|
void tearDown();
|
||||||
|
@ -18,7 +18,8 @@ namespace Data {
|
|||||||
namespace Test {
|
namespace Test {
|
||||||
|
|
||||||
|
|
||||||
Extractor::Extractor()
|
Extractor::Extractor(Poco::TextEncoding::Ptr pDBEncoding):
|
||||||
|
AbstractExtractor(pDBEncoding)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,7 +131,10 @@ bool Extractor::extract(std::size_t pos, char& val)
|
|||||||
|
|
||||||
bool Extractor::extract(std::size_t pos, std::string& val)
|
bool Extractor::extract(std::size_t pos, std::string& val)
|
||||||
{
|
{
|
||||||
val = "";
|
if (!transcodeRequired())
|
||||||
|
val = _stringValue;
|
||||||
|
else
|
||||||
|
transcode(_stringValue, val);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ class Extractor: public Poco::Data::AbstractExtractor
|
|||||||
/// A no-op implementation of AbstractExtractor for testing.
|
/// A no-op implementation of AbstractExtractor for testing.
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Extractor();
|
Extractor(Poco::TextEncoding::Ptr pDBEncoding = nullptr);
|
||||||
/// Creates the Extractor.
|
/// Creates the Extractor.
|
||||||
|
|
||||||
~Extractor();
|
~Extractor();
|
||||||
@ -110,6 +110,14 @@ public:
|
|||||||
/// Returns true if the current row value at pos column is null.
|
/// Returns true if the current row value at pos column is null.
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
|
void setString(const std::string& str)
|
||||||
|
{
|
||||||
|
_stringValue = str;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string _stringValue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user