libidav/davqlexec.c

changeset 365
f04ab0420512
parent 361
b6f2462ee055
child 387
92f8a2a243fc
equal deleted inserted replaced
364:3769ba002fd1 365:f04ab0420512
1 /* 1 /*
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 * 3 *
4 * Copyright 2016 Olaf Wintermann. All rights reserved. 4 * Copyright 2018 Olaf Wintermann. All rights reserved.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met: 7 * modification, are permitted provided that the following conditions are met:
8 * 8 *
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
37 #include "utils.h" 37 #include "utils.h"
38 #include "methods.h" 38 #include "methods.h"
39 #include "session.h" 39 #include "session.h"
40 #include "resource.h" 40 #include "resource.h"
41 41
42 DavQLArgList* dav_ql_get_args(DavQLStatement *st, va_list ap) {
43 DavQLArgList *args = malloc(sizeof(DavQLArgList));
44 if(!args) {
45 return NULL;
46 }
47 args->first = NULL;
48
49 DavQLArg *cur = NULL;
50 UCX_FOREACH(elm, st->args) {
51 intptr_t type = (intptr_t)elm->data;
52 DavQLArg *arg = calloc(1, sizeof(DavQLArg));
53 if(!arg) {
54 dav_ql_free_arglist(args);
55 return NULL;
56 }
57 arg->type = type;
58 switch(type) {
59 case 'd': {
60 arg->value.d = va_arg(ap, int);
61 break;
62 }
63 case 'u': {
64 arg->value.u = va_arg(ap, unsigned int);
65 break;
66 }
67 case 's': {
68 arg->value.s = va_arg(ap, char*);
69 break;
70 }
71 case 't': {
72 arg->value.t = va_arg(ap, time_t);
73 break;
74 }
75 default: {
76 free(arg);
77 dav_ql_free_arglist(args);
78 return NULL;
79 }
80 }
81 if(cur) {
82 cur->next = arg;
83 } else {
84 args->first = arg;
85 }
86 cur = arg;
87 }
88 args->current = args->first;
89 return args;
90 }
91
92 void dav_ql_free_arglist(DavQLArgList *args) {
93 DavQLArg *arg = args->first;
94 while(arg) {
95 DavQLArg *next = arg->next;
96 free(arg);
97 arg = next;
98 }
99 }
100
101 static DavQLArg* arglist_get(DavQLArgList *args) {
102 DavQLArg *a = args->current;
103 if(a) {
104 args->current = a->next;
105 }
106 return a;
107 }
108
109 int dav_ql_getarg_int(DavQLArgList *args) {
110 DavQLArg *a = arglist_get(args);
111 if(a && a->type == 'd') {
112 return a->value.d;
113 }
114 return 0;
115 }
116
117 unsigned int dav_ql_getarg_uint(DavQLArgList *args) {
118 DavQLArg *a = arglist_get(args);
119 if(a && a->type == 'u') {
120 return a->value.u;
121 }
122 return 0;
123 }
124
125 char* dav_ql_getarg_str(DavQLArgList *args) {
126 DavQLArg *a = arglist_get(args);
127 if(a && a->type == 's') {
128 return a->value.s;
129 }
130 return "";
131 }
132
133 time_t dav_ql_getarg_time(DavQLArgList *args) {
134 DavQLArg *a = arglist_get(args);
135 if(a && a->type == 't') {
136 return a->value.t;
137 }
138 return 0;
139 }
140
141
42 DavResult dav_statement_exec(DavSession *sn, DavQLStatement *st, ...) { 142 DavResult dav_statement_exec(DavSession *sn, DavQLStatement *st, ...) {
43 va_list ap; 143 va_list ap;
44 va_start(ap, st); 144 va_start(ap, st);
45 DavResult result = dav_statement_execv(sn, st, ap); 145 DavResult result = dav_statement_execv(sn, st, ap);
46 va_end(ap); 146 va_end(ap);
64 } 164 }
65 165
66 return result; 166 return result;
67 } 167 }
68 168
69 sstr_t dav_format_string(UcxAllocator *a, sstr_t fstr, va_list ap, davqlerror_t *error) { 169 sstr_t dav_format_string(UcxAllocator *a, sstr_t fstr, DavQLArgList *ap, davqlerror_t *error) {
70 UcxBuffer *buf = ucx_buffer_new(NULL, 128, UCX_BUFFER_AUTOEXTEND); 170 UcxBuffer *buf = ucx_buffer_new(NULL, 128, UCX_BUFFER_AUTOEXTEND);
71 171
72 int placeholder = 0; 172 int placeholder = 0;
73 for(int i=0;i<fstr.length;i++) { 173 for(int i=0;i<fstr.length;i++) {
74 char c = fstr.ptr[i]; 174 char c = fstr.ptr[i];
79 } else { 179 } else {
80 // detect placeholder type and insert arg 180 // detect placeholder type and insert arg
81 int err = 0; 181 int err = 0;
82 switch(c) { 182 switch(c) {
83 case 's': { 183 case 's': {
84 char *arg = va_arg(ap, char*); 184 char *arg = dav_ql_getarg_str(ap);
85 ucx_buffer_puts(buf, arg); 185 ucx_buffer_puts(buf, arg);
86 break; 186 break;
87 } 187 }
88 case 'd': { 188 case 'd': {
89 int arg = va_arg(ap, int); 189 int arg = dav_ql_getarg_int(ap);
90 ucx_bprintf(buf, "%d", arg); 190 ucx_bprintf(buf, "%d", arg);
91 break; 191 break;
92 } 192 }
93 case 'u': { 193 case 'u': {
94 unsigned int arg = va_arg(ap, unsigned int); 194 unsigned int arg = dav_ql_getarg_uint(ap);
95 ucx_bprintf(buf, "%u", arg); 195 ucx_bprintf(buf, "%u", arg);
96 break; 196 break;
97 } 197 }
98 case 't': { 198 case 't': {
99 // time arguments not supported for strings 199 // time arguments not supported for strings
336 UcxMempool *mp = ucx_mempool_new(128); 436 UcxMempool *mp = ucx_mempool_new(128);
337 DavResult result; 437 DavResult result;
338 result.result = NULL; 438 result.result = NULL;
339 result.status = 1; 439 result.status = 1;
340 440
441 DavQLArgList *args = dav_ql_get_args(st, ap);
442 if(!args) {
443 return result;
444 }
445 ucx_mempool_reg_destr(mp, args, (ucx_destructor)dav_ql_free_arglist);
446
341 int isallprop; 447 int isallprop;
342 UcxBuffer *rqbuf = fieldlist2propfindrequest(sn, mp, st->fields, &isallprop); 448 UcxBuffer *rqbuf = fieldlist2propfindrequest(sn, mp, st->fields, &isallprop);
343 if(!rqbuf) { 449 if(!rqbuf) {
344 ucx_mempool_destroy(mp); 450 ucx_mempool_destroy(mp);
345 return result; 451 return result;
354 // compile field expression 460 // compile field expression
355 UcxBuffer *code = dav_compile_expr( 461 UcxBuffer *code = dav_compile_expr(
356 sn->context, 462 sn->context,
357 mp->allocator, 463 mp->allocator,
358 field->expr, 464 field->expr,
359 ap); 465 args);
360 if(!code) { 466 if(!code) {
361 // TODO: set error string 467 // TODO: set error string
362 return result; 468 return result;
363 } 469 }
364 ucx_mempool_reg_destr(mp, code, (ucx_destructor)ucx_buffer_free); 470 ucx_mempool_reg_destr(mp, code, (ucx_destructor)ucx_buffer_free);
384 } 490 }
385 } 491 }
386 492
387 // get path string 493 // get path string
388 davqlerror_t error; 494 davqlerror_t error;
389 sstr_t path = dav_format_string(mp->allocator, st->path, ap, &error); 495 sstr_t path = dav_format_string(mp->allocator, st->path, args, &error);
390 if(error) { 496 if(error) {
391 // TODO: cleanup 497 // TODO: cleanup
392 ucx_mempool_destroy(mp); 498 ucx_mempool_destroy(mp);
393 return result; 499 return result;
394 } 500 }
395 501
396 int depth = st->depth == DAV_DEPTH_PLACEHOLDER ? va_arg(ap, int) : st->depth; 502 int depth = st->depth == DAV_DEPTH_PLACEHOLDER ?
397 503 dav_ql_getarg_int(args) : st->depth;
398 UcxBuffer *where = dav_compile_expr(sn->context, mp->allocator, st->where, ap); 504
505 UcxBuffer *where = dav_compile_expr(sn->context, mp->allocator, st->where, args);
399 if(st->where && !where) { 506 if(st->where && !where) {
400 // TODO: cleanup 507 // TODO: cleanup
401 ucx_mempool_destroy(mp); 508 ucx_mempool_destroy(mp);
402 return result; 509 return result;
403 } 510 }
625 return 0; 732 return 0;
626 } 733 }
627 return 1; 734 return 1;
628 } 735 }
629 736
630 static int add_cmd(DavContext *ctx, UcxAllocator *a, UcxBuffer *bcode, DavQLExpression *expr, va_list ap) { 737 static int add_cmd(DavContext *ctx, UcxAllocator *a, UcxBuffer *bcode, DavQLExpression *expr, DavQLArgList *ap) {
631 if(!expr) { 738 if(!expr) {
632 return 0; 739 return 0;
633 } 740 }
634 741
635 int numcmd = 1; 742 int numcmd = 1;
641 switch(expr->type) { 748 switch(expr->type) {
642 default: break; 749 default: break;
643 case DAVQL_NUMBER: { 750 case DAVQL_NUMBER: {
644 cmd.type = DAVQL_CMD_INT; 751 cmd.type = DAVQL_CMD_INT;
645 if(src.ptr[0] == '%') { 752 if(src.ptr[0] == '%') {
646 cmd.data.integer = va_arg(ap, int); 753 cmd.data.integer = dav_ql_getarg_int(ap);
647 } else if(util_strtoint(src.ptr, &cmd.data.integer)) { 754 } else if(util_strtoint(src.ptr, &cmd.data.integer)) {
648 ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode); 755 ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode);
649 } else { 756 } else {
650 // error 757 // error
651 return -1; 758 return -1;
660 break; 767 break;
661 } 768 }
662 case DAVQL_TIMESTAMP: { 769 case DAVQL_TIMESTAMP: {
663 if(src.ptr[0] == '%') { 770 if(src.ptr[0] == '%') {
664 cmd.type = DAVQL_CMD_TIMESTAMP; 771 cmd.type = DAVQL_CMD_TIMESTAMP;
665 cmd.data.timestamp = va_arg(ap, time_t); 772 cmd.data.timestamp = dav_ql_getarg_time(ap);
666 ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode); 773 ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode);
667 } else { 774 } else {
668 // error 775 // error
669 return -1; 776 return -1;
670 } 777 }
884 } 991 }
885 } 992 }
886 return numcmd; 993 return numcmd;
887 } 994 }
888 995
889 UcxBuffer* dav_compile_expr(DavContext *ctx, UcxAllocator *a, DavQLExpression *lexpr, va_list ap) { 996 UcxBuffer* dav_compile_expr(DavContext *ctx, UcxAllocator *a, DavQLExpression *lexpr, DavQLArgList *ap) {
890 UcxBuffer *bcode = ucx_buffer_new(NULL, 512, UCX_BUFFER_AUTOEXTEND); 997 UcxBuffer *bcode = ucx_buffer_new(NULL, 512, UCX_BUFFER_AUTOEXTEND);
891 if(!bcode) { 998 if(!bcode) {
892 return NULL; 999 return NULL;
893 } 1000 }
894 1001

mercurial