183{
184 const char * fname = "OksQuery::create_expression()";
185
187
188 OksQueryExpression *qe = 0;
189
190 if(!c) {
191 Oks::error_msg(fname) <<
"Can't create query without specified class\n";
192 return qe;
193 }
194
196 Oks::error_msg(fname) <<
"Can't create query from empty string\n";
197 return qe;
198 }
199
201
202 std::list<std::string> slist;
203
206
207 if(!
s.length())
break;
208
209 if(
210 s[0] == '\"' ||
211 s[0] == '\'' ||
212 s[0] == '`'
213 ) {
214 char delimiter =
s[0];
216
217 std::string::size_type p =
s.find(delimiter);
218
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";
224 return qe;
225 }
226
228 slist.push_back(std::string(s, 0, p));
229
231 }
232 else if(s[0] == '(') {
233 std::string::size_type p = 1;
234 size_t strLength =
s.length();
236
237 while(p < strLength) {
239 if(s[p] == ')') {
241 if(!r) break;
242 }
243 p++;
244 }
245
246 if(r) {
248 <<
"Can't parse query expression \"" <<
str <<
"\"\n"
249 <<
"There is no closing \')\' for " <<
'\"' <<
s <<
"\"\n";
250 return qe;
251 }
252
255
256 slist.push_back(std::string(s, 0, p - 1));
257
259 }
260 else {
261 std::string::size_type p = 0;
262 size_t strLength =
s.length();
263
264 while(p < strLength && s[p] != ' ') p++;
265
266 slist.push_back(std::string(s, 0, p));
267
269 }
270 }
271
272 if(slist.empty()) {
274 <<
"Can't create query from empty string \"" <<
str <<
"\"\n";
275 return qe;
276 }
277
278 const std::string first = slist.front();
279 slist.pop_front();
280
281 if(
284 ) {
285 if(slist.size() < 2) {
286 Oks::error_msg(fname) <<
"\'" << first <<
"\' must have two or more arguments: (" <<
str <<
")'\n";
287 return qe;
288 }
289
290 qe = (
292 ? (OksQueryExpression *)new OksAndExpression()
293 : (OksQueryExpression *)new OksOrExpression()
294 );
295
296 while(!slist.empty()) {
297 const std::string item2 = slist.front();
298 slist.pop_front();
299
301
302 if(qe2) {
304 ((OksAndExpression *)qe)->add(qe2);
305 else
306 ((OksOrExpression *)qe)->add(qe2);
307 }
308 }
309
310 return qe;
311 }
313 if(slist.size() != 1) {
314 Oks::error_msg(fname) <<
"\'" << first <<
"\' must have exactly one argument: (" <<
str <<
")\n";
315 return qe;
316 }
317
318 qe = (OksQueryExpression *)new OksNotExpression();
319
320 const std::string item2 = slist.front();
321 slist.pop_front();
322
324
325 if(qe2) ((OksNotExpression *)qe)->set(qe2);
326
327 return qe;
328 }
329 else if(slist.size() != 2) {
331 return qe;
332 }
333 else {
334 const std::string second = slist.front();
335 slist.pop_front();
336
337 const std::string third = slist.front();
338 slist.pop_front();
339
341 OksRelationship *
r =
c->find_relationship(first);
342
343 if(!r) {
345 <<
"For expression \"" <<
str <<
"\"\n"
346 "can't find relationship \"" << first <<
"\" in class \"" <<
c->get_name() <<
"\"\n";
347
348 return qe;
349 }
350
351 bool b;
352
355 else {
357 <<
"For relationship expression \"" <<
str <<
"\"\n"
358 "second parameter \'" << second <<
"\' must be \'" << *
OksQuery::SOME
360 return qe;
361 }
362
363 OksClass *relc =
c->get_kernel()->find_class(
r->get_type());
364
365 if(!relc) {
367 <<
"For expression \"" <<
str <<
"\"\n"
368 <<
"can't find class \"" <<
r->get_type() <<
"\"\n";
369 return qe;
370 }
371
373
374 if(qe2) qe = (OksQueryExpression *)new OksRelationshipExpression(r, qe2, b);
375
376 return qe;
377 }
378 else {
379 OksAttribute *a = ((first !=
OksQuery::OID) ?
c->find_attribute(first) : 0);
380
383 <<
"For expression \"" <<
str <<
"\"\n"
384 << "can't find attribute \"" << first << "\" in class \""
385 <<
c->get_name() <<
"\"\n";
386 return qe;
387 }
388
389 OksData *
d =
new OksData();
390
399 0
400 );
401
402 if(a) {
405 d->data.STRING =
new OksString(second);
406 }
407 else {
409 d->SetValues(second.c_str(), a);
410 }
411 }
412 else {
414 }
415
416 if(!f)
418 <<
"For expression \"" <<
str <<
"\"\n"
419 << "can't find comparator function \"" << third << "\"\n";
420 else
421 qe = (OksQueryExpression *)new OksComparator(a, d, f);
422
423 return qe;
424 }
425 }
426}
@ 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 *)
bool(*) Comparator(const OksData *, const OksData *)
static bool greater_or_equal_cmp(const OksData *, const OksData *)
static bool less_cmp(const OksData *, const OksData *)