replaced old davql (still buggy)

Wed, 08 Jul 2015 17:31:26 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Wed, 08 Jul 2015 17:31:26 +0200
changeset 135
664aeaec8d25
parent 134
4bccc18820e8
child 136
59058927b885

replaced old davql (still buggy)

dav/main.c file | annotate | diff | comparison | revisions
dav/sync.c file | annotate | diff | comparison | revisions
libidav/Makefile file | annotate | diff | comparison | revisions
libidav/davql.c file | annotate | diff | comparison | revisions
libidav/davql.h file | annotate | diff | comparison | revisions
libidav/davqlexec.c file | annotate | diff | comparison | revisions
libidav/davqlexec.h file | annotate | diff | comparison | revisions
libidav/methods.c file | annotate | diff | comparison | revisions
libidav/methods.h file | annotate | diff | comparison | revisions
libidav/resource.c file | annotate | diff | comparison | revisions
libidav/session.c file | annotate | diff | comparison | revisions
libidav/webdav.c file | annotate | diff | comparison | revisions
libidav/webdav.h file | annotate | diff | comparison | revisions
--- a/dav/main.c	Tue Jul 07 20:47:02 2015 +0200
+++ b/dav/main.c	Wed Jul 08 17:31:26 2015 +0200
@@ -50,18 +50,11 @@
     // nothing
 }
 
-#define DO_THE_TEST
+//define DO_THE_TEST
 #include <libidav/davqlparser.h>
 #include <libidav/davqlexec.h>
 void test() {
-    DavQLStatement *stmt = dav_parse_statement(S(
-        "get * from / where lastmodified > 12"));
     
-    DavSession *sn = dav_session_new(ctx, "http://test/");
-    dav_statement_exec(sn, stmt, 123, "txt");
-    
-    //dav_debug_statement(stmt);
-    dav_free_statement(stmt);
 }
 
 int main(int argc, char **argv) {
@@ -371,7 +364,7 @@
     }
     
     char *update = cmd_getoption(a, "update");
-    time_t t = -1;
+    time_t t = 1;
     if(update) {
         t = util_parse_lastmodified(update);
     }
@@ -380,12 +373,15 @@
     int ret = -1;
     DavResource *ls;
     while(ret != 0) {
+        /*
         ls = dav_query(
                 sn,
-                "get idav:crypto-name,idav:crypto-key from %s where lastmodified > %t with depth %d",
+                "select `idav:crypto-name`,`idav:crypto-key` from %s with depth = %d where lastmodified > %t",
                 path,
-                t,
-                depth);
+                depth,
+                t);
+        */
+        ls = dav_query(sn, "select * from %s", path);
         
         if(!ls) {
             if(sn->error == DAV_UNAUTHORIZED) {
@@ -405,6 +401,7 @@
         } else {
             print_func = ls_print_elm;
         }
+        
         DavResource *child = ls->children;
         while(child) {
             if(child->name[0] != '.' || show_all) {
@@ -594,7 +591,7 @@
     }
     
     char *update = cmd_getoption(a, "update");
-    time_t t = 0;
+    time_t t = -1;
     if(update) {
         t = util_parse_lastmodified(update);
     }
@@ -605,7 +602,7 @@
     int depth = recursive ? -1 : 1;
     res = dav_query(
             sn,
-            "get - from %s where lastmodified > %t with depth %d",
+            "select - from %s with = depth %d where lastmodified > %t",
             path,
             t,
             depth);
@@ -797,7 +794,7 @@
 }
 
 int put_file(Repository *repo, CmdArgs *a, DavSession *sn, char *path, char *name, FILE *in) {
-    DavResource *res = dav_query(sn, "get - from %s", path);
+    DavResource *res = dav_query(sn, "select - from %s", path);
     if(!res) {
         if(sn->error == DAV_NOT_FOUND) {
             res = dav_resource_new(sn, path);
--- a/dav/sync.c	Tue Jul 07 20:47:02 2015 +0200
+++ b/dav/sync.c	Wed Jul 08 17:31:26 2015 +0200
@@ -182,7 +182,7 @@
         curl_easy_setopt(sn->handle, CURLOPT_STDERR, stderr);
     }
     
-    DavResource *ls = dav_query(sn, "get D:getetag from / where lastmodified > 0 with depth -1");
+    DavResource *ls = dav_query(sn, "select D:getetag from / depth -1 where lastmodified > 0 with");
     if(!ls) {
         fprintf(stderr, "Error\n");
         // TODO: free
--- a/libidav/Makefile	Tue Jul 07 20:47:02 2015 +0200
+++ b/libidav/Makefile	Wed Jul 08 17:31:26 2015 +0200
@@ -36,7 +36,6 @@
 SRC += utils.c
 SRC += davqlparser.c
 SRC += davqlexec.c
-SRC += davql.c
 SRC += crypto.c
 
 OBJ = $(SRC:%.c=../build/libidav/%$(OBJ_EXT))
--- a/libidav/davql.c	Tue Jul 07 20:47:02 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,770 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2015 Olaf Wintermann. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "davql.h"
-#include "methods.h"
-#include "utils.h"
-
-DavQuery dav_ql_parse(char *query, va_list ap) {
-    DavQuery davquery;
-    davquery.command = DAV_QUERY_ERROR;
-    davquery.command_data = NULL;
-    sstr_t q = sstr(query);
-    q = sstrtrim(q);
-    
-    // get query command
-    sstr_t cmd;
-    cmd.ptr = NULL;
-    int i;
-    for(i=0;i<q.length;i++) {
-        if(q.ptr[i] == ' ') {
-            cmd = sstrsubsl(q, 0, i);
-            break;
-        }
-    }
-    if(!cmd.ptr) {
-        fprintf(stderr, "DQL syntax error\n");
-        return davquery;
-    }
-    
-    cmd = sstrtrim(cmd);
-    q = sstrtrim(sstrsubs(q, i));
-    if(!sstrcmp(cmd, S("get"))) {
-        davquery.command = DAV_QUERY_GET;
-        davquery.command_data = dav_ql_parse_get(q, ap);
-    }
-    
-    return davquery;
-}
-
-DavGetQuery* dav_ql_parse_get(sstr_t q, va_list ap) {  
-    sstr_t property_query = q;
-    q = util_getsubstr_until_token(q, S("from"), &property_query);
-    
-    sstr_t from_query = q;
-    sstr_t cond = util_getsubstr_until_token(q, S("where"), &from_query);
-    sstr_t with = util_getsubstr_until_token(cond, S("with"), &cond);
-    int depth = 1;
-       
-    // insert variable values
-    UcxBuffer *fbuf = ucx_buffer_new(NULL, 1024, UCX_BUFFER_AUTOEXTEND);
-    int var = 0;
-    for(int i=0;i<from_query.length;i++) {
-        char c = from_query.ptr[i];
-        if(c == '%') {
-            if(var) {
-                ucx_buffer_putc(fbuf, '%'); // previous '%'
-            } else {
-                var = 1;
-            }
-        } else if(var) {
-            switch(c) {
-                case 's': {
-                    char *arg = va_arg(ap, char*);
-                    ucx_buffer_puts(fbuf, arg);
-                    break;
-                }
-                default: {
-                    ucx_buffer_putc(fbuf, '%');
-                    ucx_buffer_putc(fbuf, c);
-                }
-            }
-            var = 0;
-        } else {
-            ucx_buffer_putc(fbuf, c);
-        }
-    }
-    
-    // condition
-    DavQOp *condition = NULL;
-    size_t oplen = 0;
-    if(cond.ptr) {
-        //printf("cond: {%.*s}\n", cond.length, cond.ptr);
-        UcxList *ops = NULL;
-        if(dav_parse_condition(&ops, cond, ap)) {
-            // TODO: error
-            printf("parse error\n");
-            return NULL;
-        }
-        oplen = ucx_list_size(ops);
-        condition = calloc(sizeof(DavQOp), oplen);
-        int l = 0;
-        UCX_FOREACH(elm, ops) {
-            condition[l] = *(DavQOp*)elm->data;
-            free(elm->data);
-            l++;
-        }
-        ucx_list_free(ops);
-    }
-    
-    // with
-    if(with.ptr) {
-        if(dav_parse_with(with, &depth, ap)) {
-            // TODO: error
-            printf("parse error\n");
-            return NULL;
-        }
-    }
-    
-    DavGetQuery *getquery = malloc(sizeof(DavGetQuery));
-    getquery->properties = sstrdup(property_query);
-    getquery->from = sstrdup(sstrn(fbuf->space, fbuf->pos));
-    getquery->depth = depth;
-    if(condition) {
-        getquery->condition = condition;
-        getquery->condlen = oplen;
-    } else {
-        getquery->condition = NULL;
-        getquery->condlen = 0;
-    }
-    
-    ucx_buffer_free(fbuf);
-    return getquery;
-}
-
-void free_get_query(DavGetQuery *q) {
-    free(q->from.ptr);
-    free(q->properties.ptr);
-    if(q->condition) {
-        free(q->condition);
-    }
-    free(q);
-}
-
-int parse_path_query(sstr_t query, char **path, int *depth) {
-    if(query.length == 1) {
-        if(query.ptr[0] == '/') {
-            *path = sstrdup(query).ptr;
-            *depth = 1;
-            return 0;
-        } else {
-            *path = NULL;
-            return 1;
-        }
-    }
-    
-    if(query.ptr[query.length-1] == '*') {
-        *depth = -1;
-        *path = sstrdup(sstrsubsl(query, 0, query.length-1)).ptr;
-    } else {
-        *path = sstrdup(query).ptr;
-        *depth = 1;
-    }
-    
-    return 0;
-}
-
-static int dav_str2depth(sstr_t str, int *depth) {
-    if(!sstrcmp(str, S("infinity"))) {
-        *depth = -1;
-    } else {
-        sstr_t cp = sstrdup(str); // terminate
-        *depth = atoi(cp.ptr);
-        free(cp.ptr);
-    }
-    return 0;
-}
-
-int dav_parse_with(sstr_t with, int *depth, va_list ap) {
-    int i;
-    for(i=0;i<with.length;i++) {
-        if(with.ptr[i] == ' ') {
-            break;
-        }
-    }
-    
-    sstr_t name = sstrsubsl(with, 0, i);
-    sstr_t value = sstrtrim(sstrsubs(with, i));
-    //printf("with {%.*s} {%.*s}\n", name.length, name.ptr, value.length, value.ptr);
-    
-    if(!sstrcmp(name, S("depth"))) {
-        if(value.length == 0) {
-            return 1;
-        } else if(value.ptr[0] == '%') {
-            switch(value.ptr[1]) {
-                default: return 1;
-                case 's': {
-                    sstr_t v = sstr(va_arg(ap, char*));
-                    if(dav_str2depth(value, depth)) {
-                        return 1;
-                    }
-                    break;
-                }
-                case 'd': {
-                    *depth = va_arg(ap, int);
-                    break;
-                }
-            }
-        } else {
-            if(dav_str2depth(value, depth)) {
-                return 1;
-            }
-        }
-    }
-    
-    return 0;
-}
-
-int dav_parse_condition(UcxList **ops, sstr_t cond, va_list ap) {
-    sstr_t token;
-    DavQOp *op1 = NULL; // level 1 operator
-    DavQOp *op2 = NULL; // level 2 operator
-    DavQOp *op3 = NULL; // level 3 operator
-    while((token = condition_parser_next_token(&cond)).length > 0) {
-        //printf("token: {%.*s}[%d]\n", token.length, token.ptr, token.length);
-        int64_t type = 0;
-        int tkop = condition_operator_type(token, &type);
-        DavQOp *operation = malloc(sizeof(DavQOp));
-        if(tkop > 0) {
-            // operator token
-            operation->type = DAVQOP_OPERATOR;
-            operation->val = NULL;
-            operation->intval = type;
-            switch(tkop) {
-                case 1: {
-                    // operators: + - / * not
-                    // add operation after next non operator token
-                    op1 = operation;
-                    break;
-                }
-                case 2: {
-                    // operators: < > == != <= >=
-                    if(op2) {
-                        *ops = ucx_list_append(*ops, op2);
-                    }
-                    op2 = operation;
-                    break;
-                }
-                case 3: {
-                    // operators: and or xor
-                    if(op2) {
-                        *ops = ucx_list_append(*ops, op2);
-                        op2 = NULL;
-                    }
-                    if(op3) {
-                        *ops = ucx_list_append(*ops, op3);
-                    }
-                    op3 = operation;
-                    break;
-                }
-            }
-        } else {
-            if(token.ptr[0] == '"' || token.ptr[0] == '\'') {
-                operation->type = DAVQOP_STRING;
-                operation->val = token.ptr+1;
-                operation->intval = token.length-2;
-            } else if(!sstrcmp(token, S("true")) ||
-                    !sstrcmp(token, S("false")))
-            {
-                operation->type = DAVQOP_INTEGER;
-                operation->val = NULL;
-                operation->intval = util_getboolean(token.ptr);
-            } else if(token.length == 2 && token.ptr[0] == '%') {
-                switch(token.ptr[1]) {
-                    case 's': {
-                        char *arg = va_arg(ap, char*);
-                        operation->type = DAVQOP_STRING;
-                        operation->val = arg;
-                        operation->intval = strlen(arg);
-                        break;
-                    }
-                    case 'd': {
-                        operation->type = DAVQOP_INTEGER;
-                        operation->val = NULL;
-                        operation->intval = va_arg(ap, int);
-                        break;
-                    }
-                    case 't': {
-                        operation->type = DAVQOP_INTEGER;
-                        operation->val = NULL;
-                        operation->intval = va_arg(ap, time_t);
-                        break;
-                    }
-                    default: {
-                        operation->type = DAVQOP_STRING;
-                        operation->val = token.ptr;
-                        operation->intval = token.length;
-                    }
-                }
-            } else {
-                sstr_t d = sstrdup(token);
-                int64_t val = 0;
-                int intval = util_strtoint(d.ptr, &val);
-                free(d.ptr);
-                if(intval) {
-                    operation->type = DAVQOP_INTEGER;
-                    operation->val = NULL;
-                    operation->intval = val;
-                } else {
-                    if(!sstrcmp(token, S("contentlength"))) {
-                        operation->type = DAVQOP_RESPROP;
-                    } else if(!sstrcmp(token, S("lastmodified"))) {
-                        operation->type = DAVQOP_RESPROP;
-                    } else if(!sstrcmp(token, S("creationdate"))) {
-                        operation->type = DAVQOP_RESPROP;
-                    } else if(!sstrcmp(token, S("name"))) {
-                        operation->type = DAVQOP_RESPROP;
-                    } else if(!sstrcmp(token, S("path"))) {
-                        operation->type = DAVQOP_RESPROP;
-                    } else if(!sstrcmp(token, S("iscollection"))) {
-                        operation->type = DAVQOP_RESPROP;
-                    } else {
-                        operation->type = DAVQOP_PROPERTY;
-                    }
-                    operation->val = token.ptr;
-                    operation->intval = token.length;
-                }
-            }
-            
-            // add operation
-            *ops = ucx_list_append(*ops, operation);
-            if(op1) {
-                // add level 1 operator
-                *ops = ucx_list_append(*ops, op1);
-                op1 = NULL;
-            }
-        }
-    }
-    if(op1) {
-        *ops = ucx_list_append(*ops, op1);
-    }
-    if(op2) {
-        *ops = ucx_list_append(*ops, op2);
-    }
-    if(op3) {
-        *ops = ucx_list_append(*ops, op3);
-    }
-    return 0;
-}
-
-sstr_t condition_parser_next_token(sstr_t *str) {
-    sstr_t s = *str;
-    sstr_t t;
-    t.ptr = NULL;
-    t.length = 0;
-    // remove leading space
-    int i;
-    for(i=0;i<s.length;i++) {
-        if(s.ptr[i] > 32) {
-            break;
-        }
-    }
-    s.length -= i;
-    s.ptr += i;
-    
-    if(s.length == 0) {
-        *str = s;
-        return t;
-    }
-    
-    // check for single char operators
-    switch(s.ptr[0]) {
-        case '<':
-        case '>':
-        case '+':
-        case '-':
-        case '*':
-        case '/': {
-            t.ptr = s.ptr;
-            t.length = 1;
-            str->ptr = s.ptr + 1;
-            str->length = s.length - 1;
-            return t;
-        }
-    }
-    
-    if(s.length > 1) {
-        // check for double char operators
-        int16_t op = *(int16_t*)s.ptr;
-        if(op == '==' || op == '!=' || op == '>=' || op == '=<') {
-            t.ptr = s.ptr;
-            t.length = 2;
-            str->ptr = s.ptr + 2;
-            str->length = s.length - 2;
-            return t;
-        }
-    } else {
-        t.ptr = s.ptr;
-        t.length = 1;
-        str->ptr = s.ptr + 1;
-        str->length = s.length - 1;
-        return t;
-    }
-    
-    // TODO: brackets
-    
-    // check for string literal
-    if(s.ptr[0] == '\'' || s.ptr[0] == '"') {
-        for(i=1;i<s.length;i++) {
-            if(s.ptr[0] == s.ptr[i]) {
-                i++;
-                break;
-            }
-        }
-        t.ptr = s.ptr;
-        t.length = i;
-        str->ptr = s.ptr + i;
-        str->length = s.length - i;
-        return t;
-    }
-    
-    for(i=0;i<s.length;i++) {
-        char c = s.ptr[i];
-        if((c < 33) || (c > 41 && c < 48) || (c > 59 && c < 63)) {
-            break;
-        }
-    }
-    t.ptr = s.ptr;
-    t.length = i;
-    str->ptr = s.ptr + i;
-    str->length = s.length - i;
-    return t;
-}
-
-int condition_operator_type(sstr_t token, int64_t *type) {
-    // returns the operator level and sets the type
-    
-    if(token.ptr[0] == '"' || token.ptr[0] == '\'' || token.ptr[0] == '(') {
-        return 0;
-    }
-    
-    if(token.length == 1) {
-        switch(token.ptr[0]) {
-            case '+': *type = 1; return 1;
-            case '-': *type = 2; return 1;
-            case '*': *type = 3; return 1;
-            case '/': *type = 4; return 1;
-            case '<': *type = 5; return 2;
-            case '>': *type = 6; return 2;
-        }
-    }
-    if(!sstrcmp(token, S("not"))) {
-        *type = 0;
-        return 1;
-    }
-    
-    if(!sstrcmp(token, S("=="))) {
-        *type = 7;
-        return 2;
-    }
-    if(!sstrcmp(token, S("!="))) {
-        *type = 8;
-        return 2;
-    }
-    if(!sstrcmp(token, S("<="))) {
-        *type = 9;
-        return 2;
-    }
-    if(!sstrcmp(token, S(">="))) {
-        *type = 10;
-        return 2;
-    }
-    
-    if(!sstrcmp(token, S("and"))) {
-        *type = 11;
-        return 3;
-    }
-    if(!sstrcmp(token, S("or"))) {
-        *type = 12;
-        return 3;
-    }
-    if(!sstrcmp(token, S("xor"))) {
-        *type = 13;
-        return 3;
-    }
-    
-    return 0;
-}
-
-int condition_eval(DavResource *res, DavQOp *cond, size_t len) {
-    DavQOp stack[128];
-    int stackpos = 0;
-    for(int i=0;i<len;i++) {
-        DavQOp op = cond[i];
-        switch(op.type) {
-            case DAVQOP_OPERATOR: {
-                if(op.intval == 0) {
-                    // not operator
-                    if(stackpos < 1) {
-                        // error
-                        printf("no data on stack\n");
-                        return 0;
-                    }
-                    int pos = stackpos-1;
-                    if(stack[pos].type == DAVQOP_INTEGER) {
-                        //printf("not %" PRId64 "\n", stack[pos].intval);
-                        stack[pos].intval = !stack[pos].intval;
-                    } else {
-                        // error
-                        printf("wrong value for 'not' operator\n");
-                        return 0;
-                    }
-                } else {
-                    DavQOp val1 = stack[stackpos-2];
-                    DavQOp val2 = stack[stackpos-1];
-                    DavQOp result;
-                    if(val1.type == DAVQOP_INTEGER) {
-                        if(val2.type == DAVQOP_INTEGER) {
-                            result = compare_intint(
-                                    op.intval,
-                                    val1.intval,
-                                    val2.intval);
-                        } else {
-                            result = compare_intstr(op.intval, val1, val2);
-                        }
-                    } else {
-                        if(val2.type == DAVQOP_INTEGER) {
-                            result = compare_strint(op.intval, val1, val2);
-                        } else {
-                            result = compare_strstr(op.intval, val1, val2);
-                        }
-                    } 
-                    stack[stackpos-2] = result;
-                    stackpos--;
-                }
-                break;
-            }
-            case DAVQOP_STRING:
-            case DAVQOP_INTEGER:
-            case DAVQOP_TIME: {
-                if(op.type == DAVQOP_STRING) {
-                    //printf("put on stack: '%s'\n", op.val);
-                } else {
-                    //printf("put on stack[%d]: %" PRId64 "\n", stackpos, op.intval);
-                }
-                stack[stackpos++] = op;
-                break;
-            }
-            case DAVQOP_PROPERTY: {
-                sstr_t pname = sstrn(op.val, op.intval);
-                pname = sstrdup(pname);
-                char *property_value = dav_get_property(res, pname.ptr);
-                free(pname.ptr);
-                DavQOp value;
-                value.type = DAVQOP_STRING;
-                if(property_value) {
-                    //printf("put on stack: \"%s\"\n", property_value);
-                    value.val = property_value;
-                    value.intval = strlen(property_value);
-                } else {
-                    //printf("put on stack: null string\n");
-                    value.val = NULL;
-                    value.intval = 0;
-                }
-                stack[stackpos++] = value;
-                break;
-            }
-            case DAVQOP_RESPROP: {
-                sstr_t name = sstrn(op.val, op.intval);
-                DavQOp value;
-                value.type = DAVQOP_INTEGER;
-                value.val = NULL;
-                if(!sstrcmp(name, S("contentlength"))) {
-                    //printf("put contentlength\n");
-                    value.intval = res->contentlength;
-                } else if(!sstrcmp(name, S("lastmodified"))) {
-                    //printf("put getlastmodified\n");
-                    value.intval = res->lastmodified;
-                } else if(!sstrcmp(name, S("creationdate"))) {
-                    value.intval = res->creationdate;
-                } else if(!sstrcmp(name, S("name"))) {
-                    value.type = DAVQOP_STRING;
-                    value.val = res->name;
-                    value.intval = strlen(res->name);
-                } else if(!sstrcmp(name, S("path"))) {
-                    value.type = DAVQOP_STRING;
-                    value.val = res->path;
-                    value.intval = strlen(res->path);
-                } else if(!sstrcmp(name, S("iscollection"))) {
-                    value.type = DAVQOP_INTEGER;
-                    value.val = NULL;
-                    value.intval = res->iscollection;
-                }
-                stack[stackpos++] = value;
-                break;
-            }
-        }
-    }
-    if(stackpos != 1) {
-        return 0;
-    }
-    DavQOp result = stack[0];
-    //printf("result: %" PRId64 "\n", result.intval);
-    return (int)result.intval;
-}
-
-DavQOp compare_intint(int op, int64_t v1, int64_t v2) {
-    DavQOp res;
-    res.type = DAVQOP_INTEGER;
-    res.val = NULL;
-    res.intval = 0;
-    switch(op) {
-        case 5: {
-            // <
-            //printf("compare: %" PRId64 " < %" PRId64 "\n", v1, v2);
-            res.intval = v1 < v2;
-            break;
-        }
-        case 6: {
-            // >
-            //printf("compare: %" PRId64 " > %" PRId64 "\n", v1, v2);
-            res.intval = v1 > v2;
-            break;
-        }
-        case 7: {
-            // ==
-            //printf("compare: %" PRId64 " == %" PRId64 "\n", v1, v2);
-            res.intval = v1 == v2;
-            break;
-        }
-        case 8: {
-            // !=
-            //printf("compare: %" PRId64 " != %" PRId64 "\n", v1, v2);
-            res.intval = v1 != v2;
-            break;
-        }
-        case 9: {
-            // <=
-            //printf("compare: %" PRId64 " <= %" PRId64 "\n", v1, v2);
-            res.intval = v1 <= v2;
-            break;
-        }
-        case 10: {
-            // >=
-            //printf("compare: %" PRId64 " >= %" PRId64 "\n", v1, v2);
-            res.intval = v1 >= v2;
-            break;
-        }
-        case 11: {
-            // and
-            //printf("compare: %" PRId64 " and %" PRId64 "\n", v1, v2);
-            res.intval = v1 && v2;
-            break;
-        }
-        case 12: {
-            // or
-            //printf("compare: %" PRId64 " or %" PRId64 "\n", v1, v2);
-            res.intval = v1 || v2;
-            break;
-        }
-        case 13: {
-            // xor
-            //printf("compare: %" PRId64 " xor %" PRId64 "\n", v1, v2);
-            res.intval = v1 ^ v2;
-            break;
-        }
-    }
-    return res;
-}
-
-DavQOp compare_strint(int op, DavQOp v1, DavQOp v2) {
-    int64_t v1int;
-    sstr_t s1 = sstrn(v1.val, v1.intval);
-    s1 = sstrdup(s1);
-    if(util_strtoint(s1.ptr, &v1int)) {
-        free(s1.ptr);
-        return compare_intint(op, v1int, v2.intval);
-    } else {
-        free(s1.ptr);
-        // TODO
-    }
-}
-
-DavQOp compare_intstr(int op, DavQOp v1, DavQOp v2) {
-    // TODO
-}
-
-DavQOp compare_strstr(int op, DavQOp v1, DavQOp v2) {
-    DavQOp res;
-    res.type = DAVQOP_INTEGER;
-    res.val = NULL;
-    res.intval = 0;
-    sstr_t s1 = sstrn(v1.val, v1.intval);
-    sstr_t s2 = sstrn(v2.val, v2.intval);
-    switch(op) {
-        case 5: {
-            // <
-            //printf("str compare: %.*s < %.*s\n", s1.length, s1.ptr, s2.length, s2.ptr);
-            res.intval = s1.length < s2.length;
-            break;
-        }
-        case 6: {
-            // >
-            //printf("str compare: %.*s > %.*s\n", s1.length, s1.ptr, s2.length, s2.ptr);
-            res.intval = s1.length > s2.length;
-            break;
-        }
-        case 7: {
-            // ==
-            //printf("str compare: %.*s == %.*s\n", s1.length, s1.ptr, s2.length, s2.ptr);
-            res.intval = sstrcmp(s1, s2) == 0;
-            break;
-        }
-        case 8: {
-            // !=
-            //printf("str compare: %.*s != %.*s\n", s1.length, s1.ptr, s2.length, s2.ptr);
-            res.intval = sstrcmp(s1, s2) != 0;
-            break;
-        }
-        case 9: {
-            // <=
-            //printf("str compare: %.*s <= %.*s\n", s1.length, s1.ptr, s2.length, s2.ptr);
-            res.intval = s1.length <= s2.length;
-            break;
-        }
-        case 10: {
-            // >=
-            //printf("str compare: %.*s >= %.*s\n", s1.length, s1.ptr, s2.length, s2.ptr);
-            res.intval = s1.length >= s2.length;
-            break;
-        }
-        case 11: {
-            // and
-            //printf("str compare: %.*s and %.*s\n", s1.length, s1.ptr, s2.length, s2.ptr);
-            res.intval = s1.ptr && s2.ptr;
-            break;
-        }
-        case 12: {
-            // or
-            //printf("str compare: %.*s or %.*s\n", s1.length, s1.ptr, s2.length, s2.ptr);
-            res.intval = s1.ptr || s2.ptr;
-            break;
-        }
-        case 13: {
-            // xor
-            //printf("str compare: %.*s xor %.*s\n", s1.length, s1.ptr, s2.length, s2.ptr);
-            res.intval = (intptr_t)s1.ptr ^ (intptr_t)s2.ptr;
-            break;
-        }
-    }
-    return res;
-}
--- a/libidav/davql.h	Tue Jul 07 20:47:02 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2015 Olaf Wintermann. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "webdav.h"
-
-#ifndef DAVQL_H
-#define	DAVQL_H
-
-#include <ucx/string.h>
-#include <ucx/list.h>
-#include <inttypes.h>
-#include <stdarg.h>
-
-#ifdef	__cplusplus
-extern "C" {
-#endif
-
-enum DavQueryType {
-    DAV_QUERY_ERROR = 0,
-    DAV_QUERY_GET
-};
-typedef enum DavQueryType DavQueryType;
-
-#define DAVQOP_OPERATOR    0
-#define DAVQOP_STRING      1
-#define DAVQOP_INTEGER     2
-#define DAVQOP_TIME        3
-#define DAVQOP_PROPERTY    4
-#define DAVQOP_RESPROP     5
-
-typedef struct {
-    int      type;
-    void     *val;
-    int64_t intval;
-} DavQOp;
-    
-typedef struct {
-    DavQueryType command;
-    void         *command_data;
-} DavQuery;
-
-typedef struct {
-    sstr_t properties;
-    sstr_t from;
-    DavQOp *condition;
-    size_t condlen;
-    int    depth;
-} DavGetQuery;
-    
-DavQuery dav_ql_parse(char *query, va_list ap);
-DavGetQuery* dav_ql_parse_get(sstr_t q, va_list ap);
-void free_get_query(DavGetQuery *q);
-
-int parse_path_query(sstr_t query, char **path, int *depth);
-
-int dav_parse_with(sstr_t with, int *depth, va_list ap);
-int dav_parse_condition(UcxList **ops, sstr_t cond, va_list ap);
-sstr_t condition_parser_next_token(sstr_t *str);
-int condition_operator_type(sstr_t token, int64_t *type);
-
-int condition_eval(DavResource *res, DavQOp *cond, size_t len);
-DavQOp compare_intint(int op, int64_t v1, int64_t v2);
-DavQOp compare_strint(int op, DavQOp v1, DavQOp v2);
-DavQOp compare_intstr(int op, DavQOp v1, DavQOp v2);
-DavQOp compare_strstr(int op, DavQOp v1, DavQOp v2);
-
-#ifdef	__cplusplus
-}
-#endif
-
-#endif	/* DAVQL_H */
-
--- a/libidav/davqlexec.c	Tue Jul 07 20:47:02 2015 +0200
+++ b/libidav/davqlexec.c	Wed Jul 08 17:31:26 2015 +0200
@@ -38,30 +38,27 @@
 #include "session.h"
 #include "resource.h"
 
-DavResult* dav_statement_exec(DavSession *sn, DavQLStatement *st, ...) {
+DavResult dav_statement_exec(DavSession *sn, DavQLStatement *st, ...) {
     va_list ap;
     va_start(ap, st);
-    DavResult *result = dav_statement_execv(sn, st, ap);
+    DavResult result = dav_statement_execv(sn, st, ap);
     va_end(ap);
     return result;
 }
 
-DavResult* dav_statement_execv(DavSession *sn, DavQLStatement *st, va_list ap) {
-    DavResult *result = dav_session_malloc(sn, sizeof(DavResult));
-    result->result = NULL;
-    result->status = 1;
+DavResult dav_statement_execv(DavSession *sn, DavQLStatement *st, va_list ap) {
+    DavResult result;
+    result.result = NULL;
+    result.status = 1;
     
     // make sure the statement was successfully parsed
     if(st->type == DAVQL_ERROR) {
+        DavResult result;
         return result;
     }
     
-    // get path string
-    davqlerror_t error;
-    sstr_t path = dav_format_string(sn->mp->allocator, st->path, ap, &error);
-    
     if(st->type == DAVQL_SELECT) {
-        *result = dav_exec_select(sn, st, path.ptr, ap);
+        return dav_exec_select(sn, st, ap);
     } else {
         // TODO
     }
@@ -203,6 +200,7 @@
 }
 
 static int reset_properties(DavSession *sn, DavResult *result, DavResource *res, UcxList *fields) {
+    return 0;
     UcxMap *new_properties = ucx_map_new_a(sn->mp->allocator, 32);
     DavResourceData *data = (DavResourceData*)res->data;
     
@@ -295,7 +293,7 @@
 /*
  * execute a davql select statement
  */
-DavResult dav_exec_select(DavSession *sn, DavQLStatement *st, char* path, va_list ap) {
+DavResult dav_exec_select(DavSession *sn, DavQLStatement *st, va_list ap) {
     UcxMempool *mp = ucx_mempool_new(128);
     DavResult result;
     result.result = NULL;
@@ -345,13 +343,23 @@
         } 
     }
     
+    // get path string
+    davqlerror_t error;
+    sstr_t path = dav_format_string(mp->allocator, st->path, ap, &error);
+    if(error) {
+        // TODO: cleanup
+        return result;
+    }
+    
+    int depth = st->depth == DAV_DEPTH_PLACEHOLDER ? va_arg(ap, int) : st->depth;
+    
     UcxBuffer *where = dav_compile_expr(sn->context, mp->allocator, st->where, ap);
-    if(!where) {
+    if(st->where && !where) {
         ucx_mempool_destroy(mp);
         return result;
     }
     
-    DavResource *selroot = dav_resource_new(sn, path);
+    DavResource *selroot = dav_resource_new(sn, path.ptr);
     
     UcxList *stack = NULL; // stack with DavResource* elements
     // initialize the stack with the requested resource
@@ -431,7 +439,7 @@
                             if(!reset_properties(sn, &result, child, cfieldlist)) {
                                 resource_add_child(root, child);
                                 if(child->iscollection &&
-                                    (st->depth < 0 || st->depth > sr->depth+1))
+                                    (depth < 0 || depth > sr->depth+1))
                                 {
                                     DavQLRes *rs = ucx_mempool_malloc(
                                             mp,
@@ -515,6 +523,7 @@
         }
         case DAVQL_TIMESTAMP: {
             if(src.ptr[0] == '%') {
+                cmd.type = DAVQL_CMD_TIMESTAMP;
                 cmd.data.timestamp = va_arg(ap, time_t);
                 ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode);
             } else {
@@ -764,6 +773,13 @@
 }
 
 int dav_exec_expr(UcxBuffer *bcode, DavResource *res, DavQLStackObj *result) {
+    if(!bcode) {
+        result->type = 0;
+        result->length = 0;
+        result->data.integer = 1;
+        return 0;
+    }
+    
     size_t count = bcode->pos / sizeof(DavQLCmd);
     DavQLCmd *cmds = (DavQLCmd*)bcode->space;
     
@@ -793,7 +809,7 @@
         DavQLCmd cmd = cmds[i];
         switch(cmd.type) {
             case DAVQL_CMD_INT: {
-                printf("int %lld\n", cmd.data.integer);
+                //printf("int %lld\n", cmd.data.integer);
                 obj.type = 0;
                 obj.length = 0;
                 obj.data.integer = cmd.data.integer;
@@ -801,7 +817,7 @@
                 break;
             }
             case DAVQL_CMD_STRING: {
-                printf("string \"%.*s\"\n", cmd.data.string.length, cmd.data.string.ptr);
+                //printf("string \"%.*s\"\n", cmd.data.string.length, cmd.data.string.ptr);
                 obj.type = 1;
                 obj.length = cmd.data.string.length;
                 obj.data.string = cmd.data.string.ptr;
@@ -809,16 +825,16 @@
                 break;
             }
             case DAVQL_CMD_TIMESTAMP: {
-                printf("timestamp %d\n", cmd.data.timestamp);
+                //printf("timestamp %d\n", cmd.data.timestamp);
                 obj.type = 0;
                 obj.length = 0;
-                obj.data.integer = cmd.data.timestamp;
+                obj.data.integer = (int)cmd.data.timestamp;
                 DAVQL_PUSH(obj);
                 break;
             }
             case DAVQL_CMD_RES_IDENTIFIER: {
                 char *rid[8] = {"name", "path", "href", "contentlength", "contenttype", "creationdate", "lastmodified", "iscollection"};
-                printf("resprop %s\n", rid[cmd.data.resprop]);
+                //printf("resprop %s\n", rid[cmd.data.resprop]);
                 switch(cmd.data.resprop) {
                     case DAVQL_RES_NAME: {
                         obj.type = 1;
@@ -873,7 +889,7 @@
                 break;
             }
             case DAVQL_CMD_PROP_IDENTIFIER: {
-                printf("property %s:%s\n", cmd.data.property.ns, cmd.data.property.name);
+                //printf("property %s:%s\n", cmd.data.property.ns, cmd.data.property.name);
                 char *value = dav_get_property_ns(res, cmd.data.property.ns, cmd.data.property.name);
                 obj.type = 1;
                 obj.length = value ? strlen(value) : 0;
@@ -886,7 +902,7 @@
             //    break;
             //}
             case DAVQL_CMD_OP_UNARY_SUB: {
-                printf("usub\n");
+                //printf("usub\n");
                 obj = DAVQL_POP();
                 if(obj.type == 0) {
                     obj.data.integer = -obj.data.integer;
@@ -898,7 +914,7 @@
                 break;
             }
             case DAVQL_CMD_OP_UNARY_NEG: {
-                printf("uneg\n");
+                //printf("uneg\n");
                 obj = DAVQL_POP();
                 if(obj.type == 0) {
                     obj.data.integer = obj.data.integer == 0 ? 1 : 0;
@@ -910,7 +926,7 @@
                 break;
             }
             case DAVQL_CMD_OP_BINARY_ADD: {
-                printf("add\n");
+                //printf("add\n");
                 DavQLStackObj obj2 = DAVQL_POP();
                 DavQLStackObj obj1 = DAVQL_POP();
                 if(obj1.type == 0 && obj2.type == 0) {
@@ -921,7 +937,7 @@
                 break;
             }
             case DAVQL_CMD_OP_BINARY_SUB: {
-                printf("sub\n");
+                //printf("sub\n");
                 DavQLStackObj obj2 = DAVQL_POP();
                 DavQLStackObj obj1 = DAVQL_POP();
                 if(obj1.type == 0 && obj2.type == 0) {
@@ -934,7 +950,7 @@
                 break;
             }
             case DAVQL_CMD_OP_BINARY_MUL: {
-                printf("mul\n");
+                //printf("mul\n");
                 DavQLStackObj obj2 = DAVQL_POP();
                 DavQLStackObj obj1 = DAVQL_POP();
                 if(obj1.type == 0 && obj2.type == 0) {
@@ -947,7 +963,7 @@
                 break;
             }
             case DAVQL_CMD_OP_BINARY_DIV: {
-                printf("div\n");
+                //printf("div\n");
                 DavQLStackObj obj2 = DAVQL_POP();
                 DavQLStackObj obj1 = DAVQL_POP();
                 if(obj1.type == 0 && obj2.type == 0) {
@@ -960,7 +976,7 @@
                 break;
             }
             case DAVQL_CMD_OP_BINARY_AND: {
-                printf("and\n");
+                //printf("and\n");
                 DavQLStackObj obj2 = DAVQL_POP();
                 DavQLStackObj obj1 = DAVQL_POP();
                 if(obj1.type == 0 && obj2.type == 0) {
@@ -973,7 +989,7 @@
                 break;
             }
             case DAVQL_CMD_OP_BINARY_OR: {
-                printf("or\n");
+                //printf("or\n");
                 DavQLStackObj obj2 = DAVQL_POP();
                 DavQLStackObj obj1 = DAVQL_POP();
                 if(obj1.type == 0 && obj2.type == 0) {
@@ -986,7 +1002,7 @@
                 break;
             }
             case DAVQL_CMD_OP_BINARY_XOR: {
-                printf("xor\n");
+                //printf("xor\n");
                 DavQLStackObj obj2 = DAVQL_POP();
                 DavQLStackObj obj1 = DAVQL_POP();
                 if(obj1.type == 0 && obj2.type == 0) {
@@ -999,11 +1015,11 @@
                 break;
             }
             case DAVQL_CMD_OP_LOGICAL_NOT: {
-                printf("not\n");
+                //printf("not\n");
                 break;
             }
             case DAVQL_CMD_OP_LOGICAL_AND: {
-                printf("land\n");
+                //printf("land\n");
                 DavQLStackObj obj2 = DAVQL_POP();
                 DavQLStackObj obj1 = DAVQL_POP();
                 int v1 = obj1.type == 0 ? (int)obj1.data.integer : (obj1.data.string ? 1 : 0);
@@ -1012,7 +1028,7 @@
                 break;
             }
             case DAVQL_CMD_OP_LOGICAL_OR_L: {
-                printf("or_l %d\n", cmd.data.integer);
+                //printf("or_l %d\n", cmd.data.integer);
                 DavQLStackObj obj1 = DAVQL_POP();
                 if((obj1.type == 0 && obj1.data.integer) || (obj1.type == 1 && obj1.data.string)) {
                     DAVQL_PUSH_INT(1);
@@ -1021,7 +1037,7 @@
                 break;
             }
             case DAVQL_CMD_OP_LOGICAL_OR: {
-                printf("or\n");
+                //printf("or\n");
                 DavQLStackObj obj2 = DAVQL_POP();
                 DavQLStackObj obj1 = DAVQL_POP();
                 int v1 = obj1.type == 0 ? (int)obj1.data.integer : (obj1.data.string ? 1 : 0);
@@ -1030,7 +1046,7 @@
                 break;
             }
             case DAVQL_CMD_OP_LOGICAL_XOR: {
-                printf("lxor\n");
+                //printf("lxor\n");
                 DavQLStackObj obj2 = DAVQL_POP();
                 DavQLStackObj obj1 = DAVQL_POP();
                 int v1 = obj1.type == 0 ? (int)obj1.data.integer : (obj1.data.string ? 1 : 0);
@@ -1039,7 +1055,7 @@
                 break;
             }
             case DAVQL_CMD_OP_EQ: {
-                printf("eq\n");
+                //printf("eq\n");
                 DavQLStackObj obj2 = DAVQL_POP();
                 DavQLStackObj obj1 = DAVQL_POP();
                 if(obj1.type == 0 && obj2.type == 0) {
@@ -1050,7 +1066,7 @@
                 break;
             }
             case DAVQL_CMD_OP_NEQ: {
-                printf("neq\n");
+                //printf("neq\n");
                 DavQLStackObj obj2 = DAVQL_POP();
                 DavQLStackObj obj1 = DAVQL_POP();
                 if(obj1.type == 0 && obj2.type == 0) {
@@ -1061,7 +1077,7 @@
                 break;
             }
             case DAVQL_CMD_OP_LT: {
-                printf("lt\n");
+                //printf("lt\n");
                 DavQLStackObj obj2 = DAVQL_POP();
                 DavQLStackObj obj1 = DAVQL_POP();
                 if(obj1.type == 0 && obj2.type == 0) {
@@ -1072,7 +1088,7 @@
                 break;
             }
             case DAVQL_CMD_OP_GT: {
-                printf("gt\n");
+                //printf("gt\n");
                 DavQLStackObj obj2 = DAVQL_POP();
                 DavQLStackObj obj1 = DAVQL_POP();
                 if(obj1.type == 0 && obj2.type == 0) {
@@ -1083,7 +1099,7 @@
                 break;
             }
             case DAVQL_CMD_OP_LE: {
-                printf("le\n");
+                //printf("le\n");
                 DavQLStackObj obj2 = DAVQL_POP();
                 DavQLStackObj obj1 = DAVQL_POP();
                 if(obj1.type == 0 && obj2.type == 0) {
@@ -1094,7 +1110,7 @@
                 break;
             }
             case DAVQL_CMD_OP_GE: {
-                printf("ge\n");
+                //printf("ge\n");
                 DavQLStackObj obj2 = DAVQL_POP();
                 DavQLStackObj obj1 = DAVQL_POP();
                 if(obj1.type == 0 && obj2.type == 0) {
@@ -1105,15 +1121,15 @@
                 break;
             }
             case DAVQL_CMD_OP_LIKE: {
-                printf("like\n");
+                //printf("like\n");
                 break;
             }
             case DAVQL_CMD_OP_UNLIKE: {
-                printf("unlike\n");
+                //printf("unlike\n");
                 break;
             }
             case DAVQL_CMD_CALL: {
-                printf("call %x\n", cmd.data.func);
+                //printf("call %x\n", cmd.data.func);
                 break;
             }
         }
--- a/libidav/davqlexec.h	Tue Jul 07 20:47:02 2015 +0200
+++ b/libidav/davqlexec.h	Wed Jul 08 17:31:26 2015 +0200
@@ -125,13 +125,13 @@
     UcxBuffer *code;
 } DavCompiledField;
     
-DavResult* dav_statement_exec(DavSession *sn, DavQLStatement *st, ...);
-DavResult* dav_statement_execv(DavSession *sn, DavQLStatement *st, va_list ap);
+DavResult dav_statement_exec(DavSession *sn, DavQLStatement *st, ...);
+DavResult dav_statement_execv(DavSession *sn, DavQLStatement *st, va_list ap);
 
 UcxBuffer* dav_path_string(sstr_t src, va_list ap, davqlerror_t *error);
 sstr_t dav_format_string(UcxAllocator *a, sstr_t fstr, va_list ap, davqlerror_t *error);
 
-DavResult dav_exec_select(DavSession *sn, DavQLStatement *st, char* path, va_list ap);
+DavResult dav_exec_select(DavSession *sn, DavQLStatement *st, va_list ap);
 
 UcxBuffer* dav_compile_expr(DavContext *ctx, UcxAllocator *a, DavQLExpression *lexpr, va_list ap);
 
--- a/libidav/methods.c	Tue Jul 07 20:47:02 2015 +0200
+++ b/libidav/methods.c	Wed Jul 08 17:31:26 2015 +0200
@@ -32,7 +32,6 @@
 
 #include "utils.h"
 #include "methods.h"
-#include "davql.h"
 #include "crypto.h"
 #include "session.h"
 
@@ -375,7 +374,7 @@
 }
 
 
-DavResource* parse_propfind_response(DavSession *sn, DavResource *root, UcxBuffer *response, DavQOp *cond, size_t len) {
+DavResource* parse_propfind_response(DavSession *sn, DavResource *root, UcxBuffer *response) {
     char *url = NULL;
     curl_easy_getinfo(sn->handle, CURLINFO_EFFECTIVE_URL, &url);
     if(!root) {
@@ -396,7 +395,7 @@
     while(node) {
         if(node->type == XML_ELEMENT_NODE) {
             if(xstreq(node->name, "response")) {
-                parse_response_tag(root, node, cond, len);
+                parse_response_tag(root, node);
             }
         }
         node = node->next;
@@ -463,7 +462,7 @@
     set_davprops(res);
 }
 
-int parse_response_tag(DavResource *resource, xmlNode *node, DavQOp *cond, size_t clen) {
+int parse_response_tag(DavResource *resource, xmlNode *node) {
     DavSession *sn = resource->session;
     
     //DavResource *res = resource;
@@ -607,12 +606,6 @@
     
     set_davprops(res);
     if(res != resource) {
-        if(clen > 0) {
-            if(!condition_eval(res, cond, clen)) {
-                // skip resource
-                return 0;
-            }
-        }
         resource_add_child(resource, res);
     }
     
--- a/libidav/methods.h	Tue Jul 07 20:47:02 2015 +0200
+++ b/libidav/methods.h	Wed Jul 08 17:31:26 2015 +0200
@@ -81,8 +81,8 @@
 DavResource* response2resource(DavSession *sn, ResponseTag *response, char *parent_path);
 void add_properties(DavResource *res, ResponseTag *response);
 
-DavResource* parse_propfind_response(DavSession *sn, DavResource *root, UcxBuffer *response, DavQOp *cond, size_t len);
-int parse_response_tag(DavResource *resource, xmlNode *node, DavQOp *cond, size_t len);
+DavResource* parse_propfind_response(DavSession *sn, DavResource *root, UcxBuffer *response);
+int parse_response_tag(DavResource *resource, xmlNode *node);
 void set_davprops(DavResource *res);
 
 UcxBuffer* create_proppatch_request(DavResourceData *data);
--- a/libidav/resource.c	Tue Jul 07 20:47:02 2015 +0200
+++ b/libidav/resource.c	Wed Jul 08 17:31:26 2015 +0200
@@ -34,7 +34,6 @@
 #include "utils.h"
 #include "session.h"
 #include "methods.h"
-#include "davql.h"
 #include "crypto.h"
 #include "ucx/buffer.h"
 #include "ucx/utils.h"
@@ -422,7 +421,7 @@
 
 int dav_load(DavResource *res) {
     UcxBuffer *rqbuf = create_allprop_propfind_request();
-    int ret = dav_propfind(res->session, res, rqbuf, NULL, 0);
+    int ret = dav_propfind(res->session, res, rqbuf);
     ucx_buffer_free(rqbuf);
     return ret;
 }
@@ -660,7 +659,7 @@
         
         // do a minimal propfind request
         UcxBuffer *rqbuf = create_propfind_request(sn, NULL);
-        int ret = dav_propfind(sn, res, rqbuf, NULL, 0);
+        int ret = dav_propfind(sn, res, rqbuf);
         ucx_buffer_free(rqbuf);
         return ret;
     } else {
--- a/libidav/session.c	Tue Jul 07 20:47:02 2015 +0200
+++ b/libidav/session.c	Wed Jul 08 17:31:26 2015 +0200
@@ -336,7 +336,7 @@
 }
 
 DavResource* dav_find_child(DavSession *sn, DavResource *res, UcxBuffer *rqbuf, char *name) {   
-    if(res && !dav_propfind(sn, res, rqbuf, NULL, 0)) {
+    if(res && !dav_propfind(sn, res, rqbuf)) {
         DavResource *child = res->children;
         while(child) {
             if(!strcmp(child->name, name)) {
--- a/libidav/webdav.c	Tue Jul 07 20:47:02 2015 +0200
+++ b/libidav/webdav.c	Wed Jul 08 17:31:26 2015 +0200
@@ -35,9 +35,10 @@
 #include "webdav.h"
 #include "session.h"
 #include "methods.h"
-#include "davql.h"
 #include "ucx/buffer.h"
 #include "ucx/utils.h"
+#include "davqlparser.h"
+#include "davqlexec.h"
 
 
 DavContext* dav_context_new() {
@@ -282,7 +283,8 @@
     curl_easy_getinfo (handle, CURLINFO_RESPONSE_CODE, &status);
     if(ret == CURLE_OK && status == 207) {
         //printf("response\n%s\n", rpbuf->space);
-        resource = parse_propfind_response(sn, resource, rpbuf, NULL, 0);
+        // TODO: use PropfindParser
+        resource = parse_propfind_response(sn, resource, rpbuf);
         sn->error = DAV_OK;
     } else  {
         dav_session_set_error(sn, ret, status);
@@ -296,7 +298,8 @@
     return resource;
 }
 
-int dav_propfind(DavSession *sn, DavResource *root, UcxBuffer *rqbuf, DavQOp *cond, size_t len) {
+
+int dav_propfind(DavSession *sn, DavResource *root, UcxBuffer *rqbuf) {
     // clean resource properties
     DavResourceData *data = root->data;
     size_t pcount = data->properties->count;
@@ -326,7 +329,7 @@
     curl_easy_getinfo (handle, CURLINFO_RESPONSE_CODE, &status);
     if(ret == CURLE_OK && status == 207) {
         //printf("response\n%s\n", rpbuf->space); 
-        resource = parse_propfind_response(sn, resource, rpbuf, cond, len);
+        resource = parse_propfind_response(sn, resource, rpbuf);
         sn->error = DAV_OK;
     } else  {
         dav_session_set_error(sn, ret, status);
@@ -336,75 +339,6 @@
     return error;
 }
 
-static UcxList* propfind_stack_push(UcxList *stack, DavResource *children) {
-    while(children) {
-        if(children->iscollection) {
-            stack = ucx_list_prepend(stack, children);
-        }
-        children = children->next;
-    }
-    return stack;
-}
-
-DavResource* dav_query_get(DavSession *sn, DavGetQuery *query) {
-    char *path;
-    int depth = query->depth;
-    /*
-    if(parse_path_query(query->from, &path, &depth)) {
-        sn->error = DAV_ERROR;
-        return NULL;
-    }
-    */
-    path = sstrdup(query->from).ptr;
-    
-    sstr_t ps = query->properties;
-    UcxBuffer *rqbuf;
-    if(!sstrcmp(ps, S("*"))) {
-        rqbuf = create_allprop_propfind_request();
-    } else if(!sstrcmp(ps, S("-"))) {
-        rqbuf = create_propfind_request(sn, NULL);
-    } else {
-        UcxList *proplist = parse_properties_string(sn->context, ps);
-        rqbuf = create_propfind_request(sn, proplist);
-        UCX_FOREACH(elm, proplist) {
-            DavProperty *prop = elm->data;
-            free(prop->name);
-            free(prop);
-        }
-        ucx_list_free(proplist);
-    }
-    
-    //fwrite(rqbuf->space, 1, rqbuf->size, stdout);
-    //printf("\n");
-    
-    DavResource *resource = dav_resource_new(sn, path);
-    free(path);
-    if(dav_propfind(sn, resource, rqbuf, query->condition, query->condlen)) {
-        dav_resource_free(resource);
-        resource = NULL;
-    }
-    
-    int error = 0;
-    if(resource && depth == -1) {
-        UcxList *stack = NULL; // stack with DavResource* elements
-        stack = propfind_stack_push(stack, resource->children);
-        while(stack) {
-            DavResource *sr = stack->data; // get first element from the stack
-            stack = ucx_list_remove(stack, stack); // remove first element
-            // do propfind request for sr
-            if(dav_propfind(sn, sr, rqbuf, query->condition, query->condlen)) {
-                error = 1;
-                printf("subrequest failed\n");
-                break;
-            }
-            stack = propfind_stack_push(stack, sr->children); // add children
-        }
-    }
-    
-    ucx_buffer_free(rqbuf);
-    return resource;
-}
-
 UcxList* parse_properties_string(DavContext *context, sstr_t str) {
     UcxList *proplist = NULL;
     ssize_t nprops = 0;
@@ -435,23 +369,24 @@
 }
 
 DavResource* dav_query(DavSession *sn, char *query, ...) {
+    DavQLStatement *stmt = dav_parse_statement(sstr(query));
+    if(!stmt) {
+        sn->error = DAV_ERROR;
+        return NULL;
+    }
+    if(stmt->errorcode != 0) {
+        sn->error = DAV_QL_ERROR;
+        dav_free_statement(stmt);
+        return NULL;
+    }
+    
     va_list ap;
     va_start(ap, query);
-    DavQuery q = dav_ql_parse(query, ap);
+    DavResult result = dav_statement_execv(sn, stmt, ap);
     va_end(ap);
-    DavResource *res = NULL;
-    switch(q.command) {
-        case DAV_QUERY_GET: {
-            res = dav_query_get(sn, q.command_data);
-            free_get_query(q.command_data);
-            break;
-        }
-        case DAV_QUERY_ERROR: {
-            // TODO
-            break;
-        }
-    }
-    return res;
+    
+    dav_free_statement(stmt);
+    return result.result;
 }
 
 
--- a/libidav/webdav.h	Tue Jul 07 20:47:02 2015 +0200
+++ b/libidav/webdav.h	Wed Jul 08 17:31:26 2015 +0200
@@ -51,8 +51,6 @@
 typedef struct DavPropName   DavPropName;
 typedef struct DavKey        DavKey;
 
-#include "davql.h"
-
 typedef size_t(*dav_read_func)(void*, size_t, size_t, void*);
 typedef size_t(*dav_write_func)(const void*, size_t, size_t, void*);
 
@@ -69,7 +67,8 @@
     DAV_COULDNT_RESOLVE_HOST,
     DAV_COULDNT_CONNECT,
     DAV_TIMEOUT,
-    DAV_SSL_ERROR
+    DAV_SSL_ERROR,
+    DAV_QL_ERROR
 };
 
 typedef enum DavError DavError;
@@ -190,8 +189,6 @@
 
 DavResource* dav_get(DavSession *sn, char *path, char *properties);
 
-DavResource* dav_query_get(DavSession *sn, DavGetQuery *query);
-
 UcxList* parse_properties_string(DavContext *context, sstr_t str);
 
 DavResource* dav_query(DavSession *sn, char *query, ...);
@@ -240,7 +237,7 @@
 int dav_get_content(DavResource *res, void *stream, dav_write_func write_func);
 
 // private
-int dav_propfind(DavSession *sn, DavResource *root, UcxBuffer *rqbuf, DavQOp *cond, size_t len);
+int dav_propfind(DavSession *sn, DavResource *root, UcxBuffer *rqbuf);
 
 #ifdef	__cplusplus
 }

mercurial