39 std::ostringstream text;
40 text <<
"query \"" << query <<
"\" in class \"" << c.get_name() <<
"\" failed:\n" << reason;
47 return std::string(
"failed to create reqular expression \"") + what +
"\": " + reason;
58 return boost::regex_match(d->str(), *
reinterpret_cast<const boost::regex *
>(re));
81 while(s[0] ==
' ' || s[0] ==
'\n' || s[0] ==
'\t') s.erase(0, 1);
89 const char * fname =
"OksQuery::OksQuery(OksClass *, const char *)";
90 const char * error_str =
"Can't create query ";
92 char delimiter =
'\0';
109 Oks::error_msg(fname) << error_str <<
"from string which consists of space symbols\n";
118 std::string::size_type p = s.find(
' ');
120 if(p == std::string::npos) {
122 <<
"Can't parse query expression \"" << str <<
"\"\n"
123 "it must consists of as minimum two tokens separated by space\n";
133 <<
"Can't parse query expression \"" << str <<
"\"\n"
141 if(delimiter ==
')') {
142 p = s.rfind(delimiter);
143 if(p == std::string::npos) {
145 <<
"Can't parse query expression \"" << str <<
"\"\n"
146 "it must contain closing bracket \')\' if it has opening bracket \'(\'\n";
160 if(p == std::string::npos) {
162 <<
"Can't parse query expression \"" << s <<
"\"\n"
163 "it must contain closing bracket \')\' if it has opening bracket \'(\'\n";
176 <<
"Can't parse subquery expression \"" << s <<
"\"\n"
177 "it must be enclosed by brackets\n";
184 const char * fname =
"OksQuery::create_expression()";
191 Oks::error_msg(fname) <<
"Can't create query without specified class\n";
196 Oks::error_msg(fname) <<
"Can't create query from empty string\n";
202 std::list<std::string> slist;
207 if(!s.length())
break;
214 char delimiter = s[0];
217 std::string::size_type p = s.find(delimiter);
219 if(p == std::string::npos) {
221 <<
"Can't parse query expression \"" << str <<
"\"\n"
222 "the delimiter is \' "<< delimiter <<
" \'\n"
223 "the rest of the expression is \"" << s <<
"\"\n";
228 slist.push_back(std::string(s, 0, p));
232 else if(s[0] ==
'(') {
233 std::string::size_type p = 1;
234 size_t strLength = s.length();
237 while(p < strLength) {
248 <<
"Can't parse query expression \"" << str <<
"\"\n"
249 <<
"There is no closing \')\' for " <<
'\"' << s <<
"\"\n";
256 slist.push_back(std::string(s, 0, p - 1));
261 std::string::size_type p = 0;
262 size_t strLength = s.length();
264 while(p < strLength && s[p] !=
' ') p++;
266 slist.push_back(std::string(s, 0, p));
274 <<
"Can't create query from empty string \"" << str <<
"\"\n";
278 const std::string first = slist.front();
285 if(slist.size() < 2) {
286 Oks::error_msg(fname) <<
"\'" << first <<
"\' must have two or more arguments: (" << str <<
")'\n";
296 while(!slist.empty()) {
297 const std::string item2 = slist.front();
313 if(slist.size() != 1) {
314 Oks::error_msg(fname) <<
"\'" << first <<
"\' must have exactly one argument: (" << str <<
")\n";
320 const std::string item2 = slist.front();
329 else if(slist.size() != 2) {
330 Oks::error_msg(fname) <<
"Can't parse query expression \"" << str <<
"\"\n";
334 const std::string second = slist.front();
337 const std::string third = slist.front();
345 <<
"For expression \"" << str <<
"\"\n"
346 "can't find relationship \"" << first <<
"\" in class \"" << c->get_name() <<
"\"\n";
357 <<
"For relationship expression \"" << str <<
"\"\n"
358 "second parameter \'" << second <<
"\' must be \'" << *
OksQuery::SOME
363 OksClass *relc = c->get_kernel()->find_class(r->get_type());
367 <<
"For expression \"" << str <<
"\"\n"
368 <<
"can't find class \"" << r->get_type() <<
"\"\n";
383 <<
"For expression \"" << str <<
"\"\n"
384 <<
"can't find attribute \"" << first <<
"\" in class \""
385 << c->get_name() <<
"\"\n";
409 d->SetValues(second.c_str(), a);
418 <<
"For expression \"" << str <<
"\"\n"
419 <<
"can't find comparator function \"" << third <<
"\"\n";
433 const char * fname =
"OksClass::execute_query()";
442 Oks::error_msg(fname) <<
"Can't execute query \"" << *sqe <<
"\"\n";
447 bool indexedSearch =
false;
455 indexedSearch =
true;
468 (qlist->size() == 2) &&
478 indexedSearch =
true;
480 olist = (*j).second->find_all(
492 if(indexedSearch ==
false) {
505 catch(std::exception& ex) {
517 if(c->p_objects && !c->p_objects->empty()) {
518 for(OksObject::Map::iterator i2 = c->p_objects->begin(); i2 != c->p_objects->end(); ++i2) {
530 catch(std::exception& ex) {
545 const char * fname =
"OksQueryExpression::CheckSyntax()";
551 <<
"OksComparator: Can't execute query for nil attribute or nil object-id\n";
556 <<
"OksComparator: Can't execute query for nil compare function\n";
565 <<
"OksRelationshipExpression: Can't execute query for nil relationship\n";
570 <<
"OksRelationshipExpression: Can't execute query for nil query expression\n";
579 <<
"OksNotExpression: Can't execute \'not\' for nil query expression\n";
588 <<
"OksAndExpression: Can't execute \'and\' for "
590 "Two or more arguments are required\n";
594 std::list<OksQueryExpression *> & elist = ((
OksAndExpression *)
this)->p_expressions;
596 for(std::list<OksQueryExpression *>::iterator i = elist.begin(); i != elist.end(); ++i)
597 if((*i)->CheckSyntax() ==
false)
return false;
605 <<
"OksOrExpression: Can't execute \'or\' for "
607 "Two or more arguments are required\n";
612 std::list<OksQueryExpression *> & elist = ((
OksOrExpression *)
this)->p_expressions;
614 for(std::list<OksQueryExpression *>::iterator i = elist.begin(); i != elist.end(); ++i)
615 if((*i)->CheckSyntax() ==
false)
return false;
622 <<
"Unexpected query type " << (int)
p_type << std::endl;
635 throw std::runtime_error(
"cannot execute nil query");
644 if(!a && !cmp->
value) {
645 throw std::runtime_error(
"cannot execute query for nil attribute");
648 throw std::runtime_error(
"cannot execute query for nil compare function");
657 cmp->
m_reg_exp =
new boost::regex(s.c_str());
659 catch(std::exception& ex) {
668 return (*f)(&d, cmp_value);
672 &(
data[(*(
uid.class_id->p_data_info->find(a->
get_name()))).second->offset]),
679 throw std::runtime_error(
"cannot execute query for nil relationship");
685 if(!d->data.LIST || d->data.LIST->empty())
return false;
687 for(OksData::List::iterator i = d->data.LIST->begin(); i != d->data.LIST->end(); ++i) {
691 std::ostringstream text;
692 text <<
"cannot process relationship expression: object \"" << *d2->
data.
UID2.object_id <<
'@' << *d2->
data.
UID2.class_id
694 <<
"\" is not loaded in memory";
695 throw std::runtime_error(text.str().c_str());
716 std::ostringstream text;
717 text <<
"cannot process relationship expression: object \"" << *d <<
"\" referenced through single value relationship \""
719 throw std::runtime_error(text.str().c_str());
732 throw std::runtime_error(
"cannot process \'not\' expression: referenced query expression is nil");
739 std::ostringstream text;
740 text <<
"cannot process \'and\' expression for " << ((
OksAndExpression *)qe)->p_expressions.size()
741 <<
" argument (two or more arguments are required)";
742 throw std::runtime_error(text.str().c_str());
745 std::list<OksQueryExpression *> & elist = ((
OksAndExpression *)qe)->p_expressions;
747 for(std::list<OksQueryExpression *>::iterator i = elist.begin(); i != elist.end();++i)
755 std::ostringstream text;
756 text <<
"cannot process \'or\' expression for " << ((
OksAndExpression *)qe)->p_expressions.size()
757 <<
" argument (two or more arguments are required)";
758 throw std::runtime_error(text.str().c_str());
761 std::list<OksQueryExpression *> & elist = ((
OksOrExpression *)qe)->p_expressions;
763 for(std::list<OksQueryExpression *>::iterator i = elist.begin(); i != elist.end();++i)
770 std::ostringstream text;
771 text <<
"unexpected query type " << (int)(qe->
type());
772 throw std::runtime_error(text.str().c_str());
791 s <<
'\"' << a->
get_name() <<
"\" ";
824 bool b = re->IsCheckAllObjects();
828 s <<
'\"' << r->get_name() <<
"\" ";
847 const std::list<OksQueryExpression *> & elist = ((
OksAndExpression *)&qe)->expressions();
852 for(std::list<OksQueryExpression *>::const_iterator i = elist.begin(); i != elist.end(); ++i) {
854 if(*i != last) s <<
' ';
864 const std::list<OksQueryExpression *> & elist = ((
OksOrExpression *)&qe)->expressions();
869 for(std::list<OksQueryExpression *>::const_iterator i = elist.begin(); i != elist.end(); ++i) {
871 if(*i != last) s <<
' ';
924 s <<
'\"' << *i <<
'\"';
955 for(std::list<OksObject *>::const_iterator i = path.begin(); i != path.end(); ++i) {
956 if(*i ==
this)
return false;
960 path.push_back(
const_cast<OksObject *
>(
this));
963 for(std::list<std::string>::const_iterator i = expression.
get_rel_names().begin(); i != expression.
get_rel_names().end(); ++i) {
966 if(!(*i).empty() && (*i)[0] ==
'?') {
967 std::string nm = (*i).substr(1);
968 OksDataInfo::Map::iterator i =
uid.class_id->p_data_info->find(nm);
970 if(i !=
uid.class_id->p_data_info->end()) {
991 for(OksData::List::iterator i2 = d->data.LIST->begin(); i2 != d->data.LIST->end(); ++i2) {
1013 path.push_back(
const_cast<OksObject *
>(
this));
1018 if(d->data.OBJECT->satisfies(goal, expression, path) ==
true)
return true;
1021 for(OksData::List::iterator i2 = d->data.LIST->begin(); i2 != d->data.LIST->end(); ++i2) {
1032 if(d->data.OBJECT->satisfies(goal, *expression.
get_next(), path) ==
true)
return true;
1035 for(OksData::List::iterator i2 = d->data.LIST->begin(); i2 != d->data.LIST->end(); ++i2) {
1059 std::string::size_type p = s.rfind(
')');
1061 if(p == std::string::npos) {
1062 throw oks::bad_query_syntax(std::string(
"Query expression \'") + str +
"\' must contain closing bracket");
1069 throw oks::bad_query_syntax(std::string(
"Query expression \'") + str +
"\' must be enclosed by brackets");
1074 Oks::Tokenizer t(s,
" \t\n");
1082 s.erase(0, token.size());
1085 if( s[0] ==
'\"' ) {
1086 std::string::size_type p =
s.find(
'\"', 1);
1088 if(p == std::string::npos) {
1089 throw oks::bad_query_syntax(std::string(
"No trailing delimiter of object name in query \'") + str +
"\'");
1092 std::string::size_type p2 =
s.find(
'@');
1094 if(p2 == std::string::npos || p2 > p) {
1095 throw oks::bad_query_syntax(std::string(
"Bad format of object name ") +
s.substr(0, p+1) +
" in query \'" + str +
"\'");
1098 std::string object_id = std::string(s, 1, p2 - 1);
1099 std::string class_name = std::string(s, p2 + 1, p - p2 - 1);
1102 if((p_goal =
c->get_object(object_id)) == 0) {
1103 throw oks::bad_query_syntax(std::string(
"Cannot find object ") +
s.substr(0, p+1) +
" in query \'" + str +
"\': no such object");
1107 throw oks::bad_query_syntax(std::string(
"Cannot find object ") +
s.substr(0, p+1) +
" in query \'" + str +
"\': no such class");
1113 throw oks::bad_query_syntax(std::string(
"No name of object in \'") + str +
"\'");
1117 p_start =
new QueryPathExpression(s);
1119 catch ( oks::bad_query_syntax& e ) {
1120 throw oks::bad_query_syntax(std::string(
"Failed to parse expression \'") + str +
"\' because \'" + e.what() +
"\'");
1130 throw oks::bad_query_syntax(
"Empty expression" );
1134 std::string::size_type p =
s.rfind(
')');
1136 if(p == std::string::npos) {
1137 throw oks::bad_query_syntax(std::string(
"Expression \'") + str +
"\' must contain closing bracket");
1145 std::string::size_type p1 =
s.find(
'(');
1147 if(p1 != std::string::npos) {
1148 std::string::size_type p2 =
s.rfind(
')');
1150 if(p2 == std::string::npos) {
1151 throw oks::bad_query_syntax(std::string(
"Nested expression of \'") + str +
"\' must contain closing bracket");
1154 p_next =
new QueryPathExpression(
s.substr(p1, p2));
1161 Oks::Tokenizer t(s,
" \t\n");
1166 p_use_nested_lookup =
false;
1169 p_use_nested_lookup =
true;
1172 delete p_next; p_next = 0;
1176 s.erase(0, token.size());
1181 if(!
s.length())
break;
1183 if( s[0] ==
'\"' || s[0] ==
'\'' || s[0] ==
'`' ) {
1184 char delimiter =
s[0];
1186 p =
s.find(delimiter, 1);
1188 if(p == std::string::npos) {
1189 delete p_next; p_next = 0;
1190 throw oks::bad_query_syntax(std::string(
"No trailing delimiter of \'") + s +
"\' (expression \'" + str +
"\')");
1193 p_rel_names.push_back(std::string(s, 1, p-1));
1198 delete p_next; p_next = 0;
1199 throw oks::bad_query_syntax(std::string(
"Name of relationship \'") + s +
"\' must start from a delimiter (expression \'" + str +
"\')");
1203 if(p_rel_names.empty()) {
1204 delete p_next; p_next = 0;
1205 throw oks::bad_query_syntax(std::string(
"An expression of \'") + str +
"\' has no relationship names defined");
1209 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
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
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.
OksObject describes instance of OksClass.
struct dunedaq::oks::OksObject::OksUid uid
std::list< OksObject * > List
OksData * GetRelationshipValue(const std::string &) const
Get value of relationship by name.
bool satisfies(const OksObject *goal, const oks::QueryPathExpression &expresssion, OksObject::List &path) const
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
static const char * ALL_SUBCLASSES
static bool equal_cmp(const OksData *, const OksData *)
static bool reg_exp_cmp(const OksData *, const OksData *regexp)
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 *)
static bool not_equal_cmp(const OksData *, const OksData *)
bool(*) Comparator(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.
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)
the structure to pass common parameters to various read() methods of OksData and OksObject class
std::string str(int base=0) const
union dunedaq::oks::OksData::Data data
enum dunedaq::oks::OksData::Type type
struct dunedaq::oks::OksData::Data::@166 UID2