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;
63 return boost::regex_match(d->str(), *
reinterpret_cast<const boost::regex *
>(re));
86 while(s[0] ==
' ' || s[0] ==
'\n' || s[0] ==
'\t') s.erase(0, 1);
94 const char * fname =
"OksQuery::OksQuery(OksClass *, const char *)";
95 const char * error_str =
"Can't create query ";
97 char delimiter =
'\0';
100 Oks::error_msg(fname) << error_str <<
"without specified class\n";
114 Oks::error_msg(fname) << error_str <<
"from string which consists of space symbols\n";
123 std::string::size_type p = s.find(
' ');
125 if(p == std::string::npos) {
127 <<
"Can't parse query expression \"" << str <<
"\"\n"
128 "it must consists of as minimum two tokens separated by space\n";
138 <<
"Can't parse query expression \"" << str <<
"\"\n"
146 if(delimiter ==
')') {
147 p = s.rfind(delimiter);
148 if(p == std::string::npos) {
150 <<
"Can't parse query expression \"" << str <<
"\"\n"
151 "it must contain closing bracket \')\' if it has opening bracket \'(\'\n";
165 if(p == std::string::npos) {
167 <<
"Can't parse query expression \"" << s <<
"\"\n"
168 "it must contain closing bracket \')\' if it has opening bracket \'(\'\n";
181 <<
"Can't parse subquery expression \"" << s <<
"\"\n"
182 "it must be enclosed by brackets\n";
189 const char * fname =
"OksQuery::create_expression()";
196 Oks::error_msg(fname) <<
"Can't create query without specified class\n";
201 Oks::error_msg(fname) <<
"Can't create query from empty string\n";
207 std::list<std::string> slist;
212 if(!s.length())
break;
219 char delimiter = s[0];
222 std::string::size_type p = s.find(delimiter);
224 if(p == std::string::npos) {
226 <<
"Can't parse query expression \"" << str <<
"\"\n"
227 "the delimiter is \' "<< delimiter <<
" \'\n"
228 "the rest of the expression is \"" << s <<
"\"\n";
233 slist.push_back(std::string(s, 0, p));
237 else if(s[0] ==
'(') {
238 std::string::size_type p = 1;
239 size_t strLength = s.length();
242 while(p < strLength) {
253 <<
"Can't parse query expression \"" << str <<
"\"\n"
254 <<
"There is no closing \')\' for " <<
'\"' << s <<
"\"\n";
261 slist.push_back(std::string(s, 0, p - 1));
266 std::string::size_type p = 0;
267 size_t strLength = s.length();
269 while(p < strLength && s[p] !=
' ') p++;
271 slist.push_back(std::string(s, 0, p));
279 <<
"Can't create query from empty string \"" << str <<
"\"\n";
283 const std::string first = slist.front();
290 if(slist.size() < 2) {
291 Oks::error_msg(fname) <<
"\'" << first <<
"\' must have two or more arguments: (" << str <<
")'\n";
301 while(!slist.empty()) {
302 const std::string item2 = slist.front();
318 if(slist.size() != 1) {
319 Oks::error_msg(fname) <<
"\'" << first <<
"\' must have exactly one argument: (" << str <<
")\n";
325 const std::string item2 = slist.front();
334 else if(slist.size() != 2) {
335 Oks::error_msg(fname) <<
"Can't parse query expression \"" << str <<
"\"\n";
339 const std::string second = slist.front();
342 const std::string third = slist.front();
350 <<
"For expression \"" << str <<
"\"\n"
351 "can't find relationship \"" << first <<
"\" in class \"" << c->get_name() <<
"\"\n";
362 <<
"For relationship expression \"" << str <<
"\"\n"
363 "second parameter \'" << second <<
"\' must be \'" << *
OksQuery::SOME
368 OksClass *relc = c->get_kernel()->find_class(r->get_type());
372 <<
"For expression \"" << str <<
"\"\n"
373 <<
"can't find class \"" << r->get_type() <<
"\"\n";
388 <<
"For expression \"" << str <<
"\"\n"
389 <<
"can't find attribute \"" << first <<
"\" in class \""
390 << c->get_name() <<
"\"\n";
414 d->SetValues(second.c_str(), a);
423 <<
"For expression \"" << str <<
"\"\n"
424 <<
"can't find comparator function \"" << third <<
"\"\n";
438 const char * fname =
"OksClass::execute_query()";
447 Oks::error_msg(fname) <<
"Can't execute query \"" << *sqe <<
"\"\n";
452 bool indexedSearch =
false;
460 indexedSearch =
true;
473 (qlist->size() == 2) &&
483 indexedSearch =
true;
485 olist = (*j).second->find_all(
497 if(indexedSearch ==
false) {
510 catch(std::exception& ex) {
522 if(c->p_objects && !c->p_objects->empty()) {
523 for(OksObject::Map::iterator i2 = c->p_objects->begin(); i2 != c->p_objects->end(); ++i2) {
535 catch(std::exception& ex) {
550 const char * fname =
"OksQueryExpression::CheckSyntax()";
556 <<
"OksComparator: Can't execute query for nil attribute or nil object-id\n";
561 <<
"OksComparator: Can't execute query for nil compare function\n";
570 <<
"OksRelationshipExpression: Can't execute query for nil relationship\n";
575 <<
"OksRelationshipExpression: Can't execute query for nil query expression\n";
584 <<
"OksNotExpression: Can't execute \'not\' for nil query expression\n";
593 <<
"OksAndExpression: Can't execute \'and\' for "
595 "Two or more arguments are required\n";
599 std::list<OksQueryExpression *> & elist = ((
OksAndExpression *)
this)->p_expressions;
601 for(std::list<OksQueryExpression *>::iterator i = elist.begin(); i != elist.end(); ++i)
602 if((*i)->CheckSyntax() ==
false)
return false;
610 <<
"OksOrExpression: Can't execute \'or\' for "
612 "Two or more arguments are required\n";
617 std::list<OksQueryExpression *> & elist = ((
OksOrExpression *)
this)->p_expressions;
619 for(std::list<OksQueryExpression *>::iterator i = elist.begin(); i != elist.end(); ++i)
620 if((*i)->CheckSyntax() ==
false)
return false;
627 <<
"Unexpected query type " << (int)
p_type << std::endl;
640 throw std::runtime_error(
"cannot execute nil query");
649 if(!a && !cmp->
value) {
650 throw std::runtime_error(
"cannot execute query for nil attribute");
653 throw std::runtime_error(
"cannot execute query for nil compare function");
662 cmp->
m_reg_exp =
new boost::regex(s.c_str());
664 catch(std::exception& ex) {
673 return (*f)(&d, cmp_value);
677 &(
data[(*(
uid.class_id->p_data_info->find(a->
get_name()))).second->offset]),
684 throw std::runtime_error(
"cannot execute query for nil relationship");
690 if(!d->data.LIST || d->data.LIST->empty())
return false;
692 for(OksData::List::iterator i = d->data.LIST->begin(); i != d->data.LIST->end(); ++i) {
696 std::ostringstream text;
699 <<
"\" is not loaded in memory";
700 throw std::runtime_error(text.str().c_str());
721 std::ostringstream text;
722 text <<
"cannot process relationship expression: object \"" << *d <<
"\" referenced through single value relationship \""
724 throw std::runtime_error(text.str().c_str());
737 throw std::runtime_error(
"cannot process \'not\' expression: referenced query expression is nil");
744 std::ostringstream text;
745 text <<
"cannot process \'and\' expression for " << ((
OksAndExpression *)qe)->p_expressions.size()
746 <<
" argument (two or more arguments are required)";
747 throw std::runtime_error(text.str().c_str());
750 std::list<OksQueryExpression *> & elist = ((
OksAndExpression *)qe)->p_expressions;
752 for(std::list<OksQueryExpression *>::iterator i = elist.begin(); i != elist.end();++i)
760 std::ostringstream text;
761 text <<
"cannot process \'or\' expression for " << ((
OksAndExpression *)qe)->p_expressions.size()
762 <<
" argument (two or more arguments are required)";
763 throw std::runtime_error(text.str().c_str());
766 std::list<OksQueryExpression *> & elist = ((
OksOrExpression *)qe)->p_expressions;
768 for(std::list<OksQueryExpression *>::iterator i = elist.begin(); i != elist.end();++i)
775 std::ostringstream text;
776 text <<
"unexpected query type " << (int)(qe->
type());
777 throw std::runtime_error(text.str().c_str());
796 s <<
'\"' << a->
get_name() <<
"\" ";
833 s <<
'\"' << r->get_name() <<
"\" ";
852 const std::list<OksQueryExpression *> & elist = ((
OksAndExpression *)&qe)->expressions();
857 for(std::list<OksQueryExpression *>::const_iterator i = elist.begin(); i != elist.end(); ++i) {
859 if(*i != last) s <<
' ';
869 const std::list<OksQueryExpression *> & elist = ((
OksOrExpression *)&qe)->expressions();
874 for(std::list<OksQueryExpression *>::const_iterator i = elist.begin(); i != elist.end(); ++i) {
876 if(*i != last) s <<
' ';
929 s <<
'\"' << *i <<
'\"';
960 for(std::list<OksObject *>::const_iterator i = path.begin(); i != path.end(); ++i) {
961 if(*i ==
this)
return false;
965 path.push_back(
const_cast<OksObject *
>(
this));
968 for(std::list<std::string>::const_iterator i = expression.
get_rel_names().begin(); i != expression.
get_rel_names().end(); ++i) {
971 if(!(*i).empty() && (*i)[0] ==
'?') {
972 std::string nm = (*i).substr(1);
973 OksDataInfo::Map::iterator i =
uid.class_id->p_data_info->find(nm);
975 if(i !=
uid.class_id->p_data_info->end()) {
996 for(OksData::List::iterator i2 = d->data.LIST->begin(); i2 != d->data.LIST->end(); ++i2) {
1018 path.push_back(
const_cast<OksObject *
>(
this));
1023 if(d->data.OBJECT->satisfies(goal, expression, path) ==
true)
return true;
1026 for(OksData::List::iterator i2 = d->data.LIST->begin(); i2 != d->data.LIST->end(); ++i2) {
1037 if(d->data.OBJECT->satisfies(goal, *expression.
get_next(), path) ==
true)
return true;
1040 for(OksData::List::iterator i2 = d->data.LIST->begin(); i2 != d->data.LIST->end(); ++i2) {
1064 std::string::size_type p = s.rfind(
')');
1066 if(p == std::string::npos) {
1067 throw oks::bad_query_syntax(std::string(
"Query expression \'") + str +
"\' must contain closing bracket");
1074 throw oks::bad_query_syntax(std::string(
"Query expression \'") + str +
"\' must be enclosed by brackets");
1079 Oks::Tokenizer t(s,
" \t\n");
1087 s.erase(0, token.size());
1090 if( s[0] ==
'\"' ) {
1091 std::string::size_type p =
s.find(
'\"', 1);
1093 if(p == std::string::npos) {
1094 throw oks::bad_query_syntax(std::string(
"No trailing delimiter of object name in query \'") + str +
"\'");
1097 std::string::size_type p2 =
s.find(
'@');
1099 if(p2 == std::string::npos || p2 > p) {
1100 throw oks::bad_query_syntax(std::string(
"Bad format of object name ") +
s.substr(0, p+1) +
" in query \'" + str +
"\'");
1103 std::string object_id = std::string(s, 1, p2 - 1);
1104 std::string class_name = std::string(s, p2 + 1, p - p2 - 1);
1107 if((p_goal =
c->get_object(object_id)) == 0) {
1108 throw oks::bad_query_syntax(std::string(
"Cannot find object ") +
s.substr(0, p+1) +
" in query \'" + str +
"\': no such object");
1112 throw oks::bad_query_syntax(std::string(
"Cannot find object ") +
s.substr(0, p+1) +
" in query \'" + str +
"\': no such class");
1118 throw oks::bad_query_syntax(std::string(
"No name of object in \'") + str +
"\'");
1122 p_start =
new QueryPathExpression(s);
1124 catch ( oks::bad_query_syntax& e ) {
1125 throw oks::bad_query_syntax(std::string(
"Failed to parse expression \'") + str +
"\' because \'" + e.what() +
"\'");
1135 throw oks::bad_query_syntax(
"Empty expression" );
1139 std::string::size_type p =
s.rfind(
')');
1141 if(p == std::string::npos) {
1142 throw oks::bad_query_syntax(std::string(
"Expression \'") + str +
"\' must contain closing bracket");
1150 std::string::size_type p1 =
s.find(
'(');
1152 if(p1 != std::string::npos) {
1153 std::string::size_type p2 =
s.rfind(
')');
1155 if(p2 == std::string::npos) {
1156 throw oks::bad_query_syntax(std::string(
"Nested expression of \'") + str +
"\' must contain closing bracket");
1159 p_next =
new QueryPathExpression(
s.substr(p1, p2));
1166 Oks::Tokenizer t(s,
" \t\n");
1171 p_use_nested_lookup =
false;
1174 p_use_nested_lookup =
true;
1177 delete p_next; p_next = 0;
1181 s.erase(0, token.size());
1186 if(!
s.length())
break;
1188 if( s[0] ==
'\"' || s[0] ==
'\'' || s[0] ==
'`' ) {
1189 char delimiter =
s[0];
1191 p =
s.find(delimiter, 1);
1193 if(p == std::string::npos) {
1194 delete p_next; p_next = 0;
1195 throw oks::bad_query_syntax(std::string(
"No trailing delimiter of \'") + s +
"\' (expression \'" + str +
"\')");
1198 p_rel_names.push_back(std::string(s, 1, p-1));
1203 delete p_next; p_next = 0;
1204 throw oks::bad_query_syntax(std::string(
"Name of relationship \'") + s +
"\' must start from a delimiter (expression \'" + str +
"\')");
1208 if(p_rel_names.empty()) {
1209 delete p_next; p_next = 0;
1210 throw oks::bad_query_syntax(std::string(
"An expression of \'") + str +
"\' has no relationship names defined");
1214 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
const std::string & get_name() const noexcept
OksClass(const std::string &name, OksKernel *kernel, bool transient=false)
Create OKS class.
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.
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
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)
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 *)
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 &)
bool(* Comparator)(const OksData *, const OksData *)
OksQueryExpression * get() const
OKS query relationship expression class.
OksQueryExpression * get() const
bool IsCheckAllObjects() const
const OksRelationship * GetRelationship() const
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
const OksClass * class_id
struct dunedaq::oks::OksData::Data::@226266061051241020017305361066131172152317024337 UID2