366 |
366 |
367 UcxBuffer *where = dav_compile_expr(sn->context, mp->allocator, st->where, ap); |
367 UcxBuffer *where = dav_compile_expr(sn->context, mp->allocator, st->where, ap); |
368 if(st->where && !where) { |
368 if(st->where && !where) { |
369 ucx_mempool_destroy(mp); |
369 ucx_mempool_destroy(mp); |
370 return result; |
370 return result; |
|
371 } |
|
372 |
|
373 // compile order criterion |
|
374 UcxList *ordercr = NULL; |
|
375 UCX_FOREACH(elm, st->orderby) { |
|
376 DavQLOrderCriterion *oc = elm->data; |
|
377 DavQLExpression *column = oc->column; |
|
378 //printf("%.*s %s\n", column->srctext.length, column->srctext.ptr, oc->descending ? "desc" : "asc"); |
|
379 if(column->type == DAVQL_IDENTIFIER) { |
|
380 // TODO: remove code duplication (add_cmd) |
|
381 davqlresprop_t resprop; |
|
382 sstr_t propertyname = sstrchr(column->srctext, ':'); |
|
383 if(propertyname.length > 0) { |
|
384 char *ns; |
|
385 char *name; |
|
386 dav_get_property_namespace_str( |
|
387 sn->context, |
|
388 sstrdup_a(mp->allocator, column->srctext).ptr, |
|
389 &ns, |
|
390 &name); |
|
391 if(ns && name) { |
|
392 DavOrderCriterion *cr = ucx_mempool_malloc(mp, sizeof(DavOrderCriterion)); |
|
393 cr->type = 1; |
|
394 cr->column.property = dav_property_key_a(mp->allocator, ns, name); |
|
395 cr->descending = oc->descending; |
|
396 ordercr = ucx_list_append_a(mp->allocator, ordercr, cr); |
|
397 } else { |
|
398 // error |
|
399 // TODO: cleanup |
|
400 return result; |
|
401 } |
|
402 } else if(dav_identifier2resprop(column->srctext, &resprop)) { |
|
403 DavOrderCriterion *cr = ucx_mempool_malloc(mp, sizeof(DavOrderCriterion)); |
|
404 cr->type = 0; |
|
405 cr->column.resprop = resprop; |
|
406 cr->descending = oc->descending; |
|
407 ordercr = ucx_list_append_a(mp->allocator, ordercr, cr); |
|
408 } else { |
|
409 // error |
|
410 // TODO: cleanup |
|
411 return result; |
|
412 } |
|
413 |
|
414 } else if(column->type == DAVQL_NUMBER) { |
|
415 // TODO: implement |
|
416 fprintf(stderr, "order by number not supported\n"); |
|
417 return result; |
|
418 } else { |
|
419 // something is broken |
|
420 // TODO: cleanup |
|
421 return result; |
|
422 } |
371 } |
423 } |
372 |
424 |
373 DavResource *selroot = dav_resource_new(sn, path.ptr); |
425 DavResource *selroot = dav_resource_new(sn, path.ptr); |
374 |
426 |
375 UcxList *stack = NULL; // stack with DavResource* elements |
427 UcxList *stack = NULL; // stack with DavResource* elements |
451 // check where clause |
503 // check where clause |
452 DavQLStackObj where_result; |
504 DavQLStackObj where_result; |
453 if(!dav_exec_expr(where, child, &where_result)) { |
505 if(!dav_exec_expr(where, child, &where_result)) { |
454 if(where_result.data.integer != 0) { |
506 if(where_result.data.integer != 0) { |
455 if(!reset_properties(sn, &result, child, cfieldlist)) { |
507 if(!reset_properties(sn, &result, child, cfieldlist)) { |
456 resource_add_child(root, child); |
508 //resource_add_child(root, child); |
|
509 resource_add_ordered_child(root, child, ordercr); |
457 if(child->iscollection && |
510 if(child->iscollection && |
458 (depth < 0 || depth > sr->depth+1)) |
511 (depth < 0 || depth > sr->depth+1)) |
459 { |
512 { |
460 DavQLRes *rs = ucx_mempool_malloc( |
513 DavQLRes *rs = ucx_mempool_malloc( |
461 mp, |
514 mp, |
502 } |
555 } |
503 } |
556 } |
504 return count; |
557 return count; |
505 } |
558 } |
506 |
559 |
|
560 int dav_identifier2resprop(sstr_t src, davqlresprop_t *prop) { |
|
561 if(!sstrcmp(src, S("name"))) { |
|
562 *prop = DAVQL_RES_NAME; |
|
563 } else if(!sstrcmp(src, S("path"))) { |
|
564 *prop = DAVQL_RES_PATH; |
|
565 } else if(!sstrcmp(src, S("href"))) { |
|
566 *prop = DAVQL_RES_HREF; |
|
567 } else if(!sstrcmp(src, S("contentlength"))) { |
|
568 *prop = DAVQL_RES_CONTENTLENGTH; |
|
569 } else if(!sstrcmp(src, S("contenttype"))) { |
|
570 *prop = DAVQL_RES_CONTENTTYPE; |
|
571 } else if(!sstrcmp(src, S("creationdate"))) { |
|
572 *prop = DAVQL_RES_CREATIONDATE; |
|
573 } else if(!sstrcmp(src, S("lastmodified"))) { |
|
574 *prop = DAVQL_RES_LASTMODIFIED; |
|
575 } else if(!sstrcmp(src, S("iscollection"))) { |
|
576 *prop = DAVQL_RES_ISCOLLECTION; |
|
577 } else { |
|
578 return 0; |
|
579 } |
|
580 return 1; |
|
581 } |
|
582 |
507 static int add_cmd(DavContext *ctx, UcxAllocator *a, UcxBuffer *bcode, DavQLExpression *expr, va_list ap) { |
583 static int add_cmd(DavContext *ctx, UcxAllocator *a, UcxBuffer *bcode, DavQLExpression *expr, va_list ap) { |
508 if(!expr) { |
584 if(!expr) { |
509 return 0; |
585 return 0; |
510 } |
586 } |
511 |
587 |
563 cmd.data.property.name = name; |
639 cmd.data.property.name = name; |
564 } else { |
640 } else { |
565 // error |
641 // error |
566 return -1; |
642 return -1; |
567 } |
643 } |
568 } else if(!sstrcmp(src, S("name"))) { |
644 } else if(!dav_identifier2resprop(src, &cmd.data.resprop)) { |
569 cmd.data.resprop = DAVQL_RES_NAME; |
645 if(!sstrcmp(src, S("true"))) { |
570 } else if(!sstrcmp(src, S("path"))) { |
646 cmd.type = DAVQL_CMD_INT; |
571 cmd.data.resprop = DAVQL_RES_PATH; |
647 cmd.data.integer = 1; |
572 } else if(!sstrcmp(src, S("href"))) { |
648 } else if(!sstrcmp(src, S("false"))) { |
573 cmd.data.resprop = DAVQL_RES_HREF; |
649 cmd.type = DAVQL_CMD_INT; |
574 } else if(!sstrcmp(src, S("contentlength"))) { |
650 cmd.data.integer = 0; |
575 cmd.data.resprop = DAVQL_RES_CONTENTLENGTH; |
651 } else { |
576 } else if(!sstrcmp(src, S("contenttype"))) { |
652 // error, unknown identifier |
577 cmd.data.resprop = DAVQL_RES_CONTENTTYPE; |
653 return -1; |
578 } else if(!sstrcmp(src, S("creationdate"))) { |
654 } |
579 cmd.data.resprop = DAVQL_RES_CREATIONDATE; |
|
580 } else if(!sstrcmp(src, S("lastmodified"))) { |
|
581 cmd.data.resprop = DAVQL_RES_LASTMODIFIED; |
|
582 } else if(!sstrcmp(src, S("iscollection"))) { |
|
583 cmd.data.resprop = DAVQL_RES_ISCOLLECTION; |
|
584 } else if(!sstrcmp(src, S("true"))) { |
|
585 cmd.type = DAVQL_CMD_INT; |
|
586 cmd.data.integer = 1; |
|
587 } else if(!sstrcmp(src, S("false"))) { |
|
588 cmd.type = DAVQL_CMD_INT; |
|
589 cmd.data.integer = 0; |
|
590 } else { |
|
591 // error, unknown identifier |
|
592 return -1; |
|
593 } |
655 } |
594 ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode); |
656 ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode); |
595 break; |
657 break; |
596 } |
658 } |
597 case DAVQL_UNARY: { |
659 case DAVQL_UNARY: { |
845 obj.data.integer = (int64_t)cmd.data.timestamp; |
907 obj.data.integer = (int64_t)cmd.data.timestamp; |
846 DAVQL_PUSH(obj); |
908 DAVQL_PUSH(obj); |
847 break; |
909 break; |
848 } |
910 } |
849 case DAVQL_CMD_RES_IDENTIFIER: { |
911 case DAVQL_CMD_RES_IDENTIFIER: { |
850 char *rid[8] = {"name", "path", "href", "contentlength", "contenttype", "creationdate", "lastmodified", "iscollection"}; |
912 //char *rid[8] = {"name", "path", "href", "contentlength", "contenttype", "creationdate", "lastmodified", "iscollection"}; |
851 //printf("resprop %s\n", rid[cmd.data.resprop]); |
913 //printf("resprop %s\n", rid[cmd.data.resprop]); |
852 switch(cmd.data.resprop) { |
914 switch(cmd.data.resprop) { |
853 case DAVQL_RES_NAME: { |
915 case DAVQL_RES_NAME: { |
854 obj.type = 1; |
916 obj.type = 1; |
855 obj.length = strlen(res->name); |
917 obj.length = strlen(res->name); |