libidav/davqlparser.c

changeset 95
8ed7d8df6427
parent 94
8822f7c08843
child 96
896022673e0e
equal deleted inserted replaced
94:8822f7c08843 95:8ed7d8df6427
125 } 125 }
126 if (stmt->errorcode) { 126 if (stmt->errorcode) {
127 printf("\nError code: %d\nError: %s\n", 127 printf("\nError code: %d\nError: %s\n",
128 stmt->errorcode, stmt->errormessage); 128 stmt->errorcode, stmt->errormessage);
129 } 129 }
130
131 // order by clause
132 printf("Order by: ");
133 if (stmt->orderby) {
134 UCX_FOREACH(crit, stmt->orderby) {
135 DavQLOrderCriterion *critdata = crit->data;
136 printf("%.*s %s%s", sfmtarg(critdata->column->srctext),
137 critdata->ascending ? "asc" : "desc",
138 crit->next ? ", " : "\n");
139 }
140 } else {
141 printf("nothing\n");
142 }
130 } 143 }
131 144
132 static int dav_debug_ql_expr_selected(DavQLExpression *expr) { 145 static int dav_debug_ql_expr_selected(DavQLExpression *expr) {
133 if (!expr) { 146 if (!expr) {
134 printf("Currently no expression selected.\n"); 147 printf("Currently no expression selected.\n");
410 sfmtarg(*token_sstr(token)), 423 sfmtarg(*token_sstr(token)),
411 sfmtarg(token->next?*token_sstr(token->next):emptystring)); 424 sfmtarg(token->next?*token_sstr(token->next):emptystring));
412 stmt->errormessage = errormsg.ptr; 425 stmt->errormessage = errormsg.ptr;
413 } 426 }
414 427
428
429 #define _step_fieldlist_ 10 // field list
430 #define _step_FROM_ 20 // FROM clause
431 #define _step_expect_WWO_ 530 // expecting WITH, WHERE or ORDER BY clause
432 #define _step_WITH_ 30 // WITH clause
433 #define _step_expect_WO 540 // expecting WHERE or ORDER BY clause
434 #define _step_WHERE_ 40 // WHERE clause
435 #define _step_expect_O 550 // expecting ORDER BY clause
436 #define _step_expect_BY 551 // expecting the BY token for the ORDER BY clause
437 #define _step_ORDER_BY_ 50 // ORDER BY clause
438 #define _step_end_ 500 // expect end
439
415 static int dav_parse_with_clause(DavQLStatement *stmt, UcxList *token) { 440 static int dav_parse_with_clause(DavQLStatement *stmt, UcxList *token) {
416 sstr_t tokendata = *token_sstr(token); 441 sstr_t tokendata = *token_sstr(token);
442
417 /* 443 /*
418 * 0: key 444 * 0: key
419 * 1: = 445 * 1: =
420 * 2: value 446 * 2: value
421 * TODO: commas 447 * 3: comma or new clause
422 */ 448 */
423 static int parsestate = 0; 449 static int parsestate = 0;
424 450
425 /* 451 /*
426 * 1: depth 452 * 1: depth
444 stmt->errormessage = ucx_sprintf(_duplicated_attribute, 470 stmt->errormessage = ucx_sprintf(_duplicated_attribute,
445 sfmtarg(tokendata)).ptr; 471 sfmtarg(tokendata)).ptr;
446 } else { 472 } else {
447 keymask |= key; 473 keymask |= key;
448 } 474 }
449 return 0; 475 return _step_WITH_; // continue parsing WITH clause
450 case 1: 476 case 1:
451 if (sstrcmp(tokendata, S("="))) { 477 if (sstrcmp(tokendata, S("="))) {
452 stmt->errorcode = DAVQL_ERROR_UNEXPECTED_TOKEN; 478 stmt->errorcode = DAVQL_ERROR_UNEXPECTED_TOKEN;
453 stmt->errormessage = ucx_sprintf(_expected_token, 479 stmt->errormessage = ucx_sprintf(_expected_token,
454 "=", sfmtarg(tokendata)).ptr; 480 "=", sfmtarg(tokendata)).ptr;
455 } else { 481 } else {
456 parsestate = 2; 482 parsestate = 2;
457 } 483 }
458 return 0; 484 return _step_WITH_; // continue parsing WITH clause
459 case 2: 485 case 2:
460 switch (key) { 486 switch (key) {
461 case 1: /* depth */ 487 case 1: /* depth */
462 if (!sstrcasecmp(tokendata, S("infinity"))) { 488 if (!sstrcasecmp(tokendata, S("infinity"))) {
463 stmt->depth = DAV_DEPTH_INFINITY; 489 stmt->depth = DAV_DEPTH_INFINITY;
473 } 499 }
474 free(conv); 500 free(conv);
475 } 501 }
476 break; 502 break;
477 } 503 }
478 parsestate = 0; 504 parsestate = 3;
479 return 1; 505 return _step_WITH_; // continue parsing WITH clause
506 case 3:
507 // a with clause may be continued with a comma
508 // or another clause may follow
509 if (!sstrcmp(tokendata, S(","))) {
510 parsestate = 0; // reset clause parser
511 return _step_WITH_;
512 } else if (!sstrcasecmp(tokendata, S("where"))) {
513 return _step_WHERE_;
514 } else if (!sstrcasecmp(tokendata, S("order"))) {
515 return _step_expect_BY;
516 } else {
517 dav_parse_unexpected_token(stmt, token);
518 return 0;
519 }
480 default: 520 default:
481 return -1; 521 stmt->errorcode = DAVQL_ERROR_INVALID;
482 } 522 stmt->errormessage = strdup(_parser_state);
523 return 0;
524 }
525 }
526
527 static int dav_parse_orderby_clause(DavQLStatement *stmt, UcxList *token) {
528 // TODO: implement
529
530 return _step_end_;
531 }
532
533 static void dav_free_order_criterion(DavQLOrderCriterion *crit) {
534 if (crit->column) { // do it null-safe though column is expected to be set
535 dav_free_expression(crit->column);
536 }
537 free(crit);
483 } 538 }
484 539
485 static void dav_parse_get_statement(DavQLStatement *stmt, UcxList *tokens) { 540 static void dav_parse_get_statement(DavQLStatement *stmt, UcxList *tokens) {
486 stmt->type = DAVQL_GET; 541 stmt->type = DAVQL_GET;
487
488 #define _step_fieldlist_ 10 // field list
489 #define _step_FROM_ 20 // FROM clause
490 #define _step_expect_WWO_ 530 // expecting WITH, WHERE or ORDER BY clause
491 #define _step_comma_WITH_ 531 // expecting comma for WITH clause
492 #define _step_WITH_ 30 // WITH clause
493 #define _step_expect_WO 540 // expecting WHERE or ORDER BY clause
494 #define _step_WHERE_ 40 // WHERE clause
495 #define _step_expect_O 550 // expecting ORDER BY clause
496 #define _step_expect_BY 551 // expecting the BY token for the ORDER BY clause
497 #define _step_ORDER_BY_ 50 // ORDER BY clause
498 #define _step_end_ 500 // expect end
499 542
500 int step = _step_fieldlist_; 543 int step = _step_fieldlist_;
501 544
502 // Variables for token sublists for expressions 545 // Variables for token sublists for expressions
503 UcxList *exprstart = NULL; 546 UcxList *exprstart = NULL;
538 step = _step_ORDER_BY_; 581 step = _step_ORDER_BY_;
539 } else { 582 } else {
540 stmt->errorcode = DAVQL_ERROR_UNEXPECTED_TOKEN; 583 stmt->errorcode = DAVQL_ERROR_UNEXPECTED_TOKEN;
541 stmt->errormessage = ucx_sprintf(_expected_by, 584 stmt->errormessage = ucx_sprintf(_expected_by,
542 sfmtarg(tokendata)).ptr; 585 sfmtarg(tokendata)).ptr;
543 }
544 break;
545 case _step_comma_WITH_:
546 // a with clause may be continued with a comma
547 // or another clause may follow
548 if (!sstrcmp(tokendata, S(","))) {
549 step = _step_WITH_;
550 } if (!sstrcasecmp(tokendata, S("where"))) {
551 step = _step_WHERE_;
552 } else if (!sstrcasecmp(tokendata, S("order"))) {
553 step = _step_expect_BY;
554 } else {
555 dav_parse_unexpected_token(stmt, token);
556 } 586 }
557 break; 587 break;
558 // field list 588 // field list
559 case _step_fieldlist_: { 589 case _step_fieldlist_: {
560 _Bool fromkeyword = !sstrcasecmp(tokendata, S("from")); 590 _Bool fromkeyword = !sstrcasecmp(tokendata, S("from"));
596 step = _step_expect_WWO_; 626 step = _step_expect_WWO_;
597 break; 627 break;
598 } 628 }
599 // with clause 629 // with clause
600 case _step_WITH_: { 630 case _step_WITH_: {
601 int withclause_result = dav_parse_with_clause(stmt, token); 631 step = dav_parse_with_clause(stmt, token);
602 if (withclause_result < 0) {
603 stmt->errorcode = DAVQL_ERROR_INVALID;
604 stmt->errormessage = strdup(_parser_state);
605 } else if (withclause_result > 0) {
606 step = _step_comma_WITH_;
607 }
608 break; 632 break;
609 } 633 }
610 // where clause 634 // where clause
611 case _step_WHERE_: 635 case _step_WHERE_:
612 // TODO: implement 636 // TODO: implement
613 step = _step_end_; 637 step = _step_end_;
614 break; 638 break;
615 // order by clause 639 // order by clause
616 case _step_ORDER_BY_: 640 case _step_ORDER_BY_:
617 // TODO: implement 641 step = dav_parse_orderby_clause(stmt, token);
618 step = _step_end_;
619 break; 642 break;
620 default: 643 default:
621 stmt->errorcode = DAVQL_ERROR_INVALID; 644 stmt->errorcode = DAVQL_ERROR_INVALID;
622 stmt->errormessage = strdup(_parser_state); 645 stmt->errormessage = strdup(_parser_state);
623 } 646 }
700 dav_free_expression(stmt->where); 723 dav_free_expression(stmt->where);
701 } 724 }
702 if (stmt->errormessage) { 725 if (stmt->errormessage) {
703 free(stmt->errormessage); 726 free(stmt->errormessage);
704 } 727 }
728 UCX_FOREACH(crit, stmt->orderby) {
729 dav_free_order_criterion(crit->data);
730 }
731 ucx_list_free(stmt->orderby);
705 free(stmt); 732 free(stmt);
706 } 733 }

mercurial