fix RowFilter refcounting, some cleanup

This commit is contained in:
Alex Fabijanic 2017-06-30 16:13:56 +02:00
parent 41e3f38c06
commit 96bb22621e
7 changed files with 28 additions and 170 deletions

View File

@ -188,21 +188,6 @@ void ODBCOracleTest::testInternalExtraction()
} }
void ODBCOracleTest::testInternalBulkExtraction()
{
if (!_pSession) fail ("Test not available.");
recreatePersonTable();
_pSession->setFeature("autoBind", true);
_pSession->setFeature("autoExtract", true);
#ifdef POCO_ODBC_UNICODE
_pExecutor->internalBulkExtractionUTF16<double>(0);
#else
_pExecutor->internalBulkExtraction<double>(0);
#endif
}
void ODBCOracleTest::testBLOB() void ODBCOracleTest::testBLOB()
{ {
const std::size_t maxFldSize = 1000000; const std::size_t maxFldSize = 1000000;

View File

@ -37,7 +37,6 @@ public:
void testBareboneODBC(); void testBareboneODBC();
void testInternalExtraction(); void testInternalExtraction();
void testInternalBulkExtraction();
void testBLOB(); void testBLOB();

View File

@ -989,9 +989,9 @@ void ODBCTest::testInternalBulkExtraction()
_pSession->setFeature("autoBind", true); _pSession->setFeature("autoBind", true);
_pSession->setFeature("autoExtract", true); _pSession->setFeature("autoExtract", true);
#ifdef POCO_ODBC_UNICODE #ifdef POCO_ODBC_UNICODE
_pExecutor->internalBulkExtractionUTF16(0); _pExecutor->internalBulkExtractionUTF16();
#else #else
_pExecutor->internalBulkExtraction(0); _pExecutor->internalBulkExtraction();
#endif #endif
} }

View File

@ -2811,7 +2811,7 @@ void SQLExecutor::filter(const std::string& query, const std::string& intFldName
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); } catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
} }
/*
void SQLExecutor::internalBulkExtraction() void SQLExecutor::internalBulkExtraction()
{ {
std::string funct = "internalBulkExtraction()"; std::string funct = "internalBulkExtraction()";
@ -2934,7 +2934,7 @@ void SQLExecutor::internalBulkExtractionUTF16()
catch (ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail(funct); } catch (ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail(funct); }
catch (StatementException& se){ std::cout << se.toString() << std::endl; fail(funct); } catch (StatementException& se){ std::cout << se.toString() << std::endl; fail(funct); }
} }
*/
void SQLExecutor::internalStorageType() void SQLExecutor::internalStorageType()
{ {

View File

@ -698,151 +698,11 @@ public:
} }
void filter(const std::string& query = void filter(const std::string& query =
"SELECT * FROM " + ExecUtil::vectors() + " ORDER BY i0 ASC", "SELECT * FROM " + ExecUtil::vectors() + " ORDER BY int0 ASC",
const std::string& intFldName = "i0"); const std::string& intFldName = "int0");
template <typename IntType = void internalBulkExtraction();
#if defined(POCO_PTR_IS_64_BIT) && (POCO_PTR_IS_64_BIT == 1) void internalBulkExtractionUTF16();
Poco::Int64 IntType
#else
Poco::Int32 IntType
#endif
>
void internalBulkExtraction(IntType)
{
using Poco::Data::RecordSet;
using Poco::NumberFormatter;
std::string funct = "internalBulkExtraction()";
int size = 100;
std::vector<std::string> lastName(size);
std::vector<std::string> firstName(size);
std::vector<std::string> address(size);
std::vector<IntType> age(size);
for (int i = 0; i < size; ++i)
{
lastName[i] = "LN" + NumberFormatter::format(i);
firstName[i] = "FN" + NumberFormatter::format(i);
address[i] = "Addr" + NumberFormatter::format(i);
age[i] = i;
}
try
{
session() << "INSERT INTO " << ExecUtil::person() <<" VALUES (?,?,?,?)",
use(lastName, bulk),
use(firstName, bulk),
use(address, bulk),
use(age, bulk),
now;
}
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
try
{
Statement stmt = (session() << "SELECT * FROM " << ExecUtil::person(), bulk(size), now);
RecordSet rset(stmt);
assert (size == rset.rowCount());
assert("LN0" == rset["LastName"]);
assert (0 == rset["Age"]);
rset.moveNext();
assert("LN1" == rset["LastName"]);
assert(1 == rset["Age"]);
rset.moveLast();
assert (std::string("LN") + NumberFormatter::format(size - 1) == rset["LastName"]);
assert (size - 1 == rset["Age"]);
}
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
try
{
Statement stmt = (session() << "SELECT * FROM " << ExecUtil::person(), limit(size), bulk, now);
RecordSet rset(stmt);
assert (size == rset.rowCount());
assert ("LN0" == rset["LastName"]);
assert (0 == rset["Age"]);
rset.moveLast();
assert (std::string("LN") + NumberFormatter::format(size - 1) == rset["LastName"]);
assert (size - 1 == rset["Age"]);
}
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
}
template <typename IntType =
#if defined(POCO_PTR_IS_64_BIT) && (POCO_PTR_IS_64_BIT == 1)
Poco::Int64 IntType
#else
Poco::Int32 IntType
#endif
>
void internalBulkExtractionUTF16(IntType)
{
using Poco::Data::RecordSet;
using Poco::UTF16String;
using Poco::NumberFormatter;
std::string funct = "internalBulkExtraction()";
int size = 100;
std::vector<UTF16String> lastName(size);
std::vector<UTF16String> firstName(size);
std::vector<UTF16String> address(size);
std::vector<IntType> age(size);
for (int i = 0; i < size; ++i)
{
lastName[i] = Poco::UnicodeConverter::to<UTF16String>("LN" + NumberFormatter::format(i));
firstName[i] = Poco::UnicodeConverter::to<UTF16String>("FN" + NumberFormatter::format(i));
address[i] = Poco::UnicodeConverter::to<UTF16String>("Addr" + NumberFormatter::format(i));
age[i] = i;
}
try
{
session() << "INSERT INTO " << ExecUtil::person() <<" VALUES (?,?,?,?)",
use(lastName, bulk),
use(firstName, bulk),
use(address, bulk),
use(age, bulk),
now;
}
catch (ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail(funct); }
catch (StatementException& se){ std::cout << se.toString() << std::endl; fail(funct); }
try
{
Statement stmt = (session() << "SELECT * FROM " << ExecUtil::person(), bulk(size), now);
RecordSet rset(stmt);
assert(size == rset.rowCount());
assert(Poco::UnicodeConverter::to<UTF16String>("LN0") == rset["LastName"]);
assert(0 == rset["Age"]);
rset.moveNext();
assert(Poco::UnicodeConverter::to<UTF16String>("LN1") == rset["LastName"]);
assert(1 == rset["Age"]);
rset.moveLast();
assert(std::string("LN") + NumberFormatter::format(size - 1) == rset["LastName"]);
assert(size - 1 == rset["Age"]);
}
catch (ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail(funct); }
catch (StatementException& se){ std::cout << se.toString() << std::endl; fail(funct); }
try
{
Statement stmt = (session() << "SELECT * FROM " << ExecUtil::person(), limit(size), bulk, now);
RecordSet rset(stmt);
assert(size == rset.rowCount());
assert("LN0" == rset["LastName"]);
assert(0 == rset["Age"]);
rset.moveLast();
assert(std::string("LN") + NumberFormatter::format(size - 1) == rset["LastName"]);
assert(size - 1 == rset["Age"]);
}
catch (ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail(funct); }
catch (StatementException& se){ std::cout << se.toString() << std::endl; fail(funct); }
}
void internalStorageType(); void internalStorageType();
void nulls(bool emptyStrIsSpace = false); void nulls(bool emptyStrIsSpace = false);

