using namespace ctx;
-static QueryChecker __queryChecker;
-
ContextStoreClient::ContextStoreClient(ServiceBase* hostService, const std::string& busName) :
ClientBase(hostService, busName)
{
{
Store* store = NULL;
- if (!__queryChecker.validateUri(uri))
+ if (!QueryChecker::validateUri(uri))
throw static_cast<int>(E_PARAM);
if (isSystem()) {
throw static_cast<int>(E_PARAM);
}
- if (!__queryChecker.validateProjection(cols))
+ if (!QueryChecker::validateColumns(cols))
throw static_cast<int>(E_PARAM);
std::vector<std::shared_ptr<Tuple>> tuples = Tuple::buildFrom(vals);
if (!projection || !selection || !sortOrder)
throw static_cast<int>(E_PARAM);
- if (!__queryChecker.validateProjection(projection))
+ if (!QueryChecker::validateProjection(projection))
throw static_cast<int>(E_PARAM);
- if (!__queryChecker.validateSelection(selection))
+ if (!QueryChecker::validateSelection(selection))
throw static_cast<int>(E_PARAM);
- if (!__queryChecker.validateSortOrder(sortOrder))
+ if (!QueryChecker::validateSortOrder(sortOrder))
throw static_cast<int>(E_PARAM);
std::vector<std::shared_ptr<Tuple>> tuples;
if (!selection)
throw static_cast<int>(E_PARAM);
- if (!__queryChecker.validateSelection(selection))
+ if (!QueryChecker::validateSelection(selection))
throw static_cast<int>(E_PARAM);
methodCall.reply(store.remove(*this, selection));
-
/*
* Copyright (c) 2017 Samsung Electronics Co., Ltd.
*
#include <regex>
#include "QueryChecker.h"
+#define COLUMN_REGEX R"~(^ *[A-Za-z]\w* *$)~"
+#define AGGR_REGEX R"~(^ *[A-Za-z]+\([A-Za-z]\w*\) *$)~"
+#define QUOTED_REGEX R"~(\'.*?\')~"
+#define NUMBER_REGEX R"~(^ *\-?[0-9]+(\.[0-9]+)? *$)~"
+#define ORDER_REGEX R"~( +[Aa]|([Dd][Ee])([Ss][Cc]) *$)~"
+
using namespace ctx;
-QueryChecker::QueryChecker()
+static bool __isColumnName(const std::string& column)
+{
+ static std::regex colRegex(COLUMN_REGEX, std::regex::optimize);
+ return std::regex_match(column, colRegex);
+}
+
+static bool __isAggregation(const std::string& aggr)
{
+ static std::regex aggrRegex(AGGR_REGEX, std::regex::optimize);
+ return std::regex_match(aggr, aggrRegex);
}
-QueryChecker::~QueryChecker()
+static bool __isNumber(const std::string& number)
+{
+ static std::regex numberRegex(NUMBER_REGEX, std::regex::optimize);
+ return std::regex_match(number, numberRegex);
+}
+
+QueryChecker::QueryChecker()
{
}
bool QueryChecker::validateUri(const std::string& uri)
{
- static std::regex uriRegex(URI_REGEX("context\/record"), std::regex::optimize);
- if (!std::regex_match(uri, uriRegex)) {
- _E("Invalid parameter");
+ static std::regex uriRegex(STORE_URI_REGEX, std::regex::optimize);
+
+ if (!std::regex_match(uri, uriRegex))
return false;
+
+ return true;
+}
+
+bool QueryChecker::validateColumns(const std::string& columns)
+{
+ std::vector<std::string> tokens = util::tokenizeString(columns, ",");
+
+ for (auto& token : tokens) {
+ if (!__isColumnName(token)) return false;
}
+
return true;
}
bool QueryChecker::validateProjection(const std::string& projection)
{
- // TODO
+ std::vector<std::string> tokens = util::tokenizeString(projection, ",");
+
+ for (auto& token : tokens) {
+ if (!__isColumnName(token) && !__isAggregation(token)) return false;
+ }
+
return true;
}
bool QueryChecker::validateSelection(const std::string& selection)
{
- // TODO
+ if (selection.empty())
+ return true;
+
+ static std::regex quotedStrRegex(QUOTED_REGEX, std::regex::optimize);
+
+ std::string stripped = std::regex_replace(selection, quotedStrRegex, " ");
+ std::vector<std::string> tokens = util::tokenizeString(stripped, " ()!<>=");
+
+ for (auto& token : tokens) {
+ if (!__isColumnName(token) && !__isNumber(token)) return false;
+ }
+
+ return true;
+}
+
+bool QueryChecker::validateGrouping(const std::string& grouping)
+{
+ if (grouping.empty())
+ return true;
+
+ return validateColumns(grouping);
+}
+
+bool QueryChecker::validateHaving(const std::string& having)
+{
+ if (having.empty())
+ return true;
+
+ std::vector<std::string> tokens = util::tokenizeString(having, "!<>=");
+
+ if (tokens.size() != 2)
+ return false;
+
+ if (!__isAggregation(tokens[0]))
+ return false;
+
+ if (!__isNumber(tokens[1]))
+ return false;
+
return true;
}
bool QueryChecker::validateSortOrder(const std::string& sortOrder)
{
- // TODO
+ if (sortOrder.empty())
+ return true;
+
+ static std::regex orderRegex(ORDER_REGEX, std::regex::optimize);
+
+ std::vector<std::string> tokens = util::tokenizeString(sortOrder, ",");
+
+ for (auto& token : tokens) {
+ token = std::regex_replace(token, orderRegex, EMPTY_STR);
+ if (!__isColumnName(token) && !__isAggregation(token)) return false;
+ }
+
return true;
}
#include "Schema.h"
#include "SchemaChecker.h"
-#define COL_REGEX "^[A-Za-z]+\\w*$"
+#define COL_REGEX "^[A-Za-z]\\w*$"
using namespace ctx;
SchemaChecker::SchemaChecker() :
- __uriRegex(URI_REGEX("context\/record"), std::regex::optimize),
- __privilegeRegex(URI_REGEX("privilege"), std::regex::optimize),
+ __uriRegex(STORE_URI_REGEX, std::regex::optimize),
+ __privilegeRegex(PRIVILEGE_REGEX, std::regex::optimize),
__columnNameRegex(COL_REGEX, std::regex::optimize)
{
}