libidav/davqlexec.c

changeset 139
c6424aebcf5e
parent 137
01cb9aabff05
child 143
d8b01bed3d83
--- 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: {

mercurial