188{
189 const char * fname = "OksQuery::create_expression()";
190
192
193 OksQueryExpression *qe = 0;
194
195 if(!c) {
196 Oks::error_msg(fname) <<
"Can't create query without specified class\n";
197 return qe;
198 }
199
201 Oks::error_msg(fname) <<
"Can't create query from empty string\n";
202 return qe;
203 }
204
206
207 std::list<std::string> slist;
208
211
212 if(!
s.length())
break;
213
214 if(
215 s[0] == '\"' ||
216 s[0] == '\'' ||
217 s[0] == '`'
218 ) {
219 char delimiter =
s[0];
221
222 std::string::size_type p =
s.find(delimiter);
223
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";
229 return qe;
230 }
231
233 slist.push_back(std::string(s, 0, p));
234
236 }
237 else if(s[0] == '(') {
238 std::string::size_type p = 1;
239 size_t strLength =
s.length();
241
242 while(p < strLength) {
244 if(s[p] == ')') {
246 if(!r) break;
247 }
248 p++;
249 }
250
251 if(r) {
253 <<
"Can't parse query expression \"" <<
str <<
"\"\n"
254 <<
"There is no closing \')\' for " <<
'\"' <<
s <<
"\"\n";
255 return qe;
256 }
257
260
261 slist.push_back(std::string(s, 0, p - 1));
262
264 }
265 else {
266 std::string::size_type p = 0;
267 size_t strLength =
s.length();
268
269 while(p < strLength && s[p] != ' ') p++;
270
271 slist.push_back(std::string(s, 0, p));
272
274 }
275 }
276
277 if(slist.empty()) {
279 <<
"Can't create query from empty string \"" <<
str <<
"\"\n";
280 return qe;
281 }
282
283 const std::string first = slist.front();
284 slist.pop_front();
285
286 if(
289 ) {
290 if(slist.size() < 2) {
291 Oks::error_msg(fname) <<
"\'" << first <<
"\' must have two or more arguments: (" <<
str <<
")'\n";
292 return qe;
293 }
294
295 qe = (
297 ? (OksQueryExpression *)new OksAndExpression()
298 : (OksQueryExpression *)new OksOrExpression()
299 );
300
301 while(!slist.empty()) {
302 const std::string item2 = slist.front();
303 slist.pop_front();
304
306
307 if(qe2) {
309 ((OksAndExpression *)qe)->add(qe2);
310 else
311 ((OksOrExpression *)qe)->add(qe2);
312 }
313 }
314
315 return qe;
316 }
318 if(slist.size() != 1) {
319 Oks::error_msg(fname) <<
"\'" << first <<
"\' must have exactly one argument: (" <<
str <<
")\n";
320 return qe;
321 }
322
323 qe = (OksQueryExpression *)new OksNotExpression();
324
325 const std::string item2 = slist.front();
326 slist.pop_front();
327
329
330 if(qe2) ((OksNotExpression *)qe)->set(qe2);
331
332 return qe;
333 }
334 else if(slist.size() != 2) {
336 return qe;
337 }
338 else {
339 const std::string second = slist.front();
340 slist.pop_front();
341
342 const std::string third = slist.front();
343 slist.pop_front();
344
346 OksRelationship *
r =
c->find_relationship(first);
347
348 if(!r) {
350 <<
"For expression \"" <<
str <<
"\"\n"
351 "can't find relationship \"" << first <<
"\" in class \"" <<
c->get_name() <<
"\"\n";
352
353 return qe;
354 }
355
356 bool b;
357
360 else {
362 <<
"For relationship expression \"" <<
str <<
"\"\n"
363 "second parameter \'" << second <<
"\' must be \'" << *
OksQuery::SOME
365 return qe;
366 }
367
368 OksClass *relc =
c->get_kernel()->find_class(
r->get_type());
369
370 if(!relc) {
372 <<
"For expression \"" <<
str <<
"\"\n"
373 <<
"can't find class \"" <<
r->get_type() <<
"\"\n";
374 return qe;
375 }
376
378
379 if(qe2) qe = (OksQueryExpression *)new OksRelationshipExpression(r, qe2, b);
380
381 return qe;
382 }
383 else {
384 OksAttribute *a = ((first !=
OksQuery::OID) ?
c->find_attribute(first) : 0);
385
388 <<
"For expression \"" <<
str <<
"\"\n"
389 << "can't find attribute \"" << first << "\" in class \""
390 <<
c->get_name() <<
"\"\n";
391 return qe;
392 }
393
394 OksData *
d =
new OksData();
395
404 0
405 );
406
407 if(a) {
410 d->data.STRING =
new OksString(second);
411 }
412 else {
414 d->SetValues(second.c_str(), a);
415 }
416 }
417 else {
419 }
420
421 if(!f)
423 <<
"For expression \"" <<
str <<
"\"\n"
424 << "can't find comparator function \"" << third << "\"\n";
425 else
426 qe = (OksQueryExpression *)new OksComparator(a, d, f);
427
428 return qe;
429 }
430 }
431}
@ fStringToQueryExpression
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 *)
static bool less_or_equal_cmp(const OksData *, const OksData *)
static bool not_equal_cmp(const OksData *, const OksData *)
static bool greater_or_equal_cmp(const OksData *, const OksData *)
static bool less_cmp(const OksData *, const OksData *)
bool(* Comparator)(const OksData *, const OksData *)