Fix bug to allow users to specify dataset names in the prefix-based search
Change-Id: I73d18ea31dcb8da75f57f6d808e3550833a9b3e0
diff --git a/catalog/src/query/query-adapter.hpp b/catalog/src/query/query-adapter.hpp
index c6391ef..2b85da5 100644
--- a/catalog/src/query/query-adapter.hpp
+++ b/catalog/src/query/query-adapter.hpp
@@ -49,6 +49,7 @@
#include <sstream>
#include <string>
#include <array>
+#include <utility>
namespace atmos {
namespace query {
@@ -228,8 +229,8 @@
Json::Value& jsonValue);
bool
- json2CompleteSearchSql(std::stringstream& sqlQuery,
- Json::Value& jsonValue);
+ json2PrefixBasedSearchSql(std::stringstream& sqlQuery,
+ Json::Value& jsonValue);
ndn::Name
getQueryResultsName(std::shared_ptr<const ndn::Interest> interest,
@@ -815,11 +816,11 @@
template <typename DatabaseHandler>
bool
-QueryAdapter<DatabaseHandler>::json2CompleteSearchSql(std::stringstream& sqlQuery,
- Json::Value& jsonValue)
+QueryAdapter<DatabaseHandler>::json2PrefixBasedSearchSql(std::stringstream& sqlQuery,
+ Json::Value& jsonValue)
{
#ifndef NDEBUG
- std::cout << "jsonValue in json2CompleteSearchSql: " << jsonValue.toStyledString() << std::endl;
+ std::cout << "jsonValue in json2PrefixBasedSearchSql: " << jsonValue.toStyledString() << std::endl;
#endif
if (jsonValue.type() != Json::objectValue) {
std::cout << jsonValue.toStyledString() << "is not json object" << std::endl;
@@ -846,10 +847,7 @@
if (key.asString().compare("??") == 0) {
typedString = value.asString();
- // since the front end triggers the autocompletion when users typed '/',
- // there must be a '/' at the end, and the first char must be '/'
- if (typedString.empty() || typedString.at(typedString.length() - 1) != '/' ||
- typedString.find("/") != 0)
+ if (typedString.empty() || typedString.find("/") != 0)
return false;
break;
}
@@ -859,26 +857,34 @@
size_t pos = 0;
size_t start = 1; // start from the 1st char which is not '/'
size_t count = 0; // also the name to query for
+ size_t typedStringLen = typedString.length();
std::string token;
std::string delimiter = "/";
- std::map<std::string, std::string> typedComponents;
+ std::vector<std::pair<std::string, std::string>> typedComponents;
while ((pos = typedString.find(delimiter, start)) != std::string::npos) {
token = typedString.substr(start, pos - start);
- if (count >= m_nameFields.size() - 1) {
+ if (count >= m_nameFields.size()) {
return false;
}
// add column name and value (token) into map
- typedComponents.insert(std::pair<std::string, std::string>(m_nameFields[count], token));
+ typedComponents.push_back(std::make_pair(m_nameFields[count], token));
+
count++;
start = pos + 1;
}
+ // we may have a component after the last "/"
+ if (start < typedStringLen) {
+ typedComponents.push_back(std::make_pair(m_nameFields[count],
+ typedString.substr(start, typedStringLen - start)));
+ }
+
// 2. generate the sql string (append what appears in the typed string, like activity='xxx'),
// return true
bool more = false;
sqlQuery << "SELECT name FROM " << m_databaseTable;
- for (std::map<std::string, std::string>::iterator it = typedComponents.begin();
+ for (std::vector<std::pair<std::string, std::string>>::iterator it = typedComponents.begin();
it != typedComponents.end(); ++it) {
if (more)
sqlQuery << " AND";
@@ -977,7 +983,7 @@
}
}
else if (parsedFromString.get("??", tmp) != tmp) {
- if (!json2CompleteSearchSql(sqlQuery, parsedFromString)) {
+ if (!json2PrefixBasedSearchSql(sqlQuery, parsedFromString)) {
sendNack(segmentPrefix);
return;
}
diff --git a/catalog/tests/unit-tests/query/test-query-adapter.cpp b/catalog/tests/unit-tests/query/test-query-adapter.cpp
index 568f5ad..b49ea03 100644
--- a/catalog/tests/unit-tests/query/test-query-adapter.cpp
+++ b/catalog/tests/unit-tests/query/test-query-adapter.cpp
@@ -164,10 +164,10 @@
}
bool
- json2CompleteSearchSqlTest(std::stringstream& sqlQuery,
- Json::Value& jsonValue)
+ json2PrefixBasedSearchSqlTest(std::stringstream& sqlQuery,
+ Json::Value& jsonValue)
{
- return json2CompleteSearchSql(sqlQuery, jsonValue);
+ return json2PrefixBasedSearchSql(sqlQuery, jsonValue);
}
};
@@ -573,29 +573,39 @@
BOOST_CHECK_EQUAL(false, queryAdapterTest2.json2AutocompletionSqlTest(ss, testJson4));
}
- BOOST_AUTO_TEST_CASE(QueryAdapterCompleteSearchSuccessTest)
+ BOOST_AUTO_TEST_CASE(QueryAdapterPrefixBasedSearchSuccessTest)
{
initializeQueryAdapterTest2();
std::stringstream ss;
Json::Value testJson;
testJson["??"] = "/";
- BOOST_CHECK_EQUAL(true, queryAdapterTest2.json2CompleteSearchSqlTest(ss, testJson));
+ BOOST_CHECK_EQUAL(true, queryAdapterTest2.json2PrefixBasedSearchSqlTest(ss, testJson));
BOOST_CHECK_EQUAL("SELECT name FROM cmip5;", ss.str());
ss.str("");
ss.clear();
testJson.clear();
+ testJson["??"] = "/Activity/Product";
+ BOOST_CHECK_EQUAL(true, queryAdapterTest2.json2PrefixBasedSearchSqlTest(ss, testJson));
+ BOOST_CHECK_EQUAL("SELECT name FROM cmip5 WHERE activity='Activity' AND product='Product';",
+ ss.str());
+
+ ss.str("");
+ ss.clear();
+ testJson.clear();
testJson["??"] = "/Activity/Product/Organization/Model/Experiment/Frequency/Modeling/\
-Variable/Ensemble/";
- BOOST_CHECK_EQUAL(true, queryAdapterTest2.json2CompleteSearchSqlTest(ss, testJson));
- BOOST_CHECK_EQUAL("SELECT name FROM cmip5 WHERE activity='Activity' AND ensemble=\
-'Ensemble' AND experiment='Experiment' AND frequency='Frequency' AND model='Model' AND \
-modeling_realm='Modeling' AND organization='Organization' AND product='Product' AND variable_name=\
-'Variable';",ss.str());
+Variable/Ensemble/Time/";
+
+ BOOST_CHECK_EQUAL(true, queryAdapterTest2.json2PrefixBasedSearchSqlTest(ss, testJson));
+
+ BOOST_CHECK_EQUAL("SELECT name FROM cmip5 WHERE activity='Activity' AND product='Product' \
+AND organization='Organization' AND model='Model' AND experiment='Experiment' AND frequency=\
+'Frequency' AND modeling_realm='Modeling' AND variable_name='Variable' AND ensemble='Ensemble'\
+ AND time='Time';", ss.str());
}
- BOOST_AUTO_TEST_CASE(QueryAdapterCompleteSearchFailureTest)
+ BOOST_AUTO_TEST_CASE(QueryAdapterPrefixBasedSearchFailureTest)
{
initializeQueryAdapterTest2();
@@ -606,19 +616,19 @@
ss.clear();
testJson.clear();
testJson["??"] = "";
- BOOST_CHECK_EQUAL(false, queryAdapterTest2.json2CompleteSearchSqlTest(ss, testJson));
+ BOOST_CHECK_EQUAL(false, queryAdapterTest2.json2PrefixBasedSearchSqlTest(ss, testJson));
ss.str("");
ss.clear();
Json::Value testJson2; //simply clear does not work
testJson2[0] = "test"; // incorrect json object
- BOOST_CHECK_EQUAL(false, queryAdapterTest2.json2CompleteSearchSqlTest(ss, testJson2));
+ BOOST_CHECK_EQUAL(false, queryAdapterTest2.json2PrefixBasedSearchSqlTest(ss, testJson2));
ss.str("");
ss.clear();
Json::Value testJson3;
testJson3 = Json::Value(Json::arrayValue); // incorrect json object
- BOOST_CHECK_EQUAL(false, queryAdapterTest2.json2CompleteSearchSqlTest(ss, testJson3));
+ BOOST_CHECK_EQUAL(false, queryAdapterTest2.json2PrefixBasedSearchSqlTest(ss, testJson3));
ss.str("");
ss.clear();
@@ -626,7 +636,7 @@
Json::Value param;
param[0] = "test";
testJson4["name"] = param; // incorrect json object
- BOOST_CHECK_EQUAL(false, queryAdapterTest2.json2CompleteSearchSqlTest(ss, testJson4));
+ BOOST_CHECK_EQUAL(false, queryAdapterTest2.json2PrefixBasedSearchSqlTest(ss, testJson4));
}
BOOST_AUTO_TEST_SUITE_END()