44 std::ostringstream text;
45 text <<
"query \"" << query <<
"\" in class \"" << c.get_name() <<
"\" failed:\n" << reason;
52 return std::string(
"failed to create reqular expression \"") +
what +
"\": " + reason;
88 return boost::regex_match(d->str(), *
reinterpret_cast<const boost::regex*
>(re));
112 while (s[0] ==
' ' || s[0] ==
'\n' || s[0] ==
'\t')
122 const char* fname =
"OksQuery::OksQuery(OksClass *, const char *)";
123 const char* error_str =
"Can't create query ";
125 char delimiter =
'\0';
128 Oks::error_msg(fname) << error_str <<
"without specified class\n";
142 Oks::error_msg(fname) << error_str <<
"from string which consists of space symbols\n";
151 std::string::size_type p = s.find(
' ');
153 if (p == std::string::npos) {
156 "it must consists of as minimum two tokens separated by space\n";
167 "the first token must be \'"
174 if (delimiter ==
')') {
175 p = s.rfind(delimiter);
176 if (p == std::string::npos) {
179 "it must contain closing bracket \')\' if it has opening bracket \'(\'\n";
191 if (p == std::string::npos) {
194 "it must contain closing bracket \')\' if it has opening bracket \'(\'\n";
206 Oks::error_msg(fname) <<
"Can't parse subquery expression \"" << s
208 "it must be enclosed by brackets\n";
214 const char* fname =
"OksQuery::create_expression()";
221 Oks::error_msg(fname) <<
"Can't create query without specified class\n";
226 Oks::error_msg(fname) <<
"Can't create query from empty string\n";
232 std::list<std::string> slist;
240 if (s[0] ==
'\"' || s[0] ==
'\'' || s[0] ==
'`') {
241 char delimiter = s[0];
244 std::string::size_type p = s.find(delimiter);
246 if (p == std::string::npos) {
249 "the delimiter is \' "
252 "the rest of the expression is \""
258 slist.push_back(std::string(s, 0, p));
261 }
else if (s[0] ==
'(') {
262 std::string::size_type p = 1;
263 size_t strLength = s.length();
266 while (p < strLength) {
278 Oks::error_msg(fname) <<
"Can't parse query expression \"" << str <<
"\"\n"
279 <<
"There is no closing \')\' for " <<
'\"' << s <<
"\"\n";
286 slist.push_back(std::string(s, 0, p - 1));
290 std::string::size_type p = 0;
291 size_t strLength = s.length();
293 while (p < strLength && s[p] !=
' ')
296 slist.push_back(std::string(s, 0, p));
303 Oks::error_msg(fname) <<
"Can't create query from empty string \"" << str <<
"\"\n";
307 const std::string first = slist.front();
311 if (slist.size() < 2) {
312 Oks::error_msg(fname) <<
"\'" << first <<
"\' must have two or more arguments: (" << str <<
")'\n";
319 while (!slist.empty()) {
320 const std::string item2 = slist.front();
335 if (slist.size() != 1) {
336 Oks::error_msg(fname) <<
"\'" << first <<
"\' must have exactly one argument: (" << str <<
")\n";
342 const std::string item2 = slist.front();
351 }
else if (slist.size() != 2) {
352 Oks::error_msg(fname) <<
"Can't parse query expression \"" << str <<
"\"\n";
355 const std::string second = slist.front();
358 const std::string third = slist.front();
367 "can't find relationship \""
368 << first <<
"\" in class \"" << c->get_name() <<
"\"\n";
382 "second parameter \'"
388 OksClass* relc = c->get_kernel()->find_class(r->get_type());
392 <<
"can't find class \"" << r->get_type() <<
"\"\n";
407 <<
"can't find attribute \"" << first <<
"\" in class \"" << c->get_name() <<
"\"\n";
428 d->SetValues(second.c_str(), a);
436 <<
"can't find comparator function \"" << third <<
"\"\n";
448 const char* fname =
"OksClass::execute_query()";
456 Oks::error_msg(fname) <<
"Can't execute query \"" << *sqe <<
"\"\n";
461 bool indexedSearch =
false;
469 indexedSearch =
true;
483 indexedSearch =
true;
495 if (indexedSearch ==
false) {
507 }
catch (std::exception& ex) {
518 if (c->p_objects && !c->p_objects->empty()) {
519 for (OksObject::Map::iterator i2 = c->p_objects->begin(); i2 != c->p_objects->end(); ++i2) {
530 }
catch (std::exception& ex) {
544 const char* fname =
"OksQueryExpression::CheckSyntax()";
549 Oks::error_msg(fname) <<
"OksComparator: Can't execute query for nil attribute or nil object-id\n";
552 Oks::error_msg(fname) <<
"OksComparator: Can't execute query for nil compare function\n";
560 Oks::error_msg(fname) <<
"OksRelationshipExpression: Can't execute query for nil relationship\n";
563 Oks::error_msg(fname) <<
"OksRelationshipExpression: Can't execute query for nil query expression\n";
570 Oks::error_msg(fname) <<
"OksNotExpression: Can't execute \'not\' for nil query expression\n";
578 Oks::error_msg(fname) <<
"OksAndExpression: Can't execute \'and\' for "
581 "Two or more arguments are required\n";
584 std::list<OksQueryExpression*>& elist = ((
OksAndExpression*)
this)->p_expressions;
586 for (std::list<OksQueryExpression*>::iterator i = elist.begin(); i != elist.end(); ++i)
587 if ((*i)->CheckSyntax() ==
false)
595 Oks::error_msg(fname) <<
"OksOrExpression: Can't execute \'or\' for "
598 "Two or more arguments are required\n";
602 std::list<OksQueryExpression*>& elist = ((
OksOrExpression*)
this)->p_expressions;
604 for (std::list<OksQueryExpression*>::iterator i = elist.begin(); i != elist.end(); ++i)
605 if ((*i)->CheckSyntax() ==
false)
624 throw std::runtime_error(
"cannot execute nil query");
627 switch (qe->
type()) {
633 if (!a && !cmp->
value) {
634 throw std::runtime_error(
"cannot execute query for nil attribute");
636 throw std::runtime_error(
"cannot execute query for nil compare function");
645 cmp->
m_reg_exp =
new boost::regex(s.c_str());
646 }
catch (std::exception& ex) {
655 return (*f)(&d, cmp_value);
663 throw std::runtime_error(
"cannot execute query for nil relationship");
672 if (!d->data.LIST || d->data.LIST->empty())
675 for (OksData::List::iterator i = d->data.LIST->begin(); i != d->data.LIST->end(); ++i) {
679 std::ostringstream text;
680 text <<
"cannot process relationship expression: object \"" << *d2->
data.
UID2.object_id <<
'@'
681 << *d2->
data.
UID2.class_id <<
"\" referenced through multi values relationship \""
683 throw std::runtime_error(text.str().c_str());
700 std::ostringstream text;
701 text <<
"cannot process relationship expression: object \"" << *d
702 <<
"\" referenced through single value relationship \""
704 throw std::runtime_error(text.str().c_str());
707 return (d->data.OBJECT
715 throw std::runtime_error(
"cannot process \'not\' expression: referenced query expression is nil");
722 std::ostringstream text;
723 text <<
"cannot process \'and\' expression for " << ((
OksAndExpression*)qe)->p_expressions.size()
724 <<
" argument (two or more arguments are required)";
725 throw std::runtime_error(text.str().c_str());
727 std::list<OksQueryExpression*>& elist = ((
OksAndExpression*)qe)->p_expressions;
729 for (std::list<OksQueryExpression*>::iterator i = elist.begin(); i != elist.end(); ++i)
738 std::ostringstream text;
739 text <<
"cannot process \'or\' expression for " << ((
OksAndExpression*)qe)->p_expressions.size()
740 <<
" argument (two or more arguments are required)";
741 throw std::runtime_error(text.str().c_str());
743 std::list<OksQueryExpression*>& elist = ((
OksOrExpression*)qe)->p_expressions;
745 for (std::list<OksQueryExpression*>::iterator i = elist.begin(); i != elist.end(); ++i)
753 std::ostringstream text;
754 text <<
"unexpected query type " << (int)(qe->
type());
755 throw std::runtime_error(text.str().c_str());
773 s <<
'\"' << a->
get_name() <<
"\" ";
814 s <<
'\"' << r->get_name() <<
"\" ";
836 const std::list<OksQueryExpression*>& elist = ((
OksAndExpression*)&qe)->expressions();
838 if (!elist.empty()) {
841 for (std::list<OksQueryExpression*>::const_iterator i = elist.begin(); i != elist.end(); ++i) {
854 const std::list<OksQueryExpression*>& elist = ((
OksOrExpression*)&qe)->expressions();
856 if (!elist.empty()) {
859 for (std::list<OksQueryExpression*>::const_iterator i = elist.begin(); i != elist.end(); ++i) {
911 s <<
'\"' << *i <<
'\"';
941 for (std::list<OksObject*>::const_iterator i = path.begin(); i != path.end(); ++i) {
947 path.push_back(
const_cast<OksObject*
>(
this));
949 for (std::list<std::string>::const_iterator i = expression.
get_rel_names().begin();
954 if (!(*i).empty() && (*i)[0] ==
'?') {
955 std::string nm = (*i).substr(1);
977 for (OksData::List::iterator i2 = d->data.LIST->begin(); i2 != d->data.LIST->end(); ++i2) {
999 path.push_back(
const_cast<OksObject*
>(
this));
1004 if (d->data.OBJECT->satisfies(goal, expression, path) ==
true)
1007 for (OksData::List::iterator i2 = d->data.LIST->begin(); i2 != d->data.LIST->end(); ++i2) {
1019 if (d->data.OBJECT->satisfies(goal, *expression.
get_next(), path) ==
true)
1022 for (OksData::List::iterator i2 = d->data.LIST->begin(); i2 != d->data.LIST->end(); ++i2) {
1048 std::string::size_type p = s.rfind(
')');
1050 if (p == std::string::npos) {
1051 throw oks::bad_query_syntax(std::string(
"Query expression \'") + str +
"\' must contain closing bracket");
1057 throw oks::bad_query_syntax(std::string(
"Query expression \'") + str +
"\' must be enclosed by brackets");
1062 Oks::Tokenizer t(s,
" \t\n");
1067 throw oks::bad_query_syntax(std::string(
"Expression \'") + s +
"\' must start from " +
OksQuery::DIRECT +
" or " +
1071 s.erase(0, token.size());
1075 std::string::size_type p =
s.find(
'\"', 1);
1077 if (p == std::string::npos) {
1078 throw oks::bad_query_syntax(std::string(
"No trailing delimiter of object name in query \'") + str +
"\'");
1081 std::string::size_type p2 =
s.find(
'@');
1083 if (p2 == std::string::npos || p2 > p) {
1084 throw oks::bad_query_syntax(std::string(
"Bad format of object name ") +
s.substr(0, p + 1) +
" in query \'" +
1088 std::string object_id = std::string(s, 1, p2 - 1);
1089 std::string class_name = std::string(s, p2 + 1, p - p2 - 1);
1092 if ((p_goal =
c->get_object(object_id)) == 0) {
1093 throw oks::bad_query_syntax(std::string(
"Cannot find object ") +
s.substr(0, p + 1) +
" in query \'" + str +
1094 "\': no such object");
1097 throw oks::bad_query_syntax(std::string(
"Cannot find object ") +
s.substr(0, p + 1) +
" in query \'" + str +
1098 "\': no such class");
1103 throw oks::bad_query_syntax(std::string(
"No name of object in \'") + str +
"\'");
1108 }
catch (oks::bad_query_syntax& e) {
1109 throw oks::bad_query_syntax(std::string(
"Failed to parse expression \'") + str +
"\' because \'" + e.what() +
"\'");
1120 throw oks::bad_query_syntax(
"Empty expression");
1124 std::string::size_type p =
s.rfind(
')');
1126 if (p == std::string::npos) {
1127 throw oks::bad_query_syntax(std::string(
"Expression \'") + str +
"\' must contain closing bracket");
1135 std::string::size_type p1 =
s.find(
'(');
1137 if (p1 != std::string::npos) {
1138 std::string::size_type p2 =
s.rfind(
')');
1140 if (p2 == std::string::npos) {
1141 throw oks::bad_query_syntax(std::string(
"Nested expression of \'") + str +
"\' must contain closing bracket");
1151 Oks::Tokenizer t(s,
" \t\n");
1156 p_use_nested_lookup =
false;
1158 p_use_nested_lookup =
true;
1162 throw oks::bad_query_syntax(std::string(
"Expression \'") + s +
"\' must start from " +
OksQuery::DIRECT +
" or " +
1166 s.erase(0, token.size());
1168 while (
s.length()) {
1174 if (s[0] ==
'\"' || s[0] ==
'\'' || s[0] ==
'`') {
1175 char delimiter =
s[0];
1177 p =
s.find(delimiter, 1);
1179 if (p == std::string::npos) {
1182 throw oks::bad_query_syntax(std::string(
"No trailing delimiter of \'") + s +
"\' (expression \'" + str +
1186 p_rel_names.push_back(std::string(s, 1, p - 1));
1192 throw oks::bad_query_syntax(std::string(
"Name of relationship \'") + s +
1193 "\' must start from a delimiter (expression \'" + str +
"\')");
1197 if (p_rel_names.empty()) {
1200 throw oks::bad_query_syntax(std::string(
"An expression of \'") + str +
"\' has no relationship names defined");
1203 throw oks::bad_query_syntax(std::string(
"Expression \'") + str +
"\' must be enclosed by brackets");
static std::string fill(const std::string &what, const std::string &reason) noexcept
OKS query logical AND expression class.
const std::string & get_name() const noexcept
out stream operator
OksObject::Map * p_objects
FList * p_all_sub_classes
OksIndex::Map * p_indices
OksClass(const std::string &name, OksKernel *kernel, bool transient=false)
Create OKS class.
OksDataInfo::Map * p_data_info
OksObject::List * execute_query(OksQuery *query) const
Execute query.
OKS query expression comparator class.
OksQuery::Comparator GetFunction() const
const OksAttribute * attribute
void SetValue(OksData *v)
const OksAttribute * GetAttribute() const
OksComparator(const OksAttribute *a, OksData *v, OksQuery::Comparator f)
OksQuery::Comparator m_comp_f
Provides interface to the OKS kernel.
OksClass * find_class(const std::string &class_name) const
Find class by name (C++ string).
Abstract class describing list of OKS query expressions.
OKS query logical NOT expression class.
OksNotExpression(OksQueryExpression *q=0)
struct dunedaq::oks::OksObject::OksUid uid
OksData * GetRelationshipValue(const std::string &) const
Get value of relationship by name.
std::list< OksObject * > List
bool satisfies(const OksObject *goal, const oks::QueryPathExpression &expresssion, OksObject::List &path) const
OksObject(const OksClass *oks_class, const char *object_id=0, bool skip_init=false)
OKS object constructor.
OksObject::List * find_path(const oks::QueryPath &query) const
bool SatisfiesQueryExpression(OksQueryExpression *query_exp) const
Check if object satisfies query expression.
const std::string & GetId() const
OKS query logical OR expression class.
@ fStringToQueryExpression
@ ObjectSatisfiesQueryExpression
OKS query expression class.
const OksQuery::QueryType p_type
OksQuery::QueryType type() const
friend std::ostream & operator<<(std::ostream &, const OksQueryExpression &)
OksQueryExpression(OksQuery::QueryType qet=OksQuery::unknown_type)
static const char * ALL_SUBCLASSES
static bool equal_cmp(const OksData *, const OksData *)
static bool reg_exp_cmp(const OksData *, const OksData *regexp)
bool(*) Comparator(const OksData *, const OksData *)
static bool greater_cmp(const OksData *, const OksData *)
bool search_in_subclasses() const
static const char * THIS_CLASS
static bool less_or_equal_cmp(const OksData *, const OksData *)
friend std::ostream & operator<<(std::ostream &, const OksQuery &)
static bool not_equal_cmp(const OksData *, const OksData *)
static const char * PATH_TO
OksQueryExpression * p_expression
static const char * NESTED
static bool greater_or_equal_cmp(const OksData *, const OksData *)
static bool less_cmp(const OksData *, const OksData *)
static const char * DIRECT
OksQuery(bool b, OksQueryExpression *q=0)
static OksQueryExpression * create_expression(const OksClass *, const std::string &)
OksQueryExpression * get() const
OKS query relationship expression class.
OksQueryExpression * get() const
bool IsCheckAllObjects() const
const OksRelationship * GetRelationship() const
OksRelationshipExpression(const OksRelationship *r, OksQueryExpression *q, bool b=false)
OksString()
to deallocate memory when destroyed
static std::ostream & error_msg(const char *)
static std::string fill(const OksQueryExpression &query, const OksClass &c, const std::string &reason) noexcept
QueryPathExpression(bool v)
bool get_use_nested_lookup() const
const QueryPathExpression * get_next() const
const std::list< std::string > & get_rel_names() const
const OksObject * get_goal_object() const
const QueryPathExpression * get_start_expression() const
QueryPath(const OksObject *o, QueryPathExpression *qpe)
virtual const char * what() const noexcept
#define OSK_PROFILING(FID, K)
std::ostream & operator<<(std::ostream &s, const oks::exception &ex)
void erase_empty_chars(std::string &s)
std::string str(int base=0) const
union dunedaq::oks::OksData::Data data
enum dunedaq::oks::OksData::Type type
const OksClass * class_id
struct dunedaq::oks::OksData::Data::@226266061051241020017305361066131172152317024337 UID2