diff --git a/livesupport/modules/core/include/LiveSupport/Core/UniqueId.h b/livesupport/modules/core/include/LiveSupport/Core/UniqueId.h index aa6bf1ace..64909a2c2 100644 --- a/livesupport/modules/core/include/LiveSupport/Core/UniqueId.h +++ b/livesupport/modules/core/include/LiveSupport/Core/UniqueId.h @@ -22,7 +22,7 @@ Author : $Author: fgerlits $ - Version : $Revision: 1.6 $ + Version : $Revision: 1.7 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/include/LiveSupport/Core/UniqueId.h,v $ ------------------------------------------------------------------------------*/ @@ -60,7 +60,7 @@ namespace Core { * A class representing globally unique identifiers. * * @author $Author: fgerlits $ - * @version $Revision: 1.6 $ + * @version $Revision: 1.7 $ */ class UniqueId { @@ -205,7 +205,7 @@ class UniqueId * * @return the numeric value of this id. */ - operator IdType () const throw () + operator IdType() const throw () { return id; } @@ -215,7 +215,7 @@ class UniqueId * * @return the string value of this id. */ - operator std::string () const throw () + operator std::string() const throw () { return idAsString; } diff --git a/livesupport/modules/storage/etc/Makefile.in b/livesupport/modules/storage/etc/Makefile.in index 1f14d79c5..57b66fc36 100644 --- a/livesupport/modules/storage/etc/Makefile.in +++ b/livesupport/modules/storage/etc/Makefile.in @@ -20,8 +20,8 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # -# Author : $Author: maroy $ -# Version : $Revision: 1.17 $ +# Author : $Author: fgerlits $ +# Version : $Revision: 1.18 $ # Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/storage/etc/Makefile.in,v $ # # @configure_input@ @@ -112,11 +112,13 @@ LDFLAGS = @LDFLAGS@ -pthread \ #------------------------------------------------------------------------------- # Dependencies #------------------------------------------------------------------------------- -STORAGE_LIB_OBJS = ${TMP_DIR}/StorageClientFactory.o \ +STORAGE_LIB_OBJS = ${TMP_DIR}/SearchCriteria.o \ + ${TMP_DIR}/StorageClientFactory.o \ ${TMP_DIR}/TestStorageClient.o \ ${TMP_DIR}/WebStorageClient.o TEST_RUNNER_OBJS = ${TMP_DIR}/TestRunner.o \ + ${TMP_DIR}/SearchCriteriaTest.o \ ${TMP_DIR}/StorageClientFactoryTest.o \ ${TMP_DIR}/TestStorageClientTest.o \ ${TMP_DIR}/WebStorageClientTest.o diff --git a/livesupport/modules/storage/include/LiveSupport/Storage/SearchCriteria.h b/livesupport/modules/storage/include/LiveSupport/Storage/SearchCriteria.h new file mode 100644 index 000000000..30b42324b --- /dev/null +++ b/livesupport/modules/storage/include/LiveSupport/Storage/SearchCriteria.h @@ -0,0 +1,280 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2004 Media Development Loan Fund + + This file is part of the LiveSupport project. + http://livesupport.campware.org/ + To report bugs, send an e-mail to bugs@campware.org + + LiveSupport is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + LiveSupport is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with LiveSupport; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + + Author : $Author: fgerlits $ + Version : $Revision: 1.1 $ + Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/storage/include/LiveSupport/Storage/Attic/SearchCriteria.h,v $ + +------------------------------------------------------------------------------*/ +#ifndef LiveSupport_Storage_SearchCriteria_h +#define LiveSupport_Storage_SearchCriteria_h + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "configure.h" +#endif + +#include +#include +#include + +namespace LiveSupport { +namespace Storage { + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * An object which contains a collection of search conditions. + * + * Its fields are: + *
    + *
  • type - mandatory, values in (audioClip | playlist | all)
  • + *
  • operator - values in (and | or); + * optional, default is and
  • + *
  • condition1 : { key : string, comparison: string, value : string } + * - a search condition, where key is one of the + * fields in the metadata, and comparison is + * one of ("=" | "partial" | "prefix" + * | "<" | "<=" | ">" | ">=")
  • + *
  • ...
  • + *
  • conditionN
  • + *
  • limit : int - the maximum number of results to be returned; optional, + * the default is 0, which means there is no limit
  • + *
  • offset : int - start at the offset+1-th result; optional, + * the default is 0.
  • + *
+ * + * Usage: construct a SearchCriteria object either directly using the + * constructor with 4 string arguments, or in several steps using the setter + * methods; then pass this object to Storage::search() to search the local + * storage. + * + * The key and value fields are case-sensitive, all the other + * strings (type, operator names) are case-insensitive. + */ +class SearchCriteria +{ + private: + + /** + * The kind of object we are searching for. + */ + std::string type; + + /** + * The logical operator joining the conditions: "and" or "or". + */ + std::string logicalOperator; + + /** + * A type to hold a single search condition. + */ + struct SearchConditionType + { + std::string key; + std::string comparisonOperator; + std::string value; + }; + + /** + * A type to hold the list of search conditions. + */ + typedef std::vector + SearchConditionListType; + /** + * The vector of search conditions. + */ + SearchConditionListType searchConditions; + + /** + * The maximum number of conditions to be returned. + */ + int limit; + + /** + * The index of the first matching condition to be returned. + */ + int offset; + + /** + * Lowercase a string. + */ + std::string + lowerCase(const std::string & s) throw() + { + std::string returnValue; + std::string::const_iterator it = s.begin(); + while (it != s.end()) { + returnValue += std::tolower(*it); + ++it; + } + return returnValue; + } + + public: + + /** + * Construct an empty SearchCriteria object. + * This also works as a default constructor. + * + * @param type one of "audioClip" (default), "playlist" or "all" + * @param logicalOperator either "and" (default) or "or" + */ + SearchCriteria(const std::string & type = "audioClip", + const std::string & logicalOperator = "and") + throw(std::invalid_argument) + : limit(0), offset(0) + { + setType(type); + setOperator(logicalOperator); + } + + /** + * Construct a SearchCriteria object with a single condition. + * + * @param type one of "audioClip", "playlist" or "all" + * @param key the metadata field to search in + * @param comparisonOperator one of "=", "partial", "prefix", + * "<", "<=", ">" or ">=" + * @param value the value to compare to + */ + SearchCriteria(const std::string & type, + const std::string & key, + const std::string & comparisonOperator, + const std::string & value) + throw(std::invalid_argument); + + /** + * Set the type field. + * + * @param type one of "audioClip", "playlist" or "all" + */ + void + setType(const std::string & type) + throw(std::invalid_argument) + { + std::string lowerCaseType = lowerCase(type); + if (lowerCaseType == "audioclip" + || lowerCaseType == "playlist" + || lowerCaseType == "all") { + this->type = lowerCaseType; + } else { + throw std::invalid_argument("bad type argument"); + } + + } + + /** + * Set the logical operator field. + * + * @param logicalOperator either "and" or "or" + */ + void + setOperator(const std::string & logicalOperator) + throw(std::invalid_argument) + { + std::string lowerCaseOp = lowerCase(logicalOperator); + if (lowerCaseOp == "and" || lowerCaseOp == "or") { + this->logicalOperator = lowerCaseOp; + } else { + throw std::invalid_argument("bad logical operator argument"); + } + } + + /** + * Add a search condition. + * + * @param key the metadata field to search in + * @param comparisonOperator one of "=", "partial", "prefix", + * "<", "<=", ">" or ">=" + * @param value the value to compare to + */ + void + addCondition(const std::string & key, + const std::string & comparisonOperator, + const std::string & value) + throw(std::invalid_argument); + + /** + * Set the limit field. + * + * @param limit the maximum number of search results to be returned + */ + void + setLimit(const int limit) + throw(std::invalid_argument) + { + if (limit >= 0) { + this->limit = limit; + } else { + throw std::invalid_argument("bad argument: less than zero"); + } + } + + /** + * Set the offset field. + * + * @param offset the index of the first matching condition + * to be returned (first = 0) + */ + void + setOffset(const int offset) + throw(std::invalid_argument) + { + if (offset >= 0) { + this->offset = offset; + } else { + throw std::invalid_argument("bad argument: less than zero"); + } + } + + /** + * Convert to an XmlRpc::XmlRpcValue. + */ + operator XmlRpc::XmlRpcValue() const throw(); +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + +} // namespace Storage +} // namespace LiveSupport + +#endif // LiveSupport_Storage_SearchCriteria_h + diff --git a/livesupport/modules/storage/src/SearchCriteria.cxx b/livesupport/modules/storage/src/SearchCriteria.cxx new file mode 100644 index 000000000..668c64ced --- /dev/null +++ b/livesupport/modules/storage/src/SearchCriteria.cxx @@ -0,0 +1,118 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2004 Media Development Loan Fund + + This file is part of the LiveSupport project. + http://livesupport.campware.org/ + To report bugs, send an e-mail to bugs@campware.org + + LiveSupport is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + LiveSupport is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with LiveSupport; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + + Author : $Author: fgerlits $ + Version : $Revision: 1.1 $ + Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/storage/src/Attic/SearchCriteria.cxx,v $ + +------------------------------------------------------------------------------*/ + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "configure.h" +#endif + +#include "LiveSupport/Storage/SearchCriteria.h" + +using namespace LiveSupport::Storage; + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * Construct a SearchCriteria object with a single condition. + *----------------------------------------------------------------------------*/ +SearchCriteria :: SearchCriteria(const std::string & type, + const std::string & key, + const std::string & comparisonOperator, + const std::string & value) + throw(std::invalid_argument) + : logicalOperator("and"), limit(0), offset(0) +{ + setType(type); + addCondition(key, comparisonOperator, value); +} + + +/*------------------------------------------------------------------------------ + * Add a search condition. + *----------------------------------------------------------------------------*/ +void +SearchCriteria :: addCondition(const std::string & key, + const std::string & comparisonOperator, + const std::string & value) + throw(std::invalid_argument) +{ + std::string lowerCaseOp = lowerCase(comparisonOperator); + + if (lowerCaseOp == "=" + || lowerCaseOp == "partial" || lowerCaseOp == "prefix" + || lowerCaseOp == "<" || lowerCaseOp == "<=" + || lowerCaseOp == ">" || lowerCaseOp == ">=") { + SearchConditionType condition = { key, lowerCaseOp, value }; + searchConditions.push_back(condition); + } else { + throw std::invalid_argument("bad comparison operator argument"); + } +} + + +/*------------------------------------------------------------------------------ + * Convert to an XmlRpc::XmlRpcValue. + *----------------------------------------------------------------------------*/ +SearchCriteria :: operator XmlRpc::XmlRpcValue() const + throw() +{ + XmlRpc::XmlRpcValue returnValue; + + returnValue["filetype"] = type; + returnValue["operator"] = logicalOperator; + + XmlRpc::XmlRpcValue conditionList; + conditionList.setSize(searchConditions.size()); + SearchConditionListType::const_iterator + it = searchConditions.begin(); + for (int i = 0; it != searchConditions.end(); ++i, ++it) { + XmlRpc::XmlRpcValue condition; + condition["cat"] = it->key; + condition["op"] = it->comparisonOperator; + condition["val"] = it->value; + conditionList[i] = condition; + } + returnValue["conditions"] = conditionList; + + returnValue["limit"] = limit; + returnValue["offset"] = offset; + + return returnValue; +} + diff --git a/livesupport/modules/storage/src/SearchCriteriaTest.cxx b/livesupport/modules/storage/src/SearchCriteriaTest.cxx new file mode 100644 index 000000000..39510440c --- /dev/null +++ b/livesupport/modules/storage/src/SearchCriteriaTest.cxx @@ -0,0 +1,176 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2004 Media Development Loan Fund + + This file is part of the LiveSupport project. + http://livesupport.campware.org/ + To report bugs, send an e-mail to bugs@campware.org + + LiveSupport is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + LiveSupport is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with LiveSupport; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + + Author : $Author: fgerlits $ + Version : $Revision: 1.1 $ + Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/storage/src/Attic/SearchCriteriaTest.cxx,v $ + +------------------------------------------------------------------------------*/ + +/* ============================================================ include files */ + +#include "LiveSupport/Storage/SearchCriteria.h" +#include "SearchCriteriaTest.h" + +using namespace LiveSupport::Storage; + + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +CPPUNIT_TEST_SUITE_REGISTRATION(SearchCriteriaTest); + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * Set up the test environment + *----------------------------------------------------------------------------*/ +void +SearchCriteriaTest :: setUp(void) throw () +{ +} + + +/*------------------------------------------------------------------------------ + * Clean up the test environment + *----------------------------------------------------------------------------*/ +void +SearchCriteriaTest :: tearDown(void) throw () +{ +} + + +#include + +/*------------------------------------------------------------------------------ + * Test to see if we can do some simple operations + *----------------------------------------------------------------------------*/ +void +SearchCriteriaTest :: firstTest(void) + throw (CPPUNIT_NS::Exception) +{ + XmlRpc::XmlRpcValue xmlRpcValue; + + try { + SearchCriteria firstCriteria; + xmlRpcValue = firstCriteria; + } catch (std::invalid_argument &e) { + CPPUNIT_FAIL(e.what()); + } + CPPUNIT_ASSERT(xmlRpcValue.hasMember("filetype")); + CPPUNIT_ASSERT(xmlRpcValue["filetype"] == "audioclip"); + CPPUNIT_ASSERT(xmlRpcValue.hasMember("operator")); + CPPUNIT_ASSERT(xmlRpcValue["operator"] == "and"); + CPPUNIT_ASSERT(xmlRpcValue.hasMember("conditions")); + CPPUNIT_ASSERT(xmlRpcValue["conditions"].getType() + == XmlRpc::XmlRpcValue::TypeArray); + CPPUNIT_ASSERT(xmlRpcValue["conditions"].size() == 0); + CPPUNIT_ASSERT(xmlRpcValue.hasMember("limit")); + CPPUNIT_ASSERT(xmlRpcValue["limit"].getType() + == XmlRpc::XmlRpcValue::TypeInt); + CPPUNIT_ASSERT(int(xmlRpcValue["limit"]) == 0); + CPPUNIT_ASSERT(xmlRpcValue.hasMember("offset")); + CPPUNIT_ASSERT(xmlRpcValue["offset"].getType() + == XmlRpc::XmlRpcValue::TypeInt); + CPPUNIT_ASSERT(int(xmlRpcValue["offset"]) == 0); + + try { + SearchCriteria secondCriteria("playlist", "Or"); + secondCriteria.setLimit(50); + secondCriteria.addCondition("dc:title", "PREFIX", "My "); + secondCriteria.addCondition("DcTerms:Extent", "<", "180"); + xmlRpcValue = secondCriteria; + } catch (std::invalid_argument &e) { + CPPUNIT_FAIL(e.what()); + } + CPPUNIT_ASSERT(xmlRpcValue.hasMember("filetype")); + CPPUNIT_ASSERT(xmlRpcValue["filetype"] == "playlist"); + CPPUNIT_ASSERT(xmlRpcValue.hasMember("operator")); + CPPUNIT_ASSERT(xmlRpcValue["operator"] == "or"); + CPPUNIT_ASSERT(xmlRpcValue.hasMember("conditions")); + XmlRpc::XmlRpcValue conditions = xmlRpcValue["conditions"]; + CPPUNIT_ASSERT(conditions.getType() == XmlRpc::XmlRpcValue::TypeArray); + CPPUNIT_ASSERT(conditions.size() == 2); + + XmlRpc::XmlRpcValue condition0 = conditions[0]; + CPPUNIT_ASSERT(condition0.hasMember("cat")); + CPPUNIT_ASSERT(condition0["cat"] == "dc:title"); + CPPUNIT_ASSERT(condition0.hasMember("op")); + CPPUNIT_ASSERT(condition0["op"] == "prefix"); + CPPUNIT_ASSERT(condition0.hasMember("val")); + CPPUNIT_ASSERT(condition0["val"] == "My "); + + XmlRpc::XmlRpcValue condition1 = conditions[1]; + CPPUNIT_ASSERT(condition1.hasMember("cat")); + CPPUNIT_ASSERT(condition1["cat"] == "DcTerms:Extent"); + CPPUNIT_ASSERT(condition1.hasMember("op")); + CPPUNIT_ASSERT(condition1["op"] == "<"); + CPPUNIT_ASSERT(condition1.hasMember("val")); + CPPUNIT_ASSERT(condition1["val"] == "180"); + + CPPUNIT_ASSERT(xmlRpcValue.hasMember("limit")); + CPPUNIT_ASSERT(xmlRpcValue["limit"].getType() + == XmlRpc::XmlRpcValue::TypeInt); + CPPUNIT_ASSERT(int(xmlRpcValue["limit"]) == 50); + CPPUNIT_ASSERT(xmlRpcValue.hasMember("offset")); + CPPUNIT_ASSERT(xmlRpcValue["offset"].getType() + == XmlRpc::XmlRpcValue::TypeInt); + CPPUNIT_ASSERT(int(xmlRpcValue["offset"]) == 0); + + try { + SearchCriteria thirdCriteria("all", "dc:creator", "partial", "X"); + xmlRpcValue = thirdCriteria; + } catch (std::invalid_argument &e) { + CPPUNIT_FAIL(e.what()); + } + CPPUNIT_ASSERT(xmlRpcValue.hasMember("filetype")); + CPPUNIT_ASSERT(xmlRpcValue["filetype"] == "all"); + CPPUNIT_ASSERT(xmlRpcValue.hasMember("conditions")); + conditions = xmlRpcValue["conditions"]; + CPPUNIT_ASSERT(conditions.getType() == XmlRpc::XmlRpcValue::TypeArray); + CPPUNIT_ASSERT(conditions.size() == 1); + + condition0 = conditions[0]; + CPPUNIT_ASSERT(condition0.hasMember("cat")); + CPPUNIT_ASSERT(condition0["cat"] == "dc:creator"); + CPPUNIT_ASSERT(condition0.hasMember("op")); + CPPUNIT_ASSERT(condition0["op"] == "partial"); + CPPUNIT_ASSERT(condition0.hasMember("val")); + CPPUNIT_ASSERT(condition0["val"] == "X"); + + CPPUNIT_ASSERT(xmlRpcValue.hasMember("limit")); + CPPUNIT_ASSERT(xmlRpcValue["limit"].getType() + == XmlRpc::XmlRpcValue::TypeInt); + CPPUNIT_ASSERT(int(xmlRpcValue["limit"]) == 0); + CPPUNIT_ASSERT(xmlRpcValue.hasMember("offset")); + CPPUNIT_ASSERT(xmlRpcValue["offset"].getType() + == XmlRpc::XmlRpcValue::TypeInt); + CPPUNIT_ASSERT(int(xmlRpcValue["offset"]) == 0); +} + diff --git a/livesupport/modules/storage/src/SearchCriteriaTest.h b/livesupport/modules/storage/src/SearchCriteriaTest.h new file mode 100644 index 000000000..ba75fe582 --- /dev/null +++ b/livesupport/modules/storage/src/SearchCriteriaTest.h @@ -0,0 +1,107 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2004 Media Development Loan Fund + + This file is part of the LiveSupport project. + http://livesupport.campware.org/ + To report bugs, send an e-mail to bugs@campware.org + + LiveSupport is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + LiveSupport is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with LiveSupport; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + + Author : $Author: fgerlits $ + Version : $Revision: 1.1 $ + Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/storage/src/Attic/SearchCriteriaTest.h,v $ + +------------------------------------------------------------------------------*/ +#ifndef SearchCriteriaTest_h +#define SearchCriteriaTest_h + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "configure.h" +#endif + +#include + + +namespace LiveSupport { +namespace Storage { + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * Unit test for the SearchCriteria class. + * + * @author $Author: fgerlits $ + * @version $Revision: 1.1 $ + * @see SearchCriteria + */ +class SearchCriteriaTest : public CPPUNIT_NS::TestFixture +{ + CPPUNIT_TEST_SUITE(SearchCriteriaTest); + CPPUNIT_TEST(firstTest); + CPPUNIT_TEST_SUITE_END(); + + protected: + + /** + * A simple test. + * + * @exception CPPUNIT_NS::Exception on test failures. + */ + void + firstTest(void) throw (CPPUNIT_NS::Exception); + + + public: + + /** + * Set up the environment for the test case. + */ + void + setUp(void) throw (); + + /** + * Clean up the environment after the test case. + */ + void + tearDown(void) throw (); +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + +} // namespace Storage +} // namespace LiveSupport + +#endif // SearchCriteriaTest_h +