View File

@ -85,12 +85,15 @@ public:
~RowFilter(); ~RowFilter();
/// Destroys the RowFilter. /// Destroys the RowFilter.
void addFilter(const Ptr& pFilter, LogicOperator comparison); void addFilter(Ptr pFilter, LogicOperator comparison);
/// Appends another filter to this one. /// Appends another filter to this one.
void removeFilter(const Ptr& pFilter); void removeFilter(Ptr pFilter);
/// Removes filter from this filter. /// Removes filter from this filter.
bool has(Ptr pFilter) const;
/// Returns true if this filter is parent of pFilter;
template <typename T> template <typename T>
void add(const std::string& name, Comparison comparison, const T& value, LogicOperator op = OP_OR) void add(const std::string& name, Comparison comparison, const T& value, LogicOperator op = OP_OR)
/// Adds value to the filter. /// Adds value to the filter.
@ -185,6 +188,12 @@ private:
/// ///
inline bool RowFilter::has(Ptr pFilter) const
{
return _filterMap.find(pFilter) != _filterMap.end();
}
inline bool RowFilter::isEmpty() const inline bool RowFilter::isEmpty() const
{ {
return _comparisonMap.size() == 0; return _comparisonMap.size() == 0;

View File

@ -29,6 +29,7 @@ RowFilter::RowFilter(RecordSet* pRecordSet): _pRecordSet(pRecordSet), _not(false
{ {
poco_check_ptr(pRecordSet); poco_check_ptr(pRecordSet);
init(); init();
duplicate();
_pRecordSet->filter(this); _pRecordSet->filter(this);
} }
@ -39,6 +40,7 @@ RowFilter::RowFilter(Ptr pParent, LogicOperator op): _pRecordSet(0),
{ {
poco_check_ptr(_pParent.get()); poco_check_ptr(_pParent.get());
init(); init();
duplicate();
_pParent->addFilter(this, op); _pParent->addFilter(this, op);
} }
@ -62,7 +64,9 @@ RowFilter::~RowFilter()
try try
{ {
if (_pRecordSet) _pRecordSet->filter(0); if (_pRecordSet) _pRecordSet->filter(0);
if (_pParent.get()) _pParent->removeFilter(this); if (_pParent && _pParent->has(this))
_pParent->removeFilter(this);
release();
} }
catch (...) catch (...)
{ {
@ -162,7 +166,7 @@ RowFilter::Comparison RowFilter::getComparison(const std::string& comp) const
} }
void RowFilter::addFilter(const Ptr& pFilter, LogicOperator comparison) void RowFilter::addFilter(Ptr pFilter, LogicOperator comparison)
{ {
poco_check_ptr (_pRecordSet); poco_check_ptr (_pRecordSet);
@ -172,13 +176,14 @@ void RowFilter::addFilter(const Ptr& pFilter, LogicOperator comparison)
} }
void RowFilter::removeFilter(const Ptr& pFilter) void RowFilter::removeFilter(Ptr pFilter)
{ {
poco_check_ptr (_pRecordSet); poco_check_ptr (_pRecordSet);
pFilter->_pRecordSet = 0;
_pRecordSet->moveFirst(); _pRecordSet->moveFirst();
_filterMap.erase(pFilter); _filterMap.erase(pFilter);
pFilter->_pRecordSet = 0;
pFilter->_pParent = 0;
} }