# HG changeset patch # User Olaf Wintermann # Date 1436369486 -7200 # Node ID 664aeaec8d256c04770ceb05fb35caeb9317e4ca # Parent 4bccc18820e8f5b6c36d8342921d0ba7840fe603 replaced old davql (still buggy) diff -r 4bccc18820e8 -r 664aeaec8d25 dav/main.c --- 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 #include 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); diff -r 4bccc18820e8 -r 664aeaec8d25 dav/sync.c --- 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 diff -r 4bccc18820e8 -r 664aeaec8d25 libidav/Makefile --- 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)) diff -r 4bccc18820e8 -r 664aeaec8d25 libidav/davql.c --- 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 -#include -#include - -#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;idata; - 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 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 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;iptr = s.ptr + i; - str->length = s.length - i; - return t; - } - - for(i=0;i 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;icontentlength; - } 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; -} diff -r 4bccc18820e8 -r 664aeaec8d25 libidav/davql.h --- 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 -#include -#include -#include - -#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 */ - diff -r 4bccc18820e8 -r 664aeaec8d25 libidav/davqlexec.c --- 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; } } diff -r 4bccc18820e8 -r 664aeaec8d25 libidav/davqlexec.h --- 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); diff -r 4bccc18820e8 -r 664aeaec8d25 libidav/methods.c --- 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); } diff -r 4bccc18820e8 -r 664aeaec8d25 libidav/methods.h --- 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); diff -r 4bccc18820e8 -r 664aeaec8d25 libidav/resource.c --- 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 { diff -r 4bccc18820e8 -r 664aeaec8d25 libidav/session.c --- 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)) { diff -r 4bccc18820e8 -r 664aeaec8d25 libidav/webdav.c --- 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; } diff -r 4bccc18820e8 -r 664aeaec8d25 libidav/webdav.h --- 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 }