added a SearchCriteria constructor from an XmlRpcValue;

this closes #1679
This commit is contained in:
fgerlits 2006-05-17 14:57:38 +00:00
parent 68a85e5946
commit 047ef2d923
4 changed files with 202 additions and 8 deletions

View file

@ -180,6 +180,16 @@ class SearchCriteria
*/
friend class LiveSupport::StorageClient::TestStorageClient;
/**
* Add a search condition.
*
* @param xmlRpcValue the condition to add.
* @exception std::invalid_argument on syntax errors.
*/
void
addCondition(const XmlRpc::XmlRpcValue & xmlRpcValue)
throw(std::invalid_argument);
public:
@ -189,6 +199,7 @@ class SearchCriteria
*
* @param type one of "audioClip" (default), "playlist" or "all"
* @param logicalOperator either "and" (default) or "or"
* @exception std::invalid_argument on syntax errors.
*/
SearchCriteria(const std::string & type = "all",
const std::string & logicalOperator = "and")
@ -207,6 +218,7 @@ class SearchCriteria
* @param comparisonOperator one of "=", "partial", "prefix",
* "<", "<=", ">" or ">="
* @param value the value to compare to
* @exception std::invalid_argument on syntax errors.
*/
SearchCriteria(const std::string & type,
const std::string & key,
@ -214,10 +226,21 @@ class SearchCriteria
const std::string & value)
throw(std::invalid_argument);
/**
* Construct a SearchCriteria object from an XmlRpcValue.
*
* @param xmlRpcValue an XmlRpcValue struct, containing
* the search criteria.
* @exception std::invalid_argument on syntax errors.
*/
SearchCriteria(const XmlRpc::XmlRpcValue & xmlRpcValue)
throw(std::invalid_argument);
/**
* Set the type field.
*
* @param type one of "audioClip", "playlist" or "all"
* @exception std::invalid_argument on syntax errors.
*/
void
setType(const std::string & type)
@ -238,6 +261,7 @@ class SearchCriteria
* Set the logical operator field.
*
* @param logicalOperator either "and" or "or"
* @exception std::invalid_argument on syntax errors.
*/
void
setLogicalOperator(const std::string & logicalOperator)
@ -258,6 +282,7 @@ class SearchCriteria
* @param comparisonOperator one of "=", "partial", "prefix",
* "<", "<=", ">" or ">="
* @param value the value to compare to
* @exception std::invalid_argument on syntax errors.
*/
void
addCondition(const std::string & key,
@ -271,6 +296,7 @@ class SearchCriteria
* @param comparisonOperator one of "=", "partial", "prefix",
* "<", "<=", ">" or ">="
* @param value the value of the mtime to compare to
* @exception std::invalid_argument on syntax errors.
*/
void
addMtimeCondition(const std::string & comparisonOperator,
@ -281,6 +307,7 @@ class SearchCriteria
* Add a search condition.
*
* @param condition the search condition to add
* @exception std::invalid_argument on syntax errors.
*/
void
addCondition(const Ptr<SearchConditionType>::Ref condition)
@ -295,6 +322,7 @@ class SearchCriteria
* Set the limit field.
*
* @param limit the maximum number of search results to be returned
* @exception std::invalid_argument on syntax errors.
*/
void
setLimit(const int limit)
@ -312,6 +340,7 @@ class SearchCriteria
*
* @param offset the index of the first matching condition
* to be returned (first = 0)
* @exception std::invalid_argument on syntax errors.
*/
void
setOffset(const int offset)
@ -328,6 +357,12 @@ class SearchCriteria
* Convert to an XmlRpc::XmlRpcValue.
*/
operator XmlRpc::XmlRpcValue() const throw();
/**
* Check two SearchCriteria objects for equality.
*/
bool
operator ==(const SearchCriteria & other) const throw();
};

View file

@ -38,6 +38,7 @@
using namespace LiveSupport::Core;
using namespace boost::posix_time;
using namespace XmlRpc;
/* =================================================== local data structures */
@ -65,6 +66,51 @@ SearchCriteria :: SearchCriteria(const std::string & type,
}
/*------------------------------------------------------------------------------
* Construct a SearchCriteria object from an XmlRpcValue.
*----------------------------------------------------------------------------*/
SearchCriteria :: SearchCriteria(const XmlRpcValue & xmlRpcValue)
throw(std::invalid_argument)
{
// make a non-const copy, because XmlRpcValue::operator[](const char *)
// does not work on const objects
XmlRpcValue value(xmlRpcValue);
if (value.hasMember("filetype")
&& value["filetype"].getType() == XmlRpcValue::TypeString) {
type = std::string(value["filetype"]);
} else {
throw std::invalid_argument("missing file type in search criteria");
}
if (value.hasMember("operator")
&& value["operator"].getType() == XmlRpcValue::TypeString) {
logicalOperator = std::string(value["operator"]);
} else {
logicalOperator = std::string("and");
}
if (value.hasMember("limit")
&& value["limit"].getType() == XmlRpcValue::TypeInt) {
limit = value["limit"];
}
if (value.hasMember("offset")
&& value["offset"].getType() == XmlRpcValue::TypeInt) {
offset = value["offset"];
}
if (!value.hasMember("conditions")
|| value["conditions"].getType() != XmlRpcValue::TypeArray) {
throw std::invalid_argument("missing conditions in search criteria");
}
for (int i = 0; i < value["conditions"].size(); ++i) {
addCondition(value["conditions"][i]);
}
}
/*------------------------------------------------------------------------------
* Add a search condition.
*----------------------------------------------------------------------------*/
@ -88,6 +134,38 @@ SearchCriteria :: addCondition(const std::string & key,
}
/*------------------------------------------------------------------------------
* Add a search condition.
*----------------------------------------------------------------------------*/
void
SearchCriteria :: addCondition(const XmlRpcValue & xmlRpcValue)
throw(std::invalid_argument)
{
// make a non-const copy, because XmlRpcValue::operator[](const char *)
// does not work on const objects
XmlRpcValue value(xmlRpcValue);
if (!value.hasMember("cat")
|| value["cat"].getType() != XmlRpcValue::TypeString) {
throw std::invalid_argument("missing metadata name in search criteria");
}
if (!value.hasMember("op")
|| value["op"].getType() != XmlRpcValue::TypeString) {
throw std::invalid_argument("missing operator name in search criteria");
}
if (!value.hasMember("val")
|| value["val"].getType() != XmlRpcValue::TypeString) {
throw std::invalid_argument("missing value in search criteria");
}
addCondition(std::string(value["cat"]),
std::string(value["op"]),
std::string(value["val"]));
}
/*------------------------------------------------------------------------------
* Add a search condition specifying the mtime (modified-at time).
*----------------------------------------------------------------------------*/
@ -111,25 +189,25 @@ SearchCriteria :: addMtimeCondition(const std::string & comparisonOperator,
/*------------------------------------------------------------------------------
* Convert to an XmlRpc::XmlRpcValue.
* Convert to an XmlRpcValue.
*----------------------------------------------------------------------------*/
SearchCriteria :: operator XmlRpc::XmlRpcValue() const
SearchCriteria :: operator XmlRpcValue() const
throw()
{
XmlRpc::XmlRpcValue returnValue;
XmlRpcValue returnValue;
returnValue["filetype"] = type;
if (searchConditions.size() != 1) {
returnValue["operator"] = logicalOperator;
}
XmlRpc::XmlRpcValue conditionList;
XmlRpcValue conditionList;
conditionList.setSize(searchConditions.size());
SearchConditionListType::const_iterator it, end;
it = searchConditions.begin();
end = searchConditions.end();
for (int i = 0; it != end; ++i, ++it) {
XmlRpc::XmlRpcValue condition;
XmlRpcValue condition;
condition["cat"] = it->key;
condition["op"] = it->comparisonOperator;
condition["val"] = it->value;
@ -141,10 +219,10 @@ SearchCriteria :: operator XmlRpc::XmlRpcValue() const
struct tm mtimeStructTm;
TimeConversion::ptimeToTm(mtimeValue, mtimeStructTm);
XmlRpc::XmlRpcValue condition;
XmlRpcValue condition;
condition["cat"] = "ls:mtime";
condition["op"] = mtimeComparisonOperator;
condition["val"] = XmlRpc::XmlRpcValue(&mtimeStructTm);
condition["val"] = XmlRpcValue(&mtimeStructTm);
conditionList[i] = condition;
}
@ -161,3 +239,38 @@ SearchCriteria :: operator XmlRpc::XmlRpcValue() const
return returnValue;
}
/*------------------------------------------------------------------------------
* Check two SearchCriteria objects for equality.
*----------------------------------------------------------------------------*/
bool
SearchCriteria :: operator ==(const SearchCriteria & other) const
throw()
{
if (type != other.type
|| limit != other.limit
|| offset != other.offset
|| searchConditions.size() != other.searchConditions.size()) {
return false;
}
if (searchConditions.size() != 1
&& logicalOperator != other.logicalOperator) {
return false;
}
SearchConditionListType::const_iterator it, otherIt;
it = searchConditions.begin();
otherIt = other.searchConditions.begin();
for ( ; it != searchConditions.end(); ++it, ++otherIt) {
if (it->key != otherIt->key
|| it->comparisonOperator != otherIt->comparisonOperator
|| it->value != otherIt->value) {
return false;
}
}
return true;
}

View file

@ -156,3 +156,40 @@ SearchCriteriaTest :: firstTest(void)
CPPUNIT_ASSERT(condition0["val"] == "X");
}
/*------------------------------------------------------------------------------
* Test the conversion to/from an XmlRpcValue.
*----------------------------------------------------------------------------*/
void
SearchCriteriaTest :: marshalingTest(void)
throw (CPPUNIT_NS::Exception)
{
Ptr<SearchCriteria>::Ref criteria;
CPPUNIT_ASSERT_NO_THROW(
criteria.reset(new SearchCriteria("playlist", "Or"));
criteria->setLimit(50);
criteria->setOffset(100);
criteria->addCondition("dc:title", "PREFIX", "My ");
criteria->addCondition("DcTerms:Extent", "<", "180");
);
XmlRpc::XmlRpcValue xmlRpcValue;
CPPUNIT_ASSERT_NO_THROW(
xmlRpcValue = *criteria;
);
Ptr<SearchCriteria>::Ref copyCriteria;
CPPUNIT_ASSERT_NO_THROW(
copyCriteria.reset(new SearchCriteria(xmlRpcValue));
);
CPPUNIT_ASSERT(*criteria == *copyCriteria);
XmlRpc::XmlRpcValue copyXmlRpcValue;
CPPUNIT_ASSERT_NO_THROW(
copyXmlRpcValue = *copyCriteria;
);
CPPUNIT_ASSERT(xmlRpcValue == copyXmlRpcValue);
}

View file

@ -65,6 +65,7 @@ class SearchCriteriaTest : public CPPUNIT_NS::TestFixture
{
CPPUNIT_TEST_SUITE(SearchCriteriaTest);
CPPUNIT_TEST(firstTest);
CPPUNIT_TEST(marshalingTest);
CPPUNIT_TEST_SUITE_END();
protected:
@ -77,6 +78,14 @@ class SearchCriteriaTest : public CPPUNIT_NS::TestFixture
void
firstTest(void) throw (CPPUNIT_NS::Exception);
/**
* Test the conversion to/from an XmlRpcValue.
*
* @exception CPPUNIT_NS::Exception on test failures.
*/
void
marshalingTest(void) throw (CPPUNIT_NS::Exception);
public: