diff -r 6a3248e22d58 -r c6424aebcf5e libidav/davqlexec.c --- a/libidav/davqlexec.c Thu Jul 09 17:22:55 2015 +0200 +++ b/libidav/davqlexec.c Fri Oct 02 13:18:17 2015 +0200 @@ -370,6 +370,58 @@ return result; } + // compile order criterion + UcxList *ordercr = NULL; + UCX_FOREACH(elm, st->orderby) { + DavQLOrderCriterion *oc = elm->data; + DavQLExpression *column = oc->column; + //printf("%.*s %s\n", column->srctext.length, column->srctext.ptr, oc->descending ? "desc" : "asc"); + if(column->type == DAVQL_IDENTIFIER) { + // TODO: remove code duplication (add_cmd) + davqlresprop_t resprop; + sstr_t propertyname = sstrchr(column->srctext, ':'); + if(propertyname.length > 0) { + char *ns; + char *name; + dav_get_property_namespace_str( + sn->context, + sstrdup_a(mp->allocator, column->srctext).ptr, + &ns, + &name); + if(ns && name) { + DavOrderCriterion *cr = ucx_mempool_malloc(mp, sizeof(DavOrderCriterion)); + cr->type = 1; + cr->column.property = dav_property_key_a(mp->allocator, ns, name); + cr->descending = oc->descending; + ordercr = ucx_list_append_a(mp->allocator, ordercr, cr); + } else { + // error + // TODO: cleanup + return result; + } + } else if(dav_identifier2resprop(column->srctext, &resprop)) { + DavOrderCriterion *cr = ucx_mempool_malloc(mp, sizeof(DavOrderCriterion)); + cr->type = 0; + cr->column.resprop = resprop; + cr->descending = oc->descending; + ordercr = ucx_list_append_a(mp->allocator, ordercr, cr); + } else { + // error + // TODO: cleanup + return result; + } + + } else if(column->type == DAVQL_NUMBER) { + // TODO: implement + fprintf(stderr, "order by number not supported\n"); + return result; + } else { + // something is broken + // TODO: cleanup + return result; + } + } + DavResource *selroot = dav_resource_new(sn, path.ptr); UcxList *stack = NULL; // stack with DavResource* elements @@ -453,7 +505,8 @@ if(!dav_exec_expr(where, child, &where_result)) { if(where_result.data.integer != 0) { if(!reset_properties(sn, &result, child, cfieldlist)) { - resource_add_child(root, child); + //resource_add_child(root, child); + resource_add_ordered_child(root, child, ordercr); if(child->iscollection && (depth < 0 || depth > sr->depth+1)) { @@ -504,6 +557,29 @@ return count; } +int dav_identifier2resprop(sstr_t src, davqlresprop_t *prop) { + if(!sstrcmp(src, S("name"))) { + *prop = DAVQL_RES_NAME; + } else if(!sstrcmp(src, S("path"))) { + *prop = DAVQL_RES_PATH; + } else if(!sstrcmp(src, S("href"))) { + *prop = DAVQL_RES_HREF; + } else if(!sstrcmp(src, S("contentlength"))) { + *prop = DAVQL_RES_CONTENTLENGTH; + } else if(!sstrcmp(src, S("contenttype"))) { + *prop = DAVQL_RES_CONTENTTYPE; + } else if(!sstrcmp(src, S("creationdate"))) { + *prop = DAVQL_RES_CREATIONDATE; + } else if(!sstrcmp(src, S("lastmodified"))) { + *prop = DAVQL_RES_LASTMODIFIED; + } else if(!sstrcmp(src, S("iscollection"))) { + *prop = DAVQL_RES_ISCOLLECTION; + } else { + return 0; + } + return 1; +} + static int add_cmd(DavContext *ctx, UcxAllocator *a, UcxBuffer *bcode, DavQLExpression *expr, va_list ap) { if(!expr) { return 0; @@ -565,31 +641,17 @@ // error return -1; } - } else if(!sstrcmp(src, S("name"))) { - cmd.data.resprop = DAVQL_RES_NAME; - } else if(!sstrcmp(src, S("path"))) { - cmd.data.resprop = DAVQL_RES_PATH; - } else if(!sstrcmp(src, S("href"))) { - cmd.data.resprop = DAVQL_RES_HREF; - } else if(!sstrcmp(src, S("contentlength"))) { - cmd.data.resprop = DAVQL_RES_CONTENTLENGTH; - } else if(!sstrcmp(src, S("contenttype"))) { - cmd.data.resprop = DAVQL_RES_CONTENTTYPE; - } else if(!sstrcmp(src, S("creationdate"))) { - cmd.data.resprop = DAVQL_RES_CREATIONDATE; - } else if(!sstrcmp(src, S("lastmodified"))) { - cmd.data.resprop = DAVQL_RES_LASTMODIFIED; - } else if(!sstrcmp(src, S("iscollection"))) { - cmd.data.resprop = DAVQL_RES_ISCOLLECTION; - } else if(!sstrcmp(src, S("true"))) { - cmd.type = DAVQL_CMD_INT; - cmd.data.integer = 1; - } else if(!sstrcmp(src, S("false"))) { - cmd.type = DAVQL_CMD_INT; - cmd.data.integer = 0; - } else { - // error, unknown identifier - return -1; + } else if(!dav_identifier2resprop(src, &cmd.data.resprop)) { + if(!sstrcmp(src, S("true"))) { + cmd.type = DAVQL_CMD_INT; + cmd.data.integer = 1; + } else if(!sstrcmp(src, S("false"))) { + cmd.type = DAVQL_CMD_INT; + cmd.data.integer = 0; + } else { + // error, unknown identifier + return -1; + } } ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode); break; @@ -847,7 +909,7 @@ break; } case DAVQL_CMD_RES_IDENTIFIER: { - char *rid[8] = {"name", "path", "href", "contentlength", "contenttype", "creationdate", "lastmodified", "iscollection"}; + //char *rid[8] = {"name", "path", "href", "contentlength", "contenttype", "creationdate", "lastmodified", "iscollection"}; //printf("resprop %s\n", rid[cmd.data.resprop]); switch(cmd.data.resprop) { case DAVQL_RES_NAME: {