mirror of
https://github.com/pocoproject/poco.git
synced 2025-11-28 15:41:22 +01:00
SF [2047672] RecordSet Filtering
This commit is contained in:
@@ -166,6 +166,21 @@ void ODBCDB2Test::testBLOB()
|
||||
}
|
||||
|
||||
|
||||
void ODBCDB2Test::testFilter()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
for (int i = 0; i < 8;)
|
||||
{
|
||||
recreateVectorsTable();
|
||||
_pSession->setFeature("autoBind", bindValue(i));
|
||||
_pSession->setFeature("autoExtract", bindValue(i+1));
|
||||
_pExecutor->filter("SELECT * FROM Vectors ORDER BY i0 ASC", "i0");
|
||||
i += 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ODBCDB2Test::testStoredProcedure()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
@@ -646,6 +661,7 @@ CppUnit::Test* ODBCDB2Test::suite()
|
||||
CppUnit_addTest(pSuite, ODBCDB2Test, testTuple);
|
||||
CppUnit_addTest(pSuite, ODBCDB2Test, testTupleVector);
|
||||
CppUnit_addTest(pSuite, ODBCDB2Test, testInternalExtraction);
|
||||
CppUnit_addTest(pSuite, ODBCDB2Test, testFilter);
|
||||
CppUnit_addTest(pSuite, ODBCDB2Test, testInternalBulkExtraction);
|
||||
CppUnit_addTest(pSuite, ODBCDB2Test, testInternalStorageType);
|
||||
CppUnit_addTest(pSuite, ODBCDB2Test, testStoredProcedure);
|
||||
|
||||
@@ -55,6 +55,7 @@ public:
|
||||
void testBareboneODBC();
|
||||
|
||||
void testBLOB();
|
||||
void testFilter();
|
||||
|
||||
void testStoredProcedure();
|
||||
void testStoredProcedureAny();
|
||||
|
||||
@@ -240,6 +240,21 @@ http://bugs.mysql.com/bug.php?id=7445
|
||||
}
|
||||
|
||||
|
||||
void ODBCMySQLTest::testFilter()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
for (int i = 0; i < 8;)
|
||||
{
|
||||
recreateVectorsTable();
|
||||
_pSession->setFeature("autoBind", bindValue(i));
|
||||
_pSession->setFeature("autoExtract", bindValue(i+1));
|
||||
_pExecutor->filter("SELECT * FROM Vectors ORDER BY i0 ASC", "i0");
|
||||
i += 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ODBCMySQLTest::dropObject(const std::string& type, const std::string& name)
|
||||
{
|
||||
*_pSession << format("DROP %s IF EXISTS %s", type, name), now;
|
||||
@@ -466,6 +481,7 @@ CppUnit::Test* ODBCMySQLTest::suite()
|
||||
CppUnit_addTest(pSuite, ODBCMySQLTest, testStoredProcedure);
|
||||
CppUnit_addTest(pSuite, ODBCMySQLTest, testStoredFunction);
|
||||
CppUnit_addTest(pSuite, ODBCMySQLTest, testInternalExtraction);
|
||||
CppUnit_addTest(pSuite, ODBCMySQLTest, testFilter);
|
||||
//CppUnit_addTest(pSuite, ODBCOracleTest, testInternalBulkExtraction);
|
||||
CppUnit_addTest(pSuite, ODBCMySQLTest, testInternalStorageType);
|
||||
CppUnit_addTest(pSuite, ODBCMySQLTest, testNull);
|
||||
|
||||
@@ -65,6 +65,7 @@ public:
|
||||
void testNull();
|
||||
|
||||
void testMultipleResults();
|
||||
void testFilter();
|
||||
|
||||
static CppUnit::Test* suite();
|
||||
|
||||
|
||||
@@ -905,6 +905,7 @@ CppUnit::Test* ODBCOracleTest::suite()
|
||||
CppUnit_addTest(pSuite, ODBCOracleTest, testStoredFunction);
|
||||
CppUnit_addTest(pSuite, ODBCOracleTest, testCursorStoredFunction);
|
||||
CppUnit_addTest(pSuite, ODBCOracleTest, testInternalExtraction);
|
||||
CppUnit_addTest(pSuite, ODBCOracleTest, testFilter);
|
||||
CppUnit_addTest(pSuite, ODBCOracleTest, testInternalBulkExtraction);
|
||||
CppUnit_addTest(pSuite, ODBCOracleTest, testInternalStorageType);
|
||||
CppUnit_addTest(pSuite, ODBCOracleTest, testNull);
|
||||
|
||||
@@ -629,6 +629,7 @@ CppUnit::Test* ODBCPostgreSQLTest::suite()
|
||||
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testTuple);
|
||||
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testTupleVector);
|
||||
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testInternalExtraction);
|
||||
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testFilter);
|
||||
//On Linux, PostgreSQL driver returns SQL_NEED_DATA on SQLExecute (see ODBCStatementImpl::bindImpl() )
|
||||
//this behavior is not expected and not handled for automatic binding
|
||||
#ifdef POCO_OS_FAMILY_WINDOWS
|
||||
|
||||
@@ -757,6 +757,7 @@ CppUnit::Test* ODBCSQLServerTest::suite()
|
||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testStoredProcedureDynamicAny);
|
||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testStoredFunction);
|
||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testInternalExtraction);
|
||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testFilter);
|
||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testInternalBulkExtraction);
|
||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testInternalStorageType);
|
||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testNull);
|
||||
|
||||
@@ -382,6 +382,7 @@ CppUnit::Test* ODBCSQLiteTest::suite()
|
||||
CppUnit_addTest(pSuite, ODBCSQLiteTest, testTuple);
|
||||
CppUnit_addTest(pSuite, ODBCSQLiteTest, testTupleVector);
|
||||
CppUnit_addTest(pSuite, ODBCSQLiteTest, testInternalExtraction);
|
||||
CppUnit_addTest(pSuite, ODBCSQLiteTest, testFilter);
|
||||
CppUnit_addTest(pSuite, ODBCSQLiteTest, testInternalStorageType);
|
||||
CppUnit_addTest(pSuite, ODBCSQLiteTest, testNull);
|
||||
CppUnit_addTest(pSuite, ODBCSQLiteTest, testRowIterator);
|
||||
|
||||
@@ -919,6 +919,21 @@ void ODBCTest::testInternalExtraction()
|
||||
}
|
||||
|
||||
|
||||
void ODBCTest::testFilter()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
for (int i = 0; i < 8;)
|
||||
{
|
||||
recreateVectorsTable();
|
||||
_pSession->setFeature("autoBind", bindValue(i));
|
||||
_pSession->setFeature("autoExtract", bindValue(i+1));
|
||||
_pExecutor->filter();
|
||||
i += 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ODBCTest::testInternalBulkExtraction()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
@@ -135,6 +135,7 @@ public:
|
||||
virtual void testTupleVector();
|
||||
|
||||
virtual void testInternalExtraction();
|
||||
virtual void testFilter();
|
||||
virtual void testInternalBulkExtraction();
|
||||
virtual void testInternalStorageType();
|
||||
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
#include "Poco/Data/StatementImpl.h"
|
||||
#include "Poco/Data/RecordSet.h"
|
||||
#include "Poco/Data/RowIterator.h"
|
||||
#include "Poco/Data/RowFilter.h"
|
||||
#include "Poco/Data/BulkExtraction.h"
|
||||
#include "Poco/Data/BulkBinding.h"
|
||||
#include "Poco/Data/SQLChannel.h"
|
||||
@@ -72,6 +73,8 @@ using Poco::Data::Statement;
|
||||
using Poco::Data::RecordSet;
|
||||
using Poco::Data::Column;
|
||||
using Poco::Data::Row;
|
||||
using Poco::Data::RowFilter;
|
||||
using Poco::Data::RowIterator;
|
||||
using Poco::Data::SQLChannel;
|
||||
using Poco::Data::LimitException;
|
||||
using Poco::Data::BindingException;
|
||||
@@ -2526,6 +2529,86 @@ void SQLExecutor::internalExtraction()
|
||||
}
|
||||
|
||||
|
||||
void SQLExecutor::filter(const std::string& query, const std::string& intFldName)
|
||||
{
|
||||
std::string funct = "filter()";
|
||||
std::vector<Tuple<int, double, std::string> > v;
|
||||
v.push_back(Tuple<int, double, std::string>(1, 1.5f, "3"));
|
||||
v.push_back(Tuple<int, double, std::string>(2, 2.5f, "4"));
|
||||
v.push_back(Tuple<int, double, std::string>(3, 3.5f, "5"));
|
||||
v.push_back(Tuple<int, double, std::string>(4, 4.5f, "6"));
|
||||
|
||||
try { session() << "INSERT INTO Vectors VALUES (?,?,?)", use(v), 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() << query, now);
|
||||
RecordSet rset(stmt);
|
||||
assert (rset.totalRowCount() == 4);
|
||||
RowFilter::Ptr pRF = new RowFilter(&rset);
|
||||
assert (pRF->isEmpty());
|
||||
pRF->add(intFldName, RowFilter::VALUE_EQUAL, 1);
|
||||
assert (!pRF->isEmpty());
|
||||
|
||||
DynamicAny da;
|
||||
try
|
||||
{
|
||||
da = rset.value(0, 1);
|
||||
fail ("must fail");
|
||||
} catch (InvalidAccessException&)
|
||||
{
|
||||
da = rset.value(0, 1, false);
|
||||
assert (2 == da);
|
||||
da = rset.value(0, 0);
|
||||
assert (1 == da);
|
||||
}
|
||||
|
||||
assert (rset.rowCount() == 1);
|
||||
assert (rset.moveFirst());
|
||||
assert (1 == rset[intFldName]);
|
||||
assert (!rset.moveNext());
|
||||
pRF->add("flt0", RowFilter::VALUE_LESS_THAN_OR_EQUAL, 3.5f);
|
||||
assert (rset.rowCount() == 3);
|
||||
assert (rset.moveNext());
|
||||
assert (2.5 == rset["flt0"]);
|
||||
assert (rset.moveNext());
|
||||
assert (3.5 == rset["flt0"]);
|
||||
assert (!rset.moveNext());
|
||||
pRF->add("str0", RowFilter::VALUE_EQUAL, 6);
|
||||
assert (rset.rowCount() == 4);
|
||||
assert (rset.moveLast());
|
||||
assert ("6" == rset["str0"]);
|
||||
pRF->remove("flt0");
|
||||
assert (rset.rowCount() == 2);
|
||||
assert (rset.moveFirst());
|
||||
assert ("3" == rset["str0"]);
|
||||
assert (rset.moveNext());
|
||||
assert ("6" == rset["str0"]);
|
||||
pRF->remove(intFldName);
|
||||
pRF->remove("str0");
|
||||
assert (pRF->isEmpty());
|
||||
pRF->add("str0", "!=", 3);
|
||||
assert (rset.rowCount() == 3);
|
||||
|
||||
RowFilter::Ptr pRF1 = new RowFilter(pRF, RowFilter::OP_AND);
|
||||
pRF1->add(intFldName, "==", 2);
|
||||
assert (rset.rowCount() == 1);
|
||||
pRF1->add(intFldName, "<", 2);
|
||||
assert (rset.rowCount() == 1);
|
||||
pRF1->add(intFldName, ">", 3);
|
||||
assert (rset.rowCount() == 2);
|
||||
pRF->removeFilter(pRF1);
|
||||
pRF->remove("str0");
|
||||
assert (pRF->isEmpty());
|
||||
assert (rset.rowCount() == 4);
|
||||
}
|
||||
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
|
||||
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
|
||||
}
|
||||
|
||||
|
||||
void SQLExecutor::internalBulkExtraction()
|
||||
{
|
||||
std::string funct = "internalBulkExtraction()";
|
||||
@@ -2665,7 +2748,8 @@ void SQLExecutor::notNulls(const std::string& sqlState)
|
||||
{
|
||||
//make sure we're failing for the right reason
|
||||
//default sqlState value is "23502"; some drivers report "HY???" codes
|
||||
assert (sqlState == se.diagnostics().sqlState(0));
|
||||
if (se.diagnostics().fields().size())
|
||||
assert (sqlState == se.diagnostics().sqlState(0));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2686,12 +2770,18 @@ void SQLExecutor::nulls()
|
||||
assert (rs.isNull("r"));
|
||||
assert (rs.isNull("v"));
|
||||
assert (rs["v"] != "");
|
||||
assert (rs.nvl<int>("i") == 0);
|
||||
assert (rs.nvl("i", -1) == -1);
|
||||
assert (rs.nvl<double>("r") == double());
|
||||
assert (rs.nvl("r", -1.5) == -1.5);
|
||||
assert (rs.nvl<std::string>("v") == "");
|
||||
assert (rs.nvl("v", "123") == "123");
|
||||
try { session() << "DELETE FROM NullTest", now; }
|
||||
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
|
||||
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
|
||||
|
||||
int i = 1;
|
||||
double f = 1.2;
|
||||
double f = 1.5;
|
||||
std::string s = "123";
|
||||
|
||||
try { session() << "INSERT INTO NullTest (i, r, v) VALUES (?,?,?)", use(i), use(f), use(s), now; }
|
||||
@@ -2705,7 +2795,12 @@ void SQLExecutor::nulls()
|
||||
assert (!rs.isNull("v"));
|
||||
assert (!rs.isNull("r"));
|
||||
assert (rs["v"] == "123");
|
||||
|
||||
assert (rs.nvl<int>("i") == 1);
|
||||
assert (rs.nvl("i", -1) == 1);
|
||||
assert (rs.nvl<double>("r") == 1.5);
|
||||
assert (rs.nvl("r", -1.5) == 1.5);
|
||||
assert (rs.nvl<std::string>("v") == "123");
|
||||
assert (rs.nvl("v", "456") == "123");
|
||||
try { session() << "UPDATE NullTest SET v = ? WHERE i = ?", use(null), use(i), now; }
|
||||
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
|
||||
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
|
||||
@@ -2803,6 +2898,19 @@ void SQLExecutor::rowIterator()
|
||||
std::ostringstream osCopy;
|
||||
std::copy(rset.begin(), rset.end(), std::ostream_iterator<Row>(osCopy));
|
||||
assert (osLoop.str() == osCopy.str());
|
||||
|
||||
RowFilter::Ptr pRF = new RowFilter(&rset);
|
||||
assert (pRF->isEmpty());
|
||||
pRF->add("str0", RowFilter::VALUE_EQUAL, 1);
|
||||
assert (!pRF->isEmpty());
|
||||
it = rset.begin();
|
||||
end = rset.end();
|
||||
for (int i = 1; it != end; ++it, ++i)
|
||||
{
|
||||
assert (it->get(0) == i);
|
||||
assert (1 == i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -484,6 +484,10 @@ public:
|
||||
void tupleVector();
|
||||
|
||||
void internalExtraction();
|
||||
void filter(const std::string& query =
|
||||
"SELECT * FROM Vectors ORDER BY int0 ASC",
|
||||
const std::string& intFldName = "int0");
|
||||
|
||||
void internalBulkExtraction();
|
||||
void internalStorageType();
|
||||
void nulls();
|
||||
|
||||
Reference in New Issue
Block a